var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __esm = (fn, res, err) => function __init() {
  if (err) throw err[0];
  try {
    return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
  } catch (e) {
    throw err = [e], e;
  }
};
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};

// dist/build/server/chunks/uneval.js
function is_primitive(thing) {
  return thing === null || typeof thing !== "object" && typeof thing !== "function";
}
function is_plain_object(thing) {
  const proto = Object.getPrototypeOf(thing);
  return proto === Object.prototype || proto === null || Object.getPrototypeOf(proto) === null || Object.getOwnPropertyNames(proto).sort().join("\0") === object_proto_names;
}
function get_type(thing) {
  return Object.prototype.toString.call(thing).slice(8, -1);
}
function get_escaped_char(char) {
  switch (char) {
    case '"':
      return '\\"';
    case "<":
      return "\\u003C";
    case "\\":
      return "\\\\";
    case "\n":
      return "\\n";
    case "\r":
      return "\\r";
    case "	":
      return "\\t";
    case "\b":
      return "\\b";
    case "\f":
      return "\\f";
    case "\u2028":
      return "\\u2028";
    case "\u2029":
      return "\\u2029";
    default:
      return char < " " ? `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}` : "";
  }
}
function stringify_string(str2) {
  let result = "";
  let last_pos = 0;
  const len = str2.length;
  for (let i = 0; i < len; i += 1) {
    const char = str2[i];
    const replacement = get_escaped_char(char);
    if (replacement) {
      result += str2.slice(last_pos, i) + replacement;
      last_pos = i + 1;
    }
  }
  return `"${last_pos === 0 ? str2 : result + str2.slice(last_pos)}"`;
}
function enumerable_symbols(object) {
  return Object.getOwnPropertySymbols(object).filter((symbol) => Object.getOwnPropertyDescriptor(object, symbol).enumerable);
}
function stringify_key(key2) {
  return is_identifier.test(key2) ? "." + key2 : "[" + JSON.stringify(key2) + "]";
}
function is_valid_array_index(n) {
  if (!Number.isInteger(n)) return false;
  if (n < 0) return false;
  if (n > MAX_ARRAY_INDEX) return false;
  return true;
}
function is_valid_array_len(n) {
  if (!Number.isInteger(n)) return false;
  if (n < 0) return false;
  if (n > MAX_ARRAY_LEN) return false;
  return true;
}
function is_valid_array_index_string(s3) {
  if (s3.length === 0) return false;
  if (s3.length > 1 && s3.charCodeAt(0) === 48) return false;
  for (let i = 0; i < s3.length; i++) {
    const c2 = s3.charCodeAt(i);
    if (c2 < 48 || c2 > 57) return false;
  }
  return is_valid_array_index(+s3);
}
function valid_array_indices(array2) {
  const keys = Object.keys(array2);
  for (var i = keys.length - 1; i >= 0; i--) if (is_valid_array_index_string(keys[i])) break;
  keys.length = i + 1;
  return keys;
}
function uneval(value2, replacer) {
  const counts = /* @__PURE__ */ new Map();
  const keys = [];
  const custom = /* @__PURE__ */ new Map();
  function walk(thing) {
    if (!is_primitive(thing)) {
      if (counts.has(thing)) {
        counts.set(thing, counts.get(thing) + 1);
        return;
      }
      counts.set(thing, 1);
      if (replacer) {
        const str3 = replacer(thing, (value3) => uneval(value3, replacer));
        if (typeof str3 === "string") {
          custom.set(thing, str3);
          return;
        }
      }
      if (typeof thing === "function") throw new DevalueError(`Cannot stringify a function`, keys, thing, value2);
      switch (get_type(thing)) {
        case "Number":
        case "BigInt":
        case "String":
        case "Boolean":
        case "Date":
        case "RegExp":
        case "URL":
        case "URLSearchParams":
          return;
        case "Array":
          thing.forEach((value3, i) => {
            keys.push(`[${i}]`);
            walk(value3);
            keys.pop();
          });
          break;
        case "Set":
          Array.from(thing).forEach(walk);
          break;
        case "Map":
          for (const [key2, value3] of thing) {
            keys.push(`.get(${is_primitive(key2) ? stringify_primitive(key2) : "..."})`);
            walk(value3);
            keys.pop();
          }
          break;
        case "Int8Array":
        case "Uint8Array":
        case "Uint8ClampedArray":
        case "Int16Array":
        case "Uint16Array":
        case "Float16Array":
        case "Int32Array":
        case "Uint32Array":
        case "Float32Array":
        case "Float64Array":
        case "BigInt64Array":
        case "BigUint64Array":
        case "DataView":
          walk(thing.buffer);
          return;
        case "ArrayBuffer":
          return;
        case "Temporal.Duration":
        case "Temporal.Instant":
        case "Temporal.PlainDate":
        case "Temporal.PlainTime":
        case "Temporal.PlainDateTime":
        case "Temporal.PlainMonthDay":
        case "Temporal.PlainYearMonth":
        case "Temporal.ZonedDateTime":
          return;
        default:
          if (!is_plain_object(thing)) throw new DevalueError(`Cannot stringify arbitrary non-POJOs`, keys, thing, value2);
          if (enumerable_symbols(thing).length > 0) throw new DevalueError(`Cannot stringify POJOs with symbolic keys`, keys, thing, value2);
          for (const key2 of Object.keys(thing)) {
            if (key2 === "__proto__") throw new DevalueError(`Cannot stringify objects with __proto__ keys`, keys, thing, value2);
            keys.push(stringify_key(key2));
            walk(thing[key2]);
            keys.pop();
          }
      }
    } else if (typeof thing === "symbol") throw new DevalueError(`Cannot stringify a Symbol primitive`, keys, thing, value2);
  }
  walk(value2);
  const names2 = /* @__PURE__ */ new Map();
  Array.from(counts).filter((entry) => entry[1] > 1).sort((a2, b3) => b3[1] - a2[1]).forEach((entry, i) => {
    names2.set(entry[0], get_name(i));
  });
  function stringify4(thing) {
    if (names2.has(thing)) return names2.get(thing);
    if (is_primitive(thing)) return stringify_primitive(thing);
    if (custom.has(thing)) return custom.get(thing);
    const type = get_type(thing);
    switch (type) {
      case "Number":
      case "String":
      case "Boolean":
      case "BigInt":
        return `Object(${stringify4(thing.valueOf())})`;
      case "RegExp":
        const { source: source2, flags: flags2 } = thing;
        return flags2 ? `new RegExp(${stringify_string(source2)},"${flags2}")` : `new RegExp(${stringify_string(source2)})`;
      case "Date":
        return `new Date(${thing.getTime()})`;
      case "URL":
        return `new URL(${stringify_string(thing.toString())})`;
      case "URLSearchParams":
        return `new URLSearchParams(${stringify_string(thing.toString())})`;
      case "Array": {
        let has_holes = false;
        let result = "[";
        for (let i = 0; i < thing.length; i += 1) {
          if (i > 0) result += ",";
          if (Object.hasOwn(thing, i)) result += stringify4(thing[i]);
          else if (!has_holes) {
            const populated_keys = valid_array_indices(thing);
            const population = populated_keys.length;
            const d2 = String(thing.length).length;
            if (thing.length + 2 > 25 + d2 + population * (d2 + 2)) {
              const entries = populated_keys.map((k2) => `${k2}:${stringify4(thing[k2])}`).join(",");
              return `Object.assign(Array(${thing.length}),{${entries}})`;
            }
            has_holes = true;
            i -= 1;
          }
        }
        const tail = thing.length === 0 || thing.length - 1 in thing ? "" : ",";
        return result + tail + "]";
      }
      case "Set":
      case "Map":
        return `new ${type}([${Array.from(thing).map(stringify4).join(",")}])`;
      case "Int8Array":
      case "Uint8Array":
      case "Uint8ClampedArray":
      case "Int16Array":
      case "Uint16Array":
      case "Float16Array":
      case "Int32Array":
      case "Uint32Array":
      case "Float32Array":
      case "Float64Array":
      case "BigInt64Array":
      case "BigUint64Array": {
        let str3 = `new ${type}`;
        if (!names2.has(thing.buffer)) {
          const array2 = new thing.constructor(thing.buffer);
          str3 += `([${array2}])`;
        } else str3 += `(${stringify4(thing.buffer)})`;
        if (thing.byteLength !== thing.buffer.byteLength) {
          const start = thing.byteOffset / thing.BYTES_PER_ELEMENT;
          const end = start + thing.length;
          str3 += `.subarray(${start},${end})`;
        }
        return str3;
      }
      case "DataView": {
        let str3 = `new DataView`;
        if (!names2.has(thing.buffer)) str3 += `(new Uint8Array([${new Uint8Array(thing.buffer)}]).buffer`;
        else str3 += `(${stringify4(thing.buffer)}`;
        if (thing.byteLength !== thing.buffer.byteLength) str3 += `,${thing.startOffset},${thing.byteLength}`;
        return str3 + ")";
      }
      case "ArrayBuffer":
        return `new Uint8Array([${new Uint8Array(thing).toString()}]).buffer`;
      case "Temporal.Duration":
      case "Temporal.Instant":
      case "Temporal.PlainDate":
      case "Temporal.PlainTime":
      case "Temporal.PlainDateTime":
      case "Temporal.PlainMonthDay":
      case "Temporal.PlainYearMonth":
      case "Temporal.ZonedDateTime":
        return `${type}.from(${stringify_string(thing.toString())})`;
      default:
        const keys2 = Object.keys(thing);
        const obj = keys2.map((key2) => `${safe_key(key2)}:${stringify4(thing[key2])}`).join(",");
        if (Object.getPrototypeOf(thing) === null) return keys2.length > 0 ? `{${obj},__proto__:null}` : `{__proto__:null}`;
        return `{${obj}}`;
    }
  }
  const str2 = stringify4(value2);
  if (names2.size) {
    const params = [];
    const statements = [];
    const values = [];
    names2.forEach((name, thing) => {
      params.push(name);
      if (custom.has(thing)) {
        values.push(custom.get(thing));
        return;
      }
      if (is_primitive(thing)) {
        values.push(stringify_primitive(thing));
        return;
      }
      const type = get_type(thing);
      switch (type) {
        case "Number":
        case "String":
        case "Boolean":
        case "BigInt":
          values.push(`Object(${stringify4(thing.valueOf())})`);
          break;
        case "RegExp":
          const { source: source2, flags: flags2 } = thing;
          const regexp2 = flags2 ? `new RegExp(${stringify_string(source2)},"${flags2}")` : `new RegExp(${stringify_string(source2)})`;
          values.push(regexp2);
          break;
        case "Date":
          values.push(`new Date(${thing.getTime()})`);
          break;
        case "URL":
          values.push(`new URL(${stringify_string(thing.toString())})`);
          break;
        case "URLSearchParams":
          values.push(`new URLSearchParams(${stringify_string(thing.toString())})`);
          break;
        case "Array":
          values.push(`Array(${thing.length})`);
          thing.forEach((v3, i) => {
            statements.push(`${name}[${i}]=${stringify4(v3)}`);
          });
          break;
        case "Set":
          values.push(`new Set`);
          statements.push(`${name}.${Array.from(thing).map((v3) => `add(${stringify4(v3)})`).join(".")}`);
          break;
        case "Map":
          values.push(`new Map`);
          statements.push(`${name}.${Array.from(thing).map(([k2, v3]) => `set(${stringify4(k2)}, ${stringify4(v3)})`).join(".")}`);
          break;
        case "Int8Array":
        case "Uint8Array":
        case "Uint8ClampedArray":
        case "Int16Array":
        case "Uint16Array":
        case "Float16Array":
        case "Int32Array":
        case "Uint32Array":
        case "Float32Array":
        case "Float64Array":
        case "BigInt64Array":
        case "BigUint64Array": {
          let str3 = `new ${type}`;
          if (!names2.has(thing.buffer)) {
            const array2 = new thing.constructor(thing.buffer);
            str3 += `([${array2}])`;
          } else str3 += `(${stringify4(thing.buffer)})`;
          if (thing.byteLength !== thing.buffer.byteLength) {
            const start = thing.byteOffset / thing.BYTES_PER_ELEMENT;
            const end = start + thing.length;
            str3 += `.subarray(${start},${end})`;
          }
          values.push(`{}`);
          statements.push(`${name}=${str3}`);
          break;
        }
        case "DataView": {
          let str3 = `new DataView`;
          if (!names2.has(thing.buffer)) str3 += `(new Uint8Array([${new Uint8Array(thing.buffer)}]).buffer`;
          else str3 += `(${stringify4(thing.buffer)}`;
          if (thing.byteLength !== thing.buffer.byteLength) str3 += `,${thing.byteOffset},${thing.byteLength}`;
          str3 += ")";
          values.push(`{}`);
          statements.push(`${name}=${str3}`);
          break;
        }
        case "ArrayBuffer":
          values.push(`new Uint8Array([${new Uint8Array(thing)}]).buffer`);
          break;
        default:
          values.push(Object.getPrototypeOf(thing) === null ? "Object.create(null)" : "{}");
          Object.keys(thing).forEach((key2) => {
            statements.push(`${name}${safe_prop(key2)}=${stringify4(thing[key2])}`);
          });
      }
    });
    statements.push(`return ${str2}`);
    return `(function(${params.join(",")}){${statements.join(";")}}(${values.join(",")}))`;
  } else return str2;
}
function get_name(num) {
  let name = "";
  do {
    name = chars[num % 54] + name;
    num = ~~(num / 54) - 1;
  } while (num >= 0);
  return reserved.test(name) ? `${name}0` : name;
}
function escape_unsafe_char(c2) {
  return escaped[c2] || c2;
}
function escape_unsafe_chars(str2) {
  return str2.replace(unsafe_chars, escape_unsafe_char);
}
function safe_key(key2) {
  return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key2) ? key2 : escape_unsafe_chars(JSON.stringify(key2));
}
function safe_prop(key2) {
  return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key2) ? `.${key2}` : `[${escape_unsafe_chars(JSON.stringify(key2))}]`;
}
function stringify_primitive(thing) {
  const type = typeof thing;
  if (type === "string") return stringify_string(thing);
  if (thing === void 0) return "void 0";
  if (thing === 0 && 1 / thing < 0) return "-0";
  const str2 = String(thing);
  if (type === "number") return str2.replace(/^(-)?0\./, "$1.");
  if (type === "bigint") return thing + "n";
  return str2;
}
var MAX_ARRAY_LEN, MAX_ARRAY_INDEX, escaped, DevalueError, object_proto_names, is_identifier, chars, unsafe_chars, reserved;
var init_uneval = __esm({
  "dist/build/server/chunks/uneval.js"() {
    "use strict";
    MAX_ARRAY_LEN = 2 ** 32 - 1;
    MAX_ARRAY_INDEX = MAX_ARRAY_LEN - 1;
    escaped = {
      "<": "\\u003C",
      "\\": "\\\\",
      "\b": "\\b",
      "\f": "\\f",
      "\n": "\\n",
      "\r": "\\r",
      "	": "\\t",
      "\u2028": "\\u2028",
      "\u2029": "\\u2029"
    };
    DevalueError = class extends Error {
      /**
      * @param {string} message
      * @param {string[]} keys
      * @param {any} [value] - The value that failed to be serialized
      * @param {any} [root] - The root value being serialized
      */
      constructor(message2, keys, value2, root) {
        super(message2);
        this.name = "DevalueError";
        this.path = keys.join("");
        this.value = value2;
        this.root = root;
      }
    };
    object_proto_names = /* @__PURE__ */ Object.getOwnPropertyNames(Object.prototype).sort().join("\0");
    is_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
    chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$";
    unsafe_chars = /[<\b\f\n\r\t\0\u2028\u2029]/g;
    reserved = /^(?:do|if|in|for|int|let|new|try|var|byte|case|char|else|enum|goto|long|this|void|with|await|break|catch|class|const|final|float|short|super|throw|while|yield|delete|double|export|import|native|return|switch|throws|typeof|boolean|default|extends|finally|package|private|abstract|continue|debugger|function|volatile|interface|protected|transient|implements|instanceof|synchronized)$/;
  }
});

// dist/build/server/chunks/server.js
function run(fn) {
  return fn();
}
function run_all(arr) {
  for (var i = 0; i < arr.length; i++) arr[i]();
}
function deferred() {
  var resolve6;
  var reject;
  return {
    promise: new Promise((res, rej) => {
      resolve6 = res;
      reject = rej;
    }),
    resolve: resolve6,
    reject
  };
}
function fallback(value2, fallback2, lazy = false) {
  return value2 === void 0 ? lazy ? fallback2() : fallback2 : value2;
}
function equals(value2) {
  return value2 === this.v;
}
function safe_not_equal(a2, b3) {
  return a2 != a2 ? b3 == b3 : a2 !== b3 || a2 !== null && typeof a2 === "object" || typeof a2 === "function";
}
function safe_equals(value2) {
  return !safe_not_equal(value2, this.v);
}
function experimental_async_required(name) {
  throw new Error(`https://svelte.dev/e/experimental_async_required`);
}
function lifecycle_outside_component(name) {
  throw new Error(`https://svelte.dev/e/lifecycle_outside_component`);
}
function missing_context() {
  throw new Error(`https://svelte.dev/e/missing_context`);
}
function effect_update_depth_exceeded() {
  throw new Error(`https://svelte.dev/e/effect_update_depth_exceeded`);
}
function hydration_failed() {
  throw new Error(`https://svelte.dev/e/hydration_failed`);
}
function state_descriptors_fixed() {
  throw new Error(`https://svelte.dev/e/state_descriptors_fixed`);
}
function state_prototype_fixed() {
  throw new Error(`https://svelte.dev/e/state_prototype_fixed`);
}
function state_unsafe_mutation() {
  throw new Error(`https://svelte.dev/e/state_unsafe_mutation`);
}
function svelte_boundary_reset_onerror() {
  throw new Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`);
}
function derived_inert() {
  console.warn(`https://svelte.dev/e/derived_inert`);
}
function hydration_mismatch(location) {
  console.warn(`https://svelte.dev/e/hydration_mismatch`);
}
function svelte_boundary_reset_noop() {
  console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`);
}
function set_hydrating(value2) {
  hydrating = value2;
}
function set_hydrate_node(node) {
  if (node === null) {
    hydration_mismatch();
    throw HYDRATION_ERROR;
  }
  return hydrate_node = node;
}
function hydrate_next() {
  return set_hydrate_node(/* @__PURE__ */ get_next_sibling(hydrate_node));
}
function next(count = 1) {
  if (hydrating) {
    var i = count;
    var node = hydrate_node;
    while (i--) node = /* @__PURE__ */ get_next_sibling(node);
    hydrate_node = node;
  }
}
function skip_nodes(remove5 = true) {
  var depth = 0;
  var node = hydrate_node;
  while (true) {
    if (node.nodeType === 8) {
      var data = node.data;
      if (data === "]") {
        if (depth === 0) return node;
        depth -= 1;
      } else if (data === "[" || data === "[!" || data[0] === "[" && !isNaN(Number(data.slice(1)))) depth += 1;
    }
    var next2 = /* @__PURE__ */ get_next_sibling(node);
    if (remove5) node.remove();
    node = next2;
  }
}
function set_component_context(context2) {
  component_context = context2;
}
function push$1(props, runes = false, fn) {
  component_context = {
    p: component_context,
    i: false,
    c: null,
    e: null,
    s: props,
    x: null,
    r: active_effect,
    l: legacy_mode_flag && !runes ? {
      s: null,
      u: null,
      $: []
    } : null
  };
}
function pop$1(component84) {
  var context2 = component_context;
  var effects = context2.e;
  if (effects !== null) {
    context2.e = null;
    for (var fn of effects) create_user_effect(fn);
  }
  if (component84 !== void 0) context2.x = component84;
  context2.i = true;
  component_context = context2.p;
  return component84 ?? {};
}
function is_runes() {
  return !legacy_mode_flag || component_context !== null && component_context.l === null;
}
function run_micro_tasks() {
  var tasks = micro_tasks;
  micro_tasks = [];
  run_all(tasks);
}
function queue_micro_task(fn) {
  if (micro_tasks.length === 0 && !is_flushing_sync) {
    var tasks = micro_tasks;
    queueMicrotask(() => {
      if (tasks === micro_tasks) run_micro_tasks();
    });
  }
  micro_tasks.push(fn);
}
function flush_tasks() {
  while (micro_tasks.length > 0) run_micro_tasks();
}
function handle_error(error2) {
  var effect = active_effect;
  if (effect === null) {
    active_reaction.f |= ERROR_VALUE;
    return error2;
  }
  if ((effect.f & 32768) === 0 && (effect.f & 4) === 0) throw error2;
  invoke_error_boundary(error2, effect);
}
function invoke_error_boundary(error2, effect) {
  if (effect !== null && (effect.f & 16384) !== 0) return;
  while (effect !== null) {
    if ((effect.f & 128) !== 0) {
      if ((effect.f & 32768) === 0) throw error2;
      try {
        effect.b.error(error2);
        return;
      } catch (e) {
        error2 = e;
      }
    }
    effect = effect.parent;
  }
  throw error2;
}
function set_signal_status(signal, status) {
  signal.f = signal.f & STATUS_MASK | status;
}
function update_derived_status(derived2) {
  if ((derived2.f & 512) !== 0 || derived2.deps === null) set_signal_status(derived2, CLEAN);
  else set_signal_status(derived2, MAYBE_DIRTY);
}
function clear_marked(deps) {
  if (deps === null) return;
  for (const dep of deps) {
    if ((dep.f & 2) === 0 || (dep.f & 65536) === 0) continue;
    dep.f ^= WAS_MARKED;
    clear_marked(
      /** @type {Derived} */
      dep.deps
    );
  }
}
function defer_effect(effect, dirty_effects, maybe_dirty_effects) {
  if ((effect.f & 2048) !== 0) dirty_effects.add(effect);
  else if ((effect.f & 4096) !== 0) maybe_dirty_effects.add(effect);
  clear_marked(effect.deps);
  set_signal_status(effect, CLEAN);
}
function without_reactive_context(fn) {
  var previous_reaction = active_reaction;
  var previous_effect = active_effect;
  set_active_reaction(null);
  set_active_effect(null);
  try {
    return fn();
  } finally {
    set_active_reaction(previous_reaction);
    set_active_effect(previous_effect);
  }
}
function createSubscriber(start) {
  let subscribers2 = 0;
  let version = source(0);
  let stop;
  return () => {
    if (effect_tracking()) {
      get$1(version);
      render_effect(() => {
        if (subscribers2 === 0) stop = untrack(() => start(() => increment(version)));
        subscribers2 += 1;
        return () => {
          queue_micro_task(() => {
            subscribers2 -= 1;
            if (subscribers2 === 0) {
              stop?.();
              stop = void 0;
              increment(version);
            }
          });
        };
      });
    }
  };
}
function boundary(node, props, children, transform_error) {
  new Boundary(node, props, children, transform_error);
}
function destroy_derived_effects(derived2) {
  var effects = derived2.effects;
  if (effects !== null) {
    derived2.effects = null;
    for (var i = 0; i < effects.length; i += 1) destroy_effect(effects[i]);
  }
}
function execute_derived(derived2) {
  var value2;
  var prev_active_effect = active_effect;
  var parent = derived2.parent;
  if (!is_destroying_effect && parent !== null && derived2.v !== UNINITIALIZED && (parent.f & 24576) !== 0) {
    derived_inert();
    return derived2.v;
  }
  set_active_effect(parent);
  try {
    derived2.f &= ~WAS_MARKED;
    destroy_derived_effects(derived2);
    value2 = update_reaction(derived2);
  } finally {
    set_active_effect(prev_active_effect);
  }
  return value2;
}
function update_derived(derived2) {
  var value2 = execute_derived(derived2);
  if (!derived2.equals(value2)) {
    derived2.wv = increment_write_version();
    if (!current_batch?.is_fork || derived2.deps === null) {
      if (current_batch !== null) {
        current_batch.capture(derived2, value2, true);
        previous_batch?.capture(derived2, value2, true);
      } else derived2.v = value2;
      if (derived2.deps === null) {
        set_signal_status(derived2, CLEAN);
        return;
      }
    }
  }
  if (is_destroying_effect) return;
  if (batch_values !== null) {
    if (effect_tracking() || current_batch?.is_fork) batch_values.set(derived2, value2);
  } else update_derived_status(derived2);
}
function freeze_derived_effects(derived2) {
  if (derived2.effects === null) return;
  for (const e of derived2.effects) if (e.teardown || e.ac) {
    e.teardown?.();
    if (e.ac !== null) without_reactive_context(() => {
      e.ac.abort(STALE_REACTION);
      e.ac = null;
    });
    if (e.fn !== null) e.teardown = noop;
    remove_reactions(e, 0);
    destroy_effect_children(e);
  }
}
function unfreeze_derived_effects(derived2) {
  if (derived2.effects === null) return;
  for (const e of derived2.effects) if (e.teardown && e.fn !== null) update_effect(e);
}
function flushSync(fn) {
  var was_flushing_sync = is_flushing_sync;
  is_flushing_sync = true;
  try {
    var result;
    if (fn) {
      if (current_batch !== null && !current_batch.is_fork) current_batch.flush();
      result = fn();
    }
    while (true) {
      flush_tasks();
      if (current_batch === null) return result;
      current_batch.flush();
    }
  } finally {
    is_flushing_sync = was_flushing_sync;
  }
}
function infinite_loop_guard() {
  try {
    effect_update_depth_exceeded();
  } catch (error2) {
    invoke_error_boundary(error2, last_scheduled_effect);
  }
}
function flush_queued_effects(effects) {
  var length = effects.length;
  if (length === 0) return;
  var i = 0;
  while (i < length) {
    var effect = effects[i++];
    if ((effect.f & 24576) === 0 && is_dirty(effect)) {
      eager_block_effects = /* @__PURE__ */ new Set();
      update_effect(effect);
      if (effect.deps === null && effect.first === null && effect.nodes === null && effect.teardown === null && effect.ac === null) unlink_effect(effect);
      if (eager_block_effects?.size > 0) {
        old_values.clear();
        for (const e of eager_block_effects) {
          if ((e.f & 24576) !== 0) continue;
          const ordered_effects = [e];
          let ancestor = e.parent;
          while (ancestor !== null) {
            if (eager_block_effects.has(ancestor)) {
              eager_block_effects.delete(ancestor);
              ordered_effects.push(ancestor);
            }
            ancestor = ancestor.parent;
          }
          for (let j2 = ordered_effects.length - 1; j2 >= 0; j2--) {
            const e2 = ordered_effects[j2];
            if ((e2.f & 24576) !== 0) continue;
            update_effect(e2);
          }
        }
        eager_block_effects.clear();
      }
    }
  }
  eager_block_effects = null;
}
function mark_effects(value2, sources, marked, checked) {
  if (marked.has(value2)) return;
  marked.add(value2);
  if (value2.reactions !== null) for (const reaction of value2.reactions) {
    const flags2 = reaction.f;
    if ((flags2 & 2) !== 0) mark_effects(reaction, sources, marked, checked);
    else if ((flags2 & 4194320) !== 0 && (flags2 & 2048) === 0 && depends_on(reaction, sources, checked)) {
      set_signal_status(reaction, DIRTY);
      schedule_effect(reaction);
    }
  }
}
function depends_on(reaction, sources, checked) {
  const depends = checked.get(reaction);
  if (depends !== void 0) return depends;
  if (reaction.deps !== null) for (const dep of reaction.deps) {
    if (includes.call(sources, dep)) return true;
    if ((dep.f & 2) !== 0 && depends_on(dep, sources, checked)) {
      checked.set(dep, true);
      return true;
    }
  }
  checked.set(reaction, false);
  return false;
}
function schedule_effect(effect) {
  current_batch.schedule(effect);
}
function reset_branch(effect, tracked) {
  if ((effect.f & 32) !== 0 && (effect.f & 1024) !== 0) return;
  if ((effect.f & 2048) !== 0) tracked.d.push(effect);
  else if ((effect.f & 4096) !== 0) tracked.m.push(effect);
  set_signal_status(effect, CLEAN);
  var e = effect.first;
  while (e !== null) {
    reset_branch(e, tracked);
    e = e.next;
  }
}
function reset_all(effect) {
  set_signal_status(effect, CLEAN);
  var e = effect.first;
  while (e !== null) {
    reset_all(e);
    e = e.next;
  }
}
function source(v3, stack) {
  return {
    f: 0,
    v: v3,
    reactions: null,
    equals,
    rv: 0,
    wv: 0
  };
}
// @__NO_SIDE_EFFECTS__
function state(v3, stack) {
  const s3 = source(v3, stack);
  push_reaction_value(s3);
  return s3;
}
// @__NO_SIDE_EFFECTS__
function mutable_source(initial_value, immutable = false, trackable = true) {
  const s3 = source(initial_value);
  if (!immutable) s3.equals = safe_equals;
  if (legacy_mode_flag && trackable && component_context !== null && component_context.l !== null) (component_context.l.s ??= []).push(s3);
  return s3;
}
function set(source2, value2, should_proxy = false) {
  if (active_reaction !== null && (!untracking || (active_reaction.f & 131072) !== 0) && is_runes() && (active_reaction.f & 4325394) !== 0 && (current_sources === null || !current_sources.has(source2))) state_unsafe_mutation();
  return internal_set(source2, should_proxy ? proxy(value2) : value2, legacy_updates);
}
function internal_set(source2, value2, updated_during_traversal = null) {
  if (!source2.equals(value2)) {
    old_values.set(source2, is_destroying_effect ? value2 : source2.v);
    var batch = Batch.ensure();
    batch.capture(source2, value2);
    if ((source2.f & 2) !== 0) {
      const derived2 = source2;
      if ((source2.f & 2048) !== 0) execute_derived(derived2);
      if (batch_values === null) update_derived_status(derived2);
    }
    source2.wv = increment_write_version();
    mark_reactions(source2, DIRTY, updated_during_traversal);
    if (is_runes() && active_effect !== null && (active_effect.f & 1024) !== 0 && (active_effect.f & 96) === 0) if (untracked_writes === null) set_untracked_writes([source2]);
    else untracked_writes.push(source2);
    if (!batch.is_fork && eager_effects.size > 0 && !eager_effects_deferred) flush_eager_effects();
  }
  return value2;
}
function flush_eager_effects() {
  eager_effects_deferred = false;
  for (const effect of eager_effects) {
    if ((effect.f & 1024) !== 0) set_signal_status(effect, MAYBE_DIRTY);
    let dirty;
    try {
      dirty = is_dirty(effect);
    } catch {
      dirty = true;
    }
    if (dirty) update_effect(effect);
  }
  eager_effects.clear();
}
function increment(source2) {
  set(source2, source2.v + 1);
}
function mark_reactions(signal, status, updated_during_traversal) {
  var reactions = signal.reactions;
  if (reactions === null) return;
  var runes = is_runes();
  var length = reactions.length;
  for (var i = 0; i < length; i++) {
    var reaction = reactions[i];
    var flags2 = reaction.f;
    if (!runes && reaction === active_effect) continue;
    var not_dirty = (flags2 & DIRTY) === 0;
    if (not_dirty) set_signal_status(reaction, status);
    if ((flags2 & 131072) !== 0) eager_effects.add(reaction);
    else if ((flags2 & 2) !== 0) {
      var derived2 = reaction;
      batch_values?.delete(derived2);
      if ((flags2 & 65536) === 0) {
        if (flags2 & 512 && (active_effect === null || (active_effect.f & 2097152) === 0)) reaction.f |= WAS_MARKED;
        mark_reactions(derived2, MAYBE_DIRTY, updated_during_traversal);
      }
    } else if (not_dirty) {
      var effect = reaction;
      if ((flags2 & 16) !== 0 && eager_block_effects !== null) eager_block_effects.add(effect);
      if (updated_during_traversal !== null) updated_during_traversal.push(effect);
      else schedule_effect(effect);
    }
  }
}
function proxy(value2) {
  if (typeof value2 !== "object" || value2 === null || STATE_SYMBOL in value2) return value2;
  const prototype = get_prototype_of(value2);
  if (prototype !== object_prototype && prototype !== array_prototype) return value2;
  var sources = /* @__PURE__ */ new Map();
  var is_proxied_array = is_array(value2);
  var version = /* @__PURE__ */ state(0);
  var stack = null;
  var parent_version = update_version;
  var with_parent = (fn) => {
    if (update_version === parent_version) return fn();
    var reaction = active_reaction;
    var version2 = update_version;
    set_active_reaction(null);
    set_update_version(parent_version);
    var result = fn();
    set_active_reaction(reaction);
    set_update_version(version2);
    return result;
  };
  if (is_proxied_array) sources.set("length", /* @__PURE__ */ state(
    /** @type {any[]} */
    value2.length,
    stack
  ));
  return new Proxy(value2, {
    defineProperty(_3, prop, descriptor) {
      if (!("value" in descriptor) || descriptor.configurable === false || descriptor.enumerable === false || descriptor.writable === false) state_descriptors_fixed();
      var s3 = sources.get(prop);
      if (s3 === void 0) with_parent(() => {
        var s4 = /* @__PURE__ */ state(descriptor.value, stack);
        sources.set(prop, s4);
        return s4;
      });
      else set(s3, descriptor.value, true);
      return true;
    },
    deleteProperty(target, prop) {
      var s3 = sources.get(prop);
      if (s3 === void 0) {
        if (prop in target) {
          const s4 = with_parent(() => /* @__PURE__ */ state(UNINITIALIZED, stack));
          sources.set(prop, s4);
          increment(version);
        }
      } else {
        set(s3, UNINITIALIZED);
        increment(version);
      }
      return true;
    },
    get(target, prop, receiver) {
      if (prop === STATE_SYMBOL) return value2;
      var s3 = sources.get(prop);
      var exists = prop in target;
      if (s3 === void 0 && (!exists || get_descriptor(target, prop)?.writable)) {
        s3 = with_parent(() => {
          return /* @__PURE__ */ state(proxy(exists ? target[prop] : UNINITIALIZED), stack);
        });
        sources.set(prop, s3);
      }
      if (s3 !== void 0) {
        var v3 = get$1(s3);
        return v3 === UNINITIALIZED ? void 0 : v3;
      }
      return Reflect.get(target, prop, receiver);
    },
    getOwnPropertyDescriptor(target, prop) {
      var descriptor = Reflect.getOwnPropertyDescriptor(target, prop);
      if (descriptor && "value" in descriptor) {
        var s3 = sources.get(prop);
        if (s3) descriptor.value = get$1(s3);
      } else if (descriptor === void 0) {
        var source2 = sources.get(prop);
        var value3 = source2?.v;
        if (source2 !== void 0 && value3 !== UNINITIALIZED) return {
          enumerable: true,
          configurable: true,
          value: value3,
          writable: true
        };
      }
      return descriptor;
    },
    has(target, prop) {
      if (prop === STATE_SYMBOL) return true;
      var s3 = sources.get(prop);
      var has = s3 !== void 0 && s3.v !== UNINITIALIZED || Reflect.has(target, prop);
      if (s3 !== void 0 || active_effect !== null && (!has || get_descriptor(target, prop)?.writable)) {
        if (s3 === void 0) {
          s3 = with_parent(() => {
            return /* @__PURE__ */ state(has ? proxy(target[prop]) : UNINITIALIZED, stack);
          });
          sources.set(prop, s3);
        }
        if (get$1(s3) === UNINITIALIZED) return false;
      }
      return has;
    },
    set(target, prop, value3, receiver) {
      var s3 = sources.get(prop);
      var has = prop in target;
      if (is_proxied_array && prop === "length") for (var i = value3; i < s3.v; i += 1) {
        var other_s = sources.get(i + "");
        if (other_s !== void 0) set(other_s, UNINITIALIZED);
        else if (i in target) {
          other_s = with_parent(() => /* @__PURE__ */ state(UNINITIALIZED, stack));
          sources.set(i + "", other_s);
        }
      }
      if (s3 === void 0) {
        if (!has || get_descriptor(target, prop)?.writable) {
          s3 = with_parent(() => /* @__PURE__ */ state(void 0, stack));
          set(s3, proxy(value3));
          sources.set(prop, s3);
        }
      } else {
        has = s3.v !== UNINITIALIZED;
        var p2 = with_parent(() => proxy(value3));
        set(s3, p2);
      }
      var descriptor = Reflect.getOwnPropertyDescriptor(target, prop);
      if (descriptor?.set) descriptor.set.call(receiver, value3);
      if (!has) {
        if (is_proxied_array && typeof prop === "string") {
          var ls = sources.get("length");
          var n = Number(prop);
          if (Number.isInteger(n) && n >= ls.v) set(ls, n + 1);
        }
        increment(version);
      }
      return true;
    },
    ownKeys(target) {
      get$1(version);
      var own_keys = Reflect.ownKeys(target).filter((key3) => {
        var source3 = sources.get(key3);
        return source3 === void 0 || source3.v !== UNINITIALIZED;
      });
      for (var [key2, source2] of sources) if (source2.v !== UNINITIALIZED && !(key2 in target)) own_keys.push(key2);
      return own_keys;
    },
    setPrototypeOf() {
      state_prototype_fixed();
    }
  });
}
function init_operations() {
  if ($window !== void 0) return;
  $window = window;
  /Firefox/.test(navigator.userAgent);
  var element_prototype = Element.prototype;
  var node_prototype = Node.prototype;
  var text_prototype = Text.prototype;
  first_child_getter = get_descriptor(node_prototype, "firstChild").get;
  next_sibling_getter = get_descriptor(node_prototype, "nextSibling").get;
  if (is_extensible(element_prototype)) {
    element_prototype[CLASS_CACHE] = void 0;
    element_prototype[ATTRIBUTES_CACHE] = null;
    element_prototype[STYLE_CACHE] = void 0;
    element_prototype.__e = void 0;
  }
  if (is_extensible(text_prototype))
    text_prototype[TEXT_CACHE] = void 0;
}
function create_text(value2 = "") {
  return document.createTextNode(value2);
}
// @__NO_SIDE_EFFECTS__
function get_first_child(node) {
  return first_child_getter.call(node);
}
// @__NO_SIDE_EFFECTS__
function get_next_sibling(node) {
  return next_sibling_getter.call(node);
}
function clear_text_content(node) {
  node.textContent = "";
}
function push_effect(effect, parent_effect) {
  var parent_last = parent_effect.last;
  if (parent_last === null) parent_effect.last = parent_effect.first = effect;
  else {
    parent_last.next = effect;
    effect.prev = parent_last;
    parent_effect.last = effect;
  }
}
function create_effect(type, fn) {
  var parent = active_effect;
  if (parent !== null && (parent.f & 8192) !== 0) type |= INERT;
  var effect = {
    ctx: component_context,
    deps: null,
    nodes: null,
    f: type | DIRTY | 512,
    first: null,
    fn,
    last: null,
    next: null,
    parent,
    b: parent && parent.b,
    prev: null,
    teardown: null,
    wv: 0,
    ac: null
  };
  current_batch?.register_created_effect(effect);
  var e = effect;
  if ((type & 4) !== 0) if (collected_effects !== null) collected_effects.push(effect);
  else Batch.ensure().schedule(effect);
  else if (fn !== null) {
    try {
      update_effect(effect);
    } catch (e2) {
      destroy_effect(effect);
      throw e2;
    }
    if (e.deps === null && e.teardown === null && e.nodes === null && e.first === e.last && (e.f & 524288) === 0) {
      e = e.first;
      if ((type & 16) !== 0 && (type & 65536) !== 0 && e !== null) e.f |= EFFECT_TRANSPARENT;
    }
  }
  if (e !== null) {
    e.parent = parent;
    if (parent !== null) push_effect(e, parent);
    if (active_reaction !== null && (active_reaction.f & 2) !== 0 && (type & 64) === 0) {
      var derived2 = active_reaction;
      (derived2.effects ??= []).push(e);
    }
  }
  return effect;
}
function effect_tracking() {
  return active_reaction !== null && !untracking;
}
function create_user_effect(fn) {
  return create_effect(4 | USER_EFFECT, fn);
}
function component_root(fn) {
  Batch.ensure();
  const effect = create_effect(64 | EFFECT_PRESERVED, fn);
  return (options2 = {}) => {
    return new Promise((fulfil) => {
      if (options2.outro) pause_effect(effect, () => {
        destroy_effect(effect);
        fulfil(void 0);
      });
      else {
        destroy_effect(effect);
        fulfil(void 0);
      }
    });
  };
}
function render_effect(fn, flags2 = 0) {
  return create_effect(8 | flags2, fn);
}
function block(fn, flags2 = 0) {
  return create_effect(16 | flags2, fn);
}
function branch(fn) {
  return create_effect(32 | EFFECT_PRESERVED, fn);
}
function execute_effect_teardown(effect) {
  var teardown = effect.teardown;
  if (teardown !== null) {
    const previously_destroying_effect = is_destroying_effect;
    const previous_reaction = active_reaction;
    set_is_destroying_effect(true);
    set_active_reaction(null);
    try {
      teardown.call(null);
    } finally {
      set_is_destroying_effect(previously_destroying_effect);
      set_active_reaction(previous_reaction);
    }
  }
}
function destroy_effect_children(signal, remove_dom = false) {
  var effect = signal.first;
  signal.first = signal.last = null;
  while (effect !== null) {
    const controller2 = effect.ac;
    if (controller2 !== null) without_reactive_context(() => {
      controller2.abort(STALE_REACTION);
    });
    var next2 = effect.next;
    if ((effect.f & 64) !== 0) effect.parent = null;
    else destroy_effect(effect, remove_dom);
    effect = next2;
  }
}
function destroy_block_effect_children(signal) {
  var effect = signal.first;
  while (effect !== null) {
    var next2 = effect.next;
    if ((effect.f & 32) === 0) destroy_effect(effect);
    effect = next2;
  }
}
function destroy_effect(effect, remove_dom = true) {
  var removed = false;
  if ((remove_dom || (effect.f & 262144) !== 0) && effect.nodes !== null && effect.nodes.end !== null) {
    remove_effect_dom(effect.nodes.start, effect.nodes.end);
    removed = true;
  }
  effect.f |= DESTROYING;
  destroy_effect_children(effect, remove_dom && !removed);
  remove_reactions(effect, 0);
  var transitions = effect.nodes && effect.nodes.t;
  if (transitions !== null) for (const transition of transitions) transition.stop();
  execute_effect_teardown(effect);
  effect.f ^= DESTROYING;
  effect.f |= DESTROYED;
  var parent = effect.parent;
  if (parent !== null && parent.first !== null) unlink_effect(effect);
  effect.next = effect.prev = effect.teardown = effect.ctx = effect.deps = effect.fn = effect.nodes = effect.ac = effect.b = null;
}
function remove_effect_dom(node, end) {
  while (node !== null) {
    var next2 = node === end ? null : /* @__PURE__ */ get_next_sibling(node);
    node.remove();
    node = next2;
  }
}
function unlink_effect(effect) {
  var parent = effect.parent;
  var prev = effect.prev;
  var next2 = effect.next;
  if (prev !== null) prev.next = next2;
  if (next2 !== null) next2.prev = prev;
  if (parent !== null) {
    if (parent.first === effect) parent.first = next2;
    if (parent.last === effect) parent.last = prev;
  }
}
function pause_effect(effect, callback, destroy = true) {
  var transitions = [];
  pause_children(effect, transitions, true);
  var fn = () => {
    if (destroy) destroy_effect(effect);
    if (callback) callback();
  };
  var remaining = transitions.length;
  if (remaining > 0) {
    var check = () => --remaining || fn();
    for (var transition of transitions) transition.out(check);
  } else fn();
}
function pause_children(effect, transitions, local) {
  if ((effect.f & 8192) !== 0) return;
  effect.f ^= INERT;
  var t2 = effect.nodes && effect.nodes.t;
  if (t2 !== null) {
    for (const transition of t2) if (transition.is_global || local) transitions.push(transition);
  }
  var child = effect.first;
  while (child !== null) {
    var sibling = child.next;
    if ((child.f & 64) === 0) {
      var transparent = (child.f & 65536) !== 0 || (child.f & 32) !== 0 && (effect.f & 16) !== 0;
      pause_children(child, transitions, transparent ? local : false);
    }
    child = sibling;
  }
}
function move_effect(effect, fragment) {
  if (!effect.nodes) return;
  var node = effect.nodes.start;
  var end = effect.nodes.end;
  while (node !== null) {
    var next2 = node === end ? null : /* @__PURE__ */ get_next_sibling(node);
    fragment.append(node);
    node = next2;
  }
}
function set_is_destroying_effect(value2) {
  is_destroying_effect = value2;
}
function set_active_reaction(reaction) {
  active_reaction = reaction;
}
function set_active_effect(effect) {
  active_effect = effect;
}
function push_reaction_value(value2) {
  if (active_reaction !== null && (!async_mode_flag || (active_reaction.f & 2) !== 0)) (current_sources ??= /* @__PURE__ */ new Set()).add(value2);
}
function set_untracked_writes(value2) {
  untracked_writes = value2;
}
function set_update_version(value2) {
  update_version = value2;
}
function increment_write_version() {
  return ++write_version;
}
function is_dirty(reaction) {
  var flags2 = reaction.f;
  if ((flags2 & 2048) !== 0) return true;
  if (flags2 & 2) reaction.f &= ~WAS_MARKED;
  if ((flags2 & 4096) !== 0) {
    var dependencies = reaction.deps;
    var length = dependencies.length;
    for (var i = 0; i < length; i++) {
      var dependency = dependencies[i];
      if (is_dirty(dependency)) update_derived(dependency);
      if (dependency.wv > reaction.wv) return true;
    }
    if ((flags2 & 512) !== 0 && batch_values === null) set_signal_status(reaction, CLEAN);
  }
  return false;
}
function schedule_possible_effect_self_invalidation(signal, effect, root = true) {
  var reactions = signal.reactions;
  if (reactions === null) return;
  if (!async_mode_flag && current_sources !== null && current_sources.has(signal)) return;
  for (var i = 0; i < reactions.length; i++) {
    var reaction = reactions[i];
    if ((reaction.f & 2) !== 0) schedule_possible_effect_self_invalidation(reaction, effect, false);
    else if (effect === reaction) {
      if (root) set_signal_status(reaction, DIRTY);
      else if ((reaction.f & 1024) !== 0) set_signal_status(reaction, MAYBE_DIRTY);
      schedule_effect(reaction);
    }
  }
}
function update_reaction(reaction) {
  var previous_deps = new_deps;
  var previous_skipped_deps = skipped_deps;
  var previous_untracked_writes = untracked_writes;
  var previous_reaction = active_reaction;
  var previous_sources = current_sources;
  var previous_component_context = component_context;
  var previous_untracking = untracking;
  var previous_update_version = update_version;
  var flags2 = reaction.f;
  new_deps = null;
  skipped_deps = 0;
  untracked_writes = null;
  active_reaction = (flags2 & 96) === 0 ? reaction : null;
  current_sources = null;
  set_component_context(reaction.ctx);
  untracking = false;
  update_version = ++read_version;
  if (reaction.ac !== null) {
    without_reactive_context(() => {
      reaction.ac.abort(STALE_REACTION);
    });
    reaction.ac = null;
  }
  try {
    reaction.f |= REACTION_IS_UPDATING;
    var fn = reaction.fn;
    var result = fn();
    reaction.f |= REACTION_RAN;
    var deps = reaction.deps;
    var is_fork = current_batch?.is_fork;
    if (new_deps !== null) {
      var i;
      if (!is_fork) remove_reactions(reaction, skipped_deps);
      if (deps !== null && skipped_deps > 0) {
        deps.length = skipped_deps + new_deps.length;
        for (i = 0; i < new_deps.length; i++) deps[skipped_deps + i] = new_deps[i];
      } else reaction.deps = deps = new_deps;
      if (effect_tracking() && (reaction.f & 512) !== 0) for (i = skipped_deps; i < deps.length; i++) (deps[i].reactions ??= []).push(reaction);
    } else if (!is_fork && deps !== null && skipped_deps < deps.length) {
      remove_reactions(reaction, skipped_deps);
      deps.length = skipped_deps;
    }
    if (is_runes() && untracked_writes !== null && !untracking && deps !== null && (reaction.f & 6146) === 0) for (i = 0; i < untracked_writes.length; i++) schedule_possible_effect_self_invalidation(untracked_writes[i], reaction);
    if (previous_reaction !== null && previous_reaction !== reaction) {
      read_version++;
      if (previous_reaction.deps !== null) for (let i2 = 0; i2 < previous_skipped_deps; i2 += 1) previous_reaction.deps[i2].rv = read_version;
      if (previous_deps !== null) for (const dep of previous_deps) dep.rv = read_version;
      if (untracked_writes !== null) if (previous_untracked_writes === null) previous_untracked_writes = untracked_writes;
      else previous_untracked_writes.push(...untracked_writes);
    }
    if ((reaction.f & 8388608) !== 0) reaction.f ^= ERROR_VALUE;
    return result;
  } catch (error2) {
    return handle_error(error2);
  } finally {
    reaction.f ^= REACTION_IS_UPDATING;
    new_deps = previous_deps;
    skipped_deps = previous_skipped_deps;
    untracked_writes = previous_untracked_writes;
    active_reaction = previous_reaction;
    current_sources = previous_sources;
    set_component_context(previous_component_context);
    untracking = previous_untracking;
    update_version = previous_update_version;
  }
}
function remove_reaction(signal, dependency) {
  let reactions = dependency.reactions;
  if (reactions !== null) {
    var index88 = index_of.call(reactions, signal);
    if (index88 !== -1) {
      var new_length = reactions.length - 1;
      if (new_length === 0) reactions = dependency.reactions = null;
      else {
        reactions[index88] = reactions[new_length];
        reactions.pop();
      }
    }
  }
  if (reactions === null && (dependency.f & 2) !== 0 && (new_deps === null || !includes.call(new_deps, dependency))) {
    var derived2 = dependency;
    if ((derived2.f & 512) !== 0) {
      derived2.f ^= 512;
      derived2.f &= ~WAS_MARKED;
    }
    if (derived2.v !== UNINITIALIZED) update_derived_status(derived2);
    if (derived2.ac !== null) without_reactive_context(() => {
      derived2.ac.abort(STALE_REACTION);
      derived2.ac = null;
      set_signal_status(derived2, DIRTY);
    });
    freeze_derived_effects(derived2);
    remove_reactions(derived2, 0);
  }
}
function remove_reactions(signal, start_index) {
  var dependencies = signal.deps;
  if (dependencies === null) return;
  for (var i = start_index; i < dependencies.length; i++) remove_reaction(signal, dependencies[i]);
}
function update_effect(effect) {
  var flags2 = effect.f;
  if ((flags2 & 16384) !== 0) return;
  set_signal_status(effect, CLEAN);
  var previous_effect = active_effect;
  var was_updating_effect = is_updating_effect;
  active_effect = effect;
  is_updating_effect = (flags2 & 96) === 0;
  try {
    if ((flags2 & 16777232) !== 0) destroy_block_effect_children(effect);
    else destroy_effect_children(effect);
    execute_effect_teardown(effect);
    var teardown = update_reaction(effect);
    effect.teardown = typeof teardown === "function" ? teardown : null;
    effect.wv = write_version;
  } finally {
    is_updating_effect = was_updating_effect;
    active_effect = previous_effect;
  }
}
function get$1(signal) {
  var is_derived = (signal.f & 2) !== 0;
  captured_signals?.add(signal);
  if (active_reaction !== null && !untracking) {
    if (!(active_effect !== null && (active_effect.f & 16384) !== 0) && (current_sources === null || !current_sources.has(signal))) {
      var deps = active_reaction.deps;
      if ((active_reaction.f & 2097152) !== 0) {
        if (signal.rv < read_version) {
          signal.rv = read_version;
          if (new_deps === null && deps !== null && deps[skipped_deps] === signal) skipped_deps++;
          else if (new_deps === null) new_deps = [signal];
          else new_deps.push(signal);
        }
      } else {
        active_reaction.deps ??= [];
        if (!includes.call(active_reaction.deps, signal)) active_reaction.deps.push(signal);
        var reactions = signal.reactions;
        if (reactions === null) signal.reactions = [active_reaction];
        else if (!includes.call(reactions, active_reaction)) reactions.push(active_reaction);
      }
    }
  }
  if (is_destroying_effect && old_values.has(signal)) return old_values.get(signal);
  if (is_derived) {
    var derived2 = signal;
    if (is_destroying_effect) {
      var value2 = derived2.v;
      if ((derived2.f & 1024) === 0 && derived2.reactions !== null || depends_on_old_values(derived2)) value2 = execute_derived(derived2);
      old_values.set(derived2, value2);
      return value2;
    }
    var should_connect = (derived2.f & 512) === 0 && !untracking && active_reaction !== null && (is_updating_effect || (active_reaction.f & 512) !== 0);
    var is_new = (derived2.f & REACTION_RAN) === 0;
    if (is_dirty(derived2)) {
      if (should_connect) derived2.f |= 512;
      update_derived(derived2);
    }
    if (should_connect && !is_new) {
      unfreeze_derived_effects(derived2);
      reconnect(derived2);
    }
  }
  if (batch_values?.has(signal)) return batch_values.get(signal);
  if ((signal.f & 8388608) !== 0) throw signal.v;
  return signal.v;
}
function reconnect(derived2) {
  derived2.f |= 512;
  if (derived2.deps === null) return;
  for (const dep of derived2.deps) {
    (dep.reactions ??= []).push(derived2);
    if ((dep.f & 2) !== 0 && (dep.f & 512) === 0) {
      unfreeze_derived_effects(dep);
      reconnect(dep);
    }
  }
}
function depends_on_old_values(derived2) {
  if (derived2.v === UNINITIALIZED) return true;
  if (derived2.deps === null) return false;
  for (const dep of derived2.deps) {
    if (old_values.has(dep)) return true;
    if ((dep.f & 2) !== 0 && depends_on_old_values(dep)) return true;
  }
  return false;
}
function untrack(fn) {
  var previous_untracking = untracking;
  try {
    untracking = true;
    return fn();
  } finally {
    untracking = previous_untracking;
  }
}
function subscribe_to_store(store2, run5, invalidate2) {
  if (store2 == null) {
    run5(void 0);
    if (invalidate2) invalidate2(void 0);
    return noop;
  }
  const unsub = untrack(() => store2.subscribe(run5, invalidate2));
  return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
}
function readable(value2, start) {
  return { subscribe: writable(value2, start).subscribe };
}
function writable(value2, start = noop) {
  let stop = null;
  const subscribers2 = /* @__PURE__ */ new Set();
  function set3(new_value) {
    if (safe_not_equal(value2, new_value)) {
      value2 = new_value;
      if (stop) {
        const run_queue = !subscriber_queue.length;
        for (const subscriber of subscribers2) {
          subscriber[1]();
          subscriber_queue.push(subscriber, value2);
        }
        if (run_queue) {
          for (let i = 0; i < subscriber_queue.length; i += 2) subscriber_queue[i][0](subscriber_queue[i + 1]);
          subscriber_queue.length = 0;
        }
      }
    }
  }
  function update4(fn) {
    set3(fn(value2));
  }
  function subscribe2(run5, invalidate2 = noop) {
    const subscriber = [run5, invalidate2];
    subscribers2.add(subscriber);
    if (subscribers2.size === 1) stop = start(set3, update4) || noop;
    run5(value2);
    return () => {
      subscribers2.delete(subscriber);
      if (subscribers2.size === 0 && stop) {
        stop();
        stop = null;
      }
    };
  }
  return {
    set: set3,
    update: update4,
    subscribe: subscribe2
  };
}
function derived$1(stores, fn, initial_value) {
  const single = !Array.isArray(stores);
  const stores_array = single ? [stores] : stores;
  if (!stores_array.every(Boolean)) throw new Error("derived() expects stores as input, got a falsy value");
  const auto = fn.length < 2;
  return readable(initial_value, (set3, update4) => {
    let started = false;
    const values = [];
    let pending = 0;
    let cleanup2 = noop;
    const sync = () => {
      if (pending) return;
      cleanup2();
      const result = fn(single ? values[0] : values, set3, update4);
      if (auto) set3(result);
      else cleanup2 = typeof result === "function" ? result : noop;
    };
    const unsubscribers = stores_array.map((store2, i) => subscribe_to_store(store2, (value2) => {
      values[i] = value2;
      pending &= ~(1 << i);
      if (started) sync();
    }, () => {
      pending |= 1 << i;
    }));
    started = true;
    sync();
    return function stop() {
      run_all(unsubscribers);
      cleanup2();
      started = false;
    };
  });
}
function get(store2) {
  let value2;
  subscribe_to_store(store2, (_3) => value2 = _3)();
  return value2;
}
function is_void(name) {
  return VOID_ELEMENT_NAMES.includes(name) || name.toLowerCase() === "!doctype";
}
function is_boolean_attribute(name) {
  return DOM_BOOLEAN_ATTRIBUTES.includes(name);
}
function is_passive_event(name) {
  return PASSIVE_EVENTS.includes(name);
}
function is_raw_text_element(name) {
  return RAW_TEXT_ELEMENTS.includes(name);
}
function escape_html(value2, is_attr) {
  const str2 = String(value2 ?? "");
  const pattern2 = is_attr ? ATTR_REGEX : CONTENT_REGEX;
  pattern2.lastIndex = 0;
  let escaped2 = "";
  let last = 0;
  while (pattern2.test(str2)) {
    const i = pattern2.lastIndex - 1;
    const ch = str2[i];
    escaped2 += str2.substring(last, i) + (ch === "&" ? "&amp;" : ch === '"' ? "&quot;" : "&lt;");
    last = i + 1;
  }
  return escaped2 + str2.substring(last);
}
function r(e) {
  var t2, f2, n = "";
  if ("string" == typeof e || "number" == typeof e) n += e;
  else if ("object" == typeof e) if (Array.isArray(e)) {
    var o = e.length;
    for (t2 = 0; t2 < o; t2++) e[t2] && (f2 = r(e[t2])) && (n && (n += " "), n += f2);
  } else for (f2 in e) e[f2] && (n && (n += " "), n += f2);
  return n;
}
function clsx$1() {
  for (var e, t2, f2 = 0, n = "", o = arguments.length; f2 < o; f2++) (e = arguments[f2]) && (t2 = r(e)) && (n && (n += " "), n += t2);
  return n;
}
function attr(name, value2, is_boolean = false) {
  if (name === "hidden" && value2 !== "until-found") is_boolean = true;
  if (value2 == null || !value2 && is_boolean) return "";
  const normalized = has_own_property.call(replacements, name) && replacements[name].get(value2) || value2;
  return ` ${name}${is_boolean ? `=""` : `="${escape_html(normalized, true)}"`}`;
}
function clsx(value2) {
  if (typeof value2 === "object") return clsx$1(value2);
  else return value2 ?? "";
}
function to_class(value2, hash4, directives) {
  var classname = value2 == null ? "" : "" + value2;
  if (hash4) classname = classname ? classname + " " + hash4 : hash4;
  if (directives) {
    for (var key2 of Object.keys(directives)) if (directives[key2]) classname = classname ? classname + " " + key2 : key2;
    else if (classname.length) {
      var len = key2.length;
      var a2 = 0;
      while ((a2 = classname.indexOf(key2, a2)) >= 0) {
        var b3 = a2 + len;
        if ((a2 === 0 || whitespace.includes(classname[a2 - 1])) && (b3 === classname.length || whitespace.includes(classname[b3]))) classname = (a2 === 0 ? "" : classname.substring(0, a2)) + classname.substring(b3 + 1);
        else a2 = b3;
      }
    }
  }
  return classname === "" ? null : classname;
}
function append_styles(styles, important = false) {
  var separator = important ? " !important;" : ";";
  var css = "";
  for (var key2 of Object.keys(styles)) {
    var value2 = styles[key2];
    if (value2 != null && value2 !== "") css += " " + key2 + ": " + value2 + separator;
  }
  return css;
}
function to_css_name(name) {
  if (name[0] !== "-" || name[1] !== "-") return name.toLowerCase();
  return name;
}
function to_style(value2, styles) {
  if (styles) {
    var new_style = "";
    var normal_styles;
    var important_styles;
    if (Array.isArray(styles)) {
      normal_styles = styles[0];
      important_styles = styles[1];
    } else normal_styles = styles;
    if (value2) {
      value2 = String(value2).replaceAll(/\s*\/\*.*?\*\/\s*/g, "").trim();
      var in_str = false;
      var in_apo = 0;
      var in_comment = false;
      var reserved_names = [];
      if (normal_styles) reserved_names.push(...Object.keys(normal_styles).map(to_css_name));
      if (important_styles) reserved_names.push(...Object.keys(important_styles).map(to_css_name));
      var start_index = 0;
      var name_index = -1;
      const len = value2.length;
      for (var i = 0; i < len; i++) {
        var c2 = value2[i];
        if (in_comment) {
          if (c2 === "/" && value2[i - 1] === "*") in_comment = false;
        } else if (in_str) {
          if (in_str === c2) in_str = false;
        } else if (c2 === "/" && value2[i + 1] === "*") in_comment = true;
        else if (c2 === '"' || c2 === "'") in_str = c2;
        else if (c2 === "(") in_apo++;
        else if (c2 === ")") in_apo--;
        if (!in_comment && in_str === false && in_apo === 0) {
          if (c2 === ":" && name_index === -1) name_index = i;
          else if (c2 === ";" || i === len - 1) {
            if (name_index !== -1) {
              var name = to_css_name(value2.substring(start_index, name_index).trim());
              if (!reserved_names.includes(name)) {
                if (c2 !== ";") i++;
                var property = value2.substring(start_index, i).trim();
                new_style += " " + property + ";";
              }
            }
            start_index = i + 1;
            name_index = -1;
          }
        }
      }
    }
    if (normal_styles) new_style += append_styles(normal_styles);
    if (important_styles) new_style += append_styles(important_styles, true);
    new_style = new_style.trim();
    return new_style === "" ? null : new_style;
  }
  return value2 == null ? null : String(value2);
}
function abort() {
  controller?.abort(STALE_REACTION);
  controller = null;
}
function getAbortSignal() {
  return (controller ??= new AbortController()).signal;
}
function async_local_storage_unavailable() {
  const error2 = /* @__PURE__ */ new Error(`async_local_storage_unavailable
The node API \`AsyncLocalStorage\` is not available, but is required to use async server rendering.
https://svelte.dev/e/async_local_storage_unavailable`);
  error2.name = "Svelte error";
  throw error2;
}
function await_invalid() {
  const error2 = /* @__PURE__ */ new Error(`await_invalid
Encountered asynchronous work while rendering synchronously.
https://svelte.dev/e/await_invalid`);
  error2.name = "Svelte error";
  throw error2;
}
function dynamic_element_invalid_tag(tag2) {
  const error2 = /* @__PURE__ */ new Error(`dynamic_element_invalid_tag
\`<svelte:element this="${tag2}">\` is not a valid element name \u2014 the element will not be rendered
https://svelte.dev/e/dynamic_element_invalid_tag`);
  error2.name = "Svelte error";
  throw error2;
}
function html_deprecated() {
  const error2 = /* @__PURE__ */ new Error(`html_deprecated
The \`html\` property of server render results has been deprecated. Use \`body\` instead.
https://svelte.dev/e/html_deprecated`);
  error2.name = "Svelte error";
  throw error2;
}
function hydratable_serialization_failed(key2, stack) {
  const error2 = /* @__PURE__ */ new Error(`hydratable_serialization_failed
Failed to serialize \`hydratable\` data for key \`${key2}\`.

\`hydratable\` can serialize anything [\`uneval\` from \`devalue\`](https://npmjs.com/package/uneval) can, plus Promises.

Cause:
${stack}
https://svelte.dev/e/hydratable_serialization_failed`);
  error2.name = "Svelte error";
  throw error2;
}
function invalid_csp() {
  const error2 = /* @__PURE__ */ new Error(`invalid_csp
\`csp.nonce\` was set while \`csp.hash\` was \`true\`. These options cannot be used simultaneously.
https://svelte.dev/e/invalid_csp`);
  error2.name = "Svelte error";
  throw error2;
}
function invalid_id_prefix() {
  const error2 = /* @__PURE__ */ new Error(`invalid_id_prefix
The \`idPrefix\` option cannot include \`--\`.
https://svelte.dev/e/invalid_id_prefix`);
  error2.name = "Svelte error";
  throw error2;
}
function lifecycle_function_unavailable(name) {
  const error2 = /* @__PURE__ */ new Error(`lifecycle_function_unavailable
\`${name}(...)\` is not available on the server
https://svelte.dev/e/lifecycle_function_unavailable`);
  error2.name = "Svelte error";
  throw error2;
}
function server_context_required() {
  const error2 = /* @__PURE__ */ new Error(`server_context_required
Could not resolve \`render\` context.
https://svelte.dev/e/server_context_required`);
  error2.name = "Svelte error";
  throw error2;
}
function set_ssr_context(v3) {
  ssr_context = v3;
}
function createContext() {
  const key2 = {};
  return [() => {
    if (!hasContext(key2)) missing_context();
    return getContext(key2);
  }, (context2) => setContext(key2, context2)];
}
function getContext(key2) {
  return get_or_init_context_map("getContext").get(key2);
}
function setContext(key2, context2) {
  get_or_init_context_map("setContext").set(key2, context2);
  return context2;
}
function hasContext(key2) {
  return get_or_init_context_map("hasContext").has(key2);
}
function getAllContexts() {
  return get_or_init_context_map("getAllContexts");
}
function get_or_init_context_map(name) {
  if (ssr_context === null) lifecycle_outside_component(name);
  return ssr_context.c ??= new Map(get_parent_context(ssr_context) || void 0);
}
function push(fn) {
  ssr_context = {
    p: ssr_context,
    c: null,
    r: null
  };
}
function pop() {
  ssr_context = ssr_context.p;
}
function get_parent_context(ssr_context2) {
  let parent = ssr_context2.p;
  while (parent !== null) {
    const context_map = parent.c;
    if (context_map !== null) return context_map;
    parent = parent.p;
  }
  return null;
}
function unresolved_hydratable(key2, stack) {
  console.warn(`https://svelte.dev/e/unresolved_hydratable`);
}
function get_render_context() {
  const store2 = context ?? als?.getStore();
  if (!store2) server_context_required();
  return store2;
}
async function with_render_context(fn) {
  context = { hydratable: {
    lookup: /* @__PURE__ */ new Map(),
    comparisons: [],
    unresolved_promises: /* @__PURE__ */ new Map()
  } };
  if (in_webcontainer()) {
    const { promise, resolve: resolve6 } = deferred();
    const previous_render = current_render;
    current_render = promise;
    await previous_render;
    return fn().finally(resolve6);
  }
  try {
    if (als === null) async_local_storage_unavailable();
    return als.run(context, fn);
  } finally {
    context = null;
  }
}
function init_render_context() {
  als_import ??= import("node:async_hooks").then((hooks) => {
    als = new hooks.AsyncLocalStorage();
  }).then(noop, noop);
  return als_import;
}
function in_webcontainer() {
  return !!globalThis.process?.versions?.webcontainer;
}
async function sha256(data) {
  text_encoder ??= new TextEncoder();
  crypto2 ??= globalThis.crypto?.subtle?.digest ? globalThis.crypto : (await obfuscated_import("node:crypto")).webcrypto;
  return base64_encode(await crypto2.subtle.digest("SHA-256", text_encoder.encode(data)));
}
function base64_encode(bytes) {
  if (globalThis.Buffer) return globalThis.Buffer.from(bytes).toString("base64");
  let binary2 = "";
  for (let i = 0; i < bytes.length; i++) binary2 += String.fromCharCode(bytes[i]);
  return btoa(binary2);
}
function html(value2) {
  return "<!---->" + String(value2 ?? "") + "<!---->";
}
function element(renderer, tag2, attributes_fn = noop, children_fn = noop) {
  renderer.push("<!---->");
  if (tag2) {
    if (!REGEX_VALID_TAG_NAME.test(tag2)) dynamic_element_invalid_tag(tag2);
    renderer.push(`<${tag2}`);
    attributes_fn();
    renderer.push(`>`);
    if (!is_void(tag2)) {
      children_fn();
      if (!is_raw_text_element(tag2)) renderer.push(EMPTY_COMMENT);
      renderer.push(`</${tag2}>`);
    }
  }
  renderer.push("<!---->");
}
function render(component84, options2 = {}) {
  if (options2.csp?.hash && options2.csp.nonce) invalid_csp();
  return Renderer.render(component84, options2);
}
function head(hash4, renderer, fn) {
  renderer.head((renderer2) => {
    renderer2.push(`<!--${hash4}-->`);
    renderer2.child(fn);
    renderer2.push(EMPTY_COMMENT);
  });
}
function attributes(attrs, css_hash, classes, styles, flags2 = 0) {
  if (styles) attrs.style = to_style(attrs.style, styles);
  if (attrs.class) attrs.class = clsx(attrs.class);
  if (css_hash || classes) attrs.class = to_class(attrs.class, css_hash, classes);
  let attr_str = "";
  let name;
  const is_html = (flags2 & 1) === 0;
  const lowercase = (flags2 & 2) === 0;
  const is_input = (flags2 & 4) !== 0;
  for (name of Object.keys(attrs)) {
    if (typeof attrs[name] === "function") continue;
    if (name[0] === "$" && name[1] === "$") continue;
    if (name === "" || INVALID_ATTR_NAME_CHAR_REGEX.test(name)) continue;
    var value2 = attrs[name];
    var lower = name.toLowerCase();
    if (lowercase) name = lower;
    if (lower.length > 2 && lower.startsWith("on")) continue;
    if (is_input) {
      if (name === "defaultvalue" || name === "defaultchecked") {
        name = name === "defaultvalue" ? "value" : "checked";
        if (attrs[name]) continue;
      }
    }
    attr_str += attr(name, value2, is_html && is_boolean_attribute(name));
  }
  return attr_str;
}
function spread_props(props) {
  const merged_props = {};
  let key2;
  for (let i = 0; i < props.length; i++) {
    const obj = props[i];
    if (obj == null) continue;
    for (key2 of Object.keys(obj)) {
      const desc = Object.getOwnPropertyDescriptor(obj, key2);
      if (desc) Object.defineProperty(merged_props, key2, desc);
      else merged_props[key2] = obj[key2];
    }
  }
  return merged_props;
}
function stringify(value2) {
  return typeof value2 === "string" ? value2 : value2 == null ? "" : value2 + "";
}
function attr_class(value2, hash4, directives) {
  var result = to_class(value2, hash4, directives);
  return result ? ` class="${escape_html(result, true)}"` : "";
}
function attr_style(value2, directives) {
  var result = to_style(value2, directives);
  return result ? ` style="${escape_html(result, true)}"` : "";
}
function store_get(store_values, store_name, store2) {
  if (store_name in store_values && store_values[store_name][0] === store2) return store_values[store_name][2];
  store_values[store_name]?.[1]();
  store_values[store_name] = [
    store2,
    null,
    void 0
  ];
  const unsub = subscribe_to_store(
    store2,
    /** @param {any} v */
    (v3) => store_values[store_name][2] = v3
  );
  store_values[store_name][1] = unsub;
  return store_values[store_name][2];
}
function store_set(store2, value2) {
  store2.set(value2);
  return value2;
}
function unsubscribe_stores(store_values) {
  for (const store_name of Object.keys(store_values)) store_values[store_name][1]();
}
function slot(renderer, $$props, name, slot_props, fallback_fn) {
  var slot_fn = $$props.$$slots?.[name];
  if (slot_fn === true) slot_fn = $$props[name === "default" ? "children" : name];
  if (slot_fn !== void 0) slot_fn(renderer, slot_props);
  else fallback_fn?.();
}
function rest_props(props, rest) {
  const rest_props2 = {};
  let key2;
  for (key2 of Object.keys(props)) if (!rest.includes(key2)) rest_props2[key2] = props[key2];
  return rest_props2;
}
function sanitize_props(props) {
  const { children, $$slots, ...sanitized } = props;
  return sanitized;
}
function sanitize_slots(props) {
  const sanitized = {};
  if (props.children) sanitized.default = true;
  for (const key2 of Object.keys(props.$$slots || {})) sanitized[key2] = true;
  return sanitized;
}
function bind_props(props_parent, props_now) {
  for (const key2 of Object.keys(props_now)) {
    const initial_value = props_parent[key2];
    const value2 = props_now[key2];
    if (initial_value === void 0 && value2 !== void 0 && Object.getOwnPropertyDescriptor(props_parent, key2)?.set) props_parent[key2] = value2;
  }
}
function ensure_array_like(array_like_or_iterator) {
  if (array_like_or_iterator) return array_like_or_iterator.length !== void 0 ? array_like_or_iterator : Array.from(array_like_or_iterator);
  return [];
}
function once(get_value) {
  let value2 = UNINITIALIZED;
  return () => {
    if (value2 === UNINITIALIZED) value2 = get_value();
    return value2;
  };
}
function derived(fn) {
  const get_value = ssr_context === null ? fn : once(fn);
  let updated_value;
  return function(new_value) {
    if (arguments.length === 0) return updated_value ?? get_value();
    updated_value = new_value;
    return updated_value;
  };
}
var is_array, index_of, includes, array_from, define_property, get_descriptor, object_prototype, array_prototype, get_prototype_of, is_extensible, has_own_property, noop, CLEAN, DIRTY, MAYBE_DIRTY, INERT, DESTROYED, REACTION_RAN, DESTROYING, EFFECT_TRANSPARENT, EFFECT_PRESERVED, USER_EFFECT, WAS_MARKED, REACTION_IS_UPDATING, ERROR_VALUE, STATE_SYMBOL, LEGACY_PROPS, ATTRIBUTES_CACHE, CLASS_CACHE, STYLE_CACHE, TEXT_CACHE, STALE_REACTION, HYDRATION_ERROR, UNINITIALIZED, hydrating, hydrate_node, async_mode_flag, legacy_mode_flag, component_context, micro_tasks, STATUS_MASK, legacy_is_updating_store, flags, Boundary, OBSOLETE, first_batch, last_batch, current_batch, previous_batch, batch_values, last_scheduled_effect, is_flushing_sync, is_processing, collected_effects, legacy_updates, flush_count, uid, Batch, eager_block_effects, eager_effects, old_values, eager_effects_deferred, $window, first_child_getter, next_sibling_getter, captured_signals, is_updating_effect, is_destroying_effect, active_reaction, untracking, active_effect, current_sources, new_deps, skipped_deps, untracked_writes, write_version, read_version, update_version, subscriber_queue, VOID_ELEMENT_NAMES, DOM_BOOLEAN_ATTRIBUTES, PASSIVE_EVENTS, RAW_TEXT_ELEMENTS, REGEX_VALID_TAG_NAME, ATTR_REGEX, CONTENT_REGEX, replacements, whitespace, BLOCK_OPEN, BLOCK_CLOSE, EMPTY_COMMENT, controller, ssr_context, current_render, context, als, als_import, text_encoder, crypto2, obfuscated_import, Renderer, SSRState, INVALID_ATTR_NAME_CHAR_REGEX;
var init_server = __esm({
  "dist/build/server/chunks/server.js"() {
    "use strict";
    init_uneval();
    is_array = Array.isArray;
    index_of = Array.prototype.indexOf;
    includes = Array.prototype.includes;
    array_from = Array.from;
    define_property = Object.defineProperty;
    get_descriptor = Object.getOwnPropertyDescriptor;
    object_prototype = Object.prototype;
    array_prototype = Array.prototype;
    get_prototype_of = Object.getPrototypeOf;
    is_extensible = Object.isExtensible;
    has_own_property = Object.prototype.hasOwnProperty;
    noop = () => {
    };
    CLEAN = 1024;
    DIRTY = 2048;
    MAYBE_DIRTY = 4096;
    INERT = 8192;
    DESTROYED = 16384;
    REACTION_RAN = 32768;
    DESTROYING = 1 << 25;
    EFFECT_TRANSPARENT = 65536;
    EFFECT_PRESERVED = 1 << 19;
    USER_EFFECT = 1 << 20;
    WAS_MARKED = 65536;
    REACTION_IS_UPDATING = 1 << 21;
    ERROR_VALUE = 1 << 23;
    STATE_SYMBOL = /* @__PURE__ */ Symbol("$state");
    LEGACY_PROPS = /* @__PURE__ */ Symbol("legacy props");
    ATTRIBUTES_CACHE = /* @__PURE__ */ Symbol("attributes");
    CLASS_CACHE = /* @__PURE__ */ Symbol("class");
    STYLE_CACHE = /* @__PURE__ */ Symbol("style");
    TEXT_CACHE = /* @__PURE__ */ Symbol("text");
    STALE_REACTION = new class StaleReactionError extends Error {
      name = "StaleReactionError";
      message = "The reaction that called `getAbortSignal()` was re-run or destroyed";
    }();
    globalThis.document?.contentType;
    HYDRATION_ERROR = {};
    UNINITIALIZED = /* @__PURE__ */ Symbol("uninitialized");
    hydrating = false;
    async_mode_flag = false;
    legacy_mode_flag = false;
    component_context = null;
    micro_tasks = [];
    STATUS_MASK = ~(DIRTY | MAYBE_DIRTY | CLEAN);
    legacy_is_updating_store = false;
    flags = EFFECT_TRANSPARENT | EFFECT_PRESERVED;
    Boundary = class {
      /** @type {Boundary | null} */
      parent;
      is_pending = false;
      /**
      * API-level transformError transform function. Transforms errors before they reach the `failed` snippet.
      * Inherited from parent boundary, or defaults to identity.
      * @type {(error: unknown) => unknown}
      */
      transform_error;
      /** @type {TemplateNode} */
      #anchor;
      /** @type {TemplateNode | null} */
      #hydrate_open = hydrating ? hydrate_node : null;
      /** @type {BoundaryProps} */
      #props;
      /** @type {((anchor: Node) => void)} */
      #children;
      /** @type {Effect} */
      #effect;
      /** @type {Effect | null} */
      #main_effect = null;
      /** @type {Effect | null} */
      #pending_effect = null;
      /** @type {Effect | null} */
      #failed_effect = null;
      /** @type {DocumentFragment | null} */
      #offscreen_fragment = null;
      #local_pending_count = 0;
      #pending_count = 0;
      #pending_count_update_queued = false;
      /** @type {Set<Effect>} */
      #dirty_effects = /* @__PURE__ */ new Set();
      /** @type {Set<Effect>} */
      #maybe_dirty_effects = /* @__PURE__ */ new Set();
      /**
      * A source containing the number of pending async deriveds/expressions.
      * Only created if `$effect.pending()` is used inside the boundary,
      * otherwise updating the source results in needless `Batch.ensure()`
      * calls followed by no-op flushes
      * @type {Source<number> | null}
      */
      #effect_pending = null;
      #effect_pending_subscriber = createSubscriber(() => {
        this.#effect_pending = source(this.#local_pending_count);
        return () => {
          this.#effect_pending = null;
        };
      });
      /**
      * @param {TemplateNode} node
      * @param {BoundaryProps} props
      * @param {((anchor: Node) => void)} children
      * @param {((error: unknown) => unknown) | undefined} [transform_error]
      */
      constructor(node, props, children, transform_error) {
        this.#anchor = node;
        this.#props = props;
        this.#children = (anchor) => {
          var effect = active_effect;
          effect.b = this;
          effect.f |= 128;
          children(anchor);
        };
        this.parent = active_effect.b;
        this.transform_error = transform_error ?? this.parent?.transform_error ?? ((e) => e);
        this.#effect = block(() => {
          if (hydrating) {
            const comment = this.#hydrate_open;
            hydrate_next();
            const server_rendered_pending = comment.data === "[!";
            if (comment.data.startsWith("[?")) {
              const serialized_error = JSON.parse(comment.data.slice(2));
              this.#hydrate_failed_content(serialized_error);
            } else if (server_rendered_pending) this.#hydrate_pending_content();
            else this.#hydrate_resolved_content();
          } else this.#render();
        }, flags);
        if (hydrating) this.#anchor = hydrate_node;
      }
      #hydrate_resolved_content() {
        try {
          this.#main_effect = branch(() => this.#children(this.#anchor));
        } catch (error2) {
          this.error(error2);
        }
      }
      /**
      * @param {unknown} error The deserialized error from the server's hydration comment
      */
      #hydrate_failed_content(error2) {
        const failed = this.#props.failed;
        const { reset: reset2, invoke_onerror } = this.#create_reset(error2);
        queue_micro_task(invoke_onerror);
        if (!failed) return;
        this.#failed_effect = branch(() => {
          failed(this.#anchor, () => error2, () => reset2);
        });
      }
      /**
      * Creates the `reset` function for a failed boundary, along with a function
      * that invokes `onerror` with it (if provided)
      * @param {unknown} error
      * @returns {{ reset: () => void, invoke_onerror: () => void }}
      */
      #create_reset(error2) {
        var did_reset = false;
        var calling_on_error = false;
        const reset2 = () => {
          if (did_reset) {
            svelte_boundary_reset_noop();
            return;
          }
          did_reset = true;
          if (calling_on_error) svelte_boundary_reset_onerror();
          if (this.#failed_effect !== null) pause_effect(this.#failed_effect, () => {
            this.#failed_effect = null;
          });
          this.#run(() => {
            this.#render();
          });
        };
        const invoke_onerror = () => {
          try {
            calling_on_error = true;
            this.#props.onerror?.(error2, reset2);
            calling_on_error = false;
          } catch (err) {
            invoke_error_boundary(err, this.#effect && this.#effect.parent);
          }
        };
        return {
          reset: reset2,
          invoke_onerror
        };
      }
      #hydrate_pending_content() {
        const pending = this.#props.pending;
        if (!pending) return;
        this.is_pending = true;
        this.#pending_effect = branch(() => pending(this.#anchor));
        queue_micro_task(() => {
          var fragment = this.#offscreen_fragment = document.createDocumentFragment();
          var anchor = create_text();
          fragment.append(anchor);
          this.#main_effect = this.#run(() => {
            return branch(() => this.#children(anchor));
          });
          if (this.#pending_count === 0) {
            this.#anchor.before(fragment);
            this.#offscreen_fragment = null;
            pause_effect(this.#pending_effect, () => {
              this.#pending_effect = null;
            });
            this.#resolve(current_batch);
          }
        });
      }
      #render() {
        try {
          this.is_pending = this.has_pending_snippet();
          this.#pending_count = 0;
          this.#local_pending_count = 0;
          this.#main_effect = branch(() => {
            this.#children(this.#anchor);
          });
          if (this.#pending_count > 0) {
            var fragment = this.#offscreen_fragment = document.createDocumentFragment();
            move_effect(this.#main_effect, fragment);
            const pending = this.#props.pending;
            this.#pending_effect = branch(() => pending(this.#anchor));
          } else this.#resolve(current_batch);
        } catch (error2) {
          this.error(error2);
        }
      }
      /**
      * @param {Batch} batch
      */
      #resolve(batch) {
        this.is_pending = false;
        batch.transfer_effects(this.#dirty_effects, this.#maybe_dirty_effects);
      }
      /**
      * Defer an effect inside a pending boundary until the boundary resolves
      * @param {Effect} effect
      */
      defer_effect(effect) {
        defer_effect(effect, this.#dirty_effects, this.#maybe_dirty_effects);
      }
      /**
      * Returns `false` if the effect exists inside a boundary whose pending snippet is shown
      * @returns {boolean}
      */
      is_rendered() {
        return !this.is_pending && (!this.parent || this.parent.is_rendered());
      }
      has_pending_snippet() {
        return !!this.#props.pending;
      }
      /**
      * @template T
      * @param {() => T} fn
      */
      #run(fn) {
        var previous_effect = active_effect;
        var previous_reaction = active_reaction;
        var previous_ctx = component_context;
        set_active_effect(this.#effect);
        set_active_reaction(this.#effect);
        set_component_context(this.#effect.ctx);
        try {
          Batch.ensure();
          return fn();
        } catch (e) {
          handle_error(e);
          return null;
        } finally {
          set_active_effect(previous_effect);
          set_active_reaction(previous_reaction);
          set_component_context(previous_ctx);
        }
      }
      /**
      * Updates the pending count associated with the currently visible pending snippet,
      * if any, such that we can replace the snippet with content once work is done
      * @param {1 | -1} d
      * @param {Batch} batch
      */
      #update_pending_count(d2, batch) {
        if (!this.has_pending_snippet()) {
          if (this.parent) this.parent.#update_pending_count(d2, batch);
          return;
        }
        this.#pending_count += d2;
        if (this.#pending_count === 0) {
          this.#resolve(batch);
          if (this.#pending_effect) pause_effect(this.#pending_effect, () => {
            this.#pending_effect = null;
          });
          if (this.#offscreen_fragment) {
            this.#anchor.before(this.#offscreen_fragment);
            this.#offscreen_fragment = null;
          }
        }
      }
      /**
      * Update the source that powers `$effect.pending()` inside this boundary,
      * and controls when the current `pending` snippet (if any) is removed.
      * Do not call from inside the class
      * @param {1 | -1} d
      * @param {Batch} batch
      */
      update_pending_count(d2, batch) {
        this.#update_pending_count(d2, batch);
        this.#local_pending_count += d2;
        if (!this.#effect_pending || this.#pending_count_update_queued) return;
        this.#pending_count_update_queued = true;
        queue_micro_task(() => {
          this.#pending_count_update_queued = false;
          if (this.#effect_pending) internal_set(this.#effect_pending, this.#local_pending_count);
        });
      }
      get_effect_pending() {
        this.#effect_pending_subscriber();
        return get$1(this.#effect_pending);
      }
      /** @param {unknown} error */
      error(error2) {
        if (!this.#props.onerror && !this.#props.failed) throw error2;
        if (current_batch?.is_fork) {
          if (this.#main_effect) current_batch.skip_effect(this.#main_effect);
          if (this.#pending_effect) current_batch.skip_effect(this.#pending_effect);
          if (this.#failed_effect) current_batch.skip_effect(this.#failed_effect);
          current_batch.oncommit(() => {
            this.#handle_error(error2);
          });
        } else this.#handle_error(error2);
      }
      /**
      * @param {unknown} error
      */
      #handle_error(error2) {
        if (this.#main_effect) {
          destroy_effect(this.#main_effect);
          this.#main_effect = null;
        }
        if (this.#pending_effect) {
          destroy_effect(this.#pending_effect);
          this.#pending_effect = null;
        }
        if (this.#failed_effect) {
          destroy_effect(this.#failed_effect);
          this.#failed_effect = null;
        }
        if (hydrating) {
          set_hydrate_node(this.#hydrate_open);
          next();
          set_hydrate_node(skip_nodes());
        }
        let failed = this.#props.failed;
        const handle_error_result = (transformed_error) => {
          const { reset: reset2, invoke_onerror } = this.#create_reset(transformed_error);
          invoke_onerror();
          if (failed) this.#failed_effect = this.#run(() => {
            try {
              return branch(() => {
                var effect = active_effect;
                effect.b = this;
                effect.f |= 128;
                failed(this.#anchor, () => transformed_error, () => reset2);
              });
            } catch (error3) {
              invoke_error_boundary(error3, this.#effect.parent);
              return null;
            }
          });
        };
        queue_micro_task(() => {
          var result;
          try {
            result = this.transform_error(error2);
          } catch (e) {
            invoke_error_boundary(e, this.#effect && this.#effect.parent);
            return;
          }
          if (result !== null && typeof result === "object" && typeof result.then === "function")
            result.then(
              handle_error_result,
              /** @param {unknown} e */
              (e) => invoke_error_boundary(e, this.#effect && this.#effect.parent)
            );
          else handle_error_result(result);
        });
      }
    };
    OBSOLETE = /* @__PURE__ */ Symbol("obsolete");
    first_batch = null;
    last_batch = null;
    current_batch = null;
    previous_batch = null;
    batch_values = null;
    last_scheduled_effect = null;
    is_flushing_sync = false;
    is_processing = false;
    collected_effects = null;
    legacy_updates = null;
    flush_count = 0;
    uid = 1;
    Batch = class Batch2 {
      id = uid++;
      /** True as soon as `#process` was called */
      #started = false;
      linked = true;
      /** @type {Batch | null} */
      #prev = null;
      /** @type {Batch | null} */
      #next = null;
      /** @type {Map<Effect, ReturnType<typeof deferred<any>>>} */
      async_deriveds = /* @__PURE__ */ new Map();
      /**
      * The current values of any signals that are updated in this batch.
      * Tuple format: [value, is_derived] (note: is_derived is false for deriveds, too, if they were overridden via assignment)
      * They keys of this map are identical to `this.#previous`
      * @type {Map<Value, [any, boolean]>}
      */
      current = /* @__PURE__ */ new Map();
      /**
      * The values of any signals (sources and deriveds) that are updated in this batch _before_ those updates took place.
      * They keys of this map are identical to `this.#current`
      * @type {Map<Value, any>}
      */
      previous = /* @__PURE__ */ new Map();
      /**
      * When the batch is committed (and the DOM is updated), we need to remove old branches
      * and append new ones by calling the functions added inside (if/each/key/etc) blocks
      * @type {Set<(batch: Batch) => void>}
      */
      #commit_callbacks = /* @__PURE__ */ new Set();
      /**
      * If a fork is discarded, we need to destroy any effects that are no longer needed
      * @type {Set<(batch: Batch) => void>}
      */
      #discard_callbacks = /* @__PURE__ */ new Set();
      /**
      * The number of async effects that are currently in flight
      */
      #pending = 0;
      /**
      * Async effects that are currently in flight, _not_ inside a pending boundary
      * @type {Map<Effect, number>}
      */
      #blocking_pending = /* @__PURE__ */ new Map();
      /**
      * A deferred that resolves when the batch is committed, used with `settled()`
      * TODO replace with Promise.withResolvers once supported widely enough
      * @type {{ promise: Promise<void>, resolve: (value?: any) => void, reject: (reason: unknown) => void } | null}
      */
      #deferred = null;
      /**
      * The root effects that need to be flushed
      * @type {Effect[]}
      */
      #roots = [];
      /**
      * Effects created while this batch was active.
      * @type {Effect[]}
      */
      #new_effects = [];
      /**
      * Deferred effects (which run after async work has completed) that are DIRTY
      * @type {Set<Effect>}
      */
      #dirty_effects = /* @__PURE__ */ new Set();
      /**
      * Deferred effects that are MAYBE_DIRTY
      * @type {Set<Effect>}
      */
      #maybe_dirty_effects = /* @__PURE__ */ new Set();
      /**
      * A map of branches that still exist, but will be destroyed when this batch
      * is committed — we skip over these during `process`.
      * The value contains child effects that were dirty/maybe_dirty before being reset,
      * so they can be rescheduled if the branch survives.
      * @type {Map<Effect, { d: Effect[], m: Effect[] }>}
      */
      #skipped_branches = /* @__PURE__ */ new Map();
      /**
      * Inverse of #skipped_branches which we need to tell prior batches to unskip them when committing
      * @type {Set<Effect>}
      */
      #unskipped_branches = /* @__PURE__ */ new Set();
      is_fork = false;
      #decrement_queued = false;
      constructor() {
        if (last_batch === null) first_batch = last_batch = this;
        else {
          last_batch.#next = this;
          this.#prev = last_batch;
        }
        last_batch = this;
      }
      #is_deferred() {
        if (this.is_fork) return true;
        for (const effect of this.#blocking_pending.keys()) {
          var e = effect;
          var skipped = false;
          while (e.parent !== null) {
            if (this.#skipped_branches.has(e)) {
              skipped = true;
              break;
            }
            e = e.parent;
          }
          if (!skipped) return true;
        }
        return false;
      }
      /**
      * Add an effect to the #skipped_branches map and reset its children
      * @param {Effect} effect
      */
      skip_effect(effect) {
        if (!this.#skipped_branches.has(effect)) this.#skipped_branches.set(effect, {
          d: [],
          m: []
        });
        this.#unskipped_branches.delete(effect);
      }
      /**
      * Remove an effect from the #skipped_branches map and reschedule
      * any tracked dirty/maybe_dirty child effects
      * @param {Effect} effect
      * @param {(e: Effect) => void} callback
      */
      unskip_effect(effect, callback = (e) => this.schedule(e)) {
        var tracked = this.#skipped_branches.get(effect);
        if (tracked) {
          this.#skipped_branches.delete(effect);
          for (var e of tracked.d) {
            set_signal_status(e, DIRTY);
            callback(e);
          }
          for (e of tracked.m) {
            set_signal_status(e, MAYBE_DIRTY);
            callback(e);
          }
        }
        this.#unskipped_branches.add(effect);
      }
      #process() {
        this.#started = true;
        if (flush_count++ > 1e3) {
          this.#unlink();
          infinite_loop_guard();
        }
        for (const e of this.#dirty_effects) {
          this.#maybe_dirty_effects.delete(e);
          set_signal_status(e, DIRTY);
          this.schedule(e);
        }
        for (const e of this.#maybe_dirty_effects) {
          set_signal_status(e, MAYBE_DIRTY);
          this.schedule(e);
        }
        const roots = this.#roots;
        this.#roots = [];
        this.apply();
        var effects = collected_effects = [];
        var render_effects = [];
        var updates = legacy_updates = [];
        for (const root of roots) try {
          this.#traverse(root, effects, render_effects);
        } catch (e) {
          reset_all(root);
          if (!this.#is_deferred()) this.discard();
          throw e;
        }
        current_batch = null;
        if (updates.length > 0) {
          var batch = Batch2.ensure();
          for (const e of updates) batch.schedule(e);
        }
        collected_effects = null;
        legacy_updates = null;
        if (this.#is_deferred()) {
          this.#defer_effects(render_effects);
          this.#defer_effects(effects);
          for (const [e, t2] of this.#skipped_branches) reset_branch(e, t2);
          if (updates.length > 0)
            current_batch.#process();
          return;
        }
        const earlier_batch = this.#find_earlier_batch();
        if (earlier_batch) {
          this.#defer_effects(render_effects);
          this.#defer_effects(effects);
          earlier_batch.#merge(this);
          return;
        }
        this.#dirty_effects.clear();
        this.#maybe_dirty_effects.clear();
        for (const fn of this.#commit_callbacks) fn(this);
        this.#commit_callbacks.clear();
        previous_batch = this;
        flush_queued_effects(render_effects);
        flush_queued_effects(effects);
        previous_batch = null;
        this.#deferred?.resolve();
        var next_batch = current_batch;
        if (this.#pending === 0 && (this.#roots.length === 0 || next_batch !== null)) {
          this.#unlink();
          if (async_mode_flag) {
            this.#commit();
            current_batch = next_batch;
          }
        }
        if (this.#roots.length > 0) if (next_batch !== null) {
          const batch2 = next_batch;
          batch2.#roots.push(...this.#roots.filter((r2) => !batch2.#roots.includes(r2)));
        } else next_batch = this;
        if (next_batch !== null) next_batch.#process();
      }
      /**
      * Traverse the effect tree, executing effects or stashing
      * them for later execution as appropriate
      * @param {Effect} root
      * @param {Effect[]} effects
      * @param {Effect[]} render_effects
      */
      #traverse(root, effects, render_effects) {
        root.f ^= CLEAN;
        var effect = root.first;
        while (effect !== null) {
          var flags2 = effect.f;
          var is_branch = (flags2 & 96) !== 0;
          if (!(is_branch && (flags2 & 1024) !== 0 || (flags2 & 8192) !== 0 || this.#skipped_branches.has(effect)) && effect.fn !== null) {
            if (is_branch) effect.f ^= CLEAN;
            else if ((flags2 & 4) !== 0) effects.push(effect);
            else if (async_mode_flag && (flags2 & 16777224) !== 0) render_effects.push(effect);
            else if (is_dirty(effect)) {
              if ((flags2 & 16) !== 0) this.#maybe_dirty_effects.add(effect);
              update_effect(effect);
            }
            var child = effect.first;
            if (child !== null) {
              effect = child;
              continue;
            }
          }
          while (effect !== null) {
            var next2 = effect.next;
            if (next2 !== null) {
              effect = next2;
              break;
            }
            effect = effect.parent;
          }
        }
      }
      #find_earlier_batch() {
        var batch = this.#prev;
        while (batch !== null) {
          if (!batch.is_fork) {
            for (const [value2, [, is_derived]] of this.current) if (batch.current.has(value2) && !is_derived) return batch;
          }
          batch = batch.#prev;
        }
        return null;
      }
      /**
      * @param {Batch} batch
      */
      #merge(batch) {
        for (const [source2, value2] of batch.current) {
          if (!this.previous.has(source2) && batch.previous.has(source2)) this.previous.set(source2, batch.previous.get(source2));
          this.current.set(source2, value2);
        }
        for (const [effect, deferred2] of batch.async_deriveds) {
          const d2 = this.async_deriveds.get(effect);
          if (d2) deferred2.promise.then(d2.resolve).catch(d2.reject);
        }
        batch.async_deriveds.clear();
        this.transfer_effects(batch.#dirty_effects, batch.#maybe_dirty_effects);
        const mark = (value2) => {
          var reactions = value2.reactions;
          if (reactions === null) return;
          if ((value2.f & 2) !== 0 && (value2.f & 6144) === 0) return;
          for (const reaction of reactions) {
            var flags2 = reaction.f;
            if ((flags2 & 2) !== 0) mark(reaction);
            else {
              var effect = reaction;
              if (flags2 & 4194320 && !this.async_deriveds.has(effect)) {
                this.#maybe_dirty_effects.delete(effect);
                set_signal_status(effect, DIRTY);
                this.schedule(effect);
              }
            }
          }
        };
        for (const source2 of this.current.keys()) mark(source2);
        this.oncommit(() => batch.discard());
        batch.#unlink();
        current_batch = this;
        this.#process();
      }
      /**
      * @param {Effect[]} effects
      */
      #defer_effects(effects) {
        for (var i = 0; i < effects.length; i += 1) defer_effect(effects[i], this.#dirty_effects, this.#maybe_dirty_effects);
      }
      /**
      * Associate a change to a given source with the current
      * batch, noting its previous and current values
      * @param {Value} source
      * @param {any} value
      * @param {boolean} [is_derived]
      */
      capture(source2, value2, is_derived = false) {
        if (source2.v !== UNINITIALIZED && !this.previous.has(source2)) this.previous.set(source2, source2.v);
        if ((source2.f & 8388608) === 0) {
          this.current.set(source2, [value2, is_derived]);
          batch_values?.set(source2, value2);
        }
        if (!this.is_fork) source2.v = value2;
      }
      activate() {
        current_batch = this;
      }
      deactivate() {
        current_batch = null;
        batch_values = null;
      }
      flush() {
        try {
          is_processing = true;
          current_batch = this;
          this.#process();
        } finally {
          flush_count = 0;
          last_scheduled_effect = null;
          collected_effects = null;
          legacy_updates = null;
          is_processing = false;
          current_batch = null;
          batch_values = null;
          old_values.clear();
        }
      }
      discard() {
        for (const fn of this.#discard_callbacks) fn(this);
        this.#discard_callbacks.clear();
        for (const deferred2 of this.async_deriveds.values()) deferred2.reject(OBSOLETE);
        this.#unlink();
        this.#deferred?.resolve();
      }
      /**
      * @param {Effect} effect
      */
      register_created_effect(effect) {
        this.#new_effects.push(effect);
      }
      #commit() {
        for (let batch = first_batch; batch !== null; batch = batch.#next) {
          var is_earlier = batch.id < this.id;
          var sources = [];
          for (const [source3, [value2, is_derived]] of this.current) {
            if (batch.current.has(source3)) {
              var batch_value = batch.current.get(source3)[0];
              if (is_earlier && value2 !== batch_value) batch.current.set(source3, [value2, is_derived]);
              else continue;
            }
            sources.push(source3);
          }
          if (is_earlier) for (const [effect, deferred2] of this.async_deriveds) {
            const d2 = batch.async_deriveds.get(effect);
            if (d2) deferred2.promise.then(d2.resolve).catch(d2.reject);
          }
          var current3 = [...batch.current.keys()].filter((source3) => !batch.current.get(source3)[1]);
          if (!batch.#started || current3.length === 0) continue;
          var others = current3.filter((source3) => !this.current.has(source3));
          if (others.length === 0) {
            if (is_earlier) batch.discard();
          } else if (sources.length > 0) {
            if (is_earlier) for (const unskipped of this.#unskipped_branches) batch.unskip_effect(unskipped, (e) => {
              if ((e.f & 4194320) !== 0) batch.schedule(e);
              else batch.#defer_effects([e]);
            });
            batch.activate();
            var marked = /* @__PURE__ */ new Set();
            var checked = /* @__PURE__ */ new Map();
            for (var source2 of sources) mark_effects(source2, others, marked, checked);
            checked = /* @__PURE__ */ new Map();
            var current_unequal = [...batch.current].filter(([c2, v1]) => {
              const v22 = this.current.get(c2);
              if (!v22) return true;
              return v22[0] !== v1[0] || v22[1] !== v1[1];
            }).map(([c2]) => c2);
            if (current_unequal.length > 0) {
              for (const effect of this.#new_effects) if ((effect.f & 155648) === 0 && depends_on(effect, current_unequal, checked)) if ((effect.f & 4194320) !== 0) {
                set_signal_status(effect, DIRTY);
                batch.schedule(effect);
              } else batch.#dirty_effects.add(effect);
            }
            if (batch.#roots.length > 0 && !batch.#decrement_queued) {
              batch.apply();
              for (var root of batch.#roots) batch.#traverse(root, [], []);
              batch.#roots = [];
            }
            batch.deactivate();
          }
        }
      }
      /**
      * @param {boolean} blocking
      * @param {Effect} effect
      */
      increment(blocking, effect) {
        this.#pending += 1;
        if (blocking) {
          let blocking_pending_count = this.#blocking_pending.get(effect) ?? 0;
          this.#blocking_pending.set(effect, blocking_pending_count + 1);
        }
      }
      /**
      * @param {boolean} blocking
      * @param {Effect} effect
      */
      decrement(blocking, effect) {
        this.#pending -= 1;
        if (blocking) {
          let blocking_pending_count = this.#blocking_pending.get(effect) ?? 0;
          if (blocking_pending_count === 1) this.#blocking_pending.delete(effect);
          else this.#blocking_pending.set(effect, blocking_pending_count - 1);
        }
        if (this.#decrement_queued) return;
        this.#decrement_queued = true;
        queue_micro_task(() => {
          this.#decrement_queued = false;
          if (this.linked) this.flush();
        });
      }
      /**
      * @param {Set<Effect>} dirty_effects
      * @param {Set<Effect>} maybe_dirty_effects
      */
      transfer_effects(dirty_effects, maybe_dirty_effects) {
        for (const e of dirty_effects) this.#dirty_effects.add(e);
        for (const e of maybe_dirty_effects) this.#maybe_dirty_effects.add(e);
        dirty_effects.clear();
        maybe_dirty_effects.clear();
      }
      /** @param {(batch: Batch) => void} fn */
      oncommit(fn) {
        this.#commit_callbacks.add(fn);
      }
      /** @param {(batch: Batch) => void} fn */
      ondiscard(fn) {
        this.#discard_callbacks.add(fn);
      }
      settled() {
        return (this.#deferred ??= deferred()).promise;
      }
      static ensure() {
        if (current_batch === null) {
          const batch = current_batch = new Batch2();
          if (!is_processing && !is_flushing_sync) queue_micro_task(() => {
            if (!batch.#started) batch.flush();
          });
        }
        return current_batch;
      }
      apply() {
        if (!async_mode_flag || !this.is_fork && this.#prev === null && this.#next === null) {
          batch_values = null;
          return;
        }
        batch_values = /* @__PURE__ */ new Map();
        for (const [source2, [value2]] of this.current) batch_values.set(source2, value2);
        for (let batch = first_batch; batch !== null; batch = batch.#next) {
          if (batch === this || batch.is_fork) continue;
          var intersects = false;
          if (batch.id < this.id) for (const [source2, [, is_derived]] of batch.current) {
            if (is_derived) continue;
            if (this.current.has(source2)) {
              intersects = true;
              break;
            }
          }
          if (!intersects) {
            for (const [source2, previous] of batch.previous) if (!batch_values.has(source2)) batch_values.set(source2, previous);
          }
        }
      }
      /**
      *
      * @param {Effect} effect
      */
      schedule(effect) {
        last_scheduled_effect = effect;
        if (effect.b?.is_pending && (effect.f & 16777228) !== 0 && (effect.f & 32768) === 0) {
          effect.b.defer_effect(effect);
          return;
        }
        var e = effect;
        while (e.parent !== null) {
          e = e.parent;
          var flags2 = e.f;
          if (collected_effects !== null && e === active_effect) {
            if (async_mode_flag) return;
            if ((active_reaction === null || (active_reaction.f & 2) === 0) && !legacy_is_updating_store) return;
          }
          if ((flags2 & 96) !== 0) {
            if ((flags2 & 1024) === 0) return;
            e.f ^= CLEAN;
          }
        }
        this.#roots.push(e);
      }
      #unlink() {
        if (!this.linked) return;
        var prev = this.#prev;
        var next2 = this.#next;
        if (prev === null) first_batch = next2;
        else prev.#next = next2;
        if (next2 === null) last_batch = prev;
        else next2.#prev = prev;
        this.linked = false;
      }
    };
    eager_block_effects = null;
    eager_effects = /* @__PURE__ */ new Set();
    old_values = /* @__PURE__ */ new Map();
    eager_effects_deferred = false;
    captured_signals = null;
    is_updating_effect = false;
    is_destroying_effect = false;
    active_reaction = null;
    untracking = false;
    active_effect = null;
    current_sources = null;
    new_deps = null;
    skipped_deps = 0;
    untracked_writes = null;
    write_version = 1;
    read_version = 0;
    update_version = read_version;
    subscriber_queue = [];
    VOID_ELEMENT_NAMES = [
      "area",
      "base",
      "br",
      "col",
      "command",
      "embed",
      "hr",
      "img",
      "input",
      "keygen",
      "link",
      "meta",
      "param",
      "source",
      "track",
      "wbr"
    ];
    DOM_BOOLEAN_ATTRIBUTES = [
      "allowfullscreen",
      "async",
      "autofocus",
      "autoplay",
      "checked",
      "controls",
      "default",
      "disabled",
      "formnovalidate",
      "indeterminate",
      "inert",
      "ismap",
      "loop",
      "multiple",
      "muted",
      "nomodule",
      "novalidate",
      "open",
      "playsinline",
      "readonly",
      "required",
      "reversed",
      "seamless",
      "selected",
      "webkitdirectory",
      "defer",
      "disablepictureinpicture",
      "disableremoteplayback"
    ];
    [...DOM_BOOLEAN_ATTRIBUTES];
    PASSIVE_EVENTS = ["touchstart", "touchmove"];
    RAW_TEXT_ELEMENTS = [
      "textarea",
      "script",
      "style",
      "title"
    ];
    REGEX_VALID_TAG_NAME = /^[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9.\-_\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u037D\u037F-\u1FFF\u200C-\u200D\u203F-\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u{10000}-\u{EFFFF}]*)?$/u;
    ATTR_REGEX = /[&"<]/g;
    CONTENT_REGEX = /[&<]/g;
    replacements = { translate: /* @__PURE__ */ new Map([[true, "yes"], [false, "no"]]) };
    whitespace = [..." 	\n\r\f\xA0\v\uFEFF"];
    BLOCK_OPEN = `<!--[-->`;
    BLOCK_CLOSE = `<!--]-->`;
    EMPTY_COMMENT = `<!---->`;
    controller = null;
    ssr_context = null;
    current_render = null;
    context = null;
    als = null;
    als_import = null;
    obfuscated_import = (module_name) => import(
      /* @vite-ignore */
      module_name
    );
    Renderer = class Renderer2 {
      /**
      * The contents of the renderer.
      * @type {RendererItem[]}
      */
      #out = [];
      /**
      * Any `onDestroy` callbacks registered during execution of this renderer.
      * @type {(() => void)[] | undefined}
      */
      #on_destroy = void 0;
      /**
      * Whether this renderer is a component body.
      * @type {boolean}
      */
      #is_component_body = false;
      /**
      * If set, this renderer is an error boundary. When async collection
      * of the children fails, the failed snippet is rendered instead.
      * @type {{
      * 	failed: (renderer: Renderer, error: unknown, reset: () => void) => void;
      * 	transformError: (error: unknown) => unknown;
      * 	context: SSRContext | null;
      * } | null}
      */
      #boundary = null;
      /**
      * The type of string content that this renderer is accumulating.
      * @type {RendererType}
      */
      type;
      /** @type {Renderer | undefined} */
      #parent;
      /**
      * Asynchronous work associated with this renderer
      * @type {Promise<void> | undefined}
      */
      promise = void 0;
      /**
      * State which is associated with the content tree as a whole.
      * It will be re-exposed, uncopied, on all children.
      * @type {SSRState}
      * @readonly
      */
      global;
      /**
      * State that is local to the branch it is declared in.
      * It will be shallow-copied to all children.
      *
      * @type {{ select_value: string | undefined }}
      */
      local;
      /**
      * @param {SSRState} global
      * @param {Renderer | undefined} [parent]
      */
      constructor(global, parent) {
        this.#parent = parent;
        this.global = global;
        this.local = parent ? { ...parent.local } : { select_value: void 0 };
        this.type = parent ? parent.type : "body";
      }
      /**
      * @param {(renderer: Renderer) => void} fn
      */
      head(fn) {
        const head2 = new Renderer2(this.global, this);
        head2.type = "head";
        this.#out.push(head2);
        head2.child(fn);
      }
      /**
      * @param {Array<Promise<void>>} blockers
      * @param {(renderer: Renderer) => void} fn
      */
      async_block(blockers, fn) {
        this.#out.push(BLOCK_OPEN);
        this.async(blockers, fn);
        this.#out.push(BLOCK_CLOSE);
      }
      /**
      * @param {Array<Promise<void>>} blockers
      * @param {(renderer: Renderer) => void} fn
      */
      async(blockers, fn) {
        let callback = fn;
        if (blockers.length > 0) {
          const context2 = ssr_context;
          callback = (renderer) => {
            return Promise.all(blockers).then(() => {
              const previous_context = ssr_context;
              try {
                set_ssr_context(context2);
                return fn(renderer);
              } finally {
                set_ssr_context(previous_context);
              }
            });
          };
        }
        this.child(callback);
      }
      /**
      * @param {Array<() => void>} thunks
      */
      run(thunks) {
        const context2 = ssr_context;
        let promise = Promise.resolve(thunks[0]());
        const promises = [promise];
        for (const fn of thunks.slice(1)) {
          promise = promise.then(() => {
            const previous_context = ssr_context;
            set_ssr_context(context2);
            try {
              return fn();
            } finally {
              set_ssr_context(previous_context);
            }
          });
          promises.push(promise);
        }
        promise.catch(noop);
        this.promise = promise;
        return promises;
      }
      /**
      * @param {(renderer: Renderer) => MaybePromise<void>} fn
      */
      child_block(fn) {
        this.#out.push(BLOCK_OPEN);
        this.child(fn);
        this.#out.push(BLOCK_CLOSE);
      }
      /**
      * Create a child renderer. The child renderer inherits the state from the parent,
      * but has its own content.
      * @param {(renderer: Renderer) => MaybePromise<void>} fn
      */
      child(fn) {
        const child = new Renderer2(this.global, this);
        this.#out.push(child);
        const parent = ssr_context;
        set_ssr_context({
          ...ssr_context,
          p: parent,
          c: null,
          r: child
        });
        const result = fn(child);
        set_ssr_context(parent);
        if (result instanceof Promise) {
          result.catch(noop);
          result.finally(() => set_ssr_context(null)).catch(noop);
          if (child.global.mode === "sync") await_invalid();
          child.promise = result;
        }
        return child;
      }
      /**
      * Render children inside an error boundary. If the children throw and the API-level
      * `transformError` transform handles the error (doesn't re-throw), the `failed` snippet is
      * rendered instead. Otherwise the error propagates.
      *
      * @param {{ failed?: (renderer: Renderer, error: unknown, reset: () => void) => void }} props
      * @param {(renderer: Renderer) => MaybePromise<void>} children_fn
      */
      boundary(props, children_fn) {
        const child = new Renderer2(this.global, this);
        this.#out.push(child);
        const parent_context = ssr_context;
        if (props.failed) child.#boundary = {
          failed: props.failed,
          transformError: this.global.transformError,
          context: parent_context
        };
        set_ssr_context({
          ...ssr_context,
          p: parent_context,
          c: null,
          r: child
        });
        try {
          const result = children_fn(child);
          set_ssr_context(parent_context);
          if (result instanceof Promise) {
            if (child.global.mode === "sync") await_invalid();
            result.catch(noop);
            child.promise = result;
          }
        } catch (error2) {
          set_ssr_context(parent_context);
          const failed_snippet = props.failed;
          if (!failed_snippet) throw error2;
          const result = this.global.transformError(error2);
          child.#out.length = 0;
          child.#boundary = null;
          if (result instanceof Promise) {
            if (this.global.mode === "sync") await_invalid();
            child.promise = result.then((transformed) => {
              set_ssr_context(parent_context);
              child.#out.push(Renderer2.#serialize_failed_boundary(transformed));
              failed_snippet(child, transformed, noop);
              child.#out.push(BLOCK_CLOSE);
            });
            child.promise.catch(noop);
          } else {
            child.#out.push(Renderer2.#serialize_failed_boundary(result));
            failed_snippet(child, result, noop);
            child.#out.push(BLOCK_CLOSE);
          }
        }
      }
      /**
      * Create a component renderer. The component renderer inherits the state from the parent,
      * but has its own content. It is treated as an ordering boundary for ondestroy callbacks.
      * @param {(renderer: Renderer) => MaybePromise<void>} fn
      * @param {Function} [component_fn]
      * @returns {void}
      */
      component(fn, component_fn) {
        push(component_fn);
        const child = this.child(fn);
        child.#is_component_body = true;
        pop();
      }
      /**
      * @param {Record<string, any>} attrs
      * @param {(renderer: Renderer) => void} fn
      * @param {string | undefined} [css_hash]
      * @param {Record<string, boolean> | undefined} [classes]
      * @param {Record<string, string> | undefined} [styles]
      * @param {number | undefined} [flags]
      * @param {boolean | undefined} [is_rich]
      * @returns {void}
      */
      select(attrs, fn, css_hash, classes, styles, flags2, is_rich) {
        const { value: value2, ...select_attrs } = attrs;
        this.push(`<select${attributes(select_attrs, css_hash, classes, styles, flags2)}>`);
        this.child((renderer) => {
          renderer.local.select_value = value2;
          fn(renderer);
        });
        this.push(`${is_rich ? "<!>" : ""}</select>`);
      }
      /**
      * @param {Record<string, any>} attrs
      * @param {string | number | boolean | ((renderer: Renderer) => void)} body
      * @param {string | undefined} [css_hash]
      * @param {Record<string, boolean> | undefined} [classes]
      * @param {Record<string, string> | undefined} [styles]
      * @param {number | undefined} [flags]
      * @param {boolean | undefined} [is_rich]
      */
      option(attrs, body, css_hash, classes, styles, flags2, is_rich) {
        this.#out.push(`<option${attributes(attrs, css_hash, classes, styles, flags2)}`);
        const close = (renderer, value2, { head: head2, body: body2 }) => {
          if (has_own_property.call(attrs, "value")) value2 = attrs.value;
          if (value2 === this.local.select_value) renderer.#out.push(' selected=""');
          renderer.#out.push(`>${body2}${is_rich ? "<!>" : ""}</option>`);
          if (head2) renderer.head((child) => child.push(head2));
        };
        if (typeof body === "function") this.child((renderer) => {
          const r2 = new Renderer2(this.global, this);
          body(r2);
          if (this.global.mode === "async") return r2.#collect_content_async().then((content) => {
            close(renderer, content.body.replaceAll("<!---->", ""), content);
          });
          else {
            const content = r2.#collect_content();
            close(renderer, content.body.replaceAll("<!---->", ""), content);
          }
        });
        else close(this, body, { body: escape_html(body) });
      }
      /**
      * @param {(renderer: Renderer) => void} fn
      */
      title(fn) {
        const path = this.get_path();
        const close = (head2) => {
          this.global.set_title(head2, path);
        };
        this.child((renderer) => {
          const r2 = new Renderer2(renderer.global, renderer);
          fn(r2);
          if (renderer.global.mode === "async") return r2.#collect_content_async().then((content) => {
            close(content.head);
          });
          else {
            const content = r2.#collect_content();
            close(content.head);
          }
        });
      }
      /**
      * @param {string | (() => Promise<string>)} content
      */
      push(content) {
        if (typeof content === "function") this.child(async (renderer) => renderer.push(await content()));
        else this.#out.push(content);
      }
      /**
      * @param {() => void} fn
      */
      on_destroy(fn) {
        (this.#on_destroy ??= []).push(fn);
      }
      /**
      * @returns {number[]}
      */
      get_path() {
        return this.#parent ? [...this.#parent.get_path(), this.#parent.#out.indexOf(this)] : [];
      }
      /**
      * @deprecated this is needed for legacy component bindings
      */
      copy() {
        const copy = new Renderer2(this.global, this.#parent);
        copy.#out = this.#out.map((item) => item instanceof Renderer2 ? item.copy() : item);
        copy.promise = this.promise;
        return copy;
      }
      /**
      * @param {Renderer} other
      * @deprecated this is needed for legacy component bindings
      */
      subsume(other) {
        if (this.global.mode !== other.global.mode) throw new Error("invariant: A renderer cannot switch modes. If you're seeing this, there's a compiler bug. File an issue!");
        this.local = other.local;
        this.#out = other.#out.map((item, i) => {
          const current3 = this.#out[i];
          if (current3 instanceof Renderer2 && item instanceof Renderer2) {
            current3.subsume(item);
            return current3;
          }
          return item;
        });
        this.promise = other.promise;
        this.type = other.type;
      }
      get length() {
        return this.#out.length;
      }
      /**
      * Creates the hydration comment that marks the start of a failed boundary.
      * The error is JSON-serialized and embedded inside an HTML comment for the client
      * to parse during hydration. The JSON is escaped to prevent `-->` or `<!--` sequences
      * from breaking out of the comment (XSS). Uses unicode escapes which `JSON.parse()`
      * handles transparently.
      * @param {unknown} error
      * @returns {string}
      */
      static #serialize_failed_boundary(error2) {
        return `<!--[?${JSON.stringify(error2).replace(/>/g, "\\u003e").replace(/</g, "\\u003c")}-->`;
      }
      /**
      * Only available on the server and when compiling with the `server` option.
      * Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app.
      * @template {Record<string, any>} Props
      * @param {Component<Props>} component
      * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp }} [options]
      * @returns {RenderOutput}
      */
      static render(component84, options2 = {}) {
        let sync;
        let async;
        const result = {};
        Object.defineProperties(result, {
          html: { get: () => {
            return (sync ??= Renderer2.#render(component84, options2)).body;
          } },
          head: { get: () => {
            return (sync ??= Renderer2.#render(component84, options2)).head;
          } },
          body: { get: () => {
            return (sync ??= Renderer2.#render(component84, options2)).body;
          } },
          hashes: { value: { script: "" } },
          then: { value: (
            /**
            * this is not type-safe, but honestly it's the best I can do right now, and it's a straightforward function.
            *
            * @template TResult1
            * @template [TResult2=never]
            * @param { (value: SyncRenderOutput) => TResult1 } onfulfilled
            * @param { (reason: unknown) => TResult2 } onrejected
            */
            (onfulfilled, onrejected) => {
              if (!async_mode_flag) {
                const result2 = sync ??= Renderer2.#render(component84, options2);
                const user_result = onfulfilled({
                  head: result2.head,
                  body: result2.body,
                  html: result2.body,
                  hashes: { script: [] }
                });
                return Promise.resolve(user_result);
              }
              async ??= init_render_context().then(() => with_render_context(() => Renderer2.#render_async(component84, options2)));
              return async.then((result2) => {
                Object.defineProperty(result2, "html", { get: () => {
                  html_deprecated();
                } });
                return onfulfilled(result2);
              }, onrejected);
            }
          ) }
        });
        return result;
      }
      /**
      * Collect all of the `onDestroy` callbacks registered during rendering. In an async context, this is only safe to call
      * after awaiting `collect_async`.
      *
      * Child renderers are "porous" and don't affect execution order, but component body renderers
      * create ordering boundaries. Within a renderer, callbacks run in order until hitting a component boundary.
      * @returns {Iterable<() => void>}
      */
      *#collect_on_destroy() {
        for (const component84 of this.#traverse_components()) yield* component84.#collect_ondestroy();
      }
      /**
      * Performs a depth-first search of renderers, yielding the deepest components first, then additional components as we backtrack up the tree.
      * @returns {Iterable<Renderer>}
      */
      *#traverse_components() {
        for (const child of this.#out) if (typeof child !== "string") yield* child.#traverse_components();
        if (this.#is_component_body) yield this;
      }
      /**
      * @returns {Iterable<() => void>}
      */
      *#collect_ondestroy() {
        if (this.#on_destroy) for (const fn of this.#on_destroy) yield fn;
        for (const child of this.#out) if (child instanceof Renderer2 && !child.#is_component_body) yield* child.#collect_ondestroy();
      }
      /**
      * Render a component. Throws if any of the children are performing asynchronous work.
      *
      * @template {Record<string, any>} Props
      * @param {Component<Props>} component
      * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string }} options
      * @returns {AccumulatedContent}
      */
      static #render(component84, options2) {
        var previous_context = ssr_context;
        try {
          const renderer = Renderer2.#open_render("sync", component84, options2);
          const content = renderer.#collect_content();
          return Renderer2.#close_render(content, renderer);
        } finally {
          abort();
          set_ssr_context(previous_context);
        }
      }
      /**
      * Render a component.
      *
      * @template {Record<string, any>} Props
      * @param {Component<Props>} component
      * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp }} options
      * @returns {Promise<AccumulatedContent & { hashes: { script: Sha256Source[] } }>}
      */
      static async #render_async(component84, options2) {
        const previous_context = ssr_context;
        try {
          const renderer = Renderer2.#open_render("async", component84, options2);
          const content = await renderer.#collect_content_async();
          const hydratables = await renderer.#collect_hydratables();
          if (hydratables !== null) content.head = hydratables + content.head;
          return Renderer2.#close_render(content, renderer);
        } finally {
          set_ssr_context(previous_context);
          abort();
        }
      }
      /**
      * Collect all of the code from the `out` array and return it as a string, or a promise resolving to a string.
      * @param {AccumulatedContent} content
      * @returns {AccumulatedContent}
      */
      #collect_content(content = {
        head: "",
        body: ""
      }) {
        for (const item of this.#out) if (typeof item === "string") content[this.type] += item;
        else if (item instanceof Renderer2) item.#collect_content(content);
        return content;
      }
      /**
      * Collect all of the code from the `out` array and return it as a string.
      * @param {AccumulatedContent} content
      * @returns {Promise<AccumulatedContent>}
      */
      async #collect_content_async(content = {
        head: "",
        body: ""
      }) {
        await this.promise;
        for (const item of this.#out) if (typeof item === "string") content[this.type] += item;
        else if (item instanceof Renderer2) if (item.#boundary) {
          const boundary_content = {
            head: "",
            body: ""
          };
          try {
            await item.#collect_content_async(boundary_content);
            content.head += boundary_content.head;
            content.body += boundary_content.body;
          } catch (error2) {
            const { context: context2, failed, transformError } = item.#boundary;
            set_ssr_context(context2);
            let promise = transformError(error2);
            set_ssr_context(null);
            let transformed = await promise;
            set_ssr_context(context2);
            const failed_renderer = new Renderer2(item.global, item);
            failed_renderer.type = item.type;
            failed_renderer.#out.push(Renderer2.#serialize_failed_boundary(transformed));
            failed(failed_renderer, transformed, noop);
            failed_renderer.#out.push(BLOCK_CLOSE);
            await failed_renderer.#collect_content_async(content);
          }
        } else await item.#collect_content_async(content);
        return content;
      }
      async #collect_hydratables() {
        const ctx = get_render_context().hydratable;
        for (const [_3, key2] of ctx.unresolved_promises) unresolved_hydratable(key2, ctx.lookup.get(key2)?.stack ?? "<missing stack trace>");
        for (const comparison of ctx.comparisons) await comparison;
        return await this.#hydratable_block(ctx);
      }
      /**
      * @template {Record<string, any>} Props
      * @param {'sync' | 'async'} mode
      * @param {import('svelte').Component<Props>} component
      * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp; transformError?: (error: unknown) => unknown }} options
      * @returns {Renderer}
      */
      static #open_render(mode, component84, options2) {
        if (options2.idPrefix?.includes("--")) invalid_id_prefix();
        var previous_context = ssr_context;
        try {
          const renderer = new Renderer2(new SSRState(mode, options2.idPrefix ? options2.idPrefix + "-" : "", options2.csp, options2.transformError));
          set_ssr_context({
            p: null,
            c: options2.context ?? null,
            r: renderer
          });
          renderer.push(BLOCK_OPEN);
          component84(renderer, options2.props ?? {});
          renderer.push(BLOCK_CLOSE);
          return renderer;
        } finally {
          set_ssr_context(previous_context);
        }
      }
      /**
      * @param {AccumulatedContent} content
      * @param {Renderer} renderer
      * @returns {AccumulatedContent & { hashes: { script: Sha256Source[] } }}
      */
      static #close_render(content, renderer) {
        for (const cleanup2 of renderer.#collect_on_destroy()) cleanup2();
        let head2 = content.head + renderer.global.get_title();
        let body = content.body;
        for (const { hash: hash4, code: code3 } of renderer.global.css) head2 += `<style id="${hash4}">${code3}</style>`;
        return {
          head: head2,
          body,
          hashes: { script: renderer.global.csp.script_hashes }
        };
      }
      /**
      * @param {HydratableContext} ctx
      */
      async #hydratable_block(ctx) {
        if (ctx.lookup.size === 0) return null;
        let entries = [];
        let has_promises = false;
        for (const [k2, v3] of ctx.lookup) {
          if (v3.promises) {
            has_promises = true;
            for (const p2 of v3.promises) await p2;
          }
          entries.push(`[${uneval(k2)},${v3.serialized}]`);
        }
        let prelude = `const h = (window.__svelte ??= {}).h ??= new Map();`;
        if (has_promises) prelude = `const r = (v) => Promise.resolve(v);
				${prelude}`;
        const body = `
			{
				${prelude}

				for (const [k, v] of [
					${entries.join(",\n					")}
				]) {
					h.set(k, v);
				}
			}
		`;
        let csp_attr = "";
        if (this.global.csp.nonce) csp_attr = ` nonce="${this.global.csp.nonce}"`;
        else if (this.global.csp.hash) {
          const hash4 = await sha256(body);
          this.global.csp.script_hashes.push(`sha256-${hash4}`);
        }
        return `
		<script${csp_attr}>${body}</script>`;
      }
    };
    SSRState = class {
      /** @readonly @type {Csp & { script_hashes: Sha256Source[] }} */
      csp;
      /** @readonly @type {'sync' | 'async'} */
      mode;
      /** @readonly @type {() => string} */
      uid;
      /** @readonly @type {Set<{ hash: string; code: string }>} */
      css = /* @__PURE__ */ new Set();
      /**
      * `transformError` passed to `render`. Called when an error boundary catches an error.
      * Throws by default if unset in `render`.
      * @type {(error: unknown) => unknown}
      */
      transformError;
      /** @type {{ path: number[], value: string }} */
      #title = {
        path: [],
        value: ""
      };
      /**
      * @param {'sync' | 'async'} mode
      * @param {string} id_prefix
      * @param {Csp} csp
      * @param {((error: unknown) => unknown) | undefined} [transformError]
      */
      constructor(mode, id_prefix = "", csp = { hash: false }, transformError) {
        this.mode = mode;
        this.csp = {
          ...csp,
          script_hashes: []
        };
        this.transformError = transformError ?? ((error2) => {
          throw error2;
        });
        let uid2 = 1;
        this.uid = () => `${id_prefix}s${uid2++}`;
      }
      get_title() {
        return this.#title.value;
      }
      /**
      * Performs a depth-first (lexicographic) comparison using the path. Rejects sets
      * from earlier than or equal to the current value.
      * @param {string} value
      * @param {number[]} path
      */
      set_title(value2, path) {
        const current3 = this.#title.path;
        let i = 0;
        let l3 = Math.min(path.length, current3.length);
        while (i < l3 && path[i] === current3[i]) i += 1;
        if (path[i] === void 0) return;
        if (current3[i] === void 0 || path[i] > current3[i]) {
          this.#title.path = path;
          this.#title.value = value2;
        }
      }
    };
    INVALID_ATTR_NAME_CHAR_REGEX = /[\s'">/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u;
  }
});

// dist/build/server/chunks/index-server.js
function hydratable(key2, fn) {
  if (!async_mode_flag) experimental_async_required("hydratable");
  const { hydratable: hydratable2 } = get_render_context();
  let entry = hydratable2.lookup.get(key2);
  if (entry !== void 0) return entry.value;
  const value2 = fn();
  entry = encode(key2, value2, hydratable2.unresolved_promises);
  hydratable2.lookup.set(key2, entry);
  return value2;
}
function encode(key2, value2, unresolved) {
  const entry = {
    value: value2,
    serialized: ""
  };
  let uid2 = 1;
  entry.serialized = uneval(entry.value, (value3, uneval2) => {
    if (is_promise(value3)) {
      const placeholder = `"${uid2++}"`;
      const p2 = value3.then((v3) => {
        entry.serialized = entry.serialized.replace(placeholder, () => `r(${uneval2(v3)})`);
      }).catch((devalue_error) => hydratable_serialization_failed(key2, serialization_stack(entry.stack, devalue_error?.stack)));
      unresolved?.set(p2, key2);
      p2.catch(() => {
      }).finally(() => unresolved?.delete(p2));
      (entry.promises ??= []).push(p2);
      return placeholder;
    }
  });
  return entry;
}
function is_promise(value2) {
  return Object.prototype.toString.call(value2) === "[object Promise]";
}
function serialization_stack(root_stack, uneval_stack) {
  let out = "";
  if (root_stack) out += root_stack + "\n";
  if (uneval_stack) out += "Caused by:\n" + uneval_stack + "\n";
  return out || "<missing stack trace>";
}
function createRawSnippet(fn) {
  return (renderer, ...args) => {
    var getters = args.map((value2) => () => value2);
    renderer.push(fn(...getters).render().trim());
  };
}
function onDestroy(fn) {
  ssr_context.r.on_destroy(fn);
}
function createEventDispatcher() {
  return noop;
}
function mount() {
  lifecycle_function_unavailable("mount");
}
function hydrate() {
  lifecycle_function_unavailable("hydrate");
}
function unmount() {
  lifecycle_function_unavailable("unmount");
}
function fork() {
  lifecycle_function_unavailable("fork");
}
async function tick() {
}
async function settled() {
}
var __defProp2, __commonJSMin, __exportAll, index_server_exports;
var init_index_server = __esm({
  "dist/build/server/chunks/index-server.js"() {
    "use strict";
    init_uneval();
    init_server();
    __defProp2 = Object.defineProperty;
    __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
    __exportAll = (all, no_symbols) => {
      let target = {};
      for (var name in all) __defProp2(target, name, {
        get: all[name],
        enumerable: true
      });
      if (!no_symbols) __defProp2(target, Symbol.toStringTag, { value: "Module" });
      return target;
    };
    index_server_exports = /* @__PURE__ */ __exportAll({
      afterUpdate: () => noop,
      beforeUpdate: () => noop,
      createContext: () => createContext,
      createEventDispatcher: () => createEventDispatcher,
      createRawSnippet: () => createRawSnippet,
      flushSync: () => noop,
      fork: () => fork,
      getAbortSignal: () => getAbortSignal,
      getAllContexts: () => getAllContexts,
      getContext: () => getContext,
      hasContext: () => hasContext,
      hydratable: () => hydratable,
      hydrate: () => hydrate,
      mount: () => mount,
      onDestroy: () => onDestroy,
      onMount: () => noop,
      setContext: () => setContext,
      settled: () => settled,
      tick: () => tick,
      unmount: () => unmount,
      untrack: () => run
    });
  }
});

// node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/exports/internal/remote-functions.js
var init_remote_functions = __esm({
  "node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/exports/internal/remote-functions.js"() {
  }
});

// node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/exports/internal/index.js
var HttpError, Redirect, SvelteKitError, ActionFailure;
var init_internal = __esm({
  "node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/exports/internal/index.js"() {
    init_remote_functions();
    HttpError = class {
      /**
       * @param {number} status
       * @param {{message: string} extends App.Error ? (App.Error | string | undefined) : App.Error} body
       */
      constructor(status, body) {
        this.status = status;
        if (typeof body === "string") {
          this.body = { message: body };
        } else if (body) {
          this.body = body;
        } else {
          this.body = { message: `Error: ${status}` };
        }
      }
      toString() {
        return JSON.stringify(this.body);
      }
    };
    Redirect = class {
      /**
       * @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308} status
       * @param {string} location
       */
      constructor(status, location) {
        try {
          new Headers({ location });
        } catch {
          throw new Error(
            `Invalid redirect location ${JSON.stringify(location)}: this string contains characters that cannot be used in HTTP headers`
          );
        }
        this.status = status;
        this.location = location;
      }
    };
    SvelteKitError = class extends Error {
      /**
       * @param {number} status
       * @param {string} text
       * @param {string} message
       */
      constructor(status, text2, message2) {
        super(message2);
        this.status = status;
        this.text = text2;
      }
    };
    ActionFailure = class {
      /**
       * @param {number} status
       * @param {T} data
       */
      constructor(status, data) {
        this.status = status;
        this.data = data;
      }
    };
  }
});

// dist/build/server/chunks/shared.js
function noop2() {
}
function once2(fn) {
  let done = false;
  let result;
  return () => {
    if (done) return result;
    done = true;
    return result = fn();
  };
}
function encode_native(array_buffer) {
  return new Uint8Array(array_buffer).toBase64();
}
function decode_native(base64) {
  return Uint8Array.fromBase64(base64).buffer;
}
function encode_buffer(array_buffer) {
  return Buffer.from(array_buffer).toString("base64");
}
function decode_buffer(base64) {
  return Uint8Array.from(Buffer.from(base64, "base64")).buffer;
}
function encode_legacy(array_buffer) {
  const array2 = new Uint8Array(array_buffer);
  let binary2 = "";
  const chunk_size = 32768;
  for (let i = 0; i < array2.length; i += chunk_size) {
    const chunk = array2.subarray(i, i + chunk_size);
    binary2 += String.fromCharCode.apply(null, chunk);
  }
  return btoa(binary2);
}
function decode_legacy(base64) {
  const binary_string = atob(base64);
  const len = binary_string.length;
  const array2 = new Uint8Array(len);
  for (let i = 0; i < len; i++) array2[i] = binary_string.charCodeAt(i);
  return array2.buffer;
}
function parse(serialized, revivers) {
  return unflatten(JSON.parse(serialized), revivers);
}
function unflatten(parsed, revivers) {
  if (typeof parsed === "number") return hydrate3(parsed, true);
  if (!Array.isArray(parsed) || parsed.length === 0) throw new Error("Invalid input");
  const values = parsed;
  const hydrated = Array(values.length);
  let hydrating2 = null;
  function hydrate3(index88, standalone = false) {
    if (index88 === -1) return void 0;
    if (index88 === -3) return NaN;
    if (index88 === -4) return Infinity;
    if (index88 === -5) return -Infinity;
    if (index88 === -6) return -0;
    if (standalone || typeof index88 !== "number") throw new Error(`Invalid input`);
    if (index88 in hydrated) return hydrated[index88];
    const value2 = values[index88];
    if (!value2 || typeof value2 !== "object") hydrated[index88] = value2;
    else if (Array.isArray(value2)) if (typeof value2[0] === "string") {
      const type = value2[0];
      const reviver = revivers && Object.hasOwn(revivers, type) ? revivers[type] : void 0;
      if (reviver) {
        let i = value2[1];
        if (typeof i !== "number") i = values.push(value2[1]) - 1;
        hydrating2 ??= /* @__PURE__ */ new Set();
        if (hydrating2.has(i)) throw new Error("Invalid circular reference");
        hydrating2.add(i);
        hydrated[index88] = reviver(hydrate3(i));
        hydrating2.delete(i);
        return hydrated[index88];
      }
      switch (type) {
        case "Date":
          hydrated[index88] = new Date(value2[1]);
          break;
        case "Set":
          const set3 = /* @__PURE__ */ new Set();
          hydrated[index88] = set3;
          for (let i = 1; i < value2.length; i += 1) set3.add(hydrate3(value2[i]));
          break;
        case "Map":
          const map2 = /* @__PURE__ */ new Map();
          hydrated[index88] = map2;
          for (let i = 1; i < value2.length; i += 2) map2.set(hydrate3(value2[i]), hydrate3(value2[i + 1]));
          break;
        case "RegExp":
          hydrated[index88] = new RegExp(value2[1], value2[2]);
          break;
        case "Object": {
          const wrapped_index = value2[1];
          if (typeof values[wrapped_index] === "object" && values[wrapped_index][0] !== "BigInt") throw new Error("Invalid input");
          hydrated[index88] = Object(hydrate3(wrapped_index));
          break;
        }
        case "BigInt":
          hydrated[index88] = BigInt(value2[1]);
          break;
        case "null":
          const obj = /* @__PURE__ */ Object.create(null);
          hydrated[index88] = obj;
          for (let i = 1; i < value2.length; i += 2) {
            if (value2[i] === "__proto__") throw new Error("Cannot parse an object with a `__proto__` property");
            obj[value2[i]] = hydrate3(value2[i + 1]);
          }
          break;
        case "Int8Array":
        case "Uint8Array":
        case "Uint8ClampedArray":
        case "Int16Array":
        case "Uint16Array":
        case "Float16Array":
        case "Int32Array":
        case "Uint32Array":
        case "Float32Array":
        case "Float64Array":
        case "BigInt64Array":
        case "BigUint64Array":
        case "DataView": {
          if (values[value2[1]][0] !== "ArrayBuffer") throw new Error("Invalid data");
          const TypedArrayConstructor = globalThis[type];
          const buffer2 = hydrate3(value2[1]);
          hydrated[index88] = value2[2] !== void 0 ? new TypedArrayConstructor(buffer2, value2[2], value2[3]) : new TypedArrayConstructor(buffer2);
          break;
        }
        case "ArrayBuffer": {
          const base64 = value2[1];
          if (typeof base64 !== "string") throw new Error("Invalid ArrayBuffer encoding");
          const arraybuffer = decode64(base64);
          hydrated[index88] = arraybuffer;
          break;
        }
        case "Temporal.Duration":
        case "Temporal.Instant":
        case "Temporal.PlainDate":
        case "Temporal.PlainTime":
        case "Temporal.PlainDateTime":
        case "Temporal.PlainMonthDay":
        case "Temporal.PlainYearMonth":
        case "Temporal.ZonedDateTime": {
          const temporalName = type.slice(9);
          hydrated[index88] = Temporal[temporalName].from(value2[1]);
          break;
        }
        case "URL": {
          const url = new URL(value2[1]);
          hydrated[index88] = url;
          break;
        }
        case "URLSearchParams": {
          const url = new URLSearchParams(value2[1]);
          hydrated[index88] = url;
          break;
        }
        default:
          throw new Error(`Unknown type ${type}`);
      }
    } else if (value2[0] === -7) {
      const len = value2[1];
      if (!is_valid_array_len(len)) throw new Error("Invalid input");
      const array2 = [];
      hydrated[index88] = array2;
      array2[MAX_ARRAY_INDEX] = void 0;
      delete array2[MAX_ARRAY_INDEX];
      for (let i = 2; i < value2.length; i += 2) {
        const idx = value2[i];
        if (!is_valid_array_index(idx) || idx >= len) throw new Error("Invalid input");
        array2[idx] = hydrate3(value2[i + 1]);
      }
      array2.length = len;
    } else {
      const array2 = new Array(value2.length);
      hydrated[index88] = array2;
      for (let i = 0; i < value2.length; i += 1) {
        const n = value2[i];
        if (n === -2) continue;
        array2[i] = hydrate3(n);
      }
    }
    else {
      const object = {};
      hydrated[index88] = object;
      for (const key2 of Object.keys(value2)) {
        if (key2 === "__proto__") throw new Error("Cannot parse an object with a `__proto__` property");
        const n = value2[key2];
        object[key2] = hydrate3(n);
      }
    }
    return hydrated[index88];
  }
  return hydrate3(0);
}
function stringify$1(value2, reducers) {
  const stringified = run2(false, value2, reducers);
  return typeof stringified === "string" ? stringified : `[${stringified.join(",")}]`;
}
function run2(async, value2, reducers) {
  const stringified = [];
  const indexes = /* @__PURE__ */ new Map();
  const custom = [];
  if (reducers) for (const key2 of Object.getOwnPropertyNames(reducers)) custom.push({
    key: key2,
    fn: reducers[key2]
  });
  const keys = [];
  let p2 = 0;
  function flatten(thing, index89) {
    if (thing === void 0) return -1;
    if (Number.isNaN(thing)) return -3;
    if (thing === Infinity) return -4;
    if (thing === -Infinity) return -5;
    if (thing === 0 && 1 / thing < 0) return -6;
    if (indexes.has(thing)) return indexes.get(thing);
    index89 ??= p2++;
    indexes.set(thing, index89);
    for (const { key: key2, fn } of custom) {
      const value3 = fn(thing);
      if (value3) {
        stringified[index89] = `["${key2}",${flatten(value3)}]`;
        return index89;
      }
    }
    if (typeof thing === "function") throw new DevalueError(`Cannot stringify a function`, keys, thing, value2);
    else if (typeof thing === "symbol") throw new DevalueError(`Cannot stringify a Symbol primitive`, keys, thing, value2);
    let str2 = "";
    if (is_primitive(thing)) str2 = stringify_primitive2(thing);
    else if (typeof thing.then === "function") {
      if (!async) throw new DevalueError(`Cannot stringify a Promise or thenable \u2014 use stringifyAsync instead`, keys, thing, value2);
      str2 = Promise.resolve(thing).then((value3) => {
        const i = flatten(value3, index89);
        if (i < 0) stringified[index89] = i;
      });
    } else {
      const type = get_type(thing);
      switch (type) {
        case "Number":
        case "String":
        case "Boolean":
        case "BigInt":
          str2 = `["Object",${flatten(thing.valueOf())}]`;
          break;
        case "Date":
          str2 = `["Date","${!isNaN(thing.getDate()) ? thing.toISOString() : ""}"]`;
          break;
        case "URL":
          str2 = `["URL",${stringify_string(thing.toString())}]`;
          break;
        case "URLSearchParams":
          str2 = `["URLSearchParams",${stringify_string(thing.toString())}]`;
          break;
        case "RegExp":
          const { source: source2, flags: flags2 } = thing;
          str2 = flags2 ? `["RegExp",${stringify_string(source2)},"${flags2}"]` : `["RegExp",${stringify_string(source2)}]`;
          break;
        case "Array": {
          let mostly_dense = false;
          str2 = "[";
          for (let i = 0; i < thing.length; i += 1) {
            if (i > 0) str2 += ",";
            if (Object.hasOwn(thing, i)) {
              keys.push(`[${i}]`);
              str2 += flatten(thing[i]);
              keys.pop();
            } else if (mostly_dense) str2 += -2;
            else {
              const populated_keys = valid_array_indices(thing);
              const population = populated_keys.length;
              const d2 = String(thing.length).length;
              if ((thing.length - population) * 3 > 4 + d2 + population * (d2 + 1)) {
                str2 = "[-7," + thing.length;
                for (let j2 = 0; j2 < populated_keys.length; j2++) {
                  const key2 = populated_keys[j2];
                  keys.push(`[${key2}]`);
                  str2 += "," + key2 + "," + flatten(thing[key2]);
                  keys.pop();
                }
                break;
              } else {
                mostly_dense = true;
                str2 += -2;
              }
            }
          }
          str2 += "]";
          break;
        }
        case "Set":
          str2 = '["Set"';
          for (const value3 of thing) str2 += `,${flatten(value3)}`;
          str2 += "]";
          break;
        case "Map":
          str2 = '["Map"';
          for (const [key2, value3] of thing) {
            keys.push(`.get(${is_primitive(key2) ? stringify_primitive2(key2) : "..."})`);
            str2 += `,${flatten(key2)},${flatten(value3)}`;
            keys.pop();
          }
          str2 += "]";
          break;
        case "Int8Array":
        case "Uint8Array":
        case "Uint8ClampedArray":
        case "Int16Array":
        case "Uint16Array":
        case "Float16Array":
        case "Int32Array":
        case "Uint32Array":
        case "Float32Array":
        case "Float64Array":
        case "BigInt64Array":
        case "BigUint64Array":
        case "DataView": {
          const typedArray = thing;
          str2 = '["' + type + '",' + flatten(typedArray.buffer);
          if (typedArray.byteLength !== typedArray.buffer.byteLength) str2 += `,${typedArray.byteOffset},${typedArray.length}`;
          str2 += "]";
          break;
        }
        case "ArrayBuffer":
          str2 = `["ArrayBuffer","${encode64(thing)}"]`;
          break;
        case "Temporal.Duration":
        case "Temporal.Instant":
        case "Temporal.PlainDate":
        case "Temporal.PlainTime":
        case "Temporal.PlainDateTime":
        case "Temporal.PlainMonthDay":
        case "Temporal.PlainYearMonth":
        case "Temporal.ZonedDateTime":
          str2 = `["${type}",${stringify_string(thing.toString())}]`;
          break;
        default:
          if (!is_plain_object(thing)) throw new DevalueError(`Cannot stringify arbitrary non-POJOs`, keys, thing, value2);
          if (enumerable_symbols(thing).length > 0) throw new DevalueError(`Cannot stringify POJOs with symbolic keys`, keys, thing, value2);
          if (Object.getPrototypeOf(thing) === null) {
            str2 = '["null"';
            for (const key2 of Object.keys(thing)) {
              if (key2 === "__proto__") throw new DevalueError(`Cannot stringify objects with __proto__ keys`, keys, thing, value2);
              keys.push(stringify_key(key2));
              str2 += `,${stringify_string(key2)},${flatten(thing[key2])}`;
              keys.pop();
            }
            str2 += "]";
          } else {
            str2 = "{";
            let started = false;
            for (const key2 of Object.keys(thing)) {
              if (key2 === "__proto__") throw new DevalueError(`Cannot stringify objects with __proto__ keys`, keys, thing, value2);
              if (started) str2 += ",";
              started = true;
              keys.push(stringify_key(key2));
              str2 += `${stringify_string(key2)}:${flatten(thing[key2])}`;
              keys.pop();
            }
            str2 += "}";
          }
      }
    }
    stringified[index89] = str2;
    return index89;
  }
  const index88 = flatten(value2);
  if (index88 < 0) return `${index88}`;
  return stringified;
}
function stringify_primitive2(thing) {
  const type = typeof thing;
  if (type === "string") return stringify_string(thing);
  if (thing === void 0) return (-1).toString();
  if (thing === 0 && 1 / thing < 0) return (-6).toString();
  if (type === "bigint") return `["BigInt","${thing}"]`;
  return String(thing);
}
function get_relative_path(from, to) {
  const from_parts = from.split(/[/\\]/);
  const to_parts = to.split(/[/\\]/);
  from_parts.pop();
  while (from_parts[0] === to_parts[0]) {
    from_parts.shift();
    to_parts.shift();
  }
  let i = from_parts.length;
  while (i--) from_parts[i] = "..";
  return from_parts.concat(to_parts).join("/");
}
function base64_encode2(bytes) {
  if (globalThis.Buffer) return globalThis.Buffer.from(bytes).toString("base64");
  let binary2 = "";
  for (let i = 0; i < bytes.length; i++) binary2 += String.fromCharCode(bytes[i]);
  return btoa(binary2);
}
function base64_decode(encoded) {
  if (globalThis.Buffer) {
    const buffer2 = globalThis.Buffer.from(encoded, "base64");
    return new Uint8Array(buffer2);
  }
  const binary2 = atob(encoded);
  const bytes = new Uint8Array(binary2.length);
  for (let i = 0; i < binary2.length; i++) bytes[i] = binary2.charCodeAt(i);
  return bytes;
}
function coalesce_to_error(err) {
  return err instanceof Error || err && err.name && err.message ? err : new Error(JSON.stringify(err));
}
function normalize_error(error2) {
  return error2;
}
function get_status(error2) {
  return error2 instanceof HttpError || error2 instanceof SvelteKitError ? error2.status : 500;
}
function get_message(error2) {
  return error2 instanceof SvelteKitError ? error2.text : "Internal Error";
}
function stringify2(data, transport) {
  return stringify$1(data, Object.fromEntries(Object.entries(transport).map(([k2, v3]) => [k2, v3.encode])));
}
function create_remote_arg_revivers(transport) {
  const remote_fns_revivers = {
    /** @type {(value: unknown) => unknown} */
    [remote_object]: (value2) => value2,
    /** @type {(value: unknown) => Map<unknown, unknown>} */
    [remote_map]: (value2) => {
      if (!Array.isArray(value2)) throw new Error("Invalid data for Map reviver");
      const map2 = /* @__PURE__ */ new Map();
      for (const item of value2) {
        if (!Array.isArray(item) || item.length !== 2 || typeof item[0] !== "string" || typeof item[1] !== "string") throw new Error("Invalid data for Map reviver");
        const [key2, val] = item;
        map2.set(parse$1(key2), parse$1(val));
      }
      return map2;
    },
    /** @type {(value: unknown) => Set<unknown>} */
    [remote_set]: (value2) => {
      if (!Array.isArray(value2)) throw new Error("Invalid data for Set reviver");
      const set3 = /* @__PURE__ */ new Set();
      for (const item of value2) {
        if (typeof item !== "string") throw new Error("Invalid data for Set reviver");
        set3.add(parse$1(item));
      }
      return set3;
    },
    /** @type {(value: any) => File} */
    [remote_file]: (value2) => {
      if (!value2 || typeof value2 !== "object" || typeof value2.name !== "string" || typeof value2.type !== "string" || typeof value2.size !== "number" || typeof value2.lastModified !== "number" || !(value2.data instanceof ArrayBuffer)) throw new Error("Invalid data for File reviver");
      const { data, name, ...meta } = value2;
      return new File([data], name, meta);
    }
  };
  const all_revivers = {
    ...Object.fromEntries(Object.entries(transport).map(([k2, v3]) => [k2, v3.decode])),
    ...remote_fns_revivers
  };
  const parse$1 = (data) => parse(data, all_revivers);
  return all_revivers;
}
function parse_remote_arg(string, transport) {
  if (!string) return void 0;
  return parse(new TextDecoder().decode(base64_decode(string.replaceAll("-", "+").replaceAll("_", "/"))), create_remote_arg_revivers(transport));
}
function create_remote_key(id, payload2) {
  return id + "/" + payload2;
}
function split_remote_key(key2) {
  const i = key2.lastIndexOf("/");
  if (i === -1) throw new Error(`Invalid remote key: ${key2}`);
  return {
    id: key2.slice(0, i),
    payload: key2.slice(i + 1)
  };
}
var native, buffer, encode64, decode64, text_encoder2, INVALIDATED_PARAM, TRAILING_SLASH_PARAM, remote_object, remote_map, remote_set, remote_file, remote_arg_marker;
var init_shared = __esm({
  "dist/build/server/chunks/shared.js"() {
    "use strict";
    init_uneval();
    init_internal();
    native = typeof Uint8Array.fromBase64 === "function";
    buffer = typeof process === "object" && process.versions?.node !== void 0;
    encode64 = native ? encode_native : buffer ? encode_buffer : encode_legacy;
    decode64 = native ? decode_native : buffer ? decode_buffer : decode_legacy;
    text_encoder2 = new TextEncoder();
    INVALIDATED_PARAM = "x-sveltekit-invalidated";
    TRAILING_SLASH_PARAM = "x-sveltekit-trailing-slash";
    remote_object = "__skrao";
    remote_map = "__skram";
    remote_set = "__skras";
    remote_file = "__skraf";
    remote_arg_marker = Symbol(remote_object);
  }
});

// dist/build/server/chunks/internal.js
function override(paths) {
  base = paths.base;
  assets = paths.assets;
}
function reset() {
  base = initial.base;
  assets = initial.assets;
}
var base, assets, app_dir, initial;
var init_internal2 = __esm({
  "dist/build/server/chunks/internal.js"() {
    "use strict";
    base = "";
    assets = base;
    app_dir = "_app";
    initial = {
      base,
      assets
    };
    initial.base;
  }
});

// node_modules/.deno/esm-env@1.2.2/node_modules/esm-env/browser-fallback.js
var browser_fallback_default;
var init_browser_fallback = __esm({
  "node_modules/.deno/esm-env@1.2.2/node_modules/esm-env/browser-fallback.js"() {
    browser_fallback_default = typeof window !== "undefined";
  }
});

// node_modules/.deno/esm-env@1.2.2/node_modules/esm-env/dev-fallback.js
var node_env, dev_fallback_default;
var init_dev_fallback = __esm({
  "node_modules/.deno/esm-env@1.2.2/node_modules/esm-env/dev-fallback.js"() {
    node_env = globalThis.process?.env?.NODE_ENV;
    dev_fallback_default = node_env && !node_env.toLowerCase().startsWith("prod");
  }
});

// node_modules/.deno/esm-env@1.2.2/node_modules/esm-env/true.js
var init_true = __esm({
  "node_modules/.deno/esm-env@1.2.2/node_modules/esm-env/true.js"() {
  }
});

// node_modules/.deno/esm-env@1.2.2/node_modules/esm-env/index.js
var init_esm_env = __esm({
  "node_modules/.deno/esm-env@1.2.2/node_modules/esm-env/index.js"() {
    init_browser_fallback();
    init_dev_fallback();
    init_true();
  }
});

// node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/runtime/pathname.js
var init_pathname = __esm({
  "node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/runtime/pathname.js"() {
  }
});

// node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/runtime/utils.js
var text_encoder3;
var init_utils = __esm({
  "node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/runtime/utils.js"() {
    init_esm_env();
    text_encoder3 = new TextEncoder();
  }
});

// node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/version.js
var init_version = __esm({
  "node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/version.js"() {
  }
});

// node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/exports/index.js
function error(status, body) {
  if ((!browser_fallback_default || dev_fallback_default) && (isNaN(status) || status < 400 || status > 599)) {
    throw new Error(`HTTP error status codes must be between 400 and 599 \u2014 ${status} is invalid`);
  }
  throw new HttpError(status, body);
}
function redirect(status, location) {
  if ((!browser_fallback_default || dev_fallback_default) && (isNaN(status) || status < 300 || status > 308)) {
    throw new Error("Invalid status code");
  }
  throw new Redirect(
    // @ts-ignore
    status,
    location.toString()
  );
}
function isRedirect(e) {
  return e instanceof Redirect;
}
function json(data, init3) {
  const body = JSON.stringify(data);
  const headers2 = new Headers(init3?.headers);
  if (!headers2.has("content-length")) {
    headers2.set("content-length", text_encoder3.encode(body).byteLength.toString());
  }
  if (!headers2.has("content-type")) {
    headers2.set("content-type", "application/json");
  }
  return new Response(body, {
    ...init3,
    headers: headers2
  });
}
function text(body, init3) {
  const headers2 = new Headers(init3?.headers);
  if (!headers2.has("content-length")) {
    const encoded = text_encoder3.encode(body);
    headers2.set("content-length", encoded.byteLength.toString());
    return new Response(encoded, {
      ...init3,
      headers: headers2
    });
  }
  return new Response(body, {
    ...init3,
    headers: headers2
  });
}
function fail(status, data) {
  return new ActionFailure(status, data);
}
var init_exports = __esm({
  "node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/exports/index.js"() {
    init_internal();
    init_esm_env();
    init_pathname();
    init_utils();
    init_version();
  }
});

// node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/runtime/server/constants.js
var IN_WEBCONTAINER;
var init_constants = __esm({
  "node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/runtime/server/constants.js"() {
    IN_WEBCONTAINER = !!globalThis.process?.versions?.webcontainer;
  }
});

// node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/exports/internal/event.js
function with_request_store(store2, fn) {
  try {
    sync_store = store2;
    return als2 ? als2.run(store2, fn) : fn();
  } finally {
    if (!IN_WEBCONTAINER) {
      sync_store = null;
    }
  }
}
var sync_store, als2;
var init_event = __esm({
  "node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/exports/internal/event.js"() {
    init_constants();
    sync_store = null;
    import("node:async_hooks").then((hooks) => als2 = new hooks.AsyncLocalStorage()).catch(() => {
    });
  }
});

// node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/exports/internal/server.js
function merge_tracing(event_like, current3) {
  return {
    ...event_like,
    tracing: {
      ...event_like.tracing,
      current: current3
    }
  };
}
var init_server2 = __esm({
  "node_modules/.deno/@sveltejs+kit@2.70.2/node_modules/@sveltejs/kit/src/exports/internal/server.js"() {
    init_event();
  }
});

// dist/build/server/chunks/config.js
var Config, config;
var init_config = __esm({
  "dist/build/server/chunks/config.js"() {
    "use strict";
    Config = class {
      basePath;
      timezone;
      parserUrl;
      port;
      host;
      origin;
      authMode;
      profilarrApiKey;
      oidc;
      bulletinUrl;
      constructor() {
        const envPath = Deno.env.get("APP_BASE_PATH");
        if (envPath) this.basePath = envPath;
        else {
          const execPath = Deno.execPath();
          const lastSlash = Math.max(execPath.lastIndexOf("/"), execPath.lastIndexOf("\\"));
          this.basePath = lastSlash > 0 ? execPath.substring(0, lastSlash) : ".";
        }
        this.timezone = Deno.env.get("TZ") || Intl.DateTimeFormat().resolvedOptions().timeZone;
        const parserHost = Deno.env.get("PARSER_HOST") || "localhost";
        const parserPort = Deno.env.get("PARSER_PORT") || "5000";
        this.parserUrl = `http://${parserHost}:${parserPort}`;
        this.port = parseInt(Deno.env.get("PORT") || "6868", 10);
        this.host = Deno.env.get("HOST") || "0.0.0.0";
        this.origin = (Deno.env.get("ORIGIN") || this.serverUrl).replace(/\/+$/, "");
        const auth = (Deno.env.get("AUTH") || "on").toLowerCase();
        this.authMode = [
          "on",
          "off",
          "oidc"
        ].includes(auth) ? auth : "on";
        const profilarrApiKey = Deno.env.get("PROFILARR_API_KEY") || null;
        if (profilarrApiKey !== null && profilarrApiKey.length < 32) throw new Error(`PROFILARR_API_KEY must be at least 32 characters long`);
        this.profilarrApiKey = profilarrApiKey;
        this.oidc = {
          discoveryUrl: Deno.env.get("OIDC_DISCOVERY_URL") || null,
          clientId: Deno.env.get("OIDC_CLIENT_ID") || null,
          clientSecret: Deno.env.get("OIDC_CLIENT_SECRET") || null
        };
        this.bulletinUrl = (Deno.env.get("PROFILARR_BULLETIN_URL") || "https://raw.githubusercontent.com/Dictionarry-Hub/bulletin/main").replace(/\/+$/, "");
      }
      /**
      * Get the server URL for display
      */
      get serverUrl() {
        return `http://${this.host === "0.0.0.0" ? "localhost" : this.host}:${this.port}`;
      }
      /**
      * Initialize the configuration (create directories)
      * Must be called before using the config
      */
      async init() {
        await Deno.mkdir(this.paths.logs, { recursive: true });
        await Deno.mkdir(this.paths.data, { recursive: true });
        await Deno.mkdir(this.paths.backups, { recursive: true });
        await Deno.mkdir(this.paths.databases, { recursive: true });
      }
      /**
      * Set the base path for the application
      */
      setBasePath(path) {
        this.basePath = path;
      }
      /**
      * Application paths (relative to base)
      */
      paths = {
        get base() {
          return config.basePath;
        },
        get logs() {
          return `${config.basePath}/logs`;
        },
        get logFile() {
          return `${config.basePath}/logs/app.log`;
        },
        get data() {
          return `${config.basePath}/data`;
        },
        get database() {
          return `${config.basePath}/data/profilarr.db`;
        },
        get databases() {
          return `${config.basePath}/data/databases`;
        },
        get backups() {
          return `${config.basePath}/backups`;
        }
      };
    };
    config = new Config();
  }
});

// dist/build/server/chunks/db.js
function assertArg$3(url) {
  url = url instanceof URL ? url : new URL(url);
  if (url.protocol !== "file:") throw new TypeError("Must be a file URL.");
  return url;
}
function fromFileUrl$5(url) {
  url = assertArg$3(url);
  let path = decodeURIComponent(url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25")).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\");
  if (url.hostname !== "") path = `\\\\${url.hostname}${path}`;
  return path;
}
function fromFileUrl$4(url) {
  url = assertArg$3(url);
  return decodeURIComponent(url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25"));
}
function fromFileUrl$3(url) {
  return isWindows$1 ? fromFileUrl$5(url) : fromFileUrl$4(url);
}
function checkWindows() {
  const global = globalThis;
  const platform = global.process?.platform;
  if (typeof platform === "string") return platform.startsWith("win");
  const os = global.Deno?.build?.os;
  if (typeof os === "string") return os === "windows";
  return global.navigator?.platform?.startsWith("Win") ?? false;
}
function assertPath(path) {
  if (typeof path !== "string") throw new TypeError(`Path must be a string, received "${JSON.stringify(path)}"`);
}
function assertArg$2(url) {
  url = url instanceof URL ? url : new URL(url);
  if (url.protocol !== "file:") throw new TypeError(`URL must be a file URL: received "${url.protocol}"`);
  return url;
}
function fromFileUrl$2(url) {
  url = assertArg$2(url);
  return decodeURIComponent(url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25"));
}
function stripTrailingSeparators(segment, isSep) {
  if (segment.length <= 1) return segment;
  let end = segment.length;
  for (let i = segment.length - 1; i > 0; i--) if (isSep(segment.charCodeAt(i))) end = i;
  else break;
  return segment.slice(0, end);
}
function isPosixPathSeparator$1(code3) {
  return code3 === 47;
}
function isPosixPathSeparator(code3) {
  return code3 === 47;
}
function isPathSeparator(code3) {
  return code3 === 47 || code3 === 92;
}
function isWindowsDeviceRoot(code3) {
  return code3 >= 97 && code3 <= 122 || code3 >= 65 && code3 <= 90;
}
function fromFileUrl$1(url) {
  url = assertArg$2(url);
  let path = decodeURIComponent(url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25")).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\");
  if (url.hostname !== "") path = `\\\\${url.hostname}${path}`;
  return path;
}
function assertArg$1(path) {
  assertPath(path);
  if (path.length === 0) return ".";
}
function dirname$2(path) {
  if (path instanceof URL) path = fromFileUrl$2(path);
  assertArg$1(path);
  let end = -1;
  let matchedNonSeparator = false;
  for (let i = path.length - 1; i >= 1; --i) if (isPosixPathSeparator$1(path.charCodeAt(i))) {
    if (matchedNonSeparator) {
      end = i;
      break;
    }
  } else matchedNonSeparator = true;
  if (end === -1) return isPosixPathSeparator$1(path.charCodeAt(0)) ? "/" : ".";
  return stripTrailingSeparators(path.slice(0, end), isPosixPathSeparator$1);
}
function dirname$1(path) {
  if (path instanceof URL) path = fromFileUrl$1(path);
  assertArg$1(path);
  const len = path.length;
  let rootEnd = -1;
  let end = -1;
  let matchedSlash = true;
  let offset = 0;
  const code3 = path.charCodeAt(0);
  if (len > 1) {
    if (isPathSeparator(code3)) {
      rootEnd = offset = 1;
      if (isPathSeparator(path.charCodeAt(1))) {
        let j2 = 2;
        let last = j2;
        for (; j2 < len; ++j2) if (isPathSeparator(path.charCodeAt(j2))) break;
        if (j2 < len && j2 !== last) {
          last = j2;
          for (; j2 < len; ++j2) if (!isPathSeparator(path.charCodeAt(j2))) break;
          if (j2 < len && j2 !== last) {
            last = j2;
            for (; j2 < len; ++j2) if (isPathSeparator(path.charCodeAt(j2))) break;
            if (j2 === len) return path;
            if (j2 !== last) rootEnd = offset = j2 + 1;
          }
        }
      }
    } else if (isWindowsDeviceRoot(code3)) {
      if (path.charCodeAt(1) === 58) {
        rootEnd = offset = 2;
        if (len > 2) {
          if (isPathSeparator(path.charCodeAt(2))) rootEnd = offset = 3;
        }
      }
    }
  } else if (isPathSeparator(code3)) return path;
  for (let i = len - 1; i >= offset; --i) if (isPathSeparator(path.charCodeAt(i))) {
    if (!matchedSlash) {
      end = i;
      break;
    }
  } else matchedSlash = false;
  if (end === -1) if (rootEnd === -1) return ".";
  else end = rootEnd;
  return stripTrailingSeparators(path.slice(0, end), isPosixPathSeparator);
}
function dirname(path) {
  return isWindows ? dirname$1(path) : dirname$2(path);
}
function extname$2(path) {
  if (path instanceof URL) path = fromFileUrl$2(path);
  assertPath(path);
  let startDot = -1;
  let startPart = 0;
  let end = -1;
  let matchedSlash = true;
  let preDotState = 0;
  for (let i = path.length - 1; i >= 0; --i) {
    const code3 = path.charCodeAt(i);
    if (isPosixPathSeparator$1(code3)) {
      if (!matchedSlash) {
        startPart = i + 1;
        break;
      }
      continue;
    }
    if (end === -1) {
      matchedSlash = false;
      end = i + 1;
    }
    if (code3 === 46) {
      if (startDot === -1) startDot = i;
      else if (preDotState !== 1) preDotState = 1;
    } else if (startDot !== -1) preDotState = -1;
  }
  if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) return "";
  return path.slice(startDot, end);
}
function extname$1(path) {
  if (path instanceof URL) path = fromFileUrl$1(path);
  assertPath(path);
  let start = 0;
  let startDot = -1;
  let startPart = 0;
  let end = -1;
  let matchedSlash = true;
  let preDotState = 0;
  if (path.length >= 2 && path.charCodeAt(1) === 58 && isWindowsDeviceRoot(path.charCodeAt(0))) start = startPart = 2;
  for (let i = path.length - 1; i >= start; --i) {
    const code3 = path.charCodeAt(i);
    if (isPathSeparator(code3)) {
      if (!matchedSlash) {
        startPart = i + 1;
        break;
      }
      continue;
    }
    if (end === -1) {
      matchedSlash = false;
      end = i + 1;
    }
    if (code3 === 46) {
      if (startDot === -1) startDot = i;
      else if (preDotState !== 1) preDotState = 1;
    } else if (startDot !== -1) preDotState = -1;
  }
  if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) return "";
  return path.slice(startDot, end);
}
function extname(path) {
  return isWindows ? extname$1(path) : extname$2(path);
}
function fromFileUrl(url) {
  return isWindows ? fromFileUrl$1(url) : fromFileUrl$2(url);
}
function isAbsolute$2(path) {
  assertPath(path);
  return path.length > 0 && isPosixPathSeparator$1(path.charCodeAt(0));
}
function isAbsolute$1(path) {
  assertPath(path);
  const len = path.length;
  if (len === 0) return false;
  const code3 = path.charCodeAt(0);
  if (isPathSeparator(code3)) return true;
  else if (isWindowsDeviceRoot(code3)) {
    if (len > 2 && path.charCodeAt(1) === 58) {
      if (isPathSeparator(path.charCodeAt(2))) return true;
    }
  }
  return false;
}
function isAbsolute(path) {
  return isWindows ? isAbsolute$1(path) : isAbsolute$2(path);
}
function assertArg(path) {
  assertPath(path);
  if (path.length === 0) return ".";
}
function normalizeString(path, allowAboveRoot, separator, isPathSeparator3) {
  let res = "";
  let lastSegmentLength = 0;
  let lastSlash = -1;
  let dots = 0;
  let code3;
  for (let i = 0; i <= path.length; ++i) {
    if (i < path.length) code3 = path.charCodeAt(i);
    else if (isPathSeparator3(code3)) break;
    else code3 = 47;
    if (isPathSeparator3(code3)) {
      if (lastSlash === i - 1 || dots === 1) {
      } else if (lastSlash !== i - 1 && dots === 2) {
        if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
          if (res.length > 2) {
            const lastSlashIndex = res.lastIndexOf(separator);
            if (lastSlashIndex === -1) {
              res = "";
              lastSegmentLength = 0;
            } else {
              res = res.slice(0, lastSlashIndex);
              lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);
            }
            lastSlash = i;
            dots = 0;
            continue;
          } else if (res.length === 2 || res.length === 1) {
            res = "";
            lastSegmentLength = 0;
            lastSlash = i;
            dots = 0;
            continue;
          }
        }
        if (allowAboveRoot) {
          if (res.length > 0) res += `${separator}..`;
          else res = "..";
          lastSegmentLength = 2;
        }
      } else {
        if (res.length > 0) res += separator + path.slice(lastSlash + 1, i);
        else res = path.slice(lastSlash + 1, i);
        lastSegmentLength = i - lastSlash - 1;
      }
      lastSlash = i;
      dots = 0;
    } else if (code3 === 46 && dots !== -1) ++dots;
    else dots = -1;
  }
  return res;
}
function normalize$2(path) {
  if (path instanceof URL) path = fromFileUrl$2(path);
  assertArg(path);
  const isAbsolute4 = isPosixPathSeparator$1(path.charCodeAt(0));
  const trailingSeparator = isPosixPathSeparator$1(path.charCodeAt(path.length - 1));
  path = normalizeString(path, !isAbsolute4, "/", isPosixPathSeparator$1);
  if (path.length === 0 && !isAbsolute4) path = ".";
  if (path.length > 0 && trailingSeparator) path += "/";
  if (isAbsolute4) return `/${path}`;
  return path;
}
function join$2(path, ...paths) {
  if (path === void 0) return ".";
  if (path instanceof URL) path = fromFileUrl$2(path);
  paths = path ? [path, ...paths] : paths;
  paths.forEach((path2) => assertPath(path2));
  const joined = paths.filter((path2) => path2.length > 0).join("/");
  return joined === "" ? "." : normalize$2(joined);
}
function normalize$1(path) {
  if (path instanceof URL) path = fromFileUrl$1(path);
  assertArg(path);
  const len = path.length;
  let rootEnd = 0;
  let device;
  let isAbsolute4 = false;
  const code3 = path.charCodeAt(0);
  if (len > 1) {
    if (isPathSeparator(code3)) {
      isAbsolute4 = true;
      if (isPathSeparator(path.charCodeAt(1))) {
        let j2 = 2;
        let last = j2;
        for (; j2 < len; ++j2) if (isPathSeparator(path.charCodeAt(j2))) break;
        if (j2 < len && j2 !== last) {
          const firstPart = path.slice(last, j2);
          last = j2;
          for (; j2 < len; ++j2) if (!isPathSeparator(path.charCodeAt(j2))) break;
          if (j2 < len && j2 !== last) {
            last = j2;
            for (; j2 < len; ++j2) if (isPathSeparator(path.charCodeAt(j2))) break;
            if (j2 === len) return `\\\\${firstPart}\\${path.slice(last)}\\`;
            else if (j2 !== last) {
              device = `\\\\${firstPart}\\${path.slice(last, j2)}`;
              rootEnd = j2;
            }
          }
        }
      } else rootEnd = 1;
    } else if (isWindowsDeviceRoot(code3)) {
      if (path.charCodeAt(1) === 58) {
        device = path.slice(0, 2);
        rootEnd = 2;
        if (len > 2) {
          if (isPathSeparator(path.charCodeAt(2))) {
            isAbsolute4 = true;
            rootEnd = 3;
          }
        }
      }
    }
  } else if (isPathSeparator(code3)) return "\\";
  let tail;
  if (rootEnd < len) tail = normalizeString(path.slice(rootEnd), !isAbsolute4, "\\", isPathSeparator);
  else tail = "";
  if (tail.length === 0 && !isAbsolute4) tail = ".";
  if (tail.length > 0 && isPathSeparator(path.charCodeAt(len - 1))) tail += "\\";
  if (device === void 0) {
    if (isAbsolute4) if (tail.length > 0) return `\\${tail}`;
    else return "\\";
    return tail;
  } else if (isAbsolute4) if (tail.length > 0) return `${device}\\${tail}`;
  else return `${device}\\`;
  return device + tail;
}
function join$1(path, ...paths) {
  if (path instanceof URL) path = fromFileUrl$1(path);
  paths = path ? [path, ...paths] : paths;
  paths.forEach((path2) => assertPath(path2));
  paths = paths.filter((path2) => path2.length > 0);
  if (paths.length === 0) return ".";
  let needsReplace = true;
  let slashCount = 0;
  const firstPart = paths[0];
  if (isPathSeparator(firstPart.charCodeAt(0))) {
    ++slashCount;
    const firstLen = firstPart.length;
    if (firstLen > 1) {
      if (isPathSeparator(firstPart.charCodeAt(1))) {
        ++slashCount;
        if (firstLen > 2) if (isPathSeparator(firstPart.charCodeAt(2))) ++slashCount;
        else needsReplace = false;
      }
    }
  }
  let joined = paths.join("\\");
  if (needsReplace) {
    for (; slashCount < joined.length; ++slashCount) if (!isPathSeparator(joined.charCodeAt(slashCount))) break;
    if (slashCount >= 2) joined = `\\${joined.slice(slashCount)}`;
  }
  return normalize$1(joined);
}
function join(path, ...paths) {
  return isWindows ? join$1(path, ...paths) : join$2(path, ...paths);
}
function normalize(path) {
  return isWindows ? normalize$1(path) : normalize$2(path);
}
function cwd(errorMessage) {
  const global = globalThis;
  const getCwd = global.process?.cwd ?? global.Deno?.cwd;
  if (typeof getCwd !== "function") throw new TypeError(errorMessage);
  return getCwd();
}
function resolve$2(...pathSegments) {
  let resolvedPath = "";
  let resolvedAbsolute = false;
  for (let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
    let path;
    if (i >= 0) path = pathSegments[i];
    else path = cwd("Resolved a relative path without a current working directory (CWD)");
    assertPath(path);
    if (path.length === 0) continue;
    resolvedPath = `${path}/${resolvedPath}`;
    resolvedAbsolute = isPosixPathSeparator$1(path.charCodeAt(0));
  }
  resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, "/", isPosixPathSeparator$1);
  if (resolvedAbsolute) if (resolvedPath.length > 0) return `/${resolvedPath}`;
  else return "/";
  else if (resolvedPath.length > 0) return resolvedPath;
  else return ".";
}
function resolve$1(...pathSegments) {
  let resolvedDevice = "";
  let resolvedTail = "";
  let resolvedAbsolute = false;
  for (let i = pathSegments.length - 1; i >= -1; i--) {
    let path;
    if (i >= 0) path = pathSegments[i];
    else if (!resolvedDevice) path = cwd("Resolved a drive-letter-less path without a current working directory (CWD)");
    else {
      path = cwd("Resolved a relative path without a current working directory (CWD)");
      if (path === void 0 || path.slice(0, 3).toLowerCase() !== `${resolvedDevice.toLowerCase()}\\`) path = `${resolvedDevice}\\`;
    }
    assertPath(path);
    const len = path.length;
    if (len === 0) continue;
    let rootEnd = 0;
    let device = "";
    let isAbsolute4 = false;
    const code3 = path.charCodeAt(0);
    if (len > 1) {
      if (isPathSeparator(code3)) {
        isAbsolute4 = true;
        if (isPathSeparator(path.charCodeAt(1))) {
          let j2 = 2;
          let last = j2;
          for (; j2 < len; ++j2) if (isPathSeparator(path.charCodeAt(j2))) break;
          if (j2 < len && j2 !== last) {
            const firstPart = path.slice(last, j2);
            last = j2;
            for (; j2 < len; ++j2) if (!isPathSeparator(path.charCodeAt(j2))) break;
            if (j2 < len && j2 !== last) {
              last = j2;
              for (; j2 < len; ++j2) if (isPathSeparator(path.charCodeAt(j2))) break;
              if (j2 === len) {
                device = `\\\\${firstPart}\\${path.slice(last)}`;
                rootEnd = j2;
              } else if (j2 !== last) {
                device = `\\\\${firstPart}\\${path.slice(last, j2)}`;
                rootEnd = j2;
              }
            }
          }
        } else rootEnd = 1;
      } else if (isWindowsDeviceRoot(code3)) {
        if (path.charCodeAt(1) === 58) {
          device = path.slice(0, 2);
          rootEnd = 2;
          if (len > 2) {
            if (isPathSeparator(path.charCodeAt(2))) {
              isAbsolute4 = true;
              rootEnd = 3;
            }
          }
        }
      }
    } else if (isPathSeparator(code3)) {
      rootEnd = 1;
      isAbsolute4 = true;
    }
    if (device.length > 0 && resolvedDevice.length > 0 && device.toLowerCase() !== resolvedDevice.toLowerCase()) continue;
    if (resolvedDevice.length === 0 && device.length > 0) resolvedDevice = device;
    if (!resolvedAbsolute) {
      resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`;
      resolvedAbsolute = isAbsolute4;
    }
    if (resolvedAbsolute && resolvedDevice.length > 0) break;
  }
  resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, "\\", isPathSeparator);
  return resolvedDevice + (resolvedAbsolute ? "\\" : "") + resolvedTail || ".";
}
function resolve(...pathSegments) {
  return isWindows ? resolve$1(...pathSegments) : resolve$2(...pathSegments);
}
function encodeWhitespace(string) {
  return string.replaceAll(/[\s]/g, (c2) => {
    return WHITESPACE_ENCODINGS[c2] ?? c2;
  });
}
function toFileUrl$2(path) {
  if (!isAbsolute$2(path)) throw new TypeError(`Path must be absolute: received "${path}"`);
  const url = new URL("file:///");
  url.pathname = encodeWhitespace(path.replace(/%/g, "%25").replace(/\\/g, "%5C"));
  return url;
}
function toFileUrl$1(path) {
  if (!isAbsolute$1(path)) throw new TypeError(`Path must be absolute: received "${path}"`);
  const [, hostname, pathname] = path.match(/^(?:[/\\]{2}([^/\\]+)(?=[/\\](?:[^/\\]|$)))?(.*)/);
  const url = new URL("file:///");
  url.pathname = encodeWhitespace(pathname.replace(/%/g, "%25"));
  if (hostname !== void 0 && hostname !== "localhost") {
    url.hostname = hostname;
    if (!url.hostname) throw new TypeError(`Invalid hostname: "${url.hostname}"`);
  }
  return url;
}
function toFileUrl(path) {
  return isWindows ? toFileUrl$1(path) : toFileUrl$2(path);
}
function getFileInfoType(fileInfo) {
  return fileInfo.isFile ? "file" : fileInfo.isDirectory ? "dir" : fileInfo.isSymlink ? "symlink" : void 0;
}
async function ensureDir(dir) {
  try {
    throwIfNotDirectory(await Deno.stat(dir));
    return;
  } catch (err) {
    if (!(err instanceof Deno.errors.NotFound)) throw err;
  }
  try {
    await Deno.mkdir(dir, { recursive: true });
  } catch (err) {
    if (!(err instanceof Deno.errors.AlreadyExists)) throw err;
    throwIfNotDirectory(await Deno.stat(dir));
  }
}
function throwIfNotDirectory(fileInfo) {
  if (!fileInfo.isDirectory) throw new Error(`Failed to ensure directory exists: expected 'dir', got '${getFileInfoType(fileInfo)}'`);
}
function code(open, close) {
  return {
    open: `\x1B[${open.join(";")}m`,
    close: `\x1B[${close}m`,
    regexp: new RegExp(`\\x1b\\[${close}m`, "g")
  };
}
function run3(str2, code3) {
  return enabled ? `${code3.open}${str2.replace(code3.regexp, code3.open)}${code3.close}` : str2;
}
function green(str2) {
  return run3(str2, code([32], 39));
}
function calcSizeHex(originalSize) {
  return originalSize * 2;
}
function encode2(buffer2, i, o, alphabet3) {
  for (; i < buffer2.length; ++i) {
    const x3 = buffer2[i];
    buffer2[o++] = alphabet3[x3 >> 4];
    buffer2[o++] = alphabet3[x3 & 15];
  }
  return o;
}
function detach(buffer2, maxSize) {
  const originalSize = buffer2.length;
  if (buffer2.byteOffset) {
    const b3 = new Uint8Array(buffer2.buffer);
    b3.set(buffer2);
    buffer2 = b3.subarray(0, originalSize);
  }
  buffer2 = new Uint8Array(buffer2.buffer.transfer(maxSize));
  buffer2.set(buffer2.subarray(0, originalSize), maxSize - originalSize);
  return [buffer2, maxSize - originalSize];
}
function encodeHex(src) {
  if (typeof src === "string") src = new TextEncoder().encode(src);
  else if (src instanceof ArrayBuffer) src = new Uint8Array(src).slice();
  else src = src.slice();
  const [output, i] = detach(src, calcSizeHex(src.length));
  encode2(output, i, 0, alphabet);
  return new TextDecoder().decode(output);
}
function baseUrlToFilename(url) {
  const out = [];
  const protocol2 = url.protocol.replace(":", "");
  out.push(protocol2);
  switch (protocol2) {
    case "http":
    case "https": {
      const host = url.hostname;
      const hostPort = url.port;
      out.push(hostPort ? `${host}_PORT${hostPort}` : host);
      break;
    }
    case "file":
    case "data":
    case "blob":
      break;
    default:
      throw new TypeError(`Don't know how to create cache name for protocol: ${protocol2}`);
  }
  return join(...out);
}
function stringToURL(url) {
  return url.startsWith("file://") || url.startsWith("http://") || url.startsWith("https://") ? new URL(url) : toFileUrl(resolve(url));
}
async function hash(value2) {
  return encodeHex(new Uint8Array(await crypto.subtle.digest("SHA-256", encoder$1.encode(value2))));
}
async function urlToFilename(url) {
  return join(baseUrlToFilename(url), await hash(url.pathname + url.search));
}
async function isFile(filePath) {
  try {
    return (await Deno.lstat(filePath)).isFile;
  } catch (err) {
    if (err instanceof Deno.errors.NotFound) return false;
    throw err;
  }
}
function homeDir() {
  switch (Deno.build.os) {
    case "windows":
      return Deno.env.get("USERPROFILE");
    case "linux":
    case "darwin":
    case "freebsd":
    case "netbsd":
    case "aix":
    case "solaris":
    case "illumos":
    case "android":
      return Deno.env.get("HOME");
    default:
      throw Error("unreachable");
  }
}
function cacheDir() {
  if (Deno.build.os === "darwin") {
    const home = homeDir();
    if (home) return join(home, "Library/Caches");
  } else if (Deno.build.os === "windows") return Deno.env.get("LOCALAPPDATA");
  else {
    const cacheHome = Deno.env.get("XDG_CACHE_HOME");
    if (cacheHome) return cacheHome;
    else {
      const home = homeDir();
      if (home) return join(home, ".cache");
    }
  }
}
function denoCacheDir() {
  const dd = Deno.env.get("DENO_DIR");
  let root;
  if (dd) root = normalize(isAbsolute(dd) ? dd : join(Deno.cwd(), dd));
  else {
    const cd = cacheDir();
    if (cd) root = join(cd, "deno");
    else {
      const hd = homeDir();
      if (hd) root = join(hd, ".deno");
    }
  }
  return root;
}
function getCrossOption(record) {
  if (record === void 0) return;
  if (ALL_OSS.some((os) => os in record)) {
    const subrecord = record[Deno.build.os];
    if (subrecord && typeof subrecord === "object" && ALL_ARCHS.some((arch) => arch in subrecord)) return subrecord[Deno.build.arch];
    else return subrecord;
  }
  if (ALL_ARCHS.some((arch) => arch in record)) {
    const subrecord = record[Deno.build.arch];
    if (subrecord && typeof subrecord === "object" && ALL_OSS.some((os) => os in subrecord)) return subrecord[Deno.build.os];
    else return subrecord;
  }
}
function createDownloadURL(options2) {
  if (typeof options2 === "string" || options2 instanceof URL) options2 = { url: options2 };
  options2.extensions ??= defaultExtensions;
  options2.prefixes ??= defaultPrefixes;
  for (const key2 in options2.extensions) {
    const os = key2;
    if (options2.extensions[os] !== void 0) options2.extensions[os] = options2.extensions[os].replace(/\.?(.+)/, "$1");
  }
  let url;
  if (options2.url instanceof URL) url = options2.url;
  else if (typeof options2.url === "string") url = stringToURL(options2.url);
  else {
    const tmpUrl = getCrossOption(options2.url);
    if (tmpUrl === void 0) throw new TypeError(`An URL for the "${Deno.build.os}-${Deno.build.arch}" target was not provided.`);
    if (typeof tmpUrl === "string") url = stringToURL(tmpUrl);
    else url = tmpUrl;
  }
  if ("name" in options2 && !Object.values(options2.extensions).includes(extname(url.pathname))) {
    if (!url.pathname.endsWith("/")) url.pathname = `${url.pathname}/`;
    const prefix = getCrossOption(options2.prefixes) ?? "";
    const suffix = getCrossOption(options2.suffixes) ?? "";
    const extension = options2.extensions[Deno.build.os];
    if (options2.name === void 0) throw new TypeError(`Expected the "name" property for an automatically assembled URL.`);
    const filename = `${prefix}${options2.name}${suffix}.${extension}`;
    url = new URL(filename, url);
  }
  return url;
}
async function ensureCacheLocation(location = "deno") {
  if (location === "deno") {
    const dir = denoCacheDir();
    if (dir === void 0) throw new Error("Could not get the deno cache directory, try using another CacheLocation in the plug options.");
    location = join(dir, "plug");
  } else if (location === "cache") {
    const dir = cacheDir();
    if (dir === void 0) throw new Error("Could not get the cache directory, try using another CacheLocation in the plug options.");
    location = join(dir, "plug");
  } else if (location === "cwd") location = join(Deno.cwd(), "plug");
  else if (location === "tmp") location = await Deno.makeTempDir({ prefix: "plug" });
  else if (typeof location === "string" && location.startsWith("file://")) location = fromFileUrl(location);
  else if (location instanceof URL) {
    if (location?.protocol !== "file:") throw new TypeError("Cannot use any other protocol than file:// for an URL cache location.");
    location = fromFileUrl(location);
  }
  location = resolve(normalize(location));
  await ensureDir(location);
  return location;
}
async function download(options2) {
  const location = (typeof options2 === "object" && "location" in options2 ? options2.location : void 0) ?? "deno";
  const setting = (typeof options2 === "object" && "cache" in options2 ? options2.cache : void 0) ?? "use";
  const url = createDownloadURL(options2);
  const cacheBasePath = join(await ensureCacheLocation(location), await urlToFilename(url));
  const cacheFilePath = `${cacheBasePath}${extname(url.pathname)}`;
  const cacheMetaPath = `${cacheBasePath}.metadata.json`;
  const cached2 = setting === "use" ? await isFile(cacheFilePath) : setting === "only" || setting !== "reloadAll";
  await ensureDir(dirname(cacheBasePath));
  if (!cached2) {
    const meta = { url };
    switch (url.protocol) {
      case "http:":
      case "https:": {
        console.log(`${green("Downloading")} ${url}`);
        const response = await fetch(url.toString());
        if (!response.ok) if (response.status === 404) throw new Error(`Could not find ${url}`);
        else throw new Deno.errors.Http(`${response.status} ${response.statusText}`);
        await Deno.writeFile(cacheFilePath, new Uint8Array(await response.arrayBuffer()));
        break;
      }
      case "file:":
        console.log(`${green("Copying")} ${url}`);
        await Deno.copyFile(fromFileUrl(url), cacheFilePath);
        if (Deno.build.os !== "windows") await Deno.chmod(cacheFilePath, 420);
        break;
      default:
        throw new TypeError(`Cannot fetch to cache using the "${url.protocol}" protocol`);
    }
    await Deno.writeTextFile(cacheMetaPath, JSON.stringify(meta));
  }
  if (!await isFile(cacheFilePath)) throw new Error(`Could not find "${url}" in cache.`);
  return cacheFilePath;
}
async function dlopen(options2, symbols3) {
  if (Deno.dlopen === void 0) throw new Error("`--unstable-ffi` is required");
  return Deno.dlopen(await download(options2), symbols3);
}
function tryGetEnv(key2) {
  try {
    return Deno.env.get(key2);
  } catch (e) {
    if (e instanceof Deno.errors.PermissionDenied) return;
    throw e;
  }
}
function toCString(str2) {
  return encoder.encode(str2 + "\0");
}
function unwrap(code3, db2) {
  if (code3 === 0 || code3 === 101) return;
  if (code3 === 21) throw new SqliteError(code3, "SQLite3 API misuse");
  else if (db2 !== void 0) {
    const errmsg = sqlite3_errmsg(db2);
    if (errmsg === null) throw new SqliteError(code3);
    throw new Error(Deno.UnsafePointerView.getCString(errmsg));
  } else throw new SqliteError(code3, Deno.UnsafePointerView.getCString(sqlite3_errstr(code3)));
}
function getColumn(handle2, i, int64) {
  const ty = sqlite3_column_type(handle2, i);
  if (ty === 1 && !int64) return sqlite3_column_int(handle2, i);
  switch (ty) {
    case 3: {
      const ptr = sqlite3_column_text(handle2, i);
      if (ptr === null) return null;
      const text2 = readCstr(ptr, 0);
      if (sqlite3_value_subtype(sqlite3_column_value(handle2, i)) === JSON_SUBTYPE) try {
        return JSON.parse(text2);
      } catch (_error2) {
        return text2;
      }
      return text2;
    }
    case 1: {
      const val = sqlite3_column_int64(handle2, i);
      if (val < -BIG_MAX$1 || val > BIG_MAX$1) return val;
      return Number(val);
    }
    case 2:
      return sqlite3_column_double(handle2, i);
    case 4: {
      const ptr = sqlite3_column_blob(handle2, i);
      if (ptr === null) return /* @__PURE__ */ new Uint8Array();
      const bytes = sqlite3_column_bytes(handle2, i);
      return new Uint8Array(Deno.UnsafePointerView.getArrayBuffer(ptr, bytes).slice(0));
    }
    default:
      return null;
  }
}
var deno_default, isWindows$1, isWindows, WHITESPACE_ENCODINGS, Deno$1, enabled, alphabet$1, rAlphabet$1, alphabet, rAlphabet, encoder$1, ALL_ARCHS, ALL_OSS, defaultExtensions, defaultPrefixes, symbols, lib, init, ffi_default, sqlite3_errmsg, sqlite3_errstr, encoder, SqliteError, readCstr, _computedKey$2, _computedKey1$1, _computedKey2, sqlite3_prepare_v2, sqlite3_reset, sqlite3_clear_bindings, sqlite3_step, sqlite3_column_count, sqlite3_column_type, sqlite3_column_value, sqlite3_value_subtype, sqlite3_column_text, sqlite3_finalize$1, sqlite3_column_int64, sqlite3_column_double, sqlite3_column_blob, sqlite3_column_bytes, sqlite3_column_name, sqlite3_expanded_sql, sqlite3_bind_parameter_count, sqlite3_bind_int, sqlite3_bind_int64, sqlite3_bind_text, sqlite3_bind_blob, sqlite3_bind_double, sqlite3_bind_parameter_index, sqlite3_sql, sqlite3_stmt_readonly, sqlite3_bind_parameter_name, sqlite3_changes$1, sqlite3_column_int, STATEMENTS_TO_DB, emptyStringBuffer, statementFinalizer, JSON_SUBTYPE, BIG_MAX$1, Statement, _computedKey$1, _computedKey1, sqlite3_blob_open, sqlite3_blob_bytes, sqlite3_blob_close, sqlite3_blob_read, sqlite3_blob_write, SQLBlob, _computedKey, sqlite3_open_v2, sqlite3_close_v2, sqlite3_changes, sqlite3_total_changes, sqlite3_last_insert_rowid, sqlite3_get_autocommit, sqlite3_exec, sqlite3_free, sqlite3_libversion, sqlite3_sourceid, sqlite3_complete, sqlite3_finalize, sqlite3_result_blob, sqlite3_result_double, sqlite3_result_error, sqlite3_result_int64, sqlite3_result_null, sqlite3_result_text, sqlite3_value_blob, sqlite3_value_bytes, sqlite3_value_double, sqlite3_value_int64, sqlite3_value_text, sqlite3_value_type, sqlite3_create_function, sqlite3_result_int, sqlite3_aggregate_context, sqlite3_enable_load_extension, sqlite3_load_extension, sqlite3_backup_init, sqlite3_backup_step, sqlite3_backup_finish, sqlite3_errcode, BIG_MAX, Database, controllers, getController, wrapTransaction, colors, logSettingsQueries, LogSettingsManager, logSettings, Logger, settings, logger, DatabaseManager, db;
var init_db = __esm({
  async "dist/build/server/chunks/db.js"() {
    "use strict";
    init_config();
    deno_default = {
      name: "@db/sqlite",
      version: "0.12.0",
      github: "https://github.com/denodrivers/sqlite3",
      exports: "./mod.ts",
      exclude: ["sqlite", "scripts"],
      tasks: {
        "test": "deno test --unstable-ffi -A test/test.ts",
        "build": "deno run -A scripts/build.ts",
        "bench-deno": "deno run -A --unstable-ffi bench/bench_deno.js 50 1000000",
        "bench-deno-ffi": "deno run -A --unstable-ffi bench/bench_deno_ffi.js 50 1000000",
        "bench-deno-wasm": "deno run -A --unstable-ffi bench/bench_deno_wasm.js 50 1000000",
        "bench-node": "node bench/bench_node.js 50 1000000",
        "bench-bun": "bun run bench/bench_bun.js 50 1000000",
        "bench-bun-ffi": "bun run bench/bench_bun_ffi.js 50 1000000",
        "bench-c": "./bench/bench 50 1000000",
        "bench-python": "python ./bench/bench_python.py",
        "bench:northwind": "deno bench -A --unstable-ffi bench/northwind/deno.js",
        "bench-wasm:northwind": "deno run -A --unstable-ffi bench/northwind/deno_wasm.js",
        "bench-node:northwind": "node bench/northwind/node.mjs",
        "bench-bun:northwind": "bun run bench/northwind/bun.js"
      },
      fmt: { "exclude": ["sqlite"] },
      lint: { "rules": {
        "exclude": ["camelcase", "no-explicit-any"],
        "include": [
          "explicit-function-return-type",
          "eqeqeq",
          "explicit-module-boundary-types"
        ]
      } }
    };
    isWindows$1 = (() => {
      const { Deno: Deno2 } = globalThis;
      if (typeof Deno2?.build?.os === "string") return Deno2.build.os;
      const { navigator: navigator2 } = globalThis;
      if (navigator2?.appVersion?.includes?.("Win")) return "windows";
      return "linux";
    })() === "windows";
    isWindows = checkWindows();
    WHITESPACE_ENCODINGS = {
      "	": "%09",
      "\n": "%0A",
      "\v": "%0B",
      "\f": "%0C",
      "\r": "%0D",
      " ": "%20"
    };
    globalThis.Deno?.build.os;
    globalThis.Deno?.build.os;
    ({ Deno: Deno$1 } = globalThis);
    enabled = !(typeof Deno$1?.noColor === "boolean" ? Deno$1.noColor : false);
    new RegExp(["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TXZcf-nq-uy=><~]))"].join("|"), "g");
    alphabet$1 = new TextEncoder().encode("0123456789abcdef");
    rAlphabet$1 = (/* @__PURE__ */ new Uint8Array(128)).fill(16);
    alphabet$1.forEach((byte, i) => rAlphabet$1[byte] = i);
    new TextEncoder().encode("ABCDEF").forEach((byte, i) => rAlphabet$1[byte] = i + 10);
    alphabet = new TextEncoder().encode("0123456789abcdef");
    rAlphabet = (/* @__PURE__ */ new Uint8Array(128)).fill(16);
    alphabet.forEach((byte, i) => rAlphabet[byte] = i);
    new TextEncoder().encode("ABCDEF").forEach((byte, i) => rAlphabet[byte] = i + 10);
    encoder$1 = new TextEncoder();
    ALL_ARCHS = ["x86_64", "aarch64"];
    ALL_OSS = [
      "darwin",
      "linux",
      "android",
      "windows",
      "freebsd",
      "netbsd",
      "aix",
      "solaris",
      "illumos"
    ];
    defaultExtensions = {
      darwin: "dylib",
      linux: "so",
      windows: "dll",
      freebsd: "so",
      netbsd: "so",
      aix: "so",
      solaris: "so",
      illumos: "so",
      android: "so"
    };
    defaultPrefixes = {
      darwin: "lib",
      linux: "lib",
      netbsd: "lib",
      freebsd: "lib",
      aix: "lib",
      solaris: "lib",
      illumos: "lib",
      windows: "",
      android: "lib"
    };
    symbols = {
      sqlite3_open_v2: {
        parameters: [
          "buffer",
          "buffer",
          "i32",
          "pointer"
        ],
        result: "i32"
      },
      sqlite3_close_v2: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_changes: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_total_changes: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_last_insert_rowid: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_get_autocommit: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_prepare_v2: {
        parameters: [
          "pointer",
          "buffer",
          "i32",
          "buffer",
          "pointer"
        ],
        result: "i32"
      },
      sqlite3_reset: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_clear_bindings: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_step: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_column_count: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_column_type: {
        parameters: ["pointer", "i32"],
        result: "i32"
      },
      sqlite3_column_text: {
        parameters: ["pointer", "i32"],
        result: "pointer"
      },
      sqlite3_column_value: {
        parameters: ["pointer", "i32"],
        result: "pointer"
      },
      sqlite3_finalize: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_exec: {
        parameters: [
          "pointer",
          "buffer",
          "pointer",
          "pointer",
          "buffer"
        ],
        result: "i32"
      },
      sqlite3_free: {
        parameters: ["pointer"],
        result: "void"
      },
      sqlite3_column_int: {
        parameters: ["pointer", "i32"],
        result: "i32"
      },
      sqlite3_column_double: {
        parameters: ["pointer", "i32"],
        result: "f64"
      },
      sqlite3_column_blob: {
        parameters: ["pointer", "i32"],
        result: "pointer"
      },
      sqlite3_column_bytes: {
        parameters: ["pointer", "i32"],
        result: "i32"
      },
      sqlite3_column_name: {
        parameters: ["pointer", "i32"],
        result: "pointer"
      },
      sqlite3_column_decltype: {
        parameters: ["pointer", "i32"],
        result: "u64"
      },
      sqlite3_bind_parameter_index: {
        parameters: ["pointer", "buffer"],
        result: "i32"
      },
      sqlite3_bind_text: {
        parameters: [
          "pointer",
          "i32",
          "buffer",
          "i32",
          "pointer"
        ],
        result: "i32"
      },
      sqlite3_bind_blob: {
        parameters: [
          "pointer",
          "i32",
          "buffer",
          "i32",
          "pointer"
        ],
        result: "i32"
      },
      sqlite3_bind_double: {
        parameters: [
          "pointer",
          "i32",
          "f64"
        ],
        result: "i32"
      },
      sqlite3_bind_int: {
        parameters: [
          "pointer",
          "i32",
          "i32"
        ],
        result: "i32"
      },
      sqlite3_bind_int64: {
        parameters: [
          "pointer",
          "i32",
          "i64"
        ],
        result: "i32"
      },
      sqlite3_bind_null: {
        parameters: ["pointer", "i32"],
        result: "i32"
      },
      sqlite3_expanded_sql: {
        parameters: ["pointer"],
        result: "pointer"
      },
      sqlite3_bind_parameter_count: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_complete: {
        parameters: ["buffer"],
        result: "i32"
      },
      sqlite3_sourceid: {
        parameters: [],
        result: "pointer"
      },
      sqlite3_libversion: {
        parameters: [],
        result: "pointer"
      },
      sqlite3_blob_open: {
        parameters: [
          "pointer",
          "buffer",
          "buffer",
          "buffer",
          "i64",
          "i32",
          "buffer"
        ],
        result: "i32"
      },
      sqlite3_blob_read: {
        parameters: [
          "pointer",
          "buffer",
          "i32",
          "i32"
        ],
        result: "i32"
      },
      sqlite3_blob_write: {
        parameters: [
          "pointer",
          "buffer",
          "i32",
          "i32"
        ],
        result: "i32"
      },
      sqlite3_blob_bytes: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_blob_close: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_sql: {
        parameters: ["pointer"],
        result: "pointer"
      },
      sqlite3_stmt_readonly: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_bind_parameter_name: {
        parameters: ["pointer", "i32"],
        result: "pointer"
      },
      sqlite3_errcode: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_errmsg: {
        parameters: ["pointer"],
        result: "pointer"
      },
      sqlite3_errstr: {
        parameters: ["i32"],
        result: "pointer"
      },
      sqlite3_column_int64: {
        parameters: ["pointer", "i32"],
        result: "i64"
      },
      sqlite3_backup_init: {
        parameters: [
          "pointer",
          "buffer",
          "pointer",
          "buffer"
        ],
        result: "pointer"
      },
      sqlite3_backup_step: {
        parameters: ["pointer", "i32"],
        result: "i32"
      },
      sqlite3_backup_finish: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_backup_remaining: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_backup_pagecount: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_create_function: {
        parameters: [
          "pointer",
          "buffer",
          "i32",
          "i32",
          "pointer",
          "pointer",
          "pointer",
          "pointer"
        ],
        result: "i32",
        optional: true
      },
      sqlite3_result_blob: {
        parameters: [
          "pointer",
          "buffer",
          "i32",
          "isize"
        ],
        result: "void"
      },
      sqlite3_result_double: {
        parameters: ["pointer", "f64"],
        result: "void"
      },
      sqlite3_result_error: {
        parameters: [
          "pointer",
          "buffer",
          "i32"
        ],
        result: "void"
      },
      sqlite3_result_int: {
        parameters: ["pointer", "i32"],
        result: "void"
      },
      sqlite3_result_int64: {
        parameters: ["pointer", "i64"],
        result: "void"
      },
      sqlite3_result_null: {
        parameters: ["pointer"],
        result: "void"
      },
      sqlite3_result_text: {
        parameters: [
          "pointer",
          "buffer",
          "i32",
          "isize"
        ],
        result: "void"
      },
      sqlite3_value_type: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_value_subtype: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_value_blob: {
        parameters: ["pointer"],
        result: "pointer"
      },
      sqlite3_value_double: {
        parameters: ["pointer"],
        result: "f64"
      },
      sqlite3_value_int: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_value_int64: {
        parameters: ["pointer"],
        result: "i64"
      },
      sqlite3_value_text: {
        parameters: ["pointer"],
        result: "pointer"
      },
      sqlite3_value_bytes: {
        parameters: ["pointer"],
        result: "i32"
      },
      sqlite3_aggregate_context: {
        parameters: ["pointer", "i32"],
        result: "pointer",
        optional: true
      },
      sqlite3_enable_load_extension: {
        parameters: ["pointer", "i32"],
        result: "i32",
        optional: true
      },
      sqlite3_load_extension: {
        parameters: [
          "pointer",
          "buffer",
          "buffer",
          "buffer"
        ],
        result: "i32",
        optional: true
      },
      sqlite3_initialize: {
        parameters: [],
        result: "i32"
      }
    };
    try {
      const customPath = tryGetEnv("DENO_SQLITE_PATH");
      if (tryGetEnv("DENO_SQLITE_LOCAL") === "1") lib = Deno.dlopen(new URL(`../build/${Deno.build.os === "windows" ? "" : "lib"}sqlite3${Deno.build.arch !== "x86_64" ? `_${Deno.build.arch}` : ""}.${Deno.build.os === "windows" ? "dll" : Deno.build.os === "darwin" ? "dylib" : "so"}`, import.meta.url), symbols).symbols;
      else if (customPath) lib = Deno.dlopen(customPath, symbols).symbols;
      else lib = (await dlopen({
        name: "sqlite3",
        url: `${deno_default.github}/releases/download/${deno_default.version}/`,
        suffixes: { aarch64: "_aarch64" }
      }, symbols)).symbols;
    } catch (e) {
      if (e instanceof Deno.errors.PermissionDenied) throw e;
      throw new Error("Failed to load SQLite3 Dynamic Library", { cause: e });
    }
    init = lib.sqlite3_initialize();
    if (init !== 0) throw new Error(`Failed to initialize SQLite3: ${init}`);
    ffi_default = lib;
    ({ sqlite3_errmsg, sqlite3_errstr } = ffi_default);
    encoder = new TextEncoder();
    SqliteError = class extends Error {
      code;
      name;
      constructor(code3 = 1, message2 = "Unknown Error") {
        super(`${code3}: ${message2}`);
        this.code = code3;
        this.name = "SqliteError";
      }
    };
    Deno.UnsafePointerView.getArrayBuffer;
    readCstr = Deno.UnsafePointerView.getCString;
    ({ sqlite3_prepare_v2, sqlite3_reset, sqlite3_clear_bindings, sqlite3_step, sqlite3_column_count, sqlite3_column_type, sqlite3_column_value, sqlite3_value_subtype, sqlite3_column_text, sqlite3_finalize: sqlite3_finalize$1, sqlite3_column_int64, sqlite3_column_double, sqlite3_column_blob, sqlite3_column_bytes, sqlite3_column_name, sqlite3_expanded_sql, sqlite3_bind_parameter_count, sqlite3_bind_int, sqlite3_bind_int64, sqlite3_bind_text, sqlite3_bind_blob, sqlite3_bind_double, sqlite3_bind_parameter_index, sqlite3_sql, sqlite3_stmt_readonly, sqlite3_bind_parameter_name, sqlite3_changes: sqlite3_changes$1, sqlite3_column_int } = ffi_default);
    STATEMENTS_TO_DB = /* @__PURE__ */ new Map();
    emptyStringBuffer = /* @__PURE__ */ new Uint8Array(1);
    statementFinalizer = new FinalizationRegistry((ptr) => {
      if (STATEMENTS_TO_DB.has(ptr)) {
        sqlite3_finalize$1(ptr);
        STATEMENTS_TO_DB.delete(ptr);
      }
    });
    JSON_SUBTYPE = 74;
    BIG_MAX$1 = BigInt(Number.MAX_SAFE_INTEGER);
    _computedKey$2 = Symbol.iterator, _computedKey1$1 = Symbol.dispose, _computedKey2 = /* @__PURE__ */ Symbol.for("Deno.customInspect");
    Statement = class {
      db;
      #handle;
      #finalizerToken;
      #bound;
      #hasNoArgs;
      #unsafeConcurrency;
      /**
      * Whether the query might call into JavaScript or not.
      *
      * Must enable if the query makes use of user defined functions,
      * otherwise there can be V8 crashes.
      *
      * Off by default. Causes performance degradation.
      */
      callback;
      /** Unsafe Raw (pointer) to the sqlite object */
      get unsafeHandle() {
        return this.#handle;
      }
      /** SQL string including bindings */
      get expandedSql() {
        return readCstr(sqlite3_expanded_sql(this.#handle));
      }
      /** The SQL string that we passed when creating statement */
      get sql() {
        return readCstr(sqlite3_sql(this.#handle));
      }
      /** Whether this statement doesn't make any direct changes to the DB */
      get readonly() {
        return sqlite3_stmt_readonly(this.#handle) !== 0;
      }
      /** Simply run the query without retrieving any output there may be. */
      run(...args) {
        return this.#runWithArgs(...args);
      }
      /**
      * Run the query and return the resulting rows where rows are array of columns.
      */
      values(...args) {
        return this.#valuesWithArgs(...args);
      }
      /**
      * Run the query and return the resulting rows where rows are objects
      * mapping column name to their corresponding values.
      */
      all(...args) {
        return this.#allWithArgs(...args);
      }
      #bindParameterCount;
      /** Number of parameters (to be) bound */
      get bindParameterCount() {
        return this.#bindParameterCount;
      }
      constructor(db2, sql2) {
        this.db = db2;
        this.#bound = false;
        this.#hasNoArgs = false;
        this.callback = false;
        this.#bindRefs = /* @__PURE__ */ new Set();
        this.#rowObject = {};
        const pHandle = /* @__PURE__ */ new BigUint64Array(1);
        unwrap(sqlite3_prepare_v2(db2.unsafeHandle, toCString(sql2), sql2.length, pHandle, null), db2.unsafeHandle);
        this.#handle = Deno.UnsafePointer.create(pHandle[0]);
        STATEMENTS_TO_DB.set(this.#handle, db2.unsafeHandle);
        this.#unsafeConcurrency = db2.unsafeConcurrency;
        this.#finalizerToken = { handle: this.#handle };
        statementFinalizer.register(this, this.#handle, this.#finalizerToken);
        if ((this.#bindParameterCount = sqlite3_bind_parameter_count(this.#handle)) === 0) {
          this.#hasNoArgs = true;
          this.all = this.#allNoArgs;
          this.values = this.#valuesNoArgs;
          this.run = this.#runNoArgs;
          this.value = this.#valueNoArgs;
          this.get = this.#getNoArgs;
        }
      }
      /** Shorthand for `this.callback = true`. Enables calling user defined functions. */
      enableCallback() {
        this.callback = true;
        return this;
      }
      /** Get bind parameter name by index */
      bindParameterName(i) {
        return readCstr(sqlite3_bind_parameter_name(this.#handle, i));
      }
      /** Get bind parameter index by name */
      bindParameterIndex(name) {
        if (name[0] !== ":" && name[0] !== "@" && name[0] !== "$") name = ":" + name;
        return sqlite3_bind_parameter_index(this.#handle, toCString(name));
      }
      #begin() {
        sqlite3_reset(this.#handle);
        if (!this.#bound && !this.#hasNoArgs) {
          sqlite3_clear_bindings(this.#handle);
          this.#bindRefs.clear();
        }
      }
      #bindRefs;
      #bind(i, param) {
        switch (typeof param) {
          case "number":
            if (Number.isInteger(param)) if (Number.isSafeInteger(param) && param >= -(2 ** 31) && param < 2 ** 31) unwrap(sqlite3_bind_int(this.#handle, i + 1, param));
            else unwrap(sqlite3_bind_int64(this.#handle, i + 1, BigInt(param)));
            else unwrap(sqlite3_bind_double(this.#handle, i + 1, param));
            break;
          case "string":
            if (param === "") unwrap(sqlite3_bind_text(this.#handle, i + 1, emptyStringBuffer, 0, null));
            else {
              const str2 = new TextEncoder().encode(param);
              this.#bindRefs.add(str2);
              unwrap(sqlite3_bind_text(this.#handle, i + 1, str2, str2.byteLength, null));
            }
            break;
          case "object":
            if (param === null) {
            } else if (param instanceof Uint8Array) {
              this.#bindRefs.add(param);
              unwrap(sqlite3_bind_blob(this.#handle, i + 1, param.byteLength === 0 ? emptyStringBuffer : param, param.byteLength, null));
            } else if (param instanceof Date) {
              const cstring = toCString(param.toISOString());
              this.#bindRefs.add(cstring);
              unwrap(sqlite3_bind_text(this.#handle, i + 1, cstring, -1, null));
            } else {
              const cstring = toCString(JSON.stringify(param));
              this.#bindRefs.add(cstring);
              unwrap(sqlite3_bind_text(this.#handle, i + 1, cstring, -1, null));
            }
            break;
          case "bigint":
            unwrap(sqlite3_bind_int64(this.#handle, i + 1, param));
            break;
          case "boolean":
            unwrap(sqlite3_bind_int(this.#handle, i + 1, param ? 1 : 0));
            break;
          default:
            throw new Error(`Value of unsupported type: ${Deno.inspect(param)}`);
        }
      }
      /**
      * Bind parameters to the statement. This method can only be called once
      * to set the parameters to be same throughout the statement. You cannot
      * change the parameters after this method is called.
      *
      * This method is merely just for optimization to avoid binding parameters
      * each time in prepared statement.
      */
      bind(...params) {
        this.#bindAll(params);
        this.#bound = true;
        return this;
      }
      #bindAll(params) {
        if (this.#bound) throw new Error("Statement already bound to values");
        if (typeof params[0] === "object" && params[0] !== null && !(params[0] instanceof Uint8Array) && !(params[0] instanceof Date)) params = params[0];
        if (Array.isArray(params)) for (let i = 0; i < params.length; i++) this.#bind(i, params[i]);
        else for (const [name, param] of Object.entries(params)) {
          const i = this.bindParameterIndex(name);
          if (i === 0) throw new Error(`No such parameter "${name}"`);
          this.#bind(i - 1, param);
        }
      }
      #runNoArgs() {
        const handle2 = this.#handle;
        this.#begin();
        const status = sqlite3_step(handle2);
        if (status !== 100 && status !== 101) unwrap(status, this.db.unsafeHandle);
        sqlite3_reset(handle2);
        return sqlite3_changes$1(this.db.unsafeHandle);
      }
      #runWithArgs(...params) {
        const handle2 = this.#handle;
        this.#begin();
        this.#bindAll(params);
        const status = sqlite3_step(handle2);
        if (!this.#hasNoArgs && !this.#bound && params.length) this.#bindRefs.clear();
        if (status !== 100 && status !== 101) unwrap(status, this.db.unsafeHandle);
        sqlite3_reset(handle2);
        return sqlite3_changes$1(this.db.unsafeHandle);
      }
      #valuesNoArgs() {
        const handle2 = this.#handle;
        this.#begin();
        const columnCount = sqlite3_column_count(handle2);
        const result = [];
        const getRowArray = new Function("getColumn", `
      return function(h) {
        return [${Array.from({ length: columnCount }).map((_3, i) => `getColumn(h, ${i}, ${this.db.int64})`).join(", ")}];
      };
      `)(getColumn);
        let status = sqlite3_step(handle2);
        while (status === 100) {
          result.push(getRowArray(handle2));
          status = sqlite3_step(handle2);
        }
        if (status !== 101) unwrap(status, this.db.unsafeHandle);
        sqlite3_reset(handle2);
        return result;
      }
      #valuesWithArgs(...params) {
        const handle2 = this.#handle;
        this.#begin();
        this.#bindAll(params);
        const columnCount = sqlite3_column_count(handle2);
        const result = [];
        const getRowArray = new Function("getColumn", `
      return function(h) {
        return [${Array.from({ length: columnCount }).map((_3, i) => `getColumn(h, ${i}, ${this.db.int64})`).join(", ")}];
      };
      `)(getColumn);
        let status = sqlite3_step(handle2);
        while (status === 100) {
          result.push(getRowArray(handle2));
          status = sqlite3_step(handle2);
        }
        if (!this.#hasNoArgs && !this.#bound && params.length) this.#bindRefs.clear();
        if (status !== 101) unwrap(status, this.db.unsafeHandle);
        sqlite3_reset(handle2);
        return result;
      }
      #rowObjectFn;
      getRowObject() {
        if (!this.#rowObjectFn || !this.#unsafeConcurrency) {
          const columnNames = this.columnNames();
          const getRowObject = new Function("getColumn", `
        return function(h) {
          return {
            ${columnNames.map((name, i) => `"${name}": getColumn(h, ${i}, ${this.db.int64})`).join(",\n")}
          };
        };
        `)(getColumn);
          this.#rowObjectFn = getRowObject;
        }
        return this.#rowObjectFn;
      }
      #allNoArgs() {
        const handle2 = this.#handle;
        this.#begin();
        const getRowObject = this.getRowObject();
        const result = [];
        let status = sqlite3_step(handle2);
        while (status === 100) {
          result.push(getRowObject(handle2));
          status = sqlite3_step(handle2);
        }
        if (status !== 101) unwrap(status, this.db.unsafeHandle);
        sqlite3_reset(handle2);
        return result;
      }
      #allWithArgs(...params) {
        const handle2 = this.#handle;
        this.#begin();
        this.#bindAll(params);
        const getRowObject = this.getRowObject();
        const result = [];
        let status = sqlite3_step(handle2);
        while (status === 100) {
          result.push(getRowObject(handle2));
          status = sqlite3_step(handle2);
        }
        if (!this.#hasNoArgs && !this.#bound && params.length) this.#bindRefs.clear();
        if (status !== 101) unwrap(status, this.db.unsafeHandle);
        sqlite3_reset(handle2);
        return result;
      }
      /** Fetch only first row as an array, if any. */
      value(...params) {
        const handle2 = this.#handle;
        const int64 = this.db.int64;
        const arr = new Array(sqlite3_column_count(handle2));
        sqlite3_reset(handle2);
        if (!this.#hasNoArgs && !this.#bound) {
          sqlite3_clear_bindings(handle2);
          this.#bindRefs.clear();
          if (params.length) this.#bindAll(params);
        }
        const status = sqlite3_step(handle2);
        if (!this.#hasNoArgs && !this.#bound && params.length) this.#bindRefs.clear();
        if (status === 100) {
          for (let i = 0; i < arr.length; i++) arr[i] = getColumn(handle2, i, int64);
          sqlite3_reset(this.#handle);
          return arr;
        } else if (status === 101) return;
        else unwrap(status, this.db.unsafeHandle);
      }
      #valueNoArgs() {
        const handle2 = this.#handle;
        const int64 = this.db.int64;
        const cc = sqlite3_column_count(handle2);
        const arr = new Array(cc);
        sqlite3_reset(handle2);
        const status = sqlite3_step(handle2);
        if (status === 100) {
          for (let i = 0; i < cc; i++) arr[i] = getColumn(handle2, i, int64);
          sqlite3_reset(this.#handle);
          return arr;
        } else if (status === 101) return;
        else unwrap(status, this.db.unsafeHandle);
      }
      #columnNames;
      #rowObject;
      columnNames() {
        if (!this.#columnNames || !this.#unsafeConcurrency) {
          const columnCount = sqlite3_column_count(this.#handle);
          const columnNames = new Array(columnCount);
          for (let i = 0; i < columnCount; i++) columnNames[i] = readCstr(sqlite3_column_name(this.#handle, i));
          this.#columnNames = columnNames;
          this.#rowObject = {};
          for (const name of columnNames) this.#rowObject[name] = void 0;
        }
        return this.#columnNames;
      }
      /** Fetch only first row as an object, if any. */
      get(...params) {
        const handle2 = this.#handle;
        const int64 = this.db.int64;
        const columnNames = this.columnNames();
        const row = {};
        sqlite3_reset(handle2);
        if (!this.#hasNoArgs && !this.#bound) {
          sqlite3_clear_bindings(handle2);
          this.#bindRefs.clear();
          if (params.length) this.#bindAll(params);
        }
        const status = sqlite3_step(handle2);
        if (!this.#hasNoArgs && !this.#bound && params.length) this.#bindRefs.clear();
        if (status === 100) {
          for (let i = 0; i < columnNames.length; i++) row[columnNames[i]] = getColumn(handle2, i, int64);
          sqlite3_reset(this.#handle);
          return row;
        } else if (status === 101) return;
        else unwrap(status, this.db.unsafeHandle);
      }
      #getNoArgs() {
        const handle2 = this.#handle;
        const int64 = this.db.int64;
        const columnNames = this.columnNames();
        const row = this.#rowObject;
        sqlite3_reset(handle2);
        const status = sqlite3_step(handle2);
        if (status === 100) {
          for (let i = 0; i < columnNames?.length; i++) row[columnNames[i]] = getColumn(handle2, i, int64);
          sqlite3_reset(handle2);
          return row;
        } else if (status === 101) return;
        else unwrap(status, this.db.unsafeHandle);
      }
      /** Free up the statement object. */
      finalize() {
        if (!STATEMENTS_TO_DB.has(this.#handle)) return;
        this.#bindRefs.clear();
        statementFinalizer.unregister(this.#finalizerToken);
        STATEMENTS_TO_DB.delete(this.#handle);
        unwrap(sqlite3_finalize$1(this.#handle));
      }
      /** Coerces the statement to a string, which in this case is expanded SQL. */
      toString() {
        return readCstr(sqlite3_expanded_sql(this.#handle));
      }
      /** Iterate over resultant rows from query. */
      *iter(...params) {
        this.#begin();
        this.#bindAll(params);
        const getRowObject = this.getRowObject();
        let status = sqlite3_step(this.#handle);
        while (status === 100) {
          yield getRowObject(this.#handle);
          status = sqlite3_step(this.#handle);
        }
        if (status !== 101) unwrap(status, this.db.unsafeHandle);
        sqlite3_reset(this.#handle);
      }
      [_computedKey$2]() {
        return this.iter();
      }
      [_computedKey1$1]() {
        this.finalize();
      }
      [_computedKey2]() {
        return `Statement { ${this.expandedSql} }`;
      }
    };
    ({ sqlite3_blob_open, sqlite3_blob_bytes, sqlite3_blob_close, sqlite3_blob_read, sqlite3_blob_write } = ffi_default);
    _computedKey$1 = Symbol.iterator, _computedKey1 = /* @__PURE__ */ Symbol.for("Deno.customInspect");
    SQLBlob = class {
      #handle;
      constructor(db2, options2) {
        options2 = Object.assign({
          readonly: true,
          db: "main"
        }, options2);
        const pHandle = /* @__PURE__ */ new BigUint64Array(1);
        unwrap(sqlite3_blob_open(db2.unsafeHandle, toCString(options2.db ?? "main"), toCString(options2.table), toCString(options2.column), BigInt(options2.row), options2.readonly === false ? 1 : 0, pHandle));
        this.#handle = Deno.UnsafePointer.create(pHandle[0]);
      }
      /** Byte size of the Blob */
      get byteLength() {
        return sqlite3_blob_bytes(this.#handle);
      }
      /** Read from the Blob at given offset into a buffer (Uint8Array) */
      readSync(offset, p2) {
        unwrap(sqlite3_blob_read(this.#handle, p2, p2.byteLength, offset));
      }
      /** Write a buffer (Uint8Array) at given offset in the Blob */
      writeSync(offset, p2) {
        unwrap(sqlite3_blob_write(this.#handle, p2, p2.byteLength, offset));
      }
      /** Close the Blob. It **must** be called to prevent leaks. */
      close() {
        unwrap(sqlite3_blob_close(this.#handle));
      }
      /** Obtains Web Stream for reading the Blob */
      get readable() {
        const length = this.byteLength;
        let offset = 0;
        return new ReadableStream({
          type: "bytes",
          pull: (ctx) => {
            try {
              const byob = ctx.byobRequest;
              if (byob) {
                const toRead = Math.min(length - offset, byob.view.byteLength);
                this.readSync(offset, byob.view.subarray(0, toRead));
                offset += toRead;
                byob.respond(toRead);
              } else {
                const toRead = Math.min(length - offset, ctx.desiredSize || 16384);
                if (toRead === 0) {
                  ctx.close();
                  return;
                }
                const buffer2 = new Uint8Array(toRead);
                this.readSync(offset, buffer2);
                offset += toRead;
                ctx.enqueue(buffer2);
              }
            } catch (e) {
              ctx.error(e);
              ctx.byobRequest?.respond(0);
            }
          }
        });
      }
      /** Obtains Web Stream for writing to the Blob */
      get writable() {
        const length = this.byteLength;
        let offset = 0;
        return new WritableStream({ write: (chunk, ctx) => {
          if (offset + chunk.byteLength > length) {
            ctx.error(/* @__PURE__ */ new Error("Write exceeds blob length"));
            return;
          }
          this.writeSync(offset, chunk);
          offset += chunk.byteLength;
        } });
      }
      *[_computedKey$1]() {
        const length = this.byteLength;
        let offset = 0;
        while (offset < length) {
          const toRead = Math.min(length - offset, 16384);
          const buffer2 = new Uint8Array(toRead);
          this.readSync(offset, buffer2);
          offset += toRead;
          yield buffer2;
        }
      }
      [_computedKey1]() {
        return `SQLite3.Blob(0x${this.byteLength.toString(16)})`;
      }
    };
    ({ sqlite3_open_v2, sqlite3_close_v2, sqlite3_changes, sqlite3_total_changes, sqlite3_last_insert_rowid, sqlite3_get_autocommit, sqlite3_exec, sqlite3_free, sqlite3_libversion, sqlite3_sourceid, sqlite3_complete, sqlite3_finalize, sqlite3_result_blob, sqlite3_result_double, sqlite3_result_error, sqlite3_result_int64, sqlite3_result_null, sqlite3_result_text, sqlite3_value_blob, sqlite3_value_bytes, sqlite3_value_double, sqlite3_value_int64, sqlite3_value_text, sqlite3_value_type, sqlite3_create_function, sqlite3_result_int, sqlite3_aggregate_context, sqlite3_enable_load_extension, sqlite3_load_extension, sqlite3_backup_init, sqlite3_backup_step, sqlite3_backup_finish, sqlite3_errcode } = ffi_default);
    readCstr(sqlite3_libversion());
    readCstr(sqlite3_sourceid());
    BIG_MAX = BigInt(Number.MAX_SAFE_INTEGER);
    _computedKey = /* @__PURE__ */ Symbol.for("Deno.customInspect");
    Database = class {
      #path;
      #handle;
      #open = true;
      #enableLoadExtension = false;
      /** Whether to support BigInt columns. False by default, integers larger than 32 bit will be inaccurate. */
      int64;
      unsafeConcurrency;
      /** Whether DB connection is open */
      get open() {
        return this.#open;
      }
      /** Unsafe Raw (pointer) to the sqlite object */
      get unsafeHandle() {
        return this.#handle;
      }
      /** Path of the database file. */
      get path() {
        return this.#path;
      }
      /** Number of rows changed by the last executed statement. */
      get changes() {
        return sqlite3_changes(this.#handle);
      }
      /** Number of rows changed since the database connection was opened. */
      get totalChanges() {
        return sqlite3_total_changes(this.#handle);
      }
      /** Gets last inserted Row ID */
      get lastInsertRowId() {
        return Number(sqlite3_last_insert_rowid(this.#handle));
      }
      /** Whether autocommit is enabled. Enabled by default, can be disabled using BEGIN statement. */
      get autocommit() {
        return sqlite3_get_autocommit(this.#handle) === 1;
      }
      /** Whether DB is in mid of a transaction */
      get inTransaction() {
        return this.#open && !this.autocommit;
      }
      get enableLoadExtension() {
        return this.#enableLoadExtension;
      }
      set enableLoadExtension(enabled3) {
        if (sqlite3_enable_load_extension === null) throw new Error("Extension loading is not supported by the shared library that was used.");
        unwrap(sqlite3_enable_load_extension(this.#handle, Number(enabled3)), this.#handle);
        this.#enableLoadExtension = enabled3;
      }
      constructor(path, options2 = {}) {
        this.#path = path instanceof URL ? fromFileUrl$3(path) : path;
        let flags2 = 0;
        this.int64 = options2.int64 ?? false;
        this.unsafeConcurrency = options2.unsafeConcurrency ?? false;
        if (options2.flags !== void 0) flags2 = options2.flags;
        else {
          if (options2.memory) flags2 |= 128;
          if (options2.readonly ?? false) flags2 |= 1;
          else flags2 |= 2;
          if ((options2.create ?? true) && !options2.readonly) flags2 |= 4;
        }
        const pHandle = /* @__PURE__ */ new BigUint64Array(1);
        const result = sqlite3_open_v2(toCString(this.#path), pHandle, flags2, null);
        this.#handle = Deno.UnsafePointer.create(pHandle[0]);
        if (result !== 0) sqlite3_close_v2(this.#handle);
        unwrap(result);
        if (options2.enableLoadExtension) this.enableLoadExtension = options2.enableLoadExtension;
      }
      /**
      * Creates a new Prepared Statement from the given SQL statement.
      *
      * Example:
      * ```ts
      * const stmt = db.prepare("SELECT * FROM mytable WHERE id = ?");
      *
      * for (const row of stmt.all(1)) {
      *   console.log(row);
      * }
      * ```
      *
      * Bind parameters can be either provided as an array of values, or as an object
      * mapping the parameter name to the value.
      *
      * Example:
      * ```ts
      * const stmt = db.prepare("SELECT * FROM mytable WHERE id = ?");
      * const row = stmt.get(1);
      *
      * // or
      *
      * const stmt = db.prepare("SELECT * FROM mytable WHERE id = :id");
      * const row = stmt.get({ id: 1 });
      * ```
      *
      * Statements are automatically freed once GC catches them, however
      * you can also manually free using `finalize` method.
      *
      * @param sql SQL statement string
      * @returns Statement object
      */
      prepare(sql2) {
        return new Statement(this, sql2);
      }
      /**
      * Open a Blob for incremental I/O.
      *
      * Make sure to close the blob after you are done with it,
      * otherwise you will have memory leaks.
      */
      openBlob(options2) {
        return new SQLBlob(this, options2);
      }
      /**
      * Simply executes the SQL statement (supports multiple statements separated by semicolon).
      * Returns the number of changes made by last statement.
      *
      * Example:
      * ```ts
      * // Create table
      * db.exec("create table users (id integer not null, username varchar(20) not null)");
      *
      * // Inserts
      * db.exec("insert into users (id, username) values(?, ?)", id, username);
      *
      * // Insert with named parameters
      * db.exec("insert into users (id, username) values(:id, :username)", { id, username });
      *
      * // Pragma statements
      * db.exec("pragma journal_mode = WAL");
      * db.exec("pragma synchronous = normal");
      * db.exec("pragma temp_store = memory");
      * ```
      *
      * Under the hood, it uses `sqlite3_exec` if no parameters are given to bind
      * with the SQL statement, a prepared statement otherwise.
      */
      exec(sql2, ...params) {
        if (params.length === 0) {
          const pErr = /* @__PURE__ */ new BigUint64Array(1);
          sqlite3_exec(this.#handle, toCString(sql2), null, null, new Uint8Array(pErr.buffer));
          const errPtr = Deno.UnsafePointer.create(pErr[0]);
          if (errPtr !== null) {
            const err = readCstr(errPtr);
            sqlite3_free(errPtr);
            throw new Error(err);
          }
          return sqlite3_changes(this.#handle);
        }
        this.prepare(sql2).run(...params);
        return sqlite3_changes(this.#handle);
      }
      /** Alias for `exec`. */
      run(sql2, ...params) {
        return this.exec(sql2, ...params);
      }
      /** Safely execute SQL with parameters using a tagged template */
      sql(strings, ...parameters) {
        const sql2 = strings.join("?");
        return this.prepare(sql2).all(...parameters);
      }
      /**
      * Wraps a callback function in a transaction.
      *
      * - When function is called, the transaction is started.
      * - When function returns, the transaction is committed.
      * - When function throws an error, the transaction is rolled back.
      *
      * Example:
      * ```ts
      * const stmt = db.prepare("insert into users (id, username) values(?, ?)");
      *
      * interface User {
      *   id: number;
      *   username: string;
      * }
      *
      * const insertUsers = db.transaction((data: User[]) => {
      *   for (const user of data) {
      *     stmt.run(user);
      *   }
      * });
      *
      * insertUsers([
      *   { id: 1, username: "alice" },
      *   { id: 2, username: "bob" },
      * ]);
      *
      * // May also use `insertUsers.deferred`, `immediate`, or `exclusive`.
      * // They corresspond to using `BEGIN DEFERRED`, `BEGIN IMMEDIATE`, and `BEGIN EXCLUSIVE`.
      * // For eg.
      *
      * insertUsers.deferred([
      *   { id: 1, username: "alice" },
      *   { id: 2, username: "bob" },
      * ]);
      * ```
      */
      transaction(fn) {
        const controller2 = getController(this);
        const properties = {
          default: { value: wrapTransaction(fn, this, controller2.default) },
          deferred: { value: wrapTransaction(fn, this, controller2.deferred) },
          immediate: { value: wrapTransaction(fn, this, controller2.immediate) },
          exclusive: { value: wrapTransaction(fn, this, controller2.exclusive) },
          database: {
            value: this,
            enumerable: true
          }
        };
        Object.defineProperties(properties.default.value, properties);
        Object.defineProperties(properties.deferred.value, properties);
        Object.defineProperties(properties.immediate.value, properties);
        Object.defineProperties(properties.exclusive.value, properties);
        return properties.default.value;
      }
      #callbacks = /* @__PURE__ */ new Set();
      /**
      * Creates a new user-defined function.
      *
      * Example:
      * ```ts
      * db.function("add", (a: number, b: number) => a + b);
      * db.prepare("select add(1, 2)").value<[number]>()!; // [3]
      * ```
      */
      function(name, fn, options2) {
        if (sqlite3_create_function === null) throw new Error("User-defined functions are not supported by the shared library that was used.");
        const cb = new Deno.UnsafeCallback({
          parameters: [
            "pointer",
            "i32",
            "pointer"
          ],
          result: "void"
        }, (ctx, nArgs, pArgs) => {
          const argptr = new Deno.UnsafePointerView(pArgs);
          const args = [];
          for (let i = 0; i < nArgs; i++) {
            const arg = Deno.UnsafePointer.create(argptr.getBigUint64(i * 8));
            const type = sqlite3_value_type(arg);
            switch (type) {
              case 1: {
                const value2 = sqlite3_value_int64(arg);
                if (value2 < -BIG_MAX || value2 > BIG_MAX) args.push(value2);
                else args.push(Number(value2));
                break;
              }
              case 2:
                args.push(sqlite3_value_double(arg));
                break;
              case 3:
                args.push(new TextDecoder().decode(new Uint8Array(Deno.UnsafePointerView.getArrayBuffer(sqlite3_value_text(arg), sqlite3_value_bytes(arg)))));
                break;
              case 4:
                args.push(new Uint8Array(Deno.UnsafePointerView.getArrayBuffer(sqlite3_value_blob(arg), sqlite3_value_bytes(arg))));
                break;
              case 5:
                args.push(null);
                break;
              default:
                throw new Error(`Unknown type: ${type}`);
            }
          }
          let result;
          try {
            result = fn(...args);
          } catch (err) {
            const buf = new TextEncoder().encode(err.message);
            sqlite3_result_error(ctx, buf, buf.byteLength);
            return;
          }
          if (result === void 0 || result === null) sqlite3_result_null(ctx);
          else if (typeof result === "boolean") sqlite3_result_int(ctx, result ? 1 : 0);
          else if (typeof result === "number") if (Number.isSafeInteger(result)) sqlite3_result_int64(ctx, BigInt(result));
          else sqlite3_result_double(ctx, result);
          else if (typeof result === "bigint") sqlite3_result_int64(ctx, result);
          else if (typeof result === "string") {
            const buffer2 = new TextEncoder().encode(result);
            sqlite3_result_text(ctx, buffer2, buffer2.byteLength, 0n);
          } else if (result instanceof Uint8Array) sqlite3_result_blob(ctx, result, result.length, -1n);
          else {
            const buffer2 = new TextEncoder().encode(`Invalid return value: ${Deno.inspect(result)}`);
            sqlite3_result_error(ctx, buffer2, buffer2.byteLength);
          }
        });
        let flags2 = 1;
        if (options2?.deterministic) flags2 |= 2048;
        if (options2?.directOnly) flags2 |= 524288;
        if (options2?.subtype) flags2 |= 1048576;
        if (options2?.directOnly) flags2 |= 2097152;
        unwrap(sqlite3_create_function(this.#handle, toCString(name), options2?.varargs ? -1 : fn.length, flags2, null, cb.pointer, null, null), this.#handle);
        this.#callbacks.add(cb);
      }
      /**
      * Creates a new user-defined aggregate function.
      */
      aggregate(name, options2) {
        if (sqlite3_aggregate_context === null || sqlite3_create_function === null) throw new Error("User-defined functions are not supported by the shared library that was used.");
        const contexts = /* @__PURE__ */ new Map();
        const cb = new Deno.UnsafeCallback({
          parameters: [
            "pointer",
            "i32",
            "pointer"
          ],
          result: "void"
        }, (ctx, nArgs, pArgs) => {
          const aggrCtx = sqlite3_aggregate_context(ctx, 8);
          const aggrPtr = Deno.UnsafePointer.value(aggrCtx);
          let aggregate;
          if (contexts.has(aggrPtr)) aggregate = contexts.get(aggrPtr);
          else {
            aggregate = typeof options2.start === "function" ? options2.start() : options2.start;
            contexts.set(aggrPtr, aggregate);
          }
          const argptr = new Deno.UnsafePointerView(pArgs);
          const args = [];
          for (let i = 0; i < nArgs; i++) {
            const arg = Deno.UnsafePointer.create(argptr.getBigUint64(i * 8));
            const type = sqlite3_value_type(arg);
            switch (type) {
              case 1: {
                const value2 = sqlite3_value_int64(arg);
                if (value2 < -BIG_MAX || value2 > BIG_MAX) args.push(value2);
                else args.push(Number(value2));
                break;
              }
              case 2:
                args.push(sqlite3_value_double(arg));
                break;
              case 3:
                args.push(new TextDecoder().decode(new Uint8Array(Deno.UnsafePointerView.getArrayBuffer(sqlite3_value_text(arg), sqlite3_value_bytes(arg)))));
                break;
              case 4:
                args.push(new Uint8Array(Deno.UnsafePointerView.getArrayBuffer(sqlite3_value_blob(arg), sqlite3_value_bytes(arg))));
                break;
              case 5:
                args.push(null);
                break;
              default:
                throw new Error(`Unknown type: ${type}`);
            }
          }
          let result;
          try {
            result = options2.step(aggregate, ...args);
          } catch (err) {
            const buf = new TextEncoder().encode(err.message);
            sqlite3_result_error(ctx, buf, buf.byteLength);
            return;
          }
          contexts.set(aggrPtr, result);
        });
        const cbFinal = new Deno.UnsafeCallback({
          parameters: ["pointer"],
          result: "void"
        }, (ctx) => {
          const aggrCtx = sqlite3_aggregate_context(ctx, 0);
          const aggrPtr = Deno.UnsafePointer.value(aggrCtx);
          const aggregate = contexts.get(aggrPtr);
          contexts.delete(aggrPtr);
          let result;
          try {
            result = options2.final ? options2.final(aggregate) : aggregate;
          } catch (err) {
            const buf = new TextEncoder().encode(err.message);
            sqlite3_result_error(ctx, buf, buf.byteLength);
            return;
          }
          if (result === void 0 || result === null) sqlite3_result_null(ctx);
          else if (typeof result === "boolean") sqlite3_result_int(ctx, result ? 1 : 0);
          else if (typeof result === "number") if (Number.isSafeInteger(result)) sqlite3_result_int64(ctx, BigInt(result));
          else sqlite3_result_double(ctx, result);
          else if (typeof result === "bigint") sqlite3_result_int64(ctx, result);
          else if (typeof result === "string") {
            const buffer2 = new TextEncoder().encode(result);
            sqlite3_result_text(ctx, buffer2, buffer2.byteLength, 0n);
          } else if (result instanceof Uint8Array) sqlite3_result_blob(ctx, result, result.length, -1n);
          else {
            const buffer2 = new TextEncoder().encode(`Invalid return value: ${Deno.inspect(result)}`);
            sqlite3_result_error(ctx, buffer2, buffer2.byteLength);
          }
        });
        let flags2 = 1;
        if (options2?.deterministic) flags2 |= 2048;
        if (options2?.directOnly) flags2 |= 524288;
        if (options2?.subtype) flags2 |= 1048576;
        if (options2?.directOnly) flags2 |= 2097152;
        unwrap(sqlite3_create_function(this.#handle, toCString(name), options2?.varargs ? -1 : options2.step.length - 1, flags2, null, null, cb.pointer, cbFinal.pointer), this.#handle);
        this.#callbacks.add(cb);
        this.#callbacks.add(cbFinal);
      }
      /**
      * Loads an SQLite extension library from the named file.
      */
      loadExtension(file, entryPoint) {
        if (sqlite3_load_extension === null) throw new Error("Extension loading is not supported by the shared library that was used.");
        if (!this.enableLoadExtension) throw new Error("Extension loading is not enabled");
        const pzErrMsg = /* @__PURE__ */ new BigUint64Array(1);
        const result = sqlite3_load_extension(this.#handle, toCString(file), entryPoint ? toCString(entryPoint) : null, pzErrMsg);
        const pzErrPtr = Deno.UnsafePointer.create(pzErrMsg[0]);
        if (pzErrPtr !== null) {
          const pzErr = readCstr(pzErrPtr);
          sqlite3_free(pzErrPtr);
          throw new Error(pzErr);
        }
        unwrap(result, this.#handle);
      }
      /**
      * Closes the database connection.
      *
      * Calling this method more than once is no-op.
      */
      close() {
        if (!this.#open) return;
        for (const [stmt, db2] of STATEMENTS_TO_DB) if (db2 === this.#handle) {
          sqlite3_finalize(stmt);
          STATEMENTS_TO_DB.delete(stmt);
        }
        for (const cb of this.#callbacks) cb.close();
        unwrap(sqlite3_close_v2(this.#handle));
        this.#open = false;
      }
      /**
      * @param dest The destination database connection.
      * @param name Destination database name. "main" for main database, "temp" for temporary database, or the name specified after the AS keyword in an ATTACH statement for an attached database.
      * @param pages The number of pages to copy. If it is negative, all remaining pages are copied (default).
      */
      backup(dest, name = "main", pages = -1) {
        const backup = sqlite3_backup_init(dest.#handle, toCString(name), this.#handle, toCString("main"));
        if (backup) {
          unwrap(sqlite3_backup_step(backup, pages));
          unwrap(sqlite3_backup_finish(backup));
        } else unwrap(sqlite3_errcode(dest.#handle), dest.#handle);
      }
      [_computedKey]() {
        return `SQLite3.Database { path: ${this.path} }`;
      }
    };
    controllers = /* @__PURE__ */ new WeakMap();
    getController = (db2) => {
      let controller2 = controllers.get(db2);
      if (!controller2) {
        const shared = {
          commit: db2.prepare("COMMIT"),
          rollback: db2.prepare("ROLLBACK"),
          savepoint: db2.prepare("SAVEPOINT `	_bs3.	`"),
          release: db2.prepare("RELEASE `	_bs3.	`"),
          rollbackTo: db2.prepare("ROLLBACK TO `	_bs3.	`")
        };
        controllers.set(db2, controller2 = {
          default: Object.assign({ begin: db2.prepare("BEGIN") }, shared),
          deferred: Object.assign({ begin: db2.prepare("BEGIN DEFERRED") }, shared),
          immediate: Object.assign({ begin: db2.prepare("BEGIN IMMEDIATE") }, shared),
          exclusive: Object.assign({ begin: db2.prepare("BEGIN EXCLUSIVE") }, shared)
        });
      }
      return controller2;
    };
    wrapTransaction = (fn, db2, { begin, commit: commit2, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction(...args) {
      const { apply } = Function.prototype;
      let before, after, undo;
      if (db2.inTransaction) {
        before = savepoint;
        after = release;
        undo = rollbackTo;
      } else {
        before = begin;
        after = commit2;
        undo = rollback;
      }
      before.run();
      try {
        const result = apply.call(fn, this, args);
        after.run();
        return result;
      } catch (ex) {
        if (!db2.autocommit) {
          undo.run();
          if (undo !== rollback) after.run();
        }
        throw ex;
      }
    };
    colors = {
      reset: "\x1B[0m",
      grey: "\x1B[90m",
      cyan: "\x1B[36m",
      green: "\x1B[32m",
      yellow: "\x1B[33m",
      red: "\x1B[31m"
    };
    logSettingsQueries = {
      /**
      * Get the log settings (singleton)
      */
      get() {
        return db.queryFirst("SELECT * FROM log_settings WHERE id = 1");
      },
      /**
      * Update log settings
      */
      update(input) {
        const updates = [];
        const params = [];
        if (input.retentionDays !== void 0) {
          updates.push("retention_days = ?");
          params.push(input.retentionDays);
        }
        if (input.minLevel !== void 0) {
          updates.push("min_level = ?");
          params.push(input.minLevel);
        }
        if (input.enabled !== void 0) {
          updates.push("enabled = ?");
          params.push(input.enabled ? 1 : 0);
        }
        if (input.fileLogging !== void 0) {
          updates.push("file_logging = ?");
          params.push(input.fileLogging ? 1 : 0);
        }
        if (input.consoleLogging !== void 0) {
          updates.push("console_logging = ?");
          params.push(input.consoleLogging ? 1 : 0);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(1);
        return db.execute(`UPDATE log_settings SET ${updates.join(", ")} WHERE id = ?`, ...params) > 0;
      },
      /**
      * Reset log settings to defaults
      */
      reset() {
        return db.execute(`
			UPDATE log_settings SET
				retention_days = 30,
				min_level = 'INFO',
				enabled = 1,
				file_logging = 1,
				console_logging = 1,
				updated_at = CURRENT_TIMESTAMP
			WHERE id = 1
		`) > 0;
      }
    };
    LogSettingsManager = class {
      settings = null;
      initialized = false;
      /**
      * Load settings from database
      */
      load() {
        try {
          this.settings = logSettingsQueries.get() ?? null;
          this.initialized = true;
        } catch (error2) {
          console.error("Failed to load log settings:", error2);
          this.settings = null;
          this.initialized = false;
        }
      }
      /**
      * Reload settings from database
      * Call this after updating settings
      */
      reload() {
        this.load();
      }
      /**
      * Get current settings
      * Returns defaults if not loaded
      */
      get() {
        if (!this.initialized || !this.settings) return {
          id: 1,
          retention_days: 30,
          min_level: "INFO",
          enabled: 1,
          file_logging: 1,
          console_logging: 1,
          created_at: (/* @__PURE__ */ new Date()).toISOString(),
          updated_at: (/* @__PURE__ */ new Date()).toISOString()
        };
        return this.settings;
      }
      /**
      * Check if logging is enabled
      */
      isEnabled() {
        return this.get().enabled === 1;
      }
      /**
      * Check if file logging is enabled
      */
      isFileLoggingEnabled() {
        return this.get().file_logging === 1;
      }
      /**
      * Check if console logging is enabled
      */
      isConsoleLoggingEnabled() {
        return this.get().console_logging === 1;
      }
      /**
      * Get minimum log level
      */
      getMinLevel() {
        return this.get().min_level;
      }
      /**
      * Check if a log level should be logged
      */
      shouldLog(level) {
        if (!this.isEnabled()) return false;
        const minLevel = this.getMinLevel();
        const levels = [
          "DEBUG",
          "INFO",
          "WARN",
          "ERROR"
        ];
        const minIndex = levels.indexOf(minLevel);
        return levels.indexOf(level) >= minIndex;
      }
    };
    logSettings = new LogSettingsManager();
    Logger = class {
      config;
      constructor(config2) {
        this.config = {
          logsDir: config2?.logsDir ?? "/tmp/logs",
          enabled: config2?.enabled ?? true,
          fileLogging: config2?.fileLogging ?? true,
          consoleLogging: config2?.consoleLogging ?? true,
          minLevel: config2?.minLevel ?? "INFO"
        };
      }
      formatTimestamp() {
        const timestamp2 = (/* @__PURE__ */ new Date()).toISOString();
        return `${colors.grey}${timestamp2}${colors.reset}`;
      }
      formatLevel(level, color) {
        return `${color}${level.padEnd(5)}${colors.reset}`;
      }
      formatSource(source2) {
        if (!source2) return "";
        return `${colors.grey}[${source2}]${colors.reset}`;
      }
      formatMeta(meta) {
        if (!meta) return "";
        return `${colors.grey}${JSON.stringify(meta)}${colors.reset}`;
      }
      /**
      * Get log file path with daily rotation (YYYY-MM-DD.log)
      */
      getLogFilePath() {
        const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
        return `${this.config.logsDir}/${date}.log`;
      }
      /**
      * Check if logging is enabled
      */
      isEnabled() {
        return logSettings.get().enabled === 1;
      }
      /**
      * Check if file logging is enabled
      */
      isFileLoggingEnabled() {
        return logSettings.get().file_logging === 1;
      }
      /**
      * Check if console logging is enabled
      */
      isConsoleLoggingEnabled() {
        return logSettings.get().console_logging === 1;
      }
      /**
      * Check if a log level should be logged based on minimum level
      */
      shouldLog(level) {
        if (!this.isEnabled()) return false;
        const currentMinLevel = logSettings.get().min_level;
        const levels = [
          "DEBUG",
          "INFO",
          "WARN",
          "ERROR"
        ];
        const minIndex = levels.indexOf(currentMinLevel);
        return levels.indexOf(level) >= minIndex;
      }
      async log(level, color, message2, options2) {
        if (!this.shouldLog(level)) return;
        const timestamp2 = (/* @__PURE__ */ new Date()).toISOString();
        if (this.isConsoleLoggingEnabled()) {
          const consoleParts = [
            this.formatTimestamp(),
            this.formatLevel(level, color),
            message2,
            options2?.source ? this.formatSource(options2.source) : "",
            options2?.meta ? this.formatMeta(options2.meta) : ""
          ].filter(Boolean);
          console.log(consoleParts.join(" | "));
        }
        if (this.isFileLoggingEnabled()) {
          const logEntry = {
            timestamp: timestamp2,
            level,
            message: message2,
            ...options2?.source ? { source: options2.source } : {},
            ...options2?.meta ? { meta: options2.meta } : {}
          };
          try {
            const filePath = this.getLogFilePath();
            try {
              await Deno.mkdir(this.config.logsDir, { recursive: true });
            } catch {
            }
            await Deno.writeTextFile(filePath, JSON.stringify(logEntry) + "\n", { append: true });
          } catch (error2) {
            console.error("Failed to write to log file:", error2);
          }
        }
      }
      async debug(message2, options2) {
        await this.log("DEBUG", colors.cyan, message2, options2);
      }
      async info(message2, options2) {
        await this.log("INFO", colors.green, message2, options2);
      }
      async warn(message2, options2) {
        await this.log("WARN", colors.yellow, message2, options2);
      }
      async error(message2, options2) {
        await this.log("ERROR", colors.red, message2, options2);
      }
      async errorWithTrace(message2, error2, options2) {
        await this.log("ERROR", colors.red, message2, options2);
        if (error2?.stack && this.isConsoleLoggingEnabled()) console.log(`${colors.grey}${error2.stack}${colors.reset}`);
        if (error2?.stack && this.isFileLoggingEnabled()) {
          const traceEntry = {
            timestamp: (/* @__PURE__ */ new Date()).toISOString(),
            level: "ERROR",
            message: "Stack trace",
            meta: { stack: error2.stack }
          };
          try {
            const filePath = this.getLogFilePath();
            await Deno.writeTextFile(filePath, JSON.stringify(traceEntry) + "\n", { append: true });
          } catch (writeError) {
            console.error("Failed to write stack trace to log file:", writeError);
          }
        }
      }
    };
    settings = logSettings.get();
    logger = new Logger({
      logsDir: config.paths.logs,
      enabled: settings.enabled === 1,
      fileLogging: settings.file_logging === 1,
      consoleLogging: settings.console_logging === 1,
      minLevel: settings.min_level
    });
    DatabaseManager = class {
      db = null;
      initialized = false;
      /**
      * Check if the database connection is healthy
      */
      isHealthy() {
        if (!this.db || !this.initialized) return false;
        try {
          this.db.prepare("SELECT 1").get();
          return true;
        } catch {
          return false;
        }
      }
      /**
      * Initialize the database connection
      */
      async initialize() {
        if (this.initialized && this.isHealthy()) return;
        if (this.initialized && !this.isHealthy()) {
          await logger.warn("Database connection unhealthy, reinitializing", {
            source: "DatabaseManager",
            meta: { path: config.paths.database }
          });
          this.close();
        }
        try {
          await Deno.mkdir(config.paths.data, { recursive: true });
          if (!await Deno.stat(config.paths.database).then(() => true).catch(() => false)) await logger.debug("Creating new database", {
            source: "DatabaseManager",
            meta: { path: config.paths.database }
          });
          this.db = new Database(config.paths.database);
          this.db.exec("PRAGMA foreign_keys = ON");
          this.db.exec("PRAGMA journal_mode = WAL");
          this.db.exec("PRAGMA synchronous = NORMAL");
          this.db.exec("PRAGMA busy_timeout = 5000");
          this.initialized = true;
          await logger.debug("Database initialized", {
            source: "DatabaseManager",
            meta: { path: config.paths.database }
          });
        } catch (error2) {
          const message2 = error2 instanceof Error ? error2.message : String(error2);
          await logger.error(`Failed to initialize database: ${message2}`, {
            source: "DatabaseManager",
            meta: error2
          });
          throw new Error(`Failed to initialize database: ${message2}`);
        }
      }
      /**
      * Get the database instance
      */
      getDatabase() {
        if (!this.db) throw new Error("Database not initialized. Call initialize() first.");
        return this.db;
      }
      /**
      * Execute a SQL statement
      */
      exec(sql2) {
        this.getDatabase().exec(sql2);
      }
      /**
      * Prepare a SQL statement
      */
      prepare(sql2) {
        return this.getDatabase().prepare(sql2);
      }
      /**
      * Run a query and return all results
      */
      query(sql2, ...params) {
        const stmt = this.prepare(sql2);
        if (params.length > 0) return stmt.all(...params);
        return stmt.all();
      }
      /**
      * Run a query and return the first result
      */
      queryFirst(sql2, ...params) {
        const stmt = this.prepare(sql2);
        if (params.length > 0) return stmt.get(...params);
        return stmt.get();
      }
      /**
      * Execute a statement and return the number of affected rows
      */
      execute(sql2, ...params) {
        const stmt = this.prepare(sql2);
        if (params.length > 0) stmt.run(...params);
        else stmt.run();
        return this.getDatabase().changes;
      }
      /**
      * Begin a transaction.
      *
      * Uses `BEGIN IMMEDIATE` so the write lock is acquired at BEGIN time
      * rather than on the first write. This avoids the deferred read→write
      * upgrade case where SQLite returns SQLITE_BUSY without invoking the
      * busy handler (because retrying with a stale snapshot would just
      * deadlock). With `busy_timeout = 5000` already set on the connection,
      * two concurrent writers serialize cleanly through the busy handler
      * instead of one failing immediately.
      */
      beginTransaction() {
        this.exec("BEGIN IMMEDIATE TRANSACTION");
      }
      /**
      * Commit a transaction
      */
      commit() {
        this.exec("COMMIT");
      }
      /**
      * Rollback a transaction
      */
      rollback() {
        this.exec("ROLLBACK");
      }
      /**
      * Run a function within a transaction
      */
      async transaction(fn) {
        this.beginTransaction();
        try {
          const result = await fn();
          this.commit();
          return result;
        } catch (error2) {
          this.rollback();
          await logger.error("Transaction rolled back due to error", {
            source: "DatabaseManager",
            meta: error2
          });
          throw error2;
        }
      }
      /**
      * Close the database connection
      */
      close() {
        if (this.db) {
          this.db.close();
          this.db = null;
          this.initialized = false;
        }
      }
    };
    db = new DatabaseManager();
  }
});

// dist/build/server/chunks/build.js
var build;
var init_build = __esm({
  "dist/build/server/chunks/build.js"() {
    "use strict";
    build = {
      version: "2.2.0",
      channel: "stable",
      commit: "unknown",
      builtAt: "2026-08-21T15:29:26Z"
    };
  }
});

// dist/build/server/chunks/client.js
var HttpError2, BaseHttpClient;
var init_client = __esm({
  "dist/build/server/chunks/client.js"() {
    "use strict";
    HttpError2 = class extends Error {
      status;
      response;
      constructor(message2, status, response) {
        super(message2);
        this.status = status;
        this.response = response;
        this.name = "HttpError";
      }
    };
    BaseHttpClient = class {
      baseUrl;
      defaultHeaders;
      timeout;
      retries;
      retryDelay;
      retryStatusCodes;
      httpClient;
      constructor(baseUrl, options2) {
        this.baseUrl = baseUrl.replace(/\/$/, "");
        this.timeout = options2?.timeout ?? 3e4;
        this.retries = options2?.retries ?? 3;
        this.retryDelay = options2?.retryDelay ?? 500;
        this.retryStatusCodes = options2?.retryStatusCodes ?? [
          500,
          502,
          503,
          504
        ];
        this.defaultHeaders = {
          "Content-Type": "application/json",
          ...options2?.headers
        };
        this.httpClient = Deno.createHttpClient({
          poolMaxIdlePerHost: options2?.poolMaxIdlePerHost ?? 5,
          poolIdleTimeout: options2?.poolIdleTimeout ?? 3e4
        });
      }
      /**
      * Sleep for specified milliseconds
      */
      sleep(ms) {
        return new Promise((resolve6) => setTimeout(resolve6, ms));
      }
      /**
      * Make an HTTP request with retry logic
      */
      async request(method, path, options2) {
        let lastError;
        for (let attempt = 0; attempt <= this.retries; attempt++) try {
          const url = `${this.baseUrl}${path}`;
          const timeout = options2?.timeout ?? this.timeout;
          const controller2 = new AbortController();
          const timeoutId = setTimeout(() => controller2.abort(), timeout);
          try {
            const headers2 = {
              ...this.defaultHeaders,
              ...options2?.headers
            };
            const response = await fetch(url, {
              method,
              headers: headers2,
              body: options2?.body ? JSON.stringify(options2.body) : void 0,
              signal: options2?.signal ?? controller2.signal,
              client: this.httpClient
            });
            clearTimeout(timeoutId);
            const text2 = await response.text();
            const responseType = options2?.responseType ?? "json";
            const data = responseType === "text" ? text2 : text2 ? JSON.parse(text2) : null;
            if (!response.ok) {
              const error2 = new HttpError2(`HTTP ${response.status}: ${response.statusText}`, response.status, responseType === "json" ? data : text2);
              if (this.retryStatusCodes.includes(response.status) && attempt < this.retries) {
                lastError = error2;
                const delay = this.retryDelay * Math.pow(2, attempt);
                await this.sleep(delay);
                continue;
              }
              throw error2;
            }
            return data;
          } catch (error2) {
            clearTimeout(timeoutId);
            if (error2 instanceof Error && error2.name === "AbortError") throw new HttpError2("Request timeout", 408);
            if (error2 instanceof HttpError2) throw error2;
            throw new HttpError2(error2 instanceof Error ? error2.message : "Unknown error", 0);
          }
        } catch (error2) {
          if (error2 instanceof HttpError2) {
            if (this.retryStatusCodes.includes(error2.status) && attempt < this.retries) {
              lastError = error2;
              const delay = this.retryDelay * Math.pow(2, attempt);
              await this.sleep(delay);
              continue;
            }
          }
          throw error2;
        }
        throw lastError ?? new HttpError2("Request failed after retries", 0);
      }
      /**
      * GET request
      */
      get(path, options2) {
        return this.request("GET", path, options2);
      }
      /**
      * POST request
      */
      post(path, body, options2) {
        return this.request("POST", path, {
          ...options2,
          body
        });
      }
      /**
      * PUT request
      */
      put(path, body, options2) {
        return this.request("PUT", path, {
          ...options2,
          body
        });
      }
      /**
      * DELETE request
      */
      delete(path, options2) {
        return this.request("DELETE", path, options2);
      }
      /**
      * PATCH request
      */
      patch(path, body, options2) {
        return this.request("PATCH", path, {
          ...options2,
          body
        });
      }
      /**
      * Close the HTTP client and cleanup resources
      */
      close() {
        this.httpClient.close();
      }
    };
  }
});

// dist/build/server/chunks/dates.js
function toUTC(timestamp2) {
  if (!timestamp2) return null;
  const trimmed = timestamp2.trim();
  if (/[+-]\d{2}:\d{2}$/.test(trimmed) || trimmed.endsWith("Z")) return trimmed;
  return trimmed.replace(" ", "T") + "Z";
}
function parseUTC(timestamp2) {
  const normalized = toUTC(timestamp2);
  if (!normalized) return null;
  return new Date(normalized);
}
function resolveDisplayArgs(dateFormatOrOptions, options2) {
  if (typeof dateFormatOrOptions === "string") return {
    dateFormat: dateFormatOrOptions,
    options: options2
  };
  return {
    dateFormat: "auto",
    options: dateFormatOrOptions
  };
}
function getDatePartOrder(dateFormat2) {
  if (dateFormat2 === "mdy") return [
    "month",
    "day",
    "year"
  ];
  if (dateFormat2 === "dmy") return [
    "day",
    "month",
    "year"
  ];
  if (dateFormat2 === "ymd") return [
    "year",
    "month",
    "day"
  ];
  const parts = new Intl.DateTimeFormat(void 0, {
    year: "numeric",
    month: "numeric",
    day: "numeric"
  }).formatToParts(new Date(Date.UTC(2006, 10, 22))).map((part) => part.type).filter((part) => part === "month" || part === "day" || part === "year");
  const uniqueParts = [...new Set(parts)];
  return uniqueParts.length === 3 ? uniqueParts : [
    "month",
    "day",
    "year"
  ];
}
function formatExplicitDate(date, timezone, dateFormat2) {
  const parts = new Intl.DateTimeFormat("en-US", {
    timeZone: timezone,
    year: "numeric",
    month: "2-digit",
    day: "2-digit"
  }).formatToParts(date);
  const values = Object.fromEntries(parts.map((part) => [part.type, part.value]));
  const year2 = values.year;
  const month = values.month;
  const day2 = values.day;
  if (dateFormat2 === "mdy") return `${month}/${day2}/${year2}`;
  if (dateFormat2 === "dmy") return `${day2}/${month}/${year2}`;
  return `${year2}-${month}-${day2}`;
}
function pickTimeOptions(options2) {
  if (!options2) return void 0;
  const timeOptions = {};
  let hasTimeOptions = false;
  if (options2.hour !== void 0) {
    timeOptions.hour = options2.hour;
    hasTimeOptions = true;
  }
  if (options2.minute !== void 0) {
    timeOptions.minute = options2.minute;
    hasTimeOptions = true;
  }
  if (options2.second !== void 0) {
    timeOptions.second = options2.second;
    hasTimeOptions = true;
  }
  if (options2.fractionalSecondDigits !== void 0) {
    timeOptions.fractionalSecondDigits = options2.fractionalSecondDigits;
    hasTimeOptions = true;
  }
  if (options2.hour12 !== void 0) {
    timeOptions.hour12 = options2.hour12;
    hasTimeOptions = true;
  }
  if (options2.hourCycle !== void 0) {
    timeOptions.hourCycle = options2.hourCycle;
    hasTimeOptions = true;
  }
  if (options2.timeZoneName !== void 0) {
    timeOptions.timeZoneName = options2.timeZoneName;
    hasTimeOptions = true;
  }
  return hasTimeOptions ? timeOptions : void 0;
}
function formatTime(date, timezone, options2) {
  return date.toLocaleTimeString(void 0, {
    timeZone: timezone,
    ...pickTimeOptions(options2)
  });
}
function formatDateTime(timestamp2, timezone, dateFormatOrOptions, options2) {
  if (!timestamp2) return "-";
  const date = new Date(timestamp2);
  if (Number.isNaN(date.getTime())) return "-";
  const args = resolveDisplayArgs(dateFormatOrOptions, options2);
  if (args.dateFormat === "auto") return date.toLocaleString(void 0, {
    timeZone: timezone,
    ...args.options
  });
  return `${formatExplicitDate(date, timezone, args.dateFormat)}, ${formatTime(date, timezone, args.options)}`;
}
function formatDate(timestamp2, timezone, dateFormatOrOptions, options2) {
  if (!timestamp2) return "-";
  const date = new Date(timestamp2);
  if (Number.isNaN(date.getTime())) return "-";
  const args = resolveDisplayArgs(dateFormatOrOptions, options2);
  if (args.dateFormat === "auto") return date.toLocaleDateString(void 0, {
    timeZone: timezone,
    ...args.options
  });
  return formatExplicitDate(date, timezone, args.dateFormat);
}
function formatSmartDateTime(timestamp2, timezone, dateFormat2 = "auto") {
  if (!timestamp2) return "-";
  const date = new Date(timestamp2);
  if (Number.isNaN(date.getTime())) return "-";
  const now = /* @__PURE__ */ new Date();
  const fmt = new Intl.DateTimeFormat("en-CA", { timeZone: timezone });
  const dateDay = fmt.format(date);
  const todayDay = fmt.format(now);
  const yesterday = /* @__PURE__ */ new Date(now.getTime() - 864e5);
  const yesterdayDay = fmt.format(yesterday);
  const timeStr = date.toLocaleTimeString(void 0, {
    timeZone: timezone,
    hour: "numeric",
    minute: "2-digit",
    hour12: true
  });
  if (dateDay === todayDay) return `Today, ${timeStr}`;
  if (dateDay === yesterdayDay) return `Yesterday, ${timeStr}`;
  return `${formatDate(timestamp2, timezone, dateFormat2, {
    month: "short",
    day: "numeric"
  })}, ${timeStr}`;
}
function formatRelative(timestamp2) {
  if (!timestamp2) return "-";
  const date = new Date(timestamp2);
  if (Number.isNaN(date.getTime())) return "-";
  const diff = date.getTime() - Date.now();
  const abs = Math.abs(diff);
  const past = diff < 0;
  const seconds = Math.floor(abs / 1e3);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);
  if (seconds < 10) return "just now";
  if (days > 0) return past ? `${days}d ago` : `in ${days}d`;
  if (hours > 0) return past ? `${hours}h ago` : `in ${hours}h`;
  if (minutes > 0) return past ? `${minutes}m ago` : `in ${minutes}m`;
  return past ? `${seconds}s ago` : `in ${seconds}s`;
}
var init_dates = __esm({
  "dist/build/server/chunks/dates.js"() {
    "use strict";
  }
});

// dist/build/server/chunks/arrSync.js
var arrSyncQueries;
var init_arrSync = __esm({
  async "dist/build/server/chunks/arrSync.js"() {
    "use strict";
    await init_db();
    init_dates();
    arrSyncQueries = {
      getQualityProfilesSync(instanceId) {
        const selectionRows = db.query("SELECT * FROM arr_sync_quality_profiles WHERE instance_id = ?", instanceId);
        const configRow = db.queryFirst("SELECT * FROM arr_sync_quality_profiles_config WHERE instance_id = ?", instanceId);
        return {
          selections: selectionRows.map((row) => ({
            databaseId: row.database_id,
            profileName: row.profile_name
          })),
          config: {
            trigger: configRow?.trigger ?? "manual",
            cron: configRow?.cron ?? null
          }
        };
      },
      saveQualityProfilesSync(instanceId, selections, config2) {
        db.execute("DELETE FROM arr_sync_quality_profiles WHERE instance_id = ?", instanceId);
        for (const sel of selections) db.execute("INSERT INTO arr_sync_quality_profiles (instance_id, database_id, profile_name) VALUES (?, ?, ?)", instanceId, sel.databaseId, sel.profileName);
        db.execute(`INSERT INTO arr_sync_quality_profiles_config (instance_id, trigger, cron, next_run_at)
			 VALUES (?, ?, ?, ?)
			 ON CONFLICT(instance_id) DO UPDATE SET trigger = ?, cron = ?, next_run_at = ?`, instanceId, config2.trigger, config2.cron, config2.nextRunAt ?? null, config2.trigger, config2.cron, config2.nextRunAt ?? null);
      },
      getDelayProfilesSync(instanceId) {
        const row = db.queryFirst("SELECT * FROM arr_sync_delay_profiles_config WHERE instance_id = ?", instanceId);
        return {
          databaseId: row?.database_id ?? null,
          profileName: row?.profile_name ?? null,
          trigger: row?.trigger ?? "manual",
          cron: row?.cron ?? null
        };
      },
      saveDelayProfilesSync(instanceId, data) {
        db.execute(`INSERT INTO arr_sync_delay_profiles_config
			 (instance_id, database_id, profile_name, trigger, cron, next_run_at)
			 VALUES (?, ?, ?, ?, ?, ?)
			 ON CONFLICT(instance_id) DO UPDATE SET
			 database_id = ?,
			 profile_name = ?,
			 trigger = ?,
			 cron = ?,
			 next_run_at = ?`, instanceId, data.databaseId, data.profileName, data.trigger, data.cron, data.nextRunAt ?? null, data.databaseId, data.profileName, data.trigger, data.cron, data.nextRunAt ?? null);
      },
      getMediaManagementSync(instanceId) {
        const row = db.queryFirst("SELECT * FROM arr_sync_media_management WHERE instance_id = ?", instanceId);
        return {
          namingDatabaseId: row?.naming_database_id ?? null,
          namingConfigName: row?.naming_config_name ?? null,
          qualityDefinitionsDatabaseId: row?.quality_definitions_database_id ?? null,
          qualityDefinitionsConfigName: row?.quality_definitions_config_name ?? null,
          mediaSettingsDatabaseId: row?.media_settings_database_id ?? null,
          mediaSettingsConfigName: row?.media_settings_config_name ?? null,
          trigger: row?.trigger ?? "manual",
          cron: row?.cron ?? null
        };
      },
      saveMediaManagementSync(instanceId, data) {
        db.execute(`INSERT INTO arr_sync_media_management
			 (instance_id, naming_database_id, naming_config_name, quality_definitions_database_id, quality_definitions_config_name, media_settings_database_id, media_settings_config_name, trigger, cron, next_run_at)
			 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
			 ON CONFLICT(instance_id) DO UPDATE SET
			 naming_database_id = ?,
			 naming_config_name = ?,
			 quality_definitions_database_id = ?,
			 quality_definitions_config_name = ?,
			 media_settings_database_id = ?,
			 media_settings_config_name = ?,
			 trigger = ?,
			 cron = ?,
			 next_run_at = ?`, instanceId, data.namingDatabaseId, data.namingConfigName, data.qualityDefinitionsDatabaseId, data.qualityDefinitionsConfigName, data.mediaSettingsDatabaseId, data.mediaSettingsConfigName, data.trigger, data.cron, data.nextRunAt ?? null, data.namingDatabaseId, data.namingConfigName, data.qualityDefinitionsDatabaseId, data.qualityDefinitionsConfigName, data.mediaSettingsDatabaseId, data.mediaSettingsConfigName, data.trigger, data.cron, data.nextRunAt ?? null);
      },
      getFullSyncData(instanceId) {
        return {
          qualityProfiles: this.getQualityProfilesSync(instanceId),
          delayProfiles: this.getDelayProfilesSync(instanceId),
          mediaManagement: this.getMediaManagementSync(instanceId)
        };
      },
      /**
      * Remove orphaned profile references when a profile is deleted
      */
      removeQualityProfileReference(profileName2) {
        return db.execute("DELETE FROM arr_sync_quality_profiles WHERE profile_name = ?", profileName2);
      },
      updateQualityProfileName(oldName, newName) {
        return db.execute("UPDATE arr_sync_quality_profiles SET profile_name = ? WHERE profile_name = ?", newName, oldName);
      },
      removeDelayProfileReference(profileName2) {
        return db.execute("UPDATE arr_sync_delay_profiles_config SET database_id = NULL, profile_name = NULL WHERE profile_name = ?", profileName2);
      },
      updateDelayProfileName(oldName, newName) {
        return db.execute("UPDATE arr_sync_delay_profiles_config SET profile_name = ? WHERE profile_name = ?", newName, oldName);
      },
      /**
      * Update config name references when a media management config is renamed
      */
      updateNamingConfigName(oldName, newName) {
        return db.execute("UPDATE arr_sync_media_management SET naming_config_name = ? WHERE naming_config_name = ?", newName, oldName);
      },
      updateQualityDefinitionsConfigName(oldName, newName) {
        return db.execute("UPDATE arr_sync_media_management SET quality_definitions_config_name = ? WHERE quality_definitions_config_name = ?", newName, oldName);
      },
      updateMediaSettingsConfigName(oldName, newName) {
        return db.execute("UPDATE arr_sync_media_management SET media_settings_config_name = ? WHERE media_settings_config_name = ?", newName, oldName);
      },
      /**
      * Remove all references to a database (when database is deleted)
      */
      removeDatabaseReferences(databaseId) {
        db.execute("DELETE FROM arr_sync_quality_profiles WHERE database_id = ?", databaseId);
        db.execute("UPDATE arr_sync_delay_profiles_config SET database_id = NULL, profile_name = NULL WHERE database_id = ?", databaseId);
        db.execute("UPDATE arr_sync_media_management SET naming_database_id = NULL, naming_config_name = NULL WHERE naming_database_id = ?", databaseId);
        db.execute("UPDATE arr_sync_media_management SET quality_definitions_database_id = NULL, quality_definitions_config_name = NULL WHERE quality_definitions_database_id = ?", databaseId);
        db.execute("UPDATE arr_sync_media_management SET media_settings_database_id = NULL, media_settings_config_name = NULL WHERE media_settings_database_id = ?", databaseId);
      },
      /**
      * Set should_sync flag for quality profiles
      */
      setQualityProfilesShouldSync(instanceId, shouldSync) {
        db.execute("UPDATE arr_sync_quality_profiles_config SET should_sync = ? WHERE instance_id = ?", shouldSync ? 1 : 0, instanceId);
      },
      /**
      * Set should_sync flag for delay profiles
      */
      setDelayProfilesShouldSync(instanceId, shouldSync) {
        db.execute("UPDATE arr_sync_delay_profiles_config SET should_sync = ? WHERE instance_id = ?", shouldSync ? 1 : 0, instanceId);
      },
      /**
      * Set should_sync flag for media management
      */
      setMediaManagementShouldSync(instanceId, shouldSync) {
        db.execute("UPDATE arr_sync_media_management SET should_sync = ? WHERE instance_id = ?", shouldSync ? 1 : 0, instanceId);
      },
      /**
      * Mark all configs with a specific trigger as should_sync
      * Used when events occur (pull, change)
      * Also sets sync_status to 'pending' for the new status-based flow
      */
      markForSync(trigger) {
        db.execute(`UPDATE arr_sync_quality_profiles_config SET should_sync = 1, sync_status = 'pending' WHERE trigger = ?`, trigger);
        db.execute(`UPDATE arr_sync_delay_profiles_config SET should_sync = 1, sync_status = 'pending' WHERE trigger = ?`, trigger);
        db.execute(`UPDATE arr_sync_media_management SET should_sync = 1, sync_status = 'pending' WHERE trigger = ?`, trigger);
      },
      /**
      * Get all configs that need syncing (should_sync = true)
      */
      getPendingSyncs() {
        const qp = db.query("SELECT instance_id FROM arr_sync_quality_profiles_config WHERE should_sync = 1");
        const dp = db.query("SELECT instance_id FROM arr_sync_delay_profiles_config WHERE should_sync = 1");
        const mm = db.query("SELECT instance_id FROM arr_sync_media_management WHERE should_sync = 1");
        return {
          qualityProfiles: qp.map((r2) => r2.instance_id),
          delayProfiles: dp.map((r2) => r2.instance_id),
          mediaManagement: mm.map((r2) => r2.instance_id)
        };
      },
      /**
      * Get all scheduled configs that haven't been marked for sync yet
      */
      getScheduledConfigs() {
        const qp = db.query("SELECT instance_id, cron, next_run_at FROM arr_sync_quality_profiles_config WHERE trigger = 'schedule' AND should_sync = 0");
        const dp = db.query("SELECT instance_id, cron, next_run_at FROM arr_sync_delay_profiles_config WHERE trigger = 'schedule' AND should_sync = 0");
        const mm = db.query("SELECT instance_id, cron, next_run_at FROM arr_sync_media_management WHERE trigger = 'schedule' AND should_sync = 0");
        return {
          qualityProfiles: qp.map((r2) => ({
            instanceId: r2.instance_id,
            cron: r2.cron,
            nextRunAt: toUTC(r2.next_run_at)
          })),
          delayProfiles: dp.map((r2) => ({
            instanceId: r2.instance_id,
            cron: r2.cron,
            nextRunAt: toUTC(r2.next_run_at)
          })),
          mediaManagement: mm.map((r2) => ({
            instanceId: r2.instance_id,
            cron: r2.cron,
            nextRunAt: toUTC(r2.next_run_at)
          }))
        };
      },
      /**
      * Update next_run_at for a quality profiles config
      */
      setQualityProfilesNextRunAt(instanceId, nextRunAt) {
        db.execute("UPDATE arr_sync_quality_profiles_config SET next_run_at = ? WHERE instance_id = ?", nextRunAt, instanceId);
      },
      /**
      * Update next_run_at for a delay profiles config
      */
      setDelayProfilesNextRunAt(instanceId, nextRunAt) {
        db.execute("UPDATE arr_sync_delay_profiles_config SET next_run_at = ? WHERE instance_id = ?", nextRunAt, instanceId);
      },
      /**
      * Update next_run_at for a media management config
      */
      setMediaManagementNextRunAt(instanceId, nextRunAt) {
        db.execute("UPDATE arr_sync_media_management SET next_run_at = ? WHERE instance_id = ?", nextRunAt, instanceId);
      },
      /**
      * Atomically claim a sync for processing
      * Returns true if claim succeeded (status was 'pending' and is now 'in_progress')
      */
      claimQualityProfilesSync(instanceId) {
        return db.execute("UPDATE arr_sync_quality_profiles_config SET sync_status = 'in_progress' WHERE instance_id = ? AND sync_status = 'pending'", instanceId) > 0;
      },
      claimDelayProfilesSync(instanceId) {
        return db.execute("UPDATE arr_sync_delay_profiles_config SET sync_status = 'in_progress' WHERE instance_id = ? AND sync_status = 'pending'", instanceId) > 0;
      },
      claimMediaManagementSync(instanceId) {
        return db.execute("UPDATE arr_sync_media_management SET sync_status = 'in_progress' WHERE instance_id = ? AND sync_status = 'pending'", instanceId) > 0;
      },
      /**
      * Mark sync as completed successfully
      */
      completeQualityProfilesSync(instanceId) {
        db.execute("UPDATE arr_sync_quality_profiles_config SET sync_status = 'idle', should_sync = 0, last_error = NULL, last_synced_at = ? WHERE instance_id = ?", (/* @__PURE__ */ new Date()).toISOString(), instanceId);
      },
      completeDelayProfilesSync(instanceId) {
        db.execute("UPDATE arr_sync_delay_profiles_config SET sync_status = 'idle', should_sync = 0, last_error = NULL, last_synced_at = ? WHERE instance_id = ?", (/* @__PURE__ */ new Date()).toISOString(), instanceId);
      },
      completeMediaManagementSync(instanceId) {
        db.execute("UPDATE arr_sync_media_management SET sync_status = 'idle', should_sync = 0, last_error = NULL, last_synced_at = ? WHERE instance_id = ?", (/* @__PURE__ */ new Date()).toISOString(), instanceId);
      },
      /**
      * Mark sync as failed
      */
      failQualityProfilesSync(instanceId, error2) {
        db.execute("UPDATE arr_sync_quality_profiles_config SET sync_status = 'failed', should_sync = 0, last_error = ? WHERE instance_id = ?", error2, instanceId);
      },
      failDelayProfilesSync(instanceId, error2) {
        db.execute("UPDATE arr_sync_delay_profiles_config SET sync_status = 'failed', should_sync = 0, last_error = ? WHERE instance_id = ?", error2, instanceId);
      },
      failMediaManagementSync(instanceId, error2) {
        db.execute("UPDATE arr_sync_media_management SET sync_status = 'failed', should_sync = 0, last_error = ? WHERE instance_id = ?", error2, instanceId);
      },
      /**
      * Set sync status to pending (used by markForSync and triggers)
      */
      setQualityProfilesStatusPending(instanceId) {
        db.execute("UPDATE arr_sync_quality_profiles_config SET sync_status = 'pending', should_sync = 1 WHERE instance_id = ?", instanceId);
      },
      setDelayProfilesStatusPending(instanceId) {
        db.execute("UPDATE arr_sync_delay_profiles_config SET sync_status = 'pending', should_sync = 1 WHERE instance_id = ?", instanceId);
      },
      setMediaManagementStatusPending(instanceId) {
        db.execute("UPDATE arr_sync_media_management SET sync_status = 'pending', should_sync = 1 WHERE instance_id = ?", instanceId);
      },
      /**
      * Get pending syncs by status (uses new sync_status column)
      */
      getPendingSyncsByStatus() {
        const qp = db.query("SELECT instance_id FROM arr_sync_quality_profiles_config WHERE sync_status = 'pending'");
        const dp = db.query("SELECT instance_id FROM arr_sync_delay_profiles_config WHERE sync_status = 'pending'");
        const mm = db.query("SELECT instance_id FROM arr_sync_media_management WHERE sync_status = 'pending'");
        return {
          qualityProfiles: qp.map((r2) => r2.instance_id),
          delayProfiles: dp.map((r2) => r2.instance_id),
          mediaManagement: mm.map((r2) => r2.instance_id)
        };
      },
      /**
      * Reset any pending/in_progress syncs back to idle on startup.
      * If the server restarted, the jobs that were supposed to process
      * these are gone — neither state is valid anymore.
      */
      recoverInterruptedSyncs() {
        let count = 0;
        count += db.execute("UPDATE arr_sync_quality_profiles_config SET sync_status = 'idle' WHERE sync_status IN ('pending', 'in_progress')");
        count += db.execute("UPDATE arr_sync_delay_profiles_config SET sync_status = 'idle' WHERE sync_status IN ('pending', 'in_progress')");
        count += db.execute("UPDATE arr_sync_media_management SET sync_status = 'idle' WHERE sync_status IN ('pending', 'in_progress')");
        return count;
      },
      /**
      * Check if any sync configs have a scheduled (cron) trigger
      * Used to determine if any arr.sync scheduled jobs should be enabled
      */
      hasAnyScheduledConfigs() {
        return (db.queryFirst(`
			SELECT COUNT(*) as count FROM (
				SELECT 1 FROM arr_sync_quality_profiles_config WHERE trigger = 'schedule'
				UNION ALL
				SELECT 1 FROM arr_sync_delay_profiles_config WHERE trigger = 'schedule'
				UNION ALL
				SELECT 1 FROM arr_sync_media_management WHERE trigger = 'schedule'
			)
		`)?.count ?? 0) > 0;
      },
      getSyncConfigStatus(instanceId) {
        const qp = db.queryFirst("SELECT trigger, cron, next_run_at, sync_status FROM arr_sync_quality_profiles_config WHERE instance_id = ?", instanceId);
        const dp = db.queryFirst("SELECT trigger, cron, next_run_at, sync_status FROM arr_sync_delay_profiles_config WHERE instance_id = ?", instanceId);
        const mm = db.queryFirst("SELECT trigger, cron, next_run_at, sync_status FROM arr_sync_media_management WHERE instance_id = ?", instanceId);
        return {
          qualityProfiles: {
            trigger: qp?.trigger ?? "manual",
            cron: qp?.cron ?? null,
            nextRunAt: qp?.next_run_at ?? null,
            syncStatus: qp?.sync_status ?? "idle"
          },
          delayProfiles: {
            trigger: dp?.trigger ?? "manual",
            cron: dp?.cron ?? null,
            nextRunAt: dp?.next_run_at ?? null,
            syncStatus: dp?.sync_status ?? "idle"
          },
          mediaManagement: {
            trigger: mm?.trigger ?? "manual",
            cron: mm?.cron ?? null,
            nextRunAt: mm?.next_run_at ?? null,
            syncStatus: mm?.sync_status ?? "idle"
          }
        };
      },
      getNextScheduledRunAt(instanceId) {
        const candidates = db.query(`SELECT next_run_at FROM arr_sync_quality_profiles_config WHERE instance_id = ? AND trigger = 'schedule'
			 UNION ALL
			 SELECT next_run_at FROM arr_sync_delay_profiles_config WHERE instance_id = ? AND trigger = 'schedule'
			 UNION ALL
			 SELECT next_run_at FROM arr_sync_media_management WHERE instance_id = ? AND trigger = 'schedule'`, instanceId, instanceId, instanceId).map((row) => row.next_run_at).filter((value2) => !!value2);
        if (candidates.length === 0) return null;
        return candidates.reduce((earliest, current3) => new Date(current3) < new Date(earliest) ? current3 : earliest);
      },
      /**
      * Record that an entity sync completed for a section (updates timestamp only)
      */
      touchSectionLastSynced(instanceId, section) {
        const table2 = {
          qualityProfiles: "arr_sync_quality_profiles_config",
          delayProfiles: "arr_sync_delay_profiles_config",
          mediaManagement: "arr_sync_media_management"
        }[section];
        db.execute(`UPDATE ${table2} SET last_synced_at = ? WHERE instance_id = ?`, (/* @__PURE__ */ new Date()).toISOString(), instanceId);
      },
      /**
      * Get sync status and timing for a specific section of an instance
      */
      getSectionSyncStatus(instanceId, section) {
        const table2 = {
          qualityProfiles: "arr_sync_quality_profiles_config",
          delayProfiles: "arr_sync_delay_profiles_config",
          mediaManagement: "arr_sync_media_management"
        }[section];
        return db.queryFirst(`SELECT sync_status, last_synced_at FROM ${table2} WHERE instance_id = ?`, instanceId);
      },
      /**
      * Get arr instances that sync a specific quality profile from a specific database
      */
      getInstancesForQualityProfile(databaseId, profileName2) {
        return db.query(`SELECT DISTINCT
				ai.id AS instance_id,
				ai.name AS instance_name,
				qpc.sync_status,
				qpc.last_synced_at
			FROM arr_sync_quality_profiles aqp
			JOIN arr_instances ai ON ai.id = aqp.instance_id
			JOIN arr_sync_quality_profiles_config qpc ON qpc.instance_id = aqp.instance_id
			WHERE aqp.database_id = ? AND aqp.profile_name = ? AND ai.enabled = 1`, databaseId, profileName2);
      },
      getInstancesForNaming(databaseId, configName) {
        return db.query(`SELECT DISTINCT
				ai.id AS instance_id,
				ai.name AS instance_name,
				mm.sync_status,
				mm.last_synced_at
			FROM arr_sync_media_management mm
			JOIN arr_instances ai ON ai.id = mm.instance_id
			WHERE mm.naming_database_id = ? AND mm.naming_config_name = ? AND ai.enabled = 1`, databaseId, configName);
      },
      getInstancesForDelayProfile(databaseId, profileName2) {
        return db.query(`SELECT DISTINCT
				ai.id AS instance_id,
				ai.name AS instance_name,
				dpc.sync_status,
				dpc.last_synced_at
			FROM arr_sync_delay_profiles_config dpc
			JOIN arr_instances ai ON ai.id = dpc.instance_id
			WHERE dpc.database_id = ? AND dpc.profile_name = ? AND ai.enabled = 1`, databaseId, profileName2);
      },
      getInstancesForMediaSettings(databaseId, configName) {
        return db.query(`SELECT DISTINCT
				ai.id AS instance_id,
				ai.name AS instance_name,
				mm.sync_status,
				mm.last_synced_at
			FROM arr_sync_media_management mm
			JOIN arr_instances ai ON ai.id = mm.instance_id
			WHERE mm.media_settings_database_id = ? AND mm.media_settings_config_name = ? AND ai.enabled = 1`, databaseId, configName);
      },
      getInstancesForQualityDefinitions(databaseId, configName) {
        return db.query(`SELECT DISTINCT
				ai.id AS instance_id,
				ai.name AS instance_name,
				mm.sync_status,
				mm.last_synced_at
			FROM arr_sync_media_management mm
			JOIN arr_instances ai ON ai.id = mm.instance_id
			WHERE mm.quality_definitions_database_id = ? AND mm.quality_definitions_config_name = ? AND ai.enabled = 1`, databaseId, configName);
      },
      getDatabasePriorities(instanceId) {
        return db.query(`SELECT database_id, priority FROM arr_sync_database_priority
			 WHERE instance_id = ? ORDER BY priority ASC`, instanceId).map((row) => ({
          databaseId: row.database_id,
          priority: row.priority
        }));
      },
      async saveDatabasePriorities(instanceId, priorities) {
        await db.transaction(() => {
          db.execute("DELETE FROM arr_sync_database_priority WHERE instance_id = ?", instanceId);
          for (const { databaseId, priority } of priorities) db.execute("INSERT INTO arr_sync_database_priority (instance_id, database_id, priority) VALUES (?, ?, ?)", instanceId, databaseId, priority);
        });
      },
      ensureAllDatabasePriorities(databaseId) {
        db.execute(`INSERT INTO arr_sync_database_priority (instance_id, database_id, priority)
			 SELECT ai.id, ?,
				COALESCE((SELECT MAX(priority) FROM arr_sync_database_priority WHERE instance_id = ai.id), 0) + 1
			 FROM arr_instances ai
			 WHERE NOT EXISTS (
				SELECT 1 FROM arr_sync_database_priority
				WHERE instance_id = ai.id AND database_id = ?
			 )`, databaseId, databaseId);
      },
      ensureAllInstancePriorities(instanceId) {
        db.execute(`INSERT INTO arr_sync_database_priority (instance_id, database_id, priority)
			 SELECT ?, di.id, ROW_NUMBER() OVER (ORDER BY di.id)
			 FROM database_instances di
			 WHERE NOT EXISTS (
				SELECT 1 FROM arr_sync_database_priority
				WHERE instance_id = ? AND database_id = di.id
			 )`, instanceId, instanceId);
      },
      getInstanceIdsForTrigger(trigger) {
        return db.query(`SELECT instance_id FROM arr_sync_quality_profiles_config WHERE trigger = ?
			 UNION
			 SELECT instance_id FROM arr_sync_delay_profiles_config WHERE trigger = ?
			 UNION
			 SELECT instance_id FROM arr_sync_media_management WHERE trigger = ?`, trigger, trigger, trigger).map((row) => row.instance_id);
      }
    };
  }
});

// dist/build/server/chunks/databaseInstances.js
function rowToInstance(row) {
  return {
    ...row,
    last_synced_at: toUTC(row.last_synced_at),
    created_at: toUTC(row.created_at),
    updated_at: toUTC(row.updated_at)
  };
}
function disableDatabaseInstance(id) {
  return databaseInstancesQueries.disable(id);
}
var databaseInstancesQueries;
var init_databaseInstances = __esm({
  async "dist/build/server/chunks/databaseInstances.js"() {
    "use strict";
    await init_db();
    init_dates();
    await init_arrSync();
    databaseInstancesQueries = {
      /**
      * Create a new database instance
      */
      create(input) {
        const syncStrategy = input.syncStrategy ?? 0;
        const autoPull = input.autoPull !== false ? 1 : 0;
        const enabled3 = input.enabled !== false ? 1 : 0;
        const personalAccessToken = input.personalAccessToken || null;
        const isPrivate = input.isPrivate ? 1 : 0;
        const localOpsEnabled = input.localOpsEnabled ? 1 : 0;
        const gitUserName = input.gitUserName || null;
        const gitUserEmail = input.gitUserEmail || null;
        const conflictStrategy = input.conflictStrategy ?? "override";
        db.execute(`INSERT INTO database_instances (
				uuid,
				name,
				repository_url,
				local_path,
				sync_strategy,
				auto_pull,
				enabled,
				personal_access_token,
				is_private,
				local_ops_enabled,
				git_user_name,
				git_user_email,
				conflict_strategy
			) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, input.uuid, input.name, input.repositoryUrl, input.localPath, syncStrategy, autoPull, enabled3, personalAccessToken, isPrivate, localOpsEnabled, gitUserName, gitUserEmail, conflictStrategy);
        const id = db.queryFirst("SELECT last_insert_rowid() as id")?.id ?? 0;
        if (id > 0) arrSyncQueries.ensureAllDatabasePriorities(id);
        return id;
      },
      /**
      * Get a database instance by ID
      */
      getById(id) {
        const row = db.queryFirst("SELECT * FROM database_instances WHERE id = ?", id);
        return row ? rowToInstance(row) : void 0;
      },
      /**
      * Get a database instance by UUID
      */
      getByUuid(uuid2) {
        const row = db.queryFirst("SELECT * FROM database_instances WHERE uuid = ?", uuid2);
        return row ? rowToInstance(row) : void 0;
      },
      /**
      * Get all database instances
      */
      getAll() {
        return db.query("SELECT * FROM database_instances ORDER BY name").map(rowToInstance);
      },
      /**
      * Get enabled database instances
      */
      getEnabled() {
        return db.query("SELECT * FROM database_instances WHERE enabled = 1 ORDER BY name").map(rowToInstance);
      },
      /**
      * Get databases that need auto-sync check
      * Note: last_synced_at may be ISO format (with T and Z), normalize for datetime()
      */
      getDueForSync() {
        return db.query(`SELECT * FROM database_instances
       WHERE enabled = 1
       AND sync_strategy > 0
       AND (
         last_synced_at IS NULL
         OR datetime(replace(replace(last_synced_at, 'T', ' '), 'Z', ''), '+' || sync_strategy || ' minutes') <= datetime('now')
       )
       ORDER BY last_synced_at ASC NULLS FIRST`).map(rowToInstance);
      },
      /**
      * Update a database instance
      */
      update(id, input) {
        const updates = [];
        const params = [];
        if (input.name !== void 0) {
          updates.push("name = ?");
          params.push(input.name);
        }
        if (input.repositoryUrl !== void 0) {
          updates.push("repository_url = ?");
          params.push(input.repositoryUrl);
        }
        if (input.syncStrategy !== void 0) {
          updates.push("sync_strategy = ?");
          params.push(input.syncStrategy);
        }
        if (input.autoPull !== void 0) {
          updates.push("auto_pull = ?");
          params.push(input.autoPull ? 1 : 0);
        }
        if (input.enabled !== void 0) {
          updates.push("enabled = ?");
          params.push(input.enabled ? 1 : 0);
        }
        if (input.personalAccessToken !== void 0) {
          updates.push("personal_access_token = ?");
          params.push(input.personalAccessToken || null);
        }
        if (input.localOpsEnabled !== void 0) {
          updates.push("local_ops_enabled = ?");
          params.push(input.localOpsEnabled ? 1 : 0);
        }
        if (input.gitUserName !== void 0) {
          updates.push("git_user_name = ?");
          params.push(input.gitUserName || null);
        }
        if (input.gitUserEmail !== void 0) {
          updates.push("git_user_email = ?");
          params.push(input.gitUserEmail || null);
        }
        if (input.conflictStrategy !== void 0) {
          updates.push("conflict_strategy = ?");
          params.push(input.conflictStrategy);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(id);
        return db.execute(`UPDATE database_instances SET ${updates.join(", ")} WHERE id = ?`, ...params) > 0;
      },
      /**
      * Update last_synced_at timestamp
      */
      updateSyncedAt(id) {
        return db.execute("UPDATE database_instances SET last_synced_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE id = ?", id) > 0;
      },
      /**
      * Delete a database instance
      */
      delete(id) {
        return db.execute("DELETE FROM database_instances WHERE id = ?", id) > 0;
      },
      /**
      * Check if a database name already exists
      */
      nameExists(name, excludeId) {
        if (excludeId !== void 0) return (db.queryFirst("SELECT COUNT(*) as count FROM database_instances WHERE name = ? AND id != ?", name, excludeId)?.count ?? 0) > 0;
        return (db.queryFirst("SELECT COUNT(*) as count FROM database_instances WHERE name = ?", name)?.count ?? 0) > 0;
      },
      /**
      * Disable a database instance (set enabled = 0)
      */
      disable(id) {
        return db.execute("UPDATE database_instances SET enabled = 0, updated_at = CURRENT_TIMESTAMP WHERE id = ?", id) > 0;
      }
    };
  }
});

// dist/build/server/chunks/notificationServices.js
var notificationServicesQueries;
var init_notificationServices = __esm({
  async "dist/build/server/chunks/notificationServices.js"() {
    "use strict";
    await init_db();
    notificationServicesQueries = {
      /**
      * Get all notification services
      */
      getAll() {
        return db.query("SELECT * FROM notification_services ORDER BY created_at DESC");
      },
      /**
      * Get all enabled notification services
      */
      getAllEnabled() {
        return db.query("SELECT * FROM notification_services WHERE enabled = 1 ORDER BY created_at DESC");
      },
      /**
      * Get notification service by ID
      */
      getById(id) {
        return db.queryFirst("SELECT * FROM notification_services WHERE id = ?", id);
      },
      /**
      * Get notification services by type
      */
      getByType(serviceType) {
        return db.query("SELECT * FROM notification_services WHERE service_type = ? ORDER BY created_at DESC", serviceType);
      },
      /**
      * Create a new notification service
      */
      create(input) {
        return db.execute(`INSERT INTO notification_services (
				id, name, service_type, enabled, config, enabled_types
			) VALUES (?, ?, ?, ?, ?, ?)`, input.id, input.name, input.serviceType, input.enabled ? 1 : 0, JSON.stringify(input.config), JSON.stringify(input.enabledTypes)) > 0;
      },
      /**
      * Update a notification service
      */
      update(id, input) {
        const updates = [];
        const params = [];
        if (input.name !== void 0) {
          updates.push("name = ?");
          params.push(input.name);
        }
        if (input.enabled !== void 0) {
          updates.push("enabled = ?");
          params.push(input.enabled ? 1 : 0);
        }
        if (input.config !== void 0) {
          updates.push("config = ?");
          params.push(JSON.stringify(input.config));
        }
        if (input.enabledTypes !== void 0) {
          updates.push("enabled_types = ?");
          params.push(JSON.stringify(input.enabledTypes));
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(id);
        return db.execute(`UPDATE notification_services SET ${updates.join(", ")} WHERE id = ?`, ...params) > 0;
      },
      /**
      * Delete a notification service
      */
      delete(id) {
        return db.execute("DELETE FROM notification_services WHERE id = ?", id) > 0;
      },
      /**
      * Check if a service name already exists (case-insensitive)
      */
      existsByName(name, excludeId) {
        if (excludeId) return (db.queryFirst("SELECT COUNT(*) as count FROM notification_services WHERE LOWER(name) = LOWER(?) AND id != ?", name, excludeId)?.count ?? 0) > 0;
        return (db.queryFirst("SELECT COUNT(*) as count FROM notification_services WHERE LOWER(name) = LOWER(?)", name)?.count ?? 0) > 0;
      }
    };
  }
});

// dist/build/server/chunks/notificationHistory.js
function rowToRecord(row) {
  return {
    ...row,
    sent_at: toUTC(row.sent_at)
  };
}
var notificationHistoryQueries;
var init_notificationHistory = __esm({
  async "dist/build/server/chunks/notificationHistory.js"() {
    "use strict";
    await init_db();
    init_dates();
    notificationHistoryQueries = {
      /**
      * Create a new notification history record
      */
      create(input) {
        return db.execute(`INSERT INTO notification_history (
				service_id, notification_type, title, message, metadata, status, error
			) VALUES (?, ?, ?, ?, ?, ?, ?)`, input.serviceId, input.notificationType, input.title, input.message, input.metadata ? JSON.stringify(input.metadata) : null, input.status, input.error ?? null) > 0;
      },
      /**
      * Get notification history with optional filters
      */
      getHistory(filters) {
        const conditions = [];
        const params = [];
        if (filters?.serviceId) {
          conditions.push("service_id = ?");
          params.push(filters.serviceId);
        }
        if (filters?.notificationType) {
          conditions.push("notification_type = ?");
          params.push(filters.notificationType);
        }
        if (filters?.status) {
          conditions.push("status = ?");
          params.push(filters.status);
        }
        const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
        const limit = filters?.limit ?? 100;
        const offset = filters?.offset ?? 0;
        return db.query(`SELECT * FROM notification_history ${whereClause} ORDER BY sent_at DESC LIMIT ? OFFSET ?`, ...params, limit, offset).map(rowToRecord);
      },
      /**
      * Get recent notification history (last 50 by default)
      */
      getRecent(limit = 50) {
        return db.query("SELECT * FROM notification_history ORDER BY sent_at DESC LIMIT ?", limit).map(rowToRecord);
      },
      /**
      * Get notification history for a specific service
      */
      getByServiceId(serviceId, limit = 50) {
        return db.query("SELECT * FROM notification_history WHERE service_id = ? ORDER BY sent_at DESC LIMIT ?", serviceId, limit).map(rowToRecord);
      },
      /**
      * Get notification history by type
      */
      getByType(notificationType, limit = 50) {
        return db.query("SELECT * FROM notification_history WHERE notification_type = ? ORDER BY sent_at DESC LIMIT ?", notificationType, limit).map(rowToRecord);
      },
      /**
      * Get failed notifications
      */
      getFailed(limit = 50) {
        return db.query("SELECT * FROM notification_history WHERE status = 'failed' ORDER BY sent_at DESC LIMIT ?", limit).map(rowToRecord);
      },
      /**
      * Get statistics for a service
      */
      getStats(serviceId) {
        const whereClause = serviceId ? "WHERE service_id = ?" : "";
        const params = serviceId ? [serviceId] : [];
        const result = db.queryFirst(`SELECT
				COUNT(*) as total,
				SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as success,
				SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed
			FROM notification_history ${whereClause}`, ...params);
        if (!result || result.total === 0) return {
          total: 0,
          success: 0,
          failed: 0,
          successRate: 0
        };
        return {
          total: result.total,
          success: result.success,
          failed: result.failed,
          successRate: result.success / result.total * 100
        };
      },
      /**
      * Delete old notification history records
      */
      deleteOlderThan(days) {
        return db.execute(`DELETE FROM notification_history
			WHERE sent_at < datetime('now', '-' || ? || ' days')`, days);
      },
      /**
      * Delete all history for a specific service (used when service is deleted)
      */
      deleteByServiceId(serviceId) {
        return db.execute("DELETE FROM notification_history WHERE service_id = ?", serviceId);
      }
    };
  }
});

// dist/build/server/chunks/NotificationManager.js
function getWebhookClient() {
  if (!webhookClient) webhookClient = new WebhookClient();
  return webhookClient;
}
function getEmbedCharCount(embed) {
  let size = 0;
  if (embed.author?.name) size += embed.author.name.length;
  if (embed.title) size += embed.title.length;
  if (embed.description) size += embed.description.length;
  if (embed.footer?.text) size += embed.footer.text.length;
  if (embed.fields) for (const field of embed.fields) size += field.name.length + field.value.length;
  return size;
}
var Colors, WebhookClient, webhookClient, RATE_LIMIT_DELAY, MAX_EMBED_SIZE, MAX_FIELDS_PER_EMBED, MAX_FIELD_VALUE, MAX_FIELD_NAME, DiscordNotifier, NtfyNotifier, WebhookNotifier, TELEGRAM_API, MAX_MESSAGE_LENGTH, TelegramNotifier, NotificationManager, notificationManager;
var init_NotificationManager = __esm({
  async "dist/build/server/chunks/NotificationManager.js"() {
    "use strict";
    await init_db();
    init_client();
    await init_notificationServices();
    await init_notificationHistory();
    Colors = {
      SUCCESS: 4886745,
      FAILED: 16711680,
      ERROR: 16711680,
      INFO: 39423,
      WARNING: 16755200,
      PREVIEW: 10181046
    };
    WebhookClient = class extends BaseHttpClient {
      constructor() {
        super("", {
          timeout: 1e4,
          retries: 0
        });
      }
      /**
      * POST to a webhook URL
      */
      sendWebhook(url, payload2) {
        return this.post(url, payload2);
      }
    };
    webhookClient = null;
    RATE_LIMIT_DELAY = 1e3;
    MAX_EMBED_SIZE = 5800;
    MAX_FIELDS_PER_EMBED = 25;
    MAX_FIELD_VALUE = 1024;
    MAX_FIELD_NAME = 256;
    DiscordNotifier = class {
      config;
      constructor(config2) {
        this.config = config2;
      }
      getName() {
        return "Discord";
      }
      /**
      * Render notification into embeds and send, splitting into multiple messages if needed
      */
      async notify(notification) {
        const chunks = this.renderEmbeds(notification).map((embed) => [embed]);
        for (let i = 0; i < chunks.length; i++) {
          if (i > 0) await this.sleep(RATE_LIMIT_DELAY);
          const payload2 = {
            username: this.config.username || "Profilarr",
            avatar_url: this.config.avatar_url,
            content: i === 0 && this.config.enable_mentions ? "@here" : void 0,
            embeds: chunks[i]
          };
          await this.sendWebhook(payload2);
        }
      }
      /**
      * Render a Notification into one or more Discord embeds
      */
      renderEmbeds(notification) {
        const color = this.getColorForSeverity(notification.severity);
        const blocks = notification.blocks ?? [];
        if (blocks.length === 0) return [this.buildChrome(notification, color)];
        const embeds = [];
        let currentEmbed = this.buildChrome(notification, color);
        let currentSize = getEmbedCharCount(currentEmbed);
        let currentFieldCount = currentEmbed.fields?.length ?? 0;
        for (const block2 of blocks) {
          if (block2.kind === "section" && block2.imageUrl) {
            if (currentFieldCount > 0 || currentEmbed.title) embeds.push(currentEmbed);
            const itemEmbed = {
              title: this.truncate(block2.title, 256),
              color,
              thumbnail: { url: block2.imageUrl },
              timestamp: (/* @__PURE__ */ new Date()).toISOString(),
              author: {
                name: this.config.username || "Profilarr",
                icon_url: this.config.avatar_url
              },
              footer: { text: `Type: ${notification.type}` },
              fields: []
            };
            const contentSections = block2.content.split("\n\n");
            for (const section of contentSections) {
              const lines = section.split("\n");
              const heading = lines[0] ?? "";
              const body = lines.slice(1).join("\n");
              if (body) itemEmbed.fields.push({
                name: this.truncate(heading, MAX_FIELD_NAME),
                value: "```\n" + this.truncate(body, 1016) + "\n```",
                inline: false
              });
              else itemEmbed.fields.push({
                name: this.truncate(heading, MAX_FIELD_NAME),
                value: "\u200B",
                inline: false
              });
            }
            embeds.push(itemEmbed);
            currentEmbed = this.buildContinuationChrome(notification, color);
            currentSize = getEmbedCharCount(currentEmbed);
            currentFieldCount = 0;
            continue;
          }
          let fieldName;
          let fieldValue2;
          let inline;
          if (block2.kind === "field") {
            fieldName = this.truncate(block2.label, MAX_FIELD_NAME);
            fieldValue2 = this.truncate(block2.value, MAX_FIELD_VALUE);
            inline = block2.inline;
          } else if (block2.items && block2.items.length > 0) {
            const lines = [];
            const MAX_ITEMS_SHOWN = 15;
            for (const group of block2.items) {
              let prefix;
              if (group.label === "created") prefix = "\u{1F195}";
              else if (group.label === "updated") prefix = "\u270F\uFE0F";
              else prefix = `${group.label}:`;
              const shown = group.items.slice(0, MAX_ITEMS_SHOWN);
              const remaining = group.items.length - shown.length;
              let line = `${prefix} ${shown.join(", ")}`;
              if (remaining > 0) line += `, +${remaining} more`;
              lines.push(line);
            }
            fieldName = block2.content ? this.truncate(`${block2.title} \u2014 ${block2.content}`, MAX_FIELD_NAME) : this.truncate(block2.title, MAX_FIELD_NAME);
            fieldValue2 = "```\n" + this.truncate(lines.join("\n\n"), 1016) + "\n```";
            inline = false;
          } else {
            fieldName = this.truncate(block2.title, MAX_FIELD_NAME);
            fieldValue2 = "```\n" + (block2.content.length > 1016 ? block2.content.slice(0, 1001) + "\n...(truncated)" : block2.content) + "\n```";
            inline = false;
          }
          const fieldChars = fieldName.length + fieldValue2.length;
          if (currentFieldCount >= MAX_FIELDS_PER_EMBED || currentSize + fieldChars > MAX_EMBED_SIZE) {
            embeds.push(currentEmbed);
            currentEmbed = this.buildContinuationChrome(notification, color);
            currentSize = getEmbedCharCount(currentEmbed);
            currentFieldCount = 0;
          }
          if (!currentEmbed.fields) currentEmbed.fields = [];
          currentEmbed.fields.push({
            name: fieldName,
            value: fieldValue2,
            inline
          });
          currentSize += fieldChars;
          currentFieldCount++;
        }
        if (currentFieldCount > 0) embeds.push(currentEmbed);
        if (embeds.length > 1) for (let i = 0; i < embeds.length; i++) embeds[i].footer = { text: `Type: ${notification.type} | Page ${i + 1}/${embeds.length}` };
        return embeds;
      }
      /**
      * Build a full embed with title, description, and chrome
      */
      buildChrome(notification, color) {
        const description = notification.messageFormat === "code" ? "```\n" + notification.message + "\n```" : notification.message;
        return {
          title: notification.title,
          description,
          color,
          timestamp: (/* @__PURE__ */ new Date()).toISOString(),
          author: {
            name: this.config.username || "Profilarr",
            icon_url: this.config.avatar_url
          },
          footer: { text: `Type: ${notification.type}` }
        };
      }
      /**
      * Build a chrome-only embed for continuation pages (no title/description)
      */
      buildContinuationChrome(notification, color) {
        return {
          color,
          timestamp: (/* @__PURE__ */ new Date()).toISOString(),
          author: {
            name: this.config.username || "Profilarr",
            icon_url: this.config.avatar_url
          },
          footer: { text: `Type: ${notification.type}` }
        };
      }
      /**
      * Map severity to embed color
      */
      getColorForSeverity(severity) {
        switch (severity) {
          case "success":
            return Colors.SUCCESS;
          case "error":
            return Colors.ERROR;
          case "warning":
            return Colors.WARNING;
          case "info":
            return Colors.INFO;
          default:
            return Colors.INFO;
        }
      }
      /**
      * Truncate a string to fit within a limit
      */
      truncate(text2, limit) {
        if (text2.length <= limit) return text2;
        return text2.slice(0, limit - 3) + "...";
      }
      /**
      * Send a single webhook request
      */
      async sendWebhook(payload2) {
        await getWebhookClient().sendWebhook(this.config.webhook_url, payload2);
      }
      sleep(ms) {
        return new Promise((resolve6) => setTimeout(resolve6, ms));
      }
    };
    NtfyNotifier = class {
      config;
      constructor(config2) {
        this.config = config2;
      }
      getName() {
        return "Ntfy";
      }
      async notify(notification) {
        const url = this.config.server_url;
        const payload2 = this.formatPayload(notification);
        const headers2 = {};
        if (this.config.access_token) headers2["Authorization"] = `Bearer ${this.config.access_token}`;
        await getWebhookClient().post(url, payload2, { headers: headers2 });
      }
      formatPayload(notification) {
        const blocks = notification.blocks ?? [];
        const bodyParts = [notification.message];
        for (const block2 of blocks) if (block2.kind === "field") bodyParts.push(`${block2.label}: ${block2.value}`);
        return {
          topic: this.config.topic,
          title: notification.title,
          message: bodyParts.join("\n\n"),
          priority: this.getPriority(notification.severity),
          tags: [this.getTag(notification.severity)]
        };
      }
      getPriority(severity) {
        switch (severity) {
          case "success":
          case "info":
            return 3;
          case "warning":
            return 4;
          case "error":
            return 5;
          default:
            return 3;
        }
      }
      getTag(severity) {
        switch (severity) {
          case "success":
            return "white_check_mark";
          case "info":
            return "information_source";
          case "warning":
            return "warning";
          case "error":
            return "x";
          default:
            return "information_source";
        }
      }
    };
    WebhookNotifier = class {
      config;
      constructor(config2) {
        this.config = config2;
      }
      getName() {
        return "Webhook";
      }
      async notify(notification) {
        const headers2 = {};
        if (this.config.auth_header) headers2["Authorization"] = this.config.auth_header;
        await getWebhookClient().post(this.config.webhook_url, notification, {
          headers: headers2,
          responseType: "text"
        });
      }
    };
    TELEGRAM_API = "https://api.telegram.org";
    MAX_MESSAGE_LENGTH = 4096;
    TelegramNotifier = class {
      config;
      constructor(config2) {
        this.config = config2;
      }
      getName() {
        return "Telegram";
      }
      async notify(notification) {
        const url = `${this.config.api_base_url ?? TELEGRAM_API}/bot${this.config.bot_token}/sendMessage`;
        const payload2 = this.formatPayload(notification);
        await getWebhookClient().post(url, payload2);
      }
      formatPayload(notification) {
        const emoji = this.getEmoji(notification.severity);
        const blocks = notification.blocks ?? [];
        const parts = [];
        parts.push(`${emoji} <b>${notification.title}</b>`);
        parts.push(notification.message);
        for (const block2 of blocks) if (block2.kind === "field") parts.push(`<b>${block2.label}:</b> ${block2.value}`);
        let text2 = parts.join("\n\n");
        if (text2.length > MAX_MESSAGE_LENGTH) text2 = text2.slice(0, 4095) + "\u2026";
        return {
          chat_id: this.config.chat_id,
          text: text2,
          parse_mode: "HTML"
        };
      }
      getEmoji(severity) {
        switch (severity) {
          case "success":
            return "\u2705";
          case "error":
            return "\u274C";
          case "warning":
            return "\u26A0\uFE0F";
          case "info":
            return "\u2139\uFE0F";
          default:
            return "\u2139\uFE0F";
        }
      }
    };
    NotificationManager = class {
      /**
      * Send a notification to all enabled services that have this notification type enabled.
      * Fire-and-forget: does not throw errors, failures are logged.
      */
      async notify(notification) {
        try {
          const services = notificationServicesQueries.getAllEnabled();
          if (services.length === 0) return;
          const relevantServices = services.filter((service) => {
            try {
              return JSON.parse(service.enabled_types).includes(notification.type);
            } catch {
              return false;
            }
          });
          if (relevantServices.length === 0) return;
          await Promise.allSettled(relevantServices.map((service) => this.sendToServiceInternal(service.id, service.service_type, service.config, notification)));
        } catch (error2) {
          await logger.error("Error in notification manager", {
            source: "NotificationManager",
            meta: {
              error: error2 instanceof Error ? error2.message : String(error2),
              type: notification.type
            }
          });
        }
      }
      /**
      * Send a notification to a specific service, bypassing the enabled_types filter.
      * Used for test notifications from the UI.
      */
      async sendToService(serviceId, notification) {
        try {
          const service = notificationServicesQueries.getById(serviceId);
          if (!service) {
            await logger.error("Service not found for direct send", {
              source: "NotificationManager",
              meta: { serviceId }
            });
            return;
          }
          await this.sendToServiceInternal(service.id, service.service_type, service.config, notification);
        } catch (error2) {
          await logger.error("Error in direct send", {
            source: "NotificationManager",
            meta: {
              serviceId,
              error: error2 instanceof Error ? error2.message : String(error2),
              type: notification.type
            }
          });
        }
      }
      /**
      * Internal: send notification to a specific service and record history
      */
      async sendToServiceInternal(serviceId, serviceType, configJson, notification) {
        let success = false;
        let errorMessage;
        try {
          const notifier = this.createNotifier(serviceType, configJson);
          if (!notifier) {
            errorMessage = `Unknown service type: ${serviceType}`;
            await logger.error(errorMessage, {
              source: "NotificationManager",
              meta: {
                serviceId,
                serviceType
              }
            });
            return;
          }
          await notifier.notify(notification);
          success = true;
        } catch (error2) {
          errorMessage = error2 instanceof Error ? error2.message : String(error2);
          await logger.error("Failed to send notification to service", {
            source: "NotificationManager",
            meta: {
              serviceId,
              serviceType,
              error: errorMessage
            }
          });
        } finally {
          try {
            notificationHistoryQueries.create({
              serviceId,
              notificationType: notification.type,
              title: notification.title,
              message: notification.message,
              status: success ? "success" : "failed",
              error: errorMessage
            });
          } catch (error2) {
            await logger.error("Failed to record notification history", {
              source: "NotificationManager",
              meta: {
                serviceId,
                error: error2 instanceof Error ? error2.message : String(error2)
              }
            });
          }
        }
      }
      /**
      * Create a notifier instance based on service type and config
      */
      createNotifier(serviceType, configJson) {
        try {
          const config2 = JSON.parse(configJson);
          switch (serviceType) {
            case "discord":
              return new DiscordNotifier(config2);
            case "ntfy":
              return new NtfyNotifier(config2);
            case "webhook":
              return new WebhookNotifier(config2);
            case "telegram":
              return new TelegramNotifier(config2);
            default:
              return null;
          }
        } catch (error2) {
          logger.error("Failed to parse notification service config", {
            source: "NotificationManager",
            meta: {
              serviceType,
              error: error2 instanceof Error ? error2.message : String(error2)
            }
          });
          return null;
        }
      }
    };
    notificationManager = new NotificationManager();
  }
});

// dist/build/server/chunks/test2.js
function test() {
  return {
    type: "test",
    severity: "info",
    title: "Test Notification",
    message: "This is a test notification from Profilarr. If you received this, your notification service is working correctly!"
  };
}
var init_test2 = __esm({
  "dist/build/server/chunks/test2.js"() {
    "use strict";
  }
});

// dist/build/server/chunks/operations.js
async function pathExists(path) {
  try {
    await Deno.stat(path);
    return true;
  } catch {
    return false;
  }
}
async function loadOperationsFromDir(dirPath, layer) {
  if (!await pathExists(dirPath)) return [];
  const operations = [];
  try {
    for await (const entry of Deno.readDir(dirPath)) {
      if (!entry.isFile || !entry.name.endsWith(".sql")) continue;
      const filepath = `${dirPath}/${entry.name}`;
      const sql2 = await Deno.readTextFile(filepath);
      const order = extractOrderFromFilename(entry.name);
      operations.push({
        filename: entry.name,
        filepath,
        sql: sql2,
        order,
        layer
      });
    }
  } catch (error2) {
    throw new Error(`Failed to read operations from ${dirPath}: ${error2}`);
  }
  return operations.sort((a2, b3) => a2.order - b3.order);
}
function extractOrderFromFilename(filename) {
  const match = filename.match(/^(\d+)\./);
  if (match) return parseInt(match[1], 10);
  return Infinity;
}
function validateOperations(operations) {
  for (const op of operations) if (!op.sql.trim()) throw new Error(`Operation ${op.filename} in ${op.layer} layer is empty`);
  const layerOrders = /* @__PURE__ */ new Map();
  for (const op of operations) {
    if (op.order === Infinity) continue;
    if (!layerOrders.has(op.layer)) layerOrders.set(op.layer, /* @__PURE__ */ new Set());
    const orders = layerOrders.get(op.layer);
    if (orders.has(op.order)) throw new Error(`Duplicate order number ${op.order} in ${op.layer} layer (${op.filename})`);
    orders.add(op.order);
  }
}
function getPCDPath(uuid2) {
  return `${config.paths.databases}/${uuid2}`;
}
function getBaseOpsPath(pcdPath) {
  return `${pcdPath}/ops`;
}
var init_operations2 = __esm({
  "dist/build/server/chunks/operations.js"() {
    "use strict";
    init_config();
  }
});

// dist/build/server/chunks/database.js
function reconcile(incoming, existing, options2) {
  const total = incoming.length;
  const capped = incoming.slice(0, options2.cap);
  const droppedCount = Math.max(0, total - capped.length);
  const existingById = /* @__PURE__ */ new Map();
  for (const row of existing) existingById.set(row.id, row);
  const incomingIds = /* @__PURE__ */ new Set();
  const upserts = [];
  const newlyInserted = [];
  const unwithdrawnIds = [];
  for (const entry of capped) {
    incomingIds.add(entry.id);
    upserts.push(entry);
    const existingRow = existingById.get(entry.id);
    if (!existingRow) newlyInserted.push(entry);
    else if (existingRow.withdrawn === 1) unwithdrawnIds.push(entry.id);
  }
  const withdrawnIds = [];
  for (const row of existing) if (!incomingIds.has(row.id) && row.withdrawn === 0) withdrawnIds.push(row.id);
  return {
    upserts,
    withdrawnIds,
    unwithdrawnIds,
    newlyInserted,
    droppedCount
  };
}
function getFilename(path) {
  return path.split("/").pop() || path;
}
function getTitle$1(log) {
  return `${log.config.manual ? "Manual" : "Automatic"} Rename ${log.status === "failed" ? "Failed" : "Complete"}`;
}
function parseSeasonNumber(filename) {
  const match = filename.match(/S(\d+)E\d+/i);
  return match ? parseInt(match[1], 10) : null;
}
function formatItemContent$1(item, isSonarr) {
  const sections = [];
  if (item.folder) {
    sections.push(`Folder (Before)
${item.folder.existingPath}`);
    sections.push(`Folder (After)
${item.folder.newPath}`);
  }
  if (!isSonarr || item.files.length === 0) {
    if (item.files.length > 0) {
      sections.push(`Before
${item.files.map((f2) => getFilename(f2.existingPath)).join("\n")}`);
      sections.push(`After
${item.files.map((f2) => getFilename(f2.newPath)).join("\n")}`);
    }
    return sections.join("\n\n");
  }
  const bySeasonMap = /* @__PURE__ */ new Map();
  const noSeason = [];
  for (const file of item.files) {
    const season = parseSeasonNumber(getFilename(file.existingPath));
    if (season !== null) {
      if (!bySeasonMap.has(season)) bySeasonMap.set(season, []);
      bySeasonMap.get(season).push(file);
    } else noSeason.push(file);
  }
  const seasons = Array.from(bySeasonMap.keys()).sort((a2, b3) => a2 - b3);
  for (const season of seasons) {
    const seasonFiles = bySeasonMap.get(season);
    sections.push(`Season ${season} (Before)
${seasonFiles.map((f2) => getFilename(f2.existingPath)).join("\n")}`);
    sections.push(`Season ${season} (After)
${seasonFiles.map((f2) => getFilename(f2.newPath)).join("\n")}`);
  }
  if (noSeason.length > 0) {
    sections.push(`Before
${noSeason.map((f2) => getFilename(f2.existingPath)).join("\n")}`);
    sections.push(`After
${noSeason.map((f2) => getFilename(f2.newPath)).join("\n")}`);
  }
  return sections.join("\n\n");
}
function rename({ log, summaryNotifications = true }) {
  const severity = log.status === "failed" ? "error" : log.status === "partial" ? "warning" : "success";
  const title = `${getTitle$1(log)} - ${log.instanceName}`;
  const isSonarr = log.instanceType === "sonarr";
  if (log.renamedItems.length === 0) return {
    type: `rename.${log.status}`,
    severity,
    title,
    message: `No files needed renaming for ${log.instanceName}`,
    blocks: [{
      kind: "field",
      label: "Status",
      value: "No files needed renaming"
    }]
  };
  const blocks = [];
  const statsLines = [];
  if (log.config.dryRun) {
    statsLines.push(`Mode:     Dry Run`);
    statsLines.push(`Files:    ${log.results.filesNeedingRename}`);
  } else {
    statsLines.push(`Files:    ${log.results.filesRenamed}/${log.results.filesNeedingRename}`);
    if (log.config.renameFolders) statsLines.push(`Folders:  ${log.results.foldersRenamed}`);
  }
  blocks.push({
    kind: "section",
    title: "Stats",
    content: statsLines.join("\n")
  });
  if (summaryNotifications) {
    const sample = log.renamedItems[0];
    const othersCount = log.renamedItems.length - 1;
    const othersText = othersCount > 0 ? ` + ${othersCount} other${othersCount === 1 ? "" : "s"}` : "";
    let sampleContent = "";
    if (sample.folder) {
      sampleContent += `Folder (Before)
${sample.folder.existingPath}`;
      sampleContent += `

Folder (After)
${sample.folder.newPath}`;
    }
    if (sample.files.length > 0) {
      if (sampleContent) sampleContent += "\n\n";
      sampleContent += `Before
${getFilename(sample.files[0].existingPath)}`;
      sampleContent += `

After
${getFilename(sample.files[0].newPath)}`;
    }
    if (sampleContent) blocks.push({
      kind: "section",
      title: `${sample.title}${othersText}`,
      content: sampleContent,
      imageUrl: sample.imageUrl
    });
  } else for (const item of log.renamedItems) {
    const content = formatItemContent$1(item, isSonarr);
    if (content) blocks.push({
      kind: "section",
      title: item.title,
      content,
      imageUrl: item.imageUrl
    });
  }
  const message2 = log.status === "failed" ? `Rename failed for ${log.instanceName}` : `Renamed ${log.results.filesRenamed} files for ${log.instanceName}`;
  return {
    type: `rename.${log.status}`,
    severity,
    title,
    message: message2,
    blocks
  };
}
function getTitle(log, manual = false) {
  return `${manual ? "Manual" : "Automatic"} Upgrade ${{
    success: "Complete",
    partial: "Partial",
    failed: "Failed",
    skipped: "Skipped"
  }[log.status] || "Complete"}`;
}
function formatSelector(method) {
  return method.split("_").map((w3) => w3.charAt(0).toUpperCase() + w3.slice(1)).join(" ");
}
function flattenItems(items) {
  const result = [];
  for (const item of items) {
    if (item.original.type === "movie") {
      result.push(item);
      continue;
    }
    const episodes = item.original.episodes ?? [];
    const seasonEpisodes = /* @__PURE__ */ new Map();
    for (const ep of episodes) {
      const eps = seasonEpisodes.get(ep.seasonNumber) ?? [];
      eps.push(ep);
      seasonEpisodes.set(ep.seasonNumber, eps);
    }
    const seasonUpgrades = /* @__PURE__ */ new Map();
    for (const u of item.upgrades) if (u.seasonNumber != null) {
      const ups = seasonUpgrades.get(u.seasonNumber) ?? [];
      ups.push(u);
      seasonUpgrades.set(u.seasonNumber, ups);
    }
    const allSeasons = /* @__PURE__ */ new Set([...seasonEpisodes.keys(), ...seasonUpgrades.keys()]);
    if (allSeasons.size === 0) {
      result.push(item);
      continue;
    }
    for (const season of [...allSeasons].sort((a2, b3) => a2 - b3)) result.push({
      id: item.id * 1e3 + season,
      title: `${item.title} - Season ${season}`,
      original: {
        type: "series",
        title: item.title,
        episodes: seasonEpisodes.get(season) ?? []
      },
      upgrades: seasonUpgrades.get(season) ?? [],
      imageUrl: item.imageUrl
    });
  }
  return result;
}
function formatItemContent(item) {
  if (item.upgrades.length === 0) return "No upgrade available";
  const sections = [];
  for (const upgrade2 of item.upgrades) sections.push(`Release
${upgrade2.release}`);
  if (item.original.type === "movie") sections.push(`Score
Current: ${item.original.score}
Upgrade: ${item.upgrades[0]?.score ?? 0}`);
  else {
    const episodes = item.original.episodes ?? [];
    const avgScore = episodes.length > 0 ? Math.round(episodes.reduce((sum, ep) => sum + ep.score, 0) / episodes.length) : 0;
    for (const upgrade2 of item.upgrades) sections.push(`Score
Current: ${avgScore} (avg)
Upgrade: ${upgrade2.score}`);
  }
  if (item.original.type === "movie") {
    const currentFmts = item.original.formats;
    const upgradeFmts = item.upgrades[0]?.formats ?? [];
    const lines = ["Formats"];
    if (currentFmts.length > 0) {
      lines.push("Current:");
      for (const f2 of currentFmts) lines.push(`  ${f2}`);
    }
    if (upgradeFmts.length > 0) {
      lines.push("Upgrade:");
      for (const f2 of upgradeFmts) lines.push(`  ${f2}`);
    }
    sections.push(lines.join("\n"));
  } else {
    const episodes = item.original.episodes ?? [];
    const currentFmtSet = /* @__PURE__ */ new Set();
    for (const ep of episodes) for (const f2 of ep.formats) currentFmtSet.add(f2);
    for (const upgrade2 of item.upgrades) {
      const lines = ["Formats"];
      if (currentFmtSet.size > 0) {
        lines.push("Current:");
        for (const f2 of currentFmtSet) lines.push(`  ${f2}`);
      }
      if (upgrade2.formats.length > 0) {
        lines.push("Upgrade:");
        for (const f2 of upgrade2.formats) lines.push(`  ${f2}`);
      }
      sections.push(lines.join("\n"));
    }
  }
  return sections.join("\n\n");
}
function buildGenericMessage(log) {
  const upgradesFound = log.selection.items.filter((i) => i.upgrades.length > 0).length;
  const mode = log.config.dryRun ? " (Dry Run)" : "";
  if (log.status === "failed") return `Upgrade failed for ${log.instanceName}${mode}`;
  if (log.status === "skipped") return `Upgrade skipped for ${log.instanceName}: ${log.results.errors[0] || "Unknown reason"}`;
  return `Searched ${log.selection.actualCount} items, found ${upgradesFound} upgrade${upgradesFound === 1 ? "" : "s"} for ${log.instanceName}${mode}`;
}
function upgrade({ log, manual = false }) {
  const severity = log.status === "failed" ? "error" : log.status === "partial" ? "warning" : log.status === "skipped" ? "info" : "success";
  const title = `${getTitle(log, manual)} - ${log.instanceName}`;
  const message2 = buildGenericMessage(log);
  if (log.selection.items.length === 0) return {
    type: `upgrade.${log.status}`,
    severity,
    title,
    message: `No items to search for ${log.instanceName}`,
    blocks: [
      {
        kind: "field",
        label: "Filter",
        value: log.filter.name || "Unknown",
        inline: true
      },
      {
        kind: "field",
        label: "Selector",
        value: formatSelector(log.selection.method),
        inline: true
      },
      ...log.config.dryRun ? [{
        kind: "field",
        label: "Mode",
        value: "Dry Run",
        inline: true
      }] : [],
      {
        kind: "field",
        label: "Status",
        value: "No items to search"
      }
    ]
  };
  const blocks = [];
  const upgradesFound = log.selection.items.filter((i) => i.upgrades.length > 0).length;
  let funnelText = `${log.library.totalItems} library -> ${log.filter.matchedCount} filtered -> ${log.filter.afterCooldown} after cooldown`;
  if (log.filter.dryRunExcluded > 0) {
    const afterCache = log.filter.afterCooldown - log.filter.dryRunExcluded;
    funnelText += ` -> ${afterCache} after cache`;
  }
  funnelText += ` -> ${log.selection.actualCount} selected`;
  const statsLines = [
    `Filter:    ${log.filter.name || "Unknown"}`,
    `Selector:  ${formatSelector(log.selection.method)}`,
    `Upgrades:  ${upgradesFound}/${log.selection.actualCount}`,
    ...log.config.dryRun ? ["Mode:      Dry Run"] : [],
    `Funnel:    ${funnelText}`
  ];
  blocks.push({
    kind: "section",
    title: "Stats",
    content: statsLines.join("\n")
  });
  const displayItems = flattenItems(log.selection.items);
  for (const item of displayItems) {
    if (item.upgrades.length === 0) continue;
    blocks.push({
      kind: "section",
      title: item.title,
      content: formatItemContent(item),
      imageUrl: item.imageUrl
    });
  }
  const realErrors = log.results.errors.filter((e) => !e.startsWith("[DRY RUN]"));
  if (realErrors.length > 0) {
    const errorText = realErrors.slice(0, 5).map((e) => `- ${e}`).join("\n");
    const moreText = realErrors.length > 5 ? `
...and ${realErrors.length - 5} more` : "";
    blocks.push({
      kind: "field",
      label: "Errors",
      value: errorText + moreText
    });
  }
  return {
    type: `upgrade.${log.status}`,
    severity,
    title,
    message: message2,
    blocks
  };
}
function getSectionLabel(section) {
  return sectionLabels[section] ?? section;
}
function capitalize$2(s3) {
  return s3.charAt(0).toUpperCase() + s3.slice(1);
}
function formatInstanceType$2(type) {
  return capitalize$2(type);
}
function buildSectionSummaryLine(section) {
  const label = getSectionLabel(section.section);
  if (!section.success) return `${label}: Failed \u2013 ${section.error ?? "Unknown error"}`;
  if (!section.items || section.items.length === 0) return `${label}: no changes`;
  const created = section.items.filter((i) => i.action === "created").length;
  const updated3 = section.items.filter((i) => i.action === "updated").length;
  const parts = [];
  if (updated3 > 0) parts.push(`${updated3} updated`);
  if (created > 0) parts.push(`${created} created`);
  return `${label}: ${parts.join(" \xB7 ")}`;
}
function groupByAction(items) {
  const groups = [];
  const created = items.filter((i) => i.action === "created").map((i) => i.name);
  const updated3 = items.filter((i) => i.action === "updated").map((i) => i.name);
  if (created.length > 0) groups.push({
    label: "created",
    items: created
  });
  if (updated3.length > 0) groups.push({
    label: "updated",
    items: updated3
  });
  return groups;
}
function arrSync(params) {
  const { instanceName, instanceType, sections } = params;
  const instanceLabel2 = `${formatInstanceType$2(instanceType)} (${instanceName})`;
  const successes = sections.filter((s3) => s3.success).length;
  const failures = sections.filter((s3) => !s3.success).length;
  let status;
  let severity;
  let titleStatus;
  if (failures === 0) {
    status = "success";
    severity = "success";
    titleStatus = "Complete";
  } else if (successes > 0) {
    status = "partial";
    severity = "warning";
    titleStatus = "Partial";
  } else {
    status = "failed";
    severity = "error";
    titleStatus = "Failed";
  }
  const title = `Sync ${titleStatus} \u2013 ${instanceLabel2}`;
  const message2 = sections.map(buildSectionSummaryLine).join("\n");
  const blocks = [];
  for (const section of sections) if (section.success && section.items && section.items.length > 0) blocks.push({
    kind: "section",
    title: getSectionLabel(section.section),
    content: "",
    items: groupByAction(section.items)
  });
  return {
    type: `arr.sync.${status}`,
    severity,
    title,
    message: message2,
    blocks
  };
}
function capitalize$1(s3) {
  return s3.charAt(0).toUpperCase() + s3.slice(1);
}
function formatInstanceType$1(type) {
  return capitalize$1(type);
}
function entityLabel(instanceType) {
  return instanceType === "radarr" ? "Movies" : "Series";
}
function firstLine$2(text2) {
  const idx = text2.indexOf("\n");
  return idx === -1 ? text2 : text2.slice(0, idx);
}
function groupByReason(pairs2) {
  const groups = /* @__PURE__ */ new Map();
  for (const p2 of pairs2) {
    const list5 = groups.get(p2.reason) ?? [];
    list5.push(p2.name);
    groups.set(p2.reason, list5);
  }
  return Array.from(groups.entries()).map(([label, items]) => ({
    label,
    items
  }));
}
function arrCleanup(params) {
  const { instanceName, instanceType, deletedCustomFormats, deletedQualityProfiles, skippedQualityProfiles, deletedEntities, failedEntities, error: error2 } = params;
  const instanceLabel2 = `${formatInstanceType$1(instanceType)} (${instanceName})`;
  const eLabel = entityLabel(instanceType);
  const totalDeleted = deletedCustomFormats.length + deletedQualityProfiles.length + deletedEntities.length;
  const totalNonSuccess = skippedQualityProfiles.length + failedEntities.length;
  let status;
  let severity;
  let titleStatus;
  if (error2 !== void 0) {
    status = "failed";
    severity = "error";
    titleStatus = "Failed";
  } else if (totalNonSuccess === 0 && totalDeleted > 0) {
    status = "success";
    severity = "success";
    titleStatus = "Complete";
  } else if (totalNonSuccess > 0 && totalDeleted > 0) {
    status = "partial";
    severity = "warning";
    titleStatus = "Partial";
  } else {
    status = "failed";
    severity = "error";
    titleStatus = "Failed";
  }
  const title = `Cleanup ${titleStatus} \u2013 ${instanceLabel2}`;
  let message2;
  if (error2 !== void 0) message2 = firstLine$2(error2);
  else if (status === "success") message2 = `Deleted ${totalDeleted} ${totalDeleted === 1 ? "item" : "items"}`;
  else if (status === "partial") message2 = `Deleted ${totalDeleted}, ${totalNonSuccess} not deleted`;
  else message2 = `Could not delete ${totalNonSuccess} ${totalNonSuccess === 1 ? "item" : "items"}`;
  const blocks = [];
  if (error2 !== void 0) {
    blocks.push({
      kind: "section",
      title: "Error",
      content: error2
    });
    return {
      type: `arr.cleanup.${status}`,
      severity,
      title,
      message: message2,
      blocks
    };
  }
  const deletedGroups = [];
  if (deletedQualityProfiles.length > 0) deletedGroups.push({
    label: "Profiles",
    items: deletedQualityProfiles.map((p2) => p2.name)
  });
  if (deletedCustomFormats.length > 0) deletedGroups.push({
    label: "Formats",
    items: deletedCustomFormats.map((f2) => f2.name)
  });
  if (deletedEntities.length > 0) deletedGroups.push({
    label: eLabel,
    items: deletedEntities.map((e) => e.title)
  });
  if (deletedGroups.length > 0) blocks.push({
    kind: "section",
    title: "Deleted",
    content: "",
    items: deletedGroups
  });
  if (skippedQualityProfiles.length > 0) blocks.push({
    kind: "section",
    title: "Skipped Profiles",
    content: "",
    items: groupByReason(skippedQualityProfiles.map((s3) => ({
      reason: s3.reason,
      name: s3.item.name
    })))
  });
  if (failedEntities.length > 0) blocks.push({
    kind: "section",
    title: `Failed ${eLabel}`,
    content: "",
    items: groupByReason(failedEntities.map((f2) => ({
      reason: f2.reason,
      name: f2.entity.title
    })))
  });
  return {
    type: `arr.cleanup.${status}`,
    severity,
    title,
    message: message2,
    blocks
  };
}
function capitalize(s3) {
  return s3.charAt(0).toUpperCase() + s3.slice(1);
}
function formatInstanceType(type) {
  return capitalize(type);
}
function instanceLabel(instanceType, instanceName) {
  return `${formatInstanceType(instanceType)} (${instanceName})`;
}
function firstLine$1(text2) {
  const idx = text2.indexOf("\n");
  return idx === -1 ? text2 : text2.slice(0, idx);
}
function buildDriftedItemBlocks(entities, maxEntities) {
  const shown = entities.slice(0, maxEntities);
  const remaining = entities.length - shown.length;
  const groups = /* @__PURE__ */ new Map();
  for (const entity of shown) {
    const group = groups.get(entity.sectionLabel) ?? [];
    group.push(entity);
    groups.set(entity.sectionLabel, group);
  }
  const blocks = [];
  for (const [label, group] of groups) blocks.push({
    kind: "section",
    title: label,
    content: group.map((entity) => {
      const db2 = entity.databaseName ? ` (${entity.databaseName})` : "";
      return `- ${entity.title}${db2}: ${entity.summary}`;
    }).join("\n")
  });
  if (remaining > 0) blocks.push({
    kind: "section",
    title: "More",
    content: `+${remaining} more`
  });
  return blocks;
}
function arrDriftDetected(params) {
  const { instanceName, instanceType, entities } = params;
  const maxEntities = params.maxEntities ?? DEFAULT_MAX_ENTITIES;
  return {
    type: "arr.drift.detected",
    severity: "warning",
    title: `Drift Detected - ${instanceLabel(instanceType, instanceName)}`,
    message: "",
    blocks: buildDriftedItemBlocks(entities, maxEntities)
  };
}
function arrDriftFailed(params) {
  const { instanceName, instanceType, error: error2 } = params;
  return {
    type: "arr.drift.failed",
    severity: "error",
    title: `Drift Check Failed - ${instanceLabel(instanceType, instanceName)}`,
    message: firstLine$1(error2),
    blocks: [{
      kind: "section",
      title: "Error",
      content: error2
    }]
  };
}
function buildChangesBlock(commitMessages) {
  if (commitMessages.length === 0) return null;
  return {
    kind: "section",
    title: "Changes",
    content: commitMessages.map((m3) => `\u2022 ${m3}`).join("\n")
  };
}
function pcdUpdatesAvailable(params) {
  const { name, commitsBehind, commitMessages } = params;
  const blocks = [];
  const changesBlock = buildChangesBlock(commitMessages);
  if (changesBlock) blocks.push(changesBlock);
  return {
    type: "pcd.updates_available",
    severity: "info",
    title: `Updates Available \u2013 ${name}`,
    message: `${commitsBehind} update(s) available`,
    blocks
  };
}
function pcdSyncSuccess(params) {
  const { name, commitsPulled, commitMessages, schemaUpdate } = params;
  const blocks = [];
  const changesBlock = buildChangesBlock(commitMessages);
  if (changesBlock) blocks.push(changesBlock);
  if (schemaUpdate) blocks.push({
    kind: "section",
    title: "Schema Updated",
    content: `${schemaUpdate.from} \u2192 ${schemaUpdate.to}`
  });
  return {
    type: "pcd.sync_success",
    severity: "success",
    title: `Database Synced \u2013 ${name}`,
    message: `Pulled ${commitsPulled} update(s)`,
    blocks
  };
}
function pcdSyncFailed(params) {
  const { name, error: error2 } = params;
  return {
    type: "pcd.sync_failed",
    severity: "error",
    title: `Database Sync Failed \u2013 ${name}`,
    message: error2,
    blocks: []
  };
}
function pcdLinkFailed(params) {
  const { name, error: error2 } = params;
  return {
    type: "pcd.link_failed",
    severity: "error",
    title: `Database Link Failed \u2013 ${name}`,
    message: error2,
    blocks: []
  };
}
function formatSize(bytes) {
  return `${(bytes / 1048576).toFixed(2)} MB`;
}
function formatDuration(ms) {
  if (ms < 1e3) return `${ms}ms`;
  const totalSeconds = ms / 1e3;
  if (totalSeconds < 60) return `${totalSeconds.toFixed(1)}s`;
  const minutes = Math.floor(totalSeconds / 60);
  return `${minutes}m ${Math.round(totalSeconds - minutes * 60)}s`;
}
function firstLine(text2) {
  const idx = text2.indexOf("\n");
  return idx === -1 ? text2 : text2.slice(0, idx);
}
function backupSuccess(params) {
  const { filename, sizeBytes, durationMs } = params;
  const blocks = [{
    kind: "field",
    label: "Size",
    value: formatSize(sizeBytes),
    inline: true
  }];
  if (durationMs !== void 0) blocks.push({
    kind: "field",
    label: "Duration",
    value: formatDuration(durationMs),
    inline: true
  });
  return {
    type: "backup.success",
    severity: "success",
    title: "Backup Created",
    message: filename,
    messageFormat: "code",
    blocks
  };
}
function backupFailed(params) {
  const { error: error2 } = params;
  return {
    type: "backup.failed",
    severity: "error",
    title: "Backup Failed",
    message: firstLine(error2),
    blocks: [{
      kind: "section",
      title: "Error",
      content: error2
    }]
  };
}
function announcementNew(params) {
  const { announcement } = params;
  const source2 = params.source ?? { kind: "profilarr" };
  const blocks = [{
    kind: "field",
    label: "Severity",
    value: announcement.severity,
    inline: true
  }, {
    kind: "field",
    label: "Published",
    value: announcement.publishedAt,
    inline: true
  }];
  if (source2.kind === "pcd") blocks.push({
    kind: "field",
    label: "From",
    value: source2.databaseName,
    inline: false
  });
  if (announcement.link) blocks.push({
    kind: "field",
    label: "Link",
    value: announcement.link,
    inline: false
  });
  const title = source2.kind === "pcd" ? `${source2.databaseName}: ${announcement.title}` : announcement.title;
  const message2 = source2.kind === "pcd" ? `A new announcement from ${source2.databaseName}.` : "A new announcement from the Profilarr team.";
  return {
    type: "announcement.new",
    severity: SEVERITY_MAP[announcement.severity],
    title,
    message: message2,
    blocks
  };
}
function isEOL(c2) {
  return c2 === 10 || c2 === 13;
}
function isWhiteSpace(c2) {
  return c2 === 9 || c2 === 32;
}
function isWhiteSpaceOrEOL(c2) {
  return isWhiteSpace(c2) || isEOL(c2);
}
function isFlowIndicator(c2) {
  return c2 === 44 || c2 === 91 || c2 === 93 || c2 === 123 || c2 === 125;
}
function resolveYamlBinary(data) {
  if (data === null) return false;
  let code3;
  let bitlen = 0;
  const max = data.length;
  const map2 = BASE64_MAP;
  for (let idx = 0; idx < max; idx++) {
    code3 = map2.indexOf(data.charAt(idx));
    if (code3 > 64) continue;
    if (code3 < 0) return false;
    bitlen += 6;
  }
  return bitlen % 8 === 0;
}
function constructYamlBinary(data) {
  const input = data.replace(/[\r\n=]/g, "");
  const max = input.length;
  const map2 = BASE64_MAP;
  const result = [];
  let bits = 0;
  for (let idx = 0; idx < max; idx++) {
    if (idx % 4 === 0 && idx) {
      result.push(bits >> 16 & 255);
      result.push(bits >> 8 & 255);
      result.push(bits & 255);
    }
    bits = bits << 6 | map2.indexOf(input.charAt(idx));
  }
  const tailbits = max % 4 * 6;
  if (tailbits === 0) {
    result.push(bits >> 16 & 255);
    result.push(bits >> 8 & 255);
    result.push(bits & 255);
  } else if (tailbits === 18) {
    result.push(bits >> 10 & 255);
    result.push(bits >> 2 & 255);
  } else if (tailbits === 12) result.push(bits >> 4 & 255);
  return new Uint8Array(result);
}
function representYamlBinary(object) {
  const max = object.length;
  const map2 = BASE64_MAP;
  let result = "";
  let bits = 0;
  for (let idx = 0; idx < max; idx++) {
    if (idx % 3 === 0 && idx) {
      result += map2[bits >> 18 & 63];
      result += map2[bits >> 12 & 63];
      result += map2[bits >> 6 & 63];
      result += map2[bits & 63];
    }
    bits = (bits << 8) + object[idx];
  }
  const tail = max % 3;
  if (tail === 0) {
    result += map2[bits >> 18 & 63];
    result += map2[bits >> 12 & 63];
    result += map2[bits >> 6 & 63];
    result += map2[bits & 63];
  } else if (tail === 2) {
    result += map2[bits >> 10 & 63];
    result += map2[bits >> 4 & 63];
    result += map2[bits << 2 & 63];
    result += map2[64];
  } else if (tail === 1) {
    result += map2[bits >> 2 & 63];
    result += map2[bits << 4 & 63];
    result += map2[64];
    result += map2[64];
  }
  return result;
}
function isBinary(obj) {
  return obj instanceof Uint8Array;
}
function isObject(value2) {
  return value2 !== null && typeof value2 === "object";
}
function isNegativeZero(i) {
  return i === 0 && Number.NEGATIVE_INFINITY === 1 / i;
}
function isPlainObject(object) {
  return Object.prototype.toString.call(object) === "[object Object]";
}
function resolveYamlFloat(data) {
  if (!YAML_FLOAT_REGEXP.test(data) || data[data.length - 1] === "_") return false;
  return true;
}
function constructYamlFloat(data) {
  let value2 = data.replace(/_/g, "").toLowerCase();
  const sign = value2[0] === "-" ? -1 : 1;
  if (value2[0] && "+-".includes(value2[0])) value2 = value2.slice(1);
  if (value2 === ".inf") return sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
  if (value2 === ".nan") return NaN;
  return sign * parseFloat(value2);
}
function representYamlFloat(object, style) {
  const value2 = object instanceof Number ? object.valueOf() : object;
  if (isNaN(value2)) switch (style) {
    case "lowercase":
      return ".nan";
    case "uppercase":
      return ".NAN";
    case "camelcase":
      return ".NaN";
  }
  else if (Number.POSITIVE_INFINITY === value2) switch (style) {
    case "lowercase":
      return ".inf";
    case "uppercase":
      return ".INF";
    case "camelcase":
      return ".Inf";
  }
  else if (Number.NEGATIVE_INFINITY === value2) switch (style) {
    case "lowercase":
      return "-.inf";
    case "uppercase":
      return "-.INF";
    case "camelcase":
      return "-.Inf";
  }
  else if (isNegativeZero(value2)) return "-0.0";
  const res = value2.toString(10);
  return SCIENTIFIC_WITHOUT_DOT_REGEXP.test(res) ? res.replace("e", ".e") : res;
}
function isFloat(object) {
  if (object instanceof Number) object = object.valueOf();
  return typeof object === "number" && (object % 1 !== 0 || isNegativeZero(object));
}
function isCharCodeInRange(c2, lower, upper) {
  return lower <= c2 && c2 <= upper;
}
function isHexCode(c2) {
  return isCharCodeInRange(c2, 48, 57) || isCharCodeInRange(c2, 65, 70) || isCharCodeInRange(c2, 97, 102);
}
function isOctCode(c2) {
  return isCharCodeInRange(c2, 48, 55);
}
function isDecCode(c2) {
  return isCharCodeInRange(c2, 48, 57);
}
function resolveYamlInteger(data) {
  const max = data.length;
  let index88 = 0;
  let hasDigits = false;
  if (!max) return false;
  let ch = data[index88];
  if (ch === "-" || ch === "+") ch = data[++index88];
  if (ch === "0") {
    if (index88 + 1 === max) return true;
    ch = data[++index88];
    if (ch === "b") {
      index88++;
      for (; index88 < max; index88++) {
        ch = data[index88];
        if (ch === "_") continue;
        if (ch !== "0" && ch !== "1") return false;
        hasDigits = true;
      }
      return hasDigits && ch !== "_";
    }
    if (ch === "x") {
      index88++;
      for (; index88 < max; index88++) {
        ch = data[index88];
        if (ch === "_") continue;
        if (!isHexCode(data.charCodeAt(index88))) return false;
        hasDigits = true;
      }
      return hasDigits && ch !== "_";
    }
    for (; index88 < max; index88++) {
      ch = data[index88];
      if (ch === "_") continue;
      if (!isOctCode(data.charCodeAt(index88))) return false;
      hasDigits = true;
    }
    return hasDigits && ch !== "_";
  }
  if (ch === "_") return false;
  for (; index88 < max; index88++) {
    ch = data[index88];
    if (ch === "_") continue;
    if (!isDecCode(data.charCodeAt(index88))) return false;
    hasDigits = true;
  }
  if (!hasDigits || ch === "_") return false;
  return /^(:[0-5]?[0-9])+$/.test(data.slice(index88));
}
function constructYamlInteger(data) {
  let value2 = data;
  if (value2.includes("_")) value2 = value2.replace(/_/g, "");
  let sign = 1;
  let ch = value2[0];
  if (ch === "-" || ch === "+") {
    if (ch === "-") sign = -1;
    value2 = value2.slice(1);
    ch = value2[0];
  }
  if (value2 === "0") return 0;
  if (ch === "0") {
    if (value2[1] === "b") return sign * parseInt(value2.slice(2), 2);
    if (value2[1] === "x") return sign * parseInt(value2, 16);
    return sign * parseInt(value2, 8);
  }
  return sign * parseInt(value2, 10);
}
function isInteger(object) {
  if (object instanceof Number) object = object.valueOf();
  return typeof object === "number" && object % 1 === 0 && !isNegativeZero(object);
}
function resolveYamlOmap(data) {
  const objectKeys = /* @__PURE__ */ new Set();
  for (const object of data) {
    if (!isPlainObject(object)) return false;
    const keys = Object.keys(object);
    if (keys.length !== 1) return false;
    for (const key2 of keys) {
      if (objectKeys.has(key2)) return false;
      objectKeys.add(key2);
    }
  }
  return true;
}
function resolveYamlPairs(data) {
  if (data === null) return true;
  return data.every((it2) => isPlainObject(it2) && Object.keys(it2).length === 1);
}
function resolveYamlTimestamp(data) {
  if (data === null) return false;
  if (YAML_DATE_REGEXP.exec(data) !== null) return true;
  if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
  return false;
}
function constructYamlTimestamp(data) {
  let match = YAML_DATE_REGEXP.exec(data);
  if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
  if (match === null) throw new Error("Cannot construct YAML timestamp: date resolve error");
  const year2 = +match[1];
  const month = +match[2] - 1;
  const day2 = +match[3];
  if (!match[4]) return new Date(Date.UTC(year2, month, day2));
  const hour2 = +match[4];
  const minute2 = +match[5];
  const second = +match[6];
  let fraction = 0;
  if (match[7]) {
    let partFraction = match[7].slice(0, 3);
    while (partFraction.length < 3) partFraction += "0";
    fraction = +partFraction;
  }
  let delta = null;
  if (match[9] && match[10]) {
    const tzHour = +match[10];
    const tzMinute = +(match[11] || 0);
    delta = (tzHour * 60 + tzMinute) * 6e4;
    if (match[9] === "-") delta = -delta;
  }
  const date = new Date(Date.UTC(year2, month, day2, hour2, minute2, second, fraction));
  if (delta) date.setTime(date.getTime() - delta);
  return date;
}
function representYamlTimestamp(date) {
  return date.toISOString();
}
function createTypeMap(implicitTypes, explicitTypes) {
  const result = {
    fallback: /* @__PURE__ */ new Map(),
    mapping: /* @__PURE__ */ new Map(),
    scalar: /* @__PURE__ */ new Map(),
    sequence: /* @__PURE__ */ new Map()
  };
  const fallbackMap = result.fallback;
  for (const type of [...implicitTypes, ...explicitTypes]) {
    result[type.kind].set(type.tag, type);
    fallbackMap.set(type.tag, type);
  }
  return result;
}
function createSchema({ explicitTypes = [], implicitTypes = [], include }) {
  if (include) {
    implicitTypes.push(...include.implicitTypes);
    explicitTypes.push(...include.explicitTypes);
  }
  return {
    implicitTypes,
    explicitTypes,
    typeMap: createTypeMap(implicitTypes, explicitTypes)
  };
}
function hexCharCodeToNumber(charCode) {
  if (48 <= charCode && charCode <= 57) return charCode - 48;
  const lc = charCode | 32;
  if (97 <= lc && lc <= 102) return lc - 97 + 10;
  return -1;
}
function decimalCharCodeToNumber(charCode) {
  if (48 <= charCode && charCode <= 57) return charCode - 48;
  return -1;
}
function codepointToChar(codepoint) {
  if (codepoint <= 65535) return String.fromCharCode(codepoint);
  return String.fromCharCode((codepoint - 65536 >> 10) + 55296, (codepoint - 65536 & 1023) + 56320);
}
function getSnippet(buffer2, position) {
  if (!buffer2) return null;
  let start = position;
  let end = position;
  let head2 = "";
  let tail = "";
  while (start > 0 && !DELIMITERS.includes(buffer2.charAt(start - 1))) {
    start--;
    if (position - start > MAX_LENGTH / 2 - 1) {
      head2 = " ... ";
      start += 5;
      break;
    }
  }
  while (end < buffer2.length && !DELIMITERS.includes(buffer2.charAt(end))) {
    end++;
    if (end - position > MAX_LENGTH / 2 - 1) {
      tail = " ... ";
      end -= 5;
      break;
    }
  }
  const snippet = buffer2.slice(start, end);
  const indent = " ".repeat(INDENT);
  const caretIndent = " ".repeat(INDENT + position - start + head2.length);
  return `${indent + head2 + snippet + tail}
${caretIndent}^`;
}
function getIndentStatus(lineIndent, parentIndent) {
  if (lineIndent > parentIndent) return 1;
  if (lineIndent < parentIndent) return -1;
  return 0;
}
function writeFoldedLines(count) {
  if (count === 1) return " ";
  if (count > 1) return "\n".repeat(count - 1);
  return "";
}
function sanitizeInput(input) {
  input = String(input);
  if (input.length > 0) {
    if (!isEOL(input.charCodeAt(input.length - 1))) input += "\n";
    if (input.charCodeAt(0) === 65279) input = input.slice(1);
  }
  return input;
}
function parse2(content, options2 = {}) {
  content = sanitizeInput(content);
  const documents = new LoaderState(content, {
    ...options2,
    schema: SCHEMA_MAP.get(options2.schema)
  }).readDocuments({ singleDocument: true });
  const document2 = documents.next().value;
  documents.next();
  return document2 ?? null;
}
function charCodeToHexString(charCode) {
  const hexString = charCode.toString(16).toUpperCase();
  if (charCode <= 255) return `\\x${hexString.padStart(2, "0")}`;
  if (charCode <= 65535) return `\\u${hexString.padStart(4, "0")}`;
  if (charCode <= 4294967295) return `\\U${hexString.padStart(8, "0")}`;
  throw new Error("Code point within a string may not be greater than 0xFFFFFFFF");
}
function createStyleMap(map2) {
  const result = /* @__PURE__ */ new Map();
  for (let tag2 of Object.keys(map2)) {
    const style = String(map2[tag2]);
    if (tag2.slice(0, 2) === "!!") tag2 = `tag:yaml.org,2002:${tag2.slice(2)}`;
    result.set(tag2, style);
  }
  return result;
}
function indentString(string, spaces) {
  const indent = " ".repeat(spaces);
  return string.split("\n").map((line) => line.length ? indent + line : line).join("\n");
}
function generateNextLine(indent, level) {
  return `
${" ".repeat(indent * level)}`;
}
function isPrintable(c2) {
  return 32 <= c2 && c2 <= 126 || 161 <= c2 && c2 <= 55295 && c2 !== 8232 && c2 !== 8233 || 57344 <= c2 && c2 <= 65533 && c2 !== 65279 || 65536 <= c2 && c2 <= 1114111;
}
function isPlainSafe(c2) {
  return isPrintable(c2) && c2 !== 65279 && c2 !== 44 && c2 !== 91 && c2 !== 93 && c2 !== 123 && c2 !== 125 && c2 !== 58 && c2 !== 35;
}
function isPlainSafeFirst(c2) {
  return isPlainSafe(c2) && !isWhiteSpace(c2) && c2 !== 45 && c2 !== 63 && c2 !== 38 && c2 !== 42 && c2 !== 33 && c2 !== 124 && c2 !== 62 && c2 !== 39 && c2 !== 34 && c2 !== 37 && c2 !== 64 && c2 !== 96;
}
function needIndentIndicator(string) {
  return LEADING_SPACE_REGEXP.test(string);
}
function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, implicitTypes, quoteStyle) {
  const shouldTrackWidth = lineWidth !== -1;
  let hasLineBreak = false;
  let hasFoldableLine = false;
  let previousLineBreak = -1;
  let plain = isPlainSafeFirst(string.codePointAt(0)) && !isWhiteSpace(string.charCodeAt(string.length - 1));
  let char;
  let i;
  if (singleLineOnly) for (i = 0; i < string.length; i++) {
    char = string.codePointAt(i);
    if (!isPrintable(char)) return STYLE_DOUBLE;
    plain = plain && isPlainSafe(char);
    if (char > 65535) i++;
  }
  else {
    for (i = 0; i < string.length; i++) {
      char = string.codePointAt(i);
      if (char === 10) {
        hasLineBreak = true;
        if (shouldTrackWidth) {
          hasFoldableLine = hasFoldableLine || i - previousLineBreak - 1 > lineWidth && string[previousLineBreak + 1] !== " ";
          previousLineBreak = i;
        }
      } else if (!isPrintable(char)) return STYLE_DOUBLE;
      plain = plain && isPlainSafe(char);
      if (char > 65535) i++;
    }
    hasFoldableLine = hasFoldableLine || shouldTrackWidth && i - previousLineBreak - 1 > lineWidth && string[previousLineBreak + 1] !== " ";
  }
  if (!hasLineBreak && !hasFoldableLine) return plain && !implicitTypes.some((type) => type.resolve(string)) ? STYLE_PLAIN : quoteStyle === "'" ? STYLE_SINGLE : STYLE_DOUBLE;
  if (indentPerLevel > 9 && needIndentIndicator(string)) return STYLE_DOUBLE;
  return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;
}
function foldLine(line, width) {
  if (line === "" || line[0] === " ") return line;
  const breakRegExp = / [^ ]/g;
  let start = 0;
  let end;
  let curr = 0;
  let next2 = 0;
  const lines = [];
  for (const match of line.matchAll(breakRegExp)) {
    next2 = match.index;
    if (next2 - start > width) {
      end = curr > start ? curr : next2;
      lines.push(line.slice(start, end));
      start = end + 1;
    }
    curr = next2;
  }
  if (line.length - start > width && curr > start) {
    lines.push(line.slice(start, curr));
    lines.push(line.slice(curr + 1));
  } else lines.push(line.slice(start));
  return lines.join("\n");
}
function trimTrailingNewline(string) {
  return string.at(-1) === "\n" ? string.slice(0, -1) : string;
}
function foldString(string, width) {
  const lineRe = /(\n+)([^\n]*)/g;
  let result = (() => {
    let nextLF = string.indexOf("\n");
    nextLF = nextLF !== -1 ? nextLF : string.length;
    lineRe.lastIndex = nextLF;
    return foldLine(string.slice(0, nextLF), width);
  })();
  let prevMoreIndented = string[0] === "\n" || string[0] === " ";
  let moreIndented;
  let match;
  while (match = lineRe.exec(string)) {
    const prefix = match[1];
    const line = match[2] || "";
    moreIndented = line[0] === " ";
    result += prefix + (!prevMoreIndented && !moreIndented && line !== "" ? "\n" : "") + foldLine(line, width);
    prevMoreIndented = moreIndented;
  }
  return result;
}
function escapeString(string) {
  let result = "";
  for (let i = 0; i < string.length; i++) {
    const char = string.codePointAt(i);
    if (char > 65535) {
      result += charCodeToHexString(char);
      i++;
      continue;
    }
    const escapeSeq = ESCAPE_SEQUENCES.get(char);
    result += !escapeSeq && isPrintable(char) ? string[i] : escapeSeq || charCodeToHexString(char);
  }
  return result;
}
function blockHeader(string, indentPerLevel) {
  const indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : "";
  const clip = string[string.length - 1] === "\n";
  return `${indentIndicator}${clip && (string[string.length - 2] === "\n" || string === "\n") ? "+" : clip ? "" : "-"}
`;
}
function getDuplicateObjects(root) {
  const seenObjects = /* @__PURE__ */ new Set();
  const duplicateObjects = /* @__PURE__ */ new Set();
  const queue = [root];
  for (let i = 0; i < queue.length; i++) {
    const value2 = queue[i];
    if (!isObject(value2)) continue;
    if (seenObjects.has(value2)) {
      duplicateObjects.add(value2);
      continue;
    }
    seenObjects.add(value2);
    const children = Array.isArray(value2) ? value2 : Object.values(value2);
    queue.push(...children);
  }
  return [...duplicateObjects];
}
function stringifyValue(value2, tag2) {
  if (tag2 !== null && tag2 !== "?") return `!<${tag2}> ${value2}`;
  return value2;
}
function stringify3(data, options2 = {}) {
  return new DumperState({
    ...options2,
    schema: SCHEMA_MAP.get(options2.schema)
  }).stringify(data);
}
async function parseAnnouncementsDir(pcdPath) {
  const dir = `${pcdPath}/${ANNOUNCEMENTS_SUBDIR$1}`;
  let entries;
  try {
    entries = await collectDirEntries(dir);
  } catch (error2) {
    if (error2 instanceof Deno.errors.NotFound) return {
      parsed: [],
      errors: []
    };
    throw error2;
  }
  const parsed = [];
  const errors = [];
  for (const entry of entries) {
    if (!entry.isFile) continue;
    if (!entry.name.endsWith(".md")) continue;
    const path = `${dir}/${entry.name}`;
    try {
      const content = await Deno.readTextFile(path);
      const result = parseFile(entry.name, content);
      if ("error" in result) errors.push({
        filename: entry.name,
        reason: result.error
      });
      else parsed.push(result.parsed);
    } catch (error2) {
      errors.push({
        filename: entry.name,
        reason: describe$1(error2)
      });
    }
  }
  return {
    parsed,
    errors
  };
}
async function parseAnnouncementFile(pcdPath, id) {
  const filename = `${id}.md`;
  const path = `${pcdPath}/${ANNOUNCEMENTS_SUBDIR$1}/${filename}`;
  let content;
  try {
    content = await Deno.readTextFile(path);
  } catch (error2) {
    if (error2 instanceof Deno.errors.NotFound) return null;
    return {
      filename,
      reason: describe$1(error2)
    };
  }
  const result = parseFile(filename, content);
  if ("error" in result) return {
    filename,
    reason: result.error
  };
  return result.parsed;
}
async function collectDirEntries(dir) {
  const out = [];
  for await (const entry of Deno.readDir(dir)) out.push(entry);
  return out;
}
function parseFile(filename, content) {
  const split = splitFrontmatter(content);
  if (!split) return { error: "Missing or unterminated YAML frontmatter" };
  let raw;
  try {
    raw = parse2(split.yaml);
  } catch (error2) {
    return { error: `YAML parse error: ${describe$1(error2)}` };
  }
  const validated = validateFrontmatter(raw);
  if ("error" in validated) return { error: validated.error };
  return { parsed: {
    id: filename.slice(0, -3),
    title: validated.frontmatter.title,
    severity: validated.frontmatter.severity,
    published_at: validated.frontmatter.published_at,
    expires_at: validated.frontmatter.expires_at,
    link: validated.frontmatter.link,
    body: split.body
  } };
}
function validateFrontmatter(raw) {
  if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return { error: "Frontmatter must be a YAML mapping" };
  const obj = raw;
  const title = obj.title;
  if (typeof title !== "string" || title.trim() === "") return { error: "Field `title` is required and must be a non-empty string" };
  const severity = obj.severity;
  if (typeof severity !== "string" || !SEVERITIES.includes(severity)) return { error: `Field \`severity\` is required and must be one of: ${SEVERITIES.join(", ")}` };
  const publishedAt = normalizeDate(obj.published_at);
  if (publishedAt === null) return { error: "Field `published_at` is required and must be an ISO-8601 timestamp" };
  const expiresAt = obj.expires_at === void 0 ? null : normalizeDate(obj.expires_at);
  if (obj.expires_at !== void 0 && expiresAt === null) return { error: "Field `expires_at`, when present, must be an ISO-8601 timestamp" };
  let link;
  if (obj.link === void 0 || obj.link === null) link = null;
  else if (typeof obj.link === "string") link = obj.link;
  else return { error: "Field `link`, when present, must be a string" };
  return { frontmatter: {
    title,
    severity,
    published_at: publishedAt,
    expires_at: expiresAt,
    link
  } };
}
function normalizeDate(value2) {
  if (value2 instanceof Date) {
    if (Number.isNaN(value2.getTime())) return null;
    return value2.toISOString().replace(/\.000Z$/, "Z");
  }
  if (typeof value2 === "string") {
    const parsed = Date.parse(value2);
    if (Number.isNaN(parsed)) return null;
    return value2;
  }
  return null;
}
function splitFrontmatter(content) {
  const lines = content.split(/\r?\n/);
  if (lines.length === 0 || lines[0] !== "---") return null;
  let closingIndex = -1;
  for (let i = 1; i < lines.length; i++) if (lines[i] === "---") {
    closingIndex = i;
    break;
  }
  if (closingIndex === -1) return null;
  const yaml = lines.slice(1, closingIndex).join("\n");
  let bodyLines = lines.slice(closingIndex + 1);
  if (bodyLines.length > 0 && bodyLines[0] === "") bodyLines = bodyLines.slice(1);
  return {
    yaml,
    body: bodyLines.join("\n")
  };
}
function describe$1(error2) {
  if (error2 instanceof Error) return error2.message;
  return String(error2);
}
function rowToRecord2(row) {
  return {
    id: row.id,
    databaseId: row.database_id,
    title: row.title,
    severity: row.severity,
    publishedAt: row.published_at,
    expiresAt: row.expires_at,
    link: row.link,
    body: row.body,
    withdrawn: row.withdrawn === 1,
    readAt: row.read_at,
    fetchedAt: row.fetched_at
  };
}
async function reconcileFromWorkingCopy(databaseId, opts) {
  const empty = (status, name = "") => ({
    status,
    databaseId,
    databaseName: name,
    newlyInserted: [],
    parseErrors: [],
    firstSync: opts.isFirstSync,
    counts: {
      upserts: 0,
      withdrawn: 0,
      unwithdrawn: 0,
      dropped: 0
    }
  });
  const instance = databaseInstancesQueries.getById(databaseId);
  if (!instance) {
    await logger.warn("reconcileFromWorkingCopy called with unknown database id", {
      source: LOG_SOURCE,
      meta: { databaseId }
    });
    return empty("failed");
  }
  const pcdPath = getPCDPath(instance.uuid);
  let parsed;
  let parseErrors;
  try {
    const result = await parseAnnouncementsDir(pcdPath);
    parsed = result.parsed;
    parseErrors = result.errors;
  } catch (error2) {
    await logger.error("Failed to read announcements directory", {
      source: LOG_SOURCE,
      meta: {
        databaseId,
        pcdPath,
        error: describe(error2)
      }
    });
    return empty("failed", instance.name);
  }
  if (parseErrors.length > 0) await logger.warn(`Skipped ${parseErrors.length} malformed announcement file(s)`, {
    source: LOG_SOURCE,
    meta: {
      databaseId,
      errors: parseErrors
    }
  });
  const fetchedAt = (/* @__PURE__ */ new Date()).toISOString();
  const firstSync = opts.isFirstSync;
  const readAtOnInsert = firstSync ? fetchedAt : null;
  const existing = databaseAnnouncementQueries.listForDatabase(databaseId);
  const plan = reconcile(parsed, existing, { cap: DATABASE_ANNOUNCEMENTS_CAP });
  if (plan.droppedCount > 0) await logger.warn(`Dropped ${plan.droppedCount} announcements beyond cap`, {
    source: LOG_SOURCE,
    meta: {
      databaseId,
      cap: DATABASE_ANNOUNCEMENTS_CAP
    }
  });
  try {
    await db.transaction(() => {
      for (const a2 of plan.upserts) databaseAnnouncementQueries.upsertFromParsed(a2, databaseId, fetchedAt, readAtOnInsert);
      if (plan.withdrawnIds.length > 0) databaseAnnouncementQueries.markWithdrawn(plan.withdrawnIds, databaseId);
      if (plan.unwithdrawnIds.length > 0) databaseAnnouncementQueries.markUnwithdrawn(plan.unwithdrawnIds, databaseId);
    });
  } catch (error2) {
    await logger.error("Failed to apply database announcement reconcile plan", {
      source: LOG_SOURCE,
      meta: {
        databaseId,
        error: describe(error2)
      }
    });
    return {
      ...empty("failed", instance.name),
      parseErrors,
      firstSync
    };
  }
  const newlyInserted = firstSync ? [] : plan.newlyInserted.map((p2) => {
    const row = databaseAnnouncementQueries.getById(p2.id, databaseId);
    return row ? rowToRecord2(row) : null;
  }).filter((r2) => r2 !== null);
  return {
    status: "ok",
    databaseId,
    databaseName: instance.name,
    newlyInserted,
    parseErrors,
    firstSync,
    counts: {
      upserts: plan.upserts.length,
      withdrawn: plan.withdrawnIds.length,
      unwithdrawn: plan.unwithdrawnIds.length,
      dropped: plan.droppedCount
    }
  };
}
async function reconcileAndNotify(databaseId, context2) {
  let report;
  try {
    report = await reconcileFromWorkingCopy(databaseId, { isFirstSync: context2.isFirstSync });
  } catch (error2) {
    await logger.error("Database announcements reconcile threw unexpectedly", {
      source: context2.source,
      meta: {
        jobId: context2.jobId,
        databaseId,
        error: describe(error2)
      }
    });
    return null;
  }
  if (report.status === "failed") return report;
  for (const announcement of report.newlyInserted) try {
    await notificationManager.notify(notifications.announcementNew({
      announcement,
      source: {
        kind: "pcd",
        databaseName: report.databaseName
      }
    }));
  } catch (error2) {
    await logger.error("Failed to send database announcement notification", {
      source: context2.source,
      meta: {
        jobId: context2.jobId,
        databaseId,
        announcementId: announcement.id,
        error: describe(error2)
      }
    });
  }
  return report;
}
function getDetail(id, databaseId) {
  const row = databaseAnnouncementQueries.getById(id, databaseId);
  return row ? rowToRecord2(row) : void 0;
}
function markRead(id, databaseId) {
  databaseAnnouncementQueries.markRead(id, databaseId, (/* @__PURE__ */ new Date()).toISOString());
}
function markUnread(id, databaseId) {
  databaseAnnouncementQueries.markUnread(id, databaseId);
}
function describe(error2) {
  if (error2 instanceof Error) return error2.message;
  return String(error2);
}
function generateUlid() {
  return encodeTime(Date.now(), TIME_LEN) + encodeRandom(RANDOM_LEN);
}
function encodeTime(ms, length) {
  let value2 = ms;
  let out = "";
  for (let i = length - 1; i >= 0; i--) {
    out = CROCKFORD[value2 % 32] + out;
    value2 = Math.floor(value2 / 32);
  }
  return out;
}
function encodeRandom(length) {
  const bytes = new Uint8Array(length);
  crypto.getRandomValues(bytes);
  let out = "";
  for (const byte of bytes) out += CROCKFORD[byte % 32];
  return out;
}
function generateAnnouncementId() {
  return generateUlid();
}
async function writeAnnouncement(pcdPath, id, input) {
  const dir = `${pcdPath}/${ANNOUNCEMENTS_SUBDIR}`;
  await Deno.mkdir(dir, { recursive: true });
  const targetPath = `${dir}/${id}.md`;
  const content = formatFile(input);
  const tempPath = `${targetPath}.${crypto.randomUUID()}.tmp`;
  try {
    await Deno.writeTextFile(tempPath, content);
    await Deno.rename(tempPath, targetPath);
  } catch (error2) {
    try {
      await Deno.remove(tempPath);
    } catch {
    }
    throw error2;
  }
}
async function deleteAnnouncement(pcdPath, id) {
  const path = `${pcdPath}/${ANNOUNCEMENTS_SUBDIR}/${id}.md`;
  try {
    await Deno.remove(path);
    return true;
  } catch (error2) {
    if (error2 instanceof Deno.errors.NotFound) return false;
    throw error2;
  }
}
function formatFile(input) {
  const frontmatter = {
    title: input.title,
    severity: input.severity,
    published_at: input.publishedAt
  };
  if (input.expiresAt !== null) frontmatter.expires_at = input.expiresAt;
  if (input.link !== null) frontmatter.link = input.link;
  const yaml = stringify3(frontmatter);
  if (input.body === "") return `---
${yaml}---
`;
  return `---
${yaml}---

${input.body}`;
}
var databaseAnnouncementQueries, sectionLabels, DEFAULT_MAX_ENTITIES, SEVERITY_MAP, notifications, BASE64_MAP, binary, YAML_TRUE_BOOLEANS, YAML_FALSE_BOOLEANS, YAML_BOOLEANS, bool, YAML_FLOAT_REGEXP, SCIENTIFIC_WITHOUT_DOT_REGEXP, float, int, map, merge, nil, omap, pairs, REGEXP, regexp, seq, set2, str, YAML_DATE_REGEXP, YAML_TIMESTAMP_REGEXP, timestamp, undefinedType, FAILSAFE_SCHEMA, JSON_SCHEMA, CORE_SCHEMA, DEFAULT_SCHEMA, EXTENDED_SCHEMA, SCHEMA_MAP, YamlSyntaxError, CONTEXT_FLOW_IN, CONTEXT_FLOW_OUT, CONTEXT_BLOCK_IN, CONTEXT_BLOCK_OUT, CHOMPING_CLIP, CHOMPING_STRIP, CHOMPING_KEEP, PATTERN_NON_PRINTABLE_REGEXP, PATTERN_NON_ASCII_LINE_BREAKS_REGEXP, PATTERN_FLOW_INDICATORS_REGEXP, PATTERN_TAG_HANDLE_REGEXP, PATTERN_TAG_URI_REGEXP, ESCAPED_HEX_LENGTHS, SIMPLE_ESCAPE_SEQUENCES, INDENT, MAX_LENGTH, DELIMITERS, Scanner, LoaderState, STYLE_PLAIN, STYLE_SINGLE, STYLE_LITERAL, STYLE_FOLDED, STYLE_DOUBLE, LEADING_SPACE_REGEXP, ESCAPE_SEQUENCES, DEPRECATED_BOOLEANS_SYNTAX, DumperState, ANNOUNCEMENTS_SUBDIR$1, SEVERITIES, DATABASE_ANNOUNCEMENTS_CAP, LOG_SOURCE, CROCKFORD, TIME_LEN, RANDOM_LEN, ANNOUNCEMENTS_SUBDIR;
var init_database = __esm({
  async "dist/build/server/chunks/database.js"() {
    "use strict";
    await init_db();
    await init_databaseInstances();
    await init_NotificationManager();
    init_test2();
    init_operations2();
    databaseAnnouncementQueries = {
      /**
      * Return all rows for a single database, newest first.
      */
      listForDatabase(databaseId) {
        return db.query(`SELECT * FROM database_announcements
			 WHERE database_id = ?
			 ORDER BY published_at DESC, id DESC`, databaseId);
      },
      /**
      * Return every row across every database, newest first. Used by the
      * inbox UNION in `announcements/inbox.ts`.
      */
      listAll() {
        return db.query(`SELECT * FROM database_announcements
			 ORDER BY published_at DESC, id DESC`);
      },
      /**
      * Return a single row by (id, databaseId) tuple.
      */
      getById(id, databaseId) {
        return db.queryFirst("SELECT * FROM database_announcements WHERE id = ? AND database_id = ?", id, databaseId);
      },
      /**
      * Insert a new row, or update an existing row preserving `read_at`.
      * Returns true if the row was newly inserted (so the caller can fire a
      * notification).
      *
      * `readAtOnInsert` lets the caller mark first-sync inserts as already
      * read by passing the current timestamp. Pass `null` for the normal
      * case (subsequent syncs, where new entries should appear unread and
      * fire `announcement.new`).
      */
      upsertFromParsed(announcement, databaseId, fetchedAt, readAtOnInsert) {
        if (!this.getById(announcement.id, databaseId)) {
          db.execute(`INSERT INTO database_announcements (
					id, database_id, title, severity, published_at, expires_at,
					link, body, withdrawn, read_at, fetched_at
				) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?)`, announcement.id, databaseId, announcement.title, announcement.severity, announcement.published_at, announcement.expires_at, announcement.link, announcement.body, readAtOnInsert, fetchedAt);
          return true;
        }
        db.execute(`UPDATE database_announcements SET
				title = ?,
				severity = ?,
				published_at = ?,
				expires_at = ?,
				link = ?,
				body = ?,
				fetched_at = ?
			WHERE id = ? AND database_id = ?`, announcement.title, announcement.severity, announcement.published_at, announcement.expires_at, announcement.link, announcement.body, fetchedAt, announcement.id, databaseId);
        return false;
      },
      /**
      * Set `withdrawn = 1` for the given ids within a single database.
      */
      markWithdrawn(ids, databaseId) {
        for (const id of ids) db.execute("UPDATE database_announcements SET withdrawn = 1 WHERE id = ? AND database_id = ?", id, databaseId);
      },
      /**
      * Set `withdrawn = 0` for the given ids within a single database.
      */
      markUnwithdrawn(ids, databaseId) {
        for (const id of ids) db.execute("UPDATE database_announcements SET withdrawn = 0 WHERE id = ? AND database_id = ?", id, databaseId);
      },
      /**
      * Set `read_at` for a single announcement. No-op if already read.
      */
      markRead(id, databaseId, now) {
        db.execute(`UPDATE database_announcements SET read_at = ?
			 WHERE id = ? AND database_id = ? AND read_at IS NULL`, now, id, databaseId);
      },
      /**
      * Clear `read_at` for a single announcement (flip back to unread).
      */
      markUnread(id, databaseId) {
        db.execute("UPDATE database_announcements SET read_at = NULL WHERE id = ? AND database_id = ?", id, databaseId);
      }
    };
    sectionLabels = {
      qualityProfiles: "Quality Profiles",
      delayProfiles: "Delay Profiles",
      mediaManagement: "Media Management"
    };
    DEFAULT_MAX_ENTITIES = 15;
    SEVERITY_MAP = {
      info: "info",
      warning: "warning",
      critical: "error"
    };
    notifications = {
      test,
      rename,
      upgrade,
      arrSync,
      arrCleanup,
      arrDriftDetected,
      arrDriftFailed,
      pcdUpdatesAvailable,
      pcdSyncSuccess,
      pcdSyncFailed,
      pcdLinkFailed,
      backupSuccess,
      backupFailed,
      announcementNew
    };
    BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";
    binary = {
      tag: "tag:yaml.org,2002:binary",
      construct: constructYamlBinary,
      kind: "scalar",
      predicate: isBinary,
      represent: representYamlBinary,
      resolve: resolveYamlBinary
    };
    YAML_TRUE_BOOLEANS = [
      "true",
      "True",
      "TRUE"
    ];
    YAML_FALSE_BOOLEANS = [
      "false",
      "False",
      "FALSE"
    ];
    YAML_BOOLEANS = [...YAML_TRUE_BOOLEANS, ...YAML_FALSE_BOOLEANS];
    bool = {
      tag: "tag:yaml.org,2002:bool",
      kind: "scalar",
      defaultStyle: "lowercase",
      predicate: (value2) => typeof value2 === "boolean" || value2 instanceof Boolean,
      construct: (data) => YAML_TRUE_BOOLEANS.includes(data),
      resolve: (data) => YAML_BOOLEANS.includes(data),
      represent: {
        lowercase: (object) => {
          return (object instanceof Boolean ? object.valueOf() : object) ? "true" : "false";
        },
        uppercase: (object) => {
          return (object instanceof Boolean ? object.valueOf() : object) ? "TRUE" : "FALSE";
        },
        camelcase: (object) => {
          return (object instanceof Boolean ? object.valueOf() : object) ? "True" : "False";
        }
      }
    };
    YAML_FLOAT_REGEXP = /* @__PURE__ */ new RegExp("^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");
    SCIENTIFIC_WITHOUT_DOT_REGEXP = /^[-+]?[0-9]+e/;
    float = {
      tag: "tag:yaml.org,2002:float",
      construct: constructYamlFloat,
      defaultStyle: "lowercase",
      kind: "scalar",
      predicate: isFloat,
      represent: representYamlFloat,
      resolve: resolveYamlFloat
    };
    int = {
      tag: "tag:yaml.org,2002:int",
      construct: constructYamlInteger,
      defaultStyle: "decimal",
      kind: "scalar",
      predicate: isInteger,
      represent: {
        binary(object) {
          const value2 = object instanceof Number ? object.valueOf() : object;
          return value2 >= 0 ? `0b${value2.toString(2)}` : `-0b${value2.toString(2).slice(1)}`;
        },
        octal(object) {
          const value2 = object instanceof Number ? object.valueOf() : object;
          return value2 >= 0 ? `0${value2.toString(8)}` : `-0${value2.toString(8).slice(1)}`;
        },
        decimal(object) {
          return (object instanceof Number ? object.valueOf() : object).toString(10);
        },
        hexadecimal(object) {
          const value2 = object instanceof Number ? object.valueOf() : object;
          return value2 >= 0 ? `0x${value2.toString(16).toUpperCase()}` : `-0x${value2.toString(16).toUpperCase().slice(1)}`;
        }
      },
      resolve: resolveYamlInteger
    };
    map = {
      tag: "tag:yaml.org,2002:map",
      resolve() {
        return true;
      },
      construct(data) {
        return data !== null ? data : {};
      },
      kind: "mapping"
    };
    merge = {
      tag: "tag:yaml.org,2002:merge",
      kind: "scalar",
      resolve: (data) => data === "<<" || data === null,
      construct: (data) => data
    };
    nil = {
      tag: "tag:yaml.org,2002:null",
      kind: "scalar",
      defaultStyle: "lowercase",
      predicate: (object) => object === null,
      construct: () => null,
      resolve: (data) => {
        return data === "~" || data === "null" || data === "Null" || data === "NULL";
      },
      represent: {
        lowercase: () => "null",
        uppercase: () => "NULL",
        camelcase: () => "Null"
      }
    };
    omap = {
      tag: "tag:yaml.org,2002:omap",
      kind: "sequence",
      resolve: resolveYamlOmap,
      construct(data) {
        return data;
      }
    };
    pairs = {
      tag: "tag:yaml.org,2002:pairs",
      construct(data) {
        return data?.flatMap(Object.entries) ?? [];
      },
      kind: "sequence",
      resolve: resolveYamlPairs
    };
    REGEXP = /^\/(?<regexp>[\s\S]+)\/(?<modifiers>[gismuy]*)$/;
    regexp = {
      tag: "tag:yaml.org,2002:js/regexp",
      kind: "scalar",
      resolve(data) {
        if (data === null || !data.length) return false;
        if (data.charAt(0) === "/") {
          const groups = data.match(REGEXP)?.groups;
          if (!groups) return false;
          const modifiers = groups.modifiers ?? "";
          if (new Set(modifiers).size < modifiers.length) return false;
        }
        return true;
      },
      construct(data) {
        const { regexp: regexp2 = data, modifiers = "" } = data.match(REGEXP)?.groups ?? {};
        return new RegExp(regexp2, modifiers);
      },
      predicate: (object) => object instanceof RegExp,
      represent: (object) => object.toString()
    };
    seq = {
      tag: "tag:yaml.org,2002:seq",
      kind: "sequence",
      resolve: () => true,
      construct: (data) => data !== null ? data : []
    };
    set2 = {
      tag: "tag:yaml.org,2002:set",
      kind: "mapping",
      construct: (data) => data !== null ? data : {},
      resolve: (data) => {
        if (data === null) return true;
        return Object.values(data).every((it2) => it2 === null);
      }
    };
    str = {
      tag: "tag:yaml.org,2002:str",
      kind: "scalar",
      resolve: () => true,
      construct: (data) => data !== null ? data : ""
    };
    YAML_DATE_REGEXP = /* @__PURE__ */ new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$");
    YAML_TIMESTAMP_REGEXP = /* @__PURE__ */ new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");
    timestamp = {
      tag: "tag:yaml.org,2002:timestamp",
      construct: constructYamlTimestamp,
      predicate(object) {
        return object instanceof Date;
      },
      kind: "scalar",
      represent: representYamlTimestamp,
      resolve: resolveYamlTimestamp
    };
    undefinedType = {
      tag: "tag:yaml.org,2002:js/undefined",
      kind: "scalar",
      resolve() {
        return true;
      },
      construct() {
      },
      predicate(object) {
        return typeof object === "undefined";
      },
      represent() {
        return "";
      }
    };
    FAILSAFE_SCHEMA = createSchema({ explicitTypes: [
      str,
      seq,
      map
    ] });
    JSON_SCHEMA = createSchema({
      implicitTypes: [
        nil,
        bool,
        int,
        float
      ],
      include: FAILSAFE_SCHEMA
    });
    CORE_SCHEMA = createSchema({ include: JSON_SCHEMA });
    DEFAULT_SCHEMA = createSchema({
      explicitTypes: [
        binary,
        omap,
        pairs,
        set2
      ],
      implicitTypes: [timestamp, merge],
      include: CORE_SCHEMA
    });
    EXTENDED_SCHEMA = createSchema({
      explicitTypes: [regexp, undefinedType],
      include: DEFAULT_SCHEMA
    });
    SCHEMA_MAP = /* @__PURE__ */ new Map([
      ["core", CORE_SCHEMA],
      ["default", DEFAULT_SCHEMA],
      ["failsafe", FAILSAFE_SCHEMA],
      ["json", JSON_SCHEMA],
      ["extended", EXTENDED_SCHEMA]
    ]);
    YamlSyntaxError = class extends SyntaxError {
      /**
      * The line number where the error occurred (1-indexed).
      *
      * @example Usage
      * ```ts
      * import { YamlSyntaxError } from "@std/yaml";
      * import { assertEquals } from "@std/assert";
      *
      * const error = new YamlSyntaxError("Test", { line: 5, column: 10, offset: 50 });
      * assertEquals(error.line, 5);
      * ```
      */
      line;
      /**
      * The column number where the error occurred (1-indexed).
      *
      * @example Usage
      * ```ts
      * import { YamlSyntaxError } from "@std/yaml";
      * import { assertEquals } from "@std/assert";
      *
      * const error = new YamlSyntaxError("Test", { line: 5, column: 10, offset: 50 });
      * assertEquals(error.column, 10);
      * ```
      */
      column;
      /**
      * The character offset where the error occurred (0-indexed).
      *
      * @example Usage
      * ```ts
      * import { YamlSyntaxError } from "@std/yaml";
      * import { assertEquals } from "@std/assert";
      *
      * const error = new YamlSyntaxError("Test", { line: 5, column: 10, offset: 50 });
      * assertEquals(error.offset, 50);
      * ```
      */
      offset;
      /**
      * A formatted snippet of the source around the error, including a caret
      * line indicating the column. Undefined when the source is empty.
      *
      * @example Usage
      * ```ts
      * import { YamlSyntaxError } from "@std/yaml";
      * import { assertEquals } from "@std/assert";
      *
      * const snippet = "    foo: bar\n         ^";
      * const error = new YamlSyntaxError(
      *   "Test",
      *   { line: 1, column: 6, offset: 5 },
      *   snippet,
      * );
      * assertEquals(error.snippet, snippet);
      * ```
      */
      snippet;
      /**
      * Constructs a new YamlSyntaxError.
      *
      * The constructed `message` is `${message} at line ${line}, column ${column}`,
      * with `:\n${snippet}` appended when a snippet is provided.
      *
      * @param message The error message describing the syntax issue.
      * @param position The position in the YAML source where the error occurred.
      * @param snippet Optional formatted snippet of the source around the error.
      */
      constructor(message2, position, snippet) {
        let fullMessage = `${message2} at line ${position.line}, column ${position.column}`;
        if (snippet) fullMessage += `:
${snippet}`;
        super(fullMessage);
        this.name = "YamlSyntaxError";
        this.line = position.line;
        this.column = position.column;
        this.offset = position.offset;
        if (snippet !== void 0) this.snippet = snippet;
      }
    };
    CONTEXT_FLOW_IN = 1;
    CONTEXT_FLOW_OUT = 2;
    CONTEXT_BLOCK_IN = 3;
    CONTEXT_BLOCK_OUT = 4;
    CHOMPING_CLIP = 1;
    CHOMPING_STRIP = 2;
    CHOMPING_KEEP = 3;
    PATTERN_NON_PRINTABLE_REGEXP = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
    PATTERN_NON_ASCII_LINE_BREAKS_REGEXP = /[\x85\u2028\u2029]/;
    PATTERN_FLOW_INDICATORS_REGEXP = /[,\[\]\{\}]/;
    PATTERN_TAG_HANDLE_REGEXP = /^(?:!|!!|![a-z\-]+!)$/i;
    PATTERN_TAG_URI_REGEXP = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
    ESCAPED_HEX_LENGTHS = /* @__PURE__ */ new Map([
      [120, 2],
      [117, 4],
      [85, 8]
    ]);
    SIMPLE_ESCAPE_SEQUENCES = /* @__PURE__ */ new Map([
      [48, "\0"],
      [97, "\x07"],
      [98, "\b"],
      [116, "	"],
      [9, "	"],
      [110, "\n"],
      [118, "\v"],
      [102, "\f"],
      [114, "\r"],
      [101, "\x1B"],
      [32, " "],
      [34, '"'],
      [47, "/"],
      [92, "\\"],
      [78, "\x85"],
      [95, "\xA0"],
      [76, "\u2028"],
      [80, "\u2029"]
    ]);
    INDENT = 4;
    MAX_LENGTH = 75;
    DELIMITERS = "\0\r\n\x85\u2028\u2029";
    Scanner = class {
      source;
      #length;
      position = 0;
      constructor(source2) {
        source2 += "\0";
        this.source = source2;
        this.#length = source2.length;
      }
      peek(offset = 0) {
        return this.source.charCodeAt(this.position + offset);
      }
      next() {
        this.position += 1;
      }
      eof() {
        return this.position >= this.#length - 1;
      }
    };
    LoaderState = class {
      #scanner;
      lineIndent = 0;
      lineStart = 0;
      line = 0;
      onWarning;
      allowDuplicateKeys;
      implicitTypes;
      typeMap;
      checkLineBreaks = false;
      tagMap = /* @__PURE__ */ new Map();
      anchorMap = /* @__PURE__ */ new Map();
      constructor(input, { schema = DEFAULT_SCHEMA, onWarning, allowDuplicateKeys = false }) {
        this.#scanner = new Scanner(input);
        this.onWarning = onWarning;
        this.allowDuplicateKeys = allowDuplicateKeys;
        this.implicitTypes = schema.implicitTypes;
        this.typeMap = schema.typeMap;
        this.readIndent();
      }
      skipWhitespaces() {
        let ch = this.#scanner.peek();
        while (isWhiteSpace(ch)) {
          this.#scanner.next();
          ch = this.#scanner.peek();
        }
      }
      skipComment() {
        let ch = this.#scanner.peek();
        if (ch !== 35) return;
        this.#scanner.next();
        ch = this.#scanner.peek();
        while (ch !== 0 && !isEOL(ch)) {
          this.#scanner.next();
          ch = this.#scanner.peek();
        }
      }
      readIndent() {
        let ch = this.#scanner.peek();
        while (ch === 32) {
          this.lineIndent += 1;
          this.#scanner.next();
          ch = this.#scanner.peek();
        }
      }
      #createError(message2) {
        const offset = this.#scanner.position;
        const snippet = getSnippet(this.#scanner.source, offset) ?? void 0;
        return new YamlSyntaxError(message2, {
          line: this.line + 1,
          column: offset - this.lineStart + 1,
          offset
        }, snippet);
      }
      dispatchWarning(message2) {
        const error2 = this.#createError(message2);
        this.onWarning?.(error2);
      }
      yamlDirectiveHandler(args) {
        if (args.length !== 1) throw this.#createError("Cannot handle YAML directive: YAML directive accepts exactly one argument");
        const match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
        if (match === null) throw this.#createError("Cannot handle YAML directive: ill-formed argument");
        const major = parseInt(match[1], 10);
        const minor = parseInt(match[2], 10);
        if (major !== 1) throw this.#createError("Cannot handle YAML directive: unacceptable YAML version");
        this.checkLineBreaks = minor < 2;
        if (minor !== 1 && minor !== 2) this.dispatchWarning("Cannot handle YAML directive: unsupported YAML version");
        return args[0] ?? null;
      }
      tagDirectiveHandler(args) {
        if (args.length !== 2) throw this.#createError(`Cannot handle tag directive: directive accepts exactly two arguments, received ${args.length}`);
        const handle2 = args[0];
        const prefix = args[1];
        if (!PATTERN_TAG_HANDLE_REGEXP.test(handle2)) throw this.#createError(`Cannot handle tag directive: ill-formed handle (first argument) in "${handle2}"`);
        if (this.tagMap.has(handle2)) throw this.#createError(`Cannot handle tag directive: previously declared suffix for "${handle2}" tag handle`);
        if (!PATTERN_TAG_URI_REGEXP.test(prefix)) throw this.#createError("Cannot handle tag directive: ill-formed tag prefix (second argument) of the TAG directive");
        this.tagMap.set(handle2, prefix);
      }
      captureSegment(start, end, checkJson) {
        if (start < end) {
          const result = this.#scanner.source.slice(start, end);
          if (checkJson) for (let position = 0; position < result.length; position++) {
            const character = result.charCodeAt(position);
            if (!(character === 9 || 32 <= character && character <= 1114111)) throw this.#createError(`Expected valid JSON character: received "${character}"`);
          }
          else if (PATTERN_NON_PRINTABLE_REGEXP.test(result)) throw this.#createError("Stream contains non-printable characters");
          return result;
        }
      }
      readBlockSequence(tag2, anchor, nodeIndent) {
        let detected = false;
        const result = [];
        if (anchor !== null) this.anchorMap.set(anchor, result);
        let ch = this.#scanner.peek();
        while (ch !== 0) {
          if (ch !== 45) break;
          if (!isWhiteSpaceOrEOL(this.#scanner.peek(1))) break;
          detected = true;
          this.#scanner.next();
          if (this.skipSeparationSpace(true, -1)) {
            if (this.lineIndent <= nodeIndent) {
              result.push(null);
              ch = this.#scanner.peek();
              continue;
            }
          }
          const line = this.line;
          const newState = this.composeNode({
            parentIndent: nodeIndent,
            nodeContext: CONTEXT_BLOCK_IN,
            allowToSeek: false,
            allowCompact: true
          });
          if (newState) result.push(newState.result);
          this.skipSeparationSpace(true, -1);
          ch = this.#scanner.peek();
          if ((this.line === line || this.lineIndent > nodeIndent) && ch !== 0) throw this.#createError("Cannot read block sequence: bad indentation of a sequence entry");
          else if (this.lineIndent < nodeIndent) break;
        }
        if (detected) return {
          tag: tag2,
          anchor,
          kind: "sequence",
          result
        };
      }
      mergeMappings(destination, source2, overridableKeys) {
        if (!isObject(source2)) throw this.#createError("Cannot merge mappings: the provided source object is unacceptable");
        for (const [key2, value2] of Object.entries(source2)) {
          if (Object.hasOwn(destination, key2)) continue;
          if (key2 === "__proto__") Object.defineProperty(destination, key2, {
            value: value2,
            writable: true,
            enumerable: true,
            configurable: true
          });
          else destination[key2] = value2;
          overridableKeys.add(key2);
        }
      }
      storeMappingPair(result, overridableKeys, keyTag, keyNode, valueNode, startLine, startPos) {
        if (Array.isArray(keyNode)) {
          keyNode = Array.prototype.slice.call(keyNode);
          for (let index88 = 0; index88 < keyNode.length; index88++) {
            if (Array.isArray(keyNode[index88])) throw this.#createError("Cannot store mapping pair: nested arrays are not supported inside keys");
            if (typeof keyNode === "object" && isPlainObject(keyNode[index88])) keyNode[index88] = "[object Object]";
          }
        }
        if (typeof keyNode === "object" && isPlainObject(keyNode)) keyNode = "[object Object]";
        keyNode = String(keyNode);
        if (keyTag === "tag:yaml.org,2002:merge") if (Array.isArray(valueNode)) for (let index88 = 0; index88 < valueNode.length; index88++) this.mergeMappings(result, valueNode[index88], overridableKeys);
        else this.mergeMappings(result, valueNode, overridableKeys);
        else {
          if (!this.allowDuplicateKeys && !overridableKeys.has(keyNode) && Object.hasOwn(result, keyNode)) {
            this.line = startLine || this.line;
            this.#scanner.position = startPos || this.#scanner.position;
            throw this.#createError("Cannot store mapping pair: duplicated key");
          }
          if (keyNode === "__proto__") Object.defineProperty(result, keyNode, {
            value: valueNode,
            writable: true,
            enumerable: true,
            configurable: true
          });
          else result[keyNode] = valueNode;
          overridableKeys.delete(keyNode);
        }
        return result;
      }
      readLineBreak() {
        const ch = this.#scanner.peek();
        if (ch === 10) this.#scanner.next();
        else if (ch === 13) {
          this.#scanner.next();
          if (this.#scanner.peek() === 10) this.#scanner.next();
        } else throw this.#createError("Cannot read line: line break not found");
        this.line += 1;
        this.lineStart = this.#scanner.position;
      }
      skipSeparationSpace(allowComments, checkIndent) {
        let lineBreaks = 0;
        let ch = this.#scanner.peek();
        while (ch !== 0) {
          this.skipWhitespaces();
          ch = this.#scanner.peek();
          if (allowComments) {
            this.skipComment();
            ch = this.#scanner.peek();
          }
          if (isEOL(ch)) {
            this.readLineBreak();
            ch = this.#scanner.peek();
            lineBreaks++;
            this.lineIndent = 0;
            this.readIndent();
            ch = this.#scanner.peek();
          } else break;
        }
        if (checkIndent !== -1 && lineBreaks !== 0 && this.lineIndent < checkIndent) this.dispatchWarning("deficient indentation");
        return lineBreaks;
      }
      testDocumentSeparator() {
        let ch = this.#scanner.peek();
        if ((ch === 45 || ch === 46) && ch === this.#scanner.peek(1) && ch === this.#scanner.peek(2)) {
          ch = this.#scanner.peek(3);
          if (ch === 0 || isWhiteSpaceOrEOL(ch)) return true;
        }
        return false;
      }
      readPlainScalar(tag2, anchor, nodeIndent, withinFlowCollection) {
        let ch = this.#scanner.peek();
        if (isWhiteSpaceOrEOL(ch) || isFlowIndicator(ch) || ch === 35 || ch === 38 || ch === 42 || ch === 33 || ch === 124 || ch === 62 || ch === 39 || ch === 34 || ch === 37 || ch === 64 || ch === 96) return;
        let following;
        if (ch === 63 || ch === 45) {
          following = this.#scanner.peek(1);
          if (isWhiteSpaceOrEOL(following) || withinFlowCollection && isFlowIndicator(following)) return;
        }
        let result = "";
        let captureEnd = this.#scanner.position;
        let captureStart = this.#scanner.position;
        let hasPendingContent = false;
        let line = 0;
        while (ch !== 0) {
          if (ch === 58) {
            following = this.#scanner.peek(1);
            if (isWhiteSpaceOrEOL(following) || withinFlowCollection && isFlowIndicator(following)) break;
          } else if (ch === 35) {
            if (isWhiteSpaceOrEOL(this.#scanner.peek(-1))) break;
          } else if (this.#scanner.position === this.lineStart && this.testDocumentSeparator() || withinFlowCollection && isFlowIndicator(ch)) break;
          else if (isEOL(ch)) {
            line = this.line;
            const lineStart = this.lineStart;
            const lineIndent = this.lineIndent;
            this.skipSeparationSpace(false, -1);
            if (this.lineIndent >= nodeIndent) {
              hasPendingContent = true;
              ch = this.#scanner.peek();
              continue;
            } else {
              this.#scanner.position = captureEnd;
              this.line = line;
              this.lineStart = lineStart;
              this.lineIndent = lineIndent;
              break;
            }
          }
          if (hasPendingContent) {
            const segment2 = this.captureSegment(captureStart, captureEnd, false);
            if (segment2) result += segment2;
            result += writeFoldedLines(this.line - line);
            captureStart = captureEnd = this.#scanner.position;
            hasPendingContent = false;
          }
          if (!isWhiteSpace(ch)) captureEnd = this.#scanner.position + 1;
          this.#scanner.next();
          ch = this.#scanner.peek();
        }
        const segment = this.captureSegment(captureStart, captureEnd, false);
        if (segment) result += segment;
        if (anchor !== null) this.anchorMap.set(anchor, result);
        if (result) return {
          tag: tag2,
          anchor,
          kind: "scalar",
          result
        };
      }
      readSingleQuotedScalar(tag2, anchor, nodeIndent) {
        let ch = this.#scanner.peek();
        if (ch !== 39) return;
        let result = "";
        this.#scanner.next();
        let captureStart = this.#scanner.position;
        let captureEnd = this.#scanner.position;
        ch = this.#scanner.peek();
        while (ch !== 0) {
          if (ch === 39) {
            const segment = this.captureSegment(captureStart, this.#scanner.position, true);
            if (segment) result += segment;
            this.#scanner.next();
            ch = this.#scanner.peek();
            if (ch === 39) {
              captureStart = this.#scanner.position;
              this.#scanner.next();
              captureEnd = this.#scanner.position;
            } else {
              if (anchor !== null) this.anchorMap.set(anchor, result);
              return {
                tag: tag2,
                anchor,
                kind: "scalar",
                result
              };
            }
          } else if (isEOL(ch)) {
            const segment = this.captureSegment(captureStart, captureEnd, true);
            if (segment) result += segment;
            result += writeFoldedLines(this.skipSeparationSpace(false, nodeIndent));
            captureStart = captureEnd = this.#scanner.position;
          } else if (this.#scanner.position === this.lineStart && this.testDocumentSeparator()) throw this.#createError("Unexpected end of the document within a single quoted scalar");
          else {
            this.#scanner.next();
            captureEnd = this.#scanner.position;
          }
          ch = this.#scanner.peek();
        }
        throw this.#createError("Unexpected end of the stream within a single quoted scalar");
      }
      readDoubleQuotedScalar(tag2, anchor, nodeIndent) {
        let ch = this.#scanner.peek();
        if (ch !== 34) return;
        let result = "";
        this.#scanner.next();
        let captureEnd = this.#scanner.position;
        let captureStart = this.#scanner.position;
        let tmp;
        ch = this.#scanner.peek();
        while (ch !== 0) {
          if (ch === 34) {
            const segment = this.captureSegment(captureStart, this.#scanner.position, true);
            if (segment) result += segment;
            this.#scanner.next();
            if (anchor !== null) this.anchorMap.set(anchor, result);
            return {
              tag: tag2,
              anchor,
              kind: "scalar",
              result
            };
          }
          if (ch === 92) {
            const segment = this.captureSegment(captureStart, this.#scanner.position, true);
            if (segment) result += segment;
            this.#scanner.next();
            ch = this.#scanner.peek();
            if (isEOL(ch)) this.skipSeparationSpace(false, nodeIndent);
            else if (ch < 256 && SIMPLE_ESCAPE_SEQUENCES.has(ch)) {
              result += SIMPLE_ESCAPE_SEQUENCES.get(ch);
              this.#scanner.next();
            } else if ((tmp = ESCAPED_HEX_LENGTHS.get(ch) ?? 0) > 0) {
              let hexLength = tmp;
              let hexResult = 0;
              for (; hexLength > 0; hexLength--) {
                this.#scanner.next();
                ch = this.#scanner.peek();
                if ((tmp = hexCharCodeToNumber(ch)) >= 0) hexResult = (hexResult << 4) + tmp;
                else throw this.#createError("Cannot read double quoted scalar: expected hexadecimal character");
              }
              result += codepointToChar(hexResult);
              this.#scanner.next();
            } else throw this.#createError("Cannot read double quoted scalar: unknown escape sequence");
            captureStart = captureEnd = this.#scanner.position;
          } else if (isEOL(ch)) {
            const segment = this.captureSegment(captureStart, captureEnd, true);
            if (segment) result += segment;
            result += writeFoldedLines(this.skipSeparationSpace(false, nodeIndent));
            captureStart = captureEnd = this.#scanner.position;
          } else if (this.#scanner.position === this.lineStart && this.testDocumentSeparator()) throw this.#createError("Unexpected end of the document within a double quoted scalar");
          else {
            this.#scanner.next();
            captureEnd = this.#scanner.position;
          }
          ch = this.#scanner.peek();
        }
        throw this.#createError("Unexpected end of the stream within a double quoted scalar");
      }
      readFlowCollection(tag2, anchor, nodeIndent) {
        let ch = this.#scanner.peek();
        let terminator;
        let isMapping = true;
        let result = {};
        if (ch === 91) {
          terminator = 93;
          isMapping = false;
          result = [];
        } else if (ch === 123) terminator = 125;
        else return;
        if (anchor !== null) this.anchorMap.set(anchor, result);
        this.#scanner.next();
        ch = this.#scanner.peek();
        let readNext = true;
        let valueNode = null;
        let keyNode = null;
        let keyTag = null;
        let isExplicitPair = false;
        let isPair = false;
        let following = 0;
        let line = 0;
        const overridableKeys = /* @__PURE__ */ new Set();
        while (ch !== 0) {
          this.skipSeparationSpace(true, nodeIndent);
          ch = this.#scanner.peek();
          if (ch === terminator) {
            this.#scanner.next();
            return {
              tag: tag2,
              anchor,
              kind: isMapping ? "mapping" : "sequence",
              result
            };
          }
          if (!readNext) throw this.#createError("Cannot read flow collection: missing comma between flow collection entries");
          keyTag = keyNode = valueNode = null;
          isPair = isExplicitPair = false;
          if (ch === 63) {
            following = this.#scanner.peek(1);
            if (isWhiteSpaceOrEOL(following)) {
              isPair = isExplicitPair = true;
              this.#scanner.next();
              this.skipSeparationSpace(true, nodeIndent);
            }
          }
          line = this.line;
          const newState = this.composeNode({
            parentIndent: nodeIndent,
            nodeContext: CONTEXT_FLOW_IN,
            allowToSeek: false,
            allowCompact: true
          });
          if (newState) {
            keyTag = newState.tag || null;
            keyNode = newState.result;
          }
          this.skipSeparationSpace(true, nodeIndent);
          ch = this.#scanner.peek();
          if ((isExplicitPair || this.line === line) && ch === 58) {
            isPair = true;
            this.#scanner.next();
            ch = this.#scanner.peek();
            this.skipSeparationSpace(true, nodeIndent);
            const newState2 = this.composeNode({
              parentIndent: nodeIndent,
              nodeContext: CONTEXT_FLOW_IN,
              allowToSeek: false,
              allowCompact: true
            });
            if (newState2) valueNode = newState2.result;
          }
          if (isMapping) this.storeMappingPair(result, overridableKeys, keyTag, keyNode, valueNode);
          else if (isPair) result.push(this.storeMappingPair({}, overridableKeys, keyTag, keyNode, valueNode));
          else result.push(keyNode);
          this.skipSeparationSpace(true, nodeIndent);
          ch = this.#scanner.peek();
          if (ch === 44) {
            readNext = true;
            this.#scanner.next();
            ch = this.#scanner.peek();
          } else readNext = false;
        }
        throw this.#createError("Cannot read flow collection: unexpected end of the stream within a flow collection");
      }
      readBlockScalar(tag2, anchor, nodeIndent) {
        let chomping = CHOMPING_CLIP;
        let didReadContent = false;
        let detectedIndent = false;
        let textIndent = nodeIndent;
        let emptyLines = 0;
        let atMoreIndented = false;
        let ch = this.#scanner.peek();
        let folding = false;
        if (ch === 124) folding = false;
        else if (ch === 62) folding = true;
        else return;
        let result = "";
        let tmp = 0;
        while (ch !== 0) {
          this.#scanner.next();
          ch = this.#scanner.peek();
          if (ch === 43 || ch === 45) if (CHOMPING_CLIP === chomping) chomping = ch === 43 ? CHOMPING_KEEP : CHOMPING_STRIP;
          else throw this.#createError("Cannot read block: chomping mode identifier repeated");
          else if ((tmp = decimalCharCodeToNumber(ch)) >= 0) if (tmp === 0) throw this.#createError("Cannot read block: indentation width must be greater than 0");
          else if (!detectedIndent) {
            textIndent = nodeIndent + tmp - 1;
            detectedIndent = true;
          } else throw this.#createError("Cannot read block: indentation width identifier repeated");
          else break;
        }
        if (isWhiteSpace(ch)) {
          this.skipWhitespaces();
          this.skipComment();
          ch = this.#scanner.peek();
        }
        while (ch !== 0) {
          this.readLineBreak();
          this.lineIndent = 0;
          ch = this.#scanner.peek();
          while ((!detectedIndent || this.lineIndent < textIndent) && ch === 32) {
            this.lineIndent++;
            this.#scanner.next();
            ch = this.#scanner.peek();
          }
          if (!detectedIndent && this.lineIndent > textIndent) textIndent = this.lineIndent;
          if (isEOL(ch)) {
            emptyLines++;
            continue;
          }
          if (this.lineIndent < textIndent) {
            if (chomping === CHOMPING_KEEP) result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines);
            else if (chomping === CHOMPING_CLIP) {
              if (didReadContent) result += "\n";
            }
            break;
          }
          if (folding) if (isWhiteSpace(ch)) {
            atMoreIndented = true;
            result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines);
          } else if (atMoreIndented) {
            atMoreIndented = false;
            result += "\n".repeat(emptyLines + 1);
          } else if (emptyLines === 0) {
            if (didReadContent) result += " ";
          } else result += "\n".repeat(emptyLines);
          else result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines);
          didReadContent = true;
          detectedIndent = true;
          emptyLines = 0;
          const captureStart = this.#scanner.position;
          while (!isEOL(ch) && ch !== 0) {
            this.#scanner.next();
            ch = this.#scanner.peek();
          }
          const segment = this.captureSegment(captureStart, this.#scanner.position, false);
          if (segment) result += segment;
        }
        if (anchor !== null) this.anchorMap.set(anchor, result);
        return {
          tag: tag2,
          anchor,
          kind: "scalar",
          result
        };
      }
      readBlockMapping(tag2, anchor, nodeIndent, flowIndent) {
        const result = {};
        const overridableKeys = /* @__PURE__ */ new Set();
        let allowCompact = false;
        let line;
        let pos;
        let keyTag = null;
        let keyNode = null;
        let valueNode = null;
        let atExplicitKey = false;
        let detected = false;
        if (anchor !== null) this.anchorMap.set(anchor, result);
        let ch = this.#scanner.peek();
        while (ch !== 0) {
          const following = this.#scanner.peek(1);
          line = this.line;
          pos = this.#scanner.position;
          if ((ch === 63 || ch === 58) && isWhiteSpaceOrEOL(following)) {
            if (ch === 63) {
              if (atExplicitKey) {
                this.storeMappingPair(result, overridableKeys, keyTag, keyNode, null);
                keyTag = null;
                keyNode = null;
                valueNode = null;
              }
              detected = true;
              atExplicitKey = true;
              allowCompact = true;
            } else if (atExplicitKey) {
              atExplicitKey = false;
              allowCompact = true;
            } else throw this.#createError("Cannot read block as explicit mapping pair is incomplete: a key node is missed or followed by a non-tabulated empty line");
            this.#scanner.next();
            ch = following;
          } else {
            const newState = this.composeNode({
              parentIndent: flowIndent,
              nodeContext: CONTEXT_FLOW_OUT,
              allowToSeek: false,
              allowCompact: true
            });
            if (!newState) break;
            if (this.line === line) {
              ch = this.#scanner.peek();
              this.skipWhitespaces();
              ch = this.#scanner.peek();
              if (ch === 58) {
                this.#scanner.next();
                ch = this.#scanner.peek();
                if (!isWhiteSpaceOrEOL(ch)) throw this.#createError("Cannot read block: a whitespace character is expected after the key-value separator within a block mapping");
                if (atExplicitKey) {
                  this.storeMappingPair(result, overridableKeys, keyTag, keyNode, null);
                  keyTag = null;
                  keyNode = null;
                  valueNode = null;
                }
                detected = true;
                atExplicitKey = false;
                allowCompact = false;
                keyTag = newState.tag;
                keyNode = newState.result;
              } else if (detected) throw this.#createError("Cannot read an implicit mapping pair: missing colon");
              else {
                const { kind, result: result2 } = newState;
                return {
                  tag: tag2,
                  anchor,
                  kind,
                  result: result2
                };
              }
            } else if (detected) throw this.#createError("Cannot read a block mapping entry: a multiline key may not be an implicit key");
            else {
              const { kind, result: result2 } = newState;
              return {
                tag: tag2,
                anchor,
                kind,
                result: result2
              };
            }
          }
          if (this.line === line || this.lineIndent > nodeIndent) {
            const newState = this.composeNode({
              parentIndent: nodeIndent,
              nodeContext: CONTEXT_BLOCK_OUT,
              allowToSeek: true,
              allowCompact
            });
            if (newState) if (atExplicitKey) keyNode = newState.result;
            else valueNode = newState.result;
            if (!atExplicitKey) {
              this.storeMappingPair(result, overridableKeys, keyTag, keyNode, valueNode, line, pos);
              keyTag = keyNode = valueNode = null;
            }
            this.skipSeparationSpace(true, -1);
            ch = this.#scanner.peek();
          }
          if (this.lineIndent > nodeIndent && ch !== 0) throw this.#createError("Cannot read block: bad indentation of a mapping entry");
          else if (this.lineIndent < nodeIndent) break;
        }
        if (atExplicitKey) this.storeMappingPair(result, overridableKeys, keyTag, keyNode, null);
        if (detected) return {
          tag: tag2,
          anchor,
          kind: "mapping",
          result
        };
      }
      readTagProperty(tag2) {
        let isVerbatim = false;
        let isNamed = false;
        let tagHandle = "";
        let tagName;
        let ch = this.#scanner.peek();
        if (ch !== 33) return;
        if (tag2 !== null) throw this.#createError("Cannot read tag property: duplication of a tag property");
        this.#scanner.next();
        ch = this.#scanner.peek();
        if (ch === 60) {
          isVerbatim = true;
          this.#scanner.next();
          ch = this.#scanner.peek();
        } else if (ch === 33) {
          isNamed = true;
          tagHandle = "!!";
          this.#scanner.next();
          ch = this.#scanner.peek();
        } else tagHandle = "!";
        let position = this.#scanner.position;
        if (isVerbatim) {
          do {
            this.#scanner.next();
            ch = this.#scanner.peek();
          } while (ch !== 0 && ch !== 62);
          if (!this.#scanner.eof()) {
            tagName = this.#scanner.source.slice(position, this.#scanner.position);
            this.#scanner.next();
            ch = this.#scanner.peek();
          } else throw this.#createError("Cannot read tag property: unexpected end of stream");
        } else {
          while (ch !== 0 && !isWhiteSpaceOrEOL(ch)) {
            if (ch === 33) if (!isNamed) {
              tagHandle = this.#scanner.source.slice(position - 1, this.#scanner.position + 1);
              if (!PATTERN_TAG_HANDLE_REGEXP.test(tagHandle)) throw this.#createError("Cannot read tag property: named tag handle contains invalid characters");
              isNamed = true;
              position = this.#scanner.position + 1;
            } else throw this.#createError("Cannot read tag property: tag suffix cannot contain an exclamation mark");
            this.#scanner.next();
            ch = this.#scanner.peek();
          }
          tagName = this.#scanner.source.slice(position, this.#scanner.position);
          if (PATTERN_FLOW_INDICATORS_REGEXP.test(tagName)) throw this.#createError("Cannot read tag property: tag suffix cannot contain flow indicator characters");
        }
        if (tagName && !PATTERN_TAG_URI_REGEXP.test(tagName)) throw this.#createError(`Cannot read tag property: invalid characters in tag name "${tagName}"`);
        if (isVerbatim) return tagName;
        else if (this.tagMap.has(tagHandle)) return this.tagMap.get(tagHandle) + tagName;
        else if (tagHandle === "!") return `!${tagName}`;
        else if (tagHandle === "!!") return `tag:yaml.org,2002:${tagName}`;
        throw this.#createError(`Cannot read tag property: undeclared tag handle "${tagHandle}"`);
      }
      readAnchorProperty(anchor) {
        let ch = this.#scanner.peek();
        if (ch !== 38) return;
        if (anchor !== null) throw this.#createError("Cannot read anchor property: duplicate anchor property");
        this.#scanner.next();
        ch = this.#scanner.peek();
        const position = this.#scanner.position;
        while (ch !== 0 && !isWhiteSpaceOrEOL(ch) && !isFlowIndicator(ch)) {
          this.#scanner.next();
          ch = this.#scanner.peek();
        }
        if (this.#scanner.position === position) throw this.#createError("Cannot read anchor property: name of an anchor node must contain at least one character");
        return this.#scanner.source.slice(position, this.#scanner.position);
      }
      readAlias() {
        if (this.#scanner.peek() !== 42) return;
        this.#scanner.next();
        let ch = this.#scanner.peek();
        const position = this.#scanner.position;
        while (ch !== 0 && !isWhiteSpaceOrEOL(ch) && !isFlowIndicator(ch)) {
          this.#scanner.next();
          ch = this.#scanner.peek();
        }
        if (this.#scanner.position === position) throw this.#createError("Cannot read alias: alias name must contain at least one character");
        const alias = this.#scanner.source.slice(position, this.#scanner.position);
        if (!this.anchorMap.has(alias)) throw this.#createError(`Cannot read alias: unidentified alias "${alias}"`);
        this.skipSeparationSpace(true, -1);
        return this.anchorMap.get(alias);
      }
      resolveTag(state2) {
        switch (state2.tag) {
          case null:
          case "!":
            return state2;
          case "?":
            for (const type2 of this.implicitTypes) {
              if (!type2.resolve(state2.result)) continue;
              const result2 = type2.construct(state2.result);
              state2.result = result2;
              state2.tag = type2.tag;
              const { anchor: anchor2 } = state2;
              if (anchor2 !== null) this.anchorMap.set(anchor2, result2);
              return state2;
            }
            return state2;
        }
        const kind = state2.kind ?? "fallback";
        const type = this.typeMap[kind].get(state2.tag);
        if (!type) throw this.#createError(`Cannot resolve unknown tag !<${state2.tag}>`);
        if (state2.result !== null && type.kind !== state2.kind) throw this.#createError(`Unacceptable node kind for !<${state2.tag}> tag: it should be "${type.kind}", not "${state2.kind}"`);
        if (!type.resolve(state2.result)) throw this.#createError(`Cannot resolve a node with !<${state2.tag}> explicit tag`);
        const result = type.construct(state2.result);
        state2.result = result;
        const { anchor } = state2;
        if (anchor !== null) this.anchorMap.set(anchor, result);
        return state2;
      }
      composeNode({ parentIndent, nodeContext, allowToSeek, allowCompact }) {
        let indentStatus = 1;
        let atNewLine = false;
        const allowBlockScalars = CONTEXT_BLOCK_OUT === nodeContext || CONTEXT_BLOCK_IN === nodeContext;
        let allowBlockCollections = allowBlockScalars;
        const allowBlockStyles = allowBlockScalars;
        if (allowToSeek) {
          if (this.skipSeparationSpace(true, -1)) {
            atNewLine = true;
            indentStatus = getIndentStatus(this.lineIndent, parentIndent);
          }
        }
        let tag2 = null;
        let anchor = null;
        if (indentStatus === 1) while (true) {
          const newTag = this.readTagProperty(tag2);
          if (newTag) tag2 = newTag;
          else {
            const newAnchor = this.readAnchorProperty(anchor);
            if (!newAnchor) break;
            anchor = newAnchor;
          }
          if (this.skipSeparationSpace(true, -1)) {
            atNewLine = true;
            allowBlockCollections = allowBlockStyles;
            indentStatus = getIndentStatus(this.lineIndent, parentIndent);
          } else allowBlockCollections = false;
        }
        if (allowBlockCollections) allowBlockCollections = atNewLine || allowCompact;
        if (indentStatus === 1) {
          const flowIndent = CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext ? parentIndent : parentIndent + 1;
          if (allowBlockCollections) {
            const blockIndent = this.#scanner.position - this.lineStart;
            const blockSequenceState = this.readBlockSequence(tag2, anchor, blockIndent);
            if (blockSequenceState) return this.resolveTag(blockSequenceState);
            const blockMappingState = this.readBlockMapping(tag2, anchor, blockIndent, flowIndent);
            if (blockMappingState) return this.resolveTag(blockMappingState);
          }
          const flowCollectionState = this.readFlowCollection(tag2, anchor, flowIndent);
          if (flowCollectionState) return this.resolveTag(flowCollectionState);
          if (allowBlockScalars) {
            const blockScalarState = this.readBlockScalar(tag2, anchor, flowIndent);
            if (blockScalarState) return this.resolveTag(blockScalarState);
          }
          const singleQuoteState = this.readSingleQuotedScalar(tag2, anchor, flowIndent);
          if (singleQuoteState) return this.resolveTag(singleQuoteState);
          const doubleQuoteState = this.readDoubleQuotedScalar(tag2, anchor, flowIndent);
          if (doubleQuoteState) return this.resolveTag(doubleQuoteState);
          const alias = this.readAlias();
          if (alias) {
            if (tag2 !== null || anchor !== null) throw this.#createError("Cannot compose node: alias node should not have any properties");
            return this.resolveTag({
              tag: tag2,
              anchor,
              kind: null,
              result: alias
            });
          }
          const plainScalarState = this.readPlainScalar(tag2, anchor, flowIndent, CONTEXT_FLOW_IN === nodeContext);
          if (plainScalarState) {
            plainScalarState.tag ??= "?";
            return this.resolveTag(plainScalarState);
          }
        } else if (indentStatus === 0 && CONTEXT_BLOCK_OUT === nodeContext && allowBlockCollections) {
          const blockIndent = this.#scanner.position - this.lineStart;
          const newState2 = this.readBlockSequence(tag2, anchor, blockIndent);
          if (newState2) return this.resolveTag(newState2);
        }
        const newState = this.resolveTag({
          tag: tag2,
          anchor,
          kind: null,
          result: null
        });
        if (newState.tag !== null || newState.anchor !== null) return newState;
      }
      readDirectives() {
        let hasDirectives = false;
        let version = null;
        let ch = this.#scanner.peek();
        while (ch !== 0) {
          this.skipSeparationSpace(true, -1);
          ch = this.#scanner.peek();
          if (this.lineIndent > 0 || ch !== 37) break;
          hasDirectives = true;
          this.#scanner.next();
          ch = this.#scanner.peek();
          let position = this.#scanner.position;
          while (ch !== 0 && !isWhiteSpaceOrEOL(ch)) {
            this.#scanner.next();
            ch = this.#scanner.peek();
          }
          const directiveName = this.#scanner.source.slice(position, this.#scanner.position);
          const directiveArgs = [];
          if (directiveName.length < 1) throw this.#createError("Cannot read document: directive name length must be greater than zero");
          while (ch !== 0) {
            this.skipWhitespaces();
            this.skipComment();
            ch = this.#scanner.peek();
            if (isEOL(ch)) break;
            position = this.#scanner.position;
            while (ch !== 0 && !isWhiteSpaceOrEOL(ch)) {
              this.#scanner.next();
              ch = this.#scanner.peek();
            }
            directiveArgs.push(this.#scanner.source.slice(position, this.#scanner.position));
          }
          if (ch !== 0) this.readLineBreak();
          switch (directiveName) {
            case "YAML":
              if (version !== null) throw this.#createError("Cannot handle YAML directive: duplication of %YAML directive");
              version = this.yamlDirectiveHandler(directiveArgs);
              break;
            case "TAG":
              this.tagDirectiveHandler(directiveArgs);
              break;
            default:
              this.dispatchWarning(`unknown document directive "${directiveName}"`);
          }
          ch = this.#scanner.peek();
        }
        return hasDirectives;
      }
      readDocument() {
        const documentStart = this.#scanner.position;
        this.checkLineBreaks = false;
        this.tagMap = /* @__PURE__ */ new Map();
        this.anchorMap = /* @__PURE__ */ new Map();
        const hasDirectives = this.readDirectives();
        this.skipSeparationSpace(true, -1);
        let result = null;
        if (this.lineIndent === 0 && this.#scanner.peek() === 45 && this.#scanner.peek(1) === 45 && this.#scanner.peek(2) === 45) {
          this.#scanner.position += 3;
          this.skipSeparationSpace(true, -1);
        } else if (hasDirectives) throw this.#createError("Cannot read document: directives end mark is expected");
        const newState = this.composeNode({
          parentIndent: this.lineIndent - 1,
          nodeContext: CONTEXT_BLOCK_OUT,
          allowToSeek: false,
          allowCompact: true
        });
        if (newState) result = newState.result;
        this.skipSeparationSpace(true, -1);
        if (this.checkLineBreaks && PATTERN_NON_ASCII_LINE_BREAKS_REGEXP.test(this.#scanner.source.slice(documentStart, this.#scanner.position))) this.dispatchWarning("non-ASCII line breaks are interpreted as content");
        if (this.#scanner.position === this.lineStart && this.testDocumentSeparator()) {
          if (this.#scanner.peek() === 46) {
            this.#scanner.position += 3;
            this.skipSeparationSpace(true, -1);
          }
        } else if (!this.#scanner.eof()) throw this.#createError("Cannot read document: end of the stream or a document separator is expected");
        return result;
      }
      *readDocuments(options2 = {}) {
        const { singleDocument = false } = options2;
        let yielded = 0;
        while (!this.#scanner.eof()) {
          if (singleDocument && yielded > 0) throw this.#createError("Found more than 1 document in the stream: expected a single document");
          yield this.readDocument();
          yielded++;
        }
      }
    };
    STYLE_PLAIN = 1;
    STYLE_SINGLE = 2;
    STYLE_LITERAL = 3;
    STYLE_FOLDED = 4;
    STYLE_DOUBLE = 5;
    LEADING_SPACE_REGEXP = /^\n* /;
    ESCAPE_SEQUENCES = /* @__PURE__ */ new Map([
      [0, "\\0"],
      [7, "\\a"],
      [8, "\\b"],
      [9, "\\t"],
      [10, "\\n"],
      [11, "\\v"],
      [12, "\\f"],
      [13, "\\r"],
      [27, "\\e"],
      [34, '\\"'],
      [92, "\\\\"],
      [133, "\\N"],
      [160, "\\_"],
      [8232, "\\L"],
      [8233, "\\P"]
    ]);
    DEPRECATED_BOOLEANS_SYNTAX = /* @__PURE__ */ new Set([
      "y",
      "Y",
      "yes",
      "Yes",
      "YES",
      "on",
      "On",
      "ON",
      "n",
      "N",
      "no",
      "No",
      "NO",
      "off",
      "Off",
      "OFF"
    ]);
    DumperState = class {
      indent;
      arrayIndent;
      skipInvalid;
      flowLevel;
      sortKeys;
      lineWidth;
      useAnchors;
      compatMode;
      condenseFlow;
      implicitTypes;
      explicitTypes;
      duplicates = [];
      usedDuplicates = /* @__PURE__ */ new Set();
      styleMap = /* @__PURE__ */ new Map();
      quoteStyle;
      constructor({ schema = DEFAULT_SCHEMA, indent = 2, arrayIndent = true, skipInvalid = false, flowLevel = -1, styles = void 0, sortKeys = false, lineWidth = 80, useAnchors = true, compatMode = true, condenseFlow = false, quoteStyle = "'" }) {
        this.indent = Math.max(1, indent);
        this.arrayIndent = arrayIndent;
        this.skipInvalid = skipInvalid;
        this.flowLevel = flowLevel;
        if (styles) this.styleMap = createStyleMap(styles);
        this.sortKeys = sortKeys;
        this.lineWidth = lineWidth;
        this.useAnchors = useAnchors;
        this.compatMode = compatMode;
        this.condenseFlow = condenseFlow;
        this.implicitTypes = schema.implicitTypes;
        this.explicitTypes = schema.explicitTypes;
        this.quoteStyle = quoteStyle;
      }
      stringifyScalar(string, { level, isKey }) {
        if (string.length === 0) return "''";
        if (this.compatMode && DEPRECATED_BOOLEANS_SYNTAX.has(string)) return `'${string}'`;
        const indent = this.indent * Math.max(1, level);
        const lineWidth = this.lineWidth === -1 ? -1 : Math.max(Math.min(this.lineWidth, 40), this.lineWidth - indent);
        switch (chooseScalarStyle(string, isKey || this.flowLevel > -1 && level >= this.flowLevel, this.indent, lineWidth, this.implicitTypes, this.quoteStyle)) {
          case STYLE_PLAIN:
            return string;
          case STYLE_SINGLE:
            return `'${string.replace(/'/g, "''")}'`;
          case STYLE_LITERAL:
            return `|${blockHeader(string, this.indent)}${trimTrailingNewline(indentString(string, indent))}`;
          case STYLE_FOLDED:
            return `>${blockHeader(string, this.indent)}${trimTrailingNewline(indentString(foldString(string, lineWidth), indent))}`;
          case STYLE_DOUBLE:
            return `"${escapeString(string)}"`;
          default:
            throw new TypeError("Invalid scalar style should be unreachable: please file a bug report against Deno at https://github.com/denoland/std/issues");
        }
      }
      stringifyFlowSequence(array2, { level }) {
        const results = [];
        for (const value2 of array2) {
          const string = this.stringifyNode(value2, {
            level,
            block: false,
            compact: false,
            isKey: false
          });
          if (string === null) continue;
          results.push(string);
        }
        const separator = this.condenseFlow ? "," : ", ";
        return `[${results.join(separator)}]`;
      }
      stringifyBlockSequence(array2, { level, compact: compact2 }) {
        const whitespace2 = generateNextLine(this.indent, level);
        const prefix = compact2 ? "" : whitespace2;
        const results = [];
        for (const value2 of array2) {
          const string = this.stringifyNode(value2, {
            level: level + 1,
            block: true,
            compact: true,
            isKey: false
          });
          if (string === null) continue;
          const linePrefix = 10 === string.charCodeAt(0) ? "-" : "- ";
          results.push(`${linePrefix}${string}`);
        }
        return results.length ? prefix + results.join(whitespace2) : "[]";
      }
      stringifyFlowMapping(object, { level }) {
        const quote = this.condenseFlow ? '"' : "";
        const separator = this.condenseFlow ? ":" : ": ";
        const results = [];
        for (const [key2, value2] of Object.entries(object)) {
          const keyString = this.stringifyNode(key2, {
            level,
            block: false,
            compact: false,
            isKey: false
          });
          if (keyString === null) continue;
          const valueString = this.stringifyNode(value2, {
            level,
            block: false,
            compact: false,
            isKey: false
          });
          if (valueString === null) continue;
          const keyPrefix = keyString.length > 1024 ? "? " : "";
          results.push(quote + keyPrefix + keyString + quote + separator + valueString);
        }
        return `{${results.join(", ")}}`;
      }
      stringifyBlockMapping(object, { tag: tag2, level, compact: compact2 }) {
        const keys = Object.keys(object);
        if (this.sortKeys === true) keys.sort();
        else if (typeof this.sortKeys === "function") {
          const sortKeys = this.sortKeys;
          keys.sort((a2, b3) => sortKeys(a2, b3, level));
        } else if (this.sortKeys) throw new TypeError(`"sortKeys" must be a boolean or a function: received ${typeof this.sortKeys}`);
        const separator = generateNextLine(this.indent, level);
        const results = [];
        for (const key2 of keys) {
          const value2 = object[key2];
          const keyString = this.stringifyNode(key2, {
            level: level + 1,
            block: true,
            compact: true,
            isKey: true
          });
          if (keyString === null) continue;
          const explicitPair = tag2 !== null && tag2 !== "?" || keyString.length > 1024;
          const valueString = this.stringifyNode(value2, {
            level: level + 1,
            block: true,
            compact: explicitPair,
            isKey: false
          });
          if (valueString === null) continue;
          let pairBuffer = "";
          if (explicitPair) pairBuffer += keyString.charCodeAt(0) === 10 ? "?" : "? ";
          pairBuffer += keyString;
          if (explicitPair) pairBuffer += separator;
          pairBuffer += valueString.charCodeAt(0) === 10 ? ":" : ": ";
          pairBuffer += valueString;
          results.push(pairBuffer);
        }
        const prefix = compact2 ? "" : separator;
        return results.length ? prefix + results.join(separator) : "{}";
      }
      getTypeRepresentation(type, value2) {
        if (!type.represent) return value2;
        const style = this.styleMap.get(type.tag) ?? type.defaultStyle;
        if (typeof type.represent === "function") return type.represent(value2, style);
        const represent = type.represent[style];
        if (!represent) throw new TypeError(`!<${type.tag}> tag resolver accepts not "${style}" style`);
        return represent(value2, style);
      }
      detectType(value2) {
        for (const type of this.implicitTypes) if (type.predicate?.(value2)) {
          value2 = this.getTypeRepresentation(type, value2);
          return {
            tag: "?",
            value: value2
          };
        }
        for (const type of this.explicitTypes) if (type.predicate?.(value2)) {
          value2 = this.getTypeRepresentation(type, value2);
          return {
            tag: type.tag,
            value: value2
          };
        }
        return {
          tag: null,
          value: value2
        };
      }
      stringifyNode(value2, { level, block: block2, compact: compact2, isKey }) {
        const result = this.detectType(value2);
        const tag2 = result.tag;
        value2 = result.value;
        if (block2) block2 = this.flowLevel < 0 || this.flowLevel > level;
        if (typeof value2 === "string" || value2 instanceof String) {
          value2 = value2 instanceof String ? value2.valueOf() : value2;
          if (tag2 !== "?") value2 = this.stringifyScalar(value2, {
            level,
            isKey
          });
          return stringifyValue(value2, tag2);
        }
        if (isObject(value2)) {
          const duplicateIndex = this.duplicates.indexOf(value2);
          const duplicate = duplicateIndex !== -1;
          if (duplicate) {
            if (this.usedDuplicates.has(value2)) return `*ref_${duplicateIndex}`;
            this.usedDuplicates.add(value2);
          }
          if (tag2 !== null && tag2 !== "?" || duplicate || this.indent !== 2 && level > 0) compact2 = false;
          if (Array.isArray(value2)) {
            const arrayLevel = !this.arrayIndent && level > 0 ? level - 1 : level;
            if (block2 && value2.length !== 0) {
              value2 = this.stringifyBlockSequence(value2, {
                level: arrayLevel,
                compact: compact2
              });
              if (duplicate) value2 = `&ref_${duplicateIndex}${value2}`;
              return stringifyValue(value2, tag2);
            }
            value2 = this.stringifyFlowSequence(value2, { level: arrayLevel });
            if (duplicate) value2 = `&ref_${duplicateIndex} ${value2}`;
            return stringifyValue(value2, tag2);
          }
          if (block2 && Object.keys(value2).length !== 0) {
            value2 = this.stringifyBlockMapping(value2, {
              tag: tag2,
              level,
              compact: compact2
            });
            if (duplicate) value2 = `&ref_${duplicateIndex}${value2}`;
            return stringifyValue(value2, tag2);
          }
          value2 = this.stringifyFlowMapping(value2, { level });
          if (duplicate) value2 = `&ref_${duplicateIndex} ${value2}`;
          return stringifyValue(value2, tag2);
        }
        if (this.skipInvalid) return null;
        throw new TypeError(`Cannot stringify ${typeof value2}`);
      }
      stringify(value2) {
        if (this.useAnchors) {
          this.duplicates = getDuplicateObjects(value2);
          this.usedDuplicates = /* @__PURE__ */ new Set();
        }
        const string = this.stringifyNode(value2, {
          level: 0,
          block: true,
          compact: true,
          isKey: false
        });
        if (string !== null) return `${string}
`;
        return "";
      }
    };
    ANNOUNCEMENTS_SUBDIR$1 = "announcements";
    SEVERITIES = [
      "info",
      "warning",
      "critical"
    ];
    DATABASE_ANNOUNCEMENTS_CAP = 1e3;
    LOG_SOURCE = "announcements.database.service";
    CROCKFORD = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
    TIME_LEN = 10;
    RANDOM_LEN = 16;
    ANNOUNCEMENTS_SUBDIR = "announcements";
  }
});

// dist/build/server/chunks/announcements.js
function getClient() {
  if (!client) client = new BaseHttpClient(config.bulletinUrl, {
    timeout: 1e4,
    retries: 2,
    retryDelay: 500,
    retryStatusCodes: [
      429,
      500,
      502,
      503,
      504
    ]
  });
  return client;
}
function describeError(error2) {
  if (error2 instanceof Error) return error2.message;
  return String(error2);
}
async function fetchVersions() {
  try {
    return {
      ok: true,
      data: await getClient().get("/versions.json")
    };
  } catch (error2) {
    return {
      ok: false,
      error: describeError(error2)
    };
  }
}
async function fetchAnnouncements() {
  try {
    return {
      ok: true,
      data: await getClient().get("/announcements.json")
    };
  } catch (error2) {
    return {
      ok: false,
      error: describeError(error2)
    };
  }
}
async function fetchBody(id) {
  try {
    return {
      ok: true,
      data: await getClient().get(`/announcements/${id}.md`, { responseType: "text" })
    };
  } catch (error2) {
    return {
      ok: false,
      error: describeError(error2)
    };
  }
}
function isVisibleBase(record, now) {
  if (record.withdrawn) return false;
  if (record.expiresAt !== null && record.expiresAt < now) return false;
  return true;
}
function compareVersions(a2, b3) {
  const pa = a2.split("-")[0].split(".").map((n) => parseInt(n, 10));
  const pb = b3.split("-")[0].split(".").map((n) => parseInt(n, 10));
  const len = Math.max(pa.length, pb.length);
  for (let i = 0; i < len; i++) {
    const ai = pa[i] ?? 0;
    const bi = pb[i] ?? 0;
    if (Number.isNaN(ai) || Number.isNaN(bi)) {
      const sa = a2.split("-")[0];
      const sb = b3.split("-")[0];
      if (sa < sb) return -1;
      if (sa > sb) return 1;
      return 0;
    }
    if (ai < bi) return -1;
    if (ai > bi) return 1;
  }
  return 0;
}
function satisfiesRange(current3, min, max) {
  if (min !== null && compareVersions(current3, min) < 0) return false;
  if (max !== null && compareVersions(current3, max) > 0) return false;
  return true;
}
function isVisible(announcement, ctx) {
  if (!isVisibleBase(announcement, ctx.now)) return false;
  if (ctx.channel === "dev" || ctx.version.includes("-")) return true;
  return satisfiesRange(ctx.version, announcement.minVersion, announcement.maxVersion);
}
function reconcileAnnouncements(file, existingRows) {
  if (file.schema !== 1) throw new UnsupportedSchemaError(file.schema);
  return reconcile(file.announcements, existingRows, { cap: ANNOUNCEMENTS_CAP });
}
function rowToRecord3(row) {
  return {
    id: row.id,
    title: row.title,
    severity: row.severity,
    publishedAt: row.published_at,
    expiresAt: row.expires_at,
    minVersion: row.min_version,
    maxVersion: row.max_version,
    link: row.link,
    body: row.body,
    withdrawn: row.withdrawn === 1,
    readAt: row.read_at,
    fetchedAt: row.fetched_at,
    bodyFetchedAt: row.body_fetched_at
  };
}
function currentContext() {
  return {
    now: (/* @__PURE__ */ new Date()).toISOString(),
    version: build.version,
    channel: build.channel
  };
}
function listVisible() {
  const ctx = currentContext();
  return announcementQueries.listAll().map(rowToRecord3).filter((a2) => isVisible(a2, ctx));
}
function getUnreadCount$1() {
  return listVisible().filter((a2) => a2.readAt === null).length;
}
async function getDetail$1(id, opts = {}) {
  const row = announcementQueries.getById(id);
  if (!row) return void 0;
  if (opts.loadBody && row.body === null) {
    const result = await fetchBody(id);
    if (result.ok) {
      const now = (/* @__PURE__ */ new Date()).toISOString();
      announcementQueries.setBody(id, result.data, now);
      return rowToRecord3({
        ...row,
        body: result.data,
        body_fetched_at: now
      });
    }
    await logger.warn(`Failed to fetch announcement body for ${id}`, {
      source: "AnnouncementsService",
      meta: { error: result.error }
    });
  }
  return rowToRecord3(row);
}
function markRead$1(id) {
  announcementQueries.markRead(id, (/* @__PURE__ */ new Date()).toISOString());
}
function markUnread$1(id) {
  announcementQueries.markUnread(id);
}
function getVersionsSnapshot() {
  const row = versionsSnapshotQueries.get();
  if (!row) return null;
  try {
    return {
      payload: JSON.parse(row.payload),
      fetchedAt: row.fetched_at
    };
  } catch {
    return null;
  }
}
async function reconcileFromBulletin() {
  const fetchedAt = (/* @__PURE__ */ new Date()).toISOString();
  const versionsResult = await fetchVersions();
  let versionsStatus = "failed";
  if (versionsResult.ok) try {
    if (versionsResult.data.schema !== 1) await logger.warn("Unsupported versions.json schema, ignoring", {
      source: "AnnouncementsService",
      meta: { schema: versionsResult.data.schema }
    });
    else {
      versionsSnapshotQueries.set(JSON.stringify(versionsResult.data), fetchedAt);
      versionsStatus = "ok";
    }
  } catch (error2) {
    await logger.warn("Failed to persist versions snapshot", {
      source: "AnnouncementsService",
      meta: { error: String(error2) }
    });
  }
  else await logger.warn("versions.json fetch failed", {
    source: "AnnouncementsService",
    meta: { error: versionsResult.error }
  });
  const announcementsResult = await fetchAnnouncements();
  let announcementsStatus = "failed";
  let newlyInserted = [];
  if (announcementsResult.ok) try {
    const existing = announcementQueries.listAll();
    const plan = reconcileAnnouncements(announcementsResult.data, existing);
    await applyPlan(plan, fetchedAt);
    if (plan.droppedCount > 0) await logger.warn(`Dropped ${plan.droppedCount} announcements beyond cap`, { source: "AnnouncementsService" });
    newlyInserted = plan.newlyInserted.map((a2) => {
      const row = announcementQueries.getById(a2.id);
      return row ? rowToRecord3(row) : null;
    }).filter((r2) => r2 !== null);
    announcementsStatus = "ok";
  } catch (error2) {
    if (error2 instanceof UnsupportedSchemaError) await logger.warn("Unsupported announcements.json schema, ignoring", {
      source: "AnnouncementsService",
      meta: { schema: error2.schema }
    });
    else await logger.error("Failed to reconcile announcements", {
      source: "AnnouncementsService",
      meta: { error: String(error2) }
    });
  }
  else await logger.warn("announcements.json fetch failed", {
    source: "AnnouncementsService",
    meta: { error: announcementsResult.error }
  });
  return {
    announcements: announcementsStatus,
    versions: versionsStatus,
    newlyInserted
  };
}
async function applyPlan(plan, fetchedAt) {
  await db.transaction(() => {
    for (const a2 of plan.upserts) announcementQueries.upsertFromBulletin(a2, fetchedAt);
    if (plan.withdrawnIds.length > 0) announcementQueries.markWithdrawn(plan.withdrawnIds);
    if (plan.unwithdrawnIds.length > 0) announcementQueries.markUnwithdrawn(plan.unwithdrawnIds);
  });
}
function computeVersionStatus(stableLatest, developLatest, developPublishedAt) {
  if (build.channel === "dev") return "dev-build";
  if (build.version.includes("-")) return "dev-build";
  if (build.channel === "stable") {
    if (!stableLatest) return "dev-build";
    const cmp = compareVersions(build.version, stableLatest);
    if (cmp > 0) return "dev-build";
    return cmp === 0 ? "up-to-date" : "out-of-date";
  }
  if (build.channel === "develop") {
    if (!developLatest || !build.commit) return "dev-build";
    if (build.commit.startsWith(developLatest) || developLatest.startsWith(build.commit)) return "up-to-date";
    if (build.builtAt && developPublishedAt) {
      const localMs = Date.parse(build.builtAt);
      const remoteMs = Date.parse(developPublishedAt);
      if (Number.isFinite(localMs) && Number.isFinite(remoteMs) && localMs >= remoteMs) return "dev-build";
    }
    return "out-of-date";
  }
  return "dev-build";
}
function getVersionStatus() {
  const channels = getVersionsSnapshot()?.payload.channels;
  const stableLatest = channels?.stable.latest ?? null;
  const developLatest = channels?.develop.latest ?? null;
  const status = computeVersionStatus(stableLatest, developLatest, channels?.develop.published_at ?? null);
  if (status !== "out-of-date") return {
    status,
    latestVersion: null,
    releaseUrl: null
  };
  if (build.channel === "stable" && stableLatest) {
    const release = channels?.stable.releases?.[0];
    return {
      status,
      latestVersion: `v${stableLatest}`,
      releaseUrl: release?.url ?? null
    };
  }
  if (build.channel === "develop" && developLatest) return {
    status,
    latestVersion: developLatest.slice(0, 7),
    releaseUrl: `https://github.com/Dictionarry-Hub/profilarr/commit/${developLatest}`
  };
  return {
    status,
    latestVersion: null,
    releaseUrl: null
  };
}
function listInbox() {
  const items = [...listProfilarrItems(), ...listDatabaseItems()];
  items.sort((a2, b3) => a2.publishedAt < b3.publishedAt ? 1 : a2.publishedAt > b3.publishedAt ? -1 : 0);
  return items;
}
function getUnreadCount() {
  return listInbox().filter((item) => item.readAt === null).length;
}
async function getDetail2(source2, id, databaseId, opts = {}) {
  if (source2 === "profilarr") {
    const record2 = await getDetail$1(id, opts);
    if (!record2) return void 0;
    return profilarrRecordToItem(record2);
  }
  if (databaseId === null) return void 0;
  const record = getDetail(id, databaseId);
  if (!record) return void 0;
  const instance = databaseInstancesQueries.getById(databaseId);
  return databaseRecordToItem(record, instance?.name ?? "(unknown database)", instance?.repository_url ?? null);
}
function markRead2(source2, id, databaseId) {
  if (source2 === "profilarr") {
    markRead$1(id);
    return;
  }
  if (databaseId === null) return;
  markRead(id, databaseId);
}
function markUnread2(source2, id, databaseId) {
  if (source2 === "profilarr") {
    markUnread$1(id);
    return;
  }
  if (databaseId === null) return;
  markUnread(id, databaseId);
}
function markReadMany(targets) {
  for (const t2 of targets) markRead2(t2.source, t2.id, t2.databaseId);
}
function listProfilarrItems() {
  const ctx = {
    now: (/* @__PURE__ */ new Date()).toISOString(),
    version: build.version,
    channel: build.channel
  };
  return announcementQueries.listAll().map(rowToRecord3).filter((record) => isVisible(record, ctx)).map(profilarrRecordToItem);
}
function listDatabaseItems() {
  const now = (/* @__PURE__ */ new Date()).toISOString();
  const databases = databaseInstancesQueries.getAll();
  const instanceById = new Map(databases.map((d2) => [d2.id, {
    name: d2.name,
    repoUrl: d2.repository_url
  }]));
  return databaseAnnouncementQueries.listAll().map((row) => rowToRecord2(row)).filter((record) => isVisibleBase({
    withdrawn: record.withdrawn,
    expiresAt: record.expiresAt
  }, now)).map((record) => {
    const instance = instanceById.get(record.databaseId);
    return databaseRecordToItem(record, instance?.name ?? "(unknown database)", instance?.repoUrl ?? null);
  });
}
function profilarrRecordToItem(record) {
  return {
    source: "profilarr",
    id: record.id,
    databaseId: null,
    databaseName: null,
    databaseRepoUrl: null,
    title: record.title,
    severity: record.severity,
    publishedAt: record.publishedAt,
    expiresAt: record.expiresAt,
    link: record.link,
    body: record.body,
    readAt: record.readAt
  };
}
function databaseRecordToItem(record, databaseName, databaseRepoUrl) {
  return {
    source: "pcd",
    id: record.id,
    databaseId: record.databaseId,
    databaseName,
    databaseRepoUrl,
    title: record.title,
    severity: record.severity,
    publishedAt: record.publishedAt,
    expiresAt: record.expiresAt,
    link: record.link,
    body: record.body,
    readAt: record.readAt
  };
}
var announcementQueries, versionsSnapshotQueries, client, ANNOUNCEMENTS_CAP, UnsupportedSchemaError, FETCH_INTERVAL_MS;
var init_announcements = __esm({
  async "dist/build/server/chunks/announcements.js"() {
    "use strict";
    await init_db();
    init_config();
    init_build();
    init_client();
    await init_database();
    await init_databaseInstances();
    announcementQueries = {
      /**
      * Return all rows, newest first.
      */
      listAll() {
        return db.query("SELECT * FROM announcements ORDER BY published_at DESC, id DESC");
      },
      /**
      * Return a single row by id, or undefined.
      */
      getById(id) {
        return db.queryFirst("SELECT * FROM announcements WHERE id = ?", id);
      },
      /**
      * Insert a new bulletin announcement, or update an existing row preserving
      * `read_at`, `body`, and `body_fetched_at`. Returns true if the row was
      * newly inserted (so the caller can fire a notification).
      */
      upsertFromBulletin(announcement, fetchedAt) {
        if (!this.getById(announcement.id)) {
          db.execute(`INSERT INTO announcements (
					id, title, severity, published_at, expires_at,
					min_version, max_version, link, body, withdrawn,
					read_at, fetched_at, body_fetched_at
				) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL, 0, NULL, ?, NULL)`, announcement.id, announcement.title, announcement.severity, announcement.published_at, announcement.expires_at, announcement.min_version, announcement.max_version, announcement.link, fetchedAt);
          return true;
        }
        db.execute(`UPDATE announcements SET
				title = ?,
				severity = ?,
				published_at = ?,
				expires_at = ?,
				min_version = ?,
				max_version = ?,
				link = ?,
				fetched_at = ?
			WHERE id = ?`, announcement.title, announcement.severity, announcement.published_at, announcement.expires_at, announcement.min_version, announcement.max_version, announcement.link, fetchedAt, announcement.id);
        return false;
      },
      /**
      * Set `withdrawn = 1` for the given ids.
      */
      markWithdrawn(ids) {
        for (const id of ids) db.execute("UPDATE announcements SET withdrawn = 1 WHERE id = ?", id);
      },
      /**
      * Set `withdrawn = 0` for the given ids (ids that reappeared).
      */
      markUnwithdrawn(ids) {
        for (const id of ids) db.execute("UPDATE announcements SET withdrawn = 0 WHERE id = ?", id);
      },
      /**
      * Set `read_at` for a single announcement. No-op if the row doesn't exist.
      */
      markRead(id, now) {
        db.execute("UPDATE announcements SET read_at = ? WHERE id = ? AND read_at IS NULL", now, id);
      },
      /**
      * Clear `read_at` for a single announcement (flip back to unread).
      */
      markUnread(id) {
        db.execute("UPDATE announcements SET read_at = NULL WHERE id = ?", id);
      },
      /**
      * Populate the cached body for an announcement after a lazy fetch.
      */
      setBody(id, body, now) {
        db.execute("UPDATE announcements SET body = ?, body_fetched_at = ? WHERE id = ?", body, now, id);
      }
    };
    versionsSnapshotQueries = {
      /**
      * Return the singleton snapshot row, or undefined if no sync has happened.
      */
      get() {
        return db.queryFirst("SELECT * FROM versions_snapshot WHERE id = 1");
      },
      /**
      * Upsert the singleton snapshot with the given payload (raw versions.json).
      */
      set(payload2, fetchedAt) {
        db.execute(`INSERT INTO versions_snapshot (id, payload, fetched_at) VALUES (1, ?, ?)
			 ON CONFLICT(id) DO UPDATE SET payload = excluded.payload, fetched_at = excluded.fetched_at`, payload2, fetchedAt);
      }
    };
    client = null;
    ANNOUNCEMENTS_CAP = 1e3;
    UnsupportedSchemaError = class extends Error {
      schema;
      constructor(schema) {
        super(`Unsupported announcements schema version: ${schema}`);
        this.schema = schema;
        this.name = "UnsupportedSchemaError";
      }
    };
    FETCH_INTERVAL_MS = 18e5;
  }
});

// dist/build/server/chunks/arrInstances.js
function normalizeArrInstanceUrl(value2) {
  const raw = value2.trim();
  if (!raw) return "";
  try {
    const url = new URL(raw);
    const protocol2 = url.protocol.toLowerCase();
    const hostname = url.hostname.toLowerCase();
    const port = protocol2 === "http:" && url.port === "80" || protocol2 === "https:" && url.port === "443" ? "" : url.port;
    return `${protocol2}//${port ? `${hostname}:${port}` : hostname}${url.pathname === "/" ? "" : url.pathname.replace(/\/+$/, "")}`;
  } catch {
    return raw.replace(/[?#].*$/, "").replace(/\/+$/, "");
  }
}
var arrInstancesQueries;
var init_arrInstances = __esm({
  async "dist/build/server/chunks/arrInstances.js"() {
    "use strict";
    await init_db();
    await init_arrSync();
    arrInstancesQueries = {
      /**
      * Create a new arr instance
      */
      create(input) {
        const tagsJson = input.tags && input.tags.length > 0 ? JSON.stringify(input.tags) : null;
        db.execute(`INSERT INTO arr_instances (name, type, url, external_url, api_key, tags, enabled)
       VALUES (?, ?, ?, ?, ?, ?, ?)`, input.name, input.type, input.url, input.externalUrl ?? null, input.apiKey, tagsJson, 1);
        const id = db.queryFirst("SELECT last_insert_rowid() as id")?.id ?? 0;
        if (id > 0) arrSyncQueries.ensureAllInstancePriorities(id);
        return id;
      },
      /**
      * Get an arr instance by ID
      */
      getById(id) {
        return db.queryFirst("SELECT * FROM arr_instances WHERE id = ?", id);
      },
      /**
      * Get all arr instances
      */
      getAll() {
        return db.query("SELECT * FROM arr_instances ORDER BY type, name");
      },
      /**
      * Get arr instances by type
      */
      getByType(type) {
        return db.query("SELECT * FROM arr_instances WHERE type = ? ORDER BY name", type);
      },
      /**
      * Get enabled arr instances
      */
      getEnabled() {
        return db.query("SELECT * FROM arr_instances WHERE enabled = 1 ORDER BY type, name");
      },
      /**
      * Update an arr instance
      */
      update(id, input) {
        const updates = [];
        const params = [];
        if (input.name !== void 0) {
          updates.push("name = ?");
          params.push(input.name);
        }
        if (input.type !== void 0) {
          updates.push("type = ?");
          params.push(input.type);
        }
        if (input.url !== void 0) {
          updates.push("url = ?");
          params.push(input.url);
        }
        if (input.externalUrl !== void 0) {
          updates.push("external_url = ?");
          params.push(input.externalUrl);
        }
        if (input.apiKey !== void 0) {
          updates.push("api_key = ?");
          params.push(input.apiKey);
        }
        if (input.tags !== void 0) {
          updates.push("tags = ?");
          params.push(input.tags.length > 0 ? JSON.stringify(input.tags) : null);
        }
        if (input.libraryRefreshInterval !== void 0) {
          updates.push("library_refresh_interval = ?");
          params.push(input.libraryRefreshInterval);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(id);
        return db.execute(`UPDATE arr_instances SET ${updates.join(", ")} WHERE id = ?`, ...params) > 0;
      },
      /**
      * Delete an arr instance
      */
      delete(id) {
        return db.execute("DELETE FROM arr_instances WHERE id = ?", id) > 0;
      },
      /**
      * Check if an instance name already exists
      */
      nameExists(name, excludeId) {
        if (excludeId !== void 0) return (db.queryFirst("SELECT COUNT(*) as count FROM arr_instances WHERE name = ? AND id != ?", name, excludeId)?.count ?? 0) > 0;
        return (db.queryFirst("SELECT COUNT(*) as count FROM arr_instances WHERE name = ?", name)?.count ?? 0) > 0;
      },
      /**
      * Update library_last_refreshed_at timestamp
      */
      updateLibraryRefreshedAt(id, refreshedAt = (/* @__PURE__ */ new Date()).toISOString()) {
        db.execute("UPDATE arr_instances SET library_last_refreshed_at = ? WHERE id = ?", refreshedAt, id);
      },
      /**
      * Check if an instance with the same type and normalized URL already exists
      */
      targetExists(type, url, excludeId) {
        const normalizedUrl = normalizeArrInstanceUrl(url);
        return db.query("SELECT id, url FROM arr_instances WHERE type = ?", type).some((instance) => {
          if (excludeId !== void 0 && instance.id === excludeId) return false;
          return normalizeArrInstanceUrl(instance.url) === normalizedUrl;
        });
      }
    };
  }
});

// dist/build/server/chunks/jobQueue.js
function parsePayload(raw) {
  try {
    const parsed = JSON.parse(raw);
    if (parsed && typeof parsed === "object") return parsed;
    return {};
  } catch {
    return {};
  }
}
function rowToRecord4(row) {
  return {
    id: row.id,
    jobType: row.job_type,
    status: row.status,
    runAt: toUTC(row.run_at),
    payload: parsePayload(row.payload),
    source: row.source,
    dedupeKey: row.dedupe_key,
    cooldownUntil: toUTC(row.cooldown_until),
    attempts: row.attempts,
    startedAt: toUTC(row.started_at),
    finishedAt: toUTC(row.finished_at),
    createdAt: toUTC(row.created_at),
    updatedAt: toUTC(row.updated_at)
  };
}
var jobQueueQueries;
var init_jobQueue = __esm({
  async "dist/build/server/chunks/jobQueue.js"() {
    "use strict";
    await init_db();
    init_dates();
    jobQueueQueries = {
      create(input) {
        const payload2 = JSON.stringify(input.payload ?? {});
        const source2 = input.source ?? "system";
        const dedupeKey = input.dedupeKey ?? null;
        const cooldownUntil = input.cooldownUntil ?? null;
        db.execute(`INSERT INTO job_queue (job_type, status, run_at, payload, source, dedupe_key, cooldown_until)
			 VALUES (?, 'queued', ?, ?, ?, ?, ?)`, input.jobType, input.runAt, payload2, source2, dedupeKey, cooldownUntil);
        return db.queryFirst("SELECT last_insert_rowid() as id")?.id ?? 0;
      },
      upsertScheduled(input) {
        if (!input.dedupeKey) throw new Error("dedupeKey is required for scheduled jobs");
        const existing = this.getByDedupeKey(input.dedupeKey);
        if (!existing) {
          const id = this.create({
            ...input,
            source: input.source ?? "schedule"
          });
          const created = this.getById(id);
          if (!created) throw new Error("Failed to create scheduled job");
          return created;
        }
        if (existing.status === "running") return existing;
        const payload2 = JSON.stringify(input.payload ?? {});
        const source2 = input.source ?? "schedule";
        const cooldownUntil = input.cooldownUntil ?? null;
        db.execute(`UPDATE job_queue
			 SET run_at = ?, payload = ?, source = ?, cooldown_until = ?, status = 'queued', updated_at = CURRENT_TIMESTAMP
			 WHERE dedupe_key = ?`, input.runAt, payload2, source2, cooldownUntil, input.dedupeKey);
        return this.getByDedupeKey(input.dedupeKey);
      },
      getById(id) {
        const row = db.queryFirst("SELECT * FROM job_queue WHERE id = ?", id);
        return row ? rowToRecord4(row) : void 0;
      },
      getByDedupeKey(dedupeKey) {
        const row = db.queryFirst("SELECT * FROM job_queue WHERE dedupe_key = ?", dedupeKey);
        return row ? rowToRecord4(row) : void 0;
      },
      listRecent(limit = 50) {
        return db.query(`SELECT * FROM job_queue ORDER BY run_at DESC LIMIT ?`, limit).map(rowToRecord4);
      },
      listQueued(limit = 50) {
        return db.query(`SELECT * FROM job_queue WHERE status = 'queued' ORDER BY run_at ASC LIMIT ?`, limit).map(rowToRecord4);
      },
      listScheduled() {
        return db.query(`SELECT * FROM job_queue WHERE dedupe_key IS NOT NULL AND source = 'schedule' ORDER BY job_type`).map(rowToRecord4);
      },
      listByJobTypes(jobTypes) {
        if (jobTypes.length === 0) return [];
        const placeholders = jobTypes.map(() => "?").join(", ");
        return db.query(`SELECT * FROM job_queue WHERE job_type IN (${placeholders})`, ...jobTypes).map(rowToRecord4);
      },
      getNextQueued() {
        const row = db.queryFirst(`SELECT * FROM job_queue WHERE status = 'queued' ORDER BY run_at ASC LIMIT 1`);
        return row ? rowToRecord4(row) : void 0;
      },
      getOldestQueuedRunAt() {
        return db.queryFirst(`SELECT run_at FROM job_queue WHERE status = 'queued' ORDER BY run_at ASC LIMIT 1`)?.run_at ?? null;
      },
      getNextDueQueued() {
        const row = db.queryFirst(`SELECT * FROM job_queue
			 WHERE status = 'queued'
			 AND datetime(replace(replace(run_at, 'T', ' '), 'Z', '')) <= datetime('now')
			 ORDER BY run_at ASC
			 LIMIT 1`);
        return row ? rowToRecord4(row) : void 0;
      },
      claimNextDue() {
        const next2 = this.getNextDueQueued();
        if (!next2) return void 0;
        if (db.execute(`UPDATE job_queue
			 SET status = 'running', started_at = CURRENT_TIMESTAMP, attempts = attempts + 1, updated_at = CURRENT_TIMESTAMP
			 WHERE id = ? AND status = 'queued'`, next2.id) === 0) return void 0;
        return this.getById(next2.id);
      },
      reschedule(id, runAt, cooldownUntil) {
        db.execute(`UPDATE job_queue
			 SET status = 'queued', run_at = ?, cooldown_until = ?, started_at = NULL, finished_at = NULL, updated_at = CURRENT_TIMESTAMP
			 WHERE id = ?`, runAt, cooldownUntil ?? null, id);
      },
      markFinished(id, status) {
        db.execute(`UPDATE job_queue
			 SET status = ?, finished_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP
			 WHERE id = ?`, status, id);
      },
      setRunNow(id) {
        db.execute(`UPDATE job_queue
			 SET run_at = ?, status = 'queued', updated_at = CURRENT_TIMESTAMP
			 WHERE id = ?`, (/* @__PURE__ */ new Date()).toISOString(), id);
      },
      setStatus(id, status) {
        db.execute(`UPDATE job_queue SET status = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`, status, id);
      },
      cancelByDedupeKey(dedupeKey) {
        db.execute(`UPDATE job_queue SET status = 'cancelled', updated_at = CURRENT_TIMESTAMP WHERE dedupe_key = ?`, dedupeKey);
      },
      deleteByIds(ids) {
        if (ids.length === 0) return 0;
        const placeholders = ids.map(() => "?").join(", ");
        return db.execute(`DELETE FROM job_queue WHERE id IN (${placeholders})`, ...ids);
      },
      unscheduleByDedupeKey(dedupeKey) {
        db.execute(`UPDATE job_queue
			 SET status = CASE WHEN status = 'running' THEN status ELSE 'cancelled' END,
			     dedupe_key = NULL,
			     source = 'system',
			     updated_at = CURRENT_TIMESTAMP
			 WHERE dedupe_key = ?`, dedupeKey);
      },
      recoverRunning() {
        return db.execute(`UPDATE job_queue
			 SET status = 'queued', started_at = NULL, updated_at = CURRENT_TIMESTAMP
			 WHERE status = 'running'`);
      }
    };
  }
});

// dist/build/server/chunks/jobRunHistory.js
function rowToRecord5(row) {
  return {
    id: row.id,
    queueId: row.queue_id,
    jobType: row.job_type,
    status: row.status,
    startedAt: toUTC(row.started_at),
    finishedAt: toUTC(row.finished_at),
    durationMs: row.duration_ms,
    error: row.error,
    output: row.output,
    createdAt: toUTC(row.created_at)
  };
}
var jobRunHistoryQueries;
var init_jobRunHistory = __esm({
  async "dist/build/server/chunks/jobRunHistory.js"() {
    "use strict";
    await init_db();
    init_dates();
    jobRunHistoryQueries = {
      create(queueId, jobType, status, startedAt, finishedAt, durationMs, error2, output) {
        db.execute(`INSERT INTO job_run_history
			 (queue_id, job_type, status, started_at, finished_at, duration_ms, error, output)
			 VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, queueId, jobType, status, startedAt, finishedAt, durationMs, error2 ?? null, output ?? null);
        return db.queryFirst("SELECT last_insert_rowid() as id")?.id ?? 0;
      },
      getRecent(limit = 100) {
        return db.query(`SELECT * FROM job_run_history ORDER BY started_at DESC LIMIT ?`, limit).map(rowToRecord5);
      },
      getByQueueId(queueId, limit = 1) {
        return db.query(`SELECT * FROM job_run_history WHERE queue_id = ? ORDER BY started_at DESC LIMIT ?`, queueId, limit).map(rowToRecord5);
      }
    };
  }
});

// dist/build/server/chunks/display.js
function formatJobTypeLabel(jobType) {
  switch (jobType) {
    case "arr.sync":
      return "Arr Sync";
    case "arr.sync.qualityProfiles":
      return "Arr Sync (Quality Profiles)";
    case "arr.sync.delayProfiles":
      return "Arr Sync (Delay Profiles)";
    case "arr.sync.mediaManagement":
      return "Arr Sync (Media Management)";
    case "arr.rename":
      return "Arr Rename";
    case "arr.upgrade":
      return "Arr Upgrade";
    case "arr.cleanup":
      return "Arr Cleanup";
    case "arr.drift":
      return "Arr Drift";
    case "arr.library.refresh":
      return "Library Refresh";
    case "pcd.link":
      return "PCD Link";
    case "pcd.sync":
      return "PCD Sync";
    case "backup.create":
      return "Backup Create";
    case "backup.cleanup":
      return "Backup Cleanup";
    case "logs.cleanup":
      return "Logs Cleanup";
    case "announcements.fetch":
      return "Announcements Fetch";
    default:
      return jobType.replace(/\./g, " ").split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
  }
}
function readId(raw) {
  if (typeof raw === "number" && Number.isFinite(raw)) return raw;
  if (typeof raw === "string" && raw.trim() !== "" && Number.isFinite(Number(raw))) return Number(raw);
  return null;
}
function buildJobDisplayName(jobType, payload2, lookups) {
  const base2 = formatJobTypeLabel(jobType);
  const instanceId = readId(payload2.instanceId);
  const databaseId = readId(payload2.databaseId);
  if (jobType === "pcd.link") {
    const name = typeof payload2.name === "string" ? payload2.name : null;
    return name ? `${base2} - ${name}` : base2;
  }
  if (jobType === "pcd.sync" && databaseId !== null) {
    const name = lookups?.databaseNameById?.get(databaseId) ?? databaseInstancesQueries.getById(databaseId)?.name;
    return name ? `${base2} - ${name}` : base2;
  }
  if ((jobType === "arr.sync" || jobType.startsWith("arr.sync.") || jobType === "arr.rename" || jobType === "arr.upgrade" || jobType === "arr.cleanup" || jobType === "arr.drift" || jobType === "arr.library.refresh") && instanceId !== null) {
    const name = lookups?.arrNameById?.get(instanceId) ?? arrInstancesQueries.getById(instanceId)?.name;
    return name ? `${base2} - ${name}` : base2;
  }
  return base2;
}
var init_display = __esm({
  async "dist/build/server/chunks/display.js"() {
    "use strict";
    await init_databaseInstances();
    await init_arrInstances();
  }
});

// dist/build/server/chunks/jobEvents.js
function getJobRunningLabel(jobType) {
  return JOB_RUNNING_LABELS[jobType] ?? jobType;
}
function getJobCompletedLabel(jobType) {
  return JOB_COMPLETED_LABELS[jobType] ?? jobType;
}
function subscribe(callback) {
  subscribers.add(callback);
  return () => subscribers.delete(callback);
}
function emit(event) {
  if (!EMITTED_JOB_TYPES.has(event.jobType)) return;
  for (const callback of subscribers) try {
    callback(event);
  } catch {
  }
}
var JOB_RUNNING_LABELS, JOB_COMPLETED_LABELS, EMITTED_JOB_TYPES, subscribers, jobEvents;
var init_jobEvents = __esm({
  "dist/build/server/chunks/jobEvents.js"() {
    "use strict";
    JOB_RUNNING_LABELS = {
      "arr.sync": "Syncing...",
      "arr.sync.qualityProfiles": "Syncing Quality Profiles...",
      "arr.sync.delayProfiles": "Syncing Delay Profiles...",
      "arr.sync.mediaManagement": "Syncing Media Management...",
      "arr.cleanup": "Cleaning up...",
      "arr.drift": "Checking drift...",
      "arr.upgrade": "Running upgrades...",
      "arr.rename": "Renaming files...",
      "backup.create": "Creating backup...",
      "backup.cleanup": "Cleaning up backups...",
      "pcd.link": "Linking database..."
    };
    JOB_COMPLETED_LABELS = {
      "arr.sync": "Sync",
      "arr.sync.qualityProfiles": "Quality Profiles sync",
      "arr.sync.delayProfiles": "Delay Profiles sync",
      "arr.sync.mediaManagement": "Media Management sync",
      "arr.cleanup": "Cleanup",
      "arr.drift": "Drift check",
      "arr.upgrade": "Upgrade run",
      "arr.rename": "Rename run",
      "backup.create": "Backup",
      "backup.cleanup": "Backup cleanup",
      "pcd.link": "Database link"
    };
    EMITTED_JOB_TYPES = new Set(Object.keys(JOB_RUNNING_LABELS));
    subscribers = /* @__PURE__ */ new Set();
    jobEvents = {
      subscribe,
      emit
    };
  }
});

// dist/build/server/chunks/arrCleanupSettings.js
function rowToConfig(row) {
  return {
    id: row.id,
    arrInstanceId: row.arr_instance_id,
    enabled: row.enabled === 1,
    cron: row.cron,
    nextRunAt: toUTC(row.next_run_at),
    filterMode: row.filter_mode,
    filters: JSON.parse(row.filters),
    currentFilterIndex: row.current_filter_index,
    lastRunAt: toUTC(row.last_run_at),
    createdAt: toUTC(row.created_at) ?? void 0,
    updatedAt: toUTC(row.updated_at) ?? void 0
  };
}
function rowToSettings$1(row) {
  return {
    id: row.id,
    arrInstanceId: row.arr_instance_id,
    renameFolders: row.rename_folders === 1,
    ignoreTag: row.ignore_tag,
    summaryNotifications: row.summary_notifications === 1,
    enabled: row.enabled === 1,
    cron: row.cron,
    nextRunAt: toUTC(row.next_run_at),
    lastRunAt: toUTC(row.last_run_at),
    createdAt: toUTC(row.created_at),
    updatedAt: toUTC(row.updated_at)
  };
}
function rowToSettings(row) {
  return {
    id: row.id,
    arrInstanceId: row.arr_instance_id,
    enabled: row.enabled === 1,
    cron: row.cron,
    nextRunAt: toUTC(row.next_run_at),
    lastRunAt: toUTC(row.last_run_at),
    createdAt: toUTC(row.created_at),
    updatedAt: toUTC(row.updated_at)
  };
}
var upgradeConfigsQueries, arrRenameSettingsQueries, arrCleanupSettingsQueries;
var init_arrCleanupSettings = __esm({
  async "dist/build/server/chunks/arrCleanupSettings.js"() {
    "use strict";
    await init_db();
    init_dates();
    upgradeConfigsQueries = {
      /**
      * Get upgrade config by arr instance ID
      */
      getByArrInstanceId(arrInstanceId) {
        const row = db.queryFirst("SELECT * FROM upgrade_configs WHERE arr_instance_id = ?", arrInstanceId);
        return row ? rowToConfig(row) : void 0;
      },
      /**
      * Get all upgrade configs
      */
      getAll() {
        return db.query("SELECT * FROM upgrade_configs").map(rowToConfig);
      },
      /**
      * Get all enabled upgrade configs
      */
      getEnabled() {
        return db.query("SELECT * FROM upgrade_configs WHERE enabled = 1").map(rowToConfig);
      },
      /**
      * Create or update an upgrade config for an arr instance
      * Uses upsert pattern since there's one config per instance
      */
      upsert(arrInstanceId, input) {
        if (this.getByArrInstanceId(arrInstanceId)) {
          this.update(arrInstanceId, input);
          return this.getByArrInstanceId(arrInstanceId);
        }
        const enabled3 = input.enabled !== void 0 ? input.enabled ? 1 : 0 : 0;
        const cron = input.cron ?? "0 */6 * * *";
        const filterMode2 = input.filterMode ?? "round_robin";
        const filters = JSON.stringify(input.filters ?? []);
        const currentFilterIndex = input.currentFilterIndex ?? 0;
        db.execute(`INSERT INTO upgrade_configs
			(arr_instance_id, enabled, cron, filter_mode, filters, current_filter_index)
			VALUES (?, ?, ?, ?, ?, ?)`, arrInstanceId, enabled3, cron, filterMode2, filters, currentFilterIndex);
        return this.getByArrInstanceId(arrInstanceId);
      },
      /**
      * Update an upgrade config
      */
      update(arrInstanceId, input) {
        const updates = [];
        const params = [];
        if (input.enabled !== void 0) {
          updates.push("enabled = ?");
          params.push(input.enabled ? 1 : 0);
        }
        if (input.cron !== void 0) {
          updates.push("cron = ?");
          params.push(input.cron);
        }
        if (input.filterMode !== void 0) {
          updates.push("filter_mode = ?");
          params.push(input.filterMode);
        }
        if (input.filters !== void 0) {
          updates.push("filters = ?");
          params.push(JSON.stringify(input.filters));
        }
        if (input.currentFilterIndex !== void 0) {
          updates.push("current_filter_index = ?");
          params.push(input.currentFilterIndex);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(arrInstanceId);
        return db.execute(`UPDATE upgrade_configs SET ${updates.join(", ")} WHERE arr_instance_id = ?`, ...params) > 0;
      },
      /**
      * Delete an upgrade config
      */
      delete(arrInstanceId) {
        return db.execute("DELETE FROM upgrade_configs WHERE arr_instance_id = ?", arrInstanceId) > 0;
      },
      /**
      * Increment the current filter index (for round-robin mode)
      * Wraps around to 0 when reaching the end
      */
      incrementFilterIndex(arrInstanceId) {
        const config2 = this.getByArrInstanceId(arrInstanceId);
        if (!config2) return 0;
        const enabledFilters = config2.filters.filter((f2) => f2.enabled);
        if (enabledFilters.length === 0) return 0;
        const nextIndex = (config2.currentFilterIndex + 1) % enabledFilters.length;
        db.execute("UPDATE upgrade_configs SET current_filter_index = ?, updated_at = CURRENT_TIMESTAMP WHERE arr_instance_id = ?", nextIndex, arrInstanceId);
        return nextIndex;
      },
      /**
      * Reset the filter index to 0
      */
      resetFilterIndex(arrInstanceId) {
        db.execute("UPDATE upgrade_configs SET current_filter_index = 0, updated_at = CURRENT_TIMESTAMP WHERE arr_instance_id = ?", arrInstanceId);
      },
      /**
      * Update last_run_at to current timestamp
      */
      updateLastRun(arrInstanceId) {
        db.execute("UPDATE upgrade_configs SET last_run_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE arr_instance_id = ?", arrInstanceId);
      },
      /**
      * Update next_run_at
      */
      updateNextRunAt(arrInstanceId, nextRunAt) {
        db.execute("UPDATE upgrade_configs SET next_run_at = ?, updated_at = CURRENT_TIMESTAMP WHERE arr_instance_id = ?", nextRunAt, arrInstanceId);
      },
      /**
      * Get all enabled configs that are due to run
      * A config is due if: next_run_at is null OR now >= next_run_at
      */
      getDueConfigs() {
        return db.query(`
			SELECT * FROM upgrade_configs
			WHERE enabled = 1
			AND (
				next_run_at IS NULL
				OR datetime('now') >= datetime(replace(replace(next_run_at, 'T', ' '), 'Z', ''))
			)
		`).map(rowToConfig);
      }
    };
    arrRenameSettingsQueries = {
      /**
      * Get rename settings by arr instance ID
      */
      getByInstanceId(arrInstanceId) {
        const row = db.queryFirst("SELECT * FROM arr_rename_settings WHERE arr_instance_id = ?", arrInstanceId);
        return row ? rowToSettings$1(row) : void 0;
      },
      /**
      * Get all rename settings
      */
      getAll() {
        return db.query("SELECT * FROM arr_rename_settings").map(rowToSettings$1);
      },
      /**
      * Get all enabled rename settings
      */
      getEnabled() {
        return db.query("SELECT * FROM arr_rename_settings WHERE enabled = 1").map(rowToSettings$1);
      },
      /**
      * Create or update rename settings for an arr instance
      * Uses upsert pattern since there's one config per instance
      */
      upsert(arrInstanceId, input) {
        if (this.getByInstanceId(arrInstanceId)) {
          this.update(arrInstanceId, input);
          return this.getByInstanceId(arrInstanceId);
        }
        const renameFolders = input.renameFolders !== void 0 ? input.renameFolders ? 1 : 0 : 0;
        const ignoreTag = input.ignoreTag ?? null;
        const summaryNotifications = input.summaryNotifications !== void 0 ? input.summaryNotifications ? 1 : 0 : 1;
        const enabled3 = input.enabled !== void 0 ? input.enabled ? 1 : 0 : 0;
        const cron = input.cron ?? "0 0 * * *";
        db.execute(`INSERT INTO arr_rename_settings
			(arr_instance_id, rename_folders, ignore_tag, summary_notifications, enabled, cron)
			VALUES (?, ?, ?, ?, ?, ?)`, arrInstanceId, renameFolders, ignoreTag, summaryNotifications, enabled3, cron);
        return this.getByInstanceId(arrInstanceId);
      },
      /**
      * Update rename settings
      */
      update(arrInstanceId, input) {
        const updates = [];
        const params = [];
        if (input.renameFolders !== void 0) {
          updates.push("rename_folders = ?");
          params.push(input.renameFolders ? 1 : 0);
        }
        if (input.ignoreTag !== void 0) {
          updates.push("ignore_tag = ?");
          params.push(input.ignoreTag);
        }
        if (input.summaryNotifications !== void 0) {
          updates.push("summary_notifications = ?");
          params.push(input.summaryNotifications ? 1 : 0);
        }
        if (input.enabled !== void 0) {
          updates.push("enabled = ?");
          params.push(input.enabled ? 1 : 0);
        }
        if (input.cron !== void 0) {
          updates.push("cron = ?");
          params.push(input.cron);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(arrInstanceId);
        return db.execute(`UPDATE arr_rename_settings SET ${updates.join(", ")} WHERE arr_instance_id = ?`, ...params) > 0;
      },
      /**
      * Delete rename settings
      */
      delete(arrInstanceId) {
        return db.execute("DELETE FROM arr_rename_settings WHERE arr_instance_id = ?", arrInstanceId) > 0;
      },
      /**
      * Update last_run_at to current timestamp
      */
      updateLastRun(arrInstanceId) {
        db.execute("UPDATE arr_rename_settings SET last_run_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE arr_instance_id = ?", arrInstanceId);
      },
      /**
      * Update next_run_at
      */
      updateNextRunAt(arrInstanceId, nextRunAt) {
        db.execute("UPDATE arr_rename_settings SET next_run_at = ?, updated_at = CURRENT_TIMESTAMP WHERE arr_instance_id = ?", nextRunAt, arrInstanceId);
      },
      /**
      * Get all enabled configs that are due to run
      * A config is due if: next_run_at is null OR now >= next_run_at
      */
      getDueConfigs() {
        return db.query(`
			SELECT * FROM arr_rename_settings
			WHERE enabled = 1
			AND (
				next_run_at IS NULL
				OR datetime('now') >= datetime(replace(replace(next_run_at, 'T', ' '), 'Z', ''))
			)
		`).map(rowToSettings$1);
      }
    };
    arrCleanupSettingsQueries = {
      getByInstanceId(arrInstanceId) {
        const row = db.queryFirst("SELECT * FROM arr_cleanup_settings WHERE arr_instance_id = ?", arrInstanceId);
        return row ? rowToSettings(row) : void 0;
      },
      getAll() {
        return db.query("SELECT * FROM arr_cleanup_settings").map(rowToSettings);
      },
      getEnabled() {
        return db.query("SELECT * FROM arr_cleanup_settings WHERE enabled = 1").map(rowToSettings);
      },
      upsert(arrInstanceId, input) {
        if (this.getByInstanceId(arrInstanceId)) {
          this.update(arrInstanceId, input);
          return this.getByInstanceId(arrInstanceId);
        }
        const enabled3 = input.enabled !== void 0 ? input.enabled ? 1 : 0 : 0;
        const cron = input.cron ?? "0 0 * * 0";
        db.execute(`INSERT INTO arr_cleanup_settings (arr_instance_id, enabled, cron) VALUES (?, ?, ?)`, arrInstanceId, enabled3, cron);
        return this.getByInstanceId(arrInstanceId);
      },
      update(arrInstanceId, input) {
        const updates = [];
        const params = [];
        if (input.enabled !== void 0) {
          updates.push("enabled = ?");
          params.push(input.enabled ? 1 : 0);
        }
        if (input.cron !== void 0) {
          updates.push("cron = ?");
          params.push(input.cron);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(arrInstanceId);
        return db.execute(`UPDATE arr_cleanup_settings SET ${updates.join(", ")} WHERE arr_instance_id = ?`, ...params) > 0;
      },
      delete(arrInstanceId) {
        return db.execute("DELETE FROM arr_cleanup_settings WHERE arr_instance_id = ?", arrInstanceId) > 0;
      },
      updateLastRun(arrInstanceId) {
        db.execute("UPDATE arr_cleanup_settings SET last_run_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP WHERE arr_instance_id = ?", arrInstanceId);
      },
      updateNextRunAt(arrInstanceId, nextRunAt) {
        db.execute("UPDATE arr_cleanup_settings SET next_run_at = ?, updated_at = CURRENT_TIMESTAMP WHERE arr_instance_id = ?", nextRunAt, arrInstanceId);
      },
      getDueConfigs() {
        return db.query(`
			SELECT * FROM arr_cleanup_settings
			WHERE enabled = 1
			AND (
				next_run_at IS NULL
				OR datetime('now') >= datetime(replace(replace(next_run_at, 'T', ' '), 'Z', ''))
			)
		`).map(rowToSettings);
      }
    };
  }
});

// dist/build/server/chunks/base.js
var INTERACTIVE_SEARCH_TIMEOUT_MS, LIBRARY_REQUEST_TIMEOUT_MS, BaseArrClient;
var init_base = __esm({
  async "dist/build/server/chunks/base.js"() {
    "use strict";
    await init_db();
    init_client();
    INTERACTIVE_SEARCH_TIMEOUT_MS = 12e4;
    LIBRARY_REQUEST_TIMEOUT_MS = 3e5;
    BaseArrClient = class extends BaseHttpClient {
      apiKey;
      apiVersion = "v3";
      constructor(url, apiKey, options2) {
        super(url, {
          headers: { "X-Api-Key": apiKey },
          timeout: options2?.timeout,
          retries: options2?.retries
        });
        this.apiKey = apiKey;
      }
      /**
      * Compute score breakdown for custom formats against a profile's format items
      */
      computeScoreBreakdown(customFormats, profileFormatItems) {
        return customFormats.map((cf) => {
          const profileItem = profileFormatItems.find((fi) => fi.format === cf.id);
          return {
            name: cf.name,
            score: profileItem?.score ?? 0
          };
        });
      }
      /**
      * Test connection to the arr instance
      * Calls /api/{version}/system/status endpoint
      * Note: This method has built-in retry logic (3 attempts by default)
      * @returns true if connection successful, false otherwise
      */
      async testConnection() {
        try {
          const status = await this.get(`/api/${this.apiVersion}/system/status`);
          await logger.info(`Connection successful to ${this.baseUrl}`, {
            source: "BaseArrClient",
            meta: {
              appName: status.appName,
              version: status.version,
              osName: status.osName
            }
          });
          return true;
        } catch (error2) {
          await logger.error(`Connection failed to ${this.baseUrl} after retries`, {
            source: "BaseArrClient",
            meta: error2
          });
          return false;
        }
      }
      /**
      * Get health check items from the arr instance
      */
      getHealth() {
        return this.get(`/api/${this.apiVersion}/health`);
      }
      /**
      * Get all delay profiles
      */
      getDelayProfiles() {
        return this.get(`/api/${this.apiVersion}/delayprofile`);
      }
      /**
      * Get a delay profile by ID
      */
      getDelayProfile(id) {
        return this.get(`/api/${this.apiVersion}/delayprofile/${id}`);
      }
      /**
      * Create a new delay profile
      */
      createDelayProfile(profile) {
        return this.post(`/api/${this.apiVersion}/delayprofile`, profile);
      }
      /**
      * Update an existing delay profile
      */
      updateDelayProfile(id, profile) {
        return this.put(`/api/${this.apiVersion}/delayprofile/${id}`, profile);
      }
      /**
      * Delete a delay profile
      */
      deleteDelayProfile(id) {
        return this.delete(`/api/${this.apiVersion}/delayprofile/${id}`);
      }
      /**
      * Get all tags
      */
      getTags() {
        return this.get(`/api/${this.apiVersion}/tag`);
      }
      /**
      * Create a new tag
      */
      createTag(label) {
        return this.post(`/api/${this.apiVersion}/tag`, { label });
      }
      /**
      * Get media management config
      */
      getMediaManagementConfig() {
        return this.get(`/api/${this.apiVersion}/config/mediamanagement`);
      }
      /**
      * Update media management config
      * Note: Must PUT to /{id} endpoint
      */
      updateMediaManagementConfig(config2) {
        return this.put(`/api/${this.apiVersion}/config/mediamanagement/${config2.id}`, config2);
      }
      /**
      * Get naming config
      */
      getNamingConfig() {
        return this.get(`/api/${this.apiVersion}/config/naming`);
      }
      /**
      * Update naming config
      * Note: Must PUT to /{id} endpoint
      */
      updateNamingConfig(config2) {
        return this.put(`/api/${this.apiVersion}/config/naming/${config2.id}`, config2);
      }
      /**
      * Get all quality definitions
      */
      getQualityDefinitions() {
        return this.get(`/api/${this.apiVersion}/qualitydefinition`);
      }
      /**
      * Update all quality definitions
      * Note: PUT to /update endpoint with full array
      */
      updateQualityDefinitions(definitions) {
        return this.put(`/api/${this.apiVersion}/qualitydefinition/update`, definitions);
      }
      /**
      * Get all custom formats
      */
      getCustomFormats() {
        return this.get(`/api/${this.apiVersion}/customformat`);
      }
      /**
      * Get a custom format by ID
      */
      getCustomFormat(id) {
        return this.get(`/api/${this.apiVersion}/customformat/${id}`);
      }
      /**
      * Create a new custom format
      */
      createCustomFormat(format) {
        return this.post(`/api/${this.apiVersion}/customformat`, format);
      }
      /**
      * Update an existing custom format
      */
      updateCustomFormat(id, format) {
        return this.put(`/api/${this.apiVersion}/customformat/${id}`, format);
      }
      /**
      * Delete a custom format
      */
      deleteCustomFormat(id) {
        return this.delete(`/api/${this.apiVersion}/customformat/${id}`);
      }
      /**
      * Get all quality profiles
      */
      getQualityProfiles() {
        return this.get(`/api/${this.apiVersion}/qualityprofile`);
      }
      /**
      * Get a quality profile by ID
      */
      getQualityProfile(id) {
        return this.get(`/api/${this.apiVersion}/qualityprofile/${id}`);
      }
      /**
      * Create a new quality profile
      */
      createQualityProfile(profile) {
        return this.post(`/api/${this.apiVersion}/qualityprofile`, profile);
      }
      /**
      * Update an existing quality profile
      */
      updateQualityProfile(id, profile) {
        return this.put(`/api/${this.apiVersion}/qualityprofile/${id}`, profile);
      }
      /**
      * Delete a quality profile
      */
      deleteQualityProfile(id) {
        return this.delete(`/api/${this.apiVersion}/qualityprofile/${id}`);
      }
      /**
      * Get all commands (active and recent)
      */
      getCommands() {
        return this.get(`/api/${this.apiVersion}/command`);
      }
      /**
      * Get command status by ID
      * Used to poll async operations like rename, refresh, etc.
      */
      getCommand(commandId) {
        return this.get(`/api/${this.apiVersion}/command/${commandId}`);
      }
      /**
      * Wait for a command to complete.
      * Polls as long as the command is alive (queued/started). Logs a warning
      * every 10 minutes of no status change. Hard ceiling at 60 minutes.
      */
      async waitForCommand(commandId) {
        const MAX_TIMEOUT_MS = 36e5;
        const STALE_WARN_MS = 6e5;
        const initialInterval = 500;
        const maxInterval = 5e3;
        let currentInterval = initialInterval;
        let pollCount = 0;
        const startTime = Date.now();
        let lastStatus = "";
        let lastStatusChangeTime = startTime;
        while (true) {
          pollCount++;
          let command;
          try {
            command = await this.getCommand(commandId);
          } catch {
            throw new Error(`Command ${commandId} disappeared (not found after ${pollCount} polls)`);
          }
          const elapsed = Date.now() - startTime;
          if (command.status !== lastStatus) {
            lastStatus = command.status;
            lastStatusChangeTime = Date.now();
          }
          await logger.debug(`Polling command ${commandId}: status=${command.status} (poll #${pollCount}, ${elapsed}ms elapsed)`, {
            source: "BaseArrClient",
            meta: {
              commandId,
              status: command.status,
              pollCount,
              elapsedMs: elapsed
            }
          });
          if (command.status === "completed") {
            await logger.debug(`Command ${commandId} completed after ${pollCount} polls (${elapsed}ms)`, {
              source: "BaseArrClient",
              meta: {
                commandId,
                pollCount,
                elapsedMs: elapsed,
                message: command.message
              }
            });
            return command;
          }
          if (command.status === "failed") throw new Error(`Command ${commandId} failed: ${command.message || "Unknown error"}`);
          const staleDuration = Date.now() - lastStatusChangeTime;
          if (staleDuration >= STALE_WARN_MS && staleDuration % STALE_WARN_MS < currentInterval) await logger.warn(`Command ${commandId} has been "${command.status}" for ${Math.floor(staleDuration / 6e4)} minutes`, {
            source: "BaseArrClient",
            meta: {
              commandId,
              status: command.status,
              staleMinutes: Math.floor(staleDuration / 6e4)
            }
          });
          if (elapsed >= MAX_TIMEOUT_MS) throw new Error(`Command ${commandId} timed out after 60 minutes (${pollCount} polls)`);
          await new Promise((resolve6) => setTimeout(resolve6, currentInterval));
          currentInterval = Math.min(currentInterval * 2, maxInterval);
        }
      }
      /**
      * Get paginated logs from the arr instance
      * @param params - Query parameters for filtering and pagination
      */
      getLogs(params = {}) {
        const queryParams = new URLSearchParams();
        if (params.page !== void 0) queryParams.set("page", String(params.page));
        if (params.pageSize !== void 0) queryParams.set("pageSize", String(params.pageSize));
        if (params.sortKey) queryParams.set("sortKey", params.sortKey);
        if (params.sortDirection) queryParams.set("sortDirection", params.sortDirection);
        if (params.level) queryParams.set("level", params.level.toLowerCase());
        const queryString = queryParams.toString();
        const url = `/api/${this.apiVersion}/log${queryString ? `?${queryString}` : ""}`;
        return this.get(url);
      }
      /**
      * Get list of available log files
      */
      getLogFiles() {
        return this.get(`/api/${this.apiVersion}/log/file`);
      }
      /**
      * Get raw content of a specific log file
      * @param filename - The log filename (e.g., "radarr.txt", "sonarr.debug.0.txt")
      * @returns Raw log file content as text
      */
      getLogFileContent(filename) {
        return this.get(`/api/${this.apiVersion}/log/file/${filename}`, { responseType: "text" });
      }
    };
  }
});

// dist/build/server/chunks/sort.js
function sortTitle(title) {
  return (title || "").toLowerCase().replace(/^[^a-z0-9]+/, "").replace(/^(the|a|an)\s+/, "");
}
function dateSortValue(value2) {
  if (!value2) return null;
  const timestamp2 = new Date(value2).getTime();
  return Number.isNaN(timestamp2) ? null : timestamp2;
}
function compareOptionalDates(a2, b3, direction) {
  const aValue = dateSortValue(a2);
  const bValue = dateSortValue(b3);
  if (aValue === null && bValue === null) return 0;
  if (aValue === null) return 1;
  if (bValue === null) return -1;
  return direction === "asc" ? aValue - bValue : bValue - aValue;
}
var init_sort = __esm({
  "dist/build/server/chunks/sort.js"() {
    "use strict";
  }
});

// dist/build/server/chunks/radarr.js
function resolveRadarrInitialReleaseDate(movie) {
  if (dateSortValue(movie.inCinemas) !== null) return movie.inCinemas;
  const digital = dateSortValue(movie.digitalRelease);
  const physical = dateSortValue(movie.physicalRelease);
  if (digital === null && physical === null) return void 0;
  if (digital !== null && physical !== null && digital === physical) return movie.digitalRelease;
  if (digital !== null && (physical === null || digital < physical)) return movie.digitalRelease;
  return movie.physicalRelease;
}
var RadarrClient;
var init_radarr = __esm({
  async "dist/build/server/chunks/radarr.js"() {
    "use strict";
    init_client();
    await init_base();
    init_sort();
    RadarrClient = class extends BaseArrClient {
      /**
      * Get all movies
      */
      getMovies() {
        return this.get(`/api/${this.apiVersion}/movie`);
      }
      /**
      * Get all quality profiles
      */
      getQualityProfiles() {
        return this.get(`/api/${this.apiVersion}/qualityprofile`);
      }
      /**
      * Get movie files by movie IDs
      * Uses movieId params for batching (NOT movieFileIds which can error on stale IDs)
      */
      async getMovieFiles(movieIds) {
        if (movieIds.length === 0) return [];
        const MAX_IDS_PER_REQUEST = 200;
        const fetchBatch = async (ids) => {
          const queryString = ids.map((id) => `movieId=${id}`).join("&");
          try {
            return await this.get(`/api/${this.apiVersion}/moviefile?${queryString}`);
          } catch (error2) {
            if (error2 instanceof HttpError2 && error2.status === 414 && ids.length > 1) {
              const midpoint = Math.ceil(ids.length / 2);
              const [left, right] = await Promise.all([fetchBatch(ids.slice(0, midpoint)), fetchBatch(ids.slice(midpoint))]);
              return [...left, ...right];
            }
            throw error2;
          }
        };
        const files = [];
        for (let i = 0; i < movieIds.length; i += MAX_IDS_PER_REQUEST) {
          const chunkFiles = await fetchBatch(movieIds.slice(i, i + MAX_IDS_PER_REQUEST));
          files.push(...chunkFiles);
        }
        return files;
      }
      /**
      * Fetch and compute library data with all joined information
      * Makes 3 API calls: movies, quality profiles, and movie files (batched)
      * @param profilarrProfileNames - Set of profile names from Profilarr databases
      */
      async getLibrary(profilarrProfileNames) {
        const [movies, profiles] = await Promise.all([this.getMovies(), this.getQualityProfiles()]);
        const profileMap = new Map(profiles.map((p2) => [p2.id, p2]));
        const movieIdsWithFiles = movies.filter((m3) => m3.hasFile).map((m3) => m3.id);
        const movieFiles = await this.getMovieFiles(movieIdsWithFiles);
        const movieFileMap = new Map(movieFiles.map((mf) => [mf.movieId, mf]));
        return movies.map((movie) => {
          const profile = profileMap.get(movie.qualityProfileId);
          const movieFile = movieFileMap.get(movie.id);
          const initialReleaseDate = resolveRadarrInitialReleaseDate(movie);
          const customFormats = movieFile?.customFormats ?? [];
          const customFormatScore = movieFile?.customFormatScore ?? 0;
          const cutoffScore = profile?.cutoffFormatScore ?? 0;
          const minScore = profile?.minFormatScore ?? 0;
          const scoreBreakdown = profile ? this.computeScoreBreakdown(customFormats, profile.formatItems) : [];
          const progress = cutoffScore > 0 ? customFormatScore / cutoffScore : 0;
          const profileName2 = profile?.name ?? "Unknown";
          return {
            id: movie.id,
            tmdbId: movie.tmdbId,
            imdbId: movie.imdbId,
            title: movie.title,
            year: movie.year,
            qualityProfileId: movie.qualityProfileId,
            qualityProfileName: profileName2,
            hasFile: movie.hasFile,
            monitored: movie.monitored ?? false,
            status: movie.status,
            dateAdded: movie.added,
            initialReleaseDate,
            theatricalReleaseDate: movie.inCinemas,
            digitalReleaseDate: movie.digitalRelease,
            physicalReleaseDate: movie.physicalRelease,
            popularity: movie.popularity,
            sizeOnDisk: movie.sizeOnDisk,
            runtime: movie.runtime,
            certification: movie.certification,
            genres: movie.genres,
            studio: movie.studio,
            ratings: movie.ratings,
            images: movie.images,
            collection: movie.collection,
            originalLanguage: movie.originalLanguage,
            customFormats,
            customFormatScore,
            qualityName: movieFile?.quality?.quality?.name,
            fileName: movieFile?.relativePath?.split("/").pop(),
            releaseGroup: movieFile?.releaseGroup,
            edition: movieFile?.edition,
            languages: movieFile?.languages,
            mediaInfo: movieFile?.mediaInfo ? {
              audioCodec: movieFile.mediaInfo.audioCodec,
              audioChannels: movieFile.mediaInfo.audioChannels,
              videoCodec: movieFile.mediaInfo.videoCodec,
              videoBitDepth: movieFile.mediaInfo.videoBitDepth,
              videoDynamicRange: movieFile.mediaInfo.videoDynamicRange,
              videoDynamicRangeType: movieFile.mediaInfo.videoDynamicRangeType,
              resolution: movieFile.mediaInfo.resolution,
              subtitles: movieFile.mediaInfo.subtitles
            } : void 0,
            scoreBreakdown,
            cutoffScore,
            minScore,
            progress,
            cutoffMet: customFormatScore >= cutoffScore,
            isProfilarrProfile: profilarrProfileNames?.has(profileName2) ?? false
          };
        });
      }
      /**
      * Delete a movie from Radarr
      */
      deleteMovie(movieId) {
        return this.delete(`/api/${this.apiVersion}/movie/${movieId}`);
      }
      /**
      * Trigger a search for specific movies
      * Uses the MoviesSearch command endpoint
      */
      searchMovies(movieIds) {
        return this.post(`/api/${this.apiVersion}/command`, {
          name: "MoviesSearch",
          movieIds
        });
      }
      /**
      * Get releases for a movie (interactive search)
      * Queries all configured indexers and returns available releases
      * Note: This can take several seconds as it searches indexers in real-time
      */
      getReleases(movieId) {
        return this.get(`/api/${this.apiVersion}/release?movieId=${movieId}`, { timeout: INTERACTIVE_SEARCH_TIMEOUT_MS });
      }
      /**
      * Get queue items (downloads in progress)
      * @param movieIds - Optional filter by movie IDs
      */
      async getQueue(movieIds) {
        const records = (await this.get(`/api/${this.apiVersion}/queue?page=1&pageSize=200&includeMovie=true`)).records;
        if (movieIds && movieIds.length > 0) {
          const movieIdSet = new Set(movieIds);
          return records.filter((item) => movieIdSet.has(item.movieId));
        }
        return records;
      }
      /**
      * Get all tags
      */
      getTags() {
        return this.get(`/api/${this.apiVersion}/tag`);
      }
      /**
      * Create a new tag
      */
      createTag(label) {
        return this.post(`/api/${this.apiVersion}/tag`, { label });
      }
      /**
      * Get a tag by label, or create it if it doesn't exist
      */
      async getOrCreateTag(label) {
        const existing = (await this.getTags()).find((t2) => t2.label.toLowerCase() === label.toLowerCase());
        if (existing) return existing;
        return this.createTag(label);
      }
      /**
      * Update a movie (used for adding/removing tags)
      */
      updateMovie(movie) {
        return this.put(`/api/${this.apiVersion}/movie/${movie.id}`, movie);
      }
      /**
      * Get rename preview for a movie
      * Shows what files would be renamed without making changes
      */
      getRenamePreview(movieId) {
        return this.get(`/api/${this.apiVersion}/rename?movieId=${movieId}`);
      }
      /**
      * Trigger rename for movies
      * Renames all files that need renaming for the given movie IDs
      */
      renameMovies(movieIds) {
        return this.post(`/api/${this.apiVersion}/command`, {
          name: "RenameMovie",
          movieIds
        });
      }
      /**
      * Refresh movies (update metadata from sources)
      * Required after folder rename to update paths
      */
      refreshMovies(movieIds) {
        return this.post(`/api/${this.apiVersion}/command`, {
          name: "RefreshMovie",
          movieIds
        });
      }
      /**
      * Rename movie folders using the movie editor endpoint
      * Bulk updates movie root folder paths
      */
      renameMovieFolders(movieIds, rootFolderPath) {
        return this.put(`/api/${this.apiVersion}/movie/editor`, {
          movieIds,
          rootFolderPath,
          moveFiles: true
        });
      }
    };
  }
});

// dist/build/server/chunks/sonarr.js
var SonarrClient;
var init_sonarr = __esm({
  async "dist/build/server/chunks/sonarr.js"() {
    "use strict";
    await init_base();
    SonarrClient = class extends BaseArrClient {
      /**
      * Get all series
      */
      getAllSeries() {
        return this.get(`/api/${this.apiVersion}/series`);
      }
      /**
      * Get a specific series by ID
      * Includes season information with statistics
      */
      getSeries(seriesId) {
        return this.get(`/api/${this.apiVersion}/series/${seriesId}`);
      }
      /**
      * Delete a series from Sonarr
      */
      deleteSeries(seriesId) {
        return this.delete(`/api/${this.apiVersion}/series/${seriesId}`);
      }
      /**
      * Get all episodes for a series
      */
      getEpisodes(seriesId) {
        return this.get(`/api/${this.apiVersion}/episode?seriesId=${seriesId}`);
      }
      /**
      * Get all episode files for a series
      */
      getEpisodeFiles(seriesId) {
        return this.get(`/api/${this.apiVersion}/episodefile?seriesId=${seriesId}`);
      }
      /**
      * Get quality profiles (override for proper typing)
      */
      getQualityProfiles() {
        return this.get(`/api/${this.apiVersion}/qualityprofile`);
      }
      /**
      * Fetch and compute library data (series-level, no episode details)
      * Makes 2 API calls: series and quality profiles
      * @param profilarrProfileNames - Set of profile names from Profilarr databases
      */
      async getLibrary(profilarrProfileNames) {
        const [allSeries, profiles] = await Promise.all([this.getAllSeries(), this.getQualityProfiles()]);
        const profileMap = new Map(profiles.map((p2) => [p2.id, p2]));
        return allSeries.map((series) => {
          const profileName2 = profileMap.get(series.qualityProfileId)?.name ?? "Unknown";
          const seasons = series.seasons.map((s3) => ({
            seasonNumber: s3.seasonNumber,
            monitored: s3.monitored,
            episodeCount: s3.statistics?.episodeCount ?? 0,
            episodeFileCount: s3.statistics?.episodeFileCount ?? 0,
            totalEpisodeCount: s3.statistics?.totalEpisodeCount ?? 0,
            sizeOnDisk: s3.statistics?.sizeOnDisk ?? 0,
            percentOfEpisodes: s3.statistics?.percentOfEpisodes ?? 0
          }));
          const releaseGroupSeasons = /* @__PURE__ */ new Map();
          for (const season of series.seasons) for (const group of season.statistics?.releaseGroups ?? []) releaseGroupSeasons.set(group, (releaseGroupSeasons.get(group) ?? 0) + 1);
          for (const group of series.statistics?.releaseGroups ?? []) if (!releaseGroupSeasons.has(group)) releaseGroupSeasons.set(group, 0);
          const releaseGroups = [...releaseGroupSeasons.entries()].sort(([aName, aCount], [bName, bCount]) => bCount - aCount || aName.localeCompare(bName)).map(([group]) => group);
          let monitoredState;
          if (!series.monitored) monitoredState = "unmonitored";
          else {
            const mainSeasons = seasons.filter((s3) => s3.seasonNumber !== 0);
            monitoredState = mainSeasons.length === 0 || mainSeasons.every((s3) => s3.monitored) ? "monitored" : "partial";
          }
          return {
            id: series.id,
            tvdbId: series.tvdbId,
            imdbId: series.imdbId,
            title: series.title,
            titleSlug: series.titleSlug,
            year: series.year,
            qualityProfileId: series.qualityProfileId,
            qualityProfileName: profileName2,
            status: series.status,
            monitored: series.monitored,
            monitoredState,
            seasonCount: series.statistics?.seasonCount ?? series.seasons.length,
            episodeCount: series.statistics?.episodeCount ?? 0,
            episodeFileCount: series.statistics?.episodeFileCount ?? 0,
            totalEpisodeCount: series.statistics?.totalEpisodeCount ?? 0,
            sizeOnDisk: series.statistics?.sizeOnDisk ?? 0,
            percentOfEpisodes: series.statistics?.percentOfEpisodes ?? 0,
            releaseGroups,
            dateAdded: series.added,
            seasons,
            isProfilarrProfile: profilarrProfileNames?.has(profileName2) ?? false,
            network: series.network,
            seriesType: series.seriesType,
            certification: series.certification,
            genres: series.genres,
            runtime: series.runtime,
            ratings: series.ratings,
            images: series.images,
            originalLanguage: series.originalLanguage,
            firstAired: series.firstAired,
            lastAired: series.lastAired,
            previousAiring: series.previousAiring
          };
        });
      }
      /**
      * Fetch episode details for a series (lazy-loaded on expand)
      * Fetches episodes + episode files, joins them, computes scores
      * @param seriesId - The series to fetch episode details for
      * @param profile - The quality profile for score computation
      */
      async getSeriesEpisodeDetails(seriesId, profile) {
        const [episodes, episodeFiles] = await Promise.all([this.getEpisodes(seriesId), this.getEpisodeFiles(seriesId)]);
        const fileMap = new Map(episodeFiles.map((f2) => [f2.id, f2]));
        const cutoffScore = profile.cutoffFormatScore ?? 0;
        return episodes.map((ep) => {
          const file = ep.episodeFileId ? fileMap.get(ep.episodeFileId) : void 0;
          const customFormats = file?.customFormats ?? [];
          const customFormatScore = file?.customFormatScore ?? 0;
          const scoreBreakdown = file ? this.computeScoreBreakdown(customFormats, profile.formatItems) : [];
          const progress = cutoffScore > 0 ? customFormatScore / cutoffScore : 0;
          return {
            id: ep.id,
            episodeNumber: ep.episodeNumber,
            seasonNumber: ep.seasonNumber,
            title: ep.title,
            hasFile: ep.hasFile,
            monitored: ep.monitored,
            qualityName: file?.quality?.quality?.name,
            fileName: file?.relativePath?.split("/").pop(),
            size: file?.size,
            customFormats,
            customFormatScore,
            scoreBreakdown,
            cutoffScore,
            progress,
            cutoffMet: file ? !file.qualityCutoffNotMet : false,
            releaseGroup: file?.releaseGroup,
            languages: file?.languages,
            mediaInfo: file?.mediaInfo ? {
              audioCodec: file.mediaInfo.audioCodec,
              audioChannels: file.mediaInfo.audioChannels,
              videoCodec: file.mediaInfo.videoCodec,
              videoBitDepth: file.mediaInfo.videoBitDepth,
              videoDynamicRange: file.mediaInfo.videoDynamicRange,
              videoDynamicRangeType: file.mediaInfo.videoDynamicRangeType,
              resolution: file.mediaInfo.resolution,
              subtitles: file.mediaInfo.subtitles
            } : void 0
          };
        });
      }
      /**
      * Trigger a search for a specific series
      * Sonarr searches one series at a time (not batched like Radarr)
      */
      searchSeries(seriesId) {
        return this.post(`/api/${this.apiVersion}/command`, {
          name: "SeriesSearch",
          seriesId
        });
      }
      /**
      * Get queue items (downloads in progress)
      * Returns one record per episode, even for season packs
      * @param seriesIds - Optional filter by series IDs
      */
      async getQueue(seriesIds) {
        const records = (await this.get(`/api/${this.apiVersion}/queue?page=1&pageSize=200&includeSeries=true`)).records;
        if (seriesIds && seriesIds.length > 0) {
          const seriesIdSet = new Set(seriesIds);
          return records.filter((item) => seriesIdSet.has(item.seriesId));
        }
        return records;
      }
      /**
      * Update a series (used for adding/removing tags)
      */
      updateSeries(series) {
        return this.put(`/api/${this.apiVersion}/series/${series.id}`, series);
      }
      /**
      * Bulk add a tag to multiple series via the series editor endpoint
      */
      applyTagToSeries(seriesIds, tagId) {
        return this.put(`/api/${this.apiVersion}/series/editor`, {
          seriesIds,
          tags: [tagId],
          applyTags: "add"
        });
      }
      /**
      * Bulk remove a tag from multiple series via the series editor endpoint
      */
      removeTagFromSeries(seriesIds, tagId) {
        return this.put(`/api/${this.apiVersion}/series/editor`, {
          seriesIds,
          tags: [tagId],
          applyTags: "remove"
        });
      }
      /**
      * Get all tags
      */
      getTags() {
        return this.get(`/api/${this.apiVersion}/tag`);
      }
      /**
      * Create a new tag
      */
      createTag(label) {
        return this.post(`/api/${this.apiVersion}/tag`, { label });
      }
      /**
      * Get a tag by label, or create it if it doesn't exist
      */
      async getOrCreateTag(label) {
        const existing = (await this.getTags()).find((t2) => t2.label.toLowerCase() === label.toLowerCase());
        if (existing) return existing;
        return this.createTag(label);
      }
      /**
      * Get releases for a series/season (interactive search)
      * Queries all configured indexers and returns available releases
      * Note: This can take several seconds as it searches indexers in real-time
      *
      * @param seriesId - The series ID
      * @param seasonNumber - The season number to search
      * @returns Array of releases from indexers
      */
      getReleases(seriesId, seasonNumber) {
        return this.get(`/api/${this.apiVersion}/release?seriesId=${seriesId}&seasonNumber=${seasonNumber}`, { timeout: INTERACTIVE_SEARCH_TIMEOUT_MS });
      }
      /**
      * Get only season pack releases (fullSeason: true)
      * Filters out individual episode releases
      */
      async getSeasonPackReleases(seriesId, seasonNumber) {
        return (await this.getReleases(seriesId, seasonNumber)).filter((r2) => r2.fullSeason);
      }
      /**
      * Get rename preview for a series
      * Shows what files would be renamed without making changes
      */
      getRenamePreview(seriesId) {
        return this.get(`/api/${this.apiVersion}/rename?seriesId=${seriesId}`);
      }
      /**
      * Trigger rename for series
      * Renames all files that need renaming for the given series IDs
      */
      renameSeries(seriesIds) {
        return this.post(`/api/${this.apiVersion}/command`, {
          name: "RenameSeries",
          seriesIds
        });
      }
      /**
      * Refresh series (update metadata from sources)
      * Required after folder rename to update paths
      */
      refreshSeries(seriesIds) {
        return this.post(`/api/${this.apiVersion}/command`, {
          name: "RefreshSeries",
          seriesIds
        });
      }
      /**
      * Rename series folders using the series editor endpoint
      * Bulk updates series root folder paths
      */
      renameSeriesFolders(seriesIds, rootFolderPath) {
        return this.put(`/api/${this.apiVersion}/series/editor`, {
          seriesIds,
          rootFolderPath,
          moveFiles: true
        });
      }
    };
  }
});

// dist/build/server/chunks/uuid.js
function uuid() {
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c2) => {
    const r2 = Math.random() * 16 | 0;
    return (c2 === "x" ? r2 : r2 & 3 | 8).toString(16);
  });
}
var init_uuid = __esm({
  "dist/build/server/chunks/uuid.js"() {
    "use strict";
  }
});

// node_modules/.deno/croner@10.0.1/node_modules/croner/dist/croner.js
function T(s3) {
  return Date.UTC(s3.y, s3.m - 1, s3.d, s3.h, s3.i, s3.s);
}
function D(s3, e) {
  return s3.y === e.y && s3.m === e.m && s3.d === e.d && s3.h === e.h && s3.i === e.i && s3.s === e.s;
}
function A(s3, e) {
  let t2 = new Date(Date.parse(s3));
  if (isNaN(t2)) throw new Error("Invalid ISO8601 passed to timezone parser.");
  let r2 = s3.substring(9);
  return r2.includes("Z") || r2.includes("+") || r2.includes("-") ? b(t2.getUTCFullYear(), t2.getUTCMonth() + 1, t2.getUTCDate(), t2.getUTCHours(), t2.getUTCMinutes(), t2.getUTCSeconds(), "Etc/UTC") : b(t2.getFullYear(), t2.getMonth() + 1, t2.getDate(), t2.getHours(), t2.getMinutes(), t2.getSeconds(), e);
}
function v(s3, e, t2) {
  return k(A(s3, e), t2);
}
function k(s3, e) {
  let t2 = new Date(T(s3)), r2 = g(t2, s3.tz), n = T(s3), i = T(r2), a2 = n - i, o = new Date(t2.getTime() + a2), h = g(o, s3.tz);
  if (D(h, s3)) {
    let u = new Date(o.getTime() - 36e5), d2 = g(u, s3.tz);
    return D(d2, s3) ? u : o;
  }
  let l3 = new Date(o.getTime() + T(s3) - T(h)), y2 = g(l3, s3.tz);
  if (D(y2, s3)) return l3;
  if (e) throw new Error("Invalid date passed to fromTZ()");
  return o.getTime() > l3.getTime() ? o : l3;
}
function g(s3, e) {
  let t2, r2;
  try {
    t2 = new Intl.DateTimeFormat("en-US", { timeZone: e, year: "numeric", month: "numeric", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric", hour12: false }), r2 = t2.formatToParts(s3);
  } catch (i) {
    let a2 = i instanceof Error ? i.message : String(i);
    throw new RangeError(`toTZ: Invalid timezone '${e}' or date. Please provide a valid IANA timezone (e.g., 'America/New_York', 'Europe/Stockholm'). Original error: ${a2}`);
  }
  let n = { year: 0, month: 0, day: 0, hour: 0, minute: 0, second: 0 };
  for (let i of r2) (i.type === "year" || i.type === "month" || i.type === "day" || i.type === "hour" || i.type === "minute" || i.type === "second") && (n[i.type] = parseInt(i.value, 10));
  if (isNaN(n.year) || isNaN(n.month) || isNaN(n.day) || isNaN(n.hour) || isNaN(n.minute) || isNaN(n.second)) throw new Error(`toTZ: Failed to parse all date components from timezone '${e}'. This may indicate an invalid date or timezone configuration. Parsed components: ${JSON.stringify(n)}`);
  return n.hour === 24 && (n.hour = 0), { y: n.year, m: n.month, d: n.day, h: n.hour, i: n.minute, s: n.second, tz: e };
}
function b(s3, e, t2, r2, n, i, a2) {
  return { y: s3, m: e, d: t2, h: r2, i: n, s: i, tz: a2 };
}
function R(s3) {
  if (s3 === void 0 && (s3 = {}), delete s3.name, s3.legacyMode !== void 0 && s3.domAndDow === void 0 ? s3.domAndDow = !s3.legacyMode : s3.domAndDow === void 0 && (s3.domAndDow = false), s3.legacyMode = !s3.domAndDow, s3.paused = s3.paused === void 0 ? false : s3.paused, s3.maxRuns = s3.maxRuns === void 0 ? 1 / 0 : s3.maxRuns, s3.catch = s3.catch === void 0 ? false : s3.catch, s3.interval = s3.interval === void 0 ? 0 : parseInt(s3.interval.toString(), 10), s3.utcOffset = s3.utcOffset === void 0 ? void 0 : parseInt(s3.utcOffset.toString(), 10), s3.dayOffset = s3.dayOffset === void 0 ? 0 : parseInt(s3.dayOffset.toString(), 10), s3.unref = s3.unref === void 0 ? false : s3.unref, s3.mode = s3.mode === void 0 ? "auto" : s3.mode, s3.alternativeWeekdays = s3.alternativeWeekdays === void 0 ? false : s3.alternativeWeekdays, s3.sloppyRanges = s3.sloppyRanges === void 0 ? false : s3.sloppyRanges, !["auto", "5-part", "6-part", "7-part", "5-or-6-parts", "6-or-7-parts"].includes(s3.mode)) throw new Error("CronOptions: mode must be one of 'auto', '5-part', '6-part', '7-part', '5-or-6-parts', or '6-or-7-parts'.");
  if (s3.startAt && (s3.startAt = new m(s3.startAt, s3.timezone)), s3.stopAt && (s3.stopAt = new m(s3.stopAt, s3.timezone)), s3.interval !== null) {
    if (isNaN(s3.interval)) throw new Error("CronOptions: Supplied value for interval is not a number");
    if (s3.interval < 0) throw new Error("CronOptions: Supplied value for interval can not be negative");
  }
  if (s3.utcOffset !== void 0) {
    if (isNaN(s3.utcOffset)) throw new Error("CronOptions: Invalid value passed for utcOffset, should be number representing minutes offset from UTC.");
    if (s3.utcOffset < -870 || s3.utcOffset > 870) throw new Error("CronOptions: utcOffset out of bounds.");
    if (s3.utcOffset !== void 0 && s3.timezone) throw new Error("CronOptions: Combining 'utcOffset' with 'timezone' is not allowed.");
  }
  if (s3.unref !== true && s3.unref !== false) throw new Error("CronOptions: Unref should be either true, false or undefined(false).");
  if (s3.dayOffset !== void 0 && s3.dayOffset !== 0 && isNaN(s3.dayOffset)) throw new Error("CronOptions: Invalid value passed for dayOffset, should be a number representing days to offset.");
  return s3;
}
function p(s3) {
  return Object.prototype.toString.call(s3) === "[object Function]" || typeof s3 == "function" || s3 instanceof Function;
}
function _(s3) {
  return p(s3);
}
function x(s3) {
  typeof Deno < "u" && typeof Deno.unrefTimer < "u" ? Deno.unrefTimer(s3) : s3 && typeof s3.unref < "u" && s3.unref();
}
var O, C, P, f, m, W, w, E;
var init_croner = __esm({
  "node_modules/.deno/croner@10.0.1/node_modules/croner/dist/croner.js"() {
    O = [1, 2, 4, 8, 16];
    C = class {
      pattern;
      timezone;
      mode;
      alternativeWeekdays;
      sloppyRanges;
      second;
      minute;
      hour;
      day;
      month;
      dayOfWeek;
      year;
      lastDayOfMonth;
      lastWeekday;
      nearestWeekdays;
      starDOM;
      starDOW;
      starYear;
      useAndLogic;
      constructor(e, t2, r2) {
        this.pattern = e, this.timezone = t2, this.mode = r2?.mode ?? "auto", this.alternativeWeekdays = r2?.alternativeWeekdays ?? false, this.sloppyRanges = r2?.sloppyRanges ?? false, this.second = Array(60).fill(0), this.minute = Array(60).fill(0), this.hour = Array(24).fill(0), this.day = Array(31).fill(0), this.month = Array(12).fill(0), this.dayOfWeek = Array(7).fill(0), this.year = Array(1e4).fill(0), this.lastDayOfMonth = false, this.lastWeekday = false, this.nearestWeekdays = Array(31).fill(0), this.starDOM = false, this.starDOW = false, this.starYear = false, this.useAndLogic = false, this.parse();
      }
      parse() {
        if (!(typeof this.pattern == "string" || this.pattern instanceof String)) throw new TypeError("CronPattern: Pattern has to be of type string.");
        this.pattern.indexOf("@") >= 0 && (this.pattern = this.handleNicknames(this.pattern).trim());
        let e = this.pattern.match(/\S+/g) || [""], t2 = e.length;
        if (e.length < 5 || e.length > 7) throw new TypeError("CronPattern: invalid configuration format ('" + this.pattern + "'), exactly five, six, or seven space separated parts are required.");
        if (this.mode !== "auto") {
          let n;
          switch (this.mode) {
            case "5-part":
              n = 5;
              break;
            case "6-part":
              n = 6;
              break;
            case "7-part":
              n = 7;
              break;
            case "5-or-6-parts":
              n = [5, 6];
              break;
            case "6-or-7-parts":
              n = [6, 7];
              break;
            default:
              n = 0;
          }
          if (!(Array.isArray(n) ? n.includes(t2) : t2 === n)) {
            let a2 = Array.isArray(n) ? n.join(" or ") : n.toString();
            throw new TypeError(`CronPattern: mode '${this.mode}' requires exactly ${a2} parts, but pattern '${this.pattern}' has ${t2} parts.`);
          }
        }
        if (e.length === 5 && e.unshift("0"), e.length === 6 && e.push("*"), e[3].toUpperCase() === "LW" ? (this.lastWeekday = true, e[3] = "") : e[3].toUpperCase().indexOf("L") >= 0 && (e[3] = e[3].replace(/L/gi, ""), this.lastDayOfMonth = true), e[3] == "*" && (this.starDOM = true), e[6] == "*" && (this.starYear = true), e[4].length >= 3 && (e[4] = this.replaceAlphaMonths(e[4])), e[5].length >= 3 && (e[5] = this.alternativeWeekdays ? this.replaceAlphaDaysQuartz(e[5]) : this.replaceAlphaDays(e[5])), e[5].startsWith("+") && (this.useAndLogic = true, e[5] = e[5].substring(1), e[5] === "")) throw new TypeError("CronPattern: Day-of-week field cannot be empty after '+' modifier.");
        switch (e[5] == "*" && (this.starDOW = true), this.pattern.indexOf("?") >= 0 && (e[0] = e[0].replace(/\?/g, "*"), e[1] = e[1].replace(/\?/g, "*"), e[2] = e[2].replace(/\?/g, "*"), e[3] = e[3].replace(/\?/g, "*"), e[4] = e[4].replace(/\?/g, "*"), e[5] = e[5].replace(/\?/g, "*"), e[6] && (e[6] = e[6].replace(/\?/g, "*"))), this.mode) {
          case "5-part":
            e[0] = "0", e[6] = "*";
            break;
          case "6-part":
            e[6] = "*";
            break;
          case "5-or-6-parts":
            e[6] = "*";
            break;
          case "6-or-7-parts":
            break;
          case "7-part":
          case "auto":
            break;
        }
        this.throwAtIllegalCharacters(e), this.partToArray("second", e[0], 0, 1), this.partToArray("minute", e[1], 0, 1), this.partToArray("hour", e[2], 0, 1), this.partToArray("day", e[3], -1, 1), this.partToArray("month", e[4], -1, 1);
        let r2 = this.alternativeWeekdays ? -1 : 0;
        this.partToArray("dayOfWeek", e[5], r2, 63), this.partToArray("year", e[6], 0, 1), !this.alternativeWeekdays && this.dayOfWeek[7] && (this.dayOfWeek[0] = this.dayOfWeek[7]);
      }
      partToArray(e, t2, r2, n) {
        let i = this[e], a2 = e === "day" && this.lastDayOfMonth, o = e === "day" && this.lastWeekday;
        if (t2 === "" && !a2 && !o) throw new TypeError("CronPattern: configuration entry " + e + " (" + t2 + ") is empty, check for trailing spaces.");
        if (t2 === "*") return i.fill(n);
        let h = t2.split(",");
        if (h.length > 1) for (let l3 = 0; l3 < h.length; l3++) this.partToArray(e, h[l3], r2, n);
        else t2.indexOf("-") !== -1 && t2.indexOf("/") !== -1 ? this.handleRangeWithStepping(t2, e, r2, n) : t2.indexOf("-") !== -1 ? this.handleRange(t2, e, r2, n) : t2.indexOf("/") !== -1 ? this.handleStepping(t2, e, r2, n) : t2 !== "" && this.handleNumber(t2, e, r2, n);
      }
      throwAtIllegalCharacters(e) {
        for (let t2 = 0; t2 < e.length; t2++) if ((t2 === 3 ? /[^/*0-9,\-WwLl]+/ : t2 === 5 ? /[^/*0-9,\-#Ll]+/ : /[^/*0-9,\-]+/).test(e[t2])) throw new TypeError("CronPattern: configuration entry " + t2 + " (" + e[t2] + ") contains illegal characters.");
      }
      handleNumber(e, t2, r2, n) {
        let i = this.extractNth(e, t2), a2 = e.toUpperCase().includes("W");
        if (t2 !== "day" && a2) throw new TypeError("CronPattern: Nearest weekday modifier (W) only allowed in day-of-month.");
        a2 && (t2 = "nearestWeekdays");
        let o = parseInt(i[0], 10) + r2;
        if (isNaN(o)) throw new TypeError("CronPattern: " + t2 + " is not a number: '" + e + "'");
        this.setPart(t2, o, i[1] || n);
      }
      setPart(e, t2, r2) {
        if (!Object.prototype.hasOwnProperty.call(this, e)) throw new TypeError("CronPattern: Invalid part specified: " + e);
        if (e === "dayOfWeek") {
          if (t2 === 7 && (t2 = 0), t2 < 0 || t2 > 6) throw new RangeError("CronPattern: Invalid value for dayOfWeek: " + t2);
          this.setNthWeekdayOfMonth(t2, r2);
          return;
        }
        if (e === "second" || e === "minute") {
          if (t2 < 0 || t2 >= 60) throw new RangeError("CronPattern: Invalid value for " + e + ": " + t2);
        } else if (e === "hour") {
          if (t2 < 0 || t2 >= 24) throw new RangeError("CronPattern: Invalid value for " + e + ": " + t2);
        } else if (e === "day" || e === "nearestWeekdays") {
          if (t2 < 0 || t2 >= 31) throw new RangeError("CronPattern: Invalid value for " + e + ": " + t2);
        } else if (e === "month") {
          if (t2 < 0 || t2 >= 12) throw new RangeError("CronPattern: Invalid value for " + e + ": " + t2);
        } else if (e === "year" && (t2 < 1 || t2 >= 1e4)) throw new RangeError("CronPattern: Invalid value for " + e + ": " + t2 + " (supported range: 1-9999)");
        this[e][t2] = r2;
      }
      validateNotNaN(e, t2) {
        if (isNaN(e)) throw new TypeError(t2);
      }
      validateRange(e, t2, r2, n, i) {
        if (e > t2) throw new TypeError("CronPattern: From value is larger than to value: '" + i + "'");
        if (r2 !== void 0) {
          if (r2 === 0) throw new TypeError("CronPattern: Syntax error, illegal stepping: 0");
          if (r2 > this[n].length) throw new TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part (" + this[n].length + ")");
        }
      }
      handleRangeWithStepping(e, t2, r2, n) {
        if (e.toUpperCase().includes("W")) throw new TypeError("CronPattern: Syntax error, W is not allowed in ranges with stepping.");
        let i = this.extractNth(e, t2), a2 = i[0].match(/^(\d+)-(\d+)\/(\d+)$/);
        if (a2 === null) throw new TypeError("CronPattern: Syntax error, illegal range with stepping: '" + e + "'");
        let [, o, h, l3] = a2, y2 = parseInt(o, 10) + r2, u = parseInt(h, 10) + r2, d2 = parseInt(l3, 10);
        this.validateNotNaN(y2, "CronPattern: Syntax error, illegal lower range (NaN)"), this.validateNotNaN(u, "CronPattern: Syntax error, illegal upper range (NaN)"), this.validateNotNaN(d2, "CronPattern: Syntax error, illegal stepping: (NaN)"), this.validateRange(y2, u, d2, t2, e);
        for (let c2 = y2; c2 <= u; c2 += d2) this.setPart(t2, c2, i[1] || n);
      }
      extractNth(e, t2) {
        let r2 = e, n;
        if (r2.includes("#")) {
          if (t2 !== "dayOfWeek") throw new Error("CronPattern: nth (#) only allowed in day-of-week field");
          n = r2.split("#")[1], r2 = r2.split("#")[0];
        } else if (r2.toUpperCase().endsWith("L")) {
          if (t2 !== "dayOfWeek") throw new Error("CronPattern: L modifier only allowed in day-of-week field (use L alone for day-of-month)");
          n = "L", r2 = r2.slice(0, -1);
        }
        return [r2, n];
      }
      handleRange(e, t2, r2, n) {
        if (e.toUpperCase().includes("W")) throw new TypeError("CronPattern: Syntax error, W is not allowed in a range.");
        let i = this.extractNth(e, t2), a2 = i[0].split("-");
        if (a2.length !== 2) throw new TypeError("CronPattern: Syntax error, illegal range: '" + e + "'");
        let o = parseInt(a2[0], 10) + r2, h = parseInt(a2[1], 10) + r2;
        this.validateNotNaN(o, "CronPattern: Syntax error, illegal lower range (NaN)"), this.validateNotNaN(h, "CronPattern: Syntax error, illegal upper range (NaN)"), this.validateRange(o, h, void 0, t2, e);
        for (let l3 = o; l3 <= h; l3++) this.setPart(t2, l3, i[1] || n);
      }
      handleStepping(e, t2, r2, n) {
        if (e.toUpperCase().includes("W")) throw new TypeError("CronPattern: Syntax error, W is not allowed in parts with stepping.");
        let i = this.extractNth(e, t2), a2 = i[0].split("/");
        if (a2.length !== 2) throw new TypeError("CronPattern: Syntax error, illegal stepping: '" + e + "'");
        if (this.sloppyRanges) a2[0] === "" && (a2[0] = "*");
        else {
          if (a2[0] === "") throw new TypeError("CronPattern: Syntax error, stepping with missing prefix ('" + e + "') is not allowed. Use wildcard (*/step) or range (min-max/step) instead.");
          if (a2[0] !== "*") throw new TypeError("CronPattern: Syntax error, stepping with numeric prefix ('" + e + "') is not allowed. Use wildcard (*/step) or range (min-max/step) instead.");
        }
        let o = 0;
        a2[0] !== "*" && (o = parseInt(a2[0], 10) + r2);
        let h = parseInt(a2[1], 10);
        this.validateNotNaN(h, "CronPattern: Syntax error, illegal stepping: (NaN)"), this.validateRange(0, this[t2].length - 1, h, t2, e);
        for (let l3 = o; l3 < this[t2].length; l3 += h) this.setPart(t2, l3, i[1] || n);
      }
      replaceAlphaDays(e) {
        return e.replace(/-sun/gi, "-7").replace(/sun/gi, "0").replace(/mon/gi, "1").replace(/tue/gi, "2").replace(/wed/gi, "3").replace(/thu/gi, "4").replace(/fri/gi, "5").replace(/sat/gi, "6");
      }
      replaceAlphaDaysQuartz(e) {
        return e.replace(/sun/gi, "1").replace(/mon/gi, "2").replace(/tue/gi, "3").replace(/wed/gi, "4").replace(/thu/gi, "5").replace(/fri/gi, "6").replace(/sat/gi, "7");
      }
      replaceAlphaMonths(e) {
        return e.replace(/jan/gi, "1").replace(/feb/gi, "2").replace(/mar/gi, "3").replace(/apr/gi, "4").replace(/may/gi, "5").replace(/jun/gi, "6").replace(/jul/gi, "7").replace(/aug/gi, "8").replace(/sep/gi, "9").replace(/oct/gi, "10").replace(/nov/gi, "11").replace(/dec/gi, "12");
      }
      handleNicknames(e) {
        let t2 = e.trim().toLowerCase();
        if (t2 === "@yearly" || t2 === "@annually") return "0 0 1 1 *";
        if (t2 === "@monthly") return "0 0 1 * *";
        if (t2 === "@weekly") return "0 0 * * 0";
        if (t2 === "@daily" || t2 === "@midnight") return "0 0 * * *";
        if (t2 === "@hourly") return "0 * * * *";
        if (t2 === "@reboot") throw new TypeError("CronPattern: @reboot is not supported in this environment. This is an event-based trigger that requires system startup detection.");
        return e;
      }
      setNthWeekdayOfMonth(e, t2) {
        if (typeof t2 != "number" && t2.toUpperCase() === "L") this.dayOfWeek[e] = this.dayOfWeek[e] | 32;
        else if (t2 === 63) this.dayOfWeek[e] = 63;
        else if (t2 < 6 && t2 > 0) this.dayOfWeek[e] = this.dayOfWeek[e] | O[t2 - 1];
        else throw new TypeError(`CronPattern: nth weekday out of range, should be 1-5 or L. Value: ${t2}, Type: ${typeof t2}`);
      }
    };
    P = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    f = [["month", "year", 0], ["day", "month", -1], ["hour", "day", 0], ["minute", "hour", 0], ["second", "minute", 0]];
    m = class s {
      tz;
      ms;
      second;
      minute;
      hour;
      day;
      month;
      year;
      constructor(e, t2) {
        if (this.tz = t2, e && e instanceof Date) if (!isNaN(e)) this.fromDate(e);
        else throw new TypeError("CronDate: Invalid date passed to CronDate constructor");
        else if (e == null) this.fromDate(/* @__PURE__ */ new Date());
        else if (e && typeof e == "string") this.fromString(e);
        else if (e instanceof s) this.fromCronDate(e);
        else throw new TypeError("CronDate: Invalid type (" + typeof e + ") passed to CronDate constructor");
      }
      getLastDayOfMonth(e, t2) {
        return t2 !== 1 ? P[t2] : new Date(Date.UTC(e, t2 + 1, 0)).getUTCDate();
      }
      getLastWeekday(e, t2) {
        let r2 = this.getLastDayOfMonth(e, t2), i = new Date(Date.UTC(e, t2, r2)).getUTCDay();
        return i === 0 ? r2 - 2 : i === 6 ? r2 - 1 : r2;
      }
      getNearestWeekday(e, t2, r2) {
        let n = this.getLastDayOfMonth(e, t2);
        if (r2 > n) return -1;
        let a2 = new Date(Date.UTC(e, t2, r2)).getUTCDay();
        return a2 === 0 ? r2 === n ? r2 - 2 : r2 + 1 : a2 === 6 ? r2 === 1 ? r2 + 2 : r2 - 1 : r2;
      }
      isNthWeekdayOfMonth(e, t2, r2, n) {
        let a2 = new Date(Date.UTC(e, t2, r2)).getUTCDay(), o = 0;
        for (let h = 1; h <= r2; h++) new Date(Date.UTC(e, t2, h)).getUTCDay() === a2 && o++;
        if (n & 63 && O[o - 1] & n) return true;
        if (n & 32) {
          let h = this.getLastDayOfMonth(e, t2);
          for (let l3 = r2 + 1; l3 <= h; l3++) if (new Date(Date.UTC(e, t2, l3)).getUTCDay() === a2) return false;
          return true;
        }
        return false;
      }
      fromDate(e) {
        if (this.tz !== void 0) if (typeof this.tz == "number") this.ms = e.getUTCMilliseconds(), this.second = e.getUTCSeconds(), this.minute = e.getUTCMinutes() + this.tz, this.hour = e.getUTCHours(), this.day = e.getUTCDate(), this.month = e.getUTCMonth(), this.year = e.getUTCFullYear(), this.apply();
        else try {
          let t2 = g(e, this.tz);
          this.ms = e.getMilliseconds(), this.second = t2.s, this.minute = t2.i, this.hour = t2.h, this.day = t2.d, this.month = t2.m - 1, this.year = t2.y;
        } catch (t2) {
          let r2 = t2 instanceof Error ? t2.message : String(t2);
          throw new TypeError(`CronDate: Failed to convert date to timezone '${this.tz}'. This may happen with invalid timezone names or dates. Original error: ${r2}`);
        }
        else this.ms = e.getMilliseconds(), this.second = e.getSeconds(), this.minute = e.getMinutes(), this.hour = e.getHours(), this.day = e.getDate(), this.month = e.getMonth(), this.year = e.getFullYear();
      }
      fromCronDate(e) {
        this.tz = e.tz, this.year = e.year, this.month = e.month, this.day = e.day, this.hour = e.hour, this.minute = e.minute, this.second = e.second, this.ms = e.ms;
      }
      apply() {
        if (this.month > 11 || this.month < 0 || this.day > P[this.month] || this.day < 1 || this.hour > 59 || this.minute > 59 || this.second > 59 || this.hour < 0 || this.minute < 0 || this.second < 0) {
          let e = new Date(Date.UTC(this.year, this.month, this.day, this.hour, this.minute, this.second, this.ms));
          return this.ms = e.getUTCMilliseconds(), this.second = e.getUTCSeconds(), this.minute = e.getUTCMinutes(), this.hour = e.getUTCHours(), this.day = e.getUTCDate(), this.month = e.getUTCMonth(), this.year = e.getUTCFullYear(), true;
        } else return false;
      }
      fromString(e) {
        if (typeof this.tz == "number") {
          let t2 = v(e);
          this.ms = t2.getUTCMilliseconds(), this.second = t2.getUTCSeconds(), this.minute = t2.getUTCMinutes(), this.hour = t2.getUTCHours(), this.day = t2.getUTCDate(), this.month = t2.getUTCMonth(), this.year = t2.getUTCFullYear(), this.apply();
        } else return this.fromDate(v(e, this.tz));
      }
      findNext(e, t2, r2, n) {
        return this._findMatch(e, t2, r2, n, 1);
      }
      _findMatch(e, t2, r2, n, i) {
        let a2 = this[t2], o;
        r2.lastDayOfMonth && (o = this.getLastDayOfMonth(this.year, this.month));
        let h = !r2.starDOW && t2 == "day" ? new Date(Date.UTC(this.year, this.month, 1, 0, 0, 0, 0)).getUTCDay() : void 0, l3 = this[t2] + n, y2 = i === 1 ? (u) => u < r2[t2].length : (u) => u >= 0;
        for (let u = l3; y2(u); u += i) {
          let d2 = r2[t2][u];
          if (t2 === "day" && !d2) {
            for (let c2 = 0; c2 < r2.nearestWeekdays.length; c2++) if (r2.nearestWeekdays[c2]) {
              let M2 = this.getNearestWeekday(this.year, this.month, c2 - n);
              if (M2 === -1) continue;
              if (M2 === u - n) {
                d2 = 1;
                break;
              }
            }
          }
          if (t2 === "day" && r2.lastWeekday) {
            let c2 = this.getLastWeekday(this.year, this.month);
            u - n === c2 && (d2 = 1);
          }
          if (t2 === "day" && r2.lastDayOfMonth && u - n == o && (d2 = 1), t2 === "day" && !r2.starDOW) {
            let c2 = r2.dayOfWeek[(h + (u - n - 1)) % 7];
            if (c2 && c2 & 63) c2 = this.isNthWeekdayOfMonth(this.year, this.month, u - n, c2) ? 1 : 0;
            else if (c2) throw new Error(`CronDate: Invalid value for dayOfWeek encountered. ${c2}`);
            r2.useAndLogic ? d2 = d2 && c2 : !e.domAndDow && !r2.starDOM ? d2 = d2 || c2 : d2 = d2 && c2;
          }
          if (d2) return this[t2] = u - n, a2 !== this[t2] ? 2 : 1;
        }
        return 3;
      }
      recurse(e, t2, r2) {
        if (r2 === 0 && !e.starYear) {
          if (this.year >= 0 && this.year < e.year.length && e.year[this.year] === 0) {
            let i = -1;
            for (let a2 = this.year + 1; a2 < e.year.length && a2 < 1e4; a2++) if (e.year[a2] === 1) {
              i = a2;
              break;
            }
            if (i === -1) return null;
            this.year = i, this.month = 0, this.day = 1, this.hour = 0, this.minute = 0, this.second = 0, this.ms = 0;
          }
          if (this.year >= 1e4) return null;
        }
        let n = this.findNext(t2, f[r2][0], e, f[r2][2]);
        if (n > 1) {
          let i = r2 + 1;
          for (; i < f.length; ) this[f[i][0]] = -f[i][2], i++;
          if (n === 3) {
            if (this[f[r2][1]]++, this[f[r2][0]] = -f[r2][2], this.apply(), r2 === 0 && !e.starYear) {
              for (; this.year >= 0 && this.year < e.year.length && e.year[this.year] === 0 && this.year < 1e4; ) this.year++;
              if (this.year >= 1e4 || this.year >= e.year.length) return null;
            }
            return this.recurse(e, t2, 0);
          } else if (this.apply()) return this.recurse(e, t2, r2 - 1);
        }
        return r2 += 1, r2 >= f.length ? this : (e.starYear ? this.year >= 3e3 : this.year >= 1e4) ? null : this.recurse(e, t2, r2);
      }
      increment(e, t2, r2) {
        return this.second += t2.interval !== void 0 && t2.interval > 1 && r2 ? t2.interval : 1, this.ms = 0, this.apply(), this.recurse(e, t2, 0);
      }
      decrement(e, t2) {
        return this.second -= t2.interval !== void 0 && t2.interval > 1 ? t2.interval : 1, this.ms = 0, this.apply(), this.recurseBackward(e, t2, 0, 0);
      }
      recurseBackward(e, t2, r2, n = 0) {
        if (n > 1e4) return null;
        if (r2 === 0 && !e.starYear) {
          if (this.year >= 0 && this.year < e.year.length && e.year[this.year] === 0) {
            let a2 = -1;
            for (let o = this.year - 1; o >= 0; o--) if (e.year[o] === 1) {
              a2 = o;
              break;
            }
            if (a2 === -1) return null;
            this.year = a2, this.month = 11, this.day = 31, this.hour = 23, this.minute = 59, this.second = 59, this.ms = 0;
          }
          if (this.year < 0) return null;
        }
        let i = this.findPrevious(t2, f[r2][0], e, f[r2][2]);
        if (i > 1) {
          let a2 = r2 + 1;
          for (; a2 < f.length; ) {
            let o = f[a2][0], h = f[a2][2], l3 = this.getMaxPatternValue(o, e, h);
            this[o] = l3, a2++;
          }
          if (i === 3) {
            if (this[f[r2][1]]--, r2 === 0) {
              let y2 = this.getLastDayOfMonth(this.year, this.month);
              this.day > y2 && (this.day = y2);
            }
            if (r2 === 1) if (this.day <= 0) this.day = 1;
            else {
              let y2 = this.year, u = this.month;
              for (; u < 0; ) u += 12, y2--;
              for (; u > 11; ) u -= 12, y2++;
              let d2 = u !== 1 ? P[u] : new Date(Date.UTC(y2, u + 1, 0)).getUTCDate();
              this.day > d2 && (this.day = d2);
            }
            this.apply();
            let o = f[r2][0], h = f[r2][2], l3 = this.getMaxPatternValue(o, e, h);
            if (o === "day") {
              let y2 = this.getLastDayOfMonth(this.year, this.month);
              this[o] = Math.min(l3, y2);
            } else this[o] = l3;
            if (this.apply(), r2 === 0) {
              let y2 = f[1][2], u = this.getMaxPatternValue("day", e, y2), d2 = this.getLastDayOfMonth(this.year, this.month), c2 = Math.min(u, d2);
              c2 !== this.day && (this.day = c2, this.hour = this.getMaxPatternValue("hour", e, f[2][2]), this.minute = this.getMaxPatternValue("minute", e, f[3][2]), this.second = this.getMaxPatternValue("second", e, f[4][2]));
            }
            if (r2 === 0 && !e.starYear) {
              for (; this.year >= 0 && this.year < e.year.length && e.year[this.year] === 0; ) this.year--;
              if (this.year < 0) return null;
            }
            return this.recurseBackward(e, t2, 0, n + 1);
          } else if (this.apply()) return this.recurseBackward(e, t2, r2 - 1, n + 1);
        }
        return r2 += 1, r2 >= f.length ? this : this.year < 0 ? null : this.recurseBackward(e, t2, r2, n + 1);
      }
      getMaxPatternValue(e, t2, r2) {
        if (e === "day" && t2.lastDayOfMonth) return this.getLastDayOfMonth(this.year, this.month);
        if (e === "day" && !t2.starDOW) return this.getLastDayOfMonth(this.year, this.month);
        for (let n = t2[e].length - 1; n >= 0; n--) if (t2[e][n]) return n - r2;
        return t2[e].length - 1 - r2;
      }
      findPrevious(e, t2, r2, n) {
        return this._findMatch(e, t2, r2, n, -1);
      }
      getDate(e) {
        return e || this.tz === void 0 ? new Date(this.year, this.month, this.day, this.hour, this.minute, this.second, this.ms) : typeof this.tz == "number" ? new Date(Date.UTC(this.year, this.month, this.day, this.hour, this.minute - this.tz, this.second, this.ms)) : k(b(this.year, this.month + 1, this.day, this.hour, this.minute, this.second, this.tz), false);
      }
      getTime() {
        return this.getDate(false).getTime();
      }
      match(e, t2) {
        if (!e.starYear && (this.year < 0 || this.year >= e.year.length || e.year[this.year] === 0)) return false;
        for (let r2 = 0; r2 < f.length; r2++) {
          let n = f[r2][0], i = f[r2][2], a2 = this[n];
          if (a2 + i < 0 || a2 + i >= e[n].length) return false;
          let o = e[n][a2 + i];
          if (n === "day") {
            if (!o) {
              for (let h = 0; h < e.nearestWeekdays.length; h++) if (e.nearestWeekdays[h]) {
                let l3 = this.getNearestWeekday(this.year, this.month, h - i);
                if (l3 !== -1 && l3 === a2) {
                  o = 1;
                  break;
                }
              }
            }
            if (e.lastWeekday) {
              let h = this.getLastWeekday(this.year, this.month);
              a2 === h && (o = 1);
            }
            if (e.lastDayOfMonth) {
              let h = this.getLastDayOfMonth(this.year, this.month);
              a2 === h && (o = 1);
            }
            if (!e.starDOW) {
              let h = new Date(Date.UTC(this.year, this.month, 1, 0, 0, 0, 0)).getUTCDay(), l3 = e.dayOfWeek[(h + (a2 - 1)) % 7];
              l3 && l3 & 63 && (l3 = this.isNthWeekdayOfMonth(this.year, this.month, a2, l3) ? 1 : 0), e.useAndLogic ? o = o && l3 : !t2.domAndDow && !e.starDOM ? o = o || l3 : o = o && l3;
            }
          }
          if (!o) return false;
        }
        return true;
      }
    };
    W = 30 * 1e3;
    w = [];
    E = class {
      name;
      options;
      _states;
      fn;
      getTz() {
        return this.options.timezone || this.options.utcOffset;
      }
      applyDayOffset(e) {
        if (this.options.dayOffset !== void 0 && this.options.dayOffset !== 0) {
          let t2 = this.options.dayOffset * 24 * 60 * 60 * 1e3;
          return new Date(e.getTime() + t2);
        }
        return e;
      }
      constructor(e, t2, r2) {
        let n, i;
        if (p(t2)) i = t2;
        else if (typeof t2 == "object") n = t2;
        else if (t2 !== void 0) throw new Error("Cron: Invalid argument passed for optionsIn. Should be one of function, or object (options).");
        if (p(r2)) i = r2;
        else if (typeof r2 == "object") n = r2;
        else if (r2 !== void 0) throw new Error("Cron: Invalid argument passed for funcIn. Should be one of function, or object (options).");
        if (this.name = n?.name, this.options = R(n), this._states = { kill: false, blocking: false, previousRun: void 0, currentRun: void 0, once: void 0, currentTimeout: void 0, maxRuns: n ? n.maxRuns : void 0, paused: n ? n.paused : false, pattern: new C("* * * * *", void 0, { mode: "auto" }) }, e && (e instanceof Date || typeof e == "string" && e.indexOf(":") > 0) ? this._states.once = new m(e, this.getTz()) : this._states.pattern = new C(e, this.options.timezone, { mode: this.options.mode, alternativeWeekdays: this.options.alternativeWeekdays, sloppyRanges: this.options.sloppyRanges }), this.name) {
          if (w.find((o) => o.name === this.name)) throw new Error("Cron: Tried to initialize new named job '" + this.name + "', but name already taken.");
          w.push(this);
        }
        return i !== void 0 && _(i) && (this.fn = i, this.schedule()), this;
      }
      nextRun(e) {
        let t2 = this._next(e);
        return t2 ? this.applyDayOffset(t2.getDate(false)) : null;
      }
      nextRuns(e, t2) {
        this._states.maxRuns !== void 0 && e > this._states.maxRuns && (e = this._states.maxRuns);
        let r2 = t2 || this._states.currentRun || void 0;
        return this._enumerateRuns(e, r2, "next");
      }
      previousRuns(e, t2) {
        return this._enumerateRuns(e, t2 || void 0, "previous");
      }
      _enumerateRuns(e, t2, r2) {
        let n = [], i = t2 ? new m(t2, this.getTz()) : null, a2 = r2 === "next" ? this._next : this._previous;
        for (; e--; ) {
          let o = a2.call(this, i);
          if (!o) break;
          let h = o.getDate(false);
          n.push(this.applyDayOffset(h)), i = o;
        }
        return n;
      }
      match(e) {
        if (this._states.once) {
          let r2 = new m(e, this.getTz());
          r2.ms = 0;
          let n = new m(this._states.once, this.getTz());
          return n.ms = 0, r2.getTime() === n.getTime();
        }
        let t2 = new m(e, this.getTz());
        return t2.ms = 0, t2.match(this._states.pattern, this.options);
      }
      getPattern() {
        if (!this._states.once) return this._states.pattern ? this._states.pattern.pattern : void 0;
      }
      getOnce() {
        return this._states.once ? this._states.once.getDate() : null;
      }
      isRunning() {
        let e = this.nextRun(this._states.currentRun), t2 = !this._states.paused, r2 = this.fn !== void 0, n = !this._states.kill;
        return t2 && r2 && n && e !== null;
      }
      isStopped() {
        return this._states.kill;
      }
      isBusy() {
        return this._states.blocking;
      }
      currentRun() {
        return this._states.currentRun ? this._states.currentRun.getDate() : null;
      }
      previousRun() {
        return this._states.previousRun ? this._states.previousRun.getDate() : null;
      }
      msToNext(e) {
        let t2 = this._next(e);
        return t2 ? e instanceof m || e instanceof Date ? t2.getTime() - e.getTime() : t2.getTime() - new m(e).getTime() : null;
      }
      stop() {
        this._states.kill = true, this._states.currentTimeout && clearTimeout(this._states.currentTimeout);
        let e = w.indexOf(this);
        e >= 0 && w.splice(e, 1);
      }
      pause() {
        return this._states.paused = true, !this._states.kill;
      }
      resume() {
        return this._states.paused = false, !this._states.kill;
      }
      schedule(e) {
        if (e && this.fn) throw new Error("Cron: It is not allowed to schedule two functions using the same Croner instance.");
        e && (this.fn = e);
        let t2 = this.msToNext(), r2 = this.nextRun(this._states.currentRun);
        return t2 == null || isNaN(t2) || r2 === null ? this : (t2 > W && (t2 = W), this._states.currentTimeout = setTimeout(() => this._checkTrigger(r2), t2), this._states.currentTimeout && this.options.unref && x(this._states.currentTimeout), this);
      }
      async _trigger(e) {
        this._states.blocking = true, this._states.currentRun = new m(void 0, this.getTz());
        try {
          if (this.options.catch) try {
            this.fn !== void 0 && await this.fn(this, this.options.context);
          } catch (t2) {
            if (p(this.options.catch)) try {
              this.options.catch(t2, this);
            } catch {
            }
          }
          else this.fn !== void 0 && await this.fn(this, this.options.context);
        } finally {
          this._states.previousRun = new m(e, this.getTz()), this._states.blocking = false;
        }
      }
      async trigger() {
        await this._trigger();
      }
      runsLeft() {
        return this._states.maxRuns;
      }
      _checkTrigger(e) {
        let t2 = /* @__PURE__ */ new Date(), r2 = !this._states.paused && t2.getTime() >= e.getTime(), n = this._states.blocking && this.options.protect;
        r2 && !n ? (this._states.maxRuns !== void 0 && this._states.maxRuns--, this._trigger()) : r2 && n && p(this.options.protect) && setTimeout(() => this.options.protect(this), 0), this.schedule();
      }
      _next(e) {
        let t2 = !!(e || this._states.currentRun), r2 = false;
        !e && this.options.startAt && this.options.interval && ([e, t2] = this._calculatePreviousRun(e, t2), r2 = !e), e = new m(e, this.getTz()), this.options.startAt && e && e.getTime() < this.options.startAt.getTime() && (e = this.options.startAt);
        let n = this._states.once || new m(e, this.getTz());
        return !r2 && n !== this._states.once && (n = n.increment(this._states.pattern, this.options, t2)), this._states.once && this._states.once.getTime() <= e.getTime() || n === null || this._states.maxRuns !== void 0 && this._states.maxRuns <= 0 || this._states.kill || this.options.stopAt && n.getTime() >= this.options.stopAt.getTime() ? null : n;
      }
      _previous(e) {
        let t2 = new m(e, this.getTz());
        this.options.stopAt && t2.getTime() > this.options.stopAt.getTime() && (t2 = this.options.stopAt);
        let r2 = new m(t2, this.getTz());
        return this._states.once ? this._states.once.getTime() < t2.getTime() ? this._states.once : null : (r2 = r2.decrement(this._states.pattern, this.options), r2 === null || this.options.startAt && r2.getTime() < this.options.startAt.getTime() ? null : r2);
      }
      _calculatePreviousRun(e, t2) {
        let r2 = new m(void 0, this.getTz()), n = e;
        if (this.options.startAt.getTime() <= r2.getTime()) {
          n = this.options.startAt;
          let i = n.getTime() + this.options.interval * 1e3;
          for (; i <= r2.getTime(); ) n = new m(n, this.getTz()).increment(this._states.pattern, this.options, true), i = n.getTime() + this.options.interval * 1e3;
          t2 = true;
        }
        return n === null && (n = void 0), [n, t2];
      }
    };
  }
});

// dist/build/server/chunks/selectors.js
function getDynamicFilterFieldIds(appType) {
  return [...sharedDynamicFilterFieldIds, ...appType === "sonarr" ? sonarrDynamicFilterFieldIds : radarrDynamicFilterFieldIds];
}
function createEmptyDynamicFilterOptions(appType) {
  return Object.fromEntries(getDynamicFilterFieldIds(appType).map((field) => [field, []]));
}
function isCustomFormatUnaryOperator(operator) {
  return customFormatUnaryOperators.includes(operator);
}
function isMultiValueFilterField(fieldId) {
  return multiValueFilterFieldIds.includes(fieldId);
}
function isMultiValueUnaryOperator(operator) {
  return multiValueUnaryOperators.includes(operator);
}
function normalizeMultiValueOperator(operator) {
  if (operator === "eq") return "includes";
  if (operator === "neq") return "does_not_include";
  return operator;
}
function isValuelessOperator(fieldId, operator) {
  return fieldId === "custom_format" && isCustomFormatUnaryOperator(operator) || isMultiValueFilterField(fieldId) && isMultiValueUnaryOperator(operator);
}
function getDefaultRuleValue(fieldId, field, operator, dynamicFilterOptions) {
  if (isValuelessOperator(fieldId, operator)) return null;
  if (dynamicFilterOptions && fieldId in dynamicFilterOptions) return dynamicFilterOptions[fieldId]?.[0]?.value ?? null;
  return field.values?.[0]?.value ?? null;
}
function normalizeFilterRule(rule, appType, options2 = {}) {
  const field = getFilterField(rule.field, appType);
  if (!field) return false;
  if (isMultiValueFilterField(rule.field)) {
    let changed2 = false;
    const normalizedOperator = normalizeMultiValueOperator(rule.operator);
    if (rule.operator !== normalizedOperator) {
      rule.operator = normalizedOperator;
      changed2 = true;
    }
    if (!field.operators.some((operator) => operator.id === rule.operator)) {
      rule.operator = field.operators[0].id;
      changed2 = true;
    }
    if (isMultiValueUnaryOperator(rule.operator) && rule.value !== null) {
      rule.value = null;
      changed2 = true;
    }
    if (!isMultiValueUnaryOperator(rule.operator) && rule.value === null) {
      const defaultValue = getDefaultRuleValue(rule.field, field, rule.operator, options2.dynamicFilterOptions);
      if (rule.value !== defaultValue) {
        rule.value = defaultValue;
        changed2 = true;
      }
    }
    return changed2;
  }
  if (options2.dynamicFilterOptions && rule.field in options2.dynamicFilterOptions && rule.field !== "custom_format" && rule.operator !== "eq" && rule.operator !== "neq") {
    rule.operator = "eq";
    return true;
  }
  if (rule.field !== "custom_format") return false;
  let changed = false;
  if (!field.operators.some((operator) => operator.id === rule.operator)) {
    rule.operator = field.operators[0].id;
    changed = true;
  }
  if (isCustomFormatUnaryOperator(rule.operator) && rule.value !== null) {
    rule.value = null;
    changed = true;
  }
  return changed;
}
function normalizeFilterGroup(group, appType, options2 = {}) {
  let changed = false;
  for (const child of group.children) {
    if (isRule(child)) {
      if (normalizeFilterRule(child, appType, options2)) changed = true;
      continue;
    }
    if (normalizeFilterGroup(child, appType, options2)) changed = true;
  }
  return changed;
}
function applyOrder(fields, order) {
  const byId = new Map(fields.map((f2) => [f2.id, f2]));
  const seen = /* @__PURE__ */ new Set();
  const ordered = [];
  for (const id of order) {
    const f2 = byId.get(id);
    if (f2) {
      ordered.push(f2);
      seen.add(id);
    }
  }
  for (const f2 of fields) if (!seen.has(f2.id)) ordered.push(f2);
  return ordered;
}
function getFilterFields(appType) {
  switch (appType) {
    case "radarr":
      return applyOrder([...sharedFilterFields, ...radarrFilterFields], RADARR_FIELD_ORDER);
    case "sonarr":
      return applyOrder([...sharedFilterFields, ...sonarrFilterFields], SONARR_FIELD_ORDER);
    default:
      return sharedFilterFields;
  }
}
function getFilterField(id, appType) {
  if (appType) return getFilterFields(appType).find((f2) => f2.id === id);
  return [
    ...sharedFilterFields,
    ...radarrFilterFields,
    ...sonarrFilterFields
  ].find((f2) => f2.id === id);
}
function isRule(child) {
  return child.type === "rule";
}
function isGroup(child) {
  return child.type === "group";
}
function filterGroupUsesField(group, fieldId) {
  return group.children.some((child) => isRule(child) ? child.field === fieldId : filterGroupUsesField(child, fieldId));
}
function getMultiValueItems(value2) {
  if (Array.isArray(value2)) return value2.map((item) => String(item).trim()).filter(Boolean);
  if (typeof value2 === "string") return value2.split(",").map((item) => item.trim()).filter(Boolean);
  return [];
}
function evaluateMultiValueRule(fieldValue2, rule) {
  const normalizedValues = getMultiValueItems(fieldValue2).map((value2) => value2.toLowerCase());
  const selected = typeof rule.value === "string" || typeof rule.value === "number" ? String(rule.value).trim().toLowerCase() : "";
  switch (normalizeMultiValueOperator(rule.operator)) {
    case "includes":
      return selected.length > 0 && normalizedValues.includes(selected);
    case "does_not_include":
      return selected.length > 0 && !normalizedValues.includes(selected);
    case "is_only":
      return selected.length > 0 && normalizedValues.length === 1 && normalizedValues[0] === selected;
    case "has_any":
      return normalizedValues.length > 0;
    case "has_none":
      return normalizedValues.length === 0;
    case "contains":
      return selected.length > 0 && normalizedValues.some((value2) => value2.includes(selected));
    case "not_contains":
      return selected.length > 0 && normalizedValues.every((value2) => !value2.includes(selected));
    case "starts_with":
      return selected.length > 0 && normalizedValues.some((value2) => value2.startsWith(selected));
    case "ends_with":
      return selected.length > 0 && normalizedValues.some((value2) => value2.endsWith(selected));
    default:
      return false;
  }
}
function evaluateRule(item, rule) {
  const fieldValue2 = rule.field === "custom_format" ? item.custom_formats : item[rule.field];
  const ruleValue = rule.value;
  if (rule.field === "custom_format") {
    const formats = Array.isArray(fieldValue2) ? fieldValue2.map((value2) => String(value2).toLowerCase()) : [];
    const selected = typeof ruleValue === "string" ? ruleValue.toLowerCase() : "";
    switch (rule.operator) {
      case "includes":
        return selected.length > 0 && formats.includes(selected);
      case "does_not_include":
        return selected.length > 0 && !formats.includes(selected);
      case "is_only":
        return selected.length > 0 && formats.length === 1 && formats[0] === selected;
      case "has_any":
        return formats.length > 0;
      case "has_none":
        return formats.length === 0;
      default:
        return false;
    }
  }
  if (isMultiValueFilterField(rule.field)) return evaluateMultiValueRule(fieldValue2, rule);
  if (fieldValue2 === null || fieldValue2 === void 0) {
    if ([
      "is_not",
      "neq",
      "not_contains"
    ].includes(rule.operator)) return true;
    return false;
  }
  const ordinalMap = ordinalFields[rule.field];
  switch (rule.operator) {
    case "is":
      return fieldValue2 === ruleValue;
    case "is_not":
      return fieldValue2 !== ruleValue;
    case "eq":
      if (typeof fieldValue2 === "string" && typeof ruleValue === "string") return fieldValue2.toLowerCase() === ruleValue.toLowerCase();
      return fieldValue2 === ruleValue;
    case "neq":
      if (typeof fieldValue2 === "string" && typeof ruleValue === "string") return fieldValue2.toLowerCase() !== ruleValue.toLowerCase();
      return fieldValue2 !== ruleValue;
    case "contains": {
      const strField = String(fieldValue2).toLowerCase();
      const strRule = String(ruleValue).toLowerCase();
      return strField.includes(strRule);
    }
    case "not_contains": {
      const strField = String(fieldValue2).toLowerCase();
      const strRule = String(ruleValue).toLowerCase();
      return !strField.includes(strRule);
    }
    case "starts_with": {
      const strField = String(fieldValue2).toLowerCase();
      const strRule = String(ruleValue).toLowerCase();
      return strField.startsWith(strRule);
    }
    case "ends_with": {
      const strField = String(fieldValue2).toLowerCase();
      const strRule = String(ruleValue).toLowerCase();
      return strField.endsWith(strRule);
    }
    case "gte":
      if (ordinalMap) return (ordinalMap[fieldValue2] ?? -1) >= (ordinalMap[ruleValue] ?? -1);
      return typeof fieldValue2 === "number" && typeof ruleValue === "number" && fieldValue2 >= ruleValue;
    case "lte":
      if (ordinalMap) return (ordinalMap[fieldValue2] ?? -1) <= (ordinalMap[ruleValue] ?? -1);
      return typeof fieldValue2 === "number" && typeof ruleValue === "number" && fieldValue2 <= ruleValue;
    case "gt":
      if (ordinalMap) return (ordinalMap[fieldValue2] ?? -1) > (ordinalMap[ruleValue] ?? -1);
      return typeof fieldValue2 === "number" && typeof ruleValue === "number" && fieldValue2 > ruleValue;
    case "lt":
      if (ordinalMap) return (ordinalMap[fieldValue2] ?? -1) < (ordinalMap[ruleValue] ?? -1);
      return typeof fieldValue2 === "number" && typeof ruleValue === "number" && fieldValue2 < ruleValue;
    case "before":
      return new Date(fieldValue2) < new Date(ruleValue);
    case "after":
      return new Date(fieldValue2) > new Date(ruleValue);
    case "in_last": {
      const fieldDate = new Date(fieldValue2);
      return ((/* @__PURE__ */ new Date()).getTime() - fieldDate.getTime()) / 864e5 <= ruleValue;
    }
    case "not_in_last": {
      const fieldDate = new Date(fieldValue2);
      return ((/* @__PURE__ */ new Date()).getTime() - fieldDate.getTime()) / 864e5 > ruleValue;
    }
    default:
      return false;
  }
}
function evaluateGroup(item, group) {
  if (group.children.length === 0) return true;
  if (group.match === "all") return group.children.every((child) => {
    if (isRule(child)) return evaluateRule(item, child);
    else return evaluateGroup(item, child);
  });
  else return group.children.some((child) => {
    if (isRule(child)) return evaluateRule(item, child);
    else return evaluateGroup(item, child);
  });
}
function calculateMaxCount(appType, runsPerHour) {
  const limit = searchRateLimits[appType];
  if (!limit) return 5;
  const effective = Math.max(runsPerHour, 1e-3);
  return Math.max(1, Math.min(limit.maxPerHour, Math.floor(limit.maxPerHour / effective)));
}
function getRunsPerHour(cronExpr) {
  if (!cronExpr) return null;
  try {
    const everyMatch = cronExpr.trim().match(/^\*\/(\d+)\s+\*\s+\*\s+\*\s+\*$/);
    if (everyMatch) {
      const n = parseInt(everyMatch[1], 10);
      if (n > 0 && n <= 60) return Math.ceil(60 / n);
    }
    const hourlyMatch = cronExpr.trim().match(/^(\d+)\s+\*\s+\*\s+\*\s+\*$/);
    if (hourlyMatch) {
      const m3 = parseInt(hourlyMatch[1], 10);
      if (m3 >= 0 && m3 <= 59) return 1;
    }
    const cron = new E(cronExpr);
    const start = /* @__PURE__ */ new Date("2025-06-02T00:00:00Z");
    const end = /* @__PURE__ */ new Date("2025-06-30T00:00:00Z");
    const windowHours = 672;
    let count = 0;
    let cursor = start;
    while (count < 1e5) {
      const next2 = cron.nextRun(cursor);
      if (!next2 || next2 >= end) break;
      count++;
      cursor = new Date(next2.getTime() + 1e3);
    }
    return count / windowHours;
  } catch {
    return null;
  }
}
function slugify(name) {
  return name.toLowerCase().replace(/['']/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 50);
}
function getFilterTagLabel(filterName) {
  return `${FILTER_TAG_PREFIX}${slugify(filterName)}`;
}
function resolveTagLabel(filter) {
  if (filter.tag?.trim()) return filter.tag.trim();
  return getFilterTagLabel(filter.name);
}
function compareSize(a2, b3, direction) {
  const sizeA = typeof a2.size_on_disk === "number" && Number.isFinite(a2.size_on_disk) && a2.size_on_disk > 0 ? a2.size_on_disk : null;
  const sizeB = typeof b3.size_on_disk === "number" && Number.isFinite(b3.size_on_disk) && b3.size_on_disk > 0 ? b3.size_on_disk : null;
  if (sizeA === null) return sizeB === null ? 0 : 1;
  if (sizeB === null) return -1;
  return direction === "asc" ? sizeA - sizeB : sizeB - sizeA;
}
function getSelector(id) {
  return selectors.find((s3) => s3.id === id);
}
var sharedDynamicFilterFieldIds, radarrDynamicFilterFieldIds, sonarrDynamicFilterFieldIds, filterModes, booleanOperators, numberOperators, textOperators, multiValueOperators, dateOperators, ordinalOperators, customFormatOperators, customFormatUnaryOperators, multiValueFilterFieldIds, multiValueUnaryOperators, ordinalFields, sharedFilterFields, radarrFilterFields, sonarrFilterFields, RADARR_FIELD_ORDER, SONARR_FIELD_ORDER, searchRateLimits, FILTER_TAG_PREFIX, selectors;
var init_selectors = __esm({
  "dist/build/server/chunks/selectors.js"() {
    "use strict";
    init_sort();
    init_croner();
    sharedDynamicFilterFieldIds = [
      "quality_profile",
      "tags",
      "original_language",
      "genres"
    ];
    radarrDynamicFilterFieldIds = ["custom_format", "release_group"];
    sonarrDynamicFilterFieldIds = ["network", "certification"];
    filterModes = [{
      id: "round_robin",
      label: "Round Robin",
      description: "Cycle through filters in order, one per run"
    }, {
      id: "random",
      label: "Random Shuffle",
      description: "Shuffle filters, cycle through all before repeating"
    }];
    booleanOperators = [{
      id: "is",
      label: "is",
      description: "Exact match"
    }, {
      id: "is_not",
      label: "is not",
      description: "Does not match"
    }];
    numberOperators = [
      {
        id: "eq",
        label: "=",
        description: "Exactly equals the value"
      },
      {
        id: "neq",
        label: "\u2260",
        description: "Does not equal the value"
      },
      {
        id: "gt",
        label: ">",
        description: "Greater than the value"
      },
      {
        id: "gte",
        label: "\u2265",
        description: "Greater than or equal to the value"
      },
      {
        id: "lt",
        label: "<",
        description: "Less than the value"
      },
      {
        id: "lte",
        label: "\u2264",
        description: "Less than or equal to the value"
      }
    ];
    textOperators = [
      {
        id: "contains",
        label: "contains",
        description: "Contains the text (case-insensitive)"
      },
      {
        id: "not_contains",
        label: "does not contain",
        description: "Does not contain the text"
      },
      {
        id: "starts_with",
        label: "starts with",
        description: "Starts with the text"
      },
      {
        id: "ends_with",
        label: "ends with",
        description: "Ends with the text"
      },
      {
        id: "eq",
        label: "equals",
        description: "Exactly equals the text (case-insensitive)"
      },
      {
        id: "neq",
        label: "does not equal",
        description: "Does not equal the text"
      }
    ];
    multiValueOperators = [
      {
        id: "includes",
        label: "includes",
        shortLabel: "has",
        description: "Includes this value"
      },
      {
        id: "does_not_include",
        label: "does not include",
        shortLabel: "lacks",
        description: "Does not include this value"
      },
      {
        id: "is_only",
        label: "is only",
        shortLabel: "only",
        description: "Only includes this value and no others"
      },
      {
        id: "has_any",
        label: "has any",
        shortLabel: "any",
        description: "Has one or more values"
      },
      {
        id: "has_none",
        label: "has none",
        shortLabel: "none",
        description: "Has no values"
      }
    ];
    dateOperators = [
      {
        id: "before",
        label: "is before",
        shortLabel: "<",
        description: "The date is before the specified date"
      },
      {
        id: "after",
        label: "is after",
        shortLabel: ">",
        description: "The date is after the specified date"
      },
      {
        id: "in_last",
        label: "in the last",
        shortLabel: "in last",
        description: "Within the last N days"
      },
      {
        id: "not_in_last",
        label: "not in the last",
        shortLabel: "not in last",
        description: "Not within the last N days"
      }
    ];
    ordinalOperators = [
      {
        id: "eq",
        label: "is exactly",
        description: "Exactly matches the status"
      },
      {
        id: "neq",
        label: "is not",
        description: "Does not match the status"
      },
      {
        id: "gte",
        label: "has reached",
        description: "Has reached this status or further in the progression"
      },
      {
        id: "lte",
        label: "hasn't passed",
        description: "Has not passed this status in the progression"
      },
      {
        id: "gt",
        label: "is past",
        description: "Is past this status (further along)"
      },
      {
        id: "lt",
        label: "is before",
        description: "Is before this status (not yet reached)"
      }
    ];
    customFormatOperators = [
      {
        id: "includes",
        label: "includes",
        shortLabel: "has",
        description: "Includes this custom format"
      },
      {
        id: "does_not_include",
        label: "does not include",
        shortLabel: "lacks",
        description: "Does not include this custom format"
      },
      {
        id: "is_only",
        label: "is only",
        shortLabel: "only",
        description: "Only includes this custom format and no others"
      },
      {
        id: "has_any",
        label: "has any",
        shortLabel: "any",
        description: "Has one or more custom formats"
      },
      {
        id: "has_none",
        label: "has none",
        shortLabel: "none",
        description: "Has no custom formats"
      }
    ];
    customFormatUnaryOperators = ["has_any", "has_none"];
    multiValueFilterFieldIds = ["tags", "genres"];
    multiValueUnaryOperators = ["has_any", "has_none"];
    ordinalFields = {
      minimum_availability: {
        tba: 0,
        announced: 1,
        inCinemas: 2,
        released: 3
      },
      status: {
        tba: 0,
        announced: 1,
        inCinemas: 2,
        released: 3,
        upcoming: 0,
        continuing: 1,
        ended: 2,
        deleted: 4
      }
    };
    sharedFilterFields = [
      {
        id: "monitored",
        label: "Monitored",
        description: "Whether the item is being monitored for upgrades",
        operators: booleanOperators,
        valueType: "boolean",
        values: [{
          value: true,
          label: "True"
        }, {
          value: false,
          label: "False"
        }]
      },
      {
        id: "cutoff_met",
        label: "Cutoff Met",
        description: "Whether the item's quality score meets the filter's cutoff percentage",
        operators: booleanOperators,
        valueType: "boolean",
        values: [{
          value: true,
          label: "True"
        }, {
          value: false,
          label: "False"
        }]
      },
      {
        id: "title",
        label: "Title",
        description: "The title of the item",
        operators: textOperators,
        valueType: "text"
      },
      {
        id: "quality_profile",
        label: "Quality Profile",
        description: "The assigned quality profile name",
        operators: textOperators,
        valueType: "text"
      },
      {
        id: "original_language",
        label: "Original Language",
        description: 'The original language (e.g., "English", "Japanese")',
        operators: textOperators,
        valueType: "text"
      },
      {
        id: "genres",
        label: "Genres",
        description: "Genres (Action, Comedy, Drama, etc.)",
        operators: multiValueOperators,
        valueType: "text"
      },
      {
        id: "tags",
        label: "Tags",
        description: "Tags applied to the item",
        operators: multiValueOperators,
        valueType: "text"
      },
      {
        id: "rating",
        label: "Rating",
        description: "Rating score (Radarr: TMDb, Sonarr: combined rating)",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "year",
        label: "Year",
        description: "The release year",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "runtime",
        label: "Runtime",
        description: "Runtime in minutes",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "size_on_disk",
        label: "Size on Disk",
        description: "Current file size in GB",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "date_added",
        label: "Date Added",
        shortLabel: "Added",
        description: "When the item was added to your library",
        operators: dateOperators,
        valueType: "date"
      }
    ];
    radarrFilterFields = [
      {
        id: "status",
        label: "Status",
        description: "The actual release status of the movie. Progresses: TBA \u2192 Announced \u2192 In Cinemas \u2192 Released",
        operators: ordinalOperators,
        valueType: "select",
        values: [
          {
            value: "tba",
            label: "TBA"
          },
          {
            value: "announced",
            label: "Announced"
          },
          {
            value: "inCinemas",
            label: "In Cinemas"
          },
          {
            value: "released",
            label: "Released"
          }
        ]
      },
      {
        id: "minimum_availability",
        label: "Minimum Availability",
        description: "The configured minimum availability setting. Progresses: TBA \u2192 Announced \u2192 In Cinemas \u2192 Released",
        operators: ordinalOperators,
        valueType: "select",
        values: [
          {
            value: "tba",
            label: "TBA"
          },
          {
            value: "announced",
            label: "Announced"
          },
          {
            value: "inCinemas",
            label: "In Cinemas"
          },
          {
            value: "released",
            label: "Released"
          }
        ]
      },
      {
        id: "collection",
        label: "Collection",
        description: 'The collection the movie belongs to (e.g., "Marvel Cinematic Universe")',
        operators: textOperators,
        valueType: "text"
      },
      {
        id: "studio",
        label: "Studio",
        description: "The production studio",
        operators: textOperators,
        valueType: "text"
      },
      {
        id: "keywords",
        label: "Keywords",
        description: "TMDb keywords associated with the movie",
        operators: textOperators,
        valueType: "text"
      },
      {
        id: "release_group",
        label: "Release Group",
        description: "The release group of the current file",
        operators: textOperators,
        valueType: "text"
      },
      {
        id: "custom_format",
        label: "Custom Format",
        description: "Custom formats currently matched by the movie file",
        operators: customFormatOperators,
        valueType: "text"
      },
      {
        id: "popularity",
        label: "Popularity",
        description: "TMDb popularity score",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "tmdb_rating",
        label: "TMDb Rating",
        description: "TMDb rating (0-10)",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "imdb_rating",
        label: "IMDb Rating",
        description: "IMDb rating (0-10)",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "tomato_rating",
        label: "Rotten Tomatoes",
        description: "Rotten Tomatoes score (0-100)",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "trakt_rating",
        label: "Trakt Rating",
        description: "Trakt rating (0-100)",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "digital_release",
        label: "Digital Release",
        shortLabel: "Digital",
        description: "The digital release date from TMDb",
        operators: dateOperators,
        valueType: "date"
      },
      {
        id: "physical_release",
        label: "Physical Release",
        shortLabel: "Physical",
        description: "The physical release date from TMDb",
        operators: dateOperators,
        valueType: "date"
      }
    ];
    sonarrFilterFields = [
      {
        id: "status",
        label: "Status",
        description: "The series status. Progresses: Upcoming \u2192 Continuing \u2192 Ended \u2192 Deleted",
        operators: ordinalOperators,
        valueType: "select",
        values: [
          {
            value: "upcoming",
            label: "Upcoming"
          },
          {
            value: "continuing",
            label: "Continuing"
          },
          {
            value: "ended",
            label: "Ended"
          },
          {
            value: "deleted",
            label: "Deleted"
          }
        ]
      },
      {
        id: "network",
        label: "Network",
        description: 'The TV network (e.g., "CBS", "Apple TV+")',
        operators: textOperators,
        valueType: "text"
      },
      {
        id: "series_type",
        label: "Series Type",
        description: "The type of series",
        operators: [{
          id: "eq",
          label: "is",
          description: "Exactly matches"
        }, {
          id: "neq",
          label: "is not",
          description: "Does not match"
        }],
        valueType: "select",
        values: [
          {
            value: "standard",
            label: "Standard"
          },
          {
            value: "daily",
            label: "Daily"
          },
          {
            value: "anime",
            label: "Anime"
          }
        ]
      },
      {
        id: "certification",
        label: "Certification",
        description: 'Content rating (e.g., "TV-MA", "TV-PG")',
        operators: textOperators,
        valueType: "text"
      },
      {
        id: "season_count",
        label: "Season Count",
        description: "Number of seasons",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "episode_count",
        label: "Episode Count",
        description: "Number of available episodes",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "episode_file_count",
        label: "Episode File Count",
        description: "Number of downloaded episodes",
        operators: numberOperators,
        valueType: "number"
      },
      {
        id: "first_aired",
        label: "First Aired",
        shortLabel: "First Air",
        description: "When the first episode aired",
        operators: dateOperators,
        valueType: "date"
      },
      {
        id: "last_aired",
        label: "Last Aired",
        shortLabel: "Last Air",
        description: "When the last episode aired",
        operators: dateOperators,
        valueType: "date"
      }
    ];
    RADARR_FIELD_ORDER = [
      "monitored",
      "cutoff_met",
      "quality_profile",
      "custom_format",
      "minimum_availability",
      "popularity",
      "tags",
      "title",
      "genres",
      "status",
      "original_language",
      "year",
      "rating",
      "date_added",
      "runtime",
      "size_on_disk",
      "release_group",
      "collection",
      "studio",
      "keywords",
      "digital_release",
      "physical_release",
      "tmdb_rating",
      "imdb_rating",
      "tomato_rating",
      "trakt_rating"
    ];
    SONARR_FIELD_ORDER = [
      "monitored",
      "cutoff_met",
      "quality_profile",
      "status",
      "network",
      "tags",
      "title",
      "genres",
      "original_language",
      "year",
      "rating",
      "date_added",
      "runtime",
      "size_on_disk",
      "series_type",
      "certification",
      "season_count",
      "episode_count",
      "episode_file_count",
      "first_aired",
      "last_aired"
    ];
    searchRateLimits = {
      radarr: {
        maxPerHour: 10,
        minIntervalMinutes: 10
      },
      sonarr: {
        maxPerHour: 1,
        minIntervalMinutes: 60
      }
    };
    FILTER_TAG_PREFIX = "profilarr-";
    selectors = [
      {
        id: "random",
        label: "Random",
        description: "Randomly select items",
        select: (items, count) => {
          return [...items].sort(() => Math.random() - 0.5).slice(0, count);
        }
      },
      {
        id: "oldest",
        label: "Oldest",
        description: "Select oldest items first (by date added)",
        select: (items, count) => {
          return [...items].sort((a2, b3) => {
            return new Date(a2.dateAdded || 0).getTime() - new Date(b3.dateAdded || 0).getTime();
          }).slice(0, count);
        }
      },
      {
        id: "newest",
        label: "Newest",
        description: "Select newest items first (by date added)",
        select: (items, count) => {
          return [...items].sort((a2, b3) => {
            const dateA = new Date(a2.dateAdded || 0).getTime();
            return new Date(b3.dateAdded || 0).getTime() - dateA;
          }).slice(0, count);
        }
      },
      {
        id: "lowest_score",
        label: "Lowest Score",
        description: "Select items with lowest custom format score (Sonarr: series average)",
        select: (items, count) => {
          return [...items].sort((a2, b3) => (a2.score || 0) - (b3.score || 0)).slice(0, count);
        }
      },
      {
        id: "size_desc",
        label: "Size (Largest First)",
        description: "Select items with the largest size on disk first",
        select: (items, count) => {
          return [...items].sort((a2, b3) => compareSize(a2, b3, "desc")).slice(0, count);
        }
      },
      {
        id: "size_asc",
        label: "Size (Smallest First)",
        description: "Select items with the smallest positive size on disk first",
        select: (items, count) => {
          return [...items].sort((a2, b3) => compareSize(a2, b3, "asc")).slice(0, count);
        }
      },
      {
        id: "most_popular",
        label: "Most Popular",
        description: "Select most popular items first",
        select: (items, count) => {
          return [...items].sort((a2, b3) => (b3.popularity || 0) - (a2.popularity || 0)).slice(0, count);
        }
      },
      {
        id: "least_popular",
        label: "Least Popular",
        description: "Select least popular items first",
        select: (items, count) => {
          return [...items].sort((a2, b3) => (a2.popularity || 0) - (b3.popularity || 0)).slice(0, count);
        }
      },
      {
        id: "alphabetical_asc",
        label: "A-Z",
        description: "Select items alphabetically by title (A to Z)",
        select: (items, count) => {
          return [...items].sort((a2, b3) => sortTitle(a2.title).localeCompare(sortTitle(b3.title))).slice(0, count);
        }
      },
      {
        id: "alphabetical_desc",
        label: "Z-A",
        description: "Select items alphabetically by title (Z to A)",
        select: (items, count) => {
          return [...items].sort((a2, b3) => sortTitle(b3.title).localeCompare(sortTitle(a2.title))).slice(0, count);
        }
      }
    ];
  }
});

// dist/build/server/chunks/cooldown.js
function averageEpisodeFileScore(files, seasonNumber) {
  const matchingFiles = seasonNumber === void 0 ? files : files.filter((file) => file.seasonNumber === seasonNumber);
  if (matchingFiles.length === 0) return 0;
  return matchingFiles.reduce((total, file) => total + (file.customFormatScore ?? 0), 0) / matchingFiles.length;
}
function filterNeedsSonarrScores(filter) {
  return filter.selector === "lowest_score" || filterGroupUsesField(filter.group, "cutoff_met");
}
function getEpisodeFileCount(series) {
  if (series.statistics) return series.statistics.episodeFileCount;
  if (series.seasons.every((season) => season.statistics)) return series.seasons.reduce((total, season) => total + (season.statistics?.episodeFileCount ?? 0), 0);
}
async function loadSonarrEpisodeFiles(client2, seriesList, existing = /* @__PURE__ */ new Map()) {
  const result = new Map(existing);
  const missing = seriesList.filter((series) => !result.has(series.id));
  for (let index88 = 0; index88 < missing.length; index88 += EPISODE_FILE_FETCH_CONCURRENCY) {
    const batch = missing.slice(index88, index88 + EPISODE_FILE_FETCH_CONCURRENCY);
    const loaded = await Promise.all(batch.map(async (series) => {
      if (getEpisodeFileCount(series) === 0) return [series.id, []];
      try {
        return [series.id, await client2.getEpisodeFiles(series.id)];
      } catch (error2) {
        const message2 = error2 instanceof Error ? error2.message : String(error2);
        throw new Error(`Failed to fetch episode files for "${series.title}": ${message2}`);
      }
    }));
    for (const [seriesId, files] of loaded) result.set(seriesId, files);
  }
  return result;
}
function getFileName(path) {
  if (!path) return "";
  return path.split("/").pop() ?? path;
}
function computeScoreBreakdown(customFormats, profileFormatItems) {
  return customFormats.map((format) => {
    const profileItem = profileFormatItems.find((item) => item.format === format.id);
    return {
      name: format.name,
      score: profileItem?.score ?? 0
    };
  });
}
function normalizeRadarrItem(movie, movieFile, profile, cutoffPercent, tagMap) {
  const currentScore = movieFile?.customFormatScore ?? 0;
  const cutoffMet = currentScore >= (profile?.cutoffFormatScore ?? 0) * cutoffPercent / 100;
  const sizeOnDiskGB = (movie.sizeOnDisk ?? 0) / 1073741824;
  const tmdbRating = movie.ratings?.tmdb?.value ?? 0;
  const imdbRating = movie.ratings?.imdb?.value ?? 0;
  const tomatoRating = movie.ratings?.rottenTomatoes?.value ?? 0;
  const traktRating = movie.ratings?.trakt?.value ?? 0;
  const dateAdded = movie.added ?? (/* @__PURE__ */ new Date()).toISOString();
  const digitalRelease = movie.digitalRelease ?? null;
  const physicalRelease = movie.physicalRelease ?? null;
  const tags = (movie.tags ?? []).map((tagId) => tagMap?.get(tagId) ?? "").filter(Boolean);
  return {
    id: movie.id,
    title: movie.title,
    year: movie.year ?? 0,
    monitored: movie.monitored ?? false,
    cutoff_met: cutoffMet,
    quality_profile: profile?.name ?? "Unknown",
    quality_name: movieFile?.quality?.quality?.name ?? "",
    file_name: getFileName(movieFile?.relativePath ?? movieFile?.path),
    original_language: movie.originalLanguage?.name ?? "",
    genres: movie.genres ?? [],
    tags,
    custom_formats: movieFile?.customFormats.map((cf) => cf.name) ?? [],
    score_breakdown: movieFile ? computeScoreBreakdown(movieFile.customFormats, profile?.formatItems ?? []) : [],
    rating: tmdbRating,
    runtime: movie.runtime ?? 0,
    size_on_disk: sizeOnDiskGB,
    date_added: dateAdded,
    path: movie.path ?? "",
    minimum_availability: movie.minimumAvailability ?? "released",
    collection: movie.collection?.title ?? movie.collection?.name ?? "",
    studio: movie.studio ?? "",
    keywords: movie.keywords?.join(", ") ?? "",
    release_group: movieFile?.releaseGroup ?? "",
    popularity: movie.popularity ?? 0,
    tmdb_rating: tmdbRating,
    imdb_rating: imdbRating,
    tomato_rating: tomatoRating,
    trakt_rating: traktRating,
    digital_release: digitalRelease,
    physical_release: physicalRelease,
    status: movie.status ?? "",
    network: "",
    series_type: "",
    certification: "",
    season_count: 0,
    episode_count: 0,
    episode_file_count: 0,
    first_aired: null,
    last_aired: null,
    dateAdded,
    score: currentScore,
    _raw: movie,
    _tags: movie.tags ?? []
  };
}
function normalizeRadarrItems(movies, movieFileMap, profileMap, cutoffPercent, tagMap) {
  return movies.map((movie) => {
    return normalizeRadarrItem(movie, movieFileMap.get(movie.id), profileMap.get(movie.qualityProfileId), cutoffPercent, tagMap);
  });
}
function normalizeSonarrItem(series, profile, cutoffPercent, episodeFiles, tagMap) {
  const currentScore = episodeFiles ? averageEpisodeFileScore(episodeFiles) : 0;
  const cutoffThreshold = (profile?.cutoffFormatScore ?? 0) * cutoffPercent / 100;
  const cutoffMet = Boolean(episodeFiles?.length) && currentScore >= cutoffThreshold;
  const sizeOnDiskGB = (series.statistics?.sizeOnDisk ?? 0) / 1073741824;
  const dateAdded = series.added ?? (/* @__PURE__ */ new Date()).toISOString();
  const tags = (series.tags ?? []).map((tagId) => tagMap?.get(tagId) ?? "").filter(Boolean);
  return {
    id: series.id,
    title: series.title,
    year: series.year ?? 0,
    monitored: series.monitored,
    cutoff_met: cutoffMet,
    quality_profile: profile?.name ?? "Unknown",
    quality_name: "",
    file_name: "",
    original_language: series.originalLanguage?.name ?? "",
    genres: series.genres ?? [],
    tags,
    custom_formats: [],
    score_breakdown: [],
    rating: series.ratings?.value ?? 0,
    runtime: series.runtime ?? 0,
    size_on_disk: sizeOnDiskGB,
    date_added: dateAdded,
    path: series.path ?? "",
    minimum_availability: "",
    collection: "",
    studio: "",
    keywords: "",
    release_group: "",
    popularity: 0,
    tmdb_rating: 0,
    imdb_rating: 0,
    tomato_rating: 0,
    trakt_rating: 0,
    digital_release: null,
    physical_release: null,
    status: series.status ?? "",
    network: series.network ?? "",
    series_type: series.seriesType ?? "",
    certification: series.certification ?? "",
    season_count: series.statistics?.seasonCount ?? series.seasons.length,
    episode_count: series.statistics?.episodeCount ?? 0,
    episode_file_count: series.statistics?.episodeFileCount ?? 0,
    first_aired: series.firstAired ?? null,
    last_aired: series.lastAired ?? null,
    dateAdded,
    score: currentScore,
    _raw: series,
    _tags: series.tags ?? []
  };
}
function normalizeSonarrItems(seriesList, profileMap, cutoffPercent, episodeFileMap, tagMap) {
  return seriesList.map((series) => {
    return normalizeSonarrItem(series, profileMap.get(series.qualityProfileId), cutoffPercent, episodeFileMap?.get(series.id), tagMap);
  });
}
function hasFilterTag(itemTagIds, allTags, tagLabel) {
  const tagMap = new Map(allTags.map((t2) => [t2.id, t2.label]));
  for (const tagId of itemTagIds) if (tagMap.get(tagId)?.toLowerCase() === tagLabel.toLowerCase()) return true;
  return false;
}
function filterByFilterTag(items, allTags, tagLabel) {
  return items.filter((item) => !hasFilterTag(item._tags, allTags, tagLabel));
}
async function applyFilterTag(client2, movie, tagId) {
  const currentTags = movie.tags ?? [];
  if (currentTags.includes(tagId)) return movie;
  const updatedMovie = {
    ...movie,
    tags: [...currentTags, tagId]
  };
  return await client2.updateMovie(updatedMovie);
}
async function applyFilterTagToMovies(client2, movies, tagId) {
  let success = 0;
  let failed = 0;
  const errors = [];
  for (const movie of movies) try {
    await applyFilterTag(client2, movie, tagId);
    success++;
  } catch (error2) {
    failed++;
    errors.push(`Failed to tag "${movie.title}": ${error2 instanceof Error ? error2.message : String(error2)}`);
  }
  return {
    success,
    failed,
    errors
  };
}
async function removeFilterTag(client2, movie, tagId) {
  const currentTags = movie.tags ?? [];
  if (!currentTags.includes(tagId)) return movie;
  const updatedMovie = {
    ...movie,
    tags: currentTags.filter((id) => id !== tagId)
  };
  return await client2.updateMovie(updatedMovie);
}
async function resetFilterCooldown(client2, tagLabel) {
  const filterTag = (await client2.getTags()).find((t2) => t2.label.toLowerCase() === tagLabel.toLowerCase());
  if (!filterTag) return {
    reset: 0,
    failed: 0,
    errors: []
  };
  if ("getMovies" in client2) {
    const radarrClient = client2;
    const taggedMovies = (await radarrClient.getMovies()).filter((m3) => m3.tags?.includes(filterTag.id));
    if (taggedMovies.length === 0) return {
      reset: 0,
      failed: 0,
      errors: []
    };
    let reset2 = 0;
    let failed = 0;
    const errors = [];
    for (const movie of taggedMovies) try {
      await removeFilterTag(radarrClient, movie, filterTag.id);
      reset2++;
    } catch (error2) {
      failed++;
      errors.push(`Failed to untag "${movie.title}": ${error2 instanceof Error ? error2.message : String(error2)}`);
    }
    return {
      reset: reset2,
      failed,
      errors
    };
  } else {
    const sonarrClient = client2;
    const taggedSeries = (await sonarrClient.getAllSeries()).filter((s3) => s3.tags?.includes(filterTag.id));
    if (taggedSeries.length === 0) return {
      reset: 0,
      failed: 0,
      errors: []
    };
    try {
      const seriesIds = taggedSeries.map((s3) => s3.id);
      await sonarrClient.removeTagFromSeries(seriesIds, filterTag.id);
      return {
        reset: taggedSeries.length,
        failed: 0,
        errors: []
      };
    } catch (error2) {
      return {
        reset: 0,
        failed: taggedSeries.length,
        errors: [`Failed to bulk untag series: ${error2 instanceof Error ? error2.message : String(error2)}`]
      };
    }
  }
}
async function applyFilterTagToSeries(client2, seriesList, tagId) {
  const untagged = seriesList.filter((s3) => !(s3.tags ?? []).includes(tagId));
  if (untagged.length === 0) return {
    success: seriesList.length,
    failed: 0,
    errors: []
  };
  try {
    const seriesIds = untagged.map((s3) => s3.id);
    await client2.applyTagToSeries(seriesIds, tagId);
    return {
      success: seriesList.length,
      failed: 0,
      errors: []
    };
  } catch (error2) {
    return {
      success: 0,
      failed: seriesList.length,
      errors: [`Failed to bulk tag series: ${error2 instanceof Error ? error2.message : String(error2)}`]
    };
  }
}
function isFilterExhausted(matchedItems, allTags, tagLabel) {
  return filterByFilterTag(matchedItems, allTags, tagLabel).length === 0 && matchedItems.length > 0;
}
var EPISODE_FILE_FETCH_CONCURRENCY;
var init_cooldown = __esm({
  "dist/build/server/chunks/cooldown.js"() {
    "use strict";
    init_selectors();
    EPISODE_FILE_FETCH_CONCURRENCY = 10;
  }
});

// dist/build/server/chunks/factory.js
function createArrClient(type, url, apiKey, options2) {
  switch (type) {
    case "radarr":
      return new RadarrClient(url, apiKey, options2);
    case "sonarr":
      return new SonarrClient(url, apiKey, options2);
    case "lidarr":
      return new LidarrClient(url, apiKey, options2);
    case "chaptarr":
      return new ChaptarrClient(url, apiKey, options2);
    default:
      throw new Error(`Unknown arr type: ${type}`);
  }
}
var LidarrClient, ChaptarrClient;
var init_factory = __esm({
  async "dist/build/server/chunks/factory.js"() {
    "use strict";
    await init_base();
    await init_radarr();
    await init_sonarr();
    LidarrClient = class extends BaseArrClient {
      apiVersion = "v1";
    };
    ChaptarrClient = class extends BaseArrClient {
    };
  }
});

// dist/build/server/chunks/cache.js
function getHeaders(pat) {
  const headers2 = {
    Accept: "application/vnd.github+json",
    "X-GitHub-Api-Version": "2022-11-28",
    "User-Agent": "Profilarr"
  };
  if (pat) headers2["Authorization"] = `Bearer ${pat}`;
  return headers2;
}
function parseGitHubUrl(repositoryUrl) {
  const match = repositoryUrl.replace(/\.git$/, "").match(/^https:\/\/github\.com\/([\w-]+)\/([\w-]+)\/?$/);
  if (!match) return null;
  return {
    owner: match[1],
    repo: match[2]
  };
}
async function getCachedRepoInfo(repositoryUrl, pat) {
  const parsed = parseGitHubUrl(repositoryUrl);
  if (!parsed) return null;
  const { owner, repo } = parsed;
  const cacheKey = `repo:${owner}/${repo}`;
  const cached2 = githubCacheQueries.get(cacheKey);
  if (cached2) return JSON.parse(cached2.data);
  const apiUrl = `https://api.github.com/repos/${owner}/${repo}`;
  const headers2 = getHeaders(pat);
  try {
    const response = await globalThis.fetch(apiUrl, { headers: headers2 });
    if (!response.ok) return null;
    const data = await response.json();
    const repoInfo = {
      owner: data.owner.login,
      repo: data.name,
      description: data.description,
      stars: data.stargazers_count,
      forks: data.forks_count,
      openIssues: data.open_issues_count,
      ownerAvatarUrl: data.owner.avatar_url,
      ownerType: data.owner.type,
      htmlUrl: data.html_url
    };
    githubCacheQueries.set(cacheKey, "repo_info", JSON.stringify(repoInfo), TTL.REPO_INFO);
    return repoInfo;
  } catch (err) {
    await logger.error("Failed to fetch GitHub repo info", {
      source: "GitHubCache",
      meta: {
        error: String(err),
        repositoryUrl
      }
    });
    return null;
  }
}
async function fetchAndCacheAvatar(owner, cacheKey) {
  const avatarUrl = `https://github.com/${owner}.png?size=80`;
  try {
    const response = await globalThis.fetch(avatarUrl);
    if (!response.ok) return null;
    const buffer2 = await response.arrayBuffer();
    const base64 = btoa(String.fromCharCode(...new Uint8Array(buffer2)));
    const dataUrl = `data:${response.headers.get("content-type") || "image/png"};base64,${base64}`;
    githubCacheQueries.set(cacheKey, "avatar", dataUrl, TTL.AVATAR);
    return dataUrl;
  } catch (err) {
    await logger.error("Failed to fetch GitHub avatar", {
      source: "GitHubCache",
      meta: {
        error: String(err),
        owner
      }
    });
    return null;
  }
}
async function getCachedAvatar(owner) {
  const cacheKey = `avatar:${owner}`;
  const cached2 = githubCacheQueries.getStale(cacheKey);
  if (cached2) {
    if (githubCacheQueries.isExpired(cacheKey)) fetchAndCacheAvatar(owner, cacheKey).catch(() => {
    });
    return cached2.data;
  }
  return fetchAndCacheAvatar(owner, cacheKey);
}
var githubCacheQueries, TTL;
var init_cache = __esm({
  async "dist/build/server/chunks/cache.js"() {
    "use strict";
    await init_db();
    githubCacheQueries = {
      /**
      * Get cached data by key (returns null if expired)
      */
      get(cacheKey) {
        return db.queryFirst(`SELECT * FROM github_cache
			 WHERE cache_key = ? AND expires_at > datetime('now')`, cacheKey) ?? null;
      },
      /**
      * Get cached data by key even if expired (for stale-while-revalidate)
      */
      getStale(cacheKey) {
        return db.queryFirst("SELECT * FROM github_cache WHERE cache_key = ?", cacheKey) ?? null;
      },
      /**
      * Check if cached data is expired
      */
      isExpired(cacheKey) {
        return db.queryFirst(`SELECT CASE WHEN expires_at <= datetime('now') THEN 1 ELSE 0 END as expired
			 FROM github_cache WHERE cache_key = ?`, cacheKey)?.expired === 1;
      },
      /**
      * Store data in cache with TTL (insert or replace)
      */
      set(cacheKey, cacheType, data, ttlMinutes) {
        db.execute(`INSERT OR REPLACE INTO github_cache (cache_key, cache_type, data, expires_at)
			 VALUES (?, ?, ?, datetime('now', '+' || ? || ' minutes'))`, cacheKey, cacheType, data, ttlMinutes);
      },
      /**
      * Delete a cached entry
      */
      delete(cacheKey) {
        return db.execute("DELETE FROM github_cache WHERE cache_key = ?", cacheKey) > 0;
      },
      /**
      * Delete all expired entries
      */
      deleteExpired() {
        return db.execute("DELETE FROM github_cache WHERE expires_at <= datetime('now')");
      },
      /**
      * Clear all cached entries
      */
      clear() {
        return db.execute("DELETE FROM github_cache");
      },
      /**
      * Invalidate all entries of a specific type
      */
      invalidateByType(cacheType) {
        return db.execute("DELETE FROM github_cache WHERE cache_type = ?", cacheType);
      }
    };
    TTL = {
      REPO_INFO: 60,
      AVATAR: 1440
    };
  }
});

// dist/build/server/chunks/git.js
async function execGit(args, cwd3, timeoutMs = DEFAULT_TIMEOUT_MS) {
  const process2 = new Deno.Command("git", {
    args,
    ...cwd3 && { cwd: cwd3 },
    stdout: "piped",
    stderr: "piped",
    env: GIT_ENV
  }).spawn();
  const timer = setTimeout(() => {
    try {
      process2.kill("SIGTERM");
    } catch {
    }
  }, timeoutMs);
  let status;
  let stdout;
  let stderr;
  try {
    [status, stdout, stderr] = await Promise.all([
      process2.status,
      new Response(process2.stdout).arrayBuffer().then((b3) => new Uint8Array(b3)),
      new Response(process2.stderr).arrayBuffer().then((b3) => new Uint8Array(b3))
    ]);
  } finally {
    clearTimeout(timer);
  }
  if (!status.success) {
    const errorMessage = new TextDecoder().decode(stderr);
    if (status.signal === "SIGTERM") throw new Error(`Git command timed out after ${timeoutMs}ms: git ${args.join(" ")}`);
    throw new Error(`Git command failed: ${errorMessage}`);
  }
  return new TextDecoder().decode(stdout).trim();
}
async function execGitSafe(args, cwd3) {
  try {
    return await execGit(args, cwd3);
  } catch {
    return null;
  }
}
async function parseGitHubErrorResponse(response) {
  let apiMessage = "";
  try {
    const payload2 = await response.json();
    if (payload2 && typeof payload2 === "object" && "message" in payload2 && typeof payload2.message === "string") apiMessage = payload2.message;
  } catch {
  }
  const messageLower = apiMessage.toLowerCase();
  const retryAfterRaw = response.headers.get("retry-after");
  const retryAfterSeconds = retryAfterRaw ? Number.parseInt(retryAfterRaw, 10) : null;
  const resetAtRaw = response.headers.get("x-ratelimit-reset");
  const resetAtEpoch = resetAtRaw ? Number.parseInt(resetAtRaw, 10) : null;
  const remaining = response.headers.get("x-ratelimit-remaining");
  const rateLimited = response.status === 429 || remaining === "0" || messageLower.includes("rate limit") || messageLower.includes("secondary rate limit");
  return {
    message: apiMessage,
    rateLimited,
    retryAfterSeconds: retryAfterSeconds !== null && Number.isFinite(retryAfterSeconds) ? retryAfterSeconds : null,
    resetAtEpoch: resetAtEpoch !== null && Number.isFinite(resetAtEpoch) ? resetAtEpoch : null
  };
}
function formatRateLimitMessage(context2, retryAfterSeconds, resetAtEpoch) {
  let hint = "";
  if (retryAfterSeconds !== null && retryAfterSeconds > 0) hint = ` Retry after ~${retryAfterSeconds} seconds.`;
  else if (resetAtEpoch !== null && resetAtEpoch > 0) hint = ` Rate limit resets around ${(/* @__PURE__ */ new Date(resetAtEpoch * 1e3)).toISOString()}.`;
  if (context2 === "authenticated") return `GitHub API rate limit exceeded for the supplied Personal Access Token.${hint}`;
  return `GitHub API rate limit exceeded for unauthenticated requests.${hint} Add a Personal Access Token to avoid this limit.`;
}
async function classifyGitHubResponseError(response, context2) {
  const parsed = await parseGitHubErrorResponse(response);
  if (parsed.rateLimited) return {
    message: formatRateLimitMessage(context2, parsed.retryAfterSeconds, parsed.resetAtEpoch),
    rateLimited: true
  };
  if (context2 === "authenticated") {
    if (response.status === 401) return {
      message: "Unable to access repository. Please check your Personal Access Token.",
      rateLimited: false
    };
    if (response.status === 404) return {
      message: "Repository not found or inaccessible with this Personal Access Token. Verify the URL and token permissions.",
      rateLimited: false
    };
    if (response.status === 403) return {
      message: "GitHub denied access to this repository with the supplied Personal Access Token. Check token permissions.",
      rateLimited: false
    };
  } else {
    if (response.status === 404) return {
      message: "Repository not found. If this repository is private, provide a Personal Access Token.",
      rateLimited: false
    };
    if (response.status === 403) return {
      message: "GitHub denied unauthenticated access to this repository. It may be private or access-restricted. Provide a Personal Access Token.",
      rateLimited: false
    };
  }
  const suffix = parsed.message ? ` (${parsed.message})` : "";
  return {
    message: `GitHub API error: ${response.status}${suffix}`,
    rateLimited: false
  };
}
async function validateRepository(repositoryUrl, personalAccessToken) {
  const match = repositoryUrl.replace(/\.git$/, "").match(/^https:\/\/github\.com\/([\w-]+)\/([\w-]+)\/?$/);
  if (!match) throw new Error("Repository URL must be a valid GitHub repository (https://github.com/username/repo)");
  const [, owner, repo] = match;
  const apiUrl = `https://api.github.com/repos/${owner}/${repo}`;
  const response = await globalThis.fetch(apiUrl, { headers: {
    Accept: "application/vnd.github+json",
    "X-GitHub-Api-Version": "2022-11-28",
    "User-Agent": "Profilarr"
  } });
  if (response.ok) return (await response.json()).private === true;
  if (personalAccessToken) {
    await logger.debug("GitHub repo probe failed, assuming private", {
      source: "validateRepository",
      meta: {
        url: apiUrl,
        status: response.status,
        body: await response.clone().text()
      }
    });
    return true;
  }
  const classified = await classifyGitHubResponseError(response, "unauthenticated");
  throw new Error(classified.message);
}
async function clone(repositoryUrl, targetPath, branch2, personalAccessToken) {
  const isPrivate = await validateRepository(repositoryUrl, personalAccessToken);
  const args = ["clone"];
  if (branch2) args.push("--branch", branch2);
  let authUrl = repositoryUrl;
  if (personalAccessToken) authUrl = repositoryUrl.replace("https://github.com", `https://${personalAccessToken}@github.com`);
  args.push(authUrl, targetPath);
  await execGit(args);
  return isPrivate;
}
async function fetch2(repoPath) {
  await execGitSafe(["fetch", "--quiet"], repoPath);
}
async function fetchTags(repoPath) {
  await execGitSafe([
    "fetch",
    "--tags",
    "--quiet"
  ], repoPath);
}
async function pull(repoPath) {
  await execGit(["pull"], repoPath);
}
async function checkout(repoPath, branch2) {
  await execGit(["checkout", branch2], repoPath);
}
async function restorePathsToHead(repoPath, paths) {
  if (paths.length === 0) return;
  await execGit([
    "checkout",
    "HEAD",
    "--",
    ...paths
  ], repoPath);
}
async function stage(repoPath, filepaths) {
  for (const filepath of filepaths) await execGit([
    "add",
    "-A",
    filepath.startsWith(repoPath + "/") ? filepath.slice(repoPath.length + 1) : filepath
  ], repoPath);
}
async function commit(repoPath, message2) {
  await execGit([
    "commit",
    "-m",
    message2
  ], repoPath);
}
async function configureIdentity(repoPath, name, email) {
  const trimmedName = name.trim();
  const trimmedEmail = email.trim();
  if (!trimmedName || !trimmedEmail) throw new Error("Git author name and email are required");
  await execGit([
    "config",
    "user.name",
    trimmedName
  ], repoPath);
  await execGit([
    "config",
    "user.email",
    trimmedEmail
  ], repoPath);
}
async function getRepoInfo(repositoryUrl, personalAccessToken) {
  return getCachedRepoInfo(repositoryUrl, personalAccessToken);
}
function normalizeAuthorName(name) {
  const trimmed = name.trim();
  const normalized = trimmed.toLowerCase().replace(/\s+/g, " ");
  if (normalized === "xshatterx") return "Seraphys";
  if (normalized === "sam chau" || normalized === "samuel chau") return "santiagosayshey";
  return trimmed;
}
async function getBranch(repoPath) {
  return await execGit(["branch", "--show-current"], repoPath);
}
async function getStatus(repoPath, options2 = {}) {
  const branch2 = await getBranch(repoPath);
  if (options2.fetch) await fetch2(repoPath);
  let ahead = 0;
  let behind = 0;
  const revOutput = await execGitSafe([
    "rev-list",
    "--left-right",
    "--count",
    `origin/${branch2}...HEAD`
  ], repoPath);
  if (revOutput) {
    const parts = revOutput.split("	").map((n) => parseInt(n, 10) || 0);
    behind = parts[0] || 0;
    ahead = parts[1] || 0;
  }
  const statusResult = await new Deno.Command("git", {
    args: [
      "status",
      "--porcelain",
      "--untracked-files=all"
    ],
    cwd: repoPath,
    stdout: "piped",
    stderr: "piped"
  }).output();
  const statusOutput = new TextDecoder().decode(statusResult.stdout);
  const untracked = [];
  const modified = [];
  const deleted = [];
  const staged = [];
  for (const line of statusOutput.split("\n")) {
    if (!line || line.length < 4) continue;
    const status = line.substring(0, 2);
    const file = line.substring(3);
    if (status.startsWith("??")) untracked.push(file);
    else if (status[1] === "D" || status[0] === "D") deleted.push(file);
    else if (status[1] === "M") modified.push(file);
    if (status[0] === "M" || status[0] === "A" || status[0] === "D") staged.push(file);
  }
  return {
    branch: branch2,
    isDirty: untracked.length > 0 || modified.length > 0 || deleted.length > 0 || staged.length > 0,
    ahead,
    behind,
    untracked,
    modified,
    deleted,
    staged
  };
}
async function checkForUpdates(repoPath) {
  await fetch2(repoPath);
  const remoteBranch = `origin/${await getBranch(repoPath)}`;
  const currentLocalCommit = await execGit(["rev-parse", "HEAD"], repoPath);
  let latestRemoteCommit;
  try {
    latestRemoteCommit = await execGit(["rev-parse", remoteBranch], repoPath);
  } catch {
    return {
      hasUpdates: false,
      commitsBehind: 0,
      commitsAhead: 0,
      latestRemoteCommit: currentLocalCommit,
      currentLocalCommit
    };
  }
  const behindOutput = await execGitSafe([
    "rev-list",
    "--count",
    `HEAD..${remoteBranch}`
  ], repoPath);
  const commitsBehind = parseInt(behindOutput || "0") || 0;
  const aheadOutput = await execGitSafe([
    "rev-list",
    "--count",
    `${remoteBranch}..HEAD`
  ], repoPath);
  return {
    hasUpdates: commitsBehind > 0,
    commitsBehind,
    commitsAhead: parseInt(aheadOutput || "0") || 0,
    latestRemoteCommit,
    currentLocalCommit
  };
}
async function getBranches(repoPath) {
  return (await execGit([
    "branch",
    "-a",
    "--format=%(refname:short)"
  ], repoPath)).split("\n").map((b3) => b3.trim()).filter((b3) => b3 && !b3.includes("HEAD")).map((b3) => b3.replace(/^origin\//, "")).filter((b3, i, arr) => arr.indexOf(b3) === i);
}
async function getCommits(repoPath, limit = 50, ref, status, offset = 0) {
  if (limit <= 0) return [];
  const args = [
    "log",
    `--format=%H|%h|%s|%an|%ae|%cI`,
    `-${limit}`
  ];
  if (offset > 0) args.push(`--skip=${offset}`);
  if (ref) args.push(ref);
  const output = await execGit(args, repoPath);
  if (!output.trim()) return [];
  const commits = [];
  for (const line of output.split("\n")) {
    if (!line.trim()) continue;
    const [hash4, shortHash, message2, author, authorEmail, date] = line.split("|");
    const statOutput = await execGitSafe([
      "diff-tree",
      "--no-commit-id",
      "--name-only",
      "-r",
      hash4
    ], repoPath);
    const files = statOutput ? statOutput.split("\n").filter((f2) => f2.trim()) : [];
    commits.push({
      hash: hash4,
      shortHash,
      message: message2,
      author: normalizeAuthorName(author),
      authorEmail,
      date,
      files,
      status
    });
  }
  return commits;
}
async function countCommits(repoPath, ref) {
  const output = await execGitSafe([
    "rev-list",
    "--count",
    ref
  ], repoPath);
  return parseInt(output || "0", 10) || 0;
}
async function getIncomingChanges(repoPath) {
  await fetch2(repoPath);
  const remoteBranch = `origin/${await getBranch(repoPath)}`;
  const countOutput = await execGitSafe([
    "rev-list",
    "--count",
    `HEAD..${remoteBranch}`
  ], repoPath);
  const commitsBehind = parseInt(countOutput || "0") || 0;
  if (commitsBehind === 0) return {
    hasUpdates: false,
    commitsBehind: 0,
    commits: []
  };
  const output = await execGit([
    "log",
    `--format=%H|%h|%s|%an|%ae|%cI`,
    `HEAD..${remoteBranch}`
  ], repoPath);
  const commits = [];
  for (const line of output.split("\n")) {
    if (!line.trim()) continue;
    const [hash4, shortHash, message2, author, authorEmail, date] = line.split("|");
    const filesOutput = await execGitSafe([
      "diff-tree",
      "--no-commit-id",
      "--name-only",
      "-r",
      hash4
    ], repoPath);
    const files = filesOutput ? filesOutput.split("\n").filter((f2) => f2.trim()) : [];
    commits.push({
      hash: hash4,
      shortHash,
      message: message2,
      author: normalizeAuthorName(author),
      authorEmail,
      date,
      files,
      status: "available"
    });
  }
  return {
    hasUpdates: true,
    commitsBehind,
    commits
  };
}
async function getCommitMessagesBetween(repoPath, fromRef, toRef) {
  const output = await execGitSafe([
    "log",
    "--format=%s",
    `${fromRef}..${toRef}`
  ], repoPath);
  if (!output) return [];
  return output.split("\n").filter((line) => line.trim());
}
var DEFAULT_TIMEOUT_MS, GIT_ENV;
var init_git = __esm({
  async "dist/build/server/chunks/git.js"() {
    "use strict";
    await init_db();
    await init_cache();
    DEFAULT_TIMEOUT_MS = 6e4;
    GIT_ENV = {
      GIT_TERMINAL_PROMPT: "0",
      GIT_ASKPASS: "echo",
      GIT_SSH_COMMAND: "ssh -o BatchMode=yes",
      GIT_CONFIG_COUNT: "1",
      GIT_CONFIG_KEY_0: "credential.helper",
      GIT_CONFIG_VALUE_0: ""
    };
  }
});

// dist/build/server/chunks/pcdOps.js
var pcdOpsQueries;
var init_pcdOps = __esm({
  async "dist/build/server/chunks/pcdOps.js"() {
    "use strict";
    await init_db();
    pcdOpsQueries = {
      create(input) {
        db.execute(`INSERT INTO pcd_ops (
				database_id, origin, state, source,
				filename, op_number, sequence,
				sql, metadata, desired_state,
				content_hash, last_seen_in_repo_at,
				superseded_by_op_id, pushed_at, pushed_commit
			) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, input.databaseId, input.origin, input.state, input.source, input.filename ?? null, input.opNumber ?? null, input.sequence ?? null, input.sql, input.metadata ?? null, input.desiredState ?? null, input.contentHash ?? null, input.lastSeenInRepoAt ?? null, input.supersededByOpId ?? null, input.pushedAt ?? null, input.pushedCommit ?? null);
        return db.queryFirst("SELECT last_insert_rowid() as id")?.id ?? 0;
      },
      getById(id) {
        return db.queryFirst("SELECT * FROM pcd_ops WHERE id = ?", id);
      },
      listByDatabase(databaseId, origin) {
        if (origin) return db.query("SELECT * FROM pcd_ops WHERE database_id = ? AND origin = ? ORDER BY id", databaseId, origin);
        return db.query("SELECT * FROM pcd_ops WHERE database_id = ? ORDER BY id", databaseId);
      },
      listByDatabaseAndOrigin(databaseId, origin, options2) {
        const clauses = ["database_id = ?", "origin = ?"];
        const params = [databaseId, origin];
        if (options2?.source) {
          clauses.push("source = ?");
          params.push(options2.source);
        }
        if (options2?.states && options2.states.length > 0) {
          const placeholders = options2.states.map(() => "?").join(", ");
          clauses.push(`state IN (${placeholders})`);
          params.push(...options2.states);
        }
        const where = clauses.join(" AND ");
        return db.query(`SELECT * FROM pcd_ops WHERE ${where} ORDER BY id`, ...params);
      },
      getBaseByFilename(databaseId, filename) {
        return db.queryFirst("SELECT * FROM pcd_ops WHERE database_id = ? AND origin = 'base' AND filename = ?", databaseId, filename);
      },
      update(id, input) {
        const updates = [];
        const params = [];
        if (input.state !== void 0) {
          updates.push("state = ?");
          params.push(input.state);
        }
        if (input.source !== void 0) {
          updates.push("source = ?");
          params.push(input.source);
        }
        if (input.filename !== void 0) {
          updates.push("filename = ?");
          params.push(input.filename ?? null);
        }
        if (input.opNumber !== void 0) {
          updates.push("op_number = ?");
          params.push(input.opNumber ?? null);
        }
        if (input.sequence !== void 0) {
          updates.push("sequence = ?");
          params.push(input.sequence ?? null);
        }
        if (input.sql !== void 0) {
          updates.push("sql = ?");
          params.push(input.sql);
        }
        if (input.metadata !== void 0) {
          updates.push("metadata = ?");
          params.push(input.metadata ?? null);
        }
        if (input.desiredState !== void 0) {
          updates.push("desired_state = ?");
          params.push(input.desiredState ?? null);
        }
        if (input.contentHash !== void 0) {
          updates.push("content_hash = ?");
          params.push(input.contentHash ?? null);
        }
        if (input.lastSeenInRepoAt !== void 0) {
          updates.push("last_seen_in_repo_at = ?");
          params.push(input.lastSeenInRepoAt ?? null);
        }
        if (input.supersededByOpId !== void 0) {
          updates.push("superseded_by_op_id = ?");
          params.push(input.supersededByOpId ?? null);
        }
        if (input.pushedAt !== void 0) {
          updates.push("pushed_at = ?");
          params.push(input.pushedAt ?? null);
        }
        if (input.pushedCommit !== void 0) {
          updates.push("pushed_commit = ?");
          params.push(input.pushedCommit ?? null);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(id);
        return db.execute(`UPDATE pcd_ops SET ${updates.join(", ")} WHERE id = ?`, ...params) > 0;
      },
      markBaseOrphaned(databaseId, seenAt) {
        return db.execute(`UPDATE pcd_ops
       SET state = 'orphaned', updated_at = CURRENT_TIMESTAMP
       WHERE database_id = ?
         AND origin = 'base'
         AND source = 'repo'
         AND (last_seen_in_repo_at IS NULL OR last_seen_in_repo_at < ?)`, databaseId, seenAt);
      }
    };
  }
});

// dist/build/server/chunks/registry.js
function setCache(databaseInstanceId, cache3) {
  caches.set(databaseInstanceId, cache3);
}
function getCache(databaseInstanceId) {
  return caches.get(databaseInstanceId);
}
function deleteCache(databaseInstanceId) {
  return caches.delete(databaseInstanceId);
}
function getCachedDatabaseIds() {
  return Array.from(caches.keys());
}
var caches;
var init_registry = __esm({
  "dist/build/server/chunks/registry.js"() {
    "use strict";
    caches = /* @__PURE__ */ new Map();
  }
});

// dist/build/server/chunks/sanitize.js
function escapeHtml(text2) {
  return text2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
}
function decodeEntities(str2) {
  const named = {
    "&amp;": "&",
    "&lt;": "<",
    "&gt;": ">",
    "&quot;": '"',
    "&#039;": "'",
    "&apos;": "'",
    "&nbsp;": " ",
    "&tab;": "	"
  };
  return str2.replace(/&(?:#x([0-9a-f]+)|#(\d+)|[a-z]+);/gi, (m3, hex, dec) => {
    if (hex) return String.fromCodePoint(parseInt(hex, 16));
    if (dec) return String.fromCodePoint(parseInt(dec, 10));
    return named[m3.toLowerCase()] ?? m3;
  });
}
function isSafeUrl(raw) {
  const decoded = decodeEntities(raw).replace(/[\s\x00-\x1f]+/g, "").toLowerCase();
  if (!decoded.includes(":")) return true;
  return SAFE_URL_SCHEMES.has(decoded.slice(0, decoded.indexOf(":") + 1));
}
function sanitizeHtml(html2) {
  const allowedTags = /* @__PURE__ */ new Set([
    "p",
    "br",
    "strong",
    "em",
    "u",
    "code",
    "pre",
    "blockquote",
    "ul",
    "ol",
    "li",
    "a",
    "img",
    "h1",
    "h2",
    "h3",
    "h4",
    "h5",
    "h6",
    "table",
    "thead",
    "tbody",
    "tr",
    "th",
    "td",
    "hr",
    "del",
    "ins"
  ]);
  const allowedAttrs = {
    a: /* @__PURE__ */ new Set(["href", "title"]),
    img: /* @__PURE__ */ new Set([
      "src",
      "alt",
      "title"
    ])
  };
  html2 = html2.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "");
  html2 = html2.replace(/\s*on\w+\s*=\s*["'][^"']*["']/gi, "");
  return html2.replace(/<\/?([a-z][a-z0-9]*)\b([^>]*)>/gi, (match, tag2, attrs) => {
    const lowerTag = tag2.toLowerCase();
    if (!allowedTags.has(lowerTag)) return "";
    if (match.startsWith("</")) return `</${lowerTag}>`;
    const allowedForTag = allowedAttrs[lowerTag];
    if (!allowedForTag) return `<${lowerTag}>`;
    return `<${lowerTag}${attrs.replace(/([a-z][a-z0-9-]*)\s*=\s*["']([^"']*)["']/gi, (_attrMatch, attrName, attrValue) => {
      const lowerAttr = attrName.toLowerCase();
      if (!allowedForTag.has(lowerAttr)) return "";
      if ((lowerAttr === "href" || lowerAttr === "src") && !isSafeUrl(attrValue)) return "";
      return ` ${attrName}="${attrValue}"`;
    })}>`;
  });
}
var SAFE_URL_SCHEMES;
var init_sanitize = __esm({
  "dist/build/server/chunks/sanitize.js"() {
    "use strict";
    SAFE_URL_SCHEMES = /* @__PURE__ */ new Set([
      "http:",
      "https:",
      "mailto:"
    ]);
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/object-utils.js
function isUndefined(obj) {
  return typeof obj === "undefined" || obj === void 0;
}
function isString(obj) {
  return typeof obj === "string";
}
function isNumber(obj) {
  return typeof obj === "number";
}
function isBoolean(obj) {
  return typeof obj === "boolean";
}
function isNull(obj) {
  return obj === null;
}
function isDate(obj) {
  return obj instanceof Date;
}
function isBigInt(obj) {
  return typeof obj === "bigint";
}
function isBuffer(obj) {
  return typeof Buffer !== "undefined" && Buffer.isBuffer(obj);
}
function isFunction(obj) {
  return typeof obj === "function";
}
function isObject2(obj) {
  return typeof obj === "object" && obj !== null;
}
function freeze(obj) {
  return Object.freeze(obj);
}
function asArray(arg) {
  if (isReadonlyArray(arg)) {
    return arg;
  } else {
    return [arg];
  }
}
function isReadonlyArray(arg) {
  return Array.isArray(arg);
}
function noop3(obj) {
  return obj;
}
var init_object_utils = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/object-utils.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/alter-table-node.js
var AlterTableNode;
var init_alter_table_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/alter-table-node.js"() {
    init_object_utils();
    AlterTableNode = freeze({
      is(node) {
        return node.kind === "AlterTableNode";
      },
      create(table2) {
        return freeze({
          kind: "AlterTableNode",
          table: table2
        });
      },
      cloneWithTableProps(node, props) {
        return freeze({
          ...node,
          ...props
        });
      },
      cloneWithColumnAlteration(node, columnAlteration) {
        return freeze({
          ...node,
          columnAlterations: node.columnAlterations ? [...node.columnAlterations, columnAlteration] : [columnAlteration]
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/identifier-node.js
var IdentifierNode;
var init_identifier_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/identifier-node.js"() {
    init_object_utils();
    IdentifierNode = freeze({
      is(node) {
        return node.kind === "IdentifierNode";
      },
      create(name) {
        return freeze({
          kind: "IdentifierNode",
          name
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/create-index-node.js
var CreateIndexNode;
var init_create_index_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/create-index-node.js"() {
    init_object_utils();
    init_identifier_node();
    CreateIndexNode = freeze({
      is(node) {
        return node.kind === "CreateIndexNode";
      },
      create(name) {
        return freeze({
          kind: "CreateIndexNode",
          name: IdentifierNode.create(name)
        });
      },
      cloneWith(node, props) {
        return freeze({
          ...node,
          ...props
        });
      },
      cloneWithColumns(node, columns) {
        return freeze({
          ...node,
          columns: [...node.columns || [], ...columns]
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/create-schema-node.js
var CreateSchemaNode;
var init_create_schema_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/create-schema-node.js"() {
    init_object_utils();
    init_identifier_node();
    CreateSchemaNode = freeze({
      is(node) {
        return node.kind === "CreateSchemaNode";
      },
      create(schema, params) {
        return freeze({
          kind: "CreateSchemaNode",
          schema: IdentifierNode.create(schema),
          ...params
        });
      },
      cloneWith(createSchema2, params) {
        return freeze({
          ...createSchema2,
          ...params
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/create-table-node.js
var ON_COMMIT_ACTIONS, CreateTableNode;
var init_create_table_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/create-table-node.js"() {
    init_object_utils();
    ON_COMMIT_ACTIONS = ["preserve rows", "delete rows", "drop"];
    CreateTableNode = freeze({
      is(node) {
        return node.kind === "CreateTableNode";
      },
      create(table2) {
        return freeze({
          kind: "CreateTableNode",
          table: table2,
          columns: freeze([])
        });
      },
      cloneWithColumn(createTable, column) {
        return freeze({
          ...createTable,
          columns: freeze([...createTable.columns, column])
        });
      },
      cloneWithConstraint(createTable, constraint) {
        return freeze({
          ...createTable,
          constraints: createTable.constraints ? freeze([...createTable.constraints, constraint]) : freeze([constraint])
        });
      },
      cloneWithFrontModifier(createTable, modifier) {
        return freeze({
          ...createTable,
          frontModifiers: createTable.frontModifiers ? freeze([...createTable.frontModifiers, modifier]) : freeze([modifier])
        });
      },
      cloneWithEndModifier(createTable, modifier) {
        return freeze({
          ...createTable,
          endModifiers: createTable.endModifiers ? freeze([...createTable.endModifiers, modifier]) : freeze([modifier])
        });
      },
      cloneWith(createTable, params) {
        return freeze({
          ...createTable,
          ...params
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/schemable-identifier-node.js
var SchemableIdentifierNode;
var init_schemable_identifier_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/schemable-identifier-node.js"() {
    init_object_utils();
    init_identifier_node();
    SchemableIdentifierNode = freeze({
      is(node) {
        return node.kind === "SchemableIdentifierNode";
      },
      create(identifier) {
        return freeze({
          kind: "SchemableIdentifierNode",
          identifier: IdentifierNode.create(identifier)
        });
      },
      createWithSchema(schema, identifier) {
        return freeze({
          kind: "SchemableIdentifierNode",
          schema: IdentifierNode.create(schema),
          identifier: IdentifierNode.create(identifier)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-index-node.js
var DropIndexNode;
var init_drop_index_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-index-node.js"() {
    init_object_utils();
    init_schemable_identifier_node();
    DropIndexNode = freeze({
      is(node) {
        return node.kind === "DropIndexNode";
      },
      create(name, params) {
        return freeze({
          kind: "DropIndexNode",
          name: SchemableIdentifierNode.create(name),
          ...params
        });
      },
      cloneWith(dropIndex, props) {
        return freeze({
          ...dropIndex,
          ...props
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-schema-node.js
var DropSchemaNode;
var init_drop_schema_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-schema-node.js"() {
    init_object_utils();
    init_identifier_node();
    DropSchemaNode = freeze({
      is(node) {
        return node.kind === "DropSchemaNode";
      },
      create(schema, params) {
        return freeze({
          kind: "DropSchemaNode",
          schema: IdentifierNode.create(schema),
          ...params
        });
      },
      cloneWith(dropSchema, params) {
        return freeze({
          ...dropSchema,
          ...params
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-table-node.js
var DropTableNode;
var init_drop_table_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-table-node.js"() {
    init_object_utils();
    DropTableNode = freeze({
      is(node) {
        return node.kind === "DropTableNode";
      },
      create(table2, params) {
        return freeze({
          kind: "DropTableNode",
          table: table2,
          ...params
        });
      },
      cloneWith(dropIndex, params) {
        return freeze({
          ...dropIndex,
          ...params
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/alias-node.js
var AliasNode;
var init_alias_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/alias-node.js"() {
    init_object_utils();
    AliasNode = freeze({
      is(node) {
        return node.kind === "AliasNode";
      },
      create(node, alias) {
        return freeze({
          kind: "AliasNode",
          node,
          alias
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/table-node.js
var TableNode;
var init_table_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/table-node.js"() {
    init_object_utils();
    init_schemable_identifier_node();
    TableNode = freeze({
      is(node) {
        return node.kind === "TableNode";
      },
      create(table2) {
        return freeze({
          kind: "TableNode",
          table: SchemableIdentifierNode.create(table2)
        });
      },
      createWithSchema(schema, table2) {
        return freeze({
          kind: "TableNode",
          table: SchemableIdentifierNode.createWithSchema(schema, table2)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/operation-node-source.js
function isOperationNodeSource(obj) {
  return isObject2(obj) && isFunction(obj.toOperationNode);
}
var init_operation_node_source = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/operation-node-source.js"() {
    init_object_utils();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/expression/expression.js
function isExpression(obj) {
  return isObject2(obj) && "expressionType" in obj && isOperationNodeSource(obj);
}
function isAliasedExpression(obj) {
  return isObject2(obj) && "expression" in obj && isString(obj.alias) && isOperationNodeSource(obj);
}
var init_expression = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/expression/expression.js"() {
    init_operation_node_source();
    init_object_utils();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/select-modifier-node.js
var SelectModifierNode;
var init_select_modifier_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/select-modifier-node.js"() {
    init_object_utils();
    SelectModifierNode = freeze({
      is(node) {
        return node.kind === "SelectModifierNode";
      },
      create(modifier, of) {
        return freeze({
          kind: "SelectModifierNode",
          modifier,
          of
        });
      },
      createWithExpression(modifier) {
        return freeze({
          kind: "SelectModifierNode",
          rawModifier: modifier
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/and-node.js
var AndNode;
var init_and_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/and-node.js"() {
    init_object_utils();
    AndNode = freeze({
      is(node) {
        return node.kind === "AndNode";
      },
      create(left, right) {
        return freeze({
          kind: "AndNode",
          left,
          right
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/or-node.js
var OrNode;
var init_or_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/or-node.js"() {
    init_object_utils();
    OrNode = freeze({
      is(node) {
        return node.kind === "OrNode";
      },
      create(left, right) {
        return freeze({
          kind: "OrNode",
          left,
          right
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/on-node.js
var OnNode;
var init_on_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/on-node.js"() {
    init_object_utils();
    init_and_node();
    init_or_node();
    OnNode = freeze({
      is(node) {
        return node.kind === "OnNode";
      },
      create(filter) {
        return freeze({
          kind: "OnNode",
          on: filter
        });
      },
      cloneWithOperation(onNode, operator, operation) {
        return freeze({
          ...onNode,
          on: operator === "And" ? AndNode.create(onNode.on, operation) : OrNode.create(onNode.on, operation)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/join-node.js
var JoinNode;
var init_join_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/join-node.js"() {
    init_object_utils();
    init_on_node();
    JoinNode = freeze({
      is(node) {
        return node.kind === "JoinNode";
      },
      create(joinType, table2) {
        return freeze({
          kind: "JoinNode",
          joinType,
          table: table2,
          on: void 0
        });
      },
      createWithOn(joinType, table2, on) {
        return freeze({
          kind: "JoinNode",
          joinType,
          table: table2,
          on: OnNode.create(on)
        });
      },
      cloneWithOn(joinNode, operation) {
        return freeze({
          ...joinNode,
          on: joinNode.on ? OnNode.cloneWithOperation(joinNode.on, "And", operation) : OnNode.create(operation)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/binary-operation-node.js
var BinaryOperationNode;
var init_binary_operation_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/binary-operation-node.js"() {
    init_object_utils();
    BinaryOperationNode = freeze({
      is(node) {
        return node.kind === "BinaryOperationNode";
      },
      create(leftOperand, operator, rightOperand) {
        return freeze({
          kind: "BinaryOperationNode",
          leftOperand,
          operator,
          rightOperand
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/operator-node.js
function isJSONOperator(op) {
  return isString(op) && JSON_OPERATORS.includes(op);
}
var COMPARISON_OPERATORS, ARITHMETIC_OPERATORS, JSON_OPERATORS, BINARY_OPERATORS, UNARY_FILTER_OPERATORS, UNARY_OPERATORS, OPERATORS, OperatorNode;
var init_operator_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/operator-node.js"() {
    init_object_utils();
    COMPARISON_OPERATORS = [
      "=",
      "==",
      "!=",
      "<>",
      ">",
      ">=",
      "<",
      "<=",
      "in",
      "not in",
      "is",
      "is not",
      "like",
      "not like",
      "match",
      "ilike",
      "not ilike",
      "@>",
      "<@",
      "^@",
      "&&",
      "?",
      "?&",
      "?|",
      "!<",
      "!>",
      "<=>",
      "!~",
      "~",
      "~*",
      "!~*",
      "@@",
      "@@@",
      "!!",
      "<->",
      "regexp",
      "is distinct from",
      "is not distinct from"
    ];
    ARITHMETIC_OPERATORS = [
      "+",
      "-",
      "*",
      "/",
      "%",
      "^",
      "&",
      "|",
      "#",
      "<<",
      ">>"
    ];
    JSON_OPERATORS = ["->", "->>"];
    BINARY_OPERATORS = [
      ...COMPARISON_OPERATORS,
      ...ARITHMETIC_OPERATORS,
      "&&",
      "||"
    ];
    UNARY_FILTER_OPERATORS = ["exists", "not exists"];
    UNARY_OPERATORS = ["not", "-", ...UNARY_FILTER_OPERATORS];
    OPERATORS = [
      ...BINARY_OPERATORS,
      ...JSON_OPERATORS,
      ...UNARY_OPERATORS,
      "between",
      "between symmetric"
    ];
    OperatorNode = freeze({
      is(node) {
        return node.kind === "OperatorNode";
      },
      create(operator) {
        return freeze({
          kind: "OperatorNode",
          operator
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/column-node.js
var ColumnNode;
var init_column_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/column-node.js"() {
    init_object_utils();
    init_identifier_node();
    ColumnNode = freeze({
      is(node) {
        return node.kind === "ColumnNode";
      },
      create(column) {
        return freeze({
          kind: "ColumnNode",
          column: IdentifierNode.create(column)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/select-all-node.js
var SelectAllNode;
var init_select_all_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/select-all-node.js"() {
    init_object_utils();
    SelectAllNode = freeze({
      is(node) {
        return node.kind === "SelectAllNode";
      },
      create() {
        return freeze({
          kind: "SelectAllNode"
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/reference-node.js
var ReferenceNode;
var init_reference_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/reference-node.js"() {
    init_select_all_node();
    init_object_utils();
    ReferenceNode = freeze({
      is(node) {
        return node.kind === "ReferenceNode";
      },
      create(column, table2) {
        return freeze({
          kind: "ReferenceNode",
          table: table2,
          column
        });
      },
      createSelectAll(table2) {
        return freeze({
          kind: "ReferenceNode",
          table: table2,
          column: SelectAllNode.create()
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dynamic/dynamic-reference-builder.js
function isDynamicReferenceBuilder(obj) {
  return isObject2(obj) && isOperationNodeSource(obj) && isString(obj.dynamicReference);
}
var DynamicReferenceBuilder;
var init_dynamic_reference_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dynamic/dynamic-reference-builder.js"() {
    init_operation_node_source();
    init_reference_parser();
    init_object_utils();
    DynamicReferenceBuilder = class {
      #dynamicReference;
      get dynamicReference() {
        return this.#dynamicReference;
      }
      /**
       * @private
       *
       * This needs to be here just so that the typings work. Without this
       * the generated .d.ts file contains no reference to the type param R
       * which causes this type to be equal to DynamicReferenceBuilder with
       * any R.
       */
      get refType() {
        return void 0;
      }
      constructor(reference) {
        this.#dynamicReference = reference;
      }
      toOperationNode() {
        return parseSimpleReferenceExpression(this.#dynamicReference);
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/order-by-item-node.js
var OrderByItemNode;
var init_order_by_item_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/order-by-item-node.js"() {
    init_object_utils();
    OrderByItemNode = freeze({
      is(node) {
        return node.kind === "OrderByItemNode";
      },
      create(orderBy, direction) {
        return freeze({
          kind: "OrderByItemNode",
          orderBy,
          direction
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/raw-node.js
var RawNode;
var init_raw_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/raw-node.js"() {
    init_object_utils();
    RawNode = freeze({
      is(node) {
        return node.kind === "RawNode";
      },
      create(sqlFragments, parameters) {
        return freeze({
          kind: "RawNode",
          sqlFragments: freeze(sqlFragments),
          parameters: freeze(parameters)
        });
      },
      createWithSql(sql2) {
        return RawNode.create([sql2], []);
      },
      createWithChild(child) {
        return RawNode.create(["", ""], [child]);
      },
      createWithChildren(children) {
        return RawNode.create(new Array(children.length + 1).fill(""), children);
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/order-by-parser.js
function isOrderByDirection(thing) {
  return thing === "asc" || thing === "desc";
}
function parseOrderBy(args) {
  if (args.length === 2) {
    return [parseOrderByItem(args[0], args[1])];
  }
  if (args.length === 1) {
    const [orderBy] = args;
    if (Array.isArray(orderBy)) {
      return orderBy.map((item) => parseOrderByItem(item));
    }
    return [parseOrderByItem(orderBy)];
  }
  throw new Error(`Invalid number of arguments at order by! expected 1-2, received ${args.length}`);
}
function parseOrderByItem(ref, direction) {
  const parsedRef = parseOrderByExpression(ref);
  if (OrderByItemNode.is(parsedRef)) {
    if (direction) {
      throw new Error("Cannot specify direction twice!");
    }
    return parsedRef;
  }
  return OrderByItemNode.create(parsedRef, parseOrderByDirectionExpression(direction));
}
function parseOrderByExpression(expr) {
  if (isExpressionOrFactory(expr)) {
    return parseExpression(expr);
  }
  if (isDynamicReferenceBuilder(expr)) {
    return expr.toOperationNode();
  }
  const [ref, direction] = expr.split(" ");
  if (direction) {
    if (!isOrderByDirection(direction)) {
      throw new Error(`Invalid order by direction: ${direction}`);
    }
    return OrderByItemNode.create(parseStringReference(ref), parseOrderByDirectionExpression(direction));
  }
  return parseStringReference(expr);
}
function parseOrderByDirectionExpression(expr) {
  if (!expr) {
    return void 0;
  }
  if (expr === "asc" || expr === "desc") {
    return RawNode.createWithSql(expr);
  }
  return expr.toOperationNode();
}
var init_order_by_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/order-by-parser.js"() {
    init_dynamic_reference_builder();
    init_order_by_item_node();
    init_raw_node();
    init_expression_parser();
    init_reference_parser();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/json-reference-node.js
var JSONReferenceNode;
var init_json_reference_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/json-reference-node.js"() {
    init_object_utils();
    JSONReferenceNode = freeze({
      is(node) {
        return node.kind === "JSONReferenceNode";
      },
      create(reference, traversal) {
        return freeze({
          kind: "JSONReferenceNode",
          reference,
          traversal
        });
      },
      cloneWithTraversal(node, traversal) {
        return freeze({
          ...node,
          traversal
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/json-operator-chain-node.js
var JSONOperatorChainNode;
var init_json_operator_chain_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/json-operator-chain-node.js"() {
    init_object_utils();
    JSONOperatorChainNode = freeze({
      is(node) {
        return node.kind === "JSONOperatorChainNode";
      },
      create(operator) {
        return freeze({
          kind: "JSONOperatorChainNode",
          operator,
          values: freeze([])
        });
      },
      cloneWithValue(node, value2) {
        return freeze({
          ...node,
          values: freeze([...node.values, value2])
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/json-path-node.js
var JSONPathNode;
var init_json_path_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/json-path-node.js"() {
    init_object_utils();
    JSONPathNode = freeze({
      is(node) {
        return node.kind === "JSONPathNode";
      },
      create(inOperator) {
        return freeze({
          kind: "JSONPathNode",
          inOperator,
          pathLegs: freeze([])
        });
      },
      cloneWithLeg(jsonPathNode, pathLeg) {
        return freeze({
          ...jsonPathNode,
          pathLegs: freeze([...jsonPathNode.pathLegs, pathLeg])
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/reference-parser.js
function parseSimpleReferenceExpression(exp) {
  if (isString(exp)) {
    return parseStringReference(exp);
  }
  return exp.toOperationNode();
}
function parseReferenceExpressionOrList(arg) {
  if (isReadonlyArray(arg)) {
    return arg.map((it2) => parseReferenceExpression(it2));
  } else {
    return [parseReferenceExpression(arg)];
  }
}
function parseReferenceExpression(exp) {
  if (isExpressionOrFactory(exp)) {
    return parseExpression(exp);
  }
  return parseSimpleReferenceExpression(exp);
}
function parseJSONReference(ref, op) {
  const referenceNode = parseStringReference(ref);
  if (isJSONOperator(op)) {
    return JSONReferenceNode.create(referenceNode, JSONOperatorChainNode.create(OperatorNode.create(op)));
  }
  const opWithoutLastChar = op.slice(0, -1);
  if (isJSONOperator(opWithoutLastChar)) {
    return JSONReferenceNode.create(referenceNode, JSONPathNode.create(OperatorNode.create(opWithoutLastChar)));
  }
  throw new Error(`Invalid JSON operator: ${op}`);
}
function parseStringReference(ref) {
  const COLUMN_SEPARATOR = ".";
  if (!ref.includes(COLUMN_SEPARATOR)) {
    return ReferenceNode.create(ColumnNode.create(ref));
  }
  const parts = ref.split(COLUMN_SEPARATOR).map(trim);
  if (parts.length === 3) {
    return parseStringReferenceWithTableAndSchema(parts);
  }
  if (parts.length === 2) {
    return parseStringReferenceWithTable(parts);
  }
  throw new Error(`invalid column reference ${ref}`);
}
function parseAliasedStringReference(ref) {
  const ALIAS_SEPARATOR = " as ";
  if (ref.includes(ALIAS_SEPARATOR)) {
    const [columnRef, alias] = ref.split(ALIAS_SEPARATOR).map(trim);
    return AliasNode.create(parseStringReference(columnRef), IdentifierNode.create(alias));
  } else {
    return parseStringReference(ref);
  }
}
function parseColumnName(column) {
  return ColumnNode.create(column);
}
function parseOrderedColumnName(column) {
  const ORDER_SEPARATOR = " ";
  if (column.includes(ORDER_SEPARATOR)) {
    const [columnName, order] = column.split(ORDER_SEPARATOR).map(trim);
    if (!isOrderByDirection(order)) {
      throw new Error(`invalid order direction "${order}" next to "${columnName}"`);
    }
    return parseOrderBy([columnName, order])[0];
  } else {
    return parseColumnName(column);
  }
}
function parseStringReferenceWithTableAndSchema(parts) {
  const [schema, table2, column] = parts;
  return ReferenceNode.create(ColumnNode.create(column), TableNode.createWithSchema(schema, table2));
}
function parseStringReferenceWithTable(parts) {
  const [table2, column] = parts;
  return ReferenceNode.create(ColumnNode.create(column), TableNode.create(table2));
}
function trim(str2) {
  return str2.trim();
}
var init_reference_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/reference-parser.js"() {
    init_alias_node();
    init_column_node();
    init_reference_node();
    init_table_node();
    init_object_utils();
    init_expression_parser();
    init_identifier_node();
    init_order_by_parser();
    init_operator_node();
    init_json_reference_node();
    init_json_operator_chain_node();
    init_json_path_node();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/primitive-value-list-node.js
var PrimitiveValueListNode;
var init_primitive_value_list_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/primitive-value-list-node.js"() {
    init_object_utils();
    PrimitiveValueListNode = freeze({
      is(node) {
        return node.kind === "PrimitiveValueListNode";
      },
      create(values) {
        return freeze({
          kind: "PrimitiveValueListNode",
          values: freeze([...values])
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/value-list-node.js
var ValueListNode;
var init_value_list_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/value-list-node.js"() {
    init_object_utils();
    ValueListNode = freeze({
      is(node) {
        return node.kind === "ValueListNode";
      },
      create(values) {
        return freeze({
          kind: "ValueListNode",
          values: freeze(values)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/value-node.js
var ValueNode;
var init_value_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/value-node.js"() {
    init_object_utils();
    ValueNode = freeze({
      is(node) {
        return node.kind === "ValueNode";
      },
      create(value2) {
        return freeze({
          kind: "ValueNode",
          value: value2
        });
      },
      createImmediate(value2) {
        return freeze({
          kind: "ValueNode",
          value: value2,
          immediate: true
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/value-parser.js
function parseValueExpressionOrList(arg) {
  if (isReadonlyArray(arg)) {
    return parseValueExpressionList(arg);
  }
  return parseValueExpression(arg);
}
function parseValueExpression(exp) {
  if (isExpressionOrFactory(exp)) {
    return parseExpression(exp);
  }
  return ValueNode.create(exp);
}
function isSafeImmediateValue(value2) {
  return isNumber(value2) || isBoolean(value2) || isNull(value2);
}
function parseSafeImmediateValue(value2) {
  if (!isSafeImmediateValue(value2)) {
    throw new Error(`unsafe immediate value ${JSON.stringify(value2)}`);
  }
  return ValueNode.createImmediate(value2);
}
function parseValueExpressionList(arg) {
  if (arg.some(isExpressionOrFactory)) {
    return ValueListNode.create(arg.map((it2) => parseValueExpression(it2)));
  }
  return PrimitiveValueListNode.create(arg);
}
var init_value_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/value-parser.js"() {
    init_primitive_value_list_node();
    init_value_list_node();
    init_value_node();
    init_object_utils();
    init_expression_parser();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/parens-node.js
var ParensNode;
var init_parens_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/parens-node.js"() {
    init_object_utils();
    ParensNode = freeze({
      is(node) {
        return node.kind === "ParensNode";
      },
      create(node) {
        return freeze({
          kind: "ParensNode",
          node
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/binary-operation-parser.js
function parseValueBinaryOperationOrExpression(args) {
  if (args.length === 3) {
    return parseValueBinaryOperation(args[0], args[1], args[2]);
  } else if (args.length === 1) {
    return parseValueExpression(args[0]);
  }
  throw new Error(`invalid arguments: ${JSON.stringify(args)}`);
}
function parseValueBinaryOperation(left, operator, right) {
  if (isIsOperator(operator) && needsIsOperator(right)) {
    return BinaryOperationNode.create(parseReferenceExpression(left), parseOperator(operator), ValueNode.createImmediate(right));
  }
  return BinaryOperationNode.create(parseReferenceExpression(left), parseOperator(operator), parseValueExpressionOrList(right));
}
function parseReferentialBinaryOperation(left, operator, right) {
  return BinaryOperationNode.create(parseReferenceExpression(left), parseOperator(operator), parseReferenceExpression(right));
}
function parseFilterObject(obj, combinator) {
  return parseFilterList(Object.entries(obj).filter(([, v3]) => !isUndefined(v3)).map(([k2, v3]) => parseValueBinaryOperation(k2, needsIsOperator(v3) ? "is" : "=", v3)), combinator);
}
function parseFilterList(list5, combinator, withParens = true) {
  const combine = combinator === "and" ? AndNode.create : OrNode.create;
  if (list5.length === 0) {
    return BinaryOperationNode.create(ValueNode.createImmediate(1), OperatorNode.create("="), ValueNode.createImmediate(combinator === "and" ? 1 : 0));
  }
  let node = toOperationNode(list5[0]);
  for (let i = 1; i < list5.length; ++i) {
    node = combine(node, toOperationNode(list5[i]));
  }
  if (list5.length > 1 && withParens) {
    return ParensNode.create(node);
  }
  return node;
}
function isIsOperator(operator) {
  return operator === "is" || operator === "is not";
}
function needsIsOperator(value2) {
  return isNull(value2) || isBoolean(value2);
}
function parseOperator(operator) {
  if (isString(operator) && OPERATORS.includes(operator)) {
    return OperatorNode.create(operator);
  }
  if (isOperationNodeSource(operator)) {
    return operator.toOperationNode();
  }
  throw new Error(`invalid operator ${JSON.stringify(operator)}`);
}
function toOperationNode(nodeOrSource) {
  return isOperationNodeSource(nodeOrSource) ? nodeOrSource.toOperationNode() : nodeOrSource;
}
var init_binary_operation_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/binary-operation-parser.js"() {
    init_binary_operation_node();
    init_object_utils();
    init_operation_node_source();
    init_operator_node();
    init_reference_parser();
    init_value_parser();
    init_value_node();
    init_and_node();
    init_parens_node();
    init_or_node();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/order-by-node.js
var OrderByNode;
var init_order_by_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/order-by-node.js"() {
    init_object_utils();
    OrderByNode = freeze({
      is(node) {
        return node.kind === "OrderByNode";
      },
      create(items) {
        return freeze({
          kind: "OrderByNode",
          items: freeze([...items])
        });
      },
      cloneWithItems(orderBy, items) {
        return freeze({
          ...orderBy,
          items: freeze([...orderBy.items, ...items])
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/partition-by-node.js
var PartitionByNode;
var init_partition_by_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/partition-by-node.js"() {
    init_object_utils();
    PartitionByNode = freeze({
      is(node) {
        return node.kind === "PartitionByNode";
      },
      create(items) {
        return freeze({
          kind: "PartitionByNode",
          items: freeze(items)
        });
      },
      cloneWithItems(partitionBy, items) {
        return freeze({
          ...partitionBy,
          items: freeze([...partitionBy.items, ...items])
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/over-node.js
var OverNode;
var init_over_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/over-node.js"() {
    init_object_utils();
    init_order_by_node();
    init_partition_by_node();
    OverNode = freeze({
      is(node) {
        return node.kind === "OverNode";
      },
      create() {
        return freeze({
          kind: "OverNode"
        });
      },
      cloneWithOrderByItems(overNode, items) {
        return freeze({
          ...overNode,
          orderBy: overNode.orderBy ? OrderByNode.cloneWithItems(overNode.orderBy, items) : OrderByNode.create(items)
        });
      },
      cloneWithPartitionByItems(overNode, items) {
        return freeze({
          ...overNode,
          partitionBy: overNode.partitionBy ? PartitionByNode.cloneWithItems(overNode.partitionBy, items) : PartitionByNode.create(items)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/from-node.js
var FromNode;
var init_from_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/from-node.js"() {
    init_object_utils();
    FromNode = freeze({
      is(node) {
        return node.kind === "FromNode";
      },
      create(froms) {
        return freeze({
          kind: "FromNode",
          froms: freeze(froms)
        });
      },
      cloneWithFroms(from, froms) {
        return freeze({
          ...from,
          froms: freeze([...from.froms, ...froms])
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/group-by-node.js
var GroupByNode;
var init_group_by_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/group-by-node.js"() {
    init_object_utils();
    GroupByNode = freeze({
      is(node) {
        return node.kind === "GroupByNode";
      },
      create(items) {
        return freeze({
          kind: "GroupByNode",
          items: freeze(items)
        });
      },
      cloneWithItems(groupBy, items) {
        return freeze({
          ...groupBy,
          items: freeze([...groupBy.items, ...items])
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/having-node.js
var HavingNode;
var init_having_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/having-node.js"() {
    init_object_utils();
    init_and_node();
    init_or_node();
    HavingNode = freeze({
      is(node) {
        return node.kind === "HavingNode";
      },
      create(filter) {
        return freeze({
          kind: "HavingNode",
          having: filter
        });
      },
      cloneWithOperation(havingNode, operator, operation) {
        return freeze({
          ...havingNode,
          having: operator === "And" ? AndNode.create(havingNode.having, operation) : OrNode.create(havingNode.having, operation)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/select-query-node.js
var SelectQueryNode;
var init_select_query_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/select-query-node.js"() {
    init_object_utils();
    init_from_node();
    init_group_by_node();
    init_having_node();
    init_order_by_node();
    SelectQueryNode = freeze({
      is(node) {
        return node.kind === "SelectQueryNode";
      },
      create(withNode) {
        return freeze({
          kind: "SelectQueryNode",
          ...withNode && { with: withNode }
        });
      },
      createFrom(fromItems, withNode) {
        return freeze({
          kind: "SelectQueryNode",
          from: FromNode.create(fromItems),
          ...withNode && { with: withNode }
        });
      },
      cloneWithSelections(select2, selections) {
        return freeze({
          ...select2,
          selections: select2.selections ? freeze([...select2.selections, ...selections]) : freeze(selections)
        });
      },
      cloneWithDistinctOn(select2, expressions) {
        return freeze({
          ...select2,
          distinctOn: select2.distinctOn ? freeze([...select2.distinctOn, ...expressions]) : freeze(expressions)
        });
      },
      cloneWithFrontModifier(select2, modifier) {
        return freeze({
          ...select2,
          frontModifiers: select2.frontModifiers ? freeze([...select2.frontModifiers, modifier]) : freeze([modifier])
        });
      },
      cloneWithOrderByItems(selectNode, items) {
        return freeze({
          ...selectNode,
          orderBy: selectNode.orderBy ? OrderByNode.cloneWithItems(selectNode.orderBy, items) : OrderByNode.create(items)
        });
      },
      cloneWithGroupByItems(selectNode, items) {
        return freeze({
          ...selectNode,
          groupBy: selectNode.groupBy ? GroupByNode.cloneWithItems(selectNode.groupBy, items) : GroupByNode.create(items)
        });
      },
      cloneWithLimit(selectNode, limit) {
        return freeze({
          ...selectNode,
          limit
        });
      },
      cloneWithOffset(selectNode, offset) {
        return freeze({
          ...selectNode,
          offset
        });
      },
      cloneWithFetch(selectNode, fetch3) {
        return freeze({
          ...selectNode,
          fetch: fetch3
        });
      },
      cloneWithHaving(selectNode, operation) {
        return freeze({
          ...selectNode,
          having: selectNode.having ? HavingNode.cloneWithOperation(selectNode.having, "And", operation) : HavingNode.create(operation)
        });
      },
      cloneWithSetOperations(selectNode, setOperations) {
        return freeze({
          ...selectNode,
          setOperations: selectNode.setOperations ? freeze([...selectNode.setOperations, ...setOperations]) : freeze([...setOperations])
        });
      },
      cloneWithoutSelections(select2) {
        return freeze({
          ...select2,
          selections: []
        });
      },
      cloneWithoutLimit(select2) {
        return freeze({
          ...select2,
          limit: void 0
        });
      },
      cloneWithoutOffset(select2) {
        return freeze({
          ...select2,
          offset: void 0
        });
      },
      cloneWithoutOrderBy(select2) {
        return freeze({
          ...select2,
          orderBy: void 0
        });
      },
      cloneWithoutGroupBy(select2) {
        return freeze({
          ...select2,
          groupBy: void 0
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/prevent-await.js
function preventAwait(clazz, message2) {
  Object.defineProperties(clazz.prototype, {
    then: {
      enumerable: false,
      value: () => {
        throw new Error(message2);
      }
    }
  });
}
var init_prevent_await = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/prevent-await.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/join-builder.js
var JoinBuilder;
var init_join_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/join-builder.js"() {
    init_join_node();
    init_raw_node();
    init_binary_operation_parser();
    init_object_utils();
    init_prevent_await();
    JoinBuilder = class _JoinBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      on(...args) {
        return new _JoinBuilder({
          ...this.#props,
          joinNode: JoinNode.cloneWithOn(this.#props.joinNode, parseValueBinaryOperationOrExpression(args))
        });
      }
      /**
       * Just like {@link WhereInterface.whereRef} but adds an item to the join's
       * `on` clause instead.
       *
       * See {@link WhereInterface.whereRef} for documentation and examples.
       */
      onRef(lhs, op, rhs) {
        return new _JoinBuilder({
          ...this.#props,
          joinNode: JoinNode.cloneWithOn(this.#props.joinNode, parseReferentialBinaryOperation(lhs, op, rhs))
        });
      }
      /**
       * Adds `on true`.
       */
      onTrue() {
        return new _JoinBuilder({
          ...this.#props,
          joinNode: JoinNode.cloneWithOn(this.#props.joinNode, RawNode.createWithSql("true"))
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.joinNode;
      }
    };
    preventAwait(JoinBuilder, "don't await JoinBuilder instances. They are never executed directly and are always just a part of a query.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/partition-by-item-node.js
var PartitionByItemNode;
var init_partition_by_item_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/partition-by-item-node.js"() {
    init_object_utils();
    PartitionByItemNode = freeze({
      is(node) {
        return node.kind === "PartitionByItemNode";
      },
      create(partitionBy) {
        return freeze({
          kind: "PartitionByItemNode",
          partitionBy
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/partition-by-parser.js
function parsePartitionBy(partitionBy) {
  return parseReferenceExpressionOrList(partitionBy).map(PartitionByItemNode.create);
}
var init_partition_by_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/partition-by-parser.js"() {
    init_partition_by_item_node();
    init_reference_parser();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/over-builder.js
var OverBuilder;
var init_over_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/over-builder.js"() {
    init_over_node();
    init_order_by_parser();
    init_partition_by_parser();
    init_object_utils();
    init_prevent_await();
    OverBuilder = class _OverBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Adds an order by clause item inside the over function.
       *
       * ```ts
       * const result = await db
       *   .selectFrom('person')
       *   .select(
       *     (eb) => eb.fn.avg<number>('age').over(
       *       ob => ob.orderBy('first_name', 'asc').orderBy('last_name', 'asc')
       *     ).as('average_age')
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select avg("age") over(order by "first_name" asc, "last_name" asc) as "average_age"
       * from "person"
       * ```
       */
      orderBy(orderBy, direction) {
        return new _OverBuilder({
          overNode: OverNode.cloneWithOrderByItems(this.#props.overNode, parseOrderBy([orderBy, direction]))
        });
      }
      partitionBy(partitionBy) {
        return new _OverBuilder({
          overNode: OverNode.cloneWithPartitionByItems(this.#props.overNode, parsePartitionBy(partitionBy))
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.overNode;
      }
    };
    preventAwait(OverBuilder, "don't await OverBuilder instances. They are never executed directly and are always just a part of a query.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/selection-node.js
var SelectionNode;
var init_selection_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/selection-node.js"() {
    init_object_utils();
    init_reference_node();
    init_select_all_node();
    SelectionNode = freeze({
      is(node) {
        return node.kind === "SelectionNode";
      },
      create(selection) {
        return freeze({
          kind: "SelectionNode",
          selection
        });
      },
      createSelectAll() {
        return freeze({
          kind: "SelectionNode",
          selection: SelectAllNode.create()
        });
      },
      createSelectAllFromTable(table2) {
        return freeze({
          kind: "SelectionNode",
          selection: ReferenceNode.createSelectAll(table2)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/select-parser.js
function parseSelectArg(selection) {
  if (isFunction(selection)) {
    return parseSelectArg(selection(expressionBuilder()));
  } else if (isReadonlyArray(selection)) {
    return selection.map((it2) => parseSelectExpression(it2));
  } else {
    return [parseSelectExpression(selection)];
  }
}
function parseSelectExpression(selection) {
  if (isString(selection)) {
    return SelectionNode.create(parseAliasedStringReference(selection));
  } else if (isDynamicReferenceBuilder(selection)) {
    return SelectionNode.create(selection.toOperationNode());
  } else {
    return SelectionNode.create(parseAliasedExpression(selection));
  }
}
function parseSelectAll(table2) {
  if (!table2) {
    return [SelectionNode.createSelectAll()];
  } else if (Array.isArray(table2)) {
    return table2.map(parseSelectAllArg);
  } else {
    return [parseSelectAllArg(table2)];
  }
}
function parseSelectAllArg(table2) {
  if (isString(table2)) {
    return SelectionNode.createSelectAllFromTable(parseTable(table2));
  }
  throw new Error(`invalid value selectAll expression: ${JSON.stringify(table2)}`);
}
var init_select_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/select-parser.js"() {
    init_object_utils();
    init_selection_node();
    init_reference_parser();
    init_dynamic_reference_builder();
    init_expression_parser();
    init_table_parser();
    init_expression_builder();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/values-node.js
var ValuesNode;
var init_values_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/values-node.js"() {
    init_object_utils();
    ValuesNode = freeze({
      is(node) {
        return node.kind === "ValuesNode";
      },
      create(values) {
        return freeze({
          kind: "ValuesNode",
          values: freeze(values)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/default-insert-value-node.js
var DefaultInsertValueNode;
var init_default_insert_value_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/default-insert-value-node.js"() {
    init_object_utils();
    DefaultInsertValueNode = freeze({
      is(node) {
        return node.kind === "DefaultInsertValueNode";
      },
      create() {
        return freeze({
          kind: "DefaultInsertValueNode"
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/insert-values-parser.js
function parseInsertExpression(arg) {
  const objectOrList = isFunction(arg) ? arg(expressionBuilder()) : arg;
  const list5 = isReadonlyArray(objectOrList) ? objectOrList : freeze([objectOrList]);
  return parseInsertColumnsAndValues(list5);
}
function parseInsertColumnsAndValues(rows) {
  const columns = parseColumnNamesAndIndexes(rows);
  return [
    freeze([...columns.keys()].map(ColumnNode.create)),
    ValuesNode.create(rows.map((row) => parseRowValues(row, columns)))
  ];
}
function parseColumnNamesAndIndexes(rows) {
  const columns = /* @__PURE__ */ new Map();
  for (const row of rows) {
    const cols = Object.keys(row);
    for (const col of cols) {
      if (!columns.has(col) && row[col] !== void 0) {
        columns.set(col, columns.size);
      }
    }
  }
  return columns;
}
function parseRowValues(row, columns) {
  const rowColumns = Object.keys(row);
  const rowValues = Array.from({
    length: columns.size
  });
  let hasUndefinedOrComplexColumns = false;
  let indexedRowColumns = rowColumns.length;
  for (const col of rowColumns) {
    const columnIdx = columns.get(col);
    if (isUndefined(columnIdx)) {
      indexedRowColumns--;
      continue;
    }
    const value2 = row[col];
    if (isUndefined(value2) || isExpressionOrFactory(value2)) {
      hasUndefinedOrComplexColumns = true;
    }
    rowValues[columnIdx] = value2;
  }
  const hasMissingColumns = indexedRowColumns < columns.size;
  if (hasMissingColumns || hasUndefinedOrComplexColumns) {
    const defaultValue = DefaultInsertValueNode.create();
    return ValueListNode.create(rowValues.map((it2) => isUndefined(it2) ? defaultValue : parseValueExpression(it2)));
  }
  return PrimitiveValueListNode.create(rowValues);
}
var init_insert_values_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/insert-values-parser.js"() {
    init_column_node();
    init_primitive_value_list_node();
    init_value_list_node();
    init_object_utils();
    init_value_parser();
    init_values_node();
    init_expression_parser();
    init_default_insert_value_node();
    init_expression_builder();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/insert-query-node.js
var InsertQueryNode;
var init_insert_query_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/insert-query-node.js"() {
    init_object_utils();
    InsertQueryNode = freeze({
      is(node) {
        return node.kind === "InsertQueryNode";
      },
      create(into, withNode, replace) {
        return freeze({
          kind: "InsertQueryNode",
          into,
          ...withNode && { with: withNode },
          replace
        });
      },
      createWithoutInto() {
        return freeze({
          kind: "InsertQueryNode"
        });
      },
      cloneWith(insertQuery, props) {
        return freeze({
          ...insertQuery,
          ...props
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/update-query-node.js
var UpdateQueryNode;
var init_update_query_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/update-query-node.js"() {
    init_object_utils();
    init_from_node();
    UpdateQueryNode = freeze({
      is(node) {
        return node.kind === "UpdateQueryNode";
      },
      create(table2, withNode) {
        return freeze({
          kind: "UpdateQueryNode",
          table: table2,
          ...withNode && { with: withNode }
        });
      },
      createWithoutTable() {
        return freeze({
          kind: "UpdateQueryNode"
        });
      },
      cloneWithFromItems(updateQuery, fromItems) {
        return freeze({
          ...updateQuery,
          from: updateQuery.from ? FromNode.cloneWithFroms(updateQuery.from, fromItems) : FromNode.create(fromItems)
        });
      },
      cloneWithUpdates(updateQuery, updates) {
        return freeze({
          ...updateQuery,
          updates: updateQuery.updates ? freeze([...updateQuery.updates, ...updates]) : updates
        });
      },
      cloneWithLimit(updateQuery, limit) {
        return freeze({
          ...updateQuery,
          limit
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/using-node.js
var UsingNode;
var init_using_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/using-node.js"() {
    init_object_utils();
    UsingNode = freeze({
      is(node) {
        return node.kind === "UsingNode";
      },
      create(tables) {
        return freeze({
          kind: "UsingNode",
          tables: freeze(tables)
        });
      },
      cloneWithTables(using, tables) {
        return freeze({
          ...using,
          tables: freeze([...using.tables, ...tables])
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/delete-query-node.js
var DeleteQueryNode;
var init_delete_query_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/delete-query-node.js"() {
    init_object_utils();
    init_from_node();
    init_order_by_node();
    init_using_node();
    DeleteQueryNode = freeze({
      is(node) {
        return node.kind === "DeleteQueryNode";
      },
      create(fromItems, withNode) {
        return freeze({
          kind: "DeleteQueryNode",
          from: FromNode.create(fromItems),
          ...withNode && { with: withNode }
        });
      },
      cloneWithOrderByItems(deleteNode, items) {
        return freeze({
          ...deleteNode,
          orderBy: deleteNode.orderBy ? OrderByNode.cloneWithItems(deleteNode.orderBy, items) : OrderByNode.create(items)
        });
      },
      cloneWithoutOrderBy(deleteNode) {
        return freeze({
          ...deleteNode,
          orderBy: void 0
        });
      },
      cloneWithLimit(deleteNode, limit) {
        return freeze({
          ...deleteNode,
          limit
        });
      },
      cloneWithoutLimit(deleteNode) {
        return freeze({
          ...deleteNode,
          limit: void 0
        });
      },
      cloneWithUsing(deleteNode, tables) {
        return freeze({
          ...deleteNode,
          using: deleteNode.using !== void 0 ? UsingNode.cloneWithTables(deleteNode.using, tables) : UsingNode.create(tables)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/where-node.js
var WhereNode;
var init_where_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/where-node.js"() {
    init_object_utils();
    init_and_node();
    init_or_node();
    WhereNode = freeze({
      is(node) {
        return node.kind === "WhereNode";
      },
      create(filter) {
        return freeze({
          kind: "WhereNode",
          where: filter
        });
      },
      cloneWithOperation(whereNode, operator, operation) {
        return freeze({
          ...whereNode,
          where: operator === "And" ? AndNode.create(whereNode.where, operation) : OrNode.create(whereNode.where, operation)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/returning-node.js
var ReturningNode;
var init_returning_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/returning-node.js"() {
    init_object_utils();
    ReturningNode = freeze({
      is(node) {
        return node.kind === "ReturningNode";
      },
      create(selections) {
        return freeze({
          kind: "ReturningNode",
          selections: freeze(selections)
        });
      },
      cloneWithSelections(returning, selections) {
        return freeze({
          ...returning,
          selections: returning.selections ? freeze([...returning.selections, ...selections]) : freeze(selections)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/explain-node.js
var ExplainNode;
var init_explain_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/explain-node.js"() {
    init_object_utils();
    ExplainNode = freeze({
      is(node) {
        return node.kind === "ExplainNode";
      },
      create(format, options2) {
        return freeze({
          kind: "ExplainNode",
          format,
          options: options2
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/when-node.js
var WhenNode;
var init_when_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/when-node.js"() {
    init_object_utils();
    WhenNode = freeze({
      is(node) {
        return node.kind === "WhenNode";
      },
      create(condition) {
        return freeze({
          kind: "WhenNode",
          condition
        });
      },
      cloneWithResult(whenNode, result) {
        return freeze({
          ...whenNode,
          result
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/merge-query-node.js
var MergeQueryNode;
var init_merge_query_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/merge-query-node.js"() {
    init_object_utils();
    init_when_node();
    MergeQueryNode = freeze({
      is(node) {
        return node.kind === "MergeQueryNode";
      },
      create(into, withNode) {
        return freeze({
          kind: "MergeQueryNode",
          into,
          ...withNode && { with: withNode }
        });
      },
      cloneWithUsing(mergeNode, using) {
        return freeze({
          ...mergeNode,
          using
        });
      },
      cloneWithWhen(mergeNode, when) {
        return freeze({
          ...mergeNode,
          whens: mergeNode.whens ? freeze([...mergeNode.whens, when]) : freeze([when])
        });
      },
      cloneWithThen(mergeNode, then) {
        return freeze({
          ...mergeNode,
          whens: mergeNode.whens ? freeze([
            ...mergeNode.whens.slice(0, -1),
            WhenNode.cloneWithResult(mergeNode.whens[mergeNode.whens.length - 1], then)
          ]) : void 0
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/output-node.js
var OutputNode;
var init_output_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/output-node.js"() {
    init_object_utils();
    OutputNode = freeze({
      is(node) {
        return node.kind === "OutputNode";
      },
      create(selections) {
        return freeze({
          kind: "OutputNode",
          selections: freeze(selections)
        });
      },
      cloneWithSelections(output, selections) {
        return freeze({
          ...output,
          selections: output.selections ? freeze([...output.selections, ...selections]) : freeze(selections)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/query-node.js
var QueryNode;
var init_query_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/query-node.js"() {
    init_insert_query_node();
    init_select_query_node();
    init_update_query_node();
    init_delete_query_node();
    init_where_node();
    init_object_utils();
    init_returning_node();
    init_explain_node();
    init_merge_query_node();
    init_output_node();
    QueryNode = freeze({
      is(node) {
        return SelectQueryNode.is(node) || InsertQueryNode.is(node) || UpdateQueryNode.is(node) || DeleteQueryNode.is(node) || MergeQueryNode.is(node);
      },
      cloneWithEndModifier(node, modifier) {
        return freeze({
          ...node,
          endModifiers: node.endModifiers ? freeze([...node.endModifiers, modifier]) : freeze([modifier])
        });
      },
      cloneWithWhere(node, operation) {
        return freeze({
          ...node,
          where: node.where ? WhereNode.cloneWithOperation(node.where, "And", operation) : WhereNode.create(operation)
        });
      },
      cloneWithJoin(node, join4) {
        return freeze({
          ...node,
          joins: node.joins ? freeze([...node.joins, join4]) : freeze([join4])
        });
      },
      cloneWithReturning(node, selections) {
        return freeze({
          ...node,
          returning: node.returning ? ReturningNode.cloneWithSelections(node.returning, selections) : ReturningNode.create(selections)
        });
      },
      cloneWithoutReturning(node) {
        return freeze({
          ...node,
          returning: void 0
        });
      },
      cloneWithoutWhere(node) {
        return freeze({
          ...node,
          where: void 0
        });
      },
      cloneWithExplain(node, format, options2) {
        return freeze({
          ...node,
          explain: ExplainNode.create(format, options2?.toOperationNode())
        });
      },
      cloneWithTop(node, top) {
        return freeze({
          ...node,
          top
        });
      },
      cloneWithOutput(node, selections) {
        return freeze({
          ...node,
          output: node.output ? OutputNode.cloneWithSelections(node.output, selections) : OutputNode.create(selections)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/column-update-node.js
var ColumnUpdateNode;
var init_column_update_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/column-update-node.js"() {
    init_object_utils();
    ColumnUpdateNode = freeze({
      is(node) {
        return node.kind === "ColumnUpdateNode";
      },
      create(column, value2) {
        return freeze({
          kind: "ColumnUpdateNode",
          column,
          value: value2
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/update-set-parser.js
function parseUpdate(...args) {
  if (args.length === 2) {
    return [
      ColumnUpdateNode.create(parseReferenceExpression(args[0]), parseValueExpression(args[1]))
    ];
  }
  return parseUpdateObjectExpression(args[0]);
}
function parseUpdateObjectExpression(update4) {
  const updateObj = isFunction(update4) ? update4(expressionBuilder()) : update4;
  return Object.entries(updateObj).filter(([_3, value2]) => value2 !== void 0).map(([key2, value2]) => {
    return ColumnUpdateNode.create(ColumnNode.create(key2), parseValueExpression(value2));
  });
}
var init_update_set_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/update-set-parser.js"() {
    init_column_node();
    init_column_update_node();
    init_expression_builder();
    init_object_utils();
    init_value_parser();
    init_reference_parser();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/on-duplicate-key-node.js
var OnDuplicateKeyNode;
var init_on_duplicate_key_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/on-duplicate-key-node.js"() {
    init_object_utils();
    OnDuplicateKeyNode = freeze({
      is(node) {
        return node.kind === "OnDuplicateKeyNode";
      },
      create(updates) {
        return freeze({
          kind: "OnDuplicateKeyNode",
          updates
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/insert-result.js
var InsertResult;
var init_insert_result = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/insert-result.js"() {
    InsertResult = class {
      /**
       * The auto incrementing primary key of the inserted row.
       *
       * This property can be undefined when the query contains an `on conflict`
       * clause that makes the query succeed even when nothing gets inserted.
       *
       * This property is always undefined on dialects like PostgreSQL that
       * don't return the inserted id by default. On those dialects you need
       * to use the {@link ReturningInterface.returning | returning} method.
       */
      insertId;
      /**
       * Affected rows count.
       */
      numInsertedOrUpdatedRows;
      constructor(insertId, numInsertedOrUpdatedRows) {
        this.insertId = insertId;
        this.numInsertedOrUpdatedRows = numInsertedOrUpdatedRows;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/no-result-error.js
function isNoResultErrorConstructor(fn) {
  return Object.prototype.hasOwnProperty.call(fn, "prototype");
}
var NoResultError;
var init_no_result_error = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/no-result-error.js"() {
    NoResultError = class extends Error {
      /**
       * The operation node tree of the query that was executed.
       */
      node;
      constructor(node) {
        super("no result");
        this.node = node;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/on-conflict-node.js
var OnConflictNode;
var init_on_conflict_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/on-conflict-node.js"() {
    init_object_utils();
    init_where_node();
    OnConflictNode = freeze({
      is(node) {
        return node.kind === "OnConflictNode";
      },
      create() {
        return freeze({
          kind: "OnConflictNode"
        });
      },
      cloneWith(node, props) {
        return freeze({
          ...node,
          ...props
        });
      },
      cloneWithIndexWhere(node, operation) {
        return freeze({
          ...node,
          indexWhere: node.indexWhere ? WhereNode.cloneWithOperation(node.indexWhere, "And", operation) : WhereNode.create(operation)
        });
      },
      cloneWithIndexOrWhere(node, operation) {
        return freeze({
          ...node,
          indexWhere: node.indexWhere ? WhereNode.cloneWithOperation(node.indexWhere, "Or", operation) : WhereNode.create(operation)
        });
      },
      cloneWithUpdateWhere(node, operation) {
        return freeze({
          ...node,
          updateWhere: node.updateWhere ? WhereNode.cloneWithOperation(node.updateWhere, "And", operation) : WhereNode.create(operation)
        });
      },
      cloneWithUpdateOrWhere(node, operation) {
        return freeze({
          ...node,
          updateWhere: node.updateWhere ? WhereNode.cloneWithOperation(node.updateWhere, "Or", operation) : WhereNode.create(operation)
        });
      },
      cloneWithoutIndexWhere(node) {
        return freeze({
          ...node,
          indexWhere: void 0
        });
      },
      cloneWithoutUpdateWhere(node) {
        return freeze({
          ...node,
          updateWhere: void 0
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/on-conflict-builder.js
var OnConflictBuilder, OnConflictDoNothingBuilder, OnConflictUpdateBuilder;
var init_on_conflict_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/on-conflict-builder.js"() {
    init_column_node();
    init_identifier_node();
    init_on_conflict_node();
    init_binary_operation_parser();
    init_update_set_parser();
    init_object_utils();
    init_prevent_await();
    OnConflictBuilder = class _OnConflictBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Specify a single column as the conflict target.
       *
       * Also see the {@link columns}, {@link constraint} and {@link expression}
       * methods for alternative ways to specify the conflict target.
       */
      column(column) {
        const columnNode = ColumnNode.create(column);
        return new _OnConflictBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWith(this.#props.onConflictNode, {
            columns: this.#props.onConflictNode.columns ? freeze([...this.#props.onConflictNode.columns, columnNode]) : freeze([columnNode])
          })
        });
      }
      /**
       * Specify a list of columns as the conflict target.
       *
       * Also see the {@link column}, {@link constraint} and {@link expression}
       * methods for alternative ways to specify the conflict target.
       */
      columns(columns) {
        const columnNodes = columns.map(ColumnNode.create);
        return new _OnConflictBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWith(this.#props.onConflictNode, {
            columns: this.#props.onConflictNode.columns ? freeze([...this.#props.onConflictNode.columns, ...columnNodes]) : freeze(columnNodes)
          })
        });
      }
      /**
       * Specify a specific constraint by name as the conflict target.
       *
       * Also see the {@link column}, {@link columns} and {@link expression}
       * methods for alternative ways to specify the conflict target.
       */
      constraint(constraintName) {
        return new _OnConflictBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWith(this.#props.onConflictNode, {
            constraint: IdentifierNode.create(constraintName)
          })
        });
      }
      /**
       * Specify an expression as the conflict target.
       *
       * This can be used if the unique index is an expression index.
       *
       * Also see the {@link column}, {@link columns} and {@link constraint}
       * methods for alternative ways to specify the conflict target.
       */
      expression(expression) {
        return new _OnConflictBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWith(this.#props.onConflictNode, {
            indexExpression: expression.toOperationNode()
          })
        });
      }
      where(...args) {
        return new _OnConflictBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWithIndexWhere(this.#props.onConflictNode, parseValueBinaryOperationOrExpression(args))
        });
      }
      whereRef(lhs, op, rhs) {
        return new _OnConflictBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWithIndexWhere(this.#props.onConflictNode, parseReferentialBinaryOperation(lhs, op, rhs))
        });
      }
      clearWhere() {
        return new _OnConflictBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWithoutIndexWhere(this.#props.onConflictNode)
        });
      }
      /**
       * Adds the "do nothing" conflict action.
       *
       * ### Examples
       *
       * ```ts
       * const id = 1
       * const first_name = 'John'
       *
       * await db
       *   .insertInto('person')
       *   .values({ first_name, id })
       *   .onConflict((oc) => oc
       *     .column('id')
       *     .doNothing()
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "person" ("first_name", "id")
       * values ($1, $2)
       * on conflict ("id") do nothing
       * ```
       */
      doNothing() {
        return new OnConflictDoNothingBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWith(this.#props.onConflictNode, {
            doNothing: true
          })
        });
      }
      /**
       * Adds the "do update set" conflict action.
       *
       * ### Examples
       *
       * ```ts
       * const id = 1
       * const first_name = 'John'
       *
       * await db
       *   .insertInto('person')
       *   .values({ first_name, id })
       *   .onConflict((oc) => oc
       *     .column('id')
       *     .doUpdateSet({ first_name })
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "person" ("first_name", "id")
       * values ($1, $2)
       * on conflict ("id")
       * do update set "first_name" = $3
       * ```
       *
       * In the next example we use the `ref` method to reference
       * columns of the virtual table `excluded` in a type-safe way
       * to create an upsert operation:
       *
       * ```ts
       * import type { NewPerson } from 'type-editor' // imaginary module
       *
       * async function upsertPerson(person: NewPerson): Promise<void> {
       *   await db.insertInto('person')
       *     .values(person)
       *     .onConflict((oc) => oc
       *       .column('id')
       *       .doUpdateSet((eb) => ({
       *         first_name: eb.ref('excluded.first_name'),
       *         last_name: eb.ref('excluded.last_name')
       *       })
       *     )
       *   )
       *   .execute()
       * }
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "person" ("first_name", "last_name")
       * values ($1, $2)
       * on conflict ("id")
       * do update set
       *  "first_name" = excluded."first_name",
       *  "last_name" = excluded."last_name"
       * ```
       */
      doUpdateSet(update4) {
        return new OnConflictUpdateBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWith(this.#props.onConflictNode, {
            updates: parseUpdateObjectExpression(update4)
          })
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
    };
    preventAwait(OnConflictBuilder, "don't await OnConflictBuilder instances.");
    OnConflictDoNothingBuilder = class {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      toOperationNode() {
        return this.#props.onConflictNode;
      }
    };
    preventAwait(OnConflictDoNothingBuilder, "don't await OnConflictDoNothingBuilder instances.");
    OnConflictUpdateBuilder = class _OnConflictUpdateBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      where(...args) {
        return new _OnConflictUpdateBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWithUpdateWhere(this.#props.onConflictNode, parseValueBinaryOperationOrExpression(args))
        });
      }
      /**
       * Specify a where condition for the update operation.
       *
       * See {@link WhereInterface.whereRef} for more info.
       */
      whereRef(lhs, op, rhs) {
        return new _OnConflictUpdateBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWithUpdateWhere(this.#props.onConflictNode, parseReferentialBinaryOperation(lhs, op, rhs))
        });
      }
      clearWhere() {
        return new _OnConflictUpdateBuilder({
          ...this.#props,
          onConflictNode: OnConflictNode.cloneWithoutUpdateWhere(this.#props.onConflictNode)
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.onConflictNode;
      }
    };
    preventAwait(OnConflictUpdateBuilder, "don't await OnConflictUpdateBuilder instances.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/top-node.js
var TopNode;
var init_top_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/top-node.js"() {
    init_object_utils();
    TopNode = freeze({
      is(node) {
        return node.kind === "TopNode";
      },
      create(expression, modifiers) {
        return freeze({
          kind: "TopNode",
          expression,
          modifiers
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/top-parser.js
function parseTop(expression, modifiers) {
  if (!isNumber(expression) && !isBigInt(expression)) {
    throw new Error(`Invalid top expression: ${expression}`);
  }
  if (!isUndefined(modifiers) && !isTopModifiers(modifiers)) {
    throw new Error(`Invalid top modifiers: ${modifiers}`);
  }
  return TopNode.create(expression, modifiers);
}
function isTopModifiers(modifiers) {
  return modifiers === "percent" || modifiers === "with ties" || modifiers === "percent with ties";
}
var init_top_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/top-parser.js"() {
    init_top_node();
    init_object_utils();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/insert-query-builder.js
var InsertQueryBuilder;
var init_insert_query_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/insert-query-builder.js"() {
    init_select_parser();
    init_insert_values_parser();
    init_insert_query_node();
    init_query_node();
    init_update_set_parser();
    init_prevent_await();
    init_object_utils();
    init_on_duplicate_key_node();
    init_insert_result();
    init_no_result_error();
    init_expression_parser();
    init_column_node();
    init_on_conflict_builder();
    init_on_conflict_node();
    init_top_parser();
    InsertQueryBuilder = class _InsertQueryBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Sets the values to insert for an {@link Kysely.insertInto | insert} query.
       *
       * This method takes an object whose keys are column names and values are
       * values to insert. In addition to the column's type, the values can be
       * raw {@link sql} snippets or select queries.
       *
       * You must provide all fields you haven't explicitly marked as nullable
       * or optional using {@link Generated} or {@link ColumnType}.
       *
       * The return value of an `insert` query is an instance of {@link InsertResult}. The
       * {@link InsertResult.insertId | insertId} field holds the auto incremented primary
       * key if the database returned one.
       *
       * On PostgreSQL and some other dialects, you need to call `returning` to get
       * something out of the query.
       *
       * Also see the {@link expression} method for inserting the result of a select
       * query or any other expression.
       *
       * ### Examples
       *
       * <!-- siteExample("insert", "Single row", 10) -->
       *
       * Insert a single row:
       *
       * ```ts
       * const result = await db
       *   .insertInto('person')
       *   .values({
       *     first_name: 'Jennifer',
       *     last_name: 'Aniston',
       *     age: 40
       *   })
       *   .executeTakeFirst()
       *
       * // `insertId` is only available on dialects that
       * // automatically return the id of the inserted row
       * // such as MySQL and SQLite. On PostgreSQL, for example,
       * // you need to add a `returning` clause to the query to
       * // get anything out. See the "returning data" example.
       * console.log(result.insertId)
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * insert into `person` (`first_name`, `last_name`, `age`) values (?, ?, ?)
       * ```
       *
       * <!-- siteExample("insert", "Multiple rows", 20) -->
       *
       * On dialects that support it (for example PostgreSQL) you can insert multiple
       * rows by providing an array. Note that the return value is once again very
       * dialect-specific. Some databases may only return the id of the *last* inserted
       * row and some return nothing at all unless you call `returning`.
       *
       * ```ts
       * await db
       *   .insertInto('person')
       *   .values([{
       *     first_name: 'Jennifer',
       *     last_name: 'Aniston',
       *     age: 40,
       *   }, {
       *     first_name: 'Arnold',
       *     last_name: 'Schwarzenegger',
       *     age: 70,
       *   }])
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "person" ("first_name", "last_name", "age") values (($1, $2, $3), ($4, $5, $6))
       * ```
       *
       * <!-- siteExample("insert", "Returning data", 30) -->
       *
       * On supported dialects like PostgreSQL you need to chain `returning` to the query to get
       * the inserted row's columns (or any other expression) as the return value. `returning`
       * works just like `select`. Refer to `select` method's examples and documentation for
       * more info.
       *
       * ```ts
       * const result = await db
       *   .insertInto('person')
       *   .values({
       *     first_name: 'Jennifer',
       *     last_name: 'Aniston',
       *     age: 40,
       *   })
       *   .returning(['id', 'first_name as name'])
       *   .executeTakeFirstOrThrow()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "person" ("first_name", "last_name", "age") values ($1, $2, $3) returning "id", "first_name" as "name"
       * ```
       *
       * <!-- siteExample("insert", "Complex values", 40) -->
       *
       * In addition to primitives, the values can also be arbitrary expressions.
       * You can build the expressions by using a callback and calling the methods
       * on the expression builder passed to it:
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * const ani = "Ani"
       * const ston = "ston"
       *
       * const result = await db
       *   .insertInto('person')
       *   .values(({ ref, selectFrom, fn }) => ({
       *     first_name: 'Jennifer',
       *     last_name: sql<string>`concat(${ani}, ${ston})`,
       *     middle_name: ref('first_name'),
       *     age: selectFrom('person')
       *       .select(fn.avg<number>('age').as('avg_age')),
       *   }))
       *   .executeTakeFirst()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "person" (
       *   "first_name",
       *   "last_name",
       *   "middle_name",
       *   "age"
       * )
       * values (
       *   $1,
       *   concat($2, $3),
       *   "first_name",
       *   (select avg("age") as "avg_age" from "person")
       * )
       * ```
       *
       * You can also use the callback version of subqueries or raw expressions:
       *
       * ```ts
       * await db.with('jennifer', (db) => db
       *   .selectFrom('person')
       *   .where('first_name', '=', 'Jennifer')
       *   .select(['id', 'first_name', 'gender'])
       *   .limit(1)
       * ).insertInto('pet').values((eb) => ({
       *   owner_id: eb.selectFrom('jennifer').select('id'),
       *   name: eb.selectFrom('jennifer').select('first_name'),
       *   species: 'cat',
       * }))
       * .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * with "jennifer" as (
       *   select "id", "first_name", "gender"
       *   from "person"
       *   where "first_name" = $1
       *   limit $2
       * )
       * insert into "pet" ("owner_id", "name", "species")
       * values (
       *  (select "id" from "jennifer"),
       *  (select "first_name" from "jennifer"),
       *  $3
       * )
       * ```
       */
      values(insert) {
        const [columns, values] = parseInsertExpression(insert);
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: InsertQueryNode.cloneWith(this.#props.queryNode, {
            columns,
            values
          })
        });
      }
      /**
       * Sets the columns to insert.
       *
       * The {@link values} method sets both the columns and the values and this method
       * is not needed. But if you are using the {@link expression} method, you can use
       * this method to set the columns to insert.
       *
       * ### Examples
       *
       * ```ts
       * await db.insertInto('person')
       *   .columns(['first_name'])
       *   .expression((eb) => eb.selectFrom('pet').select('pet.name'))
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "person" ("first_name")
       * select "pet"."name" from "pet"
       * ```
       */
      columns(columns) {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: InsertQueryNode.cloneWith(this.#props.queryNode, {
            columns: freeze(columns.map(ColumnNode.create))
          })
        });
      }
      /**
       * Insert an arbitrary expression. For example the result of a select query.
       *
       * ### Examples
       *
       * <!-- siteExample("insert", "Insert subquery", 50) -->
       *
       * You can create an `INSERT INTO SELECT FROM` query using the `expression` method.
       * This API doesn't follow our WYSIWYG principles and might be a bit difficult to
       * remember. The reasons for this design stem from implementation difficulties.
       *
       * ```ts
       * const result = await db.insertInto('person')
       *   .columns(['first_name', 'last_name', 'age'])
       *   .expression((eb) => eb
       *     .selectFrom('pet')
       *     .select((eb) => [
       *       'pet.name',
       *       eb.val('Petson').as('last_name'),
       *       eb.lit(7).as('age'),
       *     ])
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "person" ("first_name", "last_name", "age")
       * select "pet"."name", $1 as "last_name", 7 as "age from "pet"
       * ```
       */
      expression(expression) {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: InsertQueryNode.cloneWith(this.#props.queryNode, {
            values: parseExpression(expression)
          })
        });
      }
      /**
       * Creates an `insert into "person" default values` query.
       *
       * ### Examples
       *
       * ```ts
       * await db.insertInto('person')
       *   .defaultValues()
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "person" default values
       * ```
       */
      defaultValues() {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: InsertQueryNode.cloneWith(this.#props.queryNode, {
            defaultValues: true
          })
        });
      }
      /**
       * This can be used to add any additional SQL to the end of the query.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.insertInto('person')
       *   .values({
       *     first_name: 'John',
       *     last_name: 'Doe',
       *     gender: 'male',
       *   })
       *   .modifyEnd(sql`-- This is a comment`)
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * insert into `person` ("first_name", "last_name", "gender")
       * values (?, ?, ?) -- This is a comment
       * ```
       */
      modifyEnd(modifier) {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, modifier.toOperationNode())
        });
      }
      /**
       * Changes an `insert into` query to an `insert ignore into` query.
       *
       * If you use the ignore modifier, ignorable errors that occur while executing the
       * insert statement are ignored. For example, without ignore, a row that duplicates
       * an existing unique index or primary key value in the table causes a duplicate-key
       * error and the statement is aborted. With ignore, the row is discarded and no error
       * occurs.
       *
       * This is only supported on some dialects like MySQL. On most dialects you should
       * use the {@link onConflict} method.
       *
       * ### Examples
       *
       * ```ts
       * await db.insertInto('person')
       *   .ignore()
       *   .values({
       *     first_name: 'John',
       *     last_name: 'Doe',
       *     gender: 'female',
       *   })
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * insert ignore into `person` ("first_name", "last_name", "gender") values (?, ?, ?)
       * ```
       */
      ignore() {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: InsertQueryNode.cloneWith(this.#props.queryNode, {
            ignore: true
          })
        });
      }
      /**
       * Changes an `insert into` query to an `insert top into` query.
       *
       * `top` clause is only supported by some dialects like MS SQL Server.
       *
       * ### Examples
       *
       * Insert the first 5 rows:
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.insertInto('person')
       *   .top(5)
       *   .columns(['first_name', 'gender'])
       *   .expression(
       *     (eb) => eb.selectFrom('pet').select(['name', sql.lit('other').as('gender')])
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (MS SQL Server):
       *
       * ```sql
       * insert top(5) into "person" ("first_name", "gender") select "name", 'other' as "gender" from "pet"
       * ```
       *
       * Insert the first 50 percent of rows:
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.insertInto('person')
       *   .top(50, 'percent')
       *   .columns(['first_name', 'gender'])
       *   .expression(
       *     (eb) => eb.selectFrom('pet').select(['name', sql.lit('other').as('gender')])
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (MS SQL Server):
       *
       * ```sql
       * insert top(50) percent into "person" ("first_name", "gender") select "name", 'other' as "gender" from "pet"
       * ```
       */
      top(expression, modifiers) {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithTop(this.#props.queryNode, parseTop(expression, modifiers))
        });
      }
      /**
       * Adds an `on conflict` clause to the query.
       *
       * `on conflict` is only supported by some dialects like PostgreSQL and SQLite. On MySQL
       * you can use {@link ignore} and {@link onDuplicateKeyUpdate} to achieve similar results.
       *
       * ### Examples
       *
       * ```ts
       * await db
       *   .insertInto('pet')
       *   .values({
       *     name: 'Catto',
       *     species: 'cat',
       *     owner_id: 3,
       *   })
       *   .onConflict((oc) => oc
       *     .column('name')
       *     .doUpdateSet({ species: 'hamster' })
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "pet" ("name", "species", "owner_id")
       * values ($1, $2, $3)
       * on conflict ("name")
       * do update set "species" = $4
       * ```
       *
       * You can provide the name of the constraint instead of a column name:
       *
       * ```ts
       * await db
       *   .insertInto('pet')
       *   .values({
       *     name: 'Catto',
       *     species: 'cat',
       *     owner_id: 3,
       *   })
       *   .onConflict((oc) => oc
       *     .constraint('pet_name_key')
       *     .doUpdateSet({ species: 'hamster' })
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "pet" ("name", "species", "owner_id")
       * values ($1, $2, $3)
       * on conflict on constraint "pet_name_key"
       * do update set "species" = $4
       * ```
       *
       * You can also specify an expression as the conflict target in case
       * the unique index is an expression index:
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db
       *   .insertInto('pet')
       *   .values({
       *     name: 'Catto',
       *     species: 'cat',
       *     owner_id: 3,
       *   })
       *   .onConflict((oc) => oc
       *     .expression(sql<string>`lower(name)`)
       *     .doUpdateSet({ species: 'hamster' })
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "pet" ("name", "species", "owner_id")
       * values ($1, $2, $3)
       * on conflict (lower(name))
       * do update set "species" = $4
       * ```
       *
       * You can add a filter for the update statement like this:
       *
       * ```ts
       * await db
       *   .insertInto('pet')
       *   .values({
       *     name: 'Catto',
       *     species: 'cat',
       *     owner_id: 3,
       *   })
       *   .onConflict((oc) => oc
       *     .column('name')
       *     .doUpdateSet({ species: 'hamster' })
       *     .where('excluded.name', '!=', 'Catto')
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "pet" ("name", "species", "owner_id")
       * values ($1, $2, $3)
       * on conflict ("name")
       * do update set "species" = $4
       * where "excluded"."name" != $5
       * ```
       *
       * You can create an `on conflict do nothing` clauses like this:
       *
       * ```ts
       * await db
       *   .insertInto('pet')
       *   .values({
       *     name: 'Catto',
       *     species: 'cat',
       *     owner_id: 3,
       *   })
       *   .onConflict((oc) => oc
       *     .column('name')
       *     .doNothing()
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "pet" ("name", "species", "owner_id")
       * values ($1, $2, $3)
       * on conflict ("name") do nothing
       * ```
       *
       * You can refer to the columns of the virtual `excluded` table
       * in a type-safe way using a callback and the `ref` method of
       * `ExpressionBuilder`:
       *
       * ```ts
       * await db.insertInto('person')
       *   .values({
       *     id: 1,
       *     first_name: 'John',
       *     last_name: 'Doe',
       *     gender: 'male',
       *   })
       *   .onConflict(oc => oc
       *     .column('id')
       *     .doUpdateSet({
       *       first_name: (eb) => eb.ref('excluded.first_name'),
       *       last_name: (eb) => eb.ref('excluded.last_name')
       *     })
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * insert into "person" ("id", "first_name", "last_name", "gender")
       * values ($1, $2, $3, $4)
       * on conflict ("id")
       * do update set
       *  "first_name" = "excluded"."first_name",
       *  "last_name" = "excluded"."last_name"
       * ```
       */
      onConflict(callback) {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: InsertQueryNode.cloneWith(this.#props.queryNode, {
            onConflict: callback(new OnConflictBuilder({
              onConflictNode: OnConflictNode.create()
            })).toOperationNode()
          })
        });
      }
      /**
       * Adds `on duplicate key update` to the query.
       *
       * If you specify `on duplicate key update`, and a row is inserted that would cause
       * a duplicate value in a unique index or primary key, an update of the old row occurs.
       *
       * This is only implemented by some dialects like MySQL. On most dialects you should
       * use {@link onConflict} instead.
       *
       * ### Examples
       *
       * ```ts
       * await db
       *   .insertInto('person')
       *   .values({
       *     id: 1,
       *     first_name: 'John',
       *     last_name: 'Doe',
       *     gender: 'male',
       *   })
       *   .onDuplicateKeyUpdate({ updated_at: new Date().toISOString() })
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * insert into `person` (`id`, `first_name`, `last_name`, `gender`)
       * values (?, ?, ?, ?)
       * on duplicate key update `updated_at` = ?
       * ```
       */
      onDuplicateKeyUpdate(update4) {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: InsertQueryNode.cloneWith(this.#props.queryNode, {
            onDuplicateKey: OnDuplicateKeyNode.create(parseUpdateObjectExpression(update4))
          })
        });
      }
      returning(selection) {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithReturning(this.#props.queryNode, parseSelectArg(selection))
        });
      }
      returningAll() {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithReturning(this.#props.queryNode, parseSelectAll())
        });
      }
      output(args) {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithOutput(this.#props.queryNode, parseSelectArg(args))
        });
      }
      outputAll(table2) {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithOutput(this.#props.queryNode, parseSelectAll(table2))
        });
      }
      /**
       * Clears all `returning` clauses from the query.
       *
       * ### Examples
       *
       * ```ts
       * await db.insertInto('person')
       *   .values({ first_name: 'James', last_name: 'Smith', gender: 'male' })
       *   .returning(['first_name'])
       *   .clearReturning()
       *   .execute()
       * ```
       *
       * The generated SQL(PostgreSQL):
       *
       * ```sql
       * insert into "person" ("first_name", "last_name", "gender") values ($1, $2, $3)
       * ```
       */
      clearReturning() {
        return new _InsertQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithoutReturning(this.#props.queryNode)
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       *
       * If you want to conditionally call a method on `this`, see
       * the {@link $if} method.
       *
       * ### Examples
       *
       * The next example uses a helper function `log` to log a query:
       *
       * ```ts
       * import type { Compilable } from 'kysely'
       *
       * function log<T extends Compilable>(qb: T): T {
       *   console.log(qb.compile())
       *   return qb
       * }
       *
       * await db.insertInto('person')
       *   .values({ first_name: 'John', last_name: 'Doe', gender: 'male' })
       *   .$call(log)
       *   .execute()
       * ```
       */
      $call(func) {
        return func(this);
      }
      /**
       * Call `func(this)` if `condition` is true.
       *
       * This method is especially handy with optional selects. Any `returning` or `returningAll`
       * method calls add columns as optional fields to the output type when called inside
       * the `func` callback. This is because we can't know if those selections were actually
       * made before running the code.
       *
       * You can also call any other methods inside the callback.
       *
       * ### Examples
       *
       * ```ts
       * import type { NewPerson } from 'type-editor' // imaginary module
       *
       * async function insertPerson(values: NewPerson, returnLastName: boolean) {
       *   return await db
       *     .insertInto('person')
       *     .values(values)
       *     .returning(['id', 'first_name'])
       *     .$if(returnLastName, (qb) => qb.returning('last_name'))
       *     .executeTakeFirstOrThrow()
       * }
       * ```
       *
       * Any selections added inside the `if` callback will be added as optional fields to the
       * output type since we can't know if the selections were actually made before running
       * the code. In the example above the return type of the `insertPerson` function is:
       *
       * ```ts
       * Promise<{
       *   id: number
       *   first_name: string
       *   last_name?: string
       * }>
       * ```
       */
      $if(condition, func) {
        if (condition) {
          return func(this);
        }
        return new _InsertQueryBuilder({
          ...this.#props
        });
      }
      /**
       * Change the output type of the query.
       *
       * This method call doesn't change the SQL in any way. This methods simply
       * returns a copy of this `InsertQueryBuilder` with a new output type.
       */
      $castTo() {
        return new _InsertQueryBuilder(this.#props);
      }
      /**
       * Narrows (parts of) the output type of the query.
       *
       * Kysely tries to be as type-safe as possible, but in some cases we have to make
       * compromises for better maintainability and compilation performance. At present,
       * Kysely doesn't narrow the output type of the query based on {@link values} input
       * when using {@link returning} or {@link returningAll}.
       *
       * This utility method is very useful for these situations, as it removes unncessary
       * runtime assertion/guard code. Its input type is limited to the output type
       * of the query, so you can't add a column that doesn't exist, or change a column's
       * type to something that doesn't exist in its union type.
       *
       * ### Examples
       *
       * Turn this code:
       *
       * ```ts
       * import type { Person } from 'type-editor' // imaginary module
       *
       * const person = await db.insertInto('person')
       *   .values({
       *     first_name: 'John',
       *     last_name: 'Doe',
       *     gender: 'male',
       *     nullable_column: 'hell yeah!'
       *   })
       *   .returningAll()
       *   .executeTakeFirstOrThrow()
       *
       * if (isWithNoNullValue(person)) {
       *   functionThatExpectsPersonWithNonNullValue(person)
       * }
       *
       * function isWithNoNullValue(person: Person): person is Person & { nullable_column: string } {
       *   return person.nullable_column != null
       * }
       * ```
       *
       * Into this:
       *
       * ```ts
       * import type { NotNull } from 'kysely'
       *
       * const person = await db.insertInto('person')
       *   .values({
       *     first_name: 'John',
       *     last_name: 'Doe',
       *     gender: 'male',
       *     nullable_column: 'hell yeah!'
       *   })
       *   .returningAll()
       *   .$narrowType<{ nullable_column: NotNull }>()
       *   .executeTakeFirstOrThrow()
       *
       * functionThatExpectsPersonWithNonNullValue(person)
       * ```
       */
      $narrowType() {
        return new _InsertQueryBuilder(this.#props);
      }
      /**
       * Asserts that query's output row type equals the given type `T`.
       *
       * This method can be used to simplify excessively complex types to make TypeScript happy
       * and much faster.
       *
       * Kysely uses complex type magic to achieve its type safety. This complexity is sometimes too much
       * for TypeScript and you get errors like this:
       *
       * ```
       * error TS2589: Type instantiation is excessively deep and possibly infinite.
       * ```
       *
       * In these case you can often use this method to help TypeScript a little bit. When you use this
       * method to assert the output type of a query, Kysely can drop the complex output type that
       * consists of multiple nested helper types and replace it with the simple asserted type.
       *
       * Using this method doesn't reduce type safety at all. You have to pass in a type that is
       * structurally equal to the current type.
       *
       * ### Examples
       *
       * ```ts
       * import type { NewPerson, NewPet, Species } from 'type-editor' // imaginary module
       *
       * async function insertPersonAndPet(person: NewPerson, pet: Omit<NewPet, 'owner_id'>) {
       *   return await db
       *     .with('new_person', (qb) => qb
       *       .insertInto('person')
       *       .values(person)
       *       .returning('id')
       *       .$assertType<{ id: number }>()
       *     )
       *     .with('new_pet', (qb) => qb
       *       .insertInto('pet')
       *       .values((eb) => ({
       *         owner_id: eb.selectFrom('new_person').select('id'),
       *         ...pet
       *       }))
       *       .returning(['name as pet_name', 'species'])
       *       .$assertType<{ pet_name: string, species: Species }>()
       *     )
       *     .selectFrom(['new_person', 'new_pet'])
       *     .selectAll()
       *     .executeTakeFirstOrThrow()
       * }
       * ```
       */
      $assertType() {
        return new _InsertQueryBuilder(this.#props);
      }
      /**
       * Returns a copy of this InsertQueryBuilder instance with the given plugin installed.
       */
      withPlugin(plugin) {
        return new _InsertQueryBuilder({
          ...this.#props,
          executor: this.#props.executor.withPlugin(plugin)
        });
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.queryNode, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      /**
       * Executes the query and returns an array of rows.
       *
       * Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
       */
      async execute() {
        const compiledQuery = this.compile();
        const result = await this.#props.executor.executeQuery(compiledQuery, this.#props.queryId);
        const { adapter } = this.#props.executor;
        const query = compiledQuery.query;
        if (query.returning && adapter.supportsReturning || query.output && adapter.supportsOutput) {
          return result.rows;
        }
        return [
          new InsertResult(
            result.insertId,
            // TODO: remove numUpdatedOrDeletedRows.
            result.numAffectedRows ?? result.numUpdatedOrDeletedRows
          )
        ];
      }
      /**
       * Executes the query and returns the first result or undefined if
       * the query returned no result.
       */
      async executeTakeFirst() {
        const [result] = await this.execute();
        return result;
      }
      /**
       * Executes the query and returns the first result or throws if
       * the query returned no result.
       *
       * By default an instance of {@link NoResultError} is thrown, but you can
       * provide a custom error class, or callback as the only argument to throw a different
       * error.
       */
      async executeTakeFirstOrThrow(errorConstructor = NoResultError) {
        const result = await this.executeTakeFirst();
        if (result === void 0) {
          const error2 = isNoResultErrorConstructor(errorConstructor) ? new errorConstructor(this.toOperationNode()) : errorConstructor(this.toOperationNode());
          throw error2;
        }
        return result;
      }
      async *stream(chunkSize = 100) {
        const compiledQuery = this.compile();
        const stream = this.#props.executor.stream(compiledQuery, chunkSize, this.#props.queryId);
        for await (const item of stream) {
          yield* item.rows;
        }
      }
      async explain(format, options2) {
        const builder = new _InsertQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithExplain(this.#props.queryNode, format, options2)
        });
        return await builder.execute();
      }
    };
    preventAwait(InsertQueryBuilder, "don't await InsertQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/delete-result.js
var DeleteResult;
var init_delete_result = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/delete-result.js"() {
    DeleteResult = class {
      numDeletedRows;
      constructor(numDeletedRows) {
        this.numDeletedRows = numDeletedRows;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/limit-node.js
var LimitNode;
var init_limit_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/limit-node.js"() {
    init_object_utils();
    LimitNode = freeze({
      is(node) {
        return node.kind === "LimitNode";
      },
      create(limit) {
        return freeze({
          kind: "LimitNode",
          limit
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/delete-query-builder.js
var DeleteQueryBuilder;
var init_delete_query_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/delete-query-builder.js"() {
    init_join_parser();
    init_table_parser();
    init_select_parser();
    init_query_node();
    init_prevent_await();
    init_object_utils();
    init_no_result_error();
    init_delete_result();
    init_delete_query_node();
    init_limit_node();
    init_order_by_parser();
    init_binary_operation_parser();
    init_value_parser();
    init_top_parser();
    DeleteQueryBuilder = class _DeleteQueryBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      where(...args) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseValueBinaryOperationOrExpression(args))
        });
      }
      whereRef(lhs, op, rhs) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseReferentialBinaryOperation(lhs, op, rhs))
        });
      }
      clearWhere() {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithoutWhere(this.#props.queryNode)
        });
      }
      /**
       * Changes a `delete from` query into a `delete top from` query.
       *
       * `top` clause is only supported by some dialects like MS SQL Server.
       *
       * ### Examples
       *
       * Delete the first 5 rows:
       *
       * ```ts
       * await db
       *   .deleteFrom('person')
       *   .top(5)
       *   .where('age', '>', 18)
       *   .executeTakeFirstOrThrow()
       * ```
       *
       * The generated SQL (MS SQL Server):
       *
       * ```sql
       * delete top(5) from "person" where "age" > @1
       * ```
       *
       * Delete the first 50% of rows:
       *
       * ```ts
       * await db
       *   .deleteFrom('person')
       *   .top(50, 'percent')
       *   .where('age', '>', 18)
       *   .executeTakeFirstOrThrow()
       * ```
       *
       * The generated SQL (MS SQL Server):
       *
       * ```sql
       * delete top(50) percent from "person" where "age" > @1
       * ```
       */
      top(expression, modifiers) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithTop(this.#props.queryNode, parseTop(expression, modifiers))
        });
      }
      using(tables) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: DeleteQueryNode.cloneWithUsing(this.#props.queryNode, parseTableExpressionOrList(tables))
        });
      }
      innerJoin(...args) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("InnerJoin", args))
        });
      }
      leftJoin(...args) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("LeftJoin", args))
        });
      }
      rightJoin(...args) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("RightJoin", args))
        });
      }
      fullJoin(...args) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("FullJoin", args))
        });
      }
      returning(selection) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithReturning(this.#props.queryNode, parseSelectArg(selection))
        });
      }
      returningAll(table2) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithReturning(this.#props.queryNode, parseSelectAll(table2))
        });
      }
      output(args) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithOutput(this.#props.queryNode, parseSelectArg(args))
        });
      }
      outputAll(table2) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithOutput(this.#props.queryNode, parseSelectAll(table2))
        });
      }
      /**
       * Clears all `returning` clauses from the query.
       *
       * ### Examples
       *
       * ```ts
       * await db.deleteFrom('pet')
       *   .returningAll()
       *   .where('name', '=', 'Max')
       *   .clearReturning()
       *   .execute()
       * ```
       *
       * The generated SQL(PostgreSQL):
       *
       * ```sql
       * delete from "pet" where "name" = "Max"
       * ```
       */
      clearReturning() {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithoutReturning(this.#props.queryNode)
        });
      }
      /**
       * Clears the `limit` clause from the query.
       *
       * ### Examples
       *
       * ```ts
       * await db.deleteFrom('pet')
       *   .returningAll()
       *   .where('name', '=', 'Max')
       *   .limit(5)
       *   .clearLimit()
       *   .execute()
       * ```
       *
       * The generated SQL(PostgreSQL):
       *
       * ```sql
       * delete from "pet" where "name" = "Max" returning *
       * ```
       */
      clearLimit() {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: DeleteQueryNode.cloneWithoutLimit(this.#props.queryNode)
        });
      }
      /**
       * Clears the `order by` clause from the query.
       *
       * ### Examples
       *
       * ```ts
       * await db.deleteFrom('pet')
       *   .returningAll()
       *   .where('name', '=', 'Max')
       *   .orderBy('id')
       *   .clearOrderBy()
       *   .execute()
       * ```
       *
       * The generated SQL(PostgreSQL):
       *
       * ```sql
       * delete from "pet" where "name" = "Max" returning *
       * ```
       */
      clearOrderBy() {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: DeleteQueryNode.cloneWithoutOrderBy(this.#props.queryNode)
        });
      }
      /**
       * Adds an `order by` clause to the query.
       *
       * `orderBy` calls are additive. To order by multiple columns, call `orderBy`
       * multiple times.
       *
       * The first argument is the expression to order by and the second is the
       * order (`asc` or `desc`).
       *
       * An `order by` clause in a delete query is only supported by some dialects
       * like MySQL.
       *
       * See {@link SelectQueryBuilder.orderBy} for more examples.
       *
       * ### Examples
       *
       * Delete 5 oldest items in a table:
       *
       * ```ts
       * await db
       *   .deleteFrom('pet')
       *   .orderBy('created_at')
       *   .limit(5)
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * delete from `pet`
       * order by `created_at`
       * limit ?
       * ```
       */
      orderBy(orderBy, direction) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: DeleteQueryNode.cloneWithOrderByItems(this.#props.queryNode, parseOrderBy([orderBy, direction]))
        });
      }
      /**
       * Adds a limit clause to the query.
       *
       * A limit clause in a delete query is only supported by some dialects
       * like MySQL.
       *
       * ### Examples
       *
       * Delete 5 oldest items in a table:
       *
       * ```ts
       * await db
       *   .deleteFrom('pet')
       *   .orderBy('created_at')
       *   .limit(5)
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * delete from `pet` order by `created_at` limit ?
       * ```
       */
      limit(limit) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: DeleteQueryNode.cloneWithLimit(this.#props.queryNode, LimitNode.create(parseValueExpression(limit)))
        });
      }
      /**
       * This can be used to add any additional SQL to the end of the query.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.deleteFrom('person')
       *   .where('first_name', '=', 'John')
       *   .modifyEnd(sql`-- This is a comment`)
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * delete from `person`
       * where `first_name` = "John" -- This is a comment
       * ```
       */
      modifyEnd(modifier) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, modifier.toOperationNode())
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       *
       * If you want to conditionally call a method on `this`, see
       * the {@link $if} method.
       *
       * ### Examples
       *
       * The next example uses a helper function `log` to log a query:
       *
       * ```ts
       * import type { Compilable } from 'kysely'
       *
       * function log<T extends Compilable>(qb: T): T {
       *   console.log(qb.compile())
       *   return qb
       * }
       *
       * await db.deleteFrom('person')
       *   .$call(log)
       *   .execute()
       * ```
       */
      $call(func) {
        return func(this);
      }
      /**
       * Call `func(this)` if `condition` is true.
       *
       * This method is especially handy with optional selects. Any `returning` or `returningAll`
       * method calls add columns as optional fields to the output type when called inside
       * the `func` callback. This is because we can't know if those selections were actually
       * made before running the code.
       *
       * You can also call any other methods inside the callback.
       *
       * ### Examples
       *
       * ```ts
       * async function deletePerson(id: number, returnLastName: boolean) {
       *   return await db
       *     .deleteFrom('person')
       *     .where('id', '=', id)
       *     .returning(['id', 'first_name'])
       *     .$if(returnLastName, (qb) => qb.returning('last_name'))
       *     .executeTakeFirstOrThrow()
       * }
       * ```
       *
       * Any selections added inside the `if` callback will be added as optional fields to the
       * output type since we can't know if the selections were actually made before running
       * the code. In the example above the return type of the `deletePerson` function is:
       *
       * ```ts
       * Promise<{
       *   id: number
       *   first_name: string
       *   last_name?: string
       * }>
       * ```
       */
      $if(condition, func) {
        if (condition) {
          return func(this);
        }
        return new _DeleteQueryBuilder({
          ...this.#props
        });
      }
      /**
       * Change the output type of the query.
       *
       * This method call doesn't change the SQL in any way. This methods simply
       * returns a copy of this `DeleteQueryBuilder` with a new output type.
       */
      $castTo() {
        return new _DeleteQueryBuilder(this.#props);
      }
      /**
       * Narrows (parts of) the output type of the query.
       *
       * Kysely tries to be as type-safe as possible, but in some cases we have to make
       * compromises for better maintainability and compilation performance. At present,
       * Kysely doesn't narrow the output type of the query when using {@link where} and {@link returning} or {@link returningAll}.
       *
       * This utility method is very useful for these situations, as it removes unncessary
       * runtime assertion/guard code. Its input type is limited to the output type
       * of the query, so you can't add a column that doesn't exist, or change a column's
       * type to something that doesn't exist in its union type.
       *
       * ### Examples
       *
       * Turn this code:
       *
       * ```ts
       * import type { Person } from 'type-editor' // imaginary module
       *
       * const person = await db.deleteFrom('person')
       *   .where('id', '=', 3)
       *   .where('nullable_column', 'is not', null)
       *   .returningAll()
       *   .executeTakeFirstOrThrow()
       *
       * if (isWithNoNullValue(person)) {
       *   functionThatExpectsPersonWithNonNullValue(person)
       * }
       *
       * function isWithNoNullValue(person: Person): person is Person & { nullable_column: string } {
       *   return person.nullable_column != null
       * }
       * ```
       *
       * Into this:
       *
       * ```ts
       * import type { NotNull } from 'kysely'
       *
       * const person = await db.deleteFrom('person')
       *   .where('id', '=', 3)
       *   .where('nullable_column', 'is not', null)
       *   .returningAll()
       *   .$narrowType<{ nullable_column: NotNull }>()
       *   .executeTakeFirstOrThrow()
       *
       * functionThatExpectsPersonWithNonNullValue(person)
       * ```
       */
      $narrowType() {
        return new _DeleteQueryBuilder(this.#props);
      }
      /**
       * Asserts that query's output row type equals the given type `T`.
       *
       * This method can be used to simplify excessively complex types to make TypeScript happy
       * and much faster.
       *
       * Kysely uses complex type magic to achieve its type safety. This complexity is sometimes too much
       * for TypeScript and you get errors like this:
       *
       * ```
       * error TS2589: Type instantiation is excessively deep and possibly infinite.
       * ```
       *
       * In these case you can often use this method to help TypeScript a little bit. When you use this
       * method to assert the output type of a query, Kysely can drop the complex output type that
       * consists of multiple nested helper types and replace it with the simple asserted type.
       *
       * Using this method doesn't reduce type safety at all. You have to pass in a type that is
       * structurally equal to the current type.
       *
       * ### Examples
       *
       * ```ts
       * import type { Species } from 'type-editor' // imaginary module
       *
       * async function deletePersonAndPets(personId: number) {
       *   return await db
       *     .with('deleted_person', (qb) => qb
       *        .deleteFrom('person')
       *        .where('id', '=', personId)
       *        .returning('first_name')
       *        .$assertType<{ first_name: string }>()
       *     )
       *     .with('deleted_pets', (qb) => qb
       *       .deleteFrom('pet')
       *       .where('owner_id', '=', personId)
       *       .returning(['name as pet_name', 'species'])
       *       .$assertType<{ pet_name: string, species: Species }>()
       *     )
       *     .selectFrom(['deleted_person', 'deleted_pets'])
       *     .selectAll()
       *     .execute()
       * }
       * ```
       */
      $assertType() {
        return new _DeleteQueryBuilder(this.#props);
      }
      /**
       * Returns a copy of this DeleteQueryBuilder instance with the given plugin installed.
       */
      withPlugin(plugin) {
        return new _DeleteQueryBuilder({
          ...this.#props,
          executor: this.#props.executor.withPlugin(plugin)
        });
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.queryNode, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      /**
       * Executes the query and returns an array of rows.
       *
       * Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
       */
      async execute() {
        const compiledQuery = this.compile();
        const result = await this.#props.executor.executeQuery(compiledQuery, this.#props.queryId);
        const { adapter } = this.#props.executor;
        const query = compiledQuery.query;
        if (query.returning && adapter.supportsReturning || query.output && adapter.supportsOutput) {
          return result.rows;
        }
        return [
          new DeleteResult(
            // TODO: remove numUpdatedOrDeletedRows.
            result.numAffectedRows ?? result.numUpdatedOrDeletedRows ?? BigInt(0)
          )
        ];
      }
      /**
       * Executes the query and returns the first result or undefined if
       * the query returned no result.
       */
      async executeTakeFirst() {
        const [result] = await this.execute();
        return result;
      }
      /**
       * Executes the query and returns the first result or throws if
       * the query returned no result.
       *
       * By default an instance of {@link NoResultError} is thrown, but you can
       * provide a custom error class, or callback as the only argument to throw a different
       * error.
       */
      async executeTakeFirstOrThrow(errorConstructor = NoResultError) {
        const result = await this.executeTakeFirst();
        if (result === void 0) {
          const error2 = isNoResultErrorConstructor(errorConstructor) ? new errorConstructor(this.toOperationNode()) : errorConstructor(this.toOperationNode());
          throw error2;
        }
        return result;
      }
      async *stream(chunkSize = 100) {
        const compiledQuery = this.compile();
        const stream = this.#props.executor.stream(compiledQuery, chunkSize, this.#props.queryId);
        for await (const item of stream) {
          yield* item.rows;
        }
      }
      async explain(format, options2) {
        const builder = new _DeleteQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithExplain(this.#props.queryNode, format, options2)
        });
        return await builder.execute();
      }
    };
    preventAwait(DeleteQueryBuilder, "don't await DeleteQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/update-result.js
var UpdateResult;
var init_update_result = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/update-result.js"() {
    UpdateResult = class {
      /**
       * The number of rows the update query updated (even if not changed).
       */
      numUpdatedRows;
      /**
       * The number of rows the update query changed.
       *
       * This is **optional** and only supported in dialects such as MySQL.
       * You would probably use {@link numUpdatedRows} in most cases.
       */
      numChangedRows;
      constructor(numUpdatedRows, numChangedRows) {
        this.numUpdatedRows = numUpdatedRows;
        this.numChangedRows = numChangedRows;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/update-query-builder.js
var UpdateQueryBuilder;
var init_update_query_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/update-query-builder.js"() {
    init_join_parser();
    init_table_parser();
    init_select_parser();
    init_query_node();
    init_update_query_node();
    init_update_set_parser();
    init_prevent_await();
    init_object_utils();
    init_update_result();
    init_no_result_error();
    init_binary_operation_parser();
    init_value_parser();
    init_limit_node();
    init_top_parser();
    UpdateQueryBuilder = class _UpdateQueryBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      where(...args) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseValueBinaryOperationOrExpression(args))
        });
      }
      whereRef(lhs, op, rhs) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseReferentialBinaryOperation(lhs, op, rhs))
        });
      }
      clearWhere() {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithoutWhere(this.#props.queryNode)
        });
      }
      /**
       * Changes an `update` query into a `update top` query.
       *
       * `top` clause is only supported by some dialects like MS SQL Server.
       *
       * ### Examples
       *
       * Update the first row:
       *
       * ```ts
       * await db.updateTable('person')
       *   .top(1)
       *   .set({ first_name: 'Foo' })
       *   .where('age', '>', 18)
       *   .executeTakeFirstOrThrow()
       * ```
       *
       * The generated SQL (MS SQL Server):
       *
       * ```sql
       * update top(1) "person" set "first_name" = @1 where "age" > @2
       * ```
       *
       * Update the 50% first rows:
       *
       * ```ts
       * await db.updateTable('person')
       *   .top(50, 'percent')
       *   .set({ first_name: 'Foo' })
       *   .where('age', '>', 18)
       *   .executeTakeFirstOrThrow()
       * ```
       *
       * The generated SQL (MS SQL Server):
       *
       * ```sql
       * update top(50) percent "person" set "first_name" = @1 where "age" > @2
       * ```
       */
      top(expression, modifiers) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithTop(this.#props.queryNode, parseTop(expression, modifiers))
        });
      }
      from(from) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: UpdateQueryNode.cloneWithFromItems(this.#props.queryNode, parseTableExpressionOrList(from))
        });
      }
      innerJoin(...args) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("InnerJoin", args))
        });
      }
      leftJoin(...args) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("LeftJoin", args))
        });
      }
      rightJoin(...args) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("RightJoin", args))
        });
      }
      fullJoin(...args) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("FullJoin", args))
        });
      }
      /**
       * Adds a limit clause to the update query for supported databases, such as MySQL.
       *
       * ### Examples
       *
       * Update the first 2 rows in the 'person' table:
       *
       * ```ts
       * await db
       *   .updateTable('person')
       *   .set({ first_name: 'Foo' })
       *   .limit(2)
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * update `person` set `first_name` = ? limit ?
       * ```
       */
      limit(limit) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: UpdateQueryNode.cloneWithLimit(this.#props.queryNode, LimitNode.create(parseValueExpression(limit)))
        });
      }
      set(...args) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: UpdateQueryNode.cloneWithUpdates(this.#props.queryNode, parseUpdate(...args))
        });
      }
      returning(selection) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithReturning(this.#props.queryNode, parseSelectArg(selection))
        });
      }
      returningAll(table2) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithReturning(this.#props.queryNode, parseSelectAll(table2))
        });
      }
      output(args) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithOutput(this.#props.queryNode, parseSelectArg(args))
        });
      }
      outputAll(table2) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithOutput(this.#props.queryNode, parseSelectAll(table2))
        });
      }
      /**
       * This can be used to add any additional SQL to the end of the query.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.updateTable('person')
       *   .set({ age: 39 })
       *   .where('first_name', '=', 'John')
       *   .modifyEnd(sql.raw('-- This is a comment'))
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * update `person`
       * set `age` = 39
       * where `first_name` = "John" -- This is a comment
       * ```
       */
      modifyEnd(modifier) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, modifier.toOperationNode())
        });
      }
      /**
       * Clears all `returning` clauses from the query.
       *
       * ### Examples
       *
       * ```ts
       * db.updateTable('person')
       *   .returningAll()
       *   .set({ age: 39 })
       *   .where('first_name', '=', 'John')
       *   .clearReturning()
       * ```
       *
       * The generated SQL(PostgreSQL):
       *
       * ```sql
       * update "person" set "age" = 39 where "first_name" = "John"
       * ```
       */
      clearReturning() {
        return new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithoutReturning(this.#props.queryNode)
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       *
       * If you want to conditionally call a method on `this`, see
       * the {@link $if} method.
       *
       * ### Examples
       *
       * The next example uses a helper function `log` to log a query:
       *
       * ```ts
       * import type { Compilable } from 'kysely'
       * import type { PersonUpdate } from 'type-editor' // imaginary module
       *
       * function log<T extends Compilable>(qb: T): T {
       *   console.log(qb.compile())
       *   return qb
       * }
       *
       * const values = {
       *   first_name: 'John',
       * } satisfies PersonUpdate
       *
       * db.updateTable('person')
       *   .set(values)
       *   .$call(log)
       *   .execute()
       * ```
       */
      $call(func) {
        return func(this);
      }
      /**
       * Call `func(this)` if `condition` is true.
       *
       * This method is especially handy with optional selects. Any `returning` or `returningAll`
       * method calls add columns as optional fields to the output type when called inside
       * the `func` callback. This is because we can't know if those selections were actually
       * made before running the code.
       *
       * You can also call any other methods inside the callback.
       *
       * ### Examples
       *
       * ```ts
       * import type { PersonUpdate } from 'type-editor' // imaginary module
       *
       * async function updatePerson(id: number, updates: PersonUpdate, returnLastName: boolean) {
       *   return await db
       *     .updateTable('person')
       *     .set(updates)
       *     .where('id', '=', id)
       *     .returning(['id', 'first_name'])
       *     .$if(returnLastName, (qb) => qb.returning('last_name'))
       *     .executeTakeFirstOrThrow()
       * }
       * ```
       *
       * Any selections added inside the `if` callback will be added as optional fields to the
       * output type since we can't know if the selections were actually made before running
       * the code. In the example above the return type of the `updatePerson` function is:
       *
       * ```ts
       * Promise<{
       *   id: number
       *   first_name: string
       *   last_name?: string
       * }>
       * ```
       */
      $if(condition, func) {
        if (condition) {
          return func(this);
        }
        return new _UpdateQueryBuilder({
          ...this.#props
        });
      }
      /**
       * Change the output type of the query.
       *
       * This method call doesn't change the SQL in any way. This methods simply
       * returns a copy of this `UpdateQueryBuilder` with a new output type.
       */
      $castTo() {
        return new _UpdateQueryBuilder(this.#props);
      }
      /**
       * Narrows (parts of) the output type of the query.
       *
       * Kysely tries to be as type-safe as possible, but in some cases we have to make
       * compromises for better maintainability and compilation performance. At present,
       * Kysely doesn't narrow the output type of the query based on {@link set} input
       * when using {@link where} and/or {@link returning} or {@link returningAll}.
       *
       * This utility method is very useful for these situations, as it removes unncessary
       * runtime assertion/guard code. Its input type is limited to the output type
       * of the query, so you can't add a column that doesn't exist, or change a column's
       * type to something that doesn't exist in its union type.
       *
       * ### Examples
       *
       * Turn this code:
       *
       * ```ts
       * import type { Person } from 'type-editor' // imaginary module
       *
       * const id = 1
       * const now = new Date().toISOString()
       *
       * const person = await db.updateTable('person')
       *   .set({ deleted_at: now })
       *   .where('id', '=', id)
       *   .where('nullable_column', 'is not', null)
       *   .returningAll()
       *   .executeTakeFirstOrThrow()
       *
       * if (isWithNoNullValue(person)) {
       *   functionThatExpectsPersonWithNonNullValue(person)
       * }
       *
       * function isWithNoNullValue(person: Person): person is Person & { nullable_column: string } {
       *   return person.nullable_column != null
       * }
       * ```
       *
       * Into this:
       *
       * ```ts
       * import type { NotNull } from 'kysely'
       *
       * const id = 1
       * const now = new Date().toISOString()
       *
       * const person = await db.updateTable('person')
       *   .set({ deleted_at: now })
       *   .where('id', '=', id)
       *   .where('nullable_column', 'is not', null)
       *   .returningAll()
       *   .$narrowType<{ deleted_at: Date; nullable_column: NotNull }>()
       *   .executeTakeFirstOrThrow()
       *
       * functionThatExpectsPersonWithNonNullValue(person)
       * ```
       */
      $narrowType() {
        return new _UpdateQueryBuilder(this.#props);
      }
      /**
       * Asserts that query's output row type equals the given type `T`.
       *
       * This method can be used to simplify excessively complex types to make TypeScript happy
       * and much faster.
       *
       * Kysely uses complex type magic to achieve its type safety. This complexity is sometimes too much
       * for TypeScript and you get errors like this:
       *
       * ```
       * error TS2589: Type instantiation is excessively deep and possibly infinite.
       * ```
       *
       * In these case you can often use this method to help TypeScript a little bit. When you use this
       * method to assert the output type of a query, Kysely can drop the complex output type that
       * consists of multiple nested helper types and replace it with the simple asserted type.
       *
       * Using this method doesn't reduce type safety at all. You have to pass in a type that is
       * structurally equal to the current type.
       *
       * ### Examples
       *
       * ```ts
       * import type { PersonUpdate, PetUpdate, Species } from 'type-editor' // imaginary module
       *
       * const person = {
       *   id: 1,
       *   gender: 'other',
       * } satisfies PersonUpdate
       *
       * const pet = {
       *   name: 'Fluffy',
       * } satisfies PetUpdate
       *
       * const result = await db
       *   .with('updated_person', (qb) => qb
       *     .updateTable('person')
       *     .set(person)
       *     .where('id', '=', person.id)
       *     .returning('first_name')
       *     .$assertType<{ first_name: string }>()
       *   )
       *   .with('updated_pet', (qb) => qb
       *     .updateTable('pet')
       *     .set(pet)
       *     .where('owner_id', '=', person.id)
       *     .returning(['name as pet_name', 'species'])
       *     .$assertType<{ pet_name: string, species: Species }>()
       *   )
       *   .selectFrom(['updated_person', 'updated_pet'])
       *   .selectAll()
       *   .executeTakeFirstOrThrow()
       * ```
       */
      $assertType() {
        return new _UpdateQueryBuilder(this.#props);
      }
      /**
       * Returns a copy of this UpdateQueryBuilder instance with the given plugin installed.
       */
      withPlugin(plugin) {
        return new _UpdateQueryBuilder({
          ...this.#props,
          executor: this.#props.executor.withPlugin(plugin)
        });
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.queryNode, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      /**
       * Executes the query and returns an array of rows.
       *
       * Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
       */
      async execute() {
        const compiledQuery = this.compile();
        const result = await this.#props.executor.executeQuery(compiledQuery, this.#props.queryId);
        const { adapter } = this.#props.executor;
        const query = compiledQuery.query;
        if (query.returning && adapter.supportsReturning || query.output && adapter.supportsOutput) {
          return result.rows;
        }
        return [
          new UpdateResult(
            // TODO: remove numUpdatedOrDeletedRows.
            // TODO: https://github.com/kysely-org/kysely/pull/431#discussion_r1172330899
            result.numAffectedRows ?? result.numUpdatedOrDeletedRows ?? BigInt(0),
            result.numChangedRows
          )
        ];
      }
      /**
       * Executes the query and returns the first result or undefined if
       * the query returned no result.
       */
      async executeTakeFirst() {
        const [result] = await this.execute();
        return result;
      }
      /**
       * Executes the query and returns the first result or throws if
       * the query returned no result.
       *
       * By default an instance of {@link NoResultError} is thrown, but you can
       * provide a custom error class, or callback as the only argument to throw a different
       * error.
       */
      async executeTakeFirstOrThrow(errorConstructor = NoResultError) {
        const result = await this.executeTakeFirst();
        if (result === void 0) {
          const error2 = isNoResultErrorConstructor(errorConstructor) ? new errorConstructor(this.toOperationNode()) : errorConstructor(this.toOperationNode());
          throw error2;
        }
        return result;
      }
      async *stream(chunkSize = 100) {
        const compiledQuery = this.compile();
        const stream = this.#props.executor.stream(compiledQuery, chunkSize, this.#props.queryId);
        for await (const item of stream) {
          yield* item.rows;
        }
      }
      async explain(format, options2) {
        const builder = new _UpdateQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithExplain(this.#props.queryNode, format, options2)
        });
        return await builder.execute();
      }
    };
    preventAwait(UpdateQueryBuilder, "don't await UpdateQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/common-table-expression-name-node.js
var CommonTableExpressionNameNode;
var init_common_table_expression_name_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/common-table-expression-name-node.js"() {
    init_object_utils();
    init_column_node();
    init_table_node();
    CommonTableExpressionNameNode = freeze({
      is(node) {
        return node.kind === "CommonTableExpressionNameNode";
      },
      create(tableName, columnNames) {
        return freeze({
          kind: "CommonTableExpressionNameNode",
          table: TableNode.create(tableName),
          columns: columnNames ? freeze(columnNames.map(ColumnNode.create)) : void 0
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/common-table-expression-node.js
var CommonTableExpressionNode;
var init_common_table_expression_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/common-table-expression-node.js"() {
    init_object_utils();
    CommonTableExpressionNode = freeze({
      is(node) {
        return node.kind === "CommonTableExpressionNode";
      },
      create(name, expression) {
        return freeze({
          kind: "CommonTableExpressionNode",
          name,
          expression
        });
      },
      cloneWith(node, props) {
        return freeze({
          ...node,
          ...props
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/cte-builder.js
var CTEBuilder;
var init_cte_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/cte-builder.js"() {
    init_common_table_expression_node();
    init_prevent_await();
    init_object_utils();
    CTEBuilder = class _CTEBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Makes the common table expression materialized.
       */
      materialized() {
        return new _CTEBuilder({
          ...this.#props,
          node: CommonTableExpressionNode.cloneWith(this.#props.node, {
            materialized: true
          })
        });
      }
      /**
       * Makes the common table expression not materialized.
       */
      notMaterialized() {
        return new _CTEBuilder({
          ...this.#props,
          node: CommonTableExpressionNode.cloneWith(this.#props.node, {
            materialized: false
          })
        });
      }
      toOperationNode() {
        return this.#props.node;
      }
    };
    preventAwait(CTEBuilder, "don't await CTEBuilder instances. They are never executed directly and are always just a part of a query.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/with-parser.js
function parseCommonTableExpression(nameOrBuilderCallback, expression) {
  const expressionNode = expression(createQueryCreator()).toOperationNode();
  if (isFunction(nameOrBuilderCallback)) {
    return nameOrBuilderCallback(cteBuilderFactory(expressionNode)).toOperationNode();
  }
  return CommonTableExpressionNode.create(parseCommonTableExpressionName(nameOrBuilderCallback), expressionNode);
}
function cteBuilderFactory(expressionNode) {
  return (name) => {
    return new CTEBuilder({
      node: CommonTableExpressionNode.create(parseCommonTableExpressionName(name), expressionNode)
    });
  };
}
function parseCommonTableExpressionName(name) {
  if (name.includes("(")) {
    const parts = name.split(/[\(\)]/);
    const table2 = parts[0];
    const columns = parts[1].split(",").map((it2) => it2.trim());
    return CommonTableExpressionNameNode.create(table2, columns);
  } else {
    return CommonTableExpressionNameNode.create(name);
  }
}
var init_with_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/with-parser.js"() {
    init_common_table_expression_name_node();
    init_parse_utils();
    init_object_utils();
    init_cte_builder();
    init_common_table_expression_node();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/with-node.js
var WithNode;
var init_with_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/with-node.js"() {
    init_object_utils();
    WithNode = freeze({
      is(node) {
        return node.kind === "WithNode";
      },
      create(expression, params) {
        return freeze({
          kind: "WithNode",
          expressions: freeze([expression]),
          ...params
        });
      },
      cloneWithExpression(withNode, expression) {
        return freeze({
          ...withNode,
          expressions: freeze([...withNode.expressions, expression])
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/random-string.js
function randomString(length) {
  let chars2 = "";
  for (let i = 0; i < length; ++i) {
    chars2 += randomChar();
  }
  return chars2;
}
function randomChar() {
  return CHARS[~~(Math.random() * CHARS.length)];
}
var CHARS;
var init_random_string = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/random-string.js"() {
    CHARS = [
      "A",
      "B",
      "C",
      "D",
      "E",
      "F",
      "G",
      "H",
      "I",
      "J",
      "K",
      "L",
      "M",
      "N",
      "O",
      "P",
      "Q",
      "R",
      "S",
      "T",
      "U",
      "V",
      "W",
      "X",
      "Y",
      "Z",
      "a",
      "b",
      "c",
      "d",
      "e",
      "f",
      "g",
      "h",
      "i",
      "j",
      "k",
      "l",
      "m",
      "n",
      "o",
      "p",
      "q",
      "r",
      "s",
      "t",
      "u",
      "v",
      "w",
      "x",
      "y",
      "z",
      "0",
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8",
      "9"
    ];
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/query-id.js
function createQueryId() {
  return new LazyQueryId();
}
var LazyQueryId;
var init_query_id = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/query-id.js"() {
    init_random_string();
    LazyQueryId = class {
      #queryId;
      get queryId() {
        if (this.#queryId === void 0) {
          this.#queryId = randomString(8);
        }
        return this.#queryId;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/require-all-props.js
function requireAllProps(obj) {
  return obj;
}
var init_require_all_props = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/require-all-props.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/operation-node-transformer.js
var OperationNodeTransformer;
var init_operation_node_transformer = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/operation-node-transformer.js"() {
    init_object_utils();
    init_require_all_props();
    OperationNodeTransformer = class {
      nodeStack = [];
      #transformers = freeze({
        AliasNode: this.transformAlias.bind(this),
        ColumnNode: this.transformColumn.bind(this),
        IdentifierNode: this.transformIdentifier.bind(this),
        SchemableIdentifierNode: this.transformSchemableIdentifier.bind(this),
        RawNode: this.transformRaw.bind(this),
        ReferenceNode: this.transformReference.bind(this),
        SelectQueryNode: this.transformSelectQuery.bind(this),
        SelectionNode: this.transformSelection.bind(this),
        TableNode: this.transformTable.bind(this),
        FromNode: this.transformFrom.bind(this),
        SelectAllNode: this.transformSelectAll.bind(this),
        AndNode: this.transformAnd.bind(this),
        OrNode: this.transformOr.bind(this),
        ValueNode: this.transformValue.bind(this),
        ValueListNode: this.transformValueList.bind(this),
        PrimitiveValueListNode: this.transformPrimitiveValueList.bind(this),
        ParensNode: this.transformParens.bind(this),
        JoinNode: this.transformJoin.bind(this),
        OperatorNode: this.transformOperator.bind(this),
        WhereNode: this.transformWhere.bind(this),
        InsertQueryNode: this.transformInsertQuery.bind(this),
        DeleteQueryNode: this.transformDeleteQuery.bind(this),
        ReturningNode: this.transformReturning.bind(this),
        CreateTableNode: this.transformCreateTable.bind(this),
        AddColumnNode: this.transformAddColumn.bind(this),
        ColumnDefinitionNode: this.transformColumnDefinition.bind(this),
        DropTableNode: this.transformDropTable.bind(this),
        DataTypeNode: this.transformDataType.bind(this),
        OrderByNode: this.transformOrderBy.bind(this),
        OrderByItemNode: this.transformOrderByItem.bind(this),
        GroupByNode: this.transformGroupBy.bind(this),
        GroupByItemNode: this.transformGroupByItem.bind(this),
        UpdateQueryNode: this.transformUpdateQuery.bind(this),
        ColumnUpdateNode: this.transformColumnUpdate.bind(this),
        LimitNode: this.transformLimit.bind(this),
        OffsetNode: this.transformOffset.bind(this),
        OnConflictNode: this.transformOnConflict.bind(this),
        OnDuplicateKeyNode: this.transformOnDuplicateKey.bind(this),
        CreateIndexNode: this.transformCreateIndex.bind(this),
        DropIndexNode: this.transformDropIndex.bind(this),
        ListNode: this.transformList.bind(this),
        PrimaryKeyConstraintNode: this.transformPrimaryKeyConstraint.bind(this),
        UniqueConstraintNode: this.transformUniqueConstraint.bind(this),
        ReferencesNode: this.transformReferences.bind(this),
        CheckConstraintNode: this.transformCheckConstraint.bind(this),
        WithNode: this.transformWith.bind(this),
        CommonTableExpressionNode: this.transformCommonTableExpression.bind(this),
        CommonTableExpressionNameNode: this.transformCommonTableExpressionName.bind(this),
        HavingNode: this.transformHaving.bind(this),
        CreateSchemaNode: this.transformCreateSchema.bind(this),
        DropSchemaNode: this.transformDropSchema.bind(this),
        AlterTableNode: this.transformAlterTable.bind(this),
        DropColumnNode: this.transformDropColumn.bind(this),
        RenameColumnNode: this.transformRenameColumn.bind(this),
        AlterColumnNode: this.transformAlterColumn.bind(this),
        ModifyColumnNode: this.transformModifyColumn.bind(this),
        AddConstraintNode: this.transformAddConstraint.bind(this),
        DropConstraintNode: this.transformDropConstraint.bind(this),
        ForeignKeyConstraintNode: this.transformForeignKeyConstraint.bind(this),
        CreateViewNode: this.transformCreateView.bind(this),
        DropViewNode: this.transformDropView.bind(this),
        GeneratedNode: this.transformGenerated.bind(this),
        DefaultValueNode: this.transformDefaultValue.bind(this),
        OnNode: this.transformOn.bind(this),
        ValuesNode: this.transformValues.bind(this),
        SelectModifierNode: this.transformSelectModifier.bind(this),
        CreateTypeNode: this.transformCreateType.bind(this),
        DropTypeNode: this.transformDropType.bind(this),
        ExplainNode: this.transformExplain.bind(this),
        DefaultInsertValueNode: this.transformDefaultInsertValue.bind(this),
        AggregateFunctionNode: this.transformAggregateFunction.bind(this),
        OverNode: this.transformOver.bind(this),
        PartitionByNode: this.transformPartitionBy.bind(this),
        PartitionByItemNode: this.transformPartitionByItem.bind(this),
        SetOperationNode: this.transformSetOperation.bind(this),
        BinaryOperationNode: this.transformBinaryOperation.bind(this),
        UnaryOperationNode: this.transformUnaryOperation.bind(this),
        UsingNode: this.transformUsing.bind(this),
        FunctionNode: this.transformFunction.bind(this),
        CaseNode: this.transformCase.bind(this),
        WhenNode: this.transformWhen.bind(this),
        JSONReferenceNode: this.transformJSONReference.bind(this),
        JSONPathNode: this.transformJSONPath.bind(this),
        JSONPathLegNode: this.transformJSONPathLeg.bind(this),
        JSONOperatorChainNode: this.transformJSONOperatorChain.bind(this),
        TupleNode: this.transformTuple.bind(this),
        MergeQueryNode: this.transformMergeQuery.bind(this),
        MatchedNode: this.transformMatched.bind(this),
        AddIndexNode: this.transformAddIndex.bind(this),
        CastNode: this.transformCast.bind(this),
        FetchNode: this.transformFetch.bind(this),
        TopNode: this.transformTop.bind(this),
        OutputNode: this.transformOutput.bind(this)
      });
      transformNode(node) {
        if (!node) {
          return node;
        }
        this.nodeStack.push(node);
        const out = this.transformNodeImpl(node);
        this.nodeStack.pop();
        return freeze(out);
      }
      transformNodeImpl(node) {
        return this.#transformers[node.kind](node);
      }
      transformNodeList(list5) {
        if (!list5) {
          return list5;
        }
        return freeze(list5.map((node) => this.transformNode(node)));
      }
      transformSelectQuery(node) {
        return requireAllProps({
          kind: "SelectQueryNode",
          from: this.transformNode(node.from),
          selections: this.transformNodeList(node.selections),
          distinctOn: this.transformNodeList(node.distinctOn),
          joins: this.transformNodeList(node.joins),
          groupBy: this.transformNode(node.groupBy),
          orderBy: this.transformNode(node.orderBy),
          where: this.transformNode(node.where),
          frontModifiers: this.transformNodeList(node.frontModifiers),
          endModifiers: this.transformNodeList(node.endModifiers),
          limit: this.transformNode(node.limit),
          offset: this.transformNode(node.offset),
          with: this.transformNode(node.with),
          having: this.transformNode(node.having),
          explain: this.transformNode(node.explain),
          setOperations: this.transformNodeList(node.setOperations),
          fetch: this.transformNode(node.fetch),
          top: this.transformNode(node.top)
        });
      }
      transformSelection(node) {
        return requireAllProps({
          kind: "SelectionNode",
          selection: this.transformNode(node.selection)
        });
      }
      transformColumn(node) {
        return requireAllProps({
          kind: "ColumnNode",
          column: this.transformNode(node.column)
        });
      }
      transformAlias(node) {
        return requireAllProps({
          kind: "AliasNode",
          node: this.transformNode(node.node),
          alias: this.transformNode(node.alias)
        });
      }
      transformTable(node) {
        return requireAllProps({
          kind: "TableNode",
          table: this.transformNode(node.table)
        });
      }
      transformFrom(node) {
        return requireAllProps({
          kind: "FromNode",
          froms: this.transformNodeList(node.froms)
        });
      }
      transformReference(node) {
        return requireAllProps({
          kind: "ReferenceNode",
          column: this.transformNode(node.column),
          table: this.transformNode(node.table)
        });
      }
      transformAnd(node) {
        return requireAllProps({
          kind: "AndNode",
          left: this.transformNode(node.left),
          right: this.transformNode(node.right)
        });
      }
      transformOr(node) {
        return requireAllProps({
          kind: "OrNode",
          left: this.transformNode(node.left),
          right: this.transformNode(node.right)
        });
      }
      transformValueList(node) {
        return requireAllProps({
          kind: "ValueListNode",
          values: this.transformNodeList(node.values)
        });
      }
      transformParens(node) {
        return requireAllProps({
          kind: "ParensNode",
          node: this.transformNode(node.node)
        });
      }
      transformJoin(node) {
        return requireAllProps({
          kind: "JoinNode",
          joinType: node.joinType,
          table: this.transformNode(node.table),
          on: this.transformNode(node.on)
        });
      }
      transformRaw(node) {
        return requireAllProps({
          kind: "RawNode",
          sqlFragments: freeze([...node.sqlFragments]),
          parameters: this.transformNodeList(node.parameters)
        });
      }
      transformWhere(node) {
        return requireAllProps({
          kind: "WhereNode",
          where: this.transformNode(node.where)
        });
      }
      transformInsertQuery(node) {
        return requireAllProps({
          kind: "InsertQueryNode",
          into: this.transformNode(node.into),
          columns: this.transformNodeList(node.columns),
          values: this.transformNode(node.values),
          returning: this.transformNode(node.returning),
          onConflict: this.transformNode(node.onConflict),
          onDuplicateKey: this.transformNode(node.onDuplicateKey),
          endModifiers: this.transformNodeList(node.endModifiers),
          with: this.transformNode(node.with),
          ignore: node.ignore,
          replace: node.replace,
          explain: this.transformNode(node.explain),
          defaultValues: node.defaultValues,
          top: this.transformNode(node.top),
          output: this.transformNode(node.output)
        });
      }
      transformValues(node) {
        return requireAllProps({
          kind: "ValuesNode",
          values: this.transformNodeList(node.values)
        });
      }
      transformDeleteQuery(node) {
        return requireAllProps({
          kind: "DeleteQueryNode",
          from: this.transformNode(node.from),
          using: this.transformNode(node.using),
          joins: this.transformNodeList(node.joins),
          where: this.transformNode(node.where),
          returning: this.transformNode(node.returning),
          endModifiers: this.transformNodeList(node.endModifiers),
          with: this.transformNode(node.with),
          orderBy: this.transformNode(node.orderBy),
          limit: this.transformNode(node.limit),
          explain: this.transformNode(node.explain),
          top: this.transformNode(node.top),
          output: this.transformNode(node.output)
        });
      }
      transformReturning(node) {
        return requireAllProps({
          kind: "ReturningNode",
          selections: this.transformNodeList(node.selections)
        });
      }
      transformCreateTable(node) {
        return requireAllProps({
          kind: "CreateTableNode",
          table: this.transformNode(node.table),
          columns: this.transformNodeList(node.columns),
          constraints: this.transformNodeList(node.constraints),
          temporary: node.temporary,
          ifNotExists: node.ifNotExists,
          onCommit: node.onCommit,
          frontModifiers: this.transformNodeList(node.frontModifiers),
          endModifiers: this.transformNodeList(node.endModifiers),
          selectQuery: this.transformNode(node.selectQuery)
        });
      }
      transformColumnDefinition(node) {
        return requireAllProps({
          kind: "ColumnDefinitionNode",
          column: this.transformNode(node.column),
          dataType: this.transformNode(node.dataType),
          references: this.transformNode(node.references),
          primaryKey: node.primaryKey,
          autoIncrement: node.autoIncrement,
          unique: node.unique,
          notNull: node.notNull,
          unsigned: node.unsigned,
          defaultTo: this.transformNode(node.defaultTo),
          check: this.transformNode(node.check),
          generated: this.transformNode(node.generated),
          frontModifiers: this.transformNodeList(node.frontModifiers),
          endModifiers: this.transformNodeList(node.endModifiers),
          nullsNotDistinct: node.nullsNotDistinct,
          identity: node.identity,
          ifNotExists: node.ifNotExists
        });
      }
      transformAddColumn(node) {
        return requireAllProps({
          kind: "AddColumnNode",
          column: this.transformNode(node.column)
        });
      }
      transformDropTable(node) {
        return requireAllProps({
          kind: "DropTableNode",
          table: this.transformNode(node.table),
          ifExists: node.ifExists,
          cascade: node.cascade
        });
      }
      transformOrderBy(node) {
        return requireAllProps({
          kind: "OrderByNode",
          items: this.transformNodeList(node.items)
        });
      }
      transformOrderByItem(node) {
        return requireAllProps({
          kind: "OrderByItemNode",
          orderBy: this.transformNode(node.orderBy),
          direction: this.transformNode(node.direction)
        });
      }
      transformGroupBy(node) {
        return requireAllProps({
          kind: "GroupByNode",
          items: this.transformNodeList(node.items)
        });
      }
      transformGroupByItem(node) {
        return requireAllProps({
          kind: "GroupByItemNode",
          groupBy: this.transformNode(node.groupBy)
        });
      }
      transformUpdateQuery(node) {
        return requireAllProps({
          kind: "UpdateQueryNode",
          table: this.transformNode(node.table),
          from: this.transformNode(node.from),
          joins: this.transformNodeList(node.joins),
          where: this.transformNode(node.where),
          updates: this.transformNodeList(node.updates),
          returning: this.transformNode(node.returning),
          endModifiers: this.transformNodeList(node.endModifiers),
          with: this.transformNode(node.with),
          explain: this.transformNode(node.explain),
          limit: this.transformNode(node.limit),
          top: this.transformNode(node.top),
          output: this.transformNode(node.output)
        });
      }
      transformColumnUpdate(node) {
        return requireAllProps({
          kind: "ColumnUpdateNode",
          column: this.transformNode(node.column),
          value: this.transformNode(node.value)
        });
      }
      transformLimit(node) {
        return requireAllProps({
          kind: "LimitNode",
          limit: this.transformNode(node.limit)
        });
      }
      transformOffset(node) {
        return requireAllProps({
          kind: "OffsetNode",
          offset: this.transformNode(node.offset)
        });
      }
      transformOnConflict(node) {
        return requireAllProps({
          kind: "OnConflictNode",
          columns: this.transformNodeList(node.columns),
          constraint: this.transformNode(node.constraint),
          indexExpression: this.transformNode(node.indexExpression),
          indexWhere: this.transformNode(node.indexWhere),
          updates: this.transformNodeList(node.updates),
          updateWhere: this.transformNode(node.updateWhere),
          doNothing: node.doNothing
        });
      }
      transformOnDuplicateKey(node) {
        return requireAllProps({
          kind: "OnDuplicateKeyNode",
          updates: this.transformNodeList(node.updates)
        });
      }
      transformCreateIndex(node) {
        return requireAllProps({
          kind: "CreateIndexNode",
          name: this.transformNode(node.name),
          table: this.transformNode(node.table),
          columns: this.transformNodeList(node.columns),
          unique: node.unique,
          using: this.transformNode(node.using),
          ifNotExists: node.ifNotExists,
          where: this.transformNode(node.where),
          nullsNotDistinct: node.nullsNotDistinct
        });
      }
      transformList(node) {
        return requireAllProps({
          kind: "ListNode",
          items: this.transformNodeList(node.items)
        });
      }
      transformDropIndex(node) {
        return requireAllProps({
          kind: "DropIndexNode",
          name: this.transformNode(node.name),
          table: this.transformNode(node.table),
          ifExists: node.ifExists,
          cascade: node.cascade
        });
      }
      transformPrimaryKeyConstraint(node) {
        return requireAllProps({
          kind: "PrimaryKeyConstraintNode",
          columns: this.transformNodeList(node.columns),
          name: this.transformNode(node.name)
        });
      }
      transformUniqueConstraint(node) {
        return requireAllProps({
          kind: "UniqueConstraintNode",
          columns: this.transformNodeList(node.columns),
          name: this.transformNode(node.name),
          nullsNotDistinct: node.nullsNotDistinct
        });
      }
      transformForeignKeyConstraint(node) {
        return requireAllProps({
          kind: "ForeignKeyConstraintNode",
          columns: this.transformNodeList(node.columns),
          references: this.transformNode(node.references),
          name: this.transformNode(node.name),
          onDelete: node.onDelete,
          onUpdate: node.onUpdate
        });
      }
      transformSetOperation(node) {
        return requireAllProps({
          kind: "SetOperationNode",
          operator: node.operator,
          expression: this.transformNode(node.expression),
          all: node.all
        });
      }
      transformReferences(node) {
        return requireAllProps({
          kind: "ReferencesNode",
          table: this.transformNode(node.table),
          columns: this.transformNodeList(node.columns),
          onDelete: node.onDelete,
          onUpdate: node.onUpdate
        });
      }
      transformCheckConstraint(node) {
        return requireAllProps({
          kind: "CheckConstraintNode",
          expression: this.transformNode(node.expression),
          name: this.transformNode(node.name)
        });
      }
      transformWith(node) {
        return requireAllProps({
          kind: "WithNode",
          expressions: this.transformNodeList(node.expressions),
          recursive: node.recursive
        });
      }
      transformCommonTableExpression(node) {
        return requireAllProps({
          kind: "CommonTableExpressionNode",
          name: this.transformNode(node.name),
          materialized: node.materialized,
          expression: this.transformNode(node.expression)
        });
      }
      transformCommonTableExpressionName(node) {
        return requireAllProps({
          kind: "CommonTableExpressionNameNode",
          table: this.transformNode(node.table),
          columns: this.transformNodeList(node.columns)
        });
      }
      transformHaving(node) {
        return requireAllProps({
          kind: "HavingNode",
          having: this.transformNode(node.having)
        });
      }
      transformCreateSchema(node) {
        return requireAllProps({
          kind: "CreateSchemaNode",
          schema: this.transformNode(node.schema),
          ifNotExists: node.ifNotExists
        });
      }
      transformDropSchema(node) {
        return requireAllProps({
          kind: "DropSchemaNode",
          schema: this.transformNode(node.schema),
          ifExists: node.ifExists,
          cascade: node.cascade
        });
      }
      transformAlterTable(node) {
        return requireAllProps({
          kind: "AlterTableNode",
          table: this.transformNode(node.table),
          renameTo: this.transformNode(node.renameTo),
          setSchema: this.transformNode(node.setSchema),
          columnAlterations: this.transformNodeList(node.columnAlterations),
          addConstraint: this.transformNode(node.addConstraint),
          dropConstraint: this.transformNode(node.dropConstraint),
          addIndex: this.transformNode(node.addIndex),
          dropIndex: this.transformNode(node.dropIndex)
        });
      }
      transformDropColumn(node) {
        return requireAllProps({
          kind: "DropColumnNode",
          column: this.transformNode(node.column)
        });
      }
      transformRenameColumn(node) {
        return requireAllProps({
          kind: "RenameColumnNode",
          column: this.transformNode(node.column),
          renameTo: this.transformNode(node.renameTo)
        });
      }
      transformAlterColumn(node) {
        return requireAllProps({
          kind: "AlterColumnNode",
          column: this.transformNode(node.column),
          dataType: this.transformNode(node.dataType),
          dataTypeExpression: this.transformNode(node.dataTypeExpression),
          setDefault: this.transformNode(node.setDefault),
          dropDefault: node.dropDefault,
          setNotNull: node.setNotNull,
          dropNotNull: node.dropNotNull
        });
      }
      transformModifyColumn(node) {
        return requireAllProps({
          kind: "ModifyColumnNode",
          column: this.transformNode(node.column)
        });
      }
      transformAddConstraint(node) {
        return requireAllProps({
          kind: "AddConstraintNode",
          constraint: this.transformNode(node.constraint)
        });
      }
      transformDropConstraint(node) {
        return requireAllProps({
          kind: "DropConstraintNode",
          constraintName: this.transformNode(node.constraintName),
          ifExists: node.ifExists,
          modifier: node.modifier
        });
      }
      transformCreateView(node) {
        return requireAllProps({
          kind: "CreateViewNode",
          name: this.transformNode(node.name),
          temporary: node.temporary,
          orReplace: node.orReplace,
          ifNotExists: node.ifNotExists,
          materialized: node.materialized,
          columns: this.transformNodeList(node.columns),
          as: this.transformNode(node.as)
        });
      }
      transformDropView(node) {
        return requireAllProps({
          kind: "DropViewNode",
          name: this.transformNode(node.name),
          ifExists: node.ifExists,
          materialized: node.materialized,
          cascade: node.cascade
        });
      }
      transformGenerated(node) {
        return requireAllProps({
          kind: "GeneratedNode",
          byDefault: node.byDefault,
          always: node.always,
          identity: node.identity,
          stored: node.stored,
          expression: this.transformNode(node.expression)
        });
      }
      transformDefaultValue(node) {
        return requireAllProps({
          kind: "DefaultValueNode",
          defaultValue: this.transformNode(node.defaultValue)
        });
      }
      transformOn(node) {
        return requireAllProps({
          kind: "OnNode",
          on: this.transformNode(node.on)
        });
      }
      transformSelectModifier(node) {
        return requireAllProps({
          kind: "SelectModifierNode",
          modifier: node.modifier,
          rawModifier: this.transformNode(node.rawModifier),
          of: this.transformNodeList(node.of)
        });
      }
      transformCreateType(node) {
        return requireAllProps({
          kind: "CreateTypeNode",
          name: this.transformNode(node.name),
          enum: this.transformNode(node.enum)
        });
      }
      transformDropType(node) {
        return requireAllProps({
          kind: "DropTypeNode",
          name: this.transformNode(node.name),
          ifExists: node.ifExists
        });
      }
      transformExplain(node) {
        return requireAllProps({
          kind: "ExplainNode",
          format: node.format,
          options: this.transformNode(node.options)
        });
      }
      transformSchemableIdentifier(node) {
        return requireAllProps({
          kind: "SchemableIdentifierNode",
          schema: this.transformNode(node.schema),
          identifier: this.transformNode(node.identifier)
        });
      }
      transformAggregateFunction(node) {
        return requireAllProps({
          kind: "AggregateFunctionNode",
          aggregated: this.transformNodeList(node.aggregated),
          distinct: node.distinct,
          orderBy: this.transformNode(node.orderBy),
          filter: this.transformNode(node.filter),
          func: node.func,
          over: this.transformNode(node.over)
        });
      }
      transformOver(node) {
        return requireAllProps({
          kind: "OverNode",
          orderBy: this.transformNode(node.orderBy),
          partitionBy: this.transformNode(node.partitionBy)
        });
      }
      transformPartitionBy(node) {
        return requireAllProps({
          kind: "PartitionByNode",
          items: this.transformNodeList(node.items)
        });
      }
      transformPartitionByItem(node) {
        return requireAllProps({
          kind: "PartitionByItemNode",
          partitionBy: this.transformNode(node.partitionBy)
        });
      }
      transformBinaryOperation(node) {
        return requireAllProps({
          kind: "BinaryOperationNode",
          leftOperand: this.transformNode(node.leftOperand),
          operator: this.transformNode(node.operator),
          rightOperand: this.transformNode(node.rightOperand)
        });
      }
      transformUnaryOperation(node) {
        return requireAllProps({
          kind: "UnaryOperationNode",
          operator: this.transformNode(node.operator),
          operand: this.transformNode(node.operand)
        });
      }
      transformUsing(node) {
        return requireAllProps({
          kind: "UsingNode",
          tables: this.transformNodeList(node.tables)
        });
      }
      transformFunction(node) {
        return requireAllProps({
          kind: "FunctionNode",
          func: node.func,
          arguments: this.transformNodeList(node.arguments)
        });
      }
      transformCase(node) {
        return requireAllProps({
          kind: "CaseNode",
          value: this.transformNode(node.value),
          when: this.transformNodeList(node.when),
          else: this.transformNode(node.else),
          isStatement: node.isStatement
        });
      }
      transformWhen(node) {
        return requireAllProps({
          kind: "WhenNode",
          condition: this.transformNode(node.condition),
          result: this.transformNode(node.result)
        });
      }
      transformJSONReference(node) {
        return requireAllProps({
          kind: "JSONReferenceNode",
          reference: this.transformNode(node.reference),
          traversal: this.transformNode(node.traversal)
        });
      }
      transformJSONPath(node) {
        return requireAllProps({
          kind: "JSONPathNode",
          inOperator: this.transformNode(node.inOperator),
          pathLegs: this.transformNodeList(node.pathLegs)
        });
      }
      transformJSONPathLeg(node) {
        return requireAllProps({
          kind: "JSONPathLegNode",
          type: node.type,
          value: node.value
        });
      }
      transformJSONOperatorChain(node) {
        return requireAllProps({
          kind: "JSONOperatorChainNode",
          operator: this.transformNode(node.operator),
          values: this.transformNodeList(node.values)
        });
      }
      transformTuple(node) {
        return requireAllProps({
          kind: "TupleNode",
          values: this.transformNodeList(node.values)
        });
      }
      transformMergeQuery(node) {
        return requireAllProps({
          kind: "MergeQueryNode",
          into: this.transformNode(node.into),
          using: this.transformNode(node.using),
          whens: this.transformNodeList(node.whens),
          with: this.transformNode(node.with),
          top: this.transformNode(node.top),
          endModifiers: this.transformNodeList(node.endModifiers),
          output: this.transformNode(node.output)
        });
      }
      transformMatched(node) {
        return requireAllProps({
          kind: "MatchedNode",
          not: node.not,
          bySource: node.bySource
        });
      }
      transformAddIndex(node) {
        return requireAllProps({
          kind: "AddIndexNode",
          name: this.transformNode(node.name),
          columns: this.transformNodeList(node.columns),
          unique: node.unique,
          using: this.transformNode(node.using),
          ifNotExists: node.ifNotExists
        });
      }
      transformCast(node) {
        return requireAllProps({
          kind: "CastNode",
          expression: this.transformNode(node.expression),
          dataType: this.transformNode(node.dataType)
        });
      }
      transformFetch(node) {
        return requireAllProps({
          kind: "FetchNode",
          rowCount: this.transformNode(node.rowCount),
          modifier: node.modifier
        });
      }
      transformTop(node) {
        return requireAllProps({
          kind: "TopNode",
          expression: node.expression,
          modifiers: node.modifiers
        });
      }
      transformOutput(node) {
        return requireAllProps({
          kind: "OutputNode",
          selections: this.transformNodeList(node.selections)
        });
      }
      transformDataType(node) {
        return node;
      }
      transformSelectAll(node) {
        return node;
      }
      transformIdentifier(node) {
        return node;
      }
      transformValue(node) {
        return node;
      }
      transformPrimitiveValueList(node) {
        return node;
      }
      transformOperator(node) {
        return node;
      }
      transformDefaultInsertValue(node) {
        return node;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/with-schema/with-schema-transformer.js
var ROOT_OPERATION_NODES, SCHEMALESS_FUNCTIONS, WithSchemaTransformer;
var init_with_schema_transformer = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/with-schema/with-schema-transformer.js"() {
    init_alias_node();
    init_identifier_node();
    init_operation_node_transformer();
    init_schemable_identifier_node();
    init_table_node();
    init_object_utils();
    ROOT_OPERATION_NODES = freeze({
      AlterTableNode: true,
      CreateIndexNode: true,
      CreateSchemaNode: true,
      CreateTableNode: true,
      CreateTypeNode: true,
      CreateViewNode: true,
      DeleteQueryNode: true,
      DropIndexNode: true,
      DropSchemaNode: true,
      DropTableNode: true,
      DropTypeNode: true,
      DropViewNode: true,
      InsertQueryNode: true,
      RawNode: true,
      SelectQueryNode: true,
      UpdateQueryNode: true,
      MergeQueryNode: true
    });
    SCHEMALESS_FUNCTIONS = {
      json_agg: true,
      to_json: true
    };
    WithSchemaTransformer = class extends OperationNodeTransformer {
      #schema;
      #schemableIds = /* @__PURE__ */ new Set();
      #ctes = /* @__PURE__ */ new Set();
      constructor(schema) {
        super();
        this.#schema = schema;
      }
      transformNodeImpl(node) {
        if (!this.#isRootOperationNode(node)) {
          return super.transformNodeImpl(node);
        }
        const ctes = this.#collectCTEs(node);
        for (const cte of ctes) {
          this.#ctes.add(cte);
        }
        const tables = this.#collectSchemableIds(node);
        for (const table2 of tables) {
          this.#schemableIds.add(table2);
        }
        const transformed = super.transformNodeImpl(node);
        for (const table2 of tables) {
          this.#schemableIds.delete(table2);
        }
        for (const cte of ctes) {
          this.#ctes.delete(cte);
        }
        return transformed;
      }
      transformSchemableIdentifier(node) {
        const transformed = super.transformSchemableIdentifier(node);
        if (transformed.schema || !this.#schemableIds.has(node.identifier.name)) {
          return transformed;
        }
        return {
          ...transformed,
          schema: IdentifierNode.create(this.#schema)
        };
      }
      transformReferences(node) {
        const transformed = super.transformReferences(node);
        if (transformed.table.table.schema) {
          return transformed;
        }
        return {
          ...transformed,
          table: TableNode.createWithSchema(this.#schema, transformed.table.table.identifier.name)
        };
      }
      transformAggregateFunction(node) {
        return {
          ...super.transformAggregateFunction({ ...node, aggregated: [] }),
          aggregated: this.#transformTableArgsWithoutSchemas(node, "aggregated")
        };
      }
      transformFunction(node) {
        return {
          ...super.transformFunction({ ...node, arguments: [] }),
          arguments: this.#transformTableArgsWithoutSchemas(node, "arguments")
        };
      }
      #transformTableArgsWithoutSchemas(node, argsKey) {
        return SCHEMALESS_FUNCTIONS[node.func] ? node[argsKey].map((arg) => !TableNode.is(arg) || arg.table.schema ? this.transformNode(arg) : {
          ...arg,
          table: this.transformIdentifier(arg.table.identifier)
        }) : this.transformNodeList(node[argsKey]);
      }
      #isRootOperationNode(node) {
        return node.kind in ROOT_OPERATION_NODES;
      }
      #collectSchemableIds(node) {
        const schemableIds = /* @__PURE__ */ new Set();
        if ("name" in node && node.name && SchemableIdentifierNode.is(node.name)) {
          this.#collectSchemableId(node.name, schemableIds);
        }
        if ("from" in node && node.from) {
          for (const from of node.from.froms) {
            this.#collectSchemableIdsFromTableExpr(from, schemableIds);
          }
        }
        if ("into" in node && node.into) {
          this.#collectSchemableIdsFromTableExpr(node.into, schemableIds);
        }
        if ("table" in node && node.table) {
          this.#collectSchemableIdsFromTableExpr(node.table, schemableIds);
        }
        if ("joins" in node && node.joins) {
          for (const join4 of node.joins) {
            this.#collectSchemableIdsFromTableExpr(join4.table, schemableIds);
          }
        }
        if ("using" in node && node.using) {
          this.#collectSchemableIdsFromTableExpr(node.using, schemableIds);
        }
        return schemableIds;
      }
      #collectCTEs(node) {
        const ctes = /* @__PURE__ */ new Set();
        if ("with" in node && node.with) {
          this.#collectCTEIds(node.with, ctes);
        }
        return ctes;
      }
      #collectSchemableIdsFromTableExpr(node, schemableIds) {
        const table2 = TableNode.is(node) ? node : AliasNode.is(node) && TableNode.is(node.node) ? node.node : null;
        if (table2) {
          this.#collectSchemableId(table2.table, schemableIds);
        }
      }
      #collectSchemableId(node, schemableIds) {
        const id = node.identifier.name;
        if (!this.#schemableIds.has(id) && !this.#ctes.has(id)) {
          schemableIds.add(id);
        }
      }
      #collectCTEIds(node, ctes) {
        for (const expr of node.expressions) {
          const cteId = expr.name.table.table.identifier.name;
          if (!this.#ctes.has(cteId)) {
            ctes.add(cteId);
          }
        }
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/with-schema/with-schema-plugin.js
var WithSchemaPlugin;
var init_with_schema_plugin = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/with-schema/with-schema-plugin.js"() {
    init_with_schema_transformer();
    WithSchemaPlugin = class {
      #transformer;
      constructor(schema) {
        this.#transformer = new WithSchemaTransformer(schema);
      }
      transformQuery(args) {
        return this.#transformer.transformNode(args.node);
      }
      async transformResult(args) {
        return args.result;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/matched-node.js
var MatchedNode;
var init_matched_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/matched-node.js"() {
    init_object_utils();
    MatchedNode = freeze({
      is(node) {
        return node.kind === "MatchedNode";
      },
      create(not, bySource = false) {
        return freeze({
          kind: "MatchedNode",
          not,
          bySource
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/merge-parser.js
function parseMergeWhen(type, args, refRight) {
  return WhenNode.create(parseFilterList([
    MatchedNode.create(!type.isMatched, type.bySource),
    ...args && args.length > 0 ? [
      args.length === 3 && refRight ? parseReferentialBinaryOperation(args[0], args[1], args[2]) : parseValueBinaryOperationOrExpression(args)
    ] : []
  ], "and", false));
}
function parseMergeThen(result) {
  if (isString(result)) {
    return RawNode.create([result], []);
  }
  if (isOperationNodeSource(result)) {
    return result.toOperationNode();
  }
  return result;
}
var init_merge_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/merge-parser.js"() {
    init_matched_node();
    init_operation_node_source();
    init_raw_node();
    init_when_node();
    init_object_utils();
    init_binary_operation_parser();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/deferred.js
var Deferred;
var init_deferred = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/deferred.js"() {
    Deferred = class {
      #promise;
      #resolve;
      #reject;
      constructor() {
        this.#promise = new Promise((resolve6, reject) => {
          this.#reject = reject;
          this.#resolve = resolve6;
        });
      }
      get promise() {
        return this.#promise;
      }
      resolve = (value2) => {
        if (this.#resolve) {
          this.#resolve(value2);
        }
      };
      reject = (reason) => {
        if (this.#reject) {
          this.#reject(reason);
        }
      };
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/log-once.js
function logOnce(message2) {
  if (LOGGED_MESSAGES.has(message2)) {
    return;
  }
  LOGGED_MESSAGES.add(message2);
  console.log(message2);
}
var LOGGED_MESSAGES;
var init_log_once = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/log-once.js"() {
    LOGGED_MESSAGES = /* @__PURE__ */ new Set();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-executor/query-executor-base.js
function warnOfOutdatedDriverOrPlugins(result, transformedResult) {
  const { numAffectedRows } = result;
  if (numAffectedRows === void 0 && result.numUpdatedOrDeletedRows === void 0 || numAffectedRows !== void 0 && transformedResult.numAffectedRows !== void 0) {
    return;
  }
  logOnce("kysely:warning: outdated driver/plugin detected! QueryResult.numUpdatedOrDeletedRows is deprecated and will be removed in a future release.");
}
var NO_PLUGINS, QueryExecutorBase;
var init_query_executor_base = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-executor/query-executor-base.js"() {
    init_object_utils();
    init_deferred();
    init_log_once();
    NO_PLUGINS = freeze([]);
    QueryExecutorBase = class {
      #plugins;
      constructor(plugins = NO_PLUGINS) {
        this.#plugins = plugins;
      }
      get plugins() {
        return this.#plugins;
      }
      transformQuery(node, queryId) {
        for (const plugin of this.#plugins) {
          const transformedNode = plugin.transformQuery({ node, queryId });
          if (transformedNode.kind === node.kind) {
            node = transformedNode;
          } else {
            throw new Error([
              `KyselyPlugin.transformQuery must return a node`,
              `of the same kind that was given to it.`,
              `The plugin was given a ${node.kind}`,
              `but it returned a ${transformedNode.kind}`
            ].join(" "));
          }
        }
        return node;
      }
      async executeQuery(compiledQuery, queryId) {
        return await this.provideConnection(async (connection) => {
          const result = await connection.executeQuery(compiledQuery);
          const transformedResult = await this.#transformResult(result, queryId);
          warnOfOutdatedDriverOrPlugins(result, transformedResult);
          return transformedResult;
        });
      }
      async *stream(compiledQuery, chunkSize, queryId) {
        const connectionDefer = new Deferred();
        const connectionReleaseDefer = new Deferred();
        this.provideConnection(async (connection2) => {
          connectionDefer.resolve(connection2);
          return await connectionReleaseDefer.promise;
        }).catch((ex) => connectionDefer.reject(ex));
        const connection = await connectionDefer.promise;
        try {
          for await (const result of connection.streamQuery(compiledQuery, chunkSize)) {
            yield await this.#transformResult(result, queryId);
          }
        } finally {
          connectionReleaseDefer.resolve();
        }
      }
      async #transformResult(result, queryId) {
        for (const plugin of this.#plugins) {
          result = await plugin.transformResult({ result, queryId });
        }
        return result;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-executor/noop-query-executor.js
var NoopQueryExecutor, NOOP_QUERY_EXECUTOR;
var init_noop_query_executor = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-executor/noop-query-executor.js"() {
    init_query_executor_base();
    NoopQueryExecutor = class _NoopQueryExecutor extends QueryExecutorBase {
      get adapter() {
        throw new Error("this query cannot be compiled to SQL");
      }
      compileQuery() {
        throw new Error("this query cannot be compiled to SQL");
      }
      provideConnection() {
        throw new Error("this query cannot be executed");
      }
      withConnectionProvider() {
        throw new Error("this query cannot have a connection provider");
      }
      withPlugin(plugin) {
        return new _NoopQueryExecutor([...this.plugins, plugin]);
      }
      withPlugins(plugins) {
        return new _NoopQueryExecutor([...this.plugins, ...plugins]);
      }
      withPluginAtFront(plugin) {
        return new _NoopQueryExecutor([plugin, ...this.plugins]);
      }
      withoutPlugins() {
        return new _NoopQueryExecutor([]);
      }
    };
    NOOP_QUERY_EXECUTOR = new NoopQueryExecutor();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/merge-result.js
var MergeResult;
var init_merge_result = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/merge-result.js"() {
    MergeResult = class {
      numChangedRows;
      constructor(numChangedRows) {
        this.numChangedRows = numChangedRows;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/merge-query-builder.js
var MergeQueryBuilder, WheneableMergeQueryBuilder, MatchedThenableMergeQueryBuilder, NotMatchedThenableMergeQueryBuilder;
var init_merge_query_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/merge-query-builder.js"() {
    init_insert_query_node();
    init_merge_query_node();
    init_query_node();
    init_update_query_node();
    init_insert_values_parser();
    init_join_parser();
    init_merge_parser();
    init_select_parser();
    init_top_parser();
    init_noop_query_executor();
    init_object_utils();
    init_prevent_await();
    init_merge_result();
    init_no_result_error();
    init_update_query_builder();
    MergeQueryBuilder = class _MergeQueryBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * This can be used to add any additional SQL to the end of the query.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db
       *   .mergeInto('person')
       *   .using('pet', 'pet.owner_id', 'person.id')
       *   .whenMatched()
       *   .thenDelete()
       *   .modifyEnd(sql.raw('-- this is a comment'))
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * merge into "person" using "pet" on "pet"."owner_id" = "person"."id" when matched then delete -- this is a comment
       * ```
       */
      modifyEnd(modifier) {
        return new _MergeQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, modifier.toOperationNode())
        });
      }
      /**
       * Changes a `merge into` query to an `merge top into` query.
       *
       * `top` clause is only supported by some dialects like MS SQL Server.
       *
       * ### Examples
       *
       * Affect 5 matched rows at most:
       *
       * ```ts
       * await db.mergeInto('person')
       *   .top(5)
       *   .using('pet', 'person.id', 'pet.owner_id')
       *   .whenMatched()
       *   .thenDelete()
       *   .execute()
       * ```
       *
       * The generated SQL (MS SQL Server):
       *
       * ```sql
       * merge top(5) into "person"
       * using "pet" on "person"."id" = "pet"."owner_id"
       * when matched then
       *   delete
       * ```
       *
       * Affect 50% of matched rows:
       *
       * ```ts
       * await db.mergeInto('person')
       *   .top(50, 'percent')
       *   .using('pet', 'person.id', 'pet.owner_id')
       *   .whenMatched()
       *   .thenDelete()
       *   .execute()
       * ```
       *
       * The generated SQL (MS SQL Server):
       *
       * ```sql
       * merge top(50) percent into "person"
       * using "pet" on "person"."id" = "pet"."owner_id"
       * when matched then
       *   delete
       * ```
       */
      top(expression, modifiers) {
        return new _MergeQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithTop(this.#props.queryNode, parseTop(expression, modifiers))
        });
      }
      using(...args) {
        return new WheneableMergeQueryBuilder({
          ...this.#props,
          queryNode: MergeQueryNode.cloneWithUsing(this.#props.queryNode, parseJoin("Using", args))
        });
      }
      output(args) {
        return new _MergeQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithOutput(this.#props.queryNode, parseSelectArg(args))
        });
      }
      outputAll(table2) {
        return new _MergeQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithOutput(this.#props.queryNode, parseSelectAll(table2))
        });
      }
    };
    preventAwait(MergeQueryBuilder, "don't await MergeQueryBuilder instances directly. To execute the query you need to call `execute` when available.");
    WheneableMergeQueryBuilder = class _WheneableMergeQueryBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * This can be used to add any additional SQL to the end of the query.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db
       *   .mergeInto('person')
       *   .using('pet', 'pet.owner_id', 'person.id')
       *   .whenMatched()
       *   .thenDelete()
       *   .modifyEnd(sql.raw('-- this is a comment'))
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * merge into "person" using "pet" on "pet"."owner_id" = "person"."id" when matched then delete -- this is a comment
       * ```
       */
      modifyEnd(modifier) {
        return new _WheneableMergeQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, modifier.toOperationNode())
        });
      }
      /**
       * See {@link MergeQueryBuilder.top}.
       */
      top(expression, modifiers) {
        return new _WheneableMergeQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithTop(this.#props.queryNode, parseTop(expression, modifiers))
        });
      }
      /**
       * Adds a simple `when matched` clause to the query.
       *
       * For a `when matched` clause with an `and` condition, see {@link whenMatchedAnd}.
       *
       * For a simple `when not matched` clause, see {@link whenNotMatched}.
       *
       * For a `when not matched` clause with an `and` condition, see {@link whenNotMatchedAnd}.
       *
       * ### Examples
       *
       * ```ts
       * const result = await db.mergeInto('person')
       *   .using('pet', 'person.id', 'pet.owner_id')
       *   .whenMatched()
       *   .thenDelete()
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * merge into "person"
       * using "pet" on "person"."id" = "pet"."owner_id"
       * when matched then
       *   delete
       * ```
       */
      whenMatched() {
        return this.#whenMatched([]);
      }
      whenMatchedAnd(...args) {
        return this.#whenMatched(args);
      }
      /**
       * Adds the `when matched` clause to the query with an `and` condition. But unlike
       * {@link whenMatchedAnd}, this method accepts a column reference as the 3rd argument.
       *
       * This method is similar to {@link SelectQueryBuilder.whereRef}, so see the documentation
       * for that method for more examples.
       */
      whenMatchedAndRef(lhs, op, rhs) {
        return this.#whenMatched([lhs, op, rhs], true);
      }
      #whenMatched(args, refRight) {
        return new MatchedThenableMergeQueryBuilder({
          ...this.#props,
          queryNode: MergeQueryNode.cloneWithWhen(this.#props.queryNode, parseMergeWhen({ isMatched: true }, args, refRight))
        });
      }
      /**
       * Adds a simple `when not matched` clause to the query.
       *
       * For a `when not matched` clause with an `and` condition, see {@link whenNotMatchedAnd}.
       *
       * For a simple `when matched` clause, see {@link whenMatched}.
       *
       * For a `when matched` clause with an `and` condition, see {@link whenMatchedAnd}.
       *
       * ### Examples
       *
       * ```ts
       * const result = await db.mergeInto('person')
       *   .using('pet', 'person.id', 'pet.owner_id')
       *   .whenNotMatched()
       *   .thenInsertValues({
       *     first_name: 'John',
       *     last_name: 'Doe',
       *   })
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * merge into "person"
       * using "pet" on "person"."id" = "pet"."owner_id"
       * when not matched then
       *   insert ("first_name", "last_name") values ($1, $2)
       * ```
       */
      whenNotMatched() {
        return this.#whenNotMatched([]);
      }
      whenNotMatchedAnd(...args) {
        return this.#whenNotMatched(args);
      }
      /**
       * Adds the `when not matched` clause to the query with an `and` condition. But unlike
       * {@link whenNotMatchedAnd}, this method accepts a column reference as the 3rd argument.
       *
       * Unlike {@link whenMatchedAndRef}, you cannot reference columns from the target table.
       *
       * This method is similar to {@link SelectQueryBuilder.whereRef}, so see the documentation
       * for that method for more examples.
       */
      whenNotMatchedAndRef(lhs, op, rhs) {
        return this.#whenNotMatched([lhs, op, rhs], true);
      }
      /**
       * Adds a simple `when not matched by source` clause to the query.
       *
       * Supported in MS SQL Server.
       *
       * Similar to {@link whenNotMatched}, but returns a {@link MatchedThenableMergeQueryBuilder}.
       */
      whenNotMatchedBySource() {
        return this.#whenNotMatched([], false, true);
      }
      whenNotMatchedBySourceAnd(...args) {
        return this.#whenNotMatched(args, false, true);
      }
      /**
       * Adds the `when not matched by source` clause to the query with an `and` condition.
       *
       * Similar to {@link whenNotMatchedAndRef}, but you can reference columns from
       * the target table, and not from source table and returns a {@link MatchedThenableMergeQueryBuilder}.
       */
      whenNotMatchedBySourceAndRef(lhs, op, rhs) {
        return this.#whenNotMatched([lhs, op, rhs], true, true);
      }
      output(args) {
        return new _WheneableMergeQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithOutput(this.#props.queryNode, parseSelectArg(args))
        });
      }
      outputAll(table2) {
        return new _WheneableMergeQueryBuilder({
          ...this.#props,
          queryNode: QueryNode.cloneWithOutput(this.#props.queryNode, parseSelectAll(table2))
        });
      }
      #whenNotMatched(args, refRight = false, bySource = false) {
        const props = {
          ...this.#props,
          queryNode: MergeQueryNode.cloneWithWhen(this.#props.queryNode, parseMergeWhen({ isMatched: false, bySource }, args, refRight))
        };
        const Builder = bySource ? MatchedThenableMergeQueryBuilder : NotMatchedThenableMergeQueryBuilder;
        return new Builder(props);
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       *
       * If you want to conditionally call a method on `this`, see
       * the {@link $if} method.
       *
       * ### Examples
       *
       * The next example uses a helper function `log` to log a query:
       *
       * ```ts
       * import type { Compilable } from 'kysely'
       *
       * function log<T extends Compilable>(qb: T): T {
       *   console.log(qb.compile())
       *   return qb
       * }
       *
       * await db.updateTable('person')
       *   .set({ first_name: 'John' })
       *   .$call(log)
       *   .execute()
       * ```
       */
      $call(func) {
        return func(this);
      }
      /**
       * Call `func(this)` if `condition` is true.
       *
       * This method is especially handy with optional selects. Any `returning` or `returningAll`
       * method calls add columns as optional fields to the output type when called inside
       * the `func` callback. This is because we can't know if those selections were actually
       * made before running the code.
       *
       * You can also call any other methods inside the callback.
       *
       * ### Examples
       *
       * ```ts
       * import type { PersonUpdate } from 'type-editor' // imaginary module
       *
       * async function updatePerson(id: number, updates: PersonUpdate, returnLastName: boolean) {
       *   return await db
       *     .updateTable('person')
       *     .set(updates)
       *     .where('id', '=', id)
       *     .returning(['id', 'first_name'])
       *     .$if(returnLastName, (qb) => qb.returning('last_name'))
       *     .executeTakeFirstOrThrow()
       * }
       * ```
       *
       * Any selections added inside the `if` callback will be added as optional fields to the
       * output type since we can't know if the selections were actually made before running
       * the code. In the example above the return type of the `updatePerson` function is:
       *
       * ```ts
       * Promise<{
       *   id: number
       *   first_name: string
       *   last_name?: string
       * }>
       * ```
       */
      $if(condition, func) {
        if (condition) {
          return func(this);
        }
        return new _WheneableMergeQueryBuilder({
          ...this.#props
        });
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.queryNode, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      /**
       * Executes the query and returns an array of rows.
       *
       * Also see the {@link executeTakeFirst} and {@link executeTakeFirstOrThrow} methods.
       */
      async execute() {
        const compiledQuery = this.compile();
        const result = await this.#props.executor.executeQuery(compiledQuery, this.#props.queryId);
        if (compiledQuery.query.output && this.#props.executor.adapter.supportsOutput) {
          return result.rows;
        }
        return [new MergeResult(result.numAffectedRows)];
      }
      /**
       * Executes the query and returns the first result or undefined if
       * the query returned no result.
       */
      async executeTakeFirst() {
        const [result] = await this.execute();
        return result;
      }
      /**
       * Executes the query and returns the first result or throws if
       * the query returned no result.
       *
       * By default an instance of {@link NoResultError} is thrown, but you can
       * provide a custom error class, or callback as the only argument to throw a different
       * error.
       */
      async executeTakeFirstOrThrow(errorConstructor = NoResultError) {
        const result = await this.executeTakeFirst();
        if (result === void 0) {
          const error2 = isNoResultErrorConstructor(errorConstructor) ? new errorConstructor(this.toOperationNode()) : errorConstructor(this.toOperationNode());
          throw error2;
        }
        return result;
      }
    };
    preventAwait(WheneableMergeQueryBuilder, "don't await WheneableMergeQueryBuilder instances directly. To execute the query you need to call `execute`.");
    MatchedThenableMergeQueryBuilder = class {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Performs the `delete` action.
       *
       * To perform the `do nothing` action, see {@link thenDoNothing}.
       *
       * To perform the `update` action, see {@link thenUpdate} or {@link thenUpdateSet}.
       *
       * ### Examples
       *
       * ```ts
       * const result = await db.mergeInto('person')
       *   .using('pet', 'person.id', 'pet.owner_id')
       *   .whenMatched()
       *   .thenDelete()
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * merge into "person"
       * using "pet" on "person"."id" = "pet"."owner_id"
       * when matched then
       *   delete
       * ```
       */
      thenDelete() {
        return new WheneableMergeQueryBuilder({
          ...this.#props,
          queryNode: MergeQueryNode.cloneWithThen(this.#props.queryNode, parseMergeThen("delete"))
        });
      }
      /**
       * Performs the `do nothing` action.
       *
       * This is supported in PostgreSQL.
       *
       * To perform the `delete` action, see {@link thenDelete}.
       *
       * To perform the `update` action, see {@link thenUpdate} or {@link thenUpdateSet}.
       *
       * ### Examples
       *
       * ```ts
       * const result = await db.mergeInto('person')
       *   .using('pet', 'person.id', 'pet.owner_id')
       *   .whenMatched()
       *   .thenDoNothing()
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * merge into "person"
       * using "pet" on "person"."id" = "pet"."owner_id"
       * when matched then
       *   do nothing
       * ```
       */
      thenDoNothing() {
        return new WheneableMergeQueryBuilder({
          ...this.#props,
          queryNode: MergeQueryNode.cloneWithThen(this.#props.queryNode, parseMergeThen("do nothing"))
        });
      }
      /**
       * Perform an `update` operation with a full-fledged {@link UpdateQueryBuilder}.
       * This is handy when multiple `set` invocations are needed.
       *
       * For a shorthand version of this method, see {@link thenUpdateSet}.
       *
       * To perform the `delete` action, see {@link thenDelete}.
       *
       * To perform the `do nothing` action, see {@link thenDoNothing}.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * const result = await db.mergeInto('person')
       *   .using('pet', 'person.id', 'pet.owner_id')
       *   .whenMatched()
       *   .thenUpdate((ub) => ub
       *     .set(sql`metadata['has_pets']`, 'Y')
       *     .set({
       *       updated_at: new Date().toISOString(),
       *     })
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * merge into "person"
       * using "pet" on "person"."id" = "pet"."owner_id"
       * when matched then
       *   update set metadata['has_pets'] = $1, "updated_at" = $2
       * ```
       */
      thenUpdate(set3) {
        return new WheneableMergeQueryBuilder({
          ...this.#props,
          queryNode: MergeQueryNode.cloneWithThen(this.#props.queryNode, parseMergeThen(set3(new UpdateQueryBuilder({
            queryId: this.#props.queryId,
            executor: NOOP_QUERY_EXECUTOR,
            queryNode: UpdateQueryNode.createWithoutTable()
          }))))
        });
      }
      thenUpdateSet(...args) {
        return this.thenUpdate((ub) => ub.set(...args));
      }
    };
    preventAwait(MatchedThenableMergeQueryBuilder, "don't await MatchedThenableMergeQueryBuilder instances directly. To execute the query you need to call `execute` when available.");
    NotMatchedThenableMergeQueryBuilder = class {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Performs the `do nothing` action.
       *
       * This is supported in PostgreSQL.
       *
       * To perform the `insert` action, see {@link thenInsertValues}.
       *
       * ### Examples
       *
       * ```ts
       * const result = await db.mergeInto('person')
       *   .using('pet', 'person.id', 'pet.owner_id')
       *   .whenNotMatched()
       *   .thenDoNothing()
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * merge into "person"
       * using "pet" on "person"."id" = "pet"."owner_id"
       * when not matched then
       *   do nothing
       * ```
       */
      thenDoNothing() {
        return new WheneableMergeQueryBuilder({
          ...this.#props,
          queryNode: MergeQueryNode.cloneWithThen(this.#props.queryNode, parseMergeThen("do nothing"))
        });
      }
      thenInsertValues(insert) {
        const [columns, values] = parseInsertExpression(insert);
        return new WheneableMergeQueryBuilder({
          ...this.#props,
          queryNode: MergeQueryNode.cloneWithThen(this.#props.queryNode, parseMergeThen(InsertQueryNode.cloneWith(InsertQueryNode.createWithoutInto(), {
            columns,
            values
          })))
        });
      }
    };
    preventAwait(NotMatchedThenableMergeQueryBuilder, "don't await NotMatchedThenableMergeQueryBuilder instances directly. To execute the query you need to call `execute` when available.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-creator.js
var QueryCreator;
var init_query_creator = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-creator.js"() {
    init_select_query_builder();
    init_insert_query_builder();
    init_delete_query_builder();
    init_update_query_builder();
    init_delete_query_node();
    init_insert_query_node();
    init_select_query_node();
    init_update_query_node();
    init_table_parser();
    init_with_parser();
    init_with_node();
    init_query_id();
    init_with_schema_plugin();
    init_object_utils();
    init_select_parser();
    init_merge_query_builder();
    init_merge_query_node();
    QueryCreator = class _QueryCreator {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      selectFrom(from) {
        return createSelectQueryBuilder({
          queryId: createQueryId(),
          executor: this.#props.executor,
          queryNode: SelectQueryNode.createFrom(parseTableExpressionOrList(from), this.#props.withNode)
        });
      }
      selectNoFrom(selection) {
        return createSelectQueryBuilder({
          queryId: createQueryId(),
          executor: this.#props.executor,
          queryNode: SelectQueryNode.cloneWithSelections(SelectQueryNode.create(this.#props.withNode), parseSelectArg(selection))
        });
      }
      /**
       * Creates an insert query.
       *
       * The return value of this query is an instance of {@link InsertResult}. {@link InsertResult}
       * has the {@link InsertResult.insertId | insertId} field that holds the auto incremented id of
       * the inserted row if the db returned one.
       *
       * See the {@link InsertQueryBuilder.values | values} method for more info and examples. Also see
       * the {@link ReturningInterface.returning | returning} method for a way to return columns
       * on supported databases like PostgreSQL.
       *
       * ### Examples
       *
       * ```ts
       * const result = await db
       *   .insertInto('person')
       *   .values({
       *     first_name: 'Jennifer',
       *     last_name: 'Aniston'
       *   })
       *   .executeTakeFirst()
       *
       * console.log(result.insertId)
       * ```
       *
       * Some databases like PostgreSQL support the `returning` method:
       *
       * ```ts
       * const { id } = await db
       *   .insertInto('person')
       *   .values({
       *     first_name: 'Jennifer',
       *     last_name: 'Aniston'
       *   })
       *   .returning('id')
       *   .executeTakeFirstOrThrow()
       * ```
       */
      insertInto(table2) {
        return new InsertQueryBuilder({
          queryId: createQueryId(),
          executor: this.#props.executor,
          queryNode: InsertQueryNode.create(parseTable(table2), this.#props.withNode)
        });
      }
      /**
       * Creates a replace query.
       *
       * A MySQL-only statement similar to {@link InsertQueryBuilder.onDuplicateKeyUpdate}
       * that deletes and inserts values on collision instead of updating existing rows.
       *
       * The return value of this query is an instance of {@link InsertResult}. {@link InsertResult}
       * has the {@link InsertResult.insertId | insertId} field that holds the auto incremented id of
       * the inserted row if the db returned one.
       *
       * See the {@link InsertQueryBuilder.values | values} method for more info and examples.
       *
       * ### Examples
       *
       * ```ts
       * const result = await db
       *   .replaceInto('person')
       *   .values({
       *     first_name: 'Jennifer',
       *     last_name: 'Aniston'
       *   })
       *   .executeTakeFirst()
       *
       * console.log(result.insertId)
       * ```
       */
      replaceInto(table2) {
        return new InsertQueryBuilder({
          queryId: createQueryId(),
          executor: this.#props.executor,
          queryNode: InsertQueryNode.create(parseTable(table2), this.#props.withNode, true)
        });
      }
      deleteFrom(tables) {
        return new DeleteQueryBuilder({
          queryId: createQueryId(),
          executor: this.#props.executor,
          queryNode: DeleteQueryNode.create(parseTableExpressionOrList(tables), this.#props.withNode)
        });
      }
      updateTable(table2) {
        return new UpdateQueryBuilder({
          queryId: createQueryId(),
          executor: this.#props.executor,
          queryNode: UpdateQueryNode.create(parseTableExpression(table2), this.#props.withNode)
        });
      }
      mergeInto(targetTable) {
        return new MergeQueryBuilder({
          queryId: createQueryId(),
          executor: this.#props.executor,
          queryNode: MergeQueryNode.create(parseAliasedTable(targetTable), this.#props.withNode)
        });
      }
      /**
       * Creates a `with` query (Common Table Expression).
       *
       * ### Examples
       *
       * <!-- siteExample("cte", "Simple selects", 10) -->
       *
       * Common table expressions (CTE) are a great way to modularize complex queries.
       * Essentially they allow you to run multiple separate queries within a
       * single roundtrip to the DB.
       *
       * Since CTEs are a part of the main query, query optimizers inside DB
       * engines are able to optimize the overall query. For example, postgres
       * is able to inline the CTEs inside the using queries if it decides it's
       * faster.
       *
       * ```ts
       * const result = await db
       *   // Create a CTE called `jennifers` that selects all
       *   // persons named 'Jennifer'.
       *   .with('jennifers', (db) => db
       *     .selectFrom('person')
       *     .where('first_name', '=', 'Jennifer')
       *     .select(['id', 'age'])
       *   )
       *   // Select all rows from the `jennifers` CTE and
       *   // further filter it.
       *   .with('adult_jennifers', (db) => db
       *     .selectFrom('jennifers')
       *     .where('age', '>', 18)
       *     .select(['id', 'age'])
       *   )
       *   // Finally select all adult jennifers that are
       *   // also younger than 60.
       *   .selectFrom('adult_jennifers')
       *   .where('age', '<', 60)
       *   .selectAll()
       *   .execute()
       * ```
       *
       * <!-- siteExample("cte", "Inserts, updates and deletions", 20) -->
       *
       * Some databases like postgres also allow you to run other queries than selects
       * in CTEs. On these databases CTEs are extremely powerful:
       *
       * ```ts
       * const result = await db
       *   .with('new_person', (db) => db
       *     .insertInto('person')
       *     .values({
       *       first_name: 'Jennifer',
       *       age: 35,
       *     })
       *     .returning('id')
       *   )
       *   .with('new_pet', (db) => db
       *     .insertInto('pet')
       *     .values({
       *       name: 'Doggo',
       *       species: 'dog',
       *       is_favorite: true,
       *       // Use the id of the person we just inserted.
       *       owner_id: db
       *         .selectFrom('new_person')
       *         .select('id')
       *     })
       *     .returning('id')
       *   )
       *   .selectFrom(['new_person', 'new_pet'])
       *   .select([
       *     'new_person.id as person_id',
       *     'new_pet.id as pet_id'
       *   ])
       *   .execute()
       * ```
       *
       * The CTE name can optionally specify column names in addition to
       * a name. In that case Kysely requires the expression to retun
       * rows with the same columns.
       *
       * ```ts
       * await db
       *   .with('jennifers(id, age)', (db) => db
       *     .selectFrom('person')
       *     .where('first_name', '=', 'Jennifer')
       *     // This is ok since we return columns with the same
       *     // names as specified by `jennifers(id, age)`.
       *     .select(['id', 'age'])
       *   )
       *   .selectFrom('jennifers')
       *   .selectAll()
       *   .execute()
       * ```
       *
       * The first argument can also be a callback. The callback is passed
       * a `CTEBuilder` instance that can be used to configure the CTE:
       *
       * ```ts
       * await db
       *   .with(
       *     (cte) => cte('jennifers').materialized(),
       *     (db) => db
       *       .selectFrom('person')
       *       .where('first_name', '=', 'Jennifer')
       *       .select(['id', 'age'])
       *   )
       *   .selectFrom('jennifers')
       *   .selectAll()
       *   .execute()
       * ```
       */
      with(nameOrBuilder, expression) {
        const cte = parseCommonTableExpression(nameOrBuilder, expression);
        return new _QueryCreator({
          ...this.#props,
          withNode: this.#props.withNode ? WithNode.cloneWithExpression(this.#props.withNode, cte) : WithNode.create(cte)
        });
      }
      /**
       * Creates a recursive `with` query (Common Table Expression).
       *
       * Note that recursiveness is a property of the whole `with` statement.
       * You cannot have recursive and non-recursive CTEs in a same `with` statement.
       * Therefore the recursiveness is determined by the **first** `with` or
       * `withRecusive` call you make.
       *
       * See the {@link with} method for examples and more documentation.
       */
      withRecursive(nameOrBuilder, expression) {
        const cte = parseCommonTableExpression(nameOrBuilder, expression);
        return new _QueryCreator({
          ...this.#props,
          withNode: this.#props.withNode ? WithNode.cloneWithExpression(this.#props.withNode, cte) : WithNode.create(cte, { recursive: true })
        });
      }
      /**
       * Returns a copy of this query creator instance with the given plugin installed.
       */
      withPlugin(plugin) {
        return new _QueryCreator({
          ...this.#props,
          executor: this.#props.executor.withPlugin(plugin)
        });
      }
      /**
       * Returns a copy of this query creator instance without any plugins.
       */
      withoutPlugins() {
        return new _QueryCreator({
          ...this.#props,
          executor: this.#props.executor.withoutPlugins()
        });
      }
      /**
       * Sets the schema to be used for all table references that don't explicitly
       * specify a schema.
       *
       * This only affects the query created through the builder returned from
       * this method and doesn't modify the `db` instance.
       *
       * See [this recipe](https://github.com/kysely-org/kysely/blob/master/site/docs/recipes/0007-schemas.md)
       * for a more detailed explanation.
       *
       * ### Examples
       *
       * ```
       * await db
       *   .withSchema('mammals')
       *   .selectFrom('pet')
       *   .selectAll()
       *   .innerJoin('public.person', 'public.person.id', 'pet.owner_id')
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select * from "mammals"."pet"
       * inner join "public"."person"
       * on "public"."person"."id" = "mammals"."pet"."owner_id"
       * ```
       *
       * `withSchema` is smart enough to not add schema for aliases,
       * common table expressions or other places where the schema
       * doesn't belong to:
       *
       * ```
       * await db
       *   .withSchema('mammals')
       *   .selectFrom('pet as p')
       *   .select('p.name')
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select "p"."name" from "mammals"."pet" as "p"
       * ```
       */
      withSchema(schema) {
        return new _QueryCreator({
          ...this.#props,
          executor: this.#props.executor.withPluginAtFront(new WithSchemaPlugin(schema))
        });
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/parse-utils.js
function createQueryCreator() {
  return new QueryCreator({
    executor: NOOP_QUERY_EXECUTOR
  });
}
function createJoinBuilder(joinType, table2) {
  return new JoinBuilder({
    joinNode: JoinNode.create(joinType, parseTableExpression(table2))
  });
}
function createOverBuilder() {
  return new OverBuilder({
    overNode: OverNode.create()
  });
}
var init_parse_utils = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/parse-utils.js"() {
    init_join_node();
    init_over_node();
    init_join_builder();
    init_over_builder();
    init_query_creator();
    init_noop_query_executor();
    init_table_parser();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/join-parser.js
function parseJoin(joinType, args) {
  if (args.length === 3) {
    return parseSingleOnJoin(joinType, args[0], args[1], args[2]);
  } else if (args.length === 2) {
    return parseCallbackJoin(joinType, args[0], args[1]);
  } else {
    throw new Error("not implemented");
  }
}
function parseCallbackJoin(joinType, from, callback) {
  return callback(createJoinBuilder(joinType, from)).toOperationNode();
}
function parseSingleOnJoin(joinType, from, lhsColumn, rhsColumn) {
  return JoinNode.createWithOn(joinType, parseTableExpression(from), parseReferentialBinaryOperation(lhsColumn, "=", rhsColumn));
}
var init_join_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/join-parser.js"() {
    init_join_node();
    init_table_parser();
    init_binary_operation_parser();
    init_parse_utils();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/offset-node.js
var OffsetNode;
var init_offset_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/offset-node.js"() {
    init_object_utils();
    OffsetNode = freeze({
      is(node) {
        return node.kind === "OffsetNode";
      },
      create(offset) {
        return freeze({
          kind: "OffsetNode",
          offset
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/group-by-item-node.js
var GroupByItemNode;
var init_group_by_item_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/group-by-item-node.js"() {
    init_object_utils();
    GroupByItemNode = freeze({
      is(node) {
        return node.kind === "GroupByItemNode";
      },
      create(groupBy) {
        return freeze({
          kind: "GroupByItemNode",
          groupBy
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/group-by-parser.js
function parseGroupBy(groupBy) {
  groupBy = isFunction(groupBy) ? groupBy(expressionBuilder()) : groupBy;
  return parseReferenceExpressionOrList(groupBy).map(GroupByItemNode.create);
}
var init_group_by_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/group-by-parser.js"() {
    init_group_by_item_node();
    init_expression_builder();
    init_object_utils();
    init_reference_parser();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/set-operation-node.js
var SetOperationNode;
var init_set_operation_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/set-operation-node.js"() {
    init_object_utils();
    SetOperationNode = freeze({
      is(node) {
        return node.kind === "SetOperationNode";
      },
      create(operator, expression, all) {
        return freeze({
          kind: "SetOperationNode",
          operator,
          expression,
          all
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/set-operation-parser.js
function parseSetOperations(operator, expression, all) {
  if (isFunction(expression)) {
    expression = expression(createExpressionBuilder());
  }
  if (!isReadonlyArray(expression)) {
    expression = [expression];
  }
  return expression.map((expr) => SetOperationNode.create(operator, parseExpression(expr), all));
}
var init_set_operation_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/set-operation-parser.js"() {
    init_expression_builder();
    init_set_operation_node();
    init_object_utils();
    init_expression_parser();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/expression/expression-wrapper.js
var ExpressionWrapper, AliasedExpressionWrapper, OrWrapper, AndWrapper;
var init_expression_wrapper = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/expression/expression-wrapper.js"() {
    init_alias_node();
    init_and_node();
    init_identifier_node();
    init_operation_node_source();
    init_or_node();
    init_parens_node();
    init_binary_operation_parser();
    ExpressionWrapper = class _ExpressionWrapper {
      #node;
      constructor(node) {
        this.#node = node;
      }
      /** @private */
      get expressionType() {
        return void 0;
      }
      as(alias) {
        return new AliasedExpressionWrapper(this, alias);
      }
      or(...args) {
        return new OrWrapper(OrNode.create(this.#node, parseValueBinaryOperationOrExpression(args)));
      }
      and(...args) {
        return new AndWrapper(AndNode.create(this.#node, parseValueBinaryOperationOrExpression(args)));
      }
      /**
       * Change the output type of the expression.
       *
       * This method call doesn't change the SQL in any way. This methods simply
       * returns a copy of this `ExpressionWrapper` with a new output type.
       */
      $castTo() {
        return new _ExpressionWrapper(this.#node);
      }
      /**
       * Omit null from the expression's type.
       *
       * This function can be useful in cases where you know an expression can't be
       * null, but Kysely is unable to infer it.
       *
       * This method call doesn't change the SQL in any way. This methods simply
       * returns a copy of `this` with a new output type.
       */
      $notNull() {
        return new _ExpressionWrapper(this.#node);
      }
      toOperationNode() {
        return this.#node;
      }
    };
    AliasedExpressionWrapper = class {
      #expr;
      #alias;
      constructor(expr, alias) {
        this.#expr = expr;
        this.#alias = alias;
      }
      /** @private */
      get expression() {
        return this.#expr;
      }
      /** @private */
      get alias() {
        return this.#alias;
      }
      toOperationNode() {
        return AliasNode.create(this.#expr.toOperationNode(), isOperationNodeSource(this.#alias) ? this.#alias.toOperationNode() : IdentifierNode.create(this.#alias));
      }
    };
    OrWrapper = class _OrWrapper {
      #node;
      constructor(node) {
        this.#node = node;
      }
      /** @private */
      get expressionType() {
        return void 0;
      }
      as(alias) {
        return new AliasedExpressionWrapper(this, alias);
      }
      or(...args) {
        return new _OrWrapper(OrNode.create(this.#node, parseValueBinaryOperationOrExpression(args)));
      }
      /**
       * Change the output type of the expression.
       *
       * This method call doesn't change the SQL in any way. This methods simply
       * returns a copy of this `OrWrapper` with a new output type.
       */
      $castTo() {
        return new _OrWrapper(this.#node);
      }
      toOperationNode() {
        return ParensNode.create(this.#node);
      }
    };
    AndWrapper = class _AndWrapper {
      #node;
      constructor(node) {
        this.#node = node;
      }
      /** @private */
      get expressionType() {
        return void 0;
      }
      as(alias) {
        return new AliasedExpressionWrapper(this, alias);
      }
      and(...args) {
        return new _AndWrapper(AndNode.create(this.#node, parseValueBinaryOperationOrExpression(args)));
      }
      /**
       * Change the output type of the expression.
       *
       * This method call doesn't change the SQL in any way. This methods simply
       * returns a copy of this `AndWrapper` with a new output type.
       */
      $castTo() {
        return new _AndWrapper(this.#node);
      }
      toOperationNode() {
        return ParensNode.create(this.#node);
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/fetch-node.js
var FetchNode;
var init_fetch_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/fetch-node.js"() {
    init_value_node();
    FetchNode = {
      is(node) {
        return node.kind === "FetchNode";
      },
      create(rowCount, modifier) {
        return {
          kind: "FetchNode",
          rowCount: ValueNode.create(rowCount),
          modifier
        };
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/fetch-parser.js
function parseFetch(rowCount, modifier) {
  if (!isNumber(rowCount) && !isBigInt(rowCount)) {
    throw new Error(`Invalid fetch row count: ${rowCount}`);
  }
  if (!isFetchModifier(modifier)) {
    throw new Error(`Invalid fetch modifier: ${modifier}`);
  }
  return FetchNode.create(rowCount, modifier);
}
function isFetchModifier(value2) {
  return value2 === "only" || value2 === "with ties";
}
var init_fetch_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/fetch-parser.js"() {
    init_fetch_node();
    init_object_utils();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/select-query-builder.js
function createSelectQueryBuilder(props) {
  return new SelectQueryBuilderImpl(props);
}
var SelectQueryBuilderImpl, AliasedSelectQueryBuilderImpl;
var init_select_query_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/select-query-builder.js"() {
    init_alias_node();
    init_select_modifier_node();
    init_join_parser();
    init_table_parser();
    init_select_parser();
    init_reference_parser();
    init_select_query_node();
    init_query_node();
    init_order_by_parser();
    init_prevent_await();
    init_limit_node();
    init_offset_node();
    init_object_utils();
    init_group_by_parser();
    init_no_result_error();
    init_identifier_node();
    init_set_operation_parser();
    init_binary_operation_parser();
    init_expression_wrapper();
    init_value_parser();
    init_fetch_parser();
    init_top_parser();
    SelectQueryBuilderImpl = class _SelectQueryBuilderImpl {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      get expressionType() {
        return void 0;
      }
      get isSelectQueryBuilder() {
        return true;
      }
      where(...args) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseValueBinaryOperationOrExpression(args))
        });
      }
      whereRef(lhs, op, rhs) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithWhere(this.#props.queryNode, parseReferentialBinaryOperation(lhs, op, rhs))
        });
      }
      having(...args) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithHaving(this.#props.queryNode, parseValueBinaryOperationOrExpression(args))
        });
      }
      havingRef(lhs, op, rhs) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithHaving(this.#props.queryNode, parseReferentialBinaryOperation(lhs, op, rhs))
        });
      }
      select(selection) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithSelections(this.#props.queryNode, parseSelectArg(selection))
        });
      }
      distinctOn(selection) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithDistinctOn(this.#props.queryNode, parseReferenceExpressionOrList(selection))
        });
      }
      modifyFront(modifier) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithFrontModifier(this.#props.queryNode, SelectModifierNode.createWithExpression(modifier.toOperationNode()))
        });
      }
      modifyEnd(modifier) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.createWithExpression(modifier.toOperationNode()))
        });
      }
      distinct() {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithFrontModifier(this.#props.queryNode, SelectModifierNode.create("Distinct"))
        });
      }
      forUpdate(of) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create("ForUpdate", of ? asArray(of).map(parseTable) : void 0))
        });
      }
      forShare(of) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create("ForShare", of ? asArray(of).map(parseTable) : void 0))
        });
      }
      forKeyShare(of) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create("ForKeyShare", of ? asArray(of).map(parseTable) : void 0))
        });
      }
      forNoKeyUpdate(of) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create("ForNoKeyUpdate", of ? asArray(of).map(parseTable) : void 0))
        });
      }
      skipLocked() {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create("SkipLocked"))
        });
      }
      noWait() {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithEndModifier(this.#props.queryNode, SelectModifierNode.create("NoWait"))
        });
      }
      selectAll(table2) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithSelections(this.#props.queryNode, parseSelectAll(table2))
        });
      }
      innerJoin(...args) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("InnerJoin", args))
        });
      }
      leftJoin(...args) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("LeftJoin", args))
        });
      }
      rightJoin(...args) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("RightJoin", args))
        });
      }
      fullJoin(...args) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("FullJoin", args))
        });
      }
      innerJoinLateral(...args) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("LateralInnerJoin", args))
        });
      }
      leftJoinLateral(...args) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithJoin(this.#props.queryNode, parseJoin("LateralLeftJoin", args))
        });
      }
      orderBy(...args) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithOrderByItems(this.#props.queryNode, parseOrderBy(args))
        });
      }
      groupBy(groupBy) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithGroupByItems(this.#props.queryNode, parseGroupBy(groupBy))
        });
      }
      limit(limit) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithLimit(this.#props.queryNode, LimitNode.create(parseValueExpression(limit)))
        });
      }
      offset(offset) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithOffset(this.#props.queryNode, OffsetNode.create(parseValueExpression(offset)))
        });
      }
      fetch(rowCount, modifier = "only") {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithFetch(this.#props.queryNode, parseFetch(rowCount, modifier))
        });
      }
      top(expression, modifiers) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithTop(this.#props.queryNode, parseTop(expression, modifiers))
        });
      }
      union(expression) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations("union", expression, false))
        });
      }
      unionAll(expression) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations("union", expression, true))
        });
      }
      intersect(expression) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations("intersect", expression, false))
        });
      }
      intersectAll(expression) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations("intersect", expression, true))
        });
      }
      except(expression) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations("except", expression, false))
        });
      }
      exceptAll(expression) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithSetOperations(this.#props.queryNode, parseSetOperations("except", expression, true))
        });
      }
      as(alias) {
        return new AliasedSelectQueryBuilderImpl(this, alias);
      }
      clearSelect() {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithoutSelections(this.#props.queryNode)
        });
      }
      clearWhere() {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithoutWhere(this.#props.queryNode)
        });
      }
      clearLimit() {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithoutLimit(this.#props.queryNode)
        });
      }
      clearOffset() {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithoutOffset(this.#props.queryNode)
        });
      }
      clearOrderBy() {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithoutOrderBy(this.#props.queryNode)
        });
      }
      clearGroupBy() {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: SelectQueryNode.cloneWithoutGroupBy(this.#props.queryNode)
        });
      }
      $call(func) {
        return func(this);
      }
      $if(condition, func) {
        if (condition) {
          return func(this);
        }
        return new _SelectQueryBuilderImpl({
          ...this.#props
        });
      }
      $castTo() {
        return new _SelectQueryBuilderImpl(this.#props);
      }
      $narrowType() {
        return new _SelectQueryBuilderImpl(this.#props);
      }
      $assertType() {
        return new _SelectQueryBuilderImpl(this.#props);
      }
      $asTuple() {
        return new ExpressionWrapper(this.toOperationNode());
      }
      withPlugin(plugin) {
        return new _SelectQueryBuilderImpl({
          ...this.#props,
          executor: this.#props.executor.withPlugin(plugin)
        });
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.queryNode, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        const compiledQuery = this.compile();
        const result = await this.#props.executor.executeQuery(compiledQuery, this.#props.queryId);
        return result.rows;
      }
      async executeTakeFirst() {
        const [result] = await this.execute();
        return result;
      }
      async executeTakeFirstOrThrow(errorConstructor = NoResultError) {
        const result = await this.executeTakeFirst();
        if (result === void 0) {
          const error2 = isNoResultErrorConstructor(errorConstructor) ? new errorConstructor(this.toOperationNode()) : errorConstructor(this.toOperationNode());
          throw error2;
        }
        return result;
      }
      async *stream(chunkSize = 100) {
        const compiledQuery = this.compile();
        const stream = this.#props.executor.stream(compiledQuery, chunkSize, this.#props.queryId);
        for await (const item of stream) {
          yield* item.rows;
        }
      }
      async explain(format, options2) {
        const builder = new _SelectQueryBuilderImpl({
          ...this.#props,
          queryNode: QueryNode.cloneWithExplain(this.#props.queryNode, format, options2)
        });
        return await builder.execute();
      }
    };
    preventAwait(SelectQueryBuilderImpl, "don't await SelectQueryBuilder instances directly. To execute the query you need to call `execute` or `executeTakeFirst`.");
    AliasedSelectQueryBuilderImpl = class {
      #queryBuilder;
      #alias;
      constructor(queryBuilder, alias) {
        this.#queryBuilder = queryBuilder;
        this.#alias = alias;
      }
      get expression() {
        return this.#queryBuilder;
      }
      get alias() {
        return this.#alias;
      }
      get isAliasedSelectQueryBuilder() {
        return true;
      }
      toOperationNode() {
        return AliasNode.create(this.#queryBuilder.toOperationNode(), IdentifierNode.create(this.#alias));
      }
    };
    preventAwait(AliasedSelectQueryBuilderImpl, "don't await AliasedSelectQueryBuilder instances directly. AliasedSelectQueryBuilder should never be executed directly since it's always a part of another query.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/aggregate-function-node.js
var AggregateFunctionNode;
var init_aggregate_function_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/aggregate-function-node.js"() {
    init_object_utils();
    init_where_node();
    init_order_by_node();
    AggregateFunctionNode = freeze({
      is(node) {
        return node.kind === "AggregateFunctionNode";
      },
      create(aggregateFunction, aggregated = []) {
        return freeze({
          kind: "AggregateFunctionNode",
          func: aggregateFunction,
          aggregated
        });
      },
      cloneWithDistinct(aggregateFunctionNode) {
        return freeze({
          ...aggregateFunctionNode,
          distinct: true
        });
      },
      cloneWithOrderBy(aggregateFunctionNode, orderItems) {
        return freeze({
          ...aggregateFunctionNode,
          orderBy: aggregateFunctionNode.orderBy ? OrderByNode.cloneWithItems(aggregateFunctionNode.orderBy, orderItems) : OrderByNode.create(orderItems)
        });
      },
      cloneWithFilter(aggregateFunctionNode, filter) {
        return freeze({
          ...aggregateFunctionNode,
          filter: aggregateFunctionNode.filter ? WhereNode.cloneWithOperation(aggregateFunctionNode.filter, "And", filter) : WhereNode.create(filter)
        });
      },
      cloneWithOrFilter(aggregateFunctionNode, filter) {
        return freeze({
          ...aggregateFunctionNode,
          filter: aggregateFunctionNode.filter ? WhereNode.cloneWithOperation(aggregateFunctionNode.filter, "Or", filter) : WhereNode.create(filter)
        });
      },
      cloneWithOver(aggregateFunctionNode, over) {
        return freeze({
          ...aggregateFunctionNode,
          over
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/function-node.js
var FunctionNode;
var init_function_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/function-node.js"() {
    init_object_utils();
    FunctionNode = freeze({
      is(node) {
        return node.kind === "FunctionNode";
      },
      create(func, args) {
        return freeze({
          kind: "FunctionNode",
          func,
          arguments: args
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/aggregate-function-builder.js
var AggregateFunctionBuilder, AliasedAggregateFunctionBuilder;
var init_aggregate_function_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/aggregate-function-builder.js"() {
    init_object_utils();
    init_aggregate_function_node();
    init_alias_node();
    init_identifier_node();
    init_prevent_await();
    init_parse_utils();
    init_binary_operation_parser();
    init_order_by_parser();
    AggregateFunctionBuilder = class _AggregateFunctionBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /** @private */
      get expressionType() {
        return void 0;
      }
      /**
       * Returns an aliased version of the function.
       *
       * In addition to slapping `as "the_alias"` to the end of the SQL,
       * this method also provides strict typing:
       *
       * ```ts
       * const result = await db
       *   .selectFrom('person')
       *   .select(
       *     (eb) => eb.fn.count<number>('id').as('person_count')
       *   )
       *   .executeTakeFirstOrThrow()
       *
       * // `person_count: number` field exists in the result type.
       * console.log(result.person_count)
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select count("id") as "person_count"
       * from "person"
       * ```
       */
      as(alias) {
        return new AliasedAggregateFunctionBuilder(this, alias);
      }
      /**
       * Adds a `distinct` clause inside the function.
       *
       * ### Examples
       *
       * ```ts
       * const result = await db
       *   .selectFrom('person')
       *   .select((eb) =>
       *     eb.fn.count<number>('first_name').distinct().as('first_name_count')
       *   )
       *   .executeTakeFirstOrThrow()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select count(distinct "first_name") as "first_name_count"
       * from "person"
       * ```
       */
      distinct() {
        return new _AggregateFunctionBuilder({
          ...this.#props,
          aggregateFunctionNode: AggregateFunctionNode.cloneWithDistinct(this.#props.aggregateFunctionNode)
        });
      }
      /**
       * Adds an `order by` clause inside the aggregate function.
       *
       * ### Examples
       *
       * ```ts
       * const result = await db
       *   .selectFrom('person')
       *   .innerJoin('pet', 'pet.owner_id', 'person.id')
       *   .select((eb) =>
       *     eb.fn.jsonAgg('pet').orderBy('pet.name').as('person_pets')
       *   )
       *   .executeTakeFirstOrThrow()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select json_agg("pet" order by "pet"."name") as "person_pets"
       * from "person"
       * inner join "pet" ON "pet"."owner_id" = "person"."id"
       * ```
       */
      orderBy(orderBy, direction) {
        return new _AggregateFunctionBuilder({
          ...this.#props,
          aggregateFunctionNode: AggregateFunctionNode.cloneWithOrderBy(this.#props.aggregateFunctionNode, parseOrderBy([orderBy, direction]))
        });
      }
      filterWhere(...args) {
        return new _AggregateFunctionBuilder({
          ...this.#props,
          aggregateFunctionNode: AggregateFunctionNode.cloneWithFilter(this.#props.aggregateFunctionNode, parseValueBinaryOperationOrExpression(args))
        });
      }
      /**
       * Adds a `filter` clause with a nested `where` clause after the function, where
       * both sides of the operator are references to columns.
       *
       * Similar to {@link WhereInterface}'s `whereRef` method.
       *
       * ### Examples
       *
       * Count people with same first and last names versus general public:
       *
       * ```ts
       * const result = await db
       *   .selectFrom('person')
       *   .select((eb) => [
       *     eb.fn
       *       .count<number>('id')
       *       .filterWhereRef('first_name', '=', 'last_name')
       *       .as('repeat_name_count'),
       *     eb.fn.count<number>('id').as('total_count'),
       *   ])
       *   .executeTakeFirstOrThrow()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select
       *   count("id") filter(where "first_name" = "last_name") as "repeat_name_count",
       *   count("id") as "total_count"
       * from "person"
       * ```
       */
      filterWhereRef(lhs, op, rhs) {
        return new _AggregateFunctionBuilder({
          ...this.#props,
          aggregateFunctionNode: AggregateFunctionNode.cloneWithFilter(this.#props.aggregateFunctionNode, parseReferentialBinaryOperation(lhs, op, rhs))
        });
      }
      /**
       * Adds an `over` clause (window functions) after the function.
       *
       * ### Examples
       *
       * ```ts
       * const result = await db
       *   .selectFrom('person')
       *   .select(
       *     (eb) => eb.fn.avg<number>('age').over().as('average_age')
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select avg("age") over() as "average_age"
       * from "person"
       * ```
       *
       * Also supports passing a callback that returns an over builder,
       * allowing to add partition by and sort by clauses inside over.
       *
       * ```ts
       * const result = await db
       *   .selectFrom('person')
       *   .select(
       *     (eb) => eb.fn.avg<number>('age').over(
       *       ob => ob.partitionBy('last_name').orderBy('first_name', 'asc')
       *     ).as('average_age')
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select avg("age") over(partition by "last_name" order by "first_name" asc) as "average_age"
       * from "person"
       * ```
       */
      over(over) {
        const builder = createOverBuilder();
        return new _AggregateFunctionBuilder({
          ...this.#props,
          aggregateFunctionNode: AggregateFunctionNode.cloneWithOver(this.#props.aggregateFunctionNode, (over ? over(builder) : builder).toOperationNode())
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      /**
       * Casts the expression to the given type.
       *
       * This method call doesn't change the SQL in any way. This methods simply
       * returns a copy of this `AggregateFunctionBuilder` with a new output type.
       */
      $castTo() {
        return new _AggregateFunctionBuilder(this.#props);
      }
      /**
       * Omit null from the expression's type.
       *
       * This function can be useful in cases where you know an expression can't be
       * null, but Kysely is unable to infer it.
       *
       * This method call doesn't change the SQL in any way. This methods simply
       * returns a copy of `this` with a new output type.
       */
      $notNull() {
        return new _AggregateFunctionBuilder(this.#props);
      }
      toOperationNode() {
        return this.#props.aggregateFunctionNode;
      }
    };
    preventAwait(AggregateFunctionBuilder, "don't await AggregateFunctionBuilder instances. They are never executed directly and are always just a part of a query.");
    AliasedAggregateFunctionBuilder = class {
      #aggregateFunctionBuilder;
      #alias;
      constructor(aggregateFunctionBuilder, alias) {
        this.#aggregateFunctionBuilder = aggregateFunctionBuilder;
        this.#alias = alias;
      }
      /** @private */
      get expression() {
        return this.#aggregateFunctionBuilder;
      }
      /** @private */
      get alias() {
        return this.#alias;
      }
      toOperationNode() {
        return AliasNode.create(this.#aggregateFunctionBuilder.toOperationNode(), IdentifierNode.create(this.#alias));
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/function-module.js
function createFunctionModule() {
  const fn = (name, args) => {
    return new ExpressionWrapper(FunctionNode.create(name, parseReferenceExpressionOrList(args ?? [])));
  };
  const agg = (name, args) => {
    return new AggregateFunctionBuilder({
      aggregateFunctionNode: AggregateFunctionNode.create(name, args ? parseReferenceExpressionOrList(args) : void 0)
    });
  };
  return Object.assign(fn, {
    agg,
    avg(column) {
      return agg("avg", [column]);
    },
    coalesce(...values) {
      return fn("coalesce", values);
    },
    count(column) {
      return agg("count", [column]);
    },
    countAll(table2) {
      return new AggregateFunctionBuilder({
        aggregateFunctionNode: AggregateFunctionNode.create("count", parseSelectAll(table2))
      });
    },
    max(column) {
      return agg("max", [column]);
    },
    min(column) {
      return agg("min", [column]);
    },
    sum(column) {
      return agg("sum", [column]);
    },
    any(column) {
      return fn("any", [column]);
    },
    jsonAgg(table2) {
      return new AggregateFunctionBuilder({
        aggregateFunctionNode: AggregateFunctionNode.create("json_agg", [
          isString(table2) ? parseTable(table2) : table2.toOperationNode()
        ])
      });
    },
    toJson(table2) {
      return new ExpressionWrapper(FunctionNode.create("to_json", [
        isString(table2) ? parseTable(table2) : table2.toOperationNode()
      ]));
    }
  });
}
var init_function_module = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/function-module.js"() {
    init_expression_wrapper();
    init_aggregate_function_node();
    init_function_node();
    init_reference_parser();
    init_select_parser();
    init_aggregate_function_builder();
    init_object_utils();
    init_table_parser();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/unary-operation-node.js
var UnaryOperationNode;
var init_unary_operation_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/unary-operation-node.js"() {
    init_object_utils();
    UnaryOperationNode = freeze({
      is(node) {
        return node.kind === "UnaryOperationNode";
      },
      create(operator, operand) {
        return freeze({
          kind: "UnaryOperationNode",
          operator,
          operand
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/unary-operation-parser.js
function parseUnaryOperation(operator, operand) {
  return UnaryOperationNode.create(OperatorNode.create(operator), parseReferenceExpression(operand));
}
var init_unary_operation_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/unary-operation-parser.js"() {
    init_operator_node();
    init_unary_operation_node();
    init_reference_parser();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/case-node.js
var CaseNode;
var init_case_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/case-node.js"() {
    init_object_utils();
    init_when_node();
    CaseNode = freeze({
      is(node) {
        return node.kind === "CaseNode";
      },
      create(value2) {
        return freeze({
          kind: "CaseNode",
          value: value2
        });
      },
      cloneWithWhen(caseNode, when) {
        return freeze({
          ...caseNode,
          when: freeze(caseNode.when ? [...caseNode.when, when] : [when])
        });
      },
      cloneWithThen(caseNode, then) {
        return freeze({
          ...caseNode,
          when: caseNode.when ? freeze([
            ...caseNode.when.slice(0, -1),
            WhenNode.cloneWithResult(caseNode.when[caseNode.when.length - 1], then)
          ]) : void 0
        });
      },
      cloneWith(caseNode, props) {
        return freeze({
          ...caseNode,
          ...props
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/case-builder.js
var CaseBuilder, CaseThenBuilder, CaseWhenBuilder, CaseEndBuilder;
var init_case_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/case-builder.js"() {
    init_expression_wrapper();
    init_object_utils();
    init_case_node();
    init_when_node();
    init_binary_operation_parser();
    init_value_parser();
    CaseBuilder = class {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      when(...args) {
        return new CaseThenBuilder({
          ...this.#props,
          node: CaseNode.cloneWithWhen(this.#props.node, WhenNode.create(parseValueBinaryOperationOrExpression(args)))
        });
      }
    };
    CaseThenBuilder = class {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      then(valueExpression) {
        return new CaseWhenBuilder({
          ...this.#props,
          node: CaseNode.cloneWithThen(this.#props.node, isSafeImmediateValue(valueExpression) ? parseSafeImmediateValue(valueExpression) : parseValueExpression(valueExpression))
        });
      }
    };
    CaseWhenBuilder = class {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      when(...args) {
        return new CaseThenBuilder({
          ...this.#props,
          node: CaseNode.cloneWithWhen(this.#props.node, WhenNode.create(parseValueBinaryOperationOrExpression(args)))
        });
      }
      else(valueExpression) {
        return new CaseEndBuilder({
          ...this.#props,
          node: CaseNode.cloneWith(this.#props.node, {
            else: isSafeImmediateValue(valueExpression) ? parseSafeImmediateValue(valueExpression) : parseValueExpression(valueExpression)
          })
        });
      }
      end() {
        return new ExpressionWrapper(CaseNode.cloneWith(this.#props.node, { isStatement: false }));
      }
      endCase() {
        return new ExpressionWrapper(CaseNode.cloneWith(this.#props.node, { isStatement: true }));
      }
    };
    CaseEndBuilder = class {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      end() {
        return new ExpressionWrapper(CaseNode.cloneWith(this.#props.node, { isStatement: false }));
      }
      endCase() {
        return new ExpressionWrapper(CaseNode.cloneWith(this.#props.node, { isStatement: true }));
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/json-path-leg-node.js
var JSONPathLegNode;
var init_json_path_leg_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/json-path-leg-node.js"() {
    init_object_utils();
    JSONPathLegNode = freeze({
      is(node) {
        return node.kind === "JSONPathLegNode";
      },
      create(type, value2) {
        return freeze({
          kind: "JSONPathLegNode",
          type,
          value: value2
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/json-path-builder.js
var JSONPathBuilder, TraversedJSONPathBuilder, AliasedJSONPathBuilder;
var init_json_path_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/json-path-builder.js"() {
    init_alias_node();
    init_identifier_node();
    init_json_operator_chain_node();
    init_json_path_leg_node();
    init_json_path_node();
    init_json_reference_node();
    init_operation_node_source();
    init_value_node();
    JSONPathBuilder = class {
      #node;
      constructor(node) {
        this.#node = node;
      }
      /**
       * Access an element of a JSON array in a specific location.
       *
       * Since there's no guarantee an element exists in the given array location, the
       * resulting type is always nullable. If you're sure the element exists, you
       * should use {@link SelectQueryBuilder.$assertType} to narrow the type safely.
       *
       * See also {@link key} to access properties of JSON objects.
       *
       * ### Examples
       *
       * ```ts
       * await db.selectFrom('person')
       *   .select(eb =>
       *     eb.ref('nicknames', '->').at(0).as('primary_nickname')
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select "nicknames"->0 as "primary_nickname" from "person"
       *```
       *
       * Combined with {@link key}:
       *
       * ```ts
       * db.selectFrom('person').select(eb =>
       *   eb.ref('experience', '->').at(0).key('role').as('first_role')
       * )
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select "experience"->0->'role' as "first_role" from "person"
       * ```
       *
       * You can use `'last'` to access the last element of the array in MySQL:
       *
       * ```ts
       * db.selectFrom('person').select(eb =>
       *   eb.ref('nicknames', '->$').at('last').as('last_nickname')
       * )
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * select `nicknames`->'$[last]' as `last_nickname` from `person`
       * ```
       *
       * Or `'#-1'` in SQLite:
       *
       * ```ts
       * db.selectFrom('person').select(eb =>
       *   eb.ref('nicknames', '->>$').at('#-1').as('last_nickname')
       * )
       * ```
       *
       * The generated SQL (SQLite):
       *
       * ```sql
       * select "nicknames"->>'$[#-1]' as `last_nickname` from `person`
       * ```
       */
      at(index88) {
        return this.#createBuilderWithPathLeg("ArrayLocation", index88);
      }
      /**
       * Access a property of a JSON object.
       *
       * If a field is optional, the resulting type will be nullable.
       *
       * See also {@link at} to access elements of JSON arrays.
       *
       * ### Examples
       *
       * ```ts
       * db.selectFrom('person').select(eb =>
       *   eb.ref('address', '->').key('city').as('city')
       * )
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select "address"->'city' as "city" from "person"
       * ```
       *
       * Going deeper:
       *
       * ```ts
       * db.selectFrom('person').select(eb =>
       *   eb.ref('profile', '->$').key('website').key('url').as('website_url')
       * )
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * select `profile`->'$.website.url' as `website_url` from `person`
       * ```
       *
       * Combined with {@link at}:
       *
       * ```ts
       * db.selectFrom('person').select(eb =>
       *   eb.ref('profile', '->').key('addresses').at(0).key('city').as('city')
       * )
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select "profile"->'addresses'->0->'city' as "city" from "person"
       * ```
       */
      key(key2) {
        return this.#createBuilderWithPathLeg("Member", key2);
      }
      #createBuilderWithPathLeg(legType, value2) {
        if (JSONReferenceNode.is(this.#node)) {
          return new TraversedJSONPathBuilder(JSONReferenceNode.cloneWithTraversal(this.#node, JSONPathNode.is(this.#node.traversal) ? JSONPathNode.cloneWithLeg(this.#node.traversal, JSONPathLegNode.create(legType, value2)) : JSONOperatorChainNode.cloneWithValue(this.#node.traversal, ValueNode.createImmediate(value2))));
        }
        return new TraversedJSONPathBuilder(JSONPathNode.cloneWithLeg(this.#node, JSONPathLegNode.create(legType, value2)));
      }
    };
    TraversedJSONPathBuilder = class _TraversedJSONPathBuilder extends JSONPathBuilder {
      #node;
      constructor(node) {
        super(node);
        this.#node = node;
      }
      /** @private */
      get expressionType() {
        return void 0;
      }
      as(alias) {
        return new AliasedJSONPathBuilder(this, alias);
      }
      /**
       * Change the output type of the json path.
       *
       * This method call doesn't change the SQL in any way. This methods simply
       * returns a copy of this `JSONPathBuilder` with a new output type.
       */
      $castTo() {
        return new _TraversedJSONPathBuilder(this.#node);
      }
      $notNull() {
        return new _TraversedJSONPathBuilder(this.#node);
      }
      toOperationNode() {
        return this.#node;
      }
    };
    AliasedJSONPathBuilder = class {
      #jsonPath;
      #alias;
      constructor(jsonPath, alias) {
        this.#jsonPath = jsonPath;
        this.#alias = alias;
      }
      /** @private */
      get expression() {
        return this.#jsonPath;
      }
      /** @private */
      get alias() {
        return this.#alias;
      }
      toOperationNode() {
        return AliasNode.create(this.#jsonPath.toOperationNode(), isOperationNodeSource(this.#alias) ? this.#alias.toOperationNode() : IdentifierNode.create(this.#alias));
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/tuple-node.js
var TupleNode;
var init_tuple_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/tuple-node.js"() {
    init_object_utils();
    TupleNode = freeze({
      is(node) {
        return node.kind === "TupleNode";
      },
      create(values) {
        return freeze({
          kind: "TupleNode",
          values: freeze(values)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/data-type-node.js
function isColumnDataType(dataType) {
  if (SIMPLE_COLUMN_DATA_TYPES.includes(dataType)) {
    return true;
  }
  if (COLUMN_DATA_TYPE_REGEX.some((r2) => r2.test(dataType))) {
    return true;
  }
  return false;
}
var SIMPLE_COLUMN_DATA_TYPES, COLUMN_DATA_TYPE_REGEX, DataTypeNode;
var init_data_type_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/data-type-node.js"() {
    init_object_utils();
    SIMPLE_COLUMN_DATA_TYPES = [
      "varchar",
      "char",
      "text",
      "integer",
      "int2",
      "int4",
      "int8",
      "smallint",
      "bigint",
      "boolean",
      "real",
      "double precision",
      "float4",
      "float8",
      "decimal",
      "numeric",
      "binary",
      "bytea",
      "date",
      "datetime",
      "time",
      "timetz",
      "timestamp",
      "timestamptz",
      "serial",
      "bigserial",
      "uuid",
      "json",
      "jsonb",
      "blob",
      "varbinary",
      "int4range",
      "int4multirange",
      "int8range",
      "int8multirange",
      "numrange",
      "nummultirange",
      "tsrange",
      "tsmultirange",
      "tstzrange",
      "tstzmultirange",
      "daterange",
      "datemultirange"
    ];
    COLUMN_DATA_TYPE_REGEX = [
      /^varchar\(\d+\)$/,
      /^char\(\d+\)$/,
      /^decimal\(\d+, \d+\)$/,
      /^numeric\(\d+, \d+\)$/,
      /^binary\(\d+\)$/,
      /^datetime\(\d+\)$/,
      /^time\(\d+\)$/,
      /^timetz\(\d+\)$/,
      /^timestamp\(\d+\)$/,
      /^timestamptz\(\d+\)$/,
      /^varbinary\(\d+\)$/
    ];
    DataTypeNode = freeze({
      is(node) {
        return node.kind === "DataTypeNode";
      },
      create(dataType) {
        return freeze({
          kind: "DataTypeNode",
          dataType
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/data-type-parser.js
function parseDataTypeExpression(dataType) {
  if (isOperationNodeSource(dataType)) {
    return dataType.toOperationNode();
  }
  if (isColumnDataType(dataType)) {
    return DataTypeNode.create(dataType);
  }
  throw new Error(`invalid column data type ${JSON.stringify(dataType)}`);
}
var init_data_type_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/data-type-parser.js"() {
    init_data_type_node();
    init_operation_node_source();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/cast-node.js
var CastNode;
var init_cast_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/cast-node.js"() {
    init_object_utils();
    CastNode = freeze({
      is(node) {
        return node.kind === "CastNode";
      },
      create(expression, dataType) {
        return freeze({
          kind: "CastNode",
          expression,
          dataType
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/expression/expression-builder.js
function createExpressionBuilder(executor = NOOP_QUERY_EXECUTOR) {
  function binary2(lhs, op, rhs) {
    return new ExpressionWrapper(parseValueBinaryOperation(lhs, op, rhs));
  }
  function unary(op, expr) {
    return new ExpressionWrapper(parseUnaryOperation(op, expr));
  }
  const eb = Object.assign(binary2, {
    fn: void 0,
    eb: void 0,
    selectFrom(table2) {
      return createSelectQueryBuilder({
        queryId: createQueryId(),
        executor,
        queryNode: SelectQueryNode.createFrom(parseTableExpressionOrList(table2))
      });
    },
    case(reference) {
      return new CaseBuilder({
        node: CaseNode.create(isUndefined(reference) ? void 0 : parseReferenceExpression(reference))
      });
    },
    ref(reference, op) {
      if (isUndefined(op)) {
        return new ExpressionWrapper(parseStringReference(reference));
      }
      return new JSONPathBuilder(parseJSONReference(reference, op));
    },
    jsonPath() {
      return new JSONPathBuilder(JSONPathNode.create());
    },
    table(table2) {
      return new ExpressionWrapper(parseTable(table2));
    },
    val(value2) {
      return new ExpressionWrapper(parseValueExpression(value2));
    },
    refTuple(...values) {
      return new ExpressionWrapper(TupleNode.create(values.map(parseReferenceExpression)));
    },
    tuple(...values) {
      return new ExpressionWrapper(TupleNode.create(values.map(parseValueExpression)));
    },
    lit(value2) {
      return new ExpressionWrapper(parseSafeImmediateValue(value2));
    },
    unary,
    not(expr) {
      return unary("not", expr);
    },
    exists(expr) {
      return unary("exists", expr);
    },
    neg(expr) {
      return unary("-", expr);
    },
    between(expr, start, end) {
      return new ExpressionWrapper(BinaryOperationNode.create(parseReferenceExpression(expr), OperatorNode.create("between"), AndNode.create(parseValueExpression(start), parseValueExpression(end))));
    },
    betweenSymmetric(expr, start, end) {
      return new ExpressionWrapper(BinaryOperationNode.create(parseReferenceExpression(expr), OperatorNode.create("between symmetric"), AndNode.create(parseValueExpression(start), parseValueExpression(end))));
    },
    and(exprs) {
      if (isReadonlyArray(exprs)) {
        return new ExpressionWrapper(parseFilterList(exprs, "and"));
      }
      return new ExpressionWrapper(parseFilterObject(exprs, "and"));
    },
    or(exprs) {
      if (isReadonlyArray(exprs)) {
        return new ExpressionWrapper(parseFilterList(exprs, "or"));
      }
      return new ExpressionWrapper(parseFilterObject(exprs, "or"));
    },
    parens(...args) {
      const node = parseValueBinaryOperationOrExpression(args);
      if (ParensNode.is(node)) {
        return new ExpressionWrapper(node);
      } else {
        return new ExpressionWrapper(ParensNode.create(node));
      }
    },
    cast(expr, dataType) {
      return new ExpressionWrapper(CastNode.create(parseReferenceExpression(expr), parseDataTypeExpression(dataType)));
    },
    withSchema(schema) {
      return createExpressionBuilder(executor.withPluginAtFront(new WithSchemaPlugin(schema)));
    }
  });
  eb.fn = createFunctionModule();
  eb.eb = eb;
  return eb;
}
function expressionBuilder(_3) {
  return createExpressionBuilder();
}
var init_expression_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/expression/expression-builder.js"() {
    init_select_query_builder();
    init_select_query_node();
    init_table_parser();
    init_with_schema_plugin();
    init_query_id();
    init_function_module();
    init_reference_parser();
    init_binary_operation_parser();
    init_parens_node();
    init_expression_wrapper();
    init_operator_node();
    init_unary_operation_parser();
    init_value_parser();
    init_noop_query_executor();
    init_case_builder();
    init_case_node();
    init_object_utils();
    init_json_path_builder();
    init_binary_operation_node();
    init_and_node();
    init_tuple_node();
    init_json_path_node();
    init_data_type_parser();
    init_cast_node();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/expression-parser.js
function parseExpression(exp) {
  if (isOperationNodeSource(exp)) {
    return exp.toOperationNode();
  } else if (isFunction(exp)) {
    return exp(expressionBuilder()).toOperationNode();
  }
  throw new Error(`invalid expression: ${JSON.stringify(exp)}`);
}
function parseAliasedExpression(exp) {
  if (isOperationNodeSource(exp)) {
    return exp.toOperationNode();
  } else if (isFunction(exp)) {
    return exp(expressionBuilder()).toOperationNode();
  }
  throw new Error(`invalid aliased expression: ${JSON.stringify(exp)}`);
}
function isExpressionOrFactory(obj) {
  return isExpression(obj) || isAliasedExpression(obj) || isFunction(obj);
}
var init_expression_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/expression-parser.js"() {
    init_expression();
    init_operation_node_source();
    init_expression_builder();
    init_object_utils();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/table-parser.js
function parseTableExpressionOrList(table2) {
  if (isReadonlyArray(table2)) {
    return table2.map((it2) => parseTableExpression(it2));
  } else {
    return [parseTableExpression(table2)];
  }
}
function parseTableExpression(table2) {
  if (isString(table2)) {
    return parseAliasedTable(table2);
  } else {
    return parseAliasedExpression(table2);
  }
}
function parseAliasedTable(from) {
  const ALIAS_SEPARATOR = " as ";
  if (from.includes(ALIAS_SEPARATOR)) {
    const [table2, alias] = from.split(ALIAS_SEPARATOR).map(trim2);
    return AliasNode.create(parseTable(table2), IdentifierNode.create(alias));
  } else {
    return parseTable(from);
  }
}
function parseTable(from) {
  const SCHEMA_SEPARATOR = ".";
  if (from.includes(SCHEMA_SEPARATOR)) {
    const [schema, table2] = from.split(SCHEMA_SEPARATOR).map(trim2);
    return TableNode.createWithSchema(schema, table2);
  } else {
    return TableNode.create(from);
  }
}
function trim2(str2) {
  return str2.trim();
}
var init_table_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/table-parser.js"() {
    init_object_utils();
    init_alias_node();
    init_table_node();
    init_expression_parser();
    init_identifier_node();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/add-column-node.js
var AddColumnNode;
var init_add_column_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/add-column-node.js"() {
    init_object_utils();
    AddColumnNode = freeze({
      is(node) {
        return node.kind === "AddColumnNode";
      },
      create(column) {
        return freeze({
          kind: "AddColumnNode",
          column
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/column-definition-node.js
var ColumnDefinitionNode;
var init_column_definition_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/column-definition-node.js"() {
    init_object_utils();
    init_column_node();
    ColumnDefinitionNode = freeze({
      is(node) {
        return node.kind === "ColumnDefinitionNode";
      },
      create(column, dataType) {
        return freeze({
          kind: "ColumnDefinitionNode",
          column: ColumnNode.create(column),
          dataType
        });
      },
      cloneWithFrontModifier(node, modifier) {
        return freeze({
          ...node,
          frontModifiers: node.frontModifiers ? freeze([...node.frontModifiers, modifier]) : [modifier]
        });
      },
      cloneWithEndModifier(node, modifier) {
        return freeze({
          ...node,
          endModifiers: node.endModifiers ? freeze([...node.endModifiers, modifier]) : [modifier]
        });
      },
      cloneWith(node, props) {
        return freeze({
          ...node,
          ...props
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-column-node.js
var DropColumnNode;
var init_drop_column_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-column-node.js"() {
    init_object_utils();
    init_column_node();
    DropColumnNode = freeze({
      is(node) {
        return node.kind === "DropColumnNode";
      },
      create(column) {
        return freeze({
          kind: "DropColumnNode",
          column: ColumnNode.create(column)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/rename-column-node.js
var RenameColumnNode;
var init_rename_column_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/rename-column-node.js"() {
    init_object_utils();
    init_column_node();
    RenameColumnNode = freeze({
      is(node) {
        return node.kind === "RenameColumnNode";
      },
      create(column, newColumn) {
        return freeze({
          kind: "RenameColumnNode",
          column: ColumnNode.create(column),
          renameTo: ColumnNode.create(newColumn)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/check-constraint-node.js
var CheckConstraintNode;
var init_check_constraint_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/check-constraint-node.js"() {
    init_object_utils();
    init_identifier_node();
    CheckConstraintNode = freeze({
      is(node) {
        return node.kind === "CheckConstraintNode";
      },
      create(expression, constraintName) {
        return freeze({
          kind: "CheckConstraintNode",
          expression,
          name: constraintName ? IdentifierNode.create(constraintName) : void 0
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/references-node.js
var ON_MODIFY_FOREIGN_ACTIONS, ReferencesNode;
var init_references_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/references-node.js"() {
    init_object_utils();
    ON_MODIFY_FOREIGN_ACTIONS = [
      "no action",
      "restrict",
      "cascade",
      "set null",
      "set default"
    ];
    ReferencesNode = freeze({
      is(node) {
        return node.kind === "ReferencesNode";
      },
      create(table2, columns) {
        return freeze({
          kind: "ReferencesNode",
          table: table2,
          columns: freeze([...columns])
        });
      },
      cloneWithOnDelete(references, onDelete) {
        return freeze({
          ...references,
          onDelete
        });
      },
      cloneWithOnUpdate(references, onUpdate) {
        return freeze({
          ...references,
          onUpdate
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/default-value-parser.js
function parseDefaultValueExpression(value2) {
  return isOperationNodeSource(value2) ? value2.toOperationNode() : ValueNode.createImmediate(value2);
}
var init_default_value_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/default-value-parser.js"() {
    init_operation_node_source();
    init_value_node();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/generated-node.js
var GeneratedNode;
var init_generated_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/generated-node.js"() {
    init_object_utils();
    GeneratedNode = freeze({
      is(node) {
        return node.kind === "GeneratedNode";
      },
      create(params) {
        return freeze({
          kind: "GeneratedNode",
          ...params
        });
      },
      createWithExpression(expression) {
        return freeze({
          kind: "GeneratedNode",
          always: true,
          expression
        });
      },
      cloneWith(node, params) {
        return freeze({
          ...node,
          ...params
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/default-value-node.js
var DefaultValueNode;
var init_default_value_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/default-value-node.js"() {
    init_object_utils();
    DefaultValueNode = freeze({
      is(node) {
        return node.kind === "DefaultValueNode";
      },
      create(defaultValue) {
        return freeze({
          kind: "DefaultValueNode",
          defaultValue
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/on-modify-action-parser.js
function parseOnModifyForeignAction(action) {
  if (ON_MODIFY_FOREIGN_ACTIONS.includes(action)) {
    return action;
  }
  throw new Error(`invalid OnModifyForeignAction ${action}`);
}
var init_on_modify_action_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/on-modify-action-parser.js"() {
    init_references_node();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/column-definition-builder.js
var ColumnDefinitionBuilder;
var init_column_definition_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/column-definition-builder.js"() {
    init_check_constraint_node();
    init_references_node();
    init_select_all_node();
    init_reference_parser();
    init_prevent_await();
    init_column_definition_node();
    init_default_value_parser();
    init_generated_node();
    init_default_value_node();
    init_on_modify_action_parser();
    ColumnDefinitionBuilder = class _ColumnDefinitionBuilder {
      #node;
      constructor(node) {
        this.#node = node;
      }
      /**
       * Adds `auto_increment` or `autoincrement` to the column definition
       * depending on the dialect.
       *
       * Some dialects like PostgreSQL don't support this. On PostgreSQL
       * you can use the `serial` or `bigserial` data type instead.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', col => col.autoIncrement().primaryKey())
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `person` (
       *   `id` integer primary key auto_increment
       * )
       * ```
       */
      autoIncrement() {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, { autoIncrement: true }));
      }
      /**
       * Makes the column an identity column.
       *
       * This only works on some dialects like MS SQL Server (MSSQL).
       *
       * For PostgreSQL's `generated always as identity` use {@link generatedAlwaysAsIdentity}.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', col => col.identity().primaryKey())
       *   .execute()
       * ```
       *
       * The generated SQL (MSSQL):
       *
       * ```sql
       * create table "person" (
       *   "id" integer identity primary key
       * )
       * ```
       */
      identity() {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, { identity: true }));
      }
      /**
       * Makes the column the primary key.
       *
       * If you want to specify a composite primary key use the
       * {@link CreateTableBuilder.addPrimaryKeyConstraint} method.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', col => col.primaryKey())
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `person` (
       *   `id` integer primary key
       * )
       */
      primaryKey() {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, { primaryKey: true }));
      }
      /**
       * Adds a foreign key constraint for the column.
       *
       * If your database engine doesn't support foreign key constraints in the
       * column definition (like MySQL 5) you need to call the table level
       * {@link CreateTableBuilder.addForeignKeyConstraint} method instead.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('pet')
       *   .addColumn('owner_id', 'integer', (col) => col.references('person.id'))
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create table "pet" (
       *   "owner_id" integer references "person" ("id")
       * )
       * ```
       */
      references(ref) {
        const references = parseStringReference(ref);
        if (!references.table || SelectAllNode.is(references.column)) {
          throw new Error(`invalid call references('${ref}'). The reference must have format table.column or schema.table.column`);
        }
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, {
          references: ReferencesNode.create(references.table, [
            references.column
          ])
        }));
      }
      /**
       * Adds an `on delete` constraint for the foreign key column.
       *
       * If your database engine doesn't support foreign key constraints in the
       * column definition (like MySQL 5) you need to call the table level
       * {@link CreateTableBuilder.addForeignKeyConstraint} method instead.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('pet')
       *   .addColumn(
       *     'owner_id',
       *     'integer',
       *     (col) => col.references('person.id').onDelete('cascade')
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create table "pet" (
       *   "owner_id" integer references "person" ("id") on delete cascade
       * )
       * ```
       */
      onDelete(onDelete) {
        if (!this.#node.references) {
          throw new Error("on delete constraint can only be added for foreign keys");
        }
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, {
          references: ReferencesNode.cloneWithOnDelete(this.#node.references, parseOnModifyForeignAction(onDelete))
        }));
      }
      /**
       * Adds an `on update` constraint for the foreign key column.
       *
       * If your database engine doesn't support foreign key constraints in the
       * column definition (like MySQL 5) you need to call the table level
       * {@link CreateTableBuilder.addForeignKeyConstraint} method instead.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('pet')
       *   .addColumn(
       *     'owner_id',
       *     'integer',
       *     (col) => col.references('person.id').onUpdate('cascade')
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create table "pet" (
       *   "owner_id" integer references "person" ("id") on update cascade
       * )
       * ```
       */
      onUpdate(onUpdate) {
        if (!this.#node.references) {
          throw new Error("on update constraint can only be added for foreign keys");
        }
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, {
          references: ReferencesNode.cloneWithOnUpdate(this.#node.references, parseOnModifyForeignAction(onUpdate))
        }));
      }
      /**
       * Adds a unique constraint for the column.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('email', 'varchar(255)', col => col.unique())
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `person` (
       *   `email` varchar(255) unique
       * )
       * ```
       */
      unique() {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, { unique: true }));
      }
      /**
       * Adds a `not null` constraint for the column.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('first_name', 'varchar(255)', col => col.notNull())
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `person` (
       *   `first_name` varchar(255) not null
       * )
       * ```
       */
      notNull() {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, { notNull: true }));
      }
      /**
       * Adds a `unsigned` modifier for the column.
       *
       * This only works on some dialects like MySQL.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('age', 'integer', col => col.unsigned())
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `person` (
       *   `age` integer unsigned
       * )
       * ```
       */
      unsigned() {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, { unsigned: true }));
      }
      /**
       * Adds a default value constraint for the column.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('pet')
       *   .addColumn('number_of_legs', 'integer', (col) => col.defaultTo(4))
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `pet` (
       *   `number_of_legs` integer default 4
       * )
       * ```
       *
       * Values passed to `defaultTo` are interpreted as value literals by default. You can define
       * an arbitrary SQL expression using the {@link sql} template tag:
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createTable('pet')
       *   .addColumn(
       *     'created_at',
       *     'timestamp',
       *     (col) => col.defaultTo(sql`CURRENT_TIMESTAMP`)
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `pet` (
       *   `created_at` timestamp default CURRENT_TIMESTAMP
       * )
       * ```
       */
      defaultTo(value2) {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, {
          defaultTo: DefaultValueNode.create(parseDefaultValueExpression(value2))
        }));
      }
      /**
       * Adds a check constraint for the column.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createTable('pet')
       *   .addColumn('number_of_legs', 'integer', (col) =>
       *     col.check(sql`number_of_legs < 5`)
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `pet` (
       *   `number_of_legs` integer check (number_of_legs < 5)
       * )
       * ```
       */
      check(expression) {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, {
          check: CheckConstraintNode.create(expression.toOperationNode())
        }));
      }
      /**
       * Makes the column a generated column using a `generated always as` statement.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createTable('person')
       *   .addColumn('full_name', 'varchar(255)',
       *     (col) => col.generatedAlwaysAs(sql`concat(first_name, ' ', last_name)`)
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `person` (
       *   `full_name` varchar(255) generated always as (concat(first_name, ' ', last_name))
       * )
       * ```
       */
      generatedAlwaysAs(expression) {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, {
          generated: GeneratedNode.createWithExpression(expression.toOperationNode())
        }));
      }
      /**
       * Adds the `generated always as identity` specifier.
       *
       * This only works on some dialects like PostgreSQL.
       *
       * For MS SQL Server (MSSQL)'s identity column use {@link identity}.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', col => col.generatedAlwaysAsIdentity().primaryKey())
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create table "person" (
       *   "id" integer generated always as identity primary key
       * )
       * ```
       */
      generatedAlwaysAsIdentity() {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, {
          generated: GeneratedNode.create({ identity: true, always: true })
        }));
      }
      /**
       * Adds the `generated by default as identity` specifier on supported dialects.
       *
       * This only works on some dialects like PostgreSQL.
       *
       * For MS SQL Server (MSSQL)'s identity column use {@link identity}.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', col => col.generatedByDefaultAsIdentity().primaryKey())
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create table "person" (
       *   "id" integer generated by default as identity primary key
       * )
       * ```
       */
      generatedByDefaultAsIdentity() {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, {
          generated: GeneratedNode.create({ identity: true, byDefault: true })
        }));
      }
      /**
       * Makes a generated column stored instead of virtual. This method can only
       * be used with {@link generatedAlwaysAs}
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createTable('person')
       *   .addColumn('full_name', 'varchar(255)', (col) => col
       *     .generatedAlwaysAs(sql`concat(first_name, ' ', last_name)`)
       *     .stored()
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `person` (
       *   `full_name` varchar(255) generated always as (concat(first_name, ' ', last_name)) stored
       * )
       * ```
       */
      stored() {
        if (!this.#node.generated) {
          throw new Error("stored() can only be called after generatedAlwaysAs");
        }
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, {
          generated: GeneratedNode.cloneWith(this.#node.generated, {
            stored: true
          })
        }));
      }
      /**
       * This can be used to add any additional SQL right after the column's data type.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', col => col.primaryKey())
       *   .addColumn(
       *     'first_name',
       *     'varchar(36)',
       *     (col) => col.modifyFront(sql`collate utf8mb4_general_ci`).notNull()
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `person` (
       *   `id` integer primary key,
       *   `first_name` varchar(36) collate utf8mb4_general_ci not null
       * )
       * ```
       */
      modifyFront(modifier) {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWithFrontModifier(this.#node, modifier.toOperationNode()));
      }
      /**
       * Adds `nulls not distinct` specifier.
       * Should be used with `unique` constraint.
       *
       * This only works on some dialects like PostgreSQL.
       *
       * ### Examples
       *
       * ```ts
       * db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', col => col.primaryKey())
       *   .addColumn('first_name', 'varchar(30)', col => col.unique().nullsNotDistinct())
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create table "person" (
       *   "id" integer primary key,
       *   "first_name" varchar(30) unique nulls not distinct
       * )
       * ```
       */
      nullsNotDistinct() {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, { nullsNotDistinct: true }));
      }
      /**
       * Adds `if not exists` specifier. This only works for PostgreSQL.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .alterTable('person')
       *   .addColumn('email', 'varchar(255)', col => col.unique().ifNotExists())
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * alter table "person" add column if not exists "email" varchar(255) unique
       * ```
       */
      ifNotExists() {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWith(this.#node, { ifNotExists: true }));
      }
      /**
       * This can be used to add any additional SQL to the end of the column definition.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', col => col.primaryKey())
       *   .addColumn(
       *     'age',
       *     'integer',
       *     col => col.unsigned()
       *       .notNull()
       *       .modifyEnd(sql`comment ${sql.lit('it is not polite to ask a woman her age')}`)
       *   )
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `person` (
       *   `id` integer primary key,
       *   `age` integer unsigned not null comment 'it is not polite to ask a woman her age'
       * )
       * ```
       */
      modifyEnd(modifier) {
        return new _ColumnDefinitionBuilder(ColumnDefinitionNode.cloneWithEndModifier(this.#node, modifier.toOperationNode()));
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#node;
      }
    };
    preventAwait(ColumnDefinitionBuilder, "don't await ColumnDefinitionBuilder instances directly.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/modify-column-node.js
var ModifyColumnNode;
var init_modify_column_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/modify-column-node.js"() {
    init_object_utils();
    ModifyColumnNode = freeze({
      is(node) {
        return node.kind === "ModifyColumnNode";
      },
      create(column) {
        return freeze({
          kind: "ModifyColumnNode",
          column
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/foreign-key-constraint-node.js
var ForeignKeyConstraintNode;
var init_foreign_key_constraint_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/foreign-key-constraint-node.js"() {
    init_object_utils();
    init_identifier_node();
    init_references_node();
    ForeignKeyConstraintNode = freeze({
      is(node) {
        return node.kind === "ForeignKeyConstraintNode";
      },
      create(sourceColumns, targetTable, targetColumns, constraintName) {
        return freeze({
          kind: "ForeignKeyConstraintNode",
          columns: sourceColumns,
          references: ReferencesNode.create(targetTable, targetColumns),
          name: constraintName ? IdentifierNode.create(constraintName) : void 0
        });
      },
      cloneWith(node, props) {
        return freeze({
          ...node,
          ...props
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/foreign-key-constraint-builder.js
var ForeignKeyConstraintBuilder;
var init_foreign_key_constraint_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/foreign-key-constraint-builder.js"() {
    init_foreign_key_constraint_node();
    init_on_modify_action_parser();
    init_prevent_await();
    ForeignKeyConstraintBuilder = class _ForeignKeyConstraintBuilder {
      #node;
      constructor(node) {
        this.#node = node;
      }
      onDelete(onDelete) {
        return new _ForeignKeyConstraintBuilder(ForeignKeyConstraintNode.cloneWith(this.#node, {
          onDelete: parseOnModifyForeignAction(onDelete)
        }));
      }
      onUpdate(onUpdate) {
        return new _ForeignKeyConstraintBuilder(ForeignKeyConstraintNode.cloneWith(this.#node, {
          onUpdate: parseOnModifyForeignAction(onUpdate)
        }));
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#node;
      }
    };
    preventAwait(ForeignKeyConstraintBuilder, "don't await ForeignKeyConstraintBuilder instances directly.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/add-constraint-node.js
var AddConstraintNode;
var init_add_constraint_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/add-constraint-node.js"() {
    init_object_utils();
    AddConstraintNode = freeze({
      is(node) {
        return node.kind === "AddConstraintNode";
      },
      create(constraint) {
        return freeze({
          kind: "AddConstraintNode",
          constraint
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/unique-constraint-node.js
var UniqueConstraintNode;
var init_unique_constraint_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/unique-constraint-node.js"() {
    init_object_utils();
    init_column_node();
    init_identifier_node();
    UniqueConstraintNode = freeze({
      is(node) {
        return node.kind === "UniqueConstraintNode";
      },
      create(columns, constraintName, nullsNotDistinct) {
        return freeze({
          kind: "UniqueConstraintNode",
          columns: freeze(columns.map(ColumnNode.create)),
          name: constraintName ? IdentifierNode.create(constraintName) : void 0,
          nullsNotDistinct
        });
      },
      cloneWith(node, props) {
        return freeze({
          ...node,
          ...props
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-constraint-node.js
var DropConstraintNode;
var init_drop_constraint_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-constraint-node.js"() {
    init_object_utils();
    init_identifier_node();
    DropConstraintNode = freeze({
      is(node) {
        return node.kind === "DropConstraintNode";
      },
      create(constraintName) {
        return freeze({
          kind: "DropConstraintNode",
          constraintName: IdentifierNode.create(constraintName)
        });
      },
      cloneWith(dropConstraint, props) {
        return freeze({
          ...dropConstraint,
          ...props
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/alter-column-node.js
var AlterColumnNode;
var init_alter_column_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/alter-column-node.js"() {
    init_object_utils();
    init_column_node();
    AlterColumnNode = freeze({
      is(node) {
        return node.kind === "AlterColumnNode";
      },
      create(column, prop, value2) {
        return freeze({
          kind: "AlterColumnNode",
          column: ColumnNode.create(column),
          [prop]: value2
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-column-builder.js
var AlterColumnBuilder, AlteredColumnBuilder;
var init_alter_column_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-column-builder.js"() {
    init_alter_column_node();
    init_data_type_parser();
    init_default_value_parser();
    init_prevent_await();
    AlterColumnBuilder = class {
      #column;
      constructor(column) {
        this.#column = column;
      }
      setDataType(dataType) {
        return new AlteredColumnBuilder(AlterColumnNode.create(this.#column, "dataType", parseDataTypeExpression(dataType)));
      }
      setDefault(value2) {
        return new AlteredColumnBuilder(AlterColumnNode.create(this.#column, "setDefault", parseDefaultValueExpression(value2)));
      }
      dropDefault() {
        return new AlteredColumnBuilder(AlterColumnNode.create(this.#column, "dropDefault", true));
      }
      setNotNull() {
        return new AlteredColumnBuilder(AlterColumnNode.create(this.#column, "setNotNull", true));
      }
      dropNotNull() {
        return new AlteredColumnBuilder(AlterColumnNode.create(this.#column, "dropNotNull", true));
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
    };
    preventAwait(AlterColumnBuilder, "don't await AlterColumnBuilder instances");
    AlteredColumnBuilder = class {
      #alterColumnNode;
      constructor(alterColumnNode) {
        this.#alterColumnNode = alterColumnNode;
      }
      toOperationNode() {
        return this.#alterColumnNode;
      }
    };
    preventAwait(AlteredColumnBuilder, "don't await AlteredColumnBuilder instances");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-table-executor.js
var AlterTableExecutor;
var init_alter_table_executor = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-table-executor.js"() {
    init_object_utils();
    init_prevent_await();
    AlterTableExecutor = class {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(AlterTableExecutor, "don't await AlterTableExecutor instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-table-add-foreign-key-constraint-builder.js
var AlterTableAddForeignKeyConstraintBuilder;
var init_alter_table_add_foreign_key_constraint_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-table-add-foreign-key-constraint-builder.js"() {
    init_add_constraint_node();
    init_alter_table_node();
    init_object_utils();
    init_prevent_await();
    AlterTableAddForeignKeyConstraintBuilder = class _AlterTableAddForeignKeyConstraintBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      onDelete(onDelete) {
        return new _AlterTableAddForeignKeyConstraintBuilder({
          ...this.#props,
          constraintBuilder: this.#props.constraintBuilder.onDelete(onDelete)
        });
      }
      onUpdate(onUpdate) {
        return new _AlterTableAddForeignKeyConstraintBuilder({
          ...this.#props,
          constraintBuilder: this.#props.constraintBuilder.onUpdate(onUpdate)
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(AlterTableNode.cloneWithTableProps(this.#props.node, {
          addConstraint: AddConstraintNode.create(this.#props.constraintBuilder.toOperationNode())
        }), this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(AlterTableAddForeignKeyConstraintBuilder, "don't await AlterTableAddForeignKeyConstraintBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-table-drop-constraint-builder.js
var AlterTableDropConstraintBuilder;
var init_alter_table_drop_constraint_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-table-drop-constraint-builder.js"() {
    init_alter_table_node();
    init_drop_constraint_node();
    init_object_utils();
    init_prevent_await();
    AlterTableDropConstraintBuilder = class _AlterTableDropConstraintBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      ifExists() {
        return new _AlterTableDropConstraintBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            dropConstraint: DropConstraintNode.cloneWith(this.#props.node.dropConstraint, {
              ifExists: true
            })
          })
        });
      }
      cascade() {
        return new _AlterTableDropConstraintBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            dropConstraint: DropConstraintNode.cloneWith(this.#props.node.dropConstraint, {
              modifier: "cascade"
            })
          })
        });
      }
      restrict() {
        return new _AlterTableDropConstraintBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            dropConstraint: DropConstraintNode.cloneWith(this.#props.node.dropConstraint, {
              modifier: "restrict"
            })
          })
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(AlterTableDropConstraintBuilder, "don't await AlterTableDropConstraintBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/primary-constraint-node.js
var PrimaryConstraintNode;
var init_primary_constraint_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/primary-constraint-node.js"() {
    init_object_utils();
    init_column_node();
    init_identifier_node();
    PrimaryConstraintNode = freeze({
      is(node) {
        return node.kind === "PrimaryKeyConstraintNode";
      },
      create(columns, constraintName) {
        return freeze({
          kind: "PrimaryKeyConstraintNode",
          columns: freeze(columns.map(ColumnNode.create)),
          name: constraintName ? IdentifierNode.create(constraintName) : void 0
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/add-index-node.js
var AddIndexNode;
var init_add_index_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/add-index-node.js"() {
    init_object_utils();
    init_identifier_node();
    AddIndexNode = freeze({
      is(node) {
        return node.kind === "AddIndexNode";
      },
      create(name) {
        return freeze({
          kind: "AddIndexNode",
          name: IdentifierNode.create(name)
        });
      },
      cloneWith(node, props) {
        return freeze({
          ...node,
          ...props
        });
      },
      cloneWithColumns(node, columns) {
        return freeze({
          ...node,
          columns: [...node.columns || [], ...columns]
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-table-add-index-builder.js
var AlterTableAddIndexBuilder;
var init_alter_table_add_index_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-table-add-index-builder.js"() {
    init_add_index_node();
    init_alter_table_node();
    init_raw_node();
    init_reference_parser();
    init_object_utils();
    init_prevent_await();
    AlterTableAddIndexBuilder = class _AlterTableAddIndexBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Makes the index unique.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .alterTable('person')
       *   .addIndex('person_first_name_index')
       *   .unique()
       *   .column('email')
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * alter table `person` add unique index `person_first_name_index` (`email`)
       * ```
       */
      unique() {
        return new _AlterTableAddIndexBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            addIndex: AddIndexNode.cloneWith(this.#props.node.addIndex, {
              unique: true
            })
          })
        });
      }
      /**
       * Adds a column to the index.
       *
       * Also see {@link columns} for adding multiple columns at once or {@link expression}
       * for specifying an arbitrary expression.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .alterTable('person')
       *   .addIndex('person_first_name_and_age_index')
       *   .column('first_name')
       *   .column('age desc')
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * alter table `person` add index `person_first_name_and_age_index` (`first_name`, `age` desc)
       * ```
       */
      column(column) {
        return new _AlterTableAddIndexBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            addIndex: AddIndexNode.cloneWithColumns(this.#props.node.addIndex, [
              parseOrderedColumnName(column)
            ])
          })
        });
      }
      /**
       * Specifies a list of columns for the index.
       *
       * Also see {@link column} for adding a single column or {@link expression} for
       * specifying an arbitrary expression.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .alterTable('person')
       *   .addIndex('person_first_name_and_age_index')
       *   .columns(['first_name', 'age desc'])
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * alter table `person` add index `person_first_name_and_age_index` (`first_name`, `age` desc)
       * ```
       */
      columns(columns) {
        return new _AlterTableAddIndexBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            addIndex: AddIndexNode.cloneWithColumns(this.#props.node.addIndex, columns.map(parseOrderedColumnName))
          })
        });
      }
      /**
       * Specifies an arbitrary expression for the index.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .alterTable('person')
       *   .addIndex('person_first_name_index')
       *   .expression(sql<boolean>`(first_name < 'Sami')`)
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * alter table `person` add index `person_first_name_index` ((first_name < 'Sami'))
       * ```
       */
      expression(expression) {
        return new _AlterTableAddIndexBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            addIndex: AddIndexNode.cloneWithColumns(this.#props.node.addIndex, [
              expression.toOperationNode()
            ])
          })
        });
      }
      using(indexType) {
        return new _AlterTableAddIndexBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            addIndex: AddIndexNode.cloneWith(this.#props.node.addIndex, {
              using: RawNode.createWithSql(indexType)
            })
          })
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(AlterTableAddIndexBuilder, "don't await AlterTableAddIndexBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/unique-constraint-builder.js
var UniqueConstraintNodeBuilder;
var init_unique_constraint_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/unique-constraint-builder.js"() {
    init_unique_constraint_node();
    init_prevent_await();
    UniqueConstraintNodeBuilder = class _UniqueConstraintNodeBuilder {
      #node;
      constructor(node) {
        this.#node = node;
      }
      toOperationNode() {
        return this.#node;
      }
      /**
       * Adds `nulls not distinct` to the unique constraint definition
       *
       * Supported by PostgreSQL dialect only
       */
      nullsNotDistinct() {
        return new _UniqueConstraintNodeBuilder(UniqueConstraintNode.cloneWith(this.#node, { nullsNotDistinct: true }));
      }
    };
    preventAwait(UniqueConstraintNodeBuilder, "don't await UniqueConstraintNodeBuilder instances directly.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-table-builder.js
var AlterTableBuilder, AlterTableColumnAlteringBuilder;
var init_alter_table_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/alter-table-builder.js"() {
    init_add_column_node();
    init_alter_table_node();
    init_column_definition_node();
    init_drop_column_node();
    init_identifier_node();
    init_rename_column_node();
    init_object_utils();
    init_prevent_await();
    init_column_definition_builder();
    init_modify_column_node();
    init_data_type_parser();
    init_foreign_key_constraint_builder();
    init_add_constraint_node();
    init_unique_constraint_node();
    init_check_constraint_node();
    init_foreign_key_constraint_node();
    init_column_node();
    init_table_parser();
    init_drop_constraint_node();
    init_alter_column_builder();
    init_alter_table_executor();
    init_alter_table_add_foreign_key_constraint_builder();
    init_alter_table_drop_constraint_builder();
    init_primary_constraint_node();
    init_drop_index_node();
    init_add_index_node();
    init_alter_table_add_index_builder();
    init_unique_constraint_builder();
    AlterTableBuilder = class {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      renameTo(newTableName) {
        return new AlterTableExecutor({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            renameTo: parseTable(newTableName)
          })
        });
      }
      setSchema(newSchema) {
        return new AlterTableExecutor({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            setSchema: IdentifierNode.create(newSchema)
          })
        });
      }
      alterColumn(column, alteration) {
        const builder = alteration(new AlterColumnBuilder(column));
        return new AlterTableColumnAlteringBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithColumnAlteration(this.#props.node, builder.toOperationNode())
        });
      }
      dropColumn(column) {
        return new AlterTableColumnAlteringBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithColumnAlteration(this.#props.node, DropColumnNode.create(column))
        });
      }
      renameColumn(column, newColumn) {
        return new AlterTableColumnAlteringBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithColumnAlteration(this.#props.node, RenameColumnNode.create(column, newColumn))
        });
      }
      addColumn(columnName, dataType, build2 = noop3) {
        const builder = build2(new ColumnDefinitionBuilder(ColumnDefinitionNode.create(columnName, parseDataTypeExpression(dataType))));
        return new AlterTableColumnAlteringBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithColumnAlteration(this.#props.node, AddColumnNode.create(builder.toOperationNode()))
        });
      }
      modifyColumn(columnName, dataType, build2 = noop3) {
        const builder = build2(new ColumnDefinitionBuilder(ColumnDefinitionNode.create(columnName, parseDataTypeExpression(dataType))));
        return new AlterTableColumnAlteringBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithColumnAlteration(this.#props.node, ModifyColumnNode.create(builder.toOperationNode()))
        });
      }
      /**
       * See {@link CreateTableBuilder.addUniqueConstraint}
       */
      addUniqueConstraint(constraintName, columns, build2 = noop3) {
        const uniqueConstraintBuilder = build2(new UniqueConstraintNodeBuilder(UniqueConstraintNode.create(columns, constraintName)));
        return new AlterTableExecutor({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            addConstraint: AddConstraintNode.create(uniqueConstraintBuilder.toOperationNode())
          })
        });
      }
      /**
       * See {@link CreateTableBuilder.addCheckConstraint}
       */
      addCheckConstraint(constraintName, checkExpression) {
        return new AlterTableExecutor({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            addConstraint: AddConstraintNode.create(CheckConstraintNode.create(checkExpression.toOperationNode(), constraintName))
          })
        });
      }
      /**
       * See {@link CreateTableBuilder.addForeignKeyConstraint}
       *
       * Unlike {@link CreateTableBuilder.addForeignKeyConstraint} this method returns
       * the constraint builder and doesn't take a callback as the last argument. This
       * is because you can only add one column per `ALTER TABLE` query.
       */
      addForeignKeyConstraint(constraintName, columns, targetTable, targetColumns) {
        return new AlterTableAddForeignKeyConstraintBuilder({
          ...this.#props,
          constraintBuilder: new ForeignKeyConstraintBuilder(ForeignKeyConstraintNode.create(columns.map(ColumnNode.create), parseTable(targetTable), targetColumns.map(ColumnNode.create), constraintName))
        });
      }
      /**
       * See {@link CreateTableBuilder.addPrimaryKeyConstraint}
       */
      addPrimaryKeyConstraint(constraintName, columns) {
        return new AlterTableExecutor({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            addConstraint: AddConstraintNode.create(PrimaryConstraintNode.create(columns, constraintName))
          })
        });
      }
      dropConstraint(constraintName) {
        return new AlterTableDropConstraintBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            dropConstraint: DropConstraintNode.create(constraintName)
          })
        });
      }
      /**
       * This can be used to add index to table.
       *
       *  ### Examples
       *
       * ```ts
       * db.schema.alterTable('person')
       *   .addIndex('person_email_index')
       *   .column('email')
       *   .unique()
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * alter table `person` add unique index `person_email_index` (`email`)
       * ```
       */
      addIndex(indexName) {
        return new AlterTableAddIndexBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            addIndex: AddIndexNode.create(indexName)
          })
        });
      }
      /**
       * This can be used to drop index from table.
       *
       * ### Examples
       *
       * ```ts
       * db.schema.alterTable('person')
       *   .dropIndex('person_email_index')
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * alter table `person` drop index `test_first_name_index`
       * ```
       */
      dropIndex(indexName) {
        return new AlterTableExecutor({
          ...this.#props,
          node: AlterTableNode.cloneWithTableProps(this.#props.node, {
            dropIndex: DropIndexNode.create(indexName)
          })
        });
      }
      /**
       * Calls the given function passing `this` as the only argument.
       *
       * See {@link CreateTableBuilder.$call}
       */
      $call(func) {
        return func(this);
      }
    };
    preventAwait(AlterTableBuilder, "don't await AlterTableBuilder instances");
    AlterTableColumnAlteringBuilder = class _AlterTableColumnAlteringBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      alterColumn(column, alteration) {
        const builder = alteration(new AlterColumnBuilder(column));
        return new _AlterTableColumnAlteringBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithColumnAlteration(this.#props.node, builder.toOperationNode())
        });
      }
      dropColumn(column) {
        return new _AlterTableColumnAlteringBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithColumnAlteration(this.#props.node, DropColumnNode.create(column))
        });
      }
      renameColumn(column, newColumn) {
        return new _AlterTableColumnAlteringBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithColumnAlteration(this.#props.node, RenameColumnNode.create(column, newColumn))
        });
      }
      addColumn(columnName, dataType, build2 = noop3) {
        const builder = build2(new ColumnDefinitionBuilder(ColumnDefinitionNode.create(columnName, parseDataTypeExpression(dataType))));
        return new _AlterTableColumnAlteringBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithColumnAlteration(this.#props.node, AddColumnNode.create(builder.toOperationNode()))
        });
      }
      modifyColumn(columnName, dataType, build2 = noop3) {
        const builder = build2(new ColumnDefinitionBuilder(ColumnDefinitionNode.create(columnName, parseDataTypeExpression(dataType))));
        return new _AlterTableColumnAlteringBuilder({
          ...this.#props,
          node: AlterTableNode.cloneWithColumnAlteration(this.#props.node, ModifyColumnNode.create(builder.toOperationNode()))
        });
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(AlterTableColumnAlteringBuilder, "don't await AlterTableColumnAlteringBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/immediate-value/immediate-value-transformer.js
var ImmediateValueTransformer;
var init_immediate_value_transformer = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/immediate-value/immediate-value-transformer.js"() {
    init_operation_node_transformer();
    ImmediateValueTransformer = class extends OperationNodeTransformer {
      transformValue(node) {
        return {
          ...super.transformValue(node),
          immediate: true
        };
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/create-index-builder.js
var CreateIndexBuilder;
var init_create_index_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/create-index-builder.js"() {
    init_create_index_node();
    init_raw_node();
    init_reference_parser();
    init_table_parser();
    init_prevent_await();
    init_object_utils();
    init_binary_operation_parser();
    init_query_node();
    init_immediate_value_transformer();
    CreateIndexBuilder = class _CreateIndexBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Adds the "if not exists" modifier.
       *
       * If the index already exists, no error is thrown if this method has been called.
       */
      ifNotExists() {
        return new _CreateIndexBuilder({
          ...this.#props,
          node: CreateIndexNode.cloneWith(this.#props.node, {
            ifNotExists: true
          })
        });
      }
      /**
       * Makes the index unique.
       */
      unique() {
        return new _CreateIndexBuilder({
          ...this.#props,
          node: CreateIndexNode.cloneWith(this.#props.node, {
            unique: true
          })
        });
      }
      /**
       * Adds `nulls not distinct` specifier to index.
       * This only works on some dialects like PostgreSQL.
       *
       * ### Examples
       *
       * ```ts
       * db.schema.createIndex('person_first_name_index')
       *  .on('person')
       *  .column('first_name')
       *  .nullsNotDistinct()
       *  .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create index "person_first_name_index"
       * on "test" ("first_name")
       * nulls not distinct;
       * ```
       */
      nullsNotDistinct() {
        return new _CreateIndexBuilder({
          ...this.#props,
          node: CreateIndexNode.cloneWith(this.#props.node, {
            nullsNotDistinct: true
          })
        });
      }
      /**
       * Specifies the table for the index.
       */
      on(table2) {
        return new _CreateIndexBuilder({
          ...this.#props,
          node: CreateIndexNode.cloneWith(this.#props.node, {
            table: parseTable(table2)
          })
        });
      }
      /**
       * Adds a column to the index.
       *
       * Also see {@link columns} for adding multiple columns at once or {@link expression}
       * for specifying an arbitrary expression.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *         .createIndex('person_first_name_and_age_index')
       *         .on('person')
       *         .column('first_name')
       *         .column('age desc')
       *         .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create index "person_first_name_and_age_index" on "person" ("first_name", "age" desc)
       * ```
       */
      column(column) {
        return new _CreateIndexBuilder({
          ...this.#props,
          node: CreateIndexNode.cloneWithColumns(this.#props.node, [
            parseOrderedColumnName(column)
          ])
        });
      }
      /**
       * Specifies a list of columns for the index.
       *
       * Also see {@link column} for adding a single column or {@link expression} for
       * specifying an arbitrary expression.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *         .createIndex('person_first_name_and_age_index')
       *         .on('person')
       *         .columns(['first_name', 'age desc'])
       *         .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create index "person_first_name_and_age_index" on "person" ("first_name", "age" desc)
       * ```
       */
      columns(columns) {
        return new _CreateIndexBuilder({
          ...this.#props,
          node: CreateIndexNode.cloneWithColumns(this.#props.node, columns.map(parseOrderedColumnName))
        });
      }
      /**
       * Specifies an arbitrary expression for the index.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createIndex('person_first_name_index')
       *   .on('person')
       *   .expression(sql`first_name COLLATE "fi_FI"`)
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create index "person_first_name_index" on "person" (first_name COLLATE "fi_FI")
       * ```
       */
      expression(expression) {
        return new _CreateIndexBuilder({
          ...this.#props,
          node: CreateIndexNode.cloneWithColumns(this.#props.node, [
            expression.toOperationNode()
          ])
        });
      }
      using(indexType) {
        return new _CreateIndexBuilder({
          ...this.#props,
          node: CreateIndexNode.cloneWith(this.#props.node, {
            using: RawNode.createWithSql(indexType)
          })
        });
      }
      where(...args) {
        const transformer = new ImmediateValueTransformer();
        return new _CreateIndexBuilder({
          ...this.#props,
          node: QueryNode.cloneWithWhere(this.#props.node, transformer.transformNode(parseValueBinaryOperationOrExpression(args)))
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(CreateIndexBuilder, "don't await CreateIndexBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/create-schema-builder.js
var CreateSchemaBuilder;
var init_create_schema_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/create-schema-builder.js"() {
    init_create_schema_node();
    init_prevent_await();
    init_object_utils();
    CreateSchemaBuilder = class _CreateSchemaBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      ifNotExists() {
        return new _CreateSchemaBuilder({
          ...this.#props,
          node: CreateSchemaNode.cloneWith(this.#props.node, { ifNotExists: true })
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(CreateSchemaBuilder, "don't await CreateSchemaBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/on-commit-action-parse.js
function parseOnCommitAction(action) {
  if (ON_COMMIT_ACTIONS.includes(action)) {
    return action;
  }
  throw new Error(`invalid OnCommitAction ${action}`);
}
var init_on_commit_action_parse = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/on-commit-action-parse.js"() {
    init_create_table_node();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/create-table-builder.js
var CreateTableBuilder;
var init_create_table_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/create-table-builder.js"() {
    init_column_definition_node();
    init_create_table_node();
    init_prevent_await();
    init_column_definition_builder();
    init_object_utils();
    init_foreign_key_constraint_node();
    init_column_node();
    init_foreign_key_constraint_builder();
    init_data_type_parser();
    init_primary_constraint_node();
    init_unique_constraint_node();
    init_check_constraint_node();
    init_table_parser();
    init_on_commit_action_parse();
    init_unique_constraint_builder();
    init_expression_parser();
    CreateTableBuilder = class _CreateTableBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Adds the "temporary" modifier.
       *
       * Use this to create a temporary table.
       */
      temporary() {
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWith(this.#props.node, {
            temporary: true
          })
        });
      }
      /**
       * Adds an "on commit" statement.
       *
       * This can be used in conjunction with temporary tables on supported databases
       * like PostgreSQL.
       */
      onCommit(onCommit) {
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWith(this.#props.node, {
            onCommit: parseOnCommitAction(onCommit)
          })
        });
      }
      /**
       * Adds the "if not exists" modifier.
       *
       * If the table already exists, no error is thrown if this method has been called.
       */
      ifNotExists() {
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWith(this.#props.node, {
            ifNotExists: true
          })
        });
      }
      /**
       * Adds a column to the table.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', (col) => col.autoIncrement().primaryKey())
       *   .addColumn('first_name', 'varchar(50)', (col) => col.notNull())
       *   .addColumn('last_name', 'varchar(255)')
       *   .addColumn('bank_balance', 'numeric(8, 2)')
       *   // You can specify any data type using the `sql` tag if the types
       *   // don't include it.
       *   .addColumn('data', sql`any_type_here`)
       *   .addColumn('parent_id', 'integer', (col) =>
       *     col.references('person.id').onDelete('cascade')
       *   )
       * ```
       *
       * With this method, it's once again good to remember that Kysely just builds the
       * query and doesn't provide the same API for all databases. For example, some
       * databases like older MySQL don't support the `references` statement in the
       * column definition. Instead foreign key constraints need to be defined in the
       * `create table` query. See the next example:
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', (col) => col.primaryKey())
       *   .addColumn('parent_id', 'integer')
       *   .addForeignKeyConstraint(
       *     'person_parent_id_fk',
       *     ['parent_id'],
       *     'person',
       *     ['id'],
       *     (cb) => cb.onDelete('cascade')
       *   )
       *   .execute()
       * ```
       *
       * Another good example is that PostgreSQL doesn't support the `auto_increment`
       * keyword and you need to define an autoincrementing column for example using
       * `serial`:
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'serial', (col) => col.primaryKey())
       *   .execute()
       * ```
       */
      addColumn(columnName, dataType, build2 = noop3) {
        const columnBuilder = build2(new ColumnDefinitionBuilder(ColumnDefinitionNode.create(columnName, parseDataTypeExpression(dataType))));
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWithColumn(this.#props.node, columnBuilder.toOperationNode())
        });
      }
      /**
       * Adds a primary key constraint for one or more columns.
       *
       * The constraint name can be anything you want, but it must be unique
       * across the whole database.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('first_name', 'varchar(64)')
       *   .addColumn('last_name', 'varchar(64)')
       *   .addPrimaryKeyConstraint('primary_key', ['first_name', 'last_name'])
       *   .execute()
       * ```
       */
      addPrimaryKeyConstraint(constraintName, columns) {
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWithConstraint(this.#props.node, PrimaryConstraintNode.create(columns, constraintName))
        });
      }
      /**
       * Adds a unique constraint for one or more columns.
       *
       * The constraint name can be anything you want, but it must be unique
       * across the whole database.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('first_name', 'varchar(64)')
       *   .addColumn('last_name', 'varchar(64)')
       *   .addUniqueConstraint(
       *     'first_name_last_name_unique',
       *     ['first_name', 'last_name']
       *   )
       *   .execute()
       * ```
       *
       * In dialects such as PostgreSQL you can specify `nulls not distinct` as follows:
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('first_name', 'varchar(64)')
       *   .addColumn('last_name', 'varchar(64)')
       *   .addUniqueConstraint(
       *     'first_name_last_name_unique',
       *     ['first_name', 'last_name'],
       *     (cb) => cb.nullsNotDistinct()
       *   )
       *   .execute()
       * ```
       */
      addUniqueConstraint(constraintName, columns, build2 = noop3) {
        const uniqueConstraintBuilder = build2(new UniqueConstraintNodeBuilder(UniqueConstraintNode.create(columns, constraintName)));
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWithConstraint(this.#props.node, uniqueConstraintBuilder.toOperationNode())
        });
      }
      /**
       * Adds a check constraint.
       *
       * The constraint name can be anything you want, but it must be unique
       * across the whole database.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createTable('animal')
       *   .addColumn('number_of_legs', 'integer')
       *   .addCheckConstraint('check_legs', sql`number_of_legs < 5`)
       *   .execute()
       * ```
       */
      addCheckConstraint(constraintName, checkExpression) {
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWithConstraint(this.#props.node, CheckConstraintNode.create(checkExpression.toOperationNode(), constraintName))
        });
      }
      /**
       * Adds a foreign key constraint.
       *
       * The constraint name can be anything you want, but it must be unique
       * across the whole database.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('pet')
       *   .addColumn('owner_id', 'integer')
       *   .addForeignKeyConstraint(
       *     'owner_id_foreign',
       *     ['owner_id'],
       *     'person',
       *     ['id'],
       *   )
       *   .execute()
       * ```
       *
       * Add constraint for multiple columns:
       *
       * ```ts
       * await db.schema
       *   .createTable('pet')
       *   .addColumn('owner_id1', 'integer')
       *   .addColumn('owner_id2', 'integer')
       *   .addForeignKeyConstraint(
       *     'owner_id_foreign',
       *     ['owner_id1', 'owner_id2'],
       *     'person',
       *     ['id1', 'id2'],
       *     (cb) => cb.onDelete('cascade')
       *   )
       *   .execute()
       * ```
       */
      addForeignKeyConstraint(constraintName, columns, targetTable, targetColumns, build2 = noop3) {
        const builder = build2(new ForeignKeyConstraintBuilder(ForeignKeyConstraintNode.create(columns.map(ColumnNode.create), parseTable(targetTable), targetColumns.map(ColumnNode.create), constraintName)));
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWithConstraint(this.#props.node, builder.toOperationNode())
        });
      }
      /**
       * This can be used to add any additional SQL to the front of the query __after__ the `create` keyword.
       *
       * Also see {@link temporary}.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createTable('person')
       *   .modifyFront(sql`global temporary`)
       *   .addColumn('id', 'integer', col => col.primaryKey())
       *   .addColumn('first_name', 'varchar(64)', col => col.notNull())
       *   .addColumn('last_name', 'varchar(64)', col => col.notNull())
       *   .execute()
       * ```
       *
       * The generated SQL (Postgres):
       *
       * ```sql
       * create global temporary table "person" (
       *   "id" integer primary key,
       *   "first_name" varchar(64) not null,
       *   "last_name" varchar(64) not null
       * )
       * ```
       */
      modifyFront(modifier) {
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWithFrontModifier(this.#props.node, modifier.toOperationNode())
        });
      }
      /**
       * This can be used to add any additional SQL to the end of the query.
       *
       * Also see {@link onCommit}.
       *
       * ### Examples
       *
       * ```ts
       * import { sql } from 'kysely'
       *
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', col => col.primaryKey())
       *   .addColumn('first_name', 'varchar(64)', col => col.notNull())
       *   .addColumn('last_name', 'varchar(64)', col => col.notNull())
       *   .modifyEnd(sql`collate utf8_unicode_ci`)
       *   .execute()
       * ```
       *
       * The generated SQL (MySQL):
       *
       * ```sql
       * create table `person` (
       *   `id` integer primary key,
       *   `first_name` varchar(64) not null,
       *   `last_name` varchar(64) not null
       * ) collate utf8_unicode_ci
       * ```
       */
      modifyEnd(modifier) {
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWithEndModifier(this.#props.node, modifier.toOperationNode())
        });
      }
      /**
       * Allows to create table from `select` query.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('copy')
       *   .temporary()
       *   .as(db.selectFrom('person').select(['first_name', 'last_name']))
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * create temporary table "copy" as
       * select "first_name", "last_name" from "person"
       * ```
       */
      as(expression) {
        return new _CreateTableBuilder({
          ...this.#props,
          node: CreateTableNode.cloneWith(this.#props.node, {
            selectQuery: parseExpression(expression)
          })
        });
      }
      /**
       * Calls the given function passing `this` as the only argument.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createTable('test')
       *   .$call((builder) => builder.addColumn('id', 'integer'))
       *   .execute()
       * ```
       *
       * This is useful for creating reusable functions that can be called with a builder.
       *
       * ```ts
       * import { type CreateTableBuilder, sql } from 'kysely'
       *
       * const addDefaultColumns = (ctb: CreateTableBuilder<any, any>) => {
       *   return ctb
       *     .addColumn('id', 'integer', (col) => col.notNull())
       *     .addColumn('created_at', 'date', (col) =>
       *       col.notNull().defaultTo(sql`now()`)
       *     )
       *     .addColumn('updated_at', 'date', (col) =>
       *       col.notNull().defaultTo(sql`now()`)
       *     )
       * }
       *
       * await db.schema
       *   .createTable('test')
       *   .$call(addDefaultColumns)
       *   .execute()
       * ```
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(CreateTableBuilder, "don't await CreateTableBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/drop-index-builder.js
var DropIndexBuilder;
var init_drop_index_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/drop-index-builder.js"() {
    init_drop_index_node();
    init_prevent_await();
    init_table_parser();
    init_object_utils();
    DropIndexBuilder = class _DropIndexBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Specifies the table the index was created for. This is not needed
       * in all dialects.
       */
      on(table2) {
        return new _DropIndexBuilder({
          ...this.#props,
          node: DropIndexNode.cloneWith(this.#props.node, {
            table: parseTable(table2)
          })
        });
      }
      ifExists() {
        return new _DropIndexBuilder({
          ...this.#props,
          node: DropIndexNode.cloneWith(this.#props.node, {
            ifExists: true
          })
        });
      }
      cascade() {
        return new _DropIndexBuilder({
          ...this.#props,
          node: DropIndexNode.cloneWith(this.#props.node, {
            cascade: true
          })
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(DropIndexBuilder, "don't await DropIndexBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/drop-schema-builder.js
var DropSchemaBuilder;
var init_drop_schema_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/drop-schema-builder.js"() {
    init_drop_schema_node();
    init_prevent_await();
    init_object_utils();
    DropSchemaBuilder = class _DropSchemaBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      ifExists() {
        return new _DropSchemaBuilder({
          ...this.#props,
          node: DropSchemaNode.cloneWith(this.#props.node, {
            ifExists: true
          })
        });
      }
      cascade() {
        return new _DropSchemaBuilder({
          ...this.#props,
          node: DropSchemaNode.cloneWith(this.#props.node, {
            cascade: true
          })
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(DropSchemaBuilder, "don't await DropSchemaBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/drop-table-builder.js
var DropTableBuilder;
var init_drop_table_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/drop-table-builder.js"() {
    init_drop_table_node();
    init_prevent_await();
    init_object_utils();
    DropTableBuilder = class _DropTableBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      ifExists() {
        return new _DropTableBuilder({
          ...this.#props,
          node: DropTableNode.cloneWith(this.#props.node, {
            ifExists: true
          })
        });
      }
      cascade() {
        return new _DropTableBuilder({
          ...this.#props,
          node: DropTableNode.cloneWith(this.#props.node, {
            cascade: true
          })
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(DropTableBuilder, "don't await DropTableBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/create-view-node.js
var CreateViewNode;
var init_create_view_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/create-view-node.js"() {
    init_object_utils();
    init_schemable_identifier_node();
    CreateViewNode = freeze({
      is(node) {
        return node.kind === "CreateViewNode";
      },
      create(name) {
        return freeze({
          kind: "CreateViewNode",
          name: SchemableIdentifierNode.create(name)
        });
      },
      cloneWith(createView, params) {
        return freeze({
          ...createView,
          ...params
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/immediate-value/immediate-value-plugin.js
var ImmediateValuePlugin;
var init_immediate_value_plugin = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/immediate-value/immediate-value-plugin.js"() {
    init_immediate_value_transformer();
    ImmediateValuePlugin = class {
      #transformer = new ImmediateValueTransformer();
      transformQuery(args) {
        return this.#transformer.transformNode(args.node);
      }
      transformResult(args) {
        return Promise.resolve(args.result);
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/create-view-builder.js
var CreateViewBuilder;
var init_create_view_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/create-view-builder.js"() {
    init_prevent_await();
    init_object_utils();
    init_create_view_node();
    init_reference_parser();
    init_immediate_value_plugin();
    CreateViewBuilder = class _CreateViewBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      /**
       * Adds the "temporary" modifier.
       *
       * Use this to create a temporary view.
       */
      temporary() {
        return new _CreateViewBuilder({
          ...this.#props,
          node: CreateViewNode.cloneWith(this.#props.node, {
            temporary: true
          })
        });
      }
      materialized() {
        return new _CreateViewBuilder({
          ...this.#props,
          node: CreateViewNode.cloneWith(this.#props.node, {
            materialized: true
          })
        });
      }
      /**
       * Only implemented on some dialects like SQLite. On most dialects, use {@link orReplace}.
       */
      ifNotExists() {
        return new _CreateViewBuilder({
          ...this.#props,
          node: CreateViewNode.cloneWith(this.#props.node, {
            ifNotExists: true
          })
        });
      }
      orReplace() {
        return new _CreateViewBuilder({
          ...this.#props,
          node: CreateViewNode.cloneWith(this.#props.node, {
            orReplace: true
          })
        });
      }
      columns(columns) {
        return new _CreateViewBuilder({
          ...this.#props,
          node: CreateViewNode.cloneWith(this.#props.node, {
            columns: columns.map(parseColumnName)
          })
        });
      }
      /**
       * Sets the select query or a `values` statement that creates the view.
       *
       * WARNING!
       * Some dialects don't support parameterized queries in DDL statements and therefore
       * the query or raw {@link sql } expression passed here is interpolated into a single
       * string opening an SQL injection vulnerability. DO NOT pass unchecked user input
       * into the query or raw expression passed to this method!
       */
      as(query) {
        const queryNode = query.withPlugin(new ImmediateValuePlugin()).toOperationNode();
        return new _CreateViewBuilder({
          ...this.#props,
          node: CreateViewNode.cloneWith(this.#props.node, {
            as: queryNode
          })
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(CreateViewBuilder, "don't await CreateViewBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-view-node.js
var DropViewNode;
var init_drop_view_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-view-node.js"() {
    init_object_utils();
    init_schemable_identifier_node();
    DropViewNode = freeze({
      is(node) {
        return node.kind === "DropViewNode";
      },
      create(name) {
        return freeze({
          kind: "DropViewNode",
          name: SchemableIdentifierNode.create(name)
        });
      },
      cloneWith(dropView, params) {
        return freeze({
          ...dropView,
          ...params
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/drop-view-builder.js
var DropViewBuilder;
var init_drop_view_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/drop-view-builder.js"() {
    init_prevent_await();
    init_object_utils();
    init_drop_view_node();
    DropViewBuilder = class _DropViewBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      materialized() {
        return new _DropViewBuilder({
          ...this.#props,
          node: DropViewNode.cloneWith(this.#props.node, {
            materialized: true
          })
        });
      }
      ifExists() {
        return new _DropViewBuilder({
          ...this.#props,
          node: DropViewNode.cloneWith(this.#props.node, {
            ifExists: true
          })
        });
      }
      cascade() {
        return new _DropViewBuilder({
          ...this.#props,
          node: DropViewNode.cloneWith(this.#props.node, {
            cascade: true
          })
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(DropViewBuilder, "don't await DropViewBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/create-type-node.js
var CreateTypeNode;
var init_create_type_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/create-type-node.js"() {
    init_object_utils();
    init_value_list_node();
    init_value_node();
    CreateTypeNode = freeze({
      is(node) {
        return node.kind === "CreateTypeNode";
      },
      create(name) {
        return freeze({
          kind: "CreateTypeNode",
          name
        });
      },
      cloneWithEnum(createType, values) {
        return freeze({
          ...createType,
          enum: ValueListNode.create(values.map((value2) => ValueNode.createImmediate(value2)))
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/create-type-builder.js
var CreateTypeBuilder;
var init_create_type_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/create-type-builder.js"() {
    init_prevent_await();
    init_object_utils();
    init_create_type_node();
    CreateTypeBuilder = class _CreateTypeBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      /**
       * Creates an anum type.
       *
       * ### Examples
       *
       * ```ts
       * db.schema.createType('species').asEnum(['cat', 'dog', 'frog'])
       * ```
       */
      asEnum(values) {
        return new _CreateTypeBuilder({
          ...this.#props,
          node: CreateTypeNode.cloneWithEnum(this.#props.node, values)
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(CreateTypeBuilder, "don't await CreateTypeBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-type-node.js
var DropTypeNode;
var init_drop_type_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/drop-type-node.js"() {
    init_object_utils();
    DropTypeNode = freeze({
      is(node) {
        return node.kind === "DropTypeNode";
      },
      create(name) {
        return freeze({
          kind: "DropTypeNode",
          name
        });
      },
      cloneWith(dropType, params) {
        return freeze({
          ...dropType,
          ...params
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/drop-type-builder.js
var DropTypeBuilder;
var init_drop_type_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/drop-type-builder.js"() {
    init_drop_type_node();
    init_prevent_await();
    init_object_utils();
    DropTypeBuilder = class _DropTypeBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      ifExists() {
        return new _DropTypeBuilder({
          ...this.#props,
          node: DropTypeNode.cloneWith(this.#props.node, {
            ifExists: true
          })
        });
      }
      /**
       * Simply calls the provided function passing `this` as the only argument. `$call` returns
       * what the provided function returns.
       */
      $call(func) {
        return func(this);
      }
      toOperationNode() {
        return this.#props.executor.transformQuery(this.#props.node, this.#props.queryId);
      }
      compile() {
        return this.#props.executor.compileQuery(this.toOperationNode(), this.#props.queryId);
      }
      async execute() {
        await this.#props.executor.executeQuery(this.compile(), this.#props.queryId);
      }
    };
    preventAwait(DropTypeBuilder, "don't await DropTypeBuilder instances directly. To execute the query you need to call `execute`");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/identifier-parser.js
function parseSchemableIdentifier(id) {
  const SCHEMA_SEPARATOR = ".";
  if (id.includes(SCHEMA_SEPARATOR)) {
    const parts = id.split(SCHEMA_SEPARATOR).map(trim3);
    if (parts.length === 2) {
      return SchemableIdentifierNode.createWithSchema(parts[0], parts[1]);
    } else {
      throw new Error(`invalid schemable identifier ${id}`);
    }
  } else {
    return SchemableIdentifierNode.create(id);
  }
}
function trim3(str2) {
  return str2.trim();
}
var init_identifier_parser = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/parser/identifier-parser.js"() {
    init_schemable_identifier_node();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/schema.js
var SchemaModule;
var init_schema = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/schema/schema.js"() {
    init_alter_table_node();
    init_create_index_node();
    init_create_schema_node();
    init_create_table_node();
    init_drop_index_node();
    init_drop_schema_node();
    init_drop_table_node();
    init_table_parser();
    init_alter_table_builder();
    init_create_index_builder();
    init_create_schema_builder();
    init_create_table_builder();
    init_drop_index_builder();
    init_drop_schema_builder();
    init_drop_table_builder();
    init_query_id();
    init_with_schema_plugin();
    init_create_view_builder();
    init_create_view_node();
    init_drop_view_builder();
    init_drop_view_node();
    init_create_type_builder();
    init_drop_type_builder();
    init_create_type_node();
    init_drop_type_node();
    init_identifier_parser();
    SchemaModule = class _SchemaModule {
      #executor;
      constructor(executor) {
        this.#executor = executor;
      }
      /**
       * Create a new table.
       *
       * ### Examples
       *
       * This example creates a new table with columns `id`, `first_name`,
       * `last_name` and `gender`:
       *
       * ```ts
       * await db.schema
       *   .createTable('person')
       *   .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
       *   .addColumn('first_name', 'varchar', col => col.notNull())
       *   .addColumn('last_name', 'varchar', col => col.notNull())
       *   .addColumn('gender', 'varchar')
       *   .execute()
       * ```
       *
       * This example creates a table with a foreign key. Not all database
       * engines support column-level foreign key constraint definitions.
       * For example if you are using MySQL 5.X see the next example after
       * this one.
       *
       * ```ts
       * await db.schema
       *   .createTable('pet')
       *   .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
       *   .addColumn('owner_id', 'integer', col => col
       *     .references('person.id')
       *     .onDelete('cascade')
       *   )
       *   .execute()
       * ```
       *
       * This example adds a foreign key constraint for a columns just
       * like the previous example, but using a table-level statement.
       * On MySQL 5.X you need to define foreign key constraints like
       * this:
       *
       * ```ts
       * await db.schema
       *   .createTable('pet')
       *   .addColumn('id', 'integer', col => col.primaryKey().autoIncrement())
       *   .addColumn('owner_id', 'integer')
       *   .addForeignKeyConstraint(
       *     'pet_owner_id_foreign', ['owner_id'], 'person', ['id'],
       *     (constraint) => constraint.onDelete('cascade')
       *   )
       *   .execute()
       * ```
       */
      createTable(table2) {
        return new CreateTableBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: CreateTableNode.create(parseTable(table2))
        });
      }
      /**
       * Drop a table.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .dropTable('person')
       *   .execute()
       * ```
       */
      dropTable(table2) {
        return new DropTableBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: DropTableNode.create(parseTable(table2))
        });
      }
      /**
       * Create a new index.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createIndex('person_full_name_unique_index')
       *   .on('person')
       *   .columns(['first_name', 'last_name'])
       *   .execute()
       * ```
       */
      createIndex(indexName) {
        return new CreateIndexBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: CreateIndexNode.create(indexName)
        });
      }
      /**
       * Drop an index.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .dropIndex('person_full_name_unique_index')
       *   .execute()
       * ```
       */
      dropIndex(indexName) {
        return new DropIndexBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: DropIndexNode.create(indexName)
        });
      }
      /**
       * Create a new schema.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createSchema('some_schema')
       *   .execute()
       * ```
       */
      createSchema(schema) {
        return new CreateSchemaBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: CreateSchemaNode.create(schema)
        });
      }
      /**
       * Drop a schema.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .dropSchema('some_schema')
       *   .execute()
       * ```
       */
      dropSchema(schema) {
        return new DropSchemaBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: DropSchemaNode.create(schema)
        });
      }
      /**
       * Alter a table.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .alterTable('person')
       *   .alterColumn('first_name', (ac) => ac.setDataType('text'))
       *   .execute()
       * ```
       */
      alterTable(table2) {
        return new AlterTableBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: AlterTableNode.create(parseTable(table2))
        });
      }
      /**
       * Create a new view.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createView('dogs')
       *   .orReplace()
       *   .as(db.selectFrom('pet').selectAll().where('species', '=', 'dog'))
       *   .execute()
       * ```
       */
      createView(viewName) {
        return new CreateViewBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: CreateViewNode.create(viewName)
        });
      }
      /**
       * Drop a view.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .dropView('dogs')
       *   .ifExists()
       *   .execute()
       * ```
       */
      dropView(viewName) {
        return new DropViewBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: DropViewNode.create(viewName)
        });
      }
      /**
       * Create a new type.
       *
       * Only some dialects like PostgreSQL have user-defined types.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .createType('species')
       *   .asEnum(['dog', 'cat', 'frog'])
       *   .execute()
       * ```
       */
      createType(typeName) {
        return new CreateTypeBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: CreateTypeNode.create(parseSchemableIdentifier(typeName))
        });
      }
      /**
       * Drop a type.
       *
       * Only some dialects like PostgreSQL have user-defined types.
       *
       * ### Examples
       *
       * ```ts
       * await db.schema
       *   .dropType('species')
       *   .ifExists()
       *   .execute()
       * ```
       */
      dropType(typeName) {
        return new DropTypeBuilder({
          queryId: createQueryId(),
          executor: this.#executor,
          node: DropTypeNode.create(parseSchemableIdentifier(typeName))
        });
      }
      /**
       * Returns a copy of this schema module with the given plugin installed.
       */
      withPlugin(plugin) {
        return new _SchemaModule(this.#executor.withPlugin(plugin));
      }
      /**
       * Returns a copy of this schema module  without any plugins.
       */
      withoutPlugins() {
        return new _SchemaModule(this.#executor.withoutPlugins());
      }
      /**
       * See {@link QueryCreator.withSchema}
       */
      withSchema(schema) {
        return new _SchemaModule(this.#executor.withPluginAtFront(new WithSchemaPlugin(schema)));
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dynamic/dynamic.js
var DynamicModule;
var init_dynamic = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dynamic/dynamic.js"() {
    init_dynamic_reference_builder();
    DynamicModule = class {
      /**
       * Creates a dynamic reference to a column that is not know at compile time.
       *
       * Kysely is built in a way that by default you can't refer to tables or columns
       * that are not actually visible in the current query and context. This is all
       * done by TypeScript at compile time, which means that you need to know the
       * columns and tables at compile time. This is not always the case of course.
       *
       * This method is meant to be used in those cases where the column names
       * come from the user input or are not otherwise known at compile time.
       *
       * WARNING! Unlike values, column names are not escaped by the database engine
       * or Kysely and if you pass in unchecked column names using this method, you
       * create an SQL injection vulnerability. Always __always__ validate the user
       * input before passing it to this method.
       *
       * There are couple of examples below for some use cases, but you can pass
       * `ref` to other methods as well. If the types allow you to pass a `ref`
       * value to some place, it should work.
       *
       * ### Examples
       *
       * Filter by a column not know at compile time:
       *
       * ```ts
       * async function someQuery(filterColumn: string, filterValue: string) {
       *   const { ref } = db.dynamic
       *
       *   return await db
       *     .selectFrom('person')
       *     .selectAll()
       *     .where(ref(filterColumn), '=', filterValue)
       *     .execute()
       * }
       *
       * someQuery('first_name', 'Arnold')
       * someQuery('person.last_name', 'Aniston')
       * ```
       *
       * Order by a column not know at compile time:
       *
       * ```ts
       * async function someQuery(orderBy: string) {
       *   const { ref } = db.dynamic
       *
       *   return await db
       *     .selectFrom('person')
       *     .select('person.first_name as fn')
       *     .orderBy(ref(orderBy))
       *     .execute()
       * }
       *
       * someQuery('fn')
       * ```
       *
       * In this example we add selections dynamically:
       *
       * ```ts
       * const { ref } = db.dynamic
       *
       * // Some column name provided by the user. Value not known at compile time.
       * const columnFromUserInput: PossibleColumns = 'birthdate';
       *
       * // A type that lists all possible values `columnFromUserInput` can have.
       * // You can use `keyof Person` if any column of an interface is allowed.
       * type PossibleColumns = 'last_name' | 'first_name' | 'birthdate'
       *
       * const [person] = await db.selectFrom('person')
       *   .select([
       *     ref<PossibleColumns>(columnFromUserInput),
       *     'id'
       *   ])
       *   .execute()
       *
       * // The resulting type contains all `PossibleColumns` as optional fields
       * // because we cannot know which field was actually selected before
       * // running the code.
       * const lastName: string | null | undefined = person?.last_name
       * const firstName: string | undefined = person?.first_name
       * const birthDate: Date | null | undefined = person?.birthdate
       *
       * // The result type also contains the compile time selection `id`.
       * person?.id
       * ```
       */
      ref(reference) {
        return new DynamicReferenceBuilder(reference);
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/default-connection-provider.js
var DefaultConnectionProvider;
var init_default_connection_provider = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/default-connection-provider.js"() {
    DefaultConnectionProvider = class {
      #driver;
      constructor(driver) {
        this.#driver = driver;
      }
      async provideConnection(consumer) {
        const connection = await this.#driver.acquireConnection();
        try {
          return await consumer(connection);
        } finally {
          await this.#driver.releaseConnection(connection);
        }
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-executor/default-query-executor.js
var DefaultQueryExecutor;
var init_default_query_executor = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-executor/default-query-executor.js"() {
    init_query_executor_base();
    DefaultQueryExecutor = class _DefaultQueryExecutor extends QueryExecutorBase {
      #compiler;
      #adapter;
      #connectionProvider;
      constructor(compiler, adapter, connectionProvider, plugins = []) {
        super(plugins);
        this.#compiler = compiler;
        this.#adapter = adapter;
        this.#connectionProvider = connectionProvider;
      }
      get adapter() {
        return this.#adapter;
      }
      compileQuery(node) {
        return this.#compiler.compileQuery(node);
      }
      provideConnection(consumer) {
        return this.#connectionProvider.provideConnection(consumer);
      }
      withPlugins(plugins) {
        return new _DefaultQueryExecutor(this.#compiler, this.#adapter, this.#connectionProvider, [...this.plugins, ...plugins]);
      }
      withPlugin(plugin) {
        return new _DefaultQueryExecutor(this.#compiler, this.#adapter, this.#connectionProvider, [...this.plugins, plugin]);
      }
      withPluginAtFront(plugin) {
        return new _DefaultQueryExecutor(this.#compiler, this.#adapter, this.#connectionProvider, [plugin, ...this.plugins]);
      }
      withConnectionProvider(connectionProvider) {
        return new _DefaultQueryExecutor(this.#compiler, this.#adapter, connectionProvider, [...this.plugins]);
      }
      withoutPlugins() {
        return new _DefaultQueryExecutor(this.#compiler, this.#adapter, this.#connectionProvider, []);
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/performance-now.js
function performanceNow() {
  if (typeof performance !== "undefined" && isFunction(performance.now)) {
    return performance.now();
  } else {
    return Date.now();
  }
}
var init_performance_now = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/performance-now.js"() {
    init_object_utils();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/runtime-driver.js
var RuntimeDriver;
var init_runtime_driver = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/runtime-driver.js"() {
    init_performance_now();
    RuntimeDriver = class {
      #driver;
      #log;
      #initPromise;
      #initDone;
      #destroyPromise;
      #connections = /* @__PURE__ */ new WeakSet();
      constructor(driver, log) {
        this.#initDone = false;
        this.#driver = driver;
        this.#log = log;
      }
      async init() {
        if (this.#destroyPromise) {
          throw new Error("driver has already been destroyed");
        }
        if (!this.#initPromise) {
          this.#initPromise = this.#driver.init().then(() => {
            this.#initDone = true;
          }).catch((err) => {
            this.#initPromise = void 0;
            return Promise.reject(err);
          });
        }
        await this.#initPromise;
      }
      async acquireConnection() {
        if (this.#destroyPromise) {
          throw new Error("driver has already been destroyed");
        }
        if (!this.#initDone) {
          await this.init();
        }
        const connection = await this.#driver.acquireConnection();
        if (!this.#connections.has(connection)) {
          if (this.#needsLogging()) {
            this.#addLogging(connection);
          }
          this.#connections.add(connection);
        }
        return connection;
      }
      async releaseConnection(connection) {
        await this.#driver.releaseConnection(connection);
      }
      beginTransaction(connection, settings2) {
        return this.#driver.beginTransaction(connection, settings2);
      }
      commitTransaction(connection) {
        return this.#driver.commitTransaction(connection);
      }
      rollbackTransaction(connection) {
        return this.#driver.rollbackTransaction(connection);
      }
      async destroy() {
        if (!this.#initPromise) {
          return;
        }
        await this.#initPromise;
        if (!this.#destroyPromise) {
          this.#destroyPromise = this.#driver.destroy().catch((err) => {
            this.#destroyPromise = void 0;
            return Promise.reject(err);
          });
        }
        await this.#destroyPromise;
      }
      #needsLogging() {
        return this.#log.isLevelEnabled("query") || this.#log.isLevelEnabled("error");
      }
      // This method monkey patches the database connection's executeQuery method
      // by adding logging code around it. Monkey patching is not pretty, but it's
      // the best option in this case.
      #addLogging(connection) {
        const executeQuery = connection.executeQuery;
        connection.executeQuery = async (compiledQuery) => {
          let caughtError;
          const startTime = performanceNow();
          try {
            return await executeQuery.call(connection, compiledQuery);
          } catch (error2) {
            caughtError = error2;
            await this.#logError(error2, compiledQuery, startTime);
            throw error2;
          } finally {
            if (!caughtError) {
              await this.#logQuery(compiledQuery, startTime);
            }
          }
        };
      }
      async #logError(error2, compiledQuery, startTime) {
        await this.#log.error(() => ({
          level: "error",
          error: error2,
          query: compiledQuery,
          queryDurationMillis: this.#calculateDurationMillis(startTime)
        }));
      }
      async #logQuery(compiledQuery, startTime) {
        await this.#log.query(() => ({
          level: "query",
          query: compiledQuery,
          queryDurationMillis: this.#calculateDurationMillis(startTime)
        }));
      }
      #calculateDurationMillis(startTime) {
        return performanceNow() - startTime;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/single-connection-provider.js
var ignoreError, SingleConnectionProvider;
var init_single_connection_provider = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/single-connection-provider.js"() {
    ignoreError = () => {
    };
    SingleConnectionProvider = class {
      #connection;
      #runningPromise;
      constructor(connection) {
        this.#connection = connection;
      }
      async provideConnection(consumer) {
        while (this.#runningPromise) {
          await this.#runningPromise.catch(ignoreError);
        }
        this.#runningPromise = this.#run(consumer).finally(() => {
          this.#runningPromise = void 0;
        });
        return this.#runningPromise;
      }
      // Run the runner in an async function to make sure it doesn't
      // throw synchronous errors.
      async #run(runner) {
        return await runner(this.#connection);
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/driver.js
var TRANSACTION_ISOLATION_LEVELS;
var init_driver = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/driver.js"() {
    TRANSACTION_ISOLATION_LEVELS = [
      "read uncommitted",
      "read committed",
      "repeatable read",
      "serializable",
      "snapshot"
    ];
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/log.js
function defaultLogger(event) {
  if (event.level === "query") {
    console.log(`kysely:query: ${event.query.sql}`);
    console.log(`kysely:query: duration: ${event.queryDurationMillis.toFixed(1)}ms`);
  } else if (event.level === "error") {
    if (event.error instanceof Error) {
      console.error(`kysely:error: ${event.error.stack ?? event.error.message}`);
    } else {
      console.error(`kysely:error: ${JSON.stringify({
        error: event.error,
        query: event.query.sql,
        queryDurationMillis: event.queryDurationMillis
      })}`);
    }
  }
}
var LOG_LEVELS, Log;
var init_log = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/log.js"() {
    init_object_utils();
    LOG_LEVELS = freeze(["query", "error"]);
    Log = class {
      #levels;
      #logger;
      constructor(config2) {
        if (isFunction(config2)) {
          this.#logger = config2;
          this.#levels = freeze({
            query: true,
            error: true
          });
        } else {
          this.#logger = defaultLogger;
          this.#levels = freeze({
            query: config2.includes("query"),
            error: config2.includes("error")
          });
        }
      }
      isLevelEnabled(level) {
        return this.#levels[level];
      }
      async query(getEvent) {
        if (this.#levels.query) {
          await this.#logger(getEvent());
        }
      }
      async error(getEvent) {
        if (this.#levels.error) {
          await this.#logger(getEvent());
        }
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/compilable.js
function isCompilable(value2) {
  return isObject2(value2) && isFunction(value2.compile);
}
var init_compilable = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/compilable.js"() {
    init_object_utils();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/kysely.js
function isKyselyProps(obj) {
  return isObject2(obj) && isObject2(obj.config) && isObject2(obj.driver) && isObject2(obj.executor) && isObject2(obj.dialect);
}
function validateTransactionSettings(settings2) {
  if (settings2.isolationLevel && !TRANSACTION_ISOLATION_LEVELS.includes(settings2.isolationLevel)) {
    throw new Error(`invalid transaction isolation level ${settings2.isolationLevel}`);
  }
}
var Kysely, Transaction, ConnectionBuilder, TransactionBuilder;
var init_kysely = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/kysely.js"() {
    init_schema();
    init_dynamic();
    init_default_connection_provider();
    init_query_creator();
    init_default_query_executor();
    init_object_utils();
    init_runtime_driver();
    init_single_connection_provider();
    init_driver();
    init_prevent_await();
    init_function_module();
    init_log();
    init_query_id();
    init_compilable();
    init_case_builder();
    init_case_node();
    init_expression_parser();
    init_with_schema_plugin();
    Kysely = class _Kysely extends QueryCreator {
      #props;
      constructor(args) {
        let superProps;
        let props;
        if (isKyselyProps(args)) {
          superProps = { executor: args.executor };
          props = { ...args };
        } else {
          const dialect = args.dialect;
          const driver = dialect.createDriver();
          const compiler = dialect.createQueryCompiler();
          const adapter = dialect.createAdapter();
          const log = new Log(args.log ?? []);
          const runtimeDriver = new RuntimeDriver(driver, log);
          const connectionProvider = new DefaultConnectionProvider(runtimeDriver);
          const executor = new DefaultQueryExecutor(compiler, adapter, connectionProvider, args.plugins ?? []);
          superProps = { executor };
          props = {
            config: args,
            executor,
            dialect,
            driver: runtimeDriver
          };
        }
        super(superProps);
        this.#props = freeze(props);
      }
      /**
       * Returns the {@link SchemaModule} module for building database schema.
       */
      get schema() {
        return new SchemaModule(this.#props.executor);
      }
      /**
       * Returns a the {@link DynamicModule} module.
       *
       * The {@link DynamicModule} module can be used to bypass strict typing and
       * passing in dynamic values for the queries.
       */
      get dynamic() {
        return new DynamicModule();
      }
      /**
       * Returns a {@link DatabaseIntrospector | database introspector}.
       */
      get introspection() {
        return this.#props.dialect.createIntrospector(this.withoutPlugins());
      }
      case(value2) {
        return new CaseBuilder({
          node: CaseNode.create(isUndefined(value2) ? void 0 : parseExpression(value2))
        });
      }
      /**
       * Returns a {@link FunctionModule} that can be used to write somewhat type-safe function
       * calls.
       *
       * ```ts
       * const { count } = db.fn
       *
       * await db.selectFrom('person')
       *   .innerJoin('pet', 'pet.owner_id', 'person.id')
       *   .select([
       *     'id',
       *     count('pet.id').as('person_count'),
       *   ])
       *   .groupBy('person.id')
       *   .having(count('pet.id'), '>', 10)
       *   .execute()
       * ```
       *
       * The generated SQL (PostgreSQL):
       *
       * ```sql
       * select "person"."id", count("pet"."id") as "person_count"
       * from "person"
       * inner join "pet" on "pet"."owner_id" = "person"."id"
       * group by "person"."id"
       * having count("pet"."id") > $1
       * ```
       *
       * Why "somewhat" type-safe? Because the function calls are not bound to the
       * current query context. They allow you to reference columns and tables that
       * are not in the current query. E.g. remove the `innerJoin` from the previous
       * query and TypeScript won't even complain.
       *
       * If you want to make the function calls fully type-safe, you can use the
       * {@link ExpressionBuilder.fn} getter for a query context-aware, stricter {@link FunctionModule}.
       *
       * ```ts
       * await db.selectFrom('person')
       *   .innerJoin('pet', 'pet.owner_id', 'person.id')
       *   .select((eb) => [
       *     'person.id',
       *     eb.fn.count('pet.id').as('pet_count')
       *   ])
       *   .groupBy('person.id')
       *   .having((eb) => eb.fn.count('pet.id'), '>', 10)
       *   .execute()
       * ```
       */
      get fn() {
        return createFunctionModule();
      }
      /**
       * Creates a {@link TransactionBuilder} that can be used to run queries inside a transaction.
       *
       * The returned {@link TransactionBuilder} can be used to configure the transaction. The
       * {@link TransactionBuilder.execute} method can then be called to run the transaction.
       * {@link TransactionBuilder.execute} takes a function that is run inside the
       * transaction. If the function throws an exception,
       * 1. the exception is caught,
       * 2. the transaction is rolled back, and
       * 3. the exception is thrown again.
       * Otherwise the transaction is committed.
       *
       * The callback function passed to the {@link TransactionBuilder.execute | execute}
       * method gets the transaction object as its only argument. The transaction is
       * of type {@link Transaction} which inherits {@link Kysely}. Any query
       * started through the transaction object is executed inside the transaction.
       *
       * ### Examples
       *
       * <!-- siteExample("transactions", "Simple transaction", 10) -->
       *
       * This example inserts two rows in a transaction. If an exception is thrown inside
       * the callback passed to the `execute` method,
       * 1. the exception is caught,
       * 2. the transaction is rolled back, and
       * 3. the exception is thrown again.
       * Otherwise the transaction is committed.
       *
       * ```ts
       * const catto = await db.transaction().execute(async (trx) => {
       *   const jennifer = await trx.insertInto('person')
       *     .values({
       *       first_name: 'Jennifer',
       *       last_name: 'Aniston',
       *       age: 40,
       *     })
       *     .returning('id')
       *     .executeTakeFirstOrThrow()
       *
       *   return await trx.insertInto('pet')
       *     .values({
       *       owner_id: jennifer.id,
       *       name: 'Catto',
       *       species: 'cat',
       *       is_favorite: false,
       *     })
       *     .returningAll()
       *     .executeTakeFirst()
       * })
       * ```
       *
       * Setting the isolation level:
       *
       * ```ts
       * import type { Kysely } from 'kysely'
       *
       * await db
       *   .transaction()
       *   .setIsolationLevel('serializable')
       *   .execute(async (trx) => {
       *     await doStuff(trx)
       *   })
       *
       * async function doStuff(kysely: typeof db) {
       *   // ...
       * }
       * ```
       */
      transaction() {
        return new TransactionBuilder({ ...this.#props });
      }
      /**
       * Provides a kysely instance bound to a single database connection.
       *
       * ### Examples
       *
       * ```ts
       * await db
       *   .connection()
       *   .execute(async (db) => {
       *     // `db` is an instance of `Kysely` that's bound to a single
       *     // database connection. All queries executed through `db` use
       *     // the same connection.
       *     await doStuff(db)
       *   })
       *
       * async function doStuff(kysely: typeof db) {
       *   // ...
       * }
       * ```
       */
      connection() {
        return new ConnectionBuilder({ ...this.#props });
      }
      /**
       * Returns a copy of this Kysely instance with the given plugin installed.
       */
      withPlugin(plugin) {
        return new _Kysely({
          ...this.#props,
          executor: this.#props.executor.withPlugin(plugin)
        });
      }
      /**
       * Returns a copy of this Kysely instance without any plugins.
       */
      withoutPlugins() {
        return new _Kysely({
          ...this.#props,
          executor: this.#props.executor.withoutPlugins()
        });
      }
      /**
       * @override
       */
      withSchema(schema) {
        return new _Kysely({
          ...this.#props,
          executor: this.#props.executor.withPluginAtFront(new WithSchemaPlugin(schema))
        });
      }
      /**
       * Returns a copy of this Kysely instance with tables added to its
       * database type.
       *
       * This method only modifies the types and doesn't affect any of the
       * executed queries in any way.
       *
       * ### Examples
       *
       * The following example adds and uses a temporary table:
       *
       * ```ts
       * await db.schema
       *   .createTable('temp_table')
       *   .temporary()
       *   .addColumn('some_column', 'integer')
       *   .execute()
       *
       * const tempDb = db.withTables<{
       *   temp_table: {
       *     some_column: number
       *   }
       * }>()
       *
       * await tempDb
       *   .insertInto('temp_table')
       *   .values({ some_column: 100 })
       *   .execute()
       * ```
       */
      withTables() {
        return new _Kysely({ ...this.#props });
      }
      /**
       * Releases all resources and disconnects from the database.
       *
       * You need to call this when you are done using the `Kysely` instance.
       */
      async destroy() {
        await this.#props.driver.destroy();
      }
      /**
       * Returns true if this `Kysely` instance is a transaction.
       *
       * You can also use `db instanceof Transaction`.
       */
      get isTransaction() {
        return false;
      }
      /**
       * @internal
       * @private
       */
      getExecutor() {
        return this.#props.executor;
      }
      /**
       * Executes a given compiled query or query builder.
       *
       * See {@link https://github.com/kysely-org/kysely/blob/master/site/docs/recipes/0004-splitting-query-building-and-execution.md#execute-compiled-queries splitting build, compile and execute code recipe} for more information.
       */
      executeQuery(query, queryId = createQueryId()) {
        const compiledQuery = isCompilable(query) ? query.compile() : query;
        return this.getExecutor().executeQuery(compiledQuery, queryId);
      }
    };
    Transaction = class _Transaction extends Kysely {
      #props;
      constructor(props) {
        super(props);
        this.#props = props;
      }
      // The return type is `true` instead of `boolean` to make Kysely<DB>
      // unassignable to Transaction<DB> while allowing assignment the
      // other way around.
      get isTransaction() {
        return true;
      }
      transaction() {
        throw new Error("calling the transaction method for a Transaction is not supported");
      }
      connection() {
        throw new Error("calling the connection method for a Transaction is not supported");
      }
      async destroy() {
        throw new Error("calling the destroy method for a Transaction is not supported");
      }
      withPlugin(plugin) {
        return new _Transaction({
          ...this.#props,
          executor: this.#props.executor.withPlugin(plugin)
        });
      }
      withoutPlugins() {
        return new _Transaction({
          ...this.#props,
          executor: this.#props.executor.withoutPlugins()
        });
      }
      withSchema(schema) {
        return new _Transaction({
          ...this.#props,
          executor: this.#props.executor.withPluginAtFront(new WithSchemaPlugin(schema))
        });
      }
      withTables() {
        return new _Transaction({ ...this.#props });
      }
    };
    ConnectionBuilder = class {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      async execute(callback) {
        return this.#props.executor.provideConnection(async (connection) => {
          const executor = this.#props.executor.withConnectionProvider(new SingleConnectionProvider(connection));
          const db2 = new Kysely({
            ...this.#props,
            executor
          });
          return await callback(db2);
        });
      }
    };
    preventAwait(ConnectionBuilder, "don't await ConnectionBuilder instances directly. To execute the query you need to call the `execute` method");
    TransactionBuilder = class _TransactionBuilder {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      setIsolationLevel(isolationLevel) {
        return new _TransactionBuilder({
          ...this.#props,
          isolationLevel
        });
      }
      async execute(callback) {
        const { isolationLevel, ...kyselyProps } = this.#props;
        const settings2 = { isolationLevel };
        validateTransactionSettings(settings2);
        return this.#props.executor.provideConnection(async (connection) => {
          const executor = this.#props.executor.withConnectionProvider(new SingleConnectionProvider(connection));
          const transaction = new Transaction({
            ...kyselyProps,
            executor
          });
          try {
            await this.#props.driver.beginTransaction(connection, settings2);
            const result = await callback(transaction);
            await this.#props.driver.commitTransaction(connection);
            return result;
          } catch (error2) {
            await this.#props.driver.rollbackTransaction(connection);
            throw error2;
          }
        });
      }
    };
    preventAwait(TransactionBuilder, "don't await TransactionBuilder instances directly. To execute the transaction you need to call the `execute` method");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/where-interface.js
var init_where_interface = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/where-interface.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/returning-interface.js
var init_returning_interface = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/returning-interface.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/output-interface.js
var init_output_interface = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/output-interface.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/having-interface.js
var init_having_interface = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-builder/having-interface.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/raw-builder/raw-builder.js
function createRawBuilder(props) {
  return new RawBuilderImpl(props);
}
var RawBuilderImpl, AliasedRawBuilderImpl;
var init_raw_builder = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/raw-builder/raw-builder.js"() {
    init_alias_node();
    init_prevent_await();
    init_object_utils();
    init_noop_query_executor();
    init_identifier_node();
    init_operation_node_source();
    RawBuilderImpl = class _RawBuilderImpl {
      #props;
      constructor(props) {
        this.#props = freeze(props);
      }
      get expressionType() {
        return void 0;
      }
      get isRawBuilder() {
        return true;
      }
      as(alias) {
        return new AliasedRawBuilderImpl(this, alias);
      }
      $castTo() {
        return new _RawBuilderImpl({ ...this.#props });
      }
      $notNull() {
        return new _RawBuilderImpl(this.#props);
      }
      withPlugin(plugin) {
        return new _RawBuilderImpl({
          ...this.#props,
          plugins: this.#props.plugins !== void 0 ? freeze([...this.#props.plugins, plugin]) : freeze([plugin])
        });
      }
      toOperationNode() {
        return this.#toOperationNode(this.#getExecutor());
      }
      compile(executorProvider) {
        return this.#compile(this.#getExecutor(executorProvider));
      }
      async execute(executorProvider) {
        const executor = this.#getExecutor(executorProvider);
        return executor.executeQuery(this.#compile(executor), this.#props.queryId);
      }
      #getExecutor(executorProvider) {
        const executor = executorProvider !== void 0 ? executorProvider.getExecutor() : NOOP_QUERY_EXECUTOR;
        return this.#props.plugins !== void 0 ? executor.withPlugins(this.#props.plugins) : executor;
      }
      #toOperationNode(executor) {
        return executor.transformQuery(this.#props.rawNode, this.#props.queryId);
      }
      #compile(executor) {
        return executor.compileQuery(this.#toOperationNode(executor), this.#props.queryId);
      }
    };
    preventAwait(RawBuilderImpl, "don't await RawBuilder instances directly. To execute the query you need to call `execute`");
    AliasedRawBuilderImpl = class {
      #rawBuilder;
      #alias;
      constructor(rawBuilder, alias) {
        this.#rawBuilder = rawBuilder;
        this.#alias = alias;
      }
      get expression() {
        return this.#rawBuilder;
      }
      get alias() {
        return this.#alias;
      }
      get rawBuilder() {
        return this.#rawBuilder;
      }
      toOperationNode() {
        return AliasNode.create(this.#rawBuilder.toOperationNode(), isOperationNodeSource(this.#alias) ? this.#alias.toOperationNode() : IdentifierNode.create(this.#alias));
      }
    };
    preventAwait(AliasedRawBuilderImpl, "don't await AliasedRawBuilder instances directly. AliasedRawBuilder should never be executed directly since it's always a part of another query.");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/raw-builder/sql.js
function parseParameter(param) {
  if (isOperationNodeSource(param)) {
    return param.toOperationNode();
  }
  return parseValueExpression(param);
}
var sql;
var init_sql = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/raw-builder/sql.js"() {
    init_identifier_node();
    init_operation_node_source();
    init_raw_node();
    init_value_node();
    init_reference_parser();
    init_table_parser();
    init_value_parser();
    init_query_id();
    init_raw_builder();
    sql = Object.assign((sqlFragments, ...parameters) => {
      return createRawBuilder({
        queryId: createQueryId(),
        rawNode: RawNode.create(sqlFragments, parameters?.map(parseParameter) ?? [])
      });
    }, {
      ref(columnReference) {
        return createRawBuilder({
          queryId: createQueryId(),
          rawNode: RawNode.createWithChild(parseStringReference(columnReference))
        });
      },
      val(value2) {
        return createRawBuilder({
          queryId: createQueryId(),
          rawNode: RawNode.createWithChild(parseValueExpression(value2))
        });
      },
      value(value2) {
        return this.val(value2);
      },
      table(tableReference) {
        return createRawBuilder({
          queryId: createQueryId(),
          rawNode: RawNode.createWithChild(parseTable(tableReference))
        });
      },
      id(...ids) {
        const fragments = new Array(ids.length + 1).fill(".");
        fragments[0] = "";
        fragments[fragments.length - 1] = "";
        return createRawBuilder({
          queryId: createQueryId(),
          rawNode: RawNode.create(fragments, ids.map(IdentifierNode.create))
        });
      },
      lit(value2) {
        return createRawBuilder({
          queryId: createQueryId(),
          rawNode: RawNode.createWithChild(ValueNode.createImmediate(value2))
        });
      },
      literal(value2) {
        return this.lit(value2);
      },
      raw(sql2) {
        return createRawBuilder({
          queryId: createQueryId(),
          rawNode: RawNode.createWithSql(sql2)
        });
      },
      join(array2, separator = sql`, `) {
        const nodes = new Array(2 * array2.length - 1);
        const sep = separator.toOperationNode();
        for (let i = 0; i < array2.length; ++i) {
          nodes[2 * i] = parseParameter(array2[i]);
          if (i !== array2.length - 1) {
            nodes[2 * i + 1] = sep;
          }
        }
        return createRawBuilder({
          queryId: createQueryId(),
          rawNode: RawNode.createWithChildren(nodes)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-executor/query-executor.js
var init_query_executor = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-executor/query-executor.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-executor/query-executor-provider.js
var init_query_executor_provider = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-executor/query-executor-provider.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/operation-node-visitor.js
var OperationNodeVisitor;
var init_operation_node_visitor = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/operation-node-visitor.js"() {
    init_object_utils();
    OperationNodeVisitor = class {
      nodeStack = [];
      get parentNode() {
        return this.nodeStack[this.nodeStack.length - 2];
      }
      #visitors = freeze({
        AliasNode: this.visitAlias.bind(this),
        ColumnNode: this.visitColumn.bind(this),
        IdentifierNode: this.visitIdentifier.bind(this),
        SchemableIdentifierNode: this.visitSchemableIdentifier.bind(this),
        RawNode: this.visitRaw.bind(this),
        ReferenceNode: this.visitReference.bind(this),
        SelectQueryNode: this.visitSelectQuery.bind(this),
        SelectionNode: this.visitSelection.bind(this),
        TableNode: this.visitTable.bind(this),
        FromNode: this.visitFrom.bind(this),
        SelectAllNode: this.visitSelectAll.bind(this),
        AndNode: this.visitAnd.bind(this),
        OrNode: this.visitOr.bind(this),
        ValueNode: this.visitValue.bind(this),
        ValueListNode: this.visitValueList.bind(this),
        PrimitiveValueListNode: this.visitPrimitiveValueList.bind(this),
        ParensNode: this.visitParens.bind(this),
        JoinNode: this.visitJoin.bind(this),
        OperatorNode: this.visitOperator.bind(this),
        WhereNode: this.visitWhere.bind(this),
        InsertQueryNode: this.visitInsertQuery.bind(this),
        DeleteQueryNode: this.visitDeleteQuery.bind(this),
        ReturningNode: this.visitReturning.bind(this),
        CreateTableNode: this.visitCreateTable.bind(this),
        AddColumnNode: this.visitAddColumn.bind(this),
        ColumnDefinitionNode: this.visitColumnDefinition.bind(this),
        DropTableNode: this.visitDropTable.bind(this),
        DataTypeNode: this.visitDataType.bind(this),
        OrderByNode: this.visitOrderBy.bind(this),
        OrderByItemNode: this.visitOrderByItem.bind(this),
        GroupByNode: this.visitGroupBy.bind(this),
        GroupByItemNode: this.visitGroupByItem.bind(this),
        UpdateQueryNode: this.visitUpdateQuery.bind(this),
        ColumnUpdateNode: this.visitColumnUpdate.bind(this),
        LimitNode: this.visitLimit.bind(this),
        OffsetNode: this.visitOffset.bind(this),
        OnConflictNode: this.visitOnConflict.bind(this),
        OnDuplicateKeyNode: this.visitOnDuplicateKey.bind(this),
        CreateIndexNode: this.visitCreateIndex.bind(this),
        DropIndexNode: this.visitDropIndex.bind(this),
        ListNode: this.visitList.bind(this),
        PrimaryKeyConstraintNode: this.visitPrimaryKeyConstraint.bind(this),
        UniqueConstraintNode: this.visitUniqueConstraint.bind(this),
        ReferencesNode: this.visitReferences.bind(this),
        CheckConstraintNode: this.visitCheckConstraint.bind(this),
        WithNode: this.visitWith.bind(this),
        CommonTableExpressionNode: this.visitCommonTableExpression.bind(this),
        CommonTableExpressionNameNode: this.visitCommonTableExpressionName.bind(this),
        HavingNode: this.visitHaving.bind(this),
        CreateSchemaNode: this.visitCreateSchema.bind(this),
        DropSchemaNode: this.visitDropSchema.bind(this),
        AlterTableNode: this.visitAlterTable.bind(this),
        DropColumnNode: this.visitDropColumn.bind(this),
        RenameColumnNode: this.visitRenameColumn.bind(this),
        AlterColumnNode: this.visitAlterColumn.bind(this),
        ModifyColumnNode: this.visitModifyColumn.bind(this),
        AddConstraintNode: this.visitAddConstraint.bind(this),
        DropConstraintNode: this.visitDropConstraint.bind(this),
        ForeignKeyConstraintNode: this.visitForeignKeyConstraint.bind(this),
        CreateViewNode: this.visitCreateView.bind(this),
        DropViewNode: this.visitDropView.bind(this),
        GeneratedNode: this.visitGenerated.bind(this),
        DefaultValueNode: this.visitDefaultValue.bind(this),
        OnNode: this.visitOn.bind(this),
        ValuesNode: this.visitValues.bind(this),
        SelectModifierNode: this.visitSelectModifier.bind(this),
        CreateTypeNode: this.visitCreateType.bind(this),
        DropTypeNode: this.visitDropType.bind(this),
        ExplainNode: this.visitExplain.bind(this),
        DefaultInsertValueNode: this.visitDefaultInsertValue.bind(this),
        AggregateFunctionNode: this.visitAggregateFunction.bind(this),
        OverNode: this.visitOver.bind(this),
        PartitionByNode: this.visitPartitionBy.bind(this),
        PartitionByItemNode: this.visitPartitionByItem.bind(this),
        SetOperationNode: this.visitSetOperation.bind(this),
        BinaryOperationNode: this.visitBinaryOperation.bind(this),
        UnaryOperationNode: this.visitUnaryOperation.bind(this),
        UsingNode: this.visitUsing.bind(this),
        FunctionNode: this.visitFunction.bind(this),
        CaseNode: this.visitCase.bind(this),
        WhenNode: this.visitWhen.bind(this),
        JSONReferenceNode: this.visitJSONReference.bind(this),
        JSONPathNode: this.visitJSONPath.bind(this),
        JSONPathLegNode: this.visitJSONPathLeg.bind(this),
        JSONOperatorChainNode: this.visitJSONOperatorChain.bind(this),
        TupleNode: this.visitTuple.bind(this),
        MergeQueryNode: this.visitMergeQuery.bind(this),
        MatchedNode: this.visitMatched.bind(this),
        AddIndexNode: this.visitAddIndex.bind(this),
        CastNode: this.visitCast.bind(this),
        FetchNode: this.visitFetch.bind(this),
        TopNode: this.visitTop.bind(this),
        OutputNode: this.visitOutput.bind(this)
      });
      visitNode = (node) => {
        this.nodeStack.push(node);
        this.#visitors[node.kind](node);
        this.nodeStack.pop();
      };
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-compiler/default-query-compiler.js
var DefaultQueryCompiler, SELECT_MODIFIER_SQL, SELECT_MODIFIER_PRIORITY, JOIN_TYPE_SQL;
var init_default_query_compiler = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-compiler/default-query-compiler.js"() {
    init_create_table_node();
    init_insert_query_node();
    init_operation_node_visitor();
    init_operator_node();
    init_parens_node();
    init_query_node();
    init_object_utils();
    init_create_view_node();
    init_set_operation_node();
    init_merge_query_node();
    DefaultQueryCompiler = class extends OperationNodeVisitor {
      #sql = "";
      #parameters = [];
      get numParameters() {
        return this.#parameters.length;
      }
      compileQuery(node) {
        this.#sql = "";
        this.#parameters = [];
        this.nodeStack.splice(0, this.nodeStack.length);
        this.visitNode(node);
        return freeze({
          query: node,
          sql: this.getSql(),
          parameters: [...this.#parameters]
        });
      }
      getSql() {
        return this.#sql;
      }
      visitSelectQuery(node) {
        const wrapInParens = this.parentNode !== void 0 && !ParensNode.is(this.parentNode) && !InsertQueryNode.is(this.parentNode) && !CreateTableNode.is(this.parentNode) && !CreateViewNode.is(this.parentNode) && !SetOperationNode.is(this.parentNode);
        if (this.parentNode === void 0 && node.explain) {
          this.visitNode(node.explain);
          this.append(" ");
        }
        if (wrapInParens) {
          this.append("(");
        }
        if (node.with) {
          this.visitNode(node.with);
          this.append(" ");
        }
        this.append("select");
        if (node.distinctOn) {
          this.append(" ");
          this.compileDistinctOn(node.distinctOn);
        }
        if (node.frontModifiers?.length) {
          this.append(" ");
          this.compileList(node.frontModifiers, " ");
        }
        if (node.top) {
          this.append(" ");
          this.visitNode(node.top);
        }
        if (node.selections) {
          this.append(" ");
          this.compileList(node.selections);
        }
        if (node.from) {
          this.append(" ");
          this.visitNode(node.from);
        }
        if (node.joins) {
          this.append(" ");
          this.compileList(node.joins, " ");
        }
        if (node.where) {
          this.append(" ");
          this.visitNode(node.where);
        }
        if (node.groupBy) {
          this.append(" ");
          this.visitNode(node.groupBy);
        }
        if (node.having) {
          this.append(" ");
          this.visitNode(node.having);
        }
        if (node.setOperations) {
          this.append(" ");
          this.compileList(node.setOperations, " ");
        }
        if (node.orderBy) {
          this.append(" ");
          this.visitNode(node.orderBy);
        }
        if (node.limit) {
          this.append(" ");
          this.visitNode(node.limit);
        }
        if (node.offset) {
          this.append(" ");
          this.visitNode(node.offset);
        }
        if (node.fetch) {
          this.append(" ");
          this.visitNode(node.fetch);
        }
        if (node.endModifiers?.length) {
          this.append(" ");
          this.compileList(this.sortSelectModifiers([...node.endModifiers]), " ");
        }
        if (wrapInParens) {
          this.append(")");
        }
      }
      visitFrom(node) {
        this.append("from ");
        this.compileList(node.froms);
      }
      visitSelection(node) {
        this.visitNode(node.selection);
      }
      visitColumn(node) {
        this.visitNode(node.column);
      }
      compileDistinctOn(expressions) {
        this.append("distinct on (");
        this.compileList(expressions);
        this.append(")");
      }
      compileList(nodes, separator = ", ") {
        const lastIndex = nodes.length - 1;
        for (let i = 0; i <= lastIndex; i++) {
          this.visitNode(nodes[i]);
          if (i < lastIndex) {
            this.append(separator);
          }
        }
      }
      visitWhere(node) {
        this.append("where ");
        this.visitNode(node.where);
      }
      visitHaving(node) {
        this.append("having ");
        this.visitNode(node.having);
      }
      visitInsertQuery(node) {
        const rootQueryNode = this.nodeStack.find(QueryNode.is);
        const isSubQuery = rootQueryNode !== node;
        if (!isSubQuery && node.explain) {
          this.visitNode(node.explain);
          this.append(" ");
        }
        if (isSubQuery && !MergeQueryNode.is(rootQueryNode)) {
          this.append("(");
        }
        if (node.with) {
          this.visitNode(node.with);
          this.append(" ");
        }
        this.append(node.replace ? "replace" : "insert");
        if (node.ignore) {
          this.append(" ignore");
        }
        if (node.top) {
          this.append(" ");
          this.visitNode(node.top);
        }
        if (node.into) {
          this.append(" into ");
          this.visitNode(node.into);
        }
        if (node.columns) {
          this.append(" (");
          this.compileList(node.columns);
          this.append(")");
        }
        if (node.output) {
          this.append(" ");
          this.visitNode(node.output);
        }
        if (node.values) {
          this.append(" ");
          this.visitNode(node.values);
        }
        if (node.defaultValues) {
          this.append(" ");
          this.append("default values");
        }
        if (node.onConflict) {
          this.append(" ");
          this.visitNode(node.onConflict);
        }
        if (node.onDuplicateKey) {
          this.append(" ");
          this.visitNode(node.onDuplicateKey);
        }
        if (node.returning) {
          this.append(" ");
          this.visitNode(node.returning);
        }
        if (isSubQuery && !MergeQueryNode.is(rootQueryNode)) {
          this.append(")");
        }
        if (node.endModifiers?.length) {
          this.append(" ");
          this.compileList(node.endModifiers, " ");
        }
      }
      visitValues(node) {
        this.append("values ");
        this.compileList(node.values);
      }
      visitDeleteQuery(node) {
        const isSubQuery = this.nodeStack.find(QueryNode.is) !== node;
        if (!isSubQuery && node.explain) {
          this.visitNode(node.explain);
          this.append(" ");
        }
        if (isSubQuery) {
          this.append("(");
        }
        if (node.with) {
          this.visitNode(node.with);
          this.append(" ");
        }
        this.append("delete ");
        if (node.top) {
          this.visitNode(node.top);
          this.append(" ");
        }
        this.visitNode(node.from);
        if (node.output) {
          this.append(" ");
          this.visitNode(node.output);
        }
        if (node.using) {
          this.append(" ");
          this.visitNode(node.using);
        }
        if (node.joins) {
          this.append(" ");
          this.compileList(node.joins, " ");
        }
        if (node.where) {
          this.append(" ");
          this.visitNode(node.where);
        }
        if (node.orderBy) {
          this.append(" ");
          this.visitNode(node.orderBy);
        }
        if (node.limit) {
          this.append(" ");
          this.visitNode(node.limit);
        }
        if (node.returning) {
          this.append(" ");
          this.visitNode(node.returning);
        }
        if (isSubQuery) {
          this.append(")");
        }
        if (node.endModifiers?.length) {
          this.append(" ");
          this.compileList(node.endModifiers, " ");
        }
      }
      visitReturning(node) {
        this.append("returning ");
        this.compileList(node.selections);
      }
      visitAlias(node) {
        this.visitNode(node.node);
        this.append(" as ");
        this.visitNode(node.alias);
      }
      visitReference(node) {
        if (node.table) {
          this.visitNode(node.table);
          this.append(".");
        }
        this.visitNode(node.column);
      }
      visitSelectAll(_3) {
        this.append("*");
      }
      visitIdentifier(node) {
        this.append(this.getLeftIdentifierWrapper());
        this.compileUnwrappedIdentifier(node);
        this.append(this.getRightIdentifierWrapper());
      }
      compileUnwrappedIdentifier(node) {
        if (!isString(node.name)) {
          throw new Error("a non-string identifier was passed to compileUnwrappedIdentifier.");
        }
        this.append(this.sanitizeIdentifier(node.name));
      }
      visitAnd(node) {
        this.visitNode(node.left);
        this.append(" and ");
        this.visitNode(node.right);
      }
      visitOr(node) {
        this.visitNode(node.left);
        this.append(" or ");
        this.visitNode(node.right);
      }
      visitValue(node) {
        if (node.immediate) {
          this.appendImmediateValue(node.value);
        } else {
          this.appendValue(node.value);
        }
      }
      visitValueList(node) {
        this.append("(");
        this.compileList(node.values);
        this.append(")");
      }
      visitTuple(node) {
        this.append("(");
        this.compileList(node.values);
        this.append(")");
      }
      visitPrimitiveValueList(node) {
        this.append("(");
        const { values } = node;
        for (let i = 0; i < values.length; ++i) {
          this.appendValue(values[i]);
          if (i !== values.length - 1) {
            this.append(", ");
          }
        }
        this.append(")");
      }
      visitParens(node) {
        this.append("(");
        this.visitNode(node.node);
        this.append(")");
      }
      visitJoin(node) {
        this.append(JOIN_TYPE_SQL[node.joinType]);
        this.append(" ");
        this.visitNode(node.table);
        if (node.on) {
          this.append(" ");
          this.visitNode(node.on);
        }
      }
      visitOn(node) {
        this.append("on ");
        this.visitNode(node.on);
      }
      visitRaw(node) {
        const { sqlFragments, parameters: params } = node;
        for (let i = 0; i < sqlFragments.length; ++i) {
          this.append(sqlFragments[i]);
          if (params.length > i) {
            this.visitNode(params[i]);
          }
        }
      }
      visitOperator(node) {
        this.append(node.operator);
      }
      visitTable(node) {
        this.visitNode(node.table);
      }
      visitSchemableIdentifier(node) {
        if (node.schema) {
          this.visitNode(node.schema);
          this.append(".");
        }
        this.visitNode(node.identifier);
      }
      visitCreateTable(node) {
        this.append("create ");
        if (node.frontModifiers && node.frontModifiers.length > 0) {
          this.compileList(node.frontModifiers, " ");
          this.append(" ");
        }
        if (node.temporary) {
          this.append("temporary ");
        }
        this.append("table ");
        if (node.ifNotExists) {
          this.append("if not exists ");
        }
        this.visitNode(node.table);
        if (node.selectQuery) {
          this.append(" as ");
          this.visitNode(node.selectQuery);
        } else {
          this.append(" (");
          this.compileList([...node.columns, ...node.constraints ?? []]);
          this.append(")");
          if (node.onCommit) {
            this.append(" on commit ");
            this.append(node.onCommit);
          }
          if (node.endModifiers && node.endModifiers.length > 0) {
            this.append(" ");
            this.compileList(node.endModifiers, " ");
          }
        }
      }
      visitColumnDefinition(node) {
        if (node.ifNotExists) {
          this.append("if not exists ");
        }
        this.visitNode(node.column);
        this.append(" ");
        this.visitNode(node.dataType);
        if (node.unsigned) {
          this.append(" unsigned");
        }
        if (node.frontModifiers && node.frontModifiers.length > 0) {
          this.append(" ");
          this.compileList(node.frontModifiers, " ");
        }
        if (node.generated) {
          this.append(" ");
          this.visitNode(node.generated);
        }
        if (node.identity) {
          this.append(" identity");
        }
        if (node.defaultTo) {
          this.append(" ");
          this.visitNode(node.defaultTo);
        }
        if (node.notNull) {
          this.append(" not null");
        }
        if (node.unique) {
          this.append(" unique");
        }
        if (node.nullsNotDistinct) {
          this.append(" nulls not distinct");
        }
        if (node.primaryKey) {
          this.append(" primary key");
        }
        if (node.autoIncrement) {
          this.append(" ");
          this.append(this.getAutoIncrement());
        }
        if (node.references) {
          this.append(" ");
          this.visitNode(node.references);
        }
        if (node.check) {
          this.append(" ");
          this.visitNode(node.check);
        }
        if (node.endModifiers && node.endModifiers.length > 0) {
          this.append(" ");
          this.compileList(node.endModifiers, " ");
        }
      }
      getAutoIncrement() {
        return "auto_increment";
      }
      visitReferences(node) {
        this.append("references ");
        this.visitNode(node.table);
        this.append(" (");
        this.compileList(node.columns);
        this.append(")");
        if (node.onDelete) {
          this.append(" on delete ");
          this.append(node.onDelete);
        }
        if (node.onUpdate) {
          this.append(" on update ");
          this.append(node.onUpdate);
        }
      }
      visitDropTable(node) {
        this.append("drop table ");
        if (node.ifExists) {
          this.append("if exists ");
        }
        this.visitNode(node.table);
        if (node.cascade) {
          this.append(" cascade");
        }
      }
      visitDataType(node) {
        this.append(node.dataType);
      }
      visitOrderBy(node) {
        this.append("order by ");
        this.compileList(node.items);
      }
      visitOrderByItem(node) {
        this.visitNode(node.orderBy);
        if (node.direction) {
          this.append(" ");
          this.visitNode(node.direction);
        }
      }
      visitGroupBy(node) {
        this.append("group by ");
        this.compileList(node.items);
      }
      visitGroupByItem(node) {
        this.visitNode(node.groupBy);
      }
      visitUpdateQuery(node) {
        const rootQueryNode = this.nodeStack.find(QueryNode.is);
        const isSubQuery = rootQueryNode !== node;
        if (!isSubQuery && node.explain) {
          this.visitNode(node.explain);
          this.append(" ");
        }
        if (isSubQuery && !MergeQueryNode.is(rootQueryNode)) {
          this.append("(");
        }
        if (node.with) {
          this.visitNode(node.with);
          this.append(" ");
        }
        this.append("update ");
        if (node.top) {
          this.visitNode(node.top);
          this.append(" ");
        }
        if (node.table) {
          this.visitNode(node.table);
          this.append(" ");
        }
        this.append("set ");
        if (node.updates) {
          this.compileList(node.updates);
        }
        if (node.output) {
          this.append(" ");
          this.visitNode(node.output);
        }
        if (node.from) {
          this.append(" ");
          this.visitNode(node.from);
        }
        if (node.joins) {
          this.append(" ");
          this.compileList(node.joins, " ");
        }
        if (node.where) {
          this.append(" ");
          this.visitNode(node.where);
        }
        if (node.limit) {
          this.append(" ");
          this.visitNode(node.limit);
        }
        if (node.returning) {
          this.append(" ");
          this.visitNode(node.returning);
        }
        if (isSubQuery && !MergeQueryNode.is(rootQueryNode)) {
          this.append(")");
        }
        if (node.endModifiers?.length) {
          this.append(" ");
          this.compileList(node.endModifiers, " ");
        }
      }
      visitColumnUpdate(node) {
        this.visitNode(node.column);
        this.append(" = ");
        this.visitNode(node.value);
      }
      visitLimit(node) {
        this.append("limit ");
        this.visitNode(node.limit);
      }
      visitOffset(node) {
        this.append("offset ");
        this.visitNode(node.offset);
      }
      visitOnConflict(node) {
        this.append("on conflict");
        if (node.columns) {
          this.append(" (");
          this.compileList(node.columns);
          this.append(")");
        } else if (node.constraint) {
          this.append(" on constraint ");
          this.visitNode(node.constraint);
        } else if (node.indexExpression) {
          this.append(" (");
          this.visitNode(node.indexExpression);
          this.append(")");
        }
        if (node.indexWhere) {
          this.append(" ");
          this.visitNode(node.indexWhere);
        }
        if (node.doNothing === true) {
          this.append(" do nothing");
        } else if (node.updates) {
          this.append(" do update set ");
          this.compileList(node.updates);
          if (node.updateWhere) {
            this.append(" ");
            this.visitNode(node.updateWhere);
          }
        }
      }
      visitOnDuplicateKey(node) {
        this.append("on duplicate key update ");
        this.compileList(node.updates);
      }
      visitCreateIndex(node) {
        this.append("create ");
        if (node.unique) {
          this.append("unique ");
        }
        this.append("index ");
        if (node.ifNotExists) {
          this.append("if not exists ");
        }
        this.visitNode(node.name);
        if (node.table) {
          this.append(" on ");
          this.visitNode(node.table);
        }
        if (node.using) {
          this.append(" using ");
          this.visitNode(node.using);
        }
        if (node.columns) {
          this.append(" (");
          this.compileList(node.columns);
          this.append(")");
        }
        if (node.nullsNotDistinct) {
          this.append(" nulls not distinct");
        }
        if (node.where) {
          this.append(" ");
          this.visitNode(node.where);
        }
      }
      visitDropIndex(node) {
        this.append("drop index ");
        if (node.ifExists) {
          this.append("if exists ");
        }
        this.visitNode(node.name);
        if (node.table) {
          this.append(" on ");
          this.visitNode(node.table);
        }
        if (node.cascade) {
          this.append(" cascade");
        }
      }
      visitCreateSchema(node) {
        this.append("create schema ");
        if (node.ifNotExists) {
          this.append("if not exists ");
        }
        this.visitNode(node.schema);
      }
      visitDropSchema(node) {
        this.append("drop schema ");
        if (node.ifExists) {
          this.append("if exists ");
        }
        this.visitNode(node.schema);
        if (node.cascade) {
          this.append(" cascade");
        }
      }
      visitPrimaryKeyConstraint(node) {
        if (node.name) {
          this.append("constraint ");
          this.visitNode(node.name);
          this.append(" ");
        }
        this.append("primary key (");
        this.compileList(node.columns);
        this.append(")");
      }
      visitUniqueConstraint(node) {
        if (node.name) {
          this.append("constraint ");
          this.visitNode(node.name);
          this.append(" ");
        }
        this.append("unique");
        if (node.nullsNotDistinct) {
          this.append(" nulls not distinct");
        }
        this.append(" (");
        this.compileList(node.columns);
        this.append(")");
      }
      visitCheckConstraint(node) {
        if (node.name) {
          this.append("constraint ");
          this.visitNode(node.name);
          this.append(" ");
        }
        this.append("check (");
        this.visitNode(node.expression);
        this.append(")");
      }
      visitForeignKeyConstraint(node) {
        if (node.name) {
          this.append("constraint ");
          this.visitNode(node.name);
          this.append(" ");
        }
        this.append("foreign key (");
        this.compileList(node.columns);
        this.append(") ");
        this.visitNode(node.references);
        if (node.onDelete) {
          this.append(" on delete ");
          this.append(node.onDelete);
        }
        if (node.onUpdate) {
          this.append(" on update ");
          this.append(node.onUpdate);
        }
      }
      visitList(node) {
        this.compileList(node.items);
      }
      visitWith(node) {
        this.append("with ");
        if (node.recursive) {
          this.append("recursive ");
        }
        this.compileList(node.expressions);
      }
      visitCommonTableExpression(node) {
        this.visitNode(node.name);
        this.append(" as ");
        if (isBoolean(node.materialized)) {
          if (!node.materialized) {
            this.append("not ");
          }
          this.append("materialized ");
        }
        this.visitNode(node.expression);
      }
      visitCommonTableExpressionName(node) {
        this.visitNode(node.table);
        if (node.columns) {
          this.append("(");
          this.compileList(node.columns);
          this.append(")");
        }
      }
      visitAlterTable(node) {
        this.append("alter table ");
        this.visitNode(node.table);
        this.append(" ");
        if (node.renameTo) {
          this.append("rename to ");
          this.visitNode(node.renameTo);
        }
        if (node.setSchema) {
          this.append("set schema ");
          this.visitNode(node.setSchema);
        }
        if (node.addConstraint) {
          this.visitNode(node.addConstraint);
        }
        if (node.dropConstraint) {
          this.visitNode(node.dropConstraint);
        }
        if (node.columnAlterations) {
          this.compileColumnAlterations(node.columnAlterations);
        }
        if (node.addIndex) {
          this.visitNode(node.addIndex);
        }
        if (node.dropIndex) {
          this.visitNode(node.dropIndex);
        }
      }
      visitAddColumn(node) {
        this.append("add column ");
        this.visitNode(node.column);
      }
      visitRenameColumn(node) {
        this.append("rename column ");
        this.visitNode(node.column);
        this.append(" to ");
        this.visitNode(node.renameTo);
      }
      visitDropColumn(node) {
        this.append("drop column ");
        this.visitNode(node.column);
      }
      visitAlterColumn(node) {
        this.append("alter column ");
        this.visitNode(node.column);
        this.append(" ");
        if (node.dataType) {
          if (this.announcesNewColumnDataType()) {
            this.append("type ");
          }
          this.visitNode(node.dataType);
          if (node.dataTypeExpression) {
            this.append("using ");
            this.visitNode(node.dataTypeExpression);
          }
        }
        if (node.setDefault) {
          this.append("set default ");
          this.visitNode(node.setDefault);
        }
        if (node.dropDefault) {
          this.append("drop default");
        }
        if (node.setNotNull) {
          this.append("set not null");
        }
        if (node.dropNotNull) {
          this.append("drop not null");
        }
      }
      visitModifyColumn(node) {
        this.append("modify column ");
        this.visitNode(node.column);
      }
      visitAddConstraint(node) {
        this.append("add ");
        this.visitNode(node.constraint);
      }
      visitDropConstraint(node) {
        this.append("drop constraint ");
        if (node.ifExists) {
          this.append("if exists ");
        }
        this.visitNode(node.constraintName);
        if (node.modifier === "cascade") {
          this.append(" cascade");
        } else if (node.modifier === "restrict") {
          this.append(" restrict");
        }
      }
      visitSetOperation(node) {
        this.append(node.operator);
        this.append(" ");
        if (node.all) {
          this.append("all ");
        }
        this.visitNode(node.expression);
      }
      visitCreateView(node) {
        this.append("create ");
        if (node.orReplace) {
          this.append("or replace ");
        }
        if (node.materialized) {
          this.append("materialized ");
        }
        if (node.temporary) {
          this.append("temporary ");
        }
        this.append("view ");
        if (node.ifNotExists) {
          this.append("if not exists ");
        }
        this.visitNode(node.name);
        this.append(" ");
        if (node.columns) {
          this.append("(");
          this.compileList(node.columns);
          this.append(") ");
        }
        if (node.as) {
          this.append("as ");
          this.visitNode(node.as);
        }
      }
      visitDropView(node) {
        this.append("drop ");
        if (node.materialized) {
          this.append("materialized ");
        }
        this.append("view ");
        if (node.ifExists) {
          this.append("if exists ");
        }
        this.visitNode(node.name);
        if (node.cascade) {
          this.append(" cascade");
        }
      }
      visitGenerated(node) {
        this.append("generated ");
        if (node.always) {
          this.append("always ");
        }
        if (node.byDefault) {
          this.append("by default ");
        }
        this.append("as ");
        if (node.identity) {
          this.append("identity");
        }
        if (node.expression) {
          this.append("(");
          this.visitNode(node.expression);
          this.append(")");
        }
        if (node.stored) {
          this.append(" stored");
        }
      }
      visitDefaultValue(node) {
        this.append("default ");
        this.visitNode(node.defaultValue);
      }
      visitSelectModifier(node) {
        if (node.rawModifier) {
          this.visitNode(node.rawModifier);
        } else {
          this.append(SELECT_MODIFIER_SQL[node.modifier]);
        }
        if (node.of) {
          this.append(" of ");
          this.compileList(node.of, ", ");
        }
      }
      visitCreateType(node) {
        this.append("create type ");
        this.visitNode(node.name);
        if (node.enum) {
          this.append(" as enum ");
          this.visitNode(node.enum);
        }
      }
      visitDropType(node) {
        this.append("drop type ");
        if (node.ifExists) {
          this.append("if exists ");
        }
        this.visitNode(node.name);
      }
      visitExplain(node) {
        this.append("explain");
        if (node.options || node.format) {
          this.append(" ");
          this.append(this.getLeftExplainOptionsWrapper());
          if (node.options) {
            this.visitNode(node.options);
            if (node.format) {
              this.append(this.getExplainOptionsDelimiter());
            }
          }
          if (node.format) {
            this.append("format");
            this.append(this.getExplainOptionAssignment());
            this.append(node.format);
          }
          this.append(this.getRightExplainOptionsWrapper());
        }
      }
      visitDefaultInsertValue(_3) {
        this.append("default");
      }
      visitAggregateFunction(node) {
        this.append(node.func);
        this.append("(");
        if (node.distinct) {
          this.append("distinct ");
        }
        this.compileList(node.aggregated);
        if (node.orderBy) {
          this.append(" ");
          this.visitNode(node.orderBy);
        }
        this.append(")");
        if (node.filter) {
          this.append(" filter(");
          this.visitNode(node.filter);
          this.append(")");
        }
        if (node.over) {
          this.append(" ");
          this.visitNode(node.over);
        }
      }
      visitOver(node) {
        this.append("over(");
        if (node.partitionBy) {
          this.visitNode(node.partitionBy);
          if (node.orderBy) {
            this.append(" ");
          }
        }
        if (node.orderBy) {
          this.visitNode(node.orderBy);
        }
        this.append(")");
      }
      visitPartitionBy(node) {
        this.append("partition by ");
        this.compileList(node.items);
      }
      visitPartitionByItem(node) {
        this.visitNode(node.partitionBy);
      }
      visitBinaryOperation(node) {
        this.visitNode(node.leftOperand);
        this.append(" ");
        this.visitNode(node.operator);
        this.append(" ");
        this.visitNode(node.rightOperand);
      }
      visitUnaryOperation(node) {
        this.visitNode(node.operator);
        if (!this.isMinusOperator(node.operator)) {
          this.append(" ");
        }
        this.visitNode(node.operand);
      }
      isMinusOperator(node) {
        return OperatorNode.is(node) && node.operator === "-";
      }
      visitUsing(node) {
        this.append("using ");
        this.compileList(node.tables);
      }
      visitFunction(node) {
        this.append(node.func);
        this.append("(");
        this.compileList(node.arguments);
        this.append(")");
      }
      visitCase(node) {
        this.append("case");
        if (node.value) {
          this.append(" ");
          this.visitNode(node.value);
        }
        if (node.when) {
          this.append(" ");
          this.compileList(node.when, " ");
        }
        if (node.else) {
          this.append(" else ");
          this.visitNode(node.else);
        }
        this.append(" end");
        if (node.isStatement) {
          this.append(" case");
        }
      }
      visitWhen(node) {
        this.append("when ");
        this.visitNode(node.condition);
        if (node.result) {
          this.append(" then ");
          this.visitNode(node.result);
        }
      }
      visitJSONReference(node) {
        this.visitNode(node.reference);
        this.visitNode(node.traversal);
      }
      visitJSONPath(node) {
        if (node.inOperator) {
          this.visitNode(node.inOperator);
        }
        this.append("'$");
        for (const pathLeg of node.pathLegs) {
          this.visitNode(pathLeg);
        }
        this.append("'");
      }
      visitJSONPathLeg(node) {
        const isArrayLocation = node.type === "ArrayLocation";
        this.append(isArrayLocation ? "[" : ".");
        this.append(String(node.value));
        if (isArrayLocation) {
          this.append("]");
        }
      }
      visitJSONOperatorChain(node) {
        for (let i = 0, len = node.values.length; i < len; i++) {
          if (i === len - 1) {
            this.visitNode(node.operator);
          } else {
            this.append("->");
          }
          this.visitNode(node.values[i]);
        }
      }
      visitMergeQuery(node) {
        if (node.with) {
          this.visitNode(node.with);
          this.append(" ");
        }
        this.append("merge ");
        if (node.top) {
          this.visitNode(node.top);
          this.append(" ");
        }
        this.append("into ");
        this.visitNode(node.into);
        if (node.using) {
          this.append(" ");
          this.visitNode(node.using);
        }
        if (node.whens) {
          this.append(" ");
          this.compileList(node.whens, " ");
        }
        if (node.output) {
          this.append(" ");
          this.visitNode(node.output);
        }
        if (node.endModifiers?.length) {
          this.append(" ");
          this.compileList(node.endModifiers, " ");
        }
      }
      visitMatched(node) {
        if (node.not) {
          this.append("not ");
        }
        this.append("matched");
        if (node.bySource) {
          this.append(" by source");
        }
      }
      visitAddIndex(node) {
        this.append("add ");
        if (node.unique) {
          this.append("unique ");
        }
        this.append("index ");
        this.visitNode(node.name);
        if (node.columns) {
          this.append(" (");
          this.compileList(node.columns);
          this.append(")");
        }
        if (node.using) {
          this.append(" using ");
          this.visitNode(node.using);
        }
      }
      visitCast(node) {
        this.append("cast(");
        this.visitNode(node.expression);
        this.append(" as ");
        this.visitNode(node.dataType);
        this.append(")");
      }
      visitFetch(node) {
        this.append("fetch next ");
        this.visitNode(node.rowCount);
        this.append(` rows ${node.modifier}`);
      }
      visitOutput(node) {
        this.append("output ");
        this.compileList(node.selections);
      }
      visitTop(node) {
        this.append(`top(${node.expression})`);
        if (node.modifiers) {
          this.append(` ${node.modifiers}`);
        }
      }
      append(str2) {
        this.#sql += str2;
      }
      appendValue(parameter) {
        this.addParameter(parameter);
        this.append(this.getCurrentParameterPlaceholder());
      }
      getLeftIdentifierWrapper() {
        return '"';
      }
      getRightIdentifierWrapper() {
        return '"';
      }
      getCurrentParameterPlaceholder() {
        return "$" + this.numParameters;
      }
      getLeftExplainOptionsWrapper() {
        return "(";
      }
      getExplainOptionAssignment() {
        return " ";
      }
      getExplainOptionsDelimiter() {
        return ", ";
      }
      getRightExplainOptionsWrapper() {
        return ")";
      }
      sanitizeIdentifier(identifier) {
        const leftWrap = this.getLeftIdentifierWrapper();
        const rightWrap = this.getRightIdentifierWrapper();
        let sanitized = "";
        for (const c2 of identifier) {
          sanitized += c2;
          if (c2 === leftWrap) {
            sanitized += leftWrap;
          } else if (c2 === rightWrap) {
            sanitized += rightWrap;
          }
        }
        return sanitized;
      }
      addParameter(parameter) {
        this.#parameters.push(parameter);
      }
      appendImmediateValue(value2) {
        if (isString(value2)) {
          this.append(`'${value2}'`);
        } else if (isNumber(value2) || isBoolean(value2)) {
          this.append(value2.toString());
        } else if (isNull(value2)) {
          this.append("null");
        } else if (isDate(value2)) {
          this.appendImmediateValue(value2.toISOString());
        } else if (isBigInt(value2)) {
          this.appendImmediateValue(value2.toString());
        } else {
          throw new Error(`invalid immediate value ${value2}`);
        }
      }
      sortSelectModifiers(arr) {
        arr.sort((left, right) => left.modifier && right.modifier ? SELECT_MODIFIER_PRIORITY[left.modifier] - SELECT_MODIFIER_PRIORITY[right.modifier] : 1);
        return freeze(arr);
      }
      compileColumnAlterations(columnAlterations) {
        this.compileList(columnAlterations);
      }
      /**
       * controls whether the dialect adds a "type" keyword before a column's new data
       * type in an ALTER TABLE statement.
       */
      announcesNewColumnDataType() {
        return true;
      }
    };
    SELECT_MODIFIER_SQL = freeze({
      ForKeyShare: "for key share",
      ForNoKeyUpdate: "for no key update",
      ForUpdate: "for update",
      ForShare: "for share",
      NoWait: "nowait",
      SkipLocked: "skip locked",
      Distinct: "distinct"
    });
    SELECT_MODIFIER_PRIORITY = freeze({
      ForKeyShare: 1,
      ForNoKeyUpdate: 1,
      ForUpdate: 1,
      ForShare: 1,
      NoWait: 2,
      SkipLocked: 2,
      Distinct: 0
    });
    JOIN_TYPE_SQL = freeze({
      InnerJoin: "inner join",
      LeftJoin: "left join",
      RightJoin: "right join",
      FullJoin: "full join",
      LateralInnerJoin: "inner join lateral",
      LateralLeftJoin: "left join lateral",
      Using: "using"
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-compiler/compiled-query.js
var CompiledQuery;
var init_compiled_query = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-compiler/compiled-query.js"() {
    init_raw_node();
    init_object_utils();
    CompiledQuery = freeze({
      raw(sql2, parameters = []) {
        return freeze({
          sql: sql2,
          query: RawNode.createWithSql(sql2),
          parameters: freeze(parameters)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/database-connection.js
var init_database_connection = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/database-connection.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/connection-provider.js
var init_connection_provider = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/connection-provider.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/dummy-driver.js
var init_dummy_driver = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/driver/dummy-driver.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/dialect.js
var init_dialect = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/dialect.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/dialect-adapter.js
var init_dialect_adapter = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/dialect-adapter.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/dialect-adapter-base.js
var DialectAdapterBase;
var init_dialect_adapter_base = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/dialect-adapter-base.js"() {
    DialectAdapterBase = class {
      get supportsCreateIfNotExists() {
        return true;
      }
      get supportsTransactionalDdl() {
        return false;
      }
      get supportsReturning() {
        return false;
      }
      get supportsOutput() {
        return false;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/database-introspector.js
var init_database_introspector = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/database-introspector.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-driver.js
var init_sqlite_driver = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-driver.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-query-compiler.js
var ID_WRAP_REGEX, SqliteQueryCompiler;
var init_sqlite_query_compiler = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-query-compiler.js"() {
    init_default_query_compiler();
    ID_WRAP_REGEX = /"/g;
    SqliteQueryCompiler = class extends DefaultQueryCompiler {
      getCurrentParameterPlaceholder() {
        return "?";
      }
      getLeftExplainOptionsWrapper() {
        return "";
      }
      getRightExplainOptionsWrapper() {
        return "";
      }
      getLeftIdentifierWrapper() {
        return '"';
      }
      getRightIdentifierWrapper() {
        return '"';
      }
      getAutoIncrement() {
        return "autoincrement";
      }
      sanitizeIdentifier(identifier) {
        return identifier.replace(ID_WRAP_REGEX, '""');
      }
      visitDefaultInsertValue(_3) {
        this.append("null");
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/migration/migrator.js
var DEFAULT_MIGRATION_TABLE, DEFAULT_MIGRATION_LOCK_TABLE, NO_MIGRATIONS;
var init_migrator = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/migration/migrator.js"() {
    init_object_utils();
    DEFAULT_MIGRATION_TABLE = "kysely_migration";
    DEFAULT_MIGRATION_LOCK_TABLE = "kysely_migration_lock";
    NO_MIGRATIONS = freeze({ __noMigrations__: true });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-introspector.js
var SqliteIntrospector;
var init_sqlite_introspector = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-introspector.js"() {
    init_migrator();
    init_sql();
    SqliteIntrospector = class {
      #db;
      constructor(db2) {
        this.#db = db2;
      }
      async getSchemas() {
        return [];
      }
      async getTables(options2 = { withInternalKyselyTables: false }) {
        return await this.#getTableMetadata(options2);
      }
      async getMetadata(options2) {
        return {
          tables: await this.getTables(options2)
        };
      }
      #tablesQuery(qb, options2) {
        let tablesQuery = qb.selectFrom("sqlite_master").where("type", "in", ["table", "view"]).where("name", "not like", "sqlite_%").select(["name", "sql", "type"]).orderBy("name");
        if (!options2.withInternalKyselyTables) {
          tablesQuery = tablesQuery.where("name", "!=", DEFAULT_MIGRATION_TABLE).where("name", "!=", DEFAULT_MIGRATION_LOCK_TABLE);
        }
        return tablesQuery;
      }
      async #getTableMetadata(options2) {
        const tablesResult = await this.#tablesQuery(this.#db, options2).execute();
        const tableMetadata = await this.#db.with("table_list", (qb) => this.#tablesQuery(qb, options2)).selectFrom([
          "table_list as tl",
          sql`pragma_table_info(tl.name)`.as("p")
        ]).select([
          "tl.name as table",
          "p.cid",
          "p.name",
          "p.type",
          "p.notnull",
          "p.dflt_value",
          "p.pk"
        ]).orderBy(["tl.name", "p.cid"]).execute();
        const columnsByTable = {};
        for (const row of tableMetadata) {
          columnsByTable[row.table] ??= [];
          columnsByTable[row.table].push(row);
        }
        return tablesResult.map(({ name, sql: sql2, type }) => {
          let autoIncrementCol = sql2?.split(/[\(\),]/)?.find((it2) => it2.toLowerCase().includes("autoincrement"))?.trimStart()?.split(/\s+/)?.[0]?.replace(/["`]/g, "");
          const columns = columnsByTable[name] ?? [];
          if (!autoIncrementCol) {
            const pkCols = columns.filter((r2) => r2.pk > 0);
            if (pkCols.length === 1 && pkCols[0].type.toLowerCase() === "integer") {
              autoIncrementCol = pkCols[0].name;
            }
          }
          return {
            name,
            isView: type === "view",
            columns: columns.map((col) => ({
              name: col.name,
              dataType: col.type,
              isNullable: !col.notnull,
              isAutoIncrementing: col.name === autoIncrementCol,
              hasDefaultValue: col.dflt_value != null,
              comment: void 0
            }))
          };
        });
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-adapter.js
var SqliteAdapter;
var init_sqlite_adapter = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-adapter.js"() {
    init_dialect_adapter_base();
    SqliteAdapter = class extends DialectAdapterBase {
      get supportsTransactionalDdl() {
        return false;
      }
      get supportsReturning() {
        return true;
      }
      async acquireMigrationLock(_db, _opt) {
      }
      async releaseMigrationLock(_db, _opt) {
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-dialect.js
var init_sqlite_dialect = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-dialect.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-dialect-config.js
var init_sqlite_dialect_config = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/sqlite/sqlite-dialect-config.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-query-compiler.js
var init_postgres_query_compiler = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-query-compiler.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-introspector.js
var init_postgres_introspector = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-introspector.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-adapter.js
var LOCK_ID;
var init_postgres_adapter = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-adapter.js"() {
    LOCK_ID = BigInt("3853314791062309107");
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/stack-trace-utils.js
function extendStackTrace(err, stackError) {
  if (isStackHolder(err) && stackError.stack) {
    const stackExtension = stackError.stack.split("\n").slice(1).join("\n");
    err.stack += `
${stackExtension}`;
    return err;
  }
  return err;
}
function isStackHolder(obj) {
  return isObject2(obj) && isString(obj.stack);
}
var init_stack_trace_utils = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/stack-trace-utils.js"() {
    init_object_utils();
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-driver.js
function isOkPacket(obj) {
  return isObject2(obj) && "insertId" in obj && "affectedRows" in obj;
}
var PRIVATE_RELEASE_METHOD, MysqlConnection;
var init_mysql_driver = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-driver.js"() {
    init_object_utils();
    init_stack_trace_utils();
    PRIVATE_RELEASE_METHOD = /* @__PURE__ */ Symbol();
    MysqlConnection = class {
      #rawConnection;
      constructor(rawConnection) {
        this.#rawConnection = rawConnection;
      }
      async executeQuery(compiledQuery) {
        try {
          const result = await this.#executeQuery(compiledQuery);
          if (isOkPacket(result)) {
            const { insertId, affectedRows, changedRows } = result;
            const numAffectedRows = affectedRows !== void 0 && affectedRows !== null ? BigInt(affectedRows) : void 0;
            const numChangedRows = changedRows !== void 0 && changedRows !== null ? BigInt(changedRows) : void 0;
            return {
              insertId: insertId !== void 0 && insertId !== null && insertId.toString() !== "0" ? BigInt(insertId) : void 0,
              // TODO: remove.
              numUpdatedOrDeletedRows: numAffectedRows,
              numAffectedRows,
              numChangedRows,
              rows: []
            };
          } else if (Array.isArray(result)) {
            return {
              rows: result
            };
          }
          return {
            rows: []
          };
        } catch (err) {
          throw extendStackTrace(err, new Error());
        }
      }
      #executeQuery(compiledQuery) {
        return new Promise((resolve6, reject) => {
          this.#rawConnection.query(compiledQuery.sql, compiledQuery.parameters, (err, result) => {
            if (err) {
              reject(err);
            } else {
              resolve6(result);
            }
          });
        });
      }
      async *streamQuery(compiledQuery, _chunkSize) {
        const stream = this.#rawConnection.query(compiledQuery.sql, compiledQuery.parameters).stream({
          objectMode: true
        });
        try {
          for await (const row of stream) {
            yield {
              rows: [row]
            };
          }
        } catch (ex) {
          if (ex && typeof ex === "object" && "code" in ex && // @ts-ignore
          ex.code === "ERR_STREAM_PREMATURE_CLOSE") {
            return;
          }
          throw ex;
        }
      }
      [PRIVATE_RELEASE_METHOD]() {
        this.#rawConnection.release();
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-query-compiler.js
var init_mysql_query_compiler = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-query-compiler.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-introspector.js
var init_mysql_introspector = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-introspector.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-adapter.js
var LOCK_TIMEOUT_SECONDS;
var init_mysql_adapter = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-adapter.js"() {
    LOCK_TIMEOUT_SECONDS = 60 * 60;
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-dialect.js
var init_mysql_dialect = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-dialect.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-dialect-config.js
var init_mysql_dialect_config = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mysql/mysql-dialect-config.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-driver.js
var PRIVATE_RELEASE_METHOD2, PostgresConnection;
var init_postgres_driver = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-driver.js"() {
    init_stack_trace_utils();
    PRIVATE_RELEASE_METHOD2 = /* @__PURE__ */ Symbol();
    PostgresConnection = class {
      #client;
      #options;
      constructor(client2, options2) {
        this.#client = client2;
        this.#options = options2;
      }
      async executeQuery(compiledQuery) {
        try {
          const result = await this.#client.query(compiledQuery.sql, [
            ...compiledQuery.parameters
          ]);
          if (result.command === "INSERT" || result.command === "UPDATE" || result.command === "DELETE" || result.command === "MERGE") {
            const numAffectedRows = BigInt(result.rowCount);
            return {
              // TODO: remove.
              numUpdatedOrDeletedRows: numAffectedRows,
              numAffectedRows,
              rows: result.rows ?? []
            };
          }
          return {
            rows: result.rows ?? []
          };
        } catch (err) {
          throw extendStackTrace(err, new Error());
        }
      }
      async *streamQuery(compiledQuery, chunkSize) {
        if (!this.#options.cursor) {
          throw new Error("'cursor' is not present in your postgres dialect config. It's required to make streaming work in postgres.");
        }
        if (!Number.isInteger(chunkSize) || chunkSize <= 0) {
          throw new Error("chunkSize must be a positive integer");
        }
        const cursor = this.#client.query(new this.#options.cursor(compiledQuery.sql, compiledQuery.parameters.slice()));
        try {
          while (true) {
            const rows = await cursor.read(chunkSize);
            if (rows.length === 0) {
              break;
            }
            yield {
              rows
            };
          }
        } finally {
          await cursor.close();
        }
      }
      [PRIVATE_RELEASE_METHOD2]() {
        this.#client.release();
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect-config.js
var init_postgres_dialect_config = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect-config.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect.js
var init_postgres_dialect = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/postgres/postgres-dialect.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-adapter.js
var init_mssql_adapter = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-adapter.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-dialect-config.js
var init_mssql_dialect_config = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-dialect-config.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-driver.js
var PRIVATE_RELEASE_METHOD3, PRIVATE_DESTROY_METHOD, MssqlConnection, MssqlRequest;
var init_mssql_driver = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-driver.js"() {
    init_object_utils();
    init_compiled_query();
    init_stack_trace_utils();
    init_random_string();
    init_deferred();
    PRIVATE_RELEASE_METHOD3 = /* @__PURE__ */ Symbol();
    PRIVATE_DESTROY_METHOD = /* @__PURE__ */ Symbol();
    MssqlConnection = class {
      #connection;
      #tedious;
      constructor(connection, tedious) {
        this.#connection = connection;
        this.#tedious = tedious;
        this.#connection.on("error", console.error);
        this.#connection.once("end", () => {
          this.#connection.off("error", console.error);
        });
      }
      async beginTransaction(settings2) {
        const { isolationLevel } = settings2;
        await new Promise((resolve6, reject) => this.#connection.beginTransaction((error2) => {
          if (error2)
            reject(error2);
          else
            resolve6(void 0);
        }, isolationLevel ? randomString(8) : void 0, isolationLevel ? this.#getTediousIsolationLevel(isolationLevel) : void 0));
      }
      async commitTransaction() {
        await new Promise((resolve6, reject) => this.#connection.commitTransaction((error2) => {
          if (error2)
            reject(error2);
          else
            resolve6(void 0);
        }));
      }
      async connect() {
        await new Promise((resolve6, reject) => {
          this.#connection.connect((error2) => {
            if (error2) {
              console.error(error2);
              reject(error2);
            } else {
              resolve6(void 0);
            }
          });
        });
        return this;
      }
      async executeQuery(compiledQuery) {
        try {
          const deferred2 = new Deferred();
          const request = new MssqlRequest({
            compiledQuery,
            tedious: this.#tedious,
            onDone: deferred2
          });
          this.#connection.execSql(request.request);
          const { rowCount, rows } = await deferred2.promise;
          return {
            numAffectedRows: rowCount !== void 0 ? BigInt(rowCount) : void 0,
            rows
          };
        } catch (err) {
          throw extendStackTrace(err, new Error());
        }
      }
      async rollbackTransaction() {
        await new Promise((resolve6, reject) => this.#connection.rollbackTransaction((error2) => {
          if (error2)
            reject(error2);
          else
            resolve6(void 0);
        }));
      }
      async *streamQuery(compiledQuery, chunkSize) {
        if (!Number.isInteger(chunkSize) || chunkSize <= 0) {
          throw new Error("chunkSize must be a positive integer");
        }
        const request = new MssqlRequest({
          compiledQuery,
          streamChunkSize: chunkSize,
          tedious: this.#tedious
        });
        this.#connection.execSql(request.request);
        try {
          while (true) {
            const rows = await request.readChunk();
            if (rows.length === 0) {
              break;
            }
            yield { rows };
            if (rows.length < chunkSize) {
              break;
            }
          }
        } finally {
          await this.#cancelRequest(request);
        }
      }
      async validate() {
        try {
          const deferred2 = new Deferred();
          const request = new MssqlRequest({
            compiledQuery: CompiledQuery.raw("select 1"),
            onDone: deferred2,
            tedious: this.#tedious
          });
          this.#connection.execSql(request.request);
          await deferred2.promise;
          return true;
        } catch {
          return false;
        }
      }
      #getTediousIsolationLevel(isolationLevel) {
        const { ISOLATION_LEVEL } = this.#tedious;
        const mapper = {
          "read committed": ISOLATION_LEVEL.READ_COMMITTED,
          "read uncommitted": ISOLATION_LEVEL.READ_UNCOMMITTED,
          "repeatable read": ISOLATION_LEVEL.REPEATABLE_READ,
          serializable: ISOLATION_LEVEL.SERIALIZABLE,
          snapshot: ISOLATION_LEVEL.SNAPSHOT
        };
        const tediousIsolationLevel = mapper[isolationLevel];
        if (tediousIsolationLevel === void 0) {
          throw new Error(`Unknown isolation level: ${isolationLevel}`);
        }
        return tediousIsolationLevel;
      }
      #cancelRequest(request) {
        return new Promise((resolve6) => {
          request.request.once("requestCompleted", resolve6);
          const wasCanceled = this.#connection.cancel();
          if (!wasCanceled) {
            request.request.off("requestCompleted", resolve6);
            resolve6(void 0);
          }
        });
      }
      async [PRIVATE_RELEASE_METHOD3]() {
        if (this.#tedious.resetConnectionOnRelease !== false) {
          await new Promise((resolve6, reject) => {
            this.#connection.reset((error2) => {
              if (error2)
                reject(error2);
              else
                resolve6(void 0);
            });
          });
        }
      }
      [PRIVATE_DESTROY_METHOD]() {
        return new Promise((resolve6) => {
          this.#connection.once("end", () => {
            resolve6(void 0);
          });
          this.#connection.close();
        });
      }
    };
    MssqlRequest = class {
      #request;
      #rows;
      #streamChunkSize;
      #subscribers;
      #tedious;
      #error;
      #rowCount;
      constructor(props) {
        const { compiledQuery, onDone, streamChunkSize, tedious } = props;
        this.#rows = [];
        this.#streamChunkSize = streamChunkSize;
        this.#subscribers = {};
        this.#tedious = tedious;
        if (onDone) {
          const subscriptionKey = "onDone";
          this.#subscribers[subscriptionKey] = (event, error2) => {
            if (event === "chunkReady") {
              return;
            }
            delete this.#subscribers[subscriptionKey];
            if (event === "error") {
              onDone.reject(error2);
            } else {
              onDone.resolve({
                rowCount: this.#rowCount,
                rows: this.#rows
              });
            }
          };
        }
        this.#request = new this.#tedious.Request(compiledQuery.sql, (err, rowCount) => {
          if (err) {
            Object.values(this.#subscribers).forEach((subscriber) => subscriber("error", err instanceof AggregateError ? err.errors : err));
          } else {
            this.#rowCount = rowCount;
          }
        });
        this.#addParametersToRequest(compiledQuery.parameters);
        this.#attachListeners();
      }
      get request() {
        return this.#request;
      }
      readChunk() {
        const subscriptionKey = this.readChunk.name;
        return new Promise((resolve6, reject) => {
          this.#subscribers[subscriptionKey] = (event, error2) => {
            delete this.#subscribers[subscriptionKey];
            if (event === "error") {
              reject(error2);
            } else {
              resolve6(this.#rows.splice(0, this.#streamChunkSize));
            }
          };
          this.#request.resume();
        });
      }
      #addParametersToRequest(parameters) {
        for (let i = 0; i < parameters.length; i++) {
          const parameter = parameters[i];
          this.#request.addParameter(String(i + 1), this.#getTediousDataType(parameter), parameter);
        }
      }
      #attachListeners() {
        const pauseAndEmitChunkReady = this.#streamChunkSize ? () => {
          if (this.#streamChunkSize <= this.#rows.length) {
            this.#request.pause();
            Object.values(this.#subscribers).forEach((subscriber) => subscriber("chunkReady"));
          }
        } : () => {
        };
        const rowListener = (columns) => {
          const row = {};
          for (const column of columns) {
            row[column.metadata.colName] = column.value;
          }
          this.#rows.push(row);
          pauseAndEmitChunkReady();
        };
        this.#request.on("row", rowListener);
        this.#request.once("requestCompleted", () => {
          Object.values(this.#subscribers).forEach((subscriber) => subscriber("completed"));
          this.#request.off("row", rowListener);
        });
      }
      #getTediousDataType(value2) {
        if (isNull(value2) || isUndefined(value2) || isString(value2)) {
          return this.#tedious.TYPES.NVarChar;
        }
        if (isBigInt(value2) || isNumber(value2) && value2 % 1 === 0) {
          if (value2 < -2147483648 || value2 > 2147483647) {
            return this.#tedious.TYPES.BigInt;
          } else {
            return this.#tedious.TYPES.Int;
          }
        }
        if (isNumber(value2)) {
          return this.#tedious.TYPES.Float;
        }
        if (isBoolean(value2)) {
          return this.#tedious.TYPES.Bit;
        }
        if (isDate(value2)) {
          return this.#tedious.TYPES.DateTime;
        }
        if (isBuffer(value2)) {
          return this.#tedious.TYPES.VarBinary;
        }
        return this.#tedious.TYPES.NVarChar;
      }
    };
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-introspector.js
var init_mssql_introspector = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-introspector.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-query-compiler.js
var init_mssql_query_compiler = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-query-compiler.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-dialect.js
var init_mssql_dialect = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/dialect/mssql/mssql-dialect.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-compiler/query-compiler.js
var init_query_compiler = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/query-compiler/query-compiler.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/migration/file-migration-provider.js
var init_file_migration_provider = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/migration/file-migration-provider.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/kysely-plugin.js
var init_kysely_plugin = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/kysely-plugin.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/camel-case/camel-case-plugin.js
var init_camel_case_plugin = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/camel-case/camel-case-plugin.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.js
var init_deduplicate_joins_plugin = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/deduplicate-joins/deduplicate-joins-plugin.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/parse-json-results/parse-json-results-plugin.js
var init_parse_json_results_plugin = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/plugin/parse-json-results/parse-json-results-plugin.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/constraint-node.js
var init_constraint_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/constraint-node.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/list-node.js
var ListNode;
var init_list_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/list-node.js"() {
    init_object_utils();
    ListNode = freeze({
      is(node) {
        return node.kind === "ListNode";
      },
      create(items) {
        return freeze({
          kind: "ListNode",
          items: freeze(items)
        });
      }
    });
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/operation-node.js
var init_operation_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/operation-node.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/simple-reference-expression-node.js
var init_simple_reference_expression_node = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/operation-node/simple-reference-expression-node.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/column-type.js
var init_column_type = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/column-type.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/explainable.js
var init_explainable = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/explainable.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/streamable.js
var init_streamable = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/streamable.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/infer-result.js
var init_infer_result = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/util/infer-result.js"() {
  }
});

// node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/index.js
var init_esm = __esm({
  "node_modules/.deno/kysely@0.27.6/node_modules/kysely/dist/esm/index.js"() {
    init_kysely();
    init_query_creator();
    init_expression();
    init_expression_wrapper();
    init_where_interface();
    init_returning_interface();
    init_output_interface();
    init_having_interface();
    init_select_query_builder();
    init_insert_query_builder();
    init_update_query_builder();
    init_delete_query_builder();
    init_no_result_error();
    init_join_builder();
    init_function_module();
    init_insert_result();
    init_delete_result();
    init_update_result();
    init_on_conflict_builder();
    init_aggregate_function_builder();
    init_case_builder();
    init_json_path_builder();
    init_merge_query_builder();
    init_merge_result();
    init_raw_builder();
    init_sql();
    init_query_executor();
    init_default_query_executor();
    init_noop_query_executor();
    init_query_executor_provider();
    init_default_query_compiler();
    init_compiled_query();
    init_schema();
    init_create_table_builder();
    init_create_type_builder();
    init_drop_table_builder();
    init_drop_type_builder();
    init_create_index_builder();
    init_drop_index_builder();
    init_create_schema_builder();
    init_drop_schema_builder();
    init_column_definition_builder();
    init_foreign_key_constraint_builder();
    init_alter_table_builder();
    init_create_view_builder();
    init_drop_view_builder();
    init_alter_column_builder();
    init_dynamic();
    init_driver();
    init_database_connection();
    init_connection_provider();
    init_default_connection_provider();
    init_single_connection_provider();
    init_dummy_driver();
    init_dialect();
    init_dialect_adapter();
    init_dialect_adapter_base();
    init_database_introspector();
    init_sqlite_dialect();
    init_sqlite_dialect_config();
    init_sqlite_driver();
    init_postgres_query_compiler();
    init_postgres_introspector();
    init_postgres_adapter();
    init_mysql_dialect();
    init_mysql_dialect_config();
    init_mysql_driver();
    init_mysql_query_compiler();
    init_mysql_introspector();
    init_mysql_adapter();
    init_postgres_driver();
    init_postgres_dialect_config();
    init_postgres_dialect();
    init_sqlite_query_compiler();
    init_sqlite_introspector();
    init_sqlite_adapter();
    init_mssql_adapter();
    init_mssql_dialect_config();
    init_mssql_dialect();
    init_mssql_driver();
    init_mssql_introspector();
    init_mssql_query_compiler();
    init_default_query_compiler();
    init_query_compiler();
    init_migrator();
    init_file_migration_provider();
    init_kysely_plugin();
    init_camel_case_plugin();
    init_deduplicate_joins_plugin();
    init_with_schema_plugin();
    init_parse_json_results_plugin();
    init_add_column_node();
    init_add_constraint_node();
    init_add_index_node();
    init_aggregate_function_node();
    init_alias_node();
    init_alter_column_node();
    init_alter_table_node();
    init_and_node();
    init_binary_operation_node();
    init_case_node();
    init_cast_node();
    init_check_constraint_node();
    init_column_definition_node();
    init_column_node();
    init_column_update_node();
    init_common_table_expression_name_node();
    init_common_table_expression_node();
    init_constraint_node();
    init_create_index_node();
    init_create_schema_node();
    init_create_table_node();
    init_create_type_node();
    init_create_view_node();
    init_data_type_node();
    init_default_insert_value_node();
    init_default_value_node();
    init_delete_query_node();
    init_drop_column_node();
    init_drop_constraint_node();
    init_drop_index_node();
    init_drop_schema_node();
    init_drop_table_node();
    init_drop_type_node();
    init_drop_view_node();
    init_explain_node();
    init_fetch_node();
    init_foreign_key_constraint_node();
    init_from_node();
    init_function_node();
    init_generated_node();
    init_group_by_item_node();
    init_group_by_node();
    init_having_node();
    init_identifier_node();
    init_insert_query_node();
    init_join_node();
    init_json_operator_chain_node();
    init_json_path_leg_node();
    init_json_path_node();
    init_json_reference_node();
    init_limit_node();
    init_list_node();
    init_matched_node();
    init_merge_query_node();
    init_modify_column_node();
    init_offset_node();
    init_on_conflict_node();
    init_on_duplicate_key_node();
    init_on_node();
    init_operation_node_source();
    init_operation_node_transformer();
    init_operation_node_visitor();
    init_operation_node();
    init_operator_node();
    init_or_node();
    init_order_by_item_node();
    init_order_by_node();
    init_output_node();
    init_over_node();
    init_parens_node();
    init_partition_by_item_node();
    init_partition_by_node();
    init_primary_constraint_node();
    init_primitive_value_list_node();
    init_query_node();
    init_raw_node();
    init_reference_node();
    init_references_node();
    init_rename_column_node();
    init_returning_node();
    init_schemable_identifier_node();
    init_select_all_node();
    init_select_modifier_node();
    init_select_query_node();
    init_selection_node();
    init_set_operation_node();
    init_simple_reference_expression_node();
    init_table_node();
    init_top_node();
    init_tuple_node();
    init_unary_operation_node();
    init_unique_constraint_node();
    init_update_query_node();
    init_using_node();
    init_value_list_node();
    init_value_node();
    init_values_node();
    init_when_node();
    init_where_node();
    init_with_node();
    init_column_type();
    init_compilable();
    init_explainable();
    init_streamable();
    init_log();
    init_infer_result();
  }
});

// node_modules/.deno/marked@18.0.7/node_modules/marked/lib/marked.esm.js
function z() {
  return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
}
function N(l3) {
  T2 = l3;
}
function E2(l3) {
  let e = [];
  return (t2) => {
    let n = Math.max(0, Math.min(3, t2 - 1)), s3 = e[n];
    return s3 || (s3 = l3(n), e[n] = s3), s3;
  };
}
function d(l3, e = "") {
  let t2 = typeof l3 == "string" ? l3 : l3.source, n = { replace: (s3, r2) => {
    let i = typeof r2 == "string" ? r2 : r2.source;
    return i = i.replace(m2.caret, "$1"), t2 = t2.replace(s3, i), n;
  }, getRegex: () => new RegExp(t2, e) };
  return n;
}
function O2(l3, e) {
  if (e) {
    if (m2.escapeTest.test(l3)) return l3.replace(m2.escapeReplace, ge);
  } else if (m2.escapeTestNoEncode.test(l3)) return l3.replace(m2.escapeReplaceNoEncode, ge);
  return l3;
}
function V(l3) {
  try {
    l3 = encodeURI(l3).replace(m2.percentDecode, "%");
  } catch {
    return null;
  }
  return l3;
}
function Y(l3, e) {
  let t2 = l3.replace(m2.findPipe, (r2, i, o) => {
    let u = false, a2 = i;
    for (; --a2 >= 0 && o[a2] === "\\"; ) u = !u;
    return u ? "|" : " |";
  }), n = t2.split(m2.splitPipe), s3 = 0;
  if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
  else for (; n.length < e; ) n.push("");
  for (; s3 < n.length; s3++) n[s3] = n[s3].trim().replace(m2.slashPipe, "|");
  return n;
}
function $(l3, e, t2) {
  let n = l3.length;
  if (n === 0) return "";
  let s3 = 0;
  for (; s3 < n; ) {
    let r2 = l3.charAt(n - s3 - 1);
    if (r2 === e && !t2) s3++;
    else if (r2 !== e && t2) s3++;
    else break;
  }
  return l3.slice(0, n - s3);
}
function ee(l3) {
  let e = l3.split(`
`), t2 = e.length - 1;
  for (; t2 >= 0 && m2.blankLine.test(e[t2]); ) t2--;
  return e.length - t2 <= 2 ? l3 : e.slice(0, t2 + 1).join(`
`);
}
function fe(l3, e) {
  if (l3.indexOf(e[1]) === -1) return -1;
  let t2 = 0;
  for (let n = 0; n < l3.length; n++) if (l3[n] === "\\") n++;
  else if (l3[n] === e[0]) t2++;
  else if (l3[n] === e[1] && (t2--, t2 < 0)) return n;
  return t2 > 0 ? -2 : -1;
}
function me(l3, e = 0) {
  let t2 = e, n = "";
  for (let s3 of l3) if (s3 === "	") {
    let r2 = 4 - t2 % 4;
    n += " ".repeat(r2), t2 += r2;
  } else n += s3, t2++;
  return n;
}
function xe(l3, e, t2, n, s3) {
  let r2 = e.href, i = e.title || null, o = l3[1].replace(s3.other.outputLinkReplace, "$1");
  n.state.inLink = true;
  let u = { type: l3[0].charAt(0) === "!" ? "image" : "link", raw: t2, href: r2, title: i, text: o, tokens: n.inlineTokens(o) };
  return n.state.inLink = false, u;
}
function ot(l3, e, t2) {
  let n = l3.match(t2.other.indentCodeCompensation);
  if (n === null) return e;
  let s3 = n[1];
  return e.split(`
`).map((r2) => {
    let i = r2.match(t2.other.beginningSpace);
    if (i === null) return r2;
    let [o] = i;
    return o.length >= s3.length ? r2.slice(s3.length) : r2;
  }).join(`
`);
}
function g2(l3, e) {
  return M.parse(l3, e);
}
var T2, _2, Te, m2, Oe, we, ye, B, Pe, j, oe, ae, Se, F, $e, U, Le, _e, H, K, Me, le, ze, Ee, Ce, W2, se, Ae, Ie, Be, qe, ue, De, C2, Z, X, ve, pe, He, Ze, Ge, ce, Ne, Qe, he, je, Fe, Ue, Ke, We, Xe, Je, Ve, Ye, et, v2, tt, ke, de, nt, ie, J, rt, Q, st, q, A2, it, ge, w2, x2, y, L, b2, P2, D2, M, Kt, Wt, Xt, Jt, Vt, en, tn;
var init_marked_esm = __esm({
  "node_modules/.deno/marked@18.0.7/node_modules/marked/lib/marked.esm.js"() {
    T2 = z();
    _2 = { exec: () => null };
    Te = ((l3 = "") => {
      try {
        return !!new RegExp("(?<=1)(?<!1)" + l3);
      } catch {
        return false;
      }
    })();
    m2 = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (l3) => new RegExp(`^( {0,3}${l3})((?:[	 ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: E2((l3) => new RegExp(`^ {0,${l3}}(?:[*+-]|\\d{1,9}[.)])((?:[ 	][^\\n]*)?(?:\\n|$))`)), hrRegex: E2((l3) => new RegExp(`^ {0,${l3}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)), fencesBeginRegex: E2((l3) => new RegExp(`^ {0,${l3}}(?:\`\`\`|~~~)`)), headingBeginRegex: E2((l3) => new RegExp(`^ {0,${l3}}#`)), htmlBeginRegex: E2((l3) => new RegExp(`^ {0,${l3}}<(?:[a-z].*>|!--)`, "i")), blockquoteBeginRegex: E2((l3) => new RegExp(`^ {0,${l3}}>`)) };
    Oe = /^(?:[ \t]*(?:\n|$))+/;
    we = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
    ye = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
    B = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
    Pe = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/;
    j = / {0,3}(?:[*+-]|\d{1,9}[.)])/;
    oe = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/;
    ae = d(oe).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}(?:\s|$)/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex();
    Se = d(oe).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}(?:\s|$)/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex();
    F = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table|[ \t]+\n)[^\n]+)*)/;
    $e = /^[^\n]+/;
    U = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/;
    Le = d(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", U).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex();
    _e = d(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g, j).getRegex();
    H = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
    K = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
    Me = d("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n*|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>[^\\n]*\\n*|$)|<![A-Z][\\s\\S]*?(?:>[^\\n]*\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>[^\\n]*\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ 	]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ 	]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ 	]*)+\\n|$))", "i").replace("comment", K).replace("tag", H).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
    le = (l3) => d(F).replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~~~)[^\\n]*\\n").replace("list", l3).replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex();
    ze = le(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/);
    Ee = le(/ {0,3}(?:[*+-]|\d{1,9}[.)])(?:[ \t]|\n|$)/);
    Ce = d(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", Ee).getRegex();
    W2 = { blockquote: Ce, code: we, def: Le, fences: ye, heading: Pe, hr: B, html: Me, lheading: ae, list: _e, newline: Oe, paragraph: ze, table: _2, text: $e };
    se = d("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3}	)[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~~~)[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex();
    Ae = { ...W2, lheading: Se, table: se, paragraph: d(F).replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~~~)[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex() };
    Ie = { ...W2, html: d(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", K).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: _2, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: d(F).replace("hr", B).replace("heading", ` *#{1,6} *[^
]`).replace("lheading", ae).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
    Be = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
    qe = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
    ue = /^( {2,}|\\)\n(?!\s*$)/;
    De = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/;
    C2 = /[\p{P}\p{S}]/u;
    Z = /[\s\p{P}\p{S}]/u;
    X = /[^\s\p{P}\p{S}]/u;
    ve = d(/^((?![*_])punctSpace)/, "u").replace(/punctSpace/g, Z).getRegex();
    pe = /(?!~)[\p{P}\p{S}]/u;
    He = /(?!~)[\s\p{P}\p{S}]/u;
    Ze = /(?:[^\s\p{P}\p{S}]|~)/u;
    Ge = d(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", Te ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
    ce = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/;
    Ne = d(ce, "u").replace(/punct/g, C2).getRegex();
    Qe = d(ce, "u").replace(/punct/g, pe).getRegex();
    he = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)";
    je = d(he, "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, C2).getRegex();
    Fe = d(he, "gu").replace(/notPunctSpace/g, Ze).replace(/punctSpace/g, He).replace(/punct/g, pe).getRegex();
    Ue = d("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, C2).getRegex();
    Ke = d(/^~~?(?:((?!~)punct)|[^\s~])/, "u").replace(/punct/g, C2).getRegex();
    We = "^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)";
    Xe = d(We, "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, C2).getRegex();
    Je = d(/\\(punct)/, "gu").replace(/punct/g, C2).getRegex();
    Ve = d(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
    Ye = d(K).replace("(?:-->|$)", "-->").getRegex();
    et = d("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", Ye).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
    v2 = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/;
    tt = d(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", v2).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]+|(?=\))/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
    ke = d(/^!?\[(label)\]\[(ref)\]/).replace("label", v2).replace("ref", U).getRegex();
    de = d(/^!?\[(ref)\](?:\[\])?/).replace("ref", U).getRegex();
    nt = d("reflink|nolink(?!\\()", "g").replace("reflink", ke).replace("nolink", de).getRegex();
    ie = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
    J = { _backpedal: _2, anyPunctuation: Je, autolink: Ve, blockSkip: Ge, br: ue, code: qe, del: _2, delLDelim: _2, delRDelim: _2, emStrongLDelim: Ne, emStrongRDelimAst: je, emStrongRDelimUnd: Ue, escape: Be, link: tt, nolink: de, punctuation: ve, reflink: ke, reflinkSearch: nt, tag: et, text: De, url: _2 };
    rt = { ...J, link: d(/^!?\[(label)\]\((.*?)\)/).replace("label", v2).getRegex(), reflink: d(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", v2).getRegex() };
    Q = { ...J, emStrongRDelimAst: Fe, emStrongLDelim: Qe, delLDelim: Ke, delRDelim: Xe, url: d(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ie).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: d(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol", ie).getRegex() };
    st = { ...Q, br: d(ue).replace("{2,}", "*").getRegex(), text: d(Q.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
    q = { normal: W2, gfm: Ae, pedantic: Ie };
    A2 = { normal: J, gfm: Q, breaks: st, pedantic: rt };
    it = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" };
    ge = (l3) => it[l3];
    w2 = class {
      options;
      rules;
      lexer;
      constructor(e) {
        this.options = e || T2;
      }
      space(e) {
        let t2 = this.rules.block.newline.exec(e);
        if (t2 && t2[0].length > 0) return { type: "space", raw: t2[0] };
      }
      code(e) {
        let t2 = this.rules.block.code.exec(e);
        if (t2) {
          let n = this.options.pedantic ? t2[0] : ee(t2[0]), s3 = n.replace(this.rules.other.codeRemoveIndent, "");
          return { type: "code", raw: n, codeBlockStyle: "indented", text: s3 };
        }
      }
      fences(e) {
        let t2 = this.rules.block.fences.exec(e);
        if (t2) {
          let n = t2[0], s3 = ot(n, t2[3] || "", this.rules);
          return { type: "code", raw: n, lang: t2[2] ? t2[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t2[2], text: s3 };
        }
      }
      heading(e) {
        let t2 = this.rules.block.heading.exec(e);
        if (t2) {
          let n = t2[2].trim();
          if (this.rules.other.endingHash.test(n)) {
            let s3 = $(n, "#");
            (this.options.pedantic || !s3 || this.rules.other.endingSpaceChar.test(s3)) && (n = s3.trim());
          }
          return { type: "heading", raw: $(t2[0], `
`), depth: t2[1].length, text: n, tokens: this.lexer.inline(n) };
        }
      }
      hr(e) {
        let t2 = this.rules.block.hr.exec(e);
        if (t2) return { type: "hr", raw: $(t2[0], `
`) };
      }
      blockquote(e) {
        let t2 = this.rules.block.blockquote.exec(e);
        if (t2) {
          let n = $(t2[0], `
`).split(`
`), s3 = "", r2 = "", i = [];
          for (; n.length > 0; ) {
            let o = false, u = [], a2;
            for (a2 = 0; a2 < n.length; a2++) if (this.rules.other.blockquoteStart.test(n[a2])) u.push(n[a2]), o = true;
            else if (!o) u.push(n[a2]);
            else break;
            n = n.slice(a2);
            let p2 = u.join(`
`), c2 = p2.replace(this.rules.other.blockquoteSetextReplace, `
    $1`).replace(this.rules.other.blockquoteSetextReplace2, "");
            s3 = s3 ? `${s3}
${p2}` : p2, r2 = r2 ? `${r2}
${c2}` : c2;
            let h = this.lexer.state.top;
            if (this.lexer.state.top = true, this.lexer.blockTokens(c2, i, true), this.lexer.state.top = h, n.length === 0) break;
            let k2 = i.at(-1);
            if (k2?.type === "code") break;
            if (k2?.type === "blockquote") {
              let R2 = k2, f2 = R2.raw + `
` + n.join(`
`), S = this.blockquote(f2);
              i[i.length - 1] = S, s3 = s3.substring(0, s3.length - R2.raw.length) + S.raw, r2 = r2.substring(0, r2.length - R2.text.length) + S.text;
              break;
            } else if (k2?.type === "list") {
              let R2 = k2, f2 = R2.raw + `
` + n.join(`
`), S = this.list(f2);
              i[i.length - 1] = S, s3 = s3.substring(0, s3.length - k2.raw.length) + S.raw, r2 = r2.substring(0, r2.length - R2.raw.length) + S.raw, n = f2.substring(i.at(-1).raw.length).split(`
`);
              continue;
            }
          }
          return { type: "blockquote", raw: s3, tokens: i, text: r2 };
        }
      }
      list(e) {
        let t2 = this.rules.block.list.exec(e);
        if (t2) {
          let n = t2[1].trim(), s3 = n.length > 1, r2 = { type: "list", raw: "", ordered: s3, start: s3 ? +n.slice(0, -1) : "", loose: false, items: [] };
          n = s3 ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = s3 ? n : "[*+-]");
          let i = this.rules.other.listItemRegex(n), o = false;
          for (; e; ) {
            let a2 = false, p2 = "", c2 = "";
            if (!(t2 = i.exec(e)) || this.rules.block.hr.test(e)) break;
            p2 = t2[0], e = e.substring(p2.length);
            let h = me(t2[2].split(`
`, 1)[0], t2[1].length), k2 = e.split(`
`, 1)[0], R2 = !h.trim(), f2 = 0;
            if (this.options.pedantic ? (f2 = 2, c2 = h.trimStart()) : R2 ? f2 = t2[1].length + 1 : (f2 = h.search(this.rules.other.nonSpaceChar), f2 = f2 > 4 ? 1 : f2, c2 = h.slice(f2), f2 += t2[1].length), R2 && this.rules.other.blankLine.test(k2) && (p2 += k2 + `
`, e = e.substring(k2.length + 1), a2 = true), !a2) {
              let S = this.rules.other.nextBulletRegex(f2), te = this.rules.other.hrRegex(f2), ne = this.rules.other.fencesBeginRegex(f2), re = this.rules.other.headingBeginRegex(f2), be = this.rules.other.htmlBeginRegex(f2), Re = this.rules.other.blockquoteBeginRegex(f2);
              for (; e; ) {
                let G = e.split(`
`, 1)[0], I;
                if (k2 = G, this.options.pedantic ? (k2 = k2.replace(this.rules.other.listReplaceNesting, "  "), I = k2) : I = k2.replace(this.rules.other.tabCharGlobal, "    "), ne.test(k2) || re.test(k2) || be.test(k2) || Re.test(k2) || S.test(k2) || te.test(k2)) break;
                if (I.search(this.rules.other.nonSpaceChar) >= f2 || !k2.trim()) c2 += `
` + I.slice(f2);
                else {
                  if (R2 || h.replace(this.rules.other.tabCharGlobal, "    ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(h) || re.test(h) || te.test(h)) break;
                  c2 += `
` + k2;
                }
                R2 = !k2.trim(), p2 += G + `
`, e = e.substring(G.length + 1), h = I.slice(f2);
              }
            }
            r2.loose || (o ? r2.loose = true : this.rules.other.doubleBlankLine.test(p2) && (o = true)), r2.items.push({ type: "list_item", raw: p2, task: !!this.options.gfm && this.rules.other.listIsTask.test(c2), loose: false, text: c2, tokens: [] }), r2.raw += p2;
          }
          let u = r2.items.at(-1);
          if (u) u.raw = u.raw.trimEnd(), u.text = u.text.trimEnd();
          else return;
          r2.raw = r2.raw.trimEnd();
          for (let a2 of r2.items) {
            this.lexer.state.top = false, a2.tokens = this.lexer.blockTokens(a2.text, []);
            let p2 = a2.tokens[0];
            if (a2.task && (p2?.type === "text" || p2?.type === "paragraph")) {
              a2.text = a2.text.replace(this.rules.other.listReplaceTask, ""), p2.raw = p2.raw.replace(this.rules.other.listReplaceTask, ""), p2.text = p2.text.replace(this.rules.other.listReplaceTask, "");
              for (let h = this.lexer.inlineQueue.length - 1; h >= 0; h--) if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[h].src)) {
                this.lexer.inlineQueue[h].src = this.lexer.inlineQueue[h].src.replace(this.rules.other.listReplaceTask, "");
                break;
              }
              let c2 = this.rules.other.listTaskCheckbox.exec(a2.raw);
              if (c2) {
                let h = { type: "checkbox", raw: c2[0] + " ", checked: c2[0] !== "[ ]" };
                a2.checked = h.checked, r2.loose ? a2.tokens[0] && ["paragraph", "text"].includes(a2.tokens[0].type) && "tokens" in a2.tokens[0] && a2.tokens[0].tokens ? (a2.tokens[0].raw = h.raw + a2.tokens[0].raw, a2.tokens[0].text = h.raw + a2.tokens[0].text, a2.tokens[0].tokens.unshift(h)) : a2.tokens.unshift({ type: "paragraph", raw: h.raw, text: h.raw, tokens: [h] }) : a2.tokens.unshift(h);
              }
            } else a2.task && (a2.task = false);
            if (!r2.loose) {
              let c2 = a2.tokens.filter((k2) => k2.type === "space"), h = c2.length > 0 && c2.some((k2) => this.rules.other.anyLine.test(k2.raw));
              r2.loose = h;
            }
          }
          if (r2.loose) for (let a2 of r2.items) {
            a2.loose = true;
            for (let p2 of a2.tokens) p2.type === "text" && (p2.type = "paragraph");
          }
          return r2;
        }
      }
      html(e) {
        let t2 = this.rules.block.html.exec(e);
        if (t2) {
          let n = ee(t2[0]);
          return { type: "html", block: true, raw: n, pre: t2[1] === "pre" || t2[1] === "script" || t2[1] === "style", text: n };
        }
      }
      def(e) {
        let t2 = this.rules.block.def.exec(e);
        if (t2) {
          let n = t2[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), s3 = t2[2] ? t2[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", r2 = t2[3] ? t2[3].substring(1, t2[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t2[3];
          return { type: "def", tag: n, raw: $(t2[0], `
`), href: s3, title: r2 };
        }
      }
      table(e) {
        let t2 = this.rules.block.table.exec(e);
        if (!t2 || !this.rules.other.tableDelimiter.test(t2[2])) return;
        let n = Y(t2[1]), s3 = t2[2].replace(this.rules.other.tableAlignChars, "").split("|"), r2 = t2[3]?.trim() ? t2[3].replace(this.rules.other.tableRowBlankLine, "").split(`
`) : [], i = { type: "table", raw: $(t2[0], `
`), header: [], align: [], rows: [] };
        if (n.length === s3.length) {
          for (let o of s3) this.rules.other.tableAlignRight.test(o) ? i.align.push("right") : this.rules.other.tableAlignCenter.test(o) ? i.align.push("center") : this.rules.other.tableAlignLeft.test(o) ? i.align.push("left") : i.align.push(null);
          for (let o = 0; o < n.length; o++) i.header.push({ text: n[o], tokens: this.lexer.inline(n[o]), header: true, align: i.align[o] });
          for (let o of r2) i.rows.push(Y(o, i.header.length).map((u, a2) => ({ text: u, tokens: this.lexer.inline(u), header: false, align: i.align[a2] })));
          return i;
        }
      }
      lheading(e) {
        let t2 = this.rules.block.lheading.exec(e);
        if (t2) {
          let n = t2[1].trim();
          return { type: "heading", raw: $(t2[0], `
`), depth: t2[2].charAt(0) === "=" ? 1 : 2, text: n, tokens: this.lexer.inline(n) };
        }
      }
      paragraph(e) {
        let t2 = this.rules.block.paragraph.exec(e);
        if (t2) {
          let n = t2[1].charAt(t2[1].length - 1) === `
` ? t2[1].slice(0, -1) : t2[1];
          return { type: "paragraph", raw: t2[0], text: n, tokens: this.lexer.inline(n) };
        }
      }
      text(e) {
        let t2 = this.rules.block.text.exec(e);
        if (t2) return { type: "text", raw: t2[0], text: t2[0], tokens: this.lexer.inline(t2[0]) };
      }
      escape(e) {
        let t2 = this.rules.inline.escape.exec(e);
        if (t2) return { type: "escape", raw: t2[0], text: t2[1] };
      }
      tag(e) {
        let t2 = this.rules.inline.tag.exec(e);
        if (t2) return !this.lexer.state.inLink && this.rules.other.startATag.test(t2[0]) ? this.lexer.state.inLink = true : this.lexer.state.inLink && this.rules.other.endATag.test(t2[0]) && (this.lexer.state.inLink = false), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(t2[0]) ? this.lexer.state.inRawBlock = true : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(t2[0]) && (this.lexer.state.inRawBlock = false), { type: "html", raw: t2[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: false, text: t2[0] };
      }
      link(e) {
        let t2 = this.rules.inline.link.exec(e);
        if (t2) {
          let n = t2[2].trim();
          if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
            if (!this.rules.other.endAngleBracket.test(n)) return;
            let i = $(n.slice(0, -1), "\\");
            if ((n.length - i.length) % 2 === 0) return;
          } else {
            let i = fe(t2[2], "()");
            if (i === -2) return;
            if (i > -1) {
              let u = (t2[0].indexOf("!") === 0 ? 5 : 4) + t2[1].length + i;
              t2[2] = t2[2].substring(0, i), t2[0] = t2[0].substring(0, u).trim(), t2[3] = "";
            }
          }
          let s3 = t2[2], r2 = "";
          if (this.options.pedantic) {
            let i = this.rules.other.pedanticHrefTitle.exec(s3);
            i && (s3 = i[1], r2 = i[3]);
          } else r2 = t2[3] ? t2[3].slice(1, -1) : "";
          return s3 = s3.trim(), this.rules.other.startAngleBracket.test(s3) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? s3 = s3.slice(1) : s3 = s3.slice(1, -1)), xe(t2, { href: s3 && s3.replace(this.rules.inline.anyPunctuation, "$1"), title: r2 && r2.replace(this.rules.inline.anyPunctuation, "$1") }, t2[0], this.lexer, this.rules);
        }
      }
      reflink(e, t2) {
        let n;
        if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
          let s3 = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), r2 = t2[s3.toLowerCase()];
          if (!r2) {
            let i = n[0].charAt(0);
            return { type: "text", raw: i, text: i };
          }
          return xe(n, r2, n[0], this.lexer, this.rules);
        }
      }
      emStrong(e, t2, n = "") {
        let s3 = this.rules.inline.emStrongLDelim.exec(e);
        if (!s3 || !s3[1] && !s3[2] && !s3[3] && !s3[4] || s3[4] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
        if (!(s3[1] || s3[3] || "") || !n || this.rules.inline.punctuation.exec(n)) {
          let i = [...s3[0]].length - 1, o, u, a2 = i, p2 = 0, c2 = s3[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
          for (c2.lastIndex = 0, t2 = t2.slice(-1 * e.length + i); (s3 = c2.exec(t2)) !== null; ) {
            if (o = s3[1] || s3[2] || s3[3] || s3[4] || s3[5] || s3[6], !o) continue;
            if (u = [...o].length, s3[3] || s3[4]) {
              a2 += u;
              continue;
            } else if ((s3[5] || s3[6]) && i % 3 && !((i + u) % 3)) {
              p2 += u;
              continue;
            }
            if (a2 -= u, a2 > 0) continue;
            u = Math.min(u, u + a2 + p2);
            let h = [...s3[0]][0].length, k2 = e.slice(0, i + s3.index + h + u);
            if (Math.min(i, u) % 2) {
              let f2 = k2.slice(1, -1);
              return { type: "em", raw: k2, text: f2, tokens: this.lexer.inlineTokens(f2) };
            }
            let R2 = k2.slice(2, -2);
            return { type: "strong", raw: k2, text: R2, tokens: this.lexer.inlineTokens(R2) };
          }
        }
      }
      codespan(e) {
        let t2 = this.rules.inline.code.exec(e);
        if (t2) {
          let n = t2[2].replace(this.rules.other.newLineCharGlobal, " "), s3 = this.rules.other.nonSpaceChar.test(n), r2 = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n);
          return s3 && r2 && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t2[0], text: n };
        }
      }
      br(e) {
        let t2 = this.rules.inline.br.exec(e);
        if (t2) return { type: "br", raw: t2[0] };
      }
      del(e, t2, n = "") {
        let s3 = this.rules.inline.delLDelim.exec(e);
        if (!s3) return;
        if (!(s3[1] || "") || !n || this.rules.inline.punctuation.exec(n)) {
          let i = [...s3[0]].length - 1, o, u, a2 = i, p2 = this.rules.inline.delRDelim;
          for (p2.lastIndex = 0, t2 = t2.slice(-1 * e.length + i); (s3 = p2.exec(t2)) !== null; ) {
            if (o = s3[1] || s3[2] || s3[3] || s3[4] || s3[5] || s3[6], !o || (u = [...o].length, u !== i)) continue;
            if (s3[3] || s3[4]) {
              a2 += u;
              continue;
            }
            if (a2 -= u, a2 > 0) continue;
            u = Math.min(u, u + a2);
            let c2 = [...s3[0]][0].length, h = e.slice(0, i + s3.index + c2 + u), k2 = h.slice(i, -i);
            return { type: "del", raw: h, text: k2, tokens: this.lexer.inlineTokens(k2) };
          }
        }
      }
      autolink(e) {
        let t2 = this.rules.inline.autolink.exec(e);
        if (t2) {
          let n, s3;
          return t2[2] === "@" ? (n = t2[1], s3 = "mailto:" + n) : (n = t2[1], s3 = n), { type: "link", raw: t2[0], text: n, href: s3, tokens: [{ type: "text", raw: n, text: n }] };
        }
      }
      url(e) {
        let t2;
        if (t2 = this.rules.inline.url.exec(e)) {
          let n, s3;
          if (t2[2] === "@") n = t2[0], s3 = "mailto:" + n;
          else {
            let r2;
            do
              r2 = t2[0], t2[0] = this.rules.inline._backpedal.exec(t2[0])?.[0] ?? "";
            while (r2 !== t2[0]);
            n = t2[0], t2[1] === "www." ? s3 = "http://" + t2[0] : s3 = t2[0];
          }
          return { type: "link", raw: t2[0], text: n, href: s3, tokens: [{ type: "text", raw: n, text: n }] };
        }
      }
      inlineText(e) {
        let t2 = this.rules.inline.text.exec(e);
        if (t2) {
          let n = this.lexer.state.inRawBlock;
          return { type: "text", raw: t2[0], text: t2[0], escaped: n };
        }
      }
    };
    x2 = class l {
      tokens;
      options;
      state;
      inlineQueue;
      tokenizer;
      constructor(e) {
        this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || T2, this.options.tokenizer = this.options.tokenizer || new w2(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true };
        let t2 = { other: m2, block: q.normal, inline: A2.normal };
        this.options.pedantic ? (t2.block = q.pedantic, t2.inline = A2.pedantic) : this.options.gfm && (t2.block = q.gfm, this.options.breaks ? t2.inline = A2.breaks : t2.inline = A2.gfm), this.tokenizer.rules = t2;
      }
      static get rules() {
        return { block: q, inline: A2 };
      }
      static lex(e, t2) {
        return new l(t2).lex(e);
      }
      static lexInline(e, t2) {
        return new l(t2).inlineTokens(e);
      }
      lex(e) {
        e = e.replace(m2.carriageReturn, `
`), this.blockTokens(e, this.tokens);
        for (let t2 = 0; t2 < this.inlineQueue.length; t2++) {
          let n = this.inlineQueue[t2];
          this.inlineTokens(n.src, n.tokens);
        }
        return this.inlineQueue = [], this.tokens;
      }
      blockTokens(e, t2 = [], n = false) {
        this.tokenizer.lexer = this, this.options.pedantic && (e = e.replace(m2.tabCharGlobal, "    ").replace(m2.spaceLine, ""));
        let s3 = 1 / 0;
        for (; e; ) {
          if (e.length < s3) s3 = e.length;
          else {
            this.infiniteLoopError(e.charCodeAt(0));
            break;
          }
          let r2;
          if (this.options.extensions?.block?.some((o) => (r2 = o.call({ lexer: this }, e, t2)) ? (e = e.substring(r2.raw.length), t2.push(r2), true) : false)) continue;
          if (r2 = this.tokenizer.space(e)) {
            e = e.substring(r2.raw.length);
            let o = t2.at(-1);
            r2.raw.length === 1 && o !== void 0 ? o.raw += `
` : t2.push(r2);
            continue;
          }
          if (r2 = this.tokenizer.code(e)) {
            e = e.substring(r2.raw.length);
            let o = t2.at(-1);
            o?.type === "paragraph" || o?.type === "text" ? (o.raw += (o.raw.endsWith(`
`) ? "" : `
`) + r2.raw, o.text += `
` + r2.text, this.inlineQueue.at(-1).src = o.text) : t2.push(r2);
            continue;
          }
          if (r2 = this.tokenizer.fences(e)) {
            e = e.substring(r2.raw.length), t2.push(r2);
            continue;
          }
          if (r2 = this.tokenizer.heading(e)) {
            e = e.substring(r2.raw.length), t2.push(r2);
            continue;
          }
          if (r2 = this.tokenizer.hr(e)) {
            e = e.substring(r2.raw.length), t2.push(r2);
            continue;
          }
          if (r2 = this.tokenizer.blockquote(e)) {
            e = e.substring(r2.raw.length), t2.push(r2);
            continue;
          }
          if (r2 = this.tokenizer.list(e)) {
            e = e.substring(r2.raw.length), t2.push(r2);
            continue;
          }
          if (r2 = this.tokenizer.html(e)) {
            e = e.substring(r2.raw.length), t2.push(r2);
            continue;
          }
          if (r2 = this.tokenizer.def(e)) {
            e = e.substring(r2.raw.length);
            let o = t2.at(-1);
            o?.type === "paragraph" || o?.type === "text" ? (o.raw += (o.raw.endsWith(`
`) ? "" : `
`) + r2.raw, o.text += `
` + r2.raw, this.inlineQueue.at(-1).src = o.text) : this.tokens.links[r2.tag] || (this.tokens.links[r2.tag] = { href: r2.href, title: r2.title }, t2.push(r2));
            continue;
          }
          if (r2 = this.tokenizer.table(e)) {
            e = e.substring(r2.raw.length), t2.push(r2);
            continue;
          }
          if (r2 = this.tokenizer.lheading(e)) {
            e = e.substring(r2.raw.length), t2.push(r2);
            continue;
          }
          let i = e;
          if (this.options.extensions?.startBlock) {
            let o = 1 / 0, u = e.slice(1), a2;
            this.options.extensions.startBlock.forEach((p2) => {
              a2 = p2.call({ lexer: this }, u), typeof a2 == "number" && a2 >= 0 && (o = Math.min(o, a2));
            }), o < 1 / 0 && o >= 0 && (i = e.substring(0, o + 1));
          }
          if (this.state.top && (r2 = this.tokenizer.paragraph(i))) {
            let o = t2.at(-1);
            n && o?.type === "paragraph" ? (o.raw += (o.raw.endsWith(`
`) ? "" : `
`) + r2.raw, o.text += `
` + r2.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = o.text) : t2.push(r2), n = i.length !== e.length, e = e.substring(r2.raw.length);
            continue;
          }
          if (r2 = this.tokenizer.text(e)) {
            e = e.substring(r2.raw.length);
            let o = t2.at(-1);
            o?.type === "text" ? (o.raw += (o.raw.endsWith(`
`) ? "" : `
`) + r2.raw, o.text += `
` + r2.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = o.text) : t2.push(r2);
            continue;
          }
          if (e) {
            this.infiniteLoopError(e.charCodeAt(0));
            break;
          }
        }
        return this.state.top = true, t2;
      }
      inline(e, t2 = []) {
        return this.inlineQueue.push({ src: e, tokens: t2 }), t2;
      }
      inlineTokens(e, t2 = []) {
        this.tokenizer.lexer = this;
        let n = e;
        if (this.tokens.links) {
          let o = Object.keys(this.tokens.links);
          o.length > 0 && (n = n.replace(this.tokenizer.rules.inline.reflinkSearch, (u) => o.includes(u.slice(u.lastIndexOf("[") + 1, -1)) ? "[" + "a".repeat(u.length - 2) + "]" : u));
        }
        n = n.replace(this.tokenizer.rules.inline.anyPunctuation, "++"), n = n.replace(this.tokenizer.rules.inline.blockSkip, (o, u, a2) => {
          let p2 = a2 ? a2.length : 0;
          return o.slice(0, p2) + "[" + "a".repeat(o.length - p2 - 2) + "]";
        }), n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
        let s3 = false, r2 = "", i = 1 / 0;
        for (; e; ) {
          if (e.length < i) i = e.length;
          else {
            this.infiniteLoopError(e.charCodeAt(0));
            break;
          }
          s3 || (r2 = ""), s3 = false;
          let o;
          if (this.options.extensions?.inline?.some((a2) => (o = a2.call({ lexer: this }, e, t2)) ? (e = e.substring(o.raw.length), t2.push(o), true) : false)) continue;
          if (o = this.tokenizer.escape(e)) {
            e = e.substring(o.raw.length), t2.push(o);
            continue;
          }
          if (o = this.tokenizer.tag(e)) {
            e = e.substring(o.raw.length), t2.push(o);
            continue;
          }
          if (o = this.tokenizer.link(e)) {
            e = e.substring(o.raw.length), t2.push(o);
            continue;
          }
          if (o = this.tokenizer.reflink(e, this.tokens.links)) {
            e = e.substring(o.raw.length);
            let a2 = t2.at(-1);
            o.type === "text" && a2?.type === "text" ? (a2.raw += o.raw, a2.text += o.text) : t2.push(o);
            continue;
          }
          if (o = this.tokenizer.emStrong(e, n, r2)) {
            e = e.substring(o.raw.length), t2.push(o);
            continue;
          }
          if (o = this.tokenizer.codespan(e)) {
            e = e.substring(o.raw.length), t2.push(o);
            continue;
          }
          if (o = this.tokenizer.br(e)) {
            e = e.substring(o.raw.length), t2.push(o);
            continue;
          }
          if (o = this.tokenizer.del(e, n, r2)) {
            e = e.substring(o.raw.length), t2.push(o);
            continue;
          }
          if (o = this.tokenizer.autolink(e)) {
            e = e.substring(o.raw.length), t2.push(o);
            continue;
          }
          if (!this.state.inLink && (o = this.tokenizer.url(e))) {
            e = e.substring(o.raw.length), t2.push(o);
            continue;
          }
          let u = e;
          if (this.options.extensions?.startInline) {
            let a2 = 1 / 0, p2 = e.slice(1), c2;
            this.options.extensions.startInline.forEach((h) => {
              c2 = h.call({ lexer: this }, p2), typeof c2 == "number" && c2 >= 0 && (a2 = Math.min(a2, c2));
            }), a2 < 1 / 0 && a2 >= 0 && (u = e.substring(0, a2 + 1));
          }
          if (o = this.tokenizer.inlineText(u)) {
            e = e.substring(o.raw.length), o.raw.slice(-1) !== "_" && (r2 = o.raw.slice(-1)), s3 = true;
            let a2 = t2.at(-1);
            a2?.type === "text" ? (a2.raw += o.raw, a2.text += o.text) : t2.push(o);
            continue;
          }
          if (e) {
            this.infiniteLoopError(e.charCodeAt(0));
            break;
          }
        }
        return t2;
      }
      infiniteLoopError(e) {
        let t2 = "Infinite loop on byte: " + e;
        if (this.options.silent) console.error(t2);
        else throw new Error(t2);
      }
    };
    y = class {
      options;
      parser;
      constructor(e) {
        this.options = e || T2;
      }
      space(e) {
        return "";
      }
      code({ text: e, lang: t2, escaped: n }) {
        let s3 = (t2 || "").match(m2.notSpaceStart)?.[0], r2 = e.replace(m2.endingNewline, "") + `
`;
        return s3 ? '<pre><code class="language-' + O2(s3) + '">' + (n ? r2 : O2(r2, true)) + `</code></pre>
` : "<pre><code>" + (n ? r2 : O2(r2, true)) + `</code></pre>
`;
      }
      blockquote({ tokens: e }) {
        return `<blockquote>
${this.parser.parse(e)}</blockquote>
`;
      }
      html({ text: e }) {
        return e;
      }
      def(e) {
        return "";
      }
      heading({ tokens: e, depth: t2 }) {
        return `<h${t2}>${this.parser.parseInline(e)}</h${t2}>
`;
      }
      hr(e) {
        return `<hr>
`;
      }
      list(e) {
        let t2 = e.ordered, n = e.start, s3 = "";
        for (let o = 0; o < e.items.length; o++) {
          let u = e.items[o];
          s3 += this.listitem(u);
        }
        let r2 = t2 ? "ol" : "ul", i = t2 && n !== 1 ? ' start="' + n + '"' : "";
        return "<" + r2 + i + `>
` + s3 + "</" + r2 + `>
`;
      }
      listitem(e) {
        return `<li>${this.parser.parse(e.tokens)}</li>
`;
      }
      checkbox({ checked: e }) {
        return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox"> ';
      }
      paragraph({ tokens: e }) {
        return `<p>${this.parser.parseInline(e)}</p>
`;
      }
      table(e) {
        let t2 = "", n = "";
        for (let r2 = 0; r2 < e.header.length; r2++) n += this.tablecell(e.header[r2]);
        t2 += this.tablerow({ text: n });
        let s3 = "";
        for (let r2 = 0; r2 < e.rows.length; r2++) {
          let i = e.rows[r2];
          n = "";
          for (let o = 0; o < i.length; o++) n += this.tablecell(i[o]);
          s3 += this.tablerow({ text: n });
        }
        return s3 && (s3 = `<tbody>${s3}</tbody>`), `<table>
<thead>
` + t2 + `</thead>
` + s3 + `</table>
`;
      }
      tablerow({ text: e }) {
        return `<tr>
${e}</tr>
`;
      }
      tablecell(e) {
        let t2 = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td";
        return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t2 + `</${n}>
`;
      }
      strong({ tokens: e }) {
        return `<strong>${this.parser.parseInline(e)}</strong>`;
      }
      em({ tokens: e }) {
        return `<em>${this.parser.parseInline(e)}</em>`;
      }
      codespan({ text: e }) {
        return `<code>${O2(e, true)}</code>`;
      }
      br(e) {
        return "<br>";
      }
      del({ tokens: e }) {
        return `<del>${this.parser.parseInline(e)}</del>`;
      }
      link({ href: e, title: t2, tokens: n }) {
        let s3 = this.parser.parseInline(n), r2 = V(e);
        if (r2 === null) return s3;
        e = r2;
        let i = '<a href="' + e + '"';
        return t2 && (i += ' title="' + O2(t2) + '"'), i += ">" + s3 + "</a>", i;
      }
      image({ href: e, title: t2, text: n, tokens: s3 }) {
        s3 && (n = this.parser.parseInline(s3, this.parser.textRenderer));
        let r2 = V(e);
        if (r2 === null) return O2(n);
        e = r2;
        let i = `<img src="${e}" alt="${O2(n)}"`;
        return t2 && (i += ` title="${O2(t2)}"`), i += ">", i;
      }
      text(e) {
        return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : O2(e.text);
      }
    };
    L = class {
      strong({ text: e }) {
        return e;
      }
      em({ text: e }) {
        return e;
      }
      codespan({ text: e }) {
        return e;
      }
      del({ text: e }) {
        return e;
      }
      html({ text: e }) {
        return e;
      }
      text({ text: e }) {
        return e;
      }
      link({ text: e }) {
        return "" + e;
      }
      image({ text: e }) {
        return "" + e;
      }
      br() {
        return "";
      }
      checkbox({ raw: e }) {
        return e;
      }
    };
    b2 = class l2 {
      options;
      renderer;
      textRenderer;
      constructor(e) {
        this.options = e || T2, this.options.renderer = this.options.renderer || new y(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new L();
      }
      static parse(e, t2) {
        return new l2(t2).parse(e);
      }
      static parseInline(e, t2) {
        return new l2(t2).parseInline(e);
      }
      parse(e) {
        this.renderer.parser = this;
        let t2 = "";
        for (let n = 0; n < e.length; n++) {
          let s3 = e[n];
          if (this.options.extensions?.renderers?.[s3.type]) {
            let i = s3, o = this.options.extensions.renderers[i.type].call({ parser: this }, i);
            if (o !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "html", "def", "paragraph", "text"].includes(i.type)) {
              t2 += o || "";
              continue;
            }
          }
          let r2 = s3;
          switch (r2.type) {
            case "space": {
              t2 += this.renderer.space(r2);
              break;
            }
            case "hr": {
              t2 += this.renderer.hr(r2);
              break;
            }
            case "heading": {
              t2 += this.renderer.heading(r2);
              break;
            }
            case "code": {
              t2 += this.renderer.code(r2);
              break;
            }
            case "table": {
              t2 += this.renderer.table(r2);
              break;
            }
            case "blockquote": {
              t2 += this.renderer.blockquote(r2);
              break;
            }
            case "list": {
              t2 += this.renderer.list(r2);
              break;
            }
            case "checkbox": {
              t2 += this.renderer.checkbox(r2);
              break;
            }
            case "html": {
              t2 += this.renderer.html(r2);
              break;
            }
            case "def": {
              t2 += this.renderer.def(r2);
              break;
            }
            case "paragraph": {
              t2 += this.renderer.paragraph(r2);
              break;
            }
            case "text": {
              t2 += this.renderer.text(r2);
              break;
            }
            default: {
              let i = 'Token with "' + r2.type + '" type was not found.';
              if (this.options.silent) return console.error(i), "";
              throw new Error(i);
            }
          }
        }
        return t2;
      }
      parseInline(e, t2 = this.renderer) {
        this.renderer.parser = this;
        let n = "";
        for (let s3 = 0; s3 < e.length; s3++) {
          let r2 = e[s3];
          if (this.options.extensions?.renderers?.[r2.type]) {
            let o = this.options.extensions.renderers[r2.type].call({ parser: this }, r2);
            if (o !== false || !["escape", "html", "link", "image", "strong", "em", "codespan", "br", "del", "text"].includes(r2.type)) {
              n += o || "";
              continue;
            }
          }
          let i = r2;
          switch (i.type) {
            case "escape": {
              n += t2.text(i);
              break;
            }
            case "html": {
              n += t2.html(i);
              break;
            }
            case "link": {
              n += t2.link(i);
              break;
            }
            case "image": {
              n += t2.image(i);
              break;
            }
            case "checkbox": {
              n += t2.checkbox(i);
              break;
            }
            case "strong": {
              n += t2.strong(i);
              break;
            }
            case "em": {
              n += t2.em(i);
              break;
            }
            case "codespan": {
              n += t2.codespan(i);
              break;
            }
            case "br": {
              n += t2.br(i);
              break;
            }
            case "del": {
              n += t2.del(i);
              break;
            }
            case "text": {
              n += t2.text(i);
              break;
            }
            default: {
              let o = 'Token with "' + i.type + '" type was not found.';
              if (this.options.silent) return console.error(o), "";
              throw new Error(o);
            }
          }
        }
        return n;
      }
    };
    P2 = class {
      options;
      block;
      constructor(e) {
        this.options = e || T2;
      }
      static passThroughHooks = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens", "emStrongMask"]);
      static passThroughHooksRespectAsync = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"]);
      preprocess(e) {
        return e;
      }
      postprocess(e) {
        return e;
      }
      processAllTokens(e) {
        return e;
      }
      emStrongMask(e) {
        return e;
      }
      provideLexer(e = this.block) {
        return e ? x2.lex : x2.lexInline;
      }
      provideParser(e = this.block) {
        return e ? b2.parse : b2.parseInline;
      }
    };
    D2 = class {
      defaults = z();
      options = this.setOptions;
      parse = this.parseMarkdown(true);
      parseInline = this.parseMarkdown(false);
      Parser = b2;
      Renderer = y;
      TextRenderer = L;
      Lexer = x2;
      Tokenizer = w2;
      Hooks = P2;
      constructor(...e) {
        this.use(...e);
      }
      walkTokens(e, t2) {
        let n = [];
        for (let s3 of e) switch (n = n.concat(t2.call(this, s3)), s3.type) {
          case "table": {
            let r2 = s3;
            for (let i of r2.header) n = n.concat(this.walkTokens(i.tokens, t2));
            for (let i of r2.rows) for (let o of i) n = n.concat(this.walkTokens(o.tokens, t2));
            break;
          }
          case "list": {
            let r2 = s3;
            n = n.concat(this.walkTokens(r2.items, t2));
            break;
          }
          default: {
            let r2 = s3;
            this.defaults.extensions?.childTokens?.[r2.type] ? this.defaults.extensions.childTokens[r2.type].forEach((i) => {
              let o = r2[i].flat(1 / 0);
              n = n.concat(this.walkTokens(o, t2));
            }) : r2.tokens && (n = n.concat(this.walkTokens(r2.tokens, t2)));
          }
        }
        return n;
      }
      use(...e) {
        let t2 = this.defaults.extensions || { renderers: {}, childTokens: {} };
        return e.forEach((n) => {
          let s3 = { ...n };
          if (s3.async = this.defaults.async || s3.async || false, n.extensions && (n.extensions.forEach((r2) => {
            if (!r2.name) throw new Error("extension name required");
            if ("renderer" in r2) {
              let i = t2.renderers[r2.name];
              i ? t2.renderers[r2.name] = function(...o) {
                let u = r2.renderer.apply(this, o);
                return u === false && (u = i.apply(this, o)), u;
              } : t2.renderers[r2.name] = r2.renderer;
            }
            if ("tokenizer" in r2) {
              if (!r2.level || r2.level !== "block" && r2.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
              let i = t2[r2.level];
              i ? i.unshift(r2.tokenizer) : t2[r2.level] = [r2.tokenizer], r2.start && (r2.level === "block" ? t2.startBlock ? t2.startBlock.push(r2.start) : t2.startBlock = [r2.start] : r2.level === "inline" && (t2.startInline ? t2.startInline.push(r2.start) : t2.startInline = [r2.start]));
            }
            "childTokens" in r2 && r2.childTokens && (t2.childTokens[r2.name] = r2.childTokens);
          }), s3.extensions = t2), n.renderer) {
            let r2 = this.defaults.renderer || new y(this.defaults);
            for (let i in n.renderer) {
              if (!(i in r2)) throw new Error(`renderer '${i}' does not exist`);
              if (["options", "parser"].includes(i)) continue;
              let o = i, u = n.renderer[o], a2 = r2[o];
              r2[o] = (...p2) => {
                let c2 = u.apply(r2, p2);
                return c2 === false && (c2 = a2.apply(r2, p2)), c2 || "";
              };
            }
            s3.renderer = r2;
          }
          if (n.tokenizer) {
            let r2 = this.defaults.tokenizer || new w2(this.defaults);
            for (let i in n.tokenizer) {
              if (!(i in r2)) throw new Error(`tokenizer '${i}' does not exist`);
              if (["options", "rules", "lexer"].includes(i)) continue;
              let o = i, u = n.tokenizer[o], a2 = r2[o];
              r2[o] = (...p2) => {
                let c2 = u.apply(r2, p2);
                return c2 === false && (c2 = a2.apply(r2, p2)), c2;
              };
            }
            s3.tokenizer = r2;
          }
          if (n.hooks) {
            let r2 = this.defaults.hooks || new P2();
            for (let i in n.hooks) {
              if (!(i in r2)) throw new Error(`hook '${i}' does not exist`);
              if (["options", "block"].includes(i)) continue;
              let o = i, u = n.hooks[o], a2 = r2[o];
              P2.passThroughHooks.has(i) ? r2[o] = (p2) => {
                if (this.defaults.async && P2.passThroughHooksRespectAsync.has(i)) return (async () => {
                  let h = await u.call(r2, p2);
                  return a2.call(r2, h);
                })();
                let c2 = u.call(r2, p2);
                return a2.call(r2, c2);
              } : r2[o] = (...p2) => {
                if (this.defaults.async) return (async () => {
                  let h = await u.apply(r2, p2);
                  return h === false && (h = await a2.apply(r2, p2)), h;
                })();
                let c2 = u.apply(r2, p2);
                return c2 === false && (c2 = a2.apply(r2, p2)), c2;
              };
            }
            s3.hooks = r2;
          }
          if (n.walkTokens) {
            let r2 = this.defaults.walkTokens, i = n.walkTokens;
            s3.walkTokens = function(o) {
              let u = [];
              return u.push(i.call(this, o)), r2 && (u = u.concat(r2.call(this, o))), u;
            };
          }
          this.defaults = { ...this.defaults, ...s3 };
        }), this;
      }
      setOptions(e) {
        return this.defaults = { ...this.defaults, ...e }, this;
      }
      lexer(e, t2) {
        return x2.lex(e, t2 ?? this.defaults);
      }
      parser(e, t2) {
        return b2.parse(e, t2 ?? this.defaults);
      }
      parseMarkdown(e) {
        return (n, s3) => {
          let r2 = { ...s3 }, i = { ...this.defaults, ...r2 }, o = this.onError(!!i.silent, !!i.async);
          if (this.defaults.async === true && r2.async === false) return o(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
          if (typeof n > "u" || n === null) return o(new Error("marked(): input parameter is undefined or null"));
          if (typeof n != "string") return o(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
          if (i.hooks && (i.hooks.options = i, i.hooks.block = e), i.async) return (async () => {
            let u = i.hooks ? await i.hooks.preprocess(n) : n, p2 = await (i.hooks ? await i.hooks.provideLexer(e) : e ? x2.lex : x2.lexInline)(u, i), c2 = i.hooks ? await i.hooks.processAllTokens(p2) : p2;
            i.walkTokens && await Promise.all(this.walkTokens(c2, i.walkTokens));
            let k2 = await (i.hooks ? await i.hooks.provideParser(e) : e ? b2.parse : b2.parseInline)(c2, i);
            return i.hooks ? await i.hooks.postprocess(k2) : k2;
          })().catch(o);
          try {
            i.hooks && (n = i.hooks.preprocess(n));
            let a2 = (i.hooks ? i.hooks.provideLexer(e) : e ? x2.lex : x2.lexInline)(n, i);
            i.hooks && (a2 = i.hooks.processAllTokens(a2)), i.walkTokens && this.walkTokens(a2, i.walkTokens);
            let c2 = (i.hooks ? i.hooks.provideParser(e) : e ? b2.parse : b2.parseInline)(a2, i);
            return i.hooks && (c2 = i.hooks.postprocess(c2)), c2;
          } catch (u) {
            return o(u);
          }
        };
      }
      onError(e, t2) {
        return (n) => {
          if (n.message += `
Please report this to https://github.com/markedjs/marked.`, e) {
            let s3 = "<p>An error occurred:</p><pre>" + O2(n.message + "", true) + "</pre>";
            return t2 ? Promise.resolve(s3) : s3;
          }
          if (t2) return Promise.reject(n);
          throw n;
        };
      }
    };
    M = new D2();
    g2.options = g2.setOptions = function(l3) {
      return M.setOptions(l3), g2.defaults = M.defaults, N(g2.defaults), g2;
    };
    g2.getDefaults = z;
    g2.defaults = T2;
    g2.use = function(...l3) {
      return M.use(...l3), g2.defaults = M.defaults, N(g2.defaults), g2;
    };
    g2.walkTokens = function(l3, e) {
      return M.walkTokens(l3, e);
    };
    g2.parseInline = M.parseInline;
    g2.Parser = b2;
    g2.parser = b2.parse;
    g2.Renderer = y;
    g2.TextRenderer = L;
    g2.Lexer = x2;
    g2.lexer = x2.lex;
    g2.Tokenizer = w2;
    g2.Hooks = P2;
    g2.parse = g2;
    Kt = g2.options;
    Wt = g2.setOptions;
    Xt = g2.use;
    Jt = g2.walkTokens;
    Vt = g2.parseInline;
    en = b2.parse;
    tn = x2.lex;
  }
});

// dist/build/server/chunks/read.js
async function general(cache3, profileId) {
  const db2 = cache3.kb;
  const profile = await db2.selectFrom("quality_profiles").select([
    "id",
    "name",
    "description"
  ]).where("id", "=", profileId).executeTakeFirst();
  if (!profile) return null;
  const tags = await db2.selectFrom("quality_profile_tags as qpt").innerJoin("tags as t", "t.name", "qpt.tag_name").select(["t.name as tag_name", "t.created_at as tag_created_at"]).where("qpt.quality_profile_name", "=", profile.name).orderBy("t.name").execute();
  const languageRow = await db2.selectFrom("quality_profile_languages as qpl").select(["qpl.language_name"]).where("qpl.quality_profile_name", "=", profile.name).executeTakeFirst();
  return {
    id: profile.id,
    name: profile.name,
    description: profile.description || "",
    tags: tags.map((tag2) => ({
      name: tag2.tag_name,
      created_at: tag2.tag_created_at
    })),
    language: languageRow?.language_name ?? null
  };
}
var init_read = __esm({
  "dist/build/server/chunks/read.js"() {
    "use strict";
  }
});

// dist/build/server/chunks/read2.js
async function general2(cache3, formatId) {
  const db2 = cache3.kb;
  const format = await db2.selectFrom("custom_formats").select([
    "id",
    "name",
    "description",
    "include_in_rename"
  ]).where("id", "=", formatId).executeTakeFirst();
  if (!format) return null;
  const tags = await db2.selectFrom("custom_format_tags as cft").innerJoin("tags as t", "t.name", "cft.tag_name").select(["t.name as tag_name", "t.created_at as tag_created_at"]).where("cft.custom_format_name", "=", format.name).orderBy("t.name").execute();
  return {
    id: format.id,
    name: format.name,
    description: format.description || "",
    include_in_rename: format.include_in_rename === 1,
    tags: tags.map((tag2) => ({
      name: tag2.tag_name,
      created_at: tag2.tag_created_at
    }))
  };
}
var init_read2 = __esm({
  "dist/build/server/chunks/read2.js"() {
    "use strict";
  }
});

// dist/build/server/chunks/create.js
function esc$3(value2) {
  return value2.replace(/'/g, "''");
}
async function updateGeneral(options2) {
  const { databaseId, cache: cache3, layer, current: current3, input } = options2;
  const db2 = cache3.kb;
  const isRename = input.name !== current3.name;
  if (input.name !== current3.name) {
    if (await db2.selectFrom("custom_formats").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) {
      await logger.warn(`Duplicate custom format name "${input.name}"`, {
        source: "CustomFormat",
        meta: {
          databaseId,
          name: input.name
        }
      });
      throw new Error(`A custom format with name "${input.name}" already exists`);
    }
  }
  const rawCurrentDescription = (await db2.selectFrom("custom_formats").select("description").where("name", "=", current3.name).executeTakeFirst())?.description ?? null;
  const normalizedCurrentDescription = rawCurrentDescription ?? "";
  const normalizedNextDescription = input.description?.trim() ?? "";
  const descriptionChanged = normalizedCurrentDescription !== normalizedNextDescription;
  const descriptionNext = normalizedNextDescription;
  const descriptionQueries = [];
  if (descriptionChanged) {
    let updateDescription = db2.updateTable("custom_formats").set({ description: descriptionNext }).where("name", "=", current3.name);
    if (rawCurrentDescription === null) updateDescription = updateDescription.where("description", "is", null);
    else updateDescription = updateDescription.where("description", "=", rawCurrentDescription);
    descriptionQueries.push(updateDescription.compile());
  }
  const includeChanged = current3.include_in_rename !== input.includeInRename;
  const includeQueries = [];
  if (includeChanged) {
    const updateInclude = db2.updateTable("custom_formats").set({ include_in_rename: input.includeInRename ? 1 : 0 }).where("name", "=", current3.name).where("include_in_rename", "=", current3.include_in_rename ? 1 : 0);
    includeQueries.push(updateInclude.compile());
  }
  const renameQueries = [];
  if (isRename) {
    const updateName = db2.updateTable("custom_formats").set({ name: input.name }).where("name", "=", current3.name);
    renameQueries.push(updateName.compile());
  }
  const currentTagNames = current3.tags.map((t2) => t2.name);
  const newTagNames = Array.from(new Set(input.tags.map((tag2) => tag2.trim()).filter(Boolean)));
  const formatNameForTags = current3.name;
  const tagsToRemove = currentTagNames.filter((t2) => !newTagNames.includes(t2));
  const tagQueries = [];
  for (const tagName of tagsToRemove) {
    const removeTag = {
      sql: `DELETE FROM custom_format_tags WHERE custom_format_name = '${esc$3(formatNameForTags)}' AND tag_name = '${esc$3(tagName)}'`,
      parameters: [],
      query: {}
    };
    tagQueries.push(removeTag);
  }
  const tagsToAdd = newTagNames.filter((t2) => !currentTagNames.includes(t2));
  for (const tagName of tagsToAdd) {
    const insertTag = db2.insertInto("tags").values({ name: tagName }).onConflict((oc) => oc.column("name").doNothing()).compile();
    tagQueries.push(insertTag);
    const linkTag = {
      sql: `INSERT INTO custom_format_tags (custom_format_name, tag_name) VALUES ('${esc$3(formatNameForTags)}', '${esc$3(tagName)}')`,
      parameters: [],
      query: {}
    };
    tagQueries.push(linkTag);
  }
  const dependentScores = isRename ? await db2.selectFrom("quality_profile_custom_formats").select([
    "quality_profile_name",
    "custom_format_name",
    "arr_type",
    "score"
  ]).where("custom_format_name", "=", current3.name).execute() : [];
  const dependentOps = [];
  if (dependentScores.length > 0) {
    const scoresByProfile = /* @__PURE__ */ new Map();
    for (const score of dependentScores) {
      if (!scoresByProfile.has(score.quality_profile_name)) scoresByProfile.set(score.quality_profile_name, []);
      scoresByProfile.get(score.quality_profile_name).push({
        custom_format_name: score.custom_format_name,
        arr_type: score.arr_type,
        score: score.score
      });
    }
    for (const [profileName2, scores] of scoresByProfile.entries()) {
      const scoreQueries = scores.map((score) => db2.updateTable("quality_profile_custom_formats").set({ custom_format_name: input.name }).where("quality_profile_name", "=", profileName2).where("custom_format_name", "=", current3.name).where("arr_type", "=", score.arr_type).where("score", "=", score.score).compile());
      const customFormatScores = scores.flatMap((score) => [{
        custom_format_name: current3.name,
        arr_type: score.arr_type,
        from: score.score,
        to: null
      }, {
        custom_format_name: input.name,
        arr_type: score.arr_type,
        from: null,
        to: score.score
      }]);
      dependentOps.push({
        profileName: profileName2,
        queries: scoreQueries,
        customFormatScores
      });
    }
  }
  const changes = {};
  if (current3.name !== input.name) changes.name = {
    from: current3.name,
    to: input.name
  };
  if (descriptionChanged) changes.description = {
    from: rawCurrentDescription ?? "",
    to: normalizedNextDescription
  };
  if (current3.include_in_rename !== input.includeInRename) changes.include_in_rename = {
    from: current3.include_in_rename,
    to: input.includeInRename
  };
  if (tagsToAdd.length > 0 || tagsToRemove.length > 0) changes.tags = {
    from: currentTagNames,
    to: newTagNames
  };
  await logger.info(`Save custom format "${input.name}"`, {
    source: "CustomFormat",
    meta: {
      id: current3.id,
      changes
    }
  });
  const hasDescriptionChanges = descriptionQueries.length > 0;
  const hasIncludeChanges = includeQueries.length > 0;
  const hasTagChanges = tagsToAdd.length > 0 || tagsToRemove.length > 0;
  const hasRenameChanges = renameQueries.length > 0;
  const opCount = [
    hasDescriptionChanges,
    hasIncludeChanges,
    hasTagChanges,
    hasRenameChanges
  ].filter(Boolean).length;
  const groupId = opCount > 1 || hasRenameChanges && dependentOps.length > 0 ? uuid() : void 0;
  if (opCount === 0) return { success: true };
  let lastResult = null;
  if (hasDescriptionChanges) {
    const descriptionResult = await writeOperation({
      databaseId,
      layer,
      description: `update-custom-format-description-${input.name}`,
      queries: descriptionQueries,
      desiredState: { description: {
        from: rawCurrentDescription ?? "",
        to: normalizedNextDescription
      } },
      metadata: {
        operation: "update",
        entity: "custom_format",
        name: input.name,
        stableKey: {
          key: "custom_format_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: ["description"],
        summary: "Update custom format description",
        title: `Update description for custom format "${input.name}"`
      }
    });
    if (!descriptionResult.success) return descriptionResult;
    lastResult = descriptionResult;
  }
  if (hasIncludeChanges) {
    const includeResult = await writeOperation({
      databaseId,
      layer,
      description: `update-custom-format-include-rename-${input.name}`,
      queries: includeQueries,
      desiredState: { include_in_rename: {
        from: current3.include_in_rename,
        to: input.includeInRename
      } },
      metadata: {
        operation: "update",
        entity: "custom_format",
        name: input.name,
        stableKey: {
          key: "custom_format_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: ["include_in_rename"],
        summary: "Update custom format include in rename",
        title: `Update include in rename for custom format "${input.name}"`
      }
    });
    if (!includeResult.success) return includeResult;
    lastResult = includeResult;
  }
  if (hasTagChanges) {
    const tagsResult = await writeOperation({
      databaseId,
      layer,
      description: `update-custom-format-tags-${input.name}`,
      queries: tagQueries,
      desiredState: { tags: {
        add: tagsToAdd,
        remove: tagsToRemove
      } },
      metadata: {
        operation: "update",
        entity: "custom_format",
        name: input.name,
        stableKey: {
          key: "custom_format_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: ["tags"],
        summary: "Update custom format tags",
        title: `Update tags for custom format "${input.name}"`
      }
    });
    if (!tagsResult.success) return tagsResult;
    lastResult = tagsResult;
  }
  if (hasRenameChanges) {
    const renameResult = await writeOperation({
      databaseId,
      layer,
      description: `update-custom-format-name-${input.name}`,
      queries: renameQueries,
      desiredState: { name: {
        from: current3.name,
        to: input.name
      } },
      metadata: {
        operation: "update",
        entity: "custom_format",
        name: input.name,
        previousName: current3.name,
        stableKey: {
          key: "custom_format_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: ["name"],
        summary: "Rename custom format",
        title: `Rename custom format "${current3.name}"`
      }
    });
    if (!renameResult.success) return renameResult;
    lastResult = renameResult;
  }
  if (!hasRenameChanges || dependentScores.length === 0 || !groupId) return lastResult ?? { success: true };
  if (dependentOps.length === 0) return lastResult ?? { success: true };
  for (const op of dependentOps) {
    const scoreResult = await writeOperation({
      databaseId,
      layer,
      description: `update-quality-profile-scoring-${op.profileName}`,
      queries: op.queries,
      desiredState: { custom_format_scores: op.customFormatScores },
      metadata: {
        operation: "update",
        entity: "quality_profile",
        name: op.profileName,
        stableKey: {
          key: "quality_profile_name",
          value: op.profileName
        },
        groupId,
        generated: true,
        dependsOn: [{
          entity: "custom_format",
          key: "custom_format_name",
          value: input.name
        }],
        changedFields: ["custom_format_scores"],
        summary: "Update quality profile scoring",
        title: `Update scoring for quality profile "${op.profileName}"`
      }
    });
    if (!scoreResult.success) return scoreResult;
  }
  return lastResult ?? { success: true };
}
async function getConditionsForEvaluation(cache3, formatName) {
  const db2 = cache3.kb;
  const conditions = await db2.selectFrom("custom_format_conditions").select([
    "custom_format_name",
    "name",
    "type",
    "arr_type",
    "negate",
    "required"
  ]).where("custom_format_name", "=", formatName).execute();
  if (conditions.length === 0) return [];
  const conditionNames = conditions.map((c2) => c2.name);
  const [patterns, languages, sources, resolutions, qualityModifiers, releaseTypes, indexerFlags, sizes, years] = await Promise.all([
    db2.selectFrom("condition_patterns as cp").innerJoin("regular_expressions as re", "re.name", "cp.regular_expression_name").select([
      "cp.condition_name",
      "re.name",
      "re.pattern"
    ]).where("cp.custom_format_name", "=", formatName).where("cp.condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_languages as cl").innerJoin("languages as l", "l.name", "cl.language_name").select([
      "cl.condition_name",
      "l.name",
      "cl.except_language"
    ]).where("cl.custom_format_name", "=", formatName).where("cl.condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_sources").select(["condition_name", "source"]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_resolutions").select(["condition_name", "resolution"]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_quality_modifiers").select(["condition_name", "quality_modifier"]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_release_types").select(["condition_name", "release_type"]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_indexer_flags").select(["condition_name", "flag"]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_sizes").select([
      "condition_name",
      "min_bytes",
      "max_bytes"
    ]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_years").select([
      "condition_name",
      "min_year",
      "max_year"
    ]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute()
  ]);
  const patternsMap = /* @__PURE__ */ new Map();
  for (const p2 of patterns) {
    if (!patternsMap.has(p2.condition_name)) patternsMap.set(p2.condition_name, []);
    patternsMap.get(p2.condition_name).push({
      name: p2.name,
      pattern: p2.pattern
    });
  }
  const languagesMap = /* @__PURE__ */ new Map();
  for (const l3 of languages) {
    if (!languagesMap.has(l3.condition_name)) languagesMap.set(l3.condition_name, []);
    languagesMap.get(l3.condition_name).push({
      name: l3.name,
      except: l3.except_language === 1
    });
  }
  const sourcesMap = /* @__PURE__ */ new Map();
  for (const s3 of sources) {
    if (!sourcesMap.has(s3.condition_name)) sourcesMap.set(s3.condition_name, []);
    sourcesMap.get(s3.condition_name).push(s3.source);
  }
  const resolutionsMap = /* @__PURE__ */ new Map();
  for (const r2 of resolutions) {
    if (!resolutionsMap.has(r2.condition_name)) resolutionsMap.set(r2.condition_name, []);
    resolutionsMap.get(r2.condition_name).push(r2.resolution);
  }
  const qualityModifiersMap = /* @__PURE__ */ new Map();
  for (const q2 of qualityModifiers) {
    if (!qualityModifiersMap.has(q2.condition_name)) qualityModifiersMap.set(q2.condition_name, []);
    qualityModifiersMap.get(q2.condition_name).push(q2.quality_modifier);
  }
  const releaseTypesMap = /* @__PURE__ */ new Map();
  for (const r2 of releaseTypes) {
    if (!releaseTypesMap.has(r2.condition_name)) releaseTypesMap.set(r2.condition_name, []);
    releaseTypesMap.get(r2.condition_name).push(r2.release_type);
  }
  const indexerFlagsMap = /* @__PURE__ */ new Map();
  for (const f2 of indexerFlags) {
    if (!indexerFlagsMap.has(f2.condition_name)) indexerFlagsMap.set(f2.condition_name, []);
    indexerFlagsMap.get(f2.condition_name).push(f2.flag);
  }
  const sizesMap = /* @__PURE__ */ new Map();
  for (const s3 of sizes) sizesMap.set(s3.condition_name, {
    minBytes: s3.min_bytes,
    maxBytes: s3.max_bytes
  });
  const yearsMap = /* @__PURE__ */ new Map();
  for (const y2 of years) yearsMap.set(y2.condition_name, {
    minYear: y2.min_year,
    maxYear: y2.max_year
  });
  return conditions.map((c2) => ({
    name: c2.name,
    type: c2.type,
    arrType: c2.arr_type,
    negate: c2.negate === 1,
    required: c2.required === 1,
    patterns: patternsMap.get(c2.name),
    languages: languagesMap.get(c2.name),
    sources: sourcesMap.get(c2.name),
    resolutions: resolutionsMap.get(c2.name),
    qualityModifiers: qualityModifiersMap.get(c2.name),
    releaseTypes: releaseTypesMap.get(c2.name),
    indexerFlags: indexerFlagsMap.get(c2.name),
    size: sizesMap.get(c2.name),
    years: yearsMap.get(c2.name)
  }));
}
async function getAllConditionsForEvaluation(cache3) {
  const db2 = cache3.kb;
  const formats = await db2.selectFrom("custom_formats").select(["id", "name"]).orderBy(sql`name COLLATE NOCASE`).execute();
  if (formats.length === 0) return [];
  const conditions = await db2.selectFrom("custom_format_conditions").select([
    "custom_format_name",
    "name",
    "type",
    "arr_type",
    "negate",
    "required"
  ]).execute();
  if (conditions.length === 0) return formats.map((f2) => ({
    name: f2.name,
    conditions: []
  }));
  const [patterns, languages, sources, resolutions, qualityModifiers, releaseTypes, indexerFlags, sizes, years] = await Promise.all([
    db2.selectFrom("condition_patterns as cp").innerJoin("regular_expressions as re", "re.name", "cp.regular_expression_name").select([
      "cp.custom_format_name",
      "cp.condition_name",
      "re.name",
      "re.pattern"
    ]).execute(),
    db2.selectFrom("condition_languages as cl").innerJoin("languages as l", "l.name", "cl.language_name").select([
      "cl.custom_format_name",
      "cl.condition_name",
      "l.name",
      "cl.except_language"
    ]).execute(),
    db2.selectFrom("condition_sources").select([
      "custom_format_name",
      "condition_name",
      "source"
    ]).execute(),
    db2.selectFrom("condition_resolutions").select([
      "custom_format_name",
      "condition_name",
      "resolution"
    ]).execute(),
    db2.selectFrom("condition_quality_modifiers").select([
      "custom_format_name",
      "condition_name",
      "quality_modifier"
    ]).execute(),
    db2.selectFrom("condition_release_types").select([
      "custom_format_name",
      "condition_name",
      "release_type"
    ]).execute(),
    db2.selectFrom("condition_indexer_flags").select([
      "custom_format_name",
      "condition_name",
      "flag"
    ]).execute(),
    db2.selectFrom("condition_sizes").select([
      "custom_format_name",
      "condition_name",
      "min_bytes",
      "max_bytes"
    ]).execute(),
    db2.selectFrom("condition_years").select([
      "custom_format_name",
      "condition_name",
      "min_year",
      "max_year"
    ]).execute()
  ]);
  const patternsMap = /* @__PURE__ */ new Map();
  for (const p2 of patterns) {
    const key2 = `${p2.custom_format_name}|${p2.condition_name}`;
    if (!patternsMap.has(key2)) patternsMap.set(key2, []);
    patternsMap.get(key2).push({
      name: p2.name,
      pattern: p2.pattern
    });
  }
  const languagesMap = /* @__PURE__ */ new Map();
  for (const l3 of languages) {
    const key2 = `${l3.custom_format_name}|${l3.condition_name}`;
    if (!languagesMap.has(key2)) languagesMap.set(key2, []);
    languagesMap.get(key2).push({
      name: l3.name,
      except: l3.except_language === 1
    });
  }
  const sourcesMap = /* @__PURE__ */ new Map();
  for (const s3 of sources) {
    const key2 = `${s3.custom_format_name}|${s3.condition_name}`;
    if (!sourcesMap.has(key2)) sourcesMap.set(key2, []);
    sourcesMap.get(key2).push(s3.source);
  }
  const resolutionsMap = /* @__PURE__ */ new Map();
  for (const r2 of resolutions) {
    const key2 = `${r2.custom_format_name}|${r2.condition_name}`;
    if (!resolutionsMap.has(key2)) resolutionsMap.set(key2, []);
    resolutionsMap.get(key2).push(r2.resolution);
  }
  const qualityModifiersMap = /* @__PURE__ */ new Map();
  for (const q2 of qualityModifiers) {
    const key2 = `${q2.custom_format_name}|${q2.condition_name}`;
    if (!qualityModifiersMap.has(key2)) qualityModifiersMap.set(key2, []);
    qualityModifiersMap.get(key2).push(q2.quality_modifier);
  }
  const releaseTypesMap = /* @__PURE__ */ new Map();
  for (const r2 of releaseTypes) {
    const key2 = `${r2.custom_format_name}|${r2.condition_name}`;
    if (!releaseTypesMap.has(key2)) releaseTypesMap.set(key2, []);
    releaseTypesMap.get(key2).push(r2.release_type);
  }
  const indexerFlagsMap = /* @__PURE__ */ new Map();
  for (const f2 of indexerFlags) {
    const key2 = `${f2.custom_format_name}|${f2.condition_name}`;
    if (!indexerFlagsMap.has(key2)) indexerFlagsMap.set(key2, []);
    indexerFlagsMap.get(key2).push(f2.flag);
  }
  const sizesMap = /* @__PURE__ */ new Map();
  for (const s3 of sizes) {
    const key2 = `${s3.custom_format_name}|${s3.condition_name}`;
    sizesMap.set(key2, {
      minBytes: s3.min_bytes,
      maxBytes: s3.max_bytes
    });
  }
  const yearsMap = /* @__PURE__ */ new Map();
  for (const y2 of years) {
    const key2 = `${y2.custom_format_name}|${y2.condition_name}`;
    yearsMap.set(key2, {
      minYear: y2.min_year,
      maxYear: y2.max_year
    });
  }
  const conditionsByFormat = /* @__PURE__ */ new Map();
  for (const c2 of conditions) {
    if (!conditionsByFormat.has(c2.custom_format_name)) conditionsByFormat.set(c2.custom_format_name, []);
    const key2 = `${c2.custom_format_name}|${c2.name}`;
    conditionsByFormat.get(c2.custom_format_name).push({
      name: c2.name,
      type: c2.type,
      arrType: c2.arr_type,
      negate: c2.negate === 1,
      required: c2.required === 1,
      patterns: patternsMap.get(key2),
      languages: languagesMap.get(key2),
      sources: sourcesMap.get(key2),
      resolutions: resolutionsMap.get(key2),
      qualityModifiers: qualityModifiersMap.get(key2),
      releaseTypes: releaseTypesMap.get(key2),
      indexerFlags: indexerFlagsMap.get(key2),
      size: sizesMap.get(key2),
      years: yearsMap.get(key2)
    });
  }
  return formats.map((f2) => ({
    name: f2.name,
    conditions: conditionsByFormat.get(f2.name) || []
  }));
}
function esc$2(value2) {
  return value2.replace(/'/g, "''");
}
function generateConditionValueSql(formatName, conditionName, condition) {
  const sqls = [];
  switch (condition.type) {
    case "release_title":
    case "release_group":
    case "edition":
      if (condition.patterns && condition.patterns.length > 0) for (const pattern2 of condition.patterns) sqls.push(`INSERT INTO condition_patterns (custom_format_name, condition_name, regular_expression_name) VALUES ('${esc$2(formatName)}', '${esc$2(conditionName)}', '${esc$2(pattern2.name)}')`);
      break;
    case "language":
      if (condition.languages && condition.languages.length > 0) for (const lang of condition.languages) sqls.push(`INSERT INTO condition_languages (custom_format_name, condition_name, language_name, except_language) VALUES ('${esc$2(formatName)}', '${esc$2(conditionName)}', '${esc$2(lang.name)}', ${lang.except ? 1 : 0})`);
      break;
    case "source":
      if (condition.sources && condition.sources.length > 0) for (const source2 of condition.sources) sqls.push(`INSERT INTO condition_sources (custom_format_name, condition_name, source) VALUES ('${esc$2(formatName)}', '${esc$2(conditionName)}', '${esc$2(source2)}')`);
      break;
    case "resolution":
      if (condition.resolutions && condition.resolutions.length > 0) for (const res of condition.resolutions) sqls.push(`INSERT INTO condition_resolutions (custom_format_name, condition_name, resolution) VALUES ('${esc$2(formatName)}', '${esc$2(conditionName)}', '${esc$2(res)}')`);
      break;
    case "quality_modifier":
      if (condition.qualityModifiers && condition.qualityModifiers.length > 0) for (const qm of condition.qualityModifiers) sqls.push(`INSERT INTO condition_quality_modifiers (custom_format_name, condition_name, quality_modifier) VALUES ('${esc$2(formatName)}', '${esc$2(conditionName)}', '${esc$2(qm)}')`);
      break;
    case "release_type":
      if (condition.releaseTypes && condition.releaseTypes.length > 0) for (const rt2 of condition.releaseTypes) sqls.push(`INSERT INTO condition_release_types (custom_format_name, condition_name, release_type) VALUES ('${esc$2(formatName)}', '${esc$2(conditionName)}', '${esc$2(rt2)}')`);
      break;
    case "indexer_flag":
      if (condition.indexerFlags && condition.indexerFlags.length > 0) for (const flag of condition.indexerFlags) sqls.push(`INSERT INTO condition_indexer_flags (custom_format_name, condition_name, flag) VALUES ('${esc$2(formatName)}', '${esc$2(conditionName)}', '${esc$2(flag)}')`);
      break;
    case "size":
      if (condition.size) {
        const minBytes = condition.size.minBytes ?? "NULL";
        const maxBytes = condition.size.maxBytes ?? "NULL";
        sqls.push(`INSERT INTO condition_sizes (custom_format_name, condition_name, min_bytes, max_bytes) VALUES ('${esc$2(formatName)}', '${esc$2(conditionName)}', ${minBytes}, ${maxBytes})`);
      }
      break;
    case "year":
      if (condition.years) {
        const minYear = condition.years.minYear ?? "NULL";
        const maxYear = condition.years.maxYear ?? "NULL";
        sqls.push(`INSERT INTO condition_years (custom_format_name, condition_name, min_year, max_year) VALUES ('${esc$2(formatName)}', '${esc$2(conditionName)}', ${minYear}, ${maxYear})`);
      }
  }
  return sqls;
}
async function updateConditions(options2) {
  const { databaseId, layer, formatName, originalConditions, conditions } = options2;
  const normalizedNames = conditions.map((c2) => c2.name.trim().toLowerCase());
  if (new Set(normalizedNames).size !== normalizedNames.length) throw new Error("Condition names must be unique");
  const typeFieldMap = {
    release_title: {
      field: "patterns",
      label: "pattern"
    },
    release_group: {
      field: "patterns",
      label: "pattern"
    },
    edition: {
      field: "patterns",
      label: "pattern"
    },
    language: {
      field: "languages",
      label: "language"
    },
    source: {
      field: "sources",
      label: "source"
    },
    resolution: {
      field: "resolutions",
      label: "resolution"
    },
    quality_modifier: {
      field: "qualityModifiers",
      label: "quality modifier"
    },
    release_type: {
      field: "releaseTypes",
      label: "release type"
    },
    indexer_flag: {
      field: "indexerFlags",
      label: "indexer flag"
    },
    size: null,
    year: null
  };
  for (const condition of conditions) {
    const mapping = typeFieldMap[condition.type] ?? null;
    if (!mapping) continue;
    const values = condition[mapping.field];
    if (Array.isArray(values) && values.length > 1) throw new Error(`Condition "${condition.name}" must have a single ${mapping.label}`);
  }
  const newConditionNames = new Set(conditions.map((c2) => c2.name));
  const originalConditionNames = new Set(originalConditions.map((c2) => c2.name));
  const conditionOps = [];
  const conditionsToDelete = originalConditions.filter((c2) => !newConditionNames.has(c2.name));
  const newConditions = conditions.filter((c2) => !originalConditionNames.has(c2.name));
  const groupedDeleteByName = /* @__PURE__ */ new Map();
  const groupedAddByName = /* @__PURE__ */ new Map();
  const newConditionsByFingerprint = /* @__PURE__ */ new Map();
  for (const condition of newConditions) {
    const fingerprint = getConditionFingerprint(condition);
    const existing = newConditionsByFingerprint.get(fingerprint) ?? [];
    existing.push(condition);
    newConditionsByFingerprint.set(fingerprint, existing);
  }
  for (const condition of conditionsToDelete) {
    const fingerprint = getConditionFingerprint(condition);
    const candidates = newConditionsByFingerprint.get(fingerprint);
    if (!candidates || candidates.length === 0) continue;
    const match = candidates.shift();
    if (!match) continue;
    const groupId = uuid();
    groupedDeleteByName.set(condition.name, groupId);
    groupedAddByName.set(match.name, groupId);
  }
  for (const condition of conditionsToDelete) {
    const deleteQueries = [{
      sql: `DELETE FROM custom_format_conditions
	WHERE custom_format_name = '${esc$2(formatName)}'
	  AND name = '${esc$2(condition.name)}'
	  AND type = '${esc$2(condition.type)}'
	  AND arr_type = '${esc$2(condition.arrType ?? "all")}'
	  AND negate = ${condition.negate ? 1 : 0}
	  AND required = ${condition.required ? 1 : 0}`,
      parameters: [],
      query: {}
    }];
    conditionOps.push({
      description: `delete-condition-${formatName}-${condition.name}`,
      queries: deleteQueries,
      desiredState: { conditions: { removed: [{
        name: condition.name,
        base: baseSnapshot(condition),
        values: getConditionValues(condition)
      }] } },
      summary: "Remove custom format condition",
      title: `Remove condition "${condition.name}" from "${formatName}"`,
      changedFields: ["conditions", `condition:${condition.name}`],
      groupId: groupedDeleteByName.get(condition.name)
    });
  }
  for (const condition of newConditions) {
    const insertQueries = [];
    insertQueries.push({
      sql: `INSERT INTO custom_format_conditions (custom_format_name, name, type, arr_type, negate, required)
VALUES ('${esc$2(formatName)}', '${esc$2(condition.name)}', '${esc$2(condition.type)}', '${esc$2(condition.arrType ?? "all")}', ${condition.negate ? 1 : 0}, ${condition.required ? 1 : 0})`,
      parameters: [],
      query: {}
    });
    const valueSqls = generateConditionValueSql(formatName, condition.name, condition);
    for (const sql2 of valueSqls) insertQueries.push({
      sql: sql2,
      parameters: [],
      query: {}
    });
    const regexDependencies = getRegexDependencies(condition);
    conditionOps.push({
      description: `add-condition-${formatName}-${condition.name}`,
      queries: insertQueries,
      desiredState: { conditions: { added: [{
        name: condition.name,
        base: baseSnapshot(condition),
        values: getConditionValues(condition)
      }] } },
      summary: "Add custom format condition",
      title: `Add condition "${condition.name}" to "${formatName}"`,
      changedFields: ["conditions", `condition:${condition.name}`],
      groupId: groupedAddByName.get(condition.name),
      dependsOn: regexDependencies.map((name) => ({
        entity: "regular_expression",
        key: "regular_expression_name",
        value: name
      }))
    });
  }
  const existingConditions = conditions.filter((c2) => originalConditionNames.has(c2.name));
  const updatedConditions = [];
  for (const condition of existingConditions) {
    const original = originalConditions.find((c2) => c2.name === condition.name);
    if (!original) continue;
    const originalArrType = normalizeArrType(original);
    const nextArrType = normalizeArrType(condition);
    const baseChanged = original.type !== condition.type || originalArrType !== nextArrType || original.negate !== condition.negate || original.required !== condition.required;
    const typeChanged = original.type !== condition.type;
    const valuesChanged = !deepEquals(getConditionValues(original), getConditionValues(condition));
    if (!baseChanged && !valuesChanged) continue;
    updatedConditions.push(condition);
    const updateQueries = [];
    if (baseChanged) {
      const setParts = [];
      if (original.type !== condition.type) setParts.push(`type = '${esc$2(condition.type)}'`);
      if (originalArrType !== nextArrType) setParts.push(`arr_type = '${esc$2(nextArrType)}'`);
      if (original.negate !== condition.negate) setParts.push(`negate = ${condition.negate ? 1 : 0}`);
      if (original.required !== condition.required) setParts.push(`required = ${condition.required ? 1 : 0}`);
      if (setParts.length > 0) updateQueries.push({
        sql: `UPDATE custom_format_conditions
SET ${setParts.join(", ")}
WHERE custom_format_name = '${esc$2(formatName)}'
  AND name = '${esc$2(condition.name)}'
  AND type = '${esc$2(original.type)}'
  AND arr_type = '${esc$2(originalArrType)}'
  AND negate = ${original.negate ? 1 : 0}
  AND required = ${original.required ? 1 : 0}`,
        parameters: [],
        query: {}
      });
    }
    if (typeChanged || valuesChanged) {
      const deleteSqls = generateConditionValueDeleteSql(formatName, condition.name, original);
      for (const sql2 of deleteSqls) updateQueries.push({
        sql: sql2,
        parameters: [],
        query: {}
      });
      const valueSqls = generateConditionValueSql(formatName, condition.name, condition);
      for (const sql2 of valueSqls) updateQueries.push({
        sql: sql2,
        parameters: [],
        query: {}
      });
    }
    const regexDependencies = getRegexDependencies(condition);
    conditionOps.push({
      description: `update-condition-${formatName}-${condition.name}`,
      queries: updateQueries,
      desiredState: { conditions: { updated: [{
        name: condition.name,
        base: {
          from: baseSnapshot(original),
          to: baseSnapshot(condition)
        },
        values: {
          from: getConditionValues(original),
          to: getConditionValues(condition)
        }
      }] } },
      summary: "Update custom format condition",
      title: `Update condition "${condition.name}" on "${formatName}"`,
      changedFields: ["conditions", `condition:${condition.name}`],
      dependsOn: regexDependencies.map((name) => ({
        entity: "regular_expression",
        key: "regular_expression_name",
        value: name
      }))
    });
  }
  if (conditionOps.length === 0) return { success: true };
  await logger.info(`Save conditions for custom format "${formatName}"`, {
    source: "CustomFormat",
    meta: {
      formatName,
      deleted: conditionsToDelete.length,
      added: newConditions.length,
      updated: updatedConditions.length
    }
  });
  let lastResult = null;
  for (const op of conditionOps) {
    const result = await writeOperation({
      databaseId,
      layer,
      description: op.description,
      queries: op.queries,
      desiredState: op.desiredState,
      skipRecompile: true,
      metadata: {
        operation: "update",
        entity: "custom_format",
        name: formatName,
        stableKey: {
          key: "custom_format_name",
          value: formatName
        },
        changedFields: op.changedFields,
        summary: op.summary,
        title: op.title,
        ...op.groupId ? { groupId: op.groupId } : {},
        ...op.dependsOn && op.dependsOn.length > 0 ? { dependsOn: op.dependsOn } : {}
      }
    });
    if (!result.success) {
      await recompileCache(databaseId);
      return result;
    }
    lastResult = result;
  }
  await recompileCache(databaseId);
  return lastResult ?? { success: true };
}
function baseSnapshot(condition) {
  return {
    type: condition.type,
    arrType: normalizeArrType(condition),
    negate: condition.negate,
    required: condition.required
  };
}
function normalizeArrType(condition) {
  return condition.arrType || "all";
}
function generateConditionValueDeleteSql(formatName, conditionName, condition) {
  const sqls = [];
  switch (condition.type) {
    case "release_title":
    case "release_group":
    case "edition":
      if (condition.patterns && condition.patterns.length > 0) for (const pattern2 of condition.patterns) sqls.push(`DELETE FROM condition_patterns WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}' AND regular_expression_name = '${esc$2(pattern2.name)}'`);
      else sqls.push(`DELETE FROM condition_patterns WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}'`);
      break;
    case "language":
      if (condition.languages && condition.languages.length > 0) for (const lang of condition.languages) sqls.push(`DELETE FROM condition_languages WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}' AND language_name = '${esc$2(lang.name)}' AND except_language = ${lang.except ? 1 : 0}`);
      else sqls.push(`DELETE FROM condition_languages WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}'`);
      break;
    case "source":
      if (condition.sources && condition.sources.length > 0) for (const source2 of condition.sources) sqls.push(`DELETE FROM condition_sources WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}' AND source = '${esc$2(source2)}'`);
      else sqls.push(`DELETE FROM condition_sources WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}'`);
      break;
    case "resolution":
      if (condition.resolutions && condition.resolutions.length > 0) for (const res of condition.resolutions) sqls.push(`DELETE FROM condition_resolutions WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}' AND resolution = '${esc$2(res)}'`);
      else sqls.push(`DELETE FROM condition_resolutions WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}'`);
      break;
    case "quality_modifier":
      if (condition.qualityModifiers && condition.qualityModifiers.length > 0) for (const qm of condition.qualityModifiers) sqls.push(`DELETE FROM condition_quality_modifiers WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}' AND quality_modifier = '${esc$2(qm)}'`);
      else sqls.push(`DELETE FROM condition_quality_modifiers WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}'`);
      break;
    case "release_type":
      if (condition.releaseTypes && condition.releaseTypes.length > 0) for (const rt2 of condition.releaseTypes) sqls.push(`DELETE FROM condition_release_types WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}' AND release_type = '${esc$2(rt2)}'`);
      else sqls.push(`DELETE FROM condition_release_types WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}'`);
      break;
    case "indexer_flag":
      if (condition.indexerFlags && condition.indexerFlags.length > 0) for (const flag of condition.indexerFlags) sqls.push(`DELETE FROM condition_indexer_flags WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}' AND flag = '${esc$2(flag)}'`);
      else sqls.push(`DELETE FROM condition_indexer_flags WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}'`);
      break;
    case "size":
      if (condition.size) {
        const minBytes = condition.size.minBytes ?? "NULL";
        const maxBytes = condition.size.maxBytes ?? "NULL";
        sqls.push(`DELETE FROM condition_sizes WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}' AND min_bytes IS ${minBytes === "NULL" ? "NULL" : minBytes} AND max_bytes IS ${maxBytes === "NULL" ? "NULL" : maxBytes}`);
      } else sqls.push(`DELETE FROM condition_sizes WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}'`);
      break;
    case "year":
      if (condition.years) {
        const minYear = condition.years.minYear ?? "NULL";
        const maxYear = condition.years.maxYear ?? "NULL";
        sqls.push(`DELETE FROM condition_years WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}' AND min_year IS ${minYear === "NULL" ? "NULL" : minYear} AND max_year IS ${maxYear === "NULL" ? "NULL" : maxYear}`);
      } else sqls.push(`DELETE FROM condition_years WHERE custom_format_name = '${esc$2(formatName)}' AND condition_name = '${esc$2(conditionName)}'`);
  }
  return sqls;
}
function getConditionValues(condition) {
  return {
    patterns: condition.patterns,
    languages: condition.languages,
    sources: condition.sources,
    resolutions: condition.resolutions,
    qualityModifiers: condition.qualityModifiers,
    releaseTypes: condition.releaseTypes,
    indexerFlags: condition.indexerFlags,
    size: condition.size,
    years: condition.years
  };
}
function getRegexDependencies(condition) {
  return (condition.patterns ?? []).map((pattern2) => pattern2.name.trim()).filter(Boolean);
}
function getConditionFingerprint(condition) {
  return JSON.stringify({
    base: baseSnapshot(condition),
    values: getConditionValues(condition)
  });
}
function deepEquals(a2, b3) {
  if (a2 === b3) return true;
  if (typeof a2 !== typeof b3) return false;
  if (a2 === null || b3 === null) return a2 === b3;
  if (Array.isArray(a2) && Array.isArray(b3)) {
    if (a2.length !== b3.length) return false;
    return a2.every((item, i) => deepEquals(item, b3[i]));
  }
  if (typeof a2 === "object" && typeof b3 === "object") {
    const aObj = a2;
    const bObj = b3;
    const aKeys = Object.keys(aObj);
    const bKeys = Object.keys(bObj);
    if (aKeys.length !== bKeys.length) return false;
    return aKeys.every((key2) => deepEquals(aObj[key2], bObj[key2]));
  }
  return false;
}
function esc$1(value2) {
  return value2.replace(/'/g, "''");
}
async function createTest(options2) {
  const { databaseId, layer, formatName, input, skipRecompile } = options2;
  const cache3 = getCache(databaseId);
  if (!cache3) throw new Error("Database cache not available");
  if (await cache3.kb.selectFrom("custom_format_tests").where("custom_format_name", "=", formatName).where((eb) => eb(eb.fn("lower", [eb.ref("title")]), "=", input.title.toLowerCase())).where((eb) => eb(eb.fn("lower", [eb.ref("type")]), "=", input.type.toLowerCase())).select("id").executeTakeFirst()) throw new Error("A test with this title and type already exists for this custom format");
  const descriptionValue = input.description ? `'${esc$1(input.description)}'` : "NULL";
  const insertTest = {
    sql: `INSERT INTO custom_format_tests (custom_format_name, title, type, should_match, description) VALUES ('${esc$1(formatName)}', '${esc$1(input.title)}', '${esc$1(input.type)}', ${input.should_match ? 1 : 0}, ${descriptionValue})`,
    parameters: [],
    query: {}
  };
  return await writeOperation({
    databaseId,
    layer,
    description: `create-test-${formatName}`,
    queries: [insertTest],
    skipRecompile,
    desiredState: {
      custom_format_name: formatName,
      title: input.title,
      type: input.type,
      should_match: input.should_match,
      description: input.description ?? null,
      test_title: input.title,
      test_type: input.type,
      test_should_match: input.should_match,
      test_description: input.description ?? null
    },
    metadata: {
      operation: "create",
      entity: "custom_format",
      name: formatName,
      stableKey: {
        key: "custom_format_name",
        value: formatName
      },
      summary: "Create custom format test",
      title: `Create test for custom format "${formatName}"`
    }
  });
}
function esc(value2) {
  return value2.replace(/'/g, "''");
}
async function updateTest(options2) {
  const { databaseId, layer, formatName, current: current3, input } = options2;
  if (input.title.toLowerCase() !== current3.title.toLowerCase() || input.type.toLowerCase() !== current3.type.toLowerCase()) {
    const cache3 = getCache(databaseId);
    if (!cache3) throw new Error("Database cache not available");
    if (await cache3.kb.selectFrom("custom_format_tests").where("custom_format_name", "=", formatName).where((eb) => eb(eb.fn("lower", [eb.ref("title")]), "=", input.title.toLowerCase())).where((eb) => eb(eb.fn("lower", [eb.ref("type")]), "=", input.type.toLowerCase())).select("id").executeTakeFirst()) throw new Error("A test with this title and type already exists for this custom format");
  }
  const rawCurrentDescription = current3.description;
  const normalizedCurrentDescription = rawCurrentDescription ?? "";
  const normalizedNextDescription = input.description?.trim() ?? "";
  const descriptionChanged = normalizedCurrentDescription !== normalizedNextDescription;
  const setParts = [];
  if (current3.title !== input.title) setParts.push(`title = '${esc(input.title)}'`);
  if (current3.type !== input.type) setParts.push(`type = '${esc(input.type)}'`);
  if (current3.should_match !== input.should_match) setParts.push(`should_match = ${input.should_match ? 1 : 0}`);
  if (descriptionChanged) {
    const descriptionValue = normalizedNextDescription === "" ? "NULL" : `'${esc(normalizedNextDescription)}'`;
    setParts.push(`description = ${descriptionValue}`);
  }
  const guardParts = [
    `custom_format_name = '${esc(formatName)}'`,
    `title = '${esc(current3.title)}'`,
    `type = '${esc(current3.type)}'`
  ];
  if (current3.should_match !== input.should_match) guardParts.push(`should_match = ${current3.should_match ? 1 : 0}`);
  if (descriptionChanged) if (rawCurrentDescription === null) guardParts.push(`description IS NULL`);
  else guardParts.push(`description = '${esc(rawCurrentDescription)}'`);
  const updateTest2 = setParts.length > 0 ? {
    sql: `UPDATE custom_format_tests SET ${setParts.join(", ")} WHERE ${guardParts.join(" AND ")}`,
    parameters: [],
    query: {}
  } : null;
  const changedFields = [];
  if (current3.title !== input.title) changedFields.push("title");
  if (current3.type !== input.type) changedFields.push("type");
  if (current3.should_match !== input.should_match) changedFields.push("should_match");
  if (descriptionChanged) changedFields.push("description");
  const desiredState = {};
  desiredState.test_title = input.title;
  desiredState.test_type = input.type;
  desiredState.test_should_match = input.should_match;
  desiredState.test_description = normalizedNextDescription === "" ? null : normalizedNextDescription;
  if (current3.title !== input.title) desiredState.title = {
    from: current3.title,
    to: input.title
  };
  if (current3.type !== input.type) desiredState.type = {
    from: current3.type,
    to: input.type
  };
  if (current3.should_match !== input.should_match) desiredState.should_match = {
    from: current3.should_match,
    to: input.should_match
  };
  if (descriptionChanged) desiredState.description = {
    from: rawCurrentDescription ?? null,
    to: normalizedNextDescription === "" ? null : normalizedNextDescription
  };
  if (!updateTest2) return { success: true };
  return await writeOperation({
    databaseId,
    layer,
    description: `update-test-${formatName}`,
    queries: [updateTest2],
    desiredState,
    metadata: {
      operation: "update",
      entity: "custom_format",
      name: formatName,
      stableKey: {
        key: "custom_format_name",
        value: formatName
      },
      changedFields,
      summary: "Update custom format test",
      title: `Update test for custom format "${formatName}"`
    }
  });
}
async function create(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  if (await db2.selectFrom("custom_formats").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) {
    await logger.warn(`Duplicate custom format name "${input.name}"`, {
      source: "CustomFormat",
      meta: {
        databaseId,
        name: input.name
      }
    });
    throw new Error(`A custom format with name "${input.name}" already exists`);
  }
  const normalizedDescription = input.description?.trim() ?? "";
  const includeChanged = input.includeInRename;
  const descriptionChanged = normalizedDescription !== "";
  const uniqueTags = Array.from(new Set(input.tags.map((tag2) => tag2.trim()).filter(Boolean)));
  const groupId = (descriptionChanged ? 1 : 0) + (includeChanged ? 1 : 0) + (uniqueTags.length > 0 ? 1 : 0) > 0 ? uuid() : void 0;
  const formatQueries = [];
  const insertFormat = db2.insertInto("custom_formats").values({
    name: input.name,
    description: ""
  }).compile();
  formatQueries.push(insertFormat);
  const tagQueries = [];
  for (const tagName of uniqueTags) {
    const insertTag = db2.insertInto("tags").values({ name: tagName }).onConflict((oc) => oc.column("name").doNothing()).compile();
    tagQueries.push(insertTag);
    const linkTag = db2.insertInto("custom_format_tags").values({
      custom_format_name: input.name,
      tag_name: tagName
    }).compile();
    tagQueries.push(linkTag);
  }
  const createResult = await writeOperation({
    databaseId,
    layer,
    description: `create-custom-format-${input.name}`,
    queries: formatQueries,
    desiredState: { name: input.name },
    metadata: {
      operation: "create",
      entity: "custom_format",
      name: input.name,
      ...groupId && { groupId }
    }
  });
  if (!createResult.success) return createResult;
  let lastResult = createResult;
  if (descriptionChanged) {
    const descriptionQuery = db2.updateTable("custom_formats").set({ description: normalizedDescription }).where("name", "=", input.name).where("description", "=", "").compile();
    const descriptionResult = await writeOperation({
      databaseId,
      layer,
      description: `update-custom-format-description-${input.name}`,
      queries: [descriptionQuery],
      desiredState: { description: {
        from: "",
        to: normalizedDescription
      } },
      metadata: {
        operation: "update",
        entity: "custom_format",
        name: input.name,
        stableKey: {
          key: "custom_format_name",
          value: input.name
        },
        ...groupId && { groupId },
        changedFields: ["description"],
        summary: "Update custom format description",
        title: `Update description for custom format "${input.name}"`
      }
    });
    if (!descriptionResult.success) return descriptionResult;
    lastResult = descriptionResult;
  }
  if (includeChanged) {
    const includeQuery = db2.updateTable("custom_formats").set({ include_in_rename: 1 }).where("name", "=", input.name).where("include_in_rename", "=", 0).compile();
    const includeResult = await writeOperation({
      databaseId,
      layer,
      description: `update-custom-format-include-rename-${input.name}`,
      queries: [includeQuery],
      desiredState: { include_in_rename: {
        from: false,
        to: true
      } },
      metadata: {
        operation: "update",
        entity: "custom_format",
        name: input.name,
        stableKey: {
          key: "custom_format_name",
          value: input.name
        },
        ...groupId && { groupId },
        changedFields: ["include_in_rename"],
        summary: "Update custom format include in rename",
        title: `Update include in rename for custom format "${input.name}"`
      }
    });
    if (!includeResult.success) return includeResult;
    lastResult = includeResult;
  }
  if (tagQueries.length === 0) return lastResult;
  const tagsResult = await writeOperation({
    databaseId,
    layer,
    description: `update-custom-format-tags-${input.name}`,
    queries: tagQueries,
    desiredState: { tags: uniqueTags },
    metadata: {
      operation: "update",
      entity: "custom_format",
      name: input.name,
      stableKey: {
        key: "custom_format_name",
        value: input.name
      },
      ...groupId && { groupId },
      changedFields: ["tags"],
      summary: "Update custom format tags",
      title: `Update tags for custom format "${input.name}"`
    }
  });
  if (!tagsResult.success) return tagsResult;
  return lastResult;
}
var init_create = __esm({
  async "dist/build/server/chunks/create.js"() {
    "use strict";
    await init_db();
    await init_queueService();
    init_uuid();
    init_registry();
    init_esm();
  }
});

// dist/build/server/chunks/read3.js
async function getById(cache3, formatId) {
  const format = await cache3.kb.selectFrom("custom_formats").select([
    "id",
    "name",
    "description",
    "include_in_rename"
  ]).where("id", "=", formatId).executeTakeFirst();
  if (!format) return null;
  return {
    ...format,
    include_in_rename: format.include_in_rename === 1
  };
}
async function listTests(cache3, formatName) {
  return (await cache3.kb.selectFrom("custom_format_tests").select([
    "custom_format_name",
    "title",
    "type",
    "should_match",
    "description"
  ]).where("custom_format_name", "=", formatName).orderBy("title").execute()).map((test2) => ({
    ...test2,
    should_match: test2.should_match === 1
  }));
}
async function getTest(cache3, formatName, title, type) {
  const test2 = await cache3.kb.selectFrom("custom_format_tests").select([
    "custom_format_name",
    "title",
    "type",
    "should_match",
    "description"
  ]).where("custom_format_name", "=", formatName).where("title", "=", title).where("type", "=", type).executeTakeFirst();
  if (!test2) return null;
  return {
    ...test2,
    should_match: test2.should_match === 1
  };
}
var init_read3 = __esm({
  "dist/build/server/chunks/read3.js"() {
    "use strict";
  }
});

// dist/build/server/chunks/mediaManagement.js
function colonReplacementFromDb(value2) {
  return COLON_REPLACEMENT_FROM_DB[value2] ?? "delete";
}
function colonReplacementToDb(value2) {
  return COLON_REPLACEMENT_TO_DB[value2] ?? 0;
}
function getColonReplacementLabel(value2) {
  return SONARR_COLON_REPLACEMENT_OPTIONS.find((o) => o.value === value2)?.label ?? value2;
}
function multiEpisodeStyleFromDb(value2) {
  return MULTI_EPISODE_FROM_DB[value2] ?? "extend";
}
function multiEpisodeStyleToDb(value2) {
  return MULTI_EPISODE_TO_DB[value2] ?? 0;
}
function getMultiEpisodeStyleLabel(value2) {
  return MULTI_EPISODE_STYLE_OPTIONS.find((o) => o.value === value2)?.label ?? value2;
}
var COLON_REPLACEMENT_FROM_DB, COLON_REPLACEMENT_TO_DB, SONARR_COLON_REPLACEMENT_OPTIONS, MULTI_EPISODE_FROM_DB, MULTI_EPISODE_TO_DB, MULTI_EPISODE_STYLE_OPTIONS, RADARR_COLON_REPLACEMENT_OPTIONS, PROPERS_REPACKS_OPTIONS;
var init_mediaManagement = __esm({
  "dist/build/server/chunks/mediaManagement.js"() {
    "use strict";
    COLON_REPLACEMENT_FROM_DB = {
      0: "delete",
      1: "dash",
      2: "spaceDash",
      3: "spaceDashSpace",
      4: "smart",
      5: "custom"
    };
    COLON_REPLACEMENT_TO_DB = {
      delete: 0,
      dash: 1,
      spaceDash: 2,
      spaceDashSpace: 3,
      smart: 4,
      custom: 5
    };
    SONARR_COLON_REPLACEMENT_OPTIONS = [
      {
        value: "delete",
        label: "Delete"
      },
      {
        value: "dash",
        label: "Replace with Dash"
      },
      {
        value: "spaceDash",
        label: "Replace with Space Dash"
      },
      {
        value: "spaceDashSpace",
        label: "Replace with Space Dash Space"
      },
      {
        value: "smart",
        label: "Smart Replace"
      },
      {
        value: "custom",
        label: "Custom"
      }
    ];
    MULTI_EPISODE_FROM_DB = {
      0: "extend",
      1: "duplicate",
      2: "repeat",
      3: "scene",
      4: "range",
      5: "prefixedRange"
    };
    MULTI_EPISODE_TO_DB = {
      extend: 0,
      duplicate: 1,
      repeat: 2,
      scene: 3,
      range: 4,
      prefixedRange: 5
    };
    MULTI_EPISODE_STYLE_OPTIONS = [
      {
        value: "extend",
        label: "Extend"
      },
      {
        value: "duplicate",
        label: "Duplicate"
      },
      {
        value: "repeat",
        label: "Repeat"
      },
      {
        value: "scene",
        label: "Scene"
      },
      {
        value: "range",
        label: "Range"
      },
      {
        value: "prefixedRange",
        label: "Prefixed Range"
      }
    ];
    RADARR_COLON_REPLACEMENT_OPTIONS = [
      {
        value: "delete",
        label: "Delete"
      },
      {
        value: "dash",
        label: "Replace with Dash"
      },
      {
        value: "spaceDash",
        label: "Replace with Space Dash"
      },
      {
        value: "spaceDashSpace",
        label: "Replace with Space Dash Space"
      },
      {
        value: "smart",
        label: "Smart Replace"
      }
    ];
    PROPERS_REPACKS_OPTIONS = [
      {
        value: "doNotPrefer",
        label: "Do Not Prefer",
        description: "Propers and repacks are not preferred over existing files"
      },
      {
        value: "preferAndUpgrade",
        label: "Prefer and Upgrade",
        description: "Automatically upgrade to propers and repacks when available"
      },
      {
        value: "doNotUpgradeAutomatically",
        label: "Do Not Upgrade Automatically",
        description: "Prefer propers/repacks but do not automatically upgrade"
      }
    ];
  }
});

// dist/build/server/chunks/update.js
async function updateRadarrNaming(options2) {
  const { databaseId, cache: cache3, layer, current: current3, input } = options2;
  const db2 = cache3.kb;
  if (input.name !== current3.name) {
    if (await db2.selectFrom("radarr_naming").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) throw new Error(`A radarr naming config with name "${input.name}" already exists`);
  }
  const changes = [];
  if (current3.rename !== input.rename) changes.push({
    field: "rename",
    from: current3.rename,
    to: input.rename,
    setValue: input.rename ? 1 : 0,
    guardValue: current3.rename ? 1 : 0
  });
  if (current3.movie_format !== input.movieFormat) changes.push({
    field: "movie_format",
    from: current3.movie_format,
    to: input.movieFormat,
    setValue: input.movieFormat,
    guardValue: current3.movie_format
  });
  if (current3.movie_folder_format !== input.movieFolderFormat) changes.push({
    field: "movie_folder_format",
    from: current3.movie_folder_format,
    to: input.movieFolderFormat,
    setValue: input.movieFolderFormat,
    guardValue: current3.movie_folder_format
  });
  if (current3.replace_illegal_characters !== input.replaceIllegalCharacters) changes.push({
    field: "replace_illegal_characters",
    from: current3.replace_illegal_characters,
    to: input.replaceIllegalCharacters,
    setValue: input.replaceIllegalCharacters ? 1 : 0,
    guardValue: current3.replace_illegal_characters ? 1 : 0
  });
  if (current3.colon_replacement_format !== input.colonReplacementFormat) changes.push({
    field: "colon_replacement_format",
    from: current3.colon_replacement_format,
    to: input.colonReplacementFormat,
    setValue: input.colonReplacementFormat,
    guardValue: current3.colon_replacement_format
  });
  if (current3.name !== input.name) changes.push({
    field: "name",
    from: current3.name,
    to: input.name,
    setValue: input.name,
    guardValue: current3.name
  });
  if (changes.length === 0) return { success: true };
  const groupId = changes.length > 1 ? uuid() : void 0;
  let lastResult = null;
  for (let index88 = 0; index88 < changes.length; index88++) {
    const change = changes[index88];
    const isRename = change.field === "name";
    const result = await writeOperation({
      databaseId,
      layer,
      description: `update-radarr-naming-${change.field}-${input.name}`,
      queries: [buildRadarrUpdateQuery(cache3, current3, change)],
      desiredState: { [change.field]: {
        from: change.from,
        to: change.to
      } },
      metadata: {
        operation: "update",
        entity: "radarr_naming",
        name: input.name,
        ...isRename && { previousName: current3.name },
        stableKey: {
          key: "radarr_naming_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: [change.field],
        summary: isRename ? "Rename Radarr naming config" : "Update Radarr naming config",
        title: isRename ? `Rename Radarr naming "${current3.name}"` : `Update Radarr naming "${input.name}"`
      },
      skipRecompile: index88 < changes.length - 1
    });
    if (!result.success) return result;
    lastResult = result;
  }
  return lastResult ?? { success: true };
}
function buildRadarrUpdateQuery(cache3, current3, change) {
  const setValues = { [change.field]: change.setValue };
  let query = cache3.kb.updateTable("radarr_naming").set(setValues).where("name", "=", current3.name);
  if (change.field !== "name") query = query.where(change.field, "=", change.guardValue);
  return query.compile();
}
async function updateSonarrNaming(options2) {
  const { databaseId, cache: cache3, layer, current: current3, input } = options2;
  const db2 = cache3.kb;
  if (input.name !== current3.name) {
    if (await db2.selectFrom("sonarr_naming").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) throw new Error(`A sonarr naming config with name "${input.name}" already exists`);
  }
  const changes = [];
  if (current3.rename !== input.rename) changes.push({
    field: "rename",
    from: current3.rename,
    to: input.rename,
    setValue: input.rename ? 1 : 0,
    guardValue: current3.rename ? 1 : 0
  });
  if (current3.standard_episode_format !== input.standardEpisodeFormat) changes.push({
    field: "standard_episode_format",
    from: current3.standard_episode_format,
    to: input.standardEpisodeFormat,
    setValue: input.standardEpisodeFormat,
    guardValue: current3.standard_episode_format
  });
  if (current3.daily_episode_format !== input.dailyEpisodeFormat) changes.push({
    field: "daily_episode_format",
    from: current3.daily_episode_format,
    to: input.dailyEpisodeFormat,
    setValue: input.dailyEpisodeFormat,
    guardValue: current3.daily_episode_format
  });
  if (current3.anime_episode_format !== input.animeEpisodeFormat) changes.push({
    field: "anime_episode_format",
    from: current3.anime_episode_format,
    to: input.animeEpisodeFormat,
    setValue: input.animeEpisodeFormat,
    guardValue: current3.anime_episode_format
  });
  if (current3.series_folder_format !== input.seriesFolderFormat) changes.push({
    field: "series_folder_format",
    from: current3.series_folder_format,
    to: input.seriesFolderFormat,
    setValue: input.seriesFolderFormat,
    guardValue: current3.series_folder_format
  });
  if (current3.season_folder_format !== input.seasonFolderFormat) changes.push({
    field: "season_folder_format",
    from: current3.season_folder_format,
    to: input.seasonFolderFormat,
    setValue: input.seasonFolderFormat,
    guardValue: current3.season_folder_format
  });
  if (current3.replace_illegal_characters !== input.replaceIllegalCharacters) changes.push({
    field: "replace_illegal_characters",
    from: current3.replace_illegal_characters,
    to: input.replaceIllegalCharacters,
    setValue: input.replaceIllegalCharacters ? 1 : 0,
    guardValue: current3.replace_illegal_characters ? 1 : 0
  });
  if (current3.colon_replacement_format !== input.colonReplacementFormat) changes.push({
    field: "colon_replacement_format",
    from: current3.colon_replacement_format,
    to: input.colonReplacementFormat,
    setValue: colonReplacementToDb(input.colonReplacementFormat),
    guardValue: colonReplacementToDb(current3.colon_replacement_format)
  });
  if (current3.custom_colon_replacement_format !== input.customColonReplacementFormat) changes.push({
    field: "custom_colon_replacement_format",
    from: current3.custom_colon_replacement_format,
    to: input.customColonReplacementFormat,
    setValue: input.customColonReplacementFormat,
    guardValue: current3.custom_colon_replacement_format
  });
  if (current3.multi_episode_style !== input.multiEpisodeStyle) changes.push({
    field: "multi_episode_style",
    from: current3.multi_episode_style,
    to: input.multiEpisodeStyle,
    setValue: multiEpisodeStyleToDb(input.multiEpisodeStyle),
    guardValue: multiEpisodeStyleToDb(current3.multi_episode_style)
  });
  if (current3.name !== input.name) changes.push({
    field: "name",
    from: current3.name,
    to: input.name,
    setValue: input.name,
    guardValue: current3.name
  });
  if (changes.length === 0) return { success: true };
  const groupId = changes.length > 1 ? uuid() : void 0;
  let lastResult = null;
  for (let index88 = 0; index88 < changes.length; index88++) {
    const change = changes[index88];
    const isRename = change.field === "name";
    const result = await writeOperation({
      databaseId,
      layer,
      description: `update-sonarr-naming-${change.field}-${input.name}`,
      queries: [buildSonarrUpdateQuery(cache3, current3, change)],
      desiredState: { [change.field]: {
        from: change.from,
        to: change.to
      } },
      metadata: {
        operation: "update",
        entity: "sonarr_naming",
        name: input.name,
        ...isRename && { previousName: current3.name },
        stableKey: {
          key: "sonarr_naming_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: [change.field],
        summary: isRename ? "Rename Sonarr naming config" : "Update Sonarr naming config",
        title: isRename ? `Rename Sonarr naming "${current3.name}"` : `Update Sonarr naming "${input.name}"`
      },
      skipRecompile: index88 < changes.length - 1
    });
    if (!result.success) return result;
    lastResult = result;
  }
  return lastResult ?? { success: true };
}
function buildSonarrUpdateQuery(cache3, current3, change) {
  const setValues = { [change.field]: change.setValue };
  let query = cache3.kb.updateTable("sonarr_naming").set(setValues).where("name", "=", current3.name);
  if (change.field === "name") return query.compile();
  if (change.field === "custom_colon_replacement_format" && change.guardValue === null) query = query.where("custom_colon_replacement_format", "is", null);
  else query = query.where(change.field, "=", change.guardValue);
  return query.compile();
}
var init_update = __esm({
  async "dist/build/server/chunks/update.js"() {
    "use strict";
    await init_queueService();
    init_uuid();
    init_mediaManagement();
  }
});

// dist/build/server/chunks/update2.js
async function updateRadarrMediaSettings(options2) {
  return updateMediaSettings({
    ...options2,
    config: RADARR_CONFIG
  });
}
async function updateSonarrMediaSettings(options2) {
  return updateMediaSettings({
    ...options2,
    config: SONARR_CONFIG
  });
}
async function updateMediaSettings(options2) {
  const { databaseId, cache: cache3, layer, current: current3, input, config: config2 } = options2;
  const db2 = cache3.kb;
  if (input.name !== current3.name) {
    if (await db2.selectFrom(config2.table).where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) throw new Error(`A ${config2.arrType} media settings config with name "${input.name}" already exists`);
  }
  const changes = [];
  if (current3.propers_repacks !== input.propersRepacks) changes.push({
    field: "propers_repacks",
    from: current3.propers_repacks,
    to: input.propersRepacks,
    setValue: input.propersRepacks,
    guardValue: current3.propers_repacks
  });
  if (current3.enable_media_info !== input.enableMediaInfo) changes.push({
    field: "enable_media_info",
    from: current3.enable_media_info,
    to: input.enableMediaInfo,
    setValue: input.enableMediaInfo ? 1 : 0,
    guardValue: current3.enable_media_info ? 1 : 0
  });
  if (current3.name !== input.name) changes.push({
    field: "name",
    from: current3.name,
    to: input.name,
    setValue: input.name,
    guardValue: current3.name
  });
  if (changes.length === 0) return { success: true };
  const groupId = changes.length > 1 ? uuid() : void 0;
  let lastResult = null;
  for (let index88 = 0; index88 < changes.length; index88++) {
    const change = changes[index88];
    const isRename = change.field === "name";
    const result = await writeOperation({
      databaseId,
      layer,
      description: `update-${config2.arrType}-media-settings-${change.field}-${input.name}`,
      queries: [buildUpdateQuery(cache3, config2.table, current3, change)],
      desiredState: { [change.field]: {
        from: change.from,
        to: change.to
      } },
      metadata: {
        operation: "update",
        entity: config2.entity,
        name: input.name,
        ...isRename && { previousName: current3.name },
        stableKey: {
          key: config2.stableKey,
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: [change.field],
        summary: isRename ? `Rename ${config2.label} media settings` : `Update ${config2.label} media settings`,
        title: isRename ? `Rename ${config2.label} media settings "${current3.name}"` : `Update ${config2.label} media settings "${input.name}"`
      },
      skipRecompile: index88 < changes.length - 1
    });
    if (!result.success) return result;
    lastResult = result;
  }
  return lastResult ?? { success: true };
}
function buildUpdateQuery(cache3, table2, current3, change) {
  if (table2 === "radarr_media_settings") {
    const setValues2 = { [change.field]: change.setValue };
    let query2 = cache3.kb.updateTable("radarr_media_settings").set(setValues2).where("name", "=", current3.name);
    if (change.field !== "name") query2 = query2.where(change.field, "=", change.guardValue);
    return query2.compile();
  }
  const setValues = { [change.field]: change.setValue };
  let query = cache3.kb.updateTable("sonarr_media_settings").set(setValues).where("name", "=", current3.name);
  if (change.field !== "name") query = query.where(change.field, "=", change.guardValue);
  return query.compile();
}
var RADARR_CONFIG, SONARR_CONFIG;
var init_update2 = __esm({
  async "dist/build/server/chunks/update2.js"() {
    "use strict";
    await init_queueService();
    init_uuid();
    RADARR_CONFIG = {
      table: "radarr_media_settings",
      entity: "radarr_media_settings",
      stableKey: "radarr_media_settings_name",
      arrType: "radarr",
      label: "Radarr"
    };
    SONARR_CONFIG = {
      table: "sonarr_media_settings",
      entity: "sonarr_media_settings",
      stableKey: "sonarr_media_settings_name",
      arrType: "sonarr",
      label: "Sonarr"
    };
  }
});

// dist/build/server/chunks/update3.js
async function updateRadarrQualityDefinitions(options2) {
  return updateQualityDefinitions({
    ...options2,
    config: RADARR_CONFIG2
  });
}
async function updateSonarrQualityDefinitions(options2) {
  return updateQualityDefinitions({
    ...options2,
    config: SONARR_CONFIG2
  });
}
async function updateQualityDefinitions(options2) {
  const { databaseId, cache: cache3, layer, current: current3, input, config: config2 } = options2;
  const db2 = cache3.kb;
  ensureUniqueEntries(input.entries);
  if (input.name !== current3.name) {
    if (await db2.selectFrom(config2.table).where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) throw new Error(`A ${config2.label.toLowerCase()} quality definitions config with name "${input.name}" already exists`);
  }
  const changes = collectTierChanges(current3.entries, input.entries);
  if (current3.name !== input.name) changes.push({
    kind: "name",
    from: current3.name,
    to: input.name
  });
  if (changes.length === 0) return { success: true };
  const groupId = changes.length > 1 ? uuid() : void 0;
  let lastResult = null;
  for (let index88 = 0; index88 < changes.length; index88++) {
    const change = changes[index88];
    const result = await writeOperation({
      databaseId,
      layer,
      description: change.kind === "name" ? `update-${config2.label.toLowerCase()}-quality-definitions-name-${input.name}` : `update-${config2.label.toLowerCase()}-quality-definitions-${change.qualityName}-${input.name}`,
      queries: [buildUpdateQuery2(cache3, config2.table, current3.name, change)],
      desiredState: buildDesiredState(change),
      metadata: buildMetadata(change, config2, current3.name, input.name, groupId),
      skipRecompile: index88 < changes.length - 1
    });
    if (!result.success) return result;
    lastResult = result;
  }
  return lastResult ?? { success: true };
}
function collectTierChanges(current3, next2) {
  const currentByName = new Map(current3.map((entry) => [entry.quality_name, entry]));
  const changes = [];
  for (const nextEntry of next2) {
    const currentEntry = currentByName.get(nextEntry.quality_name);
    if (!currentEntry) continue;
    const changedFields = [];
    if (currentEntry.min_size !== nextEntry.min_size) changedFields.push("min_size");
    if (currentEntry.max_size !== nextEntry.max_size) changedFields.push("max_size");
    if (currentEntry.preferred_size !== nextEntry.preferred_size) changedFields.push("preferred_size");
    if (changedFields.length === 0) continue;
    changes.push({
      kind: "tier",
      qualityName: nextEntry.quality_name,
      changedFields,
      from: {
        min_size: currentEntry.min_size,
        max_size: currentEntry.max_size,
        preferred_size: currentEntry.preferred_size
      },
      to: {
        min_size: nextEntry.min_size,
        max_size: nextEntry.max_size,
        preferred_size: nextEntry.preferred_size
      }
    });
  }
  return changes;
}
function buildUpdateQuery2(cache3, table2, currentName, change) {
  if (change.kind === "name") {
    if (table2 === "radarr_quality_definitions") return cache3.kb.updateTable("radarr_quality_definitions").set({ name: change.to }).where("name", "=", change.from).compile();
    return cache3.kb.updateTable("sonarr_quality_definitions").set({ name: change.to }).where("name", "=", change.from).compile();
  }
  if (table2 === "radarr_quality_definitions") return cache3.kb.updateTable("radarr_quality_definitions").set({
    min_size: change.to.min_size,
    max_size: change.to.max_size,
    preferred_size: change.to.preferred_size
  }).where("name", "=", currentName).where("quality_name", "=", change.qualityName).where("min_size", "=", change.from.min_size).where("max_size", "=", change.from.max_size).where("preferred_size", "=", change.from.preferred_size).compile();
  return cache3.kb.updateTable("sonarr_quality_definitions").set({
    min_size: change.to.min_size,
    max_size: change.to.max_size,
    preferred_size: change.to.preferred_size
  }).where("name", "=", currentName).where("quality_name", "=", change.qualityName).where("min_size", "=", change.from.min_size).where("max_size", "=", change.from.max_size).where("preferred_size", "=", change.from.preferred_size).compile();
}
function buildDesiredState(change) {
  if (change.kind === "name") return { name: {
    from: change.from,
    to: change.to
  } };
  const desired = {};
  for (const field of change.changedFields) desired[field] = {
    from: change.from[field],
    to: change.to[field]
  };
  return desired;
}
function buildMetadata(change, config2, currentName, inputName, groupId) {
  if (change.kind === "name") return {
    operation: "update",
    entity: config2.table,
    name: inputName,
    previousName: currentName,
    stableKey: {
      key: config2.stableKey,
      value: currentName
    },
    ...groupId && { groupId },
    changedFields: ["name"],
    summary: `Rename ${config2.label} quality definitions`,
    title: `Rename ${config2.label} quality definitions "${currentName}"`
  };
  return {
    operation: "update",
    entity: config2.table,
    name: inputName,
    stableKey: {
      key: config2.stableKey,
      value: currentName
    },
    qualityName: change.qualityName,
    ...groupId && { groupId },
    changedFields: change.changedFields,
    summary: `Update ${config2.label} quality definitions`,
    title: `Update ${config2.label} quality definitions "${inputName}" tier "${change.qualityName}"`
  };
}
function ensureUniqueEntries(entries) {
  const normalized = entries.map((entry) => entry.quality_name.trim().toLowerCase());
  if (new Set(normalized).size !== normalized.length) throw new Error("Quality definitions cannot contain duplicate quality names");
}
var RADARR_CONFIG2, SONARR_CONFIG2;
var init_update3 = __esm({
  async "dist/build/server/chunks/update3.js"() {
    "use strict";
    await init_queueService();
    init_uuid();
    RADARR_CONFIG2 = {
      table: "radarr_quality_definitions",
      stableKey: "radarr_quality_definitions_name",
      label: "Radarr"
    };
    SONARR_CONFIG2 = {
      table: "sonarr_quality_definitions",
      stableKey: "sonarr_quality_definitions_name",
      label: "Sonarr"
    };
  }
});

// dist/build/server/chunks/update4.js
async function list(cache3) {
  const db2 = cache3.kb;
  const expressions = await db2.selectFrom("regular_expressions").select([
    "id",
    "name",
    "pattern",
    "regex101_id",
    "description",
    "created_at",
    "updated_at"
  ]).orderBy(sql`name COLLATE NOCASE`).execute();
  if (expressions.length === 0) return [];
  const expressionNames = expressions.map((e) => e.name);
  const referenceCounts = await getConditionRefCountsForRegexes(cache3, expressionNames);
  const allTags = await db2.selectFrom("regular_expression_tags as ret").innerJoin("tags as t", "t.name", "ret.tag_name").select([
    "ret.regular_expression_name",
    "t.name as tag_name",
    "t.created_at as tag_created_at"
  ]).where("ret.regular_expression_name", "in", expressionNames).orderBy("ret.regular_expression_name").orderBy("t.name").execute();
  const tagsMap = /* @__PURE__ */ new Map();
  for (const tag2 of allTags) {
    if (!tagsMap.has(tag2.regular_expression_name)) tagsMap.set(tag2.regular_expression_name, []);
    tagsMap.get(tag2.regular_expression_name).push({
      name: tag2.tag_name,
      created_at: tag2.tag_created_at
    });
  }
  return expressions.map((expression) => ({
    ...expression,
    tags: tagsMap.get(expression.name) || [],
    referenceCount: referenceCounts.get(expression.name) || 0
  }));
}
async function get2(cache3, id) {
  const db2 = cache3.kb;
  const regex = await db2.selectFrom("regular_expressions").select([
    "id",
    "name",
    "pattern",
    "regex101_id",
    "description",
    "created_at",
    "updated_at"
  ]).where("id", "=", id).executeTakeFirst();
  if (!regex) return null;
  const tags = await db2.selectFrom("regular_expression_tags as ret").innerJoin("tags as t", "t.name", "ret.tag_name").select(["t.name", "t.created_at"]).where("ret.regular_expression_name", "=", regex.name).execute();
  const referenceCounts = await getConditionRefCountsForRegexes(cache3, [regex.name]);
  return {
    ...regex,
    tags,
    referenceCount: referenceCounts.get(regex.name) || 0
  };
}
function esc2(value2) {
  return value2.replace(/'/g, "''");
}
async function update(options2) {
  const { databaseId, cache: cache3, layer, current: current3, input } = options2;
  const db2 = cache3.kb;
  const isRename = input.name !== current3.name;
  if (isRename) {
    if (await db2.selectFrom("regular_expressions").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) {
      await logger.warn(`Duplicate regular expression name "${input.name}"`, {
        source: "RegularExpression",
        meta: {
          databaseId,
          name: input.name
        }
      });
      throw new Error(`A regular expression with name "${input.name}" already exists`);
    }
  }
  const rawCurrentDescription = current3.description;
  const normalizedCurrentDescription = rawCurrentDescription?.trim() ?? "";
  const normalizedNextDescription = input.description?.trim() ?? "";
  const rawCurrentRegex101Id = current3.regex101_id;
  const normalizedCurrentRegex101Id = rawCurrentRegex101Id?.trim() ?? "";
  const normalizedNextRegex101Id = input.regex101Id?.trim() ?? "";
  const descriptionChanged = normalizedCurrentDescription !== normalizedNextDescription;
  const regex101Changed = normalizedCurrentRegex101Id !== normalizedNextRegex101Id;
  const patternChanged = current3.pattern !== input.pattern;
  const descriptionNext = normalizedNextDescription === "" ? null : normalizedNextDescription;
  const regex101Next = normalizedNextRegex101Id === "" ? null : normalizedNextRegex101Id;
  const descriptionQueries = [];
  if (descriptionChanged) {
    let updateDescription = db2.updateTable("regular_expressions").set({ description: descriptionNext }).where("name", "=", current3.name);
    if (rawCurrentDescription === null) updateDescription = updateDescription.where("description", "is", null);
    else updateDescription = updateDescription.where("description", "=", rawCurrentDescription);
    descriptionQueries.push(updateDescription.compile());
  }
  const regex101Queries = [];
  if (regex101Changed) {
    let updateRegex101 = db2.updateTable("regular_expressions").set({ regex101_id: regex101Next }).where("name", "=", current3.name);
    if (rawCurrentRegex101Id === null) updateRegex101 = updateRegex101.where("regex101_id", "is", null);
    else updateRegex101 = updateRegex101.where("regex101_id", "=", rawCurrentRegex101Id);
    regex101Queries.push(updateRegex101.compile());
  }
  const patternQueries = [];
  if (patternChanged) {
    const updatePattern = db2.updateTable("regular_expressions").set({ pattern: input.pattern }).where("name", "=", current3.name).where("pattern", "=", current3.pattern);
    patternQueries.push(updatePattern.compile());
  }
  const renameQueries = [];
  if (isRename) {
    const updateName = db2.updateTable("regular_expressions").set({ name: input.name }).where("name", "=", current3.name);
    renameQueries.push(updateName.compile());
  }
  const currentTagNames = current3.tags.map((t2) => t2.name);
  const newTagNames = Array.from(new Set(input.tags.map((tag2) => tag2.trim()).filter(Boolean)));
  const regexNameForTags = current3.name;
  const tagsToRemove = currentTagNames.filter((t2) => !newTagNames.includes(t2));
  const tagsToAdd = newTagNames.filter((t2) => !currentTagNames.includes(t2));
  const tagQueries = [];
  for (const tagName of tagsToRemove) {
    const removeTag = {
      sql: `DELETE FROM regular_expression_tags WHERE regular_expression_name = '${esc2(regexNameForTags)}' AND tag_name = '${esc2(tagName)}'`,
      parameters: [],
      query: {}
    };
    tagQueries.push(removeTag);
  }
  for (const tagName of tagsToAdd) {
    const insertTag = db2.insertInto("tags").values({ name: tagName }).onConflict((oc) => oc.column("name").doNothing()).compile();
    tagQueries.push(insertTag);
    const linkTag = {
      sql: `INSERT INTO regular_expression_tags (regular_expression_name, tag_name) VALUES ('${esc2(regexNameForTags)}', '${esc2(tagName)}')`,
      parameters: [],
      query: {}
    };
    tagQueries.push(linkTag);
  }
  const dependentOps = [];
  if (isRename) {
    const dependentConditions = await db2.selectFrom("condition_patterns as cp").innerJoin("custom_format_conditions as cfc", (join4) => join4.onRef("cfc.custom_format_name", "=", "cp.custom_format_name").onRef("cfc.name", "=", "cp.condition_name")).select([
      "cp.custom_format_name",
      "cp.condition_name",
      "cfc.type",
      "cfc.arr_type",
      "cfc.negate",
      "cfc.required"
    ]).where("cp.regular_expression_name", "=", current3.name).orderBy("cp.custom_format_name").orderBy("cp.condition_name").execute();
    const conditionsByFormat = /* @__PURE__ */ new Map();
    for (const condition of dependentConditions) {
      if (!conditionsByFormat.has(condition.custom_format_name)) conditionsByFormat.set(condition.custom_format_name, []);
      conditionsByFormat.get(condition.custom_format_name).push(condition);
    }
    const patternForDependents = patternChanged ? input.pattern : current3.pattern;
    const cascadeNameCandidates = Array.from(/* @__PURE__ */ new Set([current3.name, input.name]));
    for (const [formatName, conditions] of conditionsByFormat.entries()) {
      const conditionQueries = conditions.map((condition) => db2.updateTable("condition_patterns").set({ regular_expression_name: input.name }).where("custom_format_name", "=", condition.custom_format_name).where("condition_name", "=", condition.condition_name).where("regular_expression_name", "in", cascadeNameCandidates).compile());
      const updatedConditions = conditions.map((condition) => ({
        name: condition.condition_name,
        base: {
          from: {
            type: condition.type,
            arrType: condition.arr_type,
            negate: !!condition.negate,
            required: !!condition.required
          },
          to: {
            type: condition.type,
            arrType: condition.arr_type,
            negate: !!condition.negate,
            required: !!condition.required
          }
        },
        values: {
          from: { patterns: [{
            name: current3.name,
            pattern: current3.pattern
          }] },
          to: { patterns: [{
            name: input.name,
            pattern: patternForDependents
          }] }
        }
      }));
      if (conditionQueries.length > 0) dependentOps.push({
        formatName,
        queries: conditionQueries,
        updatedConditions
      });
    }
  }
  const changes = {};
  if (isRename) changes.name = {
    from: current3.name,
    to: input.name
  };
  if (patternChanged) changes.pattern = {
    from: current3.pattern,
    to: input.pattern
  };
  if (descriptionChanged) changes.description = {
    from: rawCurrentDescription ?? null,
    to: descriptionNext
  };
  if (regex101Changed) changes.regex101_id = {
    from: rawCurrentRegex101Id ?? null,
    to: regex101Next
  };
  if (tagsToAdd.length > 0 || tagsToRemove.length > 0) changes.tags = {
    from: currentTagNames,
    to: newTagNames
  };
  const hasDescriptionChanges = descriptionQueries.length > 0;
  const hasRegex101Changes = regex101Queries.length > 0;
  const hasPatternChanges = patternQueries.length > 0;
  const hasTagChanges = tagQueries.length > 0;
  const hasRenameChanges = renameQueries.length > 0;
  const opCount = [
    hasDescriptionChanges,
    hasRegex101Changes,
    hasPatternChanges,
    hasTagChanges,
    hasRenameChanges
  ].filter(Boolean).length;
  const groupId = opCount > 1 || hasRenameChanges && dependentOps.length > 0 ? uuid() : void 0;
  if (opCount === 0) return { success: true };
  await logger.info(`Save regular expression "${input.name}"`, {
    source: "RegularExpression",
    meta: {
      id: current3.id,
      changes
    }
  });
  let lastResult = null;
  if (hasDescriptionChanges) {
    const descriptionResult = await writeOperation({
      databaseId,
      layer,
      description: `update-regular-expression-description-${current3.name}`,
      queries: descriptionQueries,
      desiredState: { description: {
        from: rawCurrentDescription ?? null,
        to: descriptionNext
      } },
      metadata: {
        operation: "update",
        entity: "regular_expression",
        name: current3.name,
        stableKey: {
          key: "regular_expression_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: ["description"],
        summary: "Update regular expression description",
        title: `Update description for regular expression "${current3.name}"`
      }
    });
    if (!descriptionResult.success) return descriptionResult;
    lastResult = descriptionResult;
  }
  if (hasRegex101Changes) {
    const regex101Result = await writeOperation({
      databaseId,
      layer,
      description: `update-regular-expression-regex101-${current3.name}`,
      queries: regex101Queries,
      desiredState: { regex101_id: {
        from: rawCurrentRegex101Id ?? null,
        to: regex101Next
      } },
      metadata: {
        operation: "update",
        entity: "regular_expression",
        name: current3.name,
        stableKey: {
          key: "regular_expression_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: ["regex101_id"],
        summary: "Update regular expression regex101 link",
        title: `Update regex101 link for regular expression "${current3.name}"`
      }
    });
    if (!regex101Result.success) return regex101Result;
    lastResult = regex101Result;
  }
  if (hasPatternChanges) {
    const patternResult = await writeOperation({
      databaseId,
      layer,
      description: `update-regular-expression-pattern-${current3.name}`,
      queries: patternQueries,
      desiredState: { pattern: {
        from: current3.pattern,
        to: input.pattern
      } },
      metadata: {
        operation: "update",
        entity: "regular_expression",
        name: current3.name,
        stableKey: {
          key: "regular_expression_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: ["pattern"],
        summary: "Update regular expression pattern",
        title: `Update pattern for regular expression "${current3.name}"`
      }
    });
    if (!patternResult.success) return patternResult;
    lastResult = patternResult;
  }
  if (hasTagChanges) {
    const tagsResult = await writeOperation({
      databaseId,
      layer,
      description: `update-regular-expression-tags-${current3.name}`,
      queries: tagQueries,
      desiredState: { tags: {
        add: tagsToAdd,
        remove: tagsToRemove
      } },
      metadata: {
        operation: "update",
        entity: "regular_expression",
        name: current3.name,
        stableKey: {
          key: "regular_expression_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: ["tags"],
        summary: "Update regular expression tags",
        title: `Update tags for regular expression "${current3.name}"`
      }
    });
    if (!tagsResult.success) return tagsResult;
    lastResult = tagsResult;
  }
  if (hasRenameChanges) {
    const renameResult = await writeOperation({
      databaseId,
      layer,
      description: `update-regular-expression-name-${input.name}`,
      queries: renameQueries,
      desiredState: { name: {
        from: current3.name,
        to: input.name
      } },
      metadata: {
        operation: "update",
        entity: "regular_expression",
        name: input.name,
        previousName: current3.name,
        stableKey: {
          key: "regular_expression_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: ["name"],
        summary: "Rename regular expression",
        title: `Rename regular expression "${current3.name}"`
      }
    });
    if (!renameResult.success) return renameResult;
    lastResult = renameResult;
  }
  if (!hasRenameChanges || dependentOps.length === 0 || !groupId) return lastResult ?? { success: true };
  for (const op of dependentOps) {
    const conditionResult = await writeOperation({
      databaseId,
      layer,
      description: `update-conditions-${op.formatName}`,
      queries: op.queries,
      desiredState: { conditions: { updated: op.updatedConditions } },
      metadata: {
        operation: "update",
        entity: "custom_format",
        name: op.formatName,
        stableKey: {
          key: "custom_format_name",
          value: op.formatName
        },
        groupId,
        generated: true,
        dependsOn: [{
          entity: "regular_expression",
          key: "regular_expression_name",
          value: input.name
        }],
        changedFields: ["conditions"],
        summary: "Update custom format conditions",
        title: `Update conditions for custom format "${op.formatName}"`
      }
    });
    if (!conditionResult.success) return conditionResult;
  }
  return lastResult ?? { success: true };
}
var init_update4 = __esm({
  async "dist/build/server/chunks/update4.js"() {
    "use strict";
    await init_db();
    await init_queueService();
    init_uuid();
    init_esm();
  }
});

// dist/build/server/chunks/override.js
async function resolveFormatName(cache3, databaseId, metadata, desiredState) {
  const candidates = [
    metadata?.stable_key?.value,
    metadata?.name,
    getDesiredTo(desiredState?.name),
    typeof desiredState?.name === "string" ? desiredState.name : null
  ].filter((v3) => typeof v3 === "string" && v3.length > 0);
  if (candidates.length === 0) return null;
  for (const name of candidates) {
    const row = await cache3.kb.selectFrom("custom_formats").select("name").where("name", "=", name).executeTakeFirst();
    if (row) return row.name;
  }
  const resolved = followRenameChain(databaseId, "custom_format", candidates[0]);
  if (resolved !== candidates[0]) {
    const row = await cache3.kb.selectFrom("custom_formats").select("name").where("name", "=", resolved).executeTakeFirst();
    if (row) return row.name;
  }
  return null;
}
function resolveBoolean$3(value2, fallback2) {
  if (typeof value2 === "boolean") return value2;
  if (typeof value2 === "number") return value2 === 1;
  if (typeof value2 === "string") {
    if (value2 === "1" || value2.toLowerCase() === "true") return true;
    if (value2 === "0" || value2.toLowerCase() === "false") return false;
  }
  return fallback2;
}
function resolveTags$2(current3, desiredState) {
  const desiredTags = desiredState.tags;
  if (Array.isArray(desiredTags)) return normalizeTags(desiredTags);
  if (desiredTags && typeof desiredTags === "object") {
    const add = Array.isArray(desiredTags.add) ? desiredTags.add.map((tag2) => String(tag2)) : [];
    const remove5 = Array.isArray(desiredTags.remove) ? desiredTags.remove.map((tag2) => String(tag2)) : [];
    const set3 = new Set(current3);
    for (const tag2 of remove5) set3.delete(tag2);
    for (const tag2 of add) set3.add(tag2);
    return Array.from(set3);
  }
  return current3;
}
async function overrideGeneral$1(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const formatName = await resolveFormatName(cache3, databaseId, metadata, desiredState);
  const fallbackName = metadata?.stable_key?.value ?? metadata?.name ?? getDesiredTo(desiredState?.name) ?? (typeof desiredState?.name === "string" ? desiredState.name : null);
  if (!formatName && !fallbackName) return {
    success: false,
    error: "Custom format not found for override"
  };
  const formatRow = formatName ? await cache3.kb.selectFrom("custom_formats").select(["id", "name"]).where("name", "=", formatName).executeTakeFirst() : void 0;
  const desiredNameRaw = getDesiredTo(desiredState.name) ?? (typeof desiredState.name === "string" ? desiredState.name : formatName ?? fallbackName ?? "");
  const desiredDescriptionRaw = getDesiredTo(desiredState.description) ?? (typeof desiredState.description === "string" || desiredState.description === null ? desiredState.description : void 0);
  const desiredIncludeRaw = getDesiredTo(desiredState.include_in_rename) ?? desiredState.include_in_rename;
  const desiredTags = resolveTags$2([], desiredState);
  if (!formatRow) {
    const createName = desiredNameRaw || fallbackName || formatName || "";
    if (!createName) return {
      success: false,
      error: "Custom format not found for override"
    };
    const createInclude = resolveBoolean$3(desiredIncludeRaw, false);
    return create({
      databaseId,
      cache: cache3,
      layer: "user",
      input: {
        name: createName,
        description: normalizeText(desiredDescriptionRaw ?? ""),
        includeInRename: createInclude,
        tags: desiredTags
      }
    });
  }
  const current3 = await general2(cache3, formatRow.id);
  if (!current3) return {
    success: false,
    error: "Custom format not found for override"
  };
  const currentTags = current3.tags.map((tag2) => tag2.name);
  const resolvedTags = resolveTags$2(currentTags, desiredState);
  const desiredName = desiredNameRaw !== void 0 || typeof desiredState.name === "string" ? desiredNameRaw : current3.name;
  const desiredDescription = desiredDescriptionRaw !== void 0 || typeof desiredState.description === "string" || desiredState.description === null ? desiredDescriptionRaw : current3.description ?? null;
  const desiredInclude = desiredIncludeRaw !== void 0 || typeof desiredState.include_in_rename === "boolean" || typeof desiredState.include_in_rename === "number" || typeof desiredState.include_in_rename === "string" ? resolveBoolean$3(desiredIncludeRaw, current3.include_in_rename) : current3.include_in_rename;
  if (normalizeText(current3.name) === normalizeText(desiredName) && normalizeText(current3.description) === normalizeText(desiredDescription ?? "") && current3.include_in_rename === desiredInclude && tagsEqual(currentTags, resolvedTags)) return { success: true };
  return updateGeneral({
    databaseId,
    cache: cache3,
    layer: "user",
    current: current3,
    input: {
      name: desiredName,
      description: normalizeText(desiredDescription ?? ""),
      includeInRename: desiredInclude,
      tags: resolvedTags
    }
  });
}
function toConditionData(entry) {
  const name = entry.name;
  if (!name) return null;
  const base2 = entry.base && typeof entry.base === "object" && "to" in entry.base ? entry.base.to : entry.base;
  const values = entry.values && typeof entry.values === "object" && "to" in entry.values ? entry.values.to : entry.values;
  return {
    name,
    type: base2?.type ?? "",
    arrType: base2?.arrType ?? "all",
    negate: base2?.negate ?? false,
    required: base2?.required ?? false,
    patterns: values?.patterns,
    languages: values?.languages,
    sources: values?.sources,
    resolutions: values?.resolutions,
    qualityModifiers: values?.qualityModifiers,
    releaseTypes: values?.releaseTypes,
    indexerFlags: values?.indexerFlags,
    size: values?.size,
    years: values?.years
  };
}
async function overrideConditions(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for condition override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const formatName = await resolveFormatName(cache3, databaseId, metadata, desiredState);
  if (!formatName) return {
    success: false,
    error: "Custom format not found for condition override"
  };
  const currentConditions = await getConditionsForEvaluation(cache3, formatName);
  const conditionsDiff = desiredState.conditions;
  if (!conditionsDiff) return { success: true };
  const added = (conditionsDiff.added ?? []).map(toConditionData).filter((c2) => c2 !== null);
  const removedNames = new Set((conditionsDiff.removed ?? []).map((e) => e.name).filter(Boolean));
  const updatedMap = /* @__PURE__ */ new Map();
  for (const entry of conditionsDiff.updated ?? []) {
    const c2 = toConditionData(entry);
    if (c2) updatedMap.set(c2.name, c2);
  }
  const target = [];
  for (const c2 of currentConditions) {
    if (removedNames.has(c2.name)) continue;
    const updated3 = updatedMap.get(c2.name);
    target.push(updated3 ?? c2);
  }
  for (const [name, updated3] of updatedMap.entries()) {
    if (currentConditions.some((c2) => c2.name === name)) continue;
    if (removedNames.has(name)) continue;
    target.push(updated3);
  }
  for (const c2 of added) target.push(c2);
  return updateConditions({
    databaseId,
    cache: cache3,
    layer: "user",
    formatName,
    originalConditions: currentConditions,
    conditions: target
  });
}
function resolveTestValues(desiredState) {
  const title = getDesiredTo(desiredState.title) ?? (typeof desiredState.test_title === "string" ? desiredState.test_title : null);
  if (!title) return null;
  const type = (getDesiredTo(desiredState.type) ?? (typeof desiredState.test_type === "string" ? desiredState.test_type : "movie")) === "series" ? "series" : "movie";
  const rawMatch = getDesiredTo(desiredState.should_match) ?? desiredState.test_should_match;
  const should_match = typeof rawMatch === "boolean" ? rawMatch : rawMatch === 1 || rawMatch === true;
  const rawDesc = getDesiredTo(desiredState.description) ?? desiredState.test_description;
  return {
    title,
    type,
    should_match,
    description: typeof rawDesc === "string" ? rawDesc.trim() || null : null
  };
}
function resolveOriginalTitle(desiredState) {
  const titleField = desiredState.title;
  if (titleField && typeof titleField === "object" && "from" in titleField) return titleField.from;
  return typeof desiredState.test_title === "string" ? desiredState.test_title : null;
}
function resolveOriginalType(desiredState) {
  const typeField = desiredState.type;
  if (typeField && typeof typeField === "object" && "from" in typeField) return typeField.from;
  return typeof desiredState.test_type === "string" ? desiredState.test_type : "movie";
}
async function overrideTests(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for test override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const formatName = await resolveFormatName(cache3, databaseId, metadata, desiredState);
  if (!formatName) return {
    success: false,
    error: "Custom format not found for test override"
  };
  const desired = resolveTestValues(desiredState);
  if (!desired) return {
    success: false,
    error: "Cannot resolve test values from desired state"
  };
  const origTitle = resolveOriginalTitle(desiredState);
  const origType = resolveOriginalType(desiredState);
  const current3 = origTitle ? await getTest(cache3, formatName, origTitle, origType) : null;
  if (current3) {
    if (normalizeText(current3.title) === normalizeText(desired.title) && current3.type === desired.type && current3.should_match === desired.should_match && normalizeText(current3.description) === normalizeText(desired.description ?? "")) return { success: true };
    return updateTest({
      databaseId,
      layer: "user",
      formatName,
      current: current3,
      input: desired
    });
  }
  const existingWithDesiredKey = await getTest(cache3, formatName, desired.title, desired.type);
  if (existingWithDesiredKey) {
    if (existingWithDesiredKey.should_match === desired.should_match && normalizeText(existingWithDesiredKey.description) === normalizeText(desired.description ?? "")) return { success: true };
    return updateTest({
      databaseId,
      layer: "user",
      formatName,
      current: existingWithDesiredKey,
      input: desired
    });
  }
  return createTest({
    databaseId,
    layer: "user",
    formatName,
    input: desired
  });
}
function hasGeneralChanges$1(metadata) {
  if (!metadata?.changed_fields?.length) return true;
  return metadata.changed_fields.some((f2) => GENERAL_FIELDS$1.has(f2));
}
function hasConditionChanges(metadata, desiredState) {
  if (metadata?.changed_fields?.includes("conditions")) return true;
  if (desiredState?.conditions) return true;
  return false;
}
function hasTestChanges(metadata, desiredState) {
  if (metadata?.summary?.toLowerCase().includes("test")) return true;
  if (metadata?.title?.toLowerCase().includes("test")) return true;
  if (desiredState?.test_title) return true;
  return false;
}
async function overrideCreate$4(databaseId, metadata, desiredState) {
  if (hasTestChanges(metadata, desiredState)) return overrideTests(databaseId, metadata, desiredState);
  const generalResult = await overrideGeneral$1(databaseId, metadata, desiredState);
  if (!generalResult.success) return generalResult;
  if (hasConditionChanges(metadata, desiredState)) return overrideConditions(databaseId, metadata, desiredState);
  return generalResult;
}
async function overrideUpdate$4(databaseId, metadata, desiredState) {
  if (hasTestChanges(metadata, desiredState)) return overrideTests(databaseId, metadata, desiredState);
  if (hasConditionChanges(metadata, desiredState)) return overrideConditions(databaseId, metadata, desiredState);
  if (hasGeneralChanges$1(metadata)) return overrideGeneral$1(databaseId, metadata, desiredState);
  return { success: true };
}
async function resolveProfileName$1(cache3, databaseId, metadata, desiredState) {
  const candidates = [
    metadata?.stable_key?.value,
    metadata?.name,
    getDesiredTo(desiredState?.name),
    typeof desiredState?.name === "string" ? desiredState.name : null
  ].filter((v3) => typeof v3 === "string" && v3.length > 0);
  if (candidates.length === 0) return null;
  for (const name of candidates) {
    const row = await cache3.kb.selectFrom("quality_profiles").select("name").where("name", "=", name).executeTakeFirst();
    if (row) return row.name;
  }
  const resolved = followRenameChain(databaseId, "quality_profile", candidates[0]);
  if (resolved !== candidates[0]) {
    const row = await cache3.kb.selectFrom("quality_profiles").select("name").where("name", "=", resolved).executeTakeFirst();
    if (row) return row.name;
  }
  return null;
}
function resolveTags$1(current3, desiredState) {
  const desiredTags = desiredState.tags;
  if (Array.isArray(desiredTags)) return normalizeTags(desiredTags);
  if (desiredTags && typeof desiredTags === "object") {
    const add = Array.isArray(desiredTags.add) ? desiredTags.add.map((tag2) => String(tag2)) : [];
    const remove5 = Array.isArray(desiredTags.remove) ? desiredTags.remove.map((tag2) => String(tag2)) : [];
    const set3 = new Set(current3);
    for (const tag2 of remove5) set3.delete(tag2);
    for (const tag2 of add) set3.add(tag2);
    return Array.from(set3);
  }
  return current3;
}
function resolveLanguage(current3, desiredState) {
  const langField = desiredState.language;
  if (!langField || typeof langField !== "object") return current3;
  const typed = langField;
  if ("to" in typed) return typeof typed.to === "string" ? typed.to : null;
  return current3;
}
async function overrideGeneral(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const profileName2 = await resolveProfileName$1(cache3, databaseId, metadata, desiredState);
  const fallbackName = metadata?.stable_key?.value ?? metadata?.name ?? getDesiredTo(desiredState?.name) ?? (typeof desiredState?.name === "string" ? desiredState.name : null);
  if (!profileName2 && !fallbackName) return {
    success: false,
    error: "Quality profile not found for override"
  };
  const profileRow = profileName2 ? await cache3.kb.selectFrom("quality_profiles").select(["id", "name"]).where("name", "=", profileName2).executeTakeFirst() : void 0;
  const desiredNameRaw = getDesiredTo(desiredState.name) ?? (typeof desiredState.name === "string" ? desiredState.name : profileName2 ?? fallbackName ?? "");
  const desiredDescriptionRaw = getDesiredTo(desiredState.description) ?? (typeof desiredState.description === "string" || desiredState.description === null ? desiredState.description : void 0);
  const desiredTags = resolveTags$1([], desiredState);
  const desiredLanguage = resolveLanguage(null, desiredState);
  if (!profileRow) {
    const createName = desiredNameRaw || fallbackName || profileName2 || "";
    if (!createName) return {
      success: false,
      error: "Quality profile not found for override"
    };
    return create2({
      databaseId,
      cache: cache3,
      layer: "user",
      input: {
        name: createName,
        description: normalizeText(desiredDescriptionRaw ?? ""),
        tags: desiredTags,
        language: desiredLanguage
      }
    });
  }
  const current3 = await general(cache3, profileRow.id);
  if (!current3) return {
    success: false,
    error: "Quality profile not found for override"
  };
  const desiredName = desiredNameRaw || current3.name;
  const desiredDescription = desiredDescriptionRaw !== void 0 ? desiredDescriptionRaw : current3.description;
  const currentTags = current3.tags.map((tag2) => tag2.name);
  const resolvedTags = resolveTags$1(currentTags, desiredState);
  const resolvedLanguage = resolveLanguage(current3.language, desiredState);
  if (normalizeText(current3.name) === normalizeText(desiredName) && normalizeText(current3.description) === normalizeText(desiredDescription ?? "") && tagsEqual(currentTags, resolvedTags) && current3.language === resolvedLanguage) return { success: true };
  return updateGeneral2({
    databaseId,
    cache: cache3,
    layer: "user",
    current: current3,
    input: {
      name: desiredName,
      description: normalizeText(desiredDescription ?? ""),
      tags: resolvedTags,
      language: resolvedLanguage
    }
  });
}
function resolveOrderedItems(desiredState) {
  const field = desiredState.ordered_items;
  if (!field) return null;
  if (typeof field === "object" && "to" in field) {
    const to = field.to;
    if (Array.isArray(to)) return to;
  }
  if (Array.isArray(field)) return field;
  return null;
}
function resolveOrderedItemsPatch(desiredState) {
  const raw = desiredState.ordered_items;
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
  const record = raw;
  if (record.mode !== "add" && record.mode !== "remove" && record.mode !== "update") return null;
  const from = Array.isArray(record.from) ? record.from[0] ?? null : null;
  const to = Array.isArray(record.to) ? record.to[0] ?? null : null;
  const key2 = typeof record.key === "string" ? record.key : null;
  return {
    mode: record.mode,
    key: key2,
    from,
    to
  };
}
function itemKey(item) {
  return `${item.type}:${item.name}`;
}
function cloneItem(item) {
  return {
    type: item.type,
    name: item.name,
    position: item.position,
    enabled: item.enabled,
    upgradeUntil: item.upgradeUntil,
    members: item.members ? item.members.map((member) => ({ name: member.name })) : void 0
  };
}
function applyPatch(currentItems, patch) {
  const map2 = new Map(currentItems.map((item) => [itemKey(item), cloneItem(item)]));
  if (patch.mode === "add") {
    if (!patch.to) return currentItems;
    map2.set(itemKey(patch.to), cloneItem(patch.to));
  }
  if (patch.mode === "remove") {
    const key2 = patch.key ?? (patch.from ? itemKey(patch.from) : null);
    if (key2) map2.delete(key2);
  }
  if (patch.mode === "update") {
    if (!patch.to && !patch.from) return currentItems;
    const fromKey = patch.from ? itemKey(patch.from) : patch.key;
    const toKey = patch.to ? itemKey(patch.to) : patch.key;
    if (fromKey && toKey && fromKey !== toKey) map2.delete(fromKey);
    if (toKey && patch.to) map2.set(toKey, cloneItem(patch.to));
  }
  return Array.from(map2.values()).sort((a2, b3) => a2.position - b3.position);
}
async function overrideQualities(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for qualities override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const profileName2 = await resolveProfileName$1(cache3, databaseId, metadata, desiredState);
  if (!profileName2) return {
    success: false,
    error: "Quality profile not found for qualities override"
  };
  const currentData2 = await qualities(cache3, databaseId, profileName2);
  const patch = resolveOrderedItemsPatch(desiredState);
  if (patch) {
    const nextItems = applyPatch(currentData2.orderedItems, patch);
    if (orderedItemsEqual(currentData2.orderedItems, nextItems)) return { success: true };
    return updateQualities({
      databaseId,
      cache: cache3,
      layer: "user",
      profileName: profileName2,
      input: { orderedItems: nextItems }
    });
  }
  const desiredItems = resolveOrderedItems(desiredState);
  if (!desiredItems || orderedItemsEqual(currentData2.orderedItems, desiredItems)) return { success: true };
  return updateQualities({
    databaseId,
    cache: cache3,
    layer: "user",
    profileName: profileName2,
    input: { orderedItems: desiredItems }
  });
}
function resolveScoreChanges(desiredState) {
  const raw = desiredState.custom_format_scores;
  if (!Array.isArray(raw)) return [];
  return raw.map((entry) => {
    const typed = entry;
    if (!typed.custom_format_name || !typed.arr_type) return null;
    return {
      customFormatName: typed.custom_format_name,
      arrType: typed.arr_type,
      score: typed.to ?? null
    };
  }).filter((e) => e !== null);
}
async function overrideScoring(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for scoring override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const profileName2 = await resolveProfileName$1(cache3, databaseId, metadata, desiredState);
  if (!profileName2) return {
    success: false,
    error: "Quality profile not found for scoring override"
  };
  const currentScoring = await scoring(cache3, databaseId, profileName2);
  const queries = [];
  const nextDesiredState = {};
  const changedFields = [];
  const desiredUpgradesAllowed = getDesiredTo(desiredState.upgrades_allowed);
  if (desiredUpgradesAllowed !== void 0 && !valuesEqual(desiredUpgradesAllowed, currentScoring.upgrades_allowed)) {
    queries.push({
      sql: `UPDATE quality_profiles
SET upgrades_allowed = ${desiredUpgradesAllowed ? 1 : 0}
WHERE name = '${esc3(profileName2)}'
  AND upgrades_allowed = ${currentScoring.upgrades_allowed ? 1 : 0}`,
      parameters: [],
      query: {}
    });
    nextDesiredState.upgrades_allowed = {
      from: currentScoring.upgrades_allowed,
      to: desiredUpgradesAllowed
    };
    changedFields.push("upgrades_allowed");
  }
  const desiredMinimum = getDesiredTo(desiredState.minimum_custom_format_score);
  if (desiredMinimum !== void 0 && !valuesEqual(desiredMinimum, currentScoring.minimum_custom_format_score)) {
    queries.push({
      sql: `UPDATE quality_profiles
SET minimum_custom_format_score = ${desiredMinimum}
WHERE name = '${esc3(profileName2)}'
  AND minimum_custom_format_score = ${currentScoring.minimum_custom_format_score}`,
      parameters: [],
      query: {}
    });
    nextDesiredState.minimum_custom_format_score = {
      from: currentScoring.minimum_custom_format_score,
      to: desiredMinimum
    };
    changedFields.push("minimum_custom_format_score");
  }
  const desiredUpgradeUntil = getDesiredTo(desiredState.upgrade_until_score);
  if (desiredUpgradeUntil !== void 0 && !valuesEqual(desiredUpgradeUntil, currentScoring.upgrade_until_score)) {
    queries.push({
      sql: `UPDATE quality_profiles
SET upgrade_until_score = ${desiredUpgradeUntil}
WHERE name = '${esc3(profileName2)}'
  AND upgrade_until_score = ${currentScoring.upgrade_until_score}`,
      parameters: [],
      query: {}
    });
    nextDesiredState.upgrade_until_score = {
      from: currentScoring.upgrade_until_score,
      to: desiredUpgradeUntil
    };
    changedFields.push("upgrade_until_score");
  }
  const desiredIncrement = getDesiredTo(desiredState.upgrade_score_increment);
  if (desiredIncrement !== void 0 && !valuesEqual(desiredIncrement, currentScoring.upgrade_score_increment)) {
    queries.push({
      sql: `UPDATE quality_profiles
SET upgrade_score_increment = ${desiredIncrement}
WHERE name = '${esc3(profileName2)}'
  AND upgrade_score_increment = ${currentScoring.upgrade_score_increment}`,
      parameters: [],
      query: {}
    });
    nextDesiredState.upgrade_score_increment = {
      from: currentScoring.upgrade_score_increment,
      to: desiredIncrement
    };
    changedFields.push("upgrade_score_increment");
  }
  const scoreChanges = resolveScoreChanges(desiredState);
  const desiredScoreStates = [];
  for (const change of scoreChanges) {
    const resolvedName = followRenameChain(databaseId, "custom_format", change.customFormatName);
    const currentRow = await cache3.kb.selectFrom("quality_profile_custom_formats").select(["score"]).where("quality_profile_name", "=", profileName2).where("custom_format_name", "=", resolvedName).where("arr_type", "=", change.arrType).executeTakeFirst();
    const currentScore = currentRow?.score ?? null;
    if (valuesEqual(change.score, currentScore)) continue;
    if (currentRow && change.score === null) queries.push({
      sql: `DELETE FROM quality_profile_custom_formats
WHERE quality_profile_name = '${esc3(profileName2)}'
  AND custom_format_name = '${esc3(resolvedName)}'
  AND arr_type = '${esc3(change.arrType)}'
  AND score = ${currentRow.score}`,
      parameters: [],
      query: {}
    });
    else if (currentRow) queries.push({
      sql: `UPDATE quality_profile_custom_formats
SET score = ${change.score}
WHERE quality_profile_name = '${esc3(profileName2)}'
  AND custom_format_name = '${esc3(resolvedName)}'
  AND arr_type = '${esc3(change.arrType)}'
  AND score = ${currentRow.score}`,
      parameters: [],
      query: {}
    });
    else if (change.score !== null) queries.push({
      sql: `INSERT INTO quality_profile_custom_formats (quality_profile_name, custom_format_name, arr_type, score)
SELECT '${esc3(profileName2)}', '${esc3(resolvedName)}', '${esc3(change.arrType)}', ${change.score}
WHERE NOT EXISTS (
  SELECT 1 FROM quality_profile_custom_formats
  WHERE quality_profile_name = '${esc3(profileName2)}'
    AND custom_format_name = '${esc3(resolvedName)}'
    AND arr_type = '${esc3(change.arrType)}'
)`,
      parameters: [],
      query: {}
    });
    desiredScoreStates.push({
      custom_format_name: resolvedName,
      arr_type: change.arrType,
      from: currentScore,
      to: change.score
    });
    changedFields.push(`custom_format_score:${resolvedName}:${change.arrType}`);
  }
  if (desiredScoreStates.length > 0) nextDesiredState.custom_format_scores = desiredScoreStates;
  if (queries.length === 0) return { success: true };
  return writeOperation({
    databaseId,
    layer: "user",
    description: metadata?.summary ?? `override-quality-profile-scoring-${profileName2}`,
    queries,
    desiredState: nextDesiredState,
    metadata: {
      operation: "update",
      entity: "quality_profile",
      name: profileName2,
      stableKey: {
        key: "quality_profile_name",
        value: profileName2
      },
      changedFields,
      summary: metadata?.summary ?? "Override quality profile scoring conflict",
      title: metadata?.title ?? `Override scoring for quality profile "${profileName2}"`
    }
  });
}
function esc3(value2) {
  return value2.replace(/'/g, "''");
}
function hasGeneralChanges(metadata) {
  if (!metadata?.changed_fields?.length) return true;
  return metadata.changed_fields.some((f2) => GENERAL_FIELDS.has(f2));
}
function hasQualitiesChanges(metadata, desiredState) {
  if (metadata?.changed_fields?.includes("qualities")) return true;
  if (metadata?.changed_fields?.some((field) => field.startsWith("quality_item:"))) return true;
  if (desiredState?.ordered_items) return true;
  return false;
}
function hasScoringChanges(metadata, desiredState) {
  if (metadata?.changed_fields?.includes("minimum_custom_format_score")) return true;
  if (metadata?.changed_fields?.includes("upgrades_allowed")) return true;
  if (metadata?.changed_fields?.includes("upgrade_until_score")) return true;
  if (metadata?.changed_fields?.includes("upgrade_score_increment")) return true;
  if (metadata?.changed_fields?.includes("custom_format_scores")) return true;
  if (metadata?.changed_fields?.some((field) => field.startsWith("custom_format_score:"))) return true;
  if (desiredState?.custom_format_scores) return true;
  if (desiredState?.upgrades_allowed) return true;
  if (desiredState?.minimum_custom_format_score) return true;
  if (desiredState?.upgrade_until_score) return true;
  if (desiredState?.upgrade_score_increment) return true;
  return false;
}
async function overrideCreate$3(databaseId, metadata, desiredState) {
  const generalResult = await overrideGeneral(databaseId, metadata, desiredState);
  if (!generalResult.success) return generalResult;
  if (hasQualitiesChanges(metadata, desiredState)) {
    const qualitiesResult = await overrideQualities(databaseId, metadata, desiredState);
    if (!qualitiesResult.success) return qualitiesResult;
  }
  if (hasScoringChanges(metadata, desiredState)) return overrideScoring(databaseId, metadata, desiredState);
  return generalResult;
}
async function overrideUpdate$3(databaseId, metadata, desiredState) {
  if (hasQualitiesChanges(metadata, desiredState)) return overrideQualities(databaseId, metadata, desiredState);
  if (hasScoringChanges(metadata, desiredState)) return overrideScoring(databaseId, metadata, desiredState);
  if (hasGeneralChanges(metadata)) return overrideGeneral(databaseId, metadata, desiredState);
  return { success: true };
}
async function resolveRegexName(cache3, databaseId, metadata, desiredState) {
  const candidates = [
    metadata?.stable_key?.value,
    metadata?.name,
    getDesiredTo(desiredState?.name),
    typeof desiredState?.name === "string" ? desiredState.name : null
  ].filter((v3) => typeof v3 === "string" && v3.length > 0);
  if (candidates.length === 0) return null;
  for (const name of candidates) {
    const row = await cache3.kb.selectFrom("regular_expressions").select("name").where("name", "=", name).executeTakeFirst();
    if (row) return row.name;
  }
  const resolved = followRenameChain(databaseId, "regular_expression", candidates[0]);
  if (resolved !== candidates[0]) {
    const row = await cache3.kb.selectFrom("regular_expressions").select("name").where("name", "=", resolved).executeTakeFirst();
    if (row) return row.name;
  }
  return null;
}
function resolveTags(current3, desiredState) {
  const desiredTags = desiredState.tags;
  if (Array.isArray(desiredTags)) return normalizeTags(desiredTags);
  if (desiredTags && typeof desiredTags === "object") {
    const add = Array.isArray(desiredTags.add) ? desiredTags.add.map((tag2) => String(tag2)) : [];
    const remove5 = Array.isArray(desiredTags.remove) ? desiredTags.remove.map((tag2) => String(tag2)) : [];
    const set3 = new Set(current3);
    for (const tag2 of remove5) set3.delete(tag2);
    for (const tag2 of add) set3.add(tag2);
    return Array.from(set3);
  }
  return current3;
}
async function overrideRegex(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for regex override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const regexName = await resolveRegexName(cache3, databaseId, metadata, desiredState);
  if (!regexName) return {
    success: false,
    error: "Regular expression not found for override"
  };
  const regexRow = await cache3.kb.selectFrom("regular_expressions").select(["id", "name"]).where("name", "=", regexName).executeTakeFirst();
  if (!regexRow) return {
    success: false,
    error: "Regular expression not found for override"
  };
  const current3 = await get2(cache3, regexRow.id);
  if (!current3) return {
    success: false,
    error: "Regular expression not found for override"
  };
  const desiredName = getDesiredTo(desiredState.name) ?? (typeof desiredState.name === "string" ? desiredState.name : current3.name);
  const desiredPattern = getDesiredTo(desiredState.pattern) ?? (typeof desiredState.pattern === "string" ? desiredState.pattern : current3.pattern);
  const desiredDescription = getDesiredTo(desiredState.description) ?? (typeof desiredState.description === "string" || desiredState.description === null ? desiredState.description : current3.description);
  const desiredRegex101Id = getDesiredTo(desiredState.regex101_id) ?? (typeof desiredState.regex101_id === "string" || desiredState.regex101_id === null ? desiredState.regex101_id : current3.regex101_id);
  const currentTags = current3.tags.map((tag2) => tag2.name);
  const desiredTags = resolveTags(currentTags, desiredState);
  if (normalizeText(current3.name) === normalizeText(desiredName) && normalizeText(current3.pattern) === normalizeText(desiredPattern) && normalizeText(current3.description) === normalizeText(desiredDescription ?? "") && normalizeText(current3.regex101_id) === normalizeText(desiredRegex101Id ?? "") && tagsEqual(currentTags, desiredTags)) return { success: true };
  return update({
    databaseId,
    cache: cache3,
    layer: "user",
    current: current3,
    input: {
      name: desiredName,
      pattern: desiredPattern,
      tags: desiredTags,
      description: desiredDescription,
      regex101Id: desiredRegex101Id
    }
  });
}
async function resolveProfileName(cache3, databaseId, metadata, desiredState) {
  const candidates = [
    metadata?.stable_key?.value,
    metadata?.name,
    getDesiredTo(desiredState?.name),
    typeof desiredState?.name === "string" ? desiredState.name : null
  ].filter((v3) => typeof v3 === "string" && v3.length > 0);
  if (candidates.length === 0) return null;
  for (const name of candidates) {
    const row = await cache3.kb.selectFrom("delay_profiles").select("name").where("name", "=", name).executeTakeFirst();
    if (row) return row.name;
  }
  const resolved = followRenameChain(databaseId, "delay_profile", candidates[0]);
  if (resolved !== candidates[0]) {
    const row = await cache3.kb.selectFrom("delay_profiles").select("name").where("name", "=", resolved).executeTakeFirst();
    if (row) return row.name;
  }
  return null;
}
function resolveNumber(value2, fallback2) {
  const resolved = getDesiredTo(value2);
  if (typeof resolved === "number") return resolved;
  if (typeof value2 === "number") return value2;
  return fallback2 ?? 0;
}
function resolveNullableNumber(value2, fallback2) {
  const resolved = getDesiredTo(value2);
  if (resolved !== void 0) return resolved;
  if (typeof value2 === "number" || value2 === null) return value2;
  return fallback2;
}
function resolveBoolean$2(value2, fallback2) {
  const resolved = getDesiredTo(value2);
  if (typeof resolved === "boolean") return resolved;
  if (typeof value2 === "boolean") return value2;
  if (typeof value2 === "number") return value2 === 1;
  return fallback2;
}
function resolveProtocol(value2, fallback2) {
  const resolved = getDesiredTo(value2);
  if (typeof resolved === "string") return resolved;
  if (typeof value2 === "string") return value2;
  return fallback2;
}
async function overrideDelay(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for delay profile override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const profileName2 = await resolveProfileName(cache3, databaseId, metadata, desiredState);
  if (!profileName2) return {
    success: false,
    error: "Delay profile not found for override"
  };
  const profileRow = await cache3.kb.selectFrom("delay_profiles").select("id").where("name", "=", profileName2).executeTakeFirst();
  if (!profileRow) return {
    success: false,
    error: "Delay profile not found for override"
  };
  const current3 = await get3(cache3, profileRow.id);
  if (!current3) return {
    success: false,
    error: "Delay profile not found for override"
  };
  const desiredName = getDesiredTo(desiredState.name) ?? (typeof desiredState.name === "string" ? desiredState.name : current3.name);
  const desiredProtocol = resolveProtocol(desiredState.preferred_protocol, current3.preferred_protocol);
  const desiredUsenetDelay = resolveNumber(desiredState.usenet_delay, current3.usenet_delay);
  const desiredTorrentDelay = resolveNumber(desiredState.torrent_delay, current3.torrent_delay);
  const desiredBypassHighest = resolveBoolean$2(desiredState.bypass_if_highest_quality, current3.bypass_if_highest_quality);
  const desiredBypassCf = resolveBoolean$2(desiredState.bypass_if_above_custom_format_score, current3.bypass_if_above_custom_format_score);
  const desiredMinCfScore = resolveNullableNumber(desiredState.minimum_custom_format_score, current3.minimum_custom_format_score);
  if (current3.name === desiredName && current3.preferred_protocol === desiredProtocol && valuesEqual(current3.usenet_delay, desiredUsenetDelay) && valuesEqual(current3.torrent_delay, desiredTorrentDelay) && valuesEqual(current3.bypass_if_highest_quality, desiredBypassHighest) && valuesEqual(current3.bypass_if_above_custom_format_score, desiredBypassCf) && valuesEqual(current3.minimum_custom_format_score, desiredMinCfScore)) return { success: true };
  return update2({
    databaseId,
    cache: cache3,
    layer: "user",
    current: current3,
    input: {
      name: desiredName,
      preferredProtocol: desiredProtocol,
      usenetDelay: desiredUsenetDelay,
      torrentDelay: desiredTorrentDelay,
      bypassIfHighestQuality: desiredBypassHighest,
      bypassIfAboveCfScore: desiredBypassCf,
      minimumCfScore: desiredMinCfScore ?? 0
    }
  });
}
async function resolveNamingName(cache3, databaseId, table2, metadata, desiredState) {
  const candidates = [
    metadata?.stable_key?.value,
    metadata?.name,
    getDesiredTo(desiredState?.name),
    typeof desiredState?.name === "string" ? desiredState.name : null
  ].filter((v3) => typeof v3 === "string" && v3.length > 0);
  if (candidates.length === 0) return null;
  for (const name of candidates) {
    const row = await cache3.kb.selectFrom(table2).select("name").where("name", "=", name).executeTakeFirst();
    if (row) return row.name;
  }
  const resolved = followRenameChain(databaseId, table2 === "radarr_naming" ? "radarr_naming" : "sonarr_naming", candidates[0]);
  if (resolved !== candidates[0]) {
    const row = await cache3.kb.selectFrom(table2).select("name").where("name", "=", resolved).executeTakeFirst();
    if (row) return row.name;
  }
  return null;
}
function resolveString$1(value2, fallback2) {
  const resolved = getDesiredTo(value2);
  if (typeof resolved === "string") return resolved;
  if (typeof value2 === "string") return value2;
  return fallback2;
}
function resolveNullableString(value2, fallback2) {
  const resolved = getDesiredTo(value2);
  if (resolved !== void 0) return resolved;
  if (typeof value2 === "string" || value2 === null) return value2;
  return fallback2;
}
function resolveBoolean$1(value2, fallback2) {
  const resolved = getDesiredTo(value2);
  if (typeof resolved === "boolean") return resolved;
  if (typeof value2 === "boolean") return value2;
  if (typeof value2 === "number") return value2 === 1;
  return fallback2;
}
async function overrideRadarr$2(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for radarr naming override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const name = await resolveNamingName(cache3, databaseId, "radarr_naming", metadata, desiredState);
  if (!name) return {
    success: false,
    error: "Radarr naming config not found for override"
  };
  const current3 = await getRadarrByName$1(cache3, name);
  if (!current3) return {
    success: false,
    error: "Radarr naming config not found for override"
  };
  const desiredName = resolveString$1(desiredState.name, current3.name);
  const desiredRename = resolveBoolean$1(desiredState.rename, current3.rename);
  const desiredMovieFormat = resolveString$1(desiredState.movie_format, current3.movie_format);
  const desiredMovieFolderFormat = resolveString$1(desiredState.movie_folder_format, current3.movie_folder_format);
  const desiredReplaceIllegal = resolveBoolean$1(desiredState.replace_illegal_characters, current3.replace_illegal_characters);
  const desiredColonFormat = resolveString$1(desiredState.colon_replacement_format, current3.colon_replacement_format);
  if (current3.name === desiredName && valuesEqual(current3.rename, desiredRename) && current3.movie_format === desiredMovieFormat && current3.movie_folder_format === desiredMovieFolderFormat && valuesEqual(current3.replace_illegal_characters, desiredReplaceIllegal) && current3.colon_replacement_format === desiredColonFormat) return { success: true };
  return updateRadarrNaming({
    databaseId,
    cache: cache3,
    layer: "user",
    current: current3,
    input: {
      name: desiredName,
      rename: desiredRename,
      movieFormat: desiredMovieFormat,
      movieFolderFormat: desiredMovieFolderFormat,
      replaceIllegalCharacters: desiredReplaceIllegal,
      colonReplacementFormat: desiredColonFormat
    }
  });
}
async function overrideSonarr$2(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for sonarr naming override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const name = await resolveNamingName(cache3, databaseId, "sonarr_naming", metadata, desiredState);
  if (!name) return {
    success: false,
    error: "Sonarr naming config not found for override"
  };
  const current3 = await getSonarrByName$1(cache3, name);
  if (!current3) return {
    success: false,
    error: "Sonarr naming config not found for override"
  };
  const desiredName = resolveString$1(desiredState.name, current3.name);
  const desiredRename = resolveBoolean$1(desiredState.rename, current3.rename);
  const desiredStandard = resolveString$1(desiredState.standard_episode_format, current3.standard_episode_format);
  const desiredDaily = resolveString$1(desiredState.daily_episode_format, current3.daily_episode_format);
  const desiredAnime = resolveString$1(desiredState.anime_episode_format, current3.anime_episode_format);
  const desiredSeriesFolder = resolveString$1(desiredState.series_folder_format, current3.series_folder_format);
  const desiredSeasonFolder = resolveString$1(desiredState.season_folder_format, current3.season_folder_format);
  const desiredReplaceIllegal = resolveBoolean$1(desiredState.replace_illegal_characters, current3.replace_illegal_characters);
  const desiredColonFormat = resolveString$1(desiredState.colon_replacement_format, current3.colon_replacement_format);
  const desiredCustomColon = resolveNullableString(desiredState.custom_colon_replacement_format, current3.custom_colon_replacement_format);
  const desiredMultiEpisode = resolveString$1(desiredState.multi_episode_style, current3.multi_episode_style);
  if (current3.name === desiredName && valuesEqual(current3.rename, desiredRename) && current3.standard_episode_format === desiredStandard && current3.daily_episode_format === desiredDaily && current3.anime_episode_format === desiredAnime && current3.series_folder_format === desiredSeriesFolder && current3.season_folder_format === desiredSeasonFolder && valuesEqual(current3.replace_illegal_characters, desiredReplaceIllegal) && current3.colon_replacement_format === desiredColonFormat && current3.custom_colon_replacement_format === desiredCustomColon && current3.multi_episode_style === desiredMultiEpisode) return { success: true };
  return updateSonarrNaming({
    databaseId,
    cache: cache3,
    layer: "user",
    current: current3,
    input: {
      name: desiredName,
      rename: desiredRename,
      standardEpisodeFormat: desiredStandard,
      dailyEpisodeFormat: desiredDaily,
      animeEpisodeFormat: desiredAnime,
      seriesFolderFormat: desiredSeriesFolder,
      seasonFolderFormat: desiredSeasonFolder,
      replaceIllegalCharacters: desiredReplaceIllegal,
      colonReplacementFormat: desiredColonFormat,
      customColonReplacementFormat: desiredCustomColon,
      multiEpisodeStyle: desiredMultiEpisode
    }
  });
}
function overrideCreate$2(databaseId, metadata, desiredState) {
  return metadata?.entity === "sonarr_naming" ? overrideSonarr$2(databaseId, metadata, desiredState) : overrideRadarr$2(databaseId, metadata, desiredState);
}
function overrideUpdate$2(databaseId, metadata, desiredState) {
  return metadata?.entity === "sonarr_naming" ? overrideSonarr$2(databaseId, metadata, desiredState) : overrideRadarr$2(databaseId, metadata, desiredState);
}
async function resolveName$1(cache3, databaseId, table2, metadata, desiredState) {
  const candidates = [
    metadata?.stable_key?.value,
    metadata?.name,
    getDesiredTo(desiredState?.name),
    typeof desiredState?.name === "string" ? desiredState.name : null
  ].filter((v3) => typeof v3 === "string" && v3.length > 0);
  if (candidates.length === 0) return null;
  for (const name of candidates) {
    const row = await cache3.kb.selectFrom(table2).select("name").where("name", "=", name).executeTakeFirst();
    if (row) return row.name;
  }
  const resolved = followRenameChain(databaseId, table2 === "radarr_media_settings" ? "radarr_media_settings" : "sonarr_media_settings", candidates[0]);
  if (resolved !== candidates[0]) {
    const row = await cache3.kb.selectFrom(table2).select("name").where("name", "=", resolved).executeTakeFirst();
    if (row) return row.name;
  }
  return null;
}
function resolveString(value2, fallback2) {
  const resolved = getDesiredTo(value2);
  if (typeof resolved === "string") return resolved;
  if (typeof value2 === "string") return value2;
  return fallback2;
}
function resolveBoolean(value2, fallback2) {
  const resolved = getDesiredTo(value2);
  if (typeof resolved === "boolean") return resolved;
  if (typeof value2 === "boolean") return value2;
  if (typeof value2 === "number") return value2 === 1;
  return fallback2;
}
async function overrideRadarr$1(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for radarr media settings override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const name = await resolveName$1(cache3, databaseId, "radarr_media_settings", metadata, desiredState);
  if (!name) return {
    success: false,
    error: "Radarr media settings not found for override"
  };
  const current3 = await getRadarrByName$2(cache3, name);
  if (!current3) return {
    success: false,
    error: "Radarr media settings not found for override"
  };
  const desiredName = resolveString(desiredState.name, current3.name);
  const desiredPropersRepacks = resolveString(desiredState.propers_repacks, current3.propers_repacks);
  const desiredEnableMediaInfo = resolveBoolean(desiredState.enable_media_info, current3.enable_media_info);
  if (current3.name === desiredName && current3.propers_repacks === desiredPropersRepacks && valuesEqual(current3.enable_media_info, desiredEnableMediaInfo)) return { success: true };
  return updateRadarrMediaSettings({
    databaseId,
    cache: cache3,
    layer: "user",
    current: current3,
    input: {
      name: desiredName,
      propersRepacks: desiredPropersRepacks,
      enableMediaInfo: desiredEnableMediaInfo
    }
  });
}
async function overrideSonarr$1(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for sonarr media settings override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const name = await resolveName$1(cache3, databaseId, "sonarr_media_settings", metadata, desiredState);
  if (!name) return {
    success: false,
    error: "Sonarr media settings not found for override"
  };
  const current3 = await getSonarrByName$2(cache3, name);
  if (!current3) return {
    success: false,
    error: "Sonarr media settings not found for override"
  };
  const desiredName = resolveString(desiredState.name, current3.name);
  const desiredPropersRepacks = resolveString(desiredState.propers_repacks, current3.propers_repacks);
  const desiredEnableMediaInfo = resolveBoolean(desiredState.enable_media_info, current3.enable_media_info);
  if (current3.name === desiredName && current3.propers_repacks === desiredPropersRepacks && valuesEqual(current3.enable_media_info, desiredEnableMediaInfo)) return { success: true };
  return updateSonarrMediaSettings({
    databaseId,
    cache: cache3,
    layer: "user",
    current: current3,
    input: {
      name: desiredName,
      propersRepacks: desiredPropersRepacks,
      enableMediaInfo: desiredEnableMediaInfo
    }
  });
}
function overrideCreate$1(databaseId, metadata, desiredState) {
  return metadata?.entity === "sonarr_media_settings" ? overrideSonarr$1(databaseId, metadata, desiredState) : overrideRadarr$1(databaseId, metadata, desiredState);
}
function overrideUpdate$1(databaseId, metadata, desiredState) {
  return metadata?.entity === "sonarr_media_settings" ? overrideSonarr$1(databaseId, metadata, desiredState) : overrideRadarr$1(databaseId, metadata, desiredState);
}
async function resolveName(cache3, databaseId, table2, metadata, desiredState) {
  const candidates = [
    metadata?.stable_key?.value,
    metadata?.name,
    getDesiredTo(desiredState?.name),
    typeof desiredState?.name === "string" ? desiredState.name : null
  ].filter((v3) => typeof v3 === "string" && v3.length > 0);
  if (candidates.length === 0) return null;
  for (const name of candidates) {
    const row = await cache3.kb.selectFrom(table2).select("name").where("name", "=", name).executeTakeFirst();
    if (row) return row.name;
  }
  const resolved = followRenameChain(databaseId, table2 === "radarr_quality_definitions" ? "radarr_quality_definitions" : "sonarr_quality_definitions", candidates[0]);
  if (resolved !== candidates[0]) {
    const row = await cache3.kb.selectFrom(table2).select("name").where("name", "=", resolved).executeTakeFirst();
    if (row) return row.name;
  }
  return null;
}
function resolveBulkEntries(desiredState) {
  const field = desiredState.entries;
  if (!field) return null;
  if (typeof field === "object" && "to" in field) {
    const to = field.to;
    if (Array.isArray(to)) return to;
  }
  if (Array.isArray(field)) return field;
  return null;
}
function reconstructEntries(metadata, desiredState, currentEntries) {
  const bulk = resolveBulkEntries(desiredState);
  if (bulk) return bulk;
  const qualityName = metadata?.qualityName;
  if (qualityName) {
    const minTo = getDesiredTo(desiredState.min_size);
    const maxTo = getDesiredTo(desiredState.max_size);
    const preferredTo = getDesiredTo(desiredState.preferred_size);
    return currentEntries.map((entry) => entry.quality_name === qualityName ? {
      ...entry,
      min_size: minTo ?? entry.min_size,
      max_size: maxTo ?? entry.max_size,
      preferred_size: preferredTo ?? entry.preferred_size
    } : entry);
  }
  return currentEntries;
}
function entriesEqual(a2, b3) {
  const normalize4 = (entries) => entries.map((e) => ({
    quality_name: e.quality_name,
    min_size: e.min_size,
    max_size: e.max_size,
    preferred_size: e.preferred_size
  })).sort((x3, y2) => x3.quality_name.localeCompare(y2.quality_name));
  return JSON.stringify(normalize4(a2)) === JSON.stringify(normalize4(b3));
}
async function overrideRadarr(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for radarr quality definitions override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const name = await resolveName(cache3, databaseId, "radarr_quality_definitions", metadata, desiredState);
  if (!name) return {
    success: false,
    error: "Radarr quality definitions not found for override"
  };
  const current3 = await getRadarrByName(cache3, name);
  if (!current3) return {
    success: false,
    error: "Radarr quality definitions not found for override"
  };
  const desiredName = getDesiredTo(desiredState.name) ?? (typeof desiredState.name === "string" ? desiredState.name : current3.name);
  const desiredEntries = reconstructEntries(metadata, desiredState, current3.entries);
  if (current3.name === desiredName && entriesEqual(current3.entries, desiredEntries)) return { success: true };
  return updateRadarrQualityDefinitions({
    databaseId,
    cache: cache3,
    layer: "user",
    current: current3,
    input: {
      name: desiredName,
      entries: desiredEntries
    }
  });
}
async function overrideSonarr(databaseId, metadata, desiredState) {
  if (!desiredState) return {
    success: false,
    error: "Missing desired state for sonarr quality definitions override"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: "Cache not available"
  };
  const name = await resolveName(cache3, databaseId, "sonarr_quality_definitions", metadata, desiredState);
  if (!name) return {
    success: false,
    error: "Sonarr quality definitions not found for override"
  };
  const current3 = await getSonarrByName(cache3, name);
  if (!current3) return {
    success: false,
    error: "Sonarr quality definitions not found for override"
  };
  const desiredName = getDesiredTo(desiredState.name) ?? (typeof desiredState.name === "string" ? desiredState.name : current3.name);
  const desiredEntries = reconstructEntries(metadata, desiredState, current3.entries);
  if (current3.name === desiredName && entriesEqual(current3.entries, desiredEntries)) return { success: true };
  return updateSonarrQualityDefinitions({
    databaseId,
    cache: cache3,
    layer: "user",
    current: current3,
    input: {
      name: desiredName,
      entries: desiredEntries
    }
  });
}
function overrideCreate(databaseId, metadata, desiredState) {
  return metadata?.entity === "sonarr_quality_definitions" ? overrideSonarr(databaseId, metadata, desiredState) : overrideRadarr(databaseId, metadata, desiredState);
}
function overrideUpdate(databaseId, metadata, desiredState) {
  return metadata?.entity === "sonarr_quality_definitions" ? overrideSonarr(databaseId, metadata, desiredState) : overrideRadarr(databaseId, metadata, desiredState);
}
async function overrideEntity(databaseId, metadata, desiredState, operation) {
  const entity = metadata?.entity;
  switch (entity) {
    case "custom_format":
      return operation === "create" ? overrideCreate$4(databaseId, metadata, desiredState) : overrideUpdate$4(databaseId, metadata, desiredState);
    case "quality_profile":
      return operation === "create" ? overrideCreate$3(databaseId, metadata, desiredState) : overrideUpdate$3(databaseId, metadata, desiredState);
    case "regular_expression":
      return operation === "create" ? overrideRegex(databaseId, metadata, desiredState) : overrideRegex(databaseId, metadata, desiredState);
    case "delay_profile":
      return operation === "create" ? overrideDelay(databaseId, metadata, desiredState) : overrideDelay(databaseId, metadata, desiredState);
    case "radarr_naming":
    case "sonarr_naming":
      return operation === "create" ? overrideCreate$2(databaseId, metadata, desiredState) : overrideUpdate$2(databaseId, metadata, desiredState);
    case "radarr_media_settings":
    case "sonarr_media_settings":
      return operation === "create" ? overrideCreate$1(databaseId, metadata, desiredState) : overrideUpdate$1(databaseId, metadata, desiredState);
    case "radarr_quality_definitions":
    case "sonarr_quality_definitions":
      return operation === "create" ? overrideCreate(databaseId, metadata, desiredState) : overrideUpdate(databaseId, metadata, desiredState);
    default:
      return {
        success: false,
        error: `Override not yet implemented for entity: ${entity}`
      };
  }
}
async function overrideConflict(input) {
  const { databaseId, opId } = input;
  const op = pcdOpsQueries.getById(opId);
  if (!op || op.database_id !== databaseId) return {
    success: false,
    error: "Conflict operation not found"
  };
  if (op.origin !== "user" || op.state !== "published") return {
    success: false,
    error: "Only published user operations can be overridden"
  };
  const metadata = parseJson(op.metadata);
  const desiredState = parseJson(op.desired_state);
  const operation = metadata?.operation ?? "update";
  const instance = databaseInstancesQueries.getById(databaseId);
  if (operation === "delete") {
    if (!await dropOp(databaseId, opId)) return {
      success: false,
      error: "Failed to drop conflicting delete operation"
    };
    if (instance?.enabled) await compile(instance.local_path, databaseId);
    await logger.info("Overrode conflict", {
      source: "PCDConflicts",
      meta: {
        databaseId,
        opId
      }
    });
    return { success: true };
  }
  if (!await dropOp(databaseId, opId)) return {
    success: false,
    error: "Failed to drop conflicting operation for override"
  };
  if (instance?.enabled) await compile(instance.local_path, databaseId);
  const result = await overrideEntity(databaseId, metadata, desiredState, operation);
  if (!result.success) return {
    success: false,
    error: result.error || "Failed to override conflict"
  };
  const newOpId = parseOpIdFromFilepath(result.filepath ?? null);
  if (newOpId) await supersedeOp(databaseId, opId, newOpId);
  await logger.info("Overrode conflict", {
    source: "PCDConflicts",
    meta: {
      databaseId,
      opId,
      newOpId
    }
  });
  return { success: true };
}
var GENERAL_FIELDS$1, GENERAL_FIELDS;
var init_override = __esm({
  async "dist/build/server/chunks/override.js"() {
    "use strict";
    await init_db();
    await init_databaseInstances();
    await init_queueService();
    await init_markdown();
    await init_pcdOps();
    init_registry();
    init_read();
    init_read2();
    await init_create();
    init_read3();
    await init_update();
    await init_update2();
    await init_update3();
    await init_update4();
    GENERAL_FIELDS$1 = /* @__PURE__ */ new Set([
      "name",
      "description",
      "include_in_rename",
      "tags"
    ]);
    GENERAL_FIELDS = /* @__PURE__ */ new Set([
      "name",
      "description",
      "tags",
      "language"
    ]);
  }
});

// dist/build/server/chunks/override2.js
var override2_exports = {};
__export(override2_exports, {
  overrideConflict: () => overrideConflict
});
var init_override2 = __esm({
  async "dist/build/server/chunks/override2.js"() {
    "use strict";
    await init_override();
  }
});

// dist/build/server/chunks/markdown.js
async function readManifest(pcdPath) {
  const manifestPath = `${pcdPath}/pcd.json`;
  try {
    const manifestContent = await Deno.readTextFile(manifestPath);
    return JSON.parse(manifestContent);
  } catch (error2) {
    if (error2 instanceof Deno.errors.NotFound) throw new ManifestValidationError("pcd.json not found in repository");
    if (error2 instanceof SyntaxError) throw new ManifestValidationError("pcd.json contains invalid JSON");
    throw error2;
  }
}
function validateManifest(manifest2) {
  if (!manifest2 || typeof manifest2 !== "object") throw new ManifestValidationError("Manifest must be an object");
  const m3 = manifest2;
  if (typeof m3.name !== "string" || !m3.name) throw new ManifestValidationError("Manifest missing required field: name");
  if (typeof m3.version !== "string" || !m3.version) throw new ManifestValidationError("Manifest missing required field: version");
  if (typeof m3.description !== "string" || !m3.description) throw new ManifestValidationError("Manifest missing required field: description");
  if (m3.dependencies !== void 0) {
    if (typeof m3.dependencies !== "object" || m3.dependencies === null) throw new ManifestValidationError("Manifest field dependencies must be an object");
    const deps = m3.dependencies;
    if (Object.keys(deps).length > 0) {
      if (!Object.keys(deps).some((url) => url.includes("/schema"))) throw new ManifestValidationError("Manifest dependencies must include schema repository");
    }
  }
  if (!m3.profilarr || typeof m3.profilarr !== "object") throw new ManifestValidationError("Manifest missing required field: profilarr");
  const profilarr = m3.profilarr;
  if (typeof profilarr.minimum_version !== "string" || !profilarr.minimum_version) throw new ManifestValidationError("Manifest missing required field: profilarr.minimum_version");
  if (m3.arr_types !== void 0) {
    if (!Array.isArray(m3.arr_types)) throw new ManifestValidationError("Manifest field arr_types must be an array");
    const validTypes = [
      "radarr",
      "sonarr",
      "readarr",
      "lidarr",
      "prowlarr",
      "whisparr"
    ];
    for (const type of m3.arr_types) if (typeof type !== "string" || !validTypes.includes(type)) throw new ManifestValidationError(`Invalid arr_type: ${type}. Must be one of: ${validTypes.join(", ")}`);
  }
  if (m3.authors !== void 0) {
    if (!Array.isArray(m3.authors)) throw new ManifestValidationError("Manifest field authors must be an array");
    for (const author of m3.authors) {
      if (!author || typeof author !== "object") throw new ManifestValidationError("Each author must be an object");
      const a2 = author;
      if (typeof a2.name !== "string" || !a2.name) throw new ManifestValidationError("Each author must have a name");
    }
  }
  if (m3.tags !== void 0) {
    if (!Array.isArray(m3.tags)) throw new ManifestValidationError("Manifest field tags must be an array");
    for (const tag2 of m3.tags) if (typeof tag2 !== "string") throw new ManifestValidationError("Each tag must be a string");
  }
}
async function loadManifest(pcdPath) {
  const manifest2 = await readManifest(pcdPath);
  validateManifest(manifest2);
  return manifest2;
}
async function writeManifest(pcdPath, manifest2) {
  validateManifest(manifest2);
  const manifestPath = `${pcdPath}/pcd.json`;
  await Deno.writeTextFile(manifestPath, JSON.stringify(manifest2, null, 2) + "\n");
  await logger.info(`Wrote manifest: ${manifest2.name}`, {
    source: "PCDManifest",
    meta: {
      path: pcdPath,
      manifest: manifest2
    }
  });
}
async function readReadme(pcdPath) {
  try {
    return await Deno.readTextFile(`${pcdPath}/README.md`);
  } catch {
    return null;
  }
}
async function writeReadme(pcdPath, content) {
  await Deno.writeTextFile(`${pcdPath}/README.md`, content);
  await logger.info("Wrote README", {
    source: "PCDManifest",
    meta: {
      path: pcdPath,
      content
    }
  });
}
function getRepoName(repoUrl) {
  const parts = repoUrl.split("/");
  return parts[parts.length - 1];
}
function getDependencyPath(pcdPath, repoName) {
  return `${pcdPath}/deps/${repoName}`;
}
async function dirExists(path) {
  try {
    return (await Deno.stat(path)).isDirectory;
  } catch {
    return false;
  }
}
async function cloneDependency(pcdPath, repoUrl, version, personalAccessToken) {
  const depPath = getDependencyPath(pcdPath, getRepoName(repoUrl));
  await clone(repoUrl, depPath, void 0, personalAccessToken);
  await checkout(depPath, version);
  const keepItems = /* @__PURE__ */ new Set([
    ".git",
    "ops",
    "pcd.json"
  ]);
  for await (const entry of Deno.readDir(depPath)) if (!keepItems.has(entry.name)) {
    const itemPath = `${depPath}/${entry.name}`;
    await Deno.remove(itemPath, { recursive: true });
  }
}
async function getInstalledVersion(pcdPath, repoName) {
  const depManifestPath = `${pcdPath}/deps/${repoName}/pcd.json`;
  try {
    const content = await Deno.readTextFile(depManifestPath);
    return JSON.parse(content).version ?? null;
  } catch {
    return null;
  }
}
async function updateDependency(depPath, version) {
  await fetchTags(depPath);
  await checkout(depPath, version);
}
async function processDependencies(pcdPath, personalAccessToken) {
  const manifest2 = await loadManifest(pcdPath);
  if (!manifest2.dependencies || Object.keys(manifest2.dependencies).length === 0) return;
  const depsDir = `${pcdPath}/deps`;
  await Deno.mkdir(depsDir, { recursive: true });
  for (const [repoUrl, version] of Object.entries(manifest2.dependencies)) {
    const repoName = getRepoName(repoUrl);
    const depPath = getDependencyPath(pcdPath, repoName);
    await cloneDependency(pcdPath, repoUrl, version, personalAccessToken);
    await loadManifest(depPath);
    await logger.debug(`Installed dependency ${repoName}@${version}`, {
      source: "PCDDependencies",
      meta: {
        pcdPath,
        repoName,
        version
      }
    });
  }
}
async function syncDependencies(pcdPath, personalAccessToken) {
  const manifest2 = await loadManifest(pcdPath);
  if (!manifest2.dependencies || Object.keys(manifest2.dependencies).length === 0) return {
    changed: false,
    repositories: []
  };
  const depsDir = `${pcdPath}/deps`;
  await Deno.mkdir(depsDir, { recursive: true });
  const changedRepositories = [];
  for (const [repoUrl, requiredVersion] of Object.entries(manifest2.dependencies)) {
    const repoName = getRepoName(repoUrl);
    const depPath = getDependencyPath(pcdPath, repoName);
    const installedVersion = await getInstalledVersion(pcdPath, repoName);
    if (installedVersion === requiredVersion) continue;
    if (await dirExists(`${depPath}/.git`)) {
      await updateDependency(depPath, requiredVersion);
      await logger.info(`Updated dependency ${repoName}: ${installedVersion} -> ${requiredVersion}`, {
        source: "PCDDependencies",
        meta: {
          pcdPath,
          repoName,
          from: installedVersion,
          to: requiredVersion
        }
      });
      changedRepositories.push(repoName);
    } else {
      try {
        await Deno.remove(depPath, { recursive: true });
      } catch {
      }
      await cloneDependency(pcdPath, repoUrl, requiredVersion, personalAccessToken);
      await logger.info(`Re-cloned dependency ${repoName}@${requiredVersion}`, {
        source: "PCDDependencies",
        meta: {
          pcdPath,
          repoName,
          version: requiredVersion
        }
      });
      changedRepositories.push(repoName);
    }
    await loadManifest(depPath);
  }
  return {
    changed: changedRepositories.length > 0,
    repositories: changedRepositories
  };
}
async function validateDependencies(pcdPath, personalAccessToken) {
  try {
    const manifest2 = await loadManifest(pcdPath);
    if (!manifest2.dependencies || Object.keys(manifest2.dependencies).length === 0) return true;
    let allValid = true;
    for (const [repoUrl, requiredVersion] of Object.entries(manifest2.dependencies)) {
      const repoName = getRepoName(repoUrl);
      const depPath = getDependencyPath(pcdPath, repoName);
      if (!await dirExists(depPath)) {
        await logger.warn(`Missing dependency ${repoName}, will install`, {
          source: "PCDDependencies",
          meta: {
            pcdPath,
            repoName
          }
        });
        allValid = false;
        continue;
      }
      const installedVersion = await getInstalledVersion(pcdPath, repoName);
      if (installedVersion !== requiredVersion) {
        await logger.warn(`Dependency ${repoName} version mismatch: ${installedVersion} != ${requiredVersion}`, {
          source: "PCDDependencies",
          meta: {
            pcdPath,
            repoName,
            installed: installedVersion,
            required: requiredVersion
          }
        });
        allValid = false;
      }
      try {
        await loadManifest(depPath);
      } catch {
        await logger.warn(`Dependency ${repoName} has invalid manifest`, {
          source: "PCDDependencies",
          meta: {
            pcdPath,
            repoName
          }
        });
        allValid = false;
      }
    }
    if (!allValid) await syncDependencies(pcdPath, personalAccessToken);
    return true;
  } catch (error2) {
    await logger.error("Failed to validate dependencies", {
      source: "PCDDependencies",
      meta: {
        pcdPath,
        error: String(error2)
      }
    });
    return false;
  }
}
function DenoSqlite3Adapter(db2) {
  return {
    async executeQuery({ sql: sql2, parameters }) {
      const rows = db2.prepare(sql2).all(...parameters);
      const { changes, lastInsertRowId } = db2;
      return Promise.resolve({
        rows,
        numAffectedRows: BigInt(changes),
        insertId: BigInt(lastInsertRowId)
      });
    },
    async *streamQuery({ sql: sql2, parameters }) {
      const stmt = db2.prepare(sql2).bind(parameters);
      for (const row of stmt) yield { rows: [row] };
    },
    async destroy() {
      db2.close();
    }
  };
}
function toOperation(op, layer, orderOffset = 0) {
  const order = (op.sequence ?? op.id) + orderOffset;
  return {
    filename: op.filename ?? `pcd_op_${op.id}.sql`,
    filepath: `pcd_ops:${op.id}`,
    sql: op.sql,
    order,
    layer
  };
}
function loadDbOps(databaseId, origin, states, orderOffset = 0) {
  return pcdOpsQueries.listByDatabaseAndOrigin(databaseId, origin, { states }).map((op) => toOperation(op, origin, orderOffset)).sort((a2, b3) => a2.order - b3.order);
}
async function loadAllOperations(pcdPath, databaseInstanceId) {
  const allOperations = [];
  const schemaPath = `${pcdPath}/deps/schema/ops`;
  const schemaOps = await loadOperationsFromDir(schemaPath, "schema");
  allOperations.push(...schemaOps);
  const basePublished = loadDbOps(databaseInstanceId, "base", ["published"]);
  allOperations.push(...basePublished);
  const baseDrafts = loadDbOps(databaseInstanceId, "base", ["draft"], DRAFT_SEQUENCE_BASE);
  allOperations.push(...baseDrafts);
  const tweaksPath = `${pcdPath}/tweaks`;
  const tweakOps = await loadOperationsFromDir(tweaksPath, "tweaks");
  allOperations.push(...tweakOps);
  const userOps = loadDbOps(databaseInstanceId, "user", ["published"]);
  allOperations.push(...userOps);
  return allOperations;
}
function mapLatestRow(row) {
  return {
    history: {
      id: row.history_id,
      op_id: row.history_op_id,
      database_id: row.history_database_id,
      batch_id: row.history_batch_id,
      status: row.history_status,
      rowcount: row.history_rowcount,
      conflict_reason: row.history_conflict_reason,
      error: row.history_error,
      details: row.history_details,
      applied_at: toUTC(row.history_applied_at)
    },
    op: {
      id: row.op_row_id,
      database_id: row.op_database_id,
      origin: row.op_origin,
      state: row.op_state,
      source: row.op_source,
      filename: row.op_filename,
      op_number: row.op_op_number,
      sequence: row.op_sequence,
      sql: row.op_sql,
      metadata: row.op_metadata,
      desired_state: row.op_desired_state,
      content_hash: row.op_content_hash,
      last_seen_in_repo_at: toUTC(row.op_last_seen_in_repo_at),
      superseded_by_op_id: row.op_superseded_by_op_id,
      pushed_at: toUTC(row.op_pushed_at),
      pushed_commit: row.op_pushed_commit,
      created_at: toUTC(row.op_created_at),
      updated_at: toUTC(row.op_updated_at)
    }
  };
}
function isFromTo$1(value2) {
  if (!value2 || typeof value2 !== "object") return false;
  return "to" in value2;
}
function valuesEqual$1(expected, actual) {
  if (expected === null || expected === void 0) return actual === null || actual === void 0;
  if (typeof expected === "boolean") {
    if (typeof actual === "boolean") return expected === actual;
    if (typeof actual === "number") return actual === (expected ? 1 : 0);
    if (typeof actual === "string") return actual === (expected ? "1" : "0");
    return false;
  }
  if (typeof expected === "number") {
    if (typeof actual === "number") return expected === actual;
    if (typeof actual === "bigint") return expected === Number(actual);
    if (typeof actual === "string") return expected === Number(actual);
    return false;
  }
  if (typeof expected === "string") return String(actual) === expected;
  return false;
}
function fetchRow(db2, table2, keyColumn, keyValue) {
  try {
    return db2.prepare(`SELECT * FROM ${table2} WHERE ${keyColumn} = ? LIMIT 1`).get(keyValue) ?? null;
  } catch {
    return null;
  }
}
function resolveCurrentRow(db2, entity, metadata, desiredState) {
  const stableKey = metadata?.stableKey?.value;
  if (stableKey) {
    const row = fetchRow(db2, entity.table, entity.keyColumn, stableKey);
    if (row) return row;
  }
  const nameKey = metadata?.name;
  if (nameKey) {
    const row = fetchRow(db2, entity.table, entity.keyColumn, nameKey);
    if (row) return row;
  }
  const desiredName = desiredState?.name;
  if (isFromTo$1(desiredName) && typeof desiredName.to === "string") return fetchRow(db2, entity.table, entity.keyColumn, desiredName.to);
  return null;
}
function isMissingTargetRow(db2, entityName, metadata) {
  if (!entityName) return false;
  const entityConfig = AUTO_ALIGN_ENTITIES.get(entityName);
  if (!entityConfig) return false;
  const stableKey = metadata?.stableKey?.value ?? metadata?.name;
  if (!stableKey) return false;
  return !fetchRow(db2, entityConfig.table, entityConfig.keyColumn, stableKey);
}
function parseJson(raw) {
  if (!raw) return null;
  try {
    return JSON.parse(raw);
  } catch {
    return null;
  }
}
function parseOpIdFromFilepath(path) {
  if (!path) return null;
  if (!path.startsWith("pcd_ops:")) return null;
  const opId = Number(path.slice(8));
  return Number.isFinite(opId) ? opId : null;
}
async function supersedeOp(databaseId, oldOpId, newOpId) {
  if (!newOpId) return false;
  if (!pcdOpsQueries.update(oldOpId, {
    state: "superseded",
    supersededByOpId: newOpId
  })) return false;
  pcdOpHistoryQueries.create({
    opId: oldOpId,
    databaseId,
    batchId: uuid(),
    status: "superseded"
  });
  return true;
}
async function dropOp(databaseId, opId) {
  if (!pcdOpsQueries.update(opId, { state: "dropped" })) return false;
  pcdOpHistoryQueries.create({
    opId,
    databaseId,
    batchId: uuid(),
    status: "dropped"
  });
  return true;
}
function followRenameChain(databaseId, entityType, oldName, maxDepth = 10) {
  const ops = pcdOpsQueries.listByDatabase(databaseId, "base");
  const renameMap = /* @__PURE__ */ new Map();
  const tableName = AUTO_ALIGN_ENTITIES.get(entityType)?.table;
  for (const op of ops) {
    if (op.state !== "published") continue;
    const meta = parseJson(op.metadata);
    if (!meta) continue;
    if (meta.entity === entityType && meta.operation === "update") {
      const ds = parseJson(op.desired_state);
      if (!ds) continue;
      const nameField = ds.name;
      if (nameField && typeof nameField === "object" && "from" in nameField && "to" in nameField) {
        const from = nameField.from;
        const to = nameField.to;
        if (typeof from === "string" && typeof to === "string" && from !== to) renameMap.set(from, to);
      }
      continue;
    }
    if (meta.entity === "batch" && tableName && op.sql) extractRenamesFromSql(op.sql, tableName, renameMap);
  }
  let current3 = oldName;
  const visited = /* @__PURE__ */ new Set();
  for (let i = 0; i < maxDepth; i++) {
    const next2 = renameMap.get(current3);
    if (!next2 || visited.has(next2)) break;
    visited.add(current3);
    current3 = next2;
  }
  return current3;
}
function extractRenamesFromSql(sql2, tableName, renameMap) {
  const escaped2 = tableName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  const pattern2 = new RegExp(`update\\s+"${escaped2}"\\s+set\\s+"name"\\s*=\\s*'((?:[^']|'')*)'\\s+where\\s+"name"\\s*=\\s*'((?:[^']|'')*)'`, "gi");
  for (const match of sql2.matchAll(pattern2)) {
    const newName = match[1].replace(/''/g, "'");
    const oldName = match[2].replace(/''/g, "'");
    if (oldName !== newName) renameMap.set(oldName, newName);
  }
}
function isFromTo(value2) {
  return !!value2 && typeof value2 === "object" && "to" in value2;
}
function getDesiredTo(value2) {
  if (!isFromTo(value2)) return void 0;
  return value2.to;
}
function normalizeText(value2) {
  if (value2 === null || value2 === void 0) return "";
  return String(value2);
}
function normalizeTags(value2) {
  if (!Array.isArray(value2)) return [];
  const set3 = /* @__PURE__ */ new Set();
  for (const item of value2) {
    const name = String(item).trim();
    if (name) set3.add(name);
  }
  return Array.from(set3).sort();
}
function tagsEqual(a2, b3) {
  if (a2.length !== b3.length) return false;
  const sortedA = [...a2].sort();
  const sortedB = [...b3].sort();
  return sortedA.every((value2, idx) => value2 === sortedB[idx]);
}
function normalizeOrderedItems(items) {
  if (!Array.isArray(items)) return [];
  return items.map((item) => {
    const typed = item;
    const members = Array.isArray(typed.members) ? typed.members.map((member) => typeof member === "string" ? member : member?.name ?? "").filter(Boolean) : [];
    return {
      type: typed.type,
      name: typed.name,
      position: typed.position,
      enabled: typed.enabled,
      upgradeUntil: typed.upgradeUntil,
      members
    };
  }).sort((a2, b3) => (a2.position ?? 0) - (b3.position ?? 0));
}
function orderedItemsEqual(a2, b3) {
  const left = normalizeOrderedItems(a2);
  const right = normalizeOrderedItems(b3);
  return JSON.stringify(left) === JSON.stringify(right);
}
function valuesEqual(expected, actual) {
  if (expected === null || expected === void 0) return actual === null || actual === void 0;
  if (typeof expected === "boolean") {
    if (typeof actual === "boolean") return expected === actual;
    if (typeof actual === "number") return actual === (expected ? 1 : 0);
    if (typeof actual === "string") return actual === (expected ? "1" : "0");
    return false;
  }
  if (typeof expected === "number") {
    if (typeof actual === "number") return expected === actual;
    if (typeof actual === "bigint") return expected === Number(actual);
    if (typeof actual === "string") return expected === Number(actual);
    return false;
  }
  if (typeof expected === "string") return String(actual) === expected;
  return false;
}
function hasQualityGroupMembersPositionInCache(cache3) {
  return cache3.query(`PRAGMA table_info('quality_group_members')`).some((column) => column.name === "position");
}
function hasQualityGroupMembersPositionInDb(db2) {
  return db2.prepare(`PRAGMA table_info('quality_group_members')`).all().some((column) => column.name === "position");
}
function checkFullListConflict(db2, metadata, desiredState) {
  if (!desiredState) return false;
  const oi = desiredState.ordered_items;
  if (!oi || typeof oi !== "object" || Array.isArray(oi)) return false;
  const record = oi;
  if (!Array.isArray(record.from) || !Array.isArray(record.to) || "mode" in record) return false;
  const profileName2 = metadata?.stableKey?.value ?? metadata?.name;
  if (!profileName2) return false;
  return !orderedItemsEqual(readCurrentOrderedItems(db2, profileName2), record.to);
}
function readCurrentOrderedItems(db2, profileName2) {
  const rows = db2.prepare(`SELECT
	CASE WHEN quality_name IS NOT NULL THEN 'quality' ELSE 'group' END as type,
	COALESCE(quality_name, quality_group_name) as name,
	position,
	enabled,
	upgrade_until
FROM quality_profile_qualities
WHERE quality_profile_name = ?
ORDER BY position`).all(profileName2);
  const memberRows = db2.prepare(`SELECT quality_group_name, quality_name
FROM quality_group_members
WHERE quality_profile_name = ?
ORDER BY quality_group_name, ${hasQualityGroupMembersPositionInDb(db2) ? "position, " : ""}quality_name`).all(profileName2);
  const membersByGroup = /* @__PURE__ */ new Map();
  for (const row of memberRows) {
    const existing = membersByGroup.get(row.quality_group_name) ?? [];
    existing.push(row.quality_name);
    membersByGroup.set(row.quality_group_name, existing);
  }
  return rows.map((row) => ({
    type: row.type,
    name: row.name,
    position: row.position,
    enabled: row.enabled === 1,
    upgradeUntil: row.upgrade_until === 1,
    ...row.type === "group" ? { members: (membersByGroup.get(row.name) ?? []).map((n) => ({ name: n })) } : {}
  }));
}
function toBoolean(value2) {
  if (typeof value2 === "boolean") return value2;
  if (typeof value2 === "number") return value2 !== 0;
  if (typeof value2 === "string") {
    const normalized = value2.trim().toLowerCase();
    return normalized === "1" || normalized === "true";
  }
  return false;
}
function parseQualityKey(key2) {
  if (typeof key2 !== "string" || key2.length === 0) return null;
  const firstColon = key2.indexOf(":");
  if (firstColon <= 0) return null;
  const type = key2.slice(0, firstColon);
  const name = key2.slice(firstColon + 1);
  if (type !== "quality" && type !== "group" || name.length === 0) return null;
  return {
    type,
    name
  };
}
function normalizeMembers(value2) {
  if (!Array.isArray(value2)) return [];
  const members = value2.map((member) => {
    if (typeof member === "string") return member;
    if (member && typeof member === "object" && "name" in member) {
      const name = member.name;
      return typeof name === "string" ? name : "";
    }
    return "";
  }).filter((name) => name.length > 0);
  return Array.from(new Set(members));
}
function parseQualityRow(value2) {
  if (!value2 || typeof value2 !== "object") return null;
  const row = value2;
  if (row.type !== "quality" && row.type !== "group") return null;
  if (typeof row.name !== "string" || row.name.length === 0) return null;
  if (typeof row.position !== "number" || !Number.isFinite(row.position)) return null;
  const upgradeRaw = row.upgradeUntil ?? row.upgrade_until;
  return {
    type: row.type,
    name: row.name,
    position: row.position,
    enabled: toBoolean(row.enabled),
    upgradeUntil: toBoolean(upgradeRaw),
    members: row.type === "group" ? normalizeMembers(row.members) : []
  };
}
function qualityRowsEqual(a2, b3) {
  if (a2.type !== b3.type || a2.name !== b3.name || a2.position !== b3.position || a2.enabled !== b3.enabled || a2.upgradeUntil !== b3.upgradeUntil) return false;
  if (a2.type !== "group") return true;
  if (a2.members.length !== b3.members.length) return false;
  return a2.members.every((member, index88) => member === b3.members[index88]);
}
function fetchQualityProfileRow(db2, profileName2, ref) {
  const baseRow = ref.type === "quality" ? db2.prepare(`SELECT position, enabled, upgrade_until
FROM quality_profile_qualities
WHERE quality_profile_name = ?
  AND quality_name = ?
  AND quality_group_name IS NULL
LIMIT 1`).get(profileName2, ref.name) : db2.prepare(`SELECT position, enabled, upgrade_until
FROM quality_profile_qualities
WHERE quality_profile_name = ?
  AND quality_group_name = ?
  AND quality_name IS NULL
LIMIT 1`).get(profileName2, ref.name);
  if (!baseRow) return null;
  const typedRow = baseRow;
  let members = [];
  if (ref.type === "group") {
    const hasGroupMemberPosition = hasQualityGroupMembersPositionInDb(db2);
    members = db2.prepare(`SELECT quality_name
FROM quality_group_members
WHERE quality_profile_name = ?
  AND quality_group_name = ?
ORDER BY ${hasGroupMemberPosition ? "position, " : ""}quality_name`).all(profileName2, ref.name).map((row) => row.quality_name);
  }
  return {
    type: ref.type,
    name: ref.name,
    position: Number(typedRow.position),
    enabled: Number(typedRow.enabled) === 1,
    upgradeUntil: Number(typedRow.upgrade_until) === 1,
    members
  };
}
function shouldAutoAlignQualityProfileQualitiesRow(db2, metadata, desiredState) {
  const profileName2 = metadata?.stableKey?.value ?? metadata?.name;
  if (!profileName2) return false;
  const orderedItems = desiredState.ordered_items;
  if (!orderedItems || typeof orderedItems !== "object") return false;
  const rowPayload = orderedItems;
  if (!rowPayload.mode && Array.isArray(rowPayload.from) && Array.isArray(rowPayload.to)) return orderedItemsEqual(readCurrentOrderedItems(db2, profileName2), rowPayload.to);
  if (rowPayload.mode !== "add" && rowPayload.mode !== "remove" && rowPayload.mode !== "update") return false;
  const fromRows = Array.isArray(rowPayload.from) ? rowPayload.from : [];
  const toRows = Array.isArray(rowPayload.to) ? rowPayload.to : [];
  const fromRow = fromRows.length > 0 ? parseQualityRow(fromRows[0]) : null;
  const toRow = toRows.length > 0 ? parseQualityRow(toRows[0]) : null;
  const keyRef = parseQualityKey(rowPayload.key);
  if (rowPayload.mode === "remove") {
    const identity = fromRow ? {
      type: fromRow.type,
      name: fromRow.name
    } : keyRef;
    if (!identity) return false;
    return fetchQualityProfileRow(db2, profileName2, identity) === null;
  }
  const desiredRow = toRow;
  if (!desiredRow) return false;
  const currentRow = fetchQualityProfileRow(db2, profileName2, {
    type: desiredRow.type,
    name: desiredRow.name
  });
  if (!currentRow) return false;
  return qualityRowsEqual(desiredRow, currentRow);
}
function parseScoringDesiredEntry(value2) {
  if (!value2 || typeof value2 !== "object") return null;
  const row = value2;
  if (typeof row.custom_format_name !== "string" || row.custom_format_name.length === 0 || typeof row.arr_type !== "string" || row.arr_type.length === 0 || !("from" in row) || !("to" in row)) return null;
  return {
    custom_format_name: row.custom_format_name,
    arr_type: row.arr_type,
    from: row.from,
    to: row.to
  };
}
function normalizeScore(value2) {
  if (value2 === null || value2 === void 0) return null;
  if (typeof value2 === "number") return Number.isFinite(value2) ? value2 : null;
  if (typeof value2 === "bigint") return Number(value2);
  if (typeof value2 === "string") {
    const parsed = Number(value2);
    return Number.isFinite(parsed) ? parsed : null;
  }
  return null;
}
function fetchQualityProfileScore(db2, profileName2, customFormatName, arrType) {
  const row = db2.prepare(`SELECT score
FROM quality_profile_custom_formats
WHERE quality_profile_name = ?
  AND custom_format_name = ?
  AND arr_type = ?
LIMIT 1`).get(profileName2, customFormatName, arrType);
  if (!row) return null;
  return normalizeScore(row.score);
}
function shouldAutoAlignQualityProfileScoringRow(db2, metadata, desiredState) {
  const profileName2 = metadata?.stableKey?.value ?? metadata?.name;
  if (!profileName2) return false;
  const rawScores = desiredState.custom_format_scores;
  if (!Array.isArray(rawScores) || rawScores.length !== 1) return false;
  const entry = parseScoringDesiredEntry(rawScores[0]);
  if (!entry) return false;
  const currentScore = fetchQualityProfileScore(db2, profileName2, entry.custom_format_name, entry.arr_type);
  const desiredTo = normalizeScore(entry.to);
  if (desiredTo === null) return currentScore === null;
  if (currentScore === null) return false;
  return currentScore === desiredTo;
}
function evaluateAutoAlign(input) {
  if (input.conflictStrategy === "align") return {
    shouldAlign: true,
    reason: "forced",
    rule: "force_align_strategy"
  };
  if (input.metadata?.operation === "delete") {
    const ctx = {
      db: input.db,
      entityName: input.metadata.entity,
      metadata: input.metadata
    };
    for (const rule of DELETE_RULES) {
      if (!rule.matches(ctx)) continue;
      if (rule.shouldAlign(ctx)) return {
        shouldAlign: true,
        reason: "auto_delete",
        rule: rule.name
      };
    }
  }
  if (input.metadata?.operation === "update") {
    const ctx = {
      db: input.db,
      entityName: input.metadata.entity,
      metadata: input.metadata,
      desiredState: input.desiredState
    };
    for (const rule of UPDATE_RULES) {
      if (!rule.matches(ctx)) continue;
      if (rule.shouldAlign(ctx)) return {
        shouldAlign: true,
        reason: "auto_update",
        rule: rule.name
      };
    }
  }
  return {
    shouldAlign: false,
    reason: "none"
  };
}
function parseOpMetadata(raw) {
  if (!raw) return null;
  try {
    return JSON.parse(raw);
  } catch {
    return null;
  }
}
function parseDesiredState(raw) {
  if (!raw) return null;
  try {
    return JSON.parse(raw);
  } catch {
    return null;
  }
}
function parseOpId(filepath) {
  if (!filepath.startsWith("pcd_ops:")) return null;
  const raw = filepath.slice(8);
  const opId = Number(raw);
  return Number.isFinite(opId) ? opId : null;
}
function getConflictReason(metadata) {
  switch (metadata?.operation) {
    case "create":
      return "duplicate_key";
    case "delete":
      return "missing_target";
    default:
      return "guard_mismatch";
  }
}
function isUniqueConstraintError(errorStr) {
  return errorStr.includes("UNIQUE constraint failed");
}
function isForeignKeyConstraintError(errorStr) {
  return errorStr.includes("FOREIGN KEY constraint failed");
}
function listPublishedUserConflicts(databaseInstanceId) {
  const latestConflicts = pcdOpHistoryQueries.listLatestConflictsByDatabase(databaseInstanceId);
  const opIds = [];
  for (const conflict of latestConflicts) {
    if (conflict.history.status !== "conflicted") continue;
    if (conflict.op.origin !== "user") continue;
    if (conflict.op.state !== "published") continue;
    opIds.push(conflict.op.id);
  }
  return opIds.sort((a2, b3) => a2 - b3);
}
async function autoResolveOverrideConflicts(databaseInstanceId) {
  const instance = databaseInstancesQueries.getById(databaseInstanceId);
  if (!instance?.enabled) return;
  if (instance.conflict_strategy !== "override") return;
  if (autoOverrideLocks.has(databaseInstanceId)) return;
  const initialConflicts = listPublishedUserConflicts(databaseInstanceId);
  if (initialConflicts.length === 0) return;
  autoOverrideLocks.add(databaseInstanceId);
  try {
    const { overrideConflict: overrideConflict2 } = await init_override2().then(() => override2_exports);
    await logger.info("Starting automatic override conflict resolution", {
      source: "PCDCompiler",
      meta: {
        databaseInstanceId,
        conflictCount: initialConflicts.length
      }
    });
    for (let round = 1; round <= AUTO_OVERRIDE_MAX_ROUNDS; round++) {
      const conflicts = listPublishedUserConflicts(databaseInstanceId);
      if (conflicts.length === 0) {
        await logger.info("Finished automatic override conflict resolution", {
          source: "PCDCompiler",
          meta: {
            databaseInstanceId,
            rounds: round - 1
          }
        });
        return;
      }
      let resolvedThisRound = 0;
      for (const opId of conflicts) {
        const result = await overrideConflict2({
          databaseId: databaseInstanceId,
          opId
        });
        if (result.success) {
          resolvedThisRound++;
          continue;
        }
        await logger.warn("Automatic override failed for conflict op", {
          source: "PCDCompiler",
          meta: {
            databaseInstanceId,
            opId,
            error: result.error
          }
        });
      }
      if (resolvedThisRound === 0) {
        await logger.warn("Automatic override made no progress; leaving conflicts for manual resolution", {
          source: "PCDCompiler",
          meta: {
            databaseInstanceId,
            round,
            remainingConflicts: conflicts.length
          }
        });
        return;
      }
    }
    const remaining = listPublishedUserConflicts(databaseInstanceId).length;
    if (remaining > 0) await logger.warn("Automatic override reached round limit", {
      source: "PCDCompiler",
      meta: {
        databaseInstanceId,
        maxRounds: AUTO_OVERRIDE_MAX_ROUNDS,
        remainingConflicts: remaining
      }
    });
  } finally {
    autoOverrideLocks.delete(databaseInstanceId);
  }
}
async function compile(pcdPath, databaseInstanceId) {
  const existing = getCache(databaseInstanceId);
  let cache3 = new PCDCache(pcdPath, databaseInstanceId);
  let stats = await cache3.build();
  if (stats.needsRebuild) {
    cache3.close();
    cache3 = new PCDCache(pcdPath, databaseInstanceId);
    stats = await cache3.build();
  }
  setCache(databaseInstanceId, cache3);
  if (existing && existing !== cache3) existing.close();
  if (!autoOverrideLocks.has(databaseInstanceId)) await autoResolveOverrideConflicts(databaseInstanceId);
  return stats;
}
function invalidate(databaseInstanceId) {
  const cache3 = getCache(databaseInstanceId);
  if (cache3) {
    cache3.close();
    deleteCache(databaseInstanceId);
  }
}
function parseMarkdown(markdown) {
  if (!markdown) return "";
  const html2 = g2.parse(markdown);
  return sanitizeHtml(html2);
}
var PCDError, ManifestValidationError, PolySqliteDriver, PolySqliteConnection, ConnectionMutex, PolySqliteDialect, DenoSqlite3Dialect, DRAFT_SEQUENCE_BASE, pcdOpHistoryQueries, NAMING_FIELDS, SONARR_NAMING_FIELDS, MEDIA_SETTINGS_FIELDS, QUALITY_DEFINITIONS_FIELDS, AUTO_ALIGN_ENTITIES, defaultFieldGuardRule, missingTargetDeleteRule, qualityProfileQualitiesRowRule, UPDATE_RULES, DELETE_RULES, PCDCache, AUTO_OVERRIDE_MAX_ROUNDS, autoOverrideLocks;
var init_markdown = __esm({
  async "dist/build/server/chunks/markdown.js"() {
    "use strict";
    await init_db();
    init_dates();
    await init_databaseInstances();
    init_operations2();
    init_uuid();
    await init_git();
    await init_pcdOps();
    init_registry();
    init_sanitize();
    init_esm();
    init_marked_esm();
    PCDError = class extends Error {
      constructor(message2) {
        super(message2);
        this.name = "PCDError";
      }
    };
    ManifestValidationError = class extends PCDError {
      constructor(message2) {
        super(message2);
        this.name = "ManifestValidationError";
      }
    };
    PolySqliteDriver = class {
      #config;
      #connectionMutex = new ConnectionMutex();
      #connection;
      constructor(config2) {
        this.#config = Object.freeze({ ...config2 });
      }
      async init() {
        this.#connection = new PolySqliteConnection(this.#config.database);
        if (this.#config.onCreateConnection) await this.#config.onCreateConnection(this.#connection);
      }
      async acquireConnection() {
        await this.#connectionMutex.lock();
        return this.#connection;
      }
      async beginTransaction(connection) {
        await connection.executeQuery(CompiledQuery.raw("begin"));
      }
      async commitTransaction(connection) {
        await connection.executeQuery(CompiledQuery.raw("commit"));
      }
      async rollbackTransaction(connection) {
        await connection.executeQuery(CompiledQuery.raw("rollback"));
      }
      async releaseConnection() {
        this.#connectionMutex.unlock();
      }
      async destroy() {
        this.#config.database?.destroy();
      }
    };
    PolySqliteConnection = class {
      #db;
      constructor(db2) {
        this.#db = db2;
      }
      executeQuery(query) {
        return this.#db.executeQuery(query);
      }
      streamQuery(query) {
        if (!this.#db.streamQuery) throw new Error("Streaming queries are not supported by the database driver.");
        return this.#db.streamQuery(query);
      }
    };
    ConnectionMutex = class {
      #promise;
      #resolve;
      async lock() {
        while (this.#promise) await this.#promise;
        this.#promise = new Promise((resolve6) => {
          this.#resolve = resolve6;
        });
      }
      unlock() {
        const resolve6 = this.#resolve;
        this.#promise = void 0;
        this.#resolve = void 0;
        resolve6?.();
      }
    };
    PolySqliteDialect = class {
      #config;
      constructor(config2) {
        this.#config = Object.freeze({ ...config2 });
      }
      createDriver() {
        return new PolySqliteDriver(this.#config);
      }
      createQueryCompiler() {
        return new SqliteQueryCompiler();
      }
      createAdapter() {
        return new SqliteAdapter();
      }
      createIntrospector(db2) {
        return new SqliteIntrospector(db2);
      }
    };
    DenoSqlite3Dialect = class extends PolySqliteDialect {
      constructor({ database, ...config2 }) {
        super({
          ...config2,
          database: DenoSqlite3Adapter(database)
        });
      }
    };
    DRAFT_SEQUENCE_BASE = 3e9;
    pcdOpHistoryQueries = {
      create(input) {
        db.execute(`INSERT INTO pcd_op_history (
				op_id, database_id, batch_id, status,
				rowcount, conflict_reason, error, details
			) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, input.opId, input.databaseId, input.batchId, input.status, input.rowcount ?? null, input.conflictReason ?? null, input.error ?? null, input.details ?? null);
        return db.queryFirst("SELECT last_insert_rowid() as id")?.id ?? 0;
      },
      listByOp(opId) {
        return db.query("SELECT * FROM pcd_op_history WHERE op_id = ? ORDER BY applied_at DESC, id DESC", opId);
      },
      listByDatabase(databaseId) {
        return db.query("SELECT * FROM pcd_op_history WHERE database_id = ? ORDER BY applied_at DESC, id DESC", databaseId);
      },
      listLatestByDatabaseWithOps(databaseId, statuses) {
        const params = [databaseId];
        let statusClause = "";
        if (statuses && statuses.length > 0) {
          statusClause = `AND latest.status IN (${statuses.map(() => "?").join(", ")})`;
          params.push(...statuses);
        }
        return db.query(`SELECT
				latest.id as history_id,
				latest.op_id as history_op_id,
				latest.database_id as history_database_id,
				latest.batch_id as history_batch_id,
				latest.status as history_status,
				latest.rowcount as history_rowcount,
				latest.conflict_reason as history_conflict_reason,
				latest.error as history_error,
				latest.details as history_details,
				latest.applied_at as history_applied_at,
				op.id as op_row_id,
				op.database_id as op_database_id,
				op.origin as op_origin,
				op.state as op_state,
				op.source as op_source,
				op.filename as op_filename,
				op.op_number as op_op_number,
				op.sequence as op_sequence,
				op.sql as op_sql,
				op.metadata as op_metadata,
				op.desired_state as op_desired_state,
				op.content_hash as op_content_hash,
				op.last_seen_in_repo_at as op_last_seen_in_repo_at,
				op.superseded_by_op_id as op_superseded_by_op_id,
				op.pushed_at as op_pushed_at,
				op.pushed_commit as op_pushed_commit,
				op.created_at as op_created_at,
				op.updated_at as op_updated_at
			FROM (
				SELECT *,
					ROW_NUMBER() OVER (PARTITION BY op_id ORDER BY applied_at DESC, id DESC) as rn
				FROM pcd_op_history
				WHERE database_id = ?
			) as latest
			JOIN pcd_ops op ON op.id = latest.op_id
			WHERE latest.rn = 1
			${statusClause}
			ORDER BY latest.applied_at DESC, latest.id DESC`, ...params).map(mapLatestRow);
      },
      listLatestConflictsByDatabase(databaseId) {
        return this.listLatestByDatabaseWithOps(databaseId, ["conflicted", "conflicted_pending"]);
      }
    };
    NAMING_FIELDS = [
      "name",
      "rename",
      "movie_format",
      "movie_folder_format",
      "replace_illegal_characters",
      "colon_replacement_format"
    ];
    SONARR_NAMING_FIELDS = [
      ...NAMING_FIELDS,
      "standard_episode_format",
      "daily_episode_format",
      "anime_episode_format",
      "series_folder_format",
      "season_folder_format",
      "custom_colon_replacement_format",
      "multi_episode_style"
    ];
    MEDIA_SETTINGS_FIELDS = [
      "name",
      "propers_repacks",
      "enable_media_info"
    ];
    QUALITY_DEFINITIONS_FIELDS = [
      "name",
      "quality_name",
      "min_size",
      "max_size",
      "preferred_size"
    ];
    AUTO_ALIGN_ENTITIES = /* @__PURE__ */ new Map([
      ["quality_profile", {
        table: "quality_profiles",
        keyColumn: "name",
        fields: [
          "name",
          "description",
          "upgrades_allowed",
          "minimum_custom_format_score",
          "upgrade_until_score",
          "upgrade_score_increment"
        ]
      }],
      ["custom_format", {
        table: "custom_formats",
        keyColumn: "name",
        fields: [
          "name",
          "description",
          "include_in_rename"
        ]
      }],
      ["regular_expression", {
        table: "regular_expressions",
        keyColumn: "name",
        fields: [
          "name",
          "pattern",
          "regex101_id",
          "description"
        ]
      }],
      ["delay_profile", {
        table: "delay_profiles",
        keyColumn: "name",
        fields: [
          "name",
          "preferred_protocol",
          "usenet_delay",
          "torrent_delay",
          "bypass_if_highest_quality",
          "bypass_if_above_custom_format_score",
          "minimum_custom_format_score"
        ]
      }],
      ["radarr_naming", {
        table: "radarr_naming",
        keyColumn: "name",
        fields: NAMING_FIELDS
      }],
      ["sonarr_naming", {
        table: "sonarr_naming",
        keyColumn: "name",
        fields: SONARR_NAMING_FIELDS
      }],
      ["radarr_media_settings", {
        table: "radarr_media_settings",
        keyColumn: "name",
        fields: MEDIA_SETTINGS_FIELDS
      }],
      ["sonarr_media_settings", {
        table: "sonarr_media_settings",
        keyColumn: "name",
        fields: MEDIA_SETTINGS_FIELDS
      }],
      ["radarr_quality_definitions", {
        table: "radarr_quality_definitions",
        keyColumn: "name",
        fields: QUALITY_DEFINITIONS_FIELDS
      }],
      ["sonarr_quality_definitions", {
        table: "sonarr_quality_definitions",
        keyColumn: "name",
        fields: QUALITY_DEFINITIONS_FIELDS
      }]
    ]);
    defaultFieldGuardRule = {
      name: "default_field_guard",
      matches: ({ desiredState }) => !!desiredState,
      shouldAlign: ({ db: db2, entityName, metadata, desiredState }) => {
        if (!entityName || !desiredState) return false;
        const entityConfig = AUTO_ALIGN_ENTITIES.get(entityName);
        if (!entityConfig) return false;
        const fields = entityConfig.fields;
        if (!fields || fields.length === 0) return false;
        const keys = Object.keys(desiredState);
        if (keys.length === 0) return false;
        for (const key2 of keys) {
          if (!fields.includes(key2)) return false;
          if (!isFromTo$1(desiredState[key2])) return false;
        }
        const row = resolveCurrentRow(db2, entityConfig, metadata, desiredState);
        if (!row) return false;
        return keys.every((key2) => valuesEqual$1(desiredState[key2].to, row[key2]));
      }
    };
    missingTargetDeleteRule = {
      name: "missing_target",
      matches: ({ entityName }) => !!entityName,
      shouldAlign: ({ db: db2, entityName, metadata }) => isMissingTargetRow(db2, entityName, metadata)
    };
    qualityProfileQualitiesRowRule = {
      name: "quality_profile_qualities_row",
      matches: ({ entityName, desiredState }) => entityName === "quality_profile" && !!desiredState && "ordered_items" in desiredState,
      shouldAlign: ({ db: db2, metadata, desiredState }) => shouldAutoAlignQualityProfileQualitiesRow(db2, metadata, desiredState ?? {})
    };
    UPDATE_RULES = [
      qualityProfileQualitiesRowRule,
      {
        name: "quality_profile_scoring_row",
        matches: ({ entityName, desiredState }) => entityName === "quality_profile" && !!desiredState && "custom_format_scores" in desiredState,
        shouldAlign: ({ db: db2, metadata, desiredState }) => shouldAutoAlignQualityProfileScoringRow(db2, metadata, desiredState ?? {})
      },
      defaultFieldGuardRule
    ];
    DELETE_RULES = [missingTargetDeleteRule];
    PCDCache = class {
      db = null;
      kysely = null;
      pcdPath;
      databaseInstanceId;
      built = false;
      constructor(pcdPath, databaseInstanceId) {
        this.pcdPath = pcdPath;
        this.databaseInstanceId = databaseInstanceId;
      }
      /**
      * Build the cache by executing all operations in layer order
      * Returns stats about what was loaded
      */
      async build() {
        const startTime = performance.now();
        const batchId = uuid();
        const conflictStrategy = databaseInstancesQueries.getById(this.databaseInstanceId)?.conflict_strategy ?? "override";
        const userOps = pcdOpsQueries.listByDatabaseAndOrigin(this.databaseInstanceId, "user", { states: ["published"] });
        const userOpsById = new Map(userOps.map((op) => [op.id, op]));
        const priorConflicts = /* @__PURE__ */ new Map();
        try {
          const latestConflicts = pcdOpHistoryQueries.listLatestByDatabaseWithOps(this.databaseInstanceId, ["conflicted", "conflicted_pending"]);
          for (const entry of latestConflicts) priorConflicts.set(entry.history.op_id, entry.history.conflict_reason);
        } catch (error2) {
          await logger.warn("Failed to load prior conflicts", {
            source: "PCDCache",
            meta: {
              error: String(error2),
              databaseInstanceId: this.databaseInstanceId
            }
          });
        }
        try {
          this.db = new Database(":memory:", { int64: true });
          this.db.exec("PRAGMA foreign_keys = ON");
          this.kysely = new Kysely({ dialect: new DenoSqlite3Dialect({ database: this.db }) });
          this.registerHelperFunctions();
          const operations = await loadAllOperations(this.pcdPath, this.databaseInstanceId);
          validateOperations(operations);
          const stats = {
            schema: operations.filter((o) => o.layer === "schema").length,
            base: operations.filter((o) => o.layer === "base").length,
            tweaks: operations.filter((o) => o.layer === "tweaks").length,
            user: operations.filter((o) => o.layer === "user").length,
            timing: 0
          };
          for (const operation of operations) {
            const opId = parseOpId(operation.filepath);
            const trackHistory = opId !== null;
            const userOp = trackHistory ? userOpsById.get(opId) : void 0;
            const isUserOp = !!userOp;
            const beforeChanges = trackHistory ? this.db.totalChanges : 0;
            try {
              this.db.exec(operation.sql);
              if (trackHistory) {
                const rowcount = this.db.totalChanges - beforeChanges;
                try {
                  let status = rowcount === 0 ? "skipped" : "applied";
                  let conflictReason = null;
                  if (rowcount === 0 && isUserOp) {
                    const metadata = parseOpMetadata(userOp?.metadata ?? null);
                    const desiredState = parseDesiredState(userOp?.desired_state ?? null);
                    const autoAlignDecision = evaluateAutoAlign({
                      db: this.db,
                      conflictStrategy,
                      metadata,
                      desiredState
                    });
                    if (autoAlignDecision.shouldAlign) {
                      if (pcdOpsQueries.update(opId, { state: "dropped" })) {
                        status = "dropped";
                        conflictReason = "aligned";
                        await logger.info(autoAlignDecision.reason === "forced" ? "Forced align conflict" : "Auto-aligned conflict", {
                          source: "PCDCache",
                          meta: {
                            opId,
                            databaseInstanceId: this.databaseInstanceId,
                            conflictStrategy,
                            conflictReason,
                            autoAlignReason: autoAlignDecision.reason,
                            autoAlignRule: autoAlignDecision.rule
                          }
                        });
                      }
                    }
                    if (status !== "dropped") {
                      status = conflictStrategy === "ask" ? "conflicted_pending" : "conflicted";
                      conflictReason = getConflictReason(metadata);
                      if (priorConflicts.get(opId) !== conflictReason) await logger.info("Recorded op conflict", {
                        source: "PCDCache",
                        meta: {
                          opId,
                          databaseInstanceId: this.databaseInstanceId,
                          conflictStrategy,
                          conflictReason
                        }
                      });
                    }
                  }
                  if (status === "applied" && isUserOp) {
                    const metadata = parseOpMetadata(userOp?.metadata ?? null);
                    const desiredState = parseDesiredState(userOp?.desired_state ?? null);
                    if (checkFullListConflict(this.db, metadata, desiredState)) {
                      if (conflictStrategy === "align") {
                        if (pcdOpsQueries.update(opId, { state: "dropped" })) {
                          status = "dropped";
                          conflictReason = "aligned";
                          stats.needsRebuild = true;
                          await logger.info("Forced align conflict (full-list mismatch)", {
                            source: "PCDCache",
                            meta: {
                              opId,
                              databaseInstanceId: this.databaseInstanceId,
                              conflictStrategy,
                              conflictReason
                            }
                          });
                        }
                      }
                      if (status !== "dropped") {
                        status = conflictStrategy === "ask" ? "conflicted_pending" : "conflicted";
                        conflictReason = "guard_mismatch";
                        if (priorConflicts.get(opId) !== conflictReason) await logger.info("Recorded op conflict (full-list mismatch)", {
                          source: "PCDCache",
                          meta: {
                            opId,
                            databaseInstanceId: this.databaseInstanceId,
                            conflictStrategy,
                            conflictReason
                          }
                        });
                      }
                    }
                  }
                  pcdOpHistoryQueries.create({
                    opId,
                    databaseId: this.databaseInstanceId,
                    batchId,
                    status,
                    rowcount,
                    conflictReason
                  });
                } catch (historyError) {
                  await logger.warn("Failed to record op history", {
                    source: "PCDCache",
                    meta: {
                      opId,
                      databaseInstanceId: this.databaseInstanceId,
                      error: String(historyError)
                    }
                  });
                }
              }
            } catch (error2) {
              const errorStr = String(error2);
              const isDuplicateKey = isUserOp && isUniqueConstraintError(errorStr);
              const isMissingTarget = isUserOp && isForeignKeyConstraintError(errorStr);
              if (trackHistory && (isDuplicateKey || isMissingTarget)) {
                let status = conflictStrategy === "ask" ? "conflicted_pending" : "conflicted";
                let conflictReason = isDuplicateKey ? "duplicate_key" : "missing_target";
                if (conflictStrategy === "align") {
                  if (pcdOpsQueries.update(opId, { state: "dropped" })) {
                    status = "dropped";
                    conflictReason = "aligned";
                    stats.needsRebuild = true;
                    await logger.info("Forced align conflict", {
                      source: "PCDCache",
                      meta: {
                        opId,
                        databaseInstanceId: this.databaseInstanceId,
                        conflictStrategy,
                        conflictReason
                      }
                    });
                  }
                }
                if (priorConflicts.get(opId) !== conflictReason) await logger.info("Recorded op conflict", {
                  source: "PCDCache",
                  meta: {
                    opId,
                    databaseInstanceId: this.databaseInstanceId,
                    conflictStrategy,
                    conflictReason
                  }
                });
                try {
                  pcdOpHistoryQueries.create({
                    opId,
                    databaseId: this.databaseInstanceId,
                    batchId,
                    status,
                    rowcount: 0,
                    conflictReason,
                    error: errorStr,
                    details: JSON.stringify({
                      layer: operation.layer,
                      filename: operation.filename
                    })
                  });
                } catch (historyError) {
                  await logger.warn("Failed to record op history", {
                    source: "PCDCache",
                    meta: {
                      opId,
                      databaseInstanceId: this.databaseInstanceId,
                      error: String(historyError)
                    }
                  });
                }
                continue;
              }
              if (trackHistory) try {
                pcdOpHistoryQueries.create({
                  opId,
                  databaseId: this.databaseInstanceId,
                  batchId,
                  status: "error",
                  rowcount: null,
                  error: errorStr,
                  details: JSON.stringify({
                    layer: operation.layer,
                    filename: operation.filename
                  })
                });
              } catch (historyError) {
                await logger.warn("Failed to record op history", {
                  source: "PCDCache",
                  meta: {
                    opId,
                    databaseInstanceId: this.databaseInstanceId,
                    error: String(historyError)
                  }
                });
              }
              throw new Error(`Failed to execute operation ${operation.filename} in ${operation.layer} layer: ${error2}`);
            }
          }
          this.built = true;
          stats.timing = Math.round(performance.now() - startTime);
          return stats;
        } catch (error2) {
          await logger.error("Failed to build PCD cache", {
            source: "PCDCache",
            meta: {
              error: String(error2),
              databaseInstanceId: this.databaseInstanceId
            }
          });
          await disableDatabaseInstance(this.databaseInstanceId);
          this.close();
          throw error2;
        }
      }
      /**
      * Register SQL helper functions (qp, cf, dp, tag)
      */
      registerHelperFunctions() {
        if (!this.db) return;
        this.db.function("qp", (name) => {
          const result = this.db.prepare("SELECT id FROM quality_profiles WHERE name = ?").get(name);
          if (!result) throw new Error(`Quality profile not found: ${name}`);
          return result.id;
        });
        this.db.function("cf", (name) => {
          const result = this.db.prepare("SELECT id FROM custom_formats WHERE name = ?").get(name);
          if (!result) throw new Error(`Custom format not found: ${name}`);
          return result.id;
        });
        this.db.function("dp", (name) => {
          const result = this.db.prepare("SELECT id FROM delay_profiles WHERE name = ?").get(name);
          if (!result) throw new Error(`Delay profile not found: ${name}`);
          return result.id;
        });
        this.db.function("tag", (name) => {
          const result = this.db.prepare("SELECT id FROM tags WHERE name = ?").get(name);
          if (!result) throw new Error(`Tag not found: ${name}`);
          return result.id;
        });
      }
      /**
      * Check if cache is built and ready
      */
      isBuilt() {
        return this.built && this.db !== null;
      }
      /**
      * Close the database connection
      */
      close() {
        if (this.kysely) {
          this.kysely.destroy();
          this.kysely = null;
        }
        if (this.db) {
          this.db.close();
          this.db = null;
        }
        this.built = false;
      }
      /**
      * Get the Kysely query builder
      * Use this for type-safe queries
      */
      get kb() {
        if (!this.kysely) throw new Error("Cache not built");
        return this.kysely;
      }
      /**
      * Execute a raw SQL query and return all rows
      * Use this in your query functions in pcd/queries/*.ts
      */
      query(sql2, ...params) {
        if (!this.isBuilt()) throw new Error("Cache not built");
        return this.db.prepare(sql2).all(...params);
      }
      /**
      * Execute a raw SQL query and return a single row
      * Use this in your query functions in pcd/queries/*.ts
      */
      queryOne(sql2, ...params) {
        if (!this.isBuilt()) throw new Error("Cache not built");
        return this.db.prepare(sql2).get(...params);
      }
      /**
      * Validate SQL statements by doing a dry-run in a transaction
      * Returns null if valid, or an error message if invalid
      *
      * This is a safety check before writing operations to files.
      * It catches FK violations, constraint errors, etc.
      */
      validateSql(sqlStatements) {
        if (!this.isBuilt()) return {
          valid: false,
          error: "Cache not built"
        };
        try {
          this.db.exec("SAVEPOINT validation_check");
          try {
            for (const sql2 of sqlStatements) this.db.exec(sql2);
            return { valid: true };
          } finally {
            this.db.exec("ROLLBACK TO SAVEPOINT validation_check");
            this.db.exec("RELEASE SAVEPOINT validation_check");
          }
        } catch (error2) {
          const errorStr = String(error2);
          if (errorStr.includes("FOREIGN KEY constraint failed")) return {
            valid: false,
            error: `Foreign key constraint failed - referenced entity does not exist. ${errorStr}`
          };
          if (errorStr.includes("UNIQUE constraint failed")) return {
            valid: false,
            error: `Unique constraint failed - duplicate entry. ${errorStr}`
          };
          if (errorStr.includes("NOT NULL constraint failed")) return {
            valid: false,
            error: `Required field is missing. ${errorStr}`
          };
          if (errorStr.includes("CHECK constraint failed")) return {
            valid: false,
            error: `Value validation failed. ${errorStr}`
          };
          return {
            valid: false,
            error: `Database validation failed: ${errorStr}`
          };
        }
      }
    };
    AUTO_OVERRIDE_MAX_ROUNDS = 10;
    autoOverrideLocks = /* @__PURE__ */ new Set();
  }
});

// dist/build/server/chunks/mappings.js
function mapQualityName(name, arrType) {
  if (!name) return name;
  if (REMUX_MAPPINGS[arrType][name]) return REMUX_MAPPINGS[arrType][name];
  const normalized = name.toUpperCase().replace(/-/g, "").replace(/_/g, "");
  for (const [alt, standard] of Object.entries(ALTERNATE_QUALITY_NAMES)) if (normalized === alt.toUpperCase().replace(/-/g, "").replace(/_/g, "")) return standard;
  return name;
}
function normalizeLanguageName(name) {
  if (!name) return name;
  return name.toLowerCase().replace(/-/g, " ").replace(/_/g, " ");
}
function getIndexerFlag(flag, arrType) {
  return INDEXER_FLAGS[arrType][flag.toLowerCase()] ?? 0;
}
function normalizeSourceName(source2, arrType) {
  const normalized = source2.toLowerCase().replace(/ /g, "_").replace(/-/g, "_");
  return SOURCE_ALIASES[arrType][normalized] ?? normalized;
}
function getSource(source2, arrType) {
  const normalizedSource = normalizeSourceName(source2, arrType);
  return SOURCES[arrType][normalizedSource] ?? 0;
}
function getResolution(resolution) {
  return RESOLUTIONS[resolution.toLowerCase()] ?? 0;
}
function getQualityModifier(modifier) {
  return QUALITY_MODIFIERS[modifier.toLowerCase()] ?? 0;
}
function getReleaseType(releaseType) {
  return RELEASE_TYPES[releaseType.toLowerCase()] ?? 0;
}
function getAllQualities(arrType) {
  return QUALITIES[arrType];
}
function getLanguage(name, arrType) {
  const normalized = normalizeLanguageName(name);
  const languages = LANGUAGES[arrType];
  return languages[normalized] ?? languages["unknown"];
}
function getLanguageForProfile(name, arrType) {
  if (arrType === "sonarr") return {
    id: -2,
    name: "Original"
  };
  if (name === "any" || !name) return LANGUAGES.radarr["any"];
  return getLanguage(name, arrType);
}
function getRadarrLanguages() {
  return Object.values(LANGUAGES.radarr).sort((a2, b3) => {
    if (a2.id === -1) return -1;
    if (b3.id === -1) return 1;
    if (a2.id === -2) return -1;
    if (b3.id === -2) return 1;
    return a2.name.localeCompare(b3.name);
  });
}
function getLanguagesWithSupport() {
  const radarrLangs = new Set(Object.values(LANGUAGES.radarr).map((l3) => l3.name));
  const sonarrLangs = new Set(Object.values(LANGUAGES.sonarr).map((l3) => l3.name));
  const allNames = /* @__PURE__ */ new Set([...radarrLangs, ...sonarrLangs]);
  const result = [];
  for (const name of allNames) result.push({
    name,
    radarr: radarrLangs.has(name),
    sonarr: sonarrLangs.has(name)
  });
  return result.sort((a2, b3) => {
    if (a2.name === "Any") return -1;
    if (b3.name === "Any") return 1;
    if (a2.name === "Original") return -1;
    if (b3.name === "Original") return 1;
    return a2.name.localeCompare(b3.name);
  });
}
var INDEXER_FLAGS, SOURCES, QUALITY_MODIFIERS, RELEASE_TYPES, RESOLUTIONS, QUALITIES, LANGUAGES, REMUX_MAPPINGS, ALTERNATE_QUALITY_NAMES, SOURCE_ALIASES;
var init_mappings = __esm({
  "dist/build/server/chunks/mappings.js"() {
    "use strict";
    INDEXER_FLAGS = {
      radarr: {
        freeleech: 1,
        halfleech: 2,
        double_upload: 4,
        internal: 32,
        scene: 128,
        freeleech_75: 256,
        freeleech_25: 512,
        nuked: 2048,
        ptp_golden: 8,
        ptp_approved: 16
      },
      sonarr: {
        freeleech: 1,
        halfleech: 2,
        double_upload: 4,
        internal: 8,
        scene: 16,
        freeleech_75: 32,
        freeleech_25: 64,
        nuked: 128
      }
    };
    SOURCES = {
      radarr: {
        cam: 1,
        telesync: 2,
        telecine: 3,
        workprint: 4,
        dvd: 5,
        tv: 6,
        web_dl: 7,
        webrip: 8,
        bluray: 9
      },
      sonarr: {
        television: 1,
        television_raw: 2,
        web_dl: 3,
        webrip: 4,
        dvd: 5,
        bluray: 6,
        bluray_raw: 7
      }
    };
    QUALITY_MODIFIERS = {
      none: 0,
      regional: 1,
      screener: 2,
      rawhd: 3,
      brdisk: 4,
      remux: 5
    };
    RELEASE_TYPES = {
      none: 0,
      single_episode: 1,
      multi_episode: 2,
      season_pack: 3
    };
    RESOLUTIONS = {
      "360p": 360,
      "480p": 480,
      "540p": 540,
      "576p": 576,
      "720p": 720,
      "1080p": 1080,
      "2160p": 2160
    };
    QUALITIES = {
      radarr: {
        Unknown: {
          id: 0,
          name: "Unknown",
          source: "unknown",
          resolution: 0
        },
        SDTV: {
          id: 1,
          name: "SDTV",
          source: "tv",
          resolution: 480
        },
        DVD: {
          id: 2,
          name: "DVD",
          source: "dvd",
          resolution: 480
        },
        "WEBDL-1080p": {
          id: 3,
          name: "WEBDL-1080p",
          source: "webdl",
          resolution: 1080
        },
        "HDTV-720p": {
          id: 4,
          name: "HDTV-720p",
          source: "tv",
          resolution: 720
        },
        "WEBDL-720p": {
          id: 5,
          name: "WEBDL-720p",
          source: "webdl",
          resolution: 720
        },
        "Bluray-720p": {
          id: 6,
          name: "Bluray-720p",
          source: "bluray",
          resolution: 720
        },
        "Bluray-1080p": {
          id: 7,
          name: "Bluray-1080p",
          source: "bluray",
          resolution: 1080
        },
        "WEBDL-480p": {
          id: 8,
          name: "WEBDL-480p",
          source: "webdl",
          resolution: 480
        },
        "HDTV-1080p": {
          id: 9,
          name: "HDTV-1080p",
          source: "tv",
          resolution: 1080
        },
        "Raw-HD": {
          id: 10,
          name: "Raw-HD",
          source: "tv",
          resolution: 1080
        },
        "WEBRip-480p": {
          id: 12,
          name: "WEBRip-480p",
          source: "webrip",
          resolution: 480
        },
        "WEBRip-720p": {
          id: 14,
          name: "WEBRip-720p",
          source: "webrip",
          resolution: 720
        },
        "WEBRip-1080p": {
          id: 15,
          name: "WEBRip-1080p",
          source: "webrip",
          resolution: 1080
        },
        "HDTV-2160p": {
          id: 16,
          name: "HDTV-2160p",
          source: "tv",
          resolution: 2160
        },
        "WEBRip-2160p": {
          id: 17,
          name: "WEBRip-2160p",
          source: "webrip",
          resolution: 2160
        },
        "WEBDL-2160p": {
          id: 18,
          name: "WEBDL-2160p",
          source: "webdl",
          resolution: 2160
        },
        "Bluray-2160p": {
          id: 19,
          name: "Bluray-2160p",
          source: "bluray",
          resolution: 2160
        },
        "Bluray-480p": {
          id: 20,
          name: "Bluray-480p",
          source: "bluray",
          resolution: 480
        },
        "Bluray-576p": {
          id: 21,
          name: "Bluray-576p",
          source: "bluray",
          resolution: 576
        },
        "BR-DISK": {
          id: 22,
          name: "BR-DISK",
          source: "bluray",
          resolution: 1080
        },
        "DVD-R": {
          id: 23,
          name: "DVD-R",
          source: "dvd",
          resolution: 480
        },
        WORKPRINT: {
          id: 24,
          name: "WORKPRINT",
          source: "workprint",
          resolution: 0
        },
        CAM: {
          id: 25,
          name: "CAM",
          source: "cam",
          resolution: 0
        },
        TELESYNC: {
          id: 26,
          name: "TELESYNC",
          source: "telesync",
          resolution: 0
        },
        TELECINE: {
          id: 27,
          name: "TELECINE",
          source: "telecine",
          resolution: 0
        },
        DVDSCR: {
          id: 28,
          name: "DVDSCR",
          source: "dvd",
          resolution: 480
        },
        REGIONAL: {
          id: 29,
          name: "REGIONAL",
          source: "dvd",
          resolution: 480
        },
        "Remux-1080p": {
          id: 30,
          name: "Remux-1080p",
          source: "bluray",
          resolution: 1080
        },
        "Remux-2160p": {
          id: 31,
          name: "Remux-2160p",
          source: "bluray",
          resolution: 2160
        }
      },
      sonarr: {
        Unknown: {
          id: 0,
          name: "Unknown",
          source: "unknown",
          resolution: 0
        },
        SDTV: {
          id: 1,
          name: "SDTV",
          source: "television",
          resolution: 480
        },
        DVD: {
          id: 2,
          name: "DVD",
          source: "dvd",
          resolution: 480
        },
        "WEBDL-1080p": {
          id: 3,
          name: "WEBDL-1080p",
          source: "web",
          resolution: 1080
        },
        "HDTV-720p": {
          id: 4,
          name: "HDTV-720p",
          source: "television",
          resolution: 720
        },
        "WEBDL-720p": {
          id: 5,
          name: "WEBDL-720p",
          source: "web",
          resolution: 720
        },
        "Bluray-720p": {
          id: 6,
          name: "Bluray-720p",
          source: "bluray",
          resolution: 720
        },
        "Bluray-1080p": {
          id: 7,
          name: "Bluray-1080p",
          source: "bluray",
          resolution: 1080
        },
        "WEBDL-480p": {
          id: 8,
          name: "WEBDL-480p",
          source: "web",
          resolution: 480
        },
        "HDTV-1080p": {
          id: 9,
          name: "HDTV-1080p",
          source: "television",
          resolution: 1080
        },
        "Raw-HD": {
          id: 10,
          name: "Raw-HD",
          source: "televisionRaw",
          resolution: 1080
        },
        "WEBRip-480p": {
          id: 12,
          name: "WEBRip-480p",
          source: "webRip",
          resolution: 480
        },
        "Bluray-480p": {
          id: 13,
          name: "Bluray-480p",
          source: "bluray",
          resolution: 480
        },
        "WEBRip-720p": {
          id: 14,
          name: "WEBRip-720p",
          source: "webRip",
          resolution: 720
        },
        "WEBRip-1080p": {
          id: 15,
          name: "WEBRip-1080p",
          source: "webRip",
          resolution: 1080
        },
        "HDTV-2160p": {
          id: 16,
          name: "HDTV-2160p",
          source: "television",
          resolution: 2160
        },
        "WEBRip-2160p": {
          id: 17,
          name: "WEBRip-2160p",
          source: "webRip",
          resolution: 2160
        },
        "WEBDL-2160p": {
          id: 18,
          name: "WEBDL-2160p",
          source: "web",
          resolution: 2160
        },
        "Bluray-2160p": {
          id: 19,
          name: "Bluray-2160p",
          source: "bluray",
          resolution: 2160
        },
        "Bluray-1080p Remux": {
          id: 20,
          name: "Bluray-1080p Remux",
          source: "blurayRaw",
          resolution: 1080
        },
        "Bluray-2160p Remux": {
          id: 21,
          name: "Bluray-2160p Remux",
          source: "blurayRaw",
          resolution: 2160
        },
        "Bluray-576p": {
          id: 22,
          name: "Bluray-576p",
          source: "bluray",
          resolution: 576
        }
      }
    };
    LANGUAGES = {
      radarr: {
        any: {
          id: -1,
          name: "Any"
        },
        original: {
          id: -2,
          name: "Original"
        },
        unknown: {
          id: 0,
          name: "Unknown"
        },
        english: {
          id: 1,
          name: "English"
        },
        french: {
          id: 2,
          name: "French"
        },
        spanish: {
          id: 3,
          name: "Spanish"
        },
        german: {
          id: 4,
          name: "German"
        },
        italian: {
          id: 5,
          name: "Italian"
        },
        danish: {
          id: 6,
          name: "Danish"
        },
        dutch: {
          id: 7,
          name: "Dutch"
        },
        japanese: {
          id: 8,
          name: "Japanese"
        },
        icelandic: {
          id: 9,
          name: "Icelandic"
        },
        chinese: {
          id: 10,
          name: "Chinese"
        },
        russian: {
          id: 11,
          name: "Russian"
        },
        polish: {
          id: 12,
          name: "Polish"
        },
        vietnamese: {
          id: 13,
          name: "Vietnamese"
        },
        swedish: {
          id: 14,
          name: "Swedish"
        },
        norwegian: {
          id: 15,
          name: "Norwegian"
        },
        finnish: {
          id: 16,
          name: "Finnish"
        },
        turkish: {
          id: 17,
          name: "Turkish"
        },
        portuguese: {
          id: 18,
          name: "Portuguese"
        },
        flemish: {
          id: 19,
          name: "Flemish"
        },
        greek: {
          id: 20,
          name: "Greek"
        },
        korean: {
          id: 21,
          name: "Korean"
        },
        hungarian: {
          id: 22,
          name: "Hungarian"
        },
        hebrew: {
          id: 23,
          name: "Hebrew"
        },
        lithuanian: {
          id: 24,
          name: "Lithuanian"
        },
        czech: {
          id: 25,
          name: "Czech"
        },
        hindi: {
          id: 26,
          name: "Hindi"
        },
        romanian: {
          id: 27,
          name: "Romanian"
        },
        thai: {
          id: 28,
          name: "Thai"
        },
        bulgarian: {
          id: 29,
          name: "Bulgarian"
        },
        "portuguese (brazil)": {
          id: 30,
          name: "Portuguese (Brazil)"
        },
        arabic: {
          id: 31,
          name: "Arabic"
        },
        ukrainian: {
          id: 32,
          name: "Ukrainian"
        },
        persian: {
          id: 33,
          name: "Persian"
        },
        bengali: {
          id: 34,
          name: "Bengali"
        },
        slovak: {
          id: 35,
          name: "Slovak"
        },
        latvian: {
          id: 36,
          name: "Latvian"
        },
        "spanish (latino)": {
          id: 37,
          name: "Spanish (Latino)"
        },
        catalan: {
          id: 38,
          name: "Catalan"
        },
        croatian: {
          id: 39,
          name: "Croatian"
        },
        serbian: {
          id: 40,
          name: "Serbian"
        },
        bosnian: {
          id: 41,
          name: "Bosnian"
        },
        estonian: {
          id: 42,
          name: "Estonian"
        },
        tamil: {
          id: 43,
          name: "Tamil"
        },
        indonesian: {
          id: 44,
          name: "Indonesian"
        },
        telugu: {
          id: 45,
          name: "Telugu"
        },
        macedonian: {
          id: 46,
          name: "Macedonian"
        },
        slovenian: {
          id: 47,
          name: "Slovenian"
        },
        malayalam: {
          id: 48,
          name: "Malayalam"
        },
        kannada: {
          id: 49,
          name: "Kannada"
        },
        albanian: {
          id: 50,
          name: "Albanian"
        },
        afrikaans: {
          id: 51,
          name: "Afrikaans"
        },
        marathi: {
          id: 52,
          name: "Marathi"
        },
        tagalog: {
          id: 53,
          name: "Tagalog"
        },
        urdu: {
          id: 54,
          name: "Urdu"
        },
        romansh: {
          id: 55,
          name: "Romansh"
        },
        mongolian: {
          id: 56,
          name: "Mongolian"
        },
        georgian: {
          id: 57,
          name: "Georgian"
        }
      },
      sonarr: {
        unknown: {
          id: 0,
          name: "Unknown"
        },
        english: {
          id: 1,
          name: "English"
        },
        french: {
          id: 2,
          name: "French"
        },
        spanish: {
          id: 3,
          name: "Spanish"
        },
        german: {
          id: 4,
          name: "German"
        },
        italian: {
          id: 5,
          name: "Italian"
        },
        danish: {
          id: 6,
          name: "Danish"
        },
        dutch: {
          id: 7,
          name: "Dutch"
        },
        japanese: {
          id: 8,
          name: "Japanese"
        },
        icelandic: {
          id: 9,
          name: "Icelandic"
        },
        chinese: {
          id: 10,
          name: "Chinese"
        },
        russian: {
          id: 11,
          name: "Russian"
        },
        polish: {
          id: 12,
          name: "Polish"
        },
        vietnamese: {
          id: 13,
          name: "Vietnamese"
        },
        swedish: {
          id: 14,
          name: "Swedish"
        },
        norwegian: {
          id: 15,
          name: "Norwegian"
        },
        finnish: {
          id: 16,
          name: "Finnish"
        },
        turkish: {
          id: 17,
          name: "Turkish"
        },
        portuguese: {
          id: 18,
          name: "Portuguese"
        },
        flemish: {
          id: 19,
          name: "Flemish"
        },
        greek: {
          id: 20,
          name: "Greek"
        },
        korean: {
          id: 21,
          name: "Korean"
        },
        hungarian: {
          id: 22,
          name: "Hungarian"
        },
        hebrew: {
          id: 23,
          name: "Hebrew"
        },
        lithuanian: {
          id: 24,
          name: "Lithuanian"
        },
        czech: {
          id: 25,
          name: "Czech"
        },
        arabic: {
          id: 26,
          name: "Arabic"
        },
        hindi: {
          id: 27,
          name: "Hindi"
        },
        bulgarian: {
          id: 28,
          name: "Bulgarian"
        },
        malayalam: {
          id: 29,
          name: "Malayalam"
        },
        ukrainian: {
          id: 30,
          name: "Ukrainian"
        },
        slovak: {
          id: 31,
          name: "Slovak"
        },
        thai: {
          id: 32,
          name: "Thai"
        },
        "portuguese (brazil)": {
          id: 33,
          name: "Portuguese (Brazil)"
        },
        "spanish (latino)": {
          id: 34,
          name: "Spanish (Latino)"
        },
        romanian: {
          id: 35,
          name: "Romanian"
        },
        latvian: {
          id: 36,
          name: "Latvian"
        },
        persian: {
          id: 37,
          name: "Persian"
        },
        catalan: {
          id: 38,
          name: "Catalan"
        },
        croatian: {
          id: 39,
          name: "Croatian"
        },
        serbian: {
          id: 40,
          name: "Serbian"
        },
        bosnian: {
          id: 41,
          name: "Bosnian"
        },
        estonian: {
          id: 42,
          name: "Estonian"
        },
        tamil: {
          id: 43,
          name: "Tamil"
        },
        indonesian: {
          id: 44,
          name: "Indonesian"
        },
        macedonian: {
          id: 45,
          name: "Macedonian"
        },
        slovenian: {
          id: 46,
          name: "Slovenian"
        },
        original: {
          id: -2,
          name: "Original"
        }
      }
    };
    REMUX_MAPPINGS = {
      sonarr: {
        "Remux-1080p": "Bluray-1080p Remux",
        "Remux-2160p": "Bluray-2160p Remux"
      },
      radarr: {
        "Remux-1080p": "Remux-1080p",
        "Remux-2160p": "Remux-2160p"
      }
    };
    ALTERNATE_QUALITY_NAMES = {
      "BR-Disk": "BR-DISK",
      BRDISK: "BR-DISK",
      BR_DISK: "BR-DISK",
      "BLURAY-DISK": "BR-DISK",
      BLURAY_DISK: "BR-DISK",
      BLURAYDISK: "BR-DISK",
      Telecine: "TELECINE",
      TeleCine: "TELECINE",
      Telesync: "TELESYNC",
      TeleSync: "TELESYNC"
    };
    SOURCE_ALIASES = {
      radarr: {
        television: "tv",
        hdtv: "tv",
        webdl: "web_dl",
        "web-dl": "web_dl",
        web: "web_dl",
        web_rip: "webrip",
        "web-rip": "webrip"
      },
      sonarr: {
        hdtv: "television",
        tv: "television",
        webdl: "web_dl",
        "web-dl": "web_dl",
        web: "web_dl",
        web_rip: "webrip",
        "web-rip": "webrip"
      }
    };
  }
});

// dist/build/server/chunks/conditions.js
function getStatusPriority(required, negate) {
  if (required && !negate) return 0;
  if (negate) return 1;
  return 2;
}
function sortConditions(conditions) {
  return [...conditions].sort((a2, b3) => {
    const statusA = getStatusPriority(a2.required, a2.negate);
    const statusB = getStatusPriority(b3.required, b3.negate);
    if (statusA !== statusB) return statusA - statusB;
    const typeA = TYPE_ORDER.get(a2.type) ?? 999;
    const typeB = TYPE_ORDER.get(b3.type) ?? 999;
    if (typeA !== typeB) return typeA - typeB;
    return a2.name.localeCompare(b3.name);
  });
}
var CONDITION_TYPES, TYPE_ORDER, PATTERN_TYPES, SOURCE_VALUES, RESOLUTION_VALUES, QUALITY_MODIFIER_VALUES, RELEASE_TYPE_VALUES, INDEXER_FLAG_VALUES;
var init_conditions = __esm({
  "dist/build/server/chunks/conditions.js"() {
    "use strict";
    CONDITION_TYPES = [
      {
        value: "resolution",
        label: "Resolution",
        arrType: "all"
      },
      {
        value: "source",
        label: "Source",
        arrType: "all"
      },
      {
        value: "quality_modifier",
        label: "Quality Modifier",
        arrType: "radarr"
      },
      {
        value: "release_title",
        label: "Release Title",
        arrType: "all"
      },
      {
        value: "release_group",
        label: "Release Group",
        arrType: "all"
      },
      {
        value: "edition",
        label: "Edition",
        arrType: "radarr"
      },
      {
        value: "language",
        label: "Language",
        arrType: "all"
      },
      {
        value: "release_type",
        label: "Release Type",
        arrType: "sonarr"
      },
      {
        value: "indexer_flag",
        label: "Indexer Flag",
        arrType: "all"
      },
      {
        value: "size",
        label: "Size",
        arrType: "all"
      },
      {
        value: "year",
        label: "Year",
        arrType: "all"
      }
    ];
    TYPE_ORDER = new Map(CONDITION_TYPES.map((t2, i) => [t2.value, i]));
    PATTERN_TYPES = [
      "release_title",
      "release_group",
      "edition"
    ];
    SOURCE_VALUES = [
      {
        value: "unknown",
        label: "Unknown",
        arrType: "all"
      },
      {
        value: "television",
        label: "Television",
        arrType: "all"
      },
      {
        value: "television_raw",
        label: "Television Raw",
        arrType: "sonarr"
      },
      {
        value: "web_dl",
        label: "WEB-DL",
        arrType: "all"
      },
      {
        value: "webrip",
        label: "WEBRip",
        arrType: "all"
      },
      {
        value: "dvd",
        label: "DVD",
        arrType: "all"
      },
      {
        value: "bluray",
        label: "Bluray",
        arrType: "all"
      },
      {
        value: "bluray_raw",
        label: "Bluray Raw",
        arrType: "sonarr"
      },
      {
        value: "cam",
        label: "CAM",
        arrType: "all"
      },
      {
        value: "telesync",
        label: "Telesync",
        arrType: "all"
      },
      {
        value: "telecine",
        label: "Telecine",
        arrType: "all"
      },
      {
        value: "workprint",
        label: "Workprint",
        arrType: "all"
      }
    ];
    RESOLUTION_VALUES = [
      {
        value: "360p",
        label: "360p",
        arrType: "all"
      },
      {
        value: "480p",
        label: "480p",
        arrType: "all"
      },
      {
        value: "540p",
        label: "540p",
        arrType: "all"
      },
      {
        value: "576p",
        label: "576p",
        arrType: "all"
      },
      {
        value: "720p",
        label: "720p",
        arrType: "all"
      },
      {
        value: "1080p",
        label: "1080p",
        arrType: "all"
      },
      {
        value: "2160p",
        label: "2160p",
        arrType: "all"
      }
    ];
    QUALITY_MODIFIER_VALUES = [
      {
        value: "none",
        label: "None",
        arrType: "radarr"
      },
      {
        value: "regional",
        label: "Regional",
        arrType: "radarr"
      },
      {
        value: "screener",
        label: "Screener",
        arrType: "radarr"
      },
      {
        value: "rawhd",
        label: "RawHD",
        arrType: "radarr"
      },
      {
        value: "brdisk",
        label: "BRDISK",
        arrType: "radarr"
      },
      {
        value: "remux",
        label: "REMUX",
        arrType: "radarr"
      }
    ];
    RELEASE_TYPE_VALUES = [
      {
        value: "single_episode",
        label: "Single Episode",
        arrType: "sonarr"
      },
      {
        value: "multi_episode",
        label: "Multi Episode",
        arrType: "sonarr"
      },
      {
        value: "season_pack",
        label: "Season Pack",
        arrType: "sonarr"
      }
    ];
    INDEXER_FLAG_VALUES = [
      {
        value: "freeleech",
        label: "Freeleech",
        arrType: "all"
      },
      {
        value: "halfleech",
        label: "Halfleech",
        arrType: "all"
      },
      {
        value: "double_upload",
        label: "Double Upload",
        arrType: "all"
      },
      {
        value: "internal",
        label: "Internal",
        arrType: "all"
      },
      {
        value: "scene",
        label: "Scene",
        arrType: "all"
      },
      {
        value: "freeleech_75",
        label: "Freeleech 75%",
        arrType: "all"
      },
      {
        value: "freeleech_25",
        label: "Freeleech 25%",
        arrType: "all"
      },
      {
        value: "nuked",
        label: "Nuked",
        arrType: "all"
      },
      {
        value: "ptp_golden",
        label: "PTP Golden",
        arrType: "radarr"
      },
      {
        value: "ptp_approved",
        label: "PTP Approved",
        arrType: "radarr"
      }
    ];
  }
});

// dist/build/server/chunks/cleanup.js
function readId2(raw) {
  if (typeof raw === "number" && Number.isFinite(raw)) return raw;
  if (typeof raw === "string" && raw.trim() !== "" && Number.isFinite(Number(raw))) return Number(raw);
  return null;
}
function matchesPayloadId(job, key2, id) {
  const value2 = job.payload?.[key2];
  return readId2(value2) === id;
}
function cleanupJobsForArrInstance(instanceId) {
  const ids = jobQueueQueries.listByJobTypes([
    "arr.upgrade",
    "arr.rename",
    "arr.sync",
    "arr.sync.qualityProfiles",
    "arr.sync.delayProfiles",
    "arr.sync.mediaManagement",
    "arr.cleanup",
    "arr.drift",
    "arr.library.refresh"
  ]).filter((job) => matchesPayloadId(job, "instanceId", instanceId)).map((job) => job.id);
  return jobQueueQueries.deleteByIds(ids);
}
function cleanupJobsForDatabase(databaseId) {
  const ids = jobQueueQueries.listByJobTypes(["pcd.sync"]).filter((job) => matchesPayloadId(job, "databaseId", databaseId)).map((job) => job.id);
  return jobQueueQueries.deleteByIds(ids);
}
var init_cleanup = __esm({
  async "dist/build/server/chunks/cleanup.js"() {
    "use strict";
    await init_jobQueue();
  }
});

// dist/build/server/chunks/arrDriftStatus.js
function parseJson2(raw, fallback2) {
  try {
    const parsed = JSON.parse(raw);
    return parsed && typeof parsed === "object" ? parsed : fallback2;
  } catch {
    return fallback2;
  }
}
function rowToStatus(row) {
  return {
    id: row.id,
    arrInstanceId: row.arr_instance_id,
    status: row.status,
    lastCheckedAt: toUTC(row.last_checked_at),
    counts: parseJson2(row.counts_json, {}),
    diff: parseJson2(row.diff_json, {}),
    diffHash: row.diff_hash,
    lastNotifiedHash: row.last_notified_hash,
    lastNotifiedAt: toUTC(row.last_notified_at),
    lastError: row.last_error,
    errorHash: row.error_hash,
    lastNotifiedErrorHash: row.last_notified_error_hash,
    createdAt: toUTC(row.created_at),
    updatedAt: toUTC(row.updated_at)
  };
}
var arrDriftStatusQueries;
var init_arrDriftStatus = __esm({
  async "dist/build/server/chunks/arrDriftStatus.js"() {
    "use strict";
    await init_db();
    init_dates();
    arrDriftStatusQueries = {
      getByInstanceId(arrInstanceId) {
        const row = db.queryFirst("SELECT * FROM arr_drift_status WHERE arr_instance_id = ?", arrInstanceId);
        return row ? rowToStatus(row) : void 0;
      },
      getAll() {
        return db.query("SELECT * FROM arr_drift_status").map(rowToStatus);
      },
      ensure(arrInstanceId) {
        const existing = this.getByInstanceId(arrInstanceId);
        if (existing) return existing;
        db.execute("INSERT INTO arr_drift_status (arr_instance_id) VALUES (?)", arrInstanceId);
        return this.getByInstanceId(arrInstanceId);
      },
      upsert(arrInstanceId, input) {
        this.ensure(arrInstanceId);
        this.update(arrInstanceId, input);
        return this.getByInstanceId(arrInstanceId);
      },
      update(arrInstanceId, input) {
        const updates = [];
        const params = [];
        if (input.status !== void 0) {
          updates.push("status = ?");
          params.push(input.status);
        }
        if (input.lastCheckedAt !== void 0) {
          updates.push("last_checked_at = ?");
          params.push(input.lastCheckedAt);
        }
        if (input.counts !== void 0) {
          updates.push("counts_json = ?");
          params.push(JSON.stringify(input.counts));
        }
        if (input.diff !== void 0) {
          updates.push("diff_json = ?");
          params.push(JSON.stringify(input.diff));
        }
        if (input.diffHash !== void 0) {
          updates.push("diff_hash = ?");
          params.push(input.diffHash);
        }
        if (input.lastNotifiedHash !== void 0) {
          updates.push("last_notified_hash = ?");
          params.push(input.lastNotifiedHash);
        }
        if (input.lastNotifiedAt !== void 0) {
          updates.push("last_notified_at = ?");
          params.push(input.lastNotifiedAt);
        }
        if (input.lastError !== void 0) {
          updates.push("last_error = ?");
          params.push(input.lastError);
        }
        if (input.errorHash !== void 0) {
          updates.push("error_hash = ?");
          params.push(input.errorHash);
        }
        if (input.lastNotifiedErrorHash !== void 0) {
          updates.push("last_notified_error_hash = ?");
          params.push(input.lastNotifiedErrorHash);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(arrInstanceId);
        return db.execute(`UPDATE arr_drift_status SET ${updates.join(", ")} WHERE arr_instance_id = ?`, ...params) > 0;
      },
      delete(arrInstanceId) {
        return db.execute("DELETE FROM arr_drift_status WHERE arr_instance_id = ?", arrInstanceId) > 0;
      }
    };
  }
});

// dist/build/server/chunks/features.js
var FEATURES;
var init_features = __esm({
  "dist/build/server/chunks/features.js"() {
    "use strict";
    FEATURES = {
      /** PCD entity import/export */
      importExport: false,
      /** AI-powered commit message generation */
      ai: false,
      /** Cutscene onboarding system */
      cutscene: true,
      /** Database tweaks UI */
      tweaks: false,
      /** Arr drift detection */
      drift: true
    };
  }
});

// dist/build/server/chunks/cache2.js
var Cache, cache;
var init_cache2 = __esm({
  "dist/build/server/chunks/cache2.js"() {
    "use strict";
    Cache = class {
      store = /* @__PURE__ */ new Map();
      /**
      * Get a cached value
      */
      get(key2) {
        const entry = this.store.get(key2);
        if (!entry) return void 0;
        if (Date.now() > entry.expiresAt) {
          this.store.delete(key2);
          return;
        }
        return entry.data;
      }
      /**
      * Set a cached value with TTL in seconds
      */
      set(key2, data, ttlSeconds) {
        this.store.set(key2, {
          data,
          expiresAt: Date.now() + ttlSeconds * 1e3
        });
      }
      /**
      * Delete a cached value
      */
      delete(key2) {
        return this.store.delete(key2);
      }
      /**
      * Delete all cached values matching a prefix
      */
      deleteByPrefix(prefix) {
        let count = 0;
        for (const key2 of this.store.keys()) if (key2.startsWith(prefix)) {
          this.store.delete(key2);
          count++;
        }
        return count;
      }
      /**
      * Clear all cached values
      */
      clear() {
        this.store.clear();
      }
    };
    cache = new Cache();
  }
});

// dist/build/server/chunks/backupSettings.js
var backupSettingsQueries;
var init_backupSettings = __esm({
  async "dist/build/server/chunks/backupSettings.js"() {
    "use strict";
    await init_db();
    backupSettingsQueries = {
      /**
      * Get the backup settings (singleton)
      */
      get() {
        return db.queryFirst("SELECT * FROM backup_settings WHERE id = 1");
      },
      /**
      * Update backup settings
      */
      update(input) {
        const updates = [];
        const params = [];
        if (input.schedule !== void 0) {
          updates.push("schedule = ?");
          params.push(input.schedule);
        }
        if (input.retentionDays !== void 0) {
          updates.push("retention_days = ?");
          params.push(input.retentionDays);
        }
        if (input.enabled !== void 0) {
          updates.push("enabled = ?");
          params.push(input.enabled ? 1 : 0);
        }
        if (input.includeDatabase !== void 0) {
          updates.push("include_database = ?");
          params.push(input.includeDatabase ? 1 : 0);
        }
        if (input.compressionEnabled !== void 0) {
          updates.push("compression_enabled = ?");
          params.push(input.compressionEnabled ? 1 : 0);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(1);
        return db.execute(`UPDATE backup_settings SET ${updates.join(", ")} WHERE id = ?`, ...params) > 0;
      },
      /**
      * Reset backup settings to defaults
      */
      reset() {
        return db.execute(`
			UPDATE backup_settings SET
				schedule = 'daily',
				retention_days = 30,
				enabled = 1,
				include_database = 1,
				compression_enabled = 1,
				updated_at = CURRENT_TIMESTAMP
			WHERE id = 1
		`) > 0;
      }
    };
  }
});

// dist/build/server/chunks/migrations.js
function migrateFilterConfigs() {
  const rows = db.query("SELECT id, filters FROM upgrade_configs");
  for (const row of rows) try {
    const filters = JSON.parse(row.filters);
    let modified = false;
    const updatedFilters = filters.map((filter) => {
      if ("searchCooldown" in filter) {
        modified = true;
        const { searchCooldown: _3, ...rest } = filter;
        return rest;
      }
      return filter;
    });
    if (modified) db.execute("UPDATE upgrade_configs SET filters = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?", JSON.stringify(updatedFilters), row.id);
  } catch {
  }
}
function loadMigrations() {
  return [
    migration$68,
    migration$67,
    migration$66,
    migration$65,
    migration$64,
    migration$63,
    migration$62,
    migration$61,
    migration$60,
    migration$59,
    migration$58,
    migration$57,
    migration$56,
    migration$55,
    migration$54,
    migration$53,
    migration$52,
    migration$51,
    migration$50,
    migration$49,
    migration$48,
    migration$47,
    migration$46,
    migration$45,
    migration$44,
    migration$43,
    migration$42,
    migration$41,
    migration$40,
    migration$39,
    migration$38,
    migration$37,
    migration$36,
    migration$35,
    migration$34,
    migration$33,
    migration$32,
    migration$31,
    migration$30,
    migration$29,
    migration$28,
    migration$27,
    migration$26,
    migration$25,
    migration$24,
    migration$23,
    migration$22,
    migration$21,
    migration$20,
    migration$19,
    migration$18,
    migration$17,
    migration$16,
    migration$15,
    migration$14,
    migration$13,
    migration$12,
    migration$11,
    migration$10,
    migration$9,
    migration$8,
    migration$7,
    migration$6,
    migration$5,
    migration$4,
    migration$3,
    migration$2,
    migration$1,
    migration
  ].sort((a2, b3) => a2.version - b3.version);
}
async function runMigrations(migrations) {
  const migrationsToRun = migrations ?? loadMigrations();
  await migrationRunner.up(migrationsToRun);
}
var migration$68, migration$67, migration$66, migration$65, migration$64, migration$63, migration$62, migration$61, migration$60, migration$59, migration$58, migration$57, migration$56, migration$55, migration$54, migration$53, migration$52, migration$51, migration$50, migration$49, migration$48, migration$47, migration$46, migration$45, migration$44, migration$43, migration$42, migration$41, migration$40, migration$39, migration$38, migration$37, migration$36, migration$35, migration$34, migration$33, migration$32, migration$31, migration$30, migration$29, migration$28, migration$27, migration$26, migration$25, migration$24, migration$23, migration$22, migration$21, migration$20, migration$19, migration$18, migration$17, migration$16, migration$15, migration$14, migration$13, migration$12, migration$11, migration$10, migration$9, migration$8, migration$7, migration$6, migration$5, migration$4, migration$3, migration$2, migration$1, migration, MigrationRunner, migrationRunner;
var init_migrations = __esm({
  async "dist/build/server/chunks/migrations.js"() {
    "use strict";
    await init_db();
    migration$68 = {
      version: 1,
      name: "Create arr_instances table",
      up: `
		CREATE TABLE arr_instances (
			id INTEGER PRIMARY KEY AUTOINCREMENT,

			-- Instance identification
			name TEXT NOT NULL UNIQUE,
			type TEXT NOT NULL,

			-- Connection details
			url TEXT NOT NULL,
			api_key TEXT NOT NULL,

			-- Configuration
			tags TEXT,
			sync_profile TEXT,
			enabled INTEGER NOT NULL DEFAULT 1,

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);
	`,
      down: `
		DROP TABLE IF EXISTS arr_instances;
	`
    };
    migration$67 = {
      version: 2,
      name: "Remove sync_profile column from arr_instances",
      up: `
		ALTER TABLE arr_instances DROP COLUMN sync_profile;
	`,
      down: `
		ALTER TABLE arr_instances ADD COLUMN sync_profile TEXT;
	`
    };
    migration$66 = {
      version: 3,
      name: "Create log_settings table",
      up: `
		CREATE TABLE log_settings (
			id INTEGER PRIMARY KEY CHECK (id = 1),

			-- Rotation & Retention
			rotation_strategy TEXT NOT NULL DEFAULT 'daily' CHECK (rotation_strategy IN ('daily', 'size', 'both')),
			retention_days INTEGER NOT NULL DEFAULT 30,
			max_file_size INTEGER NOT NULL DEFAULT 100,

			-- Log Level
			min_level TEXT NOT NULL DEFAULT 'INFO' CHECK (min_level IN ('DEBUG', 'INFO', 'WARN', 'ERROR')),

			-- Enable/Disable
			enabled INTEGER NOT NULL DEFAULT 1,
			file_logging INTEGER NOT NULL DEFAULT 1,
			console_logging INTEGER NOT NULL DEFAULT 1,

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Insert default settings
		INSERT INTO log_settings (id) VALUES (1);
	`,
      down: `
		DROP TABLE IF EXISTS log_settings;
	`
    };
    migration$65 = {
      version: 4,
      name: "Create jobs and job_runs tables",
      up: `
		-- Jobs table (job definitions)
		CREATE TABLE jobs (
			id INTEGER PRIMARY KEY AUTOINCREMENT,

			-- Job identification
			name TEXT NOT NULL UNIQUE,
			description TEXT,

			-- Scheduling
			schedule TEXT NOT NULL,
			enabled INTEGER NOT NULL DEFAULT 1,

			-- Execution tracking
			last_run_at DATETIME,
			next_run_at DATETIME,

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Job runs table (execution history)
		CREATE TABLE job_runs (
			id INTEGER PRIMARY KEY AUTOINCREMENT,

			-- Foreign key to jobs
			job_id INTEGER NOT NULL,

			-- Execution status
			status TEXT NOT NULL CHECK (status IN ('success', 'failure')),

			-- Timing
			started_at DATETIME NOT NULL,
			finished_at DATETIME NOT NULL,
			duration_ms INTEGER NOT NULL,

			-- Output
			error TEXT,
			output TEXT,

			FOREIGN KEY (job_id) REFERENCES jobs(id) ON DELETE CASCADE
		);

		-- Create indexes for performance
		CREATE INDEX idx_jobs_enabled ON jobs(enabled);
		CREATE INDEX idx_jobs_next_run ON jobs(next_run_at);
		CREATE INDEX idx_job_runs_job_id ON job_runs(job_id);
		CREATE INDEX idx_job_runs_started_at ON job_runs(started_at);
	`,
      down: `
		DROP INDEX IF EXISTS idx_job_runs_started_at;
		DROP INDEX IF EXISTS idx_job_runs_job_id;
		DROP INDEX IF EXISTS idx_jobs_next_run;
		DROP INDEX IF EXISTS idx_jobs_enabled;
		DROP TABLE IF EXISTS job_runs;
		DROP TABLE IF EXISTS jobs;
	`
    };
    migration$64 = {
      version: 5,
      name: "Create backup_settings table",
      up: `
		CREATE TABLE backup_settings (
			id INTEGER PRIMARY KEY CHECK (id = 1),

			-- Backup Configuration
			schedule TEXT NOT NULL DEFAULT 'daily',
			retention_days INTEGER NOT NULL DEFAULT 30,
			enabled INTEGER NOT NULL DEFAULT 1,
			include_database INTEGER NOT NULL DEFAULT 1,
			compression_enabled INTEGER NOT NULL DEFAULT 1,

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Insert default settings
		INSERT INTO backup_settings (id) VALUES (1);
	`,
      down: `
		DROP TABLE IF EXISTS backup_settings;
	`
    };
    migration$63 = {
      version: 6,
      name: "Simplify log settings to daily-only rotation",
      up: `
		-- Remove rotation strategy and max file size columns
		-- SQLite doesn't support DROP COLUMN directly in all versions,
		-- so we need to recreate the table

		-- Create new table with updated schema
		CREATE TABLE log_settings_new (
			id INTEGER PRIMARY KEY CHECK (id = 1),

			-- Retention
			retention_days INTEGER NOT NULL DEFAULT 30,

			-- Log Level
			min_level TEXT NOT NULL DEFAULT 'INFO' CHECK (min_level IN ('DEBUG', 'INFO', 'WARN', 'ERROR')),

			-- Enable/Disable
			enabled INTEGER NOT NULL DEFAULT 1,
			file_logging INTEGER NOT NULL DEFAULT 1,
			console_logging INTEGER NOT NULL DEFAULT 1,

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Copy data from old table (excluding removed columns)
		INSERT INTO log_settings_new (
			id,
			retention_days,
			min_level,
			enabled,
			file_logging,
			console_logging,
			created_at,
			updated_at
		)
		SELECT
			id,
			retention_days,
			min_level,
			enabled,
			file_logging,
			console_logging,
			created_at,
			updated_at
		FROM log_settings;

		-- Drop old table
		DROP TABLE log_settings;

		-- Rename new table to original name
		ALTER TABLE log_settings_new RENAME TO log_settings;
	`,
      down: `
		-- Recreate table with rotation_strategy and max_file_size columns

		CREATE TABLE log_settings_new (
			id INTEGER PRIMARY KEY CHECK (id = 1),

			-- Rotation & Retention
			rotation_strategy TEXT NOT NULL DEFAULT 'daily' CHECK (rotation_strategy IN ('daily', 'size', 'both')),
			retention_days INTEGER NOT NULL DEFAULT 30,
			max_file_size INTEGER NOT NULL DEFAULT 100,

			-- Log Level
			min_level TEXT NOT NULL DEFAULT 'INFO' CHECK (min_level IN ('DEBUG', 'INFO', 'WARN', 'ERROR')),

			-- Enable/Disable
			enabled INTEGER NOT NULL DEFAULT 1,
			file_logging INTEGER NOT NULL DEFAULT 1,
			console_logging INTEGER NOT NULL DEFAULT 1,

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Copy data back, adding default values for removed columns
		INSERT INTO log_settings_new (
			id,
			rotation_strategy,
			retention_days,
			max_file_size,
			min_level,
			enabled,
			file_logging,
			console_logging,
			created_at,
			updated_at
		)
		SELECT
			id,
			'daily',
			retention_days,
			100,
			min_level,
			enabled,
			file_logging,
			console_logging,
			created_at,
			updated_at
		FROM log_settings;

		DROP TABLE log_settings;
		ALTER TABLE log_settings_new RENAME TO log_settings;
	`
    };
    migration$62 = {
      version: 7,
      name: "Create notification tables",
      up: `
		-- Create notification_services table
		CREATE TABLE notification_services (
			id TEXT PRIMARY KEY,                        -- UUID

			-- Service identification
			name TEXT NOT NULL,                         -- User-defined: "Main Discord", "Error Alerts"
			service_type TEXT NOT NULL,                 -- 'discord', 'slack', 'email', etc.

			-- Configuration
			enabled INTEGER NOT NULL DEFAULT 0,         -- Master on/off switch
			config TEXT NOT NULL,                       -- JSON blob: { webhook_url: "...", username: "...", ... }
			enabled_types TEXT NOT NULL,                -- JSON array: ["job.backup.success", "job.backup.failed"]

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Create notification_history table
		CREATE TABLE notification_history (
			id INTEGER PRIMARY KEY AUTOINCREMENT,

			-- Foreign key to notification service
			service_id TEXT NOT NULL,

			-- Notification details
			notification_type TEXT NOT NULL,            -- e.g., 'job.backup.success'
			title TEXT NOT NULL,
			message TEXT NOT NULL,
			metadata TEXT,                              -- JSON blob for additional context

			-- Delivery status
			status TEXT NOT NULL CHECK (status IN ('success', 'failed')),
			error TEXT,                                 -- Error message if status = 'failed'

			-- Timing
			sent_at DATETIME DEFAULT CURRENT_TIMESTAMP,

			FOREIGN KEY (service_id) REFERENCES notification_services(id) ON DELETE CASCADE
		);

		-- Create indexes for notification_services
		CREATE INDEX idx_notification_services_enabled ON notification_services(enabled);
		CREATE INDEX idx_notification_services_type ON notification_services(service_type);

		-- Create indexes for notification_history
		CREATE INDEX idx_notification_history_service_id ON notification_history(service_id);
		CREATE INDEX idx_notification_history_sent_at ON notification_history(sent_at);
		CREATE INDEX idx_notification_history_status ON notification_history(status);
	`,
      down: `
		-- Drop indexes first
		DROP INDEX IF EXISTS idx_notification_history_status;
		DROP INDEX IF EXISTS idx_notification_history_sent_at;
		DROP INDEX IF EXISTS idx_notification_history_service_id;
		DROP INDEX IF EXISTS idx_notification_services_type;
		DROP INDEX IF EXISTS idx_notification_services_enabled;

		-- Drop tables
		DROP TABLE IF EXISTS notification_history;
		DROP TABLE IF EXISTS notification_services;
	`
    };
    migration$61 = {
      version: 8,
      name: "Create database_instances table",
      up: `
		CREATE TABLE database_instances (
			id INTEGER PRIMARY KEY AUTOINCREMENT,

			-- Instance identification
			uuid TEXT NOT NULL UNIQUE,
			name TEXT NOT NULL UNIQUE,

			-- Repository connection
			repository_url TEXT NOT NULL,

			-- Local storage
			local_path TEXT NOT NULL,

			-- Sync settings
			sync_strategy INTEGER NOT NULL DEFAULT 0,
			auto_pull INTEGER NOT NULL DEFAULT 0,

			-- Status
			enabled INTEGER NOT NULL DEFAULT 1,
			last_synced_at DATETIME,

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Index for looking up by UUID
		CREATE INDEX idx_database_instances_uuid ON database_instances(uuid);
	`,
      down: `
		DROP INDEX IF EXISTS idx_database_instances_uuid;
		DROP TABLE IF EXISTS database_instances;
	`
    };
    migration$60 = {
      version: 9,
      name: "Add personal_access_token to database_instances",
      up: `
		ALTER TABLE database_instances
		ADD COLUMN personal_access_token TEXT;
	`,
      down: `
		-- SQLite doesn't support DROP COLUMN easily, so we recreate the table
		CREATE TABLE database_instances_backup (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			uuid TEXT NOT NULL UNIQUE,
			name TEXT NOT NULL UNIQUE,
			repository_url TEXT NOT NULL,
			local_path TEXT NOT NULL,
			sync_strategy INTEGER NOT NULL DEFAULT 0,
			auto_pull INTEGER NOT NULL DEFAULT 0,
			enabled INTEGER NOT NULL DEFAULT 1,
			last_synced_at DATETIME,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		INSERT INTO database_instances_backup
		SELECT id, uuid, name, repository_url, local_path, sync_strategy,
		       auto_pull, enabled, last_synced_at, created_at, updated_at
		FROM database_instances;

		DROP TABLE database_instances;

		ALTER TABLE database_instances_backup RENAME TO database_instances;

		CREATE INDEX idx_database_instances_uuid ON database_instances(uuid);
	`
    };
    migration$59 = {
      version: 10,
      name: "Add is_private to database_instances",
      up: `
		ALTER TABLE database_instances
		ADD COLUMN is_private INTEGER NOT NULL DEFAULT 0;
	`,
      down: `
		-- SQLite doesn't support DROP COLUMN easily, so we recreate the table
		CREATE TABLE database_instances_backup (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			uuid TEXT NOT NULL UNIQUE,
			name TEXT NOT NULL UNIQUE,
			repository_url TEXT NOT NULL,
			local_path TEXT NOT NULL,
			sync_strategy INTEGER NOT NULL DEFAULT 0,
			auto_pull INTEGER NOT NULL DEFAULT 0,
			enabled INTEGER NOT NULL DEFAULT 1,
			personal_access_token TEXT,
			last_synced_at DATETIME,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		INSERT INTO database_instances_backup
		SELECT id, uuid, name, repository_url, local_path, sync_strategy,
		       auto_pull, enabled, personal_access_token, last_synced_at, created_at, updated_at
		FROM database_instances;

		DROP TABLE database_instances;

		ALTER TABLE database_instances_backup RENAME TO database_instances;

		CREATE INDEX idx_database_instances_uuid ON database_instances(uuid);
	`
    };
    migration$58 = {
      version: 11,
      name: "Create upgrade_configs table",
      up: `
		CREATE TABLE upgrade_configs (
			id INTEGER PRIMARY KEY AUTOINCREMENT,

			-- Relationship
			arr_instance_id INTEGER NOT NULL UNIQUE,

			-- Core settings
			enabled INTEGER NOT NULL DEFAULT 0,
			schedule INTEGER NOT NULL DEFAULT 360,
			filter_mode TEXT NOT NULL DEFAULT 'round_robin',

			-- Filters (stored as JSON)
			filters TEXT NOT NULL DEFAULT '[]',

			-- State tracking
			current_filter_index INTEGER NOT NULL DEFAULT 0,

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,

			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		CREATE INDEX idx_upgrade_configs_arr_instance ON upgrade_configs(arr_instance_id);
	`,
      down: `
		DROP INDEX IF EXISTS idx_upgrade_configs_arr_instance;
		DROP TABLE IF EXISTS upgrade_configs;
	`
    };
    migration$57 = {
      version: 12,
      name: "Add last_run_at to upgrade_configs",
      up: `
		ALTER TABLE upgrade_configs
		ADD COLUMN last_run_at DATETIME;
	`,
      down: `
		-- SQLite doesn't support DROP COLUMN easily, so we recreate the table
		CREATE TABLE upgrade_configs_backup (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			arr_instance_id INTEGER NOT NULL UNIQUE,
			enabled INTEGER NOT NULL DEFAULT 0,
			schedule INTEGER NOT NULL DEFAULT 360,
			filter_mode TEXT NOT NULL DEFAULT 'round_robin',
			filters TEXT NOT NULL DEFAULT '[]',
			current_filter_index INTEGER NOT NULL DEFAULT 0,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		INSERT INTO upgrade_configs_backup
		SELECT id, arr_instance_id, enabled, schedule, filter_mode, filters,
		       current_filter_index, created_at, updated_at
		FROM upgrade_configs;

		DROP TABLE upgrade_configs;

		ALTER TABLE upgrade_configs_backup RENAME TO upgrade_configs;

		CREATE INDEX idx_upgrade_configs_arr_instance ON upgrade_configs(arr_instance_id);
	`
    };
    migration$56 = {
      version: 13,
      name: "Add dry_run to upgrade_configs",
      up: `
		ALTER TABLE upgrade_configs
		ADD COLUMN dry_run INTEGER NOT NULL DEFAULT 0;
	`,
      down: `
		-- SQLite doesn't support DROP COLUMN easily, so we recreate the table
		CREATE TABLE upgrade_configs_backup (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			arr_instance_id INTEGER NOT NULL UNIQUE,
			enabled INTEGER NOT NULL DEFAULT 0,
			schedule INTEGER NOT NULL DEFAULT 360,
			filter_mode TEXT NOT NULL DEFAULT 'round_robin',
			filters TEXT NOT NULL DEFAULT '[]',
			current_filter_index INTEGER NOT NULL DEFAULT 0,
			last_run_at DATETIME,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		INSERT INTO upgrade_configs_backup
		SELECT id, arr_instance_id, enabled, schedule, filter_mode, filters,
		       current_filter_index, last_run_at, created_at, updated_at
		FROM upgrade_configs;

		DROP TABLE upgrade_configs;

		ALTER TABLE upgrade_configs_backup RENAME TO upgrade_configs;

		CREATE INDEX idx_upgrade_configs_arr_instance ON upgrade_configs(arr_instance_id);
	`
    };
    migration$55 = {
      version: 14,
      name: "Create ai_settings table",
      up: `
		CREATE TABLE ai_settings (
			id INTEGER PRIMARY KEY CHECK (id = 1),

			-- AI Configuration
			enabled INTEGER NOT NULL DEFAULT 0,
			api_url TEXT NOT NULL DEFAULT 'https://api.openai.com/v1',
			api_key TEXT NOT NULL DEFAULT '',
			model TEXT NOT NULL DEFAULT 'gpt-4o-mini',

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Insert default settings
		INSERT INTO ai_settings (id) VALUES (1);
	`,
      down: `
		DROP TABLE IF EXISTS ai_settings;
	`
    };
    migration$54 = {
      version: 15,
      name: "Create arr sync tables",
      up: `
		-- Quality profile selections (many-to-many)
		CREATE TABLE arr_sync_quality_profiles (
			instance_id INTEGER NOT NULL,
			database_id INTEGER NOT NULL,
			profile_id INTEGER NOT NULL,
			PRIMARY KEY (instance_id, database_id, profile_id),
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		-- Quality profile trigger config (one per instance)
		CREATE TABLE arr_sync_quality_profiles_config (
			instance_id INTEGER PRIMARY KEY,
			trigger TEXT NOT NULL DEFAULT 'none',
			cron TEXT,
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		-- Delay profile selections (many-to-many)
		CREATE TABLE arr_sync_delay_profiles (
			instance_id INTEGER NOT NULL,
			database_id INTEGER NOT NULL,
			profile_id INTEGER NOT NULL,
			PRIMARY KEY (instance_id, database_id, profile_id),
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		-- Delay profile trigger config (one per instance)
		CREATE TABLE arr_sync_delay_profiles_config (
			instance_id INTEGER PRIMARY KEY,
			trigger TEXT NOT NULL DEFAULT 'none',
			cron TEXT,
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		-- Media management (one row per instance)
		CREATE TABLE arr_sync_media_management (
			instance_id INTEGER PRIMARY KEY,
			naming_database_id INTEGER,
			quality_definitions_database_id INTEGER,
			media_settings_database_id INTEGER,
			trigger TEXT NOT NULL DEFAULT 'none',
			cron TEXT,
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		-- Indexes for faster lookups
		CREATE INDEX idx_arr_sync_quality_profiles_instance ON arr_sync_quality_profiles(instance_id);
		CREATE INDEX idx_arr_sync_delay_profiles_instance ON arr_sync_delay_profiles(instance_id);
	`,
      down: `
		DROP INDEX IF EXISTS idx_arr_sync_delay_profiles_instance;
		DROP INDEX IF EXISTS idx_arr_sync_quality_profiles_instance;
		DROP TABLE IF EXISTS arr_sync_media_management;
		DROP TABLE IF EXISTS arr_sync_delay_profiles_config;
		DROP TABLE IF EXISTS arr_sync_delay_profiles;
		DROP TABLE IF EXISTS arr_sync_quality_profiles_config;
		DROP TABLE IF EXISTS arr_sync_quality_profiles;
	`
    };
    migration$53 = {
      version: 16,
      name: "Add should_sync flags",
      up: `
		ALTER TABLE arr_sync_quality_profiles_config ADD COLUMN should_sync INTEGER NOT NULL DEFAULT 0;
		ALTER TABLE arr_sync_delay_profiles_config ADD COLUMN should_sync INTEGER NOT NULL DEFAULT 0;
		ALTER TABLE arr_sync_media_management ADD COLUMN should_sync INTEGER NOT NULL DEFAULT 0;
	`,
      down: `
		ALTER TABLE arr_sync_quality_profiles_config DROP COLUMN should_sync;
		ALTER TABLE arr_sync_delay_profiles_config DROP COLUMN should_sync;
		ALTER TABLE arr_sync_media_management DROP COLUMN should_sync;
	`
    };
    migration$52 = {
      version: 17,
      name: "Create regex101 cache table",
      up: `
		CREATE TABLE IF NOT EXISTS regex101_cache (
			regex101_id TEXT PRIMARY KEY,
			response TEXT NOT NULL,
			fetched_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);
	`,
      down: `
		DROP TABLE IF EXISTS regex101_cache;
	`
    };
    migration$51 = {
      version: 18,
      name: "Create app_info table",
      up: `
		CREATE TABLE app_info (
			id INTEGER PRIMARY KEY CHECK (id = 1),
			version TEXT NOT NULL,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Insert initial version
		INSERT INTO app_info (id, version) VALUES (1, '2.0.0');
	`,
      down: `
		DROP TABLE IF EXISTS app_info;
	`
    };
    migration$50 = {
      version: 19,
      name: "Change default log level to DEBUG",
      up: `
		UPDATE log_settings SET min_level = 'DEBUG' WHERE id = 1 AND min_level = 'INFO';
	`,
      down: `
		UPDATE log_settings SET min_level = 'INFO' WHERE id = 1 AND min_level = 'DEBUG';
	`
    };
    migration$49 = {
      version: 20,
      name: "Create tmdb_settings table",
      up: `
		CREATE TABLE tmdb_settings (
			id INTEGER PRIMARY KEY CHECK (id = 1),

			-- TMDB Configuration
			api_key TEXT NOT NULL DEFAULT '',

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Insert default settings
		INSERT INTO tmdb_settings (id) VALUES (1);
	`,
      down: `
		DROP TABLE IF EXISTS tmdb_settings;
	`
    };
    migration$48 = {
      version: 21,
      name: "create_parsed_release_cache",
      up: `
		-- Cache for parsed release titles
		-- Stores parser microservice responses to avoid redundant HTTP calls
		-- Used by both custom format testing and quality profile entity testing
		CREATE TABLE parsed_release_cache (
			cache_key TEXT PRIMARY KEY,           -- "{title}:{type}" e.g. "Movie.2024.1080p.WEB-DL:movie"
			parser_version TEXT NOT NULL,         -- Parser version when cached (for invalidation)
			parsed_result TEXT NOT NULL,          -- Full JSON ParseResult from parser
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Index for cleanup queries by version (delete old versions)
		CREATE INDEX idx_parsed_release_cache_version ON parsed_release_cache(parser_version);

		-- Index for potential cleanup queries by age
		CREATE INDEX idx_parsed_release_cache_created_at ON parsed_release_cache(created_at);
	`,
      down: `
		DROP INDEX IF EXISTS idx_parsed_release_cache_created_at;
		DROP INDEX IF EXISTS idx_parsed_release_cache_version;
		DROP TABLE IF EXISTS parsed_release_cache;
	`
    };
    migration$47 = {
      version: 22,
      name: "Add next_run_at to sync configs",
      up: `
		ALTER TABLE arr_sync_quality_profiles_config ADD COLUMN next_run_at TEXT;
		ALTER TABLE arr_sync_delay_profiles_config ADD COLUMN next_run_at TEXT;
		ALTER TABLE arr_sync_media_management ADD COLUMN next_run_at TEXT;
	`,
      down: `
		ALTER TABLE arr_sync_quality_profiles_config DROP COLUMN next_run_at;
		ALTER TABLE arr_sync_delay_profiles_config DROP COLUMN next_run_at;
		ALTER TABLE arr_sync_media_management DROP COLUMN next_run_at;
	`
    };
    migration$46 = {
      version: 23,
      name: "create_pattern_match_cache",
      up: `
		-- Cache for pattern match results
		-- Stores regex match results to avoid redundant computation
		-- Key is title, invalidated when patterns change (via patterns_hash)
		CREATE TABLE pattern_match_cache (
			title TEXT NOT NULL,                   -- Release title being matched
			patterns_hash TEXT NOT NULL,           -- Hash of all patterns (for invalidation)
			match_results TEXT NOT NULL,           -- JSON object: { pattern: boolean }
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			PRIMARY KEY (title, patterns_hash)
		);

		-- Index for cleanup queries by hash (delete old pattern sets)
		CREATE INDEX idx_pattern_match_cache_hash ON pattern_match_cache(patterns_hash);

		-- Index for potential cleanup queries by age
		CREATE INDEX idx_pattern_match_cache_created_at ON pattern_match_cache(created_at);
	`,
      down: `
		DROP INDEX IF EXISTS idx_pattern_match_cache_created_at;
		DROP INDEX IF EXISTS idx_pattern_match_cache_hash;
		DROP TABLE IF EXISTS pattern_match_cache;
	`
    };
    migration$45 = {
      version: 24,
      name: "Create arr_rename_settings table",
      up: `
		CREATE TABLE arr_rename_settings (
			id INTEGER PRIMARY KEY AUTOINCREMENT,

			-- Relationship
			arr_instance_id INTEGER NOT NULL UNIQUE,

			-- Settings
			dry_run INTEGER NOT NULL DEFAULT 1,
			rename_folders INTEGER NOT NULL DEFAULT 0,
			ignore_tag TEXT,

			-- Job scheduling
			enabled INTEGER NOT NULL DEFAULT 0,
			schedule INTEGER NOT NULL DEFAULT 1440,
			last_run_at DATETIME,

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,

			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		CREATE INDEX idx_arr_rename_settings_arr_instance ON arr_rename_settings(arr_instance_id);
	`,
      down: `
		DROP INDEX IF EXISTS idx_arr_rename_settings_arr_instance;
		DROP TABLE IF EXISTS arr_rename_settings;
	`
    };
    migration$44 = {
      version: 25,
      name: "Add summary_notifications to arr_rename_settings",
      up: `
		ALTER TABLE arr_rename_settings ADD COLUMN summary_notifications INTEGER NOT NULL DEFAULT 1;
	`,
      down: `
		ALTER TABLE arr_rename_settings DROP COLUMN summary_notifications;
	`
    };
    migration$43 = {
      version: 26,
      name: "Create upgrade_runs table",
      up: `
		CREATE TABLE upgrade_runs (
			id TEXT PRIMARY KEY,

			-- Relationship
			instance_id INTEGER NOT NULL,

			-- Timing
			started_at TEXT NOT NULL,
			completed_at TEXT NOT NULL,

			-- Status
			status TEXT NOT NULL CHECK (status IN ('success', 'partial', 'failed', 'skipped')),
			dry_run INTEGER NOT NULL DEFAULT 0,

			-- Config snapshot
			schedule INTEGER NOT NULL,
			filter_mode TEXT NOT NULL,
			filter_name TEXT NOT NULL,

			-- Library stats
			library_total INTEGER NOT NULL,
			library_cached INTEGER NOT NULL DEFAULT 0,
			library_fetch_ms INTEGER NOT NULL,

			-- Filter stats
			matched_count INTEGER NOT NULL,
			after_cooldown INTEGER NOT NULL,
			cooldown_hours INTEGER NOT NULL,
			dry_run_excluded INTEGER NOT NULL DEFAULT 0,

			-- Selection stats
			selection_method TEXT NOT NULL,
			selection_requested INTEGER NOT NULL,
			selected_count INTEGER NOT NULL,

			-- Results stats
			searches_triggered INTEGER NOT NULL,
			successful INTEGER NOT NULL,
			failed INTEGER NOT NULL,

			-- Complex data as JSON
			items TEXT NOT NULL DEFAULT '[]',
			errors TEXT NOT NULL DEFAULT '[]',

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,

			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		CREATE INDEX idx_upgrade_runs_instance ON upgrade_runs(instance_id);
		CREATE INDEX idx_upgrade_runs_started_at ON upgrade_runs(started_at DESC);
		CREATE INDEX idx_upgrade_runs_status ON upgrade_runs(status);
	`,
      down: `
		DROP INDEX IF EXISTS idx_upgrade_runs_status;
		DROP INDEX IF EXISTS idx_upgrade_runs_started_at;
		DROP INDEX IF EXISTS idx_upgrade_runs_instance;
		DROP TABLE IF EXISTS upgrade_runs;
	`
    };
    migration$42 = {
      version: 27,
      name: "Create rename_runs table",
      up: `
		CREATE TABLE rename_runs (
			id TEXT PRIMARY KEY,

			-- Relationship
			instance_id INTEGER NOT NULL,

			-- Timing
			started_at TEXT NOT NULL,
			completed_at TEXT NOT NULL,

			-- Status
			status TEXT NOT NULL CHECK (status IN ('success', 'partial', 'failed', 'skipped')),
			dry_run INTEGER NOT NULL DEFAULT 1,
			manual INTEGER NOT NULL DEFAULT 0,

			-- Config snapshot
			rename_folders INTEGER NOT NULL DEFAULT 0,
			ignore_tag TEXT,

			-- Library stats
			library_total INTEGER NOT NULL,
			library_fetch_ms INTEGER NOT NULL,

			-- Filtering stats
			after_ignore_tag INTEGER NOT NULL,
			skipped_by_tag INTEGER NOT NULL,

			-- Results stats
			files_needing_rename INTEGER NOT NULL,
			files_renamed INTEGER NOT NULL,
			folders_renamed INTEGER NOT NULL,
			commands_triggered INTEGER NOT NULL,
			commands_completed INTEGER NOT NULL,
			commands_failed INTEGER NOT NULL,

			-- Complex data as JSON
			items TEXT NOT NULL DEFAULT '[]',
			errors TEXT NOT NULL DEFAULT '[]',

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,

			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		CREATE INDEX idx_rename_runs_instance ON rename_runs(instance_id);
		CREATE INDEX idx_rename_runs_started_at ON rename_runs(started_at DESC);
		CREATE INDEX idx_rename_runs_status ON rename_runs(status);
	`,
      down: `
		DROP INDEX IF EXISTS idx_rename_runs_status;
		DROP INDEX IF EXISTS idx_rename_runs_started_at;
		DROP INDEX IF EXISTS idx_rename_runs_instance;
		DROP TABLE IF EXISTS rename_runs;
	`
    };
    migration$41 = {
      version: 28,
      name: "Simplify delay profile sync to single profile",
      up: `
		-- Drop the multi-select table
		DROP INDEX IF EXISTS idx_arr_sync_delay_profiles_instance;
		DROP TABLE IF EXISTS arr_sync_delay_profiles;

		-- Add single profile reference to config table
		ALTER TABLE arr_sync_delay_profiles_config ADD COLUMN database_id INTEGER;
		ALTER TABLE arr_sync_delay_profiles_config ADD COLUMN profile_id INTEGER;
	`,
      down: `
		-- Recreate multi-select table
		CREATE TABLE arr_sync_delay_profiles (
			instance_id INTEGER NOT NULL,
			database_id INTEGER NOT NULL,
			profile_id INTEGER NOT NULL,
			PRIMARY KEY (instance_id, database_id, profile_id),
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);
		CREATE INDEX idx_arr_sync_delay_profiles_instance ON arr_sync_delay_profiles(instance_id);

		-- Note: Cannot easily remove columns in SQLite, leaving them
	`
    };
    migration$40 = {
      version: 29,
      name: "Add database_id foreign key constraints",
      up: `
		-- ============================================================
		-- arr_sync_quality_profiles: Add FK with CASCADE DELETE
		-- ============================================================

		-- Create new table with foreign key
		CREATE TABLE arr_sync_quality_profiles_new (
			instance_id INTEGER NOT NULL,
			database_id INTEGER NOT NULL,
			profile_id INTEGER NOT NULL,
			PRIMARY KEY (instance_id, database_id, profile_id),
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE,
			FOREIGN KEY (database_id) REFERENCES database_instances(id) ON DELETE CASCADE
		);

		-- Copy only valid data (where database still exists)
		INSERT INTO arr_sync_quality_profiles_new (instance_id, database_id, profile_id)
		SELECT qp.instance_id, qp.database_id, qp.profile_id
		FROM arr_sync_quality_profiles qp
		INNER JOIN database_instances di ON qp.database_id = di.id;

		-- Drop old table and rename
		DROP TABLE arr_sync_quality_profiles;
		ALTER TABLE arr_sync_quality_profiles_new RENAME TO arr_sync_quality_profiles;

		-- Recreate index
		CREATE INDEX idx_arr_sync_quality_profiles_instance ON arr_sync_quality_profiles(instance_id);

		-- ============================================================
		-- arr_sync_delay_profiles_config: Add FK with SET NULL
		-- ============================================================

		-- Create new table with foreign key
		CREATE TABLE arr_sync_delay_profiles_config_new (
			instance_id INTEGER PRIMARY KEY,
			trigger TEXT NOT NULL DEFAULT 'none',
			cron TEXT,
			should_sync INTEGER NOT NULL DEFAULT 0,
			next_run_at TEXT,
			database_id INTEGER,
			profile_id INTEGER,
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE,
			FOREIGN KEY (database_id) REFERENCES database_instances(id) ON DELETE SET NULL
		);

		-- Copy data, setting database_id to NULL if database doesn't exist
		INSERT INTO arr_sync_delay_profiles_config_new (instance_id, trigger, cron, should_sync, next_run_at, database_id, profile_id)
		SELECT
			dpc.instance_id,
			dpc.trigger,
			dpc.cron,
			dpc.should_sync,
			dpc.next_run_at,
			CASE WHEN di.id IS NOT NULL THEN dpc.database_id ELSE NULL END,
			CASE WHEN di.id IS NOT NULL THEN dpc.profile_id ELSE NULL END
		FROM arr_sync_delay_profiles_config dpc
		LEFT JOIN database_instances di ON dpc.database_id = di.id;

		-- Drop old table and rename
		DROP TABLE arr_sync_delay_profiles_config;
		ALTER TABLE arr_sync_delay_profiles_config_new RENAME TO arr_sync_delay_profiles_config;

		-- ============================================================
		-- arr_sync_media_management: Add FKs with SET NULL
		-- ============================================================

		-- Create new table with foreign keys
		CREATE TABLE arr_sync_media_management_new (
			instance_id INTEGER PRIMARY KEY,
			naming_database_id INTEGER,
			quality_definitions_database_id INTEGER,
			media_settings_database_id INTEGER,
			trigger TEXT NOT NULL DEFAULT 'none',
			cron TEXT,
			should_sync INTEGER NOT NULL DEFAULT 0,
			next_run_at TEXT,
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE,
			FOREIGN KEY (naming_database_id) REFERENCES database_instances(id) ON DELETE SET NULL,
			FOREIGN KEY (quality_definitions_database_id) REFERENCES database_instances(id) ON DELETE SET NULL,
			FOREIGN KEY (media_settings_database_id) REFERENCES database_instances(id) ON DELETE SET NULL
		);

		-- Copy data, setting database_ids to NULL if databases don't exist
		INSERT INTO arr_sync_media_management_new (
			instance_id, naming_database_id, quality_definitions_database_id,
			media_settings_database_id, trigger, cron, should_sync, next_run_at
		)
		SELECT
			mm.instance_id,
			CASE WHEN di1.id IS NOT NULL THEN mm.naming_database_id ELSE NULL END,
			CASE WHEN di2.id IS NOT NULL THEN mm.quality_definitions_database_id ELSE NULL END,
			CASE WHEN di3.id IS NOT NULL THEN mm.media_settings_database_id ELSE NULL END,
			mm.trigger,
			mm.cron,
			mm.should_sync,
			mm.next_run_at
		FROM arr_sync_media_management mm
		LEFT JOIN database_instances di1 ON mm.naming_database_id = di1.id
		LEFT JOIN database_instances di2 ON mm.quality_definitions_database_id = di2.id
		LEFT JOIN database_instances di3 ON mm.media_settings_database_id = di3.id;

		-- Drop old table and rename
		DROP TABLE arr_sync_media_management;
		ALTER TABLE arr_sync_media_management_new RENAME TO arr_sync_media_management;
	`,
      down: `
		-- Recreate tables without database_id foreign keys
		-- (Cannot easily remove FK constraints in SQLite)

		-- arr_sync_quality_profiles
		CREATE TABLE arr_sync_quality_profiles_new (
			instance_id INTEGER NOT NULL,
			database_id INTEGER NOT NULL,
			profile_id INTEGER NOT NULL,
			PRIMARY KEY (instance_id, database_id, profile_id),
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);
		INSERT INTO arr_sync_quality_profiles_new SELECT * FROM arr_sync_quality_profiles;
		DROP TABLE arr_sync_quality_profiles;
		ALTER TABLE arr_sync_quality_profiles_new RENAME TO arr_sync_quality_profiles;
		CREATE INDEX idx_arr_sync_quality_profiles_instance ON arr_sync_quality_profiles(instance_id);

		-- arr_sync_delay_profiles_config
		CREATE TABLE arr_sync_delay_profiles_config_new (
			instance_id INTEGER PRIMARY KEY,
			trigger TEXT NOT NULL DEFAULT 'none',
			cron TEXT,
			should_sync INTEGER NOT NULL DEFAULT 0,
			next_run_at TEXT,
			database_id INTEGER,
			profile_id INTEGER,
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);
		INSERT INTO arr_sync_delay_profiles_config_new SELECT * FROM arr_sync_delay_profiles_config;
		DROP TABLE arr_sync_delay_profiles_config;
		ALTER TABLE arr_sync_delay_profiles_config_new RENAME TO arr_sync_delay_profiles_config;

		-- arr_sync_media_management
		CREATE TABLE arr_sync_media_management_new (
			instance_id INTEGER PRIMARY KEY,
			naming_database_id INTEGER,
			quality_definitions_database_id INTEGER,
			media_settings_database_id INTEGER,
			trigger TEXT NOT NULL DEFAULT 'none',
			cron TEXT,
			should_sync INTEGER NOT NULL DEFAULT 0,
			next_run_at TEXT,
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);
		INSERT INTO arr_sync_media_management_new SELECT * FROM arr_sync_media_management;
		DROP TABLE arr_sync_media_management;
		ALTER TABLE arr_sync_media_management_new RENAME TO arr_sync_media_management;
	`
    };
    migration$39 = {
      version: 30,
      name: "Create general_settings table",
      up: `
		-- General settings table (singleton pattern)
		CREATE TABLE IF NOT EXISTS general_settings (
			id INTEGER PRIMARY KEY CHECK (id = 1),

			-- Default delay profile settings
			apply_default_delay_profiles INTEGER NOT NULL DEFAULT 1,  -- 1=apply defaults when adding arr, 0=don't

			-- Metadata
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Insert default row
		INSERT INTO general_settings (id) VALUES (1);
	`,
      down: `
		DROP TABLE IF EXISTS general_settings;
	`
    };
    migration$38 = {
      version: 31,
      name: "Remove searchCooldown from filter configs",
      up: `
		-- Data migration handled by afterUp callback
		SELECT 1;
	`,
      down: `
		-- Cannot restore removed searchCooldown values
		SELECT 1;
	`,
      afterUp: migrateFilterConfigs
    };
    migration$37 = {
      version: 32,
      name: "Add filter_id to upgrade_runs",
      up: `
		ALTER TABLE upgrade_runs ADD COLUMN filter_id TEXT NOT NULL DEFAULT '';
	`,
      down: `
		-- SQLite doesn't support dropping columns easily
		-- The column will remain but won't be used
		SELECT 1;
	`
    };
    migration$36 = {
      version: 33,
      name: "Create GitHub cache table",
      up: `
		CREATE TABLE IF NOT EXISTS github_cache (
			cache_key TEXT PRIMARY KEY,
			cache_type TEXT NOT NULL,
			data TEXT NOT NULL,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			expires_at DATETIME NOT NULL
		);

		CREATE INDEX IF NOT EXISTS idx_github_cache_type ON github_cache(cache_type);
		CREATE INDEX IF NOT EXISTS idx_github_cache_expires ON github_cache(expires_at);
	`,
      down: `
		DROP INDEX IF EXISTS idx_github_cache_expires;
		DROP INDEX IF EXISTS idx_github_cache_type;
		DROP TABLE IF EXISTS github_cache;
	`
    };
    migration$35 = {
      version: 34,
      name: "Add sync status columns",
      up: `
		-- Add sync_status to quality profiles config
		ALTER TABLE arr_sync_quality_profiles_config
			ADD COLUMN sync_status TEXT NOT NULL DEFAULT 'idle';

		ALTER TABLE arr_sync_quality_profiles_config
			ADD COLUMN last_error TEXT;

		ALTER TABLE arr_sync_quality_profiles_config
			ADD COLUMN last_synced_at TEXT;

		-- Add sync_status to delay profiles config
		ALTER TABLE arr_sync_delay_profiles_config
			ADD COLUMN sync_status TEXT NOT NULL DEFAULT 'idle';

		ALTER TABLE arr_sync_delay_profiles_config
			ADD COLUMN last_error TEXT;

		ALTER TABLE arr_sync_delay_profiles_config
			ADD COLUMN last_synced_at TEXT;

		-- Add sync_status to media management
		ALTER TABLE arr_sync_media_management
			ADD COLUMN sync_status TEXT NOT NULL DEFAULT 'idle';

		ALTER TABLE arr_sync_media_management
			ADD COLUMN last_error TEXT;

		ALTER TABLE arr_sync_media_management
			ADD COLUMN last_synced_at TEXT;

		-- Migrate existing should_sync flags to sync_status
		UPDATE arr_sync_quality_profiles_config
			SET sync_status = CASE WHEN should_sync = 1 THEN 'pending' ELSE 'idle' END;

		UPDATE arr_sync_delay_profiles_config
			SET sync_status = CASE WHEN should_sync = 1 THEN 'pending' ELSE 'idle' END;

		UPDATE arr_sync_media_management
			SET sync_status = CASE WHEN should_sync = 1 THEN 'pending' ELSE 'idle' END;
	`,
      down: `
		-- SQLite doesn't support DROP COLUMN easily
		-- These columns will remain but be unused if rolled back
	`
    };
    migration$34 = {
      version: 35,
      name: "Add skipped status to job_runs",
      up: `
		-- Create new table with updated CHECK constraint
		CREATE TABLE job_runs_new (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			job_id INTEGER NOT NULL,
			status TEXT NOT NULL CHECK (status IN ('success', 'failure', 'skipped')),
			started_at DATETIME NOT NULL,
			finished_at DATETIME NOT NULL,
			duration_ms INTEGER NOT NULL,
			error TEXT,
			output TEXT,
			FOREIGN KEY (job_id) REFERENCES jobs(id) ON DELETE CASCADE
		);

		-- Copy existing data
		INSERT INTO job_runs_new (id, job_id, status, started_at, finished_at, duration_ms, error, output)
		SELECT id, job_id, status, started_at, finished_at, duration_ms, error, output
		FROM job_runs;

		-- Drop old table
		DROP TABLE job_runs;

		-- Rename new table
		ALTER TABLE job_runs_new RENAME TO job_runs;

		-- Recreate indexes
		CREATE INDEX idx_job_runs_job_id ON job_runs(job_id);
		CREATE INDEX idx_job_runs_started_at ON job_runs(started_at);
		CREATE INDEX idx_job_runs_status ON job_runs(status);
	`,
      down: `
		-- Create old table with original CHECK constraint
		CREATE TABLE job_runs_old (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			job_id INTEGER NOT NULL,
			status TEXT NOT NULL CHECK (status IN ('success', 'failure')),
			started_at DATETIME NOT NULL,
			finished_at DATETIME NOT NULL,
			duration_ms INTEGER NOT NULL,
			error TEXT,
			output TEXT,
			FOREIGN KEY (job_id) REFERENCES jobs(id) ON DELETE CASCADE
		);

		-- Copy data (convert 'skipped' to 'success' for backwards compatibility)
		INSERT INTO job_runs_old (id, job_id, status, started_at, finished_at, duration_ms, error, output)
		SELECT id, job_id,
			CASE WHEN status = 'skipped' THEN 'success' ELSE status END,
			started_at, finished_at, duration_ms, error, output
		FROM job_runs;

		-- Drop new table
		DROP TABLE job_runs;

		-- Rename old table
		ALTER TABLE job_runs_old RENAME TO job_runs;

		-- Recreate original indexes
		CREATE INDEX idx_job_runs_job_id ON job_runs(job_id);
		CREATE INDEX idx_job_runs_started_at ON job_runs(started_at);
	`
    };
    migration$33 = {
      version: 36,
      name: "Create auth tables",
      up: `
		-- Users table (single admin user)
		CREATE TABLE users (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			username TEXT NOT NULL UNIQUE,
			password_hash TEXT NOT NULL,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Sessions table (multiple sessions per user)
		CREATE TABLE sessions (
			id TEXT PRIMARY KEY,
			user_id INTEGER NOT NULL,
			expires_at DATETIME NOT NULL,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
		);

		CREATE INDEX idx_sessions_user_id ON sessions(user_id);
		CREATE INDEX idx_sessions_expires_at ON sessions(expires_at);

		-- Auth settings table (singleton)
		CREATE TABLE auth_settings (
			id INTEGER PRIMARY KEY CHECK (id = 1),
			session_duration_hours INTEGER NOT NULL DEFAULT 168,
			api_key TEXT,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Insert default auth settings with generated API key
		INSERT INTO auth_settings (id, api_key) VALUES (1, lower(hex(randomblob(16))));
	`,
      down: `
		DROP TABLE IF EXISTS auth_settings;
		DROP INDEX IF EXISTS idx_sessions_expires_at;
		DROP INDEX IF EXISTS idx_sessions_user_id;
		DROP TABLE IF EXISTS sessions;
		DROP TABLE IF EXISTS users;
	`
    };
    migration$32 = {
      version: 37,
      name: "Add session metadata",
      up: `
		ALTER TABLE sessions ADD COLUMN ip_address TEXT;
		ALTER TABLE sessions ADD COLUMN user_agent TEXT;
		ALTER TABLE sessions ADD COLUMN browser TEXT;
		ALTER TABLE sessions ADD COLUMN os TEXT;
		ALTER TABLE sessions ADD COLUMN device_type TEXT;
		ALTER TABLE sessions ADD COLUMN last_active_at DATETIME;
	`,
      down: `
		-- SQLite doesn't support DROP COLUMN directly, so we recreate the table
		CREATE TABLE sessions_new (
			id TEXT PRIMARY KEY,
			user_id INTEGER NOT NULL,
			expires_at DATETIME NOT NULL,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
		);

		INSERT INTO sessions_new (id, user_id, expires_at, created_at)
		SELECT id, user_id, expires_at, created_at FROM sessions;

		DROP TABLE sessions;
		ALTER TABLE sessions_new RENAME TO sessions;

		CREATE INDEX idx_sessions_user_id ON sessions(user_id);
		CREATE INDEX idx_sessions_expires_at ON sessions(expires_at);
	`
    };
    migration$31 = {
      version: 38,
      name: "Add media management config names",
      up: `
		ALTER TABLE arr_sync_media_management ADD COLUMN naming_config_name TEXT;
		ALTER TABLE arr_sync_media_management ADD COLUMN quality_definitions_config_name TEXT;
		ALTER TABLE arr_sync_media_management ADD COLUMN media_settings_config_name TEXT;
	`,
      down: `
		-- SQLite doesn't support DROP COLUMN directly, so we recreate the table
		CREATE TABLE arr_sync_media_management_new (
			instance_id INTEGER PRIMARY KEY,
			naming_database_id INTEGER,
			quality_definitions_database_id INTEGER,
			media_settings_database_id INTEGER,
			trigger TEXT NOT NULL DEFAULT 'none',
			cron TEXT,
			should_sync INTEGER NOT NULL DEFAULT 0,
			next_run_at TEXT,
			sync_status TEXT NOT NULL DEFAULT 'idle',
			last_error TEXT,
			last_synced_at TEXT,
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE,
			FOREIGN KEY (naming_database_id) REFERENCES database_instances(id) ON DELETE SET NULL,
			FOREIGN KEY (quality_definitions_database_id) REFERENCES database_instances(id) ON DELETE SET NULL,
			FOREIGN KEY (media_settings_database_id) REFERENCES database_instances(id) ON DELETE SET NULL
		);

		INSERT INTO arr_sync_media_management_new (
			instance_id, naming_database_id, quality_definitions_database_id,
			media_settings_database_id, trigger, cron, should_sync, next_run_at,
			sync_status, last_error, last_synced_at
		)
		SELECT
			instance_id, naming_database_id, quality_definitions_database_id,
			media_settings_database_id, trigger, cron, should_sync, next_run_at,
			sync_status, last_error, last_synced_at
		FROM arr_sync_media_management;

		DROP TABLE arr_sync_media_management;
		ALTER TABLE arr_sync_media_management_new RENAME TO arr_sync_media_management;
	`
    };
    migration$30 = {
      version: 39,
      name: "Create setup_state table",
      up: `
		CREATE TABLE setup_state (
			id INTEGER PRIMARY KEY CHECK (id = 1),
			default_database_linked INTEGER NOT NULL DEFAULT 0,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		-- Initialize with defaults
		INSERT INTO setup_state (id, default_database_linked) VALUES (1, 0);
	`,
      down: `
		DROP TABLE setup_state;
	`
    };
    migration$29 = {
      version: 40,
      name: "Add local_ops_enabled to database_instances",
      up: `
		ALTER TABLE database_instances
		ADD COLUMN local_ops_enabled INTEGER NOT NULL DEFAULT 0;
	`,
      down: `
		-- SQLite doesn't support DROP COLUMN easily, so we recreate the table
		CREATE TABLE database_instances_backup (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			uuid TEXT NOT NULL UNIQUE,
			name TEXT NOT NULL UNIQUE,
			repository_url TEXT NOT NULL,
			personal_access_token TEXT,
			is_private INTEGER NOT NULL DEFAULT 0,
			local_path TEXT NOT NULL,
			sync_strategy INTEGER NOT NULL DEFAULT 0,
			auto_pull INTEGER NOT NULL DEFAULT 0,
			enabled INTEGER NOT NULL DEFAULT 1,
			last_synced_at DATETIME,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		INSERT INTO database_instances_backup
		SELECT id, uuid, name, repository_url, personal_access_token, is_private,
		       local_path, sync_strategy, auto_pull, enabled, last_synced_at,
		       created_at, updated_at
		FROM database_instances;

		DROP TABLE database_instances;

		ALTER TABLE database_instances_backup RENAME TO database_instances;

		CREATE INDEX idx_database_instances_uuid ON database_instances(uuid);
	`
    };
    migration$28 = {
      version: 41,
      name: "Create pcd_ops table",
      up: `
		CREATE TABLE pcd_ops (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			database_id INTEGER NOT NULL,
			origin TEXT NOT NULL CHECK (origin IN ('base', 'user')),
			state TEXT NOT NULL CHECK (state IN ('published', 'draft', 'superseded', 'dropped', 'orphaned')),
			source TEXT NOT NULL CHECK (source IN ('repo', 'local', 'import')),
			filename TEXT,
			op_number INTEGER,
			sequence INTEGER,
			sql TEXT NOT NULL,
			metadata TEXT,
			desired_state TEXT,
			content_hash TEXT,
			last_seen_in_repo_at DATETIME,
			superseded_by_op_id INTEGER,
			pushed_at DATETIME,
			pushed_commit TEXT,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (database_id) REFERENCES database_instances(id) ON DELETE CASCADE,
			FOREIGN KEY (superseded_by_op_id) REFERENCES pcd_ops(id)
		);

		CREATE INDEX idx_pcd_ops_apply_order
			ON pcd_ops(database_id, origin, state, sequence, id);

		CREATE UNIQUE INDEX idx_pcd_ops_base_filename
			ON pcd_ops(database_id, origin, filename)
			WHERE origin = 'base' AND filename IS NOT NULL;

		CREATE INDEX idx_pcd_ops_hash
			ON pcd_ops(database_id, origin, content_hash);
	`,
      down: `
		DROP INDEX IF EXISTS idx_pcd_ops_hash;
		DROP INDEX IF EXISTS idx_pcd_ops_base_filename;
		DROP INDEX IF EXISTS idx_pcd_ops_apply_order;
		DROP TABLE IF EXISTS pcd_ops;
	`
    };
    migration$27 = {
      version: 42,
      name: "Create pcd_op_history table",
      up: `
		CREATE TABLE pcd_op_history (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			op_id INTEGER NOT NULL,
			database_id INTEGER NOT NULL,
			batch_id TEXT NOT NULL,
			status TEXT NOT NULL CHECK (
				status IN ('applied', 'skipped', 'conflicted', 'conflicted_pending', 'error', 'dropped', 'superseded')
			),
			rowcount INTEGER,
			conflict_reason TEXT,
			error TEXT,
			details TEXT,
			applied_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (op_id) REFERENCES pcd_ops(id) ON DELETE CASCADE,
			FOREIGN KEY (database_id) REFERENCES database_instances(id) ON DELETE CASCADE
		);

		CREATE INDEX idx_pcd_op_history_status
			ON pcd_op_history(database_id, status, applied_at);

		CREATE INDEX idx_pcd_op_history_op
			ON pcd_op_history(op_id, applied_at);
	`,
      down: `
		DROP INDEX IF EXISTS idx_pcd_op_history_op;
		DROP INDEX IF EXISTS idx_pcd_op_history_status;
		DROP TABLE IF EXISTS pcd_op_history;
	`
    };
    migration$26 = {
      version: 43,
      name: "Add git_user_name and git_user_email to database_instances",
      up: `
		ALTER TABLE database_instances
		ADD COLUMN git_user_name TEXT;

		ALTER TABLE database_instances
		ADD COLUMN git_user_email TEXT;
	`,
      down: `
		-- SQLite doesn't support DROP COLUMN easily, so we recreate the table
		CREATE TABLE database_instances_backup (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			uuid TEXT NOT NULL UNIQUE,
			name TEXT NOT NULL UNIQUE,
			repository_url TEXT NOT NULL,
			personal_access_token TEXT,
			is_private INTEGER NOT NULL DEFAULT 0,
			local_ops_enabled INTEGER NOT NULL DEFAULT 0,
			local_path TEXT NOT NULL,
			sync_strategy INTEGER NOT NULL DEFAULT 0,
			auto_pull INTEGER NOT NULL DEFAULT 0,
			enabled INTEGER NOT NULL DEFAULT 1,
			last_synced_at DATETIME,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		INSERT INTO database_instances_backup
		SELECT id, uuid, name, repository_url, personal_access_token, is_private,
		       local_ops_enabled, local_path, sync_strategy, auto_pull, enabled,
		       last_synced_at, created_at, updated_at
		FROM database_instances;

		DROP TABLE database_instances;

		ALTER TABLE database_instances_backup RENAME TO database_instances;

		CREATE INDEX idx_database_instances_uuid ON database_instances(uuid);
	`
    };
    migration$25 = {
      version: 44,
      name: "Add conflict_strategy to database_instances",
      up: `
		ALTER TABLE database_instances
		ADD COLUMN conflict_strategy TEXT NOT NULL DEFAULT 'override'
			CHECK (conflict_strategy IN ('override', 'align', 'ask'));
	`,
      down: `
		-- SQLite doesn't support DROP COLUMN easily, so we recreate the table
		CREATE TABLE database_instances_backup (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			uuid TEXT NOT NULL UNIQUE,
			name TEXT NOT NULL UNIQUE,
			repository_url TEXT NOT NULL,
			personal_access_token TEXT,
			is_private INTEGER NOT NULL DEFAULT 0,
			local_ops_enabled INTEGER NOT NULL DEFAULT 0,
			git_user_name TEXT,
			git_user_email TEXT,
			local_path TEXT NOT NULL,
			sync_strategy INTEGER NOT NULL DEFAULT 0,
			auto_pull INTEGER NOT NULL DEFAULT 0,
			enabled INTEGER NOT NULL DEFAULT 1,
			last_synced_at DATETIME,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		INSERT INTO database_instances_backup
		SELECT id, uuid, name, repository_url, personal_access_token, is_private,
		       local_ops_enabled, git_user_name, git_user_email, local_path,
		       sync_strategy, auto_pull, enabled, last_synced_at, created_at, updated_at
		FROM database_instances;

		DROP TABLE database_instances;

		ALTER TABLE database_instances_backup RENAME TO database_instances;

		CREATE INDEX idx_database_instances_uuid ON database_instances(uuid);
	`
    };
    migration$24 = {
      version: 45,
      name: "Change delay profile sync to use profile_name",
      up: `
		CREATE TABLE arr_sync_delay_profiles_config_new (
			instance_id INTEGER PRIMARY KEY,
			trigger TEXT NOT NULL DEFAULT 'none',
			cron TEXT,
			should_sync INTEGER NOT NULL DEFAULT 0,
			next_run_at TEXT,
			database_id INTEGER,
			profile_name TEXT,
			sync_status TEXT NOT NULL DEFAULT 'idle',
			last_error TEXT,
			last_synced_at TEXT,
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE,
			FOREIGN KEY (database_id) REFERENCES database_instances(id) ON DELETE SET NULL
		);

		INSERT INTO arr_sync_delay_profiles_config_new (
			instance_id, trigger, cron, should_sync, next_run_at,
			database_id, profile_name, sync_status, last_error, last_synced_at
		)
		SELECT
			instance_id, trigger, cron, should_sync, next_run_at,
			database_id, NULL, sync_status, last_error, last_synced_at
		FROM arr_sync_delay_profiles_config;

		DROP TABLE arr_sync_delay_profiles_config;
		ALTER TABLE arr_sync_delay_profiles_config_new RENAME TO arr_sync_delay_profiles_config;
	`
    };
    migration$23 = {
      version: 46,
      name: "Change quality profile sync to use profile_name",
      up: `
		CREATE TABLE arr_sync_quality_profiles_new (
			instance_id INTEGER NOT NULL,
			database_id INTEGER NOT NULL,
			profile_name TEXT NOT NULL,
			PRIMARY KEY (instance_id, database_id, profile_name),
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		DROP TABLE arr_sync_quality_profiles;
		ALTER TABLE arr_sync_quality_profiles_new RENAME TO arr_sync_quality_profiles;
		CREATE INDEX idx_arr_sync_quality_profiles_instance ON arr_sync_quality_profiles(instance_id);
	`
    };
    migration$22 = {
      version: 47,
      name: "Create arr_database_namespaces table",
      up: `
		CREATE TABLE arr_database_namespaces (
			instance_id    INTEGER NOT NULL,
			database_id    INTEGER NOT NULL,
			namespace_index INTEGER NOT NULL,
			PRIMARY KEY (instance_id, database_id),
			UNIQUE (instance_id, namespace_index),
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE,
			FOREIGN KEY (database_id) REFERENCES database_instances(id) ON DELETE CASCADE
		);
	`,
      down: `DROP TABLE IF EXISTS arr_database_namespaces;`
    };
    migration$21 = {
      version: 48,
      name: "Restore database_id FK on arr_sync_quality_profiles",
      up: `
		-- Remove stale references to deleted databases
		DELETE FROM arr_sync_quality_profiles
		WHERE database_id NOT IN (SELECT id FROM database_instances);

		-- Recreate with both FKs
		CREATE TABLE arr_sync_quality_profiles_new (
			instance_id INTEGER NOT NULL,
			database_id INTEGER NOT NULL,
			profile_name TEXT NOT NULL,
			PRIMARY KEY (instance_id, database_id, profile_name),
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE,
			FOREIGN KEY (database_id) REFERENCES database_instances(id) ON DELETE CASCADE
		);

		INSERT INTO arr_sync_quality_profiles_new
		SELECT * FROM arr_sync_quality_profiles;

		DROP TABLE arr_sync_quality_profiles;
		ALTER TABLE arr_sync_quality_profiles_new RENAME TO arr_sync_quality_profiles;
		CREATE INDEX idx_arr_sync_quality_profiles_instance ON arr_sync_quality_profiles(instance_id);
	`
    };
    migration$20 = {
      version: 49,
      name: "Create job queue tables",
      up: `
		CREATE TABLE job_queue (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			job_type TEXT NOT NULL,
			status TEXT NOT NULL DEFAULT 'queued',
			run_at TEXT NOT NULL,
			payload TEXT NOT NULL DEFAULT '{}',
			source TEXT NOT NULL DEFAULT 'system',
			dedupe_key TEXT,
			cooldown_until TEXT,
			attempts INTEGER NOT NULL DEFAULT 0,
			started_at TEXT,
			finished_at TEXT,
			created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
			updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
		);

		CREATE TABLE job_run_history (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			queue_id INTEGER,
			job_type TEXT NOT NULL,
			status TEXT NOT NULL,
			started_at TEXT NOT NULL,
			finished_at TEXT NOT NULL,
			duration_ms INTEGER NOT NULL,
			error TEXT,
			output TEXT,
			created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (queue_id) REFERENCES job_queue(id) ON DELETE SET NULL
		);

		CREATE UNIQUE INDEX idx_job_queue_dedupe_key ON job_queue(dedupe_key) WHERE dedupe_key IS NOT NULL;
		CREATE INDEX idx_job_queue_status_run_at ON job_queue(status, run_at);
		CREATE INDEX idx_job_queue_run_at ON job_queue(run_at);
		CREATE INDEX idx_job_run_history_queue_id ON job_run_history(queue_id);
		CREATE INDEX idx_job_run_history_started_at ON job_run_history(started_at);
		CREATE INDEX idx_job_run_history_status ON job_run_history(status);
	`,
      down: `
		DROP INDEX IF EXISTS idx_job_run_history_status;
		DROP INDEX IF EXISTS idx_job_run_history_started_at;
		DROP INDEX IF EXISTS idx_job_run_history_queue_id;
		DROP INDEX IF EXISTS idx_job_queue_run_at;
		DROP INDEX IF EXISTS idx_job_queue_status_run_at;
		DROP INDEX IF EXISTS idx_job_queue_dedupe_key;
		DROP TABLE IF EXISTS job_run_history;
		DROP TABLE IF EXISTS job_queue;
	`
    };
    migration$19 = {
      version: 50,
      name: "Remove dry_run columns",
      up: `
		-- ===== upgrade_configs =====
		CREATE TABLE upgrade_configs_new (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			arr_instance_id INTEGER NOT NULL UNIQUE,
			enabled INTEGER NOT NULL DEFAULT 0,
			schedule INTEGER NOT NULL DEFAULT 360,
			filter_mode TEXT NOT NULL DEFAULT 'round_robin',
			filters TEXT NOT NULL DEFAULT '[]',
			current_filter_index INTEGER NOT NULL DEFAULT 0,
			last_run_at DATETIME,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		INSERT INTO upgrade_configs_new
			(id, arr_instance_id, enabled, schedule, filter_mode, filters,
			 current_filter_index, last_run_at, created_at, updated_at)
		SELECT id, arr_instance_id, enabled, schedule, filter_mode, filters,
			   current_filter_index, last_run_at, created_at, updated_at
		FROM upgrade_configs;

		DROP TABLE upgrade_configs;
		ALTER TABLE upgrade_configs_new RENAME TO upgrade_configs;
		CREATE INDEX idx_upgrade_configs_arr_instance ON upgrade_configs(arr_instance_id);

		-- ===== arr_rename_settings =====
		CREATE TABLE arr_rename_settings_new (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			arr_instance_id INTEGER NOT NULL UNIQUE,
			rename_folders INTEGER NOT NULL DEFAULT 0,
			ignore_tag TEXT,
			summary_notifications INTEGER NOT NULL DEFAULT 1,
			enabled INTEGER NOT NULL DEFAULT 0,
			schedule INTEGER NOT NULL DEFAULT 1440,
			last_run_at DATETIME,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		INSERT INTO arr_rename_settings_new
			(id, arr_instance_id, rename_folders, ignore_tag, summary_notifications,
			 enabled, schedule, last_run_at, created_at, updated_at)
		SELECT id, arr_instance_id, rename_folders, ignore_tag, summary_notifications,
			   enabled, schedule, last_run_at, created_at, updated_at
		FROM arr_rename_settings;

		DROP TABLE arr_rename_settings;
		ALTER TABLE arr_rename_settings_new RENAME TO arr_rename_settings;
		CREATE INDEX idx_arr_rename_settings_arr_instance ON arr_rename_settings(arr_instance_id);
	`,
      down: `
		ALTER TABLE upgrade_configs ADD COLUMN dry_run INTEGER NOT NULL DEFAULT 0;
		ALTER TABLE arr_rename_settings ADD COLUMN dry_run INTEGER NOT NULL DEFAULT 1;
	`
    };
    migration$18 = {
      version: 51,
      name: "Cron scheduling for upgrades and renames",
      up: `
		-- ===== upgrade_configs =====
		CREATE TABLE upgrade_configs_new (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			arr_instance_id INTEGER NOT NULL UNIQUE,
			enabled INTEGER NOT NULL DEFAULT 0,
			cron TEXT NOT NULL DEFAULT '0 */6 * * *',
			next_run_at TEXT,
			filter_mode TEXT NOT NULL DEFAULT 'round_robin',
			filters TEXT NOT NULL DEFAULT '[]',
			current_filter_index INTEGER NOT NULL DEFAULT 0,
			last_run_at DATETIME,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		INSERT INTO upgrade_configs_new
			(id, arr_instance_id, enabled, cron, next_run_at, filter_mode, filters,
			 current_filter_index, last_run_at, created_at, updated_at)
		SELECT id, arr_instance_id, enabled,
			CASE
				WHEN schedule <= 60 THEN '*/' || schedule || ' * * * *'
				WHEN schedule = 1440 THEN '0 0 * * *'
				WHEN schedule = 2880 THEN '0 0 */2 * *'
				WHEN schedule = 10080 THEN '0 0 * * 0'
				ELSE '0 */' || (schedule / 60) || ' * * *'
			END,
			NULL, filter_mode, filters,
			current_filter_index, last_run_at, created_at, updated_at
		FROM upgrade_configs;

		DROP TABLE upgrade_configs;
		ALTER TABLE upgrade_configs_new RENAME TO upgrade_configs;
		CREATE INDEX idx_upgrade_configs_arr_instance ON upgrade_configs(arr_instance_id);

		-- ===== arr_rename_settings =====
		CREATE TABLE arr_rename_settings_new (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			arr_instance_id INTEGER NOT NULL UNIQUE,
			rename_folders INTEGER NOT NULL DEFAULT 0,
			ignore_tag TEXT,
			summary_notifications INTEGER NOT NULL DEFAULT 1,
			enabled INTEGER NOT NULL DEFAULT 0,
			cron TEXT NOT NULL DEFAULT '0 0 * * *',
			next_run_at TEXT,
			last_run_at DATETIME,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		INSERT INTO arr_rename_settings_new
			(id, arr_instance_id, rename_folders, ignore_tag, summary_notifications,
			 enabled, cron, next_run_at, last_run_at, created_at, updated_at)
		SELECT id, arr_instance_id, rename_folders, ignore_tag, summary_notifications,
			enabled,
			CASE
				WHEN schedule <= 60 THEN '*/' || schedule || ' * * * *'
				WHEN schedule = 1440 THEN '0 0 * * *'
				WHEN schedule = 2880 THEN '0 0 */2 * *'
				WHEN schedule = 10080 THEN '0 0 * * 0'
				ELSE '0 */' || (schedule / 60) || ' * * *'
			END,
			NULL, last_run_at, created_at, updated_at
		FROM arr_rename_settings;

		DROP TABLE arr_rename_settings;
		ALTER TABLE arr_rename_settings_new RENAME TO arr_rename_settings;
		CREATE INDEX idx_arr_rename_settings_arr_instance ON arr_rename_settings(arr_instance_id);

		-- ===== upgrade_runs: rename schedule column to cron =====
		ALTER TABLE upgrade_runs RENAME COLUMN schedule TO cron;
	`,
      down: `
		-- Reverting requires table recreation to add schedule back
		-- This is a simplified rollback that adds the column with default
		ALTER TABLE upgrade_configs ADD COLUMN schedule INTEGER NOT NULL DEFAULT 360;
		ALTER TABLE arr_rename_settings ADD COLUMN schedule INTEGER NOT NULL DEFAULT 1440;
	`
    };
    migration$17 = {
      version: 52,
      name: "Create arr_cleanup_settings table",
      up: `
		CREATE TABLE arr_cleanup_settings (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			arr_instance_id INTEGER NOT NULL UNIQUE,
			enabled INTEGER NOT NULL DEFAULT 0,
			cron TEXT NOT NULL DEFAULT '0 0 * * 0',
			next_run_at TEXT,
			last_run_at TEXT,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		CREATE INDEX idx_arr_cleanup_settings_instance ON arr_cleanup_settings(arr_instance_id);
	`,
      down: `
		DROP INDEX IF EXISTS idx_arr_cleanup_settings_instance;
		DROP TABLE IF EXISTS arr_cleanup_settings;
	`
    };
    migration$16 = {
      version: 53,
      name: "Add library refresh to arr_instances",
      up: `
		ALTER TABLE arr_instances ADD COLUMN library_refresh_interval INTEGER NOT NULL DEFAULT 0;
		ALTER TABLE arr_instances ADD COLUMN library_last_refreshed_at TEXT;
	`,
      down: `
		ALTER TABLE arr_instances DROP COLUMN library_refresh_interval;
		ALTER TABLE arr_instances DROP COLUMN library_last_refreshed_at;
	`
    };
    migration$15 = {
      version: 54,
      name: "Remove namespace system",
      up: `
		DROP TABLE IF EXISTS arr_database_namespaces;
	`,
      down: `
		CREATE TABLE arr_database_namespaces (
			instance_id    INTEGER NOT NULL,
			database_id    INTEGER NOT NULL,
			namespace_index INTEGER NOT NULL,
			PRIMARY KEY (instance_id, database_id),
			UNIQUE (instance_id, namespace_index),
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE,
			FOREIGN KEY (database_id) REFERENCES database_instances(id) ON DELETE CASCADE
		);
	`
    };
    migration$14 = {
      version: 55,
      name: "Create login attempts table",
      up: `
		CREATE TABLE login_attempts (
			ip TEXT NOT NULL,
			endpoint TEXT NOT NULL,
			category TEXT NOT NULL DEFAULT 'unknown',
			failed_at DATETIME NOT NULL DEFAULT (datetime('now'))
		);

		CREATE INDEX idx_login_attempts_lookup
			ON login_attempts(ip, endpoint, failed_at);
	`,
      down: `
		DROP INDEX IF EXISTS idx_login_attempts_lookup;
		DROP TABLE IF EXISTS login_attempts;
	`
    };
    migration$13 = {
      version: 56,
      name: "Add local bypass to auth settings",
      up: `
		ALTER TABLE auth_settings ADD COLUMN local_bypass_enabled INTEGER NOT NULL DEFAULT 0;
	`,
      down: `
		ALTER TABLE auth_settings DROP COLUMN local_bypass_enabled;
	`,
      afterUp() {
        if ((Deno.env.get("AUTH") || "").toLowerCase() === "local") db.execute("UPDATE auth_settings SET local_bypass_enabled = 1 WHERE id = 1");
      }
    };
    migration$12 = {
      version: 57,
      name: "Hash API key (clear existing plaintext)",
      up: `
		UPDATE auth_settings SET api_key = NULL WHERE id = 1;
	`
    };
    migration$11 = {
      version: 58,
      name: "Add onboarding_shown to general_settings",
      up: `
		ALTER TABLE general_settings ADD COLUMN onboarding_shown INTEGER NOT NULL DEFAULT 0;
	`,
      down: `
		ALTER TABLE general_settings DROP COLUMN onboarding_shown;
	`
    };
    migration$10 = {
      version: 59,
      name: "Add external_url to arr_instances",
      up: `
		ALTER TABLE arr_instances ADD COLUMN external_url TEXT;
	`,
      down: `
		ALTER TABLE arr_instances DROP COLUMN external_url;
	`
    };
    migration$9 = {
      version: 60,
      name: "Drop app_info table",
      up: `
		DROP TABLE IF EXISTS app_info;
	`,
      down: `
		CREATE TABLE app_info (
			id INTEGER PRIMARY KEY CHECK (id = 1),
			version TEXT NOT NULL,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
		);

		INSERT INTO app_info (id, version) VALUES (1, '2.0.0');
	`
    };
    migration$8 = {
      version: 61,
      name: "Create announcements and versions_snapshot tables",
      up: `
		CREATE TABLE announcements (
			id TEXT PRIMARY KEY,                                 -- ULID from bulletin
			title TEXT NOT NULL,
			severity TEXT NOT NULL CHECK (severity IN ('info','warning','critical')),
			published_at DATETIME NOT NULL,
			expires_at DATETIME,
			min_version TEXT,
			max_version TEXT,
			link TEXT,
			body TEXT,                                           -- null until first open
			withdrawn INTEGER NOT NULL DEFAULT 0 CHECK (withdrawn IN (0,1)),
			read_at DATETIME,                                    -- null = unread
			fetched_at DATETIME NOT NULL,                        -- last manifest sync timestamp
			body_fetched_at DATETIME                             -- set when body is lazy-loaded
		);

		CREATE INDEX idx_announcements_published_at ON announcements(published_at DESC);
		CREATE INDEX idx_announcements_visible ON announcements(withdrawn, expires_at);

		CREATE TABLE versions_snapshot (
			id INTEGER PRIMARY KEY CHECK (id = 1),
			payload TEXT NOT NULL,                               -- raw versions.json as fetched
			fetched_at DATETIME NOT NULL
		);
	`,
      down: `
		DROP INDEX IF EXISTS idx_announcements_visible;
		DROP INDEX IF EXISTS idx_announcements_published_at;
		DROP TABLE IF EXISTS announcements;
		DROP TABLE IF EXISTS versions_snapshot;
	`
    };
    migration$7 = {
      version: 62,
      name: "Drop onboarding_shown from general_settings",
      up: `
		ALTER TABLE general_settings DROP COLUMN onboarding_shown;
	`,
      down: `
		ALTER TABLE general_settings ADD COLUMN onboarding_shown INTEGER NOT NULL DEFAULT 0;
	`
    };
    migration$6 = {
      version: 63,
      name: "Create database_announcements table",
      up: `
		CREATE TABLE database_announcements (
			id TEXT NOT NULL,                                    -- ULID, matches the working-copy filename
			database_id INTEGER NOT NULL,
			title TEXT NOT NULL,
			severity TEXT NOT NULL CHECK (severity IN ('info','warning','critical')),
			published_at DATETIME NOT NULL,
			expires_at DATETIME,
			link TEXT,
			body TEXT NOT NULL,                                  -- snapshotted from working copy at reconcile time
			withdrawn INTEGER NOT NULL DEFAULT 0 CHECK (withdrawn IN (0,1)),
			read_at DATETIME,                                    -- null = unread
			fetched_at DATETIME NOT NULL,                        -- last reconcile timestamp
			PRIMARY KEY (id, database_id),
			FOREIGN KEY (database_id) REFERENCES database_instances(id) ON DELETE CASCADE
		);

		CREATE INDEX idx_database_announcements_published_at
			ON database_announcements(published_at DESC);

		CREATE INDEX idx_database_announcements_visible
			ON database_announcements(database_id, withdrawn, expires_at);
	`,
      down: `
		DROP INDEX IF EXISTS idx_database_announcements_visible;
		DROP INDEX IF EXISTS idx_database_announcements_published_at;
		DROP TABLE IF EXISTS database_announcements;
	`
    };
    migration$5 = {
      version: 64,
      name: "Add fail-on-referenced-delete setting",
      up: `
		ALTER TABLE general_settings
		ADD COLUMN fail_on_referenced_delete INTEGER NOT NULL DEFAULT 1;
	`,
      down: `
		ALTER TABLE general_settings DROP COLUMN fail_on_referenced_delete;
	`
    };
    migration$4 = {
      version: 65,
      name: "Create Arr drift tables",
      up: `
		CREATE TABLE arr_drift_settings (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			arr_instance_id INTEGER NOT NULL UNIQUE,
			enabled INTEGER NOT NULL DEFAULT 0,
			cron TEXT NOT NULL DEFAULT '0 0 * * *',
			next_run_at TEXT,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		CREATE INDEX idx_arr_drift_settings_instance ON arr_drift_settings(arr_instance_id);

		CREATE TABLE arr_drift_status (
			id INTEGER PRIMARY KEY AUTOINCREMENT,
			arr_instance_id INTEGER NOT NULL UNIQUE,
			status TEXT NOT NULL DEFAULT 'never_checked' CHECK (
				status IN ('never_checked', 'clean', 'drift_detected', 'failed')
			),
			last_checked_at TEXT,
			counts_json TEXT NOT NULL DEFAULT '{}',
			diff_json TEXT NOT NULL DEFAULT '{}',
			diff_hash TEXT,
			last_notified_hash TEXT,
			last_notified_at TEXT,
			last_error TEXT,
			error_hash TEXT,
			last_notified_error_hash TEXT,
			created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
			FOREIGN KEY (arr_instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE
		);

		CREATE INDEX idx_arr_drift_status_instance ON arr_drift_status(arr_instance_id);
	`,
      down: `
		DROP INDEX IF EXISTS idx_arr_drift_status_instance;
		DROP TABLE IF EXISTS arr_drift_status;

		DROP INDEX IF EXISTS idx_arr_drift_settings_instance;
		DROP TABLE IF EXISTS arr_drift_settings;
	`
    };
    migration$3 = {
      version: 66,
      name: "Add date format setting",
      up: `
		ALTER TABLE general_settings
		ADD COLUMN date_format TEXT NOT NULL DEFAULT 'auto'
		CHECK (date_format IN ('auto', 'mdy', 'dmy', 'ymd'));
	`,
      down: `
		ALTER TABLE general_settings DROP COLUMN date_format;
	`
    };
    migration$2 = {
      version: 67,
      name: "Enable all Arr instances",
      up: `
		UPDATE arr_instances
		SET enabled = 1,
			updated_at = CURRENT_TIMESTAMP
		WHERE enabled = 0;
	`,
      down: `
		-- Previous disabled state cannot be reconstructed.
		SELECT 1;
	`
    };
    migration$1 = {
      version: 69,
      name: "Create arr sync database priority",
      up: `
		CREATE TABLE arr_sync_database_priority (
			instance_id INTEGER NOT NULL,
			database_id INTEGER NOT NULL,
			priority INTEGER NOT NULL,
			PRIMARY KEY (instance_id, database_id),
			FOREIGN KEY (instance_id) REFERENCES arr_instances(id) ON DELETE CASCADE,
			FOREIGN KEY (database_id) REFERENCES database_instances(id) ON DELETE CASCADE
		);

		INSERT INTO arr_sync_database_priority (instance_id, database_id, priority)
		SELECT ai.id, di.id, ROW_NUMBER() OVER (PARTITION BY ai.id ORDER BY di.id)
		FROM arr_instances ai
		CROSS JOIN database_instances di;
	`,
      down: `
		DROP TABLE IF EXISTS arr_sync_database_priority;
	`
    };
    migration = {
      version: 70,
      name: "Add sync prompt setting",
      up: `
		ALTER TABLE general_settings
		ADD COLUMN sync_prompt_enabled INTEGER NOT NULL DEFAULT 1;
	`,
      down: `
		ALTER TABLE general_settings DROP COLUMN sync_prompt_enabled;
	`
    };
    MigrationRunner = class {
      migrationsTable = "migrations";
      /**
      * Initialize the migrations table
      */
      initialize() {
        const sql2 = `
			CREATE TABLE IF NOT EXISTS ${this.migrationsTable} (
				version INTEGER PRIMARY KEY,
				name TEXT NOT NULL,
				applied_at DATETIME DEFAULT CURRENT_TIMESTAMP
			)
		`;
        db.exec(sql2);
      }
      /**
      * Get the current migration version
      */
      getCurrentVersion() {
        return db.queryFirst(`SELECT MAX(version) as version FROM ${this.migrationsTable}`)?.version ?? 0;
      }
      /**
      * Check if a migration has been applied
      */
      isApplied(version) {
        return (db.queryFirst(`SELECT COUNT(*) as count FROM ${this.migrationsTable} WHERE version = ?`, version)?.count ?? 0) > 0;
      }
      /**
      * Apply a single migration
      */
      async applyMigration(migration2) {
        try {
          await db.transaction(async () => {
            db.exec(migration2.up);
            db.execute(`INSERT INTO ${this.migrationsTable} (version, name) VALUES (?, ?)`, migration2.version, migration2.name);
          });
          if (migration2.afterUp) migration2.afterUp();
        } catch (error2) {
          await logger.error(`Failed to apply migration ${migration2.version}: ${migration2.name}`, {
            source: "DatabaseMigrations",
            meta: error2
          });
          throw error2;
        }
      }
      /**
      * Rollback a single migration
      */
      async rollbackMigration(migration2) {
        if (!migration2.down) throw new Error(`Migration ${migration2.version} does not support rollback`);
        try {
          await db.transaction(async () => {
            db.exec(migration2.down);
            db.execute(`DELETE FROM ${this.migrationsTable} WHERE version = ?`, migration2.version);
          });
        } catch (error2) {
          await logger.error(`Failed to rollback migration ${migration2.version}: ${migration2.name}`, {
            source: "DatabaseMigrations",
            meta: error2
          });
          throw error2;
        }
      }
      /**
      * Run all pending migrations
      */
      async up(migrations) {
        this.initialize();
        const sortedMigrations = [...migrations].sort((a2, b3) => a2.version - b3.version);
        const applied = [];
        for (const migration2 of sortedMigrations) {
          if (this.isApplied(migration2.version)) continue;
          await this.applyMigration(migration2);
          applied.push({
            version: migration2.version,
            name: migration2.name
          });
        }
        if (applied.length === 0) await logger.debug("Database up to date", { source: "DatabaseMigrations" });
        else await logger.info(`Applied ${applied.length} migration(s)`, {
          source: "DatabaseMigrations",
          meta: { migrations: applied }
        });
      }
      /**
      * Rollback to a specific version
      */
      async down(migrations, targetVersion = 0) {
        this.initialize();
        const currentVersion = this.getCurrentVersion();
        if (currentVersion <= targetVersion) {
          await logger.debug("Already at target version or below", { source: "DatabaseMigrations" });
          return;
        }
        const sortedMigrations = [...migrations].filter((m3) => m3.version > targetVersion && m3.version <= currentVersion).sort((a2, b3) => b3.version - a2.version);
        const rolledBack = [];
        for (const migration2 of sortedMigrations) {
          if (!this.isApplied(migration2.version)) continue;
          await this.rollbackMigration(migration2);
          rolledBack.push({
            version: migration2.version,
            name: migration2.name
          });
        }
        if (rolledBack.length > 0) await logger.info(`Rolled back ${rolledBack.length} migration(s)`, {
          source: "DatabaseMigrations",
          meta: { migrations: rolledBack }
        });
      }
      /**
      * Get list of applied migrations
      */
      getAppliedMigrations() {
        return db.query(`SELECT version, name, applied_at FROM ${this.migrationsTable} ORDER BY version`);
      }
      /**
      * Get list of pending migrations
      */
      getPendingMigrations(migrations) {
        const pending = [];
        for (const migration2 of migrations) if (!this.isApplied(migration2.version)) pending.push(migration2);
        return pending.sort((a2, b3) => a2.version - b3.version);
      }
      /**
      * Reset the database (rollback all migrations)
      */
      async reset(migrations) {
        await this.down(migrations, 0);
      }
      /**
      * Fresh migration (reset and reapply all)
      */
      async fresh(migrations) {
        await logger.warn("Resetting database", { source: "DatabaseMigrations" });
        await this.reset(migrations);
        await this.up(migrations);
      }
    };
    migrationRunner = new MigrationRunner();
  }
});

// dist/build/server/chunks/queueService.js
function rowToLog$1(row) {
  return {
    id: row.id,
    configId: 0,
    instanceId: row.instance_id,
    instanceName: "",
    startedAt: toUTC(row.started_at),
    completedAt: toUTC(row.completed_at),
    status: row.status,
    config: {
      cron: row.cron,
      filterMode: row.filter_mode,
      selectedFilter: row.filter_name,
      dryRun: row.dry_run === 1
    },
    library: {
      totalItems: row.library_total,
      fetchedFromCache: row.library_cached === 1,
      fetchDurationMs: row.library_fetch_ms
    },
    filter: {
      id: row.filter_id,
      name: row.filter_name,
      rules: {
        type: "group",
        match: "all",
        children: []
      },
      matchedCount: row.matched_count,
      afterCooldown: row.after_cooldown,
      dryRunExcluded: row.dry_run_excluded
    },
    selection: {
      method: row.selection_method,
      requestedCount: row.selection_requested,
      actualCount: row.selected_count,
      items: JSON.parse(row.items)
    },
    results: {
      searchesTriggered: row.searches_triggered,
      successful: row.successful,
      failed: row.failed,
      errors: JSON.parse(row.errors)
    }
  };
}
async function logUpgradeRun(log) {
  const durationSec = ((new Date(log.completedAt).getTime() - new Date(log.startedAt).getTime()) / 1e3).toFixed(1);
  const summary = `Upgrade ${log.status === "success" ? "completed" : log.status}: ${log.instanceName} "${log.filter.name}" - ${log.selection.actualCount}/${log.selection.requestedCount} items searched (${durationSec}s)`;
  const funnel = {
    library: log.library.totalItems,
    filtered: log.filter.matchedCount,
    afterCooldown: log.filter.afterCooldown
  };
  if (log.filter.dryRunExcluded > 0) {
    funnel.dryRunExcluded = log.filter.dryRunExcluded;
    funnel.available = log.filter.afterCooldown - log.filter.dryRunExcluded;
  }
  funnel.selected = log.selection.actualCount;
  const formattedItems = log.selection.items.map((item) => {
    const original = item.original.type === "movie" ? {
      fileName: item.original.fileName,
      formats: item.original.formats,
      score: item.original.score
    } : {
      title: item.original.title,
      episodes: item.original.episodes
    };
    return {
      title: item.title,
      original,
      upgrades: item.upgrades.map((u) => ({
        release: u.release,
        formats: u.formats,
        score: u.score
      }))
    };
  });
  const logOptions = {
    source: SOURCE$4,
    meta: {
      dryRun: log.config.dryRun,
      filter: log.filter.name,
      filterId: log.filter.id,
      selector: log.selection.method,
      funnel,
      items: formattedItems
    }
  };
  if (log.status === "success") await logger.info(summary, logOptions);
  else if (log.status === "partial") await logger.warn(summary, logOptions);
  else await logger.error(summary, logOptions);
  try {
    upgradeRunsQueries.insert(log);
  } catch (err) {
    await logger.error(`Failed to save upgrade run to database: ${err}`, {
      source: SOURCE$4,
      meta: {
        runId: log.id,
        error: err
      }
    });
  }
}
async function logUpgradeSkipped(instanceId, instanceName, reason) {
  await logger.debug(`Skipped ${instanceName}: ${reason}`, {
    source: SOURCE$4,
    meta: {
      instanceId,
      reason
    }
  });
}
async function logUpgradeError(instanceId, instanceName, error2) {
  await logger.error(`Upgrade failed for ${instanceName}: ${error2}`, {
    source: SOURCE$4,
    meta: {
      instanceId,
      error: error2
    }
  });
}
async function logUpgradeQueueDetectionMismatch(details) {
  await logger.warn(`Upgrade detection under-reported ${details.app} grabs: command reported ${details.reportedDownloads}, queue observation saw ${details.observedDownloads}`, {
    source: SOURCE$4,
    meta: details
  });
}
async function logUpgradeCommandCompleted(details) {
  await logger.debug(`Upgrade command ${details.commandId} completed`, {
    source: SOURCE$4,
    meta: details
  });
}
async function logDryRunCacheCleared(instanceId, instanceName, clearedItemIds) {
  const count = clearedItemIds.length;
  const message2 = count > 0 ? `Dry run cache cleared for ${instanceName}: ${count} item${count === 1 ? "" : "s"} removed` : `Dry run cache cleared for ${instanceName}: cache was empty`;
  await logger.info(message2, {
    source: SOURCE$4,
    meta: {
      instanceId,
      instanceName,
      clearedCount: count,
      clearedItemIds
    }
  });
}
function parseDownloadedReportCount(message2) {
  if (!message2) return null;
  const match = message2.match(/\b(\d+)\s+reports?\s+downloaded\b/i);
  if (!match) return null;
  return Number.parseInt(match[1], 10);
}
function getPosterUrl(raw) {
  return raw.images?.find((img) => img.coverType === "poster")?.remoteUrl || void 0;
}
function getDryRunExclusions(instanceId) {
  const entry = dryRunExclusions.get(instanceId);
  if (!entry) return /* @__PURE__ */ new Set();
  if (Date.now() - entry.timestamp > DRY_RUN_EXCLUSION_TTL_MS) {
    dryRunExclusions.delete(instanceId);
    return /* @__PURE__ */ new Set();
  }
  return entry.items;
}
function addDryRunExclusions(instanceId, itemIds) {
  const existing = getDryRunExclusions(instanceId);
  for (const id of itemIds) existing.add(id);
  dryRunExclusions.set(instanceId, {
    items: existing,
    timestamp: Date.now()
  });
}
function clearDryRunExclusions(instanceId) {
  const entry = dryRunExclusions.get(instanceId);
  const clearedIds = entry ? Array.from(entry.items) : [];
  dryRunExclusions.delete(instanceId);
  return clearedIds;
}
function sleep(ms) {
  return new Promise((resolve6) => setTimeout(resolve6, ms));
}
function isCommandComplete(command) {
  return command.status === "completed";
}
function isCommandFailed(command) {
  return command.status === "failed";
}
async function monitorQueueDuringCommand(options2) {
  const startTime = Date.now();
  let command = null;
  let completedAt = null;
  let reportedDownloads = null;
  let completionLogged = false;
  let mismatchLogged = false;
  while (true) {
    if (Date.now() - startTime >= UPGRADE_COMMAND_TIMEOUT_MS) throw new Error(`Command ${options2.commandId} timed out after 60 minutes`);
    command = await options2.getCommand(options2.commandId);
    if (isCommandFailed(command)) throw new Error(`Command ${options2.commandId} failed: ${command.message || "Unknown error"}`);
    const queue = await options2.getQueue();
    for (const item of queue) options2.mergeQueueItem(item);
    if (isCommandComplete(command)) {
      if (completedAt === null) completedAt = Date.now();
      if (reportedDownloads === null) reportedDownloads = parseDownloadedReportCount(command.message);
      if (!completionLogged) {
        await options2.onCommandComplete({
          command,
          elapsedMs: Date.now() - startTime,
          reportedDownloads,
          observedDownloads: options2.getObservedCount()
        });
        completionLogged = true;
      }
      if (reportedDownloads === 0) return command;
      if (reportedDownloads === null) return command;
      if (options2.getObservedCount() >= reportedDownloads) return command;
      const graceElapsedMs = Date.now() - completedAt;
      if (graceElapsedMs >= UPGRADE_QUEUE_GRACE_MS) {
        if (options2.getObservedCount() < reportedDownloads && !mismatchLogged) {
          await options2.onMismatch({
            command,
            reportedDownloads,
            observedDownloads: options2.getObservedCount(),
            graceElapsedMs
          });
          mismatchLogged = true;
        }
        return command;
      }
    }
    await sleep(UPGRADE_QUEUE_POLL_INTERVAL_MS);
  }
}
function mergeSonarrQueueItem(queueMap, queueItem) {
  const existing = queueMap.get(queueItem.seriesId) ?? [];
  if (!existing.some((item) => queueItem.downloadId ? item.downloadId === queueItem.downloadId : item.title === queueItem.title)) existing.push(queueItem);
  queueMap.set(queueItem.seriesId, existing);
}
async function sendUpgradeNotification(log, manual) {
  if (log.selection.actualCount > 0) await notificationManager.notify(notifications.upgrade({
    log,
    manual
  }));
}
function getNextFilter(config2) {
  const enabledFilters = config2.filters.filter((f2) => f2.enabled);
  if (enabledFilters.length === 0) return null;
  if (config2.filterMode === "random") return enabledFilters[Math.floor(Math.random() * enabledFilters.length)];
  return enabledFilters[config2.currentFilterIndex % enabledFilters.length];
}
function createSkippedLog(config2, instance, reason, dryRun = false) {
  const now = (/* @__PURE__ */ new Date()).toISOString();
  return {
    id: crypto.randomUUID(),
    configId: config2.id ?? 0,
    instanceId: instance.id,
    instanceName: instance.name,
    startedAt: now,
    completedAt: now,
    status: "skipped",
    config: {
      cron: config2.cron,
      filterMode: config2.filterMode,
      selectedFilter: "",
      dryRun
    },
    library: {
      totalItems: 0,
      fetchedFromCache: false,
      fetchDurationMs: 0
    },
    filter: {
      id: "",
      name: "",
      rules: {
        type: "group",
        match: "all",
        children: []
      },
      matchedCount: 0,
      afterCooldown: 0,
      dryRunExcluded: 0
    },
    selection: {
      method: "",
      requestedCount: 0,
      actualCount: 0,
      items: []
    },
    results: {
      searchesTriggered: 0,
      successful: 0,
      failed: 0,
      errors: [reason]
    }
  };
}
function pickSeasonForSearch(series) {
  return series.seasons.filter((s3) => s3.monitored && (s3.statistics?.episodeFileCount ?? 0) > 0).sort((a2, b3) => b3.seasonNumber - a2.seasonNumber)[0]?.seasonNumber;
}
async function processUpgradeConfig(config2, instance, manual = false, dryRun = false) {
  const startedAt = /* @__PURE__ */ new Date();
  const logId = crypto.randomUUID();
  const filter = getNextFilter(config2);
  if (!filter) {
    const log = createSkippedLog(config2, instance, "No enabled filters", dryRun);
    await logUpgradeSkipped(instance.id, instance.name, "No enabled filters");
    return log;
  }
  const isRadarr = instance.type === "radarr";
  const clientOpts = { timeout: 12e4 };
  const client2 = isRadarr ? new RadarrClient(instance.url, instance.api_key, clientOpts) : new SonarrClient(instance.url, instance.api_key, clientOpts);
  try {
    const fetchStart = Date.now();
    let normalizedItems2;
    let totalItems;
    let tags;
    let getOriginalFile;
    let movieFileMap;
    let sonarrEpisodeFiles = /* @__PURE__ */ new Map();
    if (isRadarr) {
      const radarr = client2;
      const [movies, profiles] = await Promise.all([radarr.getMovies(), radarr.getQualityProfiles()]);
      const movieIdsWithFiles = movies.filter((m3) => m3.hasFile).map((m3) => m3.id);
      const movieFiles = await radarr.getMovieFiles(movieIdsWithFiles);
      movieFileMap = new Map(movieFiles.map((mf) => [mf.movieId, mf]));
      const profileMap = new Map(profiles.map((p2) => [p2.id, p2]));
      tags = await radarr.getTags();
      const tagMap = new Map(tags.map((t2) => [t2.id, t2.label]));
      normalizedItems2 = normalizeRadarrItems(movies, movieFileMap, profileMap, filter.cutoff, tagMap);
      totalItems = movies.length;
      const mfMap = movieFileMap;
      getOriginalFile = (item) => {
        const movieFile = mfMap.get(item.id);
        return {
          type: "movie",
          fileName: movieFile?.relativePath?.split("/").pop() ?? "Unknown",
          formats: movieFile?.customFormats.map((cf) => cf.name) ?? [],
          score: item.score
        };
      };
    } else {
      const sonarr = client2;
      const [allSeries, profiles] = await Promise.all([sonarr.getAllSeries(), sonarr.getQualityProfiles()]);
      const profileMap = new Map(profiles.map((p2) => [p2.id, p2]));
      tags = await sonarr.getTags();
      const tagMap = new Map(tags.map((t2) => [t2.id, t2.label]));
      if (filterNeedsSonarrScores(filter)) sonarrEpisodeFiles = await loadSonarrEpisodeFiles(sonarr, allSeries);
      normalizedItems2 = normalizeSonarrItems(allSeries, profileMap, filter.cutoff, sonarrEpisodeFiles, tagMap);
      totalItems = allSeries.length;
      getOriginalFile = (item) => ({
        type: "series",
        title: item.title,
        episodes: (sonarrEpisodeFiles.get(item.id) ?? []).map((file) => ({
          seasonNumber: file.seasonNumber,
          fileName: file.relativePath?.split("/").pop() ?? "Unknown",
          formats: file.customFormats?.map((format) => format.name) ?? [],
          score: file.customFormatScore ?? 0
        }))
      });
    }
    const fetchDurationMs = Date.now() - fetchStart;
    const matchedItems = normalizedItems2.filter((item) => evaluateGroup(item, filter.group));
    const tagLabel = resolveTagLabel(filter);
    if (isFilterExhausted(matchedItems, tags, tagLabel)) {
      if ((await resetFilterCooldown(client2, tagLabel)).reset > 0) {
        const updatedTags = await client2.getTags();
        tags.length = 0;
        tags.push(...updatedTags);
        const filterTagId = updatedTags.find((t2) => t2.label.toLowerCase() === tagLabel.toLowerCase())?.id;
        if (filterTagId !== void 0) for (const item of matchedItems) item._tags = item._tags.filter((id) => id !== filterTagId);
      }
    }
    const afterCooldownItems = filterByFilterTag(matchedItems, tags, tagLabel);
    const afterCooldownCount = afterCooldownItems.length;
    let availableItems = afterCooldownItems;
    let dryRunExcludedCount = 0;
    if (dryRun) {
      const excluded = getDryRunExclusions(instance.id);
      if (excluded.size > 0) {
        availableItems = afterCooldownItems.filter((item) => !excluded.has(item.id));
        dryRunExcludedCount = afterCooldownCount - availableItems.length;
      }
    }
    const selector = getSelector(filter.selector);
    const selectedItems = selector ? selector.select(availableItems, filter.count) : availableItems.slice(0, filter.count);
    if (!isRadarr && selectedItems.length > 0) sonarrEpisodeFiles = await loadSonarrEpisodeFiles(client2, selectedItems.map((item) => item._raw), sonarrEpisodeFiles);
    let searchesTriggered = 0;
    let successful = 0;
    let failed = 0;
    const errors = [];
    const isDryRun = dryRun;
    const selectionItems = [];
    if (selectedItems.length > 0) if (isDryRun) {
      addDryRunExclusions(instance.id, selectedItems.map((item) => item.id));
      for (const item of selectedItems) {
        const original = getOriginalFile(item);
        let searchedSeason;
        let currentComparisonScore = item.score;
        try {
          let bestRelease;
          if (isRadarr) bestRelease = (await client2.getReleases(item.id)).find((r2) => r2.approved && !r2.rejected);
          else {
            const series = item._raw;
            searchedSeason = pickSeasonForSearch(series);
            if (searchedSeason == null) {
              selectionItems.push({
                id: item.id,
                title: item.title,
                original,
                upgrades: [],
                imageUrl: getPosterUrl(item._raw)
              });
              continue;
            }
            currentComparisonScore = averageEpisodeFileScore(sonarrEpisodeFiles.get(item.id) ?? [], searchedSeason);
            bestRelease = (await client2.getReleases(item.id, searchedSeason)).find((r2) => r2.approved && !r2.rejected);
          }
          if (bestRelease && bestRelease.customFormatScore > currentComparisonScore) {
            selectionItems.push({
              id: item.id,
              title: item.title,
              original,
              upgrades: [{
                release: bestRelease.title,
                formats: bestRelease.customFormats.map((cf) => cf.name),
                score: bestRelease.customFormatScore,
                ...searchedSeason != null ? { seasonNumber: searchedSeason } : {}
              }],
              imageUrl: getPosterUrl(item._raw),
              ...searchedSeason != null ? { searchedSeasonNumber: searchedSeason } : {}
            });
            successful++;
          } else selectionItems.push({
            id: item.id,
            title: item.title,
            original,
            upgrades: [],
            imageUrl: getPosterUrl(item._raw),
            ...searchedSeason != null ? { searchedSeasonNumber: searchedSeason } : {}
          });
          searchesTriggered++;
        } catch (error2) {
          selectionItems.push({
            id: item.id,
            title: item.title,
            original,
            upgrades: [],
            imageUrl: getPosterUrl(item._raw),
            ...searchedSeason != null ? { searchedSeasonNumber: searchedSeason } : {}
          });
          failed++;
          errors.push(`Failed to get releases for ${item.title}: ${error2 instanceof Error ? error2.message : String(error2)}`);
        }
      }
    } else try {
      const itemIds = selectedItems.map((item) => item.id);
      if (isRadarr) {
        const radarr = client2;
        const searchCommand = await radarr.searchMovies(itemIds);
        searchesTriggered = itemIds.length;
        const queueMap = /* @__PURE__ */ new Map();
        await monitorQueueDuringCommand({
          commandId: searchCommand.id,
          getCommand: (commandId) => radarr.getCommand(commandId),
          getQueue: () => radarr.getQueue(itemIds),
          mergeQueueItem: (item) => {
            queueMap.set(item.movieId, item);
          },
          getObservedCount: () => queueMap.size,
          onCommandComplete: (details) => logUpgradeCommandCompleted({
            commandId: searchCommand.id,
            status: details.command.status,
            elapsedMs: details.elapsedMs,
            commandMessage: details.command.message,
            reportedDownloads: details.reportedDownloads,
            observedDownloads: details.observedDownloads
          }),
          onMismatch: (details) => {
            const searched = selectedItems.map((item) => ({
              id: item.id,
              title: item.title
            }));
            const observedIds = new Set(queueMap.keys());
            const observed = [...queueMap.values()].map((item) => ({
              id: item.movieId,
              title: item.title
            }));
            const missed = searched.filter((item) => !observedIds.has(item.id));
            return logUpgradeQueueDetectionMismatch({
              instanceId: instance.id,
              instanceName: instance.name,
              app: "Radarr",
              filterName: filter.name,
              commandId: searchCommand.id,
              reportedDownloads: details.reportedDownloads,
              observedDownloads: details.observedDownloads,
              graceElapsedMs: details.graceElapsedMs,
              commandMessage: details.command.message,
              searchedItems: searched,
              observedItems: observed,
              missedItems: missed
            });
          }
        });
        for (const item of selectedItems) {
          const original = getOriginalFile(item);
          const grabbed = queueMap.get(item.id);
          if (grabbed) {
            selectionItems.push({
              id: item.id,
              title: item.title,
              original,
              upgrades: [{
                release: grabbed.title,
                formats: grabbed.customFormats.map((cf) => cf.name),
                score: grabbed.customFormatScore
              }],
              imageUrl: getPosterUrl(item._raw)
            });
            successful++;
          } else selectionItems.push({
            id: item.id,
            title: item.title,
            original,
            upgrades: [],
            imageUrl: getPosterUrl(item._raw)
          });
        }
        const filterTag = await radarr.getOrCreateTag(tagLabel);
        const tagResult = await applyFilterTagToMovies(radarr, selectedItems.map((item) => item._raw), filterTag.id);
        failed = tagResult.failed;
        errors.push(...tagResult.errors);
      } else {
        const sonarr = client2;
        const queueMap = /* @__PURE__ */ new Map();
        for (const item of selectedItems) {
          const cmd = await sonarr.searchSeries(item.id);
          await monitorQueueDuringCommand({
            commandId: cmd.id,
            getCommand: (commandId) => sonarr.getCommand(commandId),
            getQueue: () => sonarr.getQueue([item.id]),
            mergeQueueItem: (queueItem) => {
              mergeSonarrQueueItem(queueMap, queueItem);
            },
            getObservedCount: () => queueMap.get(item.id)?.length ?? 0,
            onCommandComplete: (details) => logUpgradeCommandCompleted({
              commandId: cmd.id,
              status: details.command.status,
              elapsedMs: details.elapsedMs,
              commandMessage: details.command.message,
              reportedDownloads: details.reportedDownloads,
              observedDownloads: details.observedDownloads
            }),
            onMismatch: (details) => {
              const searched = [{
                id: item.id,
                title: item.title
              }];
              const observed = (queueMap.get(item.id) ?? []).map((q2) => ({
                id: q2.seriesId,
                title: q2.title
              }));
              return logUpgradeQueueDetectionMismatch({
                instanceId: instance.id,
                instanceName: instance.name,
                app: "Sonarr",
                filterName: filter.name,
                commandId: cmd.id,
                reportedDownloads: details.reportedDownloads,
                observedDownloads: details.observedDownloads,
                graceElapsedMs: details.graceElapsedMs,
                commandMessage: details.command.message,
                searchedItems: searched,
                observedItems: observed,
                missedItems: searched
              });
            }
          });
          searchesTriggered++;
        }
        for (const item of selectedItems) {
          const original = getOriginalFile(item);
          const grabbed = queueMap.get(item.id) ?? [];
          if (grabbed.length > 0) {
            selectionItems.push({
              id: item.id,
              title: item.title,
              original,
              upgrades: grabbed.map((g3) => ({
                release: g3.title,
                formats: g3.customFormats.map((cf) => cf.name),
                score: g3.customFormatScore,
                seasonNumber: g3.seasonNumber
              })),
              imageUrl: getPosterUrl(item._raw)
            });
            successful++;
          } else selectionItems.push({
            id: item.id,
            title: item.title,
            original,
            upgrades: [],
            imageUrl: getPosterUrl(item._raw)
          });
        }
        const filterTag = await sonarr.getOrCreateTag(tagLabel);
        const tagResult = await applyFilterTagToSeries(sonarr, selectedItems.map((item) => item._raw), filterTag.id);
        failed = tagResult.failed;
        errors.push(...tagResult.errors);
      }
    } catch (error2) {
      failed = selectedItems.length;
      errors.push(`Search failed: ${error2 instanceof Error ? error2.message : String(error2)}`);
      for (const item of selectedItems) selectionItems.push({
        id: item.id,
        title: item.title,
        original: getOriginalFile(item),
        upgrades: [],
        imageUrl: getPosterUrl(item._raw)
      });
    }
    const completedAt = /* @__PURE__ */ new Date();
    const log = {
      id: logId,
      configId: config2.id ?? 0,
      instanceId: instance.id,
      instanceName: instance.name,
      startedAt: startedAt.toISOString(),
      completedAt: completedAt.toISOString(),
      status: failed > 0 && successful === 0 ? "failed" : failed > 0 ? "partial" : "success",
      config: {
        cron: config2.cron,
        filterMode: config2.filterMode,
        selectedFilter: filter.name,
        dryRun
      },
      library: {
        totalItems,
        fetchedFromCache: false,
        fetchDurationMs
      },
      filter: {
        id: filter.id,
        name: filter.name,
        rules: filter.group,
        matchedCount: matchedItems.length,
        afterCooldown: afterCooldownCount,
        dryRunExcluded: dryRunExcludedCount
      },
      selection: {
        method: filter.selector,
        requestedCount: filter.count,
        actualCount: selectedItems.length,
        items: selectionItems
      },
      results: {
        searchesTriggered,
        successful,
        failed,
        errors
      }
    };
    await logUpgradeRun(log);
    await sendUpgradeNotification(log, manual);
    return log;
  } catch (error2) {
    const errorMessage = error2 instanceof Error ? error2.message : String(error2);
    await logUpgradeError(instance.id, instance.name, errorMessage);
    const log = createSkippedLog(config2, instance, errorMessage, dryRun);
    log.id = logId;
    log.startedAt = startedAt.toISOString();
    log.completedAt = (/* @__PURE__ */ new Date()).toISOString();
    log.status = "failed";
    log.config.selectedFilter = filter?.name ?? "";
    log.filter.id = filter?.id ?? "";
    log.filter.name = filter?.name ?? "";
    return log;
  } finally {
    client2.close();
  }
}
function validateCronExpression(cronExpr, minIntervalMinutes = 0) {
  try {
    new E(cronExpr);
  } catch {
    return "Invalid cron expression";
  }
  if (minIntervalMinutes <= 0) return null;
  const everyMatch = cronExpr.trim().match(/^\*\/(\d+)\s+\*\s+\*\s+\*\s+\*$/);
  if (everyMatch) {
    if (parseInt(everyMatch[1], 10) < minIntervalMinutes) return `Schedule too frequent. Minimum interval is ${minIntervalMinutes} minutes.`;
    return null;
  }
  const cron = new E(cronExpr);
  const now = /* @__PURE__ */ new Date();
  const runs = [];
  let cursor = now;
  for (let i = 0; i < 3; i++) {
    const next2 = cron.nextRun(cursor);
    if (!next2) break;
    runs.push(next2);
    cursor = new Date(next2.getTime() + 1e3);
  }
  if (runs.length < 2) return null;
  for (let i = 1; i < runs.length; i++) if ((runs[i].getTime() - runs[i - 1].getTime()) / 6e4 < minIntervalMinutes) return `Schedule too frequent. Minimum interval is ${minIntervalMinutes} minutes.`;
  return null;
}
function calculateNextRun(cronExpr) {
  if (!cronExpr) return null;
  try {
    return new E(cronExpr).nextRun()?.toISOString() ?? null;
  } catch {
    return null;
  }
}
function calculateNextRunFromMinutes(lastRunAt, scheduleMinutes) {
  if (!lastRunAt) return (/* @__PURE__ */ new Date()).toISOString();
  const base2 = parseUTC(lastRunAt);
  if (!base2) return (/* @__PURE__ */ new Date()).toISOString();
  const next2 = new Date(base2);
  next2.setMinutes(next2.getMinutes() + scheduleMinutes);
  return next2.toISOString();
}
function calculateNextRunFromSchedule(schedule) {
  const now = /* @__PURE__ */ new Date();
  if (schedule === "daily") {
    const next2 = new Date(now);
    next2.setDate(next2.getDate() + 1);
    next2.setHours(0, 0, 0, 0);
    return next2.toISOString();
  }
  if (schedule === "hourly") {
    const next2 = new Date(now);
    next2.setHours(next2.getHours() + 1, 0, 0, 0);
    return next2.toISOString();
  }
  if (schedule === "weekly") {
    const next2 = new Date(now);
    next2.setDate(next2.getDate() + 7);
    next2.setHours(0, 0, 0, 0);
    return next2.toISOString();
  }
  if (schedule === "monthly") {
    const next2 = new Date(now);
    next2.setMonth(next2.getMonth() + 1, 1);
    next2.setHours(0, 0, 0, 0);
    return next2.toISOString();
  }
  try {
    const nextRun = new E(schedule).nextRun();
    if (nextRun) return nextRun.toISOString();
  } catch {
  }
  const fallback2 = new Date(now);
  fallback2.setHours(fallback2.getHours() + 1);
  return fallback2.toISOString();
}
function rowToLog(row) {
  return {
    id: row.id,
    instanceId: row.instance_id,
    instanceName: "",
    instanceType: "radarr",
    startedAt: toUTC(row.started_at),
    completedAt: toUTC(row.completed_at),
    status: row.status,
    config: {
      dryRun: row.dry_run === 1,
      renameFolders: row.rename_folders === 1,
      ignoreTag: row.ignore_tag,
      manual: row.manual === 1
    },
    library: {
      totalItems: row.library_total,
      fetchDurationMs: row.library_fetch_ms
    },
    filtering: {
      afterIgnoreTag: row.after_ignore_tag,
      skippedByTag: row.skipped_by_tag
    },
    results: {
      filesNeedingRename: row.files_needing_rename,
      filesRenamed: row.files_renamed,
      foldersRenamed: row.folders_renamed,
      commandsTriggered: row.commands_triggered,
      commandsCompleted: row.commands_completed,
      commandsFailed: row.commands_failed,
      errors: JSON.parse(row.errors)
    },
    renamedItems: JSON.parse(row.items)
  };
}
async function logRenameRun(log) {
  const duration = new Date(log.completedAt).getTime() - new Date(log.startedAt).getTime();
  const parts = ["rename"];
  if (log.config.dryRun) parts.unshift("dry run");
  if (log.config.manual) parts.unshift("manual");
  const summary = `Completed Job: ${parts.join(" ")} for "${log.instanceName}": ${log.results.filesRenamed} files, ${log.results.foldersRenamed} folders renamed across ${log.renamedItems.length} entities (${duration}ms)`;
  await logger.info(summary, {
    source: SOURCE$3,
    meta: {
      instanceId: log.instanceId,
      status: log.status,
      dryRun: log.config.dryRun,
      manual: log.config.manual,
      filesRenamed: log.results.filesRenamed,
      foldersRenamed: log.results.foldersRenamed,
      entitiesChanged: log.renamedItems.length,
      durationMs: duration
    }
  });
  try {
    renameRunsQueries.insert(log);
  } catch (err) {
    await logger.error(`Failed to save rename run to database: ${err}`, {
      source: SOURCE$3,
      meta: {
        runId: log.id,
        error: err
      }
    });
  }
}
async function logRenameError(instanceId, instanceName, error2) {
  await logger.error(`Rename failed for ${instanceName}: ${error2}`, {
    source: SOURCE$3,
    meta: {
      instanceId,
      error: error2
    }
  });
}
function parseRenamedCount(message2) {
  if (!message2) return 0;
  const match = message2.match(/^(\d+)/);
  return match ? parseInt(match[1], 10) : 0;
}
function groupByRootFolder(items) {
  const groups = /* @__PURE__ */ new Map();
  for (const item of items) {
    const existing = groups.get(item.rootFolderPath);
    if (existing) existing.push(item.id);
    else groups.set(item.rootFolderPath, [item.id]);
  }
  return groups;
}
function createLog(instance, settings2, manual, dryRun) {
  return {
    id: crypto.randomUUID(),
    instanceId: instance.id,
    instanceName: instance.name,
    instanceType: instance.type,
    startedAt: (/* @__PURE__ */ new Date()).toISOString(),
    completedAt: "",
    status: "success",
    config: {
      dryRun,
      renameFolders: settings2.renameFolders,
      ignoreTag: settings2.ignoreTag,
      manual
    },
    library: {
      totalItems: 0,
      fetchDurationMs: 0
    },
    filtering: {
      afterIgnoreTag: 0,
      skippedByTag: 0
    },
    results: {
      filesNeedingRename: 0,
      filesRenamed: 0,
      foldersRenamed: 0,
      commandsTriggered: 0,
      commandsCompleted: 0,
      commandsFailed: 0,
      errors: []
    },
    renamedItems: []
  };
}
async function processDryRun(adapter, items, log) {
  for (const item of items) try {
    const previews = await adapter.getRenamePreview(item.id);
    if (previews.length > 0) {
      log.results.filesNeedingRename += previews.length;
      log.renamedItems.push({
        id: item.id,
        title: item.title,
        files: previews.map((p2) => ({
          existingPath: p2.existingPath,
          newPath: p2.newPath
        })),
        imageUrl: item.imageUrl
      });
    }
  } catch (err) {
    log.results.errors.push(`Preview failed for "${item.title}": ${err instanceof Error ? err.message : String(err)}`);
  }
}
async function getItemsNeedingFileRename(adapter, items, log) {
  const CONCURRENCY = 10;
  const needsRename = [];
  for (let i = 0; i < items.length; i += CONCURRENCY) {
    const batch = items.slice(i, i + CONCURRENCY);
    const results = await Promise.all(batch.map(async (item) => {
      try {
        return {
          item,
          count: (await adapter.getRenamePreview(item.id)).length
        };
      } catch {
        return {
          item,
          count: 0
        };
      }
    }));
    for (const { item, count } of results) if (count > 0) {
      log.results.filesNeedingRename += count;
      needsRename.push(item);
    }
  }
  return needsRename;
}
async function processFileRename(adapter, items, log, batchSize = 50) {
  const ids = items.map((i) => i.id);
  for (let i = 0; i < ids.length; i += batchSize) {
    const batch = ids.slice(i, i + batchSize);
    try {
      const command = await adapter.renameFiles(batch);
      log.results.commandsTriggered++;
      const result = await adapter.waitForCommand(command.id);
      log.results.commandsCompleted++;
      log.results.filesRenamed += parseRenamedCount(result.message);
    } catch (err) {
      log.results.commandsFailed++;
      log.results.errors.push(`File rename failed (batch ${Math.floor(i / batchSize) + 1}): ${err instanceof Error ? err.message : String(err)}`);
      break;
    }
  }
}
function diffSnapshots(before, after) {
  const result = [];
  for (const [id, beforeEntity] of before) {
    const afterEntity = after.get(id);
    if (!afterEntity) continue;
    let folder;
    if (beforeEntity.folderPath !== afterEntity.folderPath) folder = {
      oldPath: beforeEntity.folderPath,
      newPath: afterEntity.folderPath
    };
    const changedFiles = [];
    const afterFileMap = new Map(afterEntity.files.map((f2) => [f2.id, f2]));
    for (const beforeFile of beforeEntity.files) {
      const afterFile = afterFileMap.get(beforeFile.id);
      if (!afterFile) continue;
      if (beforeFile.relativePath !== afterFile.relativePath) changedFiles.push({
        oldPath: beforeFile.relativePath,
        newPath: afterFile.relativePath
      });
    }
    if (folder || changedFiles.length > 0) result.push({
      id,
      title: beforeEntity.title,
      folder,
      files: changedFiles
    });
  }
  return result;
}
async function processFolderRename(adapter, items, log) {
  const groups = groupByRootFolder(items);
  for (const [rootFolderPath, groupIds] of groups) try {
    await adapter.renameFolders(groupIds, rootFolderPath);
    log.results.commandsTriggered++;
    log.results.commandsCompleted++;
  } catch (err) {
    log.results.commandsFailed++;
    log.results.errors.push(`Folder rename failed for root "${rootFolderPath}": ${err instanceof Error ? err.message : String(err)}`);
  }
}
async function waitForSpawnedCommand(client2, maxIdBefore, label) {
  for (let attempt = 0; attempt < 30; attempt++) {
    await new Promise((r2) => setTimeout(r2, 1e3));
    const commands = await client2.getCommands();
    const newCmd = commands.find((c2) => c2.id > maxIdBefore && (c2.status === "queued" || c2.status === "started"));
    if (newCmd) {
      await logger.debug(`Found spawned command ${newCmd.id} for ${label}, waiting...`, {
        source: SOURCE$2,
        meta: {
          commandId: newCmd.id,
          status: newCmd.status
        }
      });
      await client2.waitForCommand(newCmd.id);
      return;
    }
    const completed = commands.find((c2) => c2.id > maxIdBefore && c2.status === "completed");
    if (completed) {
      await logger.debug(`Spawned command ${completed.id} for ${label} already completed`, {
        source: SOURCE$2,
        meta: { commandId: completed.id }
      });
      return;
    }
  }
  await logger.warn(`No spawned command found for ${label} after 30s, proceeding`, { source: SOURCE$2 });
}
function createRadarrAdapter(client2) {
  return {
    async getLibraryItems() {
      return (await client2.getMovies()).map((m3) => ({
        id: m3.id,
        title: m3.title,
        tags: m3.tags ?? [],
        rootFolderPath: m3.rootFolderPath ?? "",
        imageUrl: m3.images?.find((img) => img.coverType === "poster")?.remoteUrl
      }));
    },
    getTags: () => client2.getTags(),
    getRenamePreview: (id) => client2.getRenamePreview(id),
    renameFiles: (ids) => client2.renameMovies(ids),
    async renameFolders(ids, rootFolderPath) {
      const BATCH_SIZE = 50;
      for (let i = 0; i < ids.length; i += BATCH_SIZE) {
        const batch = ids.slice(i, i + BATCH_SIZE);
        const beforeCmds = await client2.getCommands();
        const maxId = Math.max(0, ...beforeCmds.map((c2) => c2.id));
        await client2.renameMovieFolders(batch, rootFolderPath);
        await waitForSpawnedCommand(client2, maxId, `Radarr folder rename batch ${Math.floor(i / BATCH_SIZE) + 1}`);
      }
    },
    waitForCommand: (id) => client2.waitForCommand(id),
    async getSnapshot(entityIds) {
      const idSet = new Set(entityIds);
      const relevant = (await client2.getMovies()).filter((m3) => idSet.has(m3.id));
      const idsWithFiles = relevant.filter((m3) => m3.hasFile).map((m3) => m3.id);
      const movieFiles = idsWithFiles.length > 0 ? await client2.getMovieFiles(idsWithFiles) : [];
      const fileMap = new Map(movieFiles.map((mf) => [mf.movieId, mf]));
      const snapshot = /* @__PURE__ */ new Map();
      for (const movie of relevant) {
        const file = fileMap.get(movie.id);
        snapshot.set(movie.id, {
          id: movie.id,
          title: movie.title,
          folderPath: movie.path ?? "",
          files: file ? [{
            id: file.id,
            relativePath: file.relativePath ?? ""
          }] : []
        });
      }
      return snapshot;
    }
  };
}
function createSonarrAdapter(client2) {
  return {
    async getLibraryItems() {
      return (await client2.getAllSeries()).map((s3) => ({
        id: s3.id,
        title: s3.title,
        tags: s3.tags ?? [],
        rootFolderPath: s3.rootFolderPath ?? "",
        imageUrl: s3.images?.find((img) => img.coverType === "poster")?.remoteUrl
      }));
    },
    getTags: () => client2.getTags(),
    getRenamePreview: (id) => client2.getRenamePreview(id),
    renameFiles: (ids) => client2.renameSeries(ids),
    async renameFolders(ids, rootFolderPath) {
      const BATCH_SIZE = 10;
      for (let i = 0; i < ids.length; i += BATCH_SIZE) {
        const batch = ids.slice(i, i + BATCH_SIZE);
        const beforeCmds = await client2.getCommands();
        const maxId = Math.max(0, ...beforeCmds.map((c2) => c2.id));
        await client2.renameSeriesFolders(batch, rootFolderPath);
        await waitForSpawnedCommand(client2, maxId, `Sonarr folder rename batch ${Math.floor(i / BATCH_SIZE) + 1}`);
      }
    },
    waitForCommand: (id) => client2.waitForCommand(id),
    async getSnapshot(entityIds) {
      const idSet = new Set(entityIds);
      const relevant = (await client2.getAllSeries()).filter((s3) => idSet.has(s3.id));
      const snapshot = /* @__PURE__ */ new Map();
      const CONCURRENCY = 10;
      for (let i = 0; i < relevant.length; i += CONCURRENCY) {
        const batch = relevant.slice(i, i + CONCURRENCY);
        const results = await Promise.all(batch.map(async (s3) => ({
          series: s3,
          files: await client2.getEpisodeFiles(s3.id)
        })));
        for (const { series, files } of results) snapshot.set(series.id, {
          id: series.id,
          title: series.title,
          folderPath: series.path ?? "",
          files: files.map((f2) => ({
            id: f2.id,
            relativePath: f2.relativePath ?? ""
          }))
        });
      }
      return snapshot;
    }
  };
}
async function sendRenameNotification(log, summaryNotifications) {
  await notificationManager.notify(notifications.rename({
    log,
    summaryNotifications
  }));
}
async function processRenameConfig(settings2, instance, manual = false, dryRun = false) {
  const log = createLog(instance, settings2, manual, dryRun);
  try {
    const client2 = createArrClient(instance.type, instance.url, instance.api_key);
    let adapter;
    if (instance.type === "radarr") adapter = createRadarrAdapter(client2);
    else adapter = createSonarrAdapter(client2);
    const fetchStart = Date.now();
    const [items, tags] = await Promise.all([adapter.getLibraryItems(), adapter.getTags()]);
    log.library.fetchDurationMs = Date.now() - fetchStart;
    log.library.totalItems = items.length;
    await logger.debug(`Fetched library: ${items.length} items in ${log.library.fetchDurationMs}ms`, {
      source: SOURCE$2,
      meta: {
        instanceId: instance.id,
        totalItems: items.length,
        fetchDurationMs: log.library.fetchDurationMs
      }
    });
    let filteredItems = items;
    if (settings2.ignoreTag) {
      const tag2 = tags.find((t2) => t2.label.toLowerCase() === settings2.ignoreTag.toLowerCase());
      if (tag2) {
        filteredItems = items.filter((item) => !item.tags.includes(tag2.id));
        log.filtering.skippedByTag = items.length - filteredItems.length;
      }
      await logger.debug(`Filtered by tag "${settings2.ignoreTag}": ${filteredItems.length} remaining, ${log.filtering.skippedByTag} skipped`, {
        source: SOURCE$2,
        meta: {
          instanceId: instance.id,
          ignoreTag: settings2.ignoreTag,
          remaining: filteredItems.length,
          skipped: log.filtering.skippedByTag
        }
      });
    }
    log.filtering.afterIgnoreTag = filteredItems.length;
    if (filteredItems.length === 0) {
      log.status = "skipped";
      log.completedAt = (/* @__PURE__ */ new Date()).toISOString();
      await logRenameRun(log);
      return log;
    }
    if (dryRun) {
      await logger.debug(`Checking rename previews for ${filteredItems.length} items`, {
        source: SOURCE$2,
        meta: {
          instanceId: instance.id,
          itemCount: filteredItems.length
        }
      });
      await processDryRun(adapter, filteredItems, log);
      await logger.debug(`Dry run complete: ${log.results.filesNeedingRename} files need renaming across ${log.renamedItems.length} items`, {
        source: SOURCE$2,
        meta: {
          instanceId: instance.id,
          filesNeedingRename: log.results.filesNeedingRename,
          itemsWithRenames: log.renamedItems.length
        }
      });
    } else {
      const filteredIds = filteredItems.map((i) => i.id);
      const batchSize = instance.type === "sonarr" ? 10 : 50;
      const itemsNeedingRename = await getItemsNeedingFileRename(adapter, filteredItems, log);
      await logger.debug(`Preview filter: ${itemsNeedingRename.length}/${filteredItems.length} items need file renames`, {
        source: SOURCE$2,
        meta: {
          instanceId: instance.id,
          needingRename: itemsNeedingRename.length,
          total: filteredItems.length
        }
      });
      const beforeSnapshot = await adapter.getSnapshot(filteredIds);
      if (itemsNeedingRename.length > 0) await processFileRename(adapter, itemsNeedingRename, log, batchSize);
      if (settings2.renameFolders) await processFolderRename(adapter, filteredItems, log);
      const diff = diffSnapshots(beforeSnapshot, await adapter.getSnapshot(filteredIds));
      const imageUrlMap = new Map(filteredItems.map((i) => [i.id, i.imageUrl]));
      let totalFilesRenamed = 0;
      let totalFoldersRenamed = 0;
      for (const entity of diff) {
        totalFilesRenamed += entity.files.length;
        if (entity.folder) totalFoldersRenamed++;
        log.renamedItems.push({
          id: entity.id,
          title: entity.title,
          folder: entity.folder ? {
            existingPath: entity.folder.oldPath,
            newPath: entity.folder.newPath
          } : void 0,
          files: entity.files.map((f2) => ({
            existingPath: f2.oldPath,
            newPath: f2.newPath
          })),
          imageUrl: imageUrlMap.get(entity.id)
        });
      }
      log.results.filesRenamed = totalFilesRenamed;
      log.results.filesNeedingRename = totalFilesRenamed;
      log.results.foldersRenamed = totalFoldersRenamed;
      await logger.debug(`Diff: ${totalFilesRenamed} files, ${totalFoldersRenamed} folders across ${diff.length} entities`, {
        source: SOURCE$2,
        meta: {
          instanceId: instance.id,
          filesRenamed: totalFilesRenamed,
          foldersRenamed: totalFoldersRenamed,
          entitiesChanged: diff.length
        }
      });
    }
    if (log.results.errors.length > 0) {
      log.status = log.results.filesRenamed > 0 || log.results.foldersRenamed > 0 ? "partial" : "failed";
      for (const error2 of log.results.errors) await logger.warn(`Rename error: ${error2}`, {
        source: SOURCE$2,
        meta: {
          instanceId: instance.id,
          status: log.status
        }
      });
    }
    log.completedAt = (/* @__PURE__ */ new Date()).toISOString();
    await logRenameRun(log);
    if (!dryRun) try {
      await sendRenameNotification(log, settings2.summaryNotifications);
    } catch (err) {
      await logger.error("Failed to send rename notification", {
        source: SOURCE$2,
        meta: { error: err }
      });
    }
  } catch (err) {
    log.status = "failed";
    log.completedAt = (/* @__PURE__ */ new Date()).toISOString();
    log.results.errors.push(err instanceof Error ? err.message : String(err));
    await logRenameError(instance.id, instance.name, String(err));
    await logRenameRun(log);
  }
  return log;
}
async function recoverInterruptedSyncs() {
  const recovered = arrSyncQueries.recoverInterruptedSyncs();
  if (recovered > 0) await logger.info(`Recovered ${recovered} interrupted sync(s) from previous run`, {
    source: "SyncRecovery",
    meta: { recoveredCount: recovered }
  });
}
function bytesToGb(value2) {
  if (value2 == null) return 0;
  const factor = 10 ** SIZE_GB_DECIMALS;
  return Math.round((value2 / BYTES_PER_GB + Number.EPSILON) * factor) / factor;
}
function transformCondition(condition, arrType) {
  if (condition.arrType !== "all" && condition.arrType !== arrType) return null;
  if (condition.type === "quality_modifier" && arrType === "sonarr") return null;
  if (condition.type === "release_type" && arrType === "radarr") return null;
  const implementation = CONDITION_IMPLEMENTATIONS[condition.type];
  if (!implementation) return null;
  const spec = {
    name: condition.name,
    implementation,
    negate: condition.negate,
    required: condition.required,
    fields: []
  };
  switch (condition.type) {
    case "release_title":
    case "release_group":
    case "edition": {
      const pattern2 = condition.patterns?.[0]?.pattern;
      if (!pattern2) return null;
      spec.fields = [{
        name: "value",
        value: pattern2
      }];
      break;
    }
    case "source": {
      const source2 = condition.sources?.[0];
      if (!source2) return null;
      spec.fields = [{
        name: "value",
        value: getSource(source2, arrType)
      }];
      break;
    }
    case "resolution": {
      const resolution = condition.resolutions?.[0];
      if (!resolution) return null;
      spec.fields = [{
        name: "value",
        value: getResolution(resolution)
      }];
      break;
    }
    case "indexer_flag": {
      const flag = condition.indexerFlags?.[0];
      if (!flag) return null;
      spec.fields = [{
        name: "value",
        value: getIndexerFlag(flag, arrType)
      }];
      break;
    }
    case "quality_modifier": {
      const modifier = condition.qualityModifiers?.[0];
      if (!modifier) return null;
      spec.fields = [{
        name: "value",
        value: getQualityModifier(modifier)
      }];
      break;
    }
    case "release_type": {
      const releaseType = condition.releaseTypes?.[0];
      if (!releaseType) return null;
      spec.fields = [{
        name: "value",
        value: getReleaseType(releaseType)
      }];
      break;
    }
    case "size": {
      const size = condition.size;
      if (!size) return null;
      spec.fields = [{
        name: "min",
        value: bytesToGb(size.minBytes)
      }, {
        name: "max",
        value: bytesToGb(size.maxBytes)
      }];
      break;
    }
    case "year": {
      const years = condition.years;
      if (!years) return null;
      spec.fields = [{
        name: "min",
        value: years.minYear ?? 0
      }, {
        name: "max",
        value: years.maxYear ?? 0
      }];
      break;
    }
    case "language": {
      const lang = condition.languages?.[0];
      if (!lang) return null;
      spec.fields = [{
        name: "value",
        value: getLanguage(lang.name, arrType).id
      }];
      if (lang.except) spec.fields.push({
        name: "exceptLanguage",
        value: true
      });
      break;
    }
    default:
      return null;
  }
  return spec;
}
function transformCustomFormat(format, arrType) {
  const specifications = [];
  for (const condition of sortConditions(format.conditions)) {
    const spec = transformCondition(condition, arrType);
    if (spec) specifications.push(spec);
  }
  const result = {
    name: format.name,
    specifications
  };
  if (format.includeInRename) result.includeCustomFormatWhenRenaming = true;
  return result;
}
async function fetchCustomFormatFromPcd(cache3, formatName) {
  const db2 = cache3.kb;
  const format = await db2.selectFrom("custom_formats").select([
    "id",
    "name",
    "include_in_rename"
  ]).where("name", "=", formatName).executeTakeFirst();
  if (!format) return null;
  const conditions = await db2.selectFrom("custom_format_conditions").select([
    "name",
    "type",
    "arr_type",
    "negate",
    "required"
  ]).where("custom_format_name", "=", formatName).execute();
  if (conditions.length === 0) return {
    id: format.id,
    name: format.name,
    includeInRename: format.include_in_rename === 1,
    conditions: []
  };
  const conditionNames = conditions.map((c2) => c2.name);
  const [patterns, languages, sources, resolutions, qualityModifiers, releaseTypes, indexerFlags, sizes, years] = await Promise.all([
    db2.selectFrom("condition_patterns as cp").innerJoin("regular_expressions as re", "re.name", "cp.regular_expression_name").select([
      "cp.condition_name",
      "re.name",
      "re.pattern"
    ]).where("cp.custom_format_name", "=", formatName).where("cp.condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_languages as cl").innerJoin("languages as l", "l.name", "cl.language_name").select([
      "cl.condition_name",
      "l.name",
      "cl.except_language"
    ]).where("cl.custom_format_name", "=", formatName).where("cl.condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_sources").select(["condition_name", "source"]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_resolutions").select(["condition_name", "resolution"]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_quality_modifiers").select(["condition_name", "quality_modifier"]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_release_types").select(["condition_name", "release_type"]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_indexer_flags").select(["condition_name", "flag"]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_sizes").select([
      "condition_name",
      "min_bytes",
      "max_bytes"
    ]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute(),
    db2.selectFrom("condition_years").select([
      "condition_name",
      "min_year",
      "max_year"
    ]).where("custom_format_name", "=", formatName).where("condition_name", "in", conditionNames).execute()
  ]);
  const patternsMap = /* @__PURE__ */ new Map();
  for (const p2 of patterns) {
    if (!patternsMap.has(p2.condition_name)) patternsMap.set(p2.condition_name, []);
    patternsMap.get(p2.condition_name).push({
      name: p2.name,
      pattern: p2.pattern
    });
  }
  const languagesMap = /* @__PURE__ */ new Map();
  for (const l3 of languages) {
    if (!languagesMap.has(l3.condition_name)) languagesMap.set(l3.condition_name, []);
    languagesMap.get(l3.condition_name).push({
      name: l3.name,
      except: l3.except_language === 1
    });
  }
  const sourcesMap = /* @__PURE__ */ new Map();
  for (const s3 of sources) {
    if (!sourcesMap.has(s3.condition_name)) sourcesMap.set(s3.condition_name, []);
    sourcesMap.get(s3.condition_name).push(s3.source);
  }
  const resolutionsMap = /* @__PURE__ */ new Map();
  for (const r2 of resolutions) {
    if (!resolutionsMap.has(r2.condition_name)) resolutionsMap.set(r2.condition_name, []);
    resolutionsMap.get(r2.condition_name).push(r2.resolution);
  }
  const qualityModifiersMap = /* @__PURE__ */ new Map();
  for (const q2 of qualityModifiers) {
    if (!qualityModifiersMap.has(q2.condition_name)) qualityModifiersMap.set(q2.condition_name, []);
    qualityModifiersMap.get(q2.condition_name).push(q2.quality_modifier);
  }
  const releaseTypesMap = /* @__PURE__ */ new Map();
  for (const r2 of releaseTypes) {
    if (!releaseTypesMap.has(r2.condition_name)) releaseTypesMap.set(r2.condition_name, []);
    releaseTypesMap.get(r2.condition_name).push(r2.release_type);
  }
  const indexerFlagsMap = /* @__PURE__ */ new Map();
  for (const f2 of indexerFlags) {
    if (!indexerFlagsMap.has(f2.condition_name)) indexerFlagsMap.set(f2.condition_name, []);
    indexerFlagsMap.get(f2.condition_name).push(f2.flag);
  }
  const sizesMap = /* @__PURE__ */ new Map();
  for (const s3 of sizes) sizesMap.set(s3.condition_name, {
    minBytes: s3.min_bytes,
    maxBytes: s3.max_bytes
  });
  const yearsMap = /* @__PURE__ */ new Map();
  for (const y2 of years) yearsMap.set(y2.condition_name, {
    minYear: y2.min_year,
    maxYear: y2.max_year
  });
  const pcdConditions = conditions.map((c2) => ({
    name: c2.name,
    type: c2.type,
    arrType: c2.arr_type,
    negate: c2.negate === 1,
    required: c2.required === 1,
    patterns: patternsMap.get(c2.name),
    languages: languagesMap.get(c2.name),
    sources: sourcesMap.get(c2.name),
    resolutions: resolutionsMap.get(c2.name),
    qualityModifiers: qualityModifiersMap.get(c2.name),
    releaseTypes: releaseTypesMap.get(c2.name),
    indexerFlags: indexerFlagsMap.get(c2.name),
    size: sizesMap.get(c2.name),
    years: yearsMap.get(c2.name)
  }));
  return {
    id: format.id,
    name: format.name,
    includeInRename: format.include_in_rename === 1,
    conditions: pcdConditions
  };
}
async function syncCustomFormats(client2, instanceId, instanceType, pcdFormats) {
  const existingFormats = await client2.getCustomFormats();
  const existingMap = new Map(existingFormats.map((f2) => [f2.name, f2.id]));
  const formatIdMap = /* @__PURE__ */ new Map();
  for (const [pcdName, pcdFormat] of pcdFormats) {
    const arrFormat = transformCustomFormat(pcdFormat, instanceType);
    arrFormat.name = pcdName;
    await logger.debug(`Compiled custom format "${pcdName}"`, {
      source: "Compile:CustomFormat",
      meta: {
        instanceId,
        pcdName,
        format: arrFormat
      }
    });
    try {
      if (existingMap.has(pcdName)) {
        const existingId = existingMap.get(pcdName);
        arrFormat.id = existingId;
        await client2.updateCustomFormat(existingId, arrFormat);
        formatIdMap.set(pcdName, existingId);
        await logger.debug(`Updated custom format "${pcdName}"`, {
          source: "Sync:CustomFormats",
          meta: {
            instanceId,
            formatId: existingId,
            pcdName
          }
        });
      } else {
        const response = await client2.createCustomFormat(arrFormat);
        existingMap.set(pcdName, response.id);
        formatIdMap.set(pcdName, response.id);
        await logger.debug(`Created custom format "${pcdName}"`, {
          source: "Sync:CustomFormats",
          meta: {
            instanceId,
            formatId: response.id,
            pcdName
          }
        });
      }
    } catch (error2) {
      const errorDetails = extractErrorDetails(error2);
      await logger.error(`Failed to sync custom format "${pcdName}"`, {
        source: "Sync:CustomFormats",
        meta: {
          instanceId,
          pcdName,
          request: arrFormat,
          ...errorDetails
        }
      });
    }
  }
  for (const [name, id] of existingMap) if (!formatIdMap.has(name)) formatIdMap.set(name, id);
  return formatIdMap;
}
function extractErrorDetails(error2) {
  const details = { error: error2 instanceof Error ? error2.message : "Unknown error" };
  if (error2 && typeof error2 === "object") {
    const err = error2;
    if ("status" in err) details.status = err.status;
    if ("statusText" in err) details.statusText = err.statusText;
    if ("response" in err) details.response = err.response;
    if ("body" in err) details.responseBody = err.body;
    if ("data" in err) details.responseData = err.data;
    if (err.cause) details.cause = err.cause;
  }
  return details;
}
function convertGroupId(_groupId, index88) {
  return 1e3 + index88 + 1;
}
function transformQualityProfile(profile, arrType, qualityApiMappings, formatIdMap) {
  const allQualities = getAllQualities(arrType);
  const items = [];
  const usedQualityNames = /* @__PURE__ */ new Set();
  const qualityIdsInGroups = /* @__PURE__ */ new Set();
  let cutoffId;
  let groupIndex = 0;
  for (const item of profile.qualities) if (item.type === "group" && item.members) for (const member of item.members) {
    const quality = allQualities[qualityApiMappings.get(member.name.toLowerCase()) ?? mapQualityName(member.name, arrType)];
    if (quality) qualityIdsInGroups.add(quality.id);
  }
  for (const item of profile.qualities) if (item.type === "group") {
    const groupId = convertGroupId(item.referenceId, groupIndex++);
    const groupItem = {
      id: groupId,
      name: item.name,
      items: [],
      allowed: item.enabled
    };
    if (item.members) for (const member of item.members) {
      const apiName = qualityApiMappings.get(member.name.toLowerCase()) ?? mapQualityName(member.name, arrType);
      const quality = allQualities[apiName];
      if (quality) {
        groupItem.items.push({
          quality: { ...quality },
          items: [],
          allowed: true
        });
        usedQualityNames.add(apiName.toUpperCase());
      }
    }
    if (groupItem.items.length > 0) items.push(groupItem);
    if (item.upgradeUntil) cutoffId = groupId;
  } else {
    const apiName = qualityApiMappings.get(item.name.toLowerCase()) ?? mapQualityName(item.name, arrType);
    const quality = allQualities[apiName];
    if (quality) {
      items.push({
        quality: { ...quality },
        items: [],
        allowed: item.enabled
      });
      usedQualityNames.add(apiName.toUpperCase());
      if (item.upgradeUntil) cutoffId = quality.id;
    }
  }
  for (const [qualityName, quality] of Object.entries(allQualities)) if (!usedQualityNames.has(qualityName.toUpperCase()) && !qualityIdsInGroups.has(quality.id)) items.push({
    quality: { ...quality },
    items: [],
    allowed: false
  });
  items.reverse();
  const language = arrType === "radarr" ? getLanguageForProfile(profile.language?.name ?? "any", arrType) : void 0;
  const formatItems = [];
  const processedFormatIds = /* @__PURE__ */ new Set();
  for (const cf of profile.customFormats) {
    const formatId = formatIdMap.get(cf.formatName);
    if (formatId !== void 0) {
      formatItems.push({
        format: formatId,
        name: cf.formatName,
        score: cf.score
      });
      processedFormatIds.add(formatId);
    }
  }
  for (const [formatName, formatId] of formatIdMap) if (!processedFormatIds.has(formatId)) {
    formatItems.push({
      format: formatId,
      name: formatName,
      score: 0
    });
    processedFormatIds.add(formatId);
  }
  return {
    name: profile.name,
    items,
    ...language && { language },
    upgradeAllowed: profile.upgradesAllowed,
    cutoff: cutoffId ?? items[items.length - 1]?.quality?.id ?? 0,
    minFormatScore: profile.minimumCustomFormatScore,
    cutoffFormatScore: profile.upgradeUntilScore,
    minUpgradeFormatScore: Math.max(1, profile.upgradeScoreIncrement),
    formatItems
  };
}
async function fetchQualityProfileFromPcd(cache3, profileName2, arrType) {
  const db2 = cache3.kb;
  const profile = await db2.selectFrom("quality_profiles").select([
    "id",
    "name",
    "upgrades_allowed",
    "minimum_custom_format_score",
    "upgrade_until_score",
    "upgrade_score_increment"
  ]).where("name", "=", profileName2).executeTakeFirst();
  if (!profile) return null;
  const allQualities = await db2.selectFrom("qualities").select(["id", "name"]).execute();
  const groups = await db2.selectFrom("quality_groups").select(["name"]).where("quality_profile_name", "=", profile.name).execute();
  const hasGroupMemberPosition = hasQualityGroupMembersPositionInCache(cache3);
  const groupMembers = groups.length > 0 ? await (() => {
    let query = db2.selectFrom("quality_group_members").innerJoin("qualities", "qualities.name", "quality_group_members.quality_name").select([
      "quality_group_members.quality_group_name",
      "qualities.id as quality_id",
      "qualities.name as quality_name"
    ]).where("quality_group_members.quality_profile_name", "=", profile.name);
    if (hasGroupMemberPosition) query = query.orderBy("quality_group_members.position");
    return query.orderBy("quality_group_members.quality_name").execute();
  })() : [];
  const groupsMap = /* @__PURE__ */ new Map();
  for (const group of groups) groupsMap.set(group.name, {
    name: group.name,
    members: []
  });
  for (const member of groupMembers) {
    const group = groupsMap.get(member.quality_group_name);
    if (group) group.members.push({
      id: member.quality_id,
      name: member.quality_name
    });
  }
  for (const group of groupsMap.values()) group.members.reverse();
  const qualities2 = (await db2.selectFrom("quality_profile_qualities").select([
    "quality_name",
    "quality_group_name",
    "position",
    "enabled",
    "upgrade_until"
  ]).where("quality_profile_name", "=", profile.name).orderBy("position").execute()).map((item) => {
    const isGroup2 = item.quality_group_name !== null;
    const name = isGroup2 ? item.quality_group_name : item.quality_name;
    const referenceId = isGroup2 ? groups.findIndex((g3) => g3.name === name) + 1 : allQualities.find((q2) => q2.name === name)?.id ?? 0;
    const result = {
      type: isGroup2 ? "group" : "quality",
      referenceId,
      name,
      position: item.position,
      enabled: item.enabled === 1,
      upgradeUntil: item.upgrade_until === 1
    };
    if (isGroup2) result.members = groupsMap.get(name)?.members || [];
    return result;
  });
  const languageRow = await db2.selectFrom("quality_profile_languages as qpl").innerJoin("languages as l", "l.name", "qpl.language_name").select([
    "l.id as language_id",
    "l.name as language_name",
    "qpl.type"
  ]).where("qpl.quality_profile_name", "=", profile.name).executeTakeFirst();
  const language = languageRow ? {
    id: languageRow.language_id,
    name: languageRow.language_name,
    type: languageRow.type
  } : null;
  const cfScores = await db2.selectFrom("quality_profile_custom_formats as qpcf").innerJoin("custom_formats as cf", "cf.name", "qpcf.custom_format_name").select([
    "cf.id as format_id",
    "cf.name as format_name",
    "qpcf.score"
  ]).where("qpcf.quality_profile_name", "=", profile.name).where((eb) => eb.or([eb("qpcf.arr_type", "=", arrType), eb("qpcf.arr_type", "=", "all")])).execute();
  const cfScoresMap = /* @__PURE__ */ new Map();
  for (const row of cfScores) cfScoresMap.set(row.format_name, {
    formatId: row.format_id,
    formatName: row.format_name,
    score: row.score
  });
  return {
    id: profile.id,
    name: profile.name,
    upgradesAllowed: profile.upgrades_allowed === 1,
    minimumCustomFormatScore: profile.minimum_custom_format_score,
    upgradeUntilScore: profile.upgrade_until_score,
    upgradeScoreIncrement: profile.upgrade_score_increment,
    qualities: qualities2,
    language,
    customFormats: Array.from(cfScoresMap.values())
  };
}
async function getQualityApiMappings(cache3, arrType) {
  const rows = await cache3.kb.selectFrom("quality_api_mappings as qam").where("qam.arr_type", "=", arrType).select(["qam.quality_name", "qam.api_name"]).execute();
  const map2 = /* @__PURE__ */ new Map();
  for (const row of rows) map2.set(row.quality_name.toLowerCase(), row.api_name);
  return map2;
}
async function getCustomFormatsForProfile(cache3, profileName2, arrType) {
  const rows = await cache3.kb.selectFrom("quality_profile_custom_formats").select(["custom_format_name"]).where("quality_profile_name", "=", profileName2).where((eb) => eb.or([eb("arr_type", "=", arrType), eb("arr_type", "=", "all")])).execute();
  return [...new Set(rows.map((r2) => r2.custom_format_name))];
}
async function getCustomFormatsForRegex(cache3, regexName) {
  const rows = await cache3.kb.selectFrom("condition_patterns").select(["custom_format_name"]).where("regular_expression_name", "=", regexName).execute();
  return [...new Set(rows.map((r2) => r2.custom_format_name))];
}
async function getProfileRefsForCustomFormat(cache3, cfName) {
  const rows = await cache3.kb.selectFrom("quality_profile_custom_formats as qpcf").innerJoin("quality_profiles as qp", "qp.name", "qpcf.quality_profile_name").select([
    "qp.id",
    "qp.name",
    "qpcf.score",
    "qpcf.arr_type"
  ]).where("qpcf.custom_format_name", "=", cfName).orderBy("qp.name").execute();
  const map2 = /* @__PURE__ */ new Map();
  for (const r2 of rows) {
    let ref = map2.get(r2.id);
    if (!ref) {
      ref = {
        id: r2.id,
        name: r2.name,
        radarrScore: null,
        sonarrScore: null
      };
      map2.set(r2.id, ref);
    }
    if (r2.arr_type === "all") {
      if (ref.radarrScore === null) ref.radarrScore = r2.score;
      if (ref.sonarrScore === null) ref.sonarrScore = r2.score;
    } else if (r2.arr_type === "radarr") ref.radarrScore = r2.score;
    else if (r2.arr_type === "sonarr") ref.sonarrScore = r2.score;
  }
  return [...map2.values()];
}
async function getProfileRefCountsForCustomFormats(cache3, cfNames) {
  if (cfNames.length === 0) return /* @__PURE__ */ new Map();
  const rows = await cache3.kb.selectFrom("quality_profile_custom_formats as qpcf").innerJoin("quality_profiles as qp", "qp.name", "qpcf.quality_profile_name").select(["qpcf.custom_format_name", "qp.id as profile_id"]).where("qpcf.custom_format_name", "in", cfNames).execute();
  const refs = /* @__PURE__ */ new Map();
  for (const row of rows) {
    let profileIds = refs.get(row.custom_format_name);
    if (!profileIds) {
      profileIds = /* @__PURE__ */ new Set();
      refs.set(row.custom_format_name, profileIds);
    }
    profileIds.add(row.profile_id);
  }
  return new Map([...refs.entries()].map(([name, profileIds]) => [name, profileIds.size]));
}
async function getConditionRefsForRegex(cache3, regexName) {
  return (await cache3.kb.selectFrom("condition_patterns as cp").innerJoin("custom_format_conditions as cfc", (join4) => join4.onRef("cp.custom_format_name", "=", "cfc.custom_format_name").onRef("cp.condition_name", "=", "cfc.name")).innerJoin("custom_formats as cf", "cf.name", "cp.custom_format_name").select([
    "cf.id",
    "cf.name",
    "cp.condition_name",
    "cfc.negate",
    "cfc.required"
  ]).where("cp.regular_expression_name", "=", regexName).orderBy("cf.name").orderBy("cp.condition_name").execute()).map((r2) => ({
    cfId: r2.id,
    cfName: r2.name,
    conditionName: r2.condition_name,
    negate: !!r2.negate,
    required: !!r2.required
  }));
}
async function getConditionRefCountsForRegexes(cache3, regexNames) {
  if (regexNames.length === 0) return /* @__PURE__ */ new Map();
  const rows = await cache3.kb.selectFrom("condition_patterns as cp").innerJoin("custom_format_conditions as cfc", (join4) => join4.onRef("cp.custom_format_name", "=", "cfc.custom_format_name").onRef("cp.condition_name", "=", "cfc.name")).innerJoin("custom_formats as cf", "cf.name", "cp.custom_format_name").select(["cp.regular_expression_name"]).where("cp.regular_expression_name", "in", regexNames).execute();
  const counts = /* @__PURE__ */ new Map();
  for (const row of rows) counts.set(row.regular_expression_name, (counts.get(row.regular_expression_name) ?? 0) + 1);
  return counts;
}
function registerSection(handler) {
  sectionRegistry.set(handler.type, handler);
}
function getSection(type) {
  const handler = sectionRegistry.get(type);
  if (!handler) throw new Error(`Unknown section type: ${type}`);
  return handler;
}
function toDelayProfile(row) {
  return {
    id: row.id,
    name: row.name,
    preferred_protocol: row.preferred_protocol,
    usenet_delay: row.usenet_delay,
    torrent_delay: row.torrent_delay,
    bypass_if_highest_quality: row.bypass_if_highest_quality === 1,
    bypass_if_above_custom_format_score: row.bypass_if_above_custom_format_score === 1,
    minimum_custom_format_score: row.minimum_custom_format_score,
    created_at: row.created_at,
    updated_at: row.updated_at
  };
}
async function list$4(cache3) {
  return (await cache3.kb.selectFrom("delay_profiles").select([
    "id",
    "name",
    "preferred_protocol",
    "usenet_delay",
    "torrent_delay",
    "bypass_if_highest_quality",
    "bypass_if_above_custom_format_score",
    "minimum_custom_format_score",
    "created_at",
    "updated_at"
  ]).orderBy(sql`name COLLATE NOCASE`).execute()).map(toDelayProfile);
}
async function get3(cache3, id) {
  const profile = await cache3.kb.selectFrom("delay_profiles").select([
    "id",
    "name",
    "preferred_protocol",
    "usenet_delay",
    "torrent_delay",
    "bypass_if_highest_quality",
    "bypass_if_above_custom_format_score",
    "minimum_custom_format_score",
    "created_at",
    "updated_at"
  ]).where("id", "=", id).executeTakeFirst();
  if (!profile) return null;
  return toDelayProfile(profile);
}
async function getByName(cache3, name) {
  const profile = await cache3.kb.selectFrom("delay_profiles").select([
    "id",
    "name",
    "preferred_protocol",
    "usenet_delay",
    "torrent_delay",
    "bypass_if_highest_quality",
    "bypass_if_above_custom_format_score",
    "minimum_custom_format_score",
    "created_at",
    "updated_at"
  ]).where("name", "=", name).executeTakeFirst();
  if (!profile) return null;
  return toDelayProfile(profile);
}
async function create$1(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  if (await db2.selectFrom("delay_profiles").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) {
    await logger.warn(`Duplicate delay profile name "${input.name}"`, {
      source: "DelayProfile",
      meta: {
        databaseId,
        name: input.name
      }
    });
    throw new Error(`A delay profile with name "${input.name}" already exists`);
  }
  const usenetDelay = input.preferredProtocol === "only_torrent" ? null : input.usenetDelay;
  const torrentDelay = input.preferredProtocol === "only_usenet" ? null : input.torrentDelay;
  const minimumCfScore = input.bypassIfAboveCfScore ? input.minimumCfScore : null;
  const insertProfile = db2.insertInto("delay_profiles").values({
    name: input.name,
    preferred_protocol: input.preferredProtocol,
    usenet_delay: usenetDelay,
    torrent_delay: torrentDelay,
    bypass_if_highest_quality: input.bypassIfHighestQuality ? 1 : 0,
    bypass_if_above_custom_format_score: input.bypassIfAboveCfScore ? 1 : 0,
    minimum_custom_format_score: minimumCfScore
  }).compile();
  return await writeOperation({
    databaseId,
    layer,
    description: `create-delay-profile-${input.name}`,
    queries: [insertProfile],
    desiredState: {
      name: input.name,
      preferred_protocol: input.preferredProtocol,
      usenet_delay: usenetDelay,
      torrent_delay: torrentDelay,
      bypass_if_highest_quality: input.bypassIfHighestQuality,
      bypass_if_above_custom_format_score: input.bypassIfAboveCfScore,
      minimum_custom_format_score: minimumCfScore
    },
    metadata: {
      operation: "create",
      entity: "delay_profile",
      name: input.name,
      stableKey: {
        key: "delay_profile_name",
        value: input.name
      },
      summary: "Create delay profile",
      title: `Create delay profile "${input.name}"`
    }
  });
}
async function update2(options2) {
  const { databaseId, cache: cache3, layer, current: current3, input } = options2;
  const db2 = cache3.kb;
  if (input.name !== current3.name) {
    if (await db2.selectFrom("delay_profiles").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) {
      await logger.warn(`Duplicate delay profile name "${input.name}"`, {
        source: "DelayProfile",
        meta: {
          databaseId,
          name: input.name
        }
      });
      throw new Error(`A delay profile with name "${input.name}" already exists`);
    }
  }
  const usenetDelay = input.preferredProtocol === "only_torrent" ? null : input.usenetDelay;
  const torrentDelay = input.preferredProtocol === "only_usenet" ? null : input.torrentDelay;
  const minimumCfScore = input.bypassIfAboveCfScore ? input.minimumCfScore : null;
  const changes = [];
  if (current3.name !== input.name) changes.push({
    field: "name",
    from: current3.name,
    to: input.name,
    setValue: input.name,
    guardValue: current3.name
  });
  if (current3.preferred_protocol !== input.preferredProtocol) changes.push({
    field: "preferred_protocol",
    from: current3.preferred_protocol,
    to: input.preferredProtocol,
    setValue: input.preferredProtocol,
    guardValue: current3.preferred_protocol
  });
  if (current3.usenet_delay !== usenetDelay) changes.push({
    field: "usenet_delay",
    from: current3.usenet_delay,
    to: usenetDelay,
    setValue: usenetDelay,
    guardValue: current3.usenet_delay
  });
  if (current3.torrent_delay !== torrentDelay) changes.push({
    field: "torrent_delay",
    from: current3.torrent_delay,
    to: torrentDelay,
    setValue: torrentDelay,
    guardValue: current3.torrent_delay
  });
  if (current3.bypass_if_highest_quality !== input.bypassIfHighestQuality) changes.push({
    field: "bypass_if_highest_quality",
    from: current3.bypass_if_highest_quality,
    to: input.bypassIfHighestQuality,
    setValue: input.bypassIfHighestQuality ? 1 : 0,
    guardValue: current3.bypass_if_highest_quality ? 1 : 0
  });
  if (current3.bypass_if_above_custom_format_score !== input.bypassIfAboveCfScore) changes.push({
    field: "bypass_if_above_custom_format_score",
    from: current3.bypass_if_above_custom_format_score,
    to: input.bypassIfAboveCfScore,
    setValue: input.bypassIfAboveCfScore ? 1 : 0,
    guardValue: current3.bypass_if_above_custom_format_score ? 1 : 0
  });
  if (current3.minimum_custom_format_score !== minimumCfScore) changes.push({
    field: "minimum_custom_format_score",
    from: current3.minimum_custom_format_score,
    to: minimumCfScore,
    setValue: minimumCfScore,
    guardValue: current3.minimum_custom_format_score
  });
  if (changes.length === 0) return { success: true };
  await logger.info(`Save delay profile "${input.name}"`, {
    source: "DelayProfile",
    meta: {
      id: current3.id,
      changes
    }
  });
  const opGroups = groupChanges(changes, current3, usenetDelay, torrentDelay, minimumCfScore);
  const groupId = opGroups.length > 1 ? uuid() : void 0;
  const operations = opGroups.map((opChanges) => {
    const fields = opChanges.map((change) => change.field);
    return {
      fields,
      isRename: fields.length === 1 && fields[0] === "name",
      queries: [buildUpdateQuery3(cache3, current3, opChanges)],
      desiredState: buildDesiredState2(opChanges)
    };
  });
  let lastResult = null;
  for (const operation of operations) {
    const result = await writeOperation({
      databaseId,
      layer,
      description: `update-delay-profile-${operation.fields.join("-")}-${input.name}`,
      queries: operation.queries,
      desiredState: operation.desiredState,
      metadata: {
        operation: "update",
        entity: "delay_profile",
        name: input.name,
        ...operation.isRename && { previousName: current3.name },
        stableKey: {
          key: "delay_profile_name",
          value: current3.name
        },
        ...groupId && { groupId },
        changedFields: operation.fields,
        summary: operation.isRename ? "Rename delay profile" : "Update delay profile",
        title: operation.isRename ? `Rename delay profile "${current3.name}"` : `Update delay profile "${input.name}"`
      }
    });
    if (!result.success) return result;
    lastResult = result;
  }
  return lastResult ?? { success: true };
}
function groupChanges(changes, current3, usenetDelay, torrentDelay, minimumCfScore) {
  const byField = /* @__PURE__ */ new Map();
  for (const change of changes) byField.set(change.field, change);
  const groups = [];
  const used = /* @__PURE__ */ new Set();
  if (byField.get("preferred_protocol")) {
    const protocolFields = ["preferred_protocol"];
    if (current3.usenet_delay === null || usenetDelay === null) protocolFields.push("usenet_delay");
    if (current3.torrent_delay === null || torrentDelay === null) protocolFields.push("torrent_delay");
    addGroup(groups, used, byField, protocolFields);
  }
  addSingle(groups, used, byField, "usenet_delay");
  addSingle(groups, used, byField, "torrent_delay");
  addSingle(groups, used, byField, "bypass_if_highest_quality");
  if (byField.get("bypass_if_above_custom_format_score")) {
    const bypassFields = ["bypass_if_above_custom_format_score"];
    if (current3.minimum_custom_format_score === null || minimumCfScore === null) bypassFields.push("minimum_custom_format_score");
    addGroup(groups, used, byField, bypassFields);
  }
  addSingle(groups, used, byField, "minimum_custom_format_score");
  addSingle(groups, used, byField, "name");
  for (const change of changes) if (!used.has(change.field)) groups.push([change]);
  return groups;
}
function addSingle(groups, used, byField, field) {
  addGroup(groups, used, byField, [field]);
}
function addGroup(groups, used, byField, fields) {
  const group = fields.filter((field) => !used.has(field)).map((field) => byField.get(field)).filter((change) => !!change);
  if (group.length === 0) return;
  for (const change of group) used.add(change.field);
  groups.push(group);
}
function buildDesiredState2(changes) {
  const desiredState = {};
  for (const change of changes) desiredState[change.field] = {
    from: change.from,
    to: change.to
  };
  return desiredState;
}
function buildUpdateQuery3(cache3, current3, changes) {
  const db2 = cache3.kb;
  const setValues = {};
  for (const change of changes) setValues[change.field] = change.setValue;
  let query = db2.updateTable("delay_profiles").set(setValues).where("name", "=", current3.name);
  for (const change of changes) {
    if (change.field === "name") continue;
    if (change.guardValue === null) query = query.where(change.field, "is", null);
    else query = query.where(change.field, "=", change.guardValue);
  }
  return query.compile();
}
async function remove$1(options2) {
  const { databaseId, cache: cache3, layer, current: current3 } = options2;
  const deleteProfileQuery = cache3.kb.deleteFrom("delay_profiles").where("name", "=", current3.name).compile();
  return await writeOperation({
    databaseId,
    layer,
    description: `delete-delay-profile-${current3.name}`,
    queries: [deleteProfileQuery],
    desiredState: {
      deleted: true,
      name: current3.name,
      preferred_protocol: current3.preferred_protocol,
      usenet_delay: current3.usenet_delay,
      torrent_delay: current3.torrent_delay,
      bypass_if_highest_quality: current3.bypass_if_highest_quality,
      bypass_if_above_custom_format_score: current3.bypass_if_above_custom_format_score,
      minimum_custom_format_score: current3.minimum_custom_format_score
    },
    metadata: {
      operation: "delete",
      entity: "delay_profile",
      name: current3.name,
      stableKey: {
        key: "delay_profile_name",
        value: current3.name
      },
      changedFields: ["deleted"],
      summary: "Delete delay profile",
      title: `Delete delay profile "${current3.name}"`
    }
  });
}
function transformDelayProfile(profile) {
  let enableUsenet = true;
  let enableTorrent = true;
  let preferredProtocol = "usenet";
  switch (profile.preferred_protocol) {
    case "prefer_usenet":
      enableUsenet = true;
      enableTorrent = true;
      preferredProtocol = "usenet";
      break;
    case "prefer_torrent":
      enableUsenet = true;
      enableTorrent = true;
      preferredProtocol = "torrent";
      break;
    case "only_usenet":
      enableUsenet = true;
      enableTorrent = false;
      preferredProtocol = "usenet";
      break;
    case "only_torrent":
      enableUsenet = false;
      enableTorrent = true;
      preferredProtocol = "torrent";
  }
  return {
    id: 1,
    enableUsenet,
    enableTorrent,
    preferredProtocol,
    usenetDelay: profile.usenet_delay ?? 0,
    torrentDelay: profile.torrent_delay ?? 0,
    bypassIfHighestQuality: profile.bypass_if_highest_quality,
    bypassIfAboveCustomFormatScore: profile.bypass_if_above_custom_format_score,
    minimumCustomFormatScore: profile.minimum_custom_format_score ?? 0,
    order: 2147483647,
    tags: []
  };
}
async function list$3(cache3) {
  const db2 = cache3.kb;
  const [radarrRows, sonarrRows] = await Promise.all([db2.selectFrom("radarr_media_settings").select([
    "name",
    "propers_repacks",
    "enable_media_info",
    "updated_at"
  ]).execute(), db2.selectFrom("sonarr_media_settings").select([
    "name",
    "propers_repacks",
    "enable_media_info",
    "updated_at"
  ]).execute()]);
  const items = [];
  for (const row of radarrRows) items.push({
    name: row.name,
    arr_type: "radarr",
    propers_repacks: row.propers_repacks,
    enable_media_info: row.enable_media_info === 1,
    updated_at: row.updated_at
  });
  for (const row of sonarrRows) items.push({
    name: row.name,
    arr_type: "sonarr",
    propers_repacks: row.propers_repacks,
    enable_media_info: row.enable_media_info === 1,
    updated_at: row.updated_at
  });
  return items;
}
async function getRadarrByName$2(cache3, name) {
  const row = await cache3.kb.selectFrom("radarr_media_settings").selectAll().where("name", "=", name).executeTakeFirst();
  if (!row) return null;
  return {
    name: row.name,
    propers_repacks: row.propers_repacks,
    enable_media_info: row.enable_media_info === 1,
    created_at: row.created_at,
    updated_at: row.updated_at
  };
}
async function getSonarrByName$2(cache3, name) {
  const row = await cache3.kb.selectFrom("sonarr_media_settings").selectAll().where("name", "=", name).executeTakeFirst();
  if (!row) return null;
  return {
    name: row.name,
    propers_repacks: row.propers_repacks,
    enable_media_info: row.enable_media_info === 1,
    created_at: row.created_at,
    updated_at: row.updated_at
  };
}
async function list$2(cache3) {
  const db2 = cache3.kb;
  const [radarrRows, sonarrRows] = await Promise.all([db2.selectFrom("radarr_naming").select([
    "name",
    "rename",
    "replace_illegal_characters",
    "colon_replacement_format",
    "updated_at"
  ]).execute(), db2.selectFrom("sonarr_naming").select([
    "name",
    "rename",
    "replace_illegal_characters",
    "colon_replacement_format",
    "multi_episode_style",
    "updated_at"
  ]).execute()]);
  const items = [];
  for (const row of radarrRows) items.push({
    name: row.name,
    arr_type: "radarr",
    rename: row.rename === 1,
    replace_illegal_characters: row.replace_illegal_characters === 1,
    colon_replacement_format: row.colon_replacement_format,
    multi_episode_style: null,
    updated_at: row.updated_at
  });
  for (const row of sonarrRows) items.push({
    name: row.name,
    arr_type: "sonarr",
    rename: row.rename === 1,
    replace_illegal_characters: row.replace_illegal_characters === 1,
    colon_replacement_format: colonReplacementFromDb(row.colon_replacement_format),
    multi_episode_style: multiEpisodeStyleFromDb(row.multi_episode_style),
    updated_at: row.updated_at
  });
  return items;
}
async function getRadarrByName$1(cache3, name) {
  const row = await cache3.kb.selectFrom("radarr_naming").selectAll().where("name", "=", name).executeTakeFirst();
  if (!row) return null;
  return {
    name: row.name,
    rename: row.rename === 1,
    movie_format: row.movie_format,
    movie_folder_format: row.movie_folder_format,
    replace_illegal_characters: row.replace_illegal_characters === 1,
    colon_replacement_format: row.colon_replacement_format,
    created_at: row.created_at,
    updated_at: row.updated_at
  };
}
async function getSonarrByName$1(cache3, name) {
  const row = await cache3.kb.selectFrom("sonarr_naming").selectAll().where("name", "=", name).executeTakeFirst();
  if (!row) return null;
  return {
    name: row.name,
    rename: row.rename === 1,
    standard_episode_format: row.standard_episode_format,
    daily_episode_format: row.daily_episode_format,
    anime_episode_format: row.anime_episode_format,
    series_folder_format: row.series_folder_format,
    season_folder_format: row.season_folder_format,
    replace_illegal_characters: row.replace_illegal_characters === 1,
    colon_replacement_format: colonReplacementFromDb(row.colon_replacement_format),
    custom_colon_replacement_format: row.custom_colon_replacement_format,
    multi_episode_style: multiEpisodeStyleFromDb(row.multi_episode_style),
    created_at: row.created_at,
    updated_at: row.updated_at
  };
}
async function getAvailableQualities(cache3, arrType) {
  return (await cache3.kb.selectFrom("quality_api_mappings").where("arr_type", "=", arrType).select(["quality_name"]).orderBy(sql`quality_name COLLATE NOCASE`).execute()).map((row) => row.quality_name);
}
async function list$1(cache3) {
  const radarrRows = await cache3.kb.selectFrom("radarr_quality_definitions").select(["name"]).select((eb) => eb.fn.count("quality_name").as("quality_count")).select((eb) => eb.fn.max("updated_at").as("updated_at")).groupBy("name").execute();
  const sonarrRows = await cache3.kb.selectFrom("sonarr_quality_definitions").select(["name"]).select((eb) => eb.fn.count("quality_name").as("quality_count")).select((eb) => eb.fn.max("updated_at").as("updated_at")).groupBy("name").execute();
  const result = [];
  for (const row of radarrRows) result.push({
    name: row.name,
    arr_type: "radarr",
    quality_count: Number(row.quality_count),
    updated_at: row.updated_at ?? ""
  });
  for (const row of sonarrRows) result.push({
    name: row.name,
    arr_type: "sonarr",
    quality_count: Number(row.quality_count),
    updated_at: row.updated_at ?? ""
  });
  result.sort((a2, b3) => b3.updated_at.localeCompare(a2.updated_at));
  return result;
}
async function getRadarrByName(cache3, name) {
  const rows = await cache3.kb.selectFrom("radarr_quality_definitions").where("name", "=", name).select([
    "quality_name",
    "min_size",
    "max_size",
    "preferred_size"
  ]).execute();
  if (rows.length === 0) return null;
  return {
    name,
    entries: rows.map((row) => ({
      quality_name: row.quality_name,
      min_size: row.min_size,
      max_size: row.max_size,
      preferred_size: row.preferred_size
    }))
  };
}
async function getSonarrByName(cache3, name) {
  const rows = await cache3.kb.selectFrom("sonarr_quality_definitions").where("name", "=", name).select([
    "quality_name",
    "min_size",
    "max_size",
    "preferred_size"
  ]).execute();
  if (rows.length === 0) return null;
  return {
    name,
    entries: rows.map((row) => ({
      quality_name: row.quality_name,
      min_size: row.min_size,
      max_size: row.max_size,
      preferred_size: row.preferred_size
    }))
  };
}
function transformMediaSettings(mediaSettings) {
  return {
    downloadPropersAndRepacks: mapPropersRepacks(mediaSettings.propers_repacks),
    enableMediaInfo: mediaSettings.enable_media_info
  };
}
function transformRadarrNaming(naming) {
  return {
    renameMovies: naming.rename,
    replaceIllegalCharacters: naming.replace_illegal_characters,
    colonReplacementFormat: naming.colon_replacement_format,
    standardMovieFormat: naming.movie_format,
    movieFolderFormat: naming.movie_folder_format
  };
}
function transformSonarrNaming(naming) {
  return {
    renameEpisodes: naming.rename,
    replaceIllegalCharacters: naming.replace_illegal_characters,
    colonReplacementFormat: colonReplacementToDb(naming.colon_replacement_format),
    customColonReplacementFormat: naming.custom_colon_replacement_format,
    multiEpisodeStyle: multiEpisodeStyleToDb(naming.multi_episode_style),
    standardEpisodeFormat: naming.standard_episode_format,
    dailyEpisodeFormat: naming.daily_episode_format,
    animeEpisodeFormat: naming.anime_episode_format,
    seriesFolderFormat: naming.series_folder_format,
    seasonFolderFormat: naming.season_folder_format
  };
}
function transformNamingForDrift(naming, arrType) {
  if (arrType === "radarr") return transformRadarrNaming(naming);
  return normalizeSonarrNamingConfig(transformSonarrNaming(naming));
}
function transformQualityDefinitionsForArr(entries, apiMappings) {
  const definitions = [];
  const unmapped = [];
  for (const entry of entries) {
    const apiName = apiMappings.get(entry.quality_name.toLowerCase());
    if (!apiName) {
      unmapped.push(entry.quality_name);
      continue;
    }
    definitions.push({
      qualityName: apiName,
      fields: transformQualityDefinition(entry)
    });
  }
  return {
    definitions,
    unmapped
  };
}
function applyQualityDefinitionsToArr(arrDefinitions, definitions) {
  const arrDefMap = buildArrQualityDefinitionMap(arrDefinitions);
  const missing = [];
  let updatedCount = 0;
  for (const definition of definitions) {
    const arrDef = arrDefMap.get(definition.qualityName.toLowerCase());
    if (!arrDef) {
      missing.push(definition.qualityName);
      continue;
    }
    arrDef.minSize = definition.fields.minSize;
    arrDef.maxSize = definition.fields.maxSize;
    arrDef.preferredSize = definition.fields.preferredSize;
    updatedCount++;
  }
  return {
    updatedCount,
    missing
  };
}
function normalizeArrQualityDefinition(definition) {
  return {
    minSize: definition.minSize ?? null,
    maxSize: definition.maxSize ?? null,
    preferredSize: definition.preferredSize ?? null
  };
}
function mergeMediaSettingsConfig(existing, mediaSettings) {
  return {
    ...existing,
    ...transformMediaSettings(mediaSettings)
  };
}
function mergeRadarrNamingConfig(existing, naming) {
  return {
    ...existing,
    ...transformRadarrNaming(naming)
  };
}
function mergeSonarrNamingConfig(existing, naming) {
  return {
    ...existing,
    ...transformSonarrNaming(naming)
  };
}
function normalizeNamingConfig(config2, arrType) {
  if (arrType === "radarr") return normalizeRadarrNamingConfig(config2);
  return normalizeSonarrNamingConfig(config2);
}
function normalizeRadarrNamingConfig(config2) {
  return {
    renameMovies: config2.renameMovies,
    replaceIllegalCharacters: config2.replaceIllegalCharacters,
    colonReplacementFormat: config2.colonReplacementFormat,
    standardMovieFormat: config2.standardMovieFormat,
    movieFolderFormat: config2.movieFolderFormat
  };
}
function normalizeSonarrNamingConfig(config2) {
  return {
    renameEpisodes: config2.renameEpisodes,
    replaceIllegalCharacters: config2.replaceIllegalCharacters,
    colonReplacementFormat: colonReplacementFromDb(config2.colonReplacementFormat),
    customColonReplacementFormat: normalizeOptionalNamingString(config2.customColonReplacementFormat),
    multiEpisodeStyle: multiEpisodeStyleFromDb(config2.multiEpisodeStyle),
    standardEpisodeFormat: config2.standardEpisodeFormat,
    dailyEpisodeFormat: config2.dailyEpisodeFormat,
    animeEpisodeFormat: config2.animeEpisodeFormat,
    seriesFolderFormat: config2.seriesFolderFormat,
    seasonFolderFormat: config2.seasonFolderFormat
  };
}
function normalizeOptionalNamingString(value2) {
  if (value2 === null || value2 === void 0) return null;
  return value2.trim() === "" ? null : value2;
}
function transformQualityDefinition(entry) {
  return {
    minSize: entry.min_size,
    maxSize: entry.max_size === 0 ? null : entry.max_size,
    preferredSize: entry.preferred_size === 0 ? null : entry.preferred_size
  };
}
function buildArrQualityDefinitionMap(arrDefinitions) {
  const arrDefMap = /* @__PURE__ */ new Map();
  for (const definition of arrDefinitions) if (definition.quality.name) arrDefMap.set(definition.quality.name.toLowerCase(), definition);
  return arrDefMap;
}
function mapPropersRepacks(pcdValue) {
  return {
    doNotPrefer: "doNotPrefer",
    preferAndUpgrade: "preferAndUpgrade",
    doNotUpgradeAutomatically: "doNotUpgrade"
  }[pcdValue] ?? "doNotPrefer";
}
async function triggerSyncs(context2) {
  const instanceIds = arrSyncQueries.getInstanceIdsForTrigger(context2.event);
  for (const instanceId of instanceIds) {
    const status = arrSyncQueries.getSyncConfigStatus(instanceId);
    if (status.qualityProfiles.trigger === context2.event) {
      arrSyncQueries.setQualityProfilesStatusPending(instanceId);
      upsertScheduledJob({
        jobType: "arr.sync.qualityProfiles",
        runAt: (/* @__PURE__ */ new Date()).toISOString(),
        payload: { instanceId },
        source: "system",
        dedupeKey: `arr.sync.qualityProfiles:event:${instanceId}`
      });
    }
    if (status.delayProfiles.trigger === context2.event) {
      arrSyncQueries.setDelayProfilesStatusPending(instanceId);
      upsertScheduledJob({
        jobType: "arr.sync.delayProfiles",
        runAt: (/* @__PURE__ */ new Date()).toISOString(),
        payload: { instanceId },
        source: "system",
        dedupeKey: `arr.sync.delayProfiles:event:${instanceId}`
      });
    }
    if (status.mediaManagement.trigger === context2.event) {
      arrSyncQueries.setMediaManagementStatusPending(instanceId);
      upsertScheduledJob({
        jobType: "arr.sync.mediaManagement",
        runAt: (/* @__PURE__ */ new Date()).toISOString(),
        payload: { instanceId },
        source: "system",
        dedupeKey: `arr.sync.mediaManagement:event:${instanceId}`
      });
    }
  }
}
async function pathExists2(path) {
  try {
    await Deno.stat(path);
    return true;
  } catch {
    return false;
  }
}
function parseMetadata(sql2) {
  const lines = sql2.split(/\r?\n/);
  const metadata = {};
  const cleanedLines = [];
  for (const line of lines) {
    const match = line.match(/^--\s*@([a-zA-Z_]+)\s*:\s*(.*)$/);
    if (match) {
      metadata[match[1]] = match[2].trim();
      continue;
    }
    cleanedLines.push(line);
  }
  const cleanedSql = cleanedLines.join("\n").trim();
  return {
    metadataJson: !!(metadata.operation && metadata.entity && metadata.name) ? JSON.stringify(metadata) : null,
    cleanedSql
  };
}
async function hashContent$1(sql2, metadataJson) {
  const payload2 = `${sql2}
${metadataJson ?? ""}`;
  const data = new TextEncoder().encode(payload2);
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  return Array.from(new Uint8Array(hashBuffer)).map((b3) => b3.toString(16).padStart(2, "0")).join("");
}
async function importBaseOps(databaseId, pcdPath) {
  const basePath = getBaseOpsPath(pcdPath);
  if (!await pathExists2(basePath)) return {
    created: 0,
    updated: 0,
    orphaned: 0
  };
  const entries = [];
  for await (const entry of Deno.readDir(basePath)) {
    if (!entry.isFile || !entry.name.endsWith(".sql")) continue;
    const filepath = `${basePath}/${entry.name}`;
    entries.push({
      name: entry.name,
      filepath,
      order: extractOrderFromFilename(entry.name)
    });
  }
  entries.sort((a2, b3) => {
    if (a2.order !== b3.order) return a2.order - b3.order;
    return a2.name.localeCompare(b3.name);
  });
  let created = 0;
  let updated3 = 0;
  let unprefixedIndex = 0;
  const seenAt = (/* @__PURE__ */ new Date()).toISOString();
  for (const entry of entries) {
    const opNumber = entry.order === Infinity ? null : entry.order;
    const sequence = opNumber === null ? UNPREFIXED_SEQUENCE_BASE + unprefixedIndex++ : opNumber;
    const { metadataJson, cleanedSql } = parseMetadata(await Deno.readTextFile(entry.filepath));
    const contentHash = await hashContent$1(cleanedSql, metadataJson);
    const existing = pcdOpsQueries.getBaseByFilename(databaseId, entry.name);
    if (existing) {
      pcdOpsQueries.update(existing.id, {
        state: "published",
        source: "repo",
        filename: entry.name,
        opNumber,
        sequence,
        sql: cleanedSql,
        metadata: metadataJson,
        contentHash,
        lastSeenInRepoAt: seenAt
      });
      updated3 += 1;
    } else {
      pcdOpsQueries.create({
        databaseId,
        origin: "base",
        state: "published",
        source: "repo",
        filename: entry.name,
        opNumber,
        sequence,
        sql: cleanedSql,
        metadata: metadataJson,
        contentHash,
        lastSeenInRepoAt: seenAt
      });
      created += 1;
    }
  }
  const orphaned = pcdOpsQueries.markBaseOrphaned(databaseId, seenAt);
  await logger.debug("Imported base ops from repo", {
    source: "PCDImporter",
    meta: {
      databaseId,
      basePath,
      created,
      updated: updated3,
      orphaned
    }
  });
  return {
    created,
    updated: updated3,
    orphaned
  };
}
async function readSchemaVersion(pcdPath) {
  try {
    const content = await Deno.readTextFile(`${pcdPath}/deps/schema/pcd.json`);
    return JSON.parse(content).version ?? null;
  } catch {
    return null;
  }
}
function compiledQueryToSql(compiled) {
  const sql2 = compiled.sql;
  const params = compiled.parameters;
  if (params.length === 0) return sql2;
  const result = [];
  let paramIndex = 0;
  let i = 0;
  while (i < sql2.length) if (sql2[i] === "?" && paramIndex < params.length) {
    result.push(formatValue(params[paramIndex]));
    paramIndex++;
    i++;
  } else {
    result.push(sql2[i]);
    i++;
  }
  return result.join("");
}
function formatValue(value2) {
  if (value2 === null || value2 === void 0) return "NULL";
  if (typeof value2 === "number") return String(value2);
  if (typeof value2 === "boolean") return value2 ? "1" : "0";
  if (typeof value2 === "string") return `'${value2.replace(/'/g, "''")}'`;
  return `'${String(value2).replace(/'/g, "''")}'`;
}
function buildMetadataJson(metadata) {
  if (!metadata) return null;
  const payload2 = {
    operation: metadata.operation,
    entity: metadata.entity,
    name: metadata.name
  };
  if (metadata.previousName) payload2.previousName = metadata.previousName;
  if (metadata.qualityName) payload2.qualityName = metadata.qualityName;
  if (metadata.summary) payload2.summary = metadata.summary;
  if (metadata.title) payload2.title = metadata.title;
  if (metadata.changedFields && metadata.changedFields.length > 0) payload2.changed_fields = metadata.changedFields;
  if (metadata.stableKey) payload2.stable_key = metadata.stableKey;
  if (metadata.groupId) payload2.group_id = metadata.groupId;
  if (metadata.generated) payload2.generated = true;
  if (metadata.dependsOn && metadata.dependsOn.length > 0) payload2.depends_on = metadata.dependsOn;
  return JSON.stringify(payload2);
}
function serializeDesiredState(desiredState) {
  if (!desiredState) return null;
  return JSON.stringify(desiredState);
}
async function hashContent(sql2, metadataJson) {
  const payload2 = `${sql2}
${metadataJson ?? ""}`;
  const data = new TextEncoder().encode(payload2);
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  return Array.from(new Uint8Array(hashBuffer)).map((b3) => b3.toString(16).padStart(2, "0")).join("");
}
async function cancelOutCreate(databaseId, origin, metadata) {
  if (metadata.operation !== "delete") return false;
  const candidates = pcdOpsQueries.listByDatabaseAndOrigin(databaseId, origin, {
    source: "local",
    states: ["published", "draft"]
  });
  function hasDependentOps(createdOpId, createdMeta, createdStableKey) {
    for (const op of candidates) {
      if (op.id <= createdOpId) continue;
      if (!op.metadata) continue;
      let parsed;
      try {
        parsed = JSON.parse(op.metadata);
      } catch {
        continue;
      }
      const opStableKey = parsed.stable_key;
      if (createdStableKey?.key && opStableKey?.key === createdStableKey.key && opStableKey?.value === createdStableKey.value) return true;
      if (createdMeta.entity && createdMeta.name && parsed.entity === createdMeta.entity && parsed.name === createdMeta.name) return true;
      if (createdMeta.entity && createdStableKey?.key && createdStableKey.value) {
        for (const dependency of parsed.depends_on ?? []) if (dependency.entity === createdMeta.entity && dependency.key === createdStableKey.key && dependency.value === createdStableKey.value) return true;
      }
      if (createdMeta.entity === "test_entity" && createdStableKey?.value) {
        const [entityType, entityTmdbIdRaw] = createdStableKey.value.split(":");
        const entityTmdbId = Number(entityTmdbIdRaw);
        if (!entityType || Number.isNaN(entityTmdbId)) continue;
        if (parsed.entity === "test_release") {
          if (opStableKey?.value && opStableKey.value.startsWith(`${entityType}:${entityTmdbId}:`)) return true;
          if (op.desired_state) try {
            const desired = JSON.parse(op.desired_state);
            if (desired.entity_type === entityType && desired.entity_tmdb_id === entityTmdbId) return true;
          } catch {
          }
        }
      }
    }
    return false;
  }
  for (let i = candidates.length - 1; i >= 0; i--) {
    const candidate = candidates[i];
    if (!candidate.metadata) continue;
    let parsed;
    try {
      parsed = JSON.parse(candidate.metadata);
    } catch {
      continue;
    }
    if (parsed.operation === "create" && parsed.entity === metadata.entity && parsed.name === metadata.name) {
      if (hasDependentOps(candidate.id, parsed, parsed.stable_key)) return false;
      pcdOpsQueries.update(candidate.id, { state: "dropped" });
      await logger.info("Cancelled out local create operation with delete", {
        source: "PCDWriter",
        meta: {
          databaseId,
          opId: candidate.id,
          entity: metadata.entity,
          name: metadata.name
        }
      });
      return true;
    }
  }
  return false;
}
async function writeOperation(options2) {
  const { databaseId, layer, description, queries, metadata, desiredState, skipRecompile } = options2;
  try {
    const instance = databaseInstancesQueries.getById(databaseId);
    if (!instance) return {
      success: false,
      error: "Database instance not found"
    };
    if (layer === "base" && (!instance.personal_access_token || instance.local_ops_enabled)) return {
      success: false,
      error: "Base layer requires a personal access token and local ops must be disabled"
    };
    const sqlStatements = queries.map(compiledQueryToSql);
    const cache3 = getCache(databaseId);
    if (cache3) {
      const validation = cache3.validateSql(sqlStatements);
      if (!validation.valid) {
        await logger.error("Operation validation failed - refusing to write", {
          source: "PCDWriter",
          meta: {
            databaseId,
            layer,
            description,
            error: validation.error,
            queries: sqlStatements
          }
        });
        return {
          success: false,
          error: `Validation failed: ${validation.error}`
        };
      }
    } else await logger.warn("No cache available for validation - proceeding without validation", {
      source: "PCDWriter",
      meta: {
        databaseId,
        description
      }
    });
    if (metadata && await cancelOutCreate(databaseId, layer, metadata)) {
      if (!skipRecompile) await compile(instance.local_path, instance.id);
      return { success: true };
    }
    const sqlContent = `${sqlStatements.join(";\n\n")};`.trim();
    const metadataJson = buildMetadataJson(metadata);
    const desiredStateJson = serializeDesiredState(desiredState);
    const contentHash = await hashContent(sqlContent, metadataJson);
    const origin = layer === "base" ? "base" : "user";
    const state2 = layer === "base" ? "draft" : "published";
    const opId = pcdOpsQueries.create({
      databaseId,
      origin,
      state: state2,
      source: "local",
      sql: sqlContent,
      metadata: metadataJson,
      desiredState: desiredStateJson,
      contentHash
    });
    const opType = metadata?.operation ?? "write";
    const entity = metadata?.entity?.replace(/_/g, " ") ?? "operation";
    const entityName = metadata?.name ?? "";
    const message2 = `${opType.charAt(0).toUpperCase() + opType.slice(1)} ${entity} "${entityName}" in ${origin} layer`;
    if (metadata?.operation === "create" || metadata?.operation === "delete") await logger.info(message2, {
      source: "PCDWriter",
      meta: {
        databaseId,
        opId,
        layer: origin,
        entity: metadata.entity,
        name: metadata.name
      }
    });
    if (!skipRecompile) {
      await compile(instance.local_path, instance.id);
      await logger.debug("Cache recompiled after write", {
        source: "PCDWriter",
        meta: { databaseId }
      });
    }
    return {
      success: true,
      filepath: `pcd_ops:${opId}`
    };
  } catch (error2) {
    await logger.error("Failed to write operation", {
      source: "PCDWriter",
      meta: {
        error: String(error2),
        databaseId,
        layer,
        description
      }
    });
    return {
      success: false,
      error: String(error2)
    };
  }
}
async function recompileCache(databaseId) {
  const instance = databaseInstancesQueries.getById(databaseId);
  if (!instance) return;
  await compile(instance.local_path, instance.id);
  await logger.debug("Cache recompiled after batch write", {
    source: "PCDWriter",
    meta: { databaseId }
  });
}
function canWriteToBase(databaseId) {
  const instance = databaseInstancesQueries.getById(databaseId);
  return !!instance?.personal_access_token && !instance?.local_ops_enabled;
}
async function scanForStaleItems(client2, instanceId) {
  const instance = arrInstancesQueries.getById(instanceId);
  if (!instance) throw new Error(`Instance ${instanceId} not found`);
  const arrType = instance.type;
  const { selections } = arrSyncQueries.getQualityProfilesSync(instanceId);
  const expectedQPNames = new Set(selections.map((s3) => s3.profileName));
  const expectedCFNames = /* @__PURE__ */ new Set();
  for (const sel of selections) {
    const cache3 = getCache(sel.databaseId);
    if (!cache3) throw new Error(`PCD cache not found for database ${sel.databaseId}`);
    const cfNames = await getCustomFormatsForProfile(cache3, sel.profileName, arrType);
    for (const name of cfNames) expectedCFNames.add(name);
  }
  const [arrCFs, arrQPs] = await Promise.all([client2.getCustomFormats(), client2.getQualityProfiles()]);
  const staleCustomFormats = arrCFs.filter((cf) => !expectedCFNames.has(cf.name)).map((cf) => ({
    id: cf.id,
    name: cf.name
  }));
  const staleQualityProfiles = arrQPs.filter((qp) => !expectedQPNames.has(qp.name)).map((qp) => ({
    id: qp.id,
    name: qp.name
  }));
  await logger.debug("Scan complete", {
    source: SOURCE$1,
    meta: {
      instanceId,
      expectedQPs: [...expectedQPNames],
      expectedCFs: expectedCFNames.size,
      arrCFs: arrCFs.length,
      arrQPs: arrQPs.length,
      staleCFs: staleCustomFormats.length,
      staleQPs: staleQualityProfiles.length
    }
  });
  return {
    staleCustomFormats,
    staleQualityProfiles
  };
}
async function deleteStaleItems(client2, scanResult) {
  const deletedCustomFormats = [];
  const deletedQualityProfiles = [];
  const skippedQualityProfiles = [];
  for (const cf of scanResult.staleCustomFormats) try {
    await client2.deleteCustomFormat(cf.id);
    deletedCustomFormats.push(cf);
  } catch (err) {
    await logger.warn(`Failed to delete CF "${cf.name}" (id=${cf.id})`, {
      source: SOURCE$1,
      meta: { error: err instanceof Error ? err.message : String(err) }
    });
  }
  for (const qp of scanResult.staleQualityProfiles) try {
    await client2.deleteQualityProfile(qp.id);
    deletedQualityProfiles.push(qp);
  } catch (err) {
    const reason = err instanceof HttpError2 && err.status === 500 ? "Profile is assigned to media" : err instanceof Error ? err.message : String(err);
    skippedQualityProfiles.push({
      item: qp,
      reason
    });
  }
  return {
    deletedCustomFormats,
    deletedQualityProfiles,
    skippedQualityProfiles
  };
}
async function scanForRemovedEntities(client2, instanceType) {
  const health = await client2.getHealth();
  const checkSource = instanceType === "radarr" ? "RemovedMovieCheck" : "RemovedSeriesCheck";
  const idRegex = instanceType === "radarr" ? TMDB_ID_REGEX : TVDB_ID_REGEX;
  const flaggedIds = /* @__PURE__ */ new Set();
  for (const item of health) {
    if (item.source !== checkSource) continue;
    for (const match of item.message.matchAll(idRegex)) flaggedIds.add(parseInt(match[1], 10));
  }
  if (flaggedIds.size === 0) {
    await logger.debug("No removed entities found in health checks", {
      source: SOURCE,
      meta: { instanceType }
    });
    return { removedEntities: [] };
  }
  const removedEntities = [];
  if (instanceType === "radarr") {
    const movies = await client2.getMovies();
    for (const movie of movies) if (movie.tmdbId != null && flaggedIds.has(movie.tmdbId)) removedEntities.push({
      id: movie.id,
      title: movie.title,
      externalId: movie.tmdbId
    });
  } else {
    const series = await client2.getAllSeries();
    for (const s3 of series) if (s3.tvdbId != null && flaggedIds.has(s3.tvdbId)) removedEntities.push({
      id: s3.id,
      title: s3.title,
      externalId: s3.tvdbId
    });
  }
  await logger.debug("Entity scan complete", {
    source: SOURCE,
    meta: {
      instanceType,
      flaggedIds: [...flaggedIds],
      matched: removedEntities.length
    }
  });
  return { removedEntities };
}
async function deleteRemovedEntities(client2, instanceType, entities) {
  const deletedEntities = [];
  const failedEntities = [];
  for (const entity of entities) try {
    if (instanceType === "radarr") await client2.deleteMovie(entity.id);
    else await client2.deleteSeries(entity.id);
    deletedEntities.push(entity);
  } catch (err) {
    const reason = err instanceof Error ? err.message : String(err);
    failedEntities.push({
      entity,
      reason
    });
  }
  return {
    deletedEntities,
    failedEntities
  };
}
function extractPreScanned(payload2) {
  const raw = payload2.preScanned;
  if (raw === void 0 || raw === null) return void 0;
  if (typeof raw !== "object") throw new Error("preScanned payload must be an object");
  const obj = raw;
  const staleConfigs = obj.staleConfigs;
  const removedEntities = obj.removedEntities;
  if (!staleConfigs || !Array.isArray(staleConfigs.staleCustomFormats) || !Array.isArray(staleConfigs.staleQualityProfiles)) throw new Error("preScanned.staleConfigs missing or malformed");
  if (!removedEntities || !Array.isArray(removedEntities.removedEntities)) throw new Error("preScanned.removedEntities missing or malformed");
  return {
    staleConfigs,
    removedEntities
  };
}
function rowToSettings2(row) {
  return {
    id: row.id,
    arrInstanceId: row.arr_instance_id,
    enabled: row.enabled === 1,
    cron: row.cron,
    nextRunAt: toUTC(row.next_run_at),
    createdAt: toUTC(row.created_at),
    updatedAt: toUTC(row.updated_at)
  };
}
function canonicalize(value2) {
  if (Array.isArray(value2)) return value2.map(canonicalize);
  if (value2 && typeof value2 === "object") {
    const record = value2;
    const result = {};
    for (const key2 of Object.keys(record).sort()) result[key2] = canonicalize(record[key2]);
    return result;
  }
  return value2;
}
function stringifyCanonical(value2) {
  return JSON.stringify(canonicalize(value2));
}
async function hashDriftDiff(diff) {
  const data = new TextEncoder().encode(stringifyCanonical(diff));
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  return Array.from(new Uint8Array(hashBuffer)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
}
function compareByString$1(a2, b3) {
  return a2.localeCompare(b3);
}
function fieldKey(field) {
  return field.name;
}
function specificationKey(specification) {
  return `${specification.implementation}:${specification.name}`;
}
function normalizeSpecification(specification) {
  return {
    name: specification.name,
    implementation: specification.implementation,
    negate: Boolean(specification.negate),
    required: Boolean(specification.required),
    fields: [...specification.fields ?? []].map((field) => ({
      name: field.name,
      value: field.value
    })).sort((a2, b3) => compareByString$1(fieldKey(a2), fieldKey(b3)))
  };
}
function normalizeCustomFormat(format) {
  return {
    name: format.name,
    includeCustomFormatWhenRenaming: Boolean(format.includeCustomFormatWhenRenaming),
    specifications: [...format.specifications ?? []].map(normalizeSpecification).sort((a2, b3) => compareByString$1(specificationKey(a2), specificationKey(b3)))
  };
}
function valuesEqual$3(expected, actual) {
  if ((expected === null || expected === void 0 || expected === false) && (actual === null || actual === void 0 || actual === false)) return true;
  return stringifyCanonical(expected) === stringifyCanonical(actual);
}
function isAbsentDefault(value2) {
  return value2 === null || value2 === void 0 || value2 === false;
}
function compareFields(expected, actual) {
  const diffs = [];
  const actualFields = new Map(actual.fields.map((field) => [fieldKey(field), field]));
  const expectedFields = new Map(expected.fields.map((field) => [fieldKey(field), field]));
  const specPath = `specifications[${specificationKey(expected)}]`;
  for (const expectedField of expected.fields) {
    const actualField = actualFields.get(fieldKey(expectedField));
    const path = `${specPath}.fields[${fieldKey(expectedField)}]`;
    if (!actualField) {
      if (isAbsentDefault(expectedField.value)) continue;
      diffs.push({
        path,
        expected: expectedField.value,
        actual: null
      });
      continue;
    }
    if (!valuesEqual$3(expectedField.value, actualField.value)) diffs.push({
      path,
      expected: expectedField.value,
      actual: actualField.value
    });
  }
  for (const actualField of actual.fields) {
    if (expectedFields.has(fieldKey(actualField))) continue;
    if (isAbsentDefault(actualField.value)) continue;
    diffs.push({
      path: `${specPath}.fields[${fieldKey(actualField)}]`,
      expected: null,
      actual: actualField.value
    });
  }
  return diffs;
}
function compareSpecifications(expected, actual) {
  const diffs = [];
  const actualSpecs = new Map(actual.specifications.map((spec) => [specificationKey(spec), spec]));
  const expectedSpecs = new Map(expected.specifications.map((spec) => [specificationKey(spec), spec]));
  for (const expectedSpec of expected.specifications) {
    const actualSpec = actualSpecs.get(specificationKey(expectedSpec));
    const specPath = `specifications[${specificationKey(expectedSpec)}]`;
    if (!actualSpec) {
      diffs.push({
        path: specPath,
        expected: expectedSpec,
        actual: null
      });
      continue;
    }
    if (expectedSpec.negate !== actualSpec.negate) diffs.push({
      path: `${specPath}.negate`,
      expected: expectedSpec.negate,
      actual: actualSpec.negate
    });
    if (expectedSpec.required !== actualSpec.required) diffs.push({
      path: `${specPath}.required`,
      expected: expectedSpec.required,
      actual: actualSpec.required
    });
    diffs.push(...compareFields(expectedSpec, actualSpec));
  }
  for (const actualSpec of actual.specifications) {
    if (expectedSpecs.has(specificationKey(actualSpec))) continue;
    diffs.push({
      path: `specifications[${specificationKey(actualSpec)}]`,
      expected: null,
      actual: actualSpec
    });
  }
  return diffs;
}
function compareCustomFormat(expected, actual) {
  const diffs = [];
  if (expected.includeCustomFormatWhenRenaming !== actual.includeCustomFormatWhenRenaming) diffs.push({
    path: "includeCustomFormatWhenRenaming",
    expected: expected.includeCustomFormatWhenRenaming,
    actual: actual.includeCustomFormatWhenRenaming
  });
  diffs.push(...compareSpecifications(expected, actual));
  return diffs;
}
function compareCustomFormatDrift(expectedFormats, actualFormats) {
  const actualByName = new Map(actualFormats.map((format) => [format.name, normalizeCustomFormat(format)]));
  const diff = {
    missing: [],
    modified: []
  };
  for (const expectedRaw of [...expectedFormats].sort((a2, b3) => compareByString$1(a2.name, b3.name))) {
    const expected = normalizeCustomFormat(expectedRaw);
    const actual = actualByName.get(expected.name);
    if (!actual) {
      diff.missing.push({ name: expected.name });
      continue;
    }
    const fields = compareCustomFormat(expected, actual);
    if (fields.length > 0) diff.modified.push({
      name: expected.name,
      fields
    });
  }
  return {
    count: diff.missing.length + diff.modified.length,
    diff
  };
}
async function buildExpectedCustomFormatsPerDatabase(instanceId, arrType) {
  const syncConfig = arrSyncQueries.getQualityProfilesSync(instanceId);
  const result = /* @__PURE__ */ new Map();
  if (syncConfig.selections.length === 0) return result;
  const selectionsByDb = /* @__PURE__ */ new Map();
  for (const selection of syncConfig.selections) {
    const existing = selectionsByDb.get(selection.databaseId) ?? [];
    existing.push(selection);
    selectionsByDb.set(selection.databaseId, existing);
  }
  for (const [databaseId, selections] of selectionsByDb) {
    const cache3 = getCache(databaseId);
    if (!cache3) throw new Error(`PCD cache not found for database ${databaseId}`);
    const databaseName = databaseInstancesQueries.getById(databaseId)?.name ?? `Database ${databaseId}`;
    const expected = /* @__PURE__ */ new Map();
    for (const selection of selections) {
      const formatNames = await getCustomFormatsForProfile(cache3, selection.profileName, arrType);
      for (const formatName of formatNames) {
        if (expected.has(formatName)) continue;
        const pcdFormat = await fetchCustomFormatFromPcd(cache3, formatName);
        if (!pcdFormat) throw new Error(`Custom format "${formatName}" not found in database ${databaseId}`);
        const arrFormat = transformCustomFormat(pcdFormat, arrType);
        arrFormat.name = formatName;
        expected.set(formatName, arrFormat);
      }
    }
    if (expected.size > 0) result.set(databaseId, {
      databaseName,
      formats: [...expected.values()]
    });
  }
  return result;
}
function compareCustomFormatDriftPerDatabase(perDb, actualFormats) {
  const diffs = [];
  let count = 0;
  for (const [databaseId, { databaseName, formats }] of perDb) {
    const result = compareCustomFormatDrift(formats, actualFormats);
    count += result.count;
    diffs.push({
      databaseId,
      databaseName,
      diff: result.diff
    });
  }
  return {
    count,
    diffs
  };
}
function valuesEqual$2(expected, actual) {
  return stringifyCanonical(expected) === stringifyCanonical(actual);
}
function protocol(profile) {
  if (profile.enableUsenet && profile.enableTorrent) {
    if (profile.preferredProtocol === "usenet") return "prefer_usenet";
    if (profile.preferredProtocol === "torrent") return "prefer_torrent";
    return "unknown";
  }
  if (profile.enableUsenet && !profile.enableTorrent) return profile.preferredProtocol === "usenet" ? "only_usenet" : "unknown";
  if (!profile.enableUsenet && profile.enableTorrent) return profile.preferredProtocol === "torrent" ? "only_torrent" : "unknown";
  return "unknown";
}
function normalizeProfile(profile) {
  return {
    id: profile.id,
    protocol: protocol(profile),
    usenetDelay: profile.usenetDelay ?? 0,
    torrentDelay: profile.torrentDelay ?? 0,
    bypassIfHighestQuality: Boolean(profile.bypassIfHighestQuality),
    bypassIfAboveCustomFormatScore: Boolean(profile.bypassIfAboveCustomFormatScore),
    minimumCustomFormatScore: profile.minimumCustomFormatScore ?? 0,
    order: profile.order,
    tags: [...profile.tags ?? []].sort((a2, b3) => a2 - b3)
  };
}
function compareProfiles(expected, actual) {
  const diffs = [];
  for (const field of FIELD_ORDER) if (!valuesEqual$2(expected[field], actual[field])) diffs.push({
    path: field,
    expected: expected[field],
    actual: actual[field]
  });
  return diffs;
}
function compareDelayProfileDrift(expected, actualProfiles) {
  const diff = {
    missing: [],
    modified: []
  };
  if (!expected) return {
    count: 0,
    diff
  };
  const actual = actualProfiles.find((profile) => profile.id === 1);
  if (!actual) {
    diff.missing.push({ name: expected.name });
    return {
      count: 1,
      diff
    };
  }
  const fields = compareProfiles(normalizeProfile(expected.profile), normalizeProfile(actual));
  if (fields.length > 0) diff.modified.push({
    name: expected.name,
    fields
  });
  return {
    count: diff.missing.length + diff.modified.length,
    diff
  };
}
async function buildExpectedDelayProfile(instanceId) {
  const syncConfig = arrSyncQueries.getDelayProfilesSync(instanceId);
  if (!syncConfig.databaseId || !syncConfig.profileName) return null;
  const cache3 = getCache(syncConfig.databaseId);
  if (!cache3) throw new Error(`PCD cache not found for database ${syncConfig.databaseId}`);
  const profile = await getByName(cache3, syncConfig.profileName);
  if (!profile) throw new Error(`Delay profile "${syncConfig.profileName}" not found in database ${syncConfig.databaseId}`);
  return {
    name: syncConfig.profileName,
    profile: transformDelayProfile(profile)
  };
}
async function checkDelayProfileDrift(client2, instanceId) {
  const expected = await buildExpectedDelayProfile(instanceId);
  if (!expected) return compareDelayProfileDrift(null, []);
  return compareDelayProfileDrift(expected, await client2.getDelayProfiles());
}
function emptyDiff() {
  return {
    media_settings: {
      missing: [],
      modified: []
    },
    naming: {
      missing: [],
      modified: []
    },
    quality_definitions: {
      missing: [],
      modified: []
    }
  };
}
function valuesEqual$12(expected, actual) {
  return stringifyCanonical(expected) === stringifyCanonical(actual);
}
function compareMediaSettings(expected, actual) {
  if (!actual) return null;
  const diffs = [];
  for (const field of MEDIA_SETTINGS_FIELD_ORDER) if (!valuesEqual$12(expected[field], actual[field])) diffs.push({
    path: field,
    expected: expected[field],
    actual: actual[field]
  });
  return diffs;
}
function fieldValue(fields, field) {
  return fields[field];
}
function compareNaming(expected, actual) {
  if (!actual) return null;
  const actualFields = normalizeNamingConfig(actual, expected.arrType);
  const diffs = [];
  for (const field of NAMING_FIELD_ORDER[expected.arrType]) {
    const expectedValue = fieldValue(expected.fields, field);
    const actualValue = fieldValue(actualFields, field);
    if (!valuesEqual$12(expectedValue, actualValue)) diffs.push({
      path: field,
      expected: expectedValue,
      actual: actualValue
    });
  }
  return diffs;
}
function compareQualityDefinitions(expected, actual, arrType) {
  if (!actual) return null;
  const actualMap = /* @__PURE__ */ new Map();
  for (const definition of actual) if (definition.quality.name) actualMap.set(definition.quality.name.toLowerCase(), definition);
  const diffs = [];
  for (const definition of expected.definitions) {
    const actualDefinition = actualMap.get(definition.qualityName.toLowerCase());
    if (!actualDefinition) continue;
    const actualFields = normalizeArrQualityDefinition(actualDefinition);
    if (actualFields.maxSize === QUALITY_DEFINITION_UNLIMITED_MAX[arrType]) actualFields.maxSize = null;
    for (const field of QUALITY_DEFINITION_FIELD_ORDER) {
      const expectedValue = definition.fields[field];
      const actualValue = actualFields[field];
      if (!valuesEqual$12(expectedValue, actualValue)) diffs.push({
        path: `qualityDefinitions[${definition.qualityName}].${field}`,
        expected: expectedValue,
        actual: actualValue
      });
    }
  }
  return diffs;
}
function compareMediaManagementDrift(expected, actual, expectedNaming = null, actualNaming = null, expectedQualityDefinitions = null, actualQualityDefinitions = null) {
  const diff = emptyDiff();
  if (expected) {
    const fields = compareMediaSettings(expected, actual);
    if (!fields) diff.media_settings.missing.push({ name: expected.name });
    else if (fields.length > 0) diff.media_settings.modified.push({
      name: expected.name,
      fields
    });
  }
  if (expectedNaming) {
    const fields = compareNaming(expectedNaming, actualNaming);
    if (!fields) diff.naming.missing.push({ name: expectedNaming.name });
    else if (fields.length > 0) diff.naming.modified.push({
      name: expectedNaming.name,
      fields
    });
  }
  if (expectedQualityDefinitions) {
    const fields = compareQualityDefinitions(expectedQualityDefinitions, actualQualityDefinitions, expectedQualityDefinitions.arrType ?? "radarr");
    if (!fields) diff.quality_definitions.missing.push({ name: expectedQualityDefinitions.name });
    else if (fields.length > 0) diff.quality_definitions.modified.push({
      name: expectedQualityDefinitions.name,
      fields
    });
  }
  return {
    count: diff.media_settings.missing.length + diff.media_settings.modified.length + diff.naming.missing.length + diff.naming.modified.length + diff.quality_definitions.missing.length + diff.quality_definitions.modified.length,
    diff
  };
}
async function buildExpectedMediaSettings(instanceId, arrType) {
  const syncConfig = arrSyncQueries.getMediaManagementSync(instanceId);
  if (!syncConfig.mediaSettingsDatabaseId || !syncConfig.mediaSettingsConfigName) return null;
  const cache3 = getCache(syncConfig.mediaSettingsDatabaseId);
  if (!cache3) throw new Error(`PCD cache not found for database ${syncConfig.mediaSettingsDatabaseId}`);
  const mediaSettings = await (arrType === "radarr" ? getRadarrByName$2 : getSonarrByName$2)(cache3, syncConfig.mediaSettingsConfigName);
  if (!mediaSettings) throw new Error(`Media settings "${syncConfig.mediaSettingsConfigName}" not found in database ${syncConfig.mediaSettingsDatabaseId}`);
  return {
    name: syncConfig.mediaSettingsConfigName,
    ...transformMediaSettings(mediaSettings)
  };
}
async function buildExpectedNaming(instanceId, arrType) {
  const syncConfig = arrSyncQueries.getMediaManagementSync(instanceId);
  if (!syncConfig.namingDatabaseId || !syncConfig.namingConfigName) return null;
  const cache3 = getCache(syncConfig.namingDatabaseId);
  if (!cache3) throw new Error(`PCD cache not found for database ${syncConfig.namingDatabaseId}`);
  const naming = await (arrType === "radarr" ? getRadarrByName$1 : getSonarrByName$1)(cache3, syncConfig.namingConfigName);
  if (!naming) throw new Error(`Naming config "${syncConfig.namingConfigName}" not found in database ${syncConfig.namingDatabaseId}`);
  return {
    name: syncConfig.namingConfigName,
    arrType,
    fields: transformNamingForDrift(naming, arrType)
  };
}
async function buildExpectedQualityDefinitions(instanceId, arrType) {
  const syncConfig = arrSyncQueries.getMediaManagementSync(instanceId);
  if (!syncConfig.qualityDefinitionsDatabaseId || !syncConfig.qualityDefinitionsConfigName) return null;
  const cache3 = getCache(syncConfig.qualityDefinitionsDatabaseId);
  if (!cache3) throw new Error(`PCD cache not found for database ${syncConfig.qualityDefinitionsDatabaseId}`);
  const qualityDefinitions = await (arrType === "radarr" ? getRadarrByName : getSonarrByName)(cache3, syncConfig.qualityDefinitionsConfigName);
  if (!qualityDefinitions) throw new Error(`Quality definitions "${syncConfig.qualityDefinitionsConfigName}" not found in database ${syncConfig.qualityDefinitionsDatabaseId}`);
  const apiMappings = await getQualityApiMappings(cache3, arrType);
  const { definitions } = transformQualityDefinitionsForArr(qualityDefinitions.entries, apiMappings);
  return {
    name: syncConfig.qualityDefinitionsConfigName,
    arrType,
    definitions
  };
}
async function checkMediaManagementDrift(client2, instanceId, arrType) {
  const [expectedMediaSettings, expectedNaming, expectedQualityDefinitions] = await Promise.all([
    buildExpectedMediaSettings(instanceId, arrType),
    buildExpectedNaming(instanceId, arrType),
    buildExpectedQualityDefinitions(instanceId, arrType)
  ]);
  if (!expectedMediaSettings && !expectedNaming && !expectedQualityDefinitions) return compareMediaManagementDrift(null, null);
  const [actualMediaSettings, actualNaming, actualQualityDefinitions] = await Promise.all([
    expectedMediaSettings ? client2.getMediaManagementConfig() : Promise.resolve(null),
    expectedNaming ? client2.getNamingConfig() : Promise.resolve(null),
    expectedQualityDefinitions ? client2.getQualityDefinitions() : Promise.resolve(null)
  ]);
  return compareMediaManagementDrift(expectedMediaSettings, actualMediaSettings, expectedNaming, actualNaming, expectedQualityDefinitions, actualQualityDefinitions);
}
function compareByString(a2, b3) {
  return a2.localeCompare(b3);
}
function valuesEqual2(expected, actual) {
  return stringifyCanonical(expected) === stringifyCanonical(actual);
}
function profileName(profile) {
  return profile.profile.name;
}
function formatItemById(formatItems) {
  return new Map((formatItems ?? []).map((item) => [item.format, item]));
}
function customFormatsByName(formats) {
  return new Map(formats.map((format) => [format.name, format]));
}
function customFormatsById(formats) {
  const map2 = /* @__PURE__ */ new Map();
  for (const format of formats) if (format.id !== void 0) map2.set(format.id, format);
  return map2;
}
function normalizeQualityItem(item, cutoff) {
  if (item.quality) return {
    type: "quality",
    id: item.quality.id,
    name: item.quality.name,
    allowed: Boolean(item.allowed),
    upgradeUntil: item.quality.id === cutoff
  };
  return {
    type: "group",
    id: item.id ?? 0,
    name: item.name ?? "",
    allowed: Boolean(item.allowed),
    upgradeUntil: (item.id ?? 0) === cutoff,
    items: (item.items ?? []).map((child) => normalizeQualityItem(child, cutoff))
  };
}
function normalizedItems(profile) {
  return (profile.items ?? []).map((item) => normalizeQualityItem(item, profile.cutoff));
}
function languageDiff(expected, actual, arrType) {
  if (arrType !== "radarr") return null;
  const expectedLanguage = expected.language ?? null;
  const actualLanguage = actual.language ?? null;
  if (valuesEqual2(expectedLanguage, actualLanguage)) return null;
  return {
    path: "language",
    expected: expectedLanguage,
    actual: actualLanguage
  };
}
function settingDiffs(expected, actual, arrType) {
  const diffs = [];
  for (const field of [
    "cutoffFormatScore",
    "minFormatScore",
    "minUpgradeFormatScore",
    "upgradeAllowed"
  ]) if (expected[field] !== actual[field]) diffs.push({
    path: field,
    expected: expected[field],
    actual: actual[field]
  });
  const language = languageDiff(expected, actual, arrType);
  if (language) diffs.push(language);
  return diffs;
}
function qualityItemsDiff(expected, actual) {
  const expectedItems = normalizedItems(expected);
  const actualItems = normalizedItems({
    items: actual.items ?? [],
    cutoff: actual.cutoff
  });
  if (valuesEqual2(expectedItems, actualItems)) return null;
  return {
    path: "items",
    expected: expectedItems,
    actual: actualItems
  };
}
function expectedFormatScore(expected, formatName) {
  const managedScore = expected.managedCustomFormatScores?.find((item) => item.name === formatName);
  if (managedScore) return managedScore.score;
  return expected.profile.formatItems.find((item) => item.name === formatName)?.score ?? 0;
}
function formatItemDiffs(expected, actual, actualCustomFormats) {
  const diffs = [];
  const formatsByName = customFormatsByName(actualCustomFormats);
  const formatsById = customFormatsById(actualCustomFormats);
  const actualItemsById = formatItemById(actual.formatItems);
  const managedNames = new Set(expected.managedCustomFormatNames);
  for (const formatName of [...managedNames].sort(compareByString)) {
    const expectedScore = expectedFormatScore(expected, formatName);
    const arrFormat = formatsByName.get(formatName);
    const path = `formatItems[${formatName}]`;
    const expectedValue = {
      name: formatName,
      score: expectedScore
    };
    if (!arrFormat || arrFormat.id === void 0) {
      diffs.push({
        path,
        expected: expectedValue,
        actual: {
          name: formatName,
          state: "missing_custom_format"
        }
      });
      continue;
    }
    const actualItem = actualItemsById.get(arrFormat.id);
    if (!actualItem) {
      diffs.push({
        path,
        expected: expectedValue,
        actual: null
      });
      continue;
    }
    if (actualItem.score !== expectedScore) diffs.push({
      path,
      expected: expectedValue,
      actual: {
        name: formatName,
        score: actualItem.score
      }
    });
  }
  const sortedActualItems = [...actual.formatItems ?? []].sort((a2, b3) => compareByString(a2.name, b3.name));
  for (const actualItem of sortedActualItems) {
    const name = formatsById.get(actualItem.format)?.name ?? actualItem.name;
    if (!name || managedNames.has(name) || actualItem.score === 0) continue;
    diffs.push({
      path: `formatItems[${name}]`,
      expected: {
        name,
        score: 0,
        state: "unmanaged"
      },
      actual: {
        name,
        score: actualItem.score
      }
    });
  }
  return diffs;
}
function compareProfile(expected, actual, actualCustomFormats, arrType) {
  const items = qualityItemsDiff(expected.profile, actual);
  return [
    ...settingDiffs(expected.profile, actual, arrType),
    ...items ? [items] : [],
    ...formatItemDiffs(expected, actual, actualCustomFormats)
  ].sort((a2, b3) => compareByString(a2.path, b3.path));
}
function compareQualityProfileDrift(expectedProfiles, actualProfiles, actualCustomFormats, arrType) {
  const actualByName = new Map(actualProfiles.map((profile) => [profile.name, profile]));
  const diff = {
    missing: [],
    modified: []
  };
  for (const expected of [...expectedProfiles].sort((a2, b3) => compareByString(profileName(a2), profileName(b3)))) {
    const actual = actualByName.get(expected.profile.name);
    if (!actual) {
      diff.missing.push({ name: expected.profile.name });
      continue;
    }
    const fields = compareProfile(expected, actual, actualCustomFormats, arrType);
    if (fields.length > 0) diff.modified.push({
      name: expected.profile.name,
      fields
    });
  }
  return {
    count: diff.missing.length + diff.modified.length,
    diff
  };
}
async function buildExpectedQualityProfilesPerDatabase(instanceId, arrType, actualCustomFormats) {
  const syncConfig = arrSyncQueries.getQualityProfilesSync(instanceId);
  const result = /* @__PURE__ */ new Map();
  if (syncConfig.selections.length === 0) return result;
  const formatIdMap = /* @__PURE__ */ new Map();
  for (const format of actualCustomFormats) if (format.id !== void 0) formatIdMap.set(format.name, format.id);
  const selectionsByDb = /* @__PURE__ */ new Map();
  for (const selection of syncConfig.selections) {
    const existing = selectionsByDb.get(selection.databaseId) ?? [];
    existing.push(selection);
    selectionsByDb.set(selection.databaseId, existing);
  }
  for (const [databaseId, selections] of selectionsByDb) {
    const cache3 = getCache(databaseId);
    if (!cache3) throw new Error(`PCD cache not found for database ${databaseId}`);
    const databaseName = databaseInstancesQueries.getById(databaseId)?.name ?? `Database ${databaseId}`;
    const profiles = [];
    for (const selection of selections) {
      const pcdProfile = await fetchQualityProfileFromPcd(cache3, selection.profileName, arrType);
      if (!pcdProfile) throw new Error(`Quality profile "${selection.profileName}" not found in database ${databaseId}`);
      const [qualityMappings, managedCustomFormatNames] = await Promise.all([getQualityApiMappings(cache3, arrType), getCustomFormatsForProfile(cache3, selection.profileName, arrType)]);
      const profile = transformQualityProfile(pcdProfile, arrType, qualityMappings, formatIdMap);
      profile.name = pcdProfile.name;
      profiles.push({
        profile,
        managedCustomFormatNames,
        managedCustomFormatScores: pcdProfile.customFormats.map((format) => ({
          name: format.formatName,
          score: format.score
        }))
      });
    }
    if (profiles.length > 0) result.set(databaseId, {
      databaseName,
      profiles
    });
  }
  return result;
}
function compareQualityProfileDriftPerDatabase(perDb, actualProfiles, actualCustomFormats, arrType) {
  const diffs = [];
  let count = 0;
  for (const [databaseId, { databaseName, profiles }] of perDb) {
    const result = compareQualityProfileDrift(profiles, actualProfiles, actualCustomFormats, arrType);
    count += result.count;
    diffs.push({
      databaseId,
      databaseName,
      diff: result.diff
    });
  }
  return {
    count,
    diffs
  };
}
async function checkArrDrift(client2, instanceId, arrType) {
  const [expectedCfPerDb, actualCustomFormats, delayProfiles, mediaManagement] = await Promise.all([
    buildExpectedCustomFormatsPerDatabase(instanceId, arrType),
    client2.getCustomFormats(),
    checkDelayProfileDrift(client2, instanceId),
    checkMediaManagementDrift(client2, instanceId, arrType)
  ]);
  const customFormats = compareCustomFormatDriftPerDatabase(expectedCfPerDb, actualCustomFormats);
  const [expectedQpPerDb, actualProfiles] = await Promise.all([buildExpectedQualityProfilesPerDatabase(instanceId, arrType, actualCustomFormats), client2.getQualityProfiles()]);
  const qualityProfiles = compareQualityProfileDriftPerDatabase(expectedQpPerDb, actualProfiles, actualCustomFormats, arrType);
  const counts = {
    custom_formats: customFormats.count,
    quality_profiles: qualityProfiles.count,
    delay_profiles: delayProfiles.count,
    media_management: mediaManagement.count
  };
  const diff = {
    custom_formats: customFormats.diffs,
    quality_profiles: qualityProfiles.diffs,
    delay_profiles: delayProfiles.diff,
    media_management: mediaManagement.diff
  };
  return {
    status: Object.values(counts).reduce((sum, count) => sum + (count ?? 0), 0) === 0 ? "clean" : "drift_detected",
    counts,
    diff,
    diffHash: await hashDriftDiff(diff)
  };
}
function buildDriftDisplayEntities(diff, arrType, duplicateDriftLookup = /* @__PURE__ */ new Map()) {
  const syncArrType = arrType === "radarr" || arrType === "sonarr" ? arrType : void 0;
  return [
    ...buildCustomFormatEntities(diff.custom_formats, syncArrType, duplicateDriftLookup),
    ...buildQualityProfileEntities(diff.quality_profiles, syncArrType, duplicateDriftLookup),
    ...buildDelayProfileEntities(diff.delay_profiles),
    ...buildMediaManagementEntities(diff.media_management)
  ];
}
async function buildDriftDisplayEntitiesForInstance(diff, arrType, instanceId) {
  const syncArrType = arrType === "radarr" || arrType === "sonarr" ? arrType : void 0;
  if (!syncArrType) return buildDriftDisplayEntities(diff, arrType);
  try {
    return buildDriftDisplayEntities(diff, arrType, await buildDuplicateDriftLookup(instanceId, syncArrType));
  } catch {
    return buildDriftDisplayEntities(diff, arrType);
  }
}
async function buildDuplicateDriftLookup(instanceId, arrType) {
  const lookup = /* @__PURE__ */ new Map();
  const priorities = new Map(arrSyncQueries.getDatabasePriorities(instanceId).map((row) => [row.databaseId, row.priority]));
  const getDatabaseName = (databaseId) => databaseInstancesQueries.getById(databaseId)?.name ?? `Database ${databaseId}`;
  addDuplicateCandidates(lookup, "quality_profiles", arrSyncQueries.getQualityProfilesSync(instanceId).selections.map((selection) => ({
    databaseId: selection.databaseId,
    databaseName: getDatabaseName(selection.databaseId),
    name: selection.profileName
  })), priorities);
  try {
    const perDbFormats = await buildExpectedCustomFormatsPerDatabase(instanceId, arrType);
    const customFormatCandidates = [];
    for (const [databaseId, { databaseName, formats }] of perDbFormats) for (const format of formats) customFormatCandidates.push({
      databaseId,
      databaseName,
      name: format.name
    });
    addDuplicateCandidates(lookup, "custom_formats", customFormatCandidates, priorities);
  } catch {
  }
  return lookup;
}
function addDuplicateCandidates(lookup, section, candidates, priorities) {
  const byName = /* @__PURE__ */ new Map();
  for (const candidate of candidates) {
    const entries = byName.get(candidate.name) ?? /* @__PURE__ */ new Map();
    entries.set(candidate.databaseId, candidate);
    byName.set(candidate.name, entries);
  }
  for (const [name, entries] of byName) {
    const sorted = [...entries.values()].sort((a2, b3) => priorityFor(a2.databaseId, priorities) - priorityFor(b3.databaseId, priorities) || a2.databaseId - b3.databaseId);
    if (sorted.length < 2) continue;
    const winner = sorted[0];
    for (const candidate of sorted.slice(1)) lookup.set(duplicateLookupKey(section, candidate.databaseId, name), {
      reason: "lower_priority_duplicate",
      key: `${section}:${name}`,
      winnerDatabaseId: winner.databaseId,
      winnerDatabaseName: winner.databaseName
    });
  }
}
function priorityFor(databaseId, priorities) {
  return priorities.get(databaseId) ?? Number.MAX_SAFE_INTEGER;
}
function duplicateLookupKey(section, databaseId, name) {
  return `${section}:${databaseId}:${name}`;
}
function buildCustomFormatEntities(raw, arrType, duplicateDriftLookup) {
  if (Array.isArray(raw)) {
    const entities = [];
    for (const entry of raw) {
      if (!isRecord(entry)) continue;
      const databaseId = recordNumber(entry, "databaseId");
      const databaseName = recordString(entry, "databaseName");
      const diff2 = asCustomFormatDiff(entry.diff);
      if (!diff2) continue;
      entities.push(...buildCustomFormatDiffEntities(diff2, arrType, duplicateDriftLookup, databaseId, databaseName));
    }
    return entities;
  }
  const diff = asCustomFormatDiff(raw);
  if (!diff) return [];
  return buildCustomFormatDiffEntities(diff, arrType, duplicateDriftLookup);
}
function buildCustomFormatDiffEntities(diff, arrType, duplicateDriftLookup, databaseId, databaseName) {
  const entities = [];
  const idPrefix = databaseId != null ? `custom_formats:${databaseId}` : "custom_formats";
  for (const item of diff.missing ?? []) {
    const name = recordString(item, "name");
    if (!name) continue;
    entities.push({
      id: `${idPrefix}:missing:${name}`,
      section: "custom_formats",
      sectionLabel: "Custom Format",
      title: name,
      databaseId: databaseId ?? void 0,
      databaseName: databaseName ?? void 0,
      state: "missing",
      stateLabel: "Missing",
      tone: "danger",
      summary: "Profilarr expects this custom format, but Arr does not have it.",
      changes: [{
        id: `${idPrefix}:missing:${name}:format`,
        label: "Custom format",
        detail: "Missing from Arr",
        expected: value("Present"),
        actual: value("Missing", { tone: "danger" }),
        tone: "danger"
      }],
      duplicateDrift: databaseId != null ? duplicateDriftLookup.get(duplicateLookupKey("custom_formats", databaseId, name)) : void 0
    });
  }
  for (const item of diff.modified ?? []) {
    const modified = asModifiedCustomFormat(item);
    if (!modified) continue;
    if (modified.fields.length === 0) continue;
    const changes = modified.fields.map((field, index88) => formatCustomFormatFieldDiff(field, index88, arrType));
    entities.push({
      id: `${idPrefix}:modified:${modified.name}`,
      section: "custom_formats",
      sectionLabel: "Custom Format",
      title: modified.name,
      databaseId: databaseId ?? void 0,
      databaseName: databaseName ?? void 0,
      state: "modified",
      stateLabel: "Modified",
      tone: "warning",
      summary: `${changes.length} ${changes.length === 1 ? "change" : "changes"} detected`,
      changes,
      duplicateDrift: databaseId != null ? duplicateDriftLookup.get(duplicateLookupKey("custom_formats", databaseId, modified.name)) : void 0
    });
  }
  return entities;
}
function buildQualityProfileEntities(raw, arrType, duplicateDriftLookup) {
  if (Array.isArray(raw)) {
    const entities = [];
    for (const entry of raw) {
      if (!isRecord(entry)) continue;
      const databaseId = recordNumber(entry, "databaseId");
      const databaseName = recordString(entry, "databaseName");
      const diff2 = asQualityProfileDiff(entry.diff);
      if (!diff2) continue;
      entities.push(...buildQualityProfileDiffEntities(diff2, arrType, duplicateDriftLookup, databaseId, databaseName));
    }
    return entities;
  }
  const diff = asQualityProfileDiff(raw);
  if (!diff) return [];
  return buildQualityProfileDiffEntities(diff, arrType, duplicateDriftLookup);
}
function buildQualityProfileDiffEntities(diff, arrType, duplicateDriftLookup, databaseId, databaseName) {
  const entities = [];
  const idPrefix = databaseId != null ? `quality_profiles:${databaseId}` : "quality_profiles";
  for (const item of diff.missing ?? []) {
    const name = recordString(item, "name");
    if (!name) continue;
    entities.push({
      id: `${idPrefix}:missing:${name}`,
      section: "quality_profiles",
      sectionLabel: "Quality Profile",
      title: name,
      databaseId: databaseId ?? void 0,
      databaseName: databaseName ?? void 0,
      state: "missing",
      stateLabel: "Missing",
      tone: "danger",
      summary: "Profilarr expects this quality profile, but Arr does not have it.",
      changes: [{
        id: `${idPrefix}:missing:${name}:profile`,
        label: "Quality profile",
        detail: "Missing from Arr",
        expected: value("Present"),
        actual: value("Missing", { tone: "danger" }),
        tone: "danger"
      }],
      duplicateDrift: databaseId != null ? duplicateDriftLookup.get(duplicateLookupKey("quality_profiles", databaseId, name)) : void 0
    });
  }
  for (const item of diff.modified ?? []) {
    const modified = asModifiedQualityProfile(item);
    if (!modified) continue;
    if (modified.fields.length === 0) continue;
    const changes = modified.fields.map((field, index88) => formatQualityProfileFieldDiff(field, index88, arrType));
    entities.push({
      id: `${idPrefix}:modified:${modified.name}`,
      section: "quality_profiles",
      sectionLabel: "Quality Profile",
      title: modified.name,
      databaseId: databaseId ?? void 0,
      databaseName: databaseName ?? void 0,
      state: "modified",
      stateLabel: "Modified",
      tone: "warning",
      summary: `${changes.length} ${changes.length === 1 ? "change" : "changes"} detected`,
      changes,
      duplicateDrift: databaseId != null ? duplicateDriftLookup.get(duplicateLookupKey("quality_profiles", databaseId, modified.name)) : void 0
    });
  }
  return entities;
}
function buildDelayProfileEntities(raw) {
  const diff = asDelayProfileDiff(raw);
  if (!diff) return [];
  const entities = [];
  for (const item of diff.missing ?? []) {
    const name = recordString(item, "name");
    if (!name) continue;
    entities.push({
      id: `delay_profiles:missing:${name}`,
      section: "delay_profiles",
      sectionLabel: "Delay Profile",
      title: name,
      state: "missing",
      stateLabel: "Missing",
      tone: "danger",
      summary: "Profilarr expects this delay profile on Arr default profile, but Arr does not have it.",
      changes: [{
        id: `delay_profiles:missing:${name}:profile`,
        label: "Delay profile",
        detail: "Default profile missing from Arr",
        expected: value("Present"),
        actual: value("Missing", { tone: "danger" }),
        tone: "danger"
      }]
    });
  }
  for (const item of diff.modified ?? []) {
    const modified = asModifiedDelayProfile(item);
    if (!modified) continue;
    if (modified.fields.length === 0) continue;
    const changes = modified.fields.map(formatDelayProfileFieldDiff);
    entities.push({
      id: `delay_profiles:modified:${modified.name}`,
      section: "delay_profiles",
      sectionLabel: "Delay Profile",
      title: modified.name,
      state: "modified",
      stateLabel: "Modified",
      tone: "warning",
      summary: `${changes.length} ${changes.length === 1 ? "change" : "changes"} detected`,
      changes
    });
  }
  return entities;
}
function buildMediaManagementEntities(raw) {
  const diff = asMediaManagementDiff(raw);
  if (!diff) return [];
  const entities = [];
  for (const item of diff.media_settings.missing ?? []) {
    const name = recordString(item, "name");
    if (!name) continue;
    entities.push({
      id: `media_management:media_settings:missing:${name}`,
      section: "media_management",
      sectionLabel: "Media Management",
      title: `Media Settings: ${name}`,
      state: "missing",
      stateLabel: "Missing",
      tone: "danger",
      summary: "Profilarr expects this media settings config, but Arr does not have it.",
      changes: [{
        id: `media-management-media-settings-missing:${name}:config`,
        label: "Media Settings",
        detail: "Missing from Arr",
        expected: value("Present"),
        actual: value("Missing", { tone: "danger" }),
        tone: "danger"
      }]
    });
  }
  for (const item of diff.media_settings.modified ?? []) {
    const modified = asModifiedMediaSettings(item);
    if (!modified) continue;
    if (modified.fields.length === 0) continue;
    const changes = modified.fields.map(formatMediaSettingsFieldDiff);
    entities.push({
      id: `media_management:media_settings:modified:${modified.name}`,
      section: "media_management",
      sectionLabel: "Media Management",
      title: `Media Settings: ${modified.name}`,
      state: "modified",
      stateLabel: "Modified",
      tone: "warning",
      summary: `${changes.length} ${changes.length === 1 ? "change" : "changes"} detected`,
      changes
    });
  }
  for (const item of diff.naming.missing ?? []) {
    const name = recordString(item, "name");
    if (!name) continue;
    entities.push({
      id: `media_management:naming:missing:${name}`,
      section: "media_management",
      sectionLabel: "Media Management",
      title: `Naming: ${name}`,
      state: "missing",
      stateLabel: "Missing",
      tone: "danger",
      summary: "Profilarr expects this naming config, but Arr does not have it.",
      changes: [{
        id: `media-management-naming-missing:${name}:config`,
        label: "Naming",
        detail: "Missing from Arr",
        expected: value("Present"),
        actual: value("Missing", { tone: "danger" }),
        tone: "danger"
      }]
    });
  }
  for (const item of diff.naming.modified ?? []) {
    const modified = asModifiedNaming(item);
    if (!modified) continue;
    if (modified.fields.length === 0) continue;
    const changes = modified.fields.map(formatNamingFieldDiff);
    entities.push({
      id: `media_management:naming:modified:${modified.name}`,
      section: "media_management",
      sectionLabel: "Media Management",
      title: `Naming: ${modified.name}`,
      state: "modified",
      stateLabel: "Modified",
      tone: "warning",
      summary: `${changes.length} ${changes.length === 1 ? "change" : "changes"} detected`,
      changes
    });
  }
  for (const item of diff.quality_definitions.missing ?? []) {
    const name = recordString(item, "name");
    if (!name) continue;
    entities.push({
      id: `media_management:quality_definitions:missing:${name}`,
      section: "media_management",
      sectionLabel: "Media Management",
      title: `Quality Definitions: ${name}`,
      state: "missing",
      stateLabel: "Missing",
      tone: "danger",
      summary: "Profilarr expects this quality definitions config, but Arr does not have it.",
      changes: [{
        id: `media-management-quality-definitions-missing:${name}:config`,
        label: "Quality definitions",
        detail: "Missing from Arr",
        expected: value("Present"),
        actual: value("Missing", { tone: "danger" }),
        tone: "danger"
      }]
    });
  }
  for (const item of diff.quality_definitions.modified ?? []) {
    const modified = asModifiedQualityDefinitions(item);
    if (!modified) continue;
    if (modified.fields.length === 0) continue;
    const changes = modified.fields.map(formatQualityDefinitionFieldDiff);
    entities.push({
      id: `media_management:quality_definitions:modified:${modified.name}`,
      section: "media_management",
      sectionLabel: "Media Management",
      title: `Quality Definitions: ${modified.name}`,
      state: "modified",
      stateLabel: "Modified",
      tone: "warning",
      summary: `${changes.length} ${changes.length === 1 ? "change" : "changes"} detected`,
      changes
    });
  }
  return entities;
}
function formatQualityProfileFieldDiff(field, index88, arrType) {
  const formatMatch = /^formatItems\[(.+)\]$/.exec(field.path);
  if (formatMatch) {
    const formatName = formatMatch[1];
    const actualState = recordString(field.actual, "state");
    const isMissing = field.actual === null || actualState === "missing_custom_format";
    const isExtra = recordString(field.expected, "state") === "unmanaged";
    let detail = `${formatName} score changed`;
    if (isExtra) detail = `${formatName} has an unmanaged nonzero score`;
    else if (actualState === "missing_custom_format") detail = `${formatName} custom format is missing from Arr`;
    else if (isMissing) detail = `${formatName} is missing from scoring`;
    return {
      id: `quality-profile-format-item:${index88}`,
      label: "Custom format score",
      detail,
      expected: formatQualityProfileFormatItemValue(field.expected),
      actual: formatQualityProfileFormatItemValue(field.actual),
      tone: isMissing ? "danger" : "warning"
    };
  }
  if (field.path === "items") return {
    id: `quality-profile-items:${index88}`,
    label: "Qualities",
    detail: "Quality list differs from Profilarr expected layout",
    expected: formatQualityItemsValue(field.expected),
    actual: formatQualityItemsValue(field.actual),
    tone: "warning"
  };
  if (field.path === "language") return {
    id: `quality-profile-language:${index88}`,
    label: "Language",
    detail: "Profile language changed",
    expected: formatLanguageValue(field.expected, arrType),
    actual: formatLanguageValue(field.actual, arrType),
    tone: "warning"
  };
  if (field.path === "upgradeAllowed") return {
    id: `quality-profile-upgrade-allowed:${index88}`,
    label: "Upgrade Allowed",
    detail: "Upgrade behavior changed",
    expected: formatBooleanValue(field.expected),
    actual: formatBooleanValue(field.actual),
    tone: "warning"
  };
  return {
    id: `quality-profile-field:${index88}`,
    label: qualityProfileFieldLabel(field.path),
    detail: "Profile setting changed",
    expected: formatGenericValue(field.expected),
    actual: formatGenericValue(field.actual),
    tone: field.actual === null || field.actual === void 0 ? "danger" : "warning"
  };
}
function formatDelayProfileFieldDiff(field, index88) {
  if (field.path === "protocol") return {
    id: `delay-profile-protocol:${index88}`,
    label: "Protocol",
    detail: "Protocol preference changed",
    expected: formatDelayProtocolValue(field.expected),
    actual: formatDelayProtocolValue(field.actual),
    tone: "warning"
  };
  if (field.path === "usenetDelay" || field.path === "torrentDelay") return {
    id: `delay-profile-delay:${index88}`,
    label: delayProfileFieldLabel(field.path),
    detail: "Delay changed",
    expected: formatMinutesValue(field.expected),
    actual: formatMinutesValue(field.actual),
    tone: "warning"
  };
  if (field.path === "bypassIfHighestQuality" || field.path === "bypassIfAboveCustomFormatScore") return {
    id: `delay-profile-bypass:${index88}`,
    label: delayProfileFieldLabel(field.path),
    detail: "Bypass behavior changed",
    expected: formatBooleanValue(field.expected),
    actual: formatBooleanValue(field.actual),
    tone: "warning"
  };
  if (field.path === "minimumCustomFormatScore") return {
    id: `delay-profile-minimum-score:${index88}`,
    label: "Minimum Custom Format Score",
    detail: "Bypass score threshold changed",
    expected: formatGenericValue(field.expected),
    actual: formatGenericValue(field.actual),
    tone: "warning"
  };
  if (field.path === "tags") return {
    id: `delay-profile-tags:${index88}`,
    label: "Tags",
    detail: "Default profile tags changed",
    expected: formatTagIdsValue(field.expected),
    actual: formatTagIdsValue(field.actual),
    tone: "warning"
  };
  return {
    id: `delay-profile-field:${index88}`,
    label: delayProfileFieldLabel(field.path),
    detail: "Delay profile setting changed",
    expected: formatGenericValue(field.expected),
    actual: formatGenericValue(field.actual),
    tone: field.actual === null || field.actual === void 0 ? "danger" : "warning"
  };
}
function formatMediaSettingsFieldDiff(field, index88) {
  if (field.path === "downloadPropersAndRepacks") return {
    id: `media-settings-propers-repacks:${index88}`,
    label: "Propers and Repacks",
    detail: "Propers and repacks preference changed",
    expected: formatPropersRepacksValue(field.expected),
    actual: formatPropersRepacksValue(field.actual),
    tone: "warning"
  };
  if (field.path === "enableMediaInfo") return {
    id: `media-settings-enable-media-info:${index88}`,
    label: "Enable Media Info",
    detail: "Media info parsing changed",
    expected: formatBooleanValue(field.expected),
    actual: formatBooleanValue(field.actual),
    tone: "warning"
  };
  return {
    id: `media-settings-field:${index88}`,
    label: titleize(field.path),
    detail: "Media setting changed",
    expected: formatGenericValue(field.expected),
    actual: formatGenericValue(field.actual),
    tone: field.actual === null || field.actual === void 0 ? "danger" : "warning"
  };
}
function formatNamingFieldDiff(field, index88) {
  return {
    id: `naming-field:${index88}`,
    label: namingFieldLabel(field.path),
    detail: "Naming setting changed",
    expected: formatNamingValue(field.path, field.expected),
    actual: formatNamingValue(field.path, field.actual),
    tone: field.actual === null || field.actual === void 0 ? "danger" : "warning"
  };
}
function formatQualityDefinitionFieldDiff(field, index88) {
  const parsed = parseQualityDefinitionPath(field.path);
  const qualityName = parsed?.qualityName ?? "Quality definition";
  const label = parsed ? qualityDefinitionFieldLabel(parsed.field) : qualityDefinitionFieldLabel(field.path);
  return {
    id: `quality-definition-field:${index88}`,
    label: qualityName,
    detail: `${label} changed`,
    expected: formatQualityDefinitionValue(parsed?.field ?? field.path, field.expected),
    actual: formatQualityDefinitionValue(parsed?.field ?? field.path, field.actual),
    tone: "warning"
  };
}
function asQualityItems(raw) {
  if (!Array.isArray(raw)) return null;
  const items = [];
  for (const item of raw) {
    const parsed = asQualityItem(item);
    if (!parsed) return null;
    items.push(parsed);
  }
  return items;
}
function asQualityItem(raw) {
  if (!isRecord(raw)) return null;
  const type = recordString(raw, "type");
  const name = recordString(raw, "name");
  if (type !== "quality" && type !== "group" || !name || typeof raw.id !== "number") return null;
  const item = {
    type,
    id: raw.id,
    name,
    allowed: raw.allowed !== false,
    upgradeUntil: raw.upgradeUntil === true
  };
  if (type === "group") item.items = asQualityItems(raw.items) ?? [];
  return item;
}
function formatCustomFormatFieldDiff(field, index88, arrType) {
  if (field.path === "includeCustomFormatWhenRenaming") return {
    id: `include-in-rename:${index88}`,
    label: "Include in Rename",
    detail: "Rename behavior changed",
    expected: formatBooleanValue(field.expected),
    actual: formatBooleanValue(field.actual),
    tone: "warning"
  };
  const specPath = parseSpecificationPath(field.path);
  if (!specPath) return {
    id: `custom-format-field:${index88}`,
    label: "Custom format setting",
    detail: "Value changed",
    expected: formatGenericValue(field.expected),
    actual: formatGenericValue(field.actual),
    tone: field.actual === null || field.actual === void 0 ? "danger" : "warning"
  };
  const label = `${implementationLabel(specPath.implementation)} condition: ${specPath.name}`;
  if (!specPath.member && !specPath.field) return formatSpecificationChange(label, field, arrType, index88);
  if (specPath.member === "negate") return {
    id: `condition-negate:${index88}`,
    label,
    detail: "Match mode changed",
    expected: formatNegateValue(field.expected),
    actual: formatNegateValue(field.actual),
    tone: "warning"
  };
  if (specPath.member === "required") return {
    id: `condition-required:${index88}`,
    label,
    detail: "Requirement changed",
    expected: formatRequiredValue(field.expected),
    actual: formatRequiredValue(field.actual),
    tone: "warning"
  };
  if (specPath.field) return {
    id: `condition-field:${index88}`,
    label,
    detail: `${fieldLabel(specPath.implementation, specPath.field)} changed`,
    expected: formatFieldValue(specPath.implementation, specPath.field, field.expected, arrType),
    actual: formatFieldValue(specPath.implementation, specPath.field, field.actual, arrType),
    tone: field.actual === null || field.actual === void 0 ? "danger" : "warning"
  };
  return {
    id: `condition-setting:${index88}`,
    label,
    detail: "Condition setting changed",
    expected: formatGenericValue(field.expected),
    actual: formatGenericValue(field.actual),
    tone: "warning"
  };
}
function formatSpecificationChange(label, field, arrType, index88) {
  if (field.actual === null || field.actual === void 0) return {
    id: `condition-missing:${index88}`,
    label,
    detail: "Condition is missing from Arr",
    expected: formatSpecificationValue(field.expected, arrType),
    actual: value("Missing", { tone: "danger" }),
    tone: "danger"
  };
  if (field.expected === null || field.expected === void 0) return {
    id: `condition-extra:${index88}`,
    label,
    detail: "Extra condition exists in Arr",
    expected: value("Not present"),
    actual: formatSpecificationValue(field.actual, arrType),
    tone: "warning"
  };
  return {
    id: `condition-changed:${index88}`,
    label,
    detail: "Condition changed",
    expected: formatSpecificationValue(field.expected, arrType),
    actual: formatSpecificationValue(field.actual, arrType),
    tone: "warning"
  };
}
function parseSpecificationPath(path) {
  const match = /^specifications\[([^:\]]+):(.+?)\](?:\.(.+))?$/.exec(path);
  if (!match) return null;
  const tail = match[3];
  const parsed = {
    implementation: match[1],
    name: match[2]
  };
  if (!tail) return parsed;
  const fieldMatch = /^fields\[(.+)\]$/.exec(tail);
  if (fieldMatch) {
    parsed.field = fieldMatch[1];
    return parsed;
  }
  parsed.member = tail;
  return parsed;
}
function asCustomFormatDiff(raw) {
  if (!isRecord(raw)) return null;
  return {
    missing: Array.isArray(raw.missing) ? raw.missing : [],
    modified: Array.isArray(raw.modified) ? raw.modified : []
  };
}
function asQualityProfileDiff(raw) {
  if (!isRecord(raw)) return null;
  return {
    missing: Array.isArray(raw.missing) ? raw.missing : [],
    modified: Array.isArray(raw.modified) ? raw.modified : []
  };
}
function asDelayProfileDiff(raw) {
  if (!isRecord(raw)) return null;
  return {
    missing: Array.isArray(raw.missing) ? raw.missing : [],
    modified: Array.isArray(raw.modified) ? raw.modified : []
  };
}
function asMediaManagementDiff(raw) {
  if (!isRecord(raw)) return null;
  const mediaSettings = isRecord(raw.media_settings) ? raw.media_settings : {};
  const naming = isRecord(raw.naming) ? raw.naming : {};
  const qualityDefinitions = isRecord(raw.quality_definitions) ? raw.quality_definitions : {};
  return {
    media_settings: {
      missing: Array.isArray(mediaSettings.missing) ? mediaSettings.missing : [],
      modified: Array.isArray(mediaSettings.modified) ? mediaSettings.modified : []
    },
    naming: {
      missing: Array.isArray(naming.missing) ? naming.missing : [],
      modified: Array.isArray(naming.modified) ? naming.modified : []
    },
    quality_definitions: {
      missing: Array.isArray(qualityDefinitions.missing) ? qualityDefinitions.missing : [],
      modified: Array.isArray(qualityDefinitions.modified) ? qualityDefinitions.modified : []
    }
  };
}
function asModifiedCustomFormat(raw) {
  if (!isRecord(raw)) return null;
  const name = recordString(raw, "name");
  if (!name || !Array.isArray(raw.fields)) return null;
  return {
    name,
    fields: raw.fields.filter(isFieldDiff)
  };
}
function asModifiedQualityProfile(raw) {
  if (!isRecord(raw)) return null;
  const name = recordString(raw, "name");
  if (!name || !Array.isArray(raw.fields)) return null;
  return {
    name,
    fields: raw.fields.filter(isFieldDiff)
  };
}
function asModifiedDelayProfile(raw) {
  if (!isRecord(raw)) return null;
  const name = recordString(raw, "name");
  if (!name || !Array.isArray(raw.fields)) return null;
  return {
    name,
    fields: raw.fields.filter(isFieldDiff)
  };
}
function asModifiedMediaSettings(raw) {
  if (!isRecord(raw)) return null;
  const name = recordString(raw, "name");
  if (!name || !Array.isArray(raw.fields)) return null;
  return {
    name,
    fields: raw.fields.filter(isFieldDiff)
  };
}
function asModifiedNaming(raw) {
  if (!isRecord(raw)) return null;
  const name = recordString(raw, "name");
  if (!name || !Array.isArray(raw.fields)) return null;
  return {
    name,
    fields: raw.fields.filter(isFieldDiff)
  };
}
function asModifiedQualityDefinitions(raw) {
  if (!isRecord(raw)) return null;
  const name = recordString(raw, "name");
  if (!name || !Array.isArray(raw.fields)) return null;
  return {
    name,
    fields: raw.fields.filter(isQualityDefinitionFieldDiff)
  };
}
function isQualityDefinitionFieldDiff(raw) {
  return isRecord(raw) && typeof raw.path === "string" && Object.hasOwn(raw, "expected");
}
function isFieldDiff(raw) {
  return isRecord(raw) && typeof raw.path === "string" && Object.hasOwn(raw, "expected") && Object.hasOwn(raw, "actual");
}
function asSpecificationValue(raw) {
  if (!isRecord(raw)) return null;
  if (typeof raw.name !== "string" || typeof raw.implementation !== "string") return null;
  return {
    name: raw.name,
    implementation: raw.implementation,
    negate: Boolean(raw.negate),
    required: Boolean(raw.required),
    fields: Array.isArray(raw.fields) ? raw.fields.flatMap((field) => {
      if (!isRecord(field) || typeof field.name !== "string") return [];
      return [{
        name: field.name,
        value: field.value
      }];
    }) : []
  };
}
function formatSpecificationValue(raw, arrType) {
  const spec = asSpecificationValue(raw);
  if (!spec) return formatGenericValue(raw);
  const fields = spec.fields.map((field) => {
    const formatted = formatFieldValue(spec.implementation, field.name, field.value, arrType);
    return `${fieldLabel(spec.implementation, field.name)}: ${formatted.text}`;
  });
  const modes = [spec.required ? "Required" : "Optional", spec.negate ? "Must not match" : "Must match"];
  const suffix = [...fields, ...modes].join(", ");
  return value(`${implementationLabel(spec.implementation)}: ${spec.name}${suffix ? ` (${suffix})` : ""}`);
}
function formatFieldValue(implementation, field, raw, arrType) {
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  if (field === "value") {
    if (isPatternImplementation(implementation)) return value(String(raw), { mono: true });
    if (implementation === "SourceSpecification") return value(mappedName(arrType ? SOURCES[arrType] : void 0, raw) ?? String(raw));
    if (implementation === "ResolutionSpecification") return value(mappedName(RESOLUTIONS, raw) ?? `${String(raw)}p`);
    if (implementation === "IndexerFlagSpecification") return value(mappedName(arrType ? INDEXER_FLAGS[arrType] : void 0, raw) ?? String(raw));
    if (implementation === "QualityModifierSpecification") return value(mappedName(QUALITY_MODIFIERS, raw) ?? String(raw));
    if (implementation === "ReleaseTypeSpecification") return value(mappedName(RELEASE_TYPES, raw) ?? String(raw));
    if (implementation === "LanguageSpecification") return value(languageName(arrType, raw) ?? String(raw));
  }
  if (implementation === "SizeSpecification" && (field === "min" || field === "max")) return value(formatBytes(raw));
  if (field === "exceptLanguage") return formatBooleanValue(raw);
  return formatGenericValue(raw);
}
function formatGenericValue(raw) {
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  if (typeof raw === "boolean") return formatBooleanValue(raw);
  if (typeof raw === "string") return value(raw, { mono: looksTechnical(raw) });
  if (typeof raw === "number") return value(String(raw), { mono: true });
  if (Array.isArray(raw)) return value(raw.map((item) => formatGenericValue(item).text).join(", "));
  const spec = asSpecificationValue(raw);
  if (spec) return formatSpecificationValue(spec, void 0);
  return value("Structured value");
}
function formatQualityItemsValue(raw) {
  const items = asQualityItems(raw);
  if (!items) return formatGenericValue(raw);
  return value(`${items.length} top-level ${items.length === 1 ? "item" : "items"}`, { qualityList: items });
}
function formatQualityProfileFormatItemValue(raw) {
  if (raw === null || raw === void 0) return value("Missing from scoring array", { tone: "danger" });
  if (!isRecord(raw)) return formatGenericValue(raw);
  const name = recordString(raw, "name") ?? "Custom format";
  const state2 = recordString(raw, "state");
  if (state2 === "missing_custom_format") return value(`${name}: custom format missing`, { tone: "danger" });
  if (state2 === "unmanaged") return value(`${name}: 0 (unmanaged)`, { mono: true });
  if (typeof raw.score === "number") return value(`${name}: ${raw.score}`, { mono: true });
  return formatGenericValue(raw);
}
function formatDelayProtocolValue(raw) {
  const labels = {
    prefer_usenet: "Prefer Usenet",
    prefer_torrent: "Prefer Torrent",
    only_usenet: "Only Usenet",
    only_torrent: "Only Torrent",
    unknown: "Unknown"
  };
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  if (typeof raw === "string") return value(labels[raw] ?? titleize(raw));
  return formatGenericValue(raw);
}
function formatPropersRepacksValue(raw) {
  const labels = {
    doNotPrefer: "Do Not Prefer",
    preferAndUpgrade: "Prefer and Upgrade",
    doNotUpgrade: "Do Not Upgrade Automatically"
  };
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  if (typeof raw === "string") return value(labels[raw] ?? titleize(raw));
  return formatGenericValue(raw);
}
function formatNamingValue(field, raw) {
  if (field === "customColonReplacementFormat" && (raw === null || raw === void 0 || raw === "")) return value("None");
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  if (typeof raw === "boolean") return formatBooleanValue(raw);
  if (typeof raw === "string") {
    if (field === "colonReplacementFormat" || field === "multiEpisodeStyle") return value(titleize(raw));
    return value(raw, { mono: looksTechnical(raw) });
  }
  return formatGenericValue(raw);
}
function formatQualityDefinitionValue(field, raw) {
  if ((field === "maxSize" || field === "preferredSize") && (raw === null || raw === void 0 || raw === 0)) return value("Unlimited");
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  if (typeof raw === "number") return value(String(raw), { mono: true });
  return formatGenericValue(raw);
}
function formatMinutesValue(raw) {
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  if (typeof raw !== "number") return formatGenericValue(raw);
  return value(`${raw} ${raw === 1 ? "minute" : "minutes"}`, { mono: true });
}
function formatTagIdsValue(raw) {
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  if (!Array.isArray(raw)) return formatGenericValue(raw);
  if (raw.length === 0) return value("None");
  return value(raw.map((tag2) => String(tag2)).join(", "), { mono: true });
}
function formatLanguageValue(raw, arrType) {
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  if (!isRecord(raw)) return formatGenericValue(raw);
  const id = raw.id;
  const name = recordString(raw, "name");
  if (typeof id === "number") return value(name ?? languageName(arrType, id) ?? String(id));
  return formatGenericValue(raw);
}
function formatBooleanValue(raw) {
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  return value(raw ? "Enabled" : "Disabled", { tone: raw ? "success" : "neutral" });
}
function formatNegateValue(raw) {
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  return value(raw ? "Must not match" : "Must match");
}
function formatRequiredValue(raw) {
  if (raw === null || raw === void 0) return value("Missing", { tone: "danger" });
  return value(raw ? "Required" : "Optional");
}
function fieldLabel(implementation, field) {
  if (field === "value") {
    if (isPatternImplementation(implementation)) return "Pattern";
    if (implementation === "LanguageSpecification") return "Language";
    return implementationLabel(implementation);
  }
  if (field === "min") return "Minimum";
  if (field === "max") return "Maximum";
  if (field === "exceptLanguage") return "Except Language";
  return titleize(field);
}
function qualityProfileFieldLabel(path) {
  return {
    cutoffFormatScore: "Cutoff Format Score",
    minFormatScore: "Minimum Format Score",
    minUpgradeFormatScore: "Minimum Upgrade Score Increment",
    upgradeAllowed: "Upgrade Allowed"
  }[path] ?? titleize(path);
}
function delayProfileFieldLabel(path) {
  return {
    bypassIfAboveCustomFormatScore: "Bypass if Above Custom Format Score",
    bypassIfHighestQuality: "Bypass if Highest Quality",
    id: "ID",
    minimumCustomFormatScore: "Minimum Custom Format Score",
    order: "Order",
    protocol: "Protocol",
    tags: "Tags",
    torrentDelay: "Torrent Delay",
    usenetDelay: "Usenet Delay"
  }[path] ?? titleize(path);
}
function namingFieldLabel(path) {
  return {
    animeEpisodeFormat: "Anime Episode Format",
    colonReplacementFormat: "Colon Replacement",
    customColonReplacementFormat: "Custom Colon Replacement",
    dailyEpisodeFormat: "Daily Episode Format",
    movieFolderFormat: "Movie Folder Format",
    multiEpisodeStyle: "Multi Episode Style",
    renameEpisodes: "Rename Episodes",
    renameMovies: "Rename Movies",
    replaceIllegalCharacters: "Replace Illegal Characters",
    seasonFolderFormat: "Season Folder Format",
    seriesFolderFormat: "Series Folder Format",
    standardEpisodeFormat: "Standard Episode Format",
    standardMovieFormat: "Movie Format"
  }[path] ?? titleize(path);
}
function qualityDefinitionFieldLabel(path) {
  return {
    maxSize: "Maximum Size",
    minSize: "Minimum Size",
    preferredSize: "Preferred Size"
  }[path] ?? titleize(path);
}
function parseQualityDefinitionPath(path) {
  const match = /^qualityDefinitions\[(.+)\]\.(.+)$/.exec(path);
  if (!match) return null;
  return {
    qualityName: match[1],
    field: match[2]
  };
}
function implementationLabel(implementation) {
  return IMPLEMENTATION_LABELS[implementation] ?? titleize(implementation.replace(/Specification$/, ""));
}
function isPatternImplementation(implementation) {
  return implementation === "ReleaseTitleSpecification" || implementation === "ReleaseGroupSpecification" || implementation === "EditionSpecification";
}
function mappedName(map2, raw) {
  if (typeof raw !== "number" || !map2) return null;
  for (const [key2, value2] of Object.entries(map2)) if (value2 === raw) return titleizeMappingKey(key2);
  return null;
}
function languageName(arrType, raw) {
  if (typeof raw !== "number" || !arrType) return null;
  for (const language of Object.values(LANGUAGES[arrType])) if (language.id === raw) return language.name;
  return null;
}
function formatBytes(raw) {
  if (typeof raw !== "number" || raw <= 0) return "None";
  const units = [
    "B",
    "KB",
    "MB",
    "GB",
    "TB"
  ];
  let value2 = raw;
  let unitIndex = 0;
  while (value2 >= 1024 && unitIndex < units.length - 1) {
    value2 = value2 / 1024;
    unitIndex++;
  }
  const digits = value2 >= 10 || unitIndex === 0 ? 0 : 1;
  return `${value2.toFixed(digits)} ${units[unitIndex]}`;
}
function titleize(value2) {
  return value2.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\s+/g, " ").trim().replace(/\b\w/g, (letter) => letter.toUpperCase());
}
function titleizeMappingKey(value2) {
  return titleize(value2).replace(/\bTv\b/g, "TV").replace(/\bDl\b/g, "DL").replace(/\bHd\b/g, "HD").replace(/\bRawhd\b/g, "Raw HD").replace(/\bBrdisk\b/g, "BR Disk");
}
function looksTechnical(value2) {
  return /[\\^$.[\]()*+?{}|]/.test(value2);
}
function value(text2, options2 = {}) {
  return {
    text: text2,
    mono: options2.mono,
    tone: options2.tone,
    qualityList: options2.qualityList
  };
}
function recordString(raw, key2) {
  if (!isRecord(raw)) return null;
  const value2 = raw[key2];
  return typeof value2 === "string" ? value2 : null;
}
function recordNumber(raw, key2) {
  if (!isRecord(raw)) return null;
  const value2 = raw[key2];
  return typeof value2 === "number" ? value2 : null;
}
function isRecord(raw) {
  return typeof raw === "object" && raw !== null;
}
async function list2(cache3) {
  const db2 = cache3.kb;
  const profiles = await db2.selectFrom("quality_profiles").select([
    "id",
    "name",
    "description",
    "upgrades_allowed",
    "minimum_custom_format_score",
    "upgrade_until_score",
    "upgrade_score_increment"
  ]).orderBy(sql`name COLLATE NOCASE`).execute();
  if (profiles.length === 0) return [];
  const profileNames = profiles.map((p2) => p2.name);
  const allTags = await db2.selectFrom("quality_profile_tags as qpt").innerJoin("tags as t", "t.name", "qpt.tag_name").select([
    "qpt.quality_profile_name",
    "t.name as tag_name",
    "t.created_at as tag_created_at"
  ]).where("qpt.quality_profile_name", "in", profileNames).orderBy("qpt.quality_profile_name").orderBy("t.name").execute();
  const formatCounts = await db2.selectFrom("quality_profile_custom_formats").select(["quality_profile_name", "arr_type"]).select((eb) => eb.fn.count("quality_profile_name").as("count")).where("quality_profile_name", "in", profileNames).groupBy(["quality_profile_name", "arr_type"]).execute();
  const allQualities = await db2.selectFrom("quality_profile_qualities as qpq").leftJoin("qualities as q", "qpq.quality_name", "q.name").leftJoin("quality_groups as qg", (join4) => join4.onRef("qpq.quality_group_name", "=", "qg.name").onRef("qpq.quality_profile_name", "=", "qg.quality_profile_name")).select([
    "qpq.quality_profile_name",
    "qpq.position",
    "qpq.upgrade_until",
    "qpq.quality_name",
    "qpq.quality_group_name",
    "q.name as resolved_quality_name",
    "qg.name as group_name"
  ]).where("qpq.quality_profile_name", "in", profileNames).where("qpq.enabled", "=", 1).orderBy("qpq.quality_profile_name").orderBy("qpq.position").execute();
  const allLanguages = await db2.selectFrom("quality_profile_languages as qpl").innerJoin("languages as l", "qpl.language_name", "l.name").select([
    "qpl.quality_profile_name",
    "l.name as language_name",
    "qpl.type"
  ]).where("qpl.quality_profile_name", "in", profileNames).execute();
  const tagsMap = /* @__PURE__ */ new Map();
  for (const tag2 of allTags) {
    if (!tagsMap.has(tag2.quality_profile_name)) tagsMap.set(tag2.quality_profile_name, []);
    tagsMap.get(tag2.quality_profile_name).push({
      name: tag2.tag_name,
      created_at: tag2.tag_created_at
    });
  }
  const formatCountsMap = /* @__PURE__ */ new Map();
  for (const fc of formatCounts) {
    if (!formatCountsMap.has(fc.quality_profile_name)) formatCountsMap.set(fc.quality_profile_name, {
      all: 0,
      radarr: 0,
      sonarr: 0
    });
    const counts = formatCountsMap.get(fc.quality_profile_name);
    const count = Number(fc.count);
    if (fc.arr_type === "all") counts.all = count;
    else if (fc.arr_type === "radarr") counts.radarr = count;
    else if (fc.arr_type === "sonarr") counts.sonarr = count;
  }
  const qualitiesMap = /* @__PURE__ */ new Map();
  for (const qual of allQualities) {
    if (!qualitiesMap.has(qual.quality_profile_name)) qualitiesMap.set(qual.quality_profile_name, []);
    qualitiesMap.get(qual.quality_profile_name).push({
      position: qual.position,
      type: qual.quality_name ? "quality" : "group",
      name: qual.quality_name || qual.group_name,
      is_upgrade_until: qual.upgrade_until === 1
    });
  }
  const languagesMap = /* @__PURE__ */ new Map();
  for (const lang of allLanguages) languagesMap.set(lang.quality_profile_name, {
    name: lang.language_name,
    type: lang.type
  });
  return profiles.map((profile) => {
    const counts = formatCountsMap.get(profile.name) || {
      all: 0,
      radarr: 0,
      sonarr: 0
    };
    const result = {
      id: profile.id,
      name: profile.name,
      description: parseMarkdown(profile.description),
      tags: tagsMap.get(profile.name) || [],
      upgrades_allowed: profile.upgrades_allowed === 1,
      minimum_custom_format_score: profile.minimum_custom_format_score,
      custom_formats: {
        all: counts.all,
        radarr: counts.radarr,
        sonarr: counts.sonarr,
        total: counts.all + counts.radarr + counts.sonarr
      },
      qualities: qualitiesMap.get(profile.name) || [],
      language: languagesMap.get(profile.name)
    };
    if (profile.upgrades_allowed === 1) {
      result.upgrade_until_score = profile.upgrade_until_score;
      result.upgrade_score_increment = profile.upgrade_score_increment;
    }
    return result;
  });
}
async function names(cache3) {
  return (await cache3.kb.selectFrom("quality_profiles").select(["name"]).orderBy(sql`name COLLATE NOCASE`).execute()).map((p2) => p2.name);
}
async function select(cache3) {
  return await cache3.kb.selectFrom("quality_profiles").select(["id", "name"]).orderBy(sql`name COLLATE NOCASE`).execute();
}
function esc$32(value2) {
  return value2.replace(/'/g, "''");
}
async function updateGeneral2(options2) {
  const { databaseId, cache: cache3, layer, current: current3, input } = options2;
  const db2 = cache3.kb;
  if (input.name !== current3.name) {
    if (await db2.selectFrom("quality_profiles").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) {
      await logger.warn(`Duplicate quality profile name "${input.name}"`, {
        source: "QualityProfile",
        meta: {
          databaseId,
          name: input.name
        }
      });
      throw new Error(`A quality profile with name "${input.name}" already exists`);
    }
  }
  const rawCurrentDescription = (await db2.selectFrom("quality_profiles").select("description").where("name", "=", current3.name).executeTakeFirst())?.description ?? null;
  const normalizedCurrentDescription = rawCurrentDescription ?? "";
  const normalizedNextDescription = input.description?.trim() ?? "";
  const descriptionChanged = normalizedCurrentDescription !== normalizedNextDescription;
  const renameChanged = current3.name !== input.name;
  const languageChanged = current3.language !== input.language;
  const currentTagNames = current3.tags.map((t2) => t2.name);
  const newTagNames = Array.from(new Set(input.tags.map((tag2) => tag2.trim()).filter(Boolean)));
  const tagsToRemove = currentTagNames.filter((t2) => !newTagNames.includes(t2));
  const tagsToAdd = newTagNames.filter((t2) => !currentTagNames.includes(t2));
  const hasTagChanges = tagsToAdd.length > 0 || tagsToRemove.length > 0;
  const changes = {};
  if (renameChanged) changes.name = {
    from: current3.name,
    to: input.name
  };
  if (descriptionChanged) changes.description = {
    from: rawCurrentDescription ?? null,
    to: normalizedNextDescription === "" ? null : normalizedNextDescription
  };
  if (tagsToAdd.length > 0 || tagsToRemove.length > 0) changes.tags = {
    from: currentTagNames,
    to: newTagNames
  };
  if (languageChanged) changes.language = {
    from: current3.language,
    to: input.language
  };
  const descriptionQueries = [];
  if (descriptionChanged) {
    let updateDescription = db2.updateTable("quality_profiles").set({ description: normalizedNextDescription === "" ? null : normalizedNextDescription }).where("name", "=", current3.name);
    if (rawCurrentDescription === null) updateDescription = updateDescription.where("description", "is", null);
    else updateDescription = updateDescription.where("description", "=", rawCurrentDescription);
    descriptionQueries.push(updateDescription.compile());
  }
  const languageQueries = [];
  if (languageChanged) {
    if (current3.language !== null) {
      const deleteLanguage = {
        sql: `DELETE FROM quality_profile_languages WHERE quality_profile_name = '${esc$32(current3.name)}' AND language_name = '${esc$32(current3.language)}'`,
        parameters: [],
        query: {}
      };
      languageQueries.push(deleteLanguage);
    }
    if (input.language !== null) {
      const insertLanguage = {
        sql: `INSERT INTO quality_profile_languages (quality_profile_name, language_name, type)
SELECT '${esc$32(current3.name)}', '${esc$32(input.language)}', 'simple'
WHERE NOT EXISTS (
  SELECT 1 FROM quality_profile_languages
  WHERE quality_profile_name = '${esc$32(current3.name)}'
)`,
        parameters: [],
        query: {}
      };
      languageQueries.push(insertLanguage);
    }
  }
  const tagQueries = [];
  for (const tagName of tagsToRemove) {
    const removeTag = {
      sql: `DELETE FROM quality_profile_tags WHERE quality_profile_name = '${esc$32(current3.name)}' AND tag_name = '${esc$32(tagName)}'`,
      parameters: [],
      query: {}
    };
    tagQueries.push(removeTag);
  }
  for (const tagName of tagsToAdd) {
    const insertTag = db2.insertInto("tags").values({ name: tagName }).onConflict((oc) => oc.column("name").doNothing()).compile();
    tagQueries.push(insertTag);
    const linkTag = {
      sql: `INSERT INTO quality_profile_tags (quality_profile_name, tag_name) VALUES ('${esc$32(current3.name)}', '${esc$32(tagName)}')`,
      parameters: [],
      query: {}
    };
    tagQueries.push(linkTag);
  }
  const renameQueries = [];
  if (renameChanged) {
    const updateName = db2.updateTable("quality_profiles").set({ name: input.name }).where("name", "=", current3.name).compile();
    renameQueries.push(updateName);
  }
  if (!descriptionChanged && !languageChanged && !hasTagChanges && !renameChanged) return { success: true };
  await logger.info(`Save quality profile "${input.name}"`, {
    source: "QualityProfile",
    meta: {
      id: current3.id,
      changes
    }
  });
  let lastResult = null;
  if (descriptionChanged) {
    const descriptionResult = await writeOperation({
      databaseId,
      layer,
      description: `update-quality-profile-description-${input.name}`,
      queries: descriptionQueries,
      desiredState: { description: {
        from: rawCurrentDescription ?? null,
        to: normalizedNextDescription === "" ? null : normalizedNextDescription
      } },
      metadata: {
        operation: "update",
        entity: "quality_profile",
        name: input.name,
        stableKey: {
          key: "quality_profile_name",
          value: current3.name
        },
        changedFields: ["description"],
        summary: "Update quality profile description",
        title: `Update description for quality profile "${input.name}"`
      }
    });
    if (!descriptionResult.success) return descriptionResult;
    lastResult = descriptionResult;
  }
  if (languageChanged) {
    const languageResult = await writeOperation({
      databaseId,
      layer,
      description: `update-quality-profile-language-${input.name}`,
      queries: languageQueries,
      desiredState: { language: {
        from: current3.language ?? null,
        to: input.language ?? null,
        type: "simple"
      } },
      metadata: {
        operation: "update",
        entity: "quality_profile",
        name: input.name,
        stableKey: {
          key: "quality_profile_name",
          value: current3.name
        },
        changedFields: ["language"],
        summary: "Update quality profile language",
        title: `Update language for quality profile "${input.name}"`
      }
    });
    if (!languageResult.success) return languageResult;
    lastResult = languageResult;
  }
  if (hasTagChanges) {
    const tagsResult = await writeOperation({
      databaseId,
      layer,
      description: `update-quality-profile-tags-${input.name}`,
      queries: tagQueries,
      desiredState: { tags: {
        add: tagsToAdd,
        remove: tagsToRemove
      } },
      metadata: {
        operation: "update",
        entity: "quality_profile",
        name: input.name,
        stableKey: {
          key: "quality_profile_name",
          value: current3.name
        },
        changedFields: ["tags"],
        summary: "Update quality profile tags",
        title: `Update tags for quality profile "${input.name}"`
      }
    });
    if (!tagsResult.success) return tagsResult;
    lastResult = tagsResult;
  }
  if (renameChanged) {
    const renameResult = await writeOperation({
      databaseId,
      layer,
      description: `update-quality-profile-name-${input.name}`,
      queries: renameQueries,
      desiredState: { name: {
        from: current3.name,
        to: input.name
      } },
      metadata: {
        operation: "update",
        entity: "quality_profile",
        name: input.name,
        previousName: current3.name,
        stableKey: {
          key: "quality_profile_name",
          value: current3.name
        },
        changedFields: ["name"],
        summary: "Rename quality profile",
        title: `Rename quality profile "${current3.name}"`
      }
    });
    if (!renameResult.success) return renameResult;
    lastResult = renameResult;
  }
  return lastResult ?? { success: true };
}
async function scoring(cache3, databaseId, profileName2) {
  const db2 = cache3.kb;
  const profile = await db2.selectFrom("quality_profiles").select([
    "upgrades_allowed",
    "minimum_custom_format_score",
    "upgrade_until_score",
    "upgrade_score_increment"
  ]).where("name", "=", profileName2).executeTakeFirst();
  if (!profile) throw new Error(`Quality profile ${profileName2} not found`);
  const arrTypes = ["radarr", "sonarr"];
  const customFormats = await db2.selectFrom("custom_formats").select(["id", "name"]).orderBy(sql`name COLLATE NOCASE`).execute();
  const customFormatTags = await db2.selectFrom("custom_format_tags").innerJoin("tags", "tags.name", "custom_format_tags.tag_name").select(["custom_format_tags.custom_format_name", "tags.name as tag_name"]).execute();
  const tagsMap = /* @__PURE__ */ new Map();
  for (const tag2 of customFormatTags) {
    if (!tagsMap.has(tag2.custom_format_name)) tagsMap.set(tag2.custom_format_name, []);
    tagsMap.get(tag2.custom_format_name).push(tag2.tag_name);
  }
  const scores = await db2.selectFrom("quality_profile_custom_formats").select([
    "custom_format_name",
    "arr_type",
    "score"
  ]).where("quality_profile_name", "=", profileName2).execute();
  const scoresMap = /* @__PURE__ */ new Map();
  for (const score of scores) {
    if (!scoresMap.has(score.custom_format_name)) scoresMap.set(score.custom_format_name, /* @__PURE__ */ new Map());
    scoresMap.get(score.custom_format_name).set(score.arr_type, score.score);
  }
  return {
    databaseId,
    arrTypes,
    customFormats: customFormats.map((cf) => {
      const formatScores = {};
      const cfScores = scoresMap.get(cf.name);
      const allScore = cfScores?.get("all") ?? null;
      for (const arrType of arrTypes) {
        const specificScore = cfScores?.get(arrType);
        formatScores[arrType] = specificScore !== void 0 ? specificScore : allScore;
      }
      return {
        id: cf.id,
        name: cf.name,
        tags: tagsMap.get(cf.name) ?? [],
        scores: formatScores
      };
    }),
    upgrades_allowed: profile.upgrades_allowed === 1,
    minimum_custom_format_score: profile.minimum_custom_format_score,
    upgrade_until_score: profile.upgrade_until_score,
    upgrade_score_increment: profile.upgrade_score_increment
  };
}
async function allCfScores(cache3) {
  const db2 = cache3.kb;
  const customFormats = await db2.selectFrom("custom_formats").select(["name"]).orderBy(sql`name COLLATE NOCASE`).execute();
  const profiles = await db2.selectFrom("quality_profiles").select(["name"]).execute();
  const allScores = await db2.selectFrom("quality_profile_custom_formats").select([
    "quality_profile_name",
    "custom_format_name",
    "arr_type",
    "score"
  ]).execute();
  const scoresMap = /* @__PURE__ */ new Map();
  for (const score of allScores) {
    if (!scoresMap.has(score.quality_profile_name)) scoresMap.set(score.quality_profile_name, /* @__PURE__ */ new Map());
    const profileScores = scoresMap.get(score.quality_profile_name);
    if (!profileScores.has(score.custom_format_name)) profileScores.set(score.custom_format_name, /* @__PURE__ */ new Map());
    profileScores.get(score.custom_format_name).set(score.arr_type, score.score);
  }
  return {
    customFormats,
    profiles: profiles.map((profile) => {
      const profileScores = scoresMap.get(profile.name);
      const scores = {};
      for (const cf of customFormats) {
        const cfScores = profileScores?.get(cf.name);
        const allScore = cfScores?.get("all") ?? null;
        scores[cf.name] = {
          radarr: cfScores?.get("radarr") ?? allScore,
          sonarr: cfScores?.get("sonarr") ?? allScore
        };
      }
      return {
        profileName: profile.name,
        scores
      };
    })
  };
}
async function updateScoring(options2) {
  const { databaseId, cache: cache3, layer, profileName: profileName2, input } = options2;
  const db2 = cache3.kb;
  if (input.upgradeScoreIncrement < 1) throw new Error("Upgrade score increment must be at least 1");
  const currentProfile = await db2.selectFrom("quality_profiles").select([
    "upgrades_allowed",
    "minimum_custom_format_score",
    "upgrade_until_score",
    "upgrade_score_increment"
  ]).where("name", "=", profileName2).executeTakeFirst();
  if (!currentProfile) return {
    success: false,
    error: `Quality profile "${profileName2}" not found`
  };
  const currentScores = await db2.selectFrom("quality_profile_custom_formats").select([
    "custom_format_name",
    "arr_type",
    "score"
  ]).where("quality_profile_name", "=", profileName2).execute();
  const currentScoreMap = /* @__PURE__ */ new Map();
  for (const row of currentScores) currentScoreMap.set(`${row.custom_format_name}::${row.arr_type}`, row.score);
  const ops = [];
  const currentUpgradesAllowed = currentProfile.upgrades_allowed === 1;
  if (currentUpgradesAllowed !== input.upgradesAllowed) {
    const query = db2.updateTable("quality_profiles").set({ upgrades_allowed: input.upgradesAllowed ? 1 : 0 }).where("name", "=", profileName2).where("upgrades_allowed", "=", currentProfile.upgrades_allowed).compile();
    ops.push({
      description: `update-quality-profile-upgrades-allowed-${profileName2}`,
      queries: [query],
      desiredState: { upgrades_allowed: {
        from: currentUpgradesAllowed,
        to: input.upgradesAllowed
      } },
      changedFields: ["upgrades_allowed"],
      summary: "Update quality profile upgrades allowed",
      title: `Update upgrades allowed for quality profile "${profileName2}"`
    });
  }
  const modifiedCfNames = new Set(input.customFormatScores.map((s3) => s3.customFormatName));
  const arrTypes = ["radarr", "sonarr"];
  for (const cfName of modifiedCfNames) {
    const allKey = `${cfName}::all`;
    const allScore = currentScoreMap.get(allKey);
    if (allScore === void 0) continue;
    const cfInputs = input.customFormatScores.filter((s3) => s3.customFormatName === cfName && s3.arrType !== "all");
    if (cfInputs.length > 0 && cfInputs.every((s3) => s3.score === allScore)) {
      for (const arrType of arrTypes) {
        const key2 = `${cfName}::${arrType}`;
        if (!currentScoreMap.has(key2)) currentScoreMap.set(key2, allScore);
      }
      continue;
    }
    for (const arrType of arrTypes) {
      const key2 = `${cfName}::${arrType}`;
      if (!currentScoreMap.has(key2)) {
        const insertQuery = {
          sql: `INSERT INTO quality_profile_custom_formats (quality_profile_name, custom_format_name, arr_type, score)
SELECT '${esc$22(profileName2)}', '${esc$22(cfName)}', '${esc$22(arrType)}', ${allScore}
WHERE NOT EXISTS (
  SELECT 1 FROM quality_profile_custom_formats
  WHERE quality_profile_name = '${esc$22(profileName2)}'
    AND custom_format_name = '${esc$22(cfName)}'
    AND arr_type = '${esc$22(arrType)}'
)`,
          parameters: [],
          query: {}
        };
        ops.push({
          description: `expand-all-score-${profileName2}-${arrType}-${cfName}`,
          queries: [insertQuery],
          desiredState: { custom_format_scores: [{
            custom_format_name: cfName,
            arr_type: arrType,
            from: null,
            to: allScore
          }] },
          changedFields: [`custom_format_score:${cfName}:${arrType}`],
          summary: `Expand shared score to ${arrType}`,
          title: `Expand shared score for "${cfName}" to ${arrType} on "${profileName2}"`,
          dependsOn: [{
            entity: "custom_format",
            key: "custom_format_name",
            value: cfName
          }]
        });
        currentScoreMap.set(key2, allScore);
      }
    }
    const deleteAllQuery = {
      sql: `DELETE FROM quality_profile_custom_formats
WHERE quality_profile_name = '${esc$22(profileName2)}'
  AND custom_format_name = '${esc$22(cfName)}'
  AND arr_type = 'all'
  AND score = ${allScore}`,
      parameters: [],
      query: {}
    };
    ops.push({
      description: `remove-all-score-${profileName2}-${cfName}`,
      queries: [deleteAllQuery],
      desiredState: { custom_format_scores: [{
        custom_format_name: cfName,
        arr_type: "all",
        from: allScore,
        to: null
      }] },
      changedFields: [`custom_format_score:${cfName}:all`],
      summary: `Remove shared score after expansion`,
      title: `Remove shared score for "${cfName}" on "${profileName2}"`,
      dependsOn: [{
        entity: "custom_format",
        key: "custom_format_name",
        value: cfName
      }]
    });
    currentScoreMap.delete(allKey);
  }
  if (currentProfile.minimum_custom_format_score !== input.minimumScore) {
    const query = db2.updateTable("quality_profiles").set({ minimum_custom_format_score: input.minimumScore }).where("name", "=", profileName2).where("minimum_custom_format_score", "=", currentProfile.minimum_custom_format_score).compile();
    ops.push({
      description: `update-quality-profile-minimum-score-${profileName2}`,
      queries: [query],
      desiredState: { minimum_custom_format_score: {
        from: currentProfile.minimum_custom_format_score,
        to: input.minimumScore
      } },
      changedFields: ["minimum_custom_format_score"],
      summary: "Update quality profile minimum score",
      title: `Update minimum score for quality profile "${profileName2}"`
    });
  }
  if (currentProfile.upgrade_until_score !== input.upgradeUntilScore) {
    const query = db2.updateTable("quality_profiles").set({ upgrade_until_score: input.upgradeUntilScore }).where("name", "=", profileName2).where("upgrade_until_score", "=", currentProfile.upgrade_until_score).compile();
    ops.push({
      description: `update-quality-profile-upgrade-until-score-${profileName2}`,
      queries: [query],
      desiredState: { upgrade_until_score: {
        from: currentProfile.upgrade_until_score,
        to: input.upgradeUntilScore
      } },
      changedFields: ["upgrade_until_score"],
      summary: "Update quality profile upgrade-until score",
      title: `Update upgrade-until score for quality profile "${profileName2}"`
    });
  }
  if (currentProfile.upgrade_score_increment !== input.upgradeScoreIncrement) {
    const query = db2.updateTable("quality_profiles").set({ upgrade_score_increment: input.upgradeScoreIncrement }).where("name", "=", profileName2).where("upgrade_score_increment", "=", currentProfile.upgrade_score_increment).compile();
    ops.push({
      description: `update-quality-profile-upgrade-score-increment-${profileName2}`,
      queries: [query],
      desiredState: { upgrade_score_increment: {
        from: currentProfile.upgrade_score_increment,
        to: input.upgradeScoreIncrement
      } },
      changedFields: ["upgrade_score_increment"],
      summary: "Update quality profile score increment",
      title: `Update score increment for quality profile "${profileName2}"`
    });
  }
  for (const score of input.customFormatScores) {
    const key2 = `${score.customFormatName}::${score.arrType}`;
    const currentScore = currentScoreMap.get(key2);
    const dependsOn = [{
      entity: "custom_format",
      key: "custom_format_name",
      value: score.customFormatName
    }];
    const rowField = `custom_format_score:${score.customFormatName}:${score.arrType}`;
    if (currentScore === void 0) {
      if (score.score === null) continue;
      const insertScore = {
        sql: `INSERT INTO quality_profile_custom_formats (quality_profile_name, custom_format_name, arr_type, score)
SELECT '${esc$22(profileName2)}', '${esc$22(score.customFormatName)}', '${esc$22(score.arrType)}', ${score.score}
WHERE NOT EXISTS (
  SELECT 1 FROM quality_profile_custom_formats
  WHERE quality_profile_name = '${esc$22(profileName2)}'
    AND custom_format_name = '${esc$22(score.customFormatName)}'
    AND arr_type = '${esc$22(score.arrType)}'
)`,
        parameters: [],
        query: {}
      };
      ops.push({
        description: `add-quality-profile-cf-score-${profileName2}-${score.arrType}-${score.customFormatName}`,
        queries: [insertScore],
        desiredState: { custom_format_scores: [{
          custom_format_name: score.customFormatName,
          arr_type: score.arrType,
          from: null,
          to: score.score
        }] },
        changedFields: [rowField],
        summary: "Add quality profile custom format score",
        title: `Add ${score.arrType} score for "${score.customFormatName}" on "${profileName2}"`,
        dependsOn
      });
      continue;
    }
    if (score.score === null) {
      const deleteScore = {
        sql: `DELETE FROM quality_profile_custom_formats
WHERE quality_profile_name = '${esc$22(profileName2)}'
  AND custom_format_name = '${esc$22(score.customFormatName)}'
  AND arr_type = '${esc$22(score.arrType)}'
  AND score = ${currentScore}`,
        parameters: [],
        query: {}
      };
      ops.push({
        description: `remove-quality-profile-cf-score-${profileName2}-${score.arrType}-${score.customFormatName}`,
        queries: [deleteScore],
        desiredState: { custom_format_scores: [{
          custom_format_name: score.customFormatName,
          arr_type: score.arrType,
          from: currentScore,
          to: null
        }] },
        changedFields: [rowField],
        summary: "Remove quality profile custom format score",
        title: `Remove ${score.arrType} score for "${score.customFormatName}" on "${profileName2}"`,
        dependsOn
      });
      continue;
    }
    if (score.score !== currentScore) {
      const updateScore = {
        sql: `UPDATE quality_profile_custom_formats
SET score = ${score.score}
WHERE quality_profile_name = '${esc$22(profileName2)}'
  AND custom_format_name = '${esc$22(score.customFormatName)}'
  AND arr_type = '${esc$22(score.arrType)}'
  AND score = ${currentScore}`,
        parameters: [],
        query: {}
      };
      ops.push({
        description: `update-quality-profile-cf-score-${profileName2}-${score.arrType}-${score.customFormatName}`,
        queries: [updateScore],
        desiredState: { custom_format_scores: [{
          custom_format_name: score.customFormatName,
          arr_type: score.arrType,
          from: currentScore,
          to: score.score
        }] },
        changedFields: [rowField],
        summary: "Update quality profile custom format score",
        title: `Update ${score.arrType} score for "${score.customFormatName}" on "${profileName2}"`,
        dependsOn
      });
    }
  }
  if (ops.length === 0) return { success: true };
  await logger.info(`Save quality profile scoring "${profileName2}"`, {
    source: "QualityProfile",
    meta: {
      profileName: profileName2,
      opCount: ops.length
    }
  });
  let lastResult = null;
  for (const op of ops) {
    const result = await writeOperation({
      databaseId,
      layer,
      description: op.description,
      queries: op.queries,
      desiredState: op.desiredState,
      skipRecompile: true,
      metadata: {
        operation: "update",
        entity: "quality_profile",
        name: profileName2,
        stableKey: {
          key: "quality_profile_name",
          value: profileName2
        },
        changedFields: op.changedFields,
        summary: op.summary,
        title: op.title,
        ...op.dependsOn ? { dependsOn: op.dependsOn } : {}
      }
    });
    if (!result.success) {
      await recompileCache(databaseId);
      return result;
    }
    lastResult = result;
  }
  await recompileCache(databaseId);
  return lastResult ?? { success: true };
}
function esc$22(value2) {
  return value2.replace(/'/g, "''");
}
async function qualities(cache3, _databaseId, profileName2) {
  const db2 = cache3.kb;
  const allQualities = await db2.selectFrom("qualities").select(["name"]).orderBy(sql`name COLLATE NOCASE`).execute();
  const groups = await db2.selectFrom("quality_groups").select(["name"]).where("quality_profile_name", "=", profileName2).execute();
  const hasGroupMemberPosition = hasQualityGroupMembersPositionInCache(cache3);
  let groupMembersQuery = db2.selectFrom("quality_group_members").innerJoin("qualities", "qualities.name", "quality_group_members.quality_name").where("quality_group_members.quality_profile_name", "=", profileName2).select(["quality_group_members.quality_group_name", "qualities.name as quality_name"]);
  if (hasGroupMemberPosition) groupMembersQuery = groupMembersQuery.orderBy("quality_group_members.position");
  const groupMembers = await groupMembersQuery.orderBy("quality_group_members.quality_name").execute();
  const groupsMap = /* @__PURE__ */ new Map();
  for (const group of groups) groupsMap.set(group.name, {
    name: group.name,
    members: []
  });
  for (const member of groupMembers) {
    const group = groupsMap.get(member.quality_group_name);
    if (group) group.members.push({ name: member.quality_name });
  }
  const orderedItems = (await db2.selectFrom("quality_profile_qualities").leftJoin("qualities", "qualities.name", "quality_profile_qualities.quality_name").leftJoin("quality_groups", (join4) => join4.onRef("quality_groups.name", "=", "quality_profile_qualities.quality_group_name").onRef("quality_groups.quality_profile_name", "=", "quality_profile_qualities.quality_profile_name")).where("quality_profile_qualities.quality_profile_name", "=", profileName2).select([
    "quality_profile_qualities.quality_name",
    "quality_profile_qualities.quality_group_name",
    "quality_profile_qualities.position",
    "quality_profile_qualities.enabled",
    "quality_profile_qualities.upgrade_until",
    "qualities.name as resolved_quality_name",
    "quality_groups.name as group_name"
  ]).orderBy("quality_profile_qualities.position").execute()).map((item) => {
    const isGroup2 = item.quality_group_name !== null;
    const name = isGroup2 ? item.group_name : item.quality_name;
    const orderedItem = {
      type: isGroup2 ? "group" : "quality",
      name,
      position: item.position,
      enabled: item.enabled === 1,
      upgradeUntil: item.upgrade_until === 1
    };
    if (isGroup2) orderedItem.members = groupsMap.get(name)?.members || [];
    return orderedItem;
  });
  const usedQualityNames = /* @__PURE__ */ new Set();
  for (const item of orderedItems) if (item.type === "quality") usedQualityNames.add(item.name);
  else item.members?.forEach((member) => usedQualityNames.add(member.name));
  return {
    orderedItems,
    availableQualities: allQualities.filter((q2) => !usedQualityNames.has(q2.name)).map((q2) => ({ name: q2.name })),
    allQualities: allQualities.map((q2) => ({ name: q2.name })),
    groups: Array.from(groupsMap.values())
  };
}
function esc$12(str2) {
  return str2.replace(/'/g, "''");
}
function rowKey(item) {
  return `${item.type}:${item.name}`;
}
function rowFieldKey(item) {
  return `quality_item:${item.type}:${item.name}`;
}
function getMembers(item) {
  if (item.type !== "group") return [];
  return Array.from(new Set((item.members ?? []).map((member) => member.name).filter(Boolean))).sort();
}
function cloneItem2(item) {
  const cloned = {
    type: item.type,
    name: item.name,
    position: item.position,
    enabled: item.enabled,
    upgradeUntil: item.upgradeUntil
  };
  if (item.type === "group") cloned.members = (item.members ?? []).map((m3) => ({ name: m3.name }));
  return cloned;
}
function sameRow(current3, next2) {
  if (current3.type !== next2.type || current3.name !== next2.name || current3.position !== next2.position || current3.enabled !== next2.enabled || current3.upgradeUntil !== next2.upgradeUntil) return false;
  if (current3.type !== "group") return true;
  const currentMembers = (current3.members ?? []).map((m3) => m3.name).filter(Boolean);
  const nextMembers = (next2.members ?? []).map((m3) => m3.name).filter(Boolean);
  if (currentMembers.length !== nextMembers.length) return false;
  return currentMembers.every((member, index88) => member === nextMembers[index88]);
}
function buildGroupMembersGuard(profileName2, groupName, members) {
  const baseWhere = `quality_profile_name = '${esc$12(profileName2)}'
  AND quality_group_name = '${esc$12(groupName)}'`;
  if (members.length === 0) return `(SELECT COUNT(*)
FROM quality_group_members
WHERE ${baseWhere}) = 0`;
  const expectedMembers = members.map((member) => `'${esc$12(member)}'`).join(", ");
  const positionChecks = members.map((member, index88) => `(quality_name = '${esc$12(member)}'
        AND position = ${index88})`).join(`
      OR `);
  return `(SELECT COUNT(*)
FROM quality_group_members
WHERE ${baseWhere}) = ${members.length}
  AND NOT EXISTS (
    SELECT 1
    FROM quality_group_members
    WHERE ${baseWhere}
      AND quality_name NOT IN (${expectedMembers})
  )
  AND (
    NOT EXISTS (
      SELECT 1
      FROM quality_group_members
      WHERE ${baseWhere}
        AND NOT (
          ${positionChecks}
        )
    )
    OR NOT EXISTS (
      SELECT 1
      FROM quality_group_members
      WHERE ${baseWhere}
        AND position != 0
    )
  )`;
}
function buildDeleteQueries(profileName2, item) {
  const queries = [];
  if (item.type === "quality") {
    queries.push({
      sql: `DELETE FROM quality_profile_qualities
WHERE quality_profile_name = '${esc$12(profileName2)}'
  AND quality_name = '${esc$12(item.name)}'
  AND quality_group_name IS NULL
  AND position = ${item.position}
  AND enabled = ${item.enabled ? 1 : 0}
  AND upgrade_until = ${item.upgradeUntil ? 1 : 0}`,
      parameters: [],
      query: {}
    });
    return queries;
  }
  queries.push({
    sql: `DELETE FROM quality_profile_qualities
WHERE quality_profile_name = '${esc$12(profileName2)}'
  AND quality_group_name = '${esc$12(item.name)}'
  AND quality_name IS NULL
  AND position = ${item.position}
  AND enabled = ${item.enabled ? 1 : 0}
  AND upgrade_until = ${item.upgradeUntil ? 1 : 0}`,
    parameters: [],
    query: {}
  });
  for (const member of getMembers(item)) queries.push({
    sql: `DELETE FROM quality_group_members
WHERE quality_profile_name = '${esc$12(profileName2)}'
  AND quality_group_name = '${esc$12(item.name)}'
  AND quality_name = '${esc$12(member)}'`,
    parameters: [],
    query: {}
  });
  queries.push({
    sql: `DELETE FROM quality_groups
WHERE quality_profile_name = '${esc$12(profileName2)}'
  AND name = '${esc$12(item.name)}'`,
    parameters: [],
    query: {}
  });
  return queries;
}
function buildAddQueries(profileName2, item) {
  const queries = [];
  const enabled3 = item.enabled ? 1 : 0;
  const upgradeUntil = item.upgradeUntil ? 1 : 0;
  if (item.type === "group") {
    queries.push({
      sql: `INSERT INTO quality_groups (quality_profile_name, name)
SELECT '${esc$12(profileName2)}', '${esc$12(item.name)}'
WHERE NOT EXISTS (
  SELECT 1 FROM quality_groups
  WHERE quality_profile_name = '${esc$12(profileName2)}'
    AND name = '${esc$12(item.name)}'
)`,
      parameters: [],
      query: {}
    });
    const members = Array.from(new Set((item.members ?? []).map((m3) => m3.name).filter(Boolean)));
    for (let i = 0; i < members.length; i++) queries.push({
      sql: `INSERT INTO quality_group_members (quality_profile_name, quality_group_name, quality_name, position)
SELECT '${esc$12(profileName2)}', '${esc$12(item.name)}', '${esc$12(members[i])}', ${i}
WHERE NOT EXISTS (
  SELECT 1 FROM quality_group_members
  WHERE quality_profile_name = '${esc$12(profileName2)}'
    AND quality_group_name = '${esc$12(item.name)}'
    AND quality_name = '${esc$12(members[i])}'
)`,
      parameters: [],
      query: {}
    });
    queries.push({
      sql: `INSERT INTO quality_profile_qualities (quality_profile_name, quality_name, quality_group_name, position, enabled, upgrade_until)
SELECT '${esc$12(profileName2)}', NULL, '${esc$12(item.name)}', ${item.position}, ${enabled3}, ${upgradeUntil}
WHERE NOT EXISTS (
  SELECT 1 FROM quality_profile_qualities
  WHERE quality_profile_name = '${esc$12(profileName2)}'
    AND quality_name IS NULL
    AND quality_group_name = '${esc$12(item.name)}'
)`,
      parameters: [],
      query: {}
    });
    return queries;
  }
  queries.push({
    sql: `INSERT INTO quality_profile_qualities (quality_profile_name, quality_name, quality_group_name, position, enabled, upgrade_until)
SELECT '${esc$12(profileName2)}', '${esc$12(item.name)}', NULL, ${item.position}, ${enabled3}, ${upgradeUntil}
WHERE NOT EXISTS (
  SELECT 1 FROM quality_profile_qualities
  WHERE quality_profile_name = '${esc$12(profileName2)}'
    AND quality_name = '${esc$12(item.name)}'
    AND quality_group_name IS NULL
)`,
    parameters: [],
    query: {}
  });
  return queries;
}
function buildUpdateQueries(profileName2, current3, next2) {
  const queries = [];
  const parts = [];
  if (current3.position !== next2.position) parts.push(`position = ${next2.position}`);
  if (current3.enabled !== next2.enabled) parts.push(`enabled = ${next2.enabled ? 1 : 0}`);
  if (current3.upgradeUntil !== next2.upgradeUntil) parts.push(`upgrade_until = ${next2.upgradeUntil ? 1 : 0}`);
  if (parts.length > 0) if (current3.type === "quality") queries.push({
    sql: `UPDATE quality_profile_qualities
SET ${parts.join(", ")}
WHERE quality_profile_name = '${esc$12(profileName2)}'
  AND quality_name = '${esc$12(current3.name)}'
  AND quality_group_name IS NULL
  AND position = ${current3.position}
  AND enabled = ${current3.enabled ? 1 : 0}
  AND upgrade_until = ${current3.upgradeUntil ? 1 : 0}`,
    parameters: [],
    query: {}
  });
  else queries.push({
    sql: `UPDATE quality_profile_qualities
SET ${parts.join(", ")}
WHERE quality_profile_name = '${esc$12(profileName2)}'
  AND quality_group_name = '${esc$12(current3.name)}'
  AND quality_name IS NULL
  AND position = ${current3.position}
  AND enabled = ${current3.enabled ? 1 : 0}
  AND upgrade_until = ${current3.upgradeUntil ? 1 : 0}`,
    parameters: [],
    query: {}
  });
  if (current3.type === "group") {
    const currentMembers = (current3.members ?? []).map((m3) => m3.name).filter(Boolean);
    const nextMembers = (next2.members ?? []).map((m3) => m3.name).filter(Boolean);
    if (currentMembers.length !== nextMembers.length || currentMembers.some((m3, i) => m3 !== nextMembers[i])) {
      const membersGuard = buildGroupMembersGuard(profileName2, current3.name, currentMembers);
      queries.push({
        sql: `DELETE FROM quality_group_members
WHERE quality_profile_name = '${esc$12(profileName2)}'
  AND quality_group_name = '${esc$12(current3.name)}'
  AND ${membersGuard}`,
        parameters: [],
        query: {}
      });
      if (nextMembers.length > 0) {
        const insertRows = nextMembers.map((member, index88) => `SELECT '${esc$12(profileName2)}' AS quality_profile_name, '${esc$12(current3.name)}' AS quality_group_name, '${esc$12(member)}' AS quality_name, ${index88} AS position`).join(`
UNION ALL
`);
        queries.push({
          sql: `INSERT INTO quality_group_members (quality_profile_name, quality_group_name, quality_name, position)
WITH can_insert AS (
  SELECT (
    SELECT COUNT(*)
    FROM quality_group_members
    WHERE quality_profile_name = '${esc$12(profileName2)}'
      AND quality_group_name = '${esc$12(current3.name)}'
  ) = 0 AS ok
),
new_rows AS (
${insertRows}
)
SELECT
  new_rows.quality_profile_name,
  new_rows.quality_group_name,
  new_rows.quality_name,
  new_rows.position
FROM new_rows
CROSS JOIN can_insert
WHERE ok`,
          parameters: [],
          query: {}
        });
      }
    }
  }
  return queries;
}
function rowDesiredState(mode, key2, fromItem, toItem) {
  return { ordered_items: {
    mode,
    key: key2,
    from: fromItem ? [cloneItem2(fromItem)] : [],
    to: toItem ? [cloneItem2(toItem)] : []
  } };
}
async function updateQualities(options2) {
  const { databaseId, cache: cache3, layer, profileName: profileName2, input } = options2;
  if (input.orderedItems.filter((item) => item.upgradeUntil).length > 1) throw new Error('Only one quality can be marked as "upgrade until"');
  const currentData2 = await qualities(cache3, databaseId, profileName2);
  const currentByKey = new Map(currentData2.orderedItems.map((item) => [rowKey(item), item]));
  const nextByKey = new Map(input.orderedItems.map((item) => [rowKey(item), item]));
  const removedItems = currentData2.orderedItems.filter((item) => !nextByKey.has(rowKey(item)));
  const addedItems = input.orderedItems.filter((item) => !currentByKey.has(rowKey(item)));
  const updatedItems = [];
  for (const [key2, next2] of nextByKey.entries()) {
    const current3 = currentByKey.get(key2);
    if (!current3) continue;
    if (!sameRow(current3, next2)) updatedItems.push({
      current: current3,
      next: next2
    });
  }
  if (removedItems.length === 0 && addedItems.length === 0 && updatedItems.length === 0) return { success: true };
  await logger.info(`Save quality profile qualities "${profileName2}"`, {
    source: "QualityProfile",
    meta: {
      profileName: profileName2,
      removed: removedItems.length,
      added: addedItems.length,
      updated: updatedItems.length
    }
  });
  const rowOps = [];
  function pushUpdateOp(change) {
    const queries = buildUpdateQueries(profileName2, change.current, change.next);
    if (queries.length === 0) return;
    rowOps.push({
      description: `update-quality-profile-row-${profileName2}-${change.next.type}-${change.next.name}`,
      queries,
      desiredState: rowDesiredState("update", rowKey(change.next), change.current, change.next),
      changedFields: [rowFieldKey(change.next)],
      summary: "Update quality profile quality row",
      title: `Update ${change.next.type} "${change.next.name}" on quality profile "${profileName2}"`
    });
  }
  for (const item of removedItems) rowOps.push({
    description: `remove-quality-profile-row-${profileName2}-${item.type}-${item.name}`,
    queries: buildDeleteQueries(profileName2, item),
    desiredState: rowDesiredState("remove", rowKey(item), item, null),
    changedFields: [rowFieldKey(item)],
    summary: "Remove quality profile quality row",
    title: `Remove ${item.type} "${item.name}" from quality profile "${profileName2}"`
  });
  const clearingUpgradeUntilUpdates = updatedItems.filter((change) => change.current.upgradeUntil && !change.next.upgradeUntil);
  const remainingUpdates = updatedItems.filter((change) => !(change.current.upgradeUntil && !change.next.upgradeUntil));
  for (const change of clearingUpgradeUntilUpdates) pushUpdateOp(change);
  for (const item of addedItems) rowOps.push({
    description: `add-quality-profile-row-${profileName2}-${item.type}-${item.name}`,
    queries: buildAddQueries(profileName2, item),
    desiredState: rowDesiredState("add", rowKey(item), null, item),
    changedFields: [rowFieldKey(item)],
    summary: "Add quality profile quality row",
    title: `Add ${item.type} "${item.name}" to quality profile "${profileName2}"`
  });
  const sortedUpdates = [...remainingUpdates].sort((a2, b3) => {
    if (a2.next.upgradeUntil === b3.next.upgradeUntil) return 0;
    return a2.next.upgradeUntil ? 1 : -1;
  });
  for (const change of sortedUpdates) pushUpdateOp(change);
  if (rowOps.length === 0) return { success: true };
  const allQueries = rowOps.flatMap((op) => op.queries);
  const allChangedFields = rowOps.flatMap((op) => op.changedFields);
  const desiredState = { ordered_items: {
    from: currentData2.orderedItems.map(cloneItem2),
    to: input.orderedItems.map(cloneItem2)
  } };
  return writeOperation({
    databaseId,
    layer,
    description: `update-quality-profile-qualities-${profileName2}`,
    queries: allQueries,
    desiredState,
    metadata: {
      operation: "update",
      entity: "quality_profile",
      name: profileName2,
      stableKey: {
        key: "quality_profile_name",
        value: profileName2
      },
      changedFields: allChangedFields,
      summary: "Update quality profile qualities",
      title: `Update qualities on quality profile "${profileName2}"`
    }
  });
}
function esc4(value2) {
  return value2.replace(/'/g, "''");
}
async function create2(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  const queries = [];
  if (await db2.selectFrom("quality_profiles").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) {
    await logger.warn(`Duplicate quality profile name "${input.name}"`, {
      source: "QualityProfile",
      meta: {
        databaseId,
        name: input.name
      }
    });
    throw new Error(`A quality profile with name "${input.name}" already exists`);
  }
  const insertProfile = db2.insertInto("quality_profiles").values({
    name: input.name,
    description: input.description,
    upgrades_allowed: 1,
    minimum_custom_format_score: 0,
    upgrade_until_score: 0,
    upgrade_score_increment: 1
  }).compile();
  queries.push(insertProfile);
  const uniqueTags = Array.from(new Set(input.tags.map((tag2) => tag2.trim()).filter(Boolean)));
  for (const tagName of uniqueTags) {
    const insertTag = db2.insertInto("tags").values({ name: tagName }).onConflict((oc) => oc.column("name").doNothing()).compile();
    queries.push(insertTag);
    const linkTag = {
      sql: `INSERT INTO quality_profile_tags (quality_profile_name, tag_name) VALUES ('${esc4(input.name)}', '${esc4(tagName)}')`,
      parameters: [],
      query: {}
    };
    queries.push(linkTag);
  }
  if (input.orderedItems) for (const item of input.orderedItems) {
    if (item.type === "group") {
      const members = (item.members ?? []).map((m3) => m3.name).filter(Boolean);
      queries.push({
        sql: `INSERT INTO quality_groups (quality_profile_name, name) VALUES ('${esc4(input.name)}', '${esc4(item.name)}')`,
        parameters: [],
        query: {}
      });
      for (let i = 0; i < members.length; i++) queries.push({
        sql: `INSERT INTO quality_group_members (quality_profile_name, quality_group_name, quality_name, position) VALUES ('${esc4(input.name)}', '${esc4(item.name)}', '${esc4(members[i])}', ${i})`,
        parameters: [],
        query: {}
      });
    }
    queries.push({
      sql: `INSERT INTO quality_profile_qualities (quality_profile_name, quality_name, quality_group_name, position, enabled, upgrade_until) VALUES ('${esc4(input.name)}', ${item.type === "quality" ? `'${esc4(item.name)}'` : "NULL"}, ${item.type === "group" ? `'${esc4(item.name)}'` : "NULL"}, ${item.position}, ${item.enabled ? 1 : 0}, ${item.upgradeUntil ? 1 : 0})`,
      parameters: [],
      query: {}
    });
  }
  else {
    const allQualities = await db2.selectFrom("qualities").select(["id", "name"]).orderBy("id").execute();
    const allQualityNames = new Set(allQualities.map((quality) => quality.name));
    const enabledQualities = /* @__PURE__ */ new Set(["Remux-1080p", "Bluray-1080p"]);
    const upgradeUntilName = "Bluray-1080p";
    const groupDefinitions = [
      {
        name: "WEB 1080p",
        members: ["WEBDL-1080p", "WEBRip-1080p"],
        enabled: false
      },
      {
        name: "Pre-releases",
        members: [
          "REGIONAL",
          "DVDSCR",
          "TELECINE",
          "TELESYNC",
          "CAM",
          "WORKPRINT"
        ],
        enabled: false
      },
      {
        name: "Unwanted",
        members: [
          "Unknown",
          "Raw-HD",
          "BR-DISK"
        ],
        enabled: false
      }
    ];
    const groupMap = new Map(groupDefinitions.map((group) => [group.name, group]));
    const groupAvailability = new Map(groupDefinitions.map((group) => [group.name, group.members.every((member) => allQualityNames.has(member))]));
    const desiredOrder = [
      {
        type: "quality",
        name: "Remux-2160p"
      },
      {
        type: "quality",
        name: "Bluray-2160p"
      },
      {
        type: "quality",
        name: "WEBDL-2160p"
      },
      {
        type: "quality",
        name: "WEBRip-2160p"
      },
      {
        type: "quality",
        name: "HDTV-2160p"
      },
      {
        type: "quality",
        name: "Remux-1080p"
      },
      {
        type: "quality",
        name: "Bluray-1080p"
      },
      {
        type: "group",
        name: "WEB 1080p",
        members: ["WEBDL-1080p", "WEBRip-1080p"]
      },
      {
        type: "quality",
        name: "HDTV-1080p"
      },
      {
        type: "quality",
        name: "Bluray-720p"
      },
      {
        type: "quality",
        name: "WEBDL-720p"
      },
      {
        type: "quality",
        name: "WEBRip-720p"
      },
      {
        type: "quality",
        name: "HDTV-720p"
      },
      {
        type: "quality",
        name: "Bluray-576p"
      },
      {
        type: "quality",
        name: "Bluray-480p"
      },
      {
        type: "quality",
        name: "WEBDL-480p"
      },
      {
        type: "quality",
        name: "WEBRip-480p"
      },
      {
        type: "quality",
        name: "HDTV-480p"
      },
      {
        type: "quality",
        name: "DVD-R"
      },
      {
        type: "quality",
        name: "DVD"
      },
      {
        type: "quality",
        name: "SDTV"
      },
      {
        type: "group",
        name: "Pre-releases",
        members: [
          "REGIONAL",
          "DVDSCR",
          "TELECINE",
          "TELESYNC",
          "CAM",
          "WORKPRINT"
        ]
      },
      {
        type: "group",
        name: "Unwanted",
        members: [
          "Unknown",
          "Raw-HD",
          "BR-DISK"
        ]
      }
    ];
    const orderedItems = [];
    const usedNames = /* @__PURE__ */ new Set();
    let position = 1;
    for (const entry of desiredOrder) {
      if (entry.type === "group") {
        const group = groupMap.get(entry.name);
        const canGroup = groupAvailability.get(entry.name) ?? false;
        const members = group?.members ?? entry.members;
        if (!canGroup) {
          for (const member of members) {
            if (!allQualityNames.has(member) || usedNames.has(member)) continue;
            orderedItems.push({
              type: "quality",
              name: member,
              position,
              enabled: false,
              upgradeUntil: false,
              members: []
            });
            usedNames.add(member);
            position += 1;
          }
          continue;
        }
        orderedItems.push({
          type: "group",
          name: entry.name,
          position,
          enabled: group?.enabled ?? false,
          upgradeUntil: false,
          members: members.map((member) => ({ name: member }))
        });
        for (const member of members) usedNames.add(member);
        position += 1;
        continue;
      }
      if (!allQualityNames.has(entry.name) || usedNames.has(entry.name)) continue;
      orderedItems.push({
        type: "quality",
        name: entry.name,
        position,
        enabled: enabledQualities.has(entry.name),
        upgradeUntil: entry.name === upgradeUntilName,
        members: []
      });
      usedNames.add(entry.name);
      position += 1;
    }
    for (const quality of allQualities) {
      if (usedNames.has(quality.name)) continue;
      orderedItems.push({
        type: "quality",
        name: quality.name,
        position,
        enabled: false,
        upgradeUntil: false,
        members: []
      });
      position += 1;
    }
    const groupNames = orderedItems.filter((item) => item.type === "group").map((item) => item.name);
    for (const groupName of groupNames) {
      const group = groupMap.get(groupName);
      if (!group) continue;
      const insertGroup = {
        sql: `INSERT INTO quality_groups (quality_profile_name, name) VALUES ('${esc4(input.name)}', '${esc4(groupName)}')`,
        parameters: [],
        query: {}
      };
      queries.push(insertGroup);
      for (let i = 0; i < group.members.length; i++) {
        const memberName = group.members[i];
        const insertMember = {
          sql: `INSERT INTO quality_group_members (quality_profile_name, quality_group_name, quality_name, position) VALUES ('${esc4(input.name)}', '${esc4(groupName)}', '${esc4(memberName)}', ${i})`,
          parameters: [],
          query: {}
        };
        queries.push(insertMember);
      }
    }
    for (const item of orderedItems) {
      const enabled3 = item.enabled ? 1 : 0;
      const upgradeUntil = item.upgradeUntil ? 1 : 0;
      const insertQuality = {
        sql: `INSERT INTO quality_profile_qualities (quality_profile_name, quality_name, quality_group_name, position, enabled, upgrade_until) VALUES ('${esc4(input.name)}', ${item.type === "quality" ? `'${esc4(item.name)}'` : "NULL"}, ${item.type === "group" ? `'${esc4(item.name)}'` : "NULL"}, ${item.position}, ${enabled3}, ${upgradeUntil})`,
        parameters: [],
        query: {}
      };
      queries.push(insertQuality);
    }
  }
  if (input.language !== null) {
    const insertLanguage = {
      sql: `INSERT INTO quality_profile_languages (quality_profile_name, language_name, type) VALUES ('${esc4(input.name)}', '${esc4(input.language)}', 'simple')`,
      parameters: [],
      query: {}
    };
    queries.push(insertLanguage);
  }
  return await writeOperation({
    databaseId,
    layer,
    description: `create-quality-profile-${input.name}`,
    queries,
    desiredState: {
      name: input.name,
      description: input.description ?? null,
      tags: uniqueTags,
      language: input.language ?? null
    },
    metadata: {
      operation: "create",
      entity: "quality_profile",
      name: input.name,
      stableKey: {
        key: "quality_profile_name",
        value: input.name
      },
      summary: "Create quality profile",
      title: `Create quality profile "${input.name}"`
    }
  });
}
async function remove(options2) {
  const { databaseId, cache: cache3, layer, profileName: profileName2 } = options2;
  const db2 = cache3.kb;
  const queries = [];
  const tagCountRow = await db2.selectFrom("quality_profile_tags").select(db2.fn.count("quality_profile_name").as("count")).where("quality_profile_name", "=", profileName2).executeTakeFirst();
  const languageCountRow = await db2.selectFrom("quality_profile_languages").select(db2.fn.count("quality_profile_name").as("count")).where("quality_profile_name", "=", profileName2).executeTakeFirst();
  const qualitiesCountRow = await db2.selectFrom("quality_profile_qualities").select(db2.fn.count("quality_profile_name").as("count")).where("quality_profile_name", "=", profileName2).executeTakeFirst();
  const cfCountRow = await db2.selectFrom("quality_profile_custom_formats").select(db2.fn.count("quality_profile_name").as("count")).where("quality_profile_name", "=", profileName2).executeTakeFirst();
  const groupCountRow = await db2.selectFrom("quality_groups").select(db2.fn.count("quality_profile_name").as("count")).where("quality_profile_name", "=", profileName2).executeTakeFirst();
  const deleteProfileTags = db2.deleteFrom("quality_profile_tags").where("quality_profile_name", "=", profileName2).compile();
  queries.push(deleteProfileTags);
  const deleteProfileLanguages = db2.deleteFrom("quality_profile_languages").where("quality_profile_name", "=", profileName2).compile();
  queries.push(deleteProfileLanguages);
  const deleteProfileQualities = db2.deleteFrom("quality_profile_qualities").where("quality_profile_name", "=", profileName2).compile();
  queries.push(deleteProfileQualities);
  const deleteProfileCustomFormats = db2.deleteFrom("quality_profile_custom_formats").where("quality_profile_name", "=", profileName2).compile();
  queries.push(deleteProfileCustomFormats);
  const deleteQualityGroups = db2.deleteFrom("quality_groups").where("quality_profile_name", "=", profileName2).compile();
  queries.push(deleteQualityGroups);
  const deleteProfile = db2.deleteFrom("quality_profiles").where("name", "=", profileName2).compile();
  queries.push(deleteProfile);
  return await writeOperation({
    databaseId,
    layer,
    description: `delete-quality-profile-${profileName2}`,
    queries,
    desiredState: {
      deleted: true,
      name: profileName2,
      counts: {
        tags: tagCountRow?.count ?? 0,
        languages: languageCountRow?.count ?? 0,
        qualities: qualitiesCountRow?.count ?? 0,
        custom_format_scores: cfCountRow?.count ?? 0,
        groups: groupCountRow?.count ?? 0
      }
    },
    metadata: {
      operation: "delete",
      entity: "quality_profile",
      name: profileName2,
      stableKey: {
        key: "quality_profile_name",
        value: profileName2
      },
      changedFields: ["deleted"],
      summary: "Delete quality profile",
      title: `Delete quality profile "${profileName2}"`
    }
  });
}
async function getProfilarrProfileNames() {
  const profileNames = /* @__PURE__ */ new Set();
  const databases = pcdManager.getAll().filter((db2) => db2.enabled);
  for (const db2 of databases) {
    const dbCache = pcdManager.getCache(db2.id);
    if (!dbCache?.isBuilt()) continue;
    try {
      const names$1 = await names(dbCache);
      for (const name of names$1) profileNames.add(name);
    } catch {
    }
  }
  return profileNames;
}
function parseLegacySections(payload2) {
  const raw = payload2.sections ?? payload2.section;
  if (Array.isArray(raw)) {
    const sections = raw.filter((value2) => value2 === "qualityProfiles" || value2 === "delayProfiles" || value2 === "mediaManagement");
    return sections.length > 0 ? sections : null;
  }
  if (typeof raw === "string") {
    if (raw === "qualityProfiles" || raw === "delayProfiles" || raw === "mediaManagement") return [raw];
  }
  return null;
}
function resolveSections(jobType, payload2) {
  const mapped = jobTypeToSection.get(jobType);
  if (mapped) return [mapped];
  if (jobType !== "arr.sync") return [];
  return parseLegacySections(payload2) ?? sectionOrder;
}
function notify(runAt) {
  if (!runAt) return;
  jobDispatcher.notifyJobEnqueued(runAt);
}
function preservedQueuedRunAt(dedupeKey, force = false) {
  if (force) return null;
  const existing = jobQueueQueries.getByDedupeKey(dedupeKey);
  return existing?.status === "queued" ? existing.runAt : null;
}
function scheduleArrSyncForInstance(instanceId) {
  const status = arrSyncQueries.getSyncConfigStatus(instanceId);
  const schedules = [
    {
      key: "qualityProfiles",
      config: status.qualityProfiles,
      jobType: "arr.sync.qualityProfiles"
    },
    {
      key: "delayProfiles",
      config: status.delayProfiles,
      jobType: "arr.sync.delayProfiles"
    },
    {
      key: "mediaManagement",
      config: status.mediaManagement,
      jobType: "arr.sync.mediaManagement"
    }
  ];
  jobQueueQueries.unscheduleByDedupeKey(`arr.sync:${instanceId}`);
  for (const schedule of schedules) {
    const dedupeKey = `${schedule.jobType}:${instanceId}`;
    if (schedule.config.trigger !== "schedule") {
      jobQueueQueries.unscheduleByDedupeKey(dedupeKey);
      continue;
    }
    let nextRun = schedule.config.nextRunAt;
    if (!nextRun && schedule.config.cron) nextRun = calculateNextRun(schedule.config.cron) ?? null;
    if (!nextRun) {
      jobQueueQueries.unscheduleByDedupeKey(dedupeKey);
      continue;
    }
    notify(jobQueueQueries.upsertScheduled({
      jobType: schedule.jobType,
      runAt: nextRun,
      payload: { instanceId },
      source: "schedule",
      dedupeKey
    }).runAt);
  }
}
function scheduleUpgradeForInstance(instanceId) {
  const config2 = upgradeConfigsQueries.getByArrInstanceId(instanceId);
  if (!config2 || !config2.enabled) {
    jobQueueQueries.unscheduleByDedupeKey(`arr.upgrade:${instanceId}`);
    return;
  }
  let nextRun = config2.nextRunAt;
  if (!nextRun) nextRun = calculateNextRun(config2.cron) ?? null;
  if (!nextRun) {
    jobQueueQueries.unscheduleByDedupeKey(`arr.upgrade:${instanceId}`);
    return;
  }
  notify(jobQueueQueries.upsertScheduled({
    jobType: "arr.upgrade",
    runAt: nextRun,
    payload: { instanceId },
    source: "schedule",
    dedupeKey: `arr.upgrade:${instanceId}`
  }).runAt);
}
function scheduleRenameForInstance(instanceId) {
  const settings2 = arrRenameSettingsQueries.getByInstanceId(instanceId);
  if (!settings2 || !settings2.enabled) {
    jobQueueQueries.unscheduleByDedupeKey(`arr.rename:${instanceId}`);
    return;
  }
  let nextRun = settings2.nextRunAt;
  if (!nextRun) nextRun = calculateNextRun(settings2.cron) ?? null;
  if (!nextRun) {
    jobQueueQueries.unscheduleByDedupeKey(`arr.rename:${instanceId}`);
    return;
  }
  notify(jobQueueQueries.upsertScheduled({
    jobType: "arr.rename",
    runAt: nextRun,
    payload: { instanceId },
    source: "schedule",
    dedupeKey: `arr.rename:${instanceId}`
  }).runAt);
}
function scheduleCleanupForInstance(instanceId) {
  const settings2 = arrCleanupSettingsQueries.getByInstanceId(instanceId);
  if (!settings2 || !settings2.enabled) {
    jobQueueQueries.unscheduleByDedupeKey(`arr.cleanup:${instanceId}`);
    return;
  }
  let nextRun = settings2.nextRunAt;
  if (!nextRun) nextRun = calculateNextRun(settings2.cron) ?? null;
  if (!nextRun) {
    jobQueueQueries.unscheduleByDedupeKey(`arr.cleanup:${instanceId}`);
    return;
  }
  notify(jobQueueQueries.upsertScheduled({
    jobType: "arr.cleanup",
    runAt: nextRun,
    payload: { instanceId },
    source: "schedule",
    dedupeKey: `arr.cleanup:${instanceId}`
  }).runAt);
}
function scheduleDriftForInstance(instanceId) {
  if (!FEATURES.drift) {
    jobQueueQueries.unscheduleByDedupeKey(`arr.drift:${instanceId}`);
    return;
  }
  const settings2 = arrDriftSettingsQueries.getByInstanceId(instanceId);
  if (!settings2 || !settings2.enabled) {
    jobQueueQueries.unscheduleByDedupeKey(`arr.drift:${instanceId}`);
    return;
  }
  let nextRun = settings2.nextRunAt;
  if (!nextRun) nextRun = calculateNextRun(settings2.cron) ?? null;
  if (!nextRun) {
    jobQueueQueries.unscheduleByDedupeKey(`arr.drift:${instanceId}`);
    return;
  }
  notify(jobQueueQueries.upsertScheduled({
    jobType: "arr.drift",
    runAt: nextRun,
    payload: { instanceId },
    source: "schedule",
    dedupeKey: `arr.drift:${instanceId}`
  }).runAt);
}
function scheduleLibraryRefreshForInstance(instanceId) {
  const instance = arrInstancesQueries.getById(instanceId);
  if (!instance || instance.enabled === 0 || instance.library_refresh_interval <= 0) {
    jobQueueQueries.unscheduleByDedupeKey(`arr.library.refresh:${instanceId}`);
    return;
  }
  const runAt = calculateNextRunFromMinutes(instance.library_last_refreshed_at ?? (/* @__PURE__ */ new Date()).toISOString(), instance.library_refresh_interval);
  notify(jobQueueQueries.upsertScheduled({
    jobType: "arr.library.refresh",
    runAt,
    payload: { instanceId },
    source: "schedule",
    dedupeKey: `arr.library.refresh:${instanceId}`
  }).runAt);
}
function schedulePcdSyncForDatabase(databaseId) {
  const instance = databaseInstancesQueries.getById(databaseId);
  if (!instance || instance.enabled === 0 || instance.sync_strategy <= 0) {
    jobQueueQueries.unscheduleByDedupeKey(`pcd.sync:${databaseId}`);
    return;
  }
  const runAt = calculateNextRunFromMinutes(instance.last_synced_at ?? (/* @__PURE__ */ new Date()).toISOString(), instance.sync_strategy);
  notify(jobQueueQueries.upsertScheduled({
    jobType: "pcd.sync",
    runAt,
    payload: { databaseId },
    source: "schedule",
    dedupeKey: `pcd.sync:${databaseId}`
  }).runAt);
}
function scheduleBackupJobs(options2 = {}) {
  const settings2 = backupSettingsQueries.get();
  if (!settings2 || settings2.enabled !== 1) {
    jobQueueQueries.cancelByDedupeKey("backup.create");
    jobQueueQueries.cancelByDedupeKey("backup.cleanup");
    return;
  }
  const backupRunAt = preservedQueuedRunAt("backup.create", options2.forceBackup) ?? calculateNextRunFromSchedule(settings2.schedule);
  const cleanupRunAt = preservedQueuedRunAt("backup.cleanup", options2.forceCleanup) ?? calculateNextRunFromSchedule("daily");
  const backupJob = jobQueueQueries.upsertScheduled({
    jobType: "backup.create",
    runAt: backupRunAt,
    payload: {},
    source: "schedule",
    dedupeKey: "backup.create"
  });
  const cleanupJob = jobQueueQueries.upsertScheduled({
    jobType: "backup.cleanup",
    runAt: cleanupRunAt,
    payload: {},
    source: "schedule",
    dedupeKey: "backup.cleanup"
  });
  notify(backupJob.runAt);
  notify(cleanupJob.runAt);
}
function scheduleLogCleanup(options2 = {}) {
  const settings2 = logSettingsQueries.get();
  if (!settings2 || settings2.file_logging !== 1) {
    jobQueueQueries.cancelByDedupeKey("logs.cleanup");
    return;
  }
  const runAt = preservedQueuedRunAt("logs.cleanup", options2.force) ?? calculateNextRunFromSchedule("daily");
  notify(jobQueueQueries.upsertScheduled({
    jobType: "logs.cleanup",
    runAt,
    payload: {},
    source: "schedule",
    dedupeKey: "logs.cleanup"
  }).runAt);
}
function scheduleAnnouncementsFetch() {
  const runAt = (/* @__PURE__ */ new Date()).toISOString();
  notify(jobQueueQueries.upsertScheduled({
    jobType: "announcements.fetch",
    runAt,
    payload: {},
    source: "schedule",
    dedupeKey: "announcements.fetch"
  }).runAt);
}
function scheduleAllJobs() {
  const arrInstances = arrInstancesQueries.getAll();
  for (const instance of arrInstances) {
    scheduleArrSyncForInstance(instance.id);
    scheduleUpgradeForInstance(instance.id);
    scheduleRenameForInstance(instance.id);
    scheduleCleanupForInstance(instance.id);
    scheduleDriftForInstance(instance.id);
    scheduleLibraryRefreshForInstance(instance.id);
  }
  const databases = databaseInstancesQueries.getAll();
  for (const database of databases) schedulePcdSyncForDatabase(database.id);
  scheduleBackupJobs();
  scheduleLogCleanup();
  scheduleAnnouncementsFetch();
}
function stashLinkPat(pat) {
  const id = crypto.randomUUID();
  linkPats.set(id, pat);
  return id;
}
function consumeLinkPat(id) {
  const pat = linkPats.get(id);
  linkPats.delete(id);
  return pat;
}
async function createBackup(sourceDir, backupDir, timestamp2) {
  let tmpDir = null;
  try {
    const now = timestamp2 ?? /* @__PURE__ */ new Date();
    const backupFilename = `backup-${now.toISOString().split("T")[0]}-${now.toISOString().split("T")[1].split(".")[0].replace(/:/g, "")}.tar.gz`;
    const backupPath = `${backupDir}/${backupFilename}`;
    try {
      await Deno.mkdir(backupDir, { recursive: true });
    } catch (error2) {
      return {
        success: false,
        error: `Failed to create backup directory: ${error2 instanceof Error ? error2.message : String(error2)}`
      };
    }
    try {
      if (!(await Deno.stat(sourceDir)).isDirectory) return {
        success: false,
        error: `Source path is not a directory: ${sourceDir}`
      };
    } catch (_error2) {
      return {
        success: false,
        error: `Source directory does not exist: ${sourceDir}`
      };
    }
    tmpDir = await Deno.makeTempDir({ prefix: "profilarr-backup-" });
    const tmpDataDir = `${tmpDir}/data`;
    const cpResult = await new Deno.Command("cp", {
      args: [
        "-a",
        sourceDir,
        tmpDataDir
      ],
      stdout: "piped",
      stderr: "piped"
    }).output();
    if (cpResult.code !== 0) return {
      success: false,
      error: `Failed to copy source directory: ${new TextDecoder().decode(cpResult.stderr)}`
    };
    const dbPath = `${tmpDataDir}/profilarr.db`;
    const walPath = `${tmpDataDir}/profilarr.db-wal`;
    const shmPath = `${tmpDataDir}/profilarr.db-shm`;
    try {
      if ((await Deno.stat(dbPath)).isFile) {
        await Deno.remove(dbPath);
        for (const sidecar of [walPath, shmPath]) try {
          await Deno.remove(sidecar);
        } catch (err) {
          if (!(err instanceof Deno.errors.NotFound)) throw err;
        }
        const dest = new Database(dbPath);
        try {
          db.getDatabase().backup(dest);
          dest.exec("PRAGMA wal_checkpoint(TRUNCATE)");
          dest.exec("PRAGMA journal_mode = DELETE");
          const rows = dest.prepare("PRAGMA integrity_check").all();
          if (!(rows.length === 1 && rows[0].integrity_check === "ok")) await logger.warn("Backup source has integrity issues; archive contains them as-is", {
            source: "createBackup",
            meta: { issues: rows.map((r2) => r2.integrity_check).slice(0, 10) }
          });
        } finally {
          dest.close();
        }
        const info = {
          appVersion: build.version,
          appChannel: build.channel,
          schemaVersion: migrationRunner.getCurrentVersion(),
          createdAt: now.toISOString(),
          sanitized: false
        };
        await Deno.writeTextFile(`${tmpDataDir}/INFO.json`, JSON.stringify(info, null, 2));
      }
    } catch (error2) {
      if (error2 instanceof Deno.errors.NotFound) {
      } else return {
        success: false,
        error: `Failed to snapshot backup database: ${error2 instanceof Error ? error2.message : String(error2)}`
      };
    }
    const { code: code3, stderr } = await new Deno.Command("tar", {
      args: [
        "-czf",
        backupPath,
        "-C",
        tmpDir,
        "data"
      ],
      stdout: "piped",
      stderr: "piped"
    }).output();
    if (code3 !== 0) return {
      success: false,
      error: `tar command failed with code ${code3}: ${new TextDecoder().decode(stderr)}`
    };
    return {
      success: true,
      filename: backupFilename,
      sizeBytes: (await Deno.stat(backupPath)).size
    };
  } catch (error2) {
    return {
      success: false,
      error: error2 instanceof Error ? error2.message : String(error2)
    };
  } finally {
    if (tmpDir) try {
      await Deno.remove(tmpDir, { recursive: true });
    } catch {
    }
  }
}
async function notifyFailure(jobId, error2) {
  try {
    await notificationManager.notify(notifications.backupFailed({ error: error2 }));
  } catch (err) {
    await logger.error("Failed to send backup failure notification", {
      source: "BackupCreateJob",
      meta: {
        jobId,
        error: err instanceof Error ? err.message : "Unknown error"
      }
    });
  }
}
async function cleanupLogs(logsDir, retentionDays) {
  const cutoffDate = /* @__PURE__ */ new Date();
  cutoffDate.setDate(cutoffDate.getDate() - retentionDays);
  const cutoffDateStr = cutoffDate.toISOString().split("T")[0];
  let deletedCount = 0;
  let errorCount = 0;
  const errors = [];
  const dateLogPattern = /^(\d{4}-\d{2}-\d{2})\.log$/;
  try {
    for await (const entry of Deno.readDir(logsDir)) {
      if (!entry.isFile) continue;
      const match = entry.name.match(dateLogPattern);
      if (!match) continue;
      const logDate = match[1];
      const filePath = `${logsDir}/${entry.name}`;
      try {
        if (logDate < cutoffDateStr) {
          await Deno.remove(filePath);
          deletedCount++;
        }
      } catch (error2) {
        errorCount++;
        errors.push({
          file: entry.name,
          error: error2
        });
      }
    }
  } catch (error2) {
    throw new Error(`Failed to read logs directory: ${error2 instanceof Error ? error2.message : String(error2)}`);
  }
  return {
    deletedCount,
    errorCount,
    errors
  };
}
async function notifyNewAnnouncements(jobId, inserted) {
  for (const announcement of inserted) try {
    await notificationManager.notify(notifications.announcementNew({ announcement }));
  } catch (err) {
    await logger.error("Failed to send announcement notification", {
      source: "AnnouncementsFetchJob",
      meta: {
        jobId,
        announcementId: announcement.id,
        error: err instanceof Error ? err.message : String(err)
      }
    });
  }
}
function enqueueJob(input) {
  const id = jobQueueQueries.create(input);
  const record = jobQueueQueries.getById(id);
  if (!record) throw new Error("Failed to enqueue job");
  jobDispatcher.notifyJobEnqueued(record.runAt);
  return record;
}
function upsertScheduledJob(input) {
  const record = jobQueueQueries.upsertScheduled(input);
  jobDispatcher.notifyJobEnqueued(record.runAt);
  return record;
}
var JobQueueRegistry, jobQueueRegistry, upgradeRunsQueries, SOURCE$4, dryRunExclusions, DRY_RUN_EXCLUSION_TTL_MS, UPGRADE_QUEUE_POLL_INTERVAL_MS, UPGRADE_QUEUE_GRACE_MS, UPGRADE_COMMAND_TIMEOUT_MS, upgradeRunHandler, renameRunsQueries, SOURCE$3, SOURCE$2, renameRunHandler, BaseSyncer, BYTES_PER_GB, SIZE_GB_DECIMALS, CONDITION_IMPLEMENTATIONS, QualityProfileSyncer, sectionRegistry, DelayProfileSyncer, MediaManagementSyncer, UNPREFIXED_SEQUENCE_BASE, PCDManager, pcdManager, SOURCE$1, SOURCE, TMDB_ID_REGEX, TVDB_ID_REGEX, cleanupHandler, arrDriftSettingsQueries, FIELD_ORDER, MEDIA_SETTINGS_FIELD_ORDER, NAMING_FIELD_ORDER, QUALITY_DEFINITION_FIELD_ORDER, QUALITY_DEFINITION_UNLIMITED_MAX, IMPLEMENTATION_LABELS, driftHandler, libraryRefreshHandler, sectionOrder, jobTypeToSection, arrSyncHandler, linkPats, pcdLinkHandler, dbSyncHandler, backupCreateHandler, backupCleanupHandler, logsCleanupHandler, announcementsFetchHandler, JobDispatcher, jobDispatcher;
var init_queueService = __esm({
  async "dist/build/server/chunks/queueService.js"() {
    "use strict";
    await init_db();
    init_config();
    await init_announcements();
    init_build();
    init_client();
    await init_database();
    init_dates();
    await init_arrSync();
    await init_databaseInstances();
    await init_NotificationManager();
    init_operations2();
    await init_arrInstances();
    await init_jobQueue();
    await init_jobRunHistory();
    await init_display();
    init_jobEvents();
    await init_arrCleanupSettings();
    await init_base();
    await init_radarr();
    await init_sonarr();
    init_uuid();
    init_selectors();
    init_cooldown();
    await init_factory();
    await init_git();
    await init_markdown();
    await init_pcdOps();
    init_registry();
    init_mappings();
    init_conditions();
    init_mediaManagement();
    await init_cleanup();
    await init_arrDriftStatus();
    init_features();
    init_cache2();
    await init_backupSettings();
    await init_migrations();
    init_croner();
    init_esm();
    JobQueueRegistry = class {
      handlers = /* @__PURE__ */ new Map();
      register(jobType, handler) {
        this.handlers.set(jobType, handler);
      }
      get(jobType) {
        return this.handlers.get(jobType);
      }
      getAll() {
        return Array.from(this.handlers.entries()).map(([jobType, handler]) => ({
          jobType,
          handler
        }));
      }
    };
    jobQueueRegistry = new JobQueueRegistry();
    upgradeRunsQueries = {
      /**
      * Insert a new upgrade run
      */
      insert(log) {
        db.execute(`INSERT INTO upgrade_runs (
				id, instance_id, started_at, completed_at, status, dry_run,
				cron, filter_mode, filter_name, filter_id,
				library_total, library_cached, library_fetch_ms,
				matched_count, after_cooldown, cooldown_hours, dry_run_excluded,
				selection_method, selection_requested, selected_count,
				searches_triggered, successful, failed,
				items, errors
			) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, log.id, log.instanceId, log.startedAt, log.completedAt, log.status, log.config.dryRun ? 1 : 0, log.config.cron, log.config.filterMode, log.config.selectedFilter, log.filter.id, log.library.totalItems, log.library.fetchedFromCache ? 1 : 0, log.library.fetchDurationMs, log.filter.matchedCount, log.filter.afterCooldown, 0, log.filter.dryRunExcluded, log.selection.method, log.selection.requestedCount, log.selection.actualCount, log.results.searchesTriggered, log.results.successful, log.results.failed, JSON.stringify(log.selection.items), JSON.stringify(log.results.errors));
      },
      /**
      * Get all upgrade runs for an instance, newest first
      */
      getByInstanceId(instanceId, limit = 100) {
        return db.query(`SELECT * FROM upgrade_runs
			WHERE instance_id = ?
			ORDER BY started_at DESC
			LIMIT ?`, instanceId, limit).map(rowToLog$1);
      },
      /**
      * Get a single upgrade run by ID
      */
      getById(id) {
        const row = db.queryFirst("SELECT * FROM upgrade_runs WHERE id = ?", id);
        return row ? rowToLog$1(row) : void 0;
      },
      /**
      * Get recent runs across all instances
      */
      getRecent(limit = 50) {
        return db.query(`SELECT * FROM upgrade_runs
			ORDER BY started_at DESC
			LIMIT ?`, limit).map(rowToLog$1);
      },
      /**
      * Get runs by status for an instance
      */
      getByStatus(instanceId, status, limit = 50) {
        return db.query(`SELECT * FROM upgrade_runs
			WHERE instance_id = ? AND status = ?
			ORDER BY started_at DESC
			LIMIT ?`, instanceId, status, limit).map(rowToLog$1);
      },
      /**
      * Delete old runs (for retention policy)
      * Returns number of rows deleted
      */
      deleteOlderThan(days) {
        return db.execute(`DELETE FROM upgrade_runs
			WHERE datetime(started_at) < datetime('now', '-' || ? || ' days')`, days);
      },
      /**
      * Delete all runs for an instance
      */
      deleteByInstanceId(instanceId) {
        return db.execute("DELETE FROM upgrade_runs WHERE instance_id = ?", instanceId);
      },
      /**
      * Get count of runs for an instance
      */
      getCount(instanceId) {
        return db.queryFirst("SELECT COUNT(*) as count FROM upgrade_runs WHERE instance_id = ?", instanceId)?.count ?? 0;
      },
      /**
      * Get stats summary for an instance
      */
      getStats(instanceId) {
        const result = db.queryFirst(`SELECT
				COUNT(*) as total_runs,
				SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as successful_runs,
				SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed_runs,
				SUM(searches_triggered) as total_searches,
				SUM(successful) as total_upgrades
			FROM upgrade_runs
			WHERE instance_id = ?`, instanceId);
        return {
          totalRuns: result?.total_runs ?? 0,
          successfulRuns: result?.successful_runs ?? 0,
          failedRuns: result?.failed_runs ?? 0,
          totalSearches: result?.total_searches ?? 0,
          totalUpgrades: result?.total_upgrades ?? 0
        };
      }
    };
    SOURCE$4 = "UpgradeJob";
    dryRunExclusions = /* @__PURE__ */ new Map();
    DRY_RUN_EXCLUSION_TTL_MS = 36e5;
    UPGRADE_QUEUE_POLL_INTERVAL_MS = 3e3;
    UPGRADE_QUEUE_GRACE_MS = 18e4;
    UPGRADE_COMMAND_TIMEOUT_MS = 36e5;
    upgradeRunHandler = async (job) => {
      const instanceId = Number(job.payload.instanceId);
      if (!Number.isFinite(instanceId)) return {
        status: "failure",
        error: "Invalid instance ID"
      };
      const config2 = upgradeConfigsQueries.getByArrInstanceId(instanceId);
      if (!config2 || !config2.enabled) return {
        status: "cancelled",
        output: "Upgrade config disabled"
      };
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return {
        status: "failure",
        error: "Arr instance not found"
      };
      const dryRun = Boolean(job.payload.dryRun);
      if (config2.filters.filter((f2) => f2.enabled).length === 0) {
        const nextRunAt = calculateNextRun(config2.cron);
        if (nextRunAt) upgradeConfigsQueries.updateNextRunAt(config2.arrInstanceId, nextRunAt);
        return {
          status: "skipped",
          output: "No enabled upgrade filters",
          rescheduleAt: job.source === "schedule" ? nextRunAt ?? void 0 : void 0
        };
      }
      try {
        const log = await processUpgradeConfig(config2, instance, job.source === "manual", dryRun);
        if (log.status !== "failed" && config2.filterMode === "round_robin") upgradeConfigsQueries.incrementFilterIndex(config2.arrInstanceId);
        upgradeConfigsQueries.updateLastRun(config2.arrInstanceId);
        const nextRunAt = calculateNextRun(config2.cron);
        if (nextRunAt) upgradeConfigsQueries.updateNextRunAt(config2.arrInstanceId, nextRunAt);
        const output = `Processed ${log.selection.actualCount} item(s) using "${log.config.selectedFilter}"`;
        if (log.status === "failed") return {
          status: "failure",
          error: log.results.errors.join("; "),
          rescheduleAt: job.source === "schedule" ? nextRunAt ?? void 0 : void 0
        };
        if (log.selection.actualCount === 0) return {
          status: "skipped",
          output,
          rescheduleAt: job.source === "schedule" ? nextRunAt ?? void 0 : void 0
        };
        return {
          status: "success",
          output,
          rescheduleAt: job.source === "schedule" ? nextRunAt ?? void 0 : void 0
        };
      } catch (error2) {
        await logger.error("Upgrade job failed", {
          source: "UpgradeJob",
          meta: {
            jobId: job.id,
            instanceId,
            instanceName: instance.name,
            error: error2
          }
        });
        return {
          status: "failure",
          error: error2 instanceof Error ? error2.message : String(error2)
        };
      }
    };
    jobQueueRegistry.register("arr.upgrade", upgradeRunHandler);
    renameRunsQueries = {
      /**
      * Insert a new rename run
      */
      insert(log) {
        db.execute(`INSERT INTO rename_runs (
				id, instance_id, started_at, completed_at, status, dry_run, manual,
				rename_folders, ignore_tag,
				library_total, library_fetch_ms,
				after_ignore_tag, skipped_by_tag,
				files_needing_rename, files_renamed, folders_renamed,
				commands_triggered, commands_completed, commands_failed,
				items, errors
			) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, log.id, log.instanceId, log.startedAt, log.completedAt, log.status, log.config.dryRun ? 1 : 0, log.config.manual ? 1 : 0, log.config.renameFolders ? 1 : 0, log.config.ignoreTag, log.library.totalItems, log.library.fetchDurationMs, log.filtering.afterIgnoreTag, log.filtering.skippedByTag, log.results.filesNeedingRename, log.results.filesRenamed, log.results.foldersRenamed, log.results.commandsTriggered, log.results.commandsCompleted, log.results.commandsFailed, JSON.stringify(log.renamedItems), JSON.stringify(log.results.errors));
      },
      /**
      * Get all rename runs for an instance, newest first
      */
      getByInstanceId(instanceId, limit = 100) {
        return db.query(`SELECT * FROM rename_runs
			WHERE instance_id = ?
			ORDER BY started_at DESC
			LIMIT ?`, instanceId, limit).map(rowToLog);
      },
      /**
      * Get a single rename run by ID
      */
      getById(id) {
        const row = db.queryFirst("SELECT * FROM rename_runs WHERE id = ?", id);
        return row ? rowToLog(row) : void 0;
      },
      /**
      * Get recent runs across all instances
      */
      getRecent(limit = 50) {
        return db.query(`SELECT * FROM rename_runs
			ORDER BY started_at DESC
			LIMIT ?`, limit).map(rowToLog);
      },
      /**
      * Get runs by status for an instance
      */
      getByStatus(instanceId, status, limit = 50) {
        return db.query(`SELECT * FROM rename_runs
			WHERE instance_id = ? AND status = ?
			ORDER BY started_at DESC
			LIMIT ?`, instanceId, status, limit).map(rowToLog);
      },
      /**
      * Delete old runs (for retention policy)
      * Returns number of rows deleted
      */
      deleteOlderThan(days) {
        return db.execute(`DELETE FROM rename_runs
			WHERE datetime(started_at) < datetime('now', '-' || ? || ' days')`, days);
      },
      /**
      * Delete all runs for an instance
      */
      deleteByInstanceId(instanceId) {
        return db.execute("DELETE FROM rename_runs WHERE instance_id = ?", instanceId);
      },
      /**
      * Get count of runs for an instance
      */
      getCount(instanceId) {
        return db.queryFirst("SELECT COUNT(*) as count FROM rename_runs WHERE instance_id = ?", instanceId)?.count ?? 0;
      },
      /**
      * Get stats summary for an instance
      */
      getStats(instanceId) {
        const result = db.queryFirst(`SELECT
				COUNT(*) as total_runs,
				SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) as successful_runs,
				SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed_runs,
				SUM(files_renamed) as total_files_renamed,
				SUM(folders_renamed) as total_folders_renamed
			FROM rename_runs
			WHERE instance_id = ?`, instanceId);
        return {
          totalRuns: result?.total_runs ?? 0,
          successfulRuns: result?.successful_runs ?? 0,
          failedRuns: result?.failed_runs ?? 0,
          totalFilesRenamed: result?.total_files_renamed ?? 0,
          totalFoldersRenamed: result?.total_folders_renamed ?? 0
        };
      }
    };
    SOURCE$3 = "RenameJob";
    SOURCE$2 = "RenameProcessor";
    renameRunHandler = async (job) => {
      const instanceId = Number(job.payload.instanceId);
      if (!Number.isFinite(instanceId)) return {
        status: "failure",
        error: "Invalid instance ID"
      };
      const settings2 = arrRenameSettingsQueries.getByInstanceId(instanceId);
      if (!settings2 || !settings2.enabled) return {
        status: "cancelled",
        output: "Rename config disabled"
      };
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return {
        status: "failure",
        error: "Arr instance not found"
      };
      if (instance.type !== "radarr" && instance.type !== "sonarr") return {
        status: "skipped",
        output: `Rename not supported for ${instance.type}`
      };
      const dryRun = Boolean(job.payload.dryRun);
      try {
        const log = await processRenameConfig(settings2, instance, job.source === "manual", dryRun);
        arrRenameSettingsQueries.updateLastRun(instanceId);
        const nextRunAt = calculateNextRun(settings2.cron);
        if (nextRunAt) arrRenameSettingsQueries.updateNextRunAt(instanceId, nextRunAt);
        const output = dryRun ? `${log.results.filesNeedingRename} files would be renamed` : `${log.results.filesRenamed}/${log.results.filesNeedingRename} files renamed`;
        return {
          status: log.status === "failed" ? "failure" : log.results.filesNeedingRename === 0 ? "skipped" : "success",
          output,
          rescheduleAt: job.source === "schedule" ? nextRunAt ?? void 0 : void 0
        };
      } catch (error2) {
        await logger.error("Rename job failed", {
          source: "RenameJob",
          meta: {
            jobId: job.id,
            instanceId,
            instanceName: instance.name,
            error: error2
          }
        });
        return {
          status: "failure",
          error: error2 instanceof Error ? error2.message : String(error2)
        };
      }
    };
    jobQueueRegistry.register("arr.rename", renameRunHandler);
    BaseSyncer = class {
      client;
      instanceId;
      instanceName;
      constructor(client2, instanceId, instanceName) {
        this.client = client2;
        this.instanceId = instanceId;
        this.instanceName = instanceName;
      }
      /**
      * Main sync method - orchestrates fetch, transform, push
      */
      async sync() {
        try {
          await logger.info(`Starting ${this.syncType} sync for "${this.instanceName}"`, {
            source: "Syncer",
            meta: {
              instanceId: this.instanceId,
              syncType: this.syncType
            }
          });
          const pcdData = await this.fetchFromPcd();
          if (pcdData.length === 0) {
            await logger.debug(`No ${this.syncType} to sync for "${this.instanceName}"`, {
              source: "Syncer",
              meta: { instanceId: this.instanceId }
            });
            return {
              success: true,
              itemsSynced: 0
            };
          }
          const arrData = this.transformToArr(pcdData);
          await this.pushToArr(arrData);
          await logger.info(`Completed ${this.syncType} sync for "${this.instanceName}"`, {
            source: "Syncer",
            meta: {
              instanceId: this.instanceId,
              itemsSynced: arrData.length
            }
          });
          return {
            success: true,
            itemsSynced: arrData.length
          };
        } catch (error2) {
          const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
          await logger.error(`Failed ${this.syncType} sync for "${this.instanceName}"`, {
            source: "Syncer",
            meta: {
              instanceId: this.instanceId,
              error: errorMsg
            }
          });
          return {
            success: false,
            itemsSynced: 0,
            error: errorMsg
          };
        }
      }
    };
    BYTES_PER_GB = 1073741824;
    SIZE_GB_DECIMALS = 2;
    CONDITION_IMPLEMENTATIONS = {
      release_title: "ReleaseTitleSpecification",
      release_group: "ReleaseGroupSpecification",
      edition: "EditionSpecification",
      source: "SourceSpecification",
      resolution: "ResolutionSpecification",
      indexer_flag: "IndexerFlagSpecification",
      quality_modifier: "QualityModifierSpecification",
      size: "SizeSpecification",
      language: "LanguageSpecification",
      release_type: "ReleaseTypeSpecification",
      year: "YearSpecification"
    };
    QualityProfileSyncer = class extends BaseSyncer {
      instanceType;
      constructor(client2, instanceId, instanceName, instanceType) {
        super(client2, instanceId, instanceName);
        this.instanceType = instanceType;
      }
      get syncType() {
        return "quality profiles";
      }
      /**
      * Override sync to handle multi-database quality profile sync flow.
      * Processes databases from lowest priority to highest so the highest-
      * priority database's entities are what remain in Arr after sync.
      */
      async sync() {
        try {
          const syncConfig = arrSyncQueries.getQualityProfilesSync(this.instanceId);
          if (syncConfig.selections.length === 0) {
            await logger.debug(`No quality profiles to sync for "${this.instanceName}"`, {
              source: "Sync:QualityProfiles",
              meta: { instanceId: this.instanceId }
            });
            return {
              success: true,
              itemsSynced: 0
            };
          }
          const priorities = arrSyncQueries.getDatabasePriorities(this.instanceId);
          const selectionsByDb = /* @__PURE__ */ new Map();
          for (const sel of syncConfig.selections) {
            if (!selectionsByDb.has(sel.databaseId)) selectionsByDb.set(sel.databaseId, []);
            selectionsByDb.get(sel.databaseId).push(sel);
          }
          const sortedDbIds = [...selectionsByDb.keys()].sort((a2, b3) => {
            const pa = priorities.find((p2) => p2.databaseId === a2)?.priority ?? Infinity;
            return (priorities.find((p2) => p2.databaseId === b3)?.priority ?? Infinity) - pa;
          });
          const existingProfiles = await this.client.getQualityProfiles();
          const existingMap = new Map(existingProfiles.map((p2) => [p2.name, p2.id]));
          const allFormatIdMap = /* @__PURE__ */ new Map();
          const allSyncedProfiles = [];
          const failures = [];
          for (const databaseId of sortedDbIds) {
            const dbSelections = selectionsByDb.get(databaseId);
            try {
              const { profiles, customFormats } = await this.fetchSyncDataForDatabase(databaseId, dbSelections);
              if (profiles.length === 0) continue;
              const formatIdMap = await syncCustomFormats(this.client, this.instanceId, this.instanceType, customFormats);
              for (const [k2, v3] of formatIdMap) allFormatIdMap.set(k2, v3);
              const cache3 = getCache(databaseId);
              if (!cache3) throw new Error(`PCD cache not found for database ${databaseId}`);
              const qualityMappings = await getQualityApiMappings(cache3, this.instanceType);
              const synced = await this.syncQualityProfiles(profiles, allFormatIdMap, qualityMappings, existingMap);
              allSyncedProfiles.push(...synced);
              await logger.info(`Synced ${synced.length} profile(s) from database ${databaseId} for "${this.instanceName}"`, {
                source: "Sync:QualityProfiles",
                meta: {
                  instanceId: this.instanceId,
                  databaseId,
                  profiles: synced.map((p2) => ({
                    name: p2.name,
                    action: p2.action,
                    formats: p2.formats.length
                  }))
                }
              });
            } catch (error2) {
              const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
              await logger.error(`Failed syncing database ${databaseId} for "${this.instanceName}", continuing`, {
                source: "Sync:QualityProfiles",
                meta: {
                  instanceId: this.instanceId,
                  databaseId,
                  error: errorMsg
                }
              });
              failures.push({
                databaseId,
                error: errorMsg
              });
            }
          }
          if (failures.length > 0) {
            const error2 = failures.map((failure) => `database ${failure.databaseId}: ${failure.error}`).join("; ");
            return {
              success: false,
              itemsSynced: allSyncedProfiles.length,
              items: allSyncedProfiles.map((p2) => ({
                name: p2.name,
                action: p2.action
              })),
              error: `Quality profile sync failed for ${failures.length} database(s): ${error2}`
            };
          }
          await logger.info(`Completed quality profile sync for "${this.instanceName}"`, {
            source: "Sync:QualityProfiles",
            meta: {
              instanceId: this.instanceId,
              databases: sortedDbIds,
              totalProfiles: allSyncedProfiles.length
            }
          });
          return {
            success: true,
            itemsSynced: allSyncedProfiles.length,
            items: allSyncedProfiles.map((p2) => ({
              name: p2.name,
              action: p2.action
            }))
          };
        } catch (error2) {
          const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
          await logger.error(`Failed quality profile sync for "${this.instanceName}"`, {
            source: "Sync:QualityProfiles",
            meta: {
              instanceId: this.instanceId,
              error: errorMsg
            }
          });
          return {
            success: false,
            itemsSynced: 0,
            error: errorMsg
          };
        }
      }
      /**
      * Fetch profiles and CFs from a specific database for the given selections.
      */
      async fetchSyncDataForDatabase(databaseId, selections) {
        const dbInstance = databaseInstancesQueries.getById(databaseId);
        if (!dbInstance) {
          await logger.warn(`Skipping sync for deleted database ${databaseId}`, {
            source: "Sync:QualityProfiles",
            meta: {
              instanceId: this.instanceId,
              databaseId
            }
          });
          throw new Error(`Database ${databaseId} not found`);
        }
        const cache3 = getCache(databaseId);
        if (!cache3) {
          const cachedIds = getCachedDatabaseIds();
          await logger.warn(`PCD cache not found for database ${databaseId}`, {
            source: "Sync:QualityProfiles",
            meta: {
              instanceId: this.instanceId,
              requestedDatabaseId: databaseId,
              cachedDatabaseIds: cachedIds,
              databaseExists: !!dbInstance,
              databaseEnabled: dbInstance?.enabled ?? null,
              databaseName: dbInstance?.name ?? null
            }
          });
          throw new Error(`PCD cache not found for database ${databaseId}`);
        }
        const profiles = [];
        const customFormats = /* @__PURE__ */ new Map();
        for (const selection of selections) {
          const pcdProfile = await fetchQualityProfileFromPcd(cache3, selection.profileName, this.instanceType);
          if (!pcdProfile) {
            await logger.warn(`Quality profile "${selection.profileName}" not found in database ${databaseId}`, {
              source: "Sync:QualityProfiles",
              meta: {
                instanceId: this.instanceId,
                profileName: selection.profileName
              }
            });
            continue;
          }
          const referencedFormatNames = await getCustomFormatsForProfile(cache3, selection.profileName, this.instanceType);
          profiles.push({
            pcdProfile,
            referencedFormatNames
          });
          for (const formatName of referencedFormatNames) if (!customFormats.has(formatName)) {
            const pcdFormat = await fetchCustomFormatFromPcd(cache3, formatName);
            if (pcdFormat) customFormats.set(formatName, pcdFormat);
          }
        }
        return {
          profiles,
          customFormats
        };
      }
      /**
      * Sync quality profiles to the arr instance.
      */
      async syncQualityProfiles(profiles, formatIdMap, qualityMappings, existingMap) {
        const syncedProfiles = [];
        for (const { pcdProfile } of profiles) {
          const arrProfile = transformQualityProfile(pcdProfile, this.instanceType, qualityMappings, formatIdMap);
          arrProfile.name = pcdProfile.name;
          await logger.debug(`Compiled quality profile "${pcdProfile.name}"`, {
            source: "Compile:QualityProfile",
            meta: {
              instanceId: this.instanceId,
              pcdName: pcdProfile.name,
              profile: arrProfile
            }
          });
          try {
            const isUpdate = existingMap.has(pcdProfile.name);
            if (isUpdate) {
              const existingId = existingMap.get(pcdProfile.name);
              arrProfile.id = existingId;
              await this.client.updateQualityProfile(existingId, arrProfile);
              await logger.debug(`Updated quality profile "${pcdProfile.name}"`, {
                source: "Sync:QualityProfiles",
                meta: {
                  instanceId: this.instanceId,
                  profileId: existingId,
                  pcdName: pcdProfile.name
                }
              });
            } else {
              const response = await this.client.createQualityProfile(arrProfile);
              existingMap.set(pcdProfile.name, response.id);
              await logger.debug(`Created quality profile "${pcdProfile.name}"`, {
                source: "Sync:QualityProfiles",
                meta: {
                  instanceId: this.instanceId,
                  profileId: response.id,
                  pcdName: pcdProfile.name
                }
              });
            }
            const scoredFormats = arrProfile.formatItems.filter((f2) => f2.score !== 0).map((f2) => ({
              name: f2.name,
              score: f2.score
            }));
            syncedProfiles.push({
              name: pcdProfile.name,
              action: isUpdate ? "updated" : "created",
              language: arrProfile.language?.name ?? "N/A",
              cutoffFormatScore: arrProfile.cutoffFormatScore,
              minFormatScore: arrProfile.minFormatScore,
              formats: scoredFormats
            });
          } catch (error2) {
            const errorDetails = this.extractErrorDetails(error2);
            await logger.error(`Failed to sync quality profile "${pcdProfile.name}"`, {
              source: "Sync:QualityProfiles",
              meta: {
                instanceId: this.instanceId,
                pcdName: pcdProfile.name,
                request: arrProfile,
                ...errorDetails
              }
            });
          }
        }
        return syncedProfiles;
      }
      /**
      * Extract error details from HTTP errors for logging
      */
      extractErrorDetails(error2) {
        const details = { error: error2 instanceof Error ? error2.message : "Unknown error" };
        if (error2 && typeof error2 === "object") {
          const err = error2;
          if ("status" in err) details.status = err.status;
          if ("statusText" in err) details.statusText = err.statusText;
          if ("response" in err) details.response = err.response;
          if ("body" in err) details.responseBody = err.body;
          if ("data" in err) details.responseData = err.data;
          if (err.cause) details.cause = err.cause;
        }
        return details;
      }
      async fetchFromPcd() {
        return [];
      }
      transformToArr(_pcdData) {
        return [];
      }
      async pushToArr(_arrData) {
      }
    };
    sectionRegistry = /* @__PURE__ */ new Map();
    registerSection({
      type: "qualityProfiles",
      setShouldSync(instanceId, value2) {
        arrSyncQueries.setQualityProfilesShouldSync(instanceId, value2);
      },
      setNextRunAt(instanceId, nextRunAt) {
        arrSyncQueries.setQualityProfilesNextRunAt(instanceId, nextRunAt);
      },
      claimSync(instanceId) {
        return arrSyncQueries.claimQualityProfilesSync(instanceId);
      },
      completeSync(instanceId) {
        arrSyncQueries.completeQualityProfilesSync(instanceId);
      },
      failSync(instanceId, error2) {
        arrSyncQueries.failQualityProfilesSync(instanceId, error2);
      },
      setStatusPending(instanceId) {
        arrSyncQueries.setQualityProfilesStatusPending(instanceId);
      },
      getPendingInstanceIds() {
        return arrSyncQueries.getPendingSyncs().qualityProfiles;
      },
      getScheduledConfigs() {
        return arrSyncQueries.getScheduledConfigs().qualityProfiles;
      },
      createSyncer(client2, instance) {
        return new QualityProfileSyncer(client2, instance.id, instance.name, instance.type);
      },
      hasConfig(instanceId) {
        return arrSyncQueries.getQualityProfilesSync(instanceId).selections.length > 0;
      }
    });
    DelayProfileSyncer = class extends BaseSyncer {
      get syncType() {
        return "delay profile";
      }
      /**
      * Override sync to handle single profile update to id=1
      */
      async sync() {
        const syncConfig = arrSyncQueries.getDelayProfilesSync(this.instanceId);
        if (!syncConfig.databaseId || !syncConfig.profileName) {
          await logger.debug("No delay profile configured for sync", {
            source: "Sync:DelayProfile",
            meta: { instanceId: this.instanceId }
          });
          return {
            success: true,
            itemsSynced: 0
          };
        }
        const cache3 = getCache(syncConfig.databaseId);
        if (!cache3) {
          await logger.warn(`PCD cache not found for database ${syncConfig.databaseId}`, {
            source: "Sync:DelayProfile",
            meta: { instanceId: this.instanceId }
          });
          return {
            success: false,
            itemsSynced: 0,
            error: "PCD cache not found"
          };
        }
        const profile = await getByName(cache3, syncConfig.profileName);
        if (!profile) {
          await logger.warn(`Profile "${syncConfig.profileName}" not found`, {
            source: "Sync:DelayProfile",
            meta: {
              instanceId: this.instanceId,
              profileName: syncConfig.profileName
            }
          });
          return {
            success: false,
            itemsSynced: 0,
            error: "Profile not found in PCD"
          };
        }
        const transformed = transformDelayProfile(profile);
        await this.client.updateDelayProfile(1, transformed);
        await logger.info(`Synced delay profile "${profile.name}" to "${this.instanceName}"`, {
          source: "Sync:DelayProfile",
          meta: { instanceId: this.instanceId }
        });
        return {
          success: true,
          itemsSynced: 1,
          items: [{
            name: profile.name,
            action: "updated"
          }]
        };
      }
      async fetchFromPcd() {
        return [];
      }
      transformToArr(_pcdData) {
        return [];
      }
      async pushToArr(_arrData) {
      }
    };
    registerSection({
      type: "delayProfiles",
      setShouldSync(instanceId, value2) {
        arrSyncQueries.setDelayProfilesShouldSync(instanceId, value2);
      },
      setNextRunAt(instanceId, nextRunAt) {
        arrSyncQueries.setDelayProfilesNextRunAt(instanceId, nextRunAt);
      },
      claimSync(instanceId) {
        return arrSyncQueries.claimDelayProfilesSync(instanceId);
      },
      completeSync(instanceId) {
        arrSyncQueries.completeDelayProfilesSync(instanceId);
      },
      failSync(instanceId, error2) {
        arrSyncQueries.failDelayProfilesSync(instanceId, error2);
      },
      setStatusPending(instanceId) {
        arrSyncQueries.setDelayProfilesStatusPending(instanceId);
      },
      getPendingInstanceIds() {
        return arrSyncQueries.getPendingSyncs().delayProfiles;
      },
      getScheduledConfigs() {
        return arrSyncQueries.getScheduledConfigs().delayProfiles;
      },
      createSyncer(client2, instance) {
        return new DelayProfileSyncer(client2, instance.id, instance.name);
      },
      hasConfig(instanceId) {
        const config2 = arrSyncQueries.getDelayProfilesSync(instanceId);
        return config2.databaseId !== null && config2.profileName !== null;
      }
    });
    MediaManagementSyncer = class extends BaseSyncer {
      instanceType;
      constructor(client2, instanceId, instanceName, instanceType) {
        super(client2, instanceId, instanceName);
        this.instanceType = instanceType;
      }
      get syncType() {
        return "media management";
      }
      /**
      * Override sync to handle multiple config types
      */
      async sync() {
        const syncConfig = arrSyncQueries.getMediaManagementSync(this.instanceId);
        let totalSynced = 0;
        const errors = [];
        const items = [];
        if (syncConfig.mediaSettingsDatabaseId && syncConfig.mediaSettingsConfigName) try {
          if (await this.syncMediaSettings(syncConfig.mediaSettingsDatabaseId, syncConfig.mediaSettingsConfigName)) {
            totalSynced++;
            items.push({
              name: "Media Settings",
              action: "updated"
            });
          }
        } catch (error2) {
          const msg = error2 instanceof Error ? error2.message : "Unknown error";
          errors.push(`Media settings: ${msg}`);
          await logger.error(`Failed to sync media settings`, {
            source: "Sync:MediaManagement",
            meta: {
              instanceId: this.instanceId,
              error: msg
            }
          });
        }
        if (syncConfig.namingDatabaseId && syncConfig.namingConfigName) try {
          if (await this.syncNaming(syncConfig.namingDatabaseId, syncConfig.namingConfigName)) {
            totalSynced++;
            items.push({
              name: "Naming",
              action: "updated"
            });
          }
        } catch (error2) {
          const msg = error2 instanceof Error ? error2.message : "Unknown error";
          errors.push(`Naming: ${msg}`);
          await logger.error(`Failed to sync naming`, {
            source: "Sync:MediaManagement",
            meta: {
              instanceId: this.instanceId,
              error: msg
            }
          });
        }
        if (syncConfig.qualityDefinitionsDatabaseId && syncConfig.qualityDefinitionsConfigName) try {
          if (await this.syncQualityDefinitions(syncConfig.qualityDefinitionsDatabaseId, syncConfig.qualityDefinitionsConfigName)) {
            totalSynced++;
            items.push({
              name: "Quality Definitions",
              action: "updated"
            });
          }
        } catch (error2) {
          const msg = error2 instanceof Error ? error2.message : "Unknown error";
          errors.push(`Quality definitions: ${msg}`);
          await logger.error(`Failed to sync quality definitions`, {
            source: "Sync:MediaManagement",
            meta: {
              instanceId: this.instanceId,
              error: msg
            }
          });
        }
        const result = {
          success: errors.length === 0,
          itemsSynced: totalSynced,
          error: errors.length > 0 ? errors.join("; ") : void 0,
          items: items.length > 0 ? items : void 0
        };
        await logger.info(`Completed media management sync for "${this.instanceName}"`, {
          source: "Sync:MediaManagement",
          meta: {
            instanceId: this.instanceId,
            ...result
          }
        });
        return result;
      }
      async syncMediaSettings(databaseId, configName) {
        const cache3 = getCache(databaseId);
        if (!cache3) {
          await logger.warn(`PCD cache not found for database ${databaseId}`, {
            source: "Sync:MediaSettings",
            meta: { instanceId: this.instanceId }
          });
          return false;
        }
        let mediaSettings = null;
        if (this.instanceType === "radarr") mediaSettings = await getRadarrByName$2(cache3, configName);
        else if (this.instanceType === "sonarr") mediaSettings = await getSonarrByName$2(cache3, configName);
        if (!mediaSettings) {
          await logger.debug(`Media settings config "${configName}" not found in PCD`, {
            source: "Sync:MediaSettings",
            meta: {
              instanceId: this.instanceId,
              configName
            }
          });
          return false;
        }
        const updatedConfig = mergeMediaSettingsConfig(await this.client.getMediaManagementConfig(), mediaSettings);
        await logger.debug("Updating media settings", {
          source: "Sync:MediaSettings",
          meta: {
            instanceId: this.instanceId,
            configName,
            propersRepacks: updatedConfig.downloadPropersAndRepacks,
            enableMediaInfo: updatedConfig.enableMediaInfo
          }
        });
        await this.client.updateMediaManagementConfig(updatedConfig);
        return true;
      }
      async syncNaming(databaseId, configName) {
        const cache3 = getCache(databaseId);
        if (!cache3) {
          await logger.warn(`PCD cache not found for database ${databaseId}`, {
            source: "Sync:Naming",
            meta: { instanceId: this.instanceId }
          });
          return false;
        }
        if (this.instanceType === "radarr") return this.syncRadarrNaming(cache3, configName);
        else if (this.instanceType === "sonarr") return this.syncSonarrNaming(cache3, configName);
        await logger.warn(`Unsupported instance type for naming sync: ${this.instanceType}`, {
          source: "Sync:Naming",
          meta: { instanceId: this.instanceId }
        });
        return false;
      }
      async syncRadarrNaming(cache3, configName) {
        const naming = await getRadarrByName$1(cache3, configName);
        if (!naming) {
          await logger.debug(`Radarr naming config "${configName}" not found in PCD`, {
            source: "Sync:Naming",
            meta: {
              instanceId: this.instanceId,
              configName
            }
          });
          return false;
        }
        const updatedConfig = mergeRadarrNamingConfig(await this.client.getNamingConfig(), naming);
        await logger.debug("Updating Radarr naming", {
          source: "Sync:Naming",
          meta: {
            instanceId: this.instanceId,
            configName,
            renameMovies: updatedConfig.renameMovies,
            colonReplacementFormat: updatedConfig.colonReplacementFormat
          }
        });
        await this.client.updateNamingConfig(updatedConfig);
        return true;
      }
      async syncSonarrNaming(cache3, configName) {
        const naming = await getSonarrByName$1(cache3, configName);
        if (!naming) {
          await logger.debug(`Sonarr naming config "${configName}" not found in PCD`, {
            source: "Sync:Naming",
            meta: {
              instanceId: this.instanceId,
              configName
            }
          });
          return false;
        }
        const updatedConfig = mergeSonarrNamingConfig(await this.client.getNamingConfig(), naming);
        await logger.debug("Updating Sonarr naming", {
          source: "Sync:Naming",
          meta: {
            instanceId: this.instanceId,
            configName,
            renameEpisodes: updatedConfig.renameEpisodes,
            colonReplacementFormat: updatedConfig.colonReplacementFormat,
            multiEpisodeStyle: updatedConfig.multiEpisodeStyle
          }
        });
        await this.client.updateNamingConfig(updatedConfig);
        return true;
      }
      async syncQualityDefinitions(databaseId, configName) {
        const cache3 = getCache(databaseId);
        if (!cache3) {
          await logger.warn(`PCD cache not found for database ${databaseId}`, {
            source: "Sync:QualityDefinitions",
            meta: { instanceId: this.instanceId }
          });
          return false;
        }
        const qualityDefsConfig = await (this.instanceType === "radarr" ? getRadarrByName : getSonarrByName)(cache3, configName);
        if (!qualityDefsConfig) {
          await logger.debug(`Quality definitions config "${configName}" not found in PCD`, {
            source: "Sync:QualityDefinitions",
            meta: {
              instanceId: this.instanceId,
              configName
            }
          });
          return false;
        }
        if (qualityDefsConfig.entries.length === 0) {
          await logger.debug(`Quality definitions config "${configName}" has no entries`, {
            source: "Sync:QualityDefinitions",
            meta: {
              instanceId: this.instanceId,
              configName
            }
          });
          return false;
        }
        const apiMappings = await this.getQualityApiMappings(cache3);
        const arrDefinitions = await this.client.getQualityDefinitions();
        const transformed = transformQualityDefinitionsForArr(qualityDefsConfig.entries, apiMappings);
        for (const qualityName of transformed.unmapped) await logger.debug(`No API mapping found for quality "${qualityName}"`, {
          source: "Sync:QualityDefinitions",
          meta: {
            instanceId: this.instanceId,
            qualityName
          }
        });
        const { updatedCount, missing } = applyQualityDefinitionsToArr(arrDefinitions, transformed.definitions);
        for (const apiName of missing) await logger.debug(`No ARR definition found for quality "${apiName}"`, {
          source: "Sync:QualityDefinitions",
          meta: {
            instanceId: this.instanceId,
            apiName
          }
        });
        if (updatedCount === 0) {
          await logger.debug("No quality definitions matched for update", {
            source: "Sync:QualityDefinitions",
            meta: {
              instanceId: this.instanceId,
              configName
            }
          });
          return false;
        }
        await logger.debug(`Updating ${updatedCount} quality definitions`, {
          source: "Sync:QualityDefinitions",
          meta: {
            instanceId: this.instanceId,
            configName,
            updatedCount
          }
        });
        await this.client.updateQualityDefinitions(arrDefinitions);
        return true;
      }
      /**
      * Get quality API mappings from PCD
      * Returns a map of quality_name (lowercase) -> api_name
      */
      async getQualityApiMappings(cache3) {
        const arrType = this.instanceType;
        const rows = await cache3.kb.selectFrom("quality_api_mappings as qam").where("qam.arr_type", "=", arrType).select(["qam.quality_name", "qam.api_name"]).execute();
        const map2 = /* @__PURE__ */ new Map();
        for (const row of rows) map2.set(row.quality_name.toLowerCase(), row.api_name);
        return map2;
      }
      async fetchFromPcd() {
        return [];
      }
      transformToArr(_pcdData) {
        return [];
      }
      async pushToArr(_arrData) {
      }
    };
    registerSection({
      type: "mediaManagement",
      setShouldSync(instanceId, value2) {
        arrSyncQueries.setMediaManagementShouldSync(instanceId, value2);
      },
      setNextRunAt(instanceId, nextRunAt) {
        arrSyncQueries.setMediaManagementNextRunAt(instanceId, nextRunAt);
      },
      claimSync(instanceId) {
        return arrSyncQueries.claimMediaManagementSync(instanceId);
      },
      completeSync(instanceId) {
        arrSyncQueries.completeMediaManagementSync(instanceId);
      },
      failSync(instanceId, error2) {
        arrSyncQueries.failMediaManagementSync(instanceId, error2);
      },
      setStatusPending(instanceId) {
        arrSyncQueries.setMediaManagementStatusPending(instanceId);
      },
      getPendingInstanceIds() {
        return arrSyncQueries.getPendingSyncs().mediaManagement;
      },
      getScheduledConfigs() {
        return arrSyncQueries.getScheduledConfigs().mediaManagement;
      },
      createSyncer(client2, instance) {
        return new MediaManagementSyncer(client2, instance.id, instance.name, instance.type);
      },
      hasConfig(instanceId) {
        const config2 = arrSyncQueries.getMediaManagementSync(instanceId);
        return config2.namingDatabaseId !== null || config2.qualityDefinitionsDatabaseId !== null || config2.mediaSettingsDatabaseId !== null;
      }
    });
    UNPREFIXED_SEQUENCE_BASE = 2e9;
    PCDManager = class {
      /**
      * Link a new PCD repository.
      *
      * Optional progress callback receives a stage label between phases
      * (clone, manifest, deps, import, compile). Used by the async
      * `pcd.link` job handler to surface progress over SSE; sync callers
      * (startup auto-link, REST API) omit it.
      */
      async link(options2, progress) {
        await logger.debug("Starting database link operation", {
          source: "PCDManager",
          meta: {
            name: options2.name,
            repositoryUrl: options2.repositoryUrl,
            branch: options2.branch
          }
        });
        const uuid2 = crypto.randomUUID();
        const localPath = getPCDPath(uuid2);
        try {
          progress?.("Cloning repository...");
          const isPrivate = await clone(options2.repositoryUrl, localPath, options2.branch, options2.personalAccessToken);
          progress?.("Reading manifest...");
          await loadManifest(localPath);
          progress?.("Cloning dependencies...");
          await processDependencies(localPath, options2.personalAccessToken);
          const id = databaseInstancesQueries.create({
            uuid: uuid2,
            name: options2.name,
            repositoryUrl: options2.repositoryUrl,
            localPath,
            syncStrategy: options2.syncStrategy,
            autoPull: options2.autoPull,
            personalAccessToken: options2.personalAccessToken,
            isPrivate,
            localOpsEnabled: options2.localOpsEnabled,
            gitUserName: options2.gitUserName,
            gitUserEmail: options2.gitUserEmail,
            conflictStrategy: options2.conflictStrategy
          });
          const instance = databaseInstancesQueries.getById(id);
          if (!instance) throw new Error("Failed to retrieve created database instance");
          progress?.("Importing ops...");
          try {
            await importBaseOps(id, localPath);
          } catch (error2) {
            await logger.error("Failed to import base ops after linking", {
              source: "PCDManager",
              meta: {
                error: String(error2),
                databaseId: id
              }
            });
          }
          if (instance.enabled) {
            progress?.("Compiling cache...");
            try {
              const stats = await compile(localPath, id);
              await logger.debug(`Cache compiled for "${options2.name}"`, {
                source: "PCDManager",
                meta: {
                  databaseId: id,
                  schema: stats.schema,
                  base: stats.base,
                  tweaks: stats.tweaks,
                  user: stats.user
                }
              });
            } catch (error2) {
              await logger.error("Failed to compile PCD cache after linking", {
                source: "PCDManager",
                meta: {
                  error: String(error2),
                  databaseId: id
                }
              });
            }
          }
          return instance;
        } catch (error2) {
          try {
            await Deno.remove(localPath, { recursive: true });
          } catch {
          }
          throw error2;
        }
      }
      /**
      * Unlink a PCD repository
      */
      async unlink(id) {
        const instance = databaseInstancesQueries.getById(id);
        if (!instance) throw new Error(`Database instance ${id} not found`);
        invalidate(id);
        cleanupJobsForDatabase(id);
        databaseInstancesQueries.delete(id);
        try {
          await Deno.remove(instance.local_path, { recursive: true });
        } catch (error2) {
          console.error(`Failed to remove PCD directory ${instance.local_path}:`, error2);
        }
      }
      /**
      * Sync a PCD repository (pull updates)
      */
      async sync(id, trigger = "manual-ui") {
        const instance = databaseInstancesQueries.getById(id);
        if (!instance) {
          await logger.info("Database sync completed", {
            source: "PCDManager",
            meta: {
              databaseId: id,
              trigger,
              outcome: "instance-not-found"
            }
          });
          throw new Error(`Database instance ${id} not found`);
        }
        const summary = {
          databaseId: id,
          databaseName: instance.name,
          trigger,
          outcome: "failed"
        };
        try {
          const updateInfo = await checkForUpdates(instance.local_path);
          summary.commits = {
            from: updateInfo.currentLocalCommit,
            to: updateInfo.latestRemoteCommit,
            behind: updateInfo.commitsBehind
          };
          if (!updateInfo.hasUpdates) {
            databaseInstancesQueries.updateSyncedAt(id);
            summary.outcome = "no-updates";
            await logger.info("Database sync completed", {
              source: "PCDManager",
              meta: summary
            });
            return {
              success: true,
              commitsBehind: 0
            };
          }
          const oldHead = updateInfo.currentLocalCommit;
          const schemaVersionBefore = await readSchemaVersion(instance.local_path);
          await pull(instance.local_path);
          const commitMessages = await getCommitMessagesBetween(instance.local_path, oldHead, "HEAD");
          const dependencySync = await syncDependencies(instance.local_path, instance.personal_access_token ?? void 0);
          const schemaVersionAfter = await readSchemaVersion(instance.local_path);
          const schemaUpdate = schemaVersionBefore && schemaVersionAfter && schemaVersionBefore !== schemaVersionAfter ? {
            from: schemaVersionBefore,
            to: schemaVersionAfter
          } : void 0;
          try {
            const importResult = await importBaseOps(id, instance.local_path);
            summary.ops = {
              created: importResult.created,
              updated: importResult.updated,
              orphaned: importResult.orphaned
            };
          } catch (error2) {
            await logger.error("Failed to import base ops after sync", {
              source: "PCDManager",
              meta: {
                error: String(error2),
                databaseId: id
              }
            });
          }
          databaseInstancesQueries.updateSyncedAt(id);
          if (dependencySync.changed) {
            await logger.info("Dependencies changed during sync, invalidating cache before rebuild", {
              source: "PCDManager",
              meta: {
                databaseId: id,
                databaseName: instance.name,
                repositories: dependencySync.repositories
              }
            });
            invalidate(id);
          }
          if (instance.enabled) try {
            const stats = await compile(instance.local_path, id);
            summary.cache = {
              rebuilt: true,
              dependencyChanged: dependencySync.changed,
              opCounts: {
                schema: stats.schema,
                base: stats.base,
                tweaks: stats.tweaks,
                user: stats.user
              },
              timingMs: stats.timing
            };
            await logger.info("Rebuilt cache after dependency sync", {
              source: "PCDManager",
              meta: {
                databaseId: id,
                databaseName: instance.name,
                dependenciesChanged: dependencySync.changed,
                repositories: dependencySync.repositories
              }
            });
          } catch (error2) {
            await logger.error("Failed to recompile PCD cache after sync", {
              source: "PCDManager",
              meta: {
                error: String(error2),
                databaseId: id
              }
            });
          }
          await triggerSyncs({
            event: "on_pull",
            databaseId: id
          });
          try {
            await notificationManager.notify(notifications.pcdSyncSuccess({
              name: instance.name,
              commitsPulled: updateInfo.commitsBehind,
              commitMessages,
              schemaUpdate
            }));
          } catch {
          }
          summary.outcome = "pulled";
          await logger.info("Database sync completed", {
            source: "PCDManager",
            meta: summary
          });
          return {
            success: true,
            commitsBehind: updateInfo.commitsBehind
          };
        } catch (error2) {
          try {
            await notificationManager.notify(notifications.pcdSyncFailed({
              name: instance.name,
              error: error2 instanceof Error ? error2.message : "Unknown error"
            }));
          } catch {
          }
          summary.outcome = "failed";
          summary.error = error2 instanceof Error ? error2.message : "Unknown error";
          await logger.info("Database sync completed", {
            source: "PCDManager",
            meta: summary
          });
          return {
            success: false,
            commitsBehind: 0,
            error: error2 instanceof Error ? error2.message : "Unknown error"
          };
        }
      }
      /**
      * Check for available updates without pulling
      */
      async checkForUpdates(id) {
        const instance = databaseInstancesQueries.getById(id);
        if (!instance) throw new Error(`Database instance ${id} not found`);
        return await checkForUpdates(instance.local_path);
      }
      /**
      * Get parsed manifest for a PCD
      */
      async getManifest(id) {
        const instance = databaseInstancesQueries.getById(id);
        if (!instance) throw new Error(`Database instance ${id} not found`);
        return await loadManifest(instance.local_path);
      }
      /**
      * Switch branch for a PCD
      */
      async switchBranch(id, branch2) {
        const instance = databaseInstancesQueries.getById(id);
        if (!instance) throw new Error(`Database instance ${id} not found`);
        await checkout(instance.local_path, branch2);
        await pull(instance.local_path);
        try {
          await importBaseOps(id, instance.local_path);
        } catch (error2) {
          await logger.error("Failed to import base ops after branch switch", {
            source: "PCDManager",
            meta: {
              error: String(error2),
              databaseId: id
            }
          });
        }
        databaseInstancesQueries.updateSyncedAt(id);
      }
      /**
      * Get git status for a PCD
      */
      async getStatus(id) {
        const instance = databaseInstancesQueries.getById(id);
        if (!instance) throw new Error(`Database instance ${id} not found`);
        return await getStatus(instance.local_path);
      }
      /**
      * Get all PCDs
      */
      getAll() {
        return databaseInstancesQueries.getAll();
      }
      /**
      * Get all PCDs with secrets stripped (for frontend use)
      */
      getAllPublic() {
        return databaseInstancesQueries.getAll().map(({ personal_access_token, ...safe }) => ({
          ...safe,
          hasPat: personal_access_token !== null
        }));
      }
      /**
      * Get PCD by ID
      */
      getById(id) {
        return databaseInstancesQueries.getById(id);
      }
      /**
      * Get PCD by ID with secrets stripped (for frontend use)
      */
      getByIdPublic(id) {
        const instance = databaseInstancesQueries.getById(id);
        if (!instance) return void 0;
        const { personal_access_token, ...safe } = instance;
        return {
          ...safe,
          hasPat: personal_access_token !== null
        };
      }
      /**
      * Get PCDs that need auto-sync
      */
      getDueForSync() {
        return databaseInstancesQueries.getDueForSync();
      }
      /**
      * Initialize PCD caches for all enabled databases
      * Should be called on application startup
      */
      async initialize() {
        const startTime = performance.now();
        await logger.debug("Initialize caches", { source: "PCDManager" });
        const enabledInstances = databaseInstancesQueries.getAll().filter((instance) => instance.enabled);
        for (const instance of enabledInstances) try {
          await validateDependencies(instance.local_path, instance.personal_access_token ?? void 0);
        } catch (error2) {
          await logger.error(`Failed to validate dependencies for "${instance.name}"`, {
            source: "PCDManager",
            meta: {
              error: String(error2),
              databaseId: instance.id
            }
          });
        }
        for (const instance of enabledInstances) try {
          await importBaseOps(instance.id, instance.local_path);
        } catch (error2) {
          await logger.error(`Failed to import base ops for "${instance.name}"`, {
            source: "PCDManager",
            meta: {
              error: String(error2),
              databaseId: instance.id
            }
          });
        }
        const results = [];
        for (const instance of enabledInstances) try {
          const stats = await compile(instance.local_path, instance.id);
          results.push({
            name: instance.name,
            schema: stats.schema,
            base: stats.base,
            tweaks: stats.tweaks,
            user: stats.user
          });
        } catch (error2) {
          results.push({
            name: instance.name,
            schema: 0,
            base: 0,
            tweaks: 0,
            user: 0,
            error: String(error2)
          });
          await logger.error(`Cache failed "${instance.name}"`, {
            source: "PCDManager",
            meta: {
              error: String(error2),
              databaseId: instance.id
            }
          });
        }
        const timing = Math.round(performance.now() - startTime);
        const successful = results.filter((r2) => !r2.error);
        await logger.info("Caches ready", {
          source: "PCDManager",
          meta: {
            databases: successful.map((r2) => ({
              name: r2.name,
              schema: r2.schema,
              base: r2.base,
              tweaks: r2.tweaks,
              user: r2.user
            })),
            timing: `${timing}ms`
          }
        });
      }
      /**
      * Get the cache for a database instance
      */
      getCache(id) {
        return getCache(id);
      }
    };
    pcdManager = new PCDManager();
    SOURCE$1 = "Cleanup";
    SOURCE = "EntityCleanup";
    TMDB_ID_REGEX = /\btmdb(?:id)?[-_:\s]*(\d+)\b/gi;
    TVDB_ID_REGEX = /\btvdb(?:id)?[-_:\s]*(\d+)\b/gi;
    cleanupHandler = async (job) => {
      const instanceId = Number(job.payload.instanceId);
      if (!Number.isFinite(instanceId)) return {
        status: "failure",
        error: "Invalid instance ID"
      };
      const settings2 = arrCleanupSettingsQueries.getByInstanceId(instanceId);
      if (!settings2 || !settings2.enabled) return {
        status: "cancelled",
        output: "Cleanup config disabled"
      };
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return {
        status: "failure",
        error: "Arr instance not found"
      };
      if (instance.type !== "radarr" && instance.type !== "sonarr") return {
        status: "skipped",
        output: `Cleanup not supported for ${instance.type}`
      };
      const instanceType = instance.type;
      const client2 = createArrClient(instance.type, instance.url, instance.api_key, { retries: 0 });
      try {
        const preScanned = extractPreScanned(job.payload);
        const deleteResult = await deleteStaleItems(client2, preScanned?.staleConfigs ?? await scanForStaleItems(client2, instanceId));
        const entityDelete = await deleteRemovedEntities(client2, instanceType, (preScanned?.removedEntities ?? await scanForRemovedEntities(client2, instanceType)).removedEntities);
        await logger.info("Cleanup complete", {
          source: "Cleanup",
          meta: {
            instance: instance.name,
            deletedCFs: deleteResult.deletedCustomFormats.map((cf) => cf.name),
            deletedQPs: deleteResult.deletedQualityProfiles.map((qp) => qp.name),
            skippedQPs: deleteResult.skippedQualityProfiles.map((s3) => s3.item.name),
            deletedEntities: entityDelete.deletedEntities.map((e) => e.title),
            failedEntities: entityDelete.failedEntities.map((f2) => f2.entity.title)
          }
        });
        arrCleanupSettingsQueries.updateLastRun(instanceId);
        const nextRunAt = calculateNextRun(settings2.cron);
        if (nextRunAt) arrCleanupSettingsQueries.updateNextRunAt(instanceId, nextRunAt);
        const deletedConfigs = deleteResult.deletedCustomFormats.length + deleteResult.deletedQualityProfiles.length;
        const deletedEntitiesCount = entityDelete.deletedEntities.length;
        const nonSuccesses = deleteResult.skippedQualityProfiles.length + entityDelete.failedEntities.length;
        const total = deletedConfigs + deletedEntitiesCount;
        if (total > 0 || nonSuccesses > 0) try {
          await notificationManager.notify(notifications.arrCleanup({
            instanceName: instance.name,
            instanceType,
            deletedCustomFormats: deleteResult.deletedCustomFormats,
            deletedQualityProfiles: deleteResult.deletedQualityProfiles,
            skippedQualityProfiles: deleteResult.skippedQualityProfiles,
            deletedEntities: entityDelete.deletedEntities,
            failedEntities: entityDelete.failedEntities
          }));
        } catch (err) {
          await logger.error("Failed to send arr cleanup notification", {
            source: "CleanupJob",
            meta: {
              instanceId,
              error: err instanceof Error ? err.message : String(err)
            }
          });
        }
        const output = total === 0 ? "Nothing to clean up" : `Deleted ${deletedConfigs} stale config(s), ${deletedEntitiesCount} removed entit${deletedEntitiesCount === 1 ? "y" : "ies"}`;
        return {
          status: total === 0 ? "skipped" : "success",
          output,
          rescheduleAt: job.source === "schedule" ? nextRunAt ?? void 0 : void 0
        };
      } catch (error2) {
        await logger.error("Cleanup job failed", {
          source: "CleanupJob",
          meta: {
            jobId: job.id,
            instanceId,
            instanceName: instance.name,
            error: error2
          }
        });
        const errorMessage = error2 instanceof Error ? error2.message : String(error2);
        try {
          await notificationManager.notify(notifications.arrCleanup({
            instanceName: instance.name,
            instanceType,
            deletedCustomFormats: [],
            deletedQualityProfiles: [],
            skippedQualityProfiles: [],
            deletedEntities: [],
            failedEntities: [],
            error: errorMessage
          }));
        } catch (err) {
          await logger.error("Failed to send arr cleanup failure notification", {
            source: "CleanupJob",
            meta: {
              instanceId,
              error: err instanceof Error ? err.message : String(err)
            }
          });
        }
        return {
          status: "failure",
          error: errorMessage
        };
      } finally {
        client2.close();
      }
    };
    jobQueueRegistry.register("arr.cleanup", cleanupHandler);
    arrDriftSettingsQueries = {
      getByInstanceId(arrInstanceId) {
        const row = db.queryFirst("SELECT * FROM arr_drift_settings WHERE arr_instance_id = ?", arrInstanceId);
        return row ? rowToSettings2(row) : void 0;
      },
      getAll() {
        return db.query("SELECT * FROM arr_drift_settings").map(rowToSettings2);
      },
      getEnabled() {
        return db.query("SELECT * FROM arr_drift_settings WHERE enabled = 1").map(rowToSettings2);
      },
      upsert(arrInstanceId, input) {
        if (this.getByInstanceId(arrInstanceId)) {
          this.update(arrInstanceId, input);
          return this.getByInstanceId(arrInstanceId);
        }
        const enabled3 = input.enabled !== void 0 ? input.enabled ? 1 : 0 : 0;
        const cron = input.cron ?? "0 0 * * *";
        const nextRunAt = input.nextRunAt ?? null;
        db.execute(`INSERT INTO arr_drift_settings (arr_instance_id, enabled, cron, next_run_at)
			 VALUES (?, ?, ?, ?)`, arrInstanceId, enabled3, cron, nextRunAt);
        return this.getByInstanceId(arrInstanceId);
      },
      update(arrInstanceId, input) {
        const updates = [];
        const params = [];
        if (input.enabled !== void 0) {
          updates.push("enabled = ?");
          params.push(input.enabled ? 1 : 0);
        }
        if (input.cron !== void 0) {
          updates.push("cron = ?");
          params.push(input.cron);
        }
        if (input.nextRunAt !== void 0) {
          updates.push("next_run_at = ?");
          params.push(input.nextRunAt);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(arrInstanceId);
        return db.execute(`UPDATE arr_drift_settings SET ${updates.join(", ")} WHERE arr_instance_id = ?`, ...params) > 0;
      },
      delete(arrInstanceId) {
        return db.execute("DELETE FROM arr_drift_settings WHERE arr_instance_id = ?", arrInstanceId) > 0;
      },
      updateNextRunAt(arrInstanceId, nextRunAt) {
        db.execute("UPDATE arr_drift_settings SET next_run_at = ?, updated_at = CURRENT_TIMESTAMP WHERE arr_instance_id = ?", nextRunAt, arrInstanceId);
      },
      getDueConfigs() {
        return db.query(`
			SELECT * FROM arr_drift_settings
			WHERE enabled = 1
			AND (
				next_run_at IS NULL
				OR datetime('now') >= datetime(replace(replace(next_run_at, 'T', ' '), 'Z', ''))
			)
		`).map(rowToSettings2);
      }
    };
    FIELD_ORDER = [
      "id",
      "protocol",
      "usenetDelay",
      "torrentDelay",
      "bypassIfHighestQuality",
      "bypassIfAboveCustomFormatScore",
      "minimumCustomFormatScore",
      "order",
      "tags"
    ];
    MEDIA_SETTINGS_FIELD_ORDER = ["downloadPropersAndRepacks", "enableMediaInfo"];
    NAMING_FIELD_ORDER = {
      radarr: [
        "renameMovies",
        "replaceIllegalCharacters",
        "colonReplacementFormat",
        "standardMovieFormat",
        "movieFolderFormat"
      ],
      sonarr: [
        "renameEpisodes",
        "replaceIllegalCharacters",
        "colonReplacementFormat",
        "customColonReplacementFormat",
        "multiEpisodeStyle",
        "standardEpisodeFormat",
        "dailyEpisodeFormat",
        "animeEpisodeFormat",
        "seriesFolderFormat",
        "seasonFolderFormat"
      ]
    };
    QUALITY_DEFINITION_FIELD_ORDER = [
      "minSize",
      "maxSize",
      "preferredSize"
    ];
    QUALITY_DEFINITION_UNLIMITED_MAX = {
      radarr: 2e3,
      sonarr: 1e3
    };
    IMPLEMENTATION_LABELS = {
      ReleaseTitleSpecification: "Release Title",
      ReleaseGroupSpecification: "Release Group",
      EditionSpecification: "Edition",
      SourceSpecification: "Source",
      ResolutionSpecification: "Resolution",
      IndexerFlagSpecification: "Indexer Flag",
      QualityModifierSpecification: "Quality Modifier",
      SizeSpecification: "Size",
      LanguageSpecification: "Language",
      ReleaseTypeSpecification: "Release Type",
      YearSpecification: "Year"
    };
    driftHandler = async (job) => {
      const instanceId = Number(job.payload.instanceId);
      if (!Number.isFinite(instanceId)) return {
        status: "failure",
        error: "Invalid instance ID"
      };
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return {
        status: "failure",
        error: "Arr instance not found"
      };
      const settings2 = arrDriftSettingsQueries.getByInstanceId(instanceId);
      if (!settings2 || !settings2.enabled) return {
        status: "cancelled",
        output: "Drift detection disabled"
      };
      if (!FEATURES.drift) return {
        status: "cancelled",
        output: "Drift detection feature disabled"
      };
      if (instance.type !== "radarr" && instance.type !== "sonarr") return {
        status: "skipped",
        output: `Drift detection not supported for ${instance.type}`
      };
      const nextRunAt = calculateNextRun(settings2.cron);
      if (nextRunAt) arrDriftSettingsQueries.updateNextRunAt(instanceId, nextRunAt);
      const client2 = createArrClient(instance.type, instance.url, instance.api_key, { retries: 0 });
      const previousStatus = arrDriftStatusQueries.getByInstanceId(instanceId);
      try {
        const result = await checkArrDrift(client2, instanceId, instance.type);
        const now = (/* @__PURE__ */ new Date()).toISOString();
        const logMeta = {
          jobId: job.id,
          instanceId,
          instanceName: instance.name,
          status: result.status,
          counts: result.counts,
          diffHash: result.diffHash
        };
        arrDriftStatusQueries.upsert(instanceId, {
          status: result.status,
          lastCheckedAt: now,
          counts: result.counts,
          diff: result.diff,
          diffHash: result.diffHash,
          lastError: null,
          errorHash: null
        });
        const totalCount = Object.values(result.counts).reduce((sum, count) => sum + (count ?? 0), 0);
        if (result.status === "drift_detected") {
          const notified = result.diffHash !== previousStatus?.lastNotifiedHash;
          await logger.info("Drift detected", {
            source: "jobs.handlers.arrDrift",
            meta: {
              ...logMeta,
              notified
            }
          });
          if (notified) {
            await notificationManager.notify(notifications.arrDriftDetected({
              instanceName: instance.name,
              instanceType: instance.type,
              entities: buildDriftDisplayEntities(result.diff, instance.type)
            }));
            arrDriftStatusQueries.update(instanceId, {
              lastNotifiedHash: result.diffHash,
              lastNotifiedAt: now
            });
          }
        } else await logger.debug("Drift check complete", {
          source: "jobs.handlers.arrDrift",
          meta: logMeta
        });
        return {
          status: "success",
          output: totalCount === 0 ? "No drift detected" : `Detected ${totalCount} drift item(s)`,
          rescheduleAt: job.source === "schedule" ? nextRunAt ?? void 0 : void 0
        };
      } catch (error2) {
        const message2 = error2 instanceof Error ? error2.message : String(error2);
        const now = (/* @__PURE__ */ new Date()).toISOString();
        const errorHash = await hashDriftDiff({ error: message2 });
        const notified = errorHash !== previousStatus?.lastNotifiedErrorHash;
        await logger.error("Drift check failed", {
          source: "jobs.handlers.arrDrift",
          meta: {
            jobId: job.id,
            instanceId,
            instanceName: instance.name,
            error: message2,
            notified
          }
        });
        arrDriftStatusQueries.upsert(instanceId, {
          status: "failed",
          lastCheckedAt: now,
          counts: {},
          diff: {},
          diffHash: null,
          lastError: message2,
          errorHash
        });
        if (notified) {
          await notificationManager.notify(notifications.arrDriftFailed({
            instanceName: instance.name,
            instanceType: instance.type,
            error: message2
          }));
          arrDriftStatusQueries.update(instanceId, {
            lastNotifiedErrorHash: errorHash,
            lastNotifiedAt: now
          });
        }
        return {
          status: "failure",
          error: message2,
          rescheduleAt: job.source === "schedule" ? nextRunAt ?? void 0 : void 0
        };
      } finally {
        client2.close();
      }
    };
    jobQueueRegistry.register("arr.drift", driftHandler);
    libraryRefreshHandler = async (job) => {
      const instanceId = Number(job.payload.instanceId);
      if (!Number.isFinite(instanceId)) return {
        status: "failure",
        error: "Invalid instance ID"
      };
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance || instance.enabled === 0) return {
        status: "cancelled",
        output: "Instance disabled"
      };
      if (instance.library_refresh_interval <= 0) return {
        status: "cancelled",
        output: "Library refresh disabled"
      };
      const scheduledFromLastRun = calculateNextRunFromMinutes(instance.library_last_refreshed_at, instance.library_refresh_interval);
      if (job.source === "schedule" && instance.library_last_refreshed_at) {
        const dueAt = new Date(scheduledFromLastRun).getTime();
        if (Date.now() < dueAt) return {
          status: "skipped",
          output: "Library refresh not due",
          rescheduleAt: scheduledFromLastRun
        };
      }
      const rescheduleAt = job.source === "schedule" ? calculateNextRunFromMinutes((/* @__PURE__ */ new Date()).toISOString(), instance.library_refresh_interval) : void 0;
      if (instance.type !== "radarr" && instance.type !== "sonarr") return {
        status: "skipped",
        output: `Library refresh not supported for ${instance.type}`
      };
      const profilarrProfileNames = await getProfilarrProfileNames();
      const clientOptions = { timeout: LIBRARY_REQUEST_TIMEOUT_MS };
      const client2 = instance.type === "radarr" ? new RadarrClient(instance.url, instance.api_key, clientOptions) : new SonarrClient(instance.url, instance.api_key, clientOptions);
      try {
        const items = await client2.getLibrary(profilarrProfileNames);
        const ttl = instance.library_refresh_interval * 60;
        cache.set(`library:${instanceId}`, items, ttl);
        arrInstancesQueries.updateLibraryRefreshedAt(instanceId);
        await logger.info(`Library refreshed for ${instance.name}`, {
          source: "LibraryRefresh",
          meta: {
            instanceId,
            itemCount: items.length
          }
        });
        return {
          status: "success",
          output: `Cached ${items.length} item(s)`,
          rescheduleAt
        };
      } catch (error2) {
        await logger.error("Library refresh failed", {
          source: "LibraryRefresh",
          meta: {
            jobId: job.id,
            instanceId,
            instanceName: instance.name,
            error: error2
          }
        });
        return {
          status: "failure",
          error: error2 instanceof Error ? error2.message : String(error2),
          rescheduleAt
        };
      } finally {
        client2.close();
      }
    };
    jobQueueRegistry.register("arr.library.refresh", libraryRefreshHandler);
    sectionOrder = [
      "qualityProfiles",
      "delayProfiles",
      "mediaManagement"
    ];
    jobTypeToSection = /* @__PURE__ */ new Map([
      ["arr.sync.qualityProfiles", "qualityProfiles"],
      ["arr.sync.delayProfiles", "delayProfiles"],
      ["arr.sync.mediaManagement", "mediaManagement"]
    ]);
    arrSyncHandler = async (job) => {
      const instanceId = Number(job.payload.instanceId);
      if (!Number.isFinite(instanceId)) return {
        status: "failure",
        error: "Invalid instance ID"
      };
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance || !instance.enabled) return {
        status: "cancelled",
        output: "Arr instance disabled"
      };
      const configStatus = arrSyncQueries.getSyncConfigStatus(instanceId);
      const sectionsToRun = resolveSections(job.jobType, job.payload);
      if (sectionsToRun.length === 0) return {
        status: "skipped",
        output: "No sync sections specified"
      };
      const client2 = createArrClient(instance.type, instance.url, instance.api_key);
      const results = [];
      const sectionResults = [];
      let failures = 0;
      let ranSections = 0;
      let rescheduleAt = null;
      for (const section of sectionsToRun) {
        const handler = getSection(section);
        const config2 = configStatus[section];
        if (job.source === "schedule" && config2.trigger !== "schedule") {
          results.push(`${section}: skipped`);
          continue;
        }
        if (!handler.hasConfig(instanceId)) {
          handler.completeSync(instanceId);
          results.push(`${section}: skipped`);
          continue;
        }
        handler.setStatusPending(instanceId);
        if (!handler.claimSync(instanceId)) continue;
        ranSections++;
        try {
          const result = await handler.createSyncer(client2, instance).sync();
          if (result.success) {
            handler.completeSync(instanceId);
            results.push(`${section}: ${result.itemsSynced} item(s)`);
            sectionResults.push({
              section,
              success: true,
              items: result.items
            });
          } else {
            handler.failSync(instanceId, result.error ?? "Unknown error");
            results.push(`${section}: failed`);
            failures++;
            sectionResults.push({
              section,
              success: false,
              error: result.error
            });
          }
        } catch (error2) {
          const message2 = error2 instanceof Error ? error2.message : "Unknown error";
          handler.failSync(instanceId, message2);
          results.push(`${section}: failed`);
          failures++;
          sectionResults.push({
            section,
            success: false,
            error: message2
          });
          await logger.error("Arr sync failed", {
            source: "ArrSyncJob",
            meta: {
              jobId: job.id,
              instanceId,
              instanceName: instance.name,
              section,
              error: message2
            }
          });
        } finally {
          if (config2.trigger === "schedule") {
            const nextRun = calculateNextRun(config2.cron);
            handler.setNextRunAt(instanceId, nextRun);
            if (job.source === "schedule") rescheduleAt = nextRun ?? null;
          }
        }
      }
      if (ranSections > 0) {
        try {
          await notificationManager.notify(notifications.arrSync({
            instanceName: instance.name,
            instanceType: instance.type,
            sections: sectionResults
          }));
        } catch (err) {
          await logger.error("Failed to send arr sync notification", {
            source: "ArrSyncJob",
            meta: {
              instanceId,
              error: err instanceof Error ? err.message : "Unknown error"
            }
          });
        }
        if (FEATURES.drift && arrDriftSettingsQueries.getByInstanceId(instanceId)?.enabled) try {
          enqueueJob({
            jobType: "arr.drift",
            runAt: (/* @__PURE__ */ new Date()).toISOString(),
            payload: { instanceId },
            source: "manual"
          });
        } catch (err) {
          await logger.error("Failed to enqueue post-sync drift refresh", {
            source: "ArrSyncJob",
            meta: {
              instanceId,
              error: err instanceof Error ? err.message : "Unknown error"
            }
          });
        }
      }
      if (job.source === "schedule" && job.jobType === "arr.sync") {
        const nextRunAt = arrSyncQueries.getNextScheduledRunAt(instanceId);
        if (nextRunAt) return {
          status: failures > 0 ? "failure" : "success",
          output: results.join(", "),
          rescheduleAt: nextRunAt
        };
      }
      return {
        status: ranSections === 0 ? "skipped" : failures > 0 ? "failure" : "success",
        output: results.join(", "),
        rescheduleAt: job.source === "schedule" ? rescheduleAt : null
      };
    };
    jobQueueRegistry.register("arr.sync", arrSyncHandler);
    jobQueueRegistry.register("arr.sync.qualityProfiles", arrSyncHandler);
    jobQueueRegistry.register("arr.sync.delayProfiles", arrSyncHandler);
    jobQueueRegistry.register("arr.sync.mediaManagement", arrSyncHandler);
    linkPats = /* @__PURE__ */ new Map();
    pcdLinkHandler = async (job, ctx) => {
      const payload2 = job.payload;
      const name = typeof payload2.name === "string" ? payload2.name : "";
      const repositoryUrl = typeof payload2.repositoryUrl === "string" ? payload2.repositoryUrl : "";
      if (!name || !repositoryUrl) return {
        status: "failure",
        error: "Invalid link payload"
      };
      const personalAccessToken = typeof payload2.patToken === "string" ? consumeLinkPat(payload2.patToken) : void 0;
      const input = {
        name,
        repositoryUrl,
        branch: typeof payload2.branch === "string" ? payload2.branch : void 0,
        syncStrategy: typeof payload2.syncStrategy === "number" ? payload2.syncStrategy : 0,
        autoPull: payload2.autoPull === true,
        personalAccessToken,
        localOpsEnabled: payload2.localOpsEnabled === true,
        gitUserName: typeof payload2.gitUserName === "string" ? payload2.gitUserName : void 0,
        gitUserEmail: typeof payload2.gitUserEmail === "string" ? payload2.gitUserEmail : void 0,
        conflictStrategy: typeof payload2.conflictStrategy === "string" ? payload2.conflictStrategy : void 0
      };
      try {
        const instance = await pcdManager.link(input, ctx?.progress);
        schedulePcdSyncForDatabase(instance.id);
        await logger.info(`Linked database "${name}" via job`, {
          source: "PcdLinkJob",
          meta: {
            jobId: job.id,
            databaseId: instance.id,
            name
          }
        });
        return {
          status: "success",
          output: `Linked "${name}"`
        };
      } catch (error2) {
        const errorMessage = error2 instanceof Error ? error2.message : String(error2);
        await logger.error("Database link job failed", {
          source: "PcdLinkJob",
          meta: {
            jobId: job.id,
            name,
            repositoryUrl,
            error: errorMessage
          }
        });
        try {
          await notificationManager.notify(notifications.pcdLinkFailed({
            name,
            error: errorMessage
          }));
        } catch {
        }
        return {
          status: "failure",
          error: errorMessage
        };
      }
    };
    jobQueueRegistry.register("pcd.link", pcdLinkHandler);
    dbSyncHandler = async (job) => {
      const databaseId = Number(job.payload.databaseId);
      if (!Number.isFinite(databaseId)) return {
        status: "failure",
        error: "Invalid database ID"
      };
      const instance = databaseInstancesQueries.getById(databaseId);
      if (!instance || instance.enabled === 0) return {
        status: "cancelled",
        output: "Database sync disabled"
      };
      if (instance.sync_strategy <= 0 && job.source === "schedule") return {
        status: "cancelled",
        output: "Auto-sync disabled"
      };
      const scheduledFromLastRun = calculateNextRunFromMinutes(instance.last_synced_at, instance.sync_strategy);
      if (job.source === "schedule" && instance.last_synced_at) {
        const dueAt = new Date(scheduledFromLastRun).getTime();
        if (Date.now() < dueAt) return {
          status: "skipped",
          output: "Database sync not due",
          rescheduleAt: scheduledFromLastRun
        };
      }
      const rescheduleAt = job.source === "schedule" ? calculateNextRunFromMinutes((/* @__PURE__ */ new Date()).toISOString(), instance.sync_strategy) : void 0;
      const isFirstSync = instance.last_synced_at === null;
      try {
        const updateInfo = await pcdManager.checkForUpdates(databaseId);
        if (!updateInfo.hasUpdates) {
          databaseInstancesQueries.updateSyncedAt(databaseId);
          await reconcileAndNotify(databaseId, {
            source: "DbSyncJob",
            jobId: job.id,
            isFirstSync
          });
          return {
            status: "skipped",
            output: "No updates available",
            rescheduleAt
          };
        }
        if (instance.auto_pull === 1) {
          const syncResult = await pcdManager.sync(databaseId, job.source === "schedule" ? "schedule" : "manual-api");
          if (!syncResult.success) return {
            status: "failure",
            error: syncResult.error ?? "Sync failed",
            rescheduleAt
          };
          await reconcileAndNotify(databaseId, {
            source: "DbSyncJob",
            jobId: job.id,
            isFirstSync
          });
          return {
            status: "success",
            output: `Pulled ${syncResult.commitsBehind} update(s)`,
            rescheduleAt
          };
        }
        databaseInstancesQueries.updateSyncedAt(databaseId);
        try {
          const commitMessages = await getCommitMessagesBetween(instance.local_path, updateInfo.currentLocalCommit, updateInfo.latestRemoteCommit);
          await notificationManager.notify(notifications.pcdUpdatesAvailable({
            name: instance.name,
            commitsBehind: updateInfo.commitsBehind,
            commitMessages
          }));
        } catch {
        }
        await reconcileAndNotify(databaseId, {
          source: "DbSyncJob",
          jobId: job.id,
          isFirstSync
        });
        return {
          status: "success",
          output: "Updates available (auto-pull disabled)",
          rescheduleAt
        };
      } catch (error2) {
        await logger.error("Database sync job failed", {
          source: "DbSyncJob",
          meta: {
            jobId: job.id,
            databaseId,
            databaseName: instance.name,
            error: error2
          }
        });
        return {
          status: "failure",
          error: error2 instanceof Error ? error2.message : String(error2),
          rescheduleAt
        };
      }
    };
    jobQueueRegistry.register("pcd.sync", dbSyncHandler);
    backupCreateHandler = async (job) => {
      const settings2 = backupSettingsQueries.get();
      if (!settings2 || settings2.enabled !== 1) return {
        status: "cancelled",
        output: "Backups disabled"
      };
      const sourceDir = config.paths.data;
      const backupsDir = config.paths.backups;
      const startedAt = Date.now();
      try {
        const result = await createBackup(sourceDir, backupsDir);
        if (!result.success) {
          const errorMessage = result.error ?? "Backup failed";
          await notifyFailure(job.id, errorMessage);
          return {
            status: "failure",
            error: errorMessage
          };
        }
        const sizeInMB = ((result.sizeBytes ?? 0) / 1048576).toFixed(2);
        const output = `Backup created: ${result.filename} (${sizeInMB} MB)`;
        const nextRun = calculateNextRunFromSchedule(settings2.schedule);
        try {
          await notificationManager.notify(notifications.backupSuccess({
            filename: result.filename ?? "",
            sizeBytes: result.sizeBytes ?? 0,
            durationMs: Date.now() - startedAt
          }));
        } catch (err) {
          await logger.error("Failed to send backup success notification", {
            source: "BackupCreateJob",
            meta: {
              jobId: job.id,
              error: err instanceof Error ? err.message : "Unknown error"
            }
          });
        }
        return {
          status: "success",
          output,
          rescheduleAt: job.source === "schedule" ? nextRun : void 0
        };
      } catch (error2) {
        const errorMessage = error2 instanceof Error ? error2.message : String(error2);
        await logger.error("Backup creation failed", {
          source: "BackupCreateJob",
          meta: {
            jobId: job.id,
            error: error2
          }
        });
        await notifyFailure(job.id, errorMessage);
        return {
          status: "failure",
          error: errorMessage
        };
      }
    };
    jobQueueRegistry.register("backup.create", backupCreateHandler);
    backupCleanupHandler = async (job) => {
      const settings2 = backupSettingsQueries.get();
      if (!settings2 || settings2.enabled !== 1) return {
        status: "cancelled",
        output: "Backups disabled"
      };
      const retentionDays = settings2.retention_days;
      const backupsDir = config.paths.backups;
      const cutoffDate = /* @__PURE__ */ new Date();
      cutoffDate.setDate(cutoffDate.getDate() - retentionDays);
      let deletedCount = 0;
      let errorCount = 0;
      try {
        for await (const entry of Deno.readDir(backupsDir)) {
          if (!entry.isFile) continue;
          if (!entry.name.startsWith("backup-") || !entry.name.endsWith(".tar.gz")) continue;
          const filePath = `${backupsDir}/${entry.name}`;
          try {
            const stat = await Deno.stat(filePath);
            if (stat.mtime && stat.mtime < cutoffDate) {
              await Deno.remove(filePath);
              deletedCount++;
            }
          } catch (error2) {
            errorCount++;
            await logger.error(`Failed to process backup file: ${entry.name}`, {
              source: "BackupCleanupJob",
              meta: {
                jobId: job.id,
                file: entry.name,
                error: error2
              }
            });
          }
        }
      } catch (error2) {
        await logger.error("Backup cleanup failed", {
          source: "BackupCleanupJob",
          meta: {
            jobId: job.id,
            error: error2
          }
        });
        return {
          status: "failure",
          error: `Failed to read backups directory: ${error2 instanceof Error ? error2.message : String(error2)}`
        };
      }
      const message2 = `Cleanup completed: deleted ${deletedCount} backup(s), ${errorCount} error(s)`;
      const nextRun = calculateNextRunFromSchedule("daily");
      if (errorCount > 0 && deletedCount === 0) return {
        status: "failure",
        error: message2,
        rescheduleAt: job.source === "schedule" ? nextRun : void 0
      };
      if (deletedCount === 0) return {
        status: "skipped",
        output: "No old backups to clean up",
        rescheduleAt: job.source === "schedule" ? nextRun : void 0
      };
      return {
        status: "success",
        output: message2,
        rescheduleAt: job.source === "schedule" ? nextRun : void 0
      };
    };
    jobQueueRegistry.register("backup.cleanup", backupCleanupHandler);
    logsCleanupHandler = async (job) => {
      const settings2 = logSettingsQueries.get();
      if (!settings2 || settings2.file_logging !== 1) return {
        status: "cancelled",
        output: "File logging disabled"
      };
      const retentionDays = settings2.retention_days;
      const logsDir = config.paths.logs;
      try {
        const result = await cleanupLogs(logsDir, retentionDays);
        const message2 = `Cleanup completed: deleted ${result.deletedCount} file(s), ${result.errorCount} error(s)`;
        const nextRun = calculateNextRunFromSchedule("daily");
        if (result.errorCount > 0 && result.deletedCount === 0) return {
          status: "failure",
          error: message2,
          rescheduleAt: job.source === "schedule" ? nextRun : void 0
        };
        if (result.deletedCount === 0) return {
          status: "skipped",
          output: "No old log files to clean up",
          rescheduleAt: job.source === "schedule" ? nextRun : void 0
        };
        return {
          status: "success",
          output: message2,
          rescheduleAt: job.source === "schedule" ? nextRun : void 0
        };
      } catch (error2) {
        await logger.error("Logs cleanup failed", {
          source: "LogsCleanupJob",
          meta: {
            jobId: job.id,
            error: error2
          }
        });
        return {
          status: "failure",
          error: error2 instanceof Error ? error2.message : String(error2)
        };
      }
    };
    jobQueueRegistry.register("logs.cleanup", logsCleanupHandler);
    announcementsFetchHandler = async (job) => {
      const result = await reconcileFromBulletin();
      if (result.newlyInserted.length > 0) await notifyNewAnnouncements(job.id, result.newlyInserted);
      const output = JSON.stringify({
        versions: result.versions,
        announcements: result.announcements,
        inserted: result.newlyInserted.length
      });
      const rescheduleAt = job.source === "schedule" ? new Date(Date.now() + FETCH_INTERVAL_MS).toISOString() : void 0;
      if (result.announcements === "failed" && result.versions === "failed") return {
        status: "failure",
        error: "Bulletin fetch failed for both versions and announcements",
        output,
        rescheduleAt
      };
      return {
        status: "success",
        output,
        rescheduleAt
      };
    };
    jobQueueRegistry.register("announcements.fetch", announcementsFetchHandler);
    JobDispatcher = class {
      timerId = null;
      nextWakeAt = null;
      running = false;
      start() {
        this.scheduleNextWake();
      }
      stop() {
        if (this.timerId !== null) {
          clearTimeout(this.timerId);
          this.timerId = null;
        }
        this.nextWakeAt = null;
      }
      notifyJobEnqueued(runAt) {
        const runAtMs = new Date(runAt).getTime();
        if (this.nextWakeAt === null || runAtMs < this.nextWakeAt) this.scheduleNextWake();
      }
      scheduleNextWake() {
        const next2 = jobQueueQueries.getNextQueued();
        if (!next2) {
          this.stop();
          return;
        }
        const runAtMs = new Date(next2.runAt).getTime();
        const delay = Math.max(0, runAtMs - Date.now());
        this.nextWakeAt = runAtMs;
        if (this.timerId !== null) clearTimeout(this.timerId);
        this.timerId = setTimeout(() => {
          this.runDueJobs();
        }, delay);
      }
      async runDueJobs() {
        if (this.running) return;
        this.running = true;
        try {
          while (true) {
            const job = jobQueueQueries.claimNextDue();
            if (!job) break;
            await this.executeJob(job);
          }
        } finally {
          this.running = false;
          this.scheduleNextWake();
        }
      }
      async executeJob(job) {
        const displayName = buildJobDisplayName(job.jobType, job.payload);
        const handler = jobQueueRegistry.get(job.jobType);
        if (!handler) {
          await logger.error(`Job handler not found for ${job.jobType}`, {
            source: "JobDispatcher",
            meta: {
              jobId: job.id,
              jobType: job.jobType,
              displayName
            }
          });
          jobQueueQueries.markFinished(job.id, "failed");
          jobRunHistoryQueries.create(job.id, job.jobType, "failure", job.startedAt ?? (/* @__PURE__ */ new Date()).toISOString(), (/* @__PURE__ */ new Date()).toISOString(), 0, "Handler not found");
          return;
        }
        const startedAt = job.startedAt ?? (/* @__PURE__ */ new Date()).toISOString();
        const startMs = Date.now();
        await logger.debug(`Job started: ${job.jobType}`, {
          source: "JobDispatcher",
          meta: {
            jobId: job.id,
            jobType: job.jobType,
            displayName,
            sourceType: job.source,
            runAt: job.runAt
          }
        });
        jobEvents.emit({
          type: "job.started",
          jobId: job.id,
          jobType: job.jobType,
          displayLabel: getJobRunningLabel(job.jobType)
        });
        let result;
        try {
          result = await handler(job, { progress: (label) => {
            jobEvents.emit({
              type: "job.progress",
              jobId: job.id,
              jobType: job.jobType,
              label
            });
          } });
        } catch (error2) {
          result = {
            status: "failure",
            error: error2 instanceof Error ? error2.message : String(error2)
          };
        }
        const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
        const durationMs = Date.now() - startMs;
        jobRunHistoryQueries.create(job.id, job.jobType, result.status, startedAt, finishedAt, durationMs, result.error, result.output);
        jobEvents.emit({
          type: "job.finished",
          jobId: job.id,
          jobType: job.jobType,
          displayLabel: getJobCompletedLabel(job.jobType),
          status: result.status,
          durationMs
        });
        await logger.debug(`Job finished: ${job.jobType} (${result.status})`, {
          source: "JobDispatcher",
          meta: {
            jobId: job.id,
            jobType: job.jobType,
            displayName,
            status: result.status,
            durationMs,
            rescheduleAt: result.rescheduleAt ?? null,
            error: result.error ?? null
          }
        });
        if (result.rescheduleAt) {
          jobQueueQueries.reschedule(job.id, result.rescheduleAt, job.cooldownUntil);
          return;
        }
        const status = result.status === "success" ? "success" : result.status === "skipped" ? "success" : result.status === "cancelled" ? "cancelled" : "failed";
        jobQueueQueries.markFinished(job.id, status);
      }
    };
    jobDispatcher = new JobDispatcher();
  }
});

// dist/build/server/chunks/init.js
async function initializeJobs() {
  await logger.debug("Initializing job queue", { source: "JobQueue" });
  const recovered = jobQueueQueries.recoverRunning();
  if (recovered > 0) await logger.info(`Recovered ${recovered} running job(s)`, { source: "JobQueue" });
  scheduleAllJobs();
  jobDispatcher.stop();
  jobDispatcher.start();
  await logger.info("Job queue ready", { source: "JobQueue" });
}
var init_init = __esm({
  async "dist/build/server/chunks/init.js"() {
    "use strict";
    await init_db();
    await init_jobQueue();
    await init_queueService();
  }
});

// dist/build/server/chunks/users.js
function rowToSession(row) {
  return {
    ...row,
    expires_at: toUTC(row.expires_at),
    created_at: toUTC(row.created_at),
    last_active_at: toUTC(row.last_active_at)
  };
}
var sessionsQueries, usersQueries;
var init_users = __esm({
  async "dist/build/server/chunks/users.js"() {
    "use strict";
    await init_db();
    init_dates();
    sessionsQueries = {
      /**
      * Create a new session with optional metadata
      */
      create(userId, durationHours, metadata) {
        const id = crypto.randomUUID();
        const expiresAt = new Date(Date.now() + durationHours * 60 * 60 * 1e3);
        db.execute(`INSERT INTO sessions (id, user_id, expires_at, ip_address, user_agent, browser, os, device_type, last_active_at)
			 VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)`, id, userId, expiresAt.toISOString(), metadata?.ipAddress ?? null, metadata?.userAgent ?? null, metadata?.browser ?? null, metadata?.os ?? null, metadata?.deviceType ?? null);
        return id;
      },
      /**
      * Get a session by ID (regardless of expiration)
      */
      getById(id) {
        const row = db.queryFirst("SELECT * FROM sessions WHERE id = ?", id);
        return row ? rowToSession(row) : void 0;
      },
      /**
      * Get a valid (non-expired) session by ID
      */
      getValidById(id) {
        const row = db.queryFirst(`SELECT * FROM sessions
			 WHERE id = ? AND datetime(expires_at) > datetime('now')`, id);
        return row ? rowToSession(row) : void 0;
      },
      /**
      * Get all sessions for a user
      */
      getByUserId(userId) {
        return db.query("SELECT * FROM sessions WHERE user_id = ? ORDER BY created_at DESC", userId).map(rowToSession);
      },
      /**
      * Delete a specific session (logout)
      */
      deleteById(id) {
        return db.execute("DELETE FROM sessions WHERE id = ?", id) > 0;
      },
      /**
      * Delete all sessions for a user (logout everywhere)
      */
      deleteByUserId(userId) {
        return db.execute("DELETE FROM sessions WHERE user_id = ?", userId);
      },
      /**
      * Delete all sessions except one (logout other devices)
      */
      deleteOthersByUserId(userId, keepSessionId) {
        return db.execute("DELETE FROM sessions WHERE user_id = ? AND id != ?", userId, keepSessionId);
      },
      /**
      * Delete all expired sessions (cleanup)
      */
      deleteExpired() {
        return db.execute(`DELETE FROM sessions WHERE datetime(expires_at) <= datetime('now')`);
      },
      /**
      * Extend session expiration (sliding expiration)
      * Also updates last_active_at for activity tracking
      */
      extendExpiration(id, durationHours) {
        const expiresAt = new Date(Date.now() + durationHours * 60 * 60 * 1e3);
        return db.execute("UPDATE sessions SET expires_at = ?, last_active_at = CURRENT_TIMESTAMP WHERE id = ?", expiresAt.toISOString(), id) > 0;
      },
      /**
      * Count active sessions for a user
      */
      countByUserId(userId) {
        return db.queryFirst(`SELECT COUNT(*) as count FROM sessions
			 WHERE user_id = ? AND datetime(expires_at) > datetime('now')`, userId)?.count ?? 0;
      }
    };
    usersQueries = {
      /**
      * Check if any users exist (for first-run setup detection)
      */
      exists() {
        return (db.queryFirst("SELECT COUNT(*) as count FROM users")?.count ?? 0) > 0;
      },
      /**
      * Check if any local (non-OIDC) users exist
      * OIDC users have username starting with 'oidc:'
      */
      existsLocal() {
        return (db.queryFirst("SELECT COUNT(*) as count FROM users WHERE username NOT LIKE 'oidc:%'")?.count ?? 0) > 0;
      },
      /**
      * Get user by ID
      */
      getById(id) {
        return db.queryFirst("SELECT * FROM users WHERE id = ?", id);
      },
      /**
      * Get user by username
      */
      getByUsername(username) {
        return db.queryFirst("SELECT * FROM users WHERE username = ?", username);
      },
      /**
      * Get all usernames (for login analysis - typo detection)
      * Excludes OIDC users since they can't login with password
      */
      getAllUsernames() {
        return db.query("SELECT username FROM users WHERE username NOT LIKE 'oidc:%'").map((r2) => r2.username);
      },
      /**
      * Create a new user (should only be called once during setup)
      */
      create(username, passwordHash) {
        db.execute("INSERT INTO users (username, password_hash) VALUES (?, ?)", username, passwordHash);
        return db.queryFirst("SELECT last_insert_rowid() as id")?.id ?? 0;
      },
      /**
      * Update user's password
      */
      updatePassword(id, passwordHash) {
        return db.execute("UPDATE users SET password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?", passwordHash, id) > 0;
      },
      /**
      * Update username
      */
      updateUsername(id, username) {
        return db.execute("UPDATE users SET username = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?", username, id) > 0;
      },
      /**
      * Get or create OIDC user
      * OIDC users have no password (placeholder hash)
      */
      getOrCreateOidcUser(identifier) {
        const username = `oidc:${identifier}`;
        const existing = this.getByUsername(username);
        if (existing) return existing.id;
        db.execute("INSERT INTO users (username, password_hash) VALUES (?, ?)", username, "OIDC_NO_PASSWORD");
        return db.queryFirst("SELECT last_insert_rowid() as id")?.id ?? 0;
      }
    };
  }
});

// dist/build/server/chunks/authSettings.js
function generateApiKey() {
  return crypto.randomUUID().replace(/-/g, "");
}
function checkWindows2() {
  const global = globalThis;
  const platform = global.process?.platform;
  if (typeof platform === "string") return platform.startsWith("win");
  const os = global.Deno?.build?.os;
  if (typeof os === "string") return os === "windows";
  return global.navigator?.platform?.startsWith("Win") ?? false;
}
function assertPath2(path) {
  if (typeof path !== "string") throw new TypeError(`Path must be a string, received "${JSON.stringify(path)}"`);
}
function assertArg$22(url) {
  url = url instanceof URL ? url : new URL(url);
  if (url.protocol !== "file:") throw new TypeError(`URL must be a file URL: received "${url.protocol}"`);
  return url;
}
function fromFileUrl$22(url) {
  url = assertArg$22(url);
  return decodeURIComponent(url.pathname.replace(/%(?![0-9A-Fa-f]{2})/g, "%25"));
}
function stripTrailingSeparators2(segment, isSep) {
  if (segment.length <= 1) return segment;
  let end = segment.length;
  for (let i = segment.length - 1; i > 0; i--) if (isSep(segment.charCodeAt(i))) end = i;
  else break;
  return segment.slice(0, end);
}
function isPosixPathSeparator$12(code3) {
  return code3 === 47;
}
function isPosixPathSeparator2(code3) {
  return code3 === 47;
}
function isPathSeparator2(code3) {
  return code3 === 47 || code3 === 92;
}
function isWindowsDeviceRoot2(code3) {
  return code3 >= 97 && code3 <= 122 || code3 >= 65 && code3 <= 90;
}
function fromFileUrl$12(url) {
  url = assertArg$22(url);
  let path = decodeURIComponent(url.pathname.replace(/\//g, "\\").replace(/%(?![0-9A-Fa-f]{2})/g, "%25")).replace(/^\\*([A-Za-z]:)(\\|$)/, "$1\\");
  if (url.hostname !== "") path = `\\\\${url.hostname}${path}`;
  return path;
}
function assertArg$12(path) {
  assertPath2(path);
  if (path.length === 0) return ".";
}
function dirname$22(path) {
  if (path instanceof URL) path = fromFileUrl$22(path);
  assertArg$12(path);
  let end = -1;
  let matchedNonSeparator = false;
  for (let i = path.length - 1; i >= 1; --i) if (isPosixPathSeparator$12(path.charCodeAt(i))) {
    if (matchedNonSeparator) {
      end = i;
      break;
    }
  } else matchedNonSeparator = true;
  if (end === -1) return isPosixPathSeparator$12(path.charCodeAt(0)) ? "/" : ".";
  return stripTrailingSeparators2(path.slice(0, end), isPosixPathSeparator$12);
}
function dirname$12(path) {
  if (path instanceof URL) path = fromFileUrl$12(path);
  assertArg$12(path);
  const len = path.length;
  let rootEnd = -1;
  let end = -1;
  let matchedSlash = true;
  let offset = 0;
  const code3 = path.charCodeAt(0);
  if (len > 1) {
    if (isPathSeparator2(code3)) {
      rootEnd = offset = 1;
      if (isPathSeparator2(path.charCodeAt(1))) {
        let j2 = 2;
        let last = j2;
        for (; j2 < len; ++j2) if (isPathSeparator2(path.charCodeAt(j2))) break;
        if (j2 < len && j2 !== last) {
          last = j2;
          for (; j2 < len; ++j2) if (!isPathSeparator2(path.charCodeAt(j2))) break;
          if (j2 < len && j2 !== last) {
            last = j2;
            for (; j2 < len; ++j2) if (isPathSeparator2(path.charCodeAt(j2))) break;
            if (j2 === len) return path;
            if (j2 !== last) rootEnd = offset = j2 + 1;
          }
        }
      }
    } else if (isWindowsDeviceRoot2(code3)) {
      if (path.charCodeAt(1) === 58) {
        rootEnd = offset = 2;
        if (len > 2) {
          if (isPathSeparator2(path.charCodeAt(2))) rootEnd = offset = 3;
        }
      }
    }
  } else if (isPathSeparator2(code3)) return path;
  for (let i = len - 1; i >= offset; --i) if (isPathSeparator2(path.charCodeAt(i))) {
    if (!matchedSlash) {
      end = i;
      break;
    }
  } else matchedSlash = false;
  if (end === -1) if (rootEnd === -1) return ".";
  else end = rootEnd;
  return stripTrailingSeparators2(path.slice(0, end), isPosixPathSeparator2);
}
function dirname2(path) {
  return isWindows2 ? dirname$12(path) : dirname$22(path);
}
function extname$22(path) {
  if (path instanceof URL) path = fromFileUrl$22(path);
  assertPath2(path);
  let startDot = -1;
  let startPart = 0;
  let end = -1;
  let matchedSlash = true;
  let preDotState = 0;
  for (let i = path.length - 1; i >= 0; --i) {
    const code3 = path.charCodeAt(i);
    if (isPosixPathSeparator$12(code3)) {
      if (!matchedSlash) {
        startPart = i + 1;
        break;
      }
      continue;
    }
    if (end === -1) {
      matchedSlash = false;
      end = i + 1;
    }
    if (code3 === 46) {
      if (startDot === -1) startDot = i;
      else if (preDotState !== 1) preDotState = 1;
    } else if (startDot !== -1) preDotState = -1;
  }
  if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) return "";
  return path.slice(startDot, end);
}
function extname$12(path) {
  if (path instanceof URL) path = fromFileUrl$12(path);
  assertPath2(path);
  let start = 0;
  let startDot = -1;
  let startPart = 0;
  let end = -1;
  let matchedSlash = true;
  let preDotState = 0;
  if (path.length >= 2 && path.charCodeAt(1) === 58 && isWindowsDeviceRoot2(path.charCodeAt(0))) start = startPart = 2;
  for (let i = path.length - 1; i >= start; --i) {
    const code3 = path.charCodeAt(i);
    if (isPathSeparator2(code3)) {
      if (!matchedSlash) {
        startPart = i + 1;
        break;
      }
      continue;
    }
    if (end === -1) {
      matchedSlash = false;
      end = i + 1;
    }
    if (code3 === 46) {
      if (startDot === -1) startDot = i;
      else if (preDotState !== 1) preDotState = 1;
    } else if (startDot !== -1) preDotState = -1;
  }
  if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) return "";
  return path.slice(startDot, end);
}
function extname2(path) {
  return isWindows2 ? extname$12(path) : extname$22(path);
}
function fromFileUrl2(url) {
  return isWindows2 ? fromFileUrl$12(url) : fromFileUrl$22(url);
}
function isAbsolute$22(path) {
  assertPath2(path);
  return path.length > 0 && isPosixPathSeparator$12(path.charCodeAt(0));
}
function isAbsolute$12(path) {
  assertPath2(path);
  const len = path.length;
  if (len === 0) return false;
  const code3 = path.charCodeAt(0);
  if (isPathSeparator2(code3)) return true;
  else if (isWindowsDeviceRoot2(code3)) {
    if (len > 2 && path.charCodeAt(1) === 58) {
      if (isPathSeparator2(path.charCodeAt(2))) return true;
    }
  }
  return false;
}
function isAbsolute2(path) {
  return isWindows2 ? isAbsolute$12(path) : isAbsolute$22(path);
}
function assertArg2(path) {
  assertPath2(path);
  if (path.length === 0) return ".";
}
function normalizeString2(path, allowAboveRoot, separator, isPathSeparator3) {
  let res = "";
  let lastSegmentLength = 0;
  let lastSlash = -1;
  let dots = 0;
  let code3;
  for (let i = 0; i <= path.length; ++i) {
    if (i < path.length) code3 = path.charCodeAt(i);
    else if (isPathSeparator3(code3)) break;
    else code3 = 47;
    if (isPathSeparator3(code3)) {
      if (lastSlash === i - 1 || dots === 1) {
      } else if (lastSlash !== i - 1 && dots === 2) {
        if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
          if (res.length > 2) {
            const lastSlashIndex = res.lastIndexOf(separator);
            if (lastSlashIndex === -1) {
              res = "";
              lastSegmentLength = 0;
            } else {
              res = res.slice(0, lastSlashIndex);
              lastSegmentLength = res.length - 1 - res.lastIndexOf(separator);
            }
            lastSlash = i;
            dots = 0;
            continue;
          } else if (res.length === 2 || res.length === 1) {
            res = "";
            lastSegmentLength = 0;
            lastSlash = i;
            dots = 0;
            continue;
          }
        }
        if (allowAboveRoot) {
          if (res.length > 0) res += `${separator}..`;
          else res = "..";
          lastSegmentLength = 2;
        }
      } else {
        if (res.length > 0) res += separator + path.slice(lastSlash + 1, i);
        else res = path.slice(lastSlash + 1, i);
        lastSegmentLength = i - lastSlash - 1;
      }
      lastSlash = i;
      dots = 0;
    } else if (code3 === 46 && dots !== -1) ++dots;
    else dots = -1;
  }
  return res;
}
function normalize$22(path) {
  if (path instanceof URL) path = fromFileUrl$22(path);
  assertArg2(path);
  const isAbsolute4 = isPosixPathSeparator$12(path.charCodeAt(0));
  const trailingSeparator = isPosixPathSeparator$12(path.charCodeAt(path.length - 1));
  path = normalizeString2(path, !isAbsolute4, "/", isPosixPathSeparator$12);
  if (path.length === 0 && !isAbsolute4) path = ".";
  if (path.length > 0 && trailingSeparator) path += "/";
  if (isAbsolute4) return `/${path}`;
  return path;
}
function join$22(path, ...paths) {
  if (path === void 0) return ".";
  if (path instanceof URL) path = fromFileUrl$22(path);
  paths = path ? [path, ...paths] : paths;
  paths.forEach((path2) => assertPath2(path2));
  const joined = paths.filter((path2) => path2.length > 0).join("/");
  return joined === "" ? "." : normalize$22(joined);
}
function normalize$12(path) {
  if (path instanceof URL) path = fromFileUrl$12(path);
  assertArg2(path);
  const len = path.length;
  let rootEnd = 0;
  let device;
  let isAbsolute4 = false;
  const code3 = path.charCodeAt(0);
  if (len > 1) {
    if (isPathSeparator2(code3)) {
      isAbsolute4 = true;
      if (isPathSeparator2(path.charCodeAt(1))) {
        let j2 = 2;
        let last = j2;
        for (; j2 < len; ++j2) if (isPathSeparator2(path.charCodeAt(j2))) break;
        if (j2 < len && j2 !== last) {
          const firstPart = path.slice(last, j2);
          last = j2;
          for (; j2 < len; ++j2) if (!isPathSeparator2(path.charCodeAt(j2))) break;
          if (j2 < len && j2 !== last) {
            last = j2;
            for (; j2 < len; ++j2) if (isPathSeparator2(path.charCodeAt(j2))) break;
            if (j2 === len) return `\\\\${firstPart}\\${path.slice(last)}\\`;
            else if (j2 !== last) {
              device = `\\\\${firstPart}\\${path.slice(last, j2)}`;
              rootEnd = j2;
            }
          }
        }
      } else rootEnd = 1;
    } else if (isWindowsDeviceRoot2(code3)) {
      if (path.charCodeAt(1) === 58) {
        device = path.slice(0, 2);
        rootEnd = 2;
        if (len > 2) {
          if (isPathSeparator2(path.charCodeAt(2))) {
            isAbsolute4 = true;
            rootEnd = 3;
          }
        }
      }
    }
  } else if (isPathSeparator2(code3)) return "\\";
  let tail;
  if (rootEnd < len) tail = normalizeString2(path.slice(rootEnd), !isAbsolute4, "\\", isPathSeparator2);
  else tail = "";
  if (tail.length === 0 && !isAbsolute4) tail = ".";
  if (tail.length > 0 && isPathSeparator2(path.charCodeAt(len - 1))) tail += "\\";
  if (device === void 0) {
    if (isAbsolute4) if (tail.length > 0) return `\\${tail}`;
    else return "\\";
    return tail;
  } else if (isAbsolute4) if (tail.length > 0) return `${device}\\${tail}`;
  else return `${device}\\`;
  return device + tail;
}
function join$12(path, ...paths) {
  if (path instanceof URL) path = fromFileUrl$12(path);
  paths = path ? [path, ...paths] : paths;
  paths.forEach((path2) => assertPath2(path2));
  paths = paths.filter((path2) => path2.length > 0);
  if (paths.length === 0) return ".";
  let needsReplace = true;
  let slashCount = 0;
  const firstPart = paths[0];
  if (isPathSeparator2(firstPart.charCodeAt(0))) {
    ++slashCount;
    const firstLen = firstPart.length;
    if (firstLen > 1) {
      if (isPathSeparator2(firstPart.charCodeAt(1))) {
        ++slashCount;
        if (firstLen > 2) if (isPathSeparator2(firstPart.charCodeAt(2))) ++slashCount;
        else needsReplace = false;
      }
    }
  }
  let joined = paths.join("\\");
  if (needsReplace) {
    for (; slashCount < joined.length; ++slashCount) if (!isPathSeparator2(joined.charCodeAt(slashCount))) break;
    if (slashCount >= 2) joined = `\\${joined.slice(slashCount)}`;
  }
  return normalize$12(joined);
}
function join2(path, ...paths) {
  return isWindows2 ? join$12(path, ...paths) : join$22(path, ...paths);
}
function normalize2(path) {
  return isWindows2 ? normalize$12(path) : normalize$22(path);
}
function cwd2(errorMessage) {
  const global = globalThis;
  const getCwd = global.process?.cwd ?? global.Deno?.cwd;
  if (typeof getCwd !== "function") throw new TypeError(errorMessage);
  return getCwd();
}
function resolve$22(...pathSegments) {
  let resolvedPath = "";
  let resolvedAbsolute = false;
  for (let i = pathSegments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
    let path;
    if (i >= 0) path = pathSegments[i];
    else path = cwd2("Resolved a relative path without a current working directory (CWD)");
    assertPath2(path);
    if (path.length === 0) continue;
    resolvedPath = `${path}/${resolvedPath}`;
    resolvedAbsolute = isPosixPathSeparator$12(path.charCodeAt(0));
  }
  resolvedPath = normalizeString2(resolvedPath, !resolvedAbsolute, "/", isPosixPathSeparator$12);
  if (resolvedAbsolute) if (resolvedPath.length > 0) return `/${resolvedPath}`;
  else return "/";
  else if (resolvedPath.length > 0) return resolvedPath;
  else return ".";
}
function resolve$12(...pathSegments) {
  let resolvedDevice = "";
  let resolvedTail = "";
  let resolvedAbsolute = false;
  for (let i = pathSegments.length - 1; i >= -1; i--) {
    let path;
    if (i >= 0) path = pathSegments[i];
    else if (!resolvedDevice) path = cwd2("Resolved a drive-letter-less path without a current working directory (CWD)");
    else {
      path = cwd2("Resolved a relative path without a current working directory (CWD)");
      if (path === void 0 || path.slice(0, 3).toLowerCase() !== `${resolvedDevice.toLowerCase()}\\`) path = `${resolvedDevice}\\`;
    }
    assertPath2(path);
    const len = path.length;
    if (len === 0) continue;
    let rootEnd = 0;
    let device = "";
    let isAbsolute4 = false;
    const code3 = path.charCodeAt(0);
    if (len > 1) {
      if (isPathSeparator2(code3)) {
        isAbsolute4 = true;
        if (isPathSeparator2(path.charCodeAt(1))) {
          let j2 = 2;
          let last = j2;
          for (; j2 < len; ++j2) if (isPathSeparator2(path.charCodeAt(j2))) break;
          if (j2 < len && j2 !== last) {
            const firstPart = path.slice(last, j2);
            last = j2;
            for (; j2 < len; ++j2) if (!isPathSeparator2(path.charCodeAt(j2))) break;
            if (j2 < len && j2 !== last) {
              last = j2;
              for (; j2 < len; ++j2) if (isPathSeparator2(path.charCodeAt(j2))) break;
              if (j2 === len) {
                device = `\\\\${firstPart}\\${path.slice(last)}`;
                rootEnd = j2;
              } else if (j2 !== last) {
                device = `\\\\${firstPart}\\${path.slice(last, j2)}`;
                rootEnd = j2;
              }
            }
          }
        } else rootEnd = 1;
      } else if (isWindowsDeviceRoot2(code3)) {
        if (path.charCodeAt(1) === 58) {
          device = path.slice(0, 2);
          rootEnd = 2;
          if (len > 2) {
            if (isPathSeparator2(path.charCodeAt(2))) {
              isAbsolute4 = true;
              rootEnd = 3;
            }
          }
        }
      }
    } else if (isPathSeparator2(code3)) {
      rootEnd = 1;
      isAbsolute4 = true;
    }
    if (device.length > 0 && resolvedDevice.length > 0 && device.toLowerCase() !== resolvedDevice.toLowerCase()) continue;
    if (resolvedDevice.length === 0 && device.length > 0) resolvedDevice = device;
    if (!resolvedAbsolute) {
      resolvedTail = `${path.slice(rootEnd)}\\${resolvedTail}`;
      resolvedAbsolute = isAbsolute4;
    }
    if (resolvedAbsolute && resolvedDevice.length > 0) break;
  }
  resolvedTail = normalizeString2(resolvedTail, !resolvedAbsolute, "\\", isPathSeparator2);
  return resolvedDevice + (resolvedAbsolute ? "\\" : "") + resolvedTail || ".";
}
function resolve2(...pathSegments) {
  return isWindows2 ? resolve$12(...pathSegments) : resolve$22(...pathSegments);
}
function encodeWhitespace2(string) {
  return string.replaceAll(/[\s]/g, (c2) => {
    return WHITESPACE_ENCODINGS2[c2] ?? c2;
  });
}
function toFileUrl$22(path) {
  if (!isAbsolute$22(path)) throw new TypeError(`Path must be absolute: received "${path}"`);
  const url = new URL("file:///");
  url.pathname = encodeWhitespace2(path.replace(/^\/+/, "/").replace(/%/g, "%25").replace(/\\/g, "%5C"));
  return url;
}
function toFileUrl$12(path) {
  if (!isAbsolute$12(path)) throw new TypeError(`Path must be absolute: received "${path}"`);
  const [, hostname, pathname] = path.match(/^(?:[/\\]{2}([^/\\]+)(?=[/\\](?:[^/\\]|$)))?(.*)/);
  const url = new URL("file:///");
  url.pathname = encodeWhitespace2(pathname.replace(/%/g, "%25"));
  if (hostname !== void 0 && hostname !== "localhost") {
    url.hostname = hostname;
    if (!url.hostname) throw new TypeError(`Invalid hostname: "${url.hostname}"`);
  }
  return url;
}
function toFileUrl2(path) {
  return isWindows2 ? toFileUrl$12(path) : toFileUrl$22(path);
}
function getFileInfoType2(fileInfo) {
  return fileInfo.isFile ? "file" : fileInfo.isDirectory ? "dir" : fileInfo.isSymlink ? "symlink" : void 0;
}
async function ensureDir2(dir) {
  try {
    throwIfNotDirectory2(await Deno.stat(dir));
    return;
  } catch (err) {
    if (!(err instanceof Deno.errors.NotFound)) throw err;
  }
  try {
    await Deno.mkdir(dir, { recursive: true });
  } catch (err) {
    if (!(err instanceof Deno.errors.AlreadyExists)) throw err;
    throwIfNotDirectory2(await Deno.stat(dir));
  }
}
function throwIfNotDirectory2(fileInfo) {
  if (!fileInfo.isDirectory) throw new Error(`Failed to ensure directory exists: expected 'dir', got '${getFileInfoType2(fileInfo)}'`);
}
function code2(open, close) {
  return {
    open: `\x1B[${open.join(";")}m`,
    close: `\x1B[${close}m`,
    regexp: new RegExp(`\\x1b\\[${close}m`, "g")
  };
}
function run4(str2, code3) {
  return enabled2 ? `${code3.open}${str2.replace(code3.regexp, code3.open)}${code3.close}` : str2;
}
function green2(str2) {
  return run4(str2, code2([32], 39));
}
function calcSizeHex2(originalSize) {
  return originalSize * 2;
}
function encode3(buffer2, i, o, alphabet3) {
  for (; i < buffer2.length; ++i) {
    const x3 = buffer2[i];
    buffer2[o++] = alphabet3[x3 >> 4];
    buffer2[o++] = alphabet3[x3 & 15];
  }
  return o;
}
function detach2(buffer2, maxSize) {
  const originalSize = buffer2.length;
  if (buffer2.byteOffset) {
    const b3 = new Uint8Array(buffer2.buffer);
    b3.set(buffer2);
    buffer2 = b3.subarray(0, originalSize);
  }
  buffer2 = new Uint8Array(buffer2.buffer.transfer(maxSize));
  buffer2.set(buffer2.subarray(0, originalSize), maxSize - originalSize);
  return [buffer2, maxSize - originalSize];
}
function encodeHex2(src) {
  if (typeof src === "string") src = new TextEncoder().encode(src);
  else if (src instanceof ArrayBuffer) src = new Uint8Array(src).slice();
  else src = src.slice();
  const [output, i] = detach2(src, calcSizeHex2(src.length));
  encode3(output, i, 0, alphabet2);
  return new TextDecoder().decode(output);
}
function baseUrlToFilename2(url) {
  const out = [];
  const protocol2 = url.protocol.replace(":", "");
  out.push(protocol2);
  switch (protocol2) {
    case "http":
    case "https": {
      const host = url.hostname;
      const hostPort = url.port;
      out.push(hostPort ? `${host}_PORT${hostPort}` : host);
      break;
    }
    case "file":
    case "data":
    case "blob":
      break;
    default:
      throw new TypeError(`Don't know how to create cache name for protocol: ${protocol2}`);
  }
  return join2(...out);
}
function stringToURL2(url) {
  return url.startsWith("file://") || url.startsWith("http://") || url.startsWith("https://") ? new URL(url) : toFileUrl2(resolve2(url));
}
async function hash$2(value2) {
  return encodeHex2(new Uint8Array(await crypto.subtle.digest("SHA-256", encoder$2.encode(value2))));
}
async function urlToFilename2(url) {
  return join2(baseUrlToFilename2(url), await hash$2(url.pathname + url.search));
}
async function isFile2(filePath) {
  try {
    return (await Deno.lstat(filePath)).isFile;
  } catch (err) {
    if (err instanceof Deno.errors.NotFound) return false;
    throw err;
  }
}
function homeDir2() {
  switch (Deno.build.os) {
    case "windows":
      return Deno.env.get("USERPROFILE");
    case "linux":
    case "darwin":
    case "freebsd":
    case "netbsd":
    case "aix":
    case "solaris":
    case "illumos":
    case "android":
      return Deno.env.get("HOME");
    default:
      throw Error("unreachable");
  }
}
function cacheDir2() {
  if (Deno.build.os === "darwin") {
    const home = homeDir2();
    if (home) return join2(home, "Library/Caches");
  } else if (Deno.build.os === "windows") return Deno.env.get("LOCALAPPDATA");
  else {
    const cacheHome = Deno.env.get("XDG_CACHE_HOME");
    if (cacheHome) return cacheHome;
    else {
      const home = homeDir2();
      if (home) return join2(home, ".cache");
    }
  }
}
function denoCacheDir2() {
  const dd = Deno.env.get("DENO_DIR");
  let root;
  if (dd) root = normalize2(isAbsolute2(dd) ? dd : join2(Deno.cwd(), dd));
  else {
    const cd = cacheDir2();
    if (cd) root = join2(cd, "deno");
    else {
      const hd = homeDir2();
      if (hd) root = join2(hd, ".deno");
    }
  }
  return root;
}
function getCrossOption2(record) {
  if (record === void 0) return;
  if (ALL_OSS2.some((os) => os in record)) {
    const subrecord = record[Deno.build.os];
    if (subrecord && typeof subrecord === "object" && ALL_ARCHS2.some((arch) => arch in subrecord)) return subrecord[Deno.build.arch];
    else return subrecord;
  }
  if (ALL_ARCHS2.some((arch) => arch in record)) {
    const subrecord = record[Deno.build.arch];
    if (subrecord && typeof subrecord === "object" && ALL_OSS2.some((os) => os in subrecord)) return subrecord[Deno.build.os];
    else return subrecord;
  }
}
function createDownloadURL2(options2) {
  if (typeof options2 === "string" || options2 instanceof URL) options2 = { url: options2 };
  options2.extensions ??= defaultExtensions2;
  options2.prefixes ??= defaultPrefixes2;
  for (const key2 in options2.extensions) {
    const os = key2;
    if (options2.extensions[os] !== void 0) options2.extensions[os] = options2.extensions[os].replace(/\.?(.+)/, "$1");
  }
  let url;
  if (options2.url instanceof URL) url = options2.url;
  else if (typeof options2.url === "string") url = stringToURL2(options2.url);
  else {
    const tmpUrl = getCrossOption2(options2.url);
    if (tmpUrl === void 0) throw new TypeError(`An URL for the "${Deno.build.os}-${Deno.build.arch}" target was not provided.`);
    if (typeof tmpUrl === "string") url = stringToURL2(tmpUrl);
    else url = tmpUrl;
  }
  if ("name" in options2 && !Object.values(options2.extensions).includes(extname2(url.pathname))) {
    if (!url.pathname.endsWith("/")) url.pathname = `${url.pathname}/`;
    const prefix = getCrossOption2(options2.prefixes) ?? "";
    const suffix = getCrossOption2(options2.suffixes) ?? "";
    const extension = options2.extensions[Deno.build.os];
    if (options2.name === void 0) throw new TypeError(`Expected the "name" property for an automatically assembled URL.`);
    const filename = `${prefix}${options2.name}${suffix}.${extension}`;
    url = new URL(filename, url);
  }
  return url;
}
async function ensureCacheLocation2(location = "deno") {
  if (location === "deno") {
    const dir = denoCacheDir2();
    if (dir === void 0) throw new Error("Could not get the deno cache directory, try using another CacheLocation in the plug options.");
    location = join2(dir, "plug");
  } else if (location === "cache") {
    const dir = cacheDir2();
    if (dir === void 0) throw new Error("Could not get the cache directory, try using another CacheLocation in the plug options.");
    location = join2(dir, "plug");
  } else if (location === "cwd") location = join2(Deno.cwd(), "plug");
  else if (location === "tmp") location = await Deno.makeTempDir({ prefix: "plug" });
  else if (typeof location === "string" && location.startsWith("file://")) location = fromFileUrl2(location);
  else if (location instanceof URL) {
    if (location?.protocol !== "file:") throw new TypeError("Cannot use any other protocol than file:// for an URL cache location.");
    location = fromFileUrl2(location);
  }
  location = resolve2(normalize2(location));
  await ensureDir2(location);
  return location;
}
async function download2(options2) {
  const location = (typeof options2 === "object" && "location" in options2 ? options2.location : void 0) ?? "deno";
  const setting = (typeof options2 === "object" && "cache" in options2 ? options2.cache : void 0) ?? "use";
  const url = createDownloadURL2(options2);
  const cacheBasePath = join2(await ensureCacheLocation2(location), await urlToFilename2(url));
  const cacheFilePath = `${cacheBasePath}${extname2(url.pathname)}`;
  const cacheMetaPath = `${cacheBasePath}.metadata.json`;
  const cached2 = setting === "use" ? await isFile2(cacheFilePath) : setting === "only" || setting !== "reloadAll";
  await ensureDir2(dirname2(cacheBasePath));
  if (!cached2) {
    const meta = { url };
    switch (url.protocol) {
      case "http:":
      case "https:": {
        console.log(`${green2("Downloading")} ${url}`);
        const response = await fetch(url.toString());
        if (!response.ok) if (response.status === 404) throw new Error(`Could not find ${url}`);
        else throw new Deno.errors.Http(`${response.status} ${response.statusText}`);
        await Deno.writeFile(cacheFilePath, new Uint8Array(await response.arrayBuffer()));
        break;
      }
      case "file:":
        console.log(`${green2("Copying")} ${url}`);
        await Deno.copyFile(fromFileUrl2(url), cacheFilePath);
        if (Deno.build.os !== "windows") await Deno.chmod(cacheFilePath, 420);
        break;
      default:
        throw new TypeError(`Cannot fetch to cache using the "${url.protocol}" protocol`);
    }
    await Deno.writeTextFile(cacheMetaPath, JSON.stringify(meta));
  }
  if (!await isFile2(cacheFilePath)) throw new Error(`Could not find "${url}" in cache.`);
  return cacheFilePath;
}
async function dlopen2(options2, symbols3) {
  if (Deno.dlopen === void 0) throw new Error("`--unstable-ffi` is required");
  return Deno.dlopen(await download2(options2), symbols3);
}
function getLocalUrl() {
  let uri = new URL("../target/release", import.meta.url).pathname;
  if (!uri.endsWith("/")) uri += "/";
  if (Deno.build.os === "windows") {
    uri = uri.replace(/\//g, "\\");
    if (uri.startsWith("\\")) uri = uri.slice(1);
  }
  return uri;
}
function archShort() {
  switch (Deno.build.arch) {
    case "aarch64":
      return "ARM64";
    case "x86_64":
      return "X64";
  }
}
function hash$1(password, cost) {
  const pwd = encoder$12.encode(password);
  return symbols2.hash(pwd.buffer, BigInt(pwd.byteLength), cost).then((v3) => {
    const lenBuf = /* @__PURE__ */ new Uint8Array(4);
    const lenView = new DataView(lenBuf.buffer);
    const ptr = new Deno.UnsafePointerView(v3);
    ptr.copyInto(lenBuf, 0);
    const out = new Uint8Array(lenView.getUint32(0));
    ptr.copyInto(out, 4);
    symbols2.free_hash(v3);
    return decoder2.decode(out);
  });
}
function verify$1(password, hash4) {
  const pwd = encoder$12.encode(password);
  const h = encoder$12.encode(hash4);
  return symbols2.verify(pwd.buffer, BigInt(pwd.byteLength), h.buffer, BigInt(h.byteLength));
}
async function hash2(password, cost = 12) {
  return await hash$1(password, cost);
}
async function verify(password, hash4) {
  return await verify$1(password, hash4) === 1;
}
async function timingSafeStringEquals(left, right) {
  const [leftHash, rightHash] = await Promise.all([crypto.subtle.digest("SHA-256", encoder2.encode(left)), crypto.subtle.digest("SHA-256", encoder2.encode(right))]);
  const leftBytes = new Uint8Array(leftHash);
  const rightBytes = new Uint8Array(rightHash);
  let diff = 0;
  for (let i = 0; i < leftBytes.length; i++) diff |= leftBytes[i] ^ rightBytes[i];
  return diff === 0;
}
async function verifyApiKey(candidate, activeKey) {
  if (activeKey.key === null) return false;
  switch (activeKey.source) {
    case ApiKeySource.Environment:
      return timingSafeStringEquals(candidate, activeKey.key);
    case ApiKeySource.Generated:
      return verify(candidate, activeKey.key);
  }
}
var isWindows2, WHITESPACE_ENCODINGS2, Deno$12, enabled2, alphabet$12, rAlphabet$12, alphabet2, rAlphabet2, encoder$2, ALL_ARCHS2, ALL_OSS2, defaultExtensions2, defaultPrefixes2, VERSION2, encoder$12, decoder2, LOCAL, symbols2, ApiKeySource, encoder2, authSettingsQueries;
var init_authSettings = __esm({
  async "dist/build/server/chunks/authSettings.js"() {
    "use strict";
    await init_db();
    init_config();
    isWindows2 = checkWindows2();
    WHITESPACE_ENCODINGS2 = {
      "	": "%09",
      "\n": "%0A",
      "\v": "%0B",
      "\f": "%0C",
      "\r": "%0D",
      " ": "%20"
    };
    globalThis.Deno?.build.os;
    globalThis.Deno?.build.os;
    ({ Deno: Deno$12 } = globalThis);
    enabled2 = !(typeof Deno$12?.noColor === "boolean" ? Deno$12.noColor : false);
    new RegExp(["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TXZcf-nq-uy=><~]))"].join("|"), "g");
    alphabet$12 = new TextEncoder().encode("0123456789abcdef");
    rAlphabet$12 = (/* @__PURE__ */ new Uint8Array(128)).fill(16);
    alphabet$12.forEach((byte, i) => rAlphabet$12[byte] = i);
    new TextEncoder().encode("ABCDEF").forEach((byte, i) => rAlphabet$12[byte] = i + 10);
    alphabet2 = new TextEncoder().encode("0123456789abcdef");
    rAlphabet2 = (/* @__PURE__ */ new Uint8Array(128)).fill(16);
    alphabet2.forEach((byte, i) => rAlphabet2[byte] = i);
    new TextEncoder().encode("ABCDEF").forEach((byte, i) => rAlphabet2[byte] = i + 10);
    encoder$2 = new TextEncoder();
    ALL_ARCHS2 = ["x86_64", "aarch64"];
    ALL_OSS2 = [
      "darwin",
      "linux",
      "android",
      "windows",
      "freebsd",
      "netbsd",
      "aix",
      "solaris",
      "illumos"
    ];
    defaultExtensions2 = {
      darwin: "dylib",
      linux: "so",
      windows: "dll",
      freebsd: "so",
      netbsd: "so",
      aix: "so",
      solaris: "so",
      illumos: "so",
      android: "so"
    };
    defaultPrefixes2 = {
      darwin: "lib",
      linux: "lib",
      netbsd: "lib",
      freebsd: "lib",
      aix: "lib",
      solaris: "lib",
      illumos: "lib",
      windows: "",
      android: "lib"
    };
    VERSION2 = "2.1.0";
    encoder$12 = new TextEncoder();
    decoder2 = new TextDecoder();
    LOCAL = Deno.env.get("LOCAL");
    ({ symbols: symbols2 } = await dlopen2({
      name: LOCAL ? "deno_bcrypt" : "deno_bcrypt-" + archShort(),
      url: LOCAL ? getLocalUrl() : `https://github.com/felix-schindler/deno-bcrypt/releases/download/v${VERSION2}/`,
      cache: LOCAL ? "reloadAll" : "use"
    }, {
      hash: {
        parameters: [
          "buffer",
          "usize",
          "u32"
        ],
        result: "buffer",
        nonblocking: true
      },
      verify: {
        parameters: [
          "buffer",
          "usize",
          "buffer",
          "usize"
        ],
        result: "i8",
        nonblocking: true
      },
      free_hash: {
        parameters: ["pointer"],
        result: "void"
      }
    }));
    ApiKeySource = /* @__PURE__ */ (function(ApiKeySource2) {
      ApiKeySource2["Environment"] = "environment";
      ApiKeySource2["Generated"] = "generated";
      return ApiKeySource2;
    })({});
    encoder2 = new TextEncoder();
    authSettingsQueries = {
      /**
      * Get auth settings (singleton)
      */
      get() {
        const settings2 = db.queryFirst("SELECT * FROM auth_settings WHERE id = 1");
        if (!settings2) throw new Error("Auth settings not found - database may not be initialized");
        return settings2;
      },
      /**
      * Get session duration in hours
      */
      getSessionDurationHours() {
        return this.get().session_duration_hours;
      },
      /**
      * Check whether an API key is configured
      */
      hasApiKey() {
        return config.profilarrApiKey !== null || this.get().api_key !== null;
      },
      /**
      * Check whether users can regenerate the API key from the UI
      */
      canRegenerateApiKey() {
        return config.profilarrApiKey === null;
      },
      /**
      * Get the active API key and where it comes from.
      */
      getApiKey() {
        if (config.profilarrApiKey !== null) return {
          source: ApiKeySource.Environment,
          key: config.profilarrApiKey
        };
        return {
          source: ApiKeySource.Generated,
          key: this.get().api_key
        };
      },
      /**
      * Check if local bypass is enabled (skip auth for local IPs)
      */
      isLocalBypassEnabled() {
        return this.get().local_bypass_enabled === 1;
      },
      /**
      * Set local bypass toggle
      */
      setLocalBypass(enabled3) {
        return db.execute("UPDATE auth_settings SET local_bypass_enabled = ?, updated_at = CURRENT_TIMESTAMP WHERE id = 1", enabled3 ? 1 : 0) > 0;
      },
      /**
      * Update auth settings
      */
      update(input) {
        const updates = [];
        const params = [];
        if (input.sessionDurationHours !== void 0) {
          updates.push("session_duration_hours = ?");
          params.push(input.sessionDurationHours);
        }
        if (input.apiKey !== void 0) {
          updates.push("api_key = ?");
          params.push(input.apiKey);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(1);
        return db.execute(`UPDATE auth_settings SET ${updates.join(", ")} WHERE id = ?`, ...params) > 0;
      },
      /**
      * Regenerate API key — returns the plaintext key (stored as bcrypt hash)
      */
      async regenerateApiKey() {
        if (!this.canRegenerateApiKey()) throw new Error("PROFILARR_API_KEY is set; API key regeneration is disabled");
        const plaintext = generateApiKey();
        const hashed = await hash2(plaintext);
        this.update({ apiKey: hashed });
        return plaintext;
      },
      /**
      * Clear API key (disable API access)
      */
      clearApiKey() {
        return this.update({ apiKey: null });
      },
      /**
      * Validate an API key against the active source.
      */
      async validateApiKey(key2) {
        return verifyApiKey(key2, this.getApiKey());
      }
    };
  }
});

// dist/build/server/chunks/network.js
function isLocalAddress(ip) {
  if (ip.startsWith("::ffff:")) ip = ip.slice(7);
  if (ip.includes(".")) return isLocalIPv4(ip);
  return isLocalIPv6(ip);
}
function isLocalIPv4(ip) {
  const parts = ip.split(".");
  if (parts.length !== 4) return false;
  const bytes = parts.map((p2) => parseInt(p2, 10));
  if (bytes.some((b4) => isNaN(b4) || b4 < 0 || b4 > 255)) return false;
  const [a2, b3] = bytes;
  if (a2 === 127) return true;
  if (a2 === 10) return true;
  if (a2 === 172 && b3 >= 16 && b3 <= 31) return true;
  if (a2 === 192 && b3 === 168) return true;
  if (a2 === 169 && b3 === 254) return true;
  return false;
}
function isLocalIPv6(ip) {
  const lower = ip.toLowerCase();
  if (lower === "::1") return true;
  if (lower.startsWith("fe80:")) return true;
  if (lower.startsWith("fc") || lower.startsWith("fd")) return true;
  if (lower.startsWith("fec")) return true;
  return false;
}
function getClientIp(event, trustProxy = true) {
  if (trustProxy) {
    const headers2 = event.request.headers;
    for (const header of IP_HEADERS) {
      const value2 = headers2.get(header);
      if (value2) {
        const ip = value2.split(",")[0].trim();
        if (ip) return ip;
      }
    }
  }
  try {
    const address = event.getClientAddress();
    if (address && address !== "unknown") return address;
  } catch {
  }
  return trustProxy ? "127.0.0.1" : "0.0.0.0";
}
var IP_HEADERS;
var init_network = __esm({
  "dist/build/server/chunks/network.js"() {
    "use strict";
    IP_HEADERS = [
      "x-forwarded-for",
      "x-real-ip",
      "x-client-ip",
      "cf-connecting-ip",
      "fastly-client-ip",
      "true-client-ip",
      "x-cluster-client-ip"
    ];
  }
});

// dist/build/server/chunks/rateLimit.js
function checkRateLimit(ip, endpoint) {
  for (const [category, threshold] of Object.entries(THRESHOLDS)) if (loginAttemptsQueries.countRecentByCategory(ip, endpoint, category, WINDOW_MINUTES) >= threshold) return {
    blocked: true,
    retryAfter: 900
  };
  return { blocked: false };
}
function recordFailedAttempt(ip, endpoint, category) {
  loginAttemptsQueries.recordFailure(ip, endpoint, category);
}
function clearAttempts(ip) {
  loginAttemptsQueries.clearForIp(ip);
}
function cleanupExpiredAttempts() {
  return loginAttemptsQueries.deleteExpired(WINDOW_MINUTES);
}
var loginAttemptsQueries, WINDOW_MINUTES, THRESHOLDS;
var init_rateLimit = __esm({
  async "dist/build/server/chunks/rateLimit.js"() {
    "use strict";
    await init_db();
    loginAttemptsQueries = {
      /**
      * Record a failed login attempt
      */
      recordFailure(ip, endpoint, category) {
        db.execute(`INSERT INTO login_attempts (ip, endpoint, category) VALUES (?, ?, ?)`, ip, endpoint, category);
      },
      /**
      * Count recent failures for an IP + endpoint within a time window
      */
      countRecent(ip, endpoint, windowMinutes) {
        return db.queryFirst(`SELECT COUNT(*) as count FROM login_attempts
			 WHERE ip = ? AND endpoint = ? AND datetime(failed_at) > datetime('now', ?)`, ip, endpoint, `-${windowMinutes} minutes`)?.count ?? 0;
      },
      /**
      * Count recent failures for an IP + endpoint filtered by category
      */
      countRecentByCategory(ip, endpoint, category, windowMinutes) {
        return db.queryFirst(`SELECT COUNT(*) as count FROM login_attempts
			 WHERE ip = ? AND endpoint = ? AND category = ? AND datetime(failed_at) > datetime('now', ?)`, ip, endpoint, category, `-${windowMinutes} minutes`)?.count ?? 0;
      },
      /**
      * Clear all attempts for an IP (call on successful login)
      */
      clearForIp(ip) {
        return db.execute(`DELETE FROM login_attempts WHERE ip = ?`, ip);
      },
      /**
      * Delete old attempts outside the window (cleanup)
      */
      deleteExpired(windowMinutes) {
        return db.execute(`DELETE FROM login_attempts WHERE datetime(failed_at) <= datetime('now', ?)`, `-${windowMinutes} minutes`);
      }
    };
    WINDOW_MINUTES = 15;
    THRESHOLDS = {
      suspicious: 3,
      typo: 10,
      unknown: 10
    };
  }
});

// dist/build/server/chunks/spawn.js
var spawn_exports = {};
function isDocker() {
  try {
    Deno.statSync("/.dockerenv");
    return true;
  } catch {
    try {
      return Deno.readTextFileSync("/proc/1/cgroup").includes("docker");
    } catch {
      return false;
    }
  }
}
function findParserBinary() {
  const execPath = Deno.execPath();
  const lastSlash = Math.max(execPath.lastIndexOf("/"), execPath.lastIndexOf("\\"));
  const dir = lastSlash > 0 ? execPath.substring(0, lastSlash) : ".";
  const candidates = [`${dir}/profilarr-parser`, `${dir}/profilarr-parser.exe`];
  for (const path of candidates) try {
    Deno.statSync(path);
    return path;
  } catch {
    continue;
  }
  return null;
}
async function findFreePort() {
  const listener = Deno.listen({ port: 0 });
  const port = listener.addr.port;
  listener.close();
  return port;
}
async function waitForHealth(port, timeoutMs) {
  const start = Date.now();
  while (Date.now() - start < timeoutMs) {
    try {
      if ((await fetch(`http://localhost:${port}/health`, { signal: AbortSignal.timeout(2e3) })).ok) return;
    } catch {
    }
    await new Promise((r2) => setTimeout(r2, 250));
  }
  throw new Error(`Parser failed to start within ${timeoutMs}ms`);
}
async function streamOutput(reader) {
  const decoder4 = new TextDecoder();
  const color = "\x1B[33m";
  const reset2 = "\x1B[0m";
  try {
    while (true) {
      const { done, value: value2 } = await reader.read();
      if (done) break;
      const text2 = decoder4.decode(value2);
      for (const line of text2.split("\n")) if (line.trim()) console.log(`${color}[parser]${reset2} ${line}`);
    }
  } catch {
  }
}
var init_spawn = __esm({
  async "dist/build/server/chunks/spawn.js"() {
    "use strict";
    if (!isDocker() && !Deno.env.get("PARSER_HOST") && findParserBinary() !== null) {
      const binaryPath = findParserBinary();
      const port = await findFreePort();
      const process2 = new Deno.Command(binaryPath, {
        env: {
          ASPNETCORE_URLS: `http://localhost:${port}`,
          ASPNETCORE_ENVIRONMENT: "Production"
        },
        stdout: "piped",
        stderr: "piped"
      }).spawn();
      streamOutput(process2.stdout.getReader());
      streamOutput(process2.stderr.getReader());
      Deno.env.set("PARSER_HOST", "localhost");
      Deno.env.set("PARSER_PORT", String(port));
      try {
        await waitForHealth(port, 1e4);
        console.log(`\x1B[33m[parser]\x1B[0m Ready on port ${port}`);
      } catch (err) {
        console.error(`\x1B[31m[parser]\x1B[0m Failed to start: ${err}`);
      }
      const cleanup2 = () => {
        try {
          process2.kill("SIGTERM");
        } catch {
        }
      };
      Deno.addSignalListener("SIGINT", () => {
        cleanup2();
        Deno.exit(0);
      });
      if (Deno.build.os !== "windows") Deno.addSignalListener("SIGTERM", () => {
        cleanup2();
        Deno.exit(0);
      });
      process2.status.then((status) => {
        if (status.code !== 0) console.error(`\x1B[31m[parser]\x1B[0m Process exited unexpectedly (code ${status.code})`);
      });
    }
  }
});

// dist/build/server/entries/hooks.server.js
var hooks_server_exports = {};
__export(hooks_server_exports, {
  handle: () => handle
});
function isDocker2() {
  try {
    Deno.statSync("/.dockerenv");
    return true;
  } catch {
    try {
      return Deno.readTextFileSync("/proc/1/cgroup").includes("docker");
    } catch {
      return false;
    }
  }
}
async function logContainerConfig() {
  if (!isDocker2()) return;
  await logger.info("Container initialized", {
    source: "Docker",
    meta: {
      puid: Deno.env.get("PUID") || "1000",
      pgid: Deno.env.get("PGID") || "1000",
      umask: Deno.env.get("UMASK") || "022",
      tz: Deno.env.get("TZ") || "UTC"
    }
  });
}
function printBanner() {
  const version = build.version;
  const url = config.serverUrl;
  console.log(BANNER);
  console.log(`  v${version}  |  ${url}`);
  console.log();
}
function getServerInfo() {
  return {
    version: build.version,
    env: Deno.env.get("DENO_ENV") || "production",
    timezone: config.timezone,
    basePath: config.paths.base,
    hostname: typeof Deno !== "undefined" ? Deno.hostname() : "unknown"
  };
}
async function removeIfExists(path, opts) {
  try {
    await Deno.remove(path, opts);
  } catch (err) {
    if (!(err instanceof Deno.errors.NotFound)) throw err;
  }
}
async function readArchiveInfo(stagingDataDir) {
  try {
    const raw = await Deno.readTextFile(`${stagingDataDir}/INFO.json`);
    return JSON.parse(raw);
  } catch {
    return {};
  }
}
function rewriteDatabaseLocalPaths(stagedDbPath) {
  const database = new Database(stagedDbPath);
  try {
    if (!database.prepare(`SELECT COUNT(*) AS count
				 FROM sqlite_master
				 WHERE type = 'table' AND name = 'database_instances'`).get()?.count) return 0;
    database.prepare(`UPDATE database_instances
				 SET local_path = ? || '/' || uuid
				 WHERE local_path != ? || '/' || uuid`).run(config.paths.databases, config.paths.databases);
    return database.changes;
  } finally {
    database.close();
  }
}
async function applyPendingRestore() {
  const sentinelPath = `${config.paths.base}/${SENTINEL_NAME}`;
  const stagingPath = `${config.paths.base}/${STAGING_NAME}`;
  const dataDir = config.paths.data;
  let archivePath;
  try {
    archivePath = (await Deno.readTextFile(sentinelPath)).trim();
  } catch (err) {
    if (err instanceof Deno.errors.NotFound) return;
    throw err;
  }
  try {
    await Deno.stat(archivePath);
  } catch {
    await logger.error("Pending restore archive missing; aborting and clearing sentinel", {
      source: "applyPendingRestore",
      meta: { archivePath }
    });
    await removeIfExists(sentinelPath);
    return;
  }
  await removeIfExists(stagingPath, { recursive: true });
  await Deno.mkdir(stagingPath, { recursive: true });
  const tarResult = await new Deno.Command("tar", {
    args: [
      "-xzf",
      archivePath,
      "-C",
      stagingPath
    ],
    stdout: "piped",
    stderr: "piped"
  }).output();
  if (tarResult.code !== 0) {
    const stderr = new TextDecoder().decode(tarResult.stderr).trim();
    await logger.error("Pending restore extraction failed; live data left untouched", {
      source: "applyPendingRestore",
      meta: {
        archivePath,
        stderr,
        exitCode: tarResult.code
      }
    });
    await removeIfExists(stagingPath, { recursive: true });
    throw new Error(`Restore extraction failed (exit ${tarResult.code}): ${stderr}`);
  }
  const stagingDataDir = `${stagingPath}/data`;
  try {
    if (!(await Deno.stat(`${stagingDataDir}/profilarr.db`)).isFile) throw new Error("profilarr.db is not a file");
  } catch (err) {
    const message2 = err instanceof Error ? err.message : String(err);
    await logger.error("Staged archive missing profilarr.db; aborting", {
      source: "applyPendingRestore",
      meta: {
        archivePath,
        error: message2
      }
    });
    await removeIfExists(stagingPath, { recursive: true });
    throw new Error(`Restore archive does not contain data/profilarr.db: ${message2}`);
  }
  const info = await readArchiveInfo(stagingDataDir);
  const rewrittenDatabasePaths = rewriteDatabaseLocalPaths(`${stagingDataDir}/profilarr.db`);
  await removeIfExists(`${dataDir}/profilarr.db`);
  await removeIfExists(`${dataDir}/profilarr.db-wal`);
  await removeIfExists(`${dataDir}/profilarr.db-shm`);
  await removeIfExists(`${dataDir}/databases`, { recursive: true });
  await removeIfExists(`${dataDir}/INFO.json`);
  for await (const entry of Deno.readDir(stagingDataDir)) {
    const src = `${stagingDataDir}/${entry.name}`;
    const dst = `${dataDir}/${entry.name}`;
    await removeIfExists(dst, { recursive: true });
    await Deno.rename(src, dst);
  }
  await removeIfExists(stagingPath, { recursive: true });
  await Deno.remove(sentinelPath);
  await logger.info("Pending restore applied", {
    source: "applyPendingRestore",
    meta: {
      archivePath,
      info,
      rewrittenDatabasePaths
    }
  });
}
function isPublicPath(pathname) {
  if (PUBLIC_EXACT_PATHS.includes(pathname)) return true;
  return PUBLIC_PREFIX_PATHS.some((p2) => pathname === p2 || pathname.startsWith(p2 + "/"));
}
async function getAuthState(event) {
  const hasLocalUsers = usersQueries.existsLocal();
  if (config.authMode === "off") return {
    needsSetup: false,
    user: null,
    session: null,
    skipAuth: true
  };
  const apiKey = event.request.headers.get("X-Api-Key");
  if (apiKey) {
    const ip = getClientIp(event, false);
    const endpoint = event.url.pathname;
    if (await authSettingsQueries.validateApiKey(apiKey)) {
      logger.debug("API key authenticated", {
        source: "Auth:APIKey",
        meta: {
          ip,
          endpoint
        }
      });
      return {
        needsSetup: false,
        user: {
          id: 0,
          username: "api"
        },
        session: null,
        skipAuth: false
      };
    } else {
      const maskedKey = apiKey.length > 4 ? `****${apiKey.slice(-4)}` : "****";
      logger.warn("Invalid API key", {
        source: "Auth:APIKey",
        meta: {
          ip,
          endpoint,
          key: maskedKey
        }
      });
    }
  }
  if (authSettingsQueries.isLocalBypassEnabled()) {
    const clientIp = getClientIp(event, false);
    if (isLocalAddress(clientIp)) return {
      needsSetup: !hasLocalUsers,
      user: null,
      session: null,
      skipAuth: true
    };
  }
  if (config.authMode === "oidc") {
    const sessionId2 = event.cookies.get("session");
    const session2 = sessionId2 ? sessionsQueries.getValidById(sessionId2) ?? null : null;
    return {
      needsSetup: false,
      user: session2 ? usersQueries.getById(session2.user_id) ?? null : null,
      session: session2,
      skipAuth: false
    };
  }
  const sessionId = event.cookies.get("session");
  const session = sessionId ? sessionsQueries.getValidById(sessionId) ?? null : null;
  const user = session ? usersQueries.getById(session.user_id) ?? null : null;
  return {
    needsSetup: !hasLocalUsers,
    user,
    session,
    skipAuth: false
  };
}
function maybeExtendSession(session) {
  const durationHours = authSettingsQueries.getSessionDurationHours();
  const expiresAt = new Date(session.expires_at).getTime();
  const now = Date.now();
  const halfDuration = durationHours * 60 * 60 * 1e3 / 2;
  if (expiresAt - now < halfDuration) {
    sessionsQueries.extendExpiration(session.id, durationHours);
    logger.debug("Session extended", {
      source: "Auth:Session",
      meta: { userId: session.user_id }
    });
  }
}
function cleanupExpiredSessions() {
  return sessionsQueries.deleteExpired();
}
var BANNER, SENTINEL_NAME, STAGING_NAME, PUBLIC_PREFIX_PATHS, PUBLIC_EXACT_PATHS, setupStateQueries, isReload, handle;
var init_hooks_server = __esm({
  async "dist/build/server/entries/hooks.server.js"() {
    "use strict";
    await init_db();
    init_config();
    init_build();
    await init_queueService();
    await init_migrations();
    await init_init();
    await init_users();
    await init_authSettings();
    init_network();
    await init_rateLimit();
    init_exports();
    BANNER = String.raw`
                     _____.__.__
_____________  _____/ ____\__|  | _____ ______________
\____ \_  __ \/  _ \   __\|  |  | \__  \\_  __ \_  __ \
|  |_> >  | \(  <_> )  |  |  |  |__/ __ \|  | \/|  | \/
|   __/|__|   \____/|__|  |__|____(____  /__|   |__|
|__|                                   \/
`;
    SENTINEL_NAME = ".restore-pending";
    STAGING_NAME = ".restoring";
    PUBLIC_PREFIX_PATHS = [
      "/auth/login",
      "/auth/setup",
      "/auth/oidc"
    ];
    PUBLIC_EXACT_PATHS = ["/api/v1/health"];
    setupStateQueries = {
      /**
      * Get setup state (singleton)
      */
      get() {
        const state2 = db.queryFirst("SELECT * FROM setup_state WHERE id = 1");
        if (!state2) throw new Error("Setup state not found - database may not be initialized");
        return state2;
      },
      /**
      * Check if default database has been linked
      */
      isDefaultDatabaseLinked() {
        return this.get().default_database_linked === 1;
      },
      /**
      * Mark default database as linked
      */
      markDefaultDatabaseLinked() {
        return db.execute("UPDATE setup_state SET default_database_linked = 1, updated_at = CURRENT_TIMESTAMP WHERE id = 1") > 0;
      }
    };
    isReload = globalThis.__profilarr_initialized__ === true;
    globalThis.__profilarr_initialized__ = true;
    if (!isReload) await init_spawn().then(() => spawn_exports);
    if (!isReload) {
      await config.init();
      await applyPendingRestore();
      await db.initialize();
      await runMigrations();
      logSettings.load();
      await logContainerConfig();
      await pcdManager.initialize();
      if (!setupStateQueries.isDefaultDatabaseLinked() && !Deno.env.get("INTEGRATION_TEST")) try {
        await pcdManager.link({
          name: "Dictionarry",
          repositoryUrl: "https://github.com/Dictionarry-Hub/database",
          branch: "v2",
          syncStrategy: 60,
          autoPull: true,
          personalAccessToken: void 0
        });
        setupStateQueries.markDefaultDatabaseLinked();
        await logger.info("Default database auto-linked", {
          source: "Setup",
          meta: { database: "Dictionarry" }
        });
      } catch (error2) {
        setupStateQueries.markDefaultDatabaseLinked();
        await logger.warn("Failed to auto-link default database", {
          source: "Setup",
          meta: { error: String(error2) }
        });
      }
      await initializeJobs();
      await recoverInterruptedSyncs();
      cleanupExpiredAttempts();
      const expiredCount = cleanupExpiredSessions();
      if (expiredCount > 0) await logger.info(`Cleaned up ${expiredCount} expired session${expiredCount === 1 ? "" : "s"}`, {
        source: "Auth:Session",
        meta: { count: expiredCount }
      });
      await logger.info("Server ready", {
        source: "Startup",
        meta: getServerInfo()
      });
      printBanner();
    }
    handle = async ({ event, resolve: resolve6 }) => {
      async function resolveAndStrip() {
        const response = await resolve6(event);
        response.headers.delete("link");
        return response;
      }
      const auth = await getAuthState(event);
      if (auth.needsSetup) {
        if (event.url.pathname === "/auth/setup") return resolveAndStrip();
        throw redirect(303, "/auth/setup");
      }
      if (auth.skipAuth) return resolveAndStrip();
      if (event.url.pathname === "/auth/setup") throw redirect(303, "/");
      if (isPublicPath(event.url.pathname)) return resolveAndStrip();
      if (auth.user && !auth.session && auth.user.username === "api") {
        if (!event.url.pathname.startsWith("/api/")) return new Response(JSON.stringify({ error: "API key auth is not accepted for this path" }), {
          status: 403,
          headers: { "Content-Type": "application/json" }
        });
      }
      if (!auth.user) {
        if (event.url.pathname.startsWith("/api")) return new Response(JSON.stringify({ error: "Unauthorized" }), {
          status: 401,
          headers: { "Content-Type": "application/json" }
        });
        throw redirect(303, "/auth/login");
      }
      if (auth.session) maybeExtendSession(auth.session);
      event.locals.user = auth.user;
      event.locals.session = auth.session;
      return resolveAndStrip();
    };
  }
});

// dist/build/server/chunks/internal2.js
function set_private_env(environment) {
}
function set_public_env(environment) {
  public_env = environment;
}
function set_read_implementation(fn) {
  read_implementation = fn;
}
function set_manifest(_3) {
}
function handle_event_propagation(event) {
  var handler_element = this;
  var owner_document = handler_element.ownerDocument;
  var event_name = event.type;
  var path = event.composedPath?.() || [];
  var current_target = path[0] || event.target;
  last_propagated_event = event;
  var path_idx = 0;
  var handled_at = last_propagated_event === event && event[event_symbol];
  if (handled_at) {
    var at_idx = path.indexOf(handled_at);
    if (at_idx !== -1 && (handler_element === document || handler_element === window)) {
      event[event_symbol] = handler_element;
      return;
    }
    var handler_idx = path.indexOf(handler_element);
    if (handler_idx === -1) return;
    if (at_idx <= handler_idx) path_idx = at_idx;
  }
  current_target = path[path_idx] || event.target;
  if (current_target === handler_element) return;
  define_property(event, "currentTarget", {
    configurable: true,
    get() {
      return current_target || owner_document;
    }
  });
  var previous_reaction = active_reaction;
  var previous_effect = active_effect;
  set_active_reaction(null);
  set_active_effect(null);
  try {
    var throw_error;
    var other_errors = [];
    while (current_target !== null) {
      if (current_target === handler_element) break;
      try {
        var delegated = current_target[event_symbol]?.[event_name];
        if (delegated != null && (!current_target.disabled || event.target === current_target)) delegated.call(current_target, event);
      } catch (error2) {
        if (throw_error) other_errors.push(error2);
        else throw_error = error2;
      }
      if (event.cancelBubble) break;
      path_idx++;
      current_target = path_idx < path.length ? path[path_idx] : null;
    }
    if (throw_error) {
      for (let error2 of other_errors) queueMicrotask(() => {
        throw error2;
      });
      throw throw_error;
    }
  } finally {
    event[event_symbol] = handler_element;
    delete event.currentTarget;
    set_active_reaction(previous_reaction);
    set_active_effect(previous_effect);
  }
}
function assign_nodes(start, end) {
  var effect = active_effect;
  if (effect.nodes === null) effect.nodes = {
    start,
    end,
    a: null,
    t: null
  };
}
function mount2(component84, options2) {
  return _mount(component84, options2);
}
function hydrate2(component84, options2) {
  init_operations();
  options2.intro = options2.intro ?? false;
  const target = options2.target;
  const was_hydrating = hydrating;
  const previous_hydrate_node = hydrate_node;
  try {
    var anchor = /* @__PURE__ */ get_first_child(target);
    while (anchor && (anchor.nodeType !== 8 || anchor.data !== "[")) anchor = /* @__PURE__ */ get_next_sibling(anchor);
    if (!anchor) throw HYDRATION_ERROR;
    set_hydrating(true);
    set_hydrate_node(anchor);
    const instance = _mount(component84, {
      ...options2,
      anchor
    });
    set_hydrating(false);
    return instance;
  } catch (error2) {
    if (error2 instanceof Error && error2.message.split("\n").some((line) => line.startsWith("https://svelte.dev/e/"))) throw error2;
    if (error2 !== HYDRATION_ERROR) console.warn("Failed to hydrate: ", error2);
    if (options2.recover === false) hydration_failed();
    init_operations();
    clear_text_content(target);
    set_hydrating(false);
    return mount2(component84, options2);
  } finally {
    set_hydrating(was_hydrating);
    set_hydrate_node(previous_hydrate_node);
  }
}
function _mount(Component, { target, anchor, props = {}, events, context: context2, intro = true, transformError }) {
  init_operations();
  var component84 = void 0;
  var unmount3 = component_root(() => {
    var anchor_node = anchor ?? target.appendChild(create_text());
    boundary(anchor_node, { pending: () => {
    } }, (anchor_node2) => {
      push$1({});
      var ctx = component_context;
      if (context2) ctx.c = context2;
      if (events)
        props.$$events = events;
      if (hydrating) assign_nodes(anchor_node2, null);
      component84 = Component(anchor_node2, props) || {};
      if (hydrating) {
        active_effect.nodes.end = hydrate_node;
        if (hydrate_node === null || hydrate_node.nodeType !== 8 || hydrate_node.data !== "]") {
          hydration_mismatch();
          throw HYDRATION_ERROR;
        }
      }
      pop$1();
    }, transformError);
    var registered_events = /* @__PURE__ */ new Set();
    var event_handle = (events2) => {
      for (var i = 0; i < events2.length; i++) {
        var event_name = events2[i];
        if (registered_events.has(event_name)) continue;
        registered_events.add(event_name);
        var passive = is_passive_event(event_name);
        for (const node of [target, document]) {
          var counts = listeners.get(node);
          if (counts === void 0) {
            counts = /* @__PURE__ */ new Map();
            listeners.set(node, counts);
          }
          var count = counts.get(event_name);
          if (count === void 0) {
            node.addEventListener(event_name, handle_event_propagation, { passive });
            counts.set(event_name, 1);
          } else counts.set(event_name, count + 1);
        }
      }
    };
    event_handle(array_from(all_registered_events));
    root_event_handles.add(event_handle);
    return () => {
      for (var event_name of registered_events) for (const node of [target, document]) {
        var counts = listeners.get(node);
        var count = counts.get(event_name);
        if (--count == 0) {
          node.removeEventListener(event_name, handle_event_propagation);
          counts.delete(event_name);
          if (counts.size === 0) listeners.delete(node);
        } else counts.set(event_name, count);
      }
      root_event_handles.delete(event_handle);
      if (anchor_node !== anchor) anchor_node.parentNode?.removeChild(anchor_node);
    };
  });
  mounted_components.set(component84, unmount3);
  return component84;
}
function unmount2(component84, options2) {
  const fn = mounted_components.get(component84);
  if (fn) {
    mounted_components.delete(component84);
    return fn(options2);
  }
  return Promise.resolve();
}
function asClassComponent$1(component84) {
  return class extends Svelte4Component {
    /** @param {any} options */
    constructor(options2) {
      super({
        component: component84,
        ...options2
      });
    }
  };
}
function asClassComponent(component84) {
  const component_constructor = asClassComponent$1(component84);
  const _render = (props, { context: context2, csp, transformError } = {}) => {
    const result = render(component84, {
      props,
      context: context2,
      csp,
      transformError
    });
    const munged = Object.defineProperties({}, {
      css: { value: {
        code: "",
        map: null
      } },
      head: { get: () => result.head },
      html: { get: () => result.body },
      then: {
        /**
        * this is not type-safe, but honestly it's the best I can do right now, and it's a straightforward function.
        *
        * @template TResult1
        * @template [TResult2=never]
        * @param { (value: LegacyRenderResult) => TResult1 } onfulfilled
        * @param { (reason: unknown) => TResult2 } onrejected
        */
        value: (onfulfilled, onrejected) => {
          if (!async_mode_flag) {
            const user_result = onfulfilled({
              css: munged.css,
              head: munged.head,
              html: munged.html
            });
            return Promise.resolve(user_result);
          }
          return result.then((result2) => {
            return onfulfilled({
              css: munged.css,
              head: result2.head,
              html: result2.body,
              hashes: result2.hashes
            });
          }, onrejected);
        }
      }
    });
    return munged;
  };
  component_constructor.render = _render;
  return component_constructor;
}
function Root($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let { stores, page: page2, constructors, components = [], form, data_0 = null, data_1 = null, data_2 = null } = $$props;
    setContext("__svelte__", stores);
    stores.page.set(page2);
    const Pyramid_2 = derived(() => constructors[2]);
    if (constructors[1]) {
      $$renderer2.push("<!--[0-->");
      const Pyramid_0 = constructors[0];
      if (Pyramid_0) {
        $$renderer2.push("<!--[-->");
        Pyramid_0($$renderer2, {
          data: data_0,
          form,
          params: page2.params,
          children: ($$renderer3) => {
            if (constructors[2]) {
              $$renderer3.push("<!--[0-->");
              const Pyramid_1 = constructors[1];
              if (Pyramid_1) {
                $$renderer3.push("<!--[-->");
                Pyramid_1($$renderer3, {
                  data: data_1,
                  form,
                  params: page2.params,
                  children: ($$renderer4) => {
                    if (Pyramid_2()) {
                      $$renderer4.push("<!--[-->");
                      Pyramid_2()($$renderer4, {
                        data: data_2,
                        form,
                        params: page2.params
                      });
                      $$renderer4.push("<!--]-->");
                    } else {
                      $$renderer4.push("<!--[!-->");
                      $$renderer4.push("<!--]-->");
                    }
                  },
                  $$slots: { default: true }
                });
                $$renderer3.push("<!--]-->");
              } else {
                $$renderer3.push("<!--[!-->");
                $$renderer3.push("<!--]-->");
              }
            } else {
              $$renderer3.push("<!--[-1-->");
              const Pyramid_1 = constructors[1];
              if (Pyramid_1) {
                $$renderer3.push("<!--[-->");
                Pyramid_1($$renderer3, {
                  data: data_1,
                  form,
                  params: page2.params
                });
                $$renderer3.push("<!--]-->");
              } else {
                $$renderer3.push("<!--[!-->");
                $$renderer3.push("<!--]-->");
              }
            }
            $$renderer3.push(`<!--]-->`);
          },
          $$slots: { default: true }
        });
        $$renderer2.push("<!--]-->");
      } else {
        $$renderer2.push("<!--[!-->");
        $$renderer2.push("<!--]-->");
      }
    } else {
      $$renderer2.push("<!--[-1-->");
      const Pyramid_0 = constructors[0];
      if (Pyramid_0) {
        $$renderer2.push("<!--[-->");
        Pyramid_0($$renderer2, {
          data: data_0,
          form,
          params: page2.params
        });
        $$renderer2.push("<!--]-->");
      } else {
        $$renderer2.push("<!--[!-->");
        $$renderer2.push("<!--]-->");
      }
    }
    $$renderer2.push(`<!--]--> `);
    $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
  });
}
async function get_hooks() {
  let handle2;
  let handleFetch;
  let handleError;
  let handleValidationError;
  let init3;
  ({ handle: handle2, handleFetch, handleError, handleValidationError, init: init3 } = await init_hooks_server().then(() => hooks_server_exports));
  let reroute;
  let transport;
  return {
    handle: handle2,
    handleFetch,
    handleError,
    handleValidationError,
    init: init3,
    reroute,
    transport
  };
}
var public_env, read_implementation, event_symbol, all_registered_events, root_event_handles, last_propagated_event, listeners, mounted_components, Svelte4Component, root_default, error_template_default, options;
var init_internal22 = __esm({
  "dist/build/server/chunks/internal2.js"() {
    "use strict";
    init_index_server();
    init_internal2();
    init_server();
    public_env = {};
    read_implementation = null;
    event_symbol = /* @__PURE__ */ Symbol("events");
    all_registered_events = /* @__PURE__ */ new Set();
    root_event_handles = /* @__PURE__ */ new Set();
    last_propagated_event = null;
    globalThis?.window?.trustedTypes;
    listeners = /* @__PURE__ */ new Map();
    mounted_components = /* @__PURE__ */ new WeakMap();
    Svelte4Component = class {
      /** @type {any} */
      #events;
      /** @type {Record<string, any>} */
      #instance;
      /**
      * @param {ComponentConstructorOptions & {
      *  component: any;
      * }} options
      */
      constructor(options2) {
        var sources = /* @__PURE__ */ new Map();
        var add_source = (key2, value2) => {
          var s3 = /* @__PURE__ */ mutable_source(value2, false, false);
          sources.set(key2, s3);
          return s3;
        };
        const props = new Proxy({
          ...options2.props || {},
          $$events: {}
        }, {
          get(target, prop) {
            return get$1(sources.get(prop) ?? add_source(prop, Reflect.get(target, prop)));
          },
          has(target, prop) {
            if (prop === LEGACY_PROPS) return true;
            get$1(sources.get(prop) ?? add_source(prop, Reflect.get(target, prop)));
            return Reflect.has(target, prop);
          },
          set(target, prop, value2) {
            set(sources.get(prop) ?? add_source(prop, value2), value2);
            return Reflect.set(target, prop, value2);
          }
        });
        this.#instance = (options2.hydrate ? hydrate2 : mount2)(options2.component, {
          target: options2.target,
          anchor: options2.anchor,
          props,
          context: options2.context,
          intro: options2.intro ?? false,
          recover: options2.recover,
          transformError: options2.transformError
        });
        if (!async_mode_flag && (!options2?.props?.$$host || options2.sync === false)) flushSync();
        this.#events = props.$$events;
        for (const key2 of Object.keys(this.#instance)) {
          if (key2 === "$set" || key2 === "$destroy" || key2 === "$on") continue;
          define_property(this, key2, {
            get() {
              return this.#instance[key2];
            },
            /** @param {any} value */
            set(value2) {
              this.#instance[key2] = value2;
            },
            enumerable: true
          });
        }
        this.#instance.$set = (next2) => {
          Object.assign(props, next2);
        };
        this.#instance.$destroy = () => {
          unmount2(this.#instance);
        };
      }
      /** @param {Record<string, any>} props */
      $set(props) {
        this.#instance.$set(props);
      }
      /**
      * @param {string} event
      * @param {(...args: any[]) => any} callback
      * @returns {any}
      */
      $on(event, callback) {
        this.#events[event] = this.#events[event] || [];
        const cb = (...args) => callback.call(this, ...args);
        this.#events[event].push(cb);
        return () => {
          this.#events[event] = this.#events[event].filter(
            /** @param {any} fn */
            (fn) => fn !== cb
          );
        };
      }
      $destroy() {
        this.#instance.$destroy();
      }
    };
    root_default = asClassComponent(Root);
    error_template_default = ({ status, message: message2 }) => '<!doctype html>\n<html lang="en">\n	<head>\n		<meta charset="utf-8" />\n		<title>' + message2 + `</title>

		<style>
			body {
				--bg: white;
				--fg: #222;
				--divider: #ccc;
				background: var(--bg);
				color: var(--fg);
				font-family:
					system-ui,
					-apple-system,
					BlinkMacSystemFont,
					'Segoe UI',
					Roboto,
					Oxygen,
					Ubuntu,
					Cantarell,
					'Open Sans',
					'Helvetica Neue',
					sans-serif;
				display: flex;
				align-items: center;
				justify-content: center;
				height: 100vh;
				margin: 0;
			}

			.error {
				display: flex;
				align-items: center;
				max-width: 32rem;
				margin: 0 1rem;
			}

			.status {
				font-weight: 200;
				font-size: 3rem;
				line-height: 1;
				position: relative;
				top: -0.05rem;
			}

			.message {
				border-left: 1px solid var(--divider);
				padding: 0 0 0 1rem;
				margin: 0 0 0 1rem;
				min-height: 2.5rem;
				display: flex;
				align-items: center;
			}

			.message h1 {
				font-weight: 400;
				font-size: 1em;
				margin: 0;
			}

			@media (prefers-color-scheme: dark) {
				body {
					--bg: #222;
					--fg: #ddd;
					--divider: #666;
				}
			}
		</style>
	</head>
	<body>
		<div class="error">
			<span class="status">` + status + '</span>\n			<div class="message">\n				<h1>' + message2 + "</h1>\n			</div>\n		</div>\n	</body>\n</html>\n";
    options = {
      app_template_contains_nonce: false,
      async: false,
      csp: {
        "mode": "auto",
        "directives": {
          "upgrade-insecure-requests": false,
          "block-all-mixed-content": false
        },
        "reportOnly": {
          "upgrade-insecure-requests": false,
          "block-all-mixed-content": false
        }
      },
      csrf_check_origin: true,
      csrf_trusted_origins: [],
      embedded: false,
      env_public_prefix: "PUBLIC_",
      env_private_prefix: "",
      hash_routing: false,
      hooks: null,
      preload_strategy: "modulepreload",
      root: root_default,
      service_worker: false,
      service_worker_options: void 0,
      server_error_boundaries: false,
      templates: {
        app: ({ head: head2, body, assets: assets2, nonce, env }) => `<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<!-- Prevent FOUC by applying user preferences before first paint -->
		<style>
			html:not([data-nav-icons='emoji']) .nav-icon-emoji {
				display: none !important;
			}
			html[data-nav-icons='emoji'] .nav-icon-lucide {
				display: none !important;
			}
		</style>
		<script>
			(function () {
				var d = document.documentElement;

				// Theme
				var stored = localStorage.getItem('theme');
				d.classList.add(
					stored || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
				);

				// Accent color
				var accent = localStorage.getItem('accent') || 'blue';
				var palettes = {
					blue: {
						50: '#eff6ff',
						100: '#dbeafe',
						200: '#bfdbfe',
						300: '#93c5fd',
						400: '#60a5fa',
						500: '#3b82f6',
						600: '#2563eb',
						700: '#1d4ed8',
						800: '#1e40af',
						900: '#1e3a8a',
						950: '#172554'
					},
					yellow: {
						50: '#fefce8',
						100: '#fef9c3',
						200: '#fef08a',
						300: '#fde047',
						400: '#facc15',
						500: '#eab308',
						600: '#ca8a04',
						700: '#a16207',
						800: '#854d0e',
						900: '#713f12',
						950: '#422006'
					},
					green: {
						50: '#f0fdf4',
						100: '#dcfce7',
						200: '#bbf7d0',
						300: '#86efac',
						400: '#4ade80',
						500: '#22c55e',
						600: '#16a34a',
						700: '#15803d',
						800: '#166534',
						900: '#14532d',
						950: '#052e16'
					},
					orange: {
						50: '#fff7ed',
						100: '#ffedd5',
						200: '#fed7aa',
						300: '#fdba74',
						400: '#fb923c',
						500: '#f97316',
						600: '#ea580c',
						700: '#c2410c',
						800: '#9a3412',
						900: '#7c2d12',
						950: '#431407'
					},
					teal: {
						50: '#f0fdfa',
						100: '#ccfbf1',
						200: '#99f6e4',
						300: '#5eead4',
						400: '#2dd4bf',
						500: '#14b8a6',
						600: '#0d9488',
						700: '#0f766e',
						800: '#115e59',
						900: '#134e4a',
						950: '#042f2e'
					},
					purple: {
						50: '#faf5ff',
						100: '#f3e8ff',
						200: '#e9d5ff',
						300: '#d8b4fe',
						400: '#c084fc',
						500: '#a855f7',
						600: '#9333ea',
						700: '#7e22ce',
						800: '#6b21a8',
						900: '#581c87',
						950: '#3b0764'
					},
					rose: {
						50: '#fff1f2',
						100: '#ffe4e6',
						200: '#fecdd3',
						300: '#fda4af',
						400: '#fb7185',
						500: '#f43f5e',
						600: '#e11d48',
						700: '#be123c',
						800: '#9f1239',
						900: '#881337',
						950: '#4c0519'
					}
				};
				var p = palettes[accent] || palettes.blue;
				for (var shade in p) {
					d.style.setProperty('--accent-' + shade, p[shade]);
				}

				// Nav icon style
				d.dataset.navIcons = localStorage.getItem('navIconStyle') || 'lucide';
			})();
		</script>
		` + head2 + '\n	</head>\n	<body data-sveltekit-preload-data="hover">\n		<div style="display: contents">' + body + "</div>\n	</body>\n</html>\n",
        error: error_template_default
      },
      version_hash: "th6wl6"
    };
  }
});

// dist/build/server/chunks/exports.js
function compact(arr) {
  return arr.filter(
    /** @returns {val is NonNullable<T>} */
    (val) => val != null
  );
}
function has_data_suffix2(pathname) {
  return pathname.endsWith(DATA_SUFFIX) || pathname.endsWith(HTML_DATA_SUFFIX);
}
function add_data_suffix2(pathname) {
  if (pathname.endsWith(".html")) return pathname.replace(/\.html$/, HTML_DATA_SUFFIX);
  return pathname.replace(/\/$/, "") + DATA_SUFFIX;
}
function strip_data_suffix2(pathname) {
  if (pathname.endsWith(HTML_DATA_SUFFIX)) return pathname.slice(0, -16) + ".html";
  return pathname.slice(0, -12);
}
function has_resolution_suffix2(pathname) {
  return pathname.endsWith(ROUTE_SUFFIX);
}
function add_resolution_suffix2(pathname) {
  return pathname.replace(/\/$/, "") + ROUTE_SUFFIX;
}
function strip_resolution_suffix2(pathname) {
  return pathname.slice(0, -11);
}
function resolve3(base2, path) {
  if (path[0] === "/" && path[1] === "/") return path;
  let url = new URL(base2, internal);
  url = new URL(path, url);
  return url.protocol === internal.protocol ? url.pathname + url.search + url.hash : url.href;
}
function normalize_path(path, trailing_slash) {
  if (path === "/" || trailing_slash === "ignore") return path;
  if (trailing_slash === "never") return path.endsWith("/") ? path.slice(0, -1) : path;
  else if (trailing_slash === "always" && !path.endsWith("/")) return path + "/";
  return path;
}
function decode_pathname(pathname) {
  return pathname.split("%25").map(decodeURI).join("%25");
}
function decode_params(params) {
  for (const key2 in params) params[key2] = decodeURIComponent(params[key2]);
  return params;
}
function make_trackable(url, callback, search_params_callback, allow_hash = false) {
  const tracked = new URL(url);
  Object.defineProperty(tracked, "searchParams", {
    value: new Proxy(tracked.searchParams, { get(obj, key2) {
      if (key2 === "get" || key2 === "getAll" || key2 === "has") return (param, ...rest) => {
        search_params_callback(param);
        return obj[key2](param, ...rest);
      };
      callback();
      const value2 = Reflect.get(obj, key2);
      return typeof value2 === "function" ? value2.bind(obj) : value2;
    } }),
    enumerable: true,
    configurable: true
  });
  const tracked_url_properties = [
    "href",
    "pathname",
    "search",
    "toString",
    "toJSON"
  ];
  if (allow_hash) tracked_url_properties.push("hash");
  for (const property of tracked_url_properties) Object.defineProperty(tracked, property, {
    get() {
      callback();
      return url[property];
    },
    enumerable: true,
    configurable: true
  });
  tracked[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")] = (_depth, opts, inspect) => {
    return inspect(url, opts);
  };
  tracked.searchParams[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")] = (_depth, opts, inspect) => {
    return inspect(url.searchParams, opts);
  };
  if (!allow_hash) disable_hash(tracked);
  return tracked;
}
function disable_hash(url) {
  allow_nodejs_console_log(url);
  Object.defineProperty(url, "hash", { get() {
    throw new Error("Cannot access event.url.hash. Consider using `page.url.hash` inside a component instead");
  } });
}
function disable_search(url) {
  allow_nodejs_console_log(url);
  for (const property of ["search", "searchParams"]) Object.defineProperty(url, property, { get() {
    throw new Error(`Cannot access url.${property} on a page with prerendering enabled`);
  } });
}
function allow_nodejs_console_log(url) {
  url[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")] = (_depth, opts, inspect) => {
    return inspect(new URL(url), opts);
  };
}
function hash3(...values) {
  let hash4 = 5381;
  for (const value2 of values) if (typeof value2 === "string") {
    let i = value2.length;
    while (i) hash4 = hash4 * 33 ^ value2.charCodeAt(--i);
  } else if (ArrayBuffer.isView(value2)) {
    const buffer2 = new Uint8Array(value2.buffer, value2.byteOffset, value2.byteLength);
    let i = buffer2.length;
    while (i) hash4 = hash4 * 33 ^ buffer2[--i];
  } else throw new TypeError("value must be a string or TypedArray");
  return (hash4 >>> 0).toString(36);
}
function exec(match, params, matchers) {
  const result = {};
  const values = match.slice(1);
  const values_needing_match = values.filter((value2) => value2 !== void 0);
  let buffered = 0;
  for (let i = 0; i < params.length; i += 1) {
    const param = params[i];
    let value2 = values[i - buffered];
    if (param.chained && param.rest && buffered) {
      value2 = values.slice(i - buffered, i + 1).filter((s3) => s3).join("/");
      buffered = 0;
    }
    if (value2 === void 0) if (param.rest) value2 = "";
    else continue;
    if (!param.matcher || matchers[param.matcher](value2)) {
      result[param.name] = value2;
      const next_param = params[i + 1];
      const next_value = values[i + 1];
      if (next_param && !next_param.rest && next_param.optional && next_value && param.chained) buffered = 0;
      if (!next_param && !next_value && Object.keys(result).length === values_needing_match.length) buffered = 0;
      continue;
    }
    if (param.optional && param.chained) {
      buffered++;
      continue;
    }
    return;
  }
  if (buffered) return;
  return result;
}
function find_route(path, routes, matchers) {
  for (const route of routes) {
    const match = route.pattern.exec(path);
    if (!match) continue;
    const matched = exec(match, route.params, matchers);
    if (matched) return {
      route,
      params: decode_params(matched)
    };
  }
  return null;
}
function validator(expected) {
  function validate(module, file) {
    if (!module) return;
    for (const key2 in module) {
      if (key2[0] === "_" || expected.has(key2)) continue;
      const values = [...expected.values()];
      const hint = hint_for_supported_files(key2, file?.slice(file.lastIndexOf("."))) ?? `valid exports are ${values.join(", ")}, or anything with a '_' prefix`;
      throw new Error(`Invalid export '${key2}'${file ? ` in ${file}` : ""} (${hint})`);
    }
  }
  return validate;
}
function hint_for_supported_files(key2, ext = ".js") {
  const supported_files = [];
  if (valid_layout_exports.has(key2)) supported_files.push(`+layout${ext}`);
  if (valid_page_exports.has(key2)) supported_files.push(`+page${ext}`);
  if (valid_layout_server_exports.has(key2)) supported_files.push(`+layout.server${ext}`);
  if (valid_page_server_exports.has(key2)) supported_files.push(`+page.server${ext}`);
  if (valid_server_exports.has(key2)) supported_files.push(`+server${ext}`);
  if (supported_files.length > 0) return `'${key2}' is a valid export in ${supported_files.slice(0, -1).join(", ")}${supported_files.length > 1 ? " or " : ""}${supported_files.at(-1)}`;
}
var DATA_SUFFIX, HTML_DATA_SUFFIX, ROUTE_SUFFIX, noop_span, noop_span_context, internal, valid_layout_exports, valid_page_exports, valid_layout_server_exports, valid_page_server_exports, valid_server_exports, validate_layout_exports, validate_page_exports, validate_layout_server_exports, validate_page_server_exports, validate_server_exports;
var init_exports2 = __esm({
  "dist/build/server/chunks/exports.js"() {
    "use strict";
    DATA_SUFFIX = "/__data.json";
    HTML_DATA_SUFFIX = ".html__data.json";
    ROUTE_SUFFIX = "/__route.js";
    noop_span = {
      spanContext() {
        return noop_span_context;
      },
      setAttribute() {
        return this;
      },
      setAttributes() {
        return this;
      },
      addEvent() {
        return this;
      },
      setStatus() {
        return this;
      },
      updateName() {
        return this;
      },
      end() {
        return this;
      },
      isRecording() {
        return false;
      },
      recordException() {
        return this;
      },
      addLink() {
        return this;
      },
      addLinks() {
        return this;
      }
    };
    noop_span_context = {
      traceId: "",
      spanId: "",
      traceFlags: 0
    };
    internal = new URL("sveltekit-internal://");
    valid_layout_exports = /* @__PURE__ */ new Set([
      "load",
      "prerender",
      "csr",
      "ssr",
      "trailingSlash",
      "config"
    ]);
    valid_page_exports = /* @__PURE__ */ new Set([...valid_layout_exports, "entries"]);
    valid_layout_server_exports = /* @__PURE__ */ new Set([...valid_layout_exports]);
    valid_page_server_exports = /* @__PURE__ */ new Set([
      ...valid_layout_server_exports,
      "actions",
      "entries"
    ]);
    valid_server_exports = /* @__PURE__ */ new Set([
      "GET",
      "POST",
      "PATCH",
      "PUT",
      "DELETE",
      "OPTIONS",
      "HEAD",
      "fallback",
      "prerender",
      "trailingSlash",
      "config",
      "entries"
    ]);
    validate_layout_exports = validator(valid_layout_exports);
    validate_page_exports = validator(valid_page_exports);
    validate_layout_server_exports = validator(valid_layout_server_exports);
    validate_page_server_exports = validator(valid_page_server_exports);
    validate_server_exports = validator(valid_server_exports);
  }
});

// dist/build/server/chunks/index-server2.js
var init_index_server2 = __esm({
  "dist/build/server/chunks/index-server2.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/chunks/generalSettings.js
var generalSettingsQueries;
var init_generalSettings = __esm({
  async "dist/build/server/chunks/generalSettings.js"() {
    "use strict";
    await init_db();
    generalSettingsQueries = {
      /**
      * Get the general settings (singleton)
      */
      get() {
        return db.queryFirst("SELECT * FROM general_settings WHERE id = 1");
      },
      /**
      * Check if default delay profiles should be applied when adding arr
      */
      shouldApplyDefaultDelayProfiles() {
        return this.get()?.apply_default_delay_profiles === 1;
      },
      /**
      * Check if referenced custom format and regex deletes should be blocked
      */
      shouldFailOnReferencedDelete() {
        return this.get()?.fail_on_referenced_delete === 1;
      },
      /**
      * Check if entity saves should prompt to sync affected Arr instances
      */
      shouldShowSyncPrompt() {
        return this.get()?.sync_prompt_enabled !== 0;
      },
      /**
      * Update general settings
      */
      update(input) {
        const updates = [];
        const params = [];
        if (input.dateFormat !== void 0) {
          updates.push("date_format = ?");
          params.push(input.dateFormat);
        }
        if (input.applyDefaultDelayProfiles !== void 0) {
          updates.push("apply_default_delay_profiles = ?");
          params.push(input.applyDefaultDelayProfiles ? 1 : 0);
        }
        if (input.failOnReferencedDelete !== void 0) {
          updates.push("fail_on_referenced_delete = ?");
          params.push(input.failOnReferencedDelete ? 1 : 0);
        }
        if (input.syncPromptEnabled !== void 0) {
          updates.push("sync_prompt_enabled = ?");
          params.push(input.syncPromptEnabled ? 1 : 0);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(1);
        return db.execute(`UPDATE general_settings SET ${updates.join(", ")} WHERE id = ?`, ...params) > 0;
      }
    };
  }
});

// dist/build/server/chunks/types.js
var QualitySource, QualityModifier, Resolution, Language, ReleaseType;
var init_types = __esm({
  "dist/build/server/chunks/types.js"() {
    "use strict";
    QualitySource = /* @__PURE__ */ (function(QualitySource2) {
      QualitySource2[QualitySource2["Unknown"] = 0] = "Unknown";
      QualitySource2[QualitySource2["Cam"] = 1] = "Cam";
      QualitySource2[QualitySource2["Telesync"] = 2] = "Telesync";
      QualitySource2[QualitySource2["Telecine"] = 3] = "Telecine";
      QualitySource2[QualitySource2["Workprint"] = 4] = "Workprint";
      QualitySource2[QualitySource2["DVD"] = 5] = "DVD";
      QualitySource2[QualitySource2["TV"] = 6] = "TV";
      QualitySource2[QualitySource2["WebDL"] = 7] = "WebDL";
      QualitySource2[QualitySource2["WebRip"] = 8] = "WebRip";
      QualitySource2[QualitySource2["Bluray"] = 9] = "Bluray";
      return QualitySource2;
    })({});
    QualityModifier = /* @__PURE__ */ (function(QualityModifier2) {
      QualityModifier2[QualityModifier2["None"] = 0] = "None";
      QualityModifier2[QualityModifier2["Regional"] = 1] = "Regional";
      QualityModifier2[QualityModifier2["Screener"] = 2] = "Screener";
      QualityModifier2[QualityModifier2["RawHD"] = 3] = "RawHD";
      QualityModifier2[QualityModifier2["BRDisk"] = 4] = "BRDisk";
      QualityModifier2[QualityModifier2["Remux"] = 5] = "Remux";
      return QualityModifier2;
    })({});
    Resolution = /* @__PURE__ */ (function(Resolution2) {
      Resolution2[Resolution2["Unknown"] = 0] = "Unknown";
      Resolution2[Resolution2["R360p"] = 360] = "R360p";
      Resolution2[Resolution2["R480p"] = 480] = "R480p";
      Resolution2[Resolution2["R540p"] = 540] = "R540p";
      Resolution2[Resolution2["R576p"] = 576] = "R576p";
      Resolution2[Resolution2["R720p"] = 720] = "R720p";
      Resolution2[Resolution2["R1080p"] = 1080] = "R1080p";
      Resolution2[Resolution2["R2160p"] = 2160] = "R2160p";
      return Resolution2;
    })({});
    Language = /* @__PURE__ */ (function(Language2) {
      Language2[Language2["Unknown"] = 0] = "Unknown";
      Language2[Language2["English"] = 1] = "English";
      Language2[Language2["French"] = 2] = "French";
      Language2[Language2["Spanish"] = 3] = "Spanish";
      Language2[Language2["German"] = 4] = "German";
      Language2[Language2["Italian"] = 5] = "Italian";
      Language2[Language2["Danish"] = 6] = "Danish";
      Language2[Language2["Dutch"] = 7] = "Dutch";
      Language2[Language2["Japanese"] = 8] = "Japanese";
      Language2[Language2["Icelandic"] = 9] = "Icelandic";
      Language2[Language2["Chinese"] = 10] = "Chinese";
      Language2[Language2["Russian"] = 11] = "Russian";
      Language2[Language2["Polish"] = 12] = "Polish";
      Language2[Language2["Vietnamese"] = 13] = "Vietnamese";
      Language2[Language2["Swedish"] = 14] = "Swedish";
      Language2[Language2["Norwegian"] = 15] = "Norwegian";
      Language2[Language2["Finnish"] = 16] = "Finnish";
      Language2[Language2["Turkish"] = 17] = "Turkish";
      Language2[Language2["Portuguese"] = 18] = "Portuguese";
      Language2[Language2["Flemish"] = 19] = "Flemish";
      Language2[Language2["Greek"] = 20] = "Greek";
      Language2[Language2["Korean"] = 21] = "Korean";
      Language2[Language2["Hungarian"] = 22] = "Hungarian";
      Language2[Language2["Hebrew"] = 23] = "Hebrew";
      Language2[Language2["Lithuanian"] = 24] = "Lithuanian";
      Language2[Language2["Czech"] = 25] = "Czech";
      Language2[Language2["Hindi"] = 26] = "Hindi";
      Language2[Language2["Romanian"] = 27] = "Romanian";
      Language2[Language2["Thai"] = 28] = "Thai";
      Language2[Language2["Bulgarian"] = 29] = "Bulgarian";
      Language2[Language2["PortugueseBR"] = 30] = "PortugueseBR";
      Language2[Language2["Arabic"] = 31] = "Arabic";
      Language2[Language2["Ukrainian"] = 32] = "Ukrainian";
      Language2[Language2["Persian"] = 33] = "Persian";
      Language2[Language2["Bengali"] = 34] = "Bengali";
      Language2[Language2["Slovak"] = 35] = "Slovak";
      Language2[Language2["Latvian"] = 36] = "Latvian";
      Language2[Language2["SpanishLatino"] = 37] = "SpanishLatino";
      Language2[Language2["Catalan"] = 38] = "Catalan";
      Language2[Language2["Croatian"] = 39] = "Croatian";
      Language2[Language2["Serbian"] = 40] = "Serbian";
      Language2[Language2["Bosnian"] = 41] = "Bosnian";
      Language2[Language2["Estonian"] = 42] = "Estonian";
      Language2[Language2["Tamil"] = 43] = "Tamil";
      Language2[Language2["Indonesian"] = 44] = "Indonesian";
      Language2[Language2["Telugu"] = 45] = "Telugu";
      Language2[Language2["Macedonian"] = 46] = "Macedonian";
      Language2[Language2["Slovenian"] = 47] = "Slovenian";
      Language2[Language2["Malayalam"] = 48] = "Malayalam";
      Language2[Language2["Kannada"] = 49] = "Kannada";
      Language2[Language2["Albanian"] = 50] = "Albanian";
      Language2[Language2["Afrikaans"] = 51] = "Afrikaans";
      Language2[Language2["Marathi"] = 52] = "Marathi";
      Language2[Language2["Tagalog"] = 53] = "Tagalog";
      Language2[Language2["Urdu"] = 54] = "Urdu";
      Language2[Language2["Romansh"] = 55] = "Romansh";
      Language2[Language2["Mongolian"] = 56] = "Mongolian";
      Language2[Language2["Georgian"] = 57] = "Georgian";
      Language2[Language2["Original"] = 58] = "Original";
      return Language2;
    })({});
    ReleaseType = /* @__PURE__ */ (function(ReleaseType2) {
      ReleaseType2[ReleaseType2["Unknown"] = 0] = "Unknown";
      ReleaseType2[ReleaseType2["SingleEpisode"] = 1] = "SingleEpisode";
      ReleaseType2[ReleaseType2["MultiEpisode"] = 2] = "MultiEpisode";
      ReleaseType2[ReleaseType2["SeasonPack"] = 3] = "SeasonPack";
      return ReleaseType2;
    })({});
  }
});

// dist/build/server/chunks/client2.js
function getClient2() {
  if (!parserClient) parserClient = new ParserClient(config.parserUrl);
  return parserClient;
}
async function parse3(title, type) {
  const data = await getClient2().parse(title, type);
  return {
    title: data.title,
    type: data.type,
    source: QualitySource[data.source] ?? QualitySource.Unknown,
    resolution: data.resolution,
    modifier: QualityModifier[data.modifier] ?? QualityModifier.None,
    revision: data.revision,
    languages: data.languages.map((l3) => Language[l3] ?? Language.Unknown),
    releaseGroup: data.releaseGroup,
    movieTitles: data.movieTitles,
    year: data.year,
    edition: data.edition,
    imdbId: data.imdbId,
    tmdbId: data.tmdbId,
    hardcodedSubs: data.hardcodedSubs,
    releaseHash: data.releaseHash,
    episode: data.episode ? {
      seriesTitle: data.episode.seriesTitle,
      seasonNumber: data.episode.seasonNumber,
      episodeNumbers: data.episode.episodeNumbers,
      absoluteEpisodeNumbers: data.episode.absoluteEpisodeNumbers,
      airDate: data.episode.airDate,
      fullSeason: data.episode.fullSeason,
      isPartialSeason: data.episode.isPartialSeason,
      isMultiSeason: data.episode.isMultiSeason,
      isMiniSeries: data.episode.isMiniSeries,
      special: data.episode.special,
      releaseType: ReleaseType[data.episode.releaseType] ?? ReleaseType.Unknown
    } : null
  };
}
async function isParserHealthy() {
  if (cachedHealthStatus && Date.now() - cachedHealthStatus.checkedAt < HEALTH_CACHE_TTL) return cachedHealthStatus.healthy;
  try {
    const controller2 = new AbortController();
    const timeoutId = setTimeout(() => controller2.abort(), 3e3);
    const response = await fetch(`${config.parserUrl}/health`, { signal: controller2.signal });
    clearTimeout(timeoutId);
    const healthy = response.ok;
    cachedHealthStatus = {
      healthy,
      checkedAt: Date.now()
    };
    return healthy;
  } catch {
    cachedHealthStatus = {
      healthy: false,
      checkedAt: Date.now()
    };
    return false;
  }
}
async function getParserVersion() {
  if (cachedParserVersion) return cachedParserVersion;
  try {
    cachedParserVersion = (await getClient2().health()).version;
    return cachedParserVersion;
  } catch (err) {
    await logger.warn("Failed to connect to parser service", {
      source: "ParserClient",
      meta: { error: err instanceof Error ? err.message : "Unknown error" }
    });
    return null;
  }
}
function getCacheKey(title, type) {
  return `${title}:${type}`;
}
async function parseWithCacheBatch(items) {
  const results = /* @__PURE__ */ new Map();
  const parserVersion = await getParserVersion();
  if (!parserVersion) {
    for (const item of items) results.set(getCacheKey(item.title, item.type), null);
    return results;
  }
  const uncached = [];
  for (const item of items) {
    const cacheKey = getCacheKey(item.title, item.type);
    const cached2 = parsedReleaseCacheQueries.get(cacheKey, parserVersion);
    if (cached2) results.set(cacheKey, JSON.parse(cached2.parsed_result));
    else uncached.push({
      ...item,
      cacheKey
    });
  }
  if (uncached.length > 0) {
    const parsePromises = uncached.map(async (item) => {
      try {
        const result = await parse3(item.title, item.type);
        parsedReleaseCacheQueries.set(item.cacheKey, parserVersion, JSON.stringify(result));
        return {
          cacheKey: item.cacheKey,
          result
        };
      } catch {
        return {
          cacheKey: item.cacheKey,
          result: null
        };
      }
    });
    const parsed = await Promise.all(parsePromises);
    for (const { cacheKey, result } of parsed) results.set(cacheKey, result);
  }
  return results;
}
async function matchPatterns(text2, patterns) {
  if (patterns.length === 0) return /* @__PURE__ */ new Map();
  try {
    const data = await getClient2().match(text2, patterns);
    return new Map(Object.entries(data.results));
  } catch (err) {
    await logger.warn("Failed to connect to parser for pattern matching", {
      source: "ParserClient",
      meta: { error: err instanceof Error ? err.message : "Unknown error" }
    });
    return null;
  }
}
async function hashPatterns(patterns) {
  const sorted = [...patterns].sort();
  const data = new TextEncoder().encode(sorted.join("\n"));
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  return Array.from(new Uint8Array(hashBuffer)).map((b3) => b3.toString(16).padStart(2, "0")).join("").slice(0, 16);
}
async function fetchPatternMatches(texts, patterns) {
  try {
    const data = await getClient2().matchBatch(texts, patterns);
    const result = /* @__PURE__ */ new Map();
    for (const [text2, patternResults] of Object.entries(data.results)) result.set(text2, new Map(Object.entries(patternResults)));
    return result;
  } catch (err) {
    await logger.warn("Failed to connect to parser for batch pattern matching", {
      source: "ParserClient",
      meta: { error: err instanceof Error ? err.message : "Unknown error" }
    });
    return null;
  }
}
async function validateRegex(pattern2) {
  if (!await isParserHealthy()) return null;
  try {
    return await getClient2().post("/validate/regex", { pattern: pattern2 });
  } catch {
    return null;
  }
}
async function matchPatternsBatch(texts, patterns) {
  if (texts.length === 0 || patterns.length === 0) return /* @__PURE__ */ new Map();
  const patternsHash = await hashPatterns(patterns);
  const cachedResults = patternMatchCacheQueries.getBatch(texts, patternsHash);
  const results = /* @__PURE__ */ new Map();
  const uncachedTexts = [];
  for (const text2 of texts) {
    const cached2 = cachedResults.get(text2);
    if (cached2) {
      const parsed = JSON.parse(cached2);
      results.set(text2, new Map(Object.entries(parsed)));
    } else uncachedTexts.push(text2);
  }
  const cacheHits = texts.length - uncachedTexts.length;
  if (uncachedTexts.length === 0) return results;
  const fetchedResults = await fetchPatternMatches(uncachedTexts, patterns);
  if (!fetchedResults) {
    if (cacheHits > 0) return results;
    return null;
  }
  const toCache = [];
  for (const [text2, patternMatches] of fetchedResults) {
    results.set(text2, patternMatches);
    const obj = {};
    for (const [pattern2, matched] of patternMatches) obj[pattern2] = matched;
    toCache.push({
      title: text2,
      matchResults: JSON.stringify(obj)
    });
  }
  if (toCache.length > 0) patternMatchCacheQueries.setBatch(toCache, patternsHash);
  return results;
}
var parsedReleaseCacheQueries, patternMatchCacheQueries, cachedParserVersion, ParserClient, parserClient, cachedHealthStatus, HEALTH_CACHE_TTL;
var init_client2 = __esm({
  async "dist/build/server/chunks/client2.js"() {
    "use strict";
    await init_db();
    init_config();
    init_client();
    init_types();
    parsedReleaseCacheQueries = {
      /**
      * Get cached parse result by key and version
      * Returns undefined if not found or version doesn't match
      */
      get(cacheKey, parserVersion) {
        return db.queryFirst("SELECT * FROM parsed_release_cache WHERE cache_key = ? AND parser_version = ?", cacheKey, parserVersion);
      },
      /**
      * Store parse result in cache (insert or replace)
      */
      set(cacheKey, parserVersion, parsedResult) {
        db.execute("INSERT OR REPLACE INTO parsed_release_cache (cache_key, parser_version, parsed_result) VALUES (?, ?, ?)", cacheKey, parserVersion, parsedResult);
      },
      /**
      * Delete a cached entry
      */
      delete(cacheKey) {
        return db.execute("DELETE FROM parsed_release_cache WHERE cache_key = ?", cacheKey) > 0;
      },
      /**
      * Delete all entries for old parser versions
      * Call this periodically or on startup to clean up stale cache entries
      */
      deleteOldVersions(currentVersion) {
        return db.execute("DELETE FROM parsed_release_cache WHERE parser_version != ?", currentVersion);
      },
      /**
      * Clear all cached entries
      */
      clear() {
        return db.execute("DELETE FROM parsed_release_cache");
      },
      /**
      * Get cache stats
      */
      getStats() {
        const total = db.queryFirst("SELECT COUNT(*) as count FROM parsed_release_cache")?.count ?? 0;
        const versionCounts = db.query("SELECT parser_version, COUNT(*) as count FROM parsed_release_cache GROUP BY parser_version");
        const byVersion = {};
        for (const row of versionCounts) byVersion[row.parser_version] = row.count;
        return {
          total,
          byVersion
        };
      }
    };
    patternMatchCacheQueries = {
      /**
      * Get cached match results for a title with specific patterns hash
      */
      get(title, patternsHash) {
        return db.queryFirst("SELECT * FROM pattern_match_cache WHERE title = ? AND patterns_hash = ?", title, patternsHash);
      },
      /**
      * Get cached match results for multiple titles with specific patterns hash
      * Returns a map of title -> match_results JSON
      */
      getBatch(titles, patternsHash) {
        if (titles.length === 0) return /* @__PURE__ */ new Map();
        const placeholders = titles.map(() => "?").join(",");
        const results = db.query(`SELECT title, match_results FROM pattern_match_cache WHERE patterns_hash = ? AND title IN (${placeholders})`, patternsHash, ...titles);
        const map2 = /* @__PURE__ */ new Map();
        for (const row of results) map2.set(row.title, row.match_results);
        return map2;
      },
      /**
      * Store match results in cache (insert or replace)
      */
      set(title, patternsHash, matchResults) {
        db.execute("INSERT OR REPLACE INTO pattern_match_cache (title, patterns_hash, match_results) VALUES (?, ?, ?)", title, patternsHash, matchResults);
      },
      /**
      * Store multiple match results in cache (batch insert)
      */
      setBatch(entries, patternsHash) {
        if (entries.length === 0) return;
        const stmt = db.prepare("INSERT OR REPLACE INTO pattern_match_cache (title, patterns_hash, match_results) VALUES (?, ?, ?)");
        try {
          for (const entry of entries) stmt.run(entry.title, patternsHash, entry.matchResults);
        } finally {
          stmt.finalize();
        }
      },
      /**
      * Delete all entries for old pattern hashes
      * Call this periodically to clean up stale cache entries
      */
      deleteOldHashes(currentHash) {
        return db.execute("DELETE FROM pattern_match_cache WHERE patterns_hash != ?", currentHash);
      },
      /**
      * Clear all cached entries
      */
      clear() {
        return db.execute("DELETE FROM pattern_match_cache");
      },
      /**
      * Get cache stats
      */
      getStats() {
        const total = db.queryFirst("SELECT COUNT(*) as count FROM pattern_match_cache")?.count ?? 0;
        const hashCounts = db.query("SELECT patterns_hash, COUNT(*) as count FROM pattern_match_cache GROUP BY patterns_hash");
        const byHash = {};
        for (const row of hashCounts) byHash[row.patterns_hash] = row.count;
        return {
          total,
          byHash
        };
      }
    };
    cachedParserVersion = null;
    ParserClient = class extends BaseHttpClient {
      constructor(baseUrl) {
        super(baseUrl, {
          timeout: 3e4,
          retries: 2,
          retryDelay: 500
        });
      }
      /**
      * Parse a release title
      */
      async parse(title, type) {
        return this.post("/parse", {
          title,
          type
        });
      }
      /**
      * Check health and get version
      */
      async health() {
        return this.get("/health");
      }
      /**
      * Match patterns against text
      */
      async match(text2, patterns) {
        return this.post("/match", {
          text: text2,
          patterns
        });
      }
      /**
      * Match patterns against multiple texts (batch)
      */
      async matchBatch(texts, patterns) {
        return this.post("/match/batch", {
          texts,
          patterns
        });
      }
    };
    parserClient = null;
    cachedHealthStatus = null;
    HEALTH_CACHE_TTL = 3e4;
  }
});

// dist/build/server/entries/pages/_layout.server.ts.js
var layout_server_ts_exports = {};
__export(layout_server_ts_exports, {
  load: () => load
});
async function readPendingRestore() {
  try {
    const path = (await Deno.readTextFile(`${config.paths.base}/.restore-pending`)).trim();
    return { filename: path.split("/").pop() || path };
  } catch (err) {
    if (err instanceof Deno.errors.NotFound) return null;
    throw err;
  }
}
var load;
var init_layout_server_ts = __esm({
  async "dist/build/server/entries/pages/_layout.server.ts.js"() {
    "use strict";
    init_config();
    await init_announcements();
    init_build();
    await init_databaseInstances();
    await init_arrInstances();
    await init_generalSettings();
    await init_client2();
    load = async () => {
      const arrInstances = arrInstancesQueries.getAll().map((i) => ({
        id: i.id,
        name: i.name,
        type: i.type
      }));
      const databases = databaseInstancesQueries.getAll().map((d2) => ({
        id: d2.id,
        name: d2.name
      }));
      return {
        version: build.version,
        versionStatus: getVersionStatus(),
        timezone: config.timezone,
        dateFormat: generalSettingsQueries.get()?.date_format ?? "auto",
        arrInstances,
        databases,
        parserAvailable: await isParserHealthy(),
        unreadAnnouncements: getUnreadCount(),
        restorePending: await readPendingRestore()
      };
    };
  }
});

// dist/build/server/chunks/navIcons.js
function createFontStore() {
  const initial2 = { ...DEFAULT_FONTS };
  const { subscribe: subscribe2, set: set3 } = writable(initial2);
  function setFonts(next2) {
    set3(next2);
  }
  return {
    subscribe: subscribe2,
    setFonts
  };
}
function createNavIconStore() {
  const { subscribe: subscribe2, set: set3 } = writable("lucide");
  function setStyle(style) {
    set3(style);
  }
  function toggle() {
  }
  return {
    subscribe: subscribe2,
    setStyle,
    toggle
  };
}
var DEFAULT_FONTS, sansFontOptions, monoFontOptions, fontStore, navIconStore;
var init_navIcons = __esm({
  "dist/build/server/chunks/navIcons.js"() {
    "use strict";
    init_server();
    init_index_server2();
    DEFAULT_FONTS = {
      sans: "dm-sans",
      mono: "geist-mono"
    };
    sansFontOptions = [
      {
        value: "dm-sans",
        label: "DM Sans"
      },
      {
        value: "inter",
        label: "Inter"
      },
      {
        value: "ibm-plex-sans",
        label: "IBM Plex Sans"
      }
    ];
    monoFontOptions = [
      {
        value: "geist-mono",
        label: "Geist Mono"
      },
      {
        value: "jetbrains-mono",
        label: "JetBrains Mono"
      },
      {
        value: "ibm-plex-mono",
        label: "IBM Plex Mono"
      }
    ];
    fontStore = createFontStore();
    navIconStore = createNavIconStore();
  }
});

// dist/build/server/chunks/logo-512.js
var logo_512_default;
var init_logo_512 = __esm({
  "dist/build/server/chunks/logo-512.js"() {
    "use strict";
    logo_512_default = "/_app/immutable/assets/logo-512.Cu8kp5U-.png";
  }
});

// dist/build/server/chunks/Dropdown.js
function Dropdown($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let positionClass, marginClass, roundedClass, verticalClass;
    createEventDispatcher();
    let position = fallback($$props["position"], "left");
    let mobilePosition = fallback($$props["mobilePosition"], null);
    let minWidth = fallback($$props["minWidth"], "12rem");
    let width = fallback($$props["width"], void 0);
    let compact2 = fallback($$props["compact"], false);
    let placement = fallback($$props["placement"], "auto");
    let fixed = fallback($$props["fixed"], false);
    let triggerEl = fallback($$props["triggerEl"], null);
    let onboarding = fallback($$props["onboarding"], void 0);
    let fixedStyle = "";
    const positionClasses = {
      left: "left-0",
      right: "right-0",
      middle: "left-1/2 -translate-x-1/2"
    };
    const responsivePositionClasses = {
      "middle-to-right": "left-1/2 -translate-x-1/2 md:left-auto md:right-0 md:translate-x-0",
      "middle-to-left": "left-1/2 -translate-x-1/2 md:left-0 md:translate-x-0",
      "left-to-right": "left-0 md:left-auto md:right-0",
      "right-to-left": "right-0 md:right-auto md:left-0"
    };
    $: positionClass = fixed ? "" : mobilePosition && mobilePosition !== position ? responsivePositionClasses[`${mobilePosition}-to-${position}`] || positionClasses[position] : positionClasses[position];
    $: marginClass = compact2 ? "mt-1" : "mt-3";
    $: roundedClass = compact2 ? "rounded-lg" : "rounded-xl";
    $: verticalClass = `top-full ${marginClass}`;
    if (!fixed) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div${attr_class(`absolute z-40 h-3 w-full top-full`)}></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div${attr("data-onboarding", onboarding)}${attr_class(`z-50 overflow-hidden border border-neutral-300 bg-neutral-100 shadow-xl dark:border-neutral-700/60 dark:bg-neutral-900 dark:shadow-black/25 ${stringify(roundedClass)} ${fixed ? "fixed" : "absolute " + verticalClass} ${stringify(positionClass)}`)}${attr_style(`min-width: ${stringify(minWidth)}; ${width ? `width: ${width};` : ""} ${stringify(fixed ? fixedStyle : "")}`)}><div class="bg-white/80 dark:bg-neutral-800/50"><!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--></div></div>`);
    bind_props($$props, {
      position,
      mobilePosition,
      minWidth,
      width,
      compact: compact2,
      placement,
      fixed,
      triggerEl,
      onboarding
    });
  });
}
var init_Dropdown = __esm({
  "dist/build/server/chunks/Dropdown.js"() {
    "use strict";
    init_index_server();
    init_server();
  }
});

// dist/build/server/chunks/Icon.js
function Icon($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    const globalProps = getLucideContext() ?? {};
    const { name, color = globalProps.color ?? "currentColor", size = globalProps.size ?? 24, strokeWidth = globalProps.strokeWidth ?? 2, absoluteStrokeWidth = globalProps.absoluteStrokeWidth ?? false, iconNode = [], children, $$slots, $$events, ...props } = $$props;
    const calculatedStrokeWidth = derived(() => absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth);
    $$renderer2.push(`<svg${attributes({
      ...defaultAttributes,
      ...!children && !hasA11yProp(props) && { "aria-hidden": "true" },
      ...props,
      width: size,
      height: size,
      stroke: color,
      "stroke-width": calculatedStrokeWidth(),
      class: clsx([
        "lucide-icon lucide",
        globalProps.class,
        name && `lucide-${name}`,
        props.class
      ])
    }, void 0, void 0, void 0, 3)}><!--[-->`);
    const each_array = ensure_array_like(iconNode);
    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
      let [tag2, attrs] = each_array[$$index];
      element($$renderer2, tag2, () => {
        $$renderer2.push(`${attributes({ ...attrs }, void 0, void 0, void 0, 3)}`);
      });
    }
    $$renderer2.push(`<!--]-->`);
    children?.($$renderer2);
    $$renderer2.push(`<!----></svg>`);
  });
}
var defaultAttributes, hasA11yProp, LucideContext, getLucideContext;
var init_Icon = __esm({
  "dist/build/server/chunks/Icon.js"() {
    "use strict";
    init_index_server();
    init_server();
    defaultAttributes = {
      xmlns: "http://www.w3.org/2000/svg",
      width: 24,
      height: 24,
      viewBox: "0 0 24 24",
      fill: "none",
      stroke: "currentColor",
      "stroke-width": 2,
      "stroke-linecap": "round",
      "stroke-linejoin": "round"
    };
    hasA11yProp = (props) => {
      for (const prop in props) if (prop.startsWith("aria-") || prop === "role" || prop === "title") return true;
      return false;
    };
    LucideContext = /* @__PURE__ */ Symbol("lucide-context");
    getLucideContext = () => getContext(LucideContext);
  }
});

// dist/build/server/chunks/arrow-right.js
function Arrow_right($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "arrow-right" },
    props,
    { iconNode: [["path", { "d": "M5 12h14" }], ["path", { "d": "m12 5 7 7-7 7" }]] }
  ]));
}
var init_arrow_right = __esm({
  "dist/build/server/chunks/arrow-right.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/arrow-up.js
function Arrow_up($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "arrow-up" },
    props,
    { iconNode: [["path", { "d": "m5 12 7-7 7 7" }], ["path", { "d": "M12 19V5" }]] }
  ]));
}
var init_arrow_up = __esm({
  "dist/build/server/chunks/arrow-up.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/check.js
function Check($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "check" },
    props,
    { iconNode: [["path", { "d": "M20 6 9 17l-5-5" }]] }
  ]));
}
var init_check = __esm({
  "dist/build/server/chunks/check.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/chevron-left.js
function Chevron_left($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "chevron-left" },
    props,
    { iconNode: [["path", { "d": "m15 18-6-6 6-6" }]] }
  ]));
}
var init_chevron_left = __esm({
  "dist/build/server/chunks/chevron-left.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/chevron-right.js
function Chevron_right($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "chevron-right" },
    props,
    { iconNode: [["path", { "d": "m9 18 6-6-6-6" }]] }
  ]));
}
var init_chevron_right = __esm({
  "dist/build/server/chunks/chevron-right.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/circle-check-big.js
function Circle_check_big($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "circle-check-big" },
    props,
    { iconNode: [["path", { "d": "M21.801 10A10 10 0 1 1 17 3.335" }], ["path", { "d": "m9 11 3 3L22 4" }]] }
  ]));
}
var init_circle_check_big = __esm({
  "dist/build/server/chunks/circle-check-big.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/circle-check.js
function Circle_check($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "circle-check" },
    props,
    { iconNode: [["circle", {
      "cx": "12",
      "cy": "12",
      "r": "10"
    }], ["path", { "d": "m9 12 2 2 4-4" }]] }
  ]));
}
var init_circle_check = __esm({
  "dist/build/server/chunks/circle-check.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/circle-x.js
function Circle_x($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "circle-x" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "12",
        "cy": "12",
        "r": "10"
      }],
      ["path", { "d": "m15 9-6 6" }],
      ["path", { "d": "m9 9 6 6" }]
    ] }
  ]));
}
var init_circle_x = __esm({
  "dist/build/server/chunks/circle-x.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/clock.js
function Clock($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "clock" },
    props,
    { iconNode: [["circle", {
      "cx": "12",
      "cy": "12",
      "r": "10"
    }], ["path", { "d": "M12 6v6l4 2" }]] }
  ]));
}
var init_clock = __esm({
  "dist/build/server/chunks/clock.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/tv.js
function Film($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "film" },
    props,
    { iconNode: [
      ["rect", {
        "width": "18",
        "height": "18",
        "x": "3",
        "y": "3",
        "rx": "2"
      }],
      ["path", { "d": "M7 3v18" }],
      ["path", { "d": "M3 7.5h4" }],
      ["path", { "d": "M3 12h18" }],
      ["path", { "d": "M3 16.5h4" }],
      ["path", { "d": "M17 3v18" }],
      ["path", { "d": "M17 7.5h4" }],
      ["path", { "d": "M17 16.5h4" }]
    ] }
  ]));
}
function Tv($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "tv" },
    props,
    { iconNode: [["path", { "d": "m17 2-5 5-5-5" }], ["rect", {
      "width": "20",
      "height": "15",
      "x": "2",
      "y": "7",
      "rx": "2"
    }]] }
  ]));
}
var init_tv = __esm({
  "dist/build/server/chunks/tv.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/info.js
function Info($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "info" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "12",
        "cy": "12",
        "r": "10"
      }],
      ["path", { "d": "M12 16v-4" }],
      ["path", { "d": "M12 8h.01" }]
    ] }
  ]));
}
var init_info = __esm({
  "dist/build/server/chunks/info.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/link.js
function Link($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "link" },
    props,
    { iconNode: [["path", { "d": "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }], ["path", { "d": "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" }]] }
  ]));
}
var init_link = __esm({
  "dist/build/server/chunks/link.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/Button.js
function Loader_circle($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "loader-circle" },
    props,
    { iconNode: [["path", { "d": "M21 12a9 9 0 1 1-6.219-8.56" }]] }
  ]));
}
function Tooltip($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let text2 = fallback($$props["text"], "");
    let position = fallback($$props["position"], "bottom");
    let align = fallback($$props["align"], "middle");
    let fullWidth = fallback($$props["fullWidth"], false);
    let mono = fallback($$props["mono"], false);
    $$renderer2.push(`<div${attr_class(clsx(fullWidth ? "flex w-full" : "inline-flex"))}><!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--> `);
    $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, {
      text: text2,
      position,
      align,
      fullWidth,
      mono
    });
  });
}
function Button($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let justifyClass, disabledClass, baseClasses, effectiveSize, widthClass, baseTextColor, baseIconColor, effectiveIcon, effectiveIconColor, isLeadingSvg, isIconOnly, activeSizeClasses, classes, iconSize;
    let text2 = fallback($$props["text"], "");
    let variant = fallback($$props["variant"], "secondary");
    let size = fallback($$props["size"], "sm");
    let disabled = fallback($$props["disabled"], false);
    let softDisabled = fallback($$props["softDisabled"], false);
    let icon = fallback($$props["icon"], null);
    let leadingIcon = fallback($$props["leadingIcon"], null);
    let iconColor = fallback($$props["iconColor"], "");
    let textColor = fallback($$props["textColor"], "");
    let iconPosition = fallback($$props["iconPosition"], "left");
    let type = fallback($$props["type"], "button");
    let responsive = fallback($$props["responsive"], false);
    let hideTextOnMobile = fallback($$props["hideTextOnMobile"], false);
    let fullWidth = fallback($$props["fullWidth"], false);
    let href = fallback($$props["href"], void 0);
    let target = fallback($$props["target"], void 0);
    let rel = fallback($$props["rel"], void 0);
    let justify = fallback($$props["justify"], "center");
    let title = fallback($$props["title"], "");
    let ariaLabel = fallback($$props["ariaLabel"], "");
    let tooltip = fallback($$props["tooltip"], "");
    let tooltipPosition = fallback($$props["tooltipPosition"], "bottom");
    let tooltipAlign = fallback($$props["tooltipAlign"], "middle");
    let loading = fallback($$props["loading"], false);
    let onboarding = fallback($$props["onboarding"], void 0);
    onDestroy(() => {
    });
    const sizeClasses = {
      xs: "gap-1 rounded-lg px-2 py-1 text-xs",
      sm: "gap-1.5 rounded-xl px-3 py-1.5 text-sm md:py-2",
      md: "gap-2 rounded-xl px-4 py-2.5"
    };
    const iconOnlySizeClasses = {
      xs: "rounded-lg p-1.5 text-xs",
      sm: "rounded-xl p-2 text-sm",
      md: "rounded-xl p-2.5"
    };
    const variantClasses = {
      primary: "bg-accent-600 text-white hover:bg-accent-700 dark:bg-accent-500 dark:hover:bg-accent-600",
      secondary: "border border-neutral-300 bg-white text-neutral-700 hover:bg-neutral-100 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-200 dark:hover:bg-neutral-700",
      danger: "bg-red-600 text-white hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600",
      ghost: "text-neutral-500 hover:bg-neutral-100 hover:text-neutral-700 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-200",
      outline: "border border-neutral-300 text-neutral-500 hover:bg-neutral-100 hover:text-neutral-700 dark:border-neutral-700/60 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-200"
    };
    $: justifyClass = justify === "between" ? "justify-between" : "justify-center";
    $: disabledClass = disabled || softDisabled ? "cursor-not-allowed opacity-50" : "cursor-pointer";
    $: baseClasses = `inline-flex items-center ${justifyClass} font-medium transition-colors ${disabledClass}`;
    $: effectiveSize = size;
    $: widthClass = fullWidth ? "w-full" : "";
    $: baseTextColor = textColor || (variant === "ghost" || variant === "outline" ? "text-neutral-700 dark:text-neutral-300" : "");
    $: baseIconColor = iconColor || (variant === "ghost" || variant === "outline" ? "text-neutral-500 dark:text-neutral-400" : "");
    $: effectiveIcon = loading ? Loader_circle : icon;
    $: effectiveIconColor = loading ? baseIconColor + " animate-spin" : baseIconColor;
    $: isLeadingSvg = leadingIcon && typeof leadingIcon === "object" && "path" in leadingIcon;
    $: isIconOnly = icon && !text2 && !leadingIcon;
    $: activeSizeClasses = isIconOnly ? iconOnlySizeClasses : sizeClasses;
    $: classes = `group ${baseClasses} ${activeSizeClasses[effectiveSize]} ${variantClasses[variant]} ${widthClass}`;
    $: iconSize = effectiveSize === "xs" ? 12 : effectiveSize === "sm" ? 14 : 16;
    Tooltip($$renderer2, {
      text: tooltip,
      position: tooltipPosition,
      align: tooltipAlign,
      fullWidth,
      children: ($$renderer3) => {
        if (href) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<a${attr("href", href)}${attr("target", target)}${attr("rel", rel)}${attr("title", !tooltip && title ? title : void 0)}${attr("aria-label", ariaLabel || tooltip || void 0)}${attr("aria-disabled", softDisabled || disabled ? "true" : void 0)}${attr_class(clsx(classes))}${attr("data-onboarding", onboarding)}>`);
          if (effectiveIcon && iconPosition === "left") {
            $$renderer3.push("<!--[0-->");
            if (effectiveIcon) {
              $$renderer3.push("<!--[-->");
              effectiveIcon($$renderer3, {
                size: iconSize,
                class: effectiveIconColor
              });
              $$renderer3.push("<!--]-->");
            } else {
              $$renderer3.push("<!--[!-->");
              $$renderer3.push("<!--]-->");
            }
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          if (leadingIcon) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="inline-flex items-center gap-1.5">`);
            if (isLeadingSvg) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<svg role="img" viewBox="0 0 24 24" fill="currentColor"${attr("width", iconSize)}${attr("height", iconSize)}><path${attr("d", leadingIcon.path)}></path></svg>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              if (leadingIcon) {
                $$renderer3.push("<!--[-->");
                leadingIcon($$renderer3, { size: iconSize });
                $$renderer3.push("<!--]-->");
              } else {
                $$renderer3.push("<!--[!-->");
                $$renderer3.push("<!--]-->");
              }
            }
            $$renderer3.push(`<!--]--> `);
            if (text2) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<span${attr_class(`${stringify(baseTextColor)} ${hideTextOnMobile ? "hidden md:inline" : ""}`)}>${escape_html(text2)}</span>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></span>`);
          } else if (text2) {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<span${attr_class(`${stringify(baseTextColor)} ${hideTextOnMobile ? "hidden md:inline" : ""}`)}>${escape_html(text2)}</span>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> <!--[-->`);
          slot($$renderer3, $$props, "default", {}, null);
          $$renderer3.push(`<!--]--> `);
          if (effectiveIcon && iconPosition === "right") {
            $$renderer3.push("<!--[0-->");
            if (effectiveIcon) {
              $$renderer3.push("<!--[-->");
              effectiveIcon($$renderer3, {
                size: iconSize,
                class: effectiveIconColor
              });
              $$renderer3.push("<!--]-->");
            } else {
              $$renderer3.push("<!--[!-->");
              $$renderer3.push("<!--]-->");
            }
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--></a>`);
        } else {
          $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<button${attr("type", type)}${attr("disabled", disabled, true)}${attr("title", !tooltip && title ? title : void 0)}${attr("aria-label", ariaLabel || tooltip || void 0)}${attr("aria-disabled", softDisabled || disabled ? "true" : void 0)}${attr_class(clsx(classes))}${attr("data-onboarding", onboarding)}>`);
          if (effectiveIcon && iconPosition === "left") {
            $$renderer3.push("<!--[0-->");
            if (effectiveIcon) {
              $$renderer3.push("<!--[-->");
              effectiveIcon($$renderer3, {
                size: iconSize,
                class: effectiveIconColor
              });
              $$renderer3.push("<!--]-->");
            } else {
              $$renderer3.push("<!--[!-->");
              $$renderer3.push("<!--]-->");
            }
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          if (leadingIcon) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="inline-flex items-center gap-1.5">`);
            if (isLeadingSvg) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<svg role="img" viewBox="0 0 24 24" fill="currentColor"${attr("width", iconSize)}${attr("height", iconSize)}><path${attr("d", leadingIcon.path)}></path></svg>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              if (leadingIcon) {
                $$renderer3.push("<!--[-->");
                leadingIcon($$renderer3, { size: iconSize });
                $$renderer3.push("<!--]-->");
              } else {
                $$renderer3.push("<!--[!-->");
                $$renderer3.push("<!--]-->");
              }
            }
            $$renderer3.push(`<!--]--> `);
            if (text2) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<span${attr_class(`${stringify(baseTextColor)} ${hideTextOnMobile ? "hidden md:inline" : ""}`)}>${escape_html(text2)}</span>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></span>`);
          } else if (text2) {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<span${attr_class(`${stringify(baseTextColor)} ${hideTextOnMobile ? "hidden md:inline" : ""}`)}>${escape_html(text2)}</span>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> <!--[-->`);
          slot($$renderer3, $$props, "default", {}, null);
          $$renderer3.push(`<!--]--> `);
          if (effectiveIcon && iconPosition === "right") {
            $$renderer3.push("<!--[0-->");
            if (effectiveIcon) {
              $$renderer3.push("<!--[-->");
              effectiveIcon($$renderer3, {
                size: iconSize,
                class: effectiveIconColor
              });
              $$renderer3.push("<!--]-->");
            } else {
              $$renderer3.push("<!--[!-->");
              $$renderer3.push("<!--]-->");
            }
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--></button>`);
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    bind_props($$props, {
      text: text2,
      variant,
      size,
      disabled,
      softDisabled,
      icon,
      leadingIcon,
      iconColor,
      textColor,
      iconPosition,
      type,
      responsive,
      hideTextOnMobile,
      fullWidth,
      href,
      target,
      rel,
      justify,
      title,
      ariaLabel,
      tooltip,
      tooltipPosition,
      tooltipAlign,
      loading,
      onboarding
    });
  });
}
var init_Button = __esm({
  "dist/build/server/chunks/Button.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/megaphone.js
function Megaphone($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "megaphone" },
    props,
    { iconNode: [
      ["path", { "d": "M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z" }],
      ["path", { "d": "M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14" }],
      ["path", { "d": "M8 6v8" }]
    ] }
  ]));
}
var init_megaphone = __esm({
  "dist/build/server/chunks/megaphone.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/settings.js
function Settings($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "settings" },
    props,
    { iconNode: [["path", { "d": "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" }], ["circle", {
      "cx": "12",
      "cy": "12",
      "r": "3"
    }]] }
  ]));
}
var init_settings = __esm({
  "dist/build/server/chunks/settings.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/sliders-vertical.js
function Sliders_vertical($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "sliders-vertical" },
    props,
    { iconNode: [
      ["path", { "d": "M10 8h4" }],
      ["path", { "d": "M12 21v-9" }],
      ["path", { "d": "M12 8V3" }],
      ["path", { "d": "M17 16h4" }],
      ["path", { "d": "M19 12V3" }],
      ["path", { "d": "M19 21v-5" }],
      ["path", { "d": "M3 14h4" }],
      ["path", { "d": "M5 10V3" }],
      ["path", { "d": "M5 21v-7" }]
    ] }
  ]));
}
var init_sliders_vertical = __esm({
  "dist/build/server/chunks/sliders-vertical.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/tag.js
function Tag($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "tag" },
    props,
    { iconNode: [["path", { "d": "M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z" }], ["circle", {
      "cx": "7.5",
      "cy": "7.5",
      "r": ".5",
      "fill": "currentColor"
    }]] }
  ]));
}
var init_tag = __esm({
  "dist/build/server/chunks/tag.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/triangle-alert.js
function Triangle_alert($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "triangle-alert" },
    props,
    { iconNode: [
      ["path", { "d": "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" }],
      ["path", { "d": "M12 9v4" }],
      ["path", { "d": "M12 17h.01" }]
    ] }
  ]));
}
var init_triangle_alert = __esm({
  "dist/build/server/chunks/triangle-alert.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/wrench.js
function Wrench($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "wrench" },
    props,
    { iconNode: [["path", { "d": "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z" }]] }
  ]));
}
var init_wrench = __esm({
  "dist/build/server/chunks/wrench.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/x.js
function X2($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "x" },
    props,
    { iconNode: [["path", { "d": "M18 6 6 18" }], ["path", { "d": "m6 6 12 12" }]] }
  ]));
}
var init_x = __esm({
  "dist/build/server/chunks/x.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/theme.js
function createThemeStore() {
  const { subscribe: subscribe2, update: update4 } = writable("dark");
  function toggle() {
    update4((current3) => {
      return current3 === "light" ? "dark" : "light";
    });
  }
  return {
    subscribe: subscribe2,
    toggle
  };
}
var themeStore;
var init_theme = __esm({
  "dist/build/server/chunks/theme.js"() {
    "use strict";
    init_server();
    init_index_server2();
    themeStore = createThemeStore();
  }
});

// dist/build/server/chunks/client4.js
function add_navigation_callback(callbacks, callback) {
  onMount(() => {
    callbacks.add(callback);
    return () => {
      callbacks.delete(callback);
    };
  });
}
function afterNavigate(callback) {
  add_navigation_callback(after_navigate_callbacks, callback);
}
function beforeNavigate(callback) {
  add_navigation_callback(before_navigate_callbacks, callback);
}
function goto(url, opts = {}) {
  throw new Error("Cannot call goto(...) on the server");
}
function invalidateAll() {
  throw new Error("Cannot call invalidateAll() on the server");
}
var PRELOAD_PRIORITIES, updated_listener, updated2, is_legacy, placeholder_url, onMount, tick2, before_navigate_callbacks, after_navigate_callbacks;
var init_client4 = __esm({
  "dist/build/server/chunks/client4.js"() {
    "use strict";
    init_index_server();
    init_shared();
    init_internal2();
    init_internal22();
    init_exports2();
    init_server();
    init_index_server2();
    init_internal();
    init_server2();
    PRELOAD_PRIORITIES = {
      tap: 1,
      hover: 2,
      viewport: 3,
      eager: 4,
      off: -1,
      false: -1
    };
    ({ ...PRELOAD_PRIORITIES }, PRELOAD_PRIORITIES.hover);
    updated_listener = { v: noop2 };
    is_legacy = noop.toString().includes("$$") || /function \w+\(\) \{\}/.test(noop.toString());
    placeholder_url = "a:";
    if (is_legacy) {
      new URL(placeholder_url);
      updated2 = { current: false };
    } else {
      new class Page {
        data = {};
        form = null;
        error = null;
        params = {};
        route = { id: null };
        state = {};
        status = -1;
        url = new URL(placeholder_url);
      }();
      new class Navigating {
        current = null;
      }();
      updated2 = new class Updated {
        current = false;
      }();
      updated_listener.v = () => updated2.current = true;
    }
    ({ onMount, tick: tick2 } = index_server_exports);
    before_navigate_callbacks = /* @__PURE__ */ new Set();
    after_navigate_callbacks = /* @__PURE__ */ new Set();
  }
});

// dist/build/server/chunks/stores.js
var getStores, page;
var init_stores = __esm({
  "dist/build/server/chunks/stores.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_client4();
    getStores = () => {
      const stores$1 = getContext("__svelte__");
      return {
        /** @type {typeof page} */
        page: { subscribe: stores$1.page.subscribe },
        /** @type {typeof navigating} */
        navigating: { subscribe: stores$1.navigating.subscribe },
        /** @type {typeof updated} */
        updated: stores$1.updated
      };
    };
    page = { subscribe(fn) {
      return getStores().page.subscribe(fn);
    } };
  }
});

// dist/build/server/chunks/store2.js
function createAlertSettingsStore() {
  const { subscribe: subscribe2, set: set3 } = writable(DEFAULT_ALERT_SETTINGS);
  function setSettings(next2) {
    set3(next2);
  }
  return {
    subscribe: subscribe2,
    setSettings
  };
}
function createAlertStore() {
  const { subscribe: subscribe2, update: update4 } = writable([]);
  return {
    subscribe: subscribe2,
    add: (type, message2, duration) => {
      const settingsDuration = get(alertSettingsStore).durationMs;
      const resolvedDuration = typeof duration === "number" ? duration : settingsDuration;
      const id = uuid();
      const alert = {
        id,
        type,
        message: message2,
        duration: resolvedDuration
      };
      update4((alerts) => [...alerts, alert]);
      if (resolvedDuration > 0) setTimeout(() => {
        update4((alerts) => alerts.filter((a2) => a2.id !== id));
      }, resolvedDuration);
      return id;
    },
    remove: (id) => {
      update4((alerts) => alerts.filter((a2) => a2.id !== id));
    },
    clear: () => {
      update4(() => []);
    }
  };
}
var ALERT_POSITIONS, DEFAULT_ALERT_SETTINGS, alertSettingsStore, alertStore;
var init_store2 = __esm({
  "dist/build/server/chunks/store2.js"() {
    "use strict";
    init_server();
    init_index_server2();
    init_uuid();
    ALERT_POSITIONS = [
      "top-left",
      "top-center",
      "top-right",
      "bottom-left",
      "bottom-center",
      "bottom-right"
    ];
    DEFAULT_ALERT_SETTINGS = {
      position: "top-center",
      durationMs: 8e3
    };
    new Set(ALERT_POSITIONS);
    alertSettingsStore = createAlertSettingsStore();
    alertStore = createAlertStore();
  }
});

// dist/build/server/chunks/store.js
async function checkPrerequisites(stageId) {
  const stage2 = STAGES[stageId];
  if (!stage2?.prerequisites) return { ok: true };
  for (const prereq of stage2.prerequisites) {
    const check = stateChecks[prereq.check];
    if (!check) continue;
    if (!await check()) return {
      ok: false,
      message: prereq.message
    };
  }
  return { ok: true };
}
function loadState() {
  return DEFAULT_STATE;
}
function createCutsceneStore() {
  const state2 = writable(loadState());
  const justCompleted = writable(false);
  const currentStep = derived$1(state2, ($state) => {
    if (!$state.active || !$state.stageId) return null;
    const stage2 = STAGES[$state.stageId];
    if (!stage2) return null;
    return stage2.steps[$state.stepIndex] ?? null;
  });
  const currentStage = derived$1(state2, ($state) => {
    if (!$state.stageId) return null;
    return STAGES[$state.stageId] ?? null;
  });
  function init3() {
    const restored = loadState();
    if (restored.active) state2.set(restored);
  }
  async function startStage(stageId, manual = true) {
    const stage2 = STAGES[stageId];
    if (!stage2 || stage2.steps.length === 0) return;
    const result = await checkPrerequisites(stageId);
    if (!result.ok) {
      alertStore.add("error", result.message);
      return;
    }
    justCompleted.set(false);
    const newState = {
      active: true,
      stageId,
      stepIndex: 0,
      manualStart: manual
    };
    state2.set(newState);
  }
  function goBack() {
    state2.update((current3) => {
      if (!current3.active || !current3.stageId) return current3;
      if (current3.stepIndex > 0) return {
        ...current3,
        stepIndex: current3.stepIndex - 1
      };
      return current3;
    });
  }
  function advance() {
    state2.update((current3) => {
      if (!current3.active || !current3.stageId) return current3;
      const stage2 = STAGES[current3.stageId];
      if (!stage2) return current3;
      const nextStepIndex = current3.stepIndex + 1;
      if (nextStepIndex < stage2.steps.length) return {
        ...current3,
        stepIndex: nextStepIndex
      };
      const lastStage = STAGES[current3.stageId];
      if (current3.manualStart && !lastStage?.silent) justCompleted.set(true);
      return DEFAULT_STATE;
    });
  }
  function cancel() {
    if (loadState().manualStart) justCompleted.set(true);
    state2.set(DEFAULT_STATE);
  }
  function reset2() {
    state2.set(DEFAULT_STATE);
  }
  function dismissCompleted() {
    justCompleted.set(false);
  }
  return {
    subscribe: state2.subscribe,
    currentStep,
    currentStage,
    justCompleted: { subscribe: justCompleted.subscribe },
    init: init3,
    startStage,
    advance,
    goBack,
    cancel,
    dismissCompleted,
    reset: reset2
  };
}
var STAGES, GROUPS, stateChecks, DEFAULT_STATE, cutscene;
var init_store = __esm({
  "dist/build/server/chunks/store.js"() {
    "use strict";
    init_server();
    init_index_server2();
    init_stores();
    init_store2();
    STAGES = {
      welcome: {
        id: "welcome",
        name: "Welcome",
        description: "What Profilarr is and how it works",
        steps: [
          {
            id: "what-is-profilarr",
            title: "Welcome to Profilarr",
            body: "Profilarr helps you build, test, and deploy media server configurations. Instead of manually configuring Radarr and Sonarr, you connect to curated databases and sync everything across your instances, while keeping any local tweaks you make.",
            completion: { type: "manual" }
          },
          {
            id: "nav-onboarding",
            target: "nav-onboarding",
            title: "Learning Profilarr",
            body: "This is the onboarding page. It lives under Settings in the sidebar. Click it to get started.",
            position: "right",
            completion: { type: "click" }
          },
          {
            id: "welcome-onboarding",
            title: "The Onboarding Page",
            body: "Each walkthrough here teaches one part of Profilarr with guided, hands-on steps. You can come back here anytime from Settings in the sidebar.",
            completion: { type: "manual" }
          }
        ]
      },
      navigation: {
        id: "navigation",
        name: "Navigation",
        description: "The main sections of the app",
        steps: [
          {
            id: "sidebar-overview",
            target: "sidebar",
            title: "Navigation",
            body: "Let's take a quick look at the main sections of the app.",
            position: "right",
            completion: { type: "manual" }
          },
          {
            id: "nav-databases",
            route: "/databases",
            target: "nav-databases",
            title: "Databases",
            body: "Databases are where your configurations come from. Connect one and everything inside is ready to browse, customize, and deploy to your Arr instances. We'll walk through connecting one later.",
            position: "right",
            completion: { type: "manual" }
          },
          {
            id: "nav-arrs",
            route: "/arr",
            target: "nav-arrs",
            title: "Arrs",
            body: "Your Arrs are the Radarr and Sonarr instances that Profilarr manages. Add them here, and any configurations you set up will sync directly to each one. You can connect as many as you need.",
            position: "right",
            completion: { type: "manual" }
          },
          {
            id: "nav-config-entities",
            target: "nav-config-entities",
            title: "Configurations",
            body: "Databases provide several types of configuration: quality profiles, custom formats, regular expressions, delay profiles, and media management settings like naming and quality definitions. Each has its own section in the sidebar. We'll cover them in more detail later.",
            position: "right",
            completion: { type: "manual" }
          },
          {
            id: "nav-settings",
            route: "/settings",
            target: "nav-settings",
            title: "Settings",
            body: "This is where you configure Profilarr itself. Scheduled jobs, notification alerts, security, backups, and general preferences all live here. Most defaults work out of the box, so you can come back to this later.",
            position: "right",
            completion: { type: "manual" }
          }
        ]
      },
      personalize: {
        id: "personalize",
        name: "Personalize",
        description: "Set your theme and accent color",
        steps: [{
          id: "theme-toggle",
          target: "theme-toggle",
          title: "Theme",
          body: "Click this to toggle between light and dark mode. Try it out, then continue.",
          position: "center",
          completion: { type: "manual" }
        }, {
          id: "accent-picker",
          target: "accent-picker",
          title: "Accent Color",
          body: "Pick a color that suits you. Click to open the picker, then choose one you like.",
          position: "center",
          freeInteract: true,
          completion: { type: "manual" }
        }]
      },
      "database-link": {
        id: "database-link",
        name: "Link",
        description: "Connect a configuration database",
        steps: [
          {
            id: "databases-explain",
            target: "nav-databases",
            title: "Databases",
            body: "Now let's set up a database. Remember, databases are git repositories containing pre-built custom formats, quality profiles, and more. Anyone can create a Profilarr-compliant database, and you can connect as many as you like. A default database has already been connected for you, but you're free to remove it and use your own. Click Databases to continue.",
            position: "below-right",
            completion: { type: "click" }
          },
          {
            id: "databases-add",
            route: "/databases",
            target: "db-add",
            title: "Connect a New Database",
            body: "Click here to start connecting a new database.",
            position: "below-left",
            completion: { type: "click" }
          },
          {
            id: "databases-form",
            route: "/databases/new",
            target: "db-name-repo-branch",
            title: "Name, Repository & Branch",
            body: "Start by giving your database a friendly name, then paste in a GitHub repository URL. You can also specify a branch if you need one other than the default. Only GitHub is supported at the moment. If you ever need the same database on a different branch, just connect it again with a different branch selected.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "databases-pat",
            target: "db-pat",
            title: "Personal Access Token",
            body: "You only need this if you're connecting to a private repository, or if you're a database maintainer who needs to push updates back to GitHub. For most users this can be left blank. And no, you can't accidentally push anything to someone else's repo without one.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "databases-conflict",
            target: "db-conflict",
            title: "Conflict Strategy",
            body: "One of Profilarr's strengths is letting you tweak configurations locally. Occasionally those tweaks will conflict with an upstream update from the database. This setting controls what happens when that occurs: you can keep your version, accept the upstream change, or review each conflict yourself.",
            position: "above",
            completion: { type: "manual" }
          },
          {
            id: "databases-sync",
            target: "db-sync",
            title: "Sync & Auto Pull",
            body: "This controls how often Profilarr checks the remote repository for new updates, and whether those updates should be pulled in automatically or just trigger a notification so you can review them first.",
            position: "above",
            completion: { type: "manual" }
          },
          {
            id: "databases-save",
            target: "db-save",
            title: "Save",
            body: "Once you're happy with your settings, hit Save to connect the database. Profilarr will clone the repository and import all its configurations.",
            position: "below-left",
            completion: { type: "manual" }
          }
        ]
      },
      "database-manage": {
        id: "database-manage",
        name: "Overview",
        description: "Tabs and features of a connected database",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "db-nav-changes",
            route: { resolve: "firstDatabaseChanges" },
            target: "db-tab-changes",
            title: "Changes",
            body: "The Changes tab is your sync dashboard. It shows the current git status of the database and any incoming upstream updates you haven't pulled yet. From here you can pull updates to stay in sync. If you're a database developer, you'll also see your outgoing draft changes with options to export and commit them back to the repository.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "db-nav-commits",
            route: { resolve: "firstDatabaseCommits" },
            target: "db-tab-commits",
            title: "Commits",
            body: "The Commits tab shows the commit history of the database repository. You can see what changed, when, and by whom.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "db-nav-conflicts",
            route: { resolve: "firstDatabaseConflicts" },
            target: "db-tab-conflicts",
            title: "Conflicts",
            body: "When your local tweaks clash with an upstream update, they surface here. Each conflict shows what changed on both sides. You can resolve them by aligning (dropping your change in favor of upstream) or overriding (keeping your version). The conflict strategy you set on the database controls whether this happens automatically or waits for your input.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "db-nav-tweaks",
            route: { resolve: "firstDatabaseTweaks" },
            target: "db-tab-tweaks",
            title: "Tweaks",
            body: "The Tweaks tab is where you'll be able to view and manage your local overrides. This section is still being built.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "db-nav-settings",
            route: { resolve: "firstDatabaseSettings" },
            target: "db-tab-settings",
            title: "Settings",
            body: "The Settings tab lets you configure this database's name, sync schedule, auto-pull behavior, and conflict resolution strategy. You can also disconnect the database from here.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "db-summary",
            title: "You're set up with databases",
            body: "You've learned how to connect a database and explored the tabs where you'll manage changes, review commits, resolve conflicts, and configure settings. Your databases will stay in sync automatically if auto-pull is enabled, and any conflicts between your local tweaks and upstream updates will surface in the Conflicts tab when they happen.",
            completion: { type: "manual" }
          }
        ]
      },
      "arr-link": {
        id: "arr-link",
        name: "Link",
        description: "Connect a Radarr or Sonarr instance",
        steps: [
          {
            id: "arr-explain",
            target: "nav-arrs",
            title: "Arrs",
            body: "Now let's connect an Arr instance. Arrs are your Radarr and Sonarr instances that Profilarr manages. Once connected, you can push configurations directly to them. Click Arrs to continue.",
            position: "right",
            completion: { type: "click" }
          },
          {
            id: "arr-add",
            route: "/arr",
            target: "arr-add",
            title: "Add an Instance",
            body: "Click here to start connecting a new Arr instance.",
            position: "below-left",
            completion: { type: "click" }
          },
          {
            id: "arr-type",
            route: "/arr/new",
            target: "arr-type",
            title: "Instance Type",
            body: "First, select whether this is a Radarr (movies) or Sonarr (TV shows) instance.",
            position: "center",
            interactionTargets: ["arr-type-menu"],
            completion: { type: "manual" }
          },
          {
            id: "arr-connection",
            target: "arr-connection",
            title: "Connection Details",
            body: "Give your instance a name, enter its URL, and paste the API key. You can find the API key in your Arr's Settings > General page. If you're running both Profilarr and your Arr in Docker, use the container name as the host (e.g. http://radarr:7878).",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "arr-save",
            target: "arr-save",
            title: "Save",
            body: "Once you've filled in the connection details, hit Save to connect the instance. Profilarr will verify the connection and add it to your setup.",
            position: "below-left",
            completion: { type: "manual" }
          }
        ]
      },
      "arr-manage": {
        id: "arr-manage",
        name: "Overview",
        description: "Tabs and features of a connected Arr instance",
        prerequisites: [{
          check: "hasArrInstance",
          message: 'You need at least one connected Arr instance to start this stage. Follow the "Link" stage under Arr Instances from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "arr-nav-sync",
            route: { resolve: "firstArrSync" },
            target: "arr-tab-sync",
            title: "Sync",
            body: "The Sync tab is where you configure what gets pushed to this instance. You'll set up media management, delay profiles, and quality profiles here. We'll walk through this in a dedicated stage later.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "arr-nav-library",
            route: { resolve: "firstArrLibrary" },
            target: "arr-tab-library",
            title: "Library",
            body: "The Library tab shows everything on your Arr instance: movies for Radarr, series for Sonarr. You can browse items, see their quality profiles, custom format scores, and whether they've hit their quality cutoff.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "arr-nav-drift",
            route: { resolve: "firstArrDrift" },
            target: "arr-tab-drift",
            title: "Drift",
            body: "The Drift tab catches changes made directly to this Arr that no longer match your Profilarr config. Each drifted item is listed with the exact differences, so you can review what's changed and re-sync when you're ready. It also drives the per-section progress chips on the Sync tab, so you can see at a glance how much of your config is still in sync.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "arr-nav-upgrades",
            route: { resolve: "firstArrUpgrades" },
            target: "arr-tab-upgrades",
            title: "Upgrades",
            body: "The Upgrades tab lets you configure automated searches for better quality releases. Set up filters to target specific items and schedules to run searches automatically. We'll cover this in a dedicated stage later.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "arr-nav-renames",
            route: { resolve: "firstArrRename" },
            target: "arr-tab-renames",
            title: "Renames",
            body: "The Renames tab handles bulk file and folder renaming to match your naming conventions. You can preview changes with a dry run before applying them. We'll cover this in a dedicated stage later.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "arr-nav-logs",
            route: { resolve: "firstArrLogs" },
            target: "arr-tab-logs",
            title: "Logs",
            body: "The Logs tab shows activity from this Arr instance. You can filter by log level and search for specific entries.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "arr-nav-settings",
            route: { resolve: "firstArrSettings" },
            target: "arr-tab-settings",
            title: "Settings",
            body: "The Settings tab lets you update connection details, configure library refresh intervals, set up automatic cleanup of stale configurations, and remove the instance if needed.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "arr-summary",
            title: "You're connected",
            body: "You've learned how to connect an Arr instance and explored the tabs where you'll manage your setup. The next steps are configuring sync to push configurations to your instance, setting up automated upgrades to search for better releases, and configuring renames to keep your files organized. Each of these has a dedicated walkthrough you can run from the onboarding page.",
            completion: { type: "manual" }
          }
        ]
      },
      "arr-sync": {
        id: "arr-sync",
        name: "Sync",
        description: "Configure what gets synced and when",
        prerequisites: [{
          check: "hasArrInstance",
          message: 'You need at least one connected Arr instance to start this stage. Follow the "Link" stage under Arr Instances from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "sync-overview",
            route: { resolve: "firstArrSync" },
            title: "What is Sync?",
            body: "Sync pushes configurations from your databases into your Arr instances. Profilarr stores everything in its own format, then compiles it into what Radarr or Sonarr expects. This lets Profilarr do things the Arrs can't natively, like reusing regular expressions across custom formats.",
            completion: { type: "manual" }
          },
          {
            id: "sync-media-management",
            target: "sync-media-management",
            title: "Media Management",
            body: "Media management covers naming conventions, quality definitions, and media settings. This needs to be configured and saved before quality profiles can be synced.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "sync-delay-profiles",
            target: "sync-delay-profiles",
            title: "Delay Profiles",
            body: "Delay profiles control protocol preferences, delays, and score gates. Like media management, these must be configured and saved before quality profiles.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "sync-quality-profiles",
            target: "sync-quality-profiles",
            title: "Quality Profiles",
            body: "Quality profiles are the core of your configuration. Select which profiles to sync from your connected databases. Custom formats don't need to be selected individually; if a custom format is part of a quality profile, it syncs automatically.",
            position: "above",
            completion: { type: "manual" }
          },
          {
            id: "sync-required",
            title: "Required Syncing",
            body: "Quality profiles can't sync until media management and delay profiles have been saved. The custom formats and scoring inside a profile are tuned to work with specific naming, file size tiers, and protocol delays. Without those in place, the profile still syncs, but matching, scoring, and renaming break in ways that are hard to spot until something goes wrong. You're welcome to use your own naming scheme or settings if you create and sync them through the database. Just know that the recommended setup exists for a reason, and deviating from it without understanding what each piece does will produce broken results.",
            completion: { type: "manual" }
          },
          {
            id: "sync-trigger",
            target: "sync-trigger",
            title: "Triggers",
            body: "Each section has its own trigger that controls when sync happens. Manual means you click sync yourself. On Pull syncs automatically when new changes arrive from a database. Schedule runs on a cron expression you define.",
            position: "below-right",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "sync-how-it-works",
            target: "sync-how-it-works",
            title: "How it Works",
            body: "For a deeper breakdown of sync mechanics, triggers, cron expressions, and setup order, click this button anytime. It covers everything in detail.",
            position: "below-left",
            completion: { type: "manual" }
          },
          {
            id: "sync-summary",
            title: "Ready to Sync",
            body: "Configure from top to bottom: media management and delay profiles first, then quality profiles. Custom formats come along with their quality profiles automatically. Each section can have its own trigger, so you can mix manual and automatic syncing.",
            completion: { type: "manual" }
          }
        ]
      },
      "arr-upgrades": {
        id: "arr-upgrades",
        name: "Upgrades",
        description: "Automated searching for better quality releases",
        prerequisites: [{
          check: "hasArrInstance",
          message: 'You need at least one connected Arr instance to start this stage. Follow the "Link" stage under Arr Instances from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "upgrades-why",
            route: { resolve: "firstArrUpgrades" },
            title: "Why Upgrades?",
            body: "Arrs only search for releases when you first add something, then rely on RSS feeds to find upgrades. This works most of the time, but misses edge cases: your best indexers might have been down when a better release appeared, you might switch quality profiles, or a profile update might change what counts as an upgrade. Upgrades fills that gap by actively searching your library on a schedule.",
            completion: { type: "manual" }
          },
          {
            id: "upgrades-filters",
            target: "upgrades-filters",
            title: "Filters",
            body: "Filters define which items in your library are eligible for upgrade searching. You can create multiple filters for different purposes: one for old movies below cutoff, another for recent additions, etc.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "upgrades-add-filter",
            target: "upgrades-add-filter",
            title: "Add a Filter",
            body: "Click to create your first filter. This opens the filter editor where you can configure rules and settings.",
            position: "below-left",
            completion: { type: "click" }
          },
          {
            id: "upgrades-filter-rules",
            target: "upgrades-filter-rules",
            title: "Filter Rules",
            body: 'Rules match items by field: title, year, rating, status, tags, and more. Combine rules with "All" (AND) or "Any" (OR) logic. Groups can be nested for complex conditions. For example: status is Released AND (rating > 7 OR year > 2020).',
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "upgrades-cutoff",
            target: "upgrades-cutoff",
            title: "Cutoff %",
            body: `This sets the score threshold for the "cutoff met" field. If your quality profile's cutoff score is 90 and you set this to 80%, items scoring below 72 are considered below cutoff. Pair it with a "cutoff met is false" rule to target items that haven't reached your quality goals.`,
            position: "above",
            completion: { type: "manual" }
          },
          {
            id: "upgrades-method",
            target: "upgrades-method",
            title: "Method",
            body: "The selector determines how items are prioritized from the matched set. Oldest targets items that have been waiting the longest. Lowest Score finds items furthest from your quality goals. Random spreads searches evenly.",
            position: "above",
            completion: { type: "manual" }
          },
          {
            id: "upgrades-count",
            target: "upgrades-count",
            title: "Count",
            body: "How many items to search per run. This is capped based on your schedule: more frequent runs means a lower max. The cap exists because indexers rate limit search requests. Profilarr calculates the safe maximum automatically.",
            position: "above",
            completion: { type: "manual" }
          },
          {
            id: "upgrades-cooldown",
            target: "upgrades-cooldown",
            title: "Cooldown Tag",
            body: "After an item is searched, it gets tagged in your Arr instance so it won't be picked again next run. This spreads searches across your entire library over time. When every matched item has been tagged, the tags reset and the cycle starts over.",
            position: "above",
            completion: { type: "manual" }
          },
          {
            id: "upgrades-schedule",
            target: "upgrades-schedule",
            title: "The Schedule",
            body: "This controls how often a filter runs. Each time the schedule fires, only one filter executes. This is intentional; indexers rate limit search requests, and hitting them too aggressively can get you throttled or banned.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "upgrades-filter-mode",
            target: "upgrades-filter-mode",
            title: "Filter Mode",
            body: "The mode controls which filter runs on each tick. Round robin cycles through your enabled filters in order. Random picks one at random. Either way, only one filter fires per scheduled run.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "upgrades-summary",
            title: "Ready to Upgrade",
            body: "Filters target items, selectors prioritize them, the schedule spaces everything out safely. Start with a dry run to test your setup, then enable when you are confident.",
            completion: { type: "manual" }
          }
        ]
      },
      "arr-renames": {
        id: "arr-renames",
        name: "Rename",
        description: "Automated file and folder renaming",
        prerequisites: [{
          check: "hasArrInstance",
          message: 'You need at least one connected Arr instance to start this stage. Follow the "Link" stage under Arr Instances from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "rename-why",
            route: { resolve: "firstArrRename" },
            title: "Why Rename?",
            body: "Arrs name files when they're first grabbed, but file names can fall out of sync over time. TBA episodes get placeholder names that need updating once the real title is known. Switching naming conventions or syncing new naming settings from a database leaves existing files with the old format. Rename catches all of this by comparing every file against your current naming format and fixing anything that doesn't match.",
            completion: { type: "manual" }
          },
          {
            id: "rename-what",
            title: "What is Rename?",
            body: "Rename scans your library, compares each file name against your naming format, and renames anything that doesn't match. You can preview changes with a dry run before applying them.",
            completion: { type: "manual" }
          },
          {
            id: "rename-folders",
            target: "rename-folders",
            title: "Rename Folders",
            body: "When enabled, folders are renamed alongside files. When off, only file names are updated.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "rename-summary",
            target: "rename-summary",
            title: "Summary Notifications",
            body: "Controls how rename notifications are sent. Summary mode sends a compact notification with a total count. Detailed mode lists every renamed file individually.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "rename-schedule",
            target: "rename-schedule",
            title: "Schedule",
            body: "How often renames run automatically. The default is daily at midnight. Like upgrades, this uses a cron expression.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "rename-ignore-tag",
            target: "rename-ignore-tag",
            title: "Ignore Tag",
            body: "Items tagged with this value in your Arr instance will be skipped during renames. Useful for excluding items you've manually named or don't want touched.",
            position: "below",
            completion: { type: "manual" }
          },
          {
            id: "rename-summary-step",
            title: "Ready to Rename",
            body: "Start with a dry run from the button above to preview what would be renamed before running it live.",
            completion: { type: "manual" }
          }
        ]
      },
      "cf-general": {
        id: "cf-general",
        name: "General",
        description: "Identity, rename behavior, and references for a custom format",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "cf-general-intro",
            route: { resolve: "firstCustomFormatGeneral" },
            title: "Custom Formats",
            body: "A custom format is a name attached to a set of conditions. When a release matches those conditions, the format applies, identifying something about the release: a codec, a release group, a source, a resolution. Quality profiles then score matched formats to rank competing releases. This stage walks through the General tab, where you set a format's identity and rename behavior.",
            completion: { type: "manual" }
          },
          {
            id: "cf-general-name",
            target: "cf-general-name",
            title: "Name",
            body: "The name identifies this format in quality profiles and filenames. Keep it short and descriptive.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-general-include-in-rename",
            target: "cf-general-include-in-rename",
            title: "Include In Rename",
            body: "When enabled, this format's name is appended to renamed filenames whenever a release matches. Use it to surface important tags like REMUX or HDR in the file itself. Leave it off for formats that shouldn't show up in filenames.",
            position: "below-left",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-general-description-tags",
            target: "cf-general-description-tags",
            title: "Description & Tags",
            body: "Description is a markdown field for notes about what this format matches and why. Tags group formats for filtering on the custom formats list: codec, audio, HDR, language, and so on. Neither affects matching or scoring, but both pay off when you are looking through a large library of formats later.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-general-references",
            target: "cf-general-references",
            title: "References",
            body: "References lists every quality profile this format appears in, along with the score it receives in Radarr and Sonarr. Scoring is a profile-level setting, so the same format can be weighted differently in different profiles. This view is a quick check for where a change to the format might ripple before you make it.",
            position: "above",
            completion: { type: "manual" }
          },
          {
            id: "cf-general-summary",
            title: "Summary",
            body: "Name, include in rename, description, and tags all live on the General tab, and the References section shows where this format is scored. Next you will define what the format actually matches by adding conditions.",
            completion: { type: "manual" }
          }
        ]
      },
      "cf-conditions": {
        id: "cf-conditions",
        name: "Conditions",
        description: "Define what a custom format matches on a release",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "cf-conditions-intro",
            route: { resolve: "firstCustomFormatConditions" },
            title: "Conditions",
            body: "Conditions are the rules that decide whether a release matches a custom format. Each one targets a specific piece of parsed metadata (release title, release group, source, resolution, language, year, size, and so on) and checks it against a value or regex pattern. Conditions of the same type are combined with OR by default, and conditions across types are combined with AND. Two modifiers, Required and Negate, let you flip that logic where needed. This stage walks through adding one condition from scratch.",
            completion: { type: "manual" }
          },
          {
            id: "cf-conditions-add",
            target: "cf-conditions-add",
            title: "Add a Condition",
            body: "Click Add Condition to spawn a draft card. Drafts sit at the top of the list until you confirm them, which keeps you from accidentally saving a half-configured rule.",
            position: "below-left",
            completion: { type: "click" }
          },
          {
            id: "cf-conditions-name",
            target: "cf-cond-name",
            title: "Name",
            body: "Names label conditions within a format and must be unique. A good name describes the match in plain language (for example, '1080p' or 'FraMeSToR release group') so the purpose is obvious when you revisit the format later.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-conditions-type",
            target: "cf-cond-type",
            title: "Type",
            body: "Type chooses which piece of parsed metadata this condition looks at. Release Title, Release Group, and Edition take regex patterns. Resolution, Source, Quality Modifier, Language, Release Type, and Indexer Flag pick from a fixed list. Size and Year take a numeric range. The value field adapts to the type you pick.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-conditions-value",
            target: "cf-cond-value",
            title: "Value",
            body: "Value is what the condition actually matches against. For Release Title, Release Group, and Edition you pick a reusable regex pattern managed on the Regular Expressions page, which means one pattern can power many custom formats. For the other types you pick from a dropdown or enter a numeric range.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-conditions-modifiers",
            target: "cf-cond-flags-modifiers",
            title: "Required & Negate",
            body: "Required switches the logic within a type from OR to AND, so every Required condition of that type must match. Negate inverts a single condition so it matches when the pattern is absent rather than present. Together they cover the 'must have all of these' and 'must not have this' cases.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-conditions-arr",
            target: "cf-cond-flags-arr",
            title: "Radarr & Sonarr",
            body: "Radarr and Sonarr toggle which apps this condition applies to. Some metadata (Edition, Quality Modifier) only exists in Radarr; Release Type only exists in Sonarr. For everything else you can keep both on to share one condition across movies and series, or split it if the two apps need different rules.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-conditions-summary",
            title: "Summary",
            body: "Each condition pairs a type with a value. Required and Negate flip the matching logic, and the Radarr/Sonarr toggles scope it per app. Stack conditions to narrow a format down to exactly the releases you want, then head to Testing to verify it.",
            completion: { type: "manual" }
          }
        ]
      },
      "cf-testing": {
        id: "cf-testing",
        name: "Testing",
        description: "Verify a custom format against real release titles",
        prerequisites: [{
          check: "hasDevDatabase",
          message: "You need at least one development database (a database with a personal access token and local ops disabled) to start this stage. Testing is only editable on databases you own."
        }, {
          check: "parserHealthy",
          message: "The parser service is not running. Start the Profilarr parser microservice so test results can be evaluated before running this stage."
        }],
        steps: [
          {
            id: "cf-testing-intro",
            route: { resolve: "firstDevCustomFormatTesting" },
            title: "Testing",
            body: "Tests let you feed a release title into a custom format and see whether it matches, along with the parsed metadata and per-condition breakdown. Regex is easy to get subtly wrong, so tests are the safety net that proves a format does what you intended before it ends up in a quality profile. This tab is editable on development databases; other databases show tests read-only.",
            completion: { type: "manual" }
          },
          {
            id: "cf-testing-add",
            target: "cf-testing-add",
            title: "Add a Test",
            body: "Click Add Test to open a blank test form. Each test pins a release title to an expected outcome, which is how you lock in regressions as the format evolves.",
            position: "below-left",
            completion: { type: "click" }
          },
          {
            id: "cf-testing-title",
            target: "cf-test-title",
            title: "Release Title",
            body: "The release title is what gets parsed and matched against the format. Paste a real release name (for example, Movie.Name.2024.1080p.BluRay.x264-GROUP) rather than a paraphrased one, since small differences in the string can change how the parser extracts source, resolution, and group.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-testing-type",
            target: "cf-test-type",
            title: "Media Type",
            body: "Movie and Series tell the parser which naming conventions to apply. Series releases expose season and episode metadata and release types that movies do not, so picking the wrong type can change what the format sees. Match the type to where the release would actually come from.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-testing-expected",
            target: "cf-test-expected",
            title: "Expected Result",
            body: "Expected Result is your assertion: should this title match the format or not? Pass means the parsed metadata matches and the actual outcome equals the expected one. Include both positive cases (titles that should match) and negative ones (titles that look close but shouldn't) to catch regex drift in both directions.",
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-testing-description",
            target: "cf-test-description",
            title: "Description",
            body: "Description is optional context for a test case: what edge case it covers, which bug it guards against, or which real-world release it came from. It is never used for matching, only for you and anyone else reading the test list later.",
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "cf-testing-summary",
            title: "Summary",
            body: "Tests turn a custom format from something that looks right into something you can prove is right. Build up a small set of tests covering the matches you expect and the near-misses you want to avoid, and rerun them whenever the format or its patterns change.",
            completion: { type: "manual" }
          }
        ]
      },
      "qp-general": {
        id: "qp-general",
        name: "General",
        description: "Identity, description, tags, and language for a quality profile",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "qp-general-intro",
            route: { resolve: "firstQualityProfileGeneral" },
            title: "Quality Profiles",
            body: "A quality profile decides which releases Radarr and Sonarr are allowed to grab and which one they prefer when several match. It does this in two layers: qualities sort releases into coarse tiers (1080p BluRay, 2160p Remux, and so on) and custom format scores break ties inside each tier. This stage walks through the General tab, where you set a profile's identity.",
            completion: { type: "manual" }
          },
          {
            id: "qp-general-name",
            target: "qp-general-name",
            title: "Name",
            body: 'The name identifies this profile when you link it to a Radarr or Sonarr instance. Keep it descriptive (for example "Remux Tier" or "Streaming Only") so future-you knows which instance should use it.',
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-general-description",
            target: "qp-general-description",
            title: "Description",
            body: "A markdown field for notes about what this profile is for, who it targets, and any tradeoffs you baked in. It does not affect matching or scoring, but it pays off when you revisit the profile later or hand it to someone else.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-general-tags",
            target: "qp-general-tags",
            title: "Tags",
            body: "Tags group profiles on the list page so you can filter by use case (audiophile, streaming, kids, archival) once your library grows. Like the description, tags are purely for organisation and never influence grabs.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-general-language",
            target: "qp-general-language",
            title: "Language",
            body: "Language is Radarr only and sets the preferred audio language for this profile. Sonarr ignores it entirely. If you want more nuanced language behavior (required languages, language scoring, Sonarr support) create a custom format that matches on language and score it on the Scoring tab instead.",
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-general-summary",
            title: "Summary",
            body: "Name, description, tags, and language all live on the General tab. None of them decide which releases you grab, that is the job of the Scoring and Qualities tabs, which come next.",
            completion: { type: "manual" }
          }
        ]
      },
      "qp-scoring": {
        id: "qp-scoring",
        name: "Scoring",
        description: "Score custom formats and shape upgrade behavior for a profile",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "qp-scoring-intro",
            route: { resolve: "firstQualityProfileScoring" },
            title: "Scoring",
            body: "Scoring is the fine-grained preference layer. Every custom format that matches a release contributes its score, and the totals decide which release wins inside a quality tier. A high score does not guarantee a grab and a negative score does not block one; what matters is the total relative to other candidates.",
            completion: { type: "manual" }
          },
          {
            id: "qp-scoring-minimum",
            target: "qp-scoring-minimum",
            title: "Minimum Score",
            body: "The total score a release must clear to be eligible for grabbing. Database maintainers pick a conservative default that rejects releases they consider undesirable. If you rely on public trackers or a library with sparse options, lower this so something imperfect still beats nothing.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-scoring-upgrade-until",
            target: "qp-scoring-upgrade-until",
            title: "Upgrade Until Score",
            body: "Once a grabbed release reaches this score, the profile stops looking for upgrades. Drop this to the same value as the minimum (or below) to effectively disable upgrade searches when you want the first acceptable release to stick.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-scoring-increment",
            target: "qp-scoring-increment",
            title: "Upgrade Score Increment",
            body: "The smallest score jump that counts as an upgrade. Raise this so trivial sidegrades (say, swapping one release group for another with a similar score) do not trigger a re-grab, and the profile holds out for a meaningful improvement.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-scoring-actions",
            target: "qp-scoring-actions",
            title: "Actions",
            body: "The toolbar helps you navigate a long list of custom formats. Search filters by name when you know which format you need to nudge. The rest are organisers: sort by name or by arr-type score, group by tags (audio, HDR, release group), switch the grid between one, two, or three columns, hide a Radarr or Sonarr column when you only care about one, hide unscored formats, and save a set of these preferences as a named view.",
            position: "below-left",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-scoring-row",
            target: "qp-scoring-row",
            title: "Scoring a Custom Format",
            body: "Each row is one custom format. Radarr and Sonarr are scored independently: toggle the checkbox on the side you want to use, then enter the score. The same format can carry a different weight per app, and turning both off tells the profile to ignore it entirely.",
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-scoring-summary",
            title: "Summary",
            body: "Minimum, upgrade until, and increment set the guard rails. The actions bar helps you find the format you want to change. Scores are per arr-type and stack up to decide which release wins. Next, the Qualities tab handles the coarse tiering layer above all this.",
            completion: { type: "manual" }
          }
        ]
      },
      "qp-qualities": {
        id: "qp-qualities",
        name: "Qualities",
        description: "Order qualities, enable what you want, and merge tiers into groups",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "qp-qualities-intro",
            route: { resolve: "firstQualityProfileQualities" },
            title: "Qualities",
            body: "Qualities are the coarse sorting layer. A higher-ranked quality always beats a lower one regardless of score, so this tab is where you decide which tiers are eligible and how they stack. Cards are drag-and-drop, and the checkboxes on the right control whether a tier is enabled and where upgrades stop.",
            completion: { type: "manual" }
          },
          {
            id: "qp-qualities-card",
            target: "qp-qualities-card",
            title: "Quality Card",
            body: "Each card is either a single quality (for example, Bluray-1080p) or a group of qualities treated as equivalent for ranking. The list shows every quality the database knows about, including ones you currently have disabled, so ordering never silently changes when a quality is added or removed.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-qualities-drag",
            target: "qp-qualities-drag",
            title: "Drag Handle",
            body: "Click and drag the handle on the left edge of a card to reorder qualities. Higher in the list means higher priority; the top card wins any matchup where both releases are eligible. On desktop you can also drag a card onto another card to merge them into a group.",
            position: "right",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-qualities-upgrade-until",
            target: "qp-qualities-upgrade-until",
            title: "Upgrade Until",
            body: "The green arrow marks the ceiling tier. Once a grab lands at or above this card, the profile stops looking for higher quality upgrades. Only one card can hold this marker per profile, so moving it to a new card automatically clears it from the old one.",
            position: "below-left",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-qualities-enabled",
            target: "qp-qualities-enabled",
            title: "Enabled",
            body: "The blue check toggles whether this quality is eligible at all. Disabled cards stay in the list so ordering is preserved, but releases that match only a disabled tier will never be grabbed.",
            position: "below-left",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-qualities-group-button",
            target: "qp-qualities-group-button",
            title: "Groups",
            body: "Groups collapse multiple qualities into a single tier so scores, not qualities, decide between them. For example, grouping Bluray-1080p with WEBDL-1080p lets a high-scoring WEB-DL beat a low-scoring BluRay. Existing groups get a pencil icon on their card so you can edit members later.",
            position: "below-left",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "qp-qualities-summary",
            title: "Summary",
            body: "Drag to reorder, check to enable, mark the ceiling with upgrade until, and group tiers you want to treat as equals. Combined with the Scoring tab, you now have everything needed to turn your preferences into something Radarr and Sonarr can act on.",
            completion: { type: "manual" }
          }
        ]
      },
      "regex-general": {
        id: "regex-general",
        name: "General",
        description: "Reusable regex patterns shared across custom format conditions",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "regex-intro",
            route: { resolve: "firstRegularExpression" },
            title: "Regular Expressions",
            body: "Regular expressions are reusable patterns that custom format conditions match against. Profilarr keeps them on their own page rather than inlining them in conditions, so the same pattern can power many custom formats and you only update it in one place. Conditions of type Release Title, Release Group, and Edition pick a pattern from this list. The whole regex lives on a single form: identity, the pattern itself, optional regex101 tests, and the conditions that reference it.",
            completion: { type: "manual" }
          },
          {
            id: "regex-metadata",
            target: "regex-metadata",
            title: "Name, Tags & Description",
            body: 'Name is how conditions select this pattern, so make it descriptive (for example, "Release Group - SPARKS" or "Resolution - 1080p"). Tags group patterns on the list page so you can filter by codec, group, source, and so on once the library grows. Description is a markdown field for notes about what the pattern matches and any quirks worth flagging. None of these affect what the pattern matches; they pay off when you or someone else revisits the pattern later.',
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "regex-pattern",
            target: "regex-pattern",
            title: "The Pattern",
            body: "The pattern itself, written in the .NET regex flavor. Radarr and Sonarr both compile your pattern with a single flag, IgnoreCase (the i flag), and nothing else, so matching is case-insensitive by default but multiline (m) and singleline (s) modes are off; if you need them, set them inline with (?m) or (?s) in the pattern. The flavor matters because both apps run on .NET 6+, so a pattern that works in PCRE, Python, or JavaScript may behave differently here. As you type, Profilarr pings the parser microservice for live validation: Valid means the pattern compiles, Invalid surfaces the .NET error, and Parser unavailable means the parser is offline (the pattern still saves, just without the safety check).",
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "regex-tests",
            target: "regex101-id",
            title: "Regex101 Tests",
            body: 'Regex101 ID is an optional pointer to a saved pattern on regex101.com (for example, "GMV8jd/1" includes the version number, which keeps tests pinned to a specific revision). When set, Profilarr fetches the unit tests from regex101 and runs them through the parser against your pattern, surfacing pass/fail per test below. Set the regex101 entry to the .NET flavor with the i flag so the tests reflect what Radarr and Sonarr will actually do.',
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "regex-references",
            target: "regex-references",
            title: "References",
            body: "References lists every custom format condition that selects this pattern, with badges for Negate and Required. Because patterns are shared, a single edit can ripple across many formats and across both Radarr and Sonarr; this view is the quick check for what you are about to change before you save.",
            position: "above",
            completion: { type: "manual" }
          },
          {
            id: "regex-summary",
            title: "Summary",
            body: "A regex in Profilarr is a named, .NET-flavored pattern with optional regex101 tests and a list of the conditions that consume it. The reuse is the point: write a pattern once, test it once, then lean on it from every custom format that needs the same match.",
            completion: { type: "manual" }
          }
        ]
      },
      "delay-general": {
        id: "delay-general",
        name: "General",
        description: "Name, protocol preference, delays, and bypass conditions for a delay profile",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "delay-general-intro",
            route: { resolve: "firstDelayProfileGeneral" },
            title: "Delay Profiles",
            body: "A delay profile tells Radarr and Sonarr to wait before grabbing a release, which gives better copies time to appear. New content tends to land in waves: a poorly named scene WEB-DL without streaming service tags often shows up first, while cleaner releases from preferred groups with proper tags arrive later. Without a delay your *arr grabs the first release that meets your profile and then re-downloads every upgrade that lands, wasting bandwidth and storage on marginal improvements. This stage walks through the fields that make up a delay profile.",
            completion: { type: "manual" }
          },
          {
            id: "delay-general-name",
            target: "delay-general-name",
            title: "Name",
            body: 'The name identifies this delay profile when you assign it to tags inside Radarr or Sonarr. Keep it descriptive (for example "Standard 1 Hour" or "Anime Next Day") so you know which rule applies where.',
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "delay-general-protocol",
            target: "delay-general-protocol",
            title: "Protocol Preference",
            body: 'Decides which protocol your *arr favors when both have a matching release. "Prefer" modes wait the full delay and fall back to the other protocol if nothing shows up on the preferred side, while "Only" modes ignore the non-preferred protocol entirely. Pick an "Only" mode when you run a single backend and do not want the other side considered at all.',
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "delay-general-delays",
            target: "delay-general-delays",
            title: "Delays",
            body: "How long (in minutes) to wait for each protocol before committing to a grab. A longer wait gives slower release groups time to post their polished versions instead of your *arr jumping on the first thing that meets your profile. Set either side to 0 if you want releases on that protocol to download immediately.",
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "delay-general-bypass",
            target: "delay-general-bypass",
            title: "Bypass Conditions",
            body: 'Escape hatches that skip the wait when they fire. "Highest Quality" bypasses the delay once a release already sits at the top of the linked quality profile, since nothing better is coming. "Above Custom Format Score" bypasses the delay once a release clears the minimum CF score, which is useful when you trust high scores to indicate a release you are happy to grab on sight.',
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "delay-general-summary",
            title: "Summary",
            body: "Name, protocol preference, delays, and bypass conditions make up a delay profile. Together they tell your *arr to wait a set window per protocol before grabbing, unless a bypass condition says the release is already worth jumping on.",
            completion: { type: "manual" }
          }
        ]
      },
      "media-naming": {
        id: "media-naming",
        name: "Naming",
        description: "Control how Radarr and Sonarr lay out files and folders on disk",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "media-naming-intro",
            route: { resolve: "firstNaming" },
            title: "Naming",
            body: "A naming config tells Radarr or Sonarr how to name files and folders on disk. This is the Profilarr-managed equivalent of the Arr's own Settings > Media Management > Episode/Movie Naming screen, and each config lives under a single arr type. Radarr handles a movie file format and a movie folder format, while Sonarr splits things further into standard, daily, and anime episode formats plus series and season folder formats. The default config on your linked database already ships sensible formats; this stage walks the shared sections so you know what to touch if you want to tweak them.",
            completion: { type: "manual" }
          },
          {
            id: "media-naming-formats",
            target: "media-naming-formats",
            title: "Naming Formats",
            body: "Format strings use tokens (for example {Movie Title}, {Release Year}, {Quality Full} for Radarr, or {Series Title}, {season:00}, {episode:00}, {Episode Title} for Sonarr) wrapped in curly braces, and a live preview under each field shows how a real release would resolve. Type { in any format field to open the token picker. The fields themselves differ between Radarr and Sonarr; in Radarr you get movie and movie folder formats, in Sonarr you get three episode formats and two folder formats, but the token system and preview behave the same in both places.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "media-naming-character-replacement",
            target: "media-naming-character-replacement",
            title: "Character Replacement",
            body: 'Filesystems reject characters like : ? * < > | on most operating systems, so Radarr and Sonarr can rewrite them before they hit disk. "Replace Illegal Characters" is the master toggle; when it is on, the colon replacement dropdown decides how colons specifically are handled (delete, replace with space, dash, etc.). Sonarr also lets you pick a custom replacement string. Leaving this disabled instructs Sonarr to simply remove the illegal character instead. Leave this disabled unless you have a very specific reason not to.',
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "media-naming-summary",
            title: "Summary",
            body: "Naming formats shape every file and folder name, and character replacement keeps the result safe for your filesystem. Each config is tied to a single arr type, and nothing takes effect until you assign it on the Sync tab of an Arr instance.",
            completion: { type: "manual" }
          }
        ]
      },
      "media-quality-definitions": {
        id: "media-quality-definitions",
        name: "Quality Definitions",
        description: "File size gates per quality tier, and why they rarely need tuning",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [{
          id: "media-quality-definitions-intro",
          route: { resolve: "firstQualityDefinitions" },
          title: "Quality Definitions",
          body: "Quality definitions set a minimum, preferred, and maximum file size (in MB per minute of runtime) for every quality Radarr and Sonarr know about. Releases outside the min/max range are rejected outright, and the preferred value is the size the grabber aims for when nothing else breaks the tie. The important thing to know: if your quality profiles already lean on well-scored custom formats, the scoring layer is already doing the preference work, and a narrow size window here just starts arguing with it. The usual move is to leave min at 0 and max at the top of the scale for every row, so size becomes a sanity check rather than a second ranking system. This config still has to exist and be saved before the linked database will let quality profiles sync, so it is worth opening once to confirm the defaults look reasonable before you move on.",
          completion: { type: "manual" }
        }]
      },
      "media-settings": {
        id: "media-settings",
        name: "Media Settings",
        description: "Propers and repacks handling, and file analysis for renames",
        prerequisites: [{
          check: "hasDatabase",
          message: 'You need at least one connected database to start this stage. Follow the "Link" stage under Databases from the onboarding page to connect one.'
        }],
        steps: [
          {
            id: "media-settings-intro",
            route: { resolve: "firstMediaSettings" },
            title: "Media Settings",
            body: "Media settings is the miscellaneous bucket: how Radarr or Sonarr treats propers and repacks, and whether it scans files for media information after import. Two decisions, both small on the surface, but both interact with the rest of your setup.",
            completion: { type: "manual" }
          },
          {
            id: "media-settings-name",
            target: "media-settings-name",
            title: "Name",
            body: 'The name identifies this media settings config when you assign it on the Sync tab of an Arr instance. Keep it descriptive (for example "default" for your baseline or "radarr-strict" for a variant) so the dropdown is easy to read later.',
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "media-settings-propers-repacks",
            target: "media-settings-propers-repacks",
            title: "Propers and Repacks",
            body: 'Propers and repacks are re-releases that a group puts out to fix a problem in an earlier upload (scene groups call them propers, p2p groups call them repacks, but they serve the same purpose). The Arr has its own built-in preference system for these, which predates custom formats. The recommended setting here is "Do Not Prefer": a well-built PCD already scores PROPER and REPACK tags through custom formats, so the scoring layer handles the upgrade decision cleanly. Leaving the Arr-level preference on creates a second, opaque ranking system that can quietly override your scores.',
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "media-settings-file-analysis",
            target: "media-settings-file-analysis",
            title: "File Analysis",
            body: "Enable Media Info runs mediainfo against imported files to extract codec, resolution, audio tracks, and similar metadata. This matters downstream: the Rename tab builds filenames from naming tokens like {MediaInfo VideoCodec} and {MediaInfo AudioChannels}, and those tokens resolve to empty strings if media info was never collected. Leave this on if you want renames to produce complete filenames; turn it off only if the scan itself is causing problems on your storage.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "media-settings-summary",
            title: "Summary",
            body: `A descriptive name keeps the Sync dropdown readable, "Do Not Prefer" keeps propers and repacks out of your custom formats' way, and leaving file analysis on lets renames fill in media tokens. Assign the config on the Sync tab of an Arr instance to activate it there.`,
            completion: { type: "manual" }
          }
        ]
      },
      "settings-general": {
        id: "settings-general",
        name: "General",
        description: "App-wide preferences: interface, behavior, backups, logging, and TMDB",
        steps: [
          {
            id: "settings-general-intro",
            route: "/settings/general",
            title: "General Settings",
            body: "General is the app-wide preferences bucket: look-and-feel choices, behavior defaults, plus quick toggles for the backup and logging jobs. Everything on this page sits on a single form with one Save button at the top, so changes do not apply until you save.",
            completion: { type: "manual" }
          },
          {
            id: "settings-general-interface",
            target: "general-interface",
            title: "Interface",
            body: "Interface covers cosmetic preferences: whether the app uses emoji or lucide icons, where alerts appear and how long they stay on screen, and the sans and mono font families. The demo alert buttons on this card fire a sample notification so you can preview your choices without leaving the page.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-general-behavior",
            target: "general-behavior",
            title: "Behavior",
            body: 'Behavior controls app-wide action defaults. "Apply Default Delay Profile" sets a default delay profile on first sync to a new Arr. "Block Referenced Deletes" blocks deleting custom formats and regular expressions while other PCD entities still reference them.',
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-general-backups",
            target: "general-backups",
            title: "Backups",
            body: "Controls the automatic `backup.create` and `backup.cleanup` jobs: whether they run, when, and how long archives are kept. The archives themselves, plus manual create, upload, restore, and delete, all live on the Backups page. The Backups stage covers that side in detail.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-general-logging",
            target: "general-logging",
            title: "Logging",
            body: "Controls what Profilarr captures and for how long: file and console logging on/off, minimum level, and retention days for the daily-rotated files. The Logs page is where you read what was captured. The Logs stage covers that viewer.",
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-general-tmdb",
            target: "general-tmdb",
            title: "TMDB Configuration",
            body: "A TMDB API Read Access Token is only needed for the entity-testing feature inside quality profiles, which resolves titles and metadata against TMDB so you can test scoring against real releases. If you do not use entity testing, leave this blank.",
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-general-summary",
            title: "Summary",
            body: "General holds the knobs that shape the whole app: interface, behavior, the backup and logging jobs, and an optional TMDB token. Save at the top commits every change on the page at once.",
            completion: { type: "manual" }
          }
        ]
      },
      "settings-jobs": {
        id: "settings-jobs",
        name: "Jobs",
        description: "The event-driven job queue that runs background work",
        steps: [
          {
            id: "settings-jobs-intro",
            route: "/settings/jobs",
            title: "Background Jobs",
            body: "Profilarr uses a SQLite-backed job queue for background work: database syncs, format upgrades, file renames, backups, log cleanup. A single dispatcher claims jobs from the queue and runs them one at a time, strictly serially, which keeps the system deterministic. Rather than polling on an interval, the dispatcher sleeps until the next job is due and wakes up when a newly enqueued job has an earlier run time, so it costs nothing when idle.",
            completion: { type: "manual" }
          },
          {
            id: "settings-jobs-table",
            target: "jobs-table",
            title: "Jobs Table",
            body: "One row per scheduled job, with current status, when it last ran, the result of that run, and when it is due to run next. Expanding a row surfaces the details: exact timestamps, how long the last run took, and any error message the handler returned. This is the view for checking what is on the schedule and spotting anything that has failed or drifted.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-jobs-history",
            target: "jobs-history",
            title: "Recent Jobs",
            body: 'Every row here is one execution pulled from job-run history: when it started, how long it took, and its output or error. Skipped runs, where the handler had nothing to do (for example, no expired backups to clean), are hidden by default to keep the table focused on work that actually ran; toggle "Show skipped runs" to include them.',
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-jobs-summary",
            title: "Summary",
            body: "The queue plus a single event-driven dispatcher keeps Profilarr's background work cheap and predictable. Use the top table to see what is scheduled and Recent Jobs to audit what ran; both are read-only reporting views on top of the same queue.",
            completion: { type: "manual" }
          }
        ]
      },
      "settings-logs": {
        id: "settings-logs",
        name: "Logs",
        description: "Read, filter, and download the app log files",
        steps: [
          {
            id: "settings-logs-intro",
            route: "/settings/logs",
            title: "Logs",
            body: "This page is the viewer for Profilarr's own application logs. Log level, retention, and on/off controls live under General > Logging; everything here (file selection, search, filters, metadata drill-down) operates on whatever was already captured.",
            completion: { type: "manual" }
          },
          {
            id: "settings-logs-actions",
            target: "logs-actions",
            title: "Actions Bar",
            body: "The actions bar has everything you need to narrow the view: a file picker (files rotate by day as `YYYY-MM-DD.log` with each file's size next to the name), free-text search across the currently loaded file, a level filter (DEBUG/INFO/WARN/ERROR, color-coded), and a source-module filter built from the unique set of sources in the current file. On the right, Refresh reloads the file, Download saves the raw file to disk, and Cleanup kicks the `logs.cleanup` job immediately instead of waiting for its next run.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-logs-table",
            target: "logs-table",
            title: "Log Entry",
            body: "Each row is a single log entry: timestamp, level, source module, and message. The Copy button on a row copies the full formatted entry (including meta) to your clipboard; the eye icon, when present, opens a modal with the structured metadata payload pretty-printed as JSON, which is where context like job IDs, HTTP bodies, and stack traces lives.",
            position: "center",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-logs-summary",
            title: "Summary",
            body: "Pick a log file, narrow the view with search and the level and source filters, and drill into metadata when you need the context behind a line. Deeper control over what actually gets captured (level, retention, file vs console) lives one page over under General > Logging.",
            completion: { type: "manual" }
          }
        ]
      },
      "settings-backups": {
        id: "settings-backups",
        name: "Backups",
        description: "Manage archived snapshots of Profilarr's data directory",
        steps: [
          {
            id: "settings-backups-intro",
            route: "/settings/backups",
            title: "Backups",
            body: "Backups are compressed `.tar.gz` archives of Profilarr's data directory. Secrets (API keys, tokens, webhook URLs, and session records) are stripped from the database copy before it is archived, so an archive is safe to move between hosts. The automatic schedule and retention are configured under General > Backups; this page covers manual operations and restoring from an archive.",
            completion: { type: "manual" }
          },
          {
            id: "settings-backups-actions",
            target: "backups-actions",
            title: "Actions Bar",
            body: "The actions bar covers the three manual operations. Search narrows the archive list by filename. Upload lets you drop a `.tar.gz` from another Profilarr instance, which is the main path for migrating between hosts. Create Backup enqueues a `backup.create` job that runs on the normal job queue and appears in the table below once it finishes. Cleanup fires the `backup.cleanup` job immediately instead of waiting for its next scheduled run.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-backups-table",
            target: "backups-table",
            title: "Backup Row",
            body: "Each row is one archive: when it was created, its filename, and its size. Per-row actions are Download (saves the archive to your machine), Restore (replaces current state with the contents of the archive, asks for confirmation, and requires an app restart afterward), and Delete (removes the archive from disk).",
            position: "center",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-backups-summary",
            title: "Summary",
            body: "Automatic backups on the job schedule are the default protection; this page is for manual snapshots before risky operations, migrating between hosts via upload, and restoring when something has gone wrong.",
            completion: { type: "manual" }
          }
        ]
      },
      "settings-notifications": {
        id: "settings-notifications",
        name: "Notifications",
        description: "Push alerts to external services when specific events happen",
        steps: [
          {
            id: "settings-notifications-intro",
            route: "/settings/notifications",
            title: "Notifications",
            body: "Profilarr can push alerts out to external services when specific events happen: job success and failure, sync outcomes, backup results, and similar. A range of service types is supported (chat apps, push services, generic webhooks, and more), and multiple services can be active at once, each with its own subset of enabled event types, so you can route critical failures one way and routine completions another.",
            completion: { type: "manual" }
          },
          {
            id: "settings-notifications-add",
            target: "notifications-add",
            title: "Add Service",
            body: "Add Service opens the new-service form, where you pick a service type, fill in the credentials that type needs (webhook URL, bot token, topic, and so on), and choose which event types this service will listen for. We will not walk the form in this stage since it requires real credentials to finish, but it is the single entry point for wiring up a new destination.",
            position: "center",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-notifications-table",
            target: "notifications-table",
            title: "Services Table",
            body: "One row per configured service, showing its type, enabled or disabled status, and a running count of successes and failures. Per-row actions are Test (fires a sample notification to confirm credentials and network path), Edit (reopens the form), and Delete.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-notifications-history",
            target: "notifications-history",
            title: "Notification History",
            body: "Every delivery attempt is recorded here with its outcome, which is how you audit whether alerts actually made it through. If a service is silently failing, this is the view that shows it; pair with the Test action above to confirm you have fixed it.",
            position: "center",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-notifications-summary",
            title: "Summary",
            body: "Add a service, pick the event types it should listen for, use Test to confirm credentials work, and audit deliveries in the history panel. Multiple services can run side-by-side if you want different destinations for different severities.",
            completion: { type: "manual" }
          }
        ]
      },
      "settings-security": {
        id: "settings-security",
        name: "Security",
        description: "Password, API key, local-network bypass, and active sessions",
        steps: [
          {
            id: "settings-security-intro",
            route: "/settings/security",
            title: "Security",
            body: "Your password, API key, local-network bypass, and active sessions all live on this page. Which sections are meaningful depends on the `AUTH` mode you started Profilarr with: password change applies when `AUTH=on`; with `AUTH=oidc` your identity provider owns credentials; with `AUTH=off` no auth is applied at all. API keys and sessions behave the same across modes.",
            completion: { type: "manual" }
          },
          {
            id: "settings-security-password",
            target: "security-password",
            title: "Change Password",
            body: "A three-field form: current password, new password, and confirm. Only meaningful under `AUTH=on`, where Profilarr owns the credential; under `AUTH=oidc` or `AUTH=off` this form does nothing useful because Profilarr is not the source of truth for your identity.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-security-local-bypass",
            target: "security-local-bypass",
            title: "Local Bypass",
            body: "When on, requests originating from local network addresses skip authentication entirely. The tradeoff: easier API access from scripts on the same machine or LAN, but anyone else on that network is now implicitly trusted. Safe when your LAN is single-user; risky on a shared or untrusted network.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-security-api-key",
            target: "security-api-key",
            title: "API Key",
            body: "A single API key per instance, sent via the `X-Api-Key` header, bcrypt-hashed on the server so the raw value cannot be recovered after it is generated. Generate once, copy the key immediately (it is shown once and never again), and regenerate to rotate. Regenerating invalidates anything still using the old key, so rotate before deleting old clients, not after.",
            position: "below",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-security-sessions",
            target: "security-sessions",
            title: "Active Sessions",
            body: 'Browser sessions tied to the current Profilarr user. Each row shows browser, OS, device type, IP, and last active time, which is how you spot a session you do not recognize. Per-row Revoke ends that session specifically; "Revoke Others" in the section header ends every session except the one you are using right now.',
            position: "above",
            freeInteract: true,
            completion: { type: "manual" }
          },
          {
            id: "settings-security-summary",
            title: "Summary",
            body: "Security is a cross-mode toolkit: use the parts that match your auth mode, rotate the API key when credentials leak, flip local bypass only when you trust the LAN, and revoke sessions you do not recognize.",
            completion: { type: "manual" }
          }
        ]
      },
      help: {
        id: "help",
        name: "Help",
        description: "Find the help button",
        silent: true,
        steps: [{
          id: "help-button",
          target: "help-button",
          title: "Need Help?",
          body: "This is your help button. Click it now to try it out!",
          position: "above-left",
          completion: { type: "click" }
        }]
      }
    };
    GROUPS = [
      {
        name: "Getting Started",
        description: "Learn the basics of Profilarr",
        stages: [
          "welcome",
          "navigation",
          "personalize",
          "help"
        ]
      },
      {
        name: "Databases",
        description: "Connect and manage configuration databases",
        stages: ["database-link", "database-manage"]
      },
      {
        name: "Arr Instances",
        description: "Connect and manage Radarr/Sonarr instances",
        stages: [
          "arr-link",
          "arr-manage",
          "arr-sync",
          "arr-upgrades",
          "arr-renames"
        ]
      },
      {
        name: "Media Management",
        description: "Naming, quality definitions, and media settings",
        stages: [
          "media-naming",
          "media-quality-definitions",
          "media-settings"
        ]
      },
      {
        name: "Regular Expressions",
        description: "Build reusable regex patterns for custom format conditions",
        stages: ["regex-general"]
      },
      {
        name: "Custom Formats",
        description: "Build and test custom formats",
        stages: [
          "cf-general",
          "cf-conditions",
          "cf-testing"
        ]
      },
      {
        name: "Quality Profiles",
        description: "Rank releases with qualities and custom format scores",
        stages: [
          "qp-general",
          "qp-scoring",
          "qp-qualities"
        ]
      },
      {
        name: "Delay Profiles",
        description: "Wait for better releases before committing to a grab",
        stages: ["delay-general"]
      },
      {
        name: "Settings",
        description: "App-wide preferences, background jobs, logs, backups, notifications, and security",
        stages: [
          "settings-general",
          "settings-jobs",
          "settings-logs",
          "settings-backups",
          "settings-notifications",
          "settings-security"
        ]
      }
    ];
    stateChecks = {
      hasDatabase: async () => {
        const res = await fetch("/api/v1/databases");
        if (!res.ok) return false;
        return (await res.json()).length > 0;
      },
      hasArrInstance: async () => {
        const res = await fetch("/api/v1/arr");
        if (!res.ok) return false;
        return (await res.json()).length > 0;
      },
      hasDevDatabase: async () => {
        const res = await fetch("/api/v1/databases");
        if (!res.ok) return false;
        return (await res.json()).some((d2) => d2.hasPat && !d2.local_ops_enabled);
      },
      parserHealthy: async () => {
        return get(page).data?.parserAvailable === true;
      }
    };
    DEFAULT_STATE = {
      active: false,
      stageId: null,
      stepIndex: 0,
      manualStart: false
    };
    cutscene = createCutsceneStore();
  }
});

// dist/build/server/chunks/Label.js
function Label($$renderer, $$props) {
  let resolvedVariantClasses, classes;
  let variant = fallback($$props["variant"], "default");
  let customVariant = fallback($$props["customVariant"], "");
  let size = fallback($$props["size"], "md");
  let rounded = fallback($$props["rounded"], "full");
  let mono = fallback($$props["mono"], false);
  let href = fallback($$props["href"], void 0);
  let target = fallback($$props["target"], void 0);
  let rel = fallback($$props["rel"], void 0);
  const variantClasses = {
    default: "bg-accent-600 text-white dark:bg-accent-500 dark:text-white",
    secondary: "bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300",
    destructive: "bg-red-600 text-white dark:bg-red-500 dark:text-white",
    outline: "border border-neutral-300 text-neutral-700 dark:border-neutral-600 dark:text-neutral-300",
    ghost: "bg-neutral-100/60 text-neutral-600 dark:bg-neutral-800/40 dark:text-neutral-400",
    success: "bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200",
    warning: "bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200",
    danger: "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
    info: "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200",
    link: "bg-neutral-100 text-blue-700 dark:bg-neutral-800 dark:text-blue-300"
  };
  const sizeClasses = {
    sm: "gap-1 px-2 py-1 text-[10px]",
    md: "gap-1 px-2.5 py-1 text-xs",
    lg: "gap-1.5 px-3 py-1.5 text-sm"
  };
  const roundedClasses = {
    sm: "rounded",
    md: "rounded-md",
    lg: "rounded-lg",
    xl: "rounded-xl",
    full: "rounded-full"
  };
  $: resolvedVariantClasses = customVariant || variantClasses[variant];
  $: classes = `inline-flex items-center leading-none font-medium ${resolvedVariantClasses} ${sizeClasses[size]} ${roundedClasses[rounded]} ${mono ? "font-mono" : ""}`;
  if (href) {
    $$renderer.push("<!--[0-->");
    $$renderer.push(`<a${attr("href", href)}${attr("target", target)}${attr("rel", rel)}${attr_class(clsx(classes))}><!--[-->`);
    slot($$renderer, $$props, "default", {}, null);
    $$renderer.push(`<!--]--></a>`);
  } else {
    $$renderer.push("<!--[-1-->");
    $$renderer.push(`<span${attr_class(clsx(classes))}><!--[-->`);
    slot($$renderer, $$props, "default", {}, null);
    $$renderer.push(`<!--]--></span>`);
  }
  $$renderer.push(`<!--]-->`);
  bind_props($$props, {
    variant,
    customVariant,
    size,
    rounded,
    mono,
    href,
    target,
    rel
  });
}
var init_Label = __esm({
  "dist/build/server/chunks/Label.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/chunks/Card.js
function Card($$renderer, $$props) {
  const $$slots = sanitize_slots($$props);
  $$renderer.component(($$renderer2) => {
    let isFlush, hasHeader, hasFooter, interactive, paddingClass, dividerClass, bgClass, hoverClass, cursorClass, cardClass;
    let padding = fallback($$props["padding"], "md");
    let hoverable = fallback($$props["hoverable"], false);
    let href = fallback($$props["href"], void 0);
    let onclick = fallback($$props["onclick"], void 0);
    let flush = fallback($$props["flush"], false);
    let className = fallback($$props["className"], "");
    let contextFlush = false;
    try {
      contextFlush = getContext("card-flush") ?? false;
    } catch {
    }
    $: isFlush = flush || contextFlush;
    $: hasHeader = !!$$slots.header;
    $: hasFooter = !!$$slots.footer;
    $: interactive = !!href || !!onclick;
    $: paddingClass = {
      none: "",
      sm: "px-3 py-2",
      md: "px-4 py-3",
      lg: "px-5 py-4"
    }[padding];
    $: dividerClass = {
      none: "",
      sm: "mx-3",
      md: "mx-4",
      lg: "mx-5"
    }[padding];
    $: bgClass = isFlush ? "bg-neutral-50 dark:bg-neutral-900" : "bg-white dark:bg-neutral-800/50";
    $: hoverClass = hoverable || interactive ? isFlush ? "transition-colors hover:bg-neutral-100 dark:hover:bg-neutral-800/60" : "transition-colors hover:bg-neutral-50 dark:hover:bg-neutral-800/80" : "";
    $: cursorClass = interactive ? "cursor-pointer" : "";
    $: cardClass = `flex flex-col overflow-hidden rounded-xl border border-neutral-300 dark:border-neutral-700/60 ${bgClass} ${hoverClass} ${cursorClass} ${className}`;
    if (href) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<a${attr("href", href)}${attr_class(clsx(cardClass))}>`);
      if (hasHeader) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div${attr_class(clsx(paddingClass))}><!--[-->`);
        slot($$renderer2, $$props, "header", {}, null);
        $$renderer2.push(`<!--]--></div> <div${attr_class(`border-t border-neutral-200 dark:border-neutral-700/60 ${stringify(dividerClass)}`)}></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> <div${attr_class(`flex flex-1 flex-col ${stringify(paddingClass)}`)}><!--[-->`);
      slot($$renderer2, $$props, "default", {}, null);
      $$renderer2.push(`<!--]--></div> `);
      if (hasFooter) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div${attr_class(`border-t border-neutral-200 dark:border-neutral-700/60 ${stringify(dividerClass)}`)}></div> <div${attr_class(clsx(paddingClass))}><!--[-->`);
        slot($$renderer2, $$props, "footer", {}, null);
        $$renderer2.push(`<!--]--></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></a>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div${attr_class(clsx(cardClass))}>`);
      if (hasHeader) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div${attr_class(clsx(paddingClass))}><!--[-->`);
        slot($$renderer2, $$props, "header", {}, null);
        $$renderer2.push(`<!--]--></div> <div${attr_class(`border-t border-neutral-200 dark:border-neutral-700/60 ${stringify(dividerClass)}`)}></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> <div${attr_class(`flex flex-1 flex-col ${stringify(paddingClass)}`)}><!--[-->`);
      slot($$renderer2, $$props, "default", {}, null);
      $$renderer2.push(`<!--]--></div> `);
      if (hasFooter) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div${attr_class(`border-t border-neutral-200 dark:border-neutral-700/60 ${stringify(dividerClass)}`)}></div> <div${attr_class(clsx(paddingClass))}><!--[-->`);
        slot($$renderer2, $$props, "footer", {}, null);
        $$renderer2.push(`<!--]--></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div>`);
    }
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      padding,
      hoverable,
      href,
      onclick,
      flush,
      className
    });
  });
}
var init_Card = __esm({
  "dist/build/server/chunks/Card.js"() {
    "use strict";
    init_index_server();
    init_server();
  }
});

// dist/build/server/chunks/jobStatus.js
function createJobStatusStore() {
  const { subscribe: subscribe2, set: set3, update: update4 } = writable({ state: "idle" });
  let resetTimer = null;
  let holdoffTimer = null;
  let currentJobId = null;
  let eventSource = null;
  const finishedListeners = /* @__PURE__ */ new Set();
  function onJobFinished(listener) {
    finishedListeners.add(listener);
    return () => {
      finishedListeners.delete(listener);
    };
  }
  function clearTimers() {
    if (resetTimer) {
      clearTimeout(resetTimer);
      resetTimer = null;
    }
    if (holdoffTimer) {
      clearTimeout(holdoffTimer);
      holdoffTimer = null;
    }
  }
  function closeSSE() {
    eventSource?.close();
    eventSource = null;
  }
  function connect() {
  }
  function disconnect() {
    closeSSE();
    clearTimers();
    currentJobId = null;
    set3({ state: "idle" });
  }
  function setRunning(jobType, displayLabel) {
    currentJobId = null;
    set3({
      state: "running",
      jobType,
      displayLabel
    });
  }
  function cancelOptimistic() {
    update4((s3) => {
      if (s3.state === "running" && currentJobId === null) return { state: "idle" };
      return s3;
    });
  }
  return {
    subscribe: subscribe2,
    connect,
    disconnect,
    setRunning,
    cancelOptimistic,
    onJobFinished
  };
}
var jobStatus;
var init_jobStatus = __esm({
  "dist/build/server/chunks/jobStatus.js"() {
    "use strict";
    init_server();
    init_index_server2();
    jobStatus = createJobStatusStore();
  }
});

// dist/build/server/chunks/Sonarr2.js
var Radarr_default, Sonarr_default;
var init_Sonarr2 = __esm({
  "dist/build/server/chunks/Sonarr2.js"() {
    "use strict";
    Radarr_default = "data:image/svg+xml,%3csvg%20width='1024px'%20height='1024px'%20viewBox='0%200%201024%201024'%20version='1.1'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20xmlns='http://www.w3.org/2000/svg'%3e%3cdefs%3e%3crect%20width='1024'%20height='1024'%20id='artboard_1'%20/%3e%3cclipPath%20id='clip_1'%3e%3cuse%20xlink:href='%23artboard_1'%20clip-rule='evenodd'%20/%3e%3c/clipPath%3e%3c/defs%3e%3cg%20id='Simple-Logo-Light'%20clip-path='url(%23clip_1)'%3e%3cuse%20xlink:href='%23artboard_1'%20stroke='none'%20fill='%23FFFFFF'%20fill-opacity='0'%20/%3e%3cg%20id='Group-Copy'%20transform='translate(70%2021.00012)'%3e%3cpath%20d='M105.302%20154.943L112.824%20869.492C52.651%20877.014%207.52158%20846.927%207.52158%20786.755L0%20192.55C0%204.51106%20172.996%20-40.6184%20278.298%2034.5974L812.33%20342.982C887.546%20395.633%20902.589%20493.413%20864.981%20561.107C857.46%20508.456%20834.895%20478.37%20789.765%20448.284L188.039%20109.813C142.91%2079.7268%20105.302%2087.2484%20105.302%20154.943Z'%20id='Shape'%20fill='%2324292E'%20stroke='none'%20/%3e%3cpath%20d='M0%20376.079C45.1295%20391.122%2090.259%20383.6%20127.867%20361.036L744.636%200C782.244%2052.651%20774.723%20105.302%20729.593%20135.388L210.604%20436.251C135.388%20473.859%2037.6079%20436.251%200%20376.079Z'%20transform='translate(60.17249%20531.0214)'%20id='Shape'%20fill='%2324292E'%20stroke='none'%20/%3e%3cpath%20d='M0%20413.687L368.557%20203.083L7.52157%200L0%20413.687Z'%20transform='translate(240.6902%20282.8092)'%20id='Shape'%20fill='%23FFC230'%20stroke='none'%20/%3e%3c/g%3e%3c/g%3e%3c/svg%3e";
    Sonarr_default = "data:image/svg+xml,%3csvg%20height='216.9'%20viewBox='0%200%20216.7%20216.9'%20width='216.7'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20clip-rule='evenodd'%20d='M216.7%20108.45c0%2029.833-10.533%2055.4-31.6%2076.7-.7.833-1.483%201.6-2.35%202.3-3.466%203.4-7.133%206.484-11%209.25-18.267%2013.467-39.367%2020.2-63.3%2020.2-23.967%200-45.033-6.733-63.2-20.2-4.8-3.4-9.3-7.25-13.5-11.55-16.367-16.266-26.417-35.167-30.15-56.7-.733-4.2-1.217-8.467-1.45-12.8-.1-2.4-.15-4.8-.15-7.2%200-2.533.05-4.95.15-7.25%200-.233.066-.467.2-.7%201.567-26.6%2012.033-49.583%2031.4-68.95C53.05%2010.517%2078.617%200%20108.45%200c29.933%200%2055.484%2010.517%2076.65%2031.55%2021.067%2021.433%2031.6%2047.067%2031.6%2076.9z'%20fill='%23EEE'%20fill-rule='evenodd'/%3e%3cpath%20clip-rule='evenodd'%20d='M194.65%2042.5l-22.4%2022.4C159.152%2077.998%20158%2089.4%20158%20109.5c0%2017.934%202.852%2034.352%2016.2%2047.7%209.746%209.746%2019%2018.95%2019%2018.95-2.5%203.067-5.2%206.067-8.1%209-.7.833-1.483%201.6-2.35%202.3-2.533%202.5-5.167%204.817-7.9%206.95l-17.55-17.55c-15.598-15.6-27.996-17.1-48.6-17.1-19.77%200-33.223%201.822-47.7%2016.3-8.647%208.647-18.55%2018.6-18.55%2018.6-3.767-2.867-7.333-6.034-10.7-9.5-2.8-2.8-5.417-5.667-7.85-8.6%200%200%209.798-9.848%2019.15-19.2%2013.852-13.853%2016.1-29.916%2016.1-47.85%200-17.5-2.874-33.823-15.6-46.55-8.835-8.836-21.05-21-21.05-21%202.833-3.6%205.917-7.067%209.25-10.4%202.934-2.867%205.934-5.55%209-8.05L61.1%2043.85C74.102%2056.852%2090.767%2060.2%20108.7%2060.2c18.467%200%2035.077-3.577%2048.6-17.1%208.32-8.32%2019.3-19.25%2019.3-19.25%202.9%202.367%205.733%204.933%208.5%207.7%203.467%203.533%206.65%207.183%209.55%2010.95z'%20fill='%233A3F51'%20fill-rule='evenodd'/%3e%3cg%20clip-rule='evenodd'%3e%3cpath%20d='M78.7%20114c-.2-1.167-.332-2.35-.4-3.55-.032-.667-.05-1.333-.05-2%200-.7.018-1.367.05-2%200-.067.018-.133.05-.2.435-7.367%203.334-13.733%208.7-19.1%205.9-5.833%2012.984-8.75%2021.25-8.75%208.3%200%2015.384%202.917%2021.25%208.75%205.834%205.934%208.75%2013.033%208.75%2021.3%200%208.267-2.916%2015.35-8.75%2021.25-.2.233-.416.45-.65.65-.966.933-1.982%201.783-3.05%202.55-5.065%203.733-10.916%205.6-17.55%205.6s-12.466-1.866-17.5-5.6c-1.332-.934-2.582-2-3.75-3.2-4.532-4.5-7.316-9.734-8.35-15.7z'%20fill='%230CF'%20fill-rule='evenodd'/%3e%3cpath%20d='M157.8%2059.75l-15%2014.65M30.785%2032.526L71.65%2073.25m84.6%2084.25l27.808%2028.78m1.855-153.894L157.8%2059.75m-125.45%20126l27.35-27.4'%20fill='none'%20stroke='%230CF'%20stroke-miterlimit='1'%20stroke-width='2'/%3e%3cpath%20d='M157.8%2059.75l-16.95%2017.2M58.97%2060.604l17.2%2017.15M59.623%20158.43l16.75-17.4m61.928-1.396l18.028%2017.945'%20fill='none'%20stroke='%230CF'%20stroke-miterlimit='1'%20stroke-width='7'/%3e%3c/g%3e%3c/svg%3e";
  }
});

// dist/build/server/chunks/navigation.js
var init_navigation = __esm({
  "dist/build/server/chunks/navigation.js"() {
    "use strict";
    init_client4();
  }
});

// dist/build/server/chunks/InlineCode.js
function InlineCode($$renderer, $$props) {
  let text2 = $$props["text"];
  let icon = fallback($$props["icon"], null);
  let rounded = fallback($$props["rounded"], "full");
  $$renderer.push(`<code${attr_class(`inline-flex items-center gap-1.5 ${stringify({
    sm: "rounded",
    md: "rounded-md",
    lg: "rounded-lg",
    xl: "rounded-xl",
    full: "rounded-full"
  }[rounded])} bg-neutral-100 px-1 py-px text-[0.85em] text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300`)} style="font-family: var(--font-code)">`);
  if (icon) {
    $$renderer.push("<!--[0-->");
    if (icon) {
      $$renderer.push("<!--[-->");
      icon($$renderer, {
        size: 12,
        class: "shrink-0 text-neutral-400 dark:text-neutral-500"
      });
      $$renderer.push("<!--]-->");
    } else {
      $$renderer.push("<!--[!-->");
      $$renderer.push("<!--]-->");
    }
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--> ${escape_html(text2)}</code>`);
  bind_props($$props, {
    text: text2,
    icon,
    rounded
  });
}
var init_InlineCode = __esm({
  "dist/build/server/chunks/InlineCode.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/chunks/Modal.js
function Modal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let open = fallback($$props["open"], false);
    let header = fallback($$props["header"], "Confirm");
    let bodyMessage = fallback($$props["bodyMessage"], "Are you sure?");
    let confirmText = fallback($$props["confirmText"], "Confirm");
    let cancelText = fallback($$props["cancelText"], "Cancel");
    let confirmDanger = fallback($$props["confirmDanger"], false);
    let confirmDisabled = fallback($$props["confirmDisabled"], false);
    let loading = fallback($$props["loading"], false);
    let size = fallback($$props["size"], "md");
    let height = fallback($$props["height"], "auto");
    let bodyOverflow = fallback($$props["bodyOverflow"], "auto");
    const sizeClasses = {
      sm: "max-w-sm",
      md: "max-w-md",
      lg: "max-w-2xl",
      xl: "max-w-4xl",
      "2xl": "max-w-6xl"
    };
    const heightClasses = {
      auto: "",
      md: "h-[50vh]",
      lg: "h-[70vh]",
      xl: "h-[85vh]",
      full: "h-[95vh]"
    };
    createEventDispatcher();
    if (open) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="fixed inset-0 z-[100] overflow-y-auto bg-black/50 p-4 backdrop-blur-sm sm:p-6" role="dialog" aria-modal="true" tabindex="-1"><div class="flex min-h-full w-full items-start justify-center sm:items-center"><div${attr_class(`relative my-4 flex w-full flex-col ${stringify(sizeClasses[size])} ${stringify(heightClasses[height])} max-h-[calc(100svh-2rem)] rounded-xl border border-neutral-300 bg-white shadow-xl sm:my-0 dark:border-neutral-700/60 dark:bg-neutral-900`)}><div class="flex flex-shrink-0 flex-wrap items-center gap-x-3 gap-y-2 border-b border-neutral-300 px-6 py-4 dark:border-neutral-700/60"><h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(header)}</h2> <!--[-->`);
      slot($$renderer2, $$props, "header-extra", {}, null);
      $$renderer2.push(`<!--]--></div> <div${attr_class(`flex-1 px-6 py-4 ${bodyOverflow === "visible" ? "overflow-visible" : "overflow-auto"}`)}><!--[-->`);
      slot($$renderer2, $$props, "body", {}, () => {
        $$renderer2.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(bodyMessage)}</p>`);
      });
      $$renderer2.push(`<!--]--></div> <div class="flex flex-shrink-0 justify-between border-t border-neutral-300 px-6 py-4 dark:border-neutral-700/60"><!--[-->`);
      slot($$renderer2, $$props, "footer", {}, () => {
        Button($$renderer2, {
          text: cancelText,
          icon: X2,
          disabled: loading
        });
        $$renderer2.push(`<!----> `);
        Button($$renderer2, {
          text: confirmText,
          icon: loading ? Loader_circle : Check,
          variant: confirmDanger ? "danger" : "primary",
          disabled: confirmDisabled || loading,
          loading
        });
        $$renderer2.push(`<!---->`);
      });
      $$renderer2.push(`<!--]--></div></div></div></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      open,
      header,
      bodyMessage,
      confirmText,
      cancelText,
      confirmDanger,
      confirmDisabled,
      loading,
      size,
      height,
      bodyOverflow
    });
  });
}
var init_Modal = __esm({
  "dist/build/server/chunks/Modal.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_check();
    init_Button();
    init_x();
  }
});

// dist/build/server/chunks/dateFormat.js
function createDateFormatStore() {
  const { subscribe: subscribe2, set: set3 } = writable("auto");
  return {
    subscribe: subscribe2,
    set: set3
  };
}
var dateFormat;
var init_dateFormat = __esm({
  "dist/build/server/chunks/dateFormat.js"() {
    "use strict";
    init_server();
    init_index_server2();
    dateFormat = createDateFormatStore();
  }
});

// dist/build/server/chunks/timezone.js
function createTimezoneStore() {
  const { subscribe: subscribe2, set: set3 } = writable("UTC");
  return {
    subscribe: subscribe2,
    set: set3
  };
}
var serverTimezone;
var init_timezone = __esm({
  "dist/build/server/chunks/timezone.js"() {
    "use strict";
    init_server();
    init_index_server2();
    serverTimezone = createTimezoneStore();
  }
});

// dist/build/server/chunks/forms.js
var init_forms = __esm({
  "dist/build/server/chunks/forms.js"() {
    "use strict";
    init_client4();
    init_navigation();
  }
});

// dist/build/server/entries/pages/_layout.svelte.js
var layout_svelte_exports = {};
__export(layout_svelte_exports, {
  default: () => _layout
});
function createAccentStore() {
  const { subscribe: subscribe2, set: set3 } = writable("blue");
  function setAccent(accent) {
    set3(accent);
  }
  return {
    subscribe: subscribe2,
    set: setAccent
  };
}
function Bird($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "bird" },
    props,
    { iconNode: [
      ["path", { "d": "M16 7h.01" }],
      ["path", { "d": "M3.4 18H12a8 8 0 0 0 8-8V7a4 4 0 0 0-7.28-2.3L2 20" }],
      ["path", { "d": "m20 7 2 .5-2 .5" }],
      ["path", { "d": "M10 18v3" }],
      ["path", { "d": "M14 17.75V21" }],
      ["path", { "d": "M7 18a6 6 0 0 0 3.84-10.61" }]
    ] }
  ]));
}
function Folder_tree($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "folder-tree" },
    props,
    { iconNode: [
      ["path", { "d": "M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z" }],
      ["path", { "d": "M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z" }],
      ["path", { "d": "M3 5a2 2 0 0 0 2 2h3" }],
      ["path", { "d": "M3 3v13a2 2 0 0 0 2 2h3" }]
    ] }
  ]));
}
function Menu($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "menu" },
    props,
    { iconNode: [
      ["path", { "d": "M4 5h16" }],
      ["path", { "d": "M4 12h16" }],
      ["path", { "d": "M4 19h16" }]
    ] }
  ]));
}
function Microscope($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "microscope" },
    props,
    { iconNode: [
      ["path", { "d": "M6 18h8" }],
      ["path", { "d": "M3 22h18" }],
      ["path", { "d": "M14 22a7 7 0 1 0 0-14h-1" }],
      ["path", { "d": "M9 14h2" }],
      ["path", { "d": "M9 12a2 2 0 0 1-2-2V6h6v4a2 2 0 0 1-2 2Z" }],
      ["path", { "d": "M12 6V3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v3" }]
    ] }
  ]));
}
function Moon_star($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "moon-star" },
    props,
    { iconNode: [
      ["path", { "d": "M18 5h4" }],
      ["path", { "d": "M20 3v4" }],
      ["path", { "d": "M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401" }]
    ] }
  ]));
}
function Palette($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "palette" },
    props,
    { iconNode: [
      ["path", { "d": "M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z" }],
      ["circle", {
        "cx": "13.5",
        "cy": "6.5",
        "r": ".5",
        "fill": "currentColor"
      }],
      ["circle", {
        "cx": "17.5",
        "cy": "10.5",
        "r": ".5",
        "fill": "currentColor"
      }],
      ["circle", {
        "cx": "6.5",
        "cy": "12.5",
        "r": ".5",
        "fill": "currentColor"
      }],
      ["circle", {
        "cx": "8.5",
        "cy": "7.5",
        "r": ".5",
        "fill": "currentColor"
      }]
    ] }
  ]));
}
function Sun($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "sun" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "12",
        "cy": "12",
        "r": "4"
      }],
      ["path", { "d": "M12 2v2" }],
      ["path", { "d": "M12 20v2" }],
      ["path", { "d": "m4.93 4.93 1.41 1.41" }],
      ["path", { "d": "m17.66 17.66 1.41 1.41" }],
      ["path", { "d": "M2 12h2" }],
      ["path", { "d": "M20 12h2" }],
      ["path", { "d": "m6.34 17.66-1.41 1.41" }],
      ["path", { "d": "m19.07 4.93-1.41 1.41" }]
    ] }
  ]));
}
function AccentPicker($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let currentColor;
    let onboarding = fallback($$props["onboarding"], void 0);
    $: currentColor = accentColors.find((c2) => c2.value === store_get($$store_subs ??= {}, "$accentStore", accentStore)) ?? accentColors[0];
    $$renderer2.push(`<div class="accent-picker relative"${attr("data-onboarding", onboarding)}><button class="flex h-9 w-9 items-center justify-center rounded-md transition-colors hover:bg-neutral-200 dark:hover:bg-neutral-800" aria-label="Select accent color"><span class="h-4 w-4 rounded-full"${attr_style(`background-color: ${stringify(currentColor.color)}`)}></span></button> `);
    $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { onboarding });
  });
}
function ThemeToggle($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let isDark;
    let onboarding = fallback($$props["onboarding"], void 0);
    $: isDark = store_get($$store_subs ??= {}, "$themeStore", themeStore) === "dark";
    $$renderer2.push(`<button${attr("data-onboarding", onboarding)} class="relative flex h-9 w-9 items-center justify-center rounded-md transition-colors hover:bg-neutral-200 dark:hover:bg-neutral-800" aria-label="Toggle theme"><div${attr_class(`nav-icon-emoji absolute transition-all duration-300 ${isDark ? "scale-100 rotate-0 opacity-100" : "scale-75 rotate-180 opacity-0"}`)}><span class="text-lg">\u2728</span></div> <div${attr_class(`nav-icon-emoji absolute transition-all duration-300 ${isDark ? "scale-75 -rotate-180 opacity-0" : "scale-100 rotate-0 opacity-100"}`)}><span class="text-lg">\u{1F4A1}</span></div> <div${attr_class(`nav-icon-lucide absolute transition-all duration-300 ${isDark ? "scale-100 rotate-0 opacity-100" : "scale-75 rotate-180 opacity-0"}`)}>`);
    Moon_star($$renderer2, { class: "h-[18px] w-[18px] text-neutral-700 dark:text-neutral-300" });
    $$renderer2.push(`<!----></div> <div${attr_class(`nav-icon-lucide absolute transition-all duration-300 ${isDark ? "scale-75 -rotate-180 opacity-0" : "scale-100 rotate-0 opacity-100"}`)}>`);
    Sun($$renderer2, { class: "h-[18px] w-[18px] text-neutral-700 dark:text-neutral-300" });
    $$renderer2.push(`<!----></div></button>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { onboarding });
  });
}
function HelpButton($$renderer, $$props) {
  let isFab;
  let variant = fallback($$props["variant"], "fab");
  let open = false;
  $: isFab = variant === "fab";
  $$renderer.push(`<div${attr("data-onboarding", isFab ? "help-button" : void 0)}${attr_class(clsx(isFab ? "fixed right-6 bottom-6 z-50 hidden md:block" : "relative md:hidden"), "svelte-fg9qtd")}>`);
  $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--> <button${attr_class(`parrot cursor-pointer ${isFab ? "group flex h-12 w-12 items-center justify-center rounded-full border border-neutral-300 bg-neutral-100 shadow-sm transition-shadow hover:shadow-md dark:border-neutral-700/60 dark:bg-neutral-900 dark:shadow-black/10" : "flex h-9 w-9 items-center justify-center rounded-md transition-colors hover:bg-neutral-200 dark:hover:bg-neutral-800"}`, "svelte-fg9qtd")} aria-label="Help">`);
  if (isFab) {
    $$renderer.push("<!--[0-->");
    $$renderer.push(`<span${attr_class("nav-icon-emoji text-2xl select-none svelte-fg9qtd", void 0, { "squawk": open })}>\u{1F99C}</span> <span${attr_class("nav-icon-lucide text-neutral-700 dark:text-neutral-200 svelte-fg9qtd", void 0, { "squawk": open })}>`);
    Bird($$renderer, {
      size: 24,
      class: "-scale-x-100"
    });
    $$renderer.push(`<!----></span>`);
  } else {
    $$renderer.push("<!--[-1-->");
    $$renderer.push(`<span${attr_class("nav-icon-emoji text-lg svelte-fg9qtd", void 0, { "squawk": open })}>\u{1F99C}</span> <span${attr_class("nav-icon-lucide svelte-fg9qtd", void 0, { "squawk": open })}>`);
    Bird($$renderer, { class: "h-[18px] w-[18px] -scale-x-100 text-neutral-700 dark:text-neutral-300" });
    $$renderer.push(`<!----></span>`);
  }
  $$renderer.push(`<!--]--></button></div>`);
  bind_props($$props, { variant });
}
function createMobileNavStore() {
  const { subscribe: subscribe2, set: set3, update: update4 } = writable(false);
  return {
    subscribe: subscribe2,
    open: () => set3(true),
    close: () => set3(false),
    toggle: () => update4((v3) => !v3)
  };
}
function createSidebarStore() {
  const { subscribe: subscribe2, set: set3, update: update4 } = writable(false);
  return {
    subscribe: subscribe2,
    toggle: () => update4((collapsed) => {
      return !collapsed;
    }),
    collapse: () => {
      set3(true);
    },
    expand: () => {
      set3(false);
    }
  };
}
function Navbar($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let collapsed, cutsceneActive, iconStyle, currentPathname, versionStatus, outOfDate, railLinks;
    let unreadAnnouncements = fallback($$props["unreadAnnouncements"], 0);
    function isActive(href, pathname) {
      return pathname === href || pathname.startsWith(href + "/");
    }
    $: collapsed = store_get($$store_subs ??= {}, "$sidebarCollapsed", sidebarCollapsed);
    $: cutsceneActive = store_get($$store_subs ??= {}, "$cutscene", cutscene).active;
    $: iconStyle = store_get($$store_subs ??= {}, "$navIconStore", navIconStore);
    $: currentPathname = store_get($$store_subs ??= {}, "$page", page).url.pathname;
    $: versionStatus = store_get($$store_subs ??= {}, "$page", page).data.versionStatus ?? null;
    $: outOfDate = versionStatus?.status === "out-of-date" && versionStatus.latestVersion;
    $: railLinks = [
      {
        label: "Dev",
        href: "/dev",
        icon: Wrench,
        emoji: "\u{1F6E0}\uFE0F",
        devOnly: true
      },
      {
        label: "Announcements",
        href: "/announcements",
        icon: Megaphone,
        emoji: "\u{1F4E3}",
        alert: unreadAnnouncements
      },
      {
        label: "Databases",
        href: "/databases",
        icon: Folder_tree,
        emoji: "\u{1F4E6}"
      },
      {
        label: "Arrs",
        href: "/arr",
        icon: Link,
        emoji: "\u{1F517}"
      },
      {
        label: "Quality Profiles",
        href: "/quality-profiles",
        icon: Sliders_vertical,
        emoji: "\u26A1"
      },
      {
        label: "Custom Formats",
        href: "/custom-formats",
        icon: Palette,
        emoji: "\u{1F3A8}"
      },
      {
        label: "Regular Expressions",
        href: "/regular-expressions",
        icon: Microscope,
        emoji: "\u{1F52C}"
      },
      {
        label: "Media Management",
        href: "/media-management",
        icon: Tag,
        emoji: "\u{1F3F7}\uFE0F"
      },
      {
        label: "Delay Profiles",
        href: "/delay-profiles",
        icon: Clock,
        emoji: "\u23F3"
      },
      {
        label: "Settings",
        href: "/settings",
        icon: Settings,
        emoji: "\u2699\uFE0F"
      }
    ];
    $$renderer2.push(`<nav${attr_class(`fixed top-0 left-0 z-50 w-full border-r-0 border-b border-neutral-200 bg-neutral-50 transition-[width,height] duration-200 ease-in-out md:z-[80] md:overflow-hidden md:border-r dark:border-neutral-800 dark:bg-neutral-900 ${collapsed ? "md:h-screen md:w-14" : "md:h-16 md:w-80"}`)}><div class="flex items-center justify-between gap-3 px-4 py-4 md:hidden"><div class="flex items-center gap-2"><button type="button" class="rounded-md p-1.5 text-neutral-500 hover:bg-neutral-200 hover:text-neutral-700 dark:hover:bg-neutral-800 dark:hover:text-neutral-300" aria-label="Open menu">`);
    Menu($$renderer2, { size: 20 });
    $$renderer2.push(`<!----></button></div> <div class="flex items-center justify-end gap-1">`);
    AccentPicker($$renderer2, {});
    $$renderer2.push(`<!----> `);
    ThemeToggle($$renderer2, {});
    $$renderer2.push(`<!----> `);
    HelpButton($$renderer2, { variant: "navbar" });
    $$renderer2.push(`<!----></div></div> <div${attr_class(`hidden items-center justify-between gap-3 px-4 py-4 whitespace-nowrap transition-opacity duration-150 ease-in-out md:flex ${collapsed ? "opacity-0" : "opacity-100"}`)}><div class="flex items-center gap-2"><img${attr("src", logo_512_default)} alt="Profilarr logo" class="ml-4 h-5 w-5 translate-y-[2px]"/> <div class="text-xl font-bold text-neutral-900 dark:text-neutral-100">profilarr</div></div> <div class="flex items-center justify-end gap-1">`);
    AccentPicker($$renderer2, { onboarding: "accent-picker" });
    $$renderer2.push(`<!----> `);
    ThemeToggle($$renderer2, { onboarding: "theme-toggle" });
    $$renderer2.push(`<!----> `);
    HelpButton($$renderer2, { variant: "navbar" });
    $$renderer2.push(`<!----> `);
    if (!cutsceneActive) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<button type="button" class="cursor-pointer rounded-md p-1.5 text-neutral-500 transition-colors hover:bg-neutral-200 hover:text-neutral-700 dark:hover:bg-neutral-800 dark:hover:text-neutral-300" aria-label="Collapse sidebar">`);
      Chevron_left($$renderer2, { size: 18 });
      $$renderer2.push(`<!----></button>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div></div> <div${attr_class(`absolute inset-0 hidden flex-col items-center transition-opacity duration-150 ease-in-out md:flex ${collapsed ? "pointer-events-auto opacity-100" : "pointer-events-none opacity-0"}`)}><div class="mt-4">`);
    Tooltip($$renderer2, {
      text: "Expand sidebar",
      position: "right",
      children: ($$renderer3) => {
        $$renderer3.push(`<button type="button" aria-label="Expand sidebar" class="flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-neutral-500 transition-colors hover:bg-neutral-100 hover:text-neutral-700 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-200">`);
        Chevron_right($$renderer3, { size: 16 });
        $$renderer3.push(`<!----></button>`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----></div> <div class="flex min-h-0 flex-1 items-center"><div class="flex max-h-full flex-col items-center gap-2 overflow-y-auto px-3"><!--[-->`);
    const each_array = ensure_array_like(railLinks);
    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
      let item = each_array[$$index];
      if (!item.devOnly || false) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="relative">`);
        Tooltip($$renderer2, {
          text: item.label,
          position: "right",
          children: ($$renderer3) => {
            $$renderer3.push(`<a${attr("href", item.href)}${attr("aria-label", item.label)}${attr_class(`flex h-9 w-9 items-center justify-center rounded-xl border border-transparent text-neutral-500 transition-colors hover:bg-neutral-100 hover:text-neutral-700 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-200 ${isActive(item.href, currentPathname) ? "border-neutral-300 bg-white text-neutral-700 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-200" : ""}`)}>`);
            if (iconStyle === "emoji") {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<span class="text-lg leading-none">${escape_html(item.emoji)}</span>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              if (item.icon) {
                $$renderer3.push("<!--[-->");
                item.icon($$renderer3, { size: 16 });
                $$renderer3.push("<!--]-->");
              } else {
                $$renderer3.push("<!--[!-->");
                $$renderer3.push("<!--]-->");
              }
            }
            $$renderer3.push(`<!--]--></a>`);
          },
          $$slots: { default: true }
        });
        $$renderer2.push(`<!----> `);
        if ((item.alert ?? 0) > 0) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<span class="absolute -top-0.5 -right-0.5 flex h-3.5 min-w-3.5 items-center justify-center rounded-full bg-blue-600 px-1 text-[9px] leading-none font-semibold text-white dark:bg-blue-500">${escape_html(item.alert)}</span>`);
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]--></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]-->`);
    }
    $$renderer2.push(`<!--]--></div></div> <a href="/" aria-label="Profilarr home" class="rounded-md p-1 transition-colors hover:bg-neutral-200 dark:hover:bg-neutral-800"><img${attr("src", logo_512_default)} alt="Profilarr" class="h-5 w-5"/></a> `);
    if (outOfDate) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="mt-2 mb-4">`);
      Button($$renderer2, {
        icon: Arrow_up,
        variant: "outline",
        size: "sm",
        href: versionStatus.releaseUrl ?? void 0,
        target: versionStatus.releaseUrl ? "_blank" : void 0,
        rel: versionStatus.releaseUrl ? "noopener noreferrer" : void 0,
        iconColor: "text-emerald-600 dark:text-emerald-400",
        tooltip: `Update Available: ${stringify(versionStatus.latestVersion)}`,
        tooltipPosition: "right"
      });
      $$renderer2.push(`<!----></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="mb-4"></div>`);
    }
    $$renderer2.push(`<!--]--></div></nav>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { unreadAnnouncements });
  });
}
function GroupHeader($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let isActive;
    let label = $$props["label"];
    let href = $$props["href"];
    let icon = fallback($$props["icon"], void 0);
    let emoji = fallback($$props["emoji"], void 0);
    let isOpen = $$props["isOpen"];
    let hasItems = $$props["hasItems"];
    let onToggle = $$props["onToggle"];
    let alert = fallback($$props["alert"], 0);
    $: isActive = hasItems ? store_get($$store_subs ??= {}, "$page", page).url.pathname === href : store_get($$store_subs ??= {}, "$page", page).url.pathname === href || store_get($$store_subs ??= {}, "$page", page).url.pathname.startsWith(href + "/");
    $$renderer2.push(`<div class="group/header flex items-center"><a${attr("href", href)}${attr_class(`flex flex-1 items-center gap-2 py-1.5 pr-2 pl-3 font-sans text-sm font-semibold text-neutral-700 transition-colors group-hover/header:bg-neutral-200 hover:bg-neutral-200 dark:text-neutral-300 dark:group-hover/header:bg-neutral-800 dark:hover:bg-neutral-800 ${hasItems ? "rounded-l-lg" : "rounded-lg"} ${isActive ? "bg-neutral-200 hover:bg-neutral-300 dark:bg-neutral-800 dark:hover:bg-neutral-700" : ""}`)}>`);
    if (emoji) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span class="nav-icon-emoji">${escape_html(emoji)}</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (icon) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span class="nav-icon-lucide">`);
      if (icon) {
        $$renderer2.push("<!--[-->");
        icon($$renderer2, { class: "h-4 w-4" });
        $$renderer2.push("<!--]-->");
      } else {
        $$renderer2.push("<!--[!-->");
        $$renderer2.push("<!--]-->");
      }
      $$renderer2.push(`</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <span class="flex-1">${escape_html(label)}</span> `);
    if (alert > 0) {
      $$renderer2.push("<!--[0-->");
      Label($$renderer2, {
        variant: "info",
        size: "sm",
        rounded: "full",
        children: ($$renderer3) => {
          $$renderer3.push(`<!---->${escape_html(alert)}`);
        },
        $$slots: { default: true }
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></a> `);
    if (hasItems) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<button${attr_class(`flex items-center self-stretch rounded-r-lg pr-1.5 pl-1.5 transition-colors group-hover/header:bg-neutral-200 hover:!bg-neutral-300 dark:group-hover/header:bg-neutral-800 dark:hover:!bg-neutral-700 ${isActive ? "bg-neutral-200 hover:!bg-neutral-300 dark:bg-neutral-800 dark:hover:!bg-neutral-700" : ""}`)}${attr("aria-label", isOpen ? "Collapse group" : "Expand group")}><svg${attr_class(`h-4 w-4 text-neutral-600 transition-transform dark:text-neutral-400 ${isOpen ? "rotate-90" : ""}`)} fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg></button>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      label,
      href,
      icon,
      emoji,
      isOpen,
      hasItems,
      onToggle,
      alert
    });
  });
}
function Group($$renderer, $$props) {
  let label = $$props["label"];
  let href = $$props["href"];
  let icon = fallback($$props["icon"], void 0);
  let emoji = fallback($$props["emoji"], void 0);
  let initialOpen = fallback($$props["initialOpen"], true);
  let hasItems = fallback($$props["hasItems"], false);
  let onboardingId = fallback($$props["onboardingId"], void 0);
  let alert = fallback($$props["alert"], 0);
  let isOpen = initialOpen;
  function toggleOpen() {
    isOpen = !isOpen;
  }
  $$renderer.push(`<div class="mb-4"><div${attr("data-onboarding", onboardingId)}>`);
  GroupHeader($$renderer, {
    label,
    href,
    icon,
    emoji,
    isOpen,
    hasItems,
    alert,
    onToggle: toggleOpen
  });
  $$renderer.push(`<!----></div> `);
  if (isOpen && hasItems) {
    $$renderer.push("<!--[0-->");
    $$renderer.push(`<div class="mt-2 grid grid-cols-[auto_1fr]"><div class="flex justify-center px-5"><div class="w-0.5 rounded-full bg-neutral-300 dark:bg-neutral-700"></div></div> <div class="-ml-3 flex flex-col gap-1"><!--[-->`);
    slot($$renderer, $$props, "default", {}, null);
    $$renderer.push(`<!--]--></div></div>`);
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--></div>`);
  bind_props($$props, {
    label,
    href,
    icon,
    emoji,
    initialOpen,
    hasItems,
    onboardingId,
    alert
  });
}
function GroupItem($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let { label, href, activePattern, icon, iconSrc, onclick, onboardingId, alert = 0 } = $$props;
    const isActive = derived(() => {
      const pathname = store_get($$store_subs ??= {}, "$page", page).url.pathname;
      if (activePattern) {
        if (typeof activePattern === "string") return pathname.includes(activePattern);
        return activePattern.test(pathname);
      }
      return pathname === href || pathname.startsWith(href + "/");
    });
    $$renderer2.push(`<a${attr("href", href)}${attr("data-onboarding", onboardingId)}${attr_class(`flex items-center gap-2 rounded-lg py-1.5 pr-2 pl-3 font-sans text-sm font-semibold text-neutral-600 transition-colors hover:bg-neutral-200 hover:text-neutral-900 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-100 ${isActive() ? "bg-neutral-200 text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100" : ""}`)}>`);
    if (iconSrc) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span class="nav-icon-emoji"><img${attr("src", iconSrc)} alt="" class="h-3.5 w-3.5"/></span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (icon) {
      $$renderer2.push("<!--[0-->");
      const Icon2 = icon;
      $$renderer2.push(`<span class="nav-icon-lucide">`);
      if (Icon2) {
        $$renderer2.push("<!--[-->");
        Icon2($$renderer2, { size: 14 });
        $$renderer2.push("<!--]-->");
      } else {
        $$renderer2.push("<!--[!-->");
        $$renderer2.push("<!--]-->");
      }
      $$renderer2.push(`</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <span class="flex-1">${escape_html(label)}</span> `);
    if (alert > 0) {
      $$renderer2.push("<!--[0-->");
      Label($$renderer2, {
        variant: "info",
        size: "sm",
        rounded: "full",
        children: ($$renderer3) => {
          $$renderer3.push(`<!---->${escape_html(alert)}`);
        },
        $$slots: { default: true }
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></a>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
function getPlatform() {
  return "linux-amd64";
}
function getPlatformLabel() {
  const platform = getPlatform();
  return PLATFORM_LABELS[platform] || platform;
}
function Version($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let versionStatus, outOfDate;
    const CHANNEL_LABELS = {
      stable: "stable",
      develop: "develop",
      dev: "unstable"
    };
    const platform = getPlatformLabel();
    const channelLabel = CHANNEL_LABELS[build.channel];
    const buildString = build.channel === "stable" ? `v${build.version}` : build.channel === "develop" ? build.version : null;
    const line = buildString ? `${platform} \xB7 ${channelLabel} \xB7 ${buildString}` : `${platform} \xB7 ${channelLabel}`;
    $: versionStatus = store_get($$store_subs ??= {}, "$page", page).data.versionStatus ?? null;
    $: outOfDate = versionStatus?.status === "out-of-date" && versionStatus.latestVersion;
    Card($$renderer2, {
      padding: "sm",
      flush: true,
      className: "mt-2",
      children: ($$renderer3) => {
        $$renderer3.push(`<div class="flex items-center gap-2.5"><img${attr("src", logo_512_default)} alt="Profilarr logo" class="h-5 w-5 flex-shrink-0"/> <div class="flex-1"><div class="text-xs font-semibold text-neutral-900 dark:text-neutral-50">profilarr</div> <div class="font-mono text-[10px] text-neutral-600 dark:text-neutral-400">${escape_html(line)}</div></div> `);
        if (outOfDate) {
          $$renderer3.push("<!--[0-->");
          Button($$renderer3, {
            icon: Arrow_up,
            variant: "outline",
            size: "md",
            href: versionStatus.releaseUrl ?? void 0,
            target: versionStatus.releaseUrl ? "_blank" : void 0,
            rel: versionStatus.releaseUrl ? "noopener noreferrer" : void 0,
            iconColor: "text-emerald-600 dark:text-emerald-400",
            tooltip: `Update Available: ${stringify(versionStatus.latestVersion)}`,
            tooltipPosition: "right"
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      },
      $$slots: { default: true }
    });
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
function JobStatus($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    function formatDuration2(ms) {
      if (ms < 1e3) return `${ms}ms`;
      if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
      return `${(ms / 6e4).toFixed(1)}m`;
    }
    Card($$renderer2, {
      padding: "sm",
      flush: true,
      className: "mt-2",
      children: ($$renderer3) => {
        $$renderer3.push(`<div class="flex items-center gap-2.5">`);
        if (store_get($$store_subs ??= {}, "$jobStatus", jobStatus).state === "running") {
          $$renderer3.push("<!--[0-->");
          Loader_circle($$renderer3, {
            size: 16,
            class: "flex-shrink-0 animate-spin text-blue-500 dark:text-blue-400"
          });
          $$renderer3.push(`<!----> <div class="flex-1"><div class="text-xs font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(store_get($$store_subs ??= {}, "$jobStatus", jobStatus).displayLabel)}</div></div>`);
        } else if (store_get($$store_subs ??= {}, "$jobStatus", jobStatus).state === "completed") {
          $$renderer3.push("<!--[1-->");
          if (store_get($$store_subs ??= {}, "$jobStatus", jobStatus).status === "success" || store_get($$store_subs ??= {}, "$jobStatus", jobStatus).status === "skipped") {
            $$renderer3.push("<!--[0-->");
            Circle_check($$renderer3, {
              size: 16,
              class: "flex-shrink-0 text-emerald-600 dark:text-emerald-400"
            });
          } else {
            $$renderer3.push("<!--[-1-->");
            Circle_x($$renderer3, {
              size: 16,
              class: "flex-shrink-0 text-red-600 dark:text-red-400"
            });
          }
          $$renderer3.push(`<!--]--> <div class="flex-1"><div class="text-xs font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(store_get($$store_subs ??= {}, "$jobStatus", jobStatus).displayLabel)}
					${escape_html(store_get($$store_subs ??= {}, "$jobStatus", jobStatus).status === "success" || store_get($$store_subs ??= {}, "$jobStatus", jobStatus).status === "skipped" ? "complete" : "failed")}</div> <div class="font-mono text-[10px] text-neutral-600 dark:text-neutral-400">${escape_html(formatDuration2(store_get($$store_subs ??= {}, "$jobStatus", jobStatus).durationMs))}</div></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      },
      $$slots: { default: true }
    });
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
function PageNav($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let arrInstances = fallback($$props["arrInstances"], () => [], true);
    let databases = fallback($$props["databases"], () => [], true);
    let parserAvailable = fallback($$props["parserAvailable"], true);
    let unreadAnnouncements = fallback($$props["unreadAnnouncements"], 0);
    $: store_get($$store_subs ??= {}, "$page", page).url.pathname, mobileNavOpen.close();
    if (store_get($$store_subs ??= {}, "$mobileNavOpen", mobileNavOpen)) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<button type="button" class="fixed inset-0 z-[60] bg-black/50 md:hidden" aria-label="Close menu"></button>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <nav data-onboarding="sidebar"${attr_class(`fixed top-0 left-0 z-[70] flex h-full w-[90vw] flex-col border-r border-neutral-200 bg-neutral-50 transition-transform duration-200 ease-in-out dark:border-neutral-800 dark:bg-neutral-900 ${store_get($$store_subs ??= {}, "$mobileNavOpen", mobileNavOpen) ? "translate-x-0" : "-translate-x-full"} md:top-16 md:h-[calc(100vh-4rem)] md:w-80 ${store_get($$store_subs ??= {}, "$sidebarCollapsed", sidebarCollapsed) ? "md:-translate-x-full" : "md:translate-x-0"}`)}><div class="flex items-center justify-between border-b border-neutral-200 py-4 pr-4 pl-8 md:hidden dark:border-neutral-800"><div class="flex items-center gap-2"><img${attr("src", logo_512_default)} alt="Profilarr logo" class="h-5 w-5"/> <span class="text-xl font-bold text-neutral-900 dark:text-neutral-100">profilarr</span></div> <button type="button" class="rounded-md p-1.5 text-neutral-500 hover:bg-neutral-200 hover:text-neutral-700 dark:hover:bg-neutral-800 dark:hover:text-neutral-300" aria-label="Close menu">`);
    X2($$renderer2, { size: 20 });
    $$renderer2.push(`<!----></button></div> <div class="flex-1 overflow-y-auto p-4">`);
    $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    Group($$renderer2, {
      label: "Announcements",
      emoji: "\u{1F4E3}",
      href: "/announcements",
      icon: Megaphone,
      alert: unreadAnnouncements
    });
    $$renderer2.push(`<!----> `);
    Group($$renderer2, {
      label: "Databases",
      emoji: "\u{1F4E6}",
      href: "/databases",
      icon: Folder_tree,
      hasItems: databases.length > 0,
      initialOpen: true,
      onboardingId: "nav-databases",
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(databases);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let db2 = each_array[$$index];
          GroupItem($$renderer3, {
            label: db2.name,
            href: `/databases/${stringify(db2.id)}`
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> `);
    Group($$renderer2, {
      label: "Arrs",
      emoji: "\u{1F517}",
      href: "/arr",
      icon: Link,
      hasItems: arrInstances.length > 0,
      initialOpen: true,
      onboardingId: "nav-arrs",
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array_1 = ensure_array_like(arrInstances);
        for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
          let instance = each_array_1[$$index_1];
          GroupItem($$renderer3, {
            label: instance.name,
            href: `/arr/${stringify(instance.id)}`,
            icon: instance.type === "radarr" ? Film : Tv,
            iconSrc: instance.type === "radarr" ? Radarr_default : Sonarr_default
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> <div data-onboarding="nav-config-entities">`);
    Group($$renderer2, {
      label: "Quality Profiles",
      emoji: "\u26A1",
      href: "/quality-profiles",
      icon: Sliders_vertical,
      initialOpen: true,
      hasItems: parserAvailable,
      onboardingId: "nav-quality-profiles",
      children: ($$renderer3) => {
        if (parserAvailable) {
          $$renderer3.push("<!--[0-->");
          GroupItem($$renderer3, {
            label: "Testing",
            href: "/quality-profiles/entity-testing"
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> `);
    Group($$renderer2, {
      label: "Custom Formats",
      emoji: "\u{1F3A8}",
      href: "/custom-formats",
      icon: Palette,
      initialOpen: false,
      onboardingId: "nav-custom-formats"
    });
    $$renderer2.push(`<!----> `);
    Group($$renderer2, {
      label: "Regular Expressions",
      emoji: "\u{1F52C}",
      href: "/regular-expressions",
      icon: Microscope,
      initialOpen: false,
      onboardingId: "nav-regex"
    });
    $$renderer2.push(`<!----> `);
    Group($$renderer2, {
      label: "Media Management",
      emoji: "\u{1F3F7}\uFE0F",
      href: "/media-management",
      icon: Tag,
      initialOpen: true,
      hasItems: true,
      onboardingId: "nav-media-management",
      children: ($$renderer3) => {
        GroupItem($$renderer3, {
          label: "Naming Settings",
          href: "/media-management?section=naming",
          activePattern: "/naming"
        });
        $$renderer3.push(`<!----> `);
        GroupItem($$renderer3, {
          label: "Quality Definitions",
          href: "/media-management?section=quality-definitions",
          activePattern: "/quality-definitions"
        });
        $$renderer3.push(`<!----> `);
        GroupItem($$renderer3, {
          label: "Media Settings",
          href: "/media-management?section=media-settings",
          activePattern: "/media-settings"
        });
        $$renderer3.push(`<!---->`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> `);
    Group($$renderer2, {
      label: "Delay Profiles",
      emoji: "\u23F3",
      href: "/delay-profiles",
      icon: Clock,
      initialOpen: false,
      onboardingId: "nav-delay-profiles"
    });
    $$renderer2.push(`<!----></div> `);
    Group($$renderer2, {
      label: "Settings",
      emoji: "\u2699\uFE0F",
      href: "/settings",
      icon: Settings,
      initialOpen: true,
      hasItems: true,
      onboardingId: "nav-settings",
      children: ($$renderer3) => {
        GroupItem($$renderer3, {
          label: "General",
          href: "/settings/general"
        });
        $$renderer3.push(`<!----> `);
        GroupItem($$renderer3, {
          label: "Jobs",
          href: "/settings/jobs"
        });
        $$renderer3.push(`<!----> `);
        GroupItem($$renderer3, {
          label: "Logs",
          href: "/settings/logs"
        });
        $$renderer3.push(`<!----> `);
        GroupItem($$renderer3, {
          label: "Backups",
          href: "/settings/backups"
        });
        $$renderer3.push(`<!----> `);
        GroupItem($$renderer3, {
          label: "Notifications",
          href: "/settings/notifications"
        });
        $$renderer3.push(`<!----> `);
        GroupItem($$renderer3, {
          label: "Security",
          href: "/settings/security"
        });
        $$renderer3.push(`<!----> `);
        GroupItem($$renderer3, {
          label: "Onboarding",
          href: "/onboarding",
          onboardingId: "nav-onboarding"
        });
        $$renderer3.push(`<!----> `);
        GroupItem($$renderer3, {
          label: "About",
          href: "/settings/about"
        });
        $$renderer3.push(`<!----> `);
        GroupItem($$renderer3, {
          label: "Log Out",
          href: "/auth/logout",
          onclick: (e) => {
            e.preventDefault();
            fetch("/auth/logout", { method: "POST" }).then(() => {
              window.location.href = "/auth/login";
            });
          }
        });
        $$renderer3.push(`<!---->`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> <div class="mt-2 md:hidden">`);
    Version($$renderer2, {});
    $$renderer2.push(`<!----></div></div> <div class="hidden shrink-0 p-4 md:block">`);
    if (store_get($$store_subs ??= {}, "$jobStatus", jobStatus).state !== "idle") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div>`);
      JobStatus($$renderer2, {});
      $$renderer2.push(`<!----></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    Version($$renderer2, {});
    $$renderer2.push(`<!----></div></nav>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      arrInstances,
      databases,
      parserAvailable,
      unreadAnnouncements
    });
  });
}
function BottomNav($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let pathname;
    function formatDuration2(ms) {
      if (ms < 1e3) return `${ms}ms`;
      if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
      return `${(ms / 6e4).toFixed(1)}m`;
    }
    const items = [
      {
        href: "/databases",
        label: "Databases",
        icon: Folder_tree,
        emoji: "\u{1F4E6}",
        priority: "always"
      },
      {
        href: "/arr",
        label: "Arrs",
        icon: Link,
        emoji: "\u{1F517}",
        priority: "always"
      },
      {
        href: "/quality-profiles",
        label: "Profiles",
        icon: Sliders_vertical,
        emoji: "\u26A1",
        priority: "always"
      },
      {
        href: "/custom-formats",
        label: "Formats",
        icon: Palette,
        emoji: "\u{1F3A8}",
        priority: "always"
      },
      {
        href: "/settings",
        label: "Settings",
        icon: Settings,
        emoji: "\u2699\uFE0F",
        priority: "always"
      },
      {
        href: "/regular-expressions",
        label: "Regex",
        icon: Microscope,
        emoji: "\u{1F52C}",
        priority: "medium"
      },
      {
        href: "/media-management",
        label: "Media",
        icon: Tag,
        emoji: "\u{1F3F7}\uFE0F",
        priority: "low"
      },
      {
        href: "/delay-profiles",
        label: "Delay",
        icon: Clock,
        emoji: "\u23F3",
        priority: "low"
      }
    ];
    function isActive(href, currentPath) {
      if (href === "/") return currentPath === "/";
      return currentPath.startsWith(href);
    }
    $: pathname = store_get($$store_subs ??= {}, "$page", page).url.pathname;
    $$renderer2.push(`<nav class="fixed right-0 bottom-0 left-0 z-50 border-t border-neutral-200 bg-neutral-50 pb-[env(safe-area-inset-bottom)] md:hidden dark:border-neutral-800 dark:bg-neutral-900">`);
    if (store_get($$store_subs ??= {}, "$jobStatus", jobStatus).state !== "idle") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="flex items-center justify-center gap-2 border-b border-neutral-200 px-3 py-1.5 dark:border-neutral-800">`);
      if (store_get($$store_subs ??= {}, "$jobStatus", jobStatus).state === "running") {
        $$renderer2.push("<!--[0-->");
        Loader_circle($$renderer2, {
          size: 14,
          class: "flex-shrink-0 animate-spin text-blue-500 dark:text-blue-400"
        });
        $$renderer2.push(`<!----> <span class="text-xs font-medium text-neutral-700 dark:text-neutral-300">${escape_html(store_get($$store_subs ??= {}, "$jobStatus", jobStatus).displayLabel)}</span>`);
      } else if (store_get($$store_subs ??= {}, "$jobStatus", jobStatus).state === "completed") {
        $$renderer2.push("<!--[1-->");
        if (store_get($$store_subs ??= {}, "$jobStatus", jobStatus).status === "success" || store_get($$store_subs ??= {}, "$jobStatus", jobStatus).status === "skipped") {
          $$renderer2.push("<!--[0-->");
          Circle_check($$renderer2, {
            size: 14,
            class: "flex-shrink-0 text-emerald-600 dark:text-emerald-400"
          });
        } else {
          $$renderer2.push("<!--[-1-->");
          Circle_x($$renderer2, {
            size: 14,
            class: "flex-shrink-0 text-red-600 dark:text-red-400"
          });
        }
        $$renderer2.push(`<!--]--> <span class="text-xs font-medium text-neutral-700 dark:text-neutral-300">${escape_html(store_get($$store_subs ??= {}, "$jobStatus", jobStatus).displayLabel)}
					${escape_html(store_get($$store_subs ??= {}, "$jobStatus", jobStatus).status === "success" || store_get($$store_subs ??= {}, "$jobStatus", jobStatus).status === "skipped" ? "complete" : "failed")}</span> <span class="font-mono text-[10px] text-neutral-500 dark:text-neutral-500">${escape_html(formatDuration2(store_get($$store_subs ??= {}, "$jobStatus", jobStatus).durationMs))}</span>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div class="flex items-center justify-around px-1"><!--[-->`);
    const each_array = ensure_array_like(items);
    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
      let item = each_array[$$index];
      const active = isActive(item.href, pathname);
      $$renderer2.push(`<a${attr("href", item.href)}${attr_class(`flex flex-col items-center justify-center py-2 transition-colors ${item.priority === "medium" ? "hidden sm:flex" : ""} ${item.priority === "low" ? "hidden" : ""} ${active ? "text-accent-600 dark:text-accent-400" : "text-neutral-500 hover:text-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-200"}`)}><span class="nav-icon-emoji text-xl">${escape_html(item.emoji)}</span> <span class="nav-icon-lucide">`);
      if (item.icon) {
        $$renderer2.push("<!--[-->");
        item.icon($$renderer2, {
          size: 20,
          strokeWidth: active ? 2.5 : 2
        });
        $$renderer2.push("<!--]-->");
      } else {
        $$renderer2.push("<!--[!-->");
        $$renderer2.push("<!--]-->");
      }
      $$renderer2.push(`</span> <span class="mt-0.5 text-[10px] font-medium">${escape_html(item.shortLabel ?? item.label)}</span></a>`);
    }
    $$renderer2.push(`<!--]--></div></nav>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
function Alert($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let id = $$props["id"];
    let type = $$props["type"];
    let message2 = $$props["message"];
    const icons = {
      success: Circle_check_big,
      error: Circle_x,
      warning: Triangle_alert,
      info: Info
    };
    const styles = {
      success: "border-emerald-200 bg-emerald-50 text-emerald-900 hover:bg-emerald-100/80 dark:border-emerald-800/60 dark:bg-emerald-950/50 dark:text-emerald-100 dark:hover:bg-emerald-950/70",
      error: "border-red-200 bg-red-50 text-red-900 hover:bg-red-100/80 dark:border-red-800/60 dark:bg-red-950/50 dark:text-red-100 dark:hover:bg-red-950/70",
      warning: "border-amber-200 bg-amber-50 text-amber-900 hover:bg-amber-100/80 dark:border-amber-800/60 dark:bg-amber-950/50 dark:text-amber-100 dark:hover:bg-amber-950/70",
      info: "border-sky-200 bg-sky-50 text-sky-900 hover:bg-sky-100/80 dark:border-sky-800/60 dark:bg-sky-950/50 dark:text-sky-100 dark:hover:bg-sky-950/70"
    };
    const iconColors = {
      success: "text-emerald-600 dark:text-emerald-300",
      error: "text-red-600 dark:text-red-300",
      warning: "text-amber-600 dark:text-amber-300",
      info: "text-sky-600 dark:text-sky-300"
    };
    const Icon2 = icons[type];
    $$renderer2.push(`<div role="button" tabindex="0"${attr_class(`flex cursor-pointer items-center gap-3 rounded-xl border px-4 py-3 shadow-lg shadow-black/5 backdrop-blur-sm transition-colors ${stringify(styles[type])}`)}>`);
    Icon2($$renderer2, {
      size: 18,
      class: `flex-shrink-0 ${stringify(iconColors[type])}`
    });
    $$renderer2.push(`<!----> <p class="text-sm font-medium">${escape_html(message2)}</p></div>`);
    bind_props($$props, {
      id,
      type,
      message: message2
    });
  });
}
function AlertContainer($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let position, isAuthPage;
    const positionClasses = {
      "top-left": "top-4 left-4",
      "top-center": "top-4 left-1/2 -translate-x-1/2",
      "top-right": "top-4 right-4",
      "bottom-left": "bottom-4 left-4",
      "bottom-center": "bottom-4 left-1/2 -translate-x-1/2",
      "bottom-right": "bottom-4 right-4"
    };
    $: position = positionClasses[store_get($$store_subs ??= {}, "$alertSettingsStore", alertSettingsStore).position] ?? positionClasses["top-center"];
    $: isAuthPage = store_get($$store_subs ??= {}, "$page", page).url.pathname.startsWith("/auth/");
    $$renderer2.push(`<div${attr_class(`pointer-events-none fixed inset-0 z-[100] transition-[padding-left] duration-200 ease-in-out ${isAuthPage ? "" : `pt-16 pb-16 md:pt-0 md:pb-0 ${store_get($$store_subs ??= {}, "$sidebarCollapsed", sidebarCollapsed) ? "md:pl-10" : "md:pl-80"}`}`)}><div class="relative h-full w-full"><div${attr_class(`pointer-events-none absolute flex w-[calc(100%-2rem)] max-w-sm flex-col gap-2 ${stringify(position)}`)}><!--[-->`);
    const each_array = ensure_array_like(store_get($$store_subs ??= {}, "$alertStore", alertStore));
    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
      let alert = each_array[$$index];
      $$renderer2.push(`<div class="pointer-events-auto">`);
      Alert($$renderer2, {
        id: alert.id,
        type: alert.type,
        message: alert.message
      });
      $$renderer2.push(`<!----></div>`);
    }
    $$renderer2.push(`<!--]--></div></div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
function setupCompletion(step, onComplete) {
  teardownCompletion();
  switch (step.completion.type) {
    case "click": {
      if (!step.target) {
        onComplete();
        return;
      }
      const target = step.target;
      const tryAttach = () => {
        const el = document.querySelector(`[data-onboarding="${target}"]`);
        if (!el) return false;
        const handler = () => {
          onComplete();
        };
        el.addEventListener("click", handler, { once: true });
        cleanup = () => el.removeEventListener("click", handler);
        return true;
      };
      if (tryAttach()) return;
      const observer = new MutationObserver(() => {
        if (tryAttach()) observer.disconnect();
      });
      observer.observe(document.body, {
        childList: true,
        subtree: true
      });
      cleanup = () => observer.disconnect();
      break;
    }
    case "route": {
      const targetPath = step.completion.path;
      const checkRoute = () => {
        return window.location.pathname === targetPath;
      };
      if (checkRoute()) {
        onComplete();
        return;
      }
      const interval = setInterval(() => {
        if (checkRoute()) {
          clearInterval(interval);
          onComplete();
        }
      }, 200);
      cleanup = () => clearInterval(interval);
      break;
    }
    case "state": {
      const checkName = step.completion.check;
      const checkFn = stateChecks[checkName];
      if (!checkFn) {
        console.warn(`Unknown state check: ${checkName}`);
        return;
      }
      let active = true;
      const poll = async () => {
        while (active) {
          try {
            if (await checkFn()) {
              if (active) onComplete();
              return;
            }
          } catch {
          }
          await new Promise((r2) => setTimeout(r2, 1500));
        }
      };
      poll();
      cleanup = () => {
        active = false;
      };
      break;
    }
  }
}
function teardownCompletion() {
  if (cleanup) {
    cleanup();
    cleanup = null;
  }
}
function CutsceneProgress($$renderer, $$props) {
  let progressPercent, isLastStep;
  let currentStep = fallback($$props["currentStep"], 0);
  let totalSteps = fallback($$props["totalSteps"], 0);
  let onBack = fallback($$props["onBack"], void 0);
  let onForward = fallback($$props["onForward"], void 0);
  let showBack = fallback($$props["showBack"], true);
  $: progressPercent = totalSteps > 0 ? (currentStep + 1) / totalSteps * 100 : 0;
  $: isLastStep = currentStep + 1 === totalSteps;
  $$renderer.push(`<div class="flex flex-col gap-1.5"><div class="text-right text-xs text-neutral-400 dark:text-neutral-500">${escape_html(currentStep + 1)}/${escape_html(totalSteps)}</div> <div class="flex h-8 items-stretch">`);
  if (showBack) {
    $$renderer.push("<!--[0-->");
    $$renderer.push(`<button class="flex h-8 w-8 shrink-0 cursor-pointer items-center justify-center rounded-l-lg border border-neutral-300 bg-white text-neutral-500 transition-colors hover:bg-neutral-100 hover:text-neutral-700 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-200">`);
    Chevron_left($$renderer, { size: 14 });
    $$renderer.push(`<!----></button>`);
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--> <div${attr_class("relative flex min-w-[120px] flex-1 items-center overflow-hidden border-y border-neutral-300 bg-neutral-200/50 dark:border-neutral-700/60 dark:bg-neutral-800/30", void 0, {
    "border-l": !showBack,
    "rounded-l-lg": !showBack,
    "border-r": !onForward,
    "rounded-r-lg": !onForward
  })}><div class="absolute inset-y-0 left-0 bg-accent-500 transition-all duration-300"${attr_style(`width: ${stringify(progressPercent)}%`)}></div></div> `);
  if (onForward) {
    $$renderer.push("<!--[0-->");
    $$renderer.push(`<button class="flex h-8 w-8 shrink-0 cursor-pointer items-center justify-center rounded-r-lg border border-l-0 border-neutral-300 bg-white text-neutral-500 transition-colors hover:bg-neutral-100 hover:text-neutral-700 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-200">`);
    if (isLastStep) {
      $$renderer.push("<!--[0-->");
      Check($$renderer, {
        size: 14,
        class: "text-green-500"
      });
    } else {
      $$renderer.push("<!--[-1-->");
      Chevron_right($$renderer, { size: 14 });
    }
    $$renderer.push(`<!--]--></button>`);
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--></div></div>`);
  bind_props($$props, {
    currentStep,
    totalSteps,
    onBack,
    onForward,
    showBack
  });
}
function CutsceneCard($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let cancelTooltip, bodySegments;
    let title = $$props["title"];
    let body = $$props["body"];
    let onBack = fallback($$props["onBack"], void 0);
    let onForward = fallback($$props["onForward"], void 0);
    let onCancel = fallback($$props["onCancel"], void 0);
    let showBack = fallback($$props["showBack"], true);
    let currentStep = fallback($$props["currentStep"], 0);
    let totalSteps = fallback($$props["totalSteps"], 0);
    const cancelQuips = [
      "Wow. After all that.",
      "Fine. See if I care.",
      "I was just getting into it...",
      "Quitter. I'm not mad, just disappointed.",
      "My time means nothing to you, clearly."
    ];
    $: cancelTooltip = cancelQuips[Math.floor(Math.random() * cancelQuips.length)];
    $: bodySegments = (() => {
      const parts = body.split("`");
      if (parts.length % 2 === 0) return [{
        code: false,
        text: body
      }];
      return parts.map((text2, i) => ({
        code: i % 2 === 1,
        text: text2
      }));
    })();
    $$renderer2.push(`<div class="flex flex-col gap-3 rounded-xl border border-neutral-300 bg-neutral-100 p-4 dark:border-neutral-700/60 dark:bg-neutral-900"><div><div class="flex items-start justify-between gap-2"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(title)}</h3> `);
    if (onCancel) {
      $$renderer2.push("<!--[0-->");
      Button($$renderer2, {
        icon: X2,
        variant: "ghost",
        size: "xs",
        title: cancelTooltip
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div> <p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400"><!--[-->`);
    const each_array = ensure_array_like(bodySegments);
    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
      let segment = each_array[$$index];
      if (segment.code) {
        $$renderer2.push("<!--[0-->");
        InlineCode($$renderer2, {
          text: segment.text,
          rounded: "sm"
        });
      } else {
        $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`${escape_html(segment.text)}`);
      }
      $$renderer2.push(`<!--]-->`);
    }
    $$renderer2.push(`<!--]--></p></div> `);
    CutsceneProgress($$renderer2, {
      currentStep,
      totalSteps,
      onBack,
      onForward,
      showBack
    });
    $$renderer2.push(`<!----></div>`);
    bind_props($$props, {
      title,
      body,
      onBack,
      onForward,
      onCancel,
      showBack,
      currentStep,
      totalSteps
    });
  });
}
function CutsceneOverlay($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let state2, step, active, isFirstStep, progressInfo, spotlightRect, interactionSpotlightRects, clickThroughRects, clipPath, cardStyle;
    let targetRect = null;
    let windowWidth = 0;
    let windowHeight = 0;
    let interactionRects = [];
    const { currentStep } = cutscene;
    const PAD = 8;
    const INTERACTION_PAD = 2;
    const RADIUS = 12;
    let animatedRect = {
      x: 0,
      y: 0,
      w: 0,
      h: 0
    };
    let animating = false;
    function lerpRect(from, to, duration) {
      const start = performance.now();
      animating = true;
      function frame(now) {
        const t2 = Math.min((now - start) / duration, 1);
        const ease = t2 < 0.5 ? 2 * t2 * t2 : 1 - Math.pow(-2 * t2 + 2, 2) / 2;
        animatedRect = {
          x: from.x + (to.x - from.x) * ease,
          y: from.y + (to.y - from.y) * ease,
          w: from.w + (to.w - from.w) * ease,
          h: from.h + (to.h - from.h) * ease
        };
        if (t2 < 1) requestAnimationFrame(frame);
        else animating = false;
      }
      requestAnimationFrame(frame);
    }
    function isInViewport(el) {
      const rect = el.getBoundingClientRect();
      return rect.top >= 0 && rect.bottom <= window.innerHeight;
    }
    function isInsideSidebar(target) {
      const el = document.querySelector(`[data-onboarding="${target}"]`);
      if (!el) return false;
      const sidebar = document.querySelector('[data-onboarding="sidebar"]');
      return !!sidebar && (sidebar === el || sidebar.contains(el));
    }
    function ensureSidebarExpanded() {
      if (!store_get($$store_subs ??= {}, "$sidebarCollapsed", sidebarCollapsed)) return Promise.resolve();
      sidebarCollapsed.expand();
      return new Promise((r2) => setTimeout(r2, 250));
    }
    function rectChanged(current3, next2) {
      return Math.abs(current3.x - next2.x) > 0.5 || Math.abs(current3.y - next2.y) > 0.5 || Math.abs(current3.w - next2.w) > 0.5 || Math.abs(current3.h - next2.h) > 0.5;
    }
    function findTarget() {
      if (!step?.target) {
        targetRect = null;
        interactionRects = [];
        return;
      }
      const el = document.querySelector(`[data-onboarding="${step.target}"]`);
      if (el) {
        if (!isInViewport(el)) {
          el.scrollIntoView({
            block: "center",
            behavior: "smooth"
          });
          setTimeout(() => findTarget(), 400);
          return;
        }
        const rect = el.getBoundingClientRect();
        const newRect = {
          x: rect.left - PAD,
          y: rect.top - PAD,
          w: rect.width + 16,
          h: rect.height + 16
        };
        if (targetRect && (animatedRect.w > 0 || animatedRect.h > 0) && rectChanged(animatedRect, newRect)) lerpRect(animatedRect, newRect, 500);
        else animatedRect = newRect;
        targetRect = rect;
        interactionRects = (step.interactionTargets ?? []).map((target) => document.querySelector(`[data-onboarding="${target}"]`)).filter((target) => target !== null).map((target) => target.getBoundingClientRect()).filter((target) => target.width > 0 && target.height > 0);
      } else {
        targetRect = null;
        interactionRects = [];
      }
    }
    function updateDimensions() {
      windowWidth = window.innerWidth;
      windowHeight = window.innerHeight;
      findTarget();
    }
    let lastStepId = null;
    let cardReady = false;
    async function resolveRoute(route) {
      if (typeof route === "string") return route;
      const resolver = routeResolvers[route.resolve];
      if (!resolver) return "/";
      return resolver();
    }
    function onScroll() {
      if (!animating) requestAnimationFrame(findTarget);
    }
    afterNavigate(() => {
      if (active) (/* @__PURE__ */ tick()).then(() => requestAnimationFrame(findTarget));
    });
    let observer = null;
    function padRect(rect, padding) {
      return {
        x: rect.left - padding,
        y: rect.top - padding,
        w: rect.width + padding * 2,
        h: rect.height + padding * 2
      };
    }
    function overlaps(a2, b3) {
      return a2.x <= b3.x + b3.w && a2.x + a2.w >= b3.x && a2.y <= b3.y + b3.h && a2.y + a2.h >= b3.y;
    }
    function mergeOverlappingRects(rects) {
      const merged = rects.map((rect) => ({ ...rect }));
      let changed = true;
      while (changed) {
        changed = false;
        for (let i = 0; i < merged.length; i++) {
          for (let j2 = i + 1; j2 < merged.length; j2++) {
            if (!overlaps(merged[i], merged[j2])) continue;
            const left = Math.min(merged[i].x, merged[j2].x);
            const top = Math.min(merged[i].y, merged[j2].y);
            const right = Math.max(merged[i].x + merged[i].w, merged[j2].x + merged[j2].w);
            const bottom = Math.max(merged[i].y + merged[i].h, merged[j2].y + merged[j2].h);
            merged[i] = {
              x: left,
              y: top,
              w: right - left,
              h: bottom - top
            };
            merged.splice(j2, 1);
            changed = true;
            break;
          }
          if (changed) break;
        }
      }
      return merged;
    }
    function computeClipPath(rects) {
      if (rects.length === 0) return "none";
      return `path(evenodd, "${`M0,0 H${windowWidth} V${windowHeight} H0 Z`} ${rects.map((rect) => {
        const l3 = rect.x;
        const t2 = rect.y;
        const r2 = rect.x + rect.w;
        const b3 = rect.y + rect.h;
        const radius = Math.min(RADIUS, rect.w / 2, rect.h / 2);
        return `M${l3 + radius},${t2} H${r2 - radius} Q${r2},${t2} ${r2},${t2 + radius} V${b3 - radius} Q${r2},${b3} ${r2 - radius},${b3} H${l3 + radius} Q${l3},${b3} ${l3},${b3 - radius} V${t2 + radius} Q${l3},${t2} ${l3 + radius},${t2} Z`;
      }).join(" ")}")`;
    }
    function computeCardPosition(position, rect) {
      if (!rect || position === "center") return "position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);";
      const gap = 16;
      switch (position) {
        case "above":
          return `position: fixed; bottom: ${windowHeight - rect.top + gap + PAD}px; left: ${rect.left + rect.width / 2}px; transform: translateX(-50%);`;
        case "below":
          return `position: fixed; top: ${rect.bottom + gap + PAD}px; left: ${rect.left + rect.width / 2}px; transform: translateX(-50%);`;
        case "left":
          return `position: fixed; top: ${rect.top + rect.height / 2}px; right: ${windowWidth - rect.left + gap + PAD}px; transform: translateY(-50%);`;
        case "right":
          return `position: fixed; top: ${rect.top + rect.height / 2}px; left: ${rect.right + gap + PAD}px; transform: translateY(-50%);`;
        case "above-left":
          return `position: fixed; bottom: ${windowHeight - rect.top + gap + PAD}px; right: ${windowWidth - rect.right + gap + PAD}px;`;
        case "above-right":
          return `position: fixed; bottom: ${windowHeight - rect.top + gap + PAD}px; left: ${rect.left - gap - PAD}px;`;
        case "below-left":
          return `position: fixed; top: ${rect.bottom + gap + PAD}px; right: ${windowWidth - rect.right}px;`;
        case "below-right":
          return `position: fixed; top: ${rect.bottom + gap + PAD}px; left: ${rect.right + gap}px;`;
        default:
          return `position: fixed; top: ${rect.bottom + gap + PAD}px; left: ${rect.left + rect.width / 2}px; transform: translateX(-50%);`;
      }
    }
    function handleForward() {
      cutscene.advance();
    }
    function handleBack() {
      cutscene.goBack();
    }
    function handleCancel() {
      teardownCompletion();
      cutscene.cancel();
    }
    function preventScroll(e) {
      e.preventDefault();
    }
    onDestroy(() => {
      teardownCompletion();
      observer?.disconnect();
      if (typeof window !== "undefined") {
        window.removeEventListener("wheel", preventScroll);
        window.removeEventListener("touchmove", preventScroll);
        window.removeEventListener("scroll", onScroll, true);
        window.removeEventListener("resize", updateDimensions);
      }
    });
    $: state2 = store_get($$store_subs ??= {}, "$cutscene", cutscene);
    $: step = store_get($$store_subs ??= {}, "$currentStep", currentStep);
    $: active = state2.active;
    $: isFirstStep = state2.stepIndex === 0;
    $: progressInfo = (() => {
      if (!state2.active || !state2.stageId) return {
        current: 0,
        total: 0
      };
      const stage2 = STAGES[state2.stageId];
      if (!stage2) return {
        current: 0,
        total: 0
      };
      return {
        current: state2.stepIndex,
        total: stage2.steps.length
      };
    })();
    $: if (step && step.id !== lastStepId && typeof window !== "undefined") {
      lastStepId = step.id;
      cardReady = false;
      teardownCompletion();
      setupCompletion(step, () => cutscene.advance());
      const afterNav = () => {
        (/* @__PURE__ */ tick()).then(async () => {
          if (step.target && isInsideSidebar(step.target)) await ensureSidebarExpanded();
          requestAnimationFrame(() => {
            findTarget();
            setTimeout(() => {
              cardReady = true;
            }, animating ? 0 : 200);
          });
        });
      };
      if (step.route) resolveRoute(step.route).then((resolved) => {
        if (window.location.pathname !== resolved) goto(resolved).then(afterNav);
        else afterNav();
      });
      else afterNav();
    } else if (!step) lastStepId = null;
    $: if (active && typeof window !== "undefined") {
      window.addEventListener("scroll", onScroll, true);
      window.addEventListener("resize", updateDimensions);
    }
    $: if (typeof window !== "undefined") {
      observer?.disconnect();
      observer = null;
      if (step?.target && (!targetRect || (step.interactionTargets?.length ?? 0) > 0)) {
        observer = new MutationObserver(() => findTarget());
        observer.observe(document.body, {
          childList: true,
          subtree: true
        });
      }
    }
    $: spotlightRect = animatedRect;
    $: interactionSpotlightRects = interactionRects.map((rect) => padRect(rect, INTERACTION_PAD));
    $: clickThroughRects = mergeOverlappingRects([...targetRect ? [padRect(targetRect, PAD)] : [], ...interactionSpotlightRects]);
    $: clipPath = computeClipPath(clickThroughRects);
    $: cardStyle = computeCardPosition(step?.position, targetRect);
    $: if (typeof window !== "undefined") if (active) {
      window.addEventListener("wheel", preventScroll, { passive: false });
      window.addEventListener("touchmove", preventScroll, { passive: false });
    } else {
      window.removeEventListener("wheel", preventScroll);
      window.removeEventListener("touchmove", preventScroll);
    }
    if (active && step) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="fixed inset-0 z-[9999]" style="pointer-events: none;"><svg class="absolute inset-0 h-full w-full" style="pointer-events: none;"><defs><mask id="cutscene-mask"><rect width="100%" height="100%" fill="white"></rect>`);
      if (targetRect) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<rect${attr("x", spotlightRect.x)}${attr("y", spotlightRect.y)}${attr("width", spotlightRect.w)}${attr("height", spotlightRect.h)}${attr("rx", RADIUS)}${attr("ry", RADIUS)} fill="black"></rect>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--><!--[-->`);
      const each_array = ensure_array_like(interactionSpotlightRects);
      for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
        let rect = each_array[$$index];
        $$renderer2.push(`<rect${attr("x", rect.x)}${attr("y", rect.y)}${attr("width", rect.w)}${attr("height", rect.h)}${attr("rx", RADIUS)}${attr("ry", RADIUS)} fill="black"></rect>`);
      }
      $$renderer2.push(`<!--]--></mask></defs><rect width="100%" height="100%" fill="rgba(0, 0, 0, 0.6)" mask="url(#cutscene-mask)" style="pointer-events: none;"></rect></svg> `);
      if (!step.freeInteract) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="absolute inset-0"${attr_style(`pointer-events: auto; clip-path: ${stringify(clipPath)};`)}></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> `);
      if (!animating && cardReady) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="max-w-sm"${attr_style(`${stringify(cardStyle)} pointer-events: auto; z-index: 1;`)}>`);
        CutsceneCard($$renderer2, {
          title: step.title,
          body: step.body,
          onBack: handleBack,
          onForward: step.completion.type === "manual" ? handleForward : void 0,
          onCancel: handleCancel,
          showBack: !isFirstStep,
          currentStep: progressInfo.current,
          totalSteps: progressInfo.total
        });
        $$renderer2.push(`<!----></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
function CutsceneComplete($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let open;
    const { justCompleted } = cutscene;
    const quips = [
      "ANOTHER ONE?",
      "We're done already? That was painless. For you.",
      "Look at you go. A natural.",
      "Great, you finished. I'm billing you for overtime.",
      "That wasn't so bad, was it? Don't answer that.",
      "Achievement unlocked: tolerated a parrot.",
      "Congrats. I'll add it to your resume.",
      "One down. Only... several more to go.",
      "Alright, what's next? I was just getting comfortable.",
      "If you click 'Back to Onboarding' I swear..."
    ];
    let quip = quips[0];
    $: if (store_get($$store_subs ??= {}, "$justCompleted", justCompleted)) quip = quips[Math.floor(Math.random() * quips.length)];
    $: open = store_get($$store_subs ??= {}, "$justCompleted", justCompleted);
    Modal($$renderer2, {
      open,
      header: "Stage Complete",
      size: "sm",
      $$slots: {
        body: ($$renderer3) => {
          $$renderer3.push(`<div slot="body"><div class="mb-4 flex justify-center text-4xl"><span class="nav-icon-emoji">\u{1F99C}</span> <span class="nav-icon-lucide">`);
          Bird($$renderer3, {
            size: 36,
            class: "-scale-x-100 text-neutral-700 dark:text-neutral-200"
          });
          $$renderer3.push(`<!----></span></div> <p class="text-center text-sm text-neutral-500 italic dark:text-neutral-400">${escape_html(quip)}</p></div>`);
        },
        footer: ($$renderer3) => {
          $$renderer3.push(`<div slot="footer" class="flex w-full justify-between">`);
          Button($$renderer3, {
            text: "I'm done",
            icon: X2
          });
          $$renderer3.push(`<!----> `);
          Button($$renderer3, {
            text: "Back to Onboarding",
            icon: Arrow_right,
            variant: "primary"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
function _layout($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let isAuthPage, cutsceneEnabled, isDesktop;
    let data = $$props["data"];
    $: serverTimezone.set(data.timezone);
    $: dateFormat.set(data.dateFormat);
    $: isAuthPage = store_get($$store_subs ??= {}, "$page", page).url.pathname.startsWith("/auth/");
    $: cutsceneEnabled = FEATURES.cutscene || false;
    $: isDesktop = false;
    head("12qhfyh", $$renderer2, ($$renderer3) => {
      $$renderer3.title(($$renderer4) => {
        $$renderer4.push(`<title>Profilarr</title>`);
      });
      $$renderer3.push(`<link rel="icon"${attr("href", logo_512_default)}/>`);
    });
    if (!isAuthPage) {
      $$renderer2.push("<!--[0-->");
      Navbar($$renderer2, { unreadAnnouncements: data.unreadAnnouncements });
      $$renderer2.push(`<!----> `);
      PageNav($$renderer2, {
        arrInstances: data.arrInstances,
        databases: data.databases,
        parserAvailable: data.parserAvailable,
        unreadAnnouncements: data.unreadAnnouncements
      });
      $$renderer2.push(`<!----> `);
      BottomNav($$renderer2, {});
      $$renderer2.push(`<!----> `);
      HelpButton($$renderer2, {});
      $$renderer2.push(`<!----> `);
      if (cutsceneEnabled && isDesktop) {
        $$renderer2.push("<!--[0-->");
        CutsceneOverlay($$renderer2, {});
        $$renderer2.push(`<!----> `);
        CutsceneComplete($$renderer2, {});
        $$renderer2.push(`<!---->`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]-->`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    AlertContainer($$renderer2, {});
    $$renderer2.push(`<!----> <main${attr_class(`${isAuthPage ? "" : `pt-16 pb-16 md:pt-0 md:pb-0 ${store_get($$store_subs ??= {}, "$sidebarCollapsed", sidebarCollapsed) ? "md:pl-14" : "md:pl-80"}`} transition-[padding-left] duration-200 ease-in-out`)}>`);
    if (data.restorePending && !isAuthPage) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="flex h-16 items-center gap-3 border-b border-neutral-200 bg-neutral-50 px-4 text-sm text-neutral-700 dark:border-neutral-800 dark:bg-neutral-900 dark:text-neutral-200" role="status">`);
      Triangle_alert($$renderer2, { class: "h-5 w-5 shrink-0 text-amber-500 dark:text-amber-400" });
      $$renderer2.push(`<!----> <div class="min-w-0 flex-1 truncate"><strong class="font-semibold">Restore pending:</strong> <span class="font-mono">${escape_html(data.restorePending.filename)}</span> <span class="hidden md:inline">will be applied on the next restart. Any changes you make now will be lost.</span></div> <form class="shrink-0" method="POST" action="/settings/backups?/cancelRestore">`);
      Button($$renderer2, {
        type: "submit",
        size: "sm",
        text: "Cancel restore",
        icon: X2,
        iconColor: "text-red-600 dark:text-red-400",
        hideTextOnMobile: true
      });
      $$renderer2.push(`<!----></form></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--></main>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var accentColors, accentStore, mobileNavOpen, sidebarCollapsed, PLATFORM_LABELS, cleanup, routeResolvers;
var init_layout_svelte = __esm({
  "dist/build/server/entries/pages/_layout.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_index_server2();
    init_build();
    init_features();
    init_navIcons();
    init_logo_512();
    init_Dropdown();
    init_Icon();
    init_arrow_right();
    init_arrow_up();
    init_check();
    init_chevron_left();
    init_chevron_right();
    init_circle_check_big();
    init_circle_check();
    init_circle_x();
    init_clock();
    init_tv();
    init_info();
    init_link();
    init_Button();
    init_megaphone();
    init_settings();
    init_sliders_vertical();
    init_tag();
    init_triangle_alert();
    init_wrench();
    init_x();
    init_theme();
    init_store();
    init_client4();
    init_stores();
    init_store2();
    init_Label();
    init_Card();
    init_jobStatus();
    init_Sonarr2();
    init_navigation();
    init_InlineCode();
    init_Modal();
    init_dateFormat();
    init_timezone();
    init_forms();
    accentColors = [
      {
        value: "blue",
        label: "Blue",
        color: "#2563eb"
      },
      {
        value: "yellow",
        label: "Yellow",
        color: "#eab308"
      },
      {
        value: "green",
        label: "Green",
        color: "#16a34a"
      },
      {
        value: "orange",
        label: "Orange",
        color: "#ea580c"
      },
      {
        value: "teal",
        label: "Teal",
        color: "#0d9488"
      },
      {
        value: "purple",
        label: "Purple",
        color: "#9333ea"
      },
      {
        value: "rose",
        label: "Rose",
        color: "#e11d48"
      }
    ];
    accentStore = createAccentStore();
    mobileNavOpen = createMobileNavStore();
    sidebarCollapsed = createSidebarStore();
    PLATFORM_LABELS = {
      "docker-amd64": "docker/amd64",
      "docker-arm64": "docker/arm64",
      "windows-amd64": "windows/amd64",
      "linux-amd64": "linux/amd64",
      "linux-arm64": "linux/arm64",
      "macos-amd64": "macos/amd64",
      "macos-arm64": "macos/arm64"
    };
    cleanup = null;
    routeResolvers = {
      firstDatabaseChanges: async () => {
        return `/databases/${(await (await fetch("/api/v1/databases")).json())[0].id}/changes`;
      },
      firstDatabaseCommits: async () => {
        return `/databases/${(await (await fetch("/api/v1/databases")).json())[0].id}/commits`;
      },
      firstDatabaseConflicts: async () => {
        return `/databases/${(await (await fetch("/api/v1/databases")).json())[0].id}/conflicts`;
      },
      firstDatabaseTweaks: async () => {
        return `/databases/${(await (await fetch("/api/v1/databases")).json())[0].id}/tweaks`;
      },
      firstDatabaseSettings: async () => {
        return `/databases/${(await (await fetch("/api/v1/databases")).json())[0].id}/settings`;
      },
      firstArrLibrary: async () => {
        return `/arr/${(await (await fetch("/api/v1/arr")).json())[0].id}/library`;
      },
      firstArrSync: async () => {
        return `/arr/${(await (await fetch("/api/v1/arr")).json())[0].id}/sync`;
      },
      firstArrDrift: async () => {
        return `/arr/${(await (await fetch("/api/v1/arr")).json())[0].id}/drift`;
      },
      firstArrUpgrades: async () => {
        return `/arr/${(await (await fetch("/api/v1/arr")).json())[0].id}/upgrades`;
      },
      firstArrRename: async () => {
        return `/arr/${(await (await fetch("/api/v1/arr")).json())[0].id}/rename`;
      },
      firstArrLogs: async () => {
        return `/arr/${(await (await fetch("/api/v1/arr")).json())[0].id}/logs`;
      },
      firstArrSettings: async () => {
        return `/arr/${(await (await fetch("/api/v1/arr")).json())[0].id}/settings`;
      },
      firstCustomFormatGeneral: async () => {
        const dbs = await (await fetch("/api/v1/databases")).json();
        if (!dbs.length) return "/custom-formats";
        const { path } = await (await fetch(`/custom-formats/${dbs[0].id}/first/general`)).json();
        return path;
      },
      firstCustomFormatConditions: async () => {
        const dbs = await (await fetch("/api/v1/databases")).json();
        if (!dbs.length) return "/custom-formats";
        const { path } = await (await fetch(`/custom-formats/${dbs[0].id}/first/conditions`)).json();
        return path;
      },
      firstDevCustomFormatTesting: async () => {
        const dev = (await (await fetch("/api/v1/databases")).json()).find((d2) => d2.hasPat && !d2.local_ops_enabled);
        if (!dev) return "/custom-formats";
        const { path } = await (await fetch(`/custom-formats/${dev.id}/first/testing`)).json();
        return path;
      },
      firstQualityProfileGeneral: async () => {
        const dbs = await (await fetch("/api/v1/databases")).json();
        if (!dbs.length) return "/quality-profiles";
        const { path } = await (await fetch(`/quality-profiles/${dbs[0].id}/first/general`)).json();
        return path;
      },
      firstQualityProfileScoring: async () => {
        const dbs = await (await fetch("/api/v1/databases")).json();
        if (!dbs.length) return "/quality-profiles";
        const { path } = await (await fetch(`/quality-profiles/${dbs[0].id}/first/scoring`)).json();
        return path;
      },
      firstQualityProfileQualities: async () => {
        const dbs = await (await fetch("/api/v1/databases")).json();
        if (!dbs.length) return "/quality-profiles";
        const { path } = await (await fetch(`/quality-profiles/${dbs[0].id}/first/qualities`)).json();
        return path;
      },
      firstRegularExpression: async () => {
        const dbs = await (await fetch("/api/v1/databases")).json();
        if (!dbs.length) return "/regular-expressions";
        const { path } = await (await fetch(`/regular-expressions/${dbs[0].id}/first`)).json();
        return path;
      },
      firstDelayProfileGeneral: async () => {
        const dbs = await (await fetch("/api/v1/databases")).json();
        if (!dbs.length) return "/delay-profiles";
        const { path } = await (await fetch(`/delay-profiles/${dbs[0].id}/first`)).json();
        return path;
      },
      firstNaming: async () => {
        const dbs = await (await fetch("/api/v1/databases")).json();
        if (!dbs.length) return "/media-management";
        const { path } = await (await fetch(`/media-management/${dbs[0].id}/naming/first`)).json();
        return path;
      },
      firstQualityDefinitions: async () => {
        const dbs = await (await fetch("/api/v1/databases")).json();
        if (!dbs.length) return "/media-management";
        const { path } = await (await fetch(`/media-management/${dbs[0].id}/quality-definitions/first`)).json();
        return path;
      },
      firstMediaSettings: async () => {
        const dbs = await (await fetch("/api/v1/databases")).json();
        if (!dbs.length) return "/media-management";
        const { path } = await (await fetch(`/media-management/${dbs[0].id}/media-settings/first`)).json();
        return path;
      }
    };
  }
});

// dist/build/server/nodes/0.js
var __exports = {};
__export(__exports, {
  component: () => component,
  fonts: () => fonts,
  imports: () => imports,
  index: () => index,
  server: () => layout_server_ts_exports,
  server_id: () => server_id,
  stylesheets: () => stylesheets
});
var index, component_cache, component, server_id, imports, stylesheets, fonts;
var init__ = __esm({
  async "dist/build/server/nodes/0.js"() {
    "use strict";
    await init_layout_server_ts();
    index = 0;
    component = async () => component_cache ??= (await Promise.resolve().then(() => (init_layout_svelte(), layout_svelte_exports))).default;
    server_id = "src/routes/+layout.server.ts";
    imports = ["_app/immutable/nodes/0.4m9ueqXu.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BUYotPgW.js", "_app/immutable/chunks/BDqLURZS.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/D1MpTH1m.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/BGa_v0Jt2.js", "_app/immutable/chunks/uDCknttb2.js", "_app/immutable/chunks/CQskZlkd2.js", "_app/immutable/chunks/BqRH1fsh2.js", "_app/immutable/chunks/xCf7klJK.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/D8FWRTM5.js", "_app/immutable/chunks/e-haqc9Z.js", "_app/immutable/chunks/B8c7VBJ4.js", "_app/immutable/chunks/Cut3gr1-.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/CJ4k5gis2.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/DcKM5OzB2.js", "_app/immutable/chunks/CNiXNkto2.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/KgSkRyiu2.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/Dg15A-ry2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/Baki32ro2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DxZIQ_tr2.js", "_app/immutable/chunks/DCkiND_92.js"];
    stylesheets = ["_app/immutable/assets/0.CXM5YJKM.css"];
    fonts = [];
  }
});

// dist/build/server/entries/pages/_error.svelte.js
var error_svelte_exports = {};
__export(error_svelte_exports, {
  default: () => _error
});
function _error($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let statusCode, errorMessage;
    $: statusCode = store_get($$store_subs ??= {}, "$page", page).status;
    $: errorMessage = store_get($$store_subs ??= {}, "$page", page).error?.message || "An unexpected error occurred";
    $$renderer2.push(`<div class="fixed inset-0 z-50 flex items-center justify-center overflow-hidden bg-neutral-50 px-4 dark:bg-neutral-900"><div class="flex max-w-6xl items-center gap-12"><div class="flex-1"><h1 class="mb-4 text-9xl font-bold text-neutral-900 dark:text-neutral-50">${escape_html(statusCode)}</h1> <p class="mb-8 text-lg text-neutral-600 dark:text-neutral-400">${escape_html(errorMessage)}</p> <a href="/" class="inline-block rounded-lg bg-neutral-900 px-6 py-3 font-semibold text-white transition-colors hover:bg-neutral-700 dark:bg-neutral-50 dark:text-neutral-900 dark:hover:bg-neutral-200">Go Home</a></div> `);
    if (statusCode === 404) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="flex-1"><img${attr("src", _404_default)} alt="404 Not Found" class="h-auto w-full rounded-lg"/></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
var _404_default;
var init_error_svelte = __esm({
  "dist/build/server/entries/pages/_error.svelte.js"() {
    "use strict";
    init_server();
    init_stores();
    _404_default = "/_app/immutable/assets/404.BxBcHaW7.gif";
  }
});

// dist/build/server/nodes/1.js
var __exports2 = {};
__export(__exports2, {
  component: () => component2,
  fonts: () => fonts2,
  imports: () => imports2,
  index: () => index2,
  stylesheets: () => stylesheets2
});
var index2, component_cache2, component2, imports2, stylesheets2, fonts2;
var init__2 = __esm({
  "dist/build/server/nodes/1.js"() {
    "use strict";
    index2 = 1;
    component2 = async () => component_cache2 ??= (await Promise.resolve().then(() => (init_error_svelte(), error_svelte_exports))).default;
    imports2 = ["_app/immutable/nodes/1.DylE3lsz.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js"];
    stylesheets2 = [];
    fonts2 = [];
  }
});

// dist/build/server/entries/pages/arr/_id_/_layout.server.ts.js
var layout_server_ts_exports2 = {};
__export(layout_server_ts_exports2, {
  load: () => load2
});
var load2;
var init_layout_server_ts2 = __esm({
  async "dist/build/server/entries/pages/arr/_id_/_layout.server.ts.js"() {
    "use strict";
    await init_arrSync();
    await init_arrInstances();
    await init_arrDriftStatus();
    init_exports();
    load2 = ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (isNaN(id)) error(404, `Invalid instance ID: ${params.id}`);
      const instance = arrInstancesQueries.getById(id);
      if (!instance) error(404, `Instance not found: ${id}`);
      const { api_key, ...safe } = instance;
      const sync = arrSyncQueries.getFullSyncData(id);
      const hasSyncConfig = sync.qualityProfiles.selections.length > 0 || !!sync.delayProfiles.databaseId && !!sync.delayProfiles.profileName || !!sync.mediaManagement.namingDatabaseId || !!sync.mediaManagement.qualityDefinitionsDatabaseId || !!sync.mediaManagement.mediaSettingsDatabaseId;
      const driftStatus = arrDriftStatusQueries.getByInstanceId(id);
      return {
        instance: safe,
        hasSyncConfig,
        driftCount: driftStatus?.status === "drift_detected" ? Object.values(driftStatus.counts).reduce((sum, n) => sum + (n ?? 0), 0) : 0
      };
    };
  }
});

// dist/build/server/chunks/circle-arrow-up.js
function Circle_arrow_up($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "circle-arrow-up" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "12",
        "cy": "12",
        "r": "10"
      }],
      ["path", { "d": "m16 12-4-4-4 4" }],
      ["path", { "d": "M12 16V8" }]
    ] }
  ]));
}
var init_circle_arrow_up = __esm({
  "dist/build/server/chunks/circle-arrow-up.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/refresh-cw.js
function Refresh_cw($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "refresh-cw" },
    props,
    { iconNode: [
      ["path", { "d": "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }],
      ["path", { "d": "M21 3v5h-5" }],
      ["path", { "d": "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }],
      ["path", { "d": "M8 16H3v5" }]
    ] }
  ]));
}
var init_refresh_cw = __esm({
  "dist/build/server/chunks/refresh-cw.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/arrow-left.js
function Arrow_left($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "arrow-left" },
    props,
    { iconNode: [["path", { "d": "m12 19-7-7 7-7" }], ["path", { "d": "M19 12H5" }]] }
  ]));
}
var init_arrow_left = __esm({
  "dist/build/server/chunks/arrow-left.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/chevron-down.js
function Chevron_down($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "chevron-down" },
    props,
    { iconNode: [["path", { "d": "m6 9 6 6 6-6" }]] }
  ]));
}
var init_chevron_down = __esm({
  "dist/build/server/chunks/chevron-down.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/Breadcrumb.js
function Breadcrumb($$renderer, $$props) {
  let items = fallback($$props["items"], () => [], true);
  let current3 = fallback($$props["current"], "");
  $$renderer.push(`<div class="flex items-center gap-2 text-sm"><!--[-->`);
  const each_array = ensure_array_like(items);
  for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
    let item = each_array[$$index];
    $$renderer.push(`<a${attr("href", item.href)} class="text-neutral-500 transition-colors hover:text-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-200">${escape_html(item.label)}</a> `);
    Chevron_right($$renderer, {
      size: 14,
      class: "text-neutral-400 dark:text-neutral-600"
    });
    $$renderer.push(`<!---->`);
  }
  $$renderer.push(`<!--]--> <span class="font-medium text-neutral-900 dark:text-neutral-50">${escape_html(current3)}</span></div>`);
  bind_props($$props, {
    items,
    current: current3
  });
}
var init_Breadcrumb = __esm({
  "dist/build/server/chunks/Breadcrumb.js"() {
    "use strict";
    init_server();
    init_chevron_right();
  }
});

// dist/build/server/chunks/IconCheckbox.js
function IconCheckbox($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let shapeClass, isCustomColor, sizeClass, iconSize, resolvedColorKey, resolvedFilledClass, resolvedOutlineClass, stateClass, buttonStyle, outlineIconClass, resolvedIconClass;
    let checked = fallback($$props["checked"], false);
    let icon = $$props["icon"];
    let color = fallback($$props["color"], "accent");
    let shape = fallback($$props["shape"], "rounded");
    let disabled = fallback($$props["disabled"], false);
    let variant = fallback($$props["variant"], "filled");
    let iconColor = fallback($$props["iconColor"], "");
    let stopPropagation = fallback($$props["stopPropagation"], false);
    let title = fallback($$props["title"], void 0);
    let compact2 = fallback($$props["compact"], false);
    createEventDispatcher();
    const shapeClasses = {
      square: "rounded-none",
      circle: "rounded-full",
      rounded: "rounded-lg"
    };
    const uncheckedClass = "border-2 border-neutral-400 bg-white hover:border-neutral-600 hover:bg-neutral-50 dark:border-neutral-500 dark:bg-neutral-800/50 dark:hover:border-neutral-300 dark:hover:bg-neutral-800";
    const disabledClass = "cursor-not-allowed opacity-50";
    const enabledClass = "cursor-pointer focus:outline-none";
    const filledClasses = {
      accent: "border-accent-600 bg-accent-600 hover:brightness-110 dark:border-accent-500 dark:bg-accent-500",
      neutral: "border-neutral-900 bg-neutral-900 hover:brightness-110 dark:border-neutral-200 dark:bg-neutral-200",
      green: "border-green-600 bg-green-600 hover:brightness-110 dark:border-green-500 dark:bg-green-500",
      red: "border-red-600 bg-red-600 hover:brightness-110 dark:border-red-500 dark:bg-red-500",
      blue: "border-blue-600 bg-blue-600 hover:brightness-110 dark:border-blue-500 dark:bg-blue-500"
    };
    const outlineClasses = {
      accent: "border-accent-600 bg-white hover:bg-neutral-50 dark:border-accent-500 dark:bg-neutral-800/50 dark:hover:bg-neutral-800",
      neutral: "border-neutral-400 bg-white hover:bg-neutral-50 dark:border-neutral-600 dark:bg-neutral-800/50 dark:hover:bg-neutral-800",
      green: "border-green-600 bg-white hover:bg-neutral-50 dark:border-green-500 dark:bg-neutral-800/50 dark:hover:bg-neutral-800",
      red: "border-red-600 bg-white hover:bg-neutral-50 dark:border-red-500 dark:bg-neutral-800/50 dark:hover:bg-neutral-800",
      blue: "border-blue-600 bg-white hover:bg-neutral-50 dark:border-blue-500 dark:bg-neutral-800/50 dark:hover:bg-neutral-800"
    };
    const customFilledClass = "hover:brightness-110";
    const customOutlineClass = "bg-white hover:bg-neutral-50 dark:bg-neutral-800/50 dark:hover:bg-neutral-800";
    const outlineIconClasses = {
      accent: "text-accent-600 dark:text-accent-400",
      neutral: "text-neutral-900 dark:text-neutral-100",
      green: "text-green-600 dark:text-green-400",
      red: "text-red-600 dark:text-red-400",
      blue: "text-blue-600 dark:text-blue-400"
    };
    $: shapeClass = shapeClasses[shape] || shapeClasses.rounded;
    $: isCustomColor = color.startsWith("#") || color.startsWith("var(");
    $: sizeClass = compact2 ? "h-3.5 w-3.5" : "h-5 w-5";
    $: iconSize = compact2 ? 9 : 14;
    $: resolvedColorKey = isCustomColor ? "accent" : color;
    $: resolvedFilledClass = filledClasses[resolvedColorKey] ?? filledClasses.accent;
    $: resolvedOutlineClass = outlineClasses[resolvedColorKey] ?? outlineClasses.accent;
    $: stateClass = checked ? variant === "filled" ? isCustomColor ? customFilledClass : resolvedFilledClass : isCustomColor ? customOutlineClass : resolvedOutlineClass : uncheckedClass;
    $: buttonStyle = isCustomColor && checked ? `border-color: ${color}; ${variant === "filled" ? `background-color: ${color};` : ""} ${variant === "outline" ? `color: ${color};` : ""}` : "";
    $: outlineIconClass = isCustomColor ? "text-current" : outlineIconClasses[color] || outlineIconClasses.accent;
    $: resolvedIconClass = iconColor || (variant === "filled" ? "text-white" : outlineIconClass);
    $$renderer2.push(`<button type="button" role="checkbox"${attr("aria-checked", checked)}${attr("disabled", disabled, true)}${attr("title", title)}${attr_style(`${stringify(buttonStyle)}${shape === "circle" ? " border-radius: 9999px !important;" : ""}`)}${attr_class(`flex items-center justify-center border transition-colors ${stringify(sizeClass)} ${stringify(shapeClass)} ${stringify(stateClass)} ${disabled ? disabledClass : enabledClass}`)}>`);
    if (checked) {
      $$renderer2.push("<!--[0-->");
      if (icon) {
        $$renderer2.push("<!--[-->");
        icon($$renderer2, {
          size: iconSize,
          class: resolvedIconClass
        });
        $$renderer2.push("<!--]-->");
      } else {
        $$renderer2.push("<!--[!-->");
        $$renderer2.push("<!--]-->");
      }
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></button>`);
    bind_props($$props, {
      checked,
      icon,
      color,
      shape,
      disabled,
      variant,
      iconColor,
      stopPropagation,
      title,
      compact: compact2
    });
  });
}
var init_IconCheckbox = __esm({
  "dist/build/server/chunks/IconCheckbox.js"() {
    "use strict";
    init_index_server();
    init_server();
  }
});

// dist/build/server/chunks/DropdownItem.js
function DropdownItem($$renderer, $$props) {
  const $$slots = sanitize_slots($$props);
  $$renderer.component(($$renderer2) => {
    let isSvgIcon, sizeClasses, rowRoundingClasses, stateClasses, iconSize, labelTransformClass;
    let icon = fallback($$props["icon"], void 0);
    let label = $$props["label"];
    let secondaryText = fallback($$props["secondaryText"], "");
    let description = fallback($$props["description"], "");
    let disabled = fallback($$props["disabled"], false);
    let danger = fallback($$props["danger"], false);
    let selected = fallback($$props["selected"], false);
    let highlighted = fallback($$props["highlighted"], false);
    let compact2 = fallback($$props["compact"], false);
    let checkIcon = fallback($$props["checkIcon"], Check);
    let checkColor = fallback($$props["checkColor"], "accent");
    let labelClass = fallback($$props["labelClass"], "");
    let labelTransform = fallback($$props["labelTransform"], "none");
    let customContent = fallback($$props["customContent"], false);
    $: isSvgIcon = icon && typeof icon === "object" && "path" in icon;
    $: sizeClasses = compact2 ? "gap-2 px-2 py-1 text-xs" : "gap-3 px-3 py-2";
    $: rowRoundingClasses = compact2 ? "first:rounded-t-lg last:rounded-b-lg" : "first:rounded-t-xl last:rounded-b-xl";
    $: stateClasses = disabled ? "cursor-not-allowed text-neutral-400 dark:text-neutral-500" : danger ? `text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-900 ${highlighted ? "bg-red-50 dark:bg-red-900" : ""}` : `text-neutral-700 hover:bg-neutral-50 dark:text-neutral-200 dark:hover:bg-neutral-700 ${highlighted ? "bg-neutral-100 dark:bg-neutral-700" : ""}`;
    $: iconSize = compact2 ? 12 : 16;
    $: labelTransformClass = labelTransform === "capitalize" ? "capitalize" : labelTransform === "uppercase" ? "uppercase" : labelTransform === "lowercase" ? "lowercase" : "";
    $$renderer2.push(`<div${attr_class(`flex w-full items-center border-b border-neutral-200/50 last:border-b-0 dark:border-neutral-700/40 ${stringify(rowRoundingClasses)}`)}><button${attr_class(`flex min-w-0 flex-1 items-center text-left transition-colors ${stringify(sizeClasses)} ${stringify(stateClasses)}`)}${attr("disabled", disabled, true)}>`);
    if (icon) {
      $$renderer2.push("<!--[0-->");
      if (isSvgIcon) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<svg role="img" viewBox="0 0 24 24" fill="currentColor"${attr("width", iconSize)}${attr("height", iconSize)}><path${attr("d", icon.path)}></path></svg>`);
      } else {
        $$renderer2.push("<!--[-1-->");
        if (icon) {
          $$renderer2.push("<!--[-->");
          icon($$renderer2, { size: iconSize });
          $$renderer2.push("<!--]-->");
        } else {
          $$renderer2.push("<!--[!-->");
          $$renderer2.push("<!--]-->");
        }
      }
      $$renderer2.push(`<!--]-->`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (customContent) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span${attr_class(`min-w-0 flex-1 ${stringify(labelClass)}`)}><!--[-->`);
      slot($$renderer2, $$props, "default", {}, null);
      $$renderer2.push(`<!--]--></span>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<span${attr_class(`min-w-0 flex-1 ${stringify(labelClass)}`)}><span${attr_class(clsx(labelTransformClass))}>${escape_html(label)}`);
      if (secondaryText) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<span class="ml-1.5 text-xs text-neutral-400 dark:text-neutral-500">${escape_html(secondaryText)}</span>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></span> `);
      if (description) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<span class="mt-0.5 block text-xs leading-snug text-neutral-400 dark:text-neutral-500">${escape_html(description)}</span>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></span>`);
    }
    $$renderer2.push(`<!--]--> `);
    IconCheckbox($$renderer2, {
      icon: checkIcon,
      checked: selected,
      shape: "circle",
      color: checkColor,
      compact: compact2
    });
    $$renderer2.push(`<!----></button> `);
    if ($$slots.actions) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div${attr_class(`flex items-center ${compact2 ? "pr-2" : "pr-3"}`)}><!--[-->`);
      slot($$renderer2, $$props, "actions", {}, null);
      $$renderer2.push(`<!--]--></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, {
      icon,
      label,
      secondaryText,
      description,
      disabled,
      danger,
      selected,
      highlighted,
      compact: compact2,
      checkIcon,
      checkColor,
      labelClass,
      labelTransform,
      customContent
    });
  });
}
var init_DropdownItem = __esm({
  "dist/build/server/chunks/DropdownItem.js"() {
    "use strict";
    init_server();
    init_check();
    init_IconCheckbox();
  }
});

// dist/build/server/chunks/Tabs.js
function Tabs($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let useMobileMode, activeTab;
    const badgeClass = "inline-flex min-w-5 items-center justify-center rounded-full bg-blue-100 px-1.5 text-xs font-semibold text-blue-700 dark:bg-blue-900/40 dark:text-blue-300";
    let tabs = fallback($$props["tabs"], () => [], true);
    let backButton = fallback($$props["backButton"], void 0);
    let breadcrumb = fallback($$props["breadcrumb"], void 0);
    let responsive = fallback($$props["responsive"], false);
    let mobileBreakpoint = fallback($$props["mobileBreakpoint"], 768);
    let hideWhenSingle = fallback($$props["hideWhenSingle"], true);
    let hiddenSpacerClass = fallback($$props["hiddenSpacerClass"], "h-1");
    let isMobile = false;
    onDestroy(() => {
    });
    $: useMobileMode = responsive && isMobile;
    $: activeTab = tabs.find((t2) => t2.active) ?? tabs[0];
    if (hideWhenSingle && tabs.length <= 1 && !backButton && !breadcrumb) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div${attr_class(clsx(hiddenSpacerClass))}></div>`);
    } else if (useMobileMode) {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<div class="flex h-16 items-center border-b border-neutral-200 dark:border-neutral-800"><div class="flex flex-1 items-center gap-2"><div class="relative flex-1"><button type="button" class="flex w-full items-center justify-between gap-2 rounded-xl border border-neutral-300 bg-white px-3 py-2 text-sm font-medium text-neutral-900 transition-colors hover:bg-neutral-50 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-100 dark:hover:bg-neutral-700"><span class="flex items-center gap-1.5 overflow-hidden">`);
      if (breadcrumb) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<!--[-->`);
        const each_array = ensure_array_like(breadcrumb.items);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let item = each_array[$$index];
          $$renderer2.push(`<span class="shrink-0 text-neutral-500 dark:text-neutral-400">${escape_html(item.label)}</span> `);
          Chevron_right($$renderer2, {
            size: 12,
            class: "shrink-0 text-neutral-400 dark:text-neutral-600"
          });
          $$renderer2.push(`<!---->`);
        }
        $$renderer2.push(`<!--]--> <span class="shrink-0 text-neutral-500 dark:text-neutral-400">${escape_html(breadcrumb.current)}</span> `);
        Chevron_right($$renderer2, {
          size: 12,
          class: "shrink-0 text-neutral-400 dark:text-neutral-600"
        });
        $$renderer2.push(`<!---->`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> `);
      if (activeTab?.icon && !breadcrumb) {
        $$renderer2.push("<!--[0-->");
        if (activeTab.icon) {
          $$renderer2.push("<!--[-->");
          activeTab.icon($$renderer2, {
            size: 16,
            class: "shrink-0 text-accent-500"
          });
          $$renderer2.push("<!--]-->");
        } else {
          $$renderer2.push("<!--[!-->");
          $$renderer2.push("<!--]-->");
        }
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> <span class="truncate">${escape_html(activeTab?.label ?? "Select...")}</span> `);
      if (activeTab?.badge && activeTab.badge > 0) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<span${attr_class(clsx(badgeClass))}>${escape_html(activeTab.badge)}</span>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></span> `);
      Chevron_down($$renderer2, {
        size: 16,
        class: `text-neutral-400 transition-transform `
      });
      $$renderer2.push(`<!----></button> `);
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div> `);
      if (backButton) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<button type="button" class="flex cursor-pointer items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-3 py-2 text-sm font-medium text-neutral-600 transition-colors hover:bg-neutral-50 hover:text-neutral-900 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-100">`);
        Arrow_left($$renderer2, { size: 14 });
        $$renderer2.push(`<!----> ${escape_html(backButton.label)}</button>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="flex h-16 items-end border-b border-neutral-200 dark:border-neutral-800"><nav class="-mb-px flex flex-1 items-center justify-between gap-2" aria-label="Tabs"><div class="flex gap-2"><!--[-->`);
      const each_array_2 = ensure_array_like(tabs);
      for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
        let tab = each_array_2[$$index_2];
        $$renderer2.push(`<button type="button"${attr("data-onboarding", tab.onboarding || null)}${attr_class(`flex cursor-pointer items-center gap-2 border-b-2 px-4 py-3 text-sm font-medium transition-colors ${tab.active ? "border-accent-600 text-accent-600 dark:border-accent-500 dark:text-accent-500" : "border-transparent text-neutral-600 hover:border-neutral-300 hover:text-neutral-900 dark:text-neutral-400 dark:hover:border-neutral-700 dark:hover:text-neutral-50"}`)}>`);
        if (tab.icon) {
          $$renderer2.push("<!--[0-->");
          if (tab.icon) {
            $$renderer2.push("<!--[-->");
            tab.icon($$renderer2, { size: 16 });
            $$renderer2.push("<!--]-->");
          } else {
            $$renderer2.push("<!--[!-->");
            $$renderer2.push("<!--]-->");
          }
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]--> ${escape_html(tab.label)} `);
        if (tab.badge && tab.badge > 0) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<span${attr_class(clsx(badgeClass))}>${escape_html(tab.badge)}</span>`);
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]--></button>`);
      }
      $$renderer2.push(`<!--]--> <!--[-->`);
      slot($$renderer2, $$props, "actions", {}, null);
      $$renderer2.push(`<!--]--></div> `);
      if (breadcrumb) {
        $$renderer2.push("<!--[0-->");
        Breadcrumb($$renderer2, {
          items: breadcrumb.items,
          current: breadcrumb.current
        });
      } else if (backButton) {
        $$renderer2.push("<!--[1-->");
        $$renderer2.push(`<button type="button" class="flex cursor-pointer items-center gap-2 px-3 py-1.5 text-sm font-medium text-neutral-600 transition-colors hover:text-neutral-900 dark:text-neutral-400 dark:hover:text-neutral-100">`);
        Arrow_left($$renderer2, { size: 14 });
        $$renderer2.push(`<!----> ${escape_html(backButton.label)}</button>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></nav></div>`);
    }
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      tabs,
      backButton,
      breadcrumb,
      responsive,
      mobileBreakpoint,
      hideWhenSingle,
      hiddenSpacerClass
    });
  });
}
var init_Tabs = __esm({
  "dist/build/server/chunks/Tabs.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Dropdown();
    init_arrow_left();
    init_chevron_down();
    init_chevron_right();
    init_navigation();
    init_Breadcrumb();
    init_DropdownItem();
  }
});

// dist/build/server/entries/pages/arr/_id_/_layout.svelte.js
var layout_svelte_exports2 = {};
__export(layout_svelte_exports2, {
  default: () => _layout2
});
function Arrow_left_right($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "arrow-left-right" },
    props,
    { iconNode: [
      ["path", { "d": "M8 3 4 7l4 4" }],
      ["path", { "d": "M4 7h16" }],
      ["path", { "d": "m16 21 4-4-4-4" }],
      ["path", { "d": "M20 17H4" }]
    ] }
  ]));
}
function File_pen($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "file-pen" },
    props,
    { iconNode: [
      ["path", { "d": "M12.659 22H18a2 2 0 0 0 2-2V8a2.4 2.4 0 0 0-.706-1.706l-3.588-3.588A2.4 2.4 0 0 0 14 2H6a2 2 0 0 0-2 2v9.34" }],
      ["path", { "d": "M14 2v5a1 1 0 0 0 1 1h5" }],
      ["path", { "d": "M10.378 12.622a1 1 0 0 1 3 3.003L8.36 20.637a2 2 0 0 1-.854.506l-2.867.837a.5.5 0 0 1-.62-.62l.836-2.869a2 2 0 0 1 .506-.853z" }]
    ] }
  ]));
}
function Library($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "library" },
    props,
    { iconNode: [
      ["path", { "d": "m16 6 4 14" }],
      ["path", { "d": "M12 6v14" }],
      ["path", { "d": "M8 8v12" }],
      ["path", { "d": "M4 4v16" }]
    ] }
  ]));
}
function Scroll_text($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "scroll-text" },
    props,
    { iconNode: [
      ["path", { "d": "M15 12h-5" }],
      ["path", { "d": "M15 8h-5" }],
      ["path", { "d": "M19 17V5a2 2 0 0 0-2-2H4" }],
      ["path", { "d": "M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3" }]
    ] }
  ]));
}
function _layout2($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let instanceId, currentPath, libraryTab, syncTab, driftTab, otherTabs, tabs, breadcrumb;
    let data = $$props["data"];
    $: instanceId = store_get($$store_subs ??= {}, "$page", page).params.id;
    $: currentPath = store_get($$store_subs ??= {}, "$page", page).url.pathname;
    $: libraryTab = {
      label: "Library",
      href: `/arr/${instanceId}/library`,
      active: currentPath.includes("/library"),
      icon: Library,
      onboarding: "arr-tab-library"
    };
    $: syncTab = {
      label: "Sync",
      href: `/arr/${instanceId}/sync`,
      active: currentPath.includes("/sync"),
      icon: Refresh_cw,
      onboarding: "arr-tab-sync"
    };
    $: driftTab = {
      label: "Drift",
      href: `/arr/${instanceId}/drift`,
      active: currentPath.includes("/drift"),
      icon: Arrow_left_right,
      onboarding: "arr-tab-drift",
      badge: data.driftCount
    };
    $: otherTabs = [
      driftTab,
      {
        label: "Upgrades",
        href: `/arr/${instanceId}/upgrades`,
        active: currentPath.includes("/upgrades"),
        icon: Circle_arrow_up,
        onboarding: "arr-tab-upgrades"
      },
      {
        label: "Renames",
        href: `/arr/${instanceId}/rename`,
        active: currentPath.includes("/rename"),
        icon: File_pen,
        onboarding: "arr-tab-renames"
      },
      {
        label: "Logs",
        href: `/arr/${instanceId}/logs`,
        active: currentPath.includes("/logs"),
        icon: Scroll_text,
        onboarding: "arr-tab-logs"
      },
      {
        label: "Settings",
        href: `/arr/${instanceId}/settings`,
        active: currentPath.includes("/settings"),
        icon: Settings,
        onboarding: "arr-tab-settings"
      }
    ];
    $: tabs = data.hasSyncConfig ? [
      libraryTab,
      syncTab,
      ...otherTabs
    ] : [
      syncTab,
      libraryTab,
      ...otherTabs
    ];
    $: breadcrumb = {
      items: [{
        label: "Arr Instances",
        href: "/arr"
      }],
      current: data.instance.name
    };
    $$renderer2.push(`<div class="overflow-x-clip px-4 pb-4 md:px-8 md:pb-8">`);
    Tabs($$renderer2, {
      tabs,
      breadcrumb,
      responsive: true,
      mobileBreakpoint: 1400
    });
    $$renderer2.push(`<!----> <!---->`);
    $$renderer2.push(`<!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]-->`);
    $$renderer2.push(`<!----></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_layout_svelte2 = __esm({
  "dist/build/server/entries/pages/arr/_id_/_layout.svelte.js"() {
    "use strict";
    init_server();
    init_Icon();
    init_circle_arrow_up();
    init_refresh_cw();
    init_settings();
    init_stores();
    init_Tabs();
  }
});

// dist/build/server/nodes/2.js
var __exports3 = {};
__export(__exports3, {
  component: () => component3,
  fonts: () => fonts3,
  imports: () => imports3,
  index: () => index3,
  server: () => layout_server_ts_exports2,
  server_id: () => server_id2,
  stylesheets: () => stylesheets3
});
var index3, component_cache3, component3, server_id2, imports3, stylesheets3, fonts3;
var init__3 = __esm({
  async "dist/build/server/nodes/2.js"() {
    "use strict";
    await init_layout_server_ts2();
    index3 = 2;
    component3 = async () => component_cache3 ??= (await Promise.resolve().then(() => (init_layout_svelte2(), layout_svelte_exports2))).default;
    server_id2 = "src/routes/arr/[id]/+layout.server.ts";
    imports3 = ["_app/immutable/nodes/2.DtaRWeI1.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BMmWZGEU.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/e-haqc9Z.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js"];
    stylesheets3 = [];
    fonts3 = [];
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/_layout.server.ts.js
var layout_server_ts_exports3 = {};
__export(layout_server_ts_exports3, {
  load: () => load3
});
var load3;
var init_layout_server_ts3 = __esm({
  async "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/_layout.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_client2();
    init_exports();
    load3 = async ({ params }) => {
      const databaseId = parseInt(params.databaseId, 10);
      const formatId = parseInt(params.id, 10);
      if (isNaN(databaseId) || isNaN(formatId)) error(400, "Invalid parameters");
      const database = pcdManager.getByIdPublic(databaseId);
      if (!database) error(404, "Database not found");
      const cache3 = pcdManager.getCache(databaseId);
      if (!cache3) error(500, "Database cache not available");
      const format = await cache3.kb.selectFrom("custom_formats").select(["id", "name"]).where("id", "=", formatId).executeTakeFirst();
      if (!format) error(404, "Custom format not found");
      return {
        databaseName: database.name,
        formatName: format.name,
        parserAvailable: await isParserHealthy()
      };
    };
  }
});

// dist/build/server/chunks/file-text.js
function File_text($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "file-text" },
    props,
    { iconNode: [
      ["path", { "d": "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" }],
      ["path", { "d": "M14 2v5a1 1 0 0 0 1 1h5" }],
      ["path", { "d": "M10 9H8" }],
      ["path", { "d": "M16 13H8" }],
      ["path", { "d": "M16 17H8" }]
    ] }
  ]));
}
var init_file_text = __esm({
  "dist/build/server/chunks/file-text.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/flask-conical.js
function Flask_conical($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "flask-conical" },
    props,
    { iconNode: [
      ["path", { "d": "M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2" }],
      ["path", { "d": "M6.453 15h11.094" }],
      ["path", { "d": "M8.5 2h7" }]
    ] }
  ]));
}
var init_flask_conical = __esm({
  "dist/build/server/chunks/flask-conical.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/funnel.js
function Funnel($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "funnel" },
    props,
    { iconNode: [["path", { "d": "M10 20a1 1 0 0 0 .553.895l2 1A1 1 0 0 0 14 21v-7a2 2 0 0 1 .517-1.341L21.74 4.67A1 1 0 0 0 21 3H3a1 1 0 0 0-.742 1.67l7.225 7.989A2 2 0 0 1 10 14z" }]] }
  ]));
}
var init_funnel = __esm({
  "dist/build/server/chunks/funnel.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/dirty.js
function deepEquals2(a2, b3) {
  if (a2 === b3) return true;
  if (typeof a2 !== typeof b3) return false;
  if (a2 === null || b3 === null) return a2 === b3;
  if (Array.isArray(a2) && Array.isArray(b3)) {
    if (a2.length !== b3.length) return false;
    return a2.every((item, i) => deepEquals2(item, b3[i]));
  }
  if (typeof a2 === "object" && typeof b3 === "object") {
    const aObj = a2;
    const bObj = b3;
    const aKeys = Object.keys(aObj);
    const bKeys = Object.keys(bObj);
    if (aKeys.length !== bKeys.length) return false;
    return aKeys.every((key2) => deepEquals2(aObj[key2], bObj[key2]));
  }
  return false;
}
function initEdit(serverData) {
  isNewMode.set(false);
  originalSnapshot.set(structuredClone(serverData));
  currentData.set(structuredClone(serverData));
}
function initCreate(defaults) {
  isNewMode.set(false);
  originalSnapshot.set(structuredClone(defaults));
  currentData.set(structuredClone(defaults));
}
function update3(field, value2) {
  currentData.update((data) => ({
    ...data,
    [field]: value2
  }));
}
function clear() {
  isNewMode.set(false);
  const empty = {};
  originalSnapshot.set(empty);
  currentData.set(empty);
}
function confirmNavigation() {
  if (!get(isDirty)) return Promise.resolve(true);
  showWarningModal.set(true);
  return new Promise((resolve6) => {
  });
}
var originalSnapshot, currentData, isNewMode, showWarningModal, isDirty, current2, showModal;
var init_dirty = __esm({
  "dist/build/server/chunks/dirty.js"() {
    "use strict";
    init_server();
    init_index_server2();
    originalSnapshot = writable(null);
    currentData = writable({});
    isNewMode = writable(false);
    showWarningModal = writable(false);
    isDirty = derived$1([
      originalSnapshot,
      currentData,
      isNewMode
    ], ([$original, $current, $isNew]) => {
      if ($isNew) return true;
      return !deepEquals2($original, $current);
    });
    current2 = currentData;
    showModal = showWarningModal;
  }
});

// dist/build/server/chunks/DirtyModal.js
function DirtyModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let pendingNavigationUrl = null;
    beforeNavigate(async (navigation) => {
      if (store_get($$store_subs ??= {}, "$isDirty", isDirty)) {
        navigation.cancel();
        pendingNavigationUrl = navigation.to?.url.pathname || null;
        if (await confirmNavigation() && pendingNavigationUrl) goto(pendingNavigationUrl);
        pendingNavigationUrl = null;
      }
    });
    Modal($$renderer2, {
      open: store_get($$store_subs ??= {}, "$showModal", showModal),
      header: "Unsaved Changes",
      bodyMessage: "You have unsaved changes. Are you sure you want to leave this page? Your changes will be lost.",
      confirmText: "Discard Changes",
      cancelText: "Stay on Page",
      confirmDanger: true
    });
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
var init_DirtyModal = __esm({
  "dist/build/server/chunks/DirtyModal.js"() {
    "use strict";
    init_server();
    init_client4();
    init_navigation();
    init_Modal();
    init_dirty();
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/_layout.svelte.js
var layout_svelte_exports3 = {};
__export(layout_svelte_exports3, {
  default: () => _layout3
});
function _layout3($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, formatId, currentPath, tabs, breadcrumb;
    let data = $$props["data"];
    $: databaseId = store_get($$store_subs ??= {}, "$page", page).params.databaseId;
    $: formatId = store_get($$store_subs ??= {}, "$page", page).params.id;
    $: currentPath = store_get($$store_subs ??= {}, "$page", page).url.pathname;
    $: tabs = [
      {
        label: "General",
        href: `/custom-formats/${databaseId}/${formatId}/general`,
        active: currentPath.includes("/general"),
        icon: File_text
      },
      {
        label: "Conditions",
        href: `/custom-formats/${databaseId}/${formatId}/conditions`,
        active: currentPath.includes("/conditions"),
        icon: Funnel
      },
      ...data.parserAvailable ? [{
        label: "Testing",
        href: `/custom-formats/${databaseId}/${formatId}/testing`,
        active: currentPath.includes("/testing"),
        icon: Flask_conical
      }] : []
    ];
    $: breadcrumb = {
      items: [{
        label: data.databaseName,
        href: `/custom-formats/${databaseId}`
      }],
      current: data.formatName
    };
    $$renderer2.push(`<div class="px-4 pb-4 md:px-8 md:pb-8">`);
    Tabs($$renderer2, {
      tabs,
      breadcrumb,
      responsive: true
    });
    $$renderer2.push(`<!----> <!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--></div> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_layout_svelte3 = __esm({
  "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/_layout.svelte.js"() {
    "use strict";
    init_server();
    init_file_text();
    init_flask_conical();
    init_funnel();
    init_stores();
    init_Tabs();
    init_DirtyModal();
  }
});

// dist/build/server/nodes/3.js
var __exports4 = {};
__export(__exports4, {
  component: () => component4,
  fonts: () => fonts4,
  imports: () => imports4,
  index: () => index4,
  server: () => layout_server_ts_exports3,
  server_id: () => server_id3,
  stylesheets: () => stylesheets4
});
var index4, component_cache4, component4, server_id3, imports4, stylesheets4, fonts4;
var init__4 = __esm({
  async "dist/build/server/nodes/3.js"() {
    "use strict";
    await init_layout_server_ts3();
    index4 = 3;
    component4 = async () => component_cache4 ??= (await Promise.resolve().then(() => (init_layout_svelte3(), layout_svelte_exports3))).default;
    server_id3 = "src/routes/custom-formats/[databaseId]/[id]/+layout.server.ts";
    imports4 = ["_app/immutable/nodes/3.BIJt1jy9.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/SEZzcS_o.js", "_app/immutable/chunks/MJc6__n-.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js"];
    stylesheets4 = [];
    fonts4 = [];
  }
});

// dist/build/server/entries/pages/databases/_id_/_layout.server.ts.js
var layout_server_ts_exports4 = {};
__export(layout_server_ts_exports4, {
  load: () => load4
});
var load4;
var init_layout_server_ts4 = __esm({
  async "dist/build/server/entries/pages/databases/_id_/_layout.server.ts.js"() {
    "use strict";
    await init_databaseInstances();
    await init_git();
    init_exports();
    load4 = async ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (isNaN(id)) error(400, "Invalid database ID");
      const database = databaseInstancesQueries.getById(id);
      if (!database) error(404, "Database not found");
      const { personal_access_token, ...safe } = database;
      const [repoInfo, currentBranch] = await Promise.all([getRepoInfo(database.repository_url, personal_access_token), getBranch(database.local_path)]);
      return {
        database: {
          ...safe,
          hasPat: personal_access_token !== null
        },
        repoInfo,
        currentBranch
      };
    };
  }
});

// dist/build/server/chunks/git-branch.js
function Git_branch($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "git-branch" },
    props,
    { iconNode: [
      ["path", { "d": "M15 6a9 9 0 0 0-9 9V3" }],
      ["circle", {
        "cx": "18",
        "cy": "6",
        "r": "3"
      }],
      ["circle", {
        "cx": "6",
        "cy": "18",
        "r": "3"
      }]
    ] }
  ]));
}
var init_git_branch = __esm({
  "dist/build/server/chunks/git-branch.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/entries/pages/databases/_id_/_layout.svelte.js
var layout_svelte_exports4 = {};
__export(layout_svelte_exports4, {
  default: () => _layout4
});
function File_cog($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "file-cog" },
    props,
    { iconNode: [
      ["path", { "d": "M15 8a1 1 0 0 1-1-1V2a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8z" }],
      ["path", { "d": "M20 8v12a2 2 0 0 1-2 2h-4.182" }],
      ["path", { "d": "m3.305 19.53.923-.382" }],
      ["path", { "d": "M4 10.592V4a2 2 0 0 1 2-2h8" }],
      ["path", { "d": "m4.228 16.852-.924-.383" }],
      ["path", { "d": "m5.852 15.228-.383-.923" }],
      ["path", { "d": "m5.852 20.772-.383.924" }],
      ["path", { "d": "m8.148 15.228.383-.923" }],
      ["path", { "d": "m8.53 21.696-.382-.924" }],
      ["path", { "d": "m9.773 16.852.922-.383" }],
      ["path", { "d": "m9.773 19.148.922.383" }],
      ["circle", {
        "cx": "7",
        "cy": "18",
        "r": "3"
      }]
    ] }
  ]));
}
function Git_pull_request_closed($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "git-pull-request-closed" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "6",
        "cy": "6",
        "r": "3"
      }],
      ["path", { "d": "M6 9v12" }],
      ["path", { "d": "m21 3-6 6" }],
      ["path", { "d": "m21 9-6-6" }],
      ["path", { "d": "M18 11.5V15" }],
      ["circle", {
        "cx": "18",
        "cy": "18",
        "r": "3"
      }]
    ] }
  ]));
}
function Rotate_ccw_clock($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "rotate-ccw-clock" },
    props,
    { iconNode: [
      ["path", { "d": "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }],
      ["path", { "d": "M3 3v5h5" }],
      ["path", { "d": "M12 7v5l4 2" }]
    ] }
  ]));
}
function _layout4($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let database, currentPath, tabs, breadcrumb;
    $: database = store_get($$store_subs ??= {}, "$page", page).data.database;
    $: currentPath = store_get($$store_subs ??= {}, "$page", page).url.pathname;
    $: tabs = database ? [
      {
        label: "Changes",
        href: `/databases/${database.id}/changes`,
        icon: Git_branch,
        active: currentPath.endsWith("/changes"),
        onboarding: "db-tab-changes"
      },
      {
        label: "Updates",
        href: `/databases/${database.id}/commits`,
        icon: Rotate_ccw_clock,
        active: currentPath.includes("/commits"),
        onboarding: "db-tab-commits"
      },
      {
        label: "Conflicts",
        href: `/databases/${database.id}/conflicts`,
        icon: Git_pull_request_closed,
        active: currentPath.includes("/conflicts"),
        onboarding: "db-tab-conflicts"
      },
      ...FEATURES.tweaks ? [{
        label: "Tweaks",
        href: `/databases/${database.id}/tweaks`,
        icon: Wrench,
        active: currentPath.includes("/tweaks"),
        onboarding: "db-tab-tweaks"
      }] : [],
      ...database.hasPat ? [{
        label: "Announcements",
        href: `/databases/${database.id}/announcements`,
        icon: Megaphone,
        active: currentPath.includes("/announcements")
      }, {
        label: "Config",
        href: `/databases/${database.id}/config`,
        icon: File_cog,
        active: currentPath.includes("/config")
      }] : [],
      {
        label: "Settings",
        href: `/databases/${database.id}/settings`,
        icon: Settings,
        active: currentPath.includes("/settings"),
        onboarding: "db-tab-settings"
      }
    ] : [];
    $: breadcrumb = {
      items: [{
        label: "Databases",
        href: "/databases"
      }],
      current: database?.name ?? ""
    };
    $$renderer2.push(`<div class="px-4 pb-4 md:px-8 md:pb-8">`);
    Tabs($$renderer2, {
      tabs,
      breadcrumb,
      responsive: true,
      mobileBreakpoint: 1400
    });
    $$renderer2.push(`<!----> <!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
var init_layout_svelte4 = __esm({
  "dist/build/server/entries/pages/databases/_id_/_layout.svelte.js"() {
    "use strict";
    init_server();
    init_features();
    init_Icon();
    init_git_branch();
    init_megaphone();
    init_settings();
    init_wrench();
    init_stores();
    init_Tabs();
  }
});

// dist/build/server/nodes/4.js
var __exports5 = {};
__export(__exports5, {
  component: () => component5,
  fonts: () => fonts5,
  imports: () => imports5,
  index: () => index5,
  server: () => layout_server_ts_exports4,
  server_id: () => server_id4,
  stylesheets: () => stylesheets5
});
var index5, component_cache5, component5, server_id4, imports5, stylesheets5, fonts5;
var init__5 = __esm({
  async "dist/build/server/nodes/4.js"() {
    "use strict";
    await init_layout_server_ts4();
    index5 = 4;
    component5 = async () => component_cache5 ??= (await Promise.resolve().then(() => (init_layout_svelte4(), layout_svelte_exports4))).default;
    server_id4 = "src/routes/databases/[id]/+layout.server.ts";
    imports5 = ["_app/immutable/nodes/4.D9_cy2Z4.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/CqoQtmn5.js", "_app/immutable/chunks/D8FWRTM5.js", "_app/immutable/chunks/e-haqc9Z.js", "_app/immutable/chunks/CJ4k5gis2.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/DxZIQ_tr2.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js"];
    stylesheets5 = [];
    fonts5 = [];
  }
});

// dist/build/server/chunks/lastDatabase.js
function redirectToLastDatabase(cookies, cookieName, routePrefix, options2) {
  const databases = pcdManager.getAll();
  if (databases.length === 0) return null;
  const stored = cookies.get(cookieName);
  const storedId = stored ? parseInt(stored, 10) : NaN;
  const targetId = !isNaN(storedId) && databases.some((db2) => db2.id === storedId) ? storedId : databases[0].id;
  const suffix = options2?.suffix ?? "";
  redirect(302, `${routePrefix}/${targetId}${suffix}`);
}
function setLastDatabase(cookies, cookieName, databaseId) {
  cookies.set(cookieName, String(databaseId), COOKIE_OPTIONS);
}
function getLastSection(cookies, cookieName, allowed, fallback2) {
  const stored = cookies.get(cookieName);
  return stored && allowed.has(stored) ? stored : fallback2;
}
function setLastSection(cookies, cookieName, section) {
  cookies.set(cookieName, section, COOKIE_OPTIONS);
}
var COOKIE_OPTIONS;
var init_lastDatabase = __esm({
  async "dist/build/server/chunks/lastDatabase.js"() {
    "use strict";
    await init_queueService();
    init_exports();
    COOKIE_OPTIONS = {
      path: "/",
      httpOnly: true,
      sameSite: "lax",
      secure: false,
      maxAge: 31536e3
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/_layout.server.ts.js
var layout_server_ts_exports5 = {};
__export(layout_server_ts_exports5, {
  load: () => load5
});
var ALLOWED_SECTIONS, load5;
var init_layout_server_ts5 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/_layout.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_lastDatabase();
    init_exports();
    ALLOWED_SECTIONS = /* @__PURE__ */ new Set([
      "naming",
      "media-settings",
      "quality-definitions"
    ]);
    load5 = async ({ params, cookies, url }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const databases = pcdManager.getAllPublic();
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = databases.find((db2) => db2.id === currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      setLastDatabase(cookies, "last_db_mm", currentDatabaseId);
      const sectionMatch = url.pathname.match(/\/media-management\/\d+\/([^/]+)/);
      if (sectionMatch && ALLOWED_SECTIONS.has(sectionMatch[1])) setLastSection(cookies, "last_section_mm", sectionMatch[1]);
      return {
        databases,
        currentDatabase,
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/_layout.svelte.js
var layout_svelte_exports5 = {};
__export(layout_svelte_exports5, {
  default: () => _layout5
});
function _layout5($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let currentPath, currentConfigType, isNestedPage, databaseTabs;
    let data = $$props["data"];
    $: currentPath = store_get($$store_subs ??= {}, "$page", page).url.pathname;
    $: currentConfigType = currentPath.includes("/quality-definitions") ? "quality-definitions" : currentPath.includes("/media-settings") ? "media-settings" : "naming";
    $: isNestedPage = currentPath.includes("/new") || currentPath.includes("/radarr/") || currentPath.includes("/sonarr/");
    $: databaseTabs = data.databases.map((db2) => ({
      label: db2.name,
      href: `/media-management/${db2.id}/${currentConfigType}`,
      active: db2.id === data.currentDatabase.id
    }));
    head("1hbq6jz", $$renderer2, ($$renderer3) => {
      $$renderer3.title(($$renderer4) => {
        $$renderer4.push(`<title>Media Management - ${escape_html(data.currentDatabase?.name)} - Profilarr</title>`);
      });
    });
    $$renderer2.push(`<div${attr_class(`space-y-6 px-4 pb-8 md:px-8 ${isNestedPage ? "pt-3 md:pt-7" : ""}`)}>`);
    if (!isNestedPage) {
      $$renderer2.push("<!--[0-->");
      Tabs($$renderer2, { tabs: databaseTabs });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_layout_svelte5 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/_layout.svelte.js"() {
    "use strict";
    init_server();
    init_stores();
    init_Tabs();
  }
});

// dist/build/server/nodes/5.js
var __exports6 = {};
__export(__exports6, {
  component: () => component6,
  fonts: () => fonts6,
  imports: () => imports6,
  index: () => index6,
  server: () => layout_server_ts_exports5,
  server_id: () => server_id5,
  stylesheets: () => stylesheets6
});
var index6, component_cache6, component6, server_id5, imports6, stylesheets6, fonts6;
var init__6 = __esm({
  async "dist/build/server/nodes/5.js"() {
    "use strict";
    await init_layout_server_ts5();
    index6 = 5;
    component6 = async () => component_cache6 ??= (await Promise.resolve().then(() => (init_layout_svelte5(), layout_svelte_exports5))).default;
    server_id5 = "src/routes/media-management/[databaseId]/+layout.server.ts";
    imports6 = ["_app/immutable/nodes/5.DyhEHAR9.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js"];
    stylesheets6 = [];
    fonts6 = [];
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/_layout.server.ts.js
var layout_server_ts_exports6 = {};
__export(layout_server_ts_exports6, {
  load: () => load6
});
var load6;
var init_layout_server_ts6 = __esm({
  async "dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/_layout.server.ts.js"() {
    "use strict";
    await init_queueService();
    init_exports();
    load6 = async ({ params }) => {
      const databaseId = parseInt(params.databaseId, 10);
      const profileId = parseInt(params.id, 10);
      if (isNaN(databaseId) || isNaN(profileId)) error(400, "Invalid parameters");
      const database = pcdManager.getByIdPublic(databaseId);
      if (!database) error(404, "Database not found");
      const cache3 = pcdManager.getCache(databaseId);
      if (!cache3) error(500, "Database cache not available");
      const profile = (await select(cache3)).find((p2) => p2.id === profileId);
      if (!profile) error(404, "Quality profile not found");
      return {
        databaseName: database.name,
        profileName: profile.name
      };
    };
  }
});

// dist/build/server/chunks/layers.js
function Layers($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "layers" },
    props,
    { iconNode: [
      ["path", { "d": "M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z" }],
      ["path", { "d": "M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12" }],
      ["path", { "d": "M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17" }]
    ] }
  ]));
}
var init_layers = __esm({
  "dist/build/server/chunks/layers.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/_layout.svelte.js
var layout_svelte_exports6 = {};
__export(layout_svelte_exports6, {
  default: () => _layout6
});
function Scale($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "scale" },
    props,
    { iconNode: [
      ["path", { "d": "M12 3v18" }],
      ["path", { "d": "m19 8 3 8a5 5 0 0 1-6 0zV7" }],
      ["path", { "d": "M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1" }],
      ["path", { "d": "m5 8 3 8a5 5 0 0 1-6 0zV7" }],
      ["path", { "d": "M7 21h10" }]
    ] }
  ]));
}
function _layout6($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, profileId, currentPath, tabs, breadcrumb;
    let data = $$props["data"];
    $: databaseId = store_get($$store_subs ??= {}, "$page", page).params.databaseId;
    $: profileId = store_get($$store_subs ??= {}, "$page", page).params.id;
    $: currentPath = store_get($$store_subs ??= {}, "$page", page).url.pathname;
    $: tabs = [
      {
        label: "General",
        href: `/quality-profiles/${databaseId}/${profileId}/general`,
        active: currentPath.includes("/general"),
        icon: File_text
      },
      {
        label: "Scoring",
        href: `/quality-profiles/${databaseId}/${profileId}/scoring`,
        active: currentPath.includes("/scoring"),
        icon: Scale
      },
      {
        label: "Qualities",
        href: `/quality-profiles/${databaseId}/${profileId}/qualities`,
        active: currentPath.includes("/qualities"),
        icon: Layers
      }
    ];
    $: breadcrumb = {
      items: [{
        label: data.databaseName,
        href: `/quality-profiles/${databaseId}`
      }],
      current: data.profileName
    };
    $$renderer2.push(`<div class="px-4 pb-4 md:px-8 md:pb-8">`);
    Tabs($$renderer2, {
      tabs,
      breadcrumb,
      responsive: true
    });
    $$renderer2.push(`<!----> <!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--></div> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_layout_svelte6 = __esm({
  "dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/_layout.svelte.js"() {
    "use strict";
    init_server();
    init_Icon();
    init_file_text();
    init_layers();
    init_stores();
    init_Tabs();
    init_DirtyModal();
  }
});

// dist/build/server/nodes/6.js
var __exports7 = {};
__export(__exports7, {
  component: () => component7,
  fonts: () => fonts7,
  imports: () => imports7,
  index: () => index7,
  server: () => layout_server_ts_exports6,
  server_id: () => server_id6,
  stylesheets: () => stylesheets7
});
var index7, component_cache7, component7, server_id6, imports7, stylesheets7, fonts7;
var init__7 = __esm({
  async "dist/build/server/nodes/6.js"() {
    "use strict";
    await init_layout_server_ts6();
    index7 = 6;
    component7 = async () => component_cache7 ??= (await Promise.resolve().then(() => (init_layout_svelte6(), layout_svelte_exports6))).default;
    server_id6 = "src/routes/quality-profiles/[databaseId]/[id]/+layout.server.ts";
    imports7 = ["_app/immutable/nodes/6.BJY5czN4.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/DYf5Ixhg.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js"];
    stylesheets7 = [];
    fonts7 = [];
  }
});

// dist/build/server/entries/pages/_page.server.ts.js
var page_server_ts_exports = {};
__export(page_server_ts_exports, {
  load: () => load7
});
var load7;
var init_page_server_ts = __esm({
  "dist/build/server/entries/pages/_page.server.ts.js"() {
    "use strict";
    init_exports();
    load7 = async () => {
      redirect(302, "/databases");
    };
  }
});

// dist/build/server/nodes/7.js
var __exports8 = {};
__export(__exports8, {
  fonts: () => fonts8,
  imports: () => imports8,
  index: () => index8,
  server: () => page_server_ts_exports,
  server_id: () => server_id7,
  stylesheets: () => stylesheets8
});
var index8, server_id7, imports8, stylesheets8, fonts8;
var init__8 = __esm({
  "dist/build/server/nodes/7.js"() {
    "use strict";
    init_page_server_ts();
    index8 = 7;
    server_id7 = "src/routes/+page.server.ts";
    imports8 = [];
    stylesheets8 = [];
    fonts8 = [];
  }
});

// dist/build/server/entries/pages/announcements/_page.server.ts.js
var page_server_ts_exports2 = {};
__export(page_server_ts_exports2, {
  actions: () => actions,
  load: () => load8
});
function parseTarget(form) {
  const id = form.get("id");
  const source2 = form.get("source");
  if (typeof id !== "string" || !id) return null;
  if (source2 !== "profilarr" && source2 !== "pcd") return null;
  if (source2 === "profilarr") return {
    source: source2,
    id,
    databaseId: null
  };
  const rawDbId = form.get("databaseId");
  if (typeof rawDbId !== "string" || !rawDbId) return null;
  const databaseId = Number(rawDbId);
  if (!Number.isFinite(databaseId)) return null;
  return {
    source: source2,
    id,
    databaseId
  };
}
var load8, actions;
var init_page_server_ts2 = __esm({
  async "dist/build/server/entries/pages/announcements/_page.server.ts.js"() {
    "use strict";
    await init_announcements();
    init_exports();
    load8 = async () => {
      const items = listInbox();
      return { announcements: (await Promise.all(items.map(async (item) => {
        if (item.source === "profilarr" && item.body === null) return await getDetail2(item.source, item.id, item.databaseId, { loadBody: true }) ?? item;
        return item;
      }))).map((item) => ({
        source: item.source,
        id: item.id,
        databaseId: item.databaseId,
        databaseName: item.databaseName,
        databaseRepoUrl: item.databaseRepoUrl,
        title: item.title,
        severity: item.severity,
        publishedAt: item.publishedAt,
        expiresAt: item.expiresAt,
        link: item.link,
        readAt: item.readAt,
        body: item.body
      })) };
    };
    actions = {
      markRead: async ({ request }) => {
        const target = parseTarget(await request.formData());
        if (!target) return fail(400, { error: "invalid target" });
        markRead2(target.source, target.id, target.databaseId);
        return { success: true };
      },
      markUnread: async ({ request }) => {
        const target = parseTarget(await request.formData());
        if (!target) return fail(400, { error: "invalid target" });
        markUnread2(target.source, target.id, target.databaseId);
        return { success: true };
      },
      markReadMany: async ({ request }) => {
        const raw = (await request.formData()).get("targets");
        if (typeof raw !== "string") return fail(400, { error: "missing targets" });
        let parsed;
        try {
          parsed = JSON.parse(raw);
        } catch {
          return fail(400, { error: "invalid targets json" });
        }
        if (!Array.isArray(parsed)) return fail(400, { error: "targets must be an array" });
        const targets = [];
        for (const item of parsed) {
          if (!item || typeof item !== "object") continue;
          const source2 = item.source;
          const id = item.id;
          const databaseId = item.databaseId;
          if (source2 !== "profilarr" && source2 !== "pcd") continue;
          if (typeof id !== "string" || !id) continue;
          if (source2 === "profilarr") targets.push({
            source: source2,
            id,
            databaseId: null
          });
          else if (typeof databaseId === "number" && Number.isFinite(databaseId)) targets.push({
            source: source2,
            id,
            databaseId
          });
        }
        markReadMany(targets);
        return {
          success: true,
          count: targets.length
        };
      }
    };
  }
});

// dist/build/server/chunks/database2.js
function Database2($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "database" },
    props,
    { iconNode: [
      ["ellipse", {
        "cx": "12",
        "cy": "5",
        "rx": "9",
        "ry": "3"
      }],
      ["path", { "d": "M3 5V19A9 3 0 0 0 21 19V5" }],
      ["path", { "d": "M3 12A9 3 0 0 0 21 12" }]
    ] }
  ]));
}
var init_database2 = __esm({
  "dist/build/server/chunks/database2.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/eye.js
function Eye($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "eye" },
    props,
    { iconNode: [["path", { "d": "M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0" }], ["circle", {
      "cx": "12",
      "cy": "12",
      "r": "3"
    }]] }
  ]));
}
var init_eye = __esm({
  "dist/build/server/chunks/eye.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/Badge.js
function Badge($$renderer, $$props) {
  let iconSize, styleAttr;
  let variant = fallback($$props["variant"], "accent");
  let size = fallback($$props["size"], "sm");
  let icon = fallback($$props["icon"], null);
  let mono = fallback($$props["mono"], false);
  const variantClasses = {
    accent: "bg-accent-100 text-accent-800 dark:bg-accent-900 dark:text-accent-200",
    neutral: "bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300",
    success: "bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200",
    warning: "bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200",
    danger: "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
    info: "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200",
    radarr: "text-neutral-900 dark:text-neutral-100",
    sonarr: "text-neutral-900 dark:text-neutral-100"
  };
  const sizeClasses = {
    sm: "px-1.5 py-0.5 text-[10px]",
    md: "px-2 py-0.5 text-xs"
  };
  $: iconSize = size === "sm" ? 10 : 12;
  $: styleAttr = variant === "radarr" ? "background-color: var(--arr-radarr-color); color: #111827;" : variant === "sonarr" ? "background-color: var(--arr-sonarr-color); color: #111827;" : "";
  $$renderer.push(`<span${attr_style(styleAttr)}${attr_class(`inline-flex items-center gap-1 rounded font-medium ${stringify(variantClasses[variant])} ${stringify(sizeClasses[size])} ${mono ? "font-mono" : ""}`)}>`);
  if (icon) {
    $$renderer.push("<!--[0-->");
    if (icon) {
      $$renderer.push("<!--[-->");
      icon($$renderer, { size: iconSize });
      $$renderer.push("<!--]-->");
    } else {
      $$renderer.push("<!--[!-->");
      $$renderer.push("<!--]-->");
    }
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--> <!--[-->`);
  slot($$renderer, $$props, "default", {}, null);
  $$renderer.push(`<!--]--></span>`);
  bind_props($$props, {
    variant,
    size,
    icon,
    mono
  });
}
var init_Badge = __esm({
  "dist/build/server/chunks/Badge.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/chunks/search.js
function Search($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "search" },
    props,
    { iconNode: [["path", { "d": "m21 21-4.34-4.34" }], ["circle", {
      "cx": "11",
      "cy": "11",
      "r": "8"
    }]] }
  ]));
}
function SearchAction($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let useMobileMode, query;
    let searchStore = $$props["searchStore"];
    let placeholder = fallback($$props["placeholder"], "Search...");
    let activeQuery = fallback($$props["activeQuery"], "");
    let responsive = fallback($$props["responsive"], false);
    let hideIcon = fallback($$props["hideIcon"], false);
    createEventDispatcher();
    let isMobile = false;
    onDestroy(() => {
    });
    $: useMobileMode = responsive && isMobile;
    $: query = store_get($$store_subs ??= {}, "$searchStore", searchStore).query;
    if (useMobileMode) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="relative flex min-w-0 flex-1"><button type="button" class="relative flex h-10 w-full items-center justify-between rounded-xl border border-neutral-300 bg-white px-3 transition-colors hover:bg-neutral-50 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:hover:bg-neutral-800" title="Search"><span class="flex items-center gap-2">`);
      if (!hideIcon) {
        $$renderer2.push("<!--[0-->");
        Search($$renderer2, {
          size: 20,
          class: "text-neutral-700 dark:text-neutral-300"
        });
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> <span class="max-w-[14rem] truncate text-sm text-neutral-600 dark:text-neutral-300">${escape_html(query || activeQuery || "Search")}</span></span> `);
      if (query || activeQuery) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<span class="h-2.5 w-2.5 rounded-full bg-accent-500"></span>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></button></div> `);
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]-->`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="relative flex flex-1"><div class="relative flex h-10 w-full items-center rounded-xl border border-neutral-300 bg-white transition-colors dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
      if (!hideIcon) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="pointer-events-none absolute left-3 flex items-center">`);
        Search($$renderer2, {
          size: 18,
          class: "text-neutral-500 dark:text-neutral-400"
        });
        $$renderer2.push(`<!----></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> `);
      if (activeQuery) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div${attr_class(`${hideIcon ? "ml-3" : "ml-10"} flex h-full flex-shrink-0 items-center`)}>`);
        Badge($$renderer2, {
          variant: "accent",
          size: "sm",
          children: ($$renderer3) => {
            $$renderer3.push(`<!---->${escape_html(activeQuery)}`);
          },
          $$slots: { default: true }
        });
        $$renderer2.push(`<!----></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> <input type="text"${attr("value", query)}${attr("placeholder", activeQuery ? "" : placeholder)}${attr_class(`h-full w-full bg-transparent pr-10 text-base text-neutral-900 placeholder-neutral-500 outline-none sm:text-sm dark:text-neutral-100 dark:placeholder-neutral-400 ${activeQuery ? "pl-2" : hideIcon ? "pl-3" : "pl-10"}`)}/> `);
      if (query) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<button class="absolute right-2 flex h-6 w-6 items-center justify-center rounded-lg hover:bg-neutral-50 dark:hover:bg-neutral-800">`);
        X2($$renderer2, {
          size: 14,
          class: "text-neutral-500 dark:text-neutral-400"
        });
        $$renderer2.push(`<!----></button>`);
      } else if (activeQuery) {
        $$renderer2.push("<!--[1-->");
        $$renderer2.push(`<button class="absolute right-2 flex h-6 w-6 items-center justify-center rounded-lg hover:bg-neutral-50 dark:hover:bg-neutral-800">`);
        X2($$renderer2, {
          size: 14,
          class: "text-neutral-500 dark:text-neutral-400"
        });
        $$renderer2.push(`<!----></button>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div></div>`);
    }
    $$renderer2.push(`<!--]-->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      searchStore,
      placeholder,
      activeQuery,
      responsive,
      hideIcon
    });
  });
}
function createSearchStore(config2 = {}) {
  const { debounceMs = 300, caseSensitive = false } = config2;
  const state2 = writable({
    query: "",
    filters: {},
    isActive: false
  });
  let debounceTimer = null;
  const debouncedQuery = writable("");
  function setQuery(query) {
    state2.update((s3) => ({
      ...s3,
      query,
      isActive: query.length > 0
    }));
    if (debounceTimer) clearTimeout(debounceTimer);
    debounceTimer = setTimeout(() => {
      debouncedQuery.set(query);
    }, debounceMs);
  }
  function setFilter(key2, value2) {
    state2.update((s3) => ({
      ...s3,
      filters: {
        ...s3.filters,
        [key2]: value2
      },
      isActive: true
    }));
  }
  function removeFilter(key2) {
    state2.update((s3) => {
      const { [key2]: _3, ...rest } = s3.filters;
      return {
        ...s3,
        filters: rest,
        isActive: s3.query.length > 0 || Object.keys(rest).length > 0
      };
    });
  }
  function clearFilters() {
    state2.update((s3) => ({
      ...s3,
      filters: {},
      isActive: s3.query.length > 0
    }));
  }
  function clear2() {
    state2.set({
      query: "",
      filters: {},
      isActive: false
    });
    debouncedQuery.set("");
    if (debounceTimer) clearTimeout(debounceTimer);
  }
  function filterItems(items, searchFields, additionalFilter) {
    const currentState = get(state2);
    const query = get(debouncedQuery);
    if (!currentState.isActive) return items;
    return items.filter((item) => {
      if (query) {
        if (!searchFields.some((field) => {
          const value2 = String(item[field] ?? "");
          return caseSensitive ? value2.includes(query) : value2.toLowerCase().includes(query.toLowerCase());
        })) return false;
      }
      if (additionalFilter && Object.keys(currentState.filters).length > 0) return additionalFilter(item, currentState.filters);
      return true;
    });
  }
  const isActive = derived$1(state2, ($state) => $state.isActive);
  const filterCount = derived$1(state2, ($state) => Object.keys($state.filters).length);
  return {
    subscribe: state2.subscribe,
    debouncedQuery: { subscribe: debouncedQuery.subscribe },
    isActive: { subscribe: isActive.subscribe },
    filterCount: { subscribe: filterCount.subscribe },
    setQuery,
    setFilter,
    removeFilter,
    clearFilters,
    clear: clear2,
    filterItems
  };
}
function getPersistentSearchStore(key2, config2 = {}) {
  const existing = persistentStores.get(key2);
  if (existing) return existing;
  const store2 = createSearchStore(config2);
  persistentStores.set(key2, store2);
  return store2;
}
var persistentStores;
var init_search = __esm({
  "dist/build/server/chunks/search.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_index_server2();
    init_Icon();
    init_x();
    init_Badge();
    persistentStores = /* @__PURE__ */ new Map();
  }
});

// dist/build/server/chunks/arrow-up-down.js
function Arrow_down($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "arrow-down" },
    props,
    { iconNode: [["path", { "d": "M12 5v14" }], ["path", { "d": "m19 12-7 7-7-7" }]] }
  ]));
}
function Arrow_up_down($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "arrow-up-down" },
    props,
    { iconNode: [
      ["path", { "d": "m21 16-4 4-4-4" }],
      ["path", { "d": "M17 20V4" }],
      ["path", { "d": "m3 8 4-4 4 4" }],
      ["path", { "d": "M7 4v16" }]
    ] }
  ]));
}
var init_arrow_up_down = __esm({
  "dist/build/server/chunks/arrow-up-down.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/chevron-up.js
function Chevron_up($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "chevron-up" },
    props,
    { iconNode: [["path", { "d": "m18 15-6-6-6 6" }]] }
  ]));
}
var init_chevron_up = __esm({
  "dist/build/server/chunks/chevron-up.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/progressiveList.js
function createProgressiveList(options2) {
  const { pageSize, rootMargin = "200px" } = options2;
  const visibleCount = writable(pageSize);
  const totalCount = writable(0);
  const hasMore = derived$1([visibleCount, totalCount], ([$visible, $total]) => $visible < $total);
  let observer = null;
  function loadMore() {
    let current3 = 0;
    let total = 0;
    visibleCount.subscribe((v3) => current3 = v3)();
    totalCount.subscribe((v3) => total = v3)();
    if (current3 < total) visibleCount.set(Math.min(current3 + pageSize, total));
  }
  function sentinel(node) {
    observer = new IntersectionObserver((entries) => {
      if (entries[0]?.isIntersecting) loadMore();
    }, { rootMargin });
    observer.observe(node);
    return { destroy() {
      observer?.disconnect();
      observer = null;
    } };
  }
  function reset2() {
    visibleCount.set(pageSize);
  }
  function setTotalCount(n) {
    totalCount.set(n);
  }
  return {
    visibleCount,
    sentinel,
    reset: reset2,
    hasMore,
    setTotalCount
  };
}
var init_progressiveList = __esm({
  "dist/build/server/chunks/progressiveList.js"() {
    "use strict";
    init_server();
    init_index_server2();
  }
});

// dist/build/server/chunks/ExpandableTable.js
function ExpandableTable($$renderer, $$props) {
  const $$slots = sanitize_slots($$props);
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let useMobileLayout, sortedData, displayData, visibleColumns, mobilePrimaryColumn, mobileSecondaryColumns;
    let columns = $$props["columns"];
    let data = $$props["data"];
    let getRowId = $$props["getRowId"];
    let compact2 = fallback($$props["compact"], false);
    let emptyMessage = fallback($$props["emptyMessage"], "No data available");
    let defaultSort = fallback($$props["defaultSort"], null);
    let loading = fallback($$props["loading"], false);
    let loadingRows = fallback($$props["loadingRows"], 5);
    let flushExpanded = fallback($$props["flushExpanded"], false);
    let flushBottom = fallback($$props["flushBottom"], false);
    let expandedRows = fallback($$props["expandedRows"], () => /* @__PURE__ */ new Set(), true);
    let chevronPosition = fallback($$props["chevronPosition"], "right");
    let expandOnRowClick = fallback($$props["expandOnRowClick"], true);
    let onRowClick = fallback($$props["onRowClick"], null);
    let primaryColumnKey = fallback($$props["primaryColumnKey"], null);
    let disableExpandWhen = fallback($$props["disableExpandWhen"], null);
    let rowClass = fallback($$props["rowClass"], null);
    let responsive = fallback($$props["responsive"], false);
    let pageSize = fallback($$props["pageSize"], void 0);
    let fixedLayout = fallback($$props["fixedLayout"], false);
    let isMobile = false;
    onDestroy(() => {
    });
    let sortState = defaultSort;
    function getSortedData(items, sort) {
      if (!sort) return items;
      const column = columns.find((c2) => c2.key === sort.key);
      if (!column) return items;
      return [...items].sort((a2, b3) => {
        let comparison = 0;
        const aVal = column.sortAccessor ? column.sortAccessor(a2) : getCellValue(a2, column.key);
        const bVal = column.sortAccessor ? column.sortAccessor(b3) : getCellValue(b3, column.key);
        if (column.sortNullsLast) {
          if (aVal == null && bVal == null) return 0;
          if (aVal == null) return 1;
          if (bVal == null) return -1;
        }
        if (column.sortComparator) comparison = column.sortComparator(a2, b3);
        else if (aVal == null && bVal == null) comparison = 0;
        else if (aVal == null) comparison = 1;
        else if (bVal == null) comparison = -1;
        else if (typeof aVal === "string" && typeof bVal === "string") comparison = aVal.localeCompare(bVal, void 0, { sensitivity: "base" });
        else if (typeof aVal === "number" && typeof bVal === "number") comparison = aVal - bVal;
        else if (typeof aVal === "boolean" && typeof bVal === "boolean") comparison = aVal === bVal ? 0 : aVal ? -1 : 1;
        else comparison = String(aVal).localeCompare(String(bVal));
        return sort.direction === "desc" ? -comparison : comparison;
      });
    }
    const progressive = pageSize ? createProgressiveList({ pageSize }) : null;
    const progressiveCount = progressive?.visibleCount;
    function getAlignClass(align) {
      switch (align) {
        case "center":
          return "text-center";
        case "right":
          return "text-right";
        default:
          return "text-left";
      }
    }
    function getCellValue(row, key2) {
      return key2.split(".").reduce((obj, k2) => obj?.[k2], row);
    }
    function shouldDisableExpand(row) {
      return disableExpandWhen ? disableExpandWhen(row) : false;
    }
    $: useMobileLayout = responsive && isMobile;
    $: sortedData = getSortedData(data, sortState);
    $: if (progressive) progressive.setTotalCount(sortedData.length);
    $: if (progressive) progressive.reset();
    $: displayData = progressiveCount ? sortedData.slice(0, store_get($$store_subs ??= {}, "$progressiveCount", progressiveCount)) : sortedData;
    $: visibleColumns = columns.filter((column) => !column.hideOnMobile);
    $: mobilePrimaryColumn = primaryColumnKey != null ? visibleColumns.find((column) => column.key === primaryColumnKey) ?? visibleColumns[0] : visibleColumns[0];
    $: mobileSecondaryColumns = visibleColumns.filter((column) => column !== mobilePrimaryColumn);
    if (useMobileLayout) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="space-y-3">`);
      if (loading) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<!--[-->`);
        const each_array = ensure_array_like(Array(loadingRows));
        for (let $$index_1 = 0, $$length = each_array.length; $$index_1 < $$length; $$index_1++) {
          each_array[$$index_1];
          $$renderer2.push(`<div class="animate-pulse overflow-hidden rounded-xl border border-neutral-300 bg-white dark:border-neutral-700/60 dark:bg-neutral-800/50"><div class="flex items-center justify-between gap-3 px-4 py-3"><div class="h-5 w-32 rounded bg-neutral-200 dark:bg-neutral-700"></div> <div class="h-6 w-6 rounded bg-neutral-200 dark:bg-neutral-700"></div></div> <div class="space-y-2 border-t border-neutral-200 px-4 py-3 dark:border-neutral-700/60"><!--[-->`);
          const each_array_1 = ensure_array_like(columns.slice(1, 4));
          for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
            each_array_1[$$index];
            $$renderer2.push(`<div class="flex items-center justify-between gap-4"><div class="h-4 w-16 rounded bg-neutral-200 dark:bg-neutral-700"></div> <div class="h-4 w-24 rounded bg-neutral-200 dark:bg-neutral-700"></div></div>`);
          }
          $$renderer2.push(`<!--]--></div></div>`);
        }
        $$renderer2.push(`<!--]-->`);
      } else if (displayData.length === 0) {
        $$renderer2.push("<!--[1-->");
        $$renderer2.push(`<div class="rounded-xl border border-neutral-300 bg-white p-8 text-center text-sm text-neutral-500 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-400">${escape_html(emptyMessage)}</div>`);
      } else {
        $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--[-->`);
        const each_array_2 = ensure_array_like(displayData);
        for (let index88 = 0, $$length = each_array_2.length; index88 < $$length; index88++) {
          let row = each_array_2[index88];
          const rowId = getRowId(row);
          $$renderer2.push(`<div${attr_class(`overflow-hidden rounded-xl border border-neutral-300 bg-white dark:border-neutral-700/60 dark:bg-neutral-800/50 ${stringify(rowClass ? rowClass(row) : "")}`)}><div role="button" tabindex="0" class="w-full text-left"><div class="flex items-start justify-between gap-3 px-4 py-3"><div class="min-w-0 flex-1 font-medium break-words text-neutral-900 dark:text-neutral-100"><!--[-->`);
          slot($$renderer2, $$props, "cell", {
            row,
            column: mobilePrimaryColumn,
            index: index88,
            expanded: expandedRows.has(rowId)
          }, () => {
            $$renderer2.push(`${escape_html(mobilePrimaryColumn ? getCellValue(row, mobilePrimaryColumn.key) : "")}`);
          });
          $$renderer2.push(`<!--]--></div> <div class="flex shrink-0 items-center gap-2 pt-0.5">`);
          if ($$slots.actions) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<div><!--[-->`);
            slot($$renderer2, $$props, "actions", { row }, null);
            $$renderer2.push(`<!--]--></div>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--> `);
          if (!shouldDisableExpand(row)) {
            $$renderer2.push("<!--[0-->");
            Button($$renderer2, {
              icon: expandedRows.has(rowId) ? Chevron_up : Chevron_down,
              size: "xs",
              title: expandedRows.has(rowId) ? "Collapse" : "Expand"
            });
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--></div></div> `);
          if (mobileSecondaryColumns.length > 0) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<div class="space-y-2 border-t border-neutral-200 px-4 py-3 dark:border-neutral-700/60"><!--[-->`);
            const each_array_3 = ensure_array_like(mobileSecondaryColumns);
            for (let colIndex = 0, $$length2 = each_array_3.length; colIndex < $$length2; colIndex++) {
              let column = each_array_3[colIndex];
              $$renderer2.push(`<div class="flex items-center justify-between gap-4 text-sm"><span class="shrink-0 text-neutral-500 dark:text-neutral-400">${escape_html(column.header)}</span> <span class="min-w-0 text-right text-neutral-700 dark:text-neutral-300"><!--[-->`);
              slot($$renderer2, $$props, "cell", {
                row,
                column,
                index: colIndex + 1,
                expanded: expandedRows.has(rowId)
              }, () => {
                $$renderer2.push(`${escape_html(getCellValue(row, column.key))}`);
              });
              $$renderer2.push(`<!--]--></span></div>`);
            }
            $$renderer2.push(`<!--]--></div>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--></div> `);
          if (!shouldDisableExpand(row) && expandedRows.has(rowId)) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<div class="border-t border-neutral-200 bg-neutral-50 dark:border-neutral-700/60 dark:bg-neutral-900"><!--[-->`);
            slot($$renderer2, $$props, "expanded", { row }, () => {
              $$renderer2.push(`<div class="p-4 text-sm text-neutral-500 dark:text-neutral-400">No additional details</div>`);
            });
            $$renderer2.push(`<!--]--></div>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--></div>`);
        }
        $$renderer2.push(`<!--]--> `);
        if (progressive) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<div></div>`);
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]-->`);
      }
      $$renderer2.push(`<!--]--></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div${attr_class(`overflow-x-auto rounded-xl border border-neutral-300 dark:border-neutral-700/60 ${flushBottom ? "rounded-b-none border-b-0" : ""}`)}><table${attr_class(`w-full ${fixedLayout ? "table-fixed" : ""}`)}><thead class="border-b border-neutral-300 bg-neutral-50 dark:border-neutral-700/60 dark:bg-neutral-800/50"><tr>`);
      if (chevronPosition === "left") {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<th${attr_class(`${compact2 ? "px-3 py-2.5" : "px-4 py-3"} w-12`)}></th>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--><!--[-->`);
      const each_array_4 = ensure_array_like(columns);
      for (let $$index_4 = 0, $$length = each_array_4.length; $$index_4 < $$length; $$index_4++) {
        let column = each_array_4[$$index_4];
        $$renderer2.push(`<th${attr_class(`${compact2 ? "px-4 py-2.5" : "px-6 py-3"} text-xs font-semibold text-neutral-500 dark:text-neutral-400 ${stringify(getAlignClass(column.align))} ${stringify(column.width || "")}`)}>`);
        if (column.sortable) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<button type="button"${attr_class(`inline-flex items-center gap-1 transition-colors hover:text-neutral-900 dark:hover:text-neutral-100 ${column.align === "right" ? "flex-row-reverse" : ""}`)}>${escape_html(column.header)} `);
          if (sortState?.key === column.key) {
            $$renderer2.push("<!--[0-->");
            if (sortState.direction === "asc") {
              $$renderer2.push("<!--[0-->");
              Arrow_up($$renderer2, {
                size: 12,
                class: "text-accent-500"
              });
            } else {
              $$renderer2.push("<!--[-1-->");
              Arrow_down($$renderer2, {
                size: 12,
                class: "text-accent-500"
              });
            }
            $$renderer2.push(`<!--]-->`);
          } else {
            $$renderer2.push("<!--[-1-->");
            Arrow_up_down($$renderer2, {
              size: 12,
              class: "opacity-30"
            });
          }
          $$renderer2.push(`<!--]--></button>`);
        } else {
          $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`${escape_html(column.header)}`);
        }
        $$renderer2.push(`<!--]--></th>`);
      }
      $$renderer2.push(`<!--]-->`);
      if ($$slots.actions) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<th${attr_class(`${compact2 ? "px-4 py-2.5" : "px-6 py-3"} w-20 text-right text-xs font-semibold text-neutral-500 dark:text-neutral-400`)}>Actions</th>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]-->`);
      if (chevronPosition === "right") {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<th${attr_class(`${compact2 ? "px-3 py-2.5" : "px-4 py-3"} w-12`)}></th>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></tr></thead><tbody class="divide-y divide-neutral-200 bg-white dark:divide-neutral-700/40 dark:bg-neutral-900/50">`);
      if (loading) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<!--[-->`);
        const each_array_5 = ensure_array_like(Array(loadingRows));
        for (let rowIdx = 0, $$length = each_array_5.length; rowIdx < $$length; rowIdx++) {
          each_array_5[rowIdx];
          $$renderer2.push(`<tr class="animate-pulse">`);
          if (chevronPosition === "left") {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<td${attr_class(clsx(compact2 ? "px-2 py-2" : "px-3 py-3"))}><div class="h-6 w-6 rounded bg-neutral-200 dark:bg-neutral-700"></div></td>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--><!--[-->`);
          const each_array_6 = ensure_array_like(columns);
          for (let colIdx = 0, $$length2 = each_array_6.length; colIdx < $$length2; colIdx++) {
            let column = each_array_6[colIdx];
            $$renderer2.push(`<td${attr_class(`${compact2 ? "px-4 py-2" : "px-6 py-4"} ${stringify(column.width || "")}`)}><div class="h-4 rounded bg-neutral-200 dark:bg-neutral-700"${attr_style(`width: ${colIdx === 0 ? "60%" : colIdx === columns.length - 1 ? "40%" : "70%"}`)}></div></td>`);
          }
          $$renderer2.push(`<!--]-->`);
          if ($$slots.actions) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<td${attr_class(`${compact2 ? "px-4 py-2" : "px-6 py-4"} text-right`)}><div class="ml-auto h-4 w-16 rounded bg-neutral-200 dark:bg-neutral-700"></div></td>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]-->`);
          if (chevronPosition === "right") {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<td${attr_class(`${compact2 ? "px-2 py-2" : "px-3 py-3"} text-right`)}><div class="ml-auto h-6 w-6 rounded bg-neutral-200 dark:bg-neutral-700"></div></td>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--></tr>`);
        }
        $$renderer2.push(`<!--]-->`);
      } else if (displayData.length === 0) {
        $$renderer2.push("<!--[1-->");
        $$renderer2.push(`<tr><td${attr("colspan", columns.length + 1 + ($$slots.actions ? 1 : 0))} class="px-6 py-8 text-center text-sm text-neutral-500 dark:text-neutral-400">${escape_html(emptyMessage)}</td></tr>`);
      } else {
        $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--[-->`);
        const each_array_7 = ensure_array_like(displayData);
        for (let index88 = 0, $$length = each_array_7.length; index88 < $$length; index88++) {
          let row = each_array_7[index88];
          const rowId = getRowId(row);
          $$renderer2.push(`<tr${attr_class(`cursor-pointer transition-colors hover:bg-neutral-50 dark:hover:bg-neutral-800 ${stringify(rowClass ? rowClass(row) : "")}`)}>`);
          if (chevronPosition === "left") {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<td${attr_class(`${compact2 ? "px-3 py-2" : "px-4 py-3"} text-neutral-400`)}>`);
            if (!shouldDisableExpand(row)) {
              $$renderer2.push("<!--[0-->");
              Button($$renderer2, {
                icon: expandedRows.has(rowId) ? Chevron_up : Chevron_down,
                size: "xs",
                title: expandedRows.has(rowId) ? "Collapse" : "Expand"
              });
            } else $$renderer2.push("<!--[-1-->");
            $$renderer2.push(`<!--]--></td>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--><!--[-->`);
          const each_array_8 = ensure_array_like(columns);
          for (let $$index_7 = 0, $$length2 = each_array_8.length; $$index_7 < $$length2; $$index_7++) {
            let column = each_array_8[$$index_7];
            $$renderer2.push(`<td${attr_class(`${compact2 ? "px-4 py-2" : "px-6 py-4"} text-sm text-neutral-900 dark:text-neutral-100 ${stringify(getAlignClass(column.align))} ${stringify(column.width || "")}`)}><!--[-->`);
            slot($$renderer2, $$props, "cell", {
              row,
              column,
              index: index88,
              expanded: expandedRows.has(rowId)
            }, () => {
              $$renderer2.push(`${escape_html(getCellValue(row, column.key))}`);
            });
            $$renderer2.push(`<!--]--></td>`);
          }
          $$renderer2.push(`<!--]-->`);
          if ($$slots.actions) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<td${attr_class(`${compact2 ? "px-4 py-2" : "px-6 py-4"} text-right text-sm`)}><!--[-->`);
            slot($$renderer2, $$props, "actions", { row }, null);
            $$renderer2.push(`<!--]--></td>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]-->`);
          if (chevronPosition === "right") {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<td${attr_class(`${compact2 ? "px-3 py-2" : "px-4 py-3"} text-right text-neutral-400`)}>`);
            if (!shouldDisableExpand(row)) {
              $$renderer2.push("<!--[0-->");
              Button($$renderer2, {
                icon: expandedRows.has(rowId) ? Chevron_up : Chevron_down,
                size: "xs",
                title: expandedRows.has(rowId) ? "Collapse" : "Expand"
              });
            } else $$renderer2.push("<!--[-1-->");
            $$renderer2.push(`<!--]--></td>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--></tr> `);
          if (!shouldDisableExpand(row) && expandedRows.has(rowId)) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<tr class="bg-neutral-50 dark:bg-neutral-900/30"><td${attr("colspan", columns.length + 1 + ($$slots.actions ? 1 : 0))}${attr_class(clsx(flushExpanded ? "" : compact2 ? "px-4 py-3" : "px-6 py-4"))}><div${attr_class(clsx(flushExpanded ? "" : "ml-6"))}><!--[-->`);
            slot($$renderer2, $$props, "expanded", { row }, () => {
              $$renderer2.push(`<div class="text-sm text-neutral-500 dark:text-neutral-400">No additional details</div>`);
            });
            $$renderer2.push(`<!--]--></div></td></tr>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]-->`);
        }
        $$renderer2.push(`<!--]-->`);
      }
      $$renderer2.push(`<!--]--></tbody></table> `);
      if (progressive) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div>`);
    }
    $$renderer2.push(`<!--]-->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      columns,
      data,
      getRowId,
      compact: compact2,
      emptyMessage,
      defaultSort,
      loading,
      loadingRows,
      flushExpanded,
      flushBottom,
      expandedRows,
      chevronPosition,
      expandOnRowClick,
      onRowClick,
      primaryColumnKey,
      disableExpandWhen,
      rowClass,
      responsive,
      pageSize,
      fixedLayout
    });
  });
}
var init_ExpandableTable = __esm({
  "dist/build/server/chunks/ExpandableTable.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_arrow_up_down();
    init_arrow_up();
    init_chevron_down();
    init_chevron_up();
    init_Button();
    init_progressiveList();
  }
});

// dist/build/server/chunks/DateTime.js
function DateTime($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let value2 = fallback($$props["value"], void 0);
    let date = fallback($$props["date"], false);
    let options2 = fallback($$props["options"], void 0);
    if (date) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`${escape_html(formatDate(value2, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat), options2))}`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`${escape_html(formatDateTime(value2, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat), options2))}`);
    }
    $$renderer2.push(`<!--]-->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      value: value2,
      date,
      options: options2
    });
  });
}
var init_DateTime = __esm({
  "dist/build/server/chunks/DateTime.js"() {
    "use strict";
    init_server();
    init_dates();
    init_dateFormat();
    init_timezone();
  }
});

// dist/build/server/chunks/DatabaseAvatar.js
function DatabaseAvatar($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let baseSrc, avatarSrc;
    let name = $$props["name"];
    let repoUrl = $$props["repoUrl"];
    let size = fallback($$props["size"], "sm");
    const sizeClasses = {
      xs: "h-5 w-5",
      sm: "h-8 w-8",
      md: "h-10 w-10"
    };
    let loaded = false;
    let failed = false;
    let lastSrc = "";
    const LOGO_OVERRIDES = { "https://github.com/Dictionarry-Hub/trash-pcd": "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/trash-guides.png" };
    function getGitHubAvatar(url) {
      if (LOGO_OVERRIDES[url]) return LOGO_OVERRIDES[url];
      const match = url.match(/github\.com\/([^\/]+)\//);
      if (match) return `/databases/avatar/${match[1]}`;
      return "";
    }
    function checkImageState() {
    }
    $: baseSrc = getGitHubAvatar(repoUrl);
    $: avatarSrc = baseSrc ? baseSrc : "";
    $: if (!avatarSrc && !loaded) {
      loaded = true;
      failed = true;
    }
    $: if (avatarSrc && avatarSrc !== lastSrc) {
      lastSrc = avatarSrc;
      queueMicrotask(checkImageState);
    }
    $$renderer2.push(`<div${attr_class(`relative ${stringify(sizeClasses[size])}`)}>`);
    if (!loaded) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="absolute inset-0 animate-pulse rounded-lg bg-neutral-200 dark:bg-neutral-700"></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (failed) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div${attr_class(`flex ${stringify(sizeClasses[size])} items-center justify-center rounded-lg bg-neutral-200 text-xs font-semibold text-neutral-600 dark:bg-neutral-700 dark:text-neutral-300`)}>${escape_html(name?.slice(0, 1) ?? "?")}</div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<img${attr("src", avatarSrc)}${attr("alt", `${stringify(name)} avatar`)}${attr_class(`${stringify(sizeClasses[size])} rounded-lg ${loaded ? "opacity-100" : "opacity-0"}`)}/>`);
    }
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, {
      name,
      repoUrl,
      size
    });
  });
}
var init_DatabaseAvatar = __esm({
  "dist/build/server/chunks/DatabaseAvatar.js"() {
    "use strict";
    init_index_server();
    init_server();
  }
});

// dist/build/server/chunks/ActionsBar.js
function ActionsBar($$renderer, $$props) {
  let className = fallback($$props["className"], "");
  let onboarding = fallback($$props["onboarding"], void 0);
  $$renderer.push(`<div${attr_class(`actions-bar mx-auto flex w-full justify-center md:mx-0 md:w-auto ${stringify(className)}`, "svelte-13tx2l4")}${attr("data-onboarding", onboarding)}><!--[-->`);
  slot($$renderer, $$props, "default", {}, null);
  $$renderer.push(`<!--]--></div>`);
  bind_props($$props, {
    className,
    onboarding
  });
}
var init_ActionsBar = __esm({
  "dist/build/server/chunks/ActionsBar.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/chunks/ActionButton.js
function ActionButton($$renderer, $$props) {
  let icon = fallback($$props["icon"], void 0);
  let iconClass = fallback($$props["iconClass"], "");
  let square = fallback($$props["square"], true);
  let hasDropdown = fallback($$props["hasDropdown"], false);
  let dropdownPosition = fallback($$props["dropdownPosition"], "left");
  let disabled = fallback($$props["disabled"], false);
  let title = fallback($$props["title"], "");
  let type = fallback($$props["type"], "button");
  let variant = fallback($$props["variant"], "neutral");
  let onboarding = fallback($$props["onboarding"], void 0);
  const variantClasses = {
    neutral: "hover:bg-neutral-50 dark:hover:bg-neutral-800",
    danger: "hover:bg-neutral-50 dark:hover:bg-neutral-800"
  };
  const iconVariantClasses = {
    neutral: "",
    danger: "group-hover:text-red-600 dark:group-hover:text-red-400"
  };
  $$renderer.push(`<div class="group relative flex" role="group"${attr("data-onboarding", onboarding)}><button${attr("type", type)}${attr("title", title)}${attr_class(`flex items-center justify-center border border-neutral-300 bg-white transition-colors dark:border-neutral-700/60 dark:bg-neutral-800/50 ${square ? "h-10 w-10" : "h-10 px-4"} ${stringify(disabled ? "cursor-not-allowed opacity-50" : variantClasses[variant])}`)}${attr("disabled", disabled, true)}>`);
  if (icon) {
    $$renderer.push("<!--[0-->");
    if (icon) {
      $$renderer.push("<!--[-->");
      icon($$renderer, {
        size: 20,
        class: `text-neutral-700 dark:text-neutral-200 ${stringify(variant === "danger" ? iconVariantClasses.danger : "")} ${stringify(iconClass)}`
      });
      $$renderer.push("<!--]-->");
    } else {
      $$renderer.push("<!--[!-->");
      $$renderer.push("<!--]-->");
    }
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--> <!--[-->`);
  slot($$renderer, $$props, "default", {}, null);
  $$renderer.push(`<!--]--></button> `);
  $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--></div>`);
  bind_props($$props, {
    icon,
    iconClass,
    square,
    hasDropdown,
    dropdownPosition,
    disabled,
    title,
    type,
    variant,
    onboarding
  });
}
var init_ActionButton = __esm({
  "dist/build/server/chunks/ActionButton.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/chunks/DropdownHeader.js
function DropdownHeader($$renderer, $$props) {
  let sizeClasses;
  let label = $$props["label"];
  let compact2 = fallback($$props["compact"], false);
  $: sizeClasses = compact2 ? "px-2 py-1 text-xs first:rounded-t-lg" : "px-3 py-2 text-xs first:rounded-t-xl";
  $$renderer.push(`<div${attr_class(`flex w-full items-center border-b border-neutral-200/50 dark:border-neutral-700/40 ${stringify(sizeClasses)}`)}><span class="text-neutral-500 dark:text-neutral-400">${escape_html(label)}</span></div>`);
  bind_props($$props, {
    label,
    compact: compact2
  });
}
var init_DropdownHeader = __esm({
  "dist/build/server/chunks/DropdownHeader.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/chunks/InfoModal.js
function InfoModal($$renderer, $$props) {
  let open = fallback($$props["open"], false);
  let header = fallback($$props["header"], "Information");
  let size = fallback($$props["size"], "md");
  const sizeClasses = {
    sm: "max-w-sm",
    md: "max-w-lg",
    lg: "max-w-2xl",
    xl: "max-w-4xl",
    "2xl": "max-w-6xl"
  };
  function handleClose() {
    open = false;
  }
  function handleKeydown(e) {
    if (e.key === "Escape" && open) handleClose();
  }
  $: if (typeof window !== "undefined") if (open) window.addEventListener("keydown", handleKeydown);
  else window.removeEventListener("keydown", handleKeydown);
  if (open) {
    $$renderer.push("<!--[0-->");
    $$renderer.push(`<div class="fixed inset-0 z-[100] overflow-y-auto bg-black/50 p-4 backdrop-blur-sm sm:p-6" role="dialog" aria-modal="true" tabindex="-1"><div class="flex min-h-full w-full items-start justify-center sm:items-center"><div${attr_class(`relative my-4 flex max-h-[calc(100svh-2rem)] w-full ${stringify(sizeClasses[size])} flex-col rounded-xl border border-neutral-300 bg-white shadow-xl sm:my-0 dark:border-neutral-700/60 dark:bg-neutral-900`)}><div class="flex flex-shrink-0 items-center justify-between border-b border-neutral-300 px-6 py-4 dark:border-neutral-700/60"><h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(header)}</h2> <button type="button" class="rounded-lg p-1 text-neutral-500 transition-colors hover:bg-neutral-100 hover:text-neutral-700 dark:text-neutral-400 dark:hover:bg-neutral-800 dark:hover:text-neutral-200">`);
    X2($$renderer, { size: 20 });
    $$renderer.push(`<!----></button></div> <div class="flex-1 overflow-auto px-6 py-4"><!--[-->`);
    slot($$renderer, $$props, "default", {}, null);
    $$renderer.push(`<!--]--></div></div></div></div>`);
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]-->`);
  bind_props($$props, {
    open,
    header,
    size
  });
}
var init_InfoModal = __esm({
  "dist/build/server/chunks/InfoModal.js"() {
    "use strict";
    init_server();
    init_x();
  }
});

// dist/build/server/chunks/PageMeta.js
function PageMeta($$renderer, $$props) {
  let title = $$props["title"];
  head("uir8zo", $$renderer, ($$renderer2) => {
    $$renderer2.title(($$renderer3) => {
      $$renderer3.push(`<title>${escape_html(title)}</title>`);
    });
  });
  bind_props($$props, { title });
}
var init_PageMeta = __esm({
  "dist/build/server/chunks/PageMeta.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/entries/pages/announcements/_page.svelte.js
var page_svelte_exports = {};
__export(page_svelte_exports, {
  default: () => _page
});
function Arrow_down_up($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "arrow-down-up" },
    props,
    { iconNode: [
      ["path", { "d": "m3 16 4 4 4-4" }],
      ["path", { "d": "M7 20V4" }],
      ["path", { "d": "m21 8-4-4-4 4" }],
      ["path", { "d": "M17 4v16" }]
    ] }
  ]));
}
function Eye_off($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "eye-off" },
    props,
    { iconNode: [
      ["path", { "d": "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49" }],
      ["path", { "d": "M14.084 14.158a3 3 0 0 1-4.242-4.242" }],
      ["path", { "d": "M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143" }],
      ["path", { "d": "m2 2 20 20" }]
    ] }
  ]));
}
function Mail_check($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "mail-check" },
    props,
    { iconNode: [
      ["path", { "d": "M22 13V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v12c0 1.1.9 2 2 2h8" }],
      ["path", { "d": "m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" }],
      ["path", { "d": "m16 19 2 2 4-4" }]
    ] }
  ]));
}
function _page($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let searchQuery, pcdSources, availableSourceKeys, visibleRows, visibleUnreadCount;
    function renderMarkdown(text2) {
      return sanitizeHtml(g2.parse(text2));
    }
    let data = $$props["data"];
    const sortOptions = [
      {
        key: "newest",
        label: "Newest first"
      },
      {
        key: "oldest",
        label: "Oldest first"
      },
      {
        key: "title",
        label: "Title (A\u2192Z)"
      },
      {
        key: "severity",
        label: "Severity (critical first)"
      },
      {
        key: "unread",
        label: "Unread first"
      }
    ];
    const severityRank = {
      critical: 0,
      warning: 1,
      info: 2
    };
    let sortKey = "newest";
    const searchStore = getPersistentSearchStore("announcementsSearch", { debounceMs: 150 });
    let enabledSources = /* @__PURE__ */ new Set();
    let initializedSources = false;
    function rowSourceKey(row) {
      return row.source === "profilarr" ? "profilarr" : `pcd:${row.databaseId}`;
    }
    function compareRows(a2, b3, key2) {
      switch (key2) {
        case "newest":
          return a2.publishedAt < b3.publishedAt ? 1 : a2.publishedAt > b3.publishedAt ? -1 : 0;
        case "oldest":
          return a2.publishedAt < b3.publishedAt ? -1 : a2.publishedAt > b3.publishedAt ? 1 : 0;
        case "title":
          return a2.title.localeCompare(b3.title);
        case "severity": {
          const diff = severityRank[a2.severity] - severityRank[b3.severity];
          if (diff !== 0) return diff;
          return a2.publishedAt < b3.publishedAt ? 1 : -1;
        }
        case "unread": {
          const aUnread = a2.readAt === null ? 0 : 1;
          const bUnread = b3.readAt === null ? 0 : 1;
          if (aUnread !== bUnread) return aUnread - bUnread;
          return a2.publishedAt < b3.publishedAt ? 1 : -1;
        }
      }
    }
    const columns = [
      {
        key: "severity",
        header: "Severity",
        width: "w-32"
      },
      {
        key: "title",
        header: "Title"
      },
      {
        key: "publishedAt",
        header: "Published",
        width: "w-40"
      },
      {
        key: "expiresAt",
        header: "Expires",
        width: "w-40"
      },
      {
        key: "source",
        header: "Source",
        width: "w-44"
      }
    ];
    const severityVariant = {
      info: "info",
      warning: "warning",
      critical: "danger"
    };
    let actionLoading = {};
    let markAllLoading = false;
    let infoModalOpen = false;
    function rowKey2(row) {
      return row.source === "profilarr" ? `profilarr:${row.id}` : `pcd:${row.databaseId}:${row.id}`;
    }
    $: searchQuery = store_get($$store_subs ??= {}, "$searchStore", searchStore).query;
    $: pcdSources = Array.from(new Map(data.announcements.filter((r2) => r2.source === "pcd" && r2.databaseId !== null).map((r2) => [r2.databaseId, r2.databaseName ?? "(unknown)"])).entries());
    $: availableSourceKeys = ["profilarr", ...pcdSources.map(([id]) => `pcd:${id}`)];
    $: if (!initializedSources && availableSourceKeys.length > 0) {
      enabledSources = new Set(availableSourceKeys);
      initializedSources = true;
    }
    $: if (initializedSources) {
      const next2 = /* @__PURE__ */ new Set();
      for (const key2 of availableSourceKeys) if (enabledSources.has(key2)) next2.add(key2);
      if (next2.size !== enabledSources.size) enabledSources = next2;
    }
    $: visibleRows = (() => {
      const q2 = searchQuery.trim().toLowerCase();
      return [...data.announcements.filter((row) => {
        if (!enabledSources.has(rowSourceKey(row))) return false;
        if (q2 && !row.title.toLowerCase().includes(q2)) return false;
        return true;
      })].sort((a2, b3) => compareRows(a2, b3, sortKey));
    })();
    $: visibleUnreadCount = visibleRows.filter((r2) => r2.readAt === null).length;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: "Announcements" });
      $$renderer3.push(`<!----> <div class="p-4 md:p-8"><div class="mb-6"><h1 class="text-2xl font-bold text-neutral-900 md:text-3xl dark:text-neutral-50">Announcements</h1> <p class="mt-3 text-base text-neutral-600 md:text-lg dark:text-neutral-400">Messages from the Profilarr team and your linked databases. Expand a row to read it.</p></div> `);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore,
            placeholder: "Search announcements...",
            responsive: true
          });
          $$renderer4.push(`<!----> `);
          Tooltip($$renderer4, {
            text: visibleUnreadCount > 0 ? `Mark ${visibleUnreadCount} visible as read` : "Nothing to mark",
            children: ($$renderer5) => {
              ActionButton($$renderer5, {
                icon: Mail_check,
                disabled: markAllLoading
              });
            },
            $$slots: { default: true }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Arrow_down_up,
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
              Dropdown($$renderer5, {
                position: dropdownPosition,
                minWidth: "14rem",
                children: ($$renderer6) => {
                  DropdownHeader($$renderer6, { label: "Sort announcements by" });
                  $$renderer6.push(`<!----> <!--[-->`);
                  const each_array = ensure_array_like(sortOptions);
                  for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                    let option = each_array[$$index];
                    DropdownItem($$renderer6, {
                      label: option.label,
                      selected: sortKey === option.key
                    });
                  }
                  $$renderer6.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Funnel,
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
              Dropdown($$renderer5, {
                position: dropdownPosition,
                minWidth: "14rem",
                children: ($$renderer6) => {
                  DropdownHeader($$renderer6, { label: "Show announcements from" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, {
                    label: "Profilarr",
                    selected: enabledSources.has("profilarr")
                  });
                  $$renderer6.push(`<!----> `);
                  if (pcdSources.length > 0) {
                    $$renderer6.push("<!--[0-->");
                    DropdownHeader($$renderer6, { label: "Linked databases" });
                    $$renderer6.push(`<!----> <!--[-->`);
                    const each_array_1 = ensure_array_like(pcdSources);
                    for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                      let [id, name] = each_array_1[$$index_1];
                      DropdownItem($$renderer6, {
                        label: name,
                        selected: enabledSources.has(`pcd:${id}`)
                      });
                    }
                    $$renderer6.push(`<!--]-->`);
                  } else $$renderer6.push("<!--[-1-->");
                  $$renderer6.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          Tooltip($$renderer4, {
            text: "About",
            children: ($$renderer5) => {
              ActionButton($$renderer5, { icon: Info });
            },
            $$slots: { default: true }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> <div class="mt-6">`);
      ExpandableTable($$renderer3, {
        columns,
        data: visibleRows,
        getRowId: rowKey2,
        emptyMessage: "No announcements match the current filters.",
        responsive: true,
        flushExpanded: true,
        chevronPosition: "right",
        $$slots: {
          cell: ($$renderer4, { row, column }) => {
            if (column.key === "source") {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="flex items-center gap-2 text-xs text-neutral-600 dark:text-neutral-400"${attr("title", row.source === "profilarr" ? "Profilarr team" : row.databaseName ?? "")}>`);
              if (row.source === "profilarr") {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<img${attr("src", logo_512_default)} alt="" class="h-5 w-5 flex-shrink-0"/> <span class="truncate">Profilarr</span>`);
              } else if (row.databaseRepoUrl) {
                $$renderer4.push("<!--[1-->");
                DatabaseAvatar($$renderer4, {
                  name: row.databaseName ?? "",
                  repoUrl: row.databaseRepoUrl,
                  size: "xs"
                });
                $$renderer4.push(`<!----> <span class="truncate">${escape_html(row.databaseName ?? "(unknown)")}</span>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                Database2($$renderer4, { class: "h-3.5 w-3.5 flex-shrink-0" });
                $$renderer4.push(`<!----> <span class="truncate">${escape_html(row.databaseName ?? "(unknown)")}</span>`);
              }
              $$renderer4.push(`<!--]--></span>`);
            } else if (column.key === "title") {
              $$renderer4.push("<!--[1-->");
              $$renderer4.push(`<span${attr_class(`text-sm ${row.readAt ? "text-neutral-600 dark:text-neutral-400" : "font-semibold text-neutral-900 dark:text-neutral-100"}`)}>`);
              if (!row.readAt) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<span class="mr-2 inline-block h-2 w-2 rounded-full bg-accent-500" aria-label="Unread"></span>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> ${escape_html(row.title)}</span>`);
            } else if (column.key === "severity") {
              $$renderer4.push("<!--[2-->");
              Label($$renderer4, {
                variant: severityVariant[row.severity],
                size: "md",
                rounded: "md",
                mono: true,
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->${escape_html(row.severity.toUpperCase())}`);
                },
                $$slots: { default: true }
              });
            } else if (column.key === "publishedAt") {
              $$renderer4.push("<!--[3-->");
              $$renderer4.push(`<span class="text-xs text-neutral-500 dark:text-neutral-500">`);
              DateTime($$renderer4, {
                value: row.publishedAt,
                date: true
              });
              $$renderer4.push(`<!----></span>`);
            } else if (column.key === "expiresAt") {
              $$renderer4.push("<!--[4-->");
              $$renderer4.push(`<span class="text-xs text-neutral-500 dark:text-neutral-500">`);
              if (row.expiresAt) {
                $$renderer4.push("<!--[0-->");
                DateTime($$renderer4, {
                  value: row.expiresAt,
                  date: true
                });
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></span>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          actions: ($$renderer4, { row }) => {
            if (row.readAt) {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                icon: Eye_off,
                size: "xs",
                variant: "secondary",
                ariaLabel: "Mark as unread",
                tooltip: "Mark as unread",
                loading: actionLoading[rowKey2(row)],
                disabled: actionLoading[rowKey2(row)]
              });
            } else {
              $$renderer4.push("<!--[-1-->");
              Button($$renderer4, {
                icon: Eye,
                size: "xs",
                variant: "secondary",
                ariaLabel: "Mark as read",
                tooltip: "Mark as read",
                loading: actionLoading[rowKey2(row)],
                disabled: actionLoading[rowKey2(row)]
              });
            }
            $$renderer4.push(`<!--]-->`);
          },
          expanded: ($$renderer4, { row }) => {
            $$renderer4.push(`<div class="space-y-3 p-4">`);
            if (row.body) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="prose prose-sm prose-neutral dark:prose-invert max-w-none text-sm">${html(renderMarkdown(row.body))}</div>`);
            } else {
              $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<p class="text-sm text-neutral-500 dark:text-neutral-500">Announcement body is not available.</p>`);
            }
            $$renderer4.push(`<!--]--> `);
            if (row.link) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="pt-1"><a${attr("href", row.link)} target="_blank" rel="noopener noreferrer" class="text-xs text-accent-600 hover:underline dark:text-accent-400">Read more \u2197</a></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></div>`);
          }
        }
      });
      $$renderer3.push(`<!----></div></div> `);
      InfoModal($$renderer3, {
        header: "About Announcements",
        get open() {
          return infoModalOpen;
        },
        set open($$value) {
          infoModalOpen = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-700 dark:text-neutral-300"><section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">What's in here?</h3> <p>Announcements come from two places. <strong>Profilarr</strong> messages are posted by the
				Profilarr team and reach every instance via the public bulletin. <strong>Database</strong> messages are written by the maintainers of the PCDs you have linked and travel with the database
				itself.</p></section> <section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Read state</h3> <p>Read state is tracked per announcement on this instance. Use the eye icon on a row to flip
				it, or "Mark visible as read" to clear out everything currently in view (filters and search
				apply).</p></section> <section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Severity</h3> <p><strong>Info</strong> is general news. <strong>Warning</strong> means something needs attention soon. <strong>Critical</strong> is a heads-up for action that probably can't wait.</p></section></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte = __esm({
  "dist/build/server/entries/pages/announcements/_page.svelte.js"() {
    "use strict";
    init_server();
    init_sanitize();
    init_logo_512();
    init_Dropdown();
    init_Icon();
    init_database2();
    init_eye();
    init_funnel();
    init_info();
    init_Button();
    init_search();
    init_store2();
    init_Label();
    init_navigation();
    init_DropdownItem();
    init_ExpandableTable();
    init_DateTime();
    init_DatabaseAvatar();
    init_ActionsBar();
    init_ActionButton();
    init_DropdownHeader();
    init_InfoModal();
    init_PageMeta();
    init_marked_esm();
  }
});

// dist/build/server/nodes/8.js
var __exports9 = {};
__export(__exports9, {
  component: () => component8,
  fonts: () => fonts9,
  imports: () => imports9,
  index: () => index9,
  server: () => page_server_ts_exports2,
  server_id: () => server_id8,
  stylesheets: () => stylesheets9
});
var index9, component_cache8, component8, server_id8, imports9, stylesheets9, fonts9;
var init__9 = __esm({
  async "dist/build/server/nodes/8.js"() {
    "use strict";
    await init_page_server_ts2();
    index9 = 8;
    component8 = async () => component_cache8 ??= (await Promise.resolve().then(() => (init_page_svelte(), page_svelte_exports))).default;
    server_id8 = "src/routes/announcements/+page.server.ts";
    imports9 = ["_app/immutable/nodes/8.DgqupZ3j.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BDqLURZS.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/MJc6__n-.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/unOv5SWI.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/gs7jR9Ta.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets9 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css"];
    fonts9 = [];
  }
});

// dist/build/server/entries/pages/arr/_page.server.ts.js
var page_server_ts_exports3 = {};
__export(page_server_ts_exports3, {
  actions: () => actions2,
  load: () => load9
});
function computeCompositeSyncStatus(statuses) {
  if (statuses.some((s3) => s3 === "failed")) return "failed";
  if (statuses.some((s3) => s3 === "in_progress")) return "in_progress";
  if (statuses.some((s3) => s3 === "pending")) return "pending";
  return "idle";
}
var load9, actions2;
var init_page_server_ts3 = __esm({
  async "dist/build/server/entries/pages/arr/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrSync();
    await init_arrInstances();
    await init_arrCleanupSettings();
    await init_cleanup();
    init_exports();
    load9 = () => {
      return { instances: arrInstancesQueries.getAll().map(({ api_key, ...safe }) => {
        const syncStatus = arrSyncQueries.getSyncConfigStatus(safe.id);
        const qpSync = arrSyncQueries.getQualityProfilesSync(safe.id);
        const dpSync = arrSyncQueries.getDelayProfilesSync(safe.id);
        const mmSync = arrSyncQueries.getMediaManagementSync(safe.id);
        const upgradeConfig = upgradeConfigsQueries.getByArrInstanceId(safe.id);
        const renameConfig = arrRenameSettingsQueries.getByInstanceId(safe.id);
        const cleanupConfig = arrCleanupSettingsQueries.getByInstanceId(safe.id);
        const compositeSyncStatus = qpSync.selections.length > 0 || dpSync.profileName !== null || mmSync.namingDatabaseId !== null || mmSync.qualityDefinitionsDatabaseId !== null || mmSync.mediaSettingsDatabaseId !== null ? computeCompositeSyncStatus([
          syncStatus.qualityProfiles.syncStatus,
          syncStatus.delayProfiles.syncStatus,
          syncStatus.mediaManagement.syncStatus
        ]) : "not_configured";
        return {
          ...safe,
          syncedProfileNames: qpSync.selections.map((s3) => s3.profileName),
          compositeSyncStatus,
          delayProfileName: dpSync.profileName,
          namingConfigName: mmSync.namingConfigName,
          qualityDefinitionsConfigName: mmSync.qualityDefinitionsConfigName,
          mediaSettingsConfigName: mmSync.mediaSettingsConfigName,
          upgradeEnabled: upgradeConfig?.enabled ?? false,
          renameEnabled: renameConfig?.enabled ?? false,
          cleanupEnabled: cleanupConfig?.enabled ?? false
        };
      }) };
    };
    actions2 = { delete: async ({ request }) => {
      const formData = await request.formData();
      const id = parseInt(formData.get("id")?.toString() || "0", 10);
      if (!id) {
        await logger.warn("Attempted to delete arr instance without ID", { source: "arr" });
        return fail(400, { error: "Instance ID is required" });
      }
      try {
        cleanupJobsForArrInstance(id);
        if (!arrInstancesQueries.delete(id)) return fail(404, { error: "Instance not found" });
        await logger.info(`Deleted arr instance: ${id}`, {
          source: "arr",
          meta: { id }
        });
        redirect(303, "/arr");
      } catch (error2) {
        if (error2 && typeof error2 === "object" && "status" in error2 && "location" in error2) throw error2;
        await logger.error("Failed to delete arr instance", {
          source: "arr",
          meta: { error: error2 instanceof Error ? error2.message : String(error2) }
        });
        return fail(500, { error: error2 instanceof Error ? error2.message : "Failed to delete instance" });
      }
    } };
  }
});

// dist/build/server/chunks/external-link.js
function External_link($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "external-link" },
    props,
    { iconNode: [
      ["path", { "d": "M15 3h6v6" }],
      ["path", { "d": "M10 14 21 3" }],
      ["path", { "d": "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }]
    ] }
  ]));
}
var init_external_link = __esm({
  "dist/build/server/chunks/external-link.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/plus.js
function Plus($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "plus" },
    props,
    { iconNode: [["path", { "d": "M5 12h14" }], ["path", { "d": "M12 5v14" }]] }
  ]));
}
var init_plus = __esm({
  "dist/build/server/chunks/plus.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/server2.js
function Server2($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "server" },
    props,
    { iconNode: [
      ["rect", {
        "width": "20",
        "height": "8",
        "x": "2",
        "y": "2",
        "rx": "2",
        "ry": "2"
      }],
      ["rect", {
        "width": "20",
        "height": "8",
        "x": "2",
        "y": "14",
        "rx": "2",
        "ry": "2"
      }],
      ["line", {
        "x1": "6",
        "x2": "6.01",
        "y1": "6",
        "y2": "6"
      }],
      ["line", {
        "x1": "6",
        "x2": "6.01",
        "y1": "18",
        "y2": "18"
      }]
    ] }
  ]));
}
var init_server22 = __esm({
  "dist/build/server/chunks/server2.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/layout-grid.js
function Layout_grid($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "layout-grid" },
    props,
    { iconNode: [
      ["rect", {
        "width": "7",
        "height": "7",
        "x": "3",
        "y": "3",
        "rx": "1"
      }],
      ["rect", {
        "width": "7",
        "height": "7",
        "x": "14",
        "y": "3",
        "rx": "1"
      }],
      ["rect", {
        "width": "7",
        "height": "7",
        "x": "14",
        "y": "14",
        "rx": "1"
      }],
      ["rect", {
        "width": "7",
        "height": "7",
        "x": "3",
        "y": "14",
        "rx": "1"
      }]
    ] }
  ]));
}
var init_layout_grid = __esm({
  "dist/build/server/chunks/layout-grid.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/ViewToggle.js
function Table($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "table" },
    props,
    { iconNode: [
      ["path", { "d": "M12 3v18" }],
      ["rect", {
        "width": "18",
        "height": "18",
        "x": "3",
        "y": "3",
        "rx": "2"
      }],
      ["path", { "d": "M3 9h18" }],
      ["path", { "d": "M3 15h18" }]
    ] }
  ]));
}
function ViewToggle($$renderer, $$props) {
  let value2 = fallback($$props["value"], "cards");
  let position = fallback($$props["position"], "right");
  ActionButton($$renderer, {
    icon: Eye,
    hasDropdown: true,
    dropdownPosition: position,
    $$slots: { dropdown: ($$renderer2) => {
      Dropdown($$renderer2, {
        slot: "dropdown",
        position,
        children: ($$renderer3) => {
          DropdownHeader($$renderer3, { label: "View" });
          $$renderer3.push(`<!----> `);
          DropdownItem($$renderer3, {
            icon: Layout_grid,
            label: "Cards",
            selected: value2 === "cards"
          });
          $$renderer3.push(`<!----> `);
          DropdownItem($$renderer3, {
            icon: Table,
            label: "Table",
            selected: value2 === "table"
          });
          $$renderer3.push(`<!---->`);
        },
        $$slots: { default: true }
      });
    } }
  });
  bind_props($$props, {
    value: value2,
    position
  });
}
var init_ViewToggle = __esm({
  "dist/build/server/chunks/ViewToggle.js"() {
    "use strict";
    init_server();
    init_Dropdown();
    init_Icon();
    init_eye();
    init_layout_grid();
    init_DropdownItem();
    init_ActionButton();
    init_DropdownHeader();
  }
});

// dist/build/server/chunks/trash-2.js
function Trash_2($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "trash-2" },
    props,
    { iconNode: [
      ["path", { "d": "M10 11v6" }],
      ["path", { "d": "M14 11v6" }],
      ["path", { "d": "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" }],
      ["path", { "d": "M3 6h18" }],
      ["path", { "d": "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" }]
    ] }
  ]));
}
var init_trash_2 = __esm({
  "dist/build/server/chunks/trash-2.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/unlink.js
function Unlink($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "unlink" },
    props,
    { iconNode: [
      ["path", { "d": "m18.84 12.25 1.72-1.71h-.02a5.004 5.004 0 0 0-.12-7.07 5.006 5.006 0 0 0-6.95 0l-1.72 1.71" }],
      ["path", { "d": "m5.17 11.75-1.71 1.71a5.004 5.004 0 0 0 .12 7.07 5.006 5.006 0 0 0 6.95 0l1.71-1.71" }],
      ["line", {
        "x1": "8",
        "x2": "8",
        "y1": "2",
        "y2": "5"
      }],
      ["line", {
        "x1": "2",
        "x2": "5",
        "y1": "8",
        "y2": "8"
      }],
      ["line", {
        "x1": "16",
        "x2": "16",
        "y1": "19",
        "y2": "22"
      }],
      ["line", {
        "x1": "19",
        "x2": "22",
        "y1": "16",
        "y2": "16"
      }]
    ] }
  ]));
}
var init_unlink = __esm({
  "dist/build/server/chunks/unlink.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/EmptyState.js
function EmptyState($$renderer, $$props) {
  let icon = $$props["icon"];
  let title = $$props["title"];
  let description = $$props["description"];
  let buttonText = $$props["buttonText"];
  let buttonHref = $$props["buttonHref"];
  let buttonIcon = fallback($$props["buttonIcon"], Plus);
  let onboarding = fallback($$props["onboarding"], void 0);
  $$renderer.push(`<div class="flex min-h-[calc(100vh-4rem)] items-center justify-center p-8"><div class="w-full max-w-md text-center"><div class="mb-6 flex justify-center"><div class="rounded-full bg-neutral-100 p-6 dark:bg-neutral-800">`);
  if (icon) {
    $$renderer.push("<!--[-->");
    icon($$renderer, { class: "h-12 w-12 text-neutral-400 dark:text-neutral-500" });
    $$renderer.push("<!--]-->");
  } else {
    $$renderer.push("<!--[!-->");
    $$renderer.push("<!--]-->");
  }
  $$renderer.push(`</div></div> <h1 class="mb-3 text-2xl font-bold text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h1> <p class="mb-8 text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p> <span${attr("data-onboarding", onboarding)} class="inline-block">`);
  Button($$renderer, {
    text: buttonText,
    href: buttonHref,
    icon: buttonIcon,
    iconColor: "text-blue-600 dark:text-blue-400"
  });
  $$renderer.push(`<!----></span></div></div>`);
  bind_props($$props, {
    icon,
    title,
    description,
    buttonText,
    buttonHref,
    buttonIcon,
    onboarding
  });
}
var init_EmptyState = __esm({
  "dist/build/server/chunks/EmptyState.js"() {
    "use strict";
    init_server();
    init_Button();
    init_plus();
  }
});

// dist/build/server/chunks/Table.js
function Table2($$renderer, $$props) {
  const $$slots = sanitize_slots($$props);
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let useMobileLayout, displayData;
    let columns = $$props["columns"];
    let data = $$props["data"];
    let hoverable = fallback($$props["hoverable"], true);
    let compact2 = fallback($$props["compact"], false);
    let emptyMessage = fallback($$props["emptyMessage"], "No data available");
    let onRowClick = fallback($$props["onRowClick"], void 0);
    let rowHref = fallback($$props["rowHref"], void 0);
    let initialSort = fallback($$props["initialSort"], null);
    let onSortChange = fallback($$props["onSortChange"], void 0);
    let actionsHeader = fallback($$props["actionsHeader"], "Actions");
    let actionsHeaderAlign = fallback($$props["actionsHeaderAlign"], "right");
    let responsive = fallback($$props["responsive"], false);
    let pageSize = fallback($$props["pageSize"], void 0);
    let rowClass = fallback($$props["rowClass"], void 0);
    let rowAttributes = fallback($$props["rowAttributes"], void 0);
    let isMobile = false;
    onDestroy(() => {
    });
    let sortKey = initialSort?.key ?? null;
    let sortDirection = initialSort?.direction ?? "asc";
    let sortedData = data;
    function getCellValue(row, key2) {
      return key2.split(".").reduce((obj, k2) => obj?.[k2], row);
    }
    function getAlignClass(align) {
      switch (align) {
        case "center":
          return "text-center";
        case "right":
          return "text-right";
        default:
          return "text-left";
      }
    }
    function compareValues(a2, b3) {
      if (a2 == null && b3 == null) return 0;
      if (a2 == null) return -1;
      if (b3 == null) return 1;
      if (typeof a2 === "number" && typeof b3 === "number") return a2 - b3;
      if (a2 instanceof Date && b3 instanceof Date) return a2.getTime() - b3.getTime();
      return String(a2).localeCompare(String(b3));
    }
    function getSortValue(row, column) {
      if (column.sortAccessor) return column.sortAccessor(row);
      return getCellValue(row, column.key);
    }
    function sortData(rows) {
      if (!sortKey) return rows;
      const column = columns.find((col) => col.key === sortKey);
      if (!column) return rows;
      const sorted = [...rows].sort((a2, b3) => {
        if (column.sortNullsLast) {
          const aValue = getSortValue(a2, column);
          const bValue = getSortValue(b3, column);
          if (aValue == null && bValue == null) return 0;
          if (aValue == null) return sortDirection === "desc" ? -1 : 1;
          if (bValue == null) return sortDirection === "desc" ? 1 : -1;
        }
        if (column.sortComparator) return column.sortComparator(a2, b3);
        return compareValues(getSortValue(a2, column), getSortValue(b3, column));
      });
      return sortDirection === "desc" ? sorted.reverse() : sorted;
    }
    const progressive = pageSize ? createProgressiveList({ pageSize }) : null;
    const progressiveCount = progressive?.visibleCount;
    $: useMobileLayout = responsive && isMobile;
    $: sortedData = sortKey ? sortData(data) : data;
    $: sortedData = sortData(data);
    $: if (progressive) progressive.setTotalCount(sortedData.length);
    $: if (progressive) progressive.reset();
    $: displayData = progressiveCount ? sortedData.slice(0, store_get($$store_subs ??= {}, "$progressiveCount", progressiveCount)) : sortedData;
    if (useMobileLayout) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="space-y-3">`);
      if (displayData.length === 0) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="rounded-xl border border-neutral-300 bg-white p-8 text-center text-sm text-neutral-500 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-400">${escape_html(emptyMessage)}</div>`);
      } else {
        $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--[-->`);
        const each_array = ensure_array_like(displayData);
        for (let rowIndex = 0, $$length = each_array.length; rowIndex < $$length; rowIndex++) {
          let row = each_array[rowIndex];
          $$renderer2.push(`<div${attributes({
            class: `group/row relative overflow-hidden rounded-xl border border-neutral-300 bg-white dark:border-neutral-700/60 dark:bg-neutral-800/50 ${onRowClick || rowHref ? "cursor-pointer" : ""}`,
            ...rowAttributes ? rowAttributes(row, rowIndex) : {}
          }, "svelte-tbqqgh")}>`);
          if (rowHref) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<a${attr("href", rowHref(row))} class="absolute inset-0 z-10"${attr("aria-label", `Open ${stringify(columns[0]?.header || "item")}`)}></a>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--> <div class="flex items-center justify-between gap-3 px-4 py-3"><div class="min-w-0 flex-1 font-medium text-neutral-900 dark:text-neutral-100">`);
          if (columns[0].cell) {
            $$renderer2.push("<!--[0-->");
            const rendered = columns[0].cell(row);
            if (typeof rendered === "string") {
              $$renderer2.push("<!--[0-->");
              $$renderer2.push(`${escape_html(rendered)}`);
            } else if (typeof rendered === "object" && "html" in rendered) {
              $$renderer2.push("<!--[1-->");
              $$renderer2.push(`${html(rendered.html)}`);
            } else {
              $$renderer2.push("<!--[-1-->");
              if (rendered) {
                $$renderer2.push("<!--[-->");
                rendered($$renderer2, { row });
                $$renderer2.push("<!--]-->");
              } else {
                $$renderer2.push("<!--[!-->");
                $$renderer2.push("<!--]-->");
              }
            }
            $$renderer2.push(`<!--]-->`);
          } else {
            $$renderer2.push("<!--[-1-->");
            $$renderer2.push(`<!--[-->`);
            slot($$renderer2, $$props, "cell", {
              row,
              column: columns[0],
              rowIndex
            }, () => {
              $$renderer2.push(`${escape_html(getCellValue(row, columns[0].key))}`);
            });
            $$renderer2.push(`<!--]-->`);
          }
          $$renderer2.push(`<!--]--></div> `);
          if ($$slots.actions) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<div class="shrink-0"><!--[-->`);
            slot($$renderer2, $$props, "actions", {
              row,
              rowIndex
            }, null);
            $$renderer2.push(`<!--]--></div>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--></div> `);
          if (columns.length > 1) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<div class="space-y-2 border-t border-neutral-200 px-4 py-3 dark:border-neutral-700/60"><!--[-->`);
            const each_array_1 = ensure_array_like(columns.slice(1));
            for (let colIndex = 0, $$length2 = each_array_1.length; colIndex < $$length2; colIndex++) {
              let column = each_array_1[colIndex];
              $$renderer2.push(`<div class="flex items-center justify-between gap-4 text-sm"><span class="shrink-0 text-neutral-500 dark:text-neutral-400">${escape_html(column.header)}</span> <span class="min-w-0 text-right text-neutral-700 dark:text-neutral-300">`);
              if (column.cell) {
                $$renderer2.push("<!--[0-->");
                const rendered = column.cell(row);
                if (typeof rendered === "string") {
                  $$renderer2.push("<!--[0-->");
                  $$renderer2.push(`${escape_html(rendered)}`);
                } else if (typeof rendered === "object" && "html" in rendered) {
                  $$renderer2.push("<!--[1-->");
                  $$renderer2.push(`${html(rendered.html)}`);
                } else {
                  $$renderer2.push("<!--[-1-->");
                  if (rendered) {
                    $$renderer2.push("<!--[-->");
                    rendered($$renderer2, { row });
                    $$renderer2.push("<!--]-->");
                  } else {
                    $$renderer2.push("<!--[!-->");
                    $$renderer2.push("<!--]-->");
                  }
                }
                $$renderer2.push(`<!--]-->`);
              } else {
                $$renderer2.push("<!--[-1-->");
                $$renderer2.push(`<!--[-->`);
                slot($$renderer2, $$props, "cell", {
                  row,
                  column,
                  rowIndex: colIndex + 1
                }, () => {
                  $$renderer2.push(`${escape_html(getCellValue(row, column.key))}`);
                });
                $$renderer2.push(`<!--]-->`);
              }
              $$renderer2.push(`<!--]--></span></div>`);
            }
            $$renderer2.push(`<!--]--></div>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--></div>`);
        }
        $$renderer2.push(`<!--]--> `);
        if (progressive) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<div></div>`);
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]-->`);
      }
      $$renderer2.push(`<!--]--></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="overflow-x-auto rounded-xl border border-neutral-300 dark:border-neutral-700/60"><table class="w-full"><thead class="border-b border-neutral-300 bg-neutral-50 dark:border-neutral-700/60 dark:bg-neutral-800/50"><tr><!--[-->`);
      const each_array_2 = ensure_array_like(columns);
      for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
        let column = each_array_2[$$index_2];
        $$renderer2.push(`<th${attr_class(`${compact2 ? "px-4 py-2.5" : "px-6 py-3"} text-xs font-semibold text-neutral-500 dark:text-neutral-400 ${getAlignClass(column.align)} ${column.width || ""}`, "svelte-tbqqgh")}>`);
        if (column.sortable) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<div role="button" tabindex="0"${attr_class(`group flex w-full items-center gap-1.5 text-xs font-semibold ${column.align === "center" ? "justify-center" : column.align === "right" ? "justify-end" : "justify-start"}`, "svelte-tbqqgh")}>`);
          if (column.headerIcon) {
            $$renderer2.push("<!--[0-->");
            if (column.headerIcon) {
              $$renderer2.push("<!--[-->");
              column.headerIcon($$renderer2, { size: 14 });
              $$renderer2.push("<!--]-->");
            } else {
              $$renderer2.push("<!--[!-->");
              $$renderer2.push("<!--]-->");
            }
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--> <span>${escape_html(column.header)}</span> <span class="text-[0.6rem] text-neutral-400 transition-opacity group-hover:text-neutral-600 group-hover:dark:text-neutral-200">`);
          if (sortKey === column.key) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`${escape_html(sortDirection === "asc" ? "\u25B2" : "\u25BC")}`);
          } else {
            $$renderer2.push("<!--[-1-->");
            $$renderer2.push(`\u21C5`);
          }
          $$renderer2.push(`<!--]--></span></div>`);
        } else {
          $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<div${attr_class(`flex items-center gap-1.5 ${column.align === "center" ? "justify-center" : column.align === "right" ? "justify-end" : ""}`, "svelte-tbqqgh")}>`);
          if (column.headerIcon) {
            $$renderer2.push("<!--[0-->");
            if (column.headerIcon) {
              $$renderer2.push("<!--[-->");
              column.headerIcon($$renderer2, { size: 14 });
              $$renderer2.push("<!--]-->");
            } else {
              $$renderer2.push("<!--[!-->");
              $$renderer2.push("<!--]-->");
            }
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--> ${escape_html(column.header)}</div>`);
        }
        $$renderer2.push(`<!--]--></th>`);
      }
      $$renderer2.push(`<!--]-->`);
      if ($$slots.actions) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<th${attr_class(`${compact2 ? "px-4 py-2.5" : "px-6 py-3"} ${actionsHeaderAlign === "left" ? "text-left" : actionsHeaderAlign === "center" ? "text-center" : "text-right"} text-xs font-semibold text-neutral-500 dark:text-neutral-400`, "svelte-tbqqgh")}>${escape_html(actionsHeader)}</th>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></tr></thead><tbody class="divide-y divide-neutral-200 bg-white dark:divide-neutral-700/40 dark:bg-neutral-900/50">`);
      if (displayData.length === 0) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<tr><td${attr("colspan", columns.length + ($$slots.actions ? 1 : 0))} class="px-6 py-8 text-center text-sm text-neutral-500 dark:text-neutral-400 svelte-tbqqgh">${escape_html(emptyMessage)}</td></tr>`);
      } else {
        $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--[-->`);
        const each_array_3 = ensure_array_like(displayData);
        for (let rowIndex = 0, $$length = each_array_3.length; rowIndex < $$length; rowIndex++) {
          let row = each_array_3[rowIndex];
          $$renderer2.push(`<tr${attributes({
            class: `group/row ${hoverable ? "transition-colors hover:bg-neutral-50 dark:hover:bg-neutral-800" : ""} ${onRowClick || rowHref ? "cursor-pointer" : ""} ${stringify(rowClass ? rowClass(row) : "")}`,
            ...rowAttributes ? rowAttributes(row, rowIndex) : {}
          }, "svelte-tbqqgh")}><!--[-->`);
          const each_array_4 = ensure_array_like(columns);
          for (let colIndex = 0, $$length2 = each_array_4.length; colIndex < $$length2; colIndex++) {
            let column = each_array_4[colIndex];
            const tdExtraClass = typeof column.tdClass === "function" ? column.tdClass(row) : column.tdClass ?? "";
            $$renderer2.push(`<td${attr_class(`${compact2 ? "px-4 py-2" : "px-6 py-4"} text-sm text-neutral-900 dark:text-neutral-100 ${getAlignClass(column.align)} ${column.width || ""} ${rowHref ? "relative" : ""} ${tdExtraClass}`, "svelte-tbqqgh")}>`);
            if (rowHref) {
              $$renderer2.push("<!--[0-->");
              $$renderer2.push(`<a${attr("href", rowHref(row))} class="cell-link svelte-tbqqgh" aria-label="Open row"></a>`);
            } else $$renderer2.push("<!--[-1-->");
            $$renderer2.push(`<!--]--> `);
            if (column.cell) {
              $$renderer2.push("<!--[0-->");
              const rendered = column.cell(row);
              if (typeof rendered === "string") {
                $$renderer2.push("<!--[0-->");
                $$renderer2.push(`${escape_html(rendered)}`);
              } else if (typeof rendered === "object" && "html" in rendered) {
                $$renderer2.push("<!--[1-->");
                $$renderer2.push(`${html(rendered.html)}`);
              } else {
                $$renderer2.push("<!--[-1-->");
                if (rendered) {
                  $$renderer2.push("<!--[-->");
                  rendered($$renderer2, { row });
                  $$renderer2.push("<!--]-->");
                } else {
                  $$renderer2.push("<!--[!-->");
                  $$renderer2.push("<!--]-->");
                }
              }
              $$renderer2.push(`<!--]-->`);
            } else {
              $$renderer2.push("<!--[-1-->");
              $$renderer2.push(`<!--[-->`);
              slot($$renderer2, $$props, "cell", {
                row,
                column,
                rowIndex
              }, () => {
                $$renderer2.push(`${escape_html(getCellValue(row, column.key))}`);
              });
              $$renderer2.push(`<!--]-->`);
            }
            $$renderer2.push(`<!--]--></td>`);
          }
          $$renderer2.push(`<!--]-->`);
          if ($$slots.actions) {
            $$renderer2.push("<!--[0-->");
            $$renderer2.push(`<td${attr_class(`${compact2 ? "px-4 py-2" : "px-6 py-4"} ${actionsHeaderAlign === "left" ? "text-left" : actionsHeaderAlign === "center" ? "text-center" : "text-right"} text-sm`, "svelte-tbqqgh")}><!--[-->`);
            slot($$renderer2, $$props, "actions", {
              row,
              rowIndex
            }, null);
            $$renderer2.push(`<!--]--></td>`);
          } else $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<!--]--></tr>`);
        }
        $$renderer2.push(`<!--]-->`);
      }
      $$renderer2.push(`<!--]--></tbody></table> `);
      if (progressive) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div>`);
    }
    $$renderer2.push(`<!--]-->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      columns,
      data,
      hoverable,
      compact: compact2,
      emptyMessage,
      onRowClick,
      rowHref,
      initialSort,
      onSortChange,
      actionsHeader,
      actionsHeaderAlign,
      responsive,
      pageSize,
      rowClass,
      rowAttributes
    });
  });
}
var init_Table = __esm({
  "dist/build/server/chunks/Table.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_progressiveList();
  }
});

// dist/build/server/chunks/arrDisplayUrl.js
function getDisplayUrl(instance) {
  const override2 = instance.external_url?.trim();
  return (override2 && override2.length > 0 ? override2 : instance.url).replace(/\/$/, "");
}
var init_arrDisplayUrl = __esm({
  "dist/build/server/chunks/arrDisplayUrl.js"() {
    "use strict";
  }
});

// dist/build/server/chunks/CardGrid.js
function CardGrid($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let columns = fallback($$props["columns"], 3);
    let gap = fallback($$props["gap"], "md");
    let flush = fallback($$props["flush"], false);
    let className = fallback($$props["className"], "");
    const gapClasses = {
      sm: "gap-2",
      md: "gap-4",
      lg: "gap-6"
    };
    const columnClasses = {
      1: "grid-cols-1",
      2: "grid-cols-1 md:grid-cols-2",
      3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
      4: "grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4",
      5: "grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5"
    };
    $: setContext("card-flush", flush);
    $$renderer2.push(`<div${attr_class(`grid ${stringify(columnClasses[columns])} ${stringify(gapClasses[gap])} ${stringify(className)}`)}><!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, {
      columns,
      gap,
      flush,
      className
    });
  });
}
var init_CardGrid = __esm({
  "dist/build/server/chunks/CardGrid.js"() {
    "use strict";
    init_index_server();
    init_server();
  }
});

// dist/build/server/chunks/dataPage.js
function createViewModeStore(config2) {
  const { storageKey, defaultView = "cards", mobileBreakpoint = 768 } = config2;
  return writable(defaultView);
}
function createDataPageStore(initialItems, config2) {
  const { storageKey, searchKeys, defaultView = "cards", debounceMs = 300 } = config2;
  const items = writable(initialItems);
  const search = config2.searchStore ?? (config2.searchKey ? getPersistentSearchStore(config2.searchKey, { debounceMs }) : createSearchStore({ debounceMs }));
  const view = createViewModeStore({
    storageKey,
    defaultView
  });
  const filtered = derived$1([items, search.debouncedQuery], ([$items, $query]) => {
    if (!$query) return $items;
    const queryLower = $query.toLowerCase();
    return $items.filter((item) => searchKeys.some((key2) => {
      const value2 = item[key2];
      if (value2 == null) return false;
      return String(value2).toLowerCase().includes(queryLower);
    }));
  });
  return {
    search,
    view: {
      subscribe: view.subscribe,
      set: view.set
    },
    filtered: { subscribe: filtered.subscribe },
    setItems: (newItems) => items.set(newItems)
  };
}
var init_dataPage = __esm({
  "dist/build/server/chunks/dataPage.js"() {
    "use strict";
    init_server();
    init_index_server2();
    init_search();
  }
});

// dist/build/server/entries/pages/arr/_page.svelte.js
var page_svelte_exports2 = {};
__export(page_svelte_exports2, {
  default: () => _page2
});
function Type($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "type" },
    props,
    { iconNode: [
      ["path", { "d": "M12 4v16" }],
      ["path", { "d": "M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2" }],
      ["path", { "d": "M9 20h6" }]
    ] }
  ]));
}
function TableView($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let instances = $$props["instances"];
    createEventDispatcher();
    const logos = {
      radarr: Radarr_default,
      sonarr: Sonarr_default
    };
    let loadedImages = /* @__PURE__ */ new Set();
    function getLogoPath(type) {
      return logos[type] || "";
    }
    function formatType(type) {
      return type.charAt(0).toUpperCase() + type.slice(1);
    }
    function getRowHref(instance) {
      return `/arr/${instance.id}`;
    }
    Table2($$renderer2, {
      columns: [
        {
          key: "name",
          header: "Name",
          align: "left"
        },
        {
          key: "qualityProfiles",
          header: "Quality Profiles",
          align: "left"
        },
        {
          key: "delayProfile",
          header: "Delay Profile",
          align: "left"
        },
        {
          key: "mediaManagement",
          header: "Media Management",
          align: "left"
        },
        {
          key: "upgrades",
          header: "Upgrades",
          align: "center",
          width: "w-24"
        },
        {
          key: "renames",
          header: "Renames",
          align: "center",
          width: "w-24"
        },
        {
          key: "cleanup",
          header: "Cleanup",
          align: "center",
          width: "w-24"
        }
      ],
      data: instances,
      hoverable: true,
      rowHref: getRowHref,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "name") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex items-center gap-3"><div class="relative h-6 w-6 flex-shrink-0">`);
            if (!loadedImages.has(row.id)) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="absolute inset-0 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--> <img${attr("src", getLogoPath(row.type))}${attr("alt", `${formatType(row.type)} logo`)}${attr_class(`h-6 w-6 rounded ${loadedImages.has(row.id) ? "opacity-100" : "opacity-0"}`)} onload="this.__e=event" onerror="this.__e=event"/></div> <span class="font-medium text-neutral-900 dark:text-neutral-50">${escape_html(row.name)}</span></div>`);
          } else if (column.key === "qualityProfiles") {
            $$renderer3.push("<!--[1-->");
            if (row.syncedProfileNames.length > 0) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
              const each_array = ensure_array_like(row.syncedProfileNames);
              for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                let name = each_array[$$index];
                Label($$renderer3, {
                  variant: "secondary",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer4) => {
                    $$renderer4.push(`<!---->${escape_html(name)}`);
                  },
                  $$slots: { default: true }
                });
              }
              $$renderer3.push(`<!--]--></div>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<span class="text-xs text-neutral-400 dark:text-neutral-500">None</span>`);
            }
            $$renderer3.push(`<!--]-->`);
          } else if (column.key === "delayProfile") {
            $$renderer3.push("<!--[2-->");
            if (row.delayProfileName) {
              $$renderer3.push("<!--[0-->");
              Label($$renderer3, {
                variant: "secondary",
                size: "sm",
                rounded: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(row.delayProfileName)}`);
                },
                $$slots: { default: true }
              });
            } else {
              $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<span class="text-xs text-neutral-400 dark:text-neutral-500">None</span>`);
            }
            $$renderer3.push(`<!--]-->`);
          } else if (column.key === "mediaManagement") {
            $$renderer3.push("<!--[3-->");
            if (row.namingConfigName || row.qualityDefinitionsConfigName || row.mediaSettingsConfigName) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="flex flex-wrap gap-1">`);
              if (row.namingConfigName) {
                $$renderer3.push("<!--[0-->");
                Label($$renderer3, {
                  variant: "secondary",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer4) => {
                    $$renderer4.push(`<!---->Naming: ${escape_html(row.namingConfigName)}`);
                  },
                  $$slots: { default: true }
                });
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--> `);
              if (row.qualityDefinitionsConfigName) {
                $$renderer3.push("<!--[0-->");
                Label($$renderer3, {
                  variant: "secondary",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer4) => {
                    $$renderer4.push(`<!---->Quality Definitions: ${escape_html(row.qualityDefinitionsConfigName)}`);
                  },
                  $$slots: { default: true }
                });
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--> `);
              if (row.mediaSettingsConfigName) {
                $$renderer3.push("<!--[0-->");
                Label($$renderer3, {
                  variant: "secondary",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer4) => {
                    $$renderer4.push(`<!---->Media Settings: ${escape_html(row.mediaSettingsConfigName)}`);
                  },
                  $$slots: { default: true }
                });
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--></div>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<span class="text-xs text-neutral-400 dark:text-neutral-500">None</span>`);
            }
            $$renderer3.push(`<!--]-->`);
          } else if (column.key === "upgrades") {
            $$renderer3.push("<!--[4-->");
            $$renderer3.push(`<div class="flex justify-center">`);
            Label($$renderer3, {
              variant: row.upgradeEnabled ? "success" : "secondary",
              size: "sm",
              rounded: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.upgradeEnabled ? "On" : "Off")}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----></div>`);
          } else if (column.key === "renames") {
            $$renderer3.push("<!--[5-->");
            $$renderer3.push(`<div class="flex justify-center">`);
            Label($$renderer3, {
              variant: row.renameEnabled ? "success" : "secondary",
              size: "sm",
              rounded: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.renameEnabled ? "On" : "Off")}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----></div>`);
          } else if (column.key === "cleanup") {
            $$renderer3.push("<!--[6-->");
            $$renderer3.push(`<div class="flex justify-center">`);
            Label($$renderer3, {
              variant: row.cleanupEnabled ? "success" : "secondary",
              size: "sm",
              rounded: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.cleanupEnabled ? "On" : "Off")}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        actions: ($$renderer3, { row }) => {
          $$renderer3.push(`<div class="relative z-10 flex items-center justify-end gap-1">`);
          Button($$renderer3, {
            icon: External_link,
            size: "xs",
            variant: "secondary",
            title: `Open in ${formatType(row.type)}`,
            ariaLabel: `Open in ${formatType(row.type)}`,
            href: getDisplayUrl(row),
            target: "_blank",
            rel: "noopener noreferrer"
          });
          $$renderer3.push(`<!----> `);
          Button($$renderer3, {
            icon: Unlink,
            size: "xs",
            title: "Unlink instance",
            variant: "secondary",
            iconColor: "text-red-600 dark:text-red-400"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    bind_props($$props, { instances });
  });
}
function CardView($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let instances = $$props["instances"];
    createEventDispatcher();
    const logos = {
      radarr: Radarr_default,
      sonarr: Sonarr_default
    };
    let loadedImages = /* @__PURE__ */ new Set();
    function getLogoPath(type) {
      return logos[type] || "";
    }
    function formatType(type) {
      return type.charAt(0).toUpperCase() + type.slice(1);
    }
    CardGrid($$renderer2, {
      columns: 1,
      className: "lg:grid-cols-2 2xl:grid-cols-3",
      flush: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(instances);
        for (let $$index_1 = 0, $$length = each_array.length; $$index_1 < $$length; $$index_1++) {
          let instance = each_array[$$index_1];
          Card($$renderer3, {
            href: `/arr/${stringify(instance.id)}`,
            hoverable: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="flex flex-1 flex-col gap-2"><div><span class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Quality Profiles:</span> `);
              if (instance.syncedProfileNames.length > 0) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="mt-1 flex flex-wrap gap-1"><!--[-->`);
                const each_array_1 = ensure_array_like(instance.syncedProfileNames);
                for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
                  let name = each_array_1[$$index];
                  Label($$renderer4, {
                    variant: "secondary",
                    size: "sm",
                    rounded: "md",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->${escape_html(name)}`);
                    },
                    $$slots: { default: true }
                  });
                }
                $$renderer4.push(`<!--]--></div>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<span class="ml-1 text-xs text-neutral-400 dark:text-neutral-500">None</span>`);
              }
              $$renderer4.push(`<!--]--></div> <div><span class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Delay Profile:</span> `);
              if (instance.delayProfileName) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<span class="ml-1">`);
                Label($$renderer4, {
                  variant: "secondary",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->${escape_html(instance.delayProfileName)}`);
                  },
                  $$slots: { default: true }
                });
                $$renderer4.push(`<!----></span>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<span class="ml-1 text-xs text-neutral-400 dark:text-neutral-500">None</span>`);
              }
              $$renderer4.push(`<!--]--></div> <div><span class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Media Management:</span> `);
              if (instance.namingConfigName || instance.qualityDefinitionsConfigName || instance.mediaSettingsConfigName) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="mt-1 flex flex-wrap gap-1">`);
                if (instance.namingConfigName) {
                  $$renderer4.push("<!--[0-->");
                  Label($$renderer4, {
                    variant: "secondary",
                    size: "sm",
                    rounded: "md",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->Naming: ${escape_html(instance.namingConfigName)}`);
                    },
                    $$slots: { default: true }
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                if (instance.qualityDefinitionsConfigName) {
                  $$renderer4.push("<!--[0-->");
                  Label($$renderer4, {
                    variant: "secondary",
                    size: "sm",
                    rounded: "md",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->Quality Definitions: ${escape_html(instance.qualityDefinitionsConfigName)}`);
                    },
                    $$slots: { default: true }
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                if (instance.mediaSettingsConfigName) {
                  $$renderer4.push("<!--[0-->");
                  Label($$renderer4, {
                    variant: "secondary",
                    size: "sm",
                    rounded: "md",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->Media Settings: ${escape_html(instance.mediaSettingsConfigName)}`);
                    },
                    $$slots: { default: true }
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--></div>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<span class="ml-1 text-xs text-neutral-400 dark:text-neutral-500">None</span>`);
              }
              $$renderer4.push(`<!--]--></div></div>`);
            },
            $$slots: {
              default: true,
              header: ($$renderer4) => {
                $$renderer4.push(`<div class="flex items-center justify-between gap-2"><div class="flex min-w-0 items-center gap-2"><div class="relative h-6 w-6 flex-shrink-0">`);
                if (!loadedImages.has(instance.id)) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="absolute inset-0 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> <img${attr("src", getLogoPath(instance.type))}${attr("alt", `${instance.type} logo`)}${attr_class(`h-6 w-6 rounded ${loadedImages.has(instance.id) ? "opacity-100" : "opacity-0"}`)} onload="this.__e=event" onerror="this.__e=event"/></div> <h3 class="truncate text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(instance.name)}</h3></div> <div class="flex shrink-0 items-center gap-0.5">`);
                Button($$renderer4, {
                  icon: External_link,
                  size: "xs",
                  variant: "ghost",
                  tooltip: `Open in ${stringify(formatType(instance.type))}`
                });
                $$renderer4.push(`<!----> `);
                Button($$renderer4, {
                  icon: Unlink,
                  size: "xs",
                  variant: "ghost",
                  iconColor: "text-red-600 dark:text-red-400",
                  tooltip: "Unlink instance"
                });
                $$renderer4.push(`<!----></div></div>`);
              },
              footer: ($$renderer4) => {
                $$renderer4.push(`<div class="flex flex-col items-start gap-1.5 text-xs text-neutral-600 sm:flex-row sm:items-center sm:gap-3 dark:text-neutral-400"><div class="flex items-center gap-1">`);
                Circle_arrow_up($$renderer4, {
                  size: 12,
                  class: "text-amber-500 dark:text-amber-400"
                });
                $$renderer4.push(`<!----> <span>Upgrades: ${escape_html(instance.upgradeEnabled ? "On" : "Off")}</span></div> <span class="hidden text-neutral-300 sm:inline dark:text-neutral-600">\xB7</span> <div class="flex items-center gap-1">`);
                Type($$renderer4, {
                  size: 12,
                  class: "text-blue-500 dark:text-blue-400"
                });
                $$renderer4.push(`<!----> <span>Renames: ${escape_html(instance.renameEnabled ? "On" : "Off")}</span></div> <span class="hidden text-neutral-300 sm:inline dark:text-neutral-600">\xB7</span> <div class="flex items-center gap-1">`);
                Trash_2($$renderer4, {
                  size: 12,
                  class: "text-rose-500 dark:text-rose-400"
                });
                $$renderer4.push(`<!----> <span>Cleanup: ${escape_html(instance.cleanupEnabled ? "On" : "Off")}</span></div></div>`);
              }
            }
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    bind_props($$props, { instances });
  });
}
function _page2($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    const { search, view, filtered, setItems } = createDataPageStore(data.instances, {
      storageKey: "arrInstancesView",
      searchKeys: [
        "name",
        "url",
        "type"
      ]
    });
    let showDeleteModal = false;
    let showInfoModal = false;
    $: setItems(data.instances);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: "Arr" });
      $$renderer3.push(`<!----> `);
      if (data.instances.length === 0) {
        $$renderer3.push("<!--[0-->");
        EmptyState($$renderer3, {
          icon: Server2,
          title: "No Arr Instances",
          description: "Add a Radarr or Sonarr instance to get started.",
          buttonText: "Add Instance",
          buttonHref: "/arr/new",
          buttonIcon: Plus,
          onboarding: "arr-add"
        });
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<div class="space-y-6 px-4 pt-4 pb-8 md:px-8">`);
        ActionsBar($$renderer3, {
          children: ($$renderer4) => {
            SearchAction($$renderer4, {
              searchStore: search,
              placeholder: "Search instances..."
            });
            $$renderer4.push(`<!----> `);
            ActionButton($$renderer4, {
              icon: Plus,
              title: "Add Instance",
              onboarding: "arr-add"
            });
            $$renderer4.push(`<!----> `);
            ActionButton($$renderer4, {
              icon: Info,
              title: "Info"
            });
            $$renderer4.push(`<!----> `);
            ViewToggle($$renderer4, {
              get value() {
                return store_get($$store_subs ??= {}, "$view", view);
              },
              set value($$value) {
                store_set(view, $$value);
                $$settled = false;
              }
            });
            $$renderer4.push(`<!---->`);
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----> <div class="mt-6">`);
        if (store_get($$store_subs ??= {}, "$filtered", filtered).length === 0) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No instances match your search</p></div>`);
        } else if (store_get($$store_subs ??= {}, "$view", view) === "table") {
          $$renderer3.push("<!--[1-->");
          TableView($$renderer3, { instances: store_get($$store_subs ??= {}, "$filtered", filtered) });
        } else {
          $$renderer3.push("<!--[-1-->");
          CardView($$renderer3, { instances: store_get($$store_subs ??= {}, "$filtered", filtered) });
        }
        $$renderer3.push(`<!--]--></div></div>`);
      }
      $$renderer3.push(`<!--]--> `);
      Modal($$renderer3, {
        open: showDeleteModal,
        header: "Delete Instance",
        bodyMessage: `Are you sure you want to delete "undefined"? This action cannot be undone.`,
        confirmText: "Delete",
        cancelText: "Cancel",
        confirmDanger: true
      });
      $$renderer3.push(`<!----> <form method="POST" action="?/delete" class="hidden"><input type="hidden" name="id"${attr("value", "")}/></form> `);
      InfoModal($$renderer3, {
        header: "Arr Instances",
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">What are Arr Instances?</div> <div class="mt-1">Arr instances are your Radarr and Sonarr applications. Profilarr connects to these instances
				to sync quality profiles, custom formats, and other configurations.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Adding an Instance</div> <div class="mt-1">To add an instance, you'll need the URL and API key from your Radarr or Sonarr application.
				You can find the API key in Settings \u2192 General \u2192 Security.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Syncing</div> <div class="mt-1">Once connected, you can configure sync settings to push profiles and formats from your
				linked databases to each instance. Sync can be triggered manually, on a schedule, or
				automatically when changes are detected.</div></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte2 = __esm({
  "dist/build/server/entries/pages/arr/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Icon();
    init_circle_arrow_up();
    init_external_link();
    init_info();
    init_Button();
    init_plus();
    init_search();
    init_server22();
    init_ViewToggle();
    init_trash_2();
    init_unlink();
    init_store2();
    init_Label();
    init_Card();
    init_Sonarr2();
    init_navigation();
    init_Modal();
    init_forms();
    init_ActionsBar();
    init_ActionButton();
    init_InfoModal();
    init_PageMeta();
    init_EmptyState();
    init_Table();
    init_arrDisplayUrl();
    init_CardGrid();
    init_dataPage();
  }
});

// dist/build/server/nodes/9.js
var __exports10 = {};
__export(__exports10, {
  component: () => component9,
  fonts: () => fonts10,
  imports: () => imports10,
  index: () => index10,
  server: () => page_server_ts_exports3,
  server_id: () => server_id9,
  stylesheets: () => stylesheets10
});
var index10, component_cache9, component9, server_id9, imports10, stylesheets10, fonts10;
var init__10 = __esm({
  async "dist/build/server/nodes/9.js"() {
    "use strict";
    await init_page_server_ts3();
    index10 = 9;
    component9 = async () => component_cache9 ??= (await Promise.resolve().then(() => (init_page_svelte2(), page_svelte_exports2))).default;
    server_id9 = "src/routes/arr/+page.server.ts";
    imports10 = ["_app/immutable/nodes/9.ZfdoKy0U.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BMmWZGEU.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/CRKwypWu.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/VS2JNRG_.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/Dg15A-ry2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D_awjkBZ.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/BGwVTtPU.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js"];
    stylesheets10 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts10 = [];
  }
});

// dist/build/server/entries/pages/arr/_id_/_page.server.ts.js
var page_server_ts_exports4 = {};
__export(page_server_ts_exports4, {
  load: () => load10
});
var load10;
var init_page_server_ts4 = __esm({
  async "dist/build/server/entries/pages/arr/_id_/_page.server.ts.js"() {
    "use strict";
    await init_arrSync();
    init_exports();
    load10 = ({ params }) => {
      const id = parseInt(params.id || "", 10);
      const sync = arrSyncQueries.getFullSyncData(id);
      const hasSyncConfig = sync.qualityProfiles.selections.length > 0 || !!sync.delayProfiles.databaseId && !!sync.delayProfiles.profileName || !!sync.mediaManagement.namingDatabaseId || !!sync.mediaManagement.qualityDefinitionsDatabaseId || !!sync.mediaManagement.mediaSettingsDatabaseId;
      redirect(302, `/arr/${params.id}/${hasSyncConfig ? "library" : "sync"}`);
    };
  }
});

// dist/build/server/entries/pages/arr/_id_/_page.svelte.js
var page_svelte_exports3 = {};
__export(page_svelte_exports3, {
  default: () => _page3
});
function _page3($$renderer) {
  PageMeta($$renderer, { title: "Arr" });
}
var init_page_svelte3 = __esm({
  "dist/build/server/entries/pages/arr/_id_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_PageMeta();
  }
});

// dist/build/server/nodes/10.js
var __exports11 = {};
__export(__exports11, {
  component: () => component10,
  fonts: () => fonts11,
  imports: () => imports11,
  index: () => index11,
  server: () => page_server_ts_exports4,
  server_id: () => server_id10,
  stylesheets: () => stylesheets11
});
var index11, component_cache10, component10, server_id10, imports11, stylesheets11, fonts11;
var init__11 = __esm({
  async "dist/build/server/nodes/10.js"() {
    "use strict";
    await init_page_server_ts4();
    index11 = 10;
    component10 = async () => component_cache10 ??= (await Promise.resolve().then(() => (init_page_svelte3(), page_svelte_exports3))).default;
    server_id10 = "src/routes/arr/[id]/+page.server.ts";
    imports11 = ["_app/immutable/nodes/10.1C6wttyN.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets11 = [];
    fonts11 = [];
  }
});

// dist/build/server/entries/pages/arr/_id_/drift/_page.server.ts.js
var page_server_ts_exports5 = {};
__export(page_server_ts_exports5, {
  actions: () => actions3,
  load: () => load11
});
var load11, actions3;
var init_page_server_ts5 = __esm({
  async "dist/build/server/entries/pages/arr/_id_/drift/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_display();
    await init_queueService();
    await init_arrDriftStatus();
    init_features();
    await init_init();
    init_exports();
    load11 = async ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (isNaN(id)) error(404, `Invalid instance ID: ${params.id}`);
      const instance = arrInstancesQueries.getById(id);
      if (!instance) error(404, `Instance not found: ${id}`);
      const driftSettings = arrDriftSettingsQueries.getByInstanceId(id);
      const driftStatus = arrDriftStatusQueries.getByInstanceId(id);
      const { api_key: _3, ...safeInstance } = instance;
      const diff = driftStatus?.diff ?? {};
      const driftEntities = await buildDriftDisplayEntitiesForInstance(diff, instance.type, id);
      const duplicateDriftCount = driftEntities.filter((entity) => entity.duplicateDrift).length;
      return {
        instance: safeInstance,
        featureEnabled: FEATURES.drift,
        settings: {
          enabled: driftSettings?.enabled ?? false,
          cron: driftSettings?.cron ?? "0 0 * * *",
          nextRunAt: driftSettings?.nextRunAt ?? null
        },
        status: {
          status: driftStatus?.status ?? "never_checked",
          lastCheckedAt: driftStatus?.lastCheckedAt ?? null,
          lastError: driftStatus?.lastError ?? null
        },
        driftEntities,
        driftView: {
          duplicateDriftCount,
          hasDuplicateDrift: duplicateDriftCount > 0
        }
      };
    };
    actions3 = {
      save: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        if (!FEATURES.drift) return fail(404, { error: "Drift detection is not available" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        const formData = await request.formData();
        const enabled3 = formData.get("enabled") === "true";
        const cron = (formData.get("cron") || "0 0 * * *").trim();
        const cronError = enabled3 ? validateCronExpression(cron, 10) : null;
        if (cronError) return fail(400, { error: cronError });
        const nextRunAt = enabled3 ? calculateNextRun(cron) : null;
        if (enabled3 && !nextRunAt) return fail(400, { error: "Invalid drift schedule" });
        try {
          arrDriftSettingsQueries.upsert(id, {
            enabled: enabled3,
            cron,
            nextRunAt
          });
          scheduleDriftForInstance(id);
          await logger.info(`Drift detection settings saved for "${instance.name}"`, {
            source: "drift",
            meta: {
              instanceId: id,
              enabled: enabled3
            }
          });
          return {
            success: true,
            nextRunAt
          };
        } catch (err) {
          await logger.error("Failed to save drift detection settings", {
            source: "drift",
            meta: {
              instanceId: id,
              error: err
            }
          });
          return fail(500, { error: "Failed to save drift detection settings" });
        }
      },
      run: async ({ params }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        if (!FEATURES.drift) return fail(404, { error: "Drift detection is not available" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        const settings2 = arrDriftSettingsQueries.getByInstanceId(id);
        if (!settings2 || !settings2.enabled) return fail(400, { error: "Drift detection is disabled" });
        try {
          const queued = enqueueJob({
            jobType: "arr.drift",
            runAt: (/* @__PURE__ */ new Date()).toISOString(),
            payload: { instanceId: id },
            source: "manual"
          });
          await logger.info("Manual drift check queued", {
            source: "drift",
            meta: {
              jobId: queued.id,
              instanceId: id,
              instanceName: instance.name,
              displayName: buildJobDisplayName("arr.drift", { instanceId: id })
            }
          });
          return {
            success: true,
            queued: true
          };
        } catch (err) {
          await logger.error("Manual drift check failed", {
            source: "drift",
            meta: {
              instanceId: id,
              error: err
            }
          });
          return fail(500, { error: "Failed to queue drift check" });
        }
      }
    };
  }
});

// dist/build/server/chunks/play.js
function Play($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "play" },
    props,
    { iconNode: [["path", { "d": "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z" }]] }
  ]));
}
var init_play = __esm({
  "dist/build/server/chunks/play.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/save.js
function Save($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "save" },
    props,
    { iconNode: [
      ["path", { "d": "M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z" }],
      ["path", { "d": "M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7" }],
      ["path", { "d": "M7 3v4a1 1 0 0 0 1 1h7" }]
    ] }
  ]));
}
var init_save = __esm({
  "dist/build/server/chunks/save.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/StickyCard.js
function StickyCard($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let bgClass, hasBreadcrumb, stickyPositionClass;
    let position = fallback($$props["position"], "top");
    let variant = fallback($$props["variant"], "default");
    let breadcrumbItems = fallback($$props["breadcrumbItems"], () => [], true);
    let breadcrumbCurrent = fallback($$props["breadcrumbCurrent"], "");
    let stickyBreadcrumb = fallback($$props["stickyBreadcrumb"], true);
    $: bgClass = variant === "default" ? "bg-neutral-50 dark:bg-neutral-900" : variant === "blur" ? "backdrop-blur-sm bg-neutral-50/50 dark:bg-neutral-900/50" : "";
    $: hasBreadcrumb = breadcrumbItems.length > 0;
    $: stickyPositionClass = position === "bottom" ? "bottom-0" : hasBreadcrumb && !stickyBreadcrumb ? "top-[-37px]" : "top-0";
    $$renderer2.push(`<div${attr_class(`sticky z-10 -mx-4 md:-mx-8 ${stringify(bgClass)} ${stringify(stickyPositionClass)}`)}>`);
    if (hasBreadcrumb) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="px-4 py-2 md:px-12">`);
      Breadcrumb($$renderer2, {
        items: breadcrumbItems,
        current: breadcrumbCurrent
      });
      $$renderer2.push(`<!----></div> <div class="mx-4 border-b border-neutral-200 md:mx-8 dark:border-neutral-800"></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div class="px-4 py-3 md:px-12 md:py-4"><div class="flex flex-col gap-3 md:flex-row md:items-center md:justify-between md:gap-4"><div class="min-w-0 [&amp;_h1]:text-base [&amp;_h1]:font-semibold [&amp;_h1]:md:text-xl [&amp;_p]:text-xs [&amp;_p]:md:text-sm"><!--[-->`);
    slot($$renderer2, $$props, "left", {}, null);
    $$renderer2.push(`<!--]--></div> <div class="border-t border-neutral-200 pt-3 md:border-0 md:pt-0 dark:border-neutral-800"><div class="flex flex-shrink-0 flex-wrap items-center gap-2"><!--[-->`);
    slot($$renderer2, $$props, "right", {}, null);
    $$renderer2.push(`<!--]--></div></div></div></div> `);
    if (variant === "default") {
      $$renderer2.push("<!--[0-->");
      if (position === "top") {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="mx-4 border-b border-neutral-200 md:mx-8 dark:border-neutral-800"></div>`);
      } else {
        $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<div class="mx-4 border-t border-neutral-200 md:mx-8 dark:border-neutral-800"></div>`);
      }
      $$renderer2.push(`<!--]-->`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, {
      position,
      variant,
      breadcrumbItems,
      breadcrumbCurrent,
      stickyBreadcrumb
    });
  });
}
var init_StickyCard = __esm({
  "dist/build/server/chunks/StickyCard.js"() {
    "use strict";
    init_server();
    init_Breadcrumb();
  }
});

// dist/build/server/chunks/DropdownSelect.js
function DropdownSelect($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let matchedOption, currentIcon, currentLabel, isPlaceholder, isCompactButton, resolvedButtonSize, resolvedJustify, chevronIcon, labelClasses;
    let label = fallback($$props["label"], void 0);
    let value2 = $$props["value"];
    let options2 = $$props["options"];
    let placeholder = fallback($$props["placeholder"], "Select...");
    let minWidth = fallback($$props["minWidth"], "8rem");
    let position = fallback($$props["position"], "left");
    let mobilePosition = fallback($$props["mobilePosition"], null);
    let placement = fallback($$props["placement"], "auto");
    let compact2 = fallback($$props["compact"], false);
    let compactButton = fallback($$props["compactButton"], void 0);
    let compactDropdown = fallback($$props["compactDropdown"], void 0);
    let compactDropdownThreshold = fallback($$props["compactDropdownThreshold"], 0);
    let responsiveButton = fallback($$props["responsiveButton"], false);
    let responsiveDropdown = fallback($$props["responsiveDropdown"], false);
    let mobileDropdownShortLabels = fallback($$props["mobileDropdownShortLabels"], false);
    let fullWidth = fallback($$props["fullWidth"], false);
    let fixed = fallback($$props["fixed"], false);
    let width = fallback($$props["width"], void 0);
    let justify = fallback($$props["justify"], null);
    let disabled = fallback($$props["disabled"], false);
    let buttonSize = fallback($$props["buttonSize"], null);
    let menuOnboarding = fallback($$props["menuOnboarding"], void 0);
    createEventDispatcher();
    let isSmallScreen = false;
    onDestroy(() => {
    });
    $: matchedOption = options2.find((o) => o.value === value2);
    $: currentIcon = matchedOption?.icon ?? null;
    $: currentLabel = matchedOption?.shortLabel ? matchedOption.shortLabel : matchedOption?.label || placeholder;
    $: isPlaceholder = !matchedOption;
    $: isCompactButton = compactButton ?? (responsiveButton ? isSmallScreen : compact2);
    $: compactDropdown !== void 0 || compactDropdownThreshold > 0 && options2.length;
    $: resolvedButtonSize = buttonSize ?? (isCompactButton ? "xs" : "sm");
    $: resolvedJustify = justify ?? (fullWidth || width ? "between" : "center");
    $: chevronIcon = Chevron_down;
    $: labelClasses = isCompactButton ? "text-xs text-neutral-500 dark:text-neutral-400" : "text-sm text-neutral-500 dark:text-neutral-400";
    $$renderer2.push(`<div${attr_class(`flex items-center gap-2 ${stringify(width ?? "")}`, void 0, { "w-full": fullWidth && !width })}>`);
    if (label) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span${attr_class(clsx(labelClasses))}>${escape_html(label)}</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div${attr_class("relative", void 0, { "flex-1": fullWidth })}>`);
    Button($$renderer2, {
      text: currentLabel,
      icon: chevronIcon,
      iconPosition: "right",
      leadingIcon: currentIcon,
      size: resolvedButtonSize,
      fullWidth,
      disabled,
      justify: resolvedJustify,
      textColor: isPlaceholder ? "text-neutral-400 dark:text-neutral-500" : ""
    });
    $$renderer2.push(`<!----> `);
    $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div></div>`);
    bind_props($$props, {
      label,
      value: value2,
      options: options2,
      placeholder,
      minWidth,
      position,
      mobilePosition,
      placement,
      compact: compact2,
      compactButton,
      compactDropdown,
      compactDropdownThreshold,
      responsiveButton,
      responsiveDropdown,
      mobileDropdownShortLabels,
      fullWidth,
      fixed,
      width,
      justify,
      disabled,
      buttonSize,
      menuOnboarding
    });
  });
}
var init_DropdownSelect = __esm({
  "dist/build/server/chunks/DropdownSelect.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Dropdown();
    init_chevron_down();
    init_Button();
    init_DropdownItem();
  }
});

// dist/build/server/chunks/FormInput.js
function FormInput($$renderer, $$props) {
  const $$slots = sanitize_slots($$props);
  $$renderer.component(($$renderer2) => {
    let fontClass, pickerClass, stateClass, containerClass, hasSuffix, inputType, effectiveSize, effectiveAutoWidth, sizeClasses, privatePaddingClass, widthClass, autoWidthPadding, autoWidthCharacters, autoWidthStyle;
    let label = $$props["label"];
    let description = fallback($$props["description"], "");
    let placeholder = fallback($$props["placeholder"], "");
    let value2 = fallback($$props["value"], "");
    let textarea = fallback($$props["textarea"], false);
    let rows = fallback($$props["rows"], 6);
    let type = fallback($$props["type"], "text");
    let required = fallback($$props["required"], false);
    let hideLabel = fallback($$props["hideLabel"], false);
    let name = fallback($$props["name"], "");
    let autocomplete = fallback($$props["autocomplete"], "");
    let private_ = fallback($$props["private_"], false);
    let readonly = fallback($$props["readonly"], false);
    let mono = fallback($$props["mono"], false);
    let disabled = fallback($$props["disabled"], false);
    let wrap = fallback($$props["wrap"], false);
    let size = fallback($$props["size"], "md");
    let responsive = fallback($$props["responsive"], false);
    let autoWidth = fallback($$props["autoWidth"], false);
    let inputClass = fallback($$props["inputClass"], "");
    let inputElement = fallback($$props["inputElement"], null);
    let lowercase = fallback($$props["lowercase"], false);
    createEventDispatcher();
    let isSmallScreen = false;
    onDestroy(() => {
    });
    $: fontClass = mono ? "font-mono" : "";
    $: pickerClass = type === "time" || type === "date" ? "dark:[color-scheme:dark]" : "";
    $: stateClass = readonly || disabled ? "bg-neutral-100 text-neutral-500 cursor-not-allowed dark:bg-neutral-800/40 dark:text-neutral-500" : "bg-white focus:border-neutral-400 dark:bg-neutral-800/50 dark:focus:border-neutral-600";
    $: containerClass = hideLabel && !description ? "space-y-0" : "space-y-2";
    $: hasSuffix = !!$$slots.suffix;
    $: inputType = private_ ? "password" : type;
    $: effectiveSize = size;
    $: effectiveAutoWidth = autoWidth && (!responsive || isSmallScreen);
    $: sizeClasses = {
      sm: "rounded-lg px-2 py-1 text-xs",
      md: "rounded-xl px-3 py-2 text-sm",
      lg: "rounded-xl px-4 py-2.5 text-base"
    }[effectiveSize];
    $: privatePaddingClass = hasSuffix ? "pr-16" : "pr-10";
    $: widthClass = effectiveAutoWidth ? "w-auto" : "w-full";
    $: autoWidthPadding = effectiveSize === "sm" ? "1.75rem" : effectiveSize === "lg" ? "2.75rem" : "2.25rem";
    $: autoWidthCharacters = Math.max(value2?.length ?? 0, placeholder.length, 1);
    $: autoWidthStyle = effectiveAutoWidth ? `width: calc(${autoWidthCharacters}ch + ${autoWidthPadding});` : void 0;
    $$renderer2.push(`<div${attr_class(clsx(containerClass))}><label${attr("for", name)}${attr_class(`block text-sm font-medium text-neutral-900 dark:text-neutral-100 ${hideLabel ? "sr-only" : ""}`)}>${escape_html(label)}`);
    if (required) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span class="text-red-500">*</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></label> `);
    if (description) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<p class="text-xs text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (textarea) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div${attr_class(clsx(hasSuffix ? "relative" : ""))}><textarea${attr("id", name)}${attr("name", name)}${attr("placeholder", placeholder)}${attr("required", required, true)}${attr("disabled", disabled, true)}${attr("readonly", readonly, true)}${attr("rows", rows)}${attr_class(`block w-full resize-none border border-neutral-300 text-neutral-900 placeholder-neutral-400 transition-colors focus:border-neutral-300 focus:outline-none dark:border-neutral-700/60 dark:text-neutral-50 dark:placeholder-neutral-500 dark:focus:border-neutral-600 ${stringify(sizeClasses)} ${stringify(fontClass)} ${stringify(pickerClass)} ${stringify(stateClass)} ${stringify(inputClass)} ${hasSuffix ? "pr-10" : ""}`)}>`);
      const $$body = escape_html(value2);
      if ($$body) $$renderer2.push(`${$$body}`);
      $$renderer2.push(`</textarea> `);
      if (hasSuffix) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="absolute top-3 right-3"><!--[-->`);
        slot($$renderer2, $$props, "suffix", {}, null);
        $$renderer2.push(`<!--]--></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div>`);
    } else if (private_) {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<div class="relative"><input${attr("id", name)}${attr("name", name)}${attr("type", inputType)}${attr("value", value2)}${attr("placeholder", placeholder)}${attr("required", required, true)}${attr("disabled", disabled, true)}${attr("readonly", readonly, true)}${attr("autocomplete", autocomplete ? autocomplete : void 0)}${attr_style(autoWidthStyle)}${attr_class(`block ${stringify(widthClass)} border border-neutral-300 text-neutral-900 placeholder-neutral-400 transition-colors focus:outline-none dark:border-neutral-700/60 dark:text-neutral-50 dark:placeholder-neutral-500 ${stringify(sizeClasses)} ${stringify(fontClass)} ${stringify(pickerClass)} ${stringify(stateClass)} ${stringify(inputClass)} ${stringify(privatePaddingClass)} tracking-[0.25em] placeholder:tracking-normal`)}/> `);
      if (hasSuffix) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="absolute top-1/2 right-10 -translate-y-1/2"><!--[-->`);
        slot($$renderer2, $$props, "suffix", {}, null);
        $$renderer2.push(`<!--]--></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> <button type="button" class="absolute top-1/2 right-3 -translate-y-1/2 text-neutral-400 hover:text-neutral-600 dark:text-neutral-500 dark:hover:text-neutral-300">`);
      $$renderer2.push("<!--[-1-->");
      Eye($$renderer2, { size: 18 });
      $$renderer2.push(`<!--]--></button></div>`);
    } else if (wrap) {
      $$renderer2.push("<!--[2-->");
      $$renderer2.push(`<div${attr_class(clsx(hasSuffix ? "relative" : ""))}><textarea${attr("id", name)}${attr("name", name)}${attr("placeholder", placeholder)}${attr("required", required, true)}${attr("disabled", disabled, true)}${attr("readonly", readonly, true)}${attr("rows", 1)}${attr_class(`block w-full resize-none overflow-hidden border border-neutral-300 text-neutral-900 placeholder-neutral-400 transition-colors focus:outline-none dark:border-neutral-700/60 dark:text-neutral-50 dark:placeholder-neutral-500 ${stringify(sizeClasses)} ${stringify(fontClass)} ${stringify(pickerClass)} ${stringify(stateClass)} ${stringify(inputClass)} ${hasSuffix ? "pr-10" : ""}`)}>`);
      const $$body_1 = escape_html(value2);
      if ($$body_1) $$renderer2.push(`${$$body_1}`);
      $$renderer2.push(`</textarea> `);
      if (hasSuffix) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="absolute top-3 right-3"><!--[-->`);
        slot($$renderer2, $$props, "suffix", {}, null);
        $$renderer2.push(`<!--]--></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div${attr_class(clsx(hasSuffix ? "relative" : ""))}><input${attr("id", name)}${attr("name", name)}${attr("type", type)}${attr("value", value2)}${attr("placeholder", placeholder)}${attr("required", required, true)}${attr("disabled", disabled, true)}${attr("readonly", readonly, true)}${attr("autocomplete", autocomplete ? autocomplete : void 0)}${attr_style(autoWidthStyle)}${attr_class(`block ${stringify(widthClass)} border border-neutral-300 text-neutral-900 placeholder-neutral-400 transition-colors focus:outline-none dark:border-neutral-700/60 dark:text-neutral-50 dark:placeholder-neutral-500 ${stringify(sizeClasses)} ${stringify(fontClass)} ${stringify(pickerClass)} ${stringify(stateClass)} ${stringify(inputClass)} ${hasSuffix ? "pr-10" : ""}`)}/> `);
      if (hasSuffix) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="absolute top-1/2 right-3 -translate-y-1/2"><!--[-->`);
        slot($$renderer2, $$props, "suffix", {}, null);
        $$renderer2.push(`<!--]--></div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div>`);
    }
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, {
      label,
      description,
      placeholder,
      value: value2,
      textarea,
      rows,
      type,
      required,
      hideLabel,
      name,
      autocomplete,
      private_,
      readonly,
      mono,
      disabled,
      wrap,
      size,
      responsive,
      autoWidth,
      inputClass,
      inputElement,
      lowercase
    });
  });
}
var init_FormInput = __esm({
  "dist/build/server/chunks/FormInput.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_eye();
    init_store2();
  }
});

// dist/build/server/chunks/circle-alert.js
function Circle_alert($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "circle-alert" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "12",
        "cy": "12",
        "r": "10"
      }],
      ["line", {
        "x1": "12",
        "x2": "12",
        "y1": "8",
        "y2": "12"
      }],
      ["line", {
        "x1": "12",
        "x2": "12.01",
        "y1": "16",
        "y2": "16"
      }]
    ] }
  ]));
}
var init_circle_alert = __esm({
  "dist/build/server/chunks/circle-alert.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/NumberInput.js
function NumberInput($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let isCompact, hideButtons, effectiveAutoWidth, fontClass, warningPaddingClass, inputSizeClasses, buttonWidthClass, iconSize, warningRightClass, buttonTopRadius, buttonBottomRadius, widthClass, autoWidthPadding, autoWidthCharacters, autoWidthStyle, stepDecimals, normalizedMaxDecimals, effectiveMaxDecimals, allowDecimals, hasInvalidDraft, inputStateClass, canIncrement, canDecrement, incrementDisabled, decrementDisabled;
    createEventDispatcher();
    let name = $$props["name"];
    let id = fallback($$props["id"], name);
    let value2 = fallback($$props["value"], void 0);
    let min = fallback($$props["min"], void 0);
    let max = fallback($$props["max"], void 0);
    let step = fallback($$props["step"], 1);
    let maxDecimals = fallback($$props["maxDecimals"], void 0);
    let emptyStepValue = fallback($$props["emptyStepValue"], void 0);
    let required = fallback($$props["required"], false);
    let disabled = fallback($$props["disabled"], false);
    let warningTooltip = fallback($$props["warningTooltip"], "");
    let placeholder = fallback($$props["placeholder"], "");
    let font = fallback($$props["font"], void 0);
    let compact2 = fallback($$props["compact"], false);
    let validateOn = fallback($$props["validateOn"], "input");
    let responsive = fallback($$props["responsive"], false);
    let autoWidth = fallback($$props["autoWidth"], false);
    let onchange = fallback($$props["onchange"], void 0);
    let onMinBlocked = fallback($$props["onMinBlocked"], void 0);
    let onMaxBlocked = fallback($$props["onMaxBlocked"], void 0);
    const ignoreClickResetDelayMs = 100;
    let inputValue = value2 === void 0 || value2 === null ? "" : String(value2);
    let isFocused = false;
    let isSmallScreen = false;
    let repeatTimeout = null;
    let ignoreClickResetTimeout = null;
    let ignoreNextClick = false;
    let inputMode = "numeric";
    onDestroy(() => {
      clearStepRepeat();
      clearIgnoredClickReset();
    });
    function getDecimalPlaces(number) {
      if (!Number.isFinite(number)) return 0;
      const text2 = String(number);
      if (text2.includes("e-")) {
        const [, exponent] = text2.split("e-");
        return Number(exponent) || 0;
      }
      return text2.split(".")[1]?.length ?? 0;
    }
    function normalizeMaxDecimals(value3) {
      if (value3 === void 0 || !Number.isFinite(value3)) return void 0;
      return Math.max(0, Math.floor(value3));
    }
    function formatValue3(nextValue) {
      if (nextValue === void 0 || nextValue === null) return "";
      if (normalizedMaxDecimals !== void 0 || stepDecimals > 0) return String(roundToDecimals(nextValue, effectiveMaxDecimals));
      return String(nextValue);
    }
    function roundToDecimals(rawValue, decimals) {
      if (decimals <= 0) return Math.round(rawValue);
      const factor = 10 ** decimals;
      return Math.round((rawValue + Number.EPSILON) * factor) / factor;
    }
    function getDecimalLength(text2) {
      const [, decimals = ""] = text2.split(".");
      return decimals.length;
    }
    function isEmptyDraft(text2) {
      return text2 === "" || text2 === "-" || text2 === "." || text2 === "-.";
    }
    function isIncompleteDecimal(text2) {
      return allowDecimals && /^-?\d+\.$/.test(text2);
    }
    function getDraftState(text2) {
      if (text2 === "") return { status: "empty" };
      if (isEmptyDraft(text2) || isIncompleteDecimal(text2)) return { status: "partial" };
      if (!(allowDecimals ? /^-?(?:\d+|\d+\.\d+|\.\d+)$/ : /^-?\d+$/).test(text2)) return { status: "invalid" };
      if (allowDecimals && getDecimalLength(text2) > effectiveMaxDecimals) return { status: "invalid" };
      const rawValue = Number(text2);
      if (!Number.isFinite(rawValue)) return { status: "invalid" };
      return {
        status: "valid",
        value: rawValue
      };
    }
    function clearIgnoredClickReset() {
      if (ignoreClickResetTimeout) {
        clearTimeout(ignoreClickResetTimeout);
        ignoreClickResetTimeout = null;
      }
    }
    function clearStepRepeat() {
      if (repeatTimeout) {
        clearTimeout(repeatTimeout);
        repeatTimeout = null;
      }
      if (typeof window !== "undefined") {
        window.removeEventListener("pointerup", clearStepRepeat);
        window.removeEventListener("blur", clearStepRepeat);
      }
      if (ignoreNextClick && !ignoreClickResetTimeout) ignoreClickResetTimeout = setTimeout(() => {
        ignoreNextClick = false;
        ignoreClickResetTimeout = null;
      }, ignoreClickResetDelayMs);
    }
    $: isCompact = compact2 || responsive && isSmallScreen;
    $: hideButtons = responsive && isSmallScreen;
    $: effectiveAutoWidth = autoWidth && (!responsive || isSmallScreen);
    $: fontClass = font === "mono" ? "font-mono" : font === "sans" ? "font-sans" : "";
    $: warningPaddingClass = warningTooltip ? isCompact && hideButtons ? "pr-7" : "pr-16" : isCompact && hideButtons ? "pr-2" : isCompact ? "pr-7" : "pr-10";
    $: inputSizeClasses = isCompact ? hideButtons ? `rounded-lg py-1 pl-2 text-xs ${warningPaddingClass}` : `rounded-lg px-2 py-1 text-xs ${warningPaddingClass}` : `rounded-xl py-2 pl-3 text-sm ${warningPaddingClass}`;
    $: buttonWidthClass = isCompact ? "w-4" : "w-6";
    $: iconSize = isCompact ? 10 : 12;
    $: warningRightClass = warningTooltip && !hideButtons ? isCompact ? "right-6" : "right-8" : "right-2";
    $: buttonTopRadius = isCompact ? "rounded-tr-lg rounded-tl-none rounded-br-none rounded-bl-none" : "rounded-tr-xl rounded-tl-none rounded-br-none rounded-bl-none";
    $: buttonBottomRadius = isCompact ? "rounded-br-lg rounded-bl-none rounded-tr-none rounded-tl-none" : "rounded-br-xl rounded-bl-none rounded-tr-none rounded-tl-none";
    $: widthClass = effectiveAutoWidth ? "w-auto" : "w-full";
    $: autoWidthPadding = isCompact ? "1.75rem" : "4rem";
    $: inputValue = formatValue3(value2);
    $: autoWidthCharacters = Math.max(inputValue.length, placeholder.length, 1);
    $: autoWidthStyle = effectiveAutoWidth ? `width: calc(${autoWidthCharacters}ch + ${autoWidthPadding});` : void 0;
    $: stepDecimals = getDecimalPlaces(step);
    $: normalizedMaxDecimals = normalizeMaxDecimals(maxDecimals);
    $: effectiveMaxDecimals = normalizedMaxDecimals ?? stepDecimals;
    $: allowDecimals = effectiveMaxDecimals > 0;
    $: inputMode = allowDecimals ? "decimal" : "numeric";
    $: getDraftState(inputValue);
    $: hasInvalidDraft = isFocused;
    $: inputStateClass = hasInvalidDraft ? "border-red-500 bg-white focus:border-red-500 dark:border-red-500/70 dark:bg-neutral-800/50 dark:focus:border-red-400" : "border-neutral-300 bg-white focus:border-neutral-400 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:focus:border-neutral-600";
    $: canIncrement = max === void 0 || value2 === void 0 || value2 < max;
    $: canDecrement = min === void 0 || value2 === void 0 || value2 > min;
    $: incrementDisabled = disabled || !canIncrement;
    $: decrementDisabled = disabled || !canDecrement;
    $$renderer2.push(`<div class="relative"><input type="text"${attr("id", id)}${attr("name", name)}${attr("inputmode", inputMode)} role="spinbutton"${attr("aria-valuemin", min)}${attr("aria-valuemax", max)}${attr("aria-valuenow", value2)}${attr("aria-invalid", hasInvalidDraft ? "true" : void 0)}${attr("value", inputValue)}${attr("required", required, true)}${attr("disabled", disabled, true)}${attr("placeholder", placeholder)}${attr_style(autoWidthStyle)}${attr_class(`block ${stringify(widthClass)} border text-neutral-900 placeholder-neutral-400 transition-colors focus:outline-none disabled:cursor-not-allowed disabled:bg-neutral-100 disabled:text-neutral-500 dark:text-neutral-50 dark:placeholder-neutral-500 dark:disabled:bg-neutral-800/40 dark:disabled:text-neutral-500 ${stringify(inputSizeClasses)} ${stringify(fontClass)} ${stringify(inputStateClass)}`)}/> `);
    if (warningTooltip) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div${attr_class(`absolute top-1/2 z-10 -translate-y-1/2 ${stringify(warningRightClass)}`)}>`);
      Tooltip($$renderer2, {
        text: warningTooltip,
        position: "top",
        children: ($$renderer3) => {
          $$renderer3.push(`<span class="inline-flex items-center text-red-600 dark:text-red-400">`);
          Circle_alert($$renderer3, { size: isCompact ? 12 : 14 });
          $$renderer3.push(`<!----></span>`);
        },
        $$slots: { default: true }
      });
      $$renderer2.push(`<!----></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (!hideButtons) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="absolute top-0 right-0 bottom-0 flex flex-col"><button type="button"${attr("disabled", incrementDisabled, true)}${attr_class(`flex flex-1 ${stringify(buttonWidthClass)} cursor-pointer items-center justify-center ${stringify(buttonTopRadius)} border border-neutral-300 bg-white text-neutral-600 transition-colors hover:bg-neutral-50 disabled:cursor-not-allowed disabled:opacity-40 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-300 dark:hover:bg-neutral-800`)}>`);
      Chevron_up($$renderer2, { size: iconSize });
      $$renderer2.push(`<!----></button> <button type="button"${attr("disabled", decrementDisabled, true)}${attr_class(`flex flex-1 ${stringify(buttonWidthClass)} cursor-pointer items-center justify-center ${stringify(buttonBottomRadius)} border border-t-0 border-neutral-300 bg-white text-neutral-600 transition-colors hover:bg-neutral-50 disabled:cursor-not-allowed disabled:opacity-40 dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-300 dark:hover:bg-neutral-800`)}>`);
      Chevron_down($$renderer2, { size: iconSize });
      $$renderer2.push(`<!----></button></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, {
      name,
      id,
      value: value2,
      min,
      max,
      step,
      maxDecimals,
      emptyStepValue,
      required,
      disabled,
      warningTooltip,
      placeholder,
      font,
      compact: compact2,
      validateOn,
      responsive,
      autoWidth,
      onchange,
      onMinBlocked,
      onMaxBlocked
    });
  });
}
var init_NumberInput = __esm({
  "dist/build/server/chunks/NumberInput.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_chevron_down();
    init_chevron_up();
    init_circle_alert();
    init_Button();
  }
});

// dist/build/server/chunks/DropdownCombobox.js
function DropdownCombobox($$renderer, $$props) {
  sanitize_slots($$props);
  $$renderer.component(($$renderer2) => {
    let matchedOption, currentIcon, currentLabel, isPlaceholder, isCompactButton, resolvedButtonSize, resolvedJustify, chevronIcon, labelClasses;
    let label = fallback($$props["label"], void 0);
    let value2 = fallback($$props["value"], null);
    let options2 = fallback($$props["options"], () => [], true);
    let placeholder = fallback($$props["placeholder"], "Select...");
    let limit = fallback($$props["limit"], null);
    let minWidth = fallback($$props["minWidth"], "12rem");
    let position = fallback($$props["position"], "left");
    let mobilePosition = fallback($$props["mobilePosition"], null);
    let placement = fallback($$props["placement"], "auto");
    let compact2 = fallback($$props["compact"], false);
    let compactButton = fallback($$props["compactButton"], void 0);
    let compactDropdown = fallback($$props["compactDropdown"], void 0);
    let compactDropdownThreshold = fallback($$props["compactDropdownThreshold"], 0);
    let responsiveButton = fallback($$props["responsiveButton"], false);
    let responsiveDropdown = fallback($$props["responsiveDropdown"], false);
    let fullWidth = fallback($$props["fullWidth"], false);
    let fixed = fallback($$props["fixed"], false);
    let width = fallback($$props["width"], void 0);
    let dropdownWidth = fallback($$props["dropdownWidth"], void 0);
    let justify = fallback($$props["justify"], null);
    let disabled = fallback($$props["disabled"], false);
    let buttonSize = fallback($$props["buttonSize"], null);
    let clearable = fallback($$props["clearable"], false);
    createEventDispatcher();
    let query = "";
    let isSmallScreen = false;
    onDestroy(() => {
    });
    $: matchedOption = options2.find((o) => o.value === value2) ?? null;
    $: currentIcon = matchedOption?.icon ?? null;
    $: currentLabel = matchedOption?.shortLabel ? matchedOption.shortLabel : matchedOption?.label ?? placeholder;
    $: isPlaceholder = !matchedOption;
    $: isCompactButton = compactButton ?? (responsiveButton ? isSmallScreen : compact2);
    $: compactDropdown !== void 0 || compactDropdownThreshold > 0 && options2.length;
    $: resolvedButtonSize = buttonSize ?? (isCompactButton ? "xs" : "sm");
    $: resolvedJustify = justify ?? "between";
    $: chevronIcon = Chevron_down;
    $: query.trim();
    $: limit != null && `${limit}`;
    $: labelClasses = isCompactButton ? "text-xs text-neutral-500 dark:text-neutral-400" : "text-sm text-neutral-500 dark:text-neutral-400";
    $$renderer2.push(`<div${attr_class(`flex items-center gap-2 ${stringify(width ?? "")}`, void 0, { "w-full": fullWidth && !width })}>`);
    if (label) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span${attr_class(clsx(labelClasses))}>${escape_html(label)}</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div${attr_class("relative", void 0, { "flex-1": fullWidth })}${attr_style(`min-width: ${stringify(minWidth)}`)}>`);
    $$renderer2.push("<!--[-1-->");
    Button($$renderer2, {
      text: currentLabel,
      icon: chevronIcon,
      iconPosition: "right",
      leadingIcon: currentIcon,
      size: resolvedButtonSize,
      fullWidth: true,
      disabled,
      justify: resolvedJustify,
      textColor: isPlaceholder ? "text-neutral-400 dark:text-neutral-500" : ""
    });
    $$renderer2.push(`<!--]--> `);
    $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div></div>`);
    bind_props($$props, {
      label,
      value: value2,
      options: options2,
      placeholder,
      limit,
      minWidth,
      position,
      mobilePosition,
      placement,
      compact: compact2,
      compactButton,
      compactDropdown,
      compactDropdownThreshold,
      responsiveButton,
      responsiveDropdown,
      fullWidth,
      fixed,
      width,
      dropdownWidth,
      justify,
      disabled,
      buttonSize,
      clearable
    });
  });
}
var init_DropdownCombobox = __esm({
  "dist/build/server/chunks/DropdownCombobox.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Dropdown();
    init_chevron_down();
    init_Button();
    init_DropdownItem();
  }
});

// dist/build/server/chunks/CronInput.js
function TimeInput($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let containerClass, fieldStyle;
    let label = $$props["label"];
    let description = fallback($$props["description"], "");
    let value2 = fallback($$props["value"], "");
    let required = fallback($$props["required"], false);
    let hideLabel = fallback($$props["hideLabel"], false);
    let name = fallback($$props["name"], "");
    let readonly = fallback($$props["readonly"], false);
    let disabled = fallback($$props["disabled"], false);
    let size = fallback($$props["size"], "md");
    let fieldWidthRem = fallback($$props["fieldWidthRem"], 5);
    let responsive = fallback($$props["responsive"], false);
    createEventDispatcher();
    let hour2 = "00";
    let minute2 = "00";
    let lastValue = "";
    let comboboxButtonSize;
    let responsiveButtonSize;
    const hourOptions = Array.from({ length: 24 }, (_3, idx) => {
      const value3 = String(idx).padStart(2, "0");
      return {
        value: value3,
        label: value3
      };
    });
    const minuteOptions = Array.from({ length: 60 }, (_3, idx) => {
      const value3 = String(idx).padStart(2, "0");
      return {
        value: value3,
        label: value3
      };
    });
    function parseValue(nextValue) {
      const [h, m3] = nextValue.split(":");
      if (h && m3 && /^\d+$/.test(h) && /^\d+$/.test(m3)) {
        hour2 = String(Math.min(Math.max(parseInt(h, 10), 0), 23)).padStart(2, "0");
        minute2 = String(Math.min(Math.max(parseInt(m3, 10), 0), 59)).padStart(2, "0");
        return;
      }
      hour2 = "00";
      minute2 = "00";
    }
    $: containerClass = hideLabel && !description ? "space-y-0" : "space-y-2";
    $: fieldStyle = `width: ${fieldWidthRem}rem;`;
    $: comboboxButtonSize = size === "sm" ? "xs" : size === "lg" ? "md" : "sm";
    $: responsiveButtonSize = responsive ? null : comboboxButtonSize;
    $: if (value2 !== lastValue) {
      parseValue(value2);
      lastValue = value2;
    }
    $$renderer2.push(`<div${attr_class(`${containerClass} inline-flex flex-col`)}>`);
    if (!hideLabel) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<label${attr("for", name)} class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(label)}`);
      if (required) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<span class="text-red-500">*</span>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></label>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (description) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<p class="text-xs text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div class="flex items-center gap-1.5"><div class="shrink-0"${attr_style(fieldStyle)}>`);
    DropdownCombobox($$renderer2, {
      value: hour2,
      options: hourOptions,
      placeholder: "Hour",
      minWidth: "0",
      width: "w-full",
      buttonSize: responsiveButtonSize,
      limit: 6,
      responsiveButton: responsive,
      responsiveDropdown: responsive,
      compactDropdownThreshold: 7,
      disabled: disabled || readonly,
      fullWidth: true
    });
    $$renderer2.push(`<!----></div> <span class="text-sm text-neutral-500 dark:text-neutral-400">:</span> <div class="shrink-0"${attr_style(fieldStyle)}>`);
    DropdownCombobox($$renderer2, {
      value: minute2,
      options: minuteOptions,
      placeholder: "Minute",
      minWidth: "0",
      width: "w-full",
      buttonSize: responsiveButtonSize,
      limit: 6,
      responsiveButton: responsive,
      responsiveDropdown: responsive,
      compactDropdownThreshold: 7,
      disabled: disabled || readonly,
      fullWidth: true
    });
    $$renderer2.push(`<!----></div></div></div>`);
    bind_props($$props, {
      label,
      description,
      value: value2,
      required,
      hideLabel,
      name,
      readonly,
      disabled,
      size,
      fieldWidthRem,
      responsive
    });
  });
}
function CronInput($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let everyMin;
    let value2 = fallback($$props["value"], "0 * * * *");
    let disabled = fallback($$props["disabled"], false);
    let fixed = fallback($$props["fixed"], false);
    let minIntervalMinutes = fallback($$props["minIntervalMinutes"], 0);
    let onWarning = fallback($$props["onWarning"], void 0);
    let scheduleType = "hourly";
    let intervalMinutes = 30;
    let hourlyMinute = 0;
    let dailyTime = "03:00";
    let weeklyDay = 1;
    let weeklyTime = "03:00";
    let monthlyDay = 1;
    let monthlyTime = "03:00";
    let customCron = value2;
    let lastParsedValue = "";
    let cronError = null;
    const dayOptions = [
      {
        value: 0,
        label: "Sun"
      },
      {
        value: 1,
        label: "Mon"
      },
      {
        value: 2,
        label: "Tue"
      },
      {
        value: 3,
        label: "Wed"
      },
      {
        value: 4,
        label: "Thu"
      },
      {
        value: 5,
        label: "Fri"
      },
      {
        value: 6,
        label: "Sat"
      }
    ];
    const scheduleOptions = [
      {
        value: "every",
        label: "Every"
      },
      {
        value: "hourly",
        label: "Hourly"
      },
      {
        value: "daily",
        label: "Daily"
      },
      {
        value: "weekly",
        label: "Weekly"
      },
      {
        value: "monthly",
        label: "Monthly"
      },
      {
        value: "custom",
        label: "Custom"
      }
    ];
    const weekdayOptions = dayOptions.map((day2) => ({
      value: String(day2.value),
      label: day2.label
    }));
    function parseTime(value3) {
      const [h, m3] = value3.split(":").map((part) => parseInt(part, 10));
      return {
        hour: Number.isFinite(h) ? Math.min(Math.max(h, 0), 23) : 0,
        minute: Number.isFinite(m3) ? Math.min(Math.max(m3, 0), 59) : 0
      };
    }
    function formatTime2(hour2, minute2) {
      return `${String(Math.min(Math.max(hour2, 0), 23)).padStart(2, "0")}:${String(Math.min(Math.max(minute2, 0), 59)).padStart(2, "0")}`;
    }
    function buildCronFromSimple() {
      if (scheduleType === "every") return `*/${Math.max(1, Math.min(intervalMinutes, 60))} * * * *`;
      if (scheduleType === "hourly") return `${Math.max(0, Math.min(hourlyMinute, 59))} * * * *`;
      if (scheduleType === "daily") {
        const { hour: hour3, minute: minute3 } = parseTime(dailyTime);
        return `${minute3} ${hour3} * * *`;
      }
      if (scheduleType === "weekly") {
        const { hour: hour3, minute: minute3 } = parseTime(weeklyTime);
        return `${minute3} ${hour3} * * ${weeklyDay}`;
      }
      const { hour: hour2, minute: minute2 } = parseTime(monthlyTime);
      return `${minute2} ${hour2} ${Math.max(1, Math.min(monthlyDay, 31))} * *`;
    }
    function parseSimple(cron) {
      const parts = cron.trim().split(/\s+/);
      if (parts.length === 6) parts.shift();
      if (parts.length !== 5) return false;
      const [minute2, hour2, dom, month, dow] = parts;
      if (month !== "*") return false;
      if (dom === "*" && dow === "*") {
        if (hour2 === "*" && minute2.startsWith("*/")) {
          const interval = parseInt(minute2.slice(2), 10);
          if (!Number.isFinite(interval) || interval <= 0) return false;
          scheduleType = "every";
          intervalMinutes = interval;
          return true;
        }
        if (hour2 === "*" && /^\d+$/.test(minute2)) {
          scheduleType = "hourly";
          hourlyMinute = parseInt(minute2, 10);
          return true;
        }
        if (/^\d+$/.test(minute2) && /^\d+$/.test(hour2)) {
          scheduleType = "daily";
          dailyTime = formatTime2(parseInt(hour2, 10), parseInt(minute2, 10));
          return true;
        }
      }
      if (dom === "*" && dow !== "*") {
        if (!/^\d+$/.test(minute2) || !/^\d+$/.test(hour2)) return false;
        const days = dow.split(",").map((part) => parseInt(part, 10)).filter((day2) => Number.isFinite(day2) && day2 >= 0 && day2 <= 6);
        if (days.length !== 1) return false;
        scheduleType = "weekly";
        weeklyDay = days[0];
        weeklyTime = formatTime2(parseInt(hour2, 10), parseInt(minute2, 10));
        return true;
      }
      if (dow === "*" && dom !== "*") {
        if (!/^\d+$/.test(minute2) || !/^\d+$/.test(hour2) || !/^\d+$/.test(dom)) return false;
        scheduleType = "monthly";
        monthlyTime = formatTime2(parseInt(hour2, 10), parseInt(minute2, 10));
        monthlyDay = parseInt(dom, 10);
        return true;
      }
      return false;
    }
    function validateMinInterval(expr) {
      if (minIntervalMinutes <= 0) return null;
      try {
        const cron = new E(expr);
        const now = /* @__PURE__ */ new Date();
        const runs = [];
        let cursor = now;
        for (let i = 0; i < 3; i++) {
          const next2 = cron.nextRun(cursor);
          if (!next2) break;
          runs.push(next2);
          cursor = new Date(next2.getTime() + 1e3);
        }
        if (runs.length < 2) return null;
        for (let i = 1; i < runs.length; i++) if ((runs[i].getTime() - runs[i - 1].getTime()) / 6e4 < minIntervalMinutes) return `Minimum interval is ${minIntervalMinutes} minutes`;
        return null;
      } catch {
        return null;
      }
    }
    function setValue(nextValue) {
      if (nextValue === value2) return;
      value2 = nextValue;
      lastParsedValue = nextValue;
    }
    function syncFromValue() {
      if (value2 === lastParsedValue) return;
      if (parseSimple(value2)) {
        customCron = value2;
        lastParsedValue = value2;
        return;
      }
      scheduleType = "custom";
      customCron = value2;
      lastParsedValue = value2;
    }
    function updateCron() {
      if (scheduleType === "custom") {
        setValue(customCron);
        return;
      }
      setValue(buildCronFromSimple());
    }
    $: if (value2 !== lastParsedValue) syncFromValue();
    $: if (scheduleType !== "custom") updateCron();
    $: everyMin = minIntervalMinutes > 0 ? Math.max(1, minIntervalMinutes) : 1;
    $: if (scheduleType === "every" && intervalMinutes < everyMin) {
      intervalMinutes = everyMin;
      updateCron();
    }
    $: cronError = (() => {
      if (scheduleType === "custom") {
        try {
          new E(customCron);
        } catch (error2) {
          return error2 instanceof Error ? error2.message : "Invalid cron expression";
        }
        return validateMinInterval(value2);
      }
      if (scheduleType === "every") {
        if (minIntervalMinutes <= 0) return null;
        if (intervalMinutes < minIntervalMinutes) return `Minimum interval is ${minIntervalMinutes} minutes`;
        return null;
      }
      return null;
    })();
    $$renderer2.push(`<div${attr_class("flex items-center gap-1.5 md:flex-nowrap", void 0, { "flex-wrap": scheduleType === "weekly" || scheduleType === "monthly" })}>`);
    DropdownSelect($$renderer2, {
      value: scheduleType,
      options: scheduleOptions,
      disabled,
      fixed,
      buttonSize: "sm",
      width: "w-24",
      justify: "center",
      responsiveDropdown: true
    });
    $$renderer2.push(`<!----> `);
    if (scheduleType === "every") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="w-24">`);
      NumberInput($$renderer2, {
        name: "cron-interval-minutes",
        value: intervalMinutes,
        min: everyMin,
        max: 60,
        step: 1,
        disabled,
        onMinBlocked: () => onWarning?.(`Minimum interval is ${everyMin} minutes`),
        onMaxBlocked: () => onWarning?.("Maximum interval is 60 minutes")
      });
      $$renderer2.push(`<!----></div> <span class="text-sm text-neutral-500 dark:text-neutral-400">minutes</span>`);
    } else if (scheduleType === "hourly") {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<span class="text-sm text-neutral-500 dark:text-neutral-400">at</span> <div class="w-24">`);
      NumberInput($$renderer2, {
        name: "cron-hourly-minute",
        value: hourlyMinute,
        min: 0,
        max: 59,
        step: 1,
        disabled
      });
      $$renderer2.push(`<!----></div> <span class="text-sm text-neutral-500 dark:text-neutral-400">min</span>`);
    } else if (scheduleType === "daily") {
      $$renderer2.push("<!--[2-->");
      TimeInput($$renderer2, {
        label: "Time",
        hideLabel: true,
        name: "cron-daily-time",
        fieldWidthRem: 5,
        value: dailyTime,
        responsive: true,
        disabled
      });
    } else if (scheduleType === "weekly") {
      $$renderer2.push("<!--[3-->");
      $$renderer2.push(`<div class="basis-full md:hidden"></div> `);
      DropdownSelect($$renderer2, {
        value: String(weeklyDay),
        options: weekdayOptions,
        disabled,
        fixed,
        buttonSize: "sm",
        width: "w-20",
        justify: "center",
        responsiveDropdown: true
      });
      $$renderer2.push(`<!----> `);
      TimeInput($$renderer2, {
        label: "Time",
        hideLabel: true,
        name: "cron-weekly-time",
        fieldWidthRem: 5,
        value: weeklyTime,
        responsive: true,
        disabled
      });
      $$renderer2.push(`<!---->`);
    } else if (scheduleType === "monthly") {
      $$renderer2.push("<!--[4-->");
      $$renderer2.push(`<div class="basis-full md:hidden"></div> <span class="text-sm text-neutral-500 dark:text-neutral-400">day</span> <div class="w-24">`);
      NumberInput($$renderer2, {
        name: "cron-monthly-day",
        value: monthlyDay,
        min: 1,
        max: 31,
        step: 1,
        disabled
      });
      $$renderer2.push(`<!----></div> `);
      TimeInput($$renderer2, {
        label: "Time",
        hideLabel: true,
        name: "cron-monthly-time",
        fieldWidthRem: 5,
        value: monthlyTime,
        responsive: true,
        disabled
      });
      $$renderer2.push(`<!---->`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="w-56">`);
      FormInput($$renderer2, {
        label: "Custom cron",
        hideLabel: true,
        name: "cron-custom",
        value: customCron,
        placeholder: "0 * * * *",
        mono: true,
        disabled,
        inputClass: cronError ? "border-red-500 focus:border-red-500" : ""
      });
      $$renderer2.push(`<!----></div>`);
    }
    $$renderer2.push(`<!--]--> `);
    if (cronError && scheduleType !== "custom") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span class="text-xs text-red-500">${escape_html(cronError)}</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, {
      value: value2,
      disabled,
      fixed,
      minIntervalMinutes,
      onWarning
    });
  });
}
var init_CronInput = __esm({
  "dist/build/server/chunks/CronInput.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_DropdownSelect();
    init_FormInput();
    init_NumberInput();
    init_DropdownCombobox();
    init_croner();
  }
});

// dist/build/server/chunks/Toggle.js
function Toggle($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let resolvedLabel, resolvedCheckboxColor, hasInfo;
    let checked = fallback($$props["checked"], false);
    let disabled = fallback($$props["disabled"], false);
    let label = fallback($$props["label"], "");
    let ariaLabel = fallback($$props["ariaLabel"], "Toggle");
    let color = fallback($$props["color"], "accent");
    let icon = fallback($$props["icon"], Check);
    let checkboxColor = fallback($$props["checkboxColor"], "");
    let shape = fallback($$props["shape"], "circle");
    let variant = fallback($$props["variant"], "filled");
    let iconColor = fallback($$props["iconColor"], "");
    let fullWidth = fallback($$props["fullWidth"], false);
    let infoHeader = fallback($$props["infoHeader"], "");
    let infoBody = fallback($$props["infoBody"], "");
    createEventDispatcher();
    let showInfoModal = false;
    $: resolvedLabel = label || ariaLabel;
    $: resolvedCheckboxColor = checkboxColor ? checkboxColor : color === "amber" ? "#F59E0B" : color;
    $: hasInfo = infoHeader.trim() !== "" || infoBody.trim() !== "";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div role="switch"${attr("aria-checked", checked)}${attr("aria-label", resolvedLabel)}${attr("aria-disabled", disabled)}${attr("tabindex", disabled ? void 0 : 0)}${attr_class(`flex ${fullWidth ? "w-full justify-between" : "w-fit"} items-center gap-3 rounded-xl border border-neutral-300 bg-white px-3 py-2 text-sm text-neutral-700 transition-colors dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-200 ${disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer hover:bg-neutral-50 dark:hover:bg-neutral-800"}`)}><div class="flex min-w-0 items-center gap-2">`);
      if (label) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="min-w-0">${escape_html(label)}</span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (hasInfo) {
        $$renderer3.push("<!--[0-->");
        Button($$renderer3, {
          icon: Info,
          variant: "secondary",
          size: "xs",
          ariaLabel: `More information about ${stringify(resolvedLabel)}`
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> `);
      IconCheckbox($$renderer3, {
        checked,
        icon,
        color: resolvedCheckboxColor || "accent",
        shape,
        variant,
        iconColor,
        disabled,
        stopPropagation: true
      });
      $$renderer3.push(`<!----></div> `);
      if (hasInfo) {
        $$renderer3.push("<!--[0-->");
        InfoModal($$renderer3, {
          header: infoHeader || resolvedLabel,
          get open() {
            return showInfoModal;
          },
          set open($$value) {
            showInfoModal = $$value;
            $$settled = false;
          },
          children: ($$renderer4) => {
            $$renderer4.push(`<p class="text-sm leading-6 text-neutral-700 dark:text-neutral-300">${escape_html(infoBody)}</p>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]-->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      checked,
      disabled,
      label,
      ariaLabel,
      color,
      icon,
      checkboxColor,
      shape,
      variant,
      iconColor,
      fullWidth,
      infoHeader,
      infoBody
    });
  });
}
var init_Toggle = __esm({
  "dist/build/server/chunks/Toggle.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_check();
    init_info();
    init_Button();
    init_IconCheckbox();
    init_InfoModal();
  }
});

// dist/build/server/entries/pages/arr/_id_/drift/_page.svelte.js
var page_svelte_exports4 = {};
__export(page_svelte_exports4, {
  default: () => _page4
});
function QualityListDiff($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let rows;
    let items = fallback($$props["items"], () => [], true);
    const columns = [{
      key: "position",
      header: "#",
      width: "w-12"
    }, {
      key: "name",
      header: "Quality / Group"
    }];
    const memberColumns = [{
      key: "position",
      header: "#",
      width: "w-12"
    }, {
      key: "name",
      header: "Quality"
    }];
    function disableExpand(row) {
      return row.type !== "group" || !row.items || row.items.length === 0;
    }
    function rowKey2(row) {
      return `${row.type}:${row.id}:${row.position}`;
    }
    function memberRows(members) {
      return members.map((member, i) => ({
        ...member,
        position: i + 1
      }));
    }
    $: rows = [...items].reverse().map((item, index88) => ({
      ...item,
      position: index88 + 1,
      items: item.items ? [...item.items].reverse() : item.items
    }));
    ExpandableTable($$renderer2, {
      columns,
      data: rows,
      getRowId: rowKey2,
      disableExpandWhen: disableExpand,
      compact: true,
      flushExpanded: true,
      chevronPosition: "right",
      emptyMessage: "No qualities",
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "position") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="text-sm text-neutral-500 tabular-nums dark:text-neutral-400">${escape_html(row.position)}</span>`);
          } else if (column.key === "name") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="flex items-center justify-between gap-2"><span class="text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(row.name)}</span> <div class="flex shrink-0 items-center gap-1.5">`);
            Label($$renderer3, {
              variant: row.allowed ? "success" : "secondary",
              size: "sm",
              rounded: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.allowed ? "Enabled" : "Disabled")}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            if (row.upgradeUntil) {
              $$renderer3.push("<!--[0-->");
              Label($$renderer3, {
                variant: "info",
                size: "sm",
                rounded: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Upgrade Until`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        expanded: ($$renderer3, { row }) => {
          if (row.type === "group" && row.items && row.items.length > 0) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="p-4">`);
            Table2($$renderer3, {
              columns: memberColumns,
              data: memberRows(row.items),
              compact: true,
              hoverable: false,
              $$slots: { cell: ($$renderer4, { row: row2, column }) => {
                if (column.key === "position") {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<span class="text-sm text-neutral-500 tabular-nums dark:text-neutral-400">${escape_html(row2.position)}</span>`);
                } else if (column.key === "name") {
                  $$renderer4.push("<!--[1-->");
                  $$renderer4.push(`<div class="flex items-center justify-between gap-2"><span class="text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(row2.name)}</span> `);
                  if (row2.upgradeUntil) {
                    $$renderer4.push("<!--[0-->");
                    Label($$renderer4, {
                      variant: "info",
                      size: "sm",
                      rounded: "md",
                      children: ($$renderer5) => {
                        $$renderer5.push(`<!---->Upgrade Until`);
                      },
                      $$slots: { default: true }
                    });
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--></div>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]-->`);
              } }
            });
            $$renderer3.push(`<!----></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        }
      }
    });
    bind_props($$props, { items });
  });
}
function DriftFieldDiffTable($$renderer, $$props) {
  let columns;
  let changes = $$props["changes"];
  let arrLabel = fallback($$props["arrLabel"], "Arr");
  const toneToVariant = {
    neutral: "secondary",
    success: "success",
    warning: "warning",
    danger: "danger",
    info: "info"
  };
  function valueVariant(value2) {
    return toneToVariant[value2.tone ?? "neutral"];
  }
  $: columns = [
    {
      key: "label",
      header: "Field"
    },
    {
      key: "expected",
      header: "Profilarr"
    },
    {
      key: "actual",
      header: arrLabel
    }
  ];
  Table2($$renderer, {
    columns,
    data: changes,
    compact: true,
    hoverable: false,
    responsive: true,
    $$slots: { cell: ($$renderer2, { row, column }) => {
      if (column.key === "label") {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="flex flex-col gap-0.5"><span class="text-sm font-medium text-neutral-700 dark:text-neutral-200">${escape_html(row.label)}</span> `);
        if (row.detail) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<span class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(row.detail)}</span>`);
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]--></div>`);
      } else if (column.key === "expected") {
        $$renderer2.push("<!--[1-->");
        if (row.expected) {
          $$renderer2.push("<!--[0-->");
          if (row.expected.qualityList) {
            $$renderer2.push("<!--[0-->");
            QualityListDiff($$renderer2, { items: row.expected.qualityList });
          } else {
            $$renderer2.push("<!--[-1-->");
            Label($$renderer2, {
              variant: valueVariant(row.expected),
              size: "md",
              rounded: "md",
              mono: row.expected.mono,
              children: ($$renderer3) => {
                $$renderer3.push(`<!---->${escape_html(row.expected.text)}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer2.push(`<!--]-->`);
        } else {
          $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<span class="text-xs text-neutral-400 dark:text-neutral-500">None</span>`);
        }
        $$renderer2.push(`<!--]-->`);
      } else if (column.key === "actual") {
        $$renderer2.push("<!--[2-->");
        if (row.actual) {
          $$renderer2.push("<!--[0-->");
          if (row.actual.qualityList) {
            $$renderer2.push("<!--[0-->");
            QualityListDiff($$renderer2, { items: row.actual.qualityList });
          } else {
            $$renderer2.push("<!--[-1-->");
            Label($$renderer2, {
              variant: valueVariant(row.actual),
              size: "md",
              rounded: "md",
              mono: row.actual.mono,
              children: ($$renderer3) => {
                $$renderer3.push(`<!---->${escape_html(row.actual.text)}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer2.push(`<!--]-->`);
        } else {
          $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<span class="text-xs text-neutral-400 dark:text-neutral-500">None</span>`);
        }
        $$renderer2.push(`<!--]-->`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]-->`);
    } }
  });
  bind_props($$props, {
    changes,
    arrLabel
  });
}
function _page4($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let nextRunTime, timeUntilNext, driftArrLabel;
    let data = $$props["data"];
    let form = $$props["form"];
    const toneToVariant = {
      neutral: "secondary",
      success: "success",
      warning: "warning",
      danger: "danger",
      info: "info"
    };
    const driftColumns = [
      {
        key: "title",
        header: "Name"
      },
      {
        key: "section",
        header: "Entity",
        width: "w-56"
      },
      {
        key: "state",
        header: "State",
        width: "w-32"
      }
    ];
    const arrTypeLabels = {
      radarr: "Radarr",
      sonarr: "Sonarr"
    };
    const emptyDriftEntities = [];
    let lastFormId = null;
    let enabled3 = data.settings.enabled;
    let cron = data.settings.cron;
    let nextRunAt = data.settings.nextRunAt;
    let now = Date.now();
    onDestroy(() => {
    });
    function formatTimeRemaining(ms) {
      if (ms <= 0) return "now";
      const seconds = Math.floor(ms / 1e3);
      const minutes = Math.floor(seconds / 60);
      const hours = Math.floor(minutes / 60);
      if (hours > 0) return `${hours}h ${minutes % 60}m`;
      if (minutes > 0) return `${minutes}m`;
      return `${seconds}s`;
    }
    $: update3("enabled", enabled3);
    $: update3("cron", cron);
    $: if (form && form !== lastFormId) {
      lastFormId = form;
      if (form.success && form.queued) alertStore.add("success", "Drift check queued");
      if (form.success && !form.queued) {
        if (form.nextRunAt || form.nextRunAt === null) nextRunAt = form.nextRunAt;
        alertStore.add("success", "Drift detection settings saved");
        initEdit({
          enabled: enabled3,
          cron
        });
      }
      if (form.error) {
        jobStatus.cancelOptimistic();
        alertStore.add("error", form.error);
      }
    }
    $: nextRunTime = nextRunAt ? new Date(nextRunAt).getTime() : null;
    $: timeUntilNext = nextRunTime ? nextRunTime - now : null;
    $: driftArrLabel = `${arrTypeLabels[data.instance.type] ?? data.instance.type} - ${data.instance.name}`;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.instance.name} \xB7 Drift` });
      $$renderer3.push(`<!----> <!---->`);
      StickyCard($$renderer3, {
        position: "top",
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<div slot="left"><h1 class="text-xl font-semibold text-neutral-900 dark:text-neutral-50">Drift</h1> <p class="text-sm text-neutral-500 dark:text-neutral-400">Compare synced configuration against the current Arr state.</p></div>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div slot="right" class="flex items-center gap-2">`);
            Button($$renderer4, {
              text: "Run Now",
              icon: Play,
              iconColor: "text-green-600 dark:text-green-400",
              disabled: store_get($$store_subs ??= {}, "$isDirty", isDirty) || !data.featureEnabled || !enabled3
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Save",
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              disabled: !store_get($$store_subs ??= {}, "$isDirty", isDirty) || !data.featureEnabled
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="mt-4 space-y-6 pb-32"><section class="border-b border-neutral-200 pb-5 dark:border-neutral-800">`);
      if (data.featureEnabled) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="flex flex-wrap gap-4 md:items-end md:gap-x-5 md:gap-y-3 md:px-4"><div><span class="mb-1 block text-[10px] font-medium tracking-wider text-neutral-400 uppercase dark:text-neutral-500">Detection</span> `);
        Toggle($$renderer3, {
          checked: enabled3,
          label: enabled3 ? "Enabled" : "Disabled",
          color: enabled3 ? "green" : "red"
        });
        $$renderer3.push(`<!----></div> <div data-onboarding="drift-schedule"><span class="mb-1 block text-[10px] font-medium tracking-wider text-neutral-400 uppercase dark:text-neutral-500">Schedule</span> `);
        CronInput($$renderer3, {
          disabled: !enabled3,
          minIntervalMinutes: 10,
          onWarning: (msg) => alertStore.add("warning", msg),
          get value() {
            return cron;
          },
          set value($$value) {
            cron = $$value;
            $$settled = false;
          }
        });
        $$renderer3.push(`<!----></div> `);
        if (data.status.lastCheckedAt) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="flex w-full flex-wrap items-center gap-1.5 border-t border-neutral-200 pt-3 md:ml-auto md:w-auto md:border-0 md:pt-0 dark:border-neutral-800">`);
          if (!enabled3) {
            $$renderer3.push("<!--[0-->");
            Label($$renderer3, {
              variant: "warning",
              size: "md",
              rounded: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->Paused`);
              },
              $$slots: { default: true }
            });
          } else if (timeUntilNext !== null && timeUntilNext <= 0) {
            $$renderer3.push("<!--[1-->");
            Label($$renderer3, {
              variant: "success",
              size: "md",
              rounded: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->Ready`);
              },
              $$slots: { default: true }
            });
          } else if (timeUntilNext !== null) {
            $$renderer3.push("<!--[2-->");
            Label($$renderer3, {
              variant: "secondary",
              size: "md",
              rounded: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->Next ${escape_html(formatTimeRemaining(timeUntilNext))}`);
              },
              $$slots: { default: true }
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          Label($$renderer3, {
            variant: "secondary",
            size: "md",
            rounded: "md",
            mono: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->Last ${escape_html(formatSmartDateTime(data.status.lastCheckedAt, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat)))}`);
            },
            $$slots: { default: true }
          });
          $$renderer3.push(`<!----> `);
          if (data.driftView.hasDuplicateDrift) {
            $$renderer3.push("<!--[0-->");
            Label($$renderer3, {
              variant: "info",
              size: "md",
              rounded: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(data.driftView.duplicateDriftCount)}
									${escape_html(data.driftView.duplicateDriftCount === 1 ? "duplicate" : "duplicates")}`);
              },
              $$slots: { default: true }
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<div class="text-sm text-neutral-500 md:px-4 dark:text-neutral-400">Drift detection is not available.</div>`);
      }
      $$renderer3.push(`<!--]--></section> `);
      if (data.featureEnabled) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<section class="md:px-4">`);
        if (!enabled3) {
          $$renderer3.push("<!--[0-->");
          ExpandableTable($$renderer3, {
            columns: driftColumns,
            data: emptyDriftEntities,
            getRowId: (row) => row.id,
            responsive: true,
            chevronPosition: "right",
            primaryColumnKey: "title",
            flushExpanded: true,
            emptyMessage: "Drift detection is disabled. Toggle it on above to start checking."
          });
        } else if (data.status.status === "failed" && data.status.lastError) {
          $$renderer3.push("<!--[1-->");
          $$renderer3.push(`<div class="rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-900 dark:bg-red-950/40 dark:text-red-300">${escape_html(data.status.lastError)}</div>`);
        } else if (data.status.status === "never_checked") {
          $$renderer3.push("<!--[2-->");
          ExpandableTable($$renderer3, {
            columns: driftColumns,
            data: emptyDriftEntities,
            getRowId: (row) => row.id,
            responsive: true,
            chevronPosition: "right",
            primaryColumnKey: "title",
            flushExpanded: true,
            emptyMessage: "No drift check has run yet. Hit Run Now above to check."
          });
        } else if (data.status.status === "clean") {
          $$renderer3.push("<!--[3-->");
          ExpandableTable($$renderer3, {
            columns: driftColumns,
            data: emptyDriftEntities,
            getRowId: (row) => row.id,
            responsive: true,
            chevronPosition: "right",
            primaryColumnKey: "title",
            flushExpanded: true,
            emptyMessage: "\u2705 All synced up. Move along, nothing to see here."
          });
        } else if (data.driftEntities.length > 0) {
          $$renderer3.push("<!--[4-->");
          ExpandableTable($$renderer3, {
            columns: driftColumns,
            data: data.driftEntities,
            getRowId: (row) => row.id,
            responsive: true,
            chevronPosition: "right",
            primaryColumnKey: "title",
            flushExpanded: true,
            $$slots: {
              cell: ($$renderer4, { row, column }) => {
                if (column.key === "title") {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="flex flex-col gap-1"><div class="flex flex-wrap items-center gap-1.5"><span class="text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(row.title)}</span> `);
                  if (row.duplicateDrift) {
                    $$renderer4.push("<!--[0-->");
                    Label($$renderer4, {
                      variant: "info",
                      size: "sm",
                      rounded: "md",
                      children: ($$renderer5) => {
                        $$renderer5.push(`<!---->Duplicate`);
                      },
                      $$slots: { default: true }
                    });
                    $$renderer4.push(`<!----> `);
                    Label($$renderer4, {
                      variant: "secondary",
                      size: "sm",
                      rounded: "md",
                      children: ($$renderer5) => {
                        $$renderer5.push(`<!---->${escape_html(row.duplicateDrift.winnerDatabaseName)} wins`);
                      },
                      $$slots: { default: true }
                    });
                    $$renderer4.push(`<!---->`);
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--></div> `);
                  if (row.databaseName) {
                    $$renderer4.push("<!--[0-->");
                    $$renderer4.push(`<span class="text-xs text-neutral-400 dark:text-neutral-500">${escape_html(row.databaseName)}</span>`);
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--> `);
                  if (row.summary) {
                    $$renderer4.push("<!--[0-->");
                    $$renderer4.push(`<span class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(row.summary)}</span>`);
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--></div>`);
                } else if (column.key === "section") {
                  $$renderer4.push("<!--[1-->");
                  Label($$renderer4, {
                    variant: "secondary",
                    size: "md",
                    rounded: "md",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->${escape_html(row.sectionLabel)}`);
                    },
                    $$slots: { default: true }
                  });
                } else if (column.key === "state") {
                  $$renderer4.push("<!--[2-->");
                  Label($$renderer4, {
                    variant: toneToVariant[row.tone],
                    size: "md",
                    rounded: "md",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->${escape_html(row.stateLabel)}`);
                    },
                    $$slots: { default: true }
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]-->`);
              },
              expanded: ($$renderer4, { row }) => {
                $$renderer4.push(`<div class="px-4 py-3 md:px-6 md:py-4">`);
                DriftFieldDiffTable($$renderer4, {
                  changes: row.changes,
                  arrLabel: driftArrLabel
                });
                $$renderer4.push(`<!----></div>`);
              }
            }
          });
        } else {
          $$renderer3.push("<!--[-1-->");
          ExpandableTable($$renderer3, {
            columns: driftColumns,
            data: emptyDriftEntities,
            getRowId: (row) => row.id,
            responsive: true,
            chevronPosition: "right",
            primaryColumnKey: "title",
            flushExpanded: true,
            emptyMessage: "Drift was detected, but no displayable items were stored."
          });
        }
        $$renderer3.push(`<!--]--></section>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> <form id="drift-save-form" method="POST" action="?/save" class="hidden"><input type="hidden" name="enabled"${attr("value", enabled3)}/> <input type="hidden" name="cron"${attr("value", cron)}/></form> <form id="drift-run-form" method="POST" action="?/run" class="hidden"></form> `);
      DirtyModal($$renderer3, {});
      $$renderer3.push(`<!---->`);
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      data,
      form
    });
  });
}
var init_page_svelte4 = __esm({
  "dist/build/server/entries/pages/arr/_id_/drift/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_dates();
    init_Button();
    init_play();
    init_save();
    init_client4();
    init_store2();
    init_Label();
    init_jobStatus();
    init_navigation();
    init_dateFormat();
    init_timezone();
    init_forms();
    init_dirty();
    init_DirtyModal();
    init_ExpandableTable();
    init_PageMeta();
    init_Table();
    init_StickyCard();
    init_CronInput();
    init_Toggle();
  }
});

// dist/build/server/nodes/11.js
var __exports12 = {};
__export(__exports12, {
  component: () => component11,
  fonts: () => fonts12,
  imports: () => imports12,
  index: () => index12,
  server: () => page_server_ts_exports5,
  server_id: () => server_id11,
  stylesheets: () => stylesheets12
});
var index12, component_cache11, component11, server_id11, imports12, stylesheets12, fonts12;
var init__12 = __esm({
  async "dist/build/server/nodes/11.js"() {
    "use strict";
    await init_page_server_ts5();
    index12 = 11;
    component11 = async () => component_cache11 ??= (await Promise.resolve().then(() => (init_page_svelte4(), page_svelte_exports4))).default;
    server_id11 = "src/routes/arr/[id]/drift/+page.server.ts";
    imports12 = ["_app/immutable/nodes/11.Cf15qz-P.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BlAgBW4v.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/COLvC_Ug.js", "_app/immutable/chunks/C47WFcPn.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DGICnufN.js"];
    stylesheets12 = ["_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts12 = [];
  }
});

// dist/build/server/entries/pages/arr/_id_/library/_page.server.ts.js
var page_server_ts_exports6 = {};
__export(page_server_ts_exports6, {
  actions: () => actions4
});
var actions4;
var init_page_server_ts6 = __esm({
  async "dist/build/server/entries/pages/arr/_id_/library/_page.server.ts.js"() {
    "use strict";
    await init_arrInstances();
    await init_cleanup();
    init_cache2();
    init_exports();
    actions4 = { delete: ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (!isNaN(id)) {
        cleanupJobsForArrInstance(id);
        arrInstancesQueries.delete(id);
        cache.delete(`library:${id}`);
      }
      redirect(303, "/arr");
    } };
  }
});

// dist/build/server/chunks/calendar.js
function Calendar($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "calendar" },
    props,
    { iconNode: [
      ["path", { "d": "M8 2v3" }],
      ["path", { "d": "M16 2v3" }],
      ["rect", {
        "x": "3",
        "y": "3",
        "width": "18",
        "height": "18",
        "rx": "2"
      }],
      ["path", { "d": "M3 9h18" }]
    ] }
  ]));
}
var init_calendar = __esm({
  "dist/build/server/chunks/calendar.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/hard-drive.js
function Clapperboard($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "clapperboard" },
    props,
    { iconNode: [
      ["path", { "d": "m12.296 3.464 3.02 3.956" }],
      ["path", { "d": "M20.2 6 3 11l-.9-2.4c-.3-1.1.3-2.2 1.3-2.5l13.5-4c1.1-.3 2.2.3 2.5 1.3z" }],
      ["path", { "d": "M3 11h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }],
      ["path", { "d": "m6.18 5.276 3.1 3.899" }]
    ] }
  ]));
}
function Hard_drive($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "hard-drive" },
    props,
    { iconNode: [
      ["path", { "d": "M10 16h.01" }],
      ["path", { "d": "M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" }],
      ["path", { "d": "M21.946 12.013H2.054" }],
      ["path", { "d": "M6 16h.01" }]
    ] }
  ]));
}
var init_hard_drive = __esm({
  "dist/build/server/chunks/hard-drive.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/filterMode.js
function Sliders_horizontal($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "sliders-horizontal" },
    props,
    { iconNode: [
      ["path", { "d": "M10 5H3" }],
      ["path", { "d": "M12 19H3" }],
      ["path", { "d": "M14 3v4" }],
      ["path", { "d": "M16 17v4" }],
      ["path", { "d": "M21 12h-9" }],
      ["path", { "d": "M21 19h-5" }],
      ["path", { "d": "M21 5h-7" }],
      ["path", { "d": "M8 10v4" }],
      ["path", { "d": "M8 12H3" }]
    ] }
  ]));
}
function parseNumberCondition(raw) {
  const trimmed = raw.trim();
  if (!trimmed) return null;
  const rangeMatch = trimmed.match(/^(-?\d+(?:\.\d+)?)\s*-\s*(-?\d+(?:\.\d+)?)$/);
  if (rangeMatch) return {
    operator: "range",
    value: parseFloat(rangeMatch[1]),
    upperValue: parseFloat(rangeMatch[2])
  };
  const opMatch = trimmed.match(/^(>=|<=|>|<)\s*(-?\d+(?:\.\d+)?)$/);
  if (opMatch) return {
    operator: opMatch[1],
    value: parseFloat(opMatch[2])
  };
  const num = parseFloat(trimmed);
  if (!isNaN(num)) return {
    operator: "=",
    value: num
  };
  return null;
}
function matchesNumberCondition(actual, condition) {
  switch (condition.operator) {
    case ">":
      return actual > condition.value;
    case "<":
      return actual < condition.value;
    case ">=":
      return actual >= condition.value;
    case "<=":
      return actual <= condition.value;
    case "=":
      return actual === condition.value;
    case "range":
      return actual >= condition.value && actual <= (condition.upperValue ?? condition.value);
  }
}
function stringValues(rawValue) {
  if (rawValue == null) return [];
  if (Array.isArray(rawValue)) return rawValue;
  return [String(rawValue)];
}
function applySmartFilters(items, tags, fields) {
  if (tags.length === 0) return items;
  const fieldMap = new Map(fields.map((f2) => [f2.key, f2]));
  return items.map((item, index88) => {
    let exactRank = 0;
    return tags.every((tag2) => {
      const field = fieldMap.get(tag2.field);
      if (!field) return true;
      const rawValue = field.accessor(item);
      let matches;
      if (field.type === "number") {
        const condition = parseNumberCondition(tag2.value);
        if (!condition || rawValue == null) return !tag2.negated;
        matches = matchesNumberCondition(Number(rawValue), condition);
      } else {
        const tagLower = tag2.value.toLowerCase();
        const values = stringValues(rawValue);
        const hasExactMatch = values.some((v3) => v3.toLowerCase() === tagLower);
        matches = values.some((v3) => v3.toLowerCase().includes(tagLower));
        if (matches && !tag2.negated && hasExactMatch) exactRank += 1;
      }
      return tag2.negated ? !matches : matches;
    }) ? {
      item,
      index: index88,
      exactRank
    } : null;
  }).filter((result) => result !== null).sort((a2, b3) => b3.exactRank - a2.exactRank || a2.index - b3.index).map((result) => result.item);
}
function FilterModeToggle($$renderer, $$props) {
  let value2 = fallback($$props["value"], "smart");
  let position = fallback($$props["position"], "right");
  ActionButton($$renderer, {
    icon: Sliders_horizontal,
    hasDropdown: true,
    dropdownPosition: position,
    $$slots: { dropdown: ($$renderer2) => {
      Dropdown($$renderer2, {
        slot: "dropdown",
        position,
        children: ($$renderer3) => {
          DropdownHeader($$renderer3, { label: "Bar mode" });
          $$renderer3.push(`<!----> `);
          DropdownItem($$renderer3, {
            icon: Funnel,
            label: "Filter",
            selected: value2 === "smart"
          });
          $$renderer3.push(`<!----> `);
          DropdownItem($$renderer3, {
            icon: Search,
            label: "Search",
            selected: value2 === "simple"
          });
          $$renderer3.push(`<!---->`);
        },
        $$slots: { default: true }
      });
    } }
  });
  bind_props($$props, {
    value: value2,
    position
  });
}
function FilterTag($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let tag2 = $$props["tag"];
    let fieldLabel2 = $$props["fieldLabel"];
    let onremove = $$props["onremove"];
    let ontogglenegated = $$props["ontogglenegated"];
    $$renderer2.push(`<span class="inline-flex items-center gap-1"><button type="button" class="cursor-pointer">`);
    Label($$renderer2, {
      variant: tag2.negated ? "danger" : "info",
      size: "md",
      rounded: "md",
      children: ($$renderer3) => {
        $$renderer3.push(`<span class="opacity-60">${escape_html(fieldLabel2)}:</span> <span${attr_class(clsx(tag2.negated ? "line-through" : ""))}>${escape_html(tag2.value)}</span>`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----></button> <button type="button" class="text-neutral-400 hover:text-neutral-600 dark:hover:text-neutral-200" aria-label="Remove filter">`);
    X2($$renderer2, { size: 14 });
    $$renderer2.push(`<!----></button></span>`);
    bind_props($$props, {
      tag: tag2,
      fieldLabel: fieldLabel2,
      onremove,
      ontogglenegated
    });
  });
}
function SmartFilterBar($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let fieldMap, phase, fieldSuggestions, valueSuggestions;
    let fields = fallback($$props["fields"], () => [], true);
    let items = fallback($$props["items"], () => [], true);
    let tags = fallback($$props["tags"], () => [], true);
    let storageKey = fallback($$props["storageKey"], "");
    let placeholder = fallback($$props["placeholder"], "Filter...");
    let onchange = fallback($$props["onchange"], void 0);
    let inputValue = "";
    let isFocused = false;
    function updateTags(newTags) {
      tags = newTags;
      onchange?.(newTags);
    }
    function removeTag(index88) {
      updateTags(tags.filter((_3, i) => i !== index88));
    }
    function toggleNegated(index88) {
      tags = tags.map((t2, i) => i === index88 ? {
        ...t2,
        negated: !t2.negated
      } : t2);
      onchange?.(tags);
    }
    $: storageKey && `${storageKey}`;
    $: fieldMap = new Map(fields.map((f2) => [f2.key, f2]));
    $: fields.find((f2) => f2.isDefault) ?? fields[0];
    $: phase = (() => {
      if (inputValue.trim(), isFocused) ;
      return "idle";
    })();
    $: fieldSuggestions = (() => {
      if (phase !== "field") return [];
      const q2 = inputValue.trim().toLowerCase();
      if (!q2) return fields.map((f2) => ({
        key: f2.key,
        label: f2.label,
        description: f2.description ?? "",
        type: f2.type
      }));
      return fields.filter((f2) => f2.label.toLowerCase().includes(q2) || f2.key.toLowerCase().includes(q2)).map((f2) => ({
        key: f2.key,
        label: f2.label,
        description: f2.description ?? "",
        type: f2.type
      }));
    })();
    $: valueSuggestions = /* @__PURE__ */ (() => {
      return [];
    })();
    $: phase === "field" ? fieldSuggestions.map((f2) => ({
      label: f2.label,
      description: f2.description,
      hint: f2.type,
      value: f2.key
    })) : phase === "value" && valueSuggestions.map((s3) => ({
      label: s3,
      description: "",
      hint: "",
      value: s3
    }));
    $$renderer2.push(`<div class="smart-filter-bar relative flex min-w-0 flex-1 svelte-xblpyh"><div class="relative flex h-10 w-full items-center gap-1.5 overflow-x-auto rounded-xl border border-neutral-300 bg-white px-3 transition-colors dark:border-neutral-700/60 dark:bg-neutral-800/50"><div class="pointer-events-none flex-shrink-0">`);
    Funnel($$renderer2, {
      size: 16,
      class: "text-neutral-500 dark:text-neutral-400"
    });
    $$renderer2.push(`<!----></div> <!--[-->`);
    const each_array = ensure_array_like(tags);
    for (let index88 = 0, $$length = each_array.length; index88 < $$length; index88++) {
      let tag2 = each_array[index88];
      FilterTag($$renderer2, {
        tag: tag2,
        fieldLabel: fieldMap.get(tag2.field)?.label ?? tag2.field,
        onremove: () => removeTag(index88),
        ontogglenegated: () => toggleNegated(index88)
      });
    }
    $$renderer2.push(`<!--]--> `);
    $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<input type="text"${attr("value", inputValue)}${attr("placeholder", placeholder)} class="h-full min-w-[120px] flex-1 bg-transparent text-base text-neutral-900 placeholder-neutral-500 outline-none sm:text-sm dark:text-neutral-100 dark:placeholder-neutral-400"/>`);
    $$renderer2.push(`<!--]--></div> `);
    $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, {
      fields,
      items,
      tags,
      storageKey,
      placeholder,
      onchange
    });
  });
}
function loadFilterMode() {
  return "smart";
}
var filterMode;
var init_filterMode = __esm({
  "dist/build/server/chunks/filterMode.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_index_server2();
    init_uuid();
    init_Dropdown();
    init_Icon();
    init_funnel();
    init_search();
    init_x();
    init_Label();
    init_DropdownItem();
    init_ActionButton();
    init_DropdownHeader();
    filterMode = writable(loadFilterMode());
  }
});

// dist/build/server/chunks/star.js
function Star($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "star" },
    props,
    { iconNode: [["path", { "d": "M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z" }]] }
  ]));
}
var init_star = __esm({
  "dist/build/server/chunks/star.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/users2.js
function Users($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "users" },
    props,
    { iconNode: [
      ["path", { "d": "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }],
      ["path", { "d": "M16 3.128a4 4 0 0 1 0 7.744" }],
      ["path", { "d": "M22 21v-2a4 4 0 0 0-3-3.87" }],
      ["circle", {
        "cx": "9",
        "cy": "7",
        "r": "4"
      }]
    ] }
  ]));
}
var init_users2 = __esm({
  "dist/build/server/chunks/users2.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/ProgressIndicator.js
function ProgressIndicator($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let progress, progressPercent, barColor;
    let current3 = fallback($$props["current"], 0);
    let target = fallback($$props["target"], 0);
    let met = fallback($$props["met"], false);
    let mode = fallback($$props["mode"], "compact");
    let colorMode = fallback($$props["colorMode"], "threshold");
    let tooltip = fallback($$props["tooltip"], "");
    let tooltipPosition = fallback($$props["tooltipPosition"], "bottom");
    let tooltipAlign = fallback($$props["tooltipAlign"], "middle");
    function getBarColor(p2, done, mode2) {
      if (done) return "bg-green-500 dark:bg-green-400";
      if (mode2 === "completion") return "bg-yellow-500 dark:bg-yellow-400";
      if (p2 >= 0.75) return "bg-green-500 dark:bg-green-400";
      if (p2 >= 0.5) return "bg-yellow-500 dark:bg-yellow-400";
      return "bg-red-500 dark:bg-red-400";
    }
    $: progress = target > 0 ? Math.max(0, Math.min(current3 / target, 1)) : 0;
    $: progressPercent = Math.round(progress * 100);
    $: barColor = getBarColor(progress, met, colorMode);
    if (tooltip) {
      $$renderer2.push("<!--[0-->");
      Tooltip($$renderer2, {
        text: tooltip,
        position: tooltipPosition,
        align: tooltipAlign,
        fullWidth: mode === "compact",
        children: ($$renderer3) => {
          if (mode === "compact") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex w-full flex-col gap-1"><div class="flex items-center justify-between gap-2"><span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(current3.toLocaleString())} <span class="text-neutral-400 dark:text-neutral-500">/ ${escape_html(target.toLocaleString())}</span></span> `);
            if (met) {
              $$renderer3.push("<!--[0-->");
              Check($$renderer3, {
                size: 14,
                class: "flex-shrink-0 text-green-600 dark:text-green-400"
              });
            } else {
              $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<span class="font-mono text-xs text-neutral-400 dark:text-neutral-500">${escape_html(progressPercent)}%</span>`);
            }
            $$renderer3.push(`<!--]--></div> <div class="h-1.5 w-full overflow-hidden rounded-full bg-neutral-200 dark:bg-neutral-700"><div${attr_class(`h-full rounded-full transition-all ${stringify(barColor)}`)}${attr_style(`width: ${stringify(progressPercent)}%`)}></div></div></div>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<div class="flex items-center gap-2 whitespace-nowrap"><div class="h-1.5 w-12 flex-shrink-0 overflow-hidden rounded-full bg-neutral-200 dark:bg-neutral-700"><div${attr_class(`h-full rounded-full transition-all ${stringify(barColor)}`)}${attr_style(`width: ${stringify(progressPercent)}%`)}></div></div> <span class="font-mono text-xs text-neutral-500 dark:text-neutral-400">${escape_html(current3.toLocaleString())} / ${escape_html(target.toLocaleString())}</span> `);
            if (met) {
              $$renderer3.push("<!--[0-->");
              Check($$renderer3, {
                size: 12,
                class: "flex-shrink-0 text-green-600 dark:text-green-400"
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div>`);
          }
          $$renderer3.push(`<!--]-->`);
        },
        $$slots: { default: true }
      });
    } else if (mode === "compact") {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<div class="flex flex-col gap-1"><div class="flex items-center justify-between gap-2"><span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(current3.toLocaleString())} <span class="text-neutral-400 dark:text-neutral-500">/ ${escape_html(target.toLocaleString())}</span></span> `);
      if (met) {
        $$renderer2.push("<!--[0-->");
        Check($$renderer2, {
          size: 14,
          class: "flex-shrink-0 text-green-600 dark:text-green-400"
        });
      } else {
        $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<span class="font-mono text-xs text-neutral-400 dark:text-neutral-500">${escape_html(progressPercent)}%</span>`);
      }
      $$renderer2.push(`<!--]--></div> <div class="h-1.5 w-full overflow-hidden rounded-full bg-neutral-200 dark:bg-neutral-700"><div${attr_class(`h-full rounded-full transition-all ${stringify(barColor)}`)}${attr_style(`width: ${stringify(progressPercent)}%`)}></div></div></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="flex items-center gap-2 whitespace-nowrap"><div class="h-1.5 w-12 flex-shrink-0 overflow-hidden rounded-full bg-neutral-200 dark:bg-neutral-700"><div${attr_class(`h-full rounded-full transition-all ${stringify(barColor)}`)}${attr_style(`width: ${stringify(progressPercent)}%`)}></div></div> <span class="font-mono text-xs text-neutral-500 dark:text-neutral-400">${escape_html(current3.toLocaleString())} / ${escape_html(target.toLocaleString())}</span> `);
      if (met) {
        $$renderer2.push("<!--[0-->");
        Check($$renderer2, {
          size: 12,
          class: "flex-shrink-0 text-green-600 dark:text-green-400"
        });
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div>`);
    }
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      current: current3,
      target,
      met,
      mode,
      colorMode,
      tooltip,
      tooltipPosition,
      tooltipAlign
    });
  });
}
var init_ProgressIndicator = __esm({
  "dist/build/server/chunks/ProgressIndicator.js"() {
    "use strict";
    init_server();
    init_check();
    init_Button();
  }
});

// dist/build/server/chunks/Score.js
function Score($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let colorClass, sizeClass, displayValue;
    let score = fallback($$props["score"], null);
    let showSign = fallback($$props["showSign"], true);
    let size = fallback($$props["size"], "md");
    let colored = fallback($$props["colored"], true);
    $: colorClass = score === null ? "text-neutral-400" : !colored ? "text-neutral-900 dark:text-neutral-100" : score > 0 ? "text-emerald-600 dark:text-emerald-400" : score < 0 ? "text-red-600 dark:text-red-400" : "text-neutral-500";
    $: sizeClass = size === "sm" ? "text-xs" : "text-sm";
    $: displayValue = score === null ? null : showSign && score > 0 ? `+${score.toLocaleString()}` : score.toLocaleString();
    if (score !== null) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span${attr_class(`font-mono font-medium ${stringify(colorClass)} ${stringify(sizeClass)}`)}>${escape_html(displayValue)}</span>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<span${attr_class(`text-neutral-400 ${stringify(sizeClass)}`)}>\u2014</span>`);
    }
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      score,
      showSign,
      size,
      colored
    });
  });
}
var init_Score = __esm({
  "dist/build/server/chunks/Score.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/chunks/CustomFormatBadge.js
function CustomFormatBadge($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let scoreClass, displayScore;
    let name = $$props["name"];
    let score = $$props["score"];
    $: scoreClass = score > 0 ? "text-emerald-600 dark:text-emerald-400" : score < 0 ? "text-red-600 dark:text-red-400" : "text-neutral-500";
    $: displayScore = score > 0 ? `+${score.toLocaleString()}` : score.toLocaleString();
    $$renderer2.push(`<span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 text-xs dark:border-neutral-700/60 dark:bg-neutral-800/50"><span class="text-neutral-500 dark:text-neutral-400">${escape_html(name)}</span> <span${attr_class(`font-mono font-medium ${stringify(scoreClass)}`)}>${escape_html(displayScore)}</span></span>`);
    bind_props($$props, {
      name,
      score
    });
  });
}
var init_CustomFormatBadge = __esm({
  "dist/build/server/chunks/CustomFormatBadge.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/entries/pages/arr/_id_/library/_page.svelte.js
var page_svelte_exports5 = {};
__export(page_svelte_exports5, {
  default: () => _page5
});
function Chevrons_down_up($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "chevrons-down-up" },
    props,
    { iconNode: [["path", { "d": "m7 20 5-5 5 5" }], ["path", { "d": "m7 4 5 5 5-5" }]] }
  ]));
}
function Chevrons_up_down($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "chevrons-up-down" },
    props,
    { iconNode: [["path", { "d": "m7 15 5 5 5-5" }], ["path", { "d": "m7 9 5-5 5 5" }]] }
  ]));
}
function Clock_3($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "clock-3" },
    props,
    { iconNode: [["circle", {
      "cx": "12",
      "cy": "12",
      "r": "10"
    }], ["path", { "d": "M12 6v6h4" }]] }
  ]));
}
function File_question_mark($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "file-question-mark" },
    props,
    { iconNode: [
      ["path", { "d": "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" }],
      ["path", { "d": "M12 17h.01" }],
      ["path", { "d": "M9.1 9a3 3 0 0 1 5.82 1c0 2-3 3-3 3" }]
    ] }
  ]));
}
function Flame($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "flame" },
    props,
    { iconNode: [["path", { "d": "M12 3q1 4 4 6.5t3 5.5a1 1 0 0 1-14 0 5 5 0 0 1 1-3 1 1 0 0 0 5 0c0-2-1.5-3-1.5-5q0-2 2.5-4" }]] }
  ]));
}
function Square($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "square" },
    props,
    { iconNode: [["rect", {
      "width": "18",
      "height": "18",
      "x": "3",
      "y": "3",
      "rx": "2"
    }]] }
  ]));
}
function Table_properties($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "table-properties" },
    props,
    { iconNode: [
      ["path", { "d": "M15 3v18" }],
      ["rect", {
        "width": "18",
        "height": "18",
        "x": "3",
        "y": "3",
        "rx": "2"
      }],
      ["path", { "d": "M21 9H3" }],
      ["path", { "d": "M21 15H3" }]
    ] }
  ]));
}
function LibraryActionBar($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let isRadarr, sortOptions, filterPlaceholder, openLabel, refreshTooltip;
    let fields = fallback($$props["fields"], () => [], true);
    let items = fallback($$props["items"], () => [], true);
    let tags = fallback($$props["tags"], () => [], true);
    let filterStorageKey = fallback($$props["filterStorageKey"], "");
    let searchStore = $$props["searchStore"];
    let visibleColumns = $$props["visibleColumns"];
    let toggleableColumns = $$props["toggleableColumns"];
    let columnLabels = $$props["columnLabels"];
    let visibleCardFields = fallback($$props["visibleCardFields"], () => /* @__PURE__ */ new Set(), true);
    let toggleableCardFields = fallback($$props["toggleableCardFields"], () => [], true);
    let cardFieldLabels = fallback($$props["cardFieldLabels"], () => ({}), true);
    let onToggleCardField = fallback($$props["onToggleCardField"], () => {
    });
    let refreshStatusText = fallback($$props["refreshStatusText"], null);
    let refreshing = fallback($$props["refreshing"], false);
    let onToggleColumn = $$props["onToggleColumn"];
    let onFilterInfo = $$props["onFilterInfo"];
    let onRefresh = $$props["onRefresh"];
    let onOpen = $$props["onOpen"];
    let instanceType = fallback($$props["instanceType"], "radarr");
    let movieDownloadStatuses = fallback($$props["movieDownloadStatuses"], () => /* @__PURE__ */ new Set(["downloaded", "missing"]), true);
    let onMovieDownloadStatusToggle = fallback($$props["onMovieDownloadStatusToggle"], () => {
    });
    let viewMode = fallback($$props["viewMode"], "cards");
    let expandAll = fallback($$props["expandAll"], false);
    let onToggleExpandAll = fallback($$props["onToggleExpandAll"], () => {
    });
    let sortKey = fallback($$props["sortKey"], "title");
    let sortDirection = fallback($$props["sortDirection"], "asc");
    let onSort = fallback($$props["onSort"], () => {
    });
    let useSimpleMode = fallback($$props["useSimpleMode"], false);
    const commonSortOptions = [
      {
        key: "title",
        label: "Title"
      },
      {
        key: "size",
        label: "Size"
      },
      {
        key: "dateAdded",
        label: "Date Added"
      },
      {
        key: "year",
        label: "Year"
      },
      {
        key: "score",
        label: "Score"
      }
    ];
    onDestroy(() => {
    });
    $: isRadarr = instanceType === "radarr";
    $: sortOptions = isRadarr ? [
      ...commonSortOptions,
      {
        key: "initialReleaseDate",
        label: "Initial Release"
      },
      {
        key: "theatricalReleaseDate",
        label: "Theatrical Release"
      },
      {
        key: "digitalReleaseDate",
        label: "Digital Release"
      },
      {
        key: "physicalReleaseDate",
        label: "Physical Release"
      }
    ] : [
      ...commonSortOptions,
      {
        key: "firstAired",
        label: "Series Premiere"
      },
      {
        key: "previousAiring",
        label: "Latest Aired Episode"
      }
    ];
    $: filterPlaceholder = isRadarr ? "Filter movies..." : "Filter series...";
    $: openLabel = isRadarr ? "Open in Radarr" : "Open in Sonarr";
    $: refreshTooltip = refreshStatusText ? `Refresh \xB7 ${refreshStatusText}` : "Refresh";
    $: useSimpleMode = store_get($$store_subs ??= {}, "$filterMode", filterMode) === "simple";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          if (useSimpleMode) {
            $$renderer4.push("<!--[0-->");
            SearchAction($$renderer4, {
              searchStore,
              placeholder: filterPlaceholder,
              responsive: true
            });
          } else {
            $$renderer4.push("<!--[-1-->");
            SmartFilterBar($$renderer4, {
              fields,
              items,
              storageKey: filterStorageKey,
              placeholder: filterPlaceholder,
              get tags() {
                return tags;
              },
              set tags($$value) {
                tags = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            Tooltip($$renderer4, {
              text: "Filter help",
              children: ($$renderer5) => {
                ActionButton($$renderer5, { icon: Info });
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!---->`);
          }
          $$renderer4.push(`<!--]--> `);
          Tooltip($$renderer4, {
            text: refreshTooltip,
            children: ($$renderer5) => {
              ActionButton($$renderer5, {
                icon: Refresh_cw,
                iconClass: refreshing ? "animate-spin" : ""
              });
            },
            $$slots: { default: true }
          });
          $$renderer4.push(`<!----> `);
          Tooltip($$renderer4, {
            text: openLabel,
            children: ($$renderer5) => {
              ActionButton($$renderer5, { icon: External_link });
            },
            $$slots: { default: true }
          });
          $$renderer4.push(`<!----> `);
          if (viewMode === "cards") {
            $$renderer4.push("<!--[0-->");
            ActionButton($$renderer4, {
              icon: Table_properties,
              hasDropdown: true,
              dropdownPosition: "right",
              $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
                Dropdown($$renderer5, {
                  position: dropdownPosition,
                  minWidth: "14rem",
                  children: ($$renderer6) => {
                    DropdownHeader($$renderer6, { label: "Toggle fields" });
                    $$renderer6.push(`<!----> <!--[-->`);
                    const each_array = ensure_array_like(toggleableCardFields);
                    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                      let fieldKey2 = each_array[$$index];
                      DropdownItem($$renderer6, {
                        label: cardFieldLabels[fieldKey2],
                        selected: visibleCardFields.has(fieldKey2)
                      });
                    }
                    $$renderer6.push(`<!--]-->`);
                  },
                  $$slots: { default: true }
                });
              } }
            });
            $$renderer4.push(`<!----> `);
            ActionButton($$renderer4, {
              icon: Arrow_up_down,
              hasDropdown: true,
              dropdownPosition: "right",
              $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
                Dropdown($$renderer5, {
                  position: dropdownPosition,
                  minWidth: "12rem",
                  children: ($$renderer6) => {
                    DropdownHeader($$renderer6, { label: "Sort by" });
                    $$renderer6.push(`<!----> <!--[-->`);
                    const each_array_1 = ensure_array_like(sortOptions);
                    for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                      let option = each_array_1[$$index_1];
                      DropdownItem($$renderer6, {
                        label: option.label,
                        selected: sortKey === option.key,
                        checkIcon: sortDirection === "asc" ? Arrow_up : Arrow_down
                      });
                    }
                    $$renderer6.push(`<!--]-->`);
                  },
                  $$slots: { default: true }
                });
              } }
            });
            $$renderer4.push(`<!---->`);
          } else $$renderer4.push("<!--[-1-->");
          $$renderer4.push(`<!--]--> `);
          if (viewMode === "table") {
            $$renderer4.push("<!--[0-->");
            Tooltip($$renderer4, {
              text: expandAll ? "Collapse all rows" : "Expand all rows",
              children: ($$renderer5) => {
                ActionButton($$renderer5, { icon: expandAll ? Chevrons_down_up : Chevrons_up_down });
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            ActionButton($$renderer4, {
              icon: Table_properties,
              hasDropdown: true,
              dropdownPosition: "right",
              $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
                Dropdown($$renderer5, {
                  position: dropdownPosition,
                  minWidth: "14rem",
                  children: ($$renderer6) => {
                    DropdownHeader($$renderer6, { label: "Toggle columns" });
                    $$renderer6.push(`<!----> <!--[-->`);
                    const each_array_2 = ensure_array_like(toggleableColumns);
                    for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
                      let colKey = each_array_2[$$index_2];
                      DropdownItem($$renderer6, {
                        label: columnLabels[colKey],
                        selected: visibleColumns.has(colKey)
                      });
                    }
                    $$renderer6.push(`<!--]-->`);
                  },
                  $$slots: { default: true }
                });
              } }
            });
            $$renderer4.push(`<!---->`);
          } else $$renderer4.push("<!--[-1-->");
          $$renderer4.push(`<!--]--> `);
          $$renderer4.push("<!--[0-->");
          FilterModeToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$filterMode", filterMode);
            },
            set value($$value) {
              store_set(filterMode, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!--]--> `);
          if (isRadarr) {
            $$renderer4.push("<!--[0-->");
            ActionButton($$renderer4, {
              icon: Hard_drive,
              hasDropdown: true,
              dropdownPosition: "right",
              $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
                Dropdown($$renderer5, {
                  position: dropdownPosition,
                  minWidth: "12rem",
                  children: ($$renderer6) => {
                    DropdownHeader($$renderer6, { label: "Download status" });
                    $$renderer6.push(`<!----> `);
                    DropdownItem($$renderer6, {
                      label: "Downloaded",
                      selected: movieDownloadStatuses.has("downloaded")
                    });
                    $$renderer6.push(`<!----> `);
                    DropdownItem($$renderer6, {
                      label: "Missing",
                      selected: movieDownloadStatuses.has("missing")
                    });
                    $$renderer6.push(`<!---->`);
                  },
                  $$slots: { default: true }
                });
              } }
            });
          } else $$renderer4.push("<!--[-1-->");
          $$renderer4.push(`<!--]--> `);
          ViewToggle($$renderer4, {
            get value() {
              return viewMode;
            },
            set value($$value) {
              viewMode = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      fields,
      items,
      tags,
      filterStorageKey,
      searchStore,
      visibleColumns,
      toggleableColumns,
      columnLabels,
      visibleCardFields,
      toggleableCardFields,
      cardFieldLabels,
      onToggleCardField,
      refreshStatusText,
      refreshing,
      onToggleColumn,
      onFilterInfo,
      onRefresh,
      onOpen,
      instanceType,
      movieDownloadStatuses,
      onMovieDownloadStatusToggle,
      viewMode,
      expandAll,
      onToggleExpandAll,
      sortKey,
      sortDirection,
      onSort,
      useSimpleMode
    });
  });
}
function MovieAvailabilityBadge($$renderer, $$props) {
  let availability;
  let hasFile = $$props["hasFile"];
  let status = fallback($$props["status"], void 0);
  $: availability = status === "released" ? {
    label: "Missing",
    variant: "danger",
    icon: Circle_alert
  } : status === "inCinemas" || status === "announced" || status === "tba" ? {
    label: "Pending",
    variant: "info",
    icon: Clock_3
  } : {
    label: "No File",
    variant: "neutral",
    icon: File_question_mark
  };
  if (!hasFile) {
    $$renderer.push("<!--[0-->");
    Badge($$renderer, {
      variant: availability.variant,
      icon: availability.icon,
      children: ($$renderer2) => {
        $$renderer2.push(`<!---->${escape_html(availability.label)}`);
      },
      $$slots: { default: true }
    });
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]-->`);
  bind_props($$props, {
    hasFile,
    status
  });
}
function MovieRow($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let posterUrl;
    let row = $$props["row"];
    let column = $$props["column"];
    let mode = fallback($$props["mode"], "cell");
    function getProgressColor(progress, cutoffMet) {
      if (cutoffMet) return "bg-green-500 dark:bg-green-400";
      if (progress >= 0.75) return "bg-yellow-500 dark:bg-yellow-400";
      if (progress >= 0.5) return "bg-orange-500 dark:bg-orange-400";
      return "bg-red-500 dark:bg-red-400";
    }
    function fmtDate(isoString) {
      if (!isoString) return "-";
      return formatDate(isoString, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat), {
        month: "short",
        day: "numeric",
        year: "numeric"
      });
    }
    $: posterUrl = row.images?.find((i) => i.coverType === "poster")?.remoteUrl;
    if (mode === "cell") {
      $$renderer2.push("<!--[0-->");
      if (column.key === "monitored") {
        $$renderer2.push("<!--[0-->");
        IconCheckbox($$renderer2, {
          checked: row.monitored,
          icon: Check,
          color: row.monitored ? "accent" : "neutral",
          shape: "circle"
        });
      } else if (column.key === "title") {
        $$renderer2.push("<!--[1-->");
        $$renderer2.push(`<div class="flex items-center gap-3"><div class="h-12 w-8 flex-shrink-0 overflow-hidden rounded bg-neutral-200 dark:bg-neutral-800">`);
        if (posterUrl) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<img${attr("src", posterUrl)} alt="" loading="lazy" class="h-full w-full object-cover"/>`);
        } else {
          $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<div class="flex h-full w-full items-center justify-center">`);
          Film($$renderer2, {
            size: 12,
            class: "text-neutral-400 dark:text-neutral-600"
          });
          $$renderer2.push(`<!----></div>`);
        }
        $$renderer2.push(`<!--]--></div> <div class="min-w-0"><div class="flex flex-wrap items-center gap-2"><div class="font-medium text-neutral-900 dark:text-neutral-50">${escape_html(row.title)}</div> `);
        if (!row.hasFile) {
          $$renderer2.push("<!--[0-->");
          MovieAvailabilityBadge($$renderer2, {
            hasFile: row.hasFile,
            status: row.status
          });
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]--></div> `);
        if (row.year) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<div class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(row.year)}</div>`);
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]--></div></div>`);
      } else if (column.key === "qualityProfileName") {
        $$renderer2.push("<!--[2-->");
        Tooltip($$renderer2, {
          text: row.isProfilarrProfile ? "" : "Not managed by Profilarr",
          position: "top",
          children: ($$renderer3) => {
            Badge($$renderer3, {
              variant: row.isProfilarrProfile ? "accent" : "warning",
              icon: row.isProfilarrProfile ? null : Circle_alert,
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.qualityProfileName)}`);
              },
              $$slots: { default: true }
            });
          },
          $$slots: { default: true }
        });
      } else if (column.key === "qualityName") {
        $$renderer2.push("<!--[3-->");
        Badge($$renderer2, {
          variant: "neutral",
          mono: true,
          children: ($$renderer3) => {
            $$renderer3.push(`<!---->${escape_html(row.qualityName ?? "N/A")}`);
          },
          $$slots: { default: true }
        });
      } else if (column.key === "customFormatScore") {
        $$renderer2.push("<!--[4-->");
        $$renderer2.push(`<div class="text-right">`);
        Score($$renderer2, {
          score: row.customFormatScore,
          showSign: false,
          colored: false
        });
        $$renderer2.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">/ ${escape_html(row.cutoffScore.toLocaleString())}</span></div>`);
      } else if (column.key === "progress") {
        $$renderer2.push("<!--[5-->");
        $$renderer2.push(`<div class="flex items-center gap-2"><div class="h-2 flex-1 overflow-hidden rounded-full bg-neutral-200 dark:bg-neutral-700"><div${attr_class(`h-full rounded-full transition-all ${stringify(getProgressColor(row.progress, row.cutoffMet))}`)}${attr_style(`width: ${stringify(Math.max(0, Math.min(row.progress * 100, 100)))}%`)}></div></div> `);
        if (row.cutoffMet) {
          $$renderer2.push("<!--[0-->");
          Check($$renderer2, {
            size: 16,
            class: "flex-shrink-0 text-green-600 dark:text-green-400"
          });
        } else {
          $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<span class="w-10 text-right font-mono text-xs text-neutral-500 dark:text-neutral-400">${escape_html(Math.max(0, Math.min(Math.round(row.progress * 100), 100)))}%</span>`);
        }
        $$renderer2.push(`<!--]--></div>`);
      } else if (column.key === "releaseGroup") {
        $$renderer2.push("<!--[6-->");
        $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(row.releaseGroup ?? "-")}</span>`);
      } else if (column.key === "sizeOnDisk") {
        $$renderer2.push("<!--[7-->");
        $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">`);
        if (row.sizeOnDisk) {
          $$renderer2.push("<!--[0-->");
          const gb = row.sizeOnDisk / 1073741824;
          $$renderer2.push(`${escape_html(gb >= 1 ? `${gb.toFixed(1)} GB` : `${Math.round(row.sizeOnDisk / 1048576)} MB`)}`);
        } else {
          $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`-`);
        }
        $$renderer2.push(`<!--]--></span>`);
      } else if (column.key === "status") {
        $$renderer2.push("<!--[8-->");
        if (row.status === "released") {
          $$renderer2.push("<!--[0-->");
          Label($$renderer2, {
            variant: "success",
            size: "sm",
            children: ($$renderer3) => {
              if (Circle_check_big) {
                $$renderer3.push("<!--[-->");
                Circle_check_big($$renderer3, { size: 12 });
                $$renderer3.push("<!--]-->");
              } else {
                $$renderer3.push("<!--[!-->");
                $$renderer3.push("<!--]-->");
              }
              $$renderer3.push(` Released`);
            },
            $$slots: { default: true }
          });
        } else if (row.status === "inCinemas") {
          $$renderer2.push("<!--[1-->");
          Label($$renderer2, {
            variant: "warning",
            size: "sm",
            children: ($$renderer3) => {
              if (Clapperboard) {
                $$renderer3.push("<!--[-->");
                Clapperboard($$renderer3, { size: 12 });
                $$renderer3.push("<!--]-->");
              } else {
                $$renderer3.push("<!--[!-->");
                $$renderer3.push("<!--]-->");
              }
              $$renderer3.push(` In Cinemas`);
            },
            $$slots: { default: true }
          });
        } else if (row.status === "announced") {
          $$renderer2.push("<!--[2-->");
          Label($$renderer2, {
            variant: "info",
            size: "sm",
            children: ($$renderer3) => {
              if (Megaphone) {
                $$renderer3.push("<!--[-->");
                Megaphone($$renderer3, { size: 12 });
                $$renderer3.push("<!--]-->");
              } else {
                $$renderer3.push("<!--[!-->");
                $$renderer3.push("<!--]-->");
              }
              $$renderer3.push(` Announced`);
            },
            $$slots: { default: true }
          });
        } else {
          $$renderer2.push("<!--[-1-->");
          Label($$renderer2, {
            variant: "secondary",
            size: "sm",
            children: ($$renderer3) => {
              $$renderer3.push(`<!---->${escape_html(row.status ?? "-")}`);
            },
            $$slots: { default: true }
          });
        }
        $$renderer2.push(`<!--]-->`);
      } else if (column.key === "popularity") {
        $$renderer2.push("<!--[9-->");
        $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(row.popularity?.toFixed(1) ?? "-")}</span>`);
      } else if (column.key === "dateAdded") {
        $$renderer2.push("<!--[10-->");
        $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(fmtDate(row.dateAdded))}</span>`);
      } else if (column.key === "initialReleaseDate") {
        $$renderer2.push("<!--[11-->");
        $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(fmtDate(row.initialReleaseDate))}</span>`);
      } else if (column.key === "theatricalReleaseDate") {
        $$renderer2.push("<!--[12-->");
        $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(fmtDate(row.theatricalReleaseDate))}</span>`);
      } else if (column.key === "digitalReleaseDate") {
        $$renderer2.push("<!--[13-->");
        $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(fmtDate(row.digitalReleaseDate))}</span>`);
      } else if (column.key === "physicalReleaseDate") {
        $$renderer2.push("<!--[14-->");
        $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(fmtDate(row.physicalReleaseDate))}</span>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]-->`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="flex flex-col gap-3 p-4">`);
      if (!row.hasFile) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="text-sm text-neutral-600 dark:text-neutral-400">No file yet \u2014 this movie is still waiting for its big download debut.</div>`);
      } else {
        $$renderer2.push("<!--[-1-->");
        if (row.fileName) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<code class="font-mono text-xs break-all text-neutral-600 dark:text-neutral-400">${escape_html(row.fileName)}</code>`);
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]--> `);
        if (row.scoreBreakdown.length > 0) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<div class="flex flex-wrap items-center gap-2"><!--[-->`);
          const each_array = ensure_array_like([...row.scoreBreakdown].sort((a2, b3) => b3.score - a2.score));
          for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
            let item = each_array[$$index];
            CustomFormatBadge($$renderer2, {
              name: item.name,
              score: item.score
            });
          }
          $$renderer2.push(`<!--]--></div>`);
        } else {
          $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<div class="text-xs text-neutral-500 dark:text-neutral-400">No custom formats matched</div>`);
        }
        $$renderer2.push(`<!--]-->`);
      }
      $$renderer2.push(`<!--]--></div>`);
    }
    $$renderer2.push(`<!--]-->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      row,
      column,
      mode
    });
  });
}
function MovieRowSkeleton($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let column = $$props["column"];
    const widths = [
      "w-24",
      "w-32",
      "w-40",
      "w-28",
      "w-36"
    ];
    const randomWidth = () => widths[Math.floor(Math.random() * widths.length)];
    if (column.key === "title") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="space-y-1.5"><div${attr_class(`h-4 ${stringify(randomWidth())} animate-pulse rounded bg-neutral-200 dark:bg-neutral-700`)}></div> <div class="h-3 w-12 animate-pulse rounded bg-neutral-100 dark:bg-neutral-800"></div></div>`);
    } else if (column.key === "qualityProfileName") {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<div class="h-5 w-20 animate-pulse rounded-full bg-neutral-200 dark:bg-neutral-700"></div>`);
    } else if (column.key === "qualityName") {
      $$renderer2.push("<!--[2-->");
      $$renderer2.push(`<div class="h-6 w-16 animate-pulse rounded bg-neutral-100 dark:bg-neutral-800"></div>`);
    } else if (column.key === "customFormatScore") {
      $$renderer2.push("<!--[3-->");
      $$renderer2.push(`<div class="flex justify-end gap-1"><div class="h-4 w-10 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div> <div class="h-4 w-12 animate-pulse rounded bg-neutral-100 dark:bg-neutral-800"></div></div>`);
    } else if (column.key === "progress") {
      $$renderer2.push("<!--[4-->");
      $$renderer2.push(`<div class="flex items-center gap-2"><div class="h-2 flex-1 animate-pulse rounded-full bg-neutral-200 dark:bg-neutral-700"></div> <div class="h-4 w-8 animate-pulse rounded bg-neutral-100 dark:bg-neutral-800"></div></div>`);
    } else if (column.key === "popularity") {
      $$renderer2.push("<!--[5-->");
      $$renderer2.push(`<div class="h-4 w-8 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div>`);
    } else if (column.key === "dateAdded" || column.key === "initialReleaseDate" || column.key === "theatricalReleaseDate" || column.key === "digitalReleaseDate" || column.key === "physicalReleaseDate") {
      $$renderer2.push("<!--[6-->");
      $$renderer2.push(`<div class="h-4 w-16 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div>`);
    } else if (column.key === "actions") {
      $$renderer2.push("<!--[7-->");
      $$renderer2.push(`<div class="flex justify-center"><div class="h-7 w-7 animate-pulse rounded border border-neutral-200 dark:border-neutral-700"></div></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, { column });
  });
}
function RadarrTableView($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let columns;
    let data = $$props["data"];
    let loading = fallback($$props["loading"], false);
    let baseUrl = fallback($$props["baseUrl"], "");
    let expandAll = fallback($$props["expandAll"], false);
    let emptyMessage = fallback($$props["emptyMessage"], "No movies with files");
    let visibleColumns = $$props["visibleColumns"];
    let expandedRows = /* @__PURE__ */ new Set();
    const allColumns = [
      {
        key: "title",
        header: "Title",
        align: "left",
        sortable: true,
        sortAccessor: (row) => sortTitle(row.title)
      },
      {
        key: "status",
        header: "Status",
        align: "left",
        width: "w-28",
        sortable: true
      },
      {
        key: "qualityName",
        header: "Quality",
        align: "left",
        width: "w-32",
        sortable: true
      },
      {
        key: "qualityProfileName",
        header: "Profile",
        align: "left",
        width: "w-40",
        sortable: true
      },
      {
        key: "score",
        header: "Score",
        align: "right",
        width: "w-48",
        sortable: true,
        sortAccessor: (row) => row.customFormatScore,
        defaultSortDirection: "desc"
      },
      {
        key: "sizeOnDisk",
        header: "Size",
        align: "right",
        width: "w-24",
        sortable: true,
        sortAccessor: (row) => row.sizeOnDisk ?? 0,
        defaultSortDirection: "desc"
      },
      {
        key: "popularity",
        header: "Popularity",
        align: "right",
        width: "w-24",
        sortable: true,
        defaultSortDirection: "desc"
      },
      {
        key: "dateAdded",
        header: "Added",
        align: "right",
        width: "w-28",
        sortable: true,
        sortAccessor: (row) => row.dateAdded ? new Date(row.dateAdded).getTime() : 0,
        defaultSortDirection: "desc"
      },
      {
        key: "initialReleaseDate",
        header: "Initial Release",
        align: "right",
        width: "w-32",
        sortable: true,
        sortAccessor: (row) => dateSortValue(row.initialReleaseDate),
        defaultSortDirection: "desc",
        sortNullsLast: true
      },
      {
        key: "theatricalReleaseDate",
        header: "Theatrical Release",
        align: "right",
        width: "w-40",
        sortable: true,
        sortAccessor: (row) => dateSortValue(row.theatricalReleaseDate),
        defaultSortDirection: "desc",
        sortNullsLast: true
      },
      {
        key: "digitalReleaseDate",
        header: "Digital Release",
        align: "right",
        width: "w-36",
        sortable: true,
        sortAccessor: (row) => dateSortValue(row.digitalReleaseDate),
        defaultSortDirection: "desc",
        sortNullsLast: true
      },
      {
        key: "physicalReleaseDate",
        header: "Physical Release",
        align: "right",
        width: "w-36",
        sortable: true,
        sortAccessor: (row) => dateSortValue(row.physicalReleaseDate),
        defaultSortDirection: "desc",
        sortNullsLast: true
      },
      {
        key: "releaseGroup",
        header: "Release Group",
        align: "left",
        width: "w-36",
        sortable: true
      }
    ];
    const defaultSort = {
      key: "title",
      direction: "asc"
    };
    const skeletonData = Array.from({ length: 12 }, (_3, i) => ({
      id: `skeleton-${i}`,
      title: "",
      year: 0,
      tmdbId: 0,
      hasFile: true,
      monitored: true,
      qualityProfileId: 0,
      qualityProfileName: "",
      isProfilarrProfile: false,
      qualityName: null,
      customFormatScore: 0,
      cutoffScore: 0,
      cutoffMet: false,
      progress: 0,
      popularity: 0,
      dateAdded: "",
      fileName: null,
      scoreBreakdown: []
    }));
    $: if (expandAll) expandedRows = new Set(data.map((row) => row.id));
    else expandedRows = /* @__PURE__ */ new Set();
    $: columns = allColumns.filter((col) => col.key === "title" || col.key === "qualityProfileName" || visibleColumns.has(col.key));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      ExpandableTable($$renderer3, {
        columns,
        data: loading ? skeletonData : data,
        getRowId: (row) => row.id,
        compact: true,
        defaultSort,
        pageSize: 25,
        responsive: true,
        flushExpanded: true,
        emptyMessage,
        get expandedRows() {
          return expandedRows;
        },
        set expandedRows($$value) {
          expandedRows = $$value;
          $$settled = false;
        },
        $$slots: {
          cell: ($$renderer4, { row, column }) => {
            if (loading) {
              $$renderer4.push("<!--[0-->");
              MovieRowSkeleton($$renderer4, { column });
            } else if (column.key === "score") {
              $$renderer4.push("<!--[1-->");
              ProgressIndicator($$renderer4, {
                current: row.customFormatScore,
                target: row.cutoffScore,
                met: row.cutoffMet,
                mode: "compact"
              });
            } else {
              $$renderer4.push("<!--[-1-->");
              MovieRow($$renderer4, {
                row,
                column,
                mode: "cell"
              });
            }
            $$renderer4.push(`<!--]-->`);
          },
          actions: ($$renderer4, { row }) => {
            if (!loading && row.tmdbId) {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                icon: External_link,
                size: "xs",
                variant: "secondary",
                href: `${stringify(baseUrl)}/movie/${stringify(row.tmdbId)}`,
                target: "_blank",
                rel: "noopener noreferrer",
                tooltip: "Open in Radarr"
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          expanded: ($$renderer4, { row }) => {
            if (!loading) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="p-4">`);
              MovieRow($$renderer4, {
                row,
                column: allColumns[0],
                mode: "expanded"
              });
              $$renderer4.push(`<!----></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          }
        }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      data,
      loading,
      baseUrl,
      expandAll,
      emptyMessage,
      visibleColumns
    });
  });
}
function primaryReleaseGroup(groups, highlightGroups = []) {
  if (groups.length === 0) return "";
  return groups.find((group) => highlightGroups.some((filter) => group.toLowerCase().includes(filter.toLowerCase()))) ?? groups[0];
}
function SeriesRow($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let posterUrl;
    let row = $$props["row"];
    let column = $$props["column"];
    let highlightGroups = fallback($$props["highlightGroups"], () => [], true);
    function formatSize2(bytes) {
      if (!bytes) return "-";
      const gb = bytes / 1073741824;
      if (gb >= 1) return `${gb.toFixed(1)} GB`;
      return `${(bytes / 1048576).toFixed(0)} MB`;
    }
    function fmtDate(isoString) {
      if (!isoString) return "-";
      return formatDate(isoString, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat), {
        month: "short",
        day: "numeric",
        year: "numeric"
      });
    }
    $: posterUrl = row.images?.find((i) => i.coverType === "poster")?.remoteUrl;
    if (column.key === "monitored") {
      $$renderer2.push("<!--[0-->");
      IconCheckbox($$renderer2, {
        checked: row.monitored,
        icon: Check,
        color: row.monitored ? "accent" : "neutral",
        shape: "circle"
      });
    } else if (column.key === "title") {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<div class="flex items-center gap-3"><div class="h-12 w-8 flex-shrink-0 overflow-hidden rounded bg-neutral-200 dark:bg-neutral-800">`);
      if (posterUrl) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<img${attr("src", posterUrl)} alt="" loading="lazy" class="h-full w-full object-cover"/>`);
      } else {
        $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<div class="flex h-full w-full items-center justify-center">`);
        Tv($$renderer2, {
          size: 12,
          class: "text-neutral-400 dark:text-neutral-600"
        });
        $$renderer2.push(`<!----></div>`);
      }
      $$renderer2.push(`<!--]--></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-50">${escape_html(row.title)}</div> `);
      if (row.year) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(row.year)}</div>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div></div>`);
    } else if (column.key === "qualityProfileName") {
      $$renderer2.push("<!--[2-->");
      Tooltip($$renderer2, {
        text: row.isProfilarrProfile ? "" : "Not managed by Profilarr",
        position: "top",
        children: ($$renderer3) => {
          Badge($$renderer3, {
            variant: row.isProfilarrProfile ? "accent" : "warning",
            icon: row.isProfilarrProfile ? null : Circle_alert,
            mono: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(row.qualityProfileName)}`);
            },
            $$slots: { default: true }
          });
        },
        $$slots: { default: true }
      });
    } else if (column.key === "episodes") {
      $$renderer2.push("<!--[3-->");
      Badge($$renderer2, {
        variant: row.episodeFileCount === row.episodeCount ? "success" : "neutral",
        mono: true,
        children: ($$renderer3) => {
          $$renderer3.push(`<!---->${escape_html(row.episodeFileCount)}/${escape_html(row.episodeCount)}`);
        },
        $$slots: { default: true }
      });
    } else if (column.key === "status") {
      $$renderer2.push("<!--[4-->");
      if (row.status === "continuing") {
        $$renderer2.push("<!--[0-->");
        Label($$renderer2, {
          variant: "success",
          size: "sm",
          children: ($$renderer3) => {
            if (Play) {
              $$renderer3.push("<!--[-->");
              Play($$renderer3, { size: 12 });
              $$renderer3.push("<!--]-->");
            } else {
              $$renderer3.push("<!--[!-->");
              $$renderer3.push("<!--]-->");
            }
            $$renderer3.push(` Continuing`);
          },
          $$slots: { default: true }
        });
      } else if (row.status === "ended") {
        $$renderer2.push("<!--[1-->");
        Label($$renderer2, {
          variant: "secondary",
          size: "sm",
          children: ($$renderer3) => {
            if (Square) {
              $$renderer3.push("<!--[-->");
              Square($$renderer3, { size: 12 });
              $$renderer3.push("<!--]-->");
            } else {
              $$renderer3.push("<!--[!-->");
              $$renderer3.push("<!--]-->");
            }
            $$renderer3.push(` Ended`);
          },
          $$slots: { default: true }
        });
      } else if (row.status === "upcoming") {
        $$renderer2.push("<!--[2-->");
        Label($$renderer2, {
          variant: "info",
          size: "sm",
          children: ($$renderer3) => {
            if (Clock) {
              $$renderer3.push("<!--[-->");
              Clock($$renderer3, { size: 12 });
              $$renderer3.push("<!--]-->");
            } else {
              $$renderer3.push("<!--[!-->");
              $$renderer3.push("<!--]-->");
            }
            $$renderer3.push(` Upcoming`);
          },
          $$slots: { default: true }
        });
      } else {
        $$renderer2.push("<!--[-1-->");
        Label($$renderer2, {
          variant: "secondary",
          size: "sm",
          children: ($$renderer3) => {
            $$renderer3.push(`<!---->${escape_html(row.status ?? "-")}`);
          },
          $$slots: { default: true }
        });
      }
      $$renderer2.push(`<!--]-->`);
    } else if (column.key === "releaseGroups") {
      $$renderer2.push("<!--[5-->");
      const groups = row.releaseGroups ?? [];
      if (groups.length > 0) {
        $$renderer2.push("<!--[0-->");
        Tooltip($$renderer2, {
          text: groups.length > 1 ? groups.join(", ") : "",
          position: "top",
          children: ($$renderer3) => {
            $$renderer3.push(`<span class="truncate font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(primaryReleaseGroup(groups, highlightGroups))} `);
            if (groups.length > 1) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<span class="text-neutral-500 dark:text-neutral-400">+${escape_html(groups.length - 1)}</span>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></span>`);
          },
          $$slots: { default: true }
        });
      } else {
        $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">-</span>`);
      }
      $$renderer2.push(`<!--]-->`);
    } else if (column.key === "sizeOnDisk") {
      $$renderer2.push("<!--[6-->");
      $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(formatSize2(row.sizeOnDisk))}</span>`);
    } else if (column.key === "dateAdded") {
      $$renderer2.push("<!--[7-->");
      $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(fmtDate(row.dateAdded))}</span>`);
    } else if (column.key === "firstAired") {
      $$renderer2.push("<!--[8-->");
      $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(fmtDate(row.firstAired))}</span>`);
    } else if (column.key === "previousAiring") {
      $$renderer2.push("<!--[9-->");
      $$renderer2.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(fmtDate(row.previousAiring))}</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      row,
      column,
      highlightGroups
    });
  });
}
function SeriesRowSkeleton($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let column = $$props["column"];
    const widths = [
      "w-24",
      "w-32",
      "w-40",
      "w-28",
      "w-36"
    ];
    const randomWidth = () => widths[Math.floor(Math.random() * widths.length)];
    if (column.key === "title") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="space-y-1.5"><div${attr_class(`h-4 ${stringify(randomWidth())} animate-pulse rounded bg-neutral-200 dark:bg-neutral-700`)}></div> <div class="h-3 w-12 animate-pulse rounded bg-neutral-100 dark:bg-neutral-800"></div></div>`);
    } else if (column.key === "qualityProfileName") {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<div class="h-5 w-20 animate-pulse rounded-full bg-neutral-200 dark:bg-neutral-700"></div>`);
    } else if (column.key === "episodes") {
      $$renderer2.push("<!--[2-->");
      $$renderer2.push(`<div class="h-5 w-14 animate-pulse rounded-full bg-neutral-200 dark:bg-neutral-700"></div>`);
    } else if (column.key === "sizeOnDisk") {
      $$renderer2.push("<!--[3-->");
      $$renderer2.push(`<div class="h-4 w-16 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div>`);
    } else if (column.key === "releaseGroups") {
      $$renderer2.push("<!--[4-->");
      $$renderer2.push(`<div class="h-4 w-20 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div>`);
    } else if (column.key === "dateAdded" || column.key === "firstAired" || column.key === "previousAiring") {
      $$renderer2.push("<!--[5-->");
      $$renderer2.push(`<div class="h-4 w-16 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, { column });
  });
}
function EpisodeTable($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let sortedEpisodes;
    let episodes = $$props["episodes"];
    function formatSize2(bytes) {
      if (!bytes) return "-";
      const gb = bytes / 1073741824;
      if (gb >= 1) return `${gb.toFixed(1)} GB`;
      return `${(bytes / 1048576).toFixed(0)} MB`;
    }
    const columns = [
      {
        key: "episodeNumber",
        header: "Ep",
        align: "center",
        width: "w-12",
        sortable: true
      },
      {
        key: "title",
        header: "Title",
        align: "left",
        sortable: true
      },
      {
        key: "qualityName",
        header: "Quality",
        align: "left",
        width: "w-28",
        sortable: true
      },
      {
        key: "progress",
        header: "Score",
        align: "right",
        width: "w-76",
        sortable: true,
        sortAccessor: (row) => row.customFormatScore,
        defaultSortDirection: "desc"
      }
    ];
    $: sortedEpisodes = [...episodes].sort((a2, b3) => a2.episodeNumber - b3.episodeNumber);
    ExpandableTable($$renderer2, {
      columns,
      data: sortedEpisodes,
      getRowId: (row) => row.id,
      compact: true,
      flushExpanded: true,
      chevronPosition: "right",
      emptyMessage: "No episodes",
      disableExpandWhen: (row) => !row.hasFile || row.scoreBreakdown.length === 0 && !row.fileName,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "episodeNumber") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="font-mono text-xs text-neutral-500 dark:text-neutral-400">${escape_html(row.episodeNumber)}</span>`);
          } else if (column.key === "title") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div><span class="text-sm text-neutral-900 dark:text-neutral-100">${escape_html(row.title)}</span> `);
            if (row.size) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<span class="ml-2 font-mono text-xs text-neutral-400">${escape_html(formatSize2(row.size))}</span>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div>`);
          } else if (column.key === "qualityName") {
            $$renderer3.push("<!--[2-->");
            Badge($$renderer3, {
              variant: "neutral",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.qualityName ?? "N/A")}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "progress") {
            $$renderer3.push("<!--[3-->");
            if (row.hasFile) {
              $$renderer3.push("<!--[0-->");
              ProgressIndicator($$renderer3, {
                current: row.customFormatScore,
                target: row.cutoffScore,
                met: row.cutoffMet,
                mode: "compact"
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]-->`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        expanded: ($$renderer3, { row }) => {
          $$renderer3.push(`<div class="flex flex-col gap-2 px-4 py-2">`);
          if (row.fileName) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<code class="font-mono text-xs break-all text-neutral-600 dark:text-neutral-400">${escape_html(row.fileName)}</code>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          if (row.scoreBreakdown.length > 0) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex flex-wrap items-center gap-1.5"><!--[-->`);
            const each_array = ensure_array_like([...row.scoreBreakdown].sort((a2, b3) => b3.score - a2.score));
            for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
              let item = each_array[$$index];
              CustomFormatBadge($$renderer3, {
                name: item.name,
                score: item.score
              });
            }
            $$renderer3.push(`<!--]--></div>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<div class="text-xs text-neutral-500 dark:text-neutral-400">No custom formats matched</div>`);
          }
          $$renderer3.push(`<!--]--></div>`);
        }
      }
    });
    bind_props($$props, { episodes });
  });
}
function SeasonTable($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let visibleSeasons;
    let seasons = $$props["seasons"];
    let episodesBySeasonNumber = $$props["episodesBySeasonNumber"];
    let loadingSeasons = fallback($$props["loadingSeasons"], () => /* @__PURE__ */ new Set(), true);
    let onExpandSeason = fallback($$props["onExpandSeason"], void 0);
    let expandedRows = /* @__PURE__ */ new Set();
    function formatSize2(bytes) {
      if (!bytes) return "-";
      const gb = bytes / 1073741824;
      if (gb >= 1) return `${gb.toFixed(1)} GB`;
      return `${(bytes / 1048576).toFixed(0)} MB`;
    }
    function getSeasonLabel(seasonNumber) {
      return seasonNumber === 0 ? "Specials" : `Season ${seasonNumber}`;
    }
    const columns = [
      {
        key: "seasonNumber",
        header: "Season",
        align: "left",
        sortable: true
      },
      {
        key: "episodeFileCount",
        header: "Episodes",
        align: "right",
        width: "w-36",
        sortable: true,
        defaultSortDirection: "desc"
      },
      {
        key: "sizeOnDisk",
        header: "Size",
        align: "right",
        width: "w-24",
        sortable: true,
        sortAccessor: (row) => row.sizeOnDisk,
        defaultSortDirection: "desc"
      }
    ];
    $: if (onExpandSeason && expandedRows.size > 0) for (const id of expandedRows) onExpandSeason(typeof id === "string" ? parseInt(id) : id);
    $: visibleSeasons = seasons.filter((s3) => s3.totalEpisodeCount > 0).sort((a2, b3) => a2.seasonNumber - b3.seasonNumber);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      ExpandableTable($$renderer3, {
        columns,
        data: visibleSeasons,
        getRowId: (row) => row.seasonNumber,
        compact: true,
        flushExpanded: true,
        chevronPosition: "right",
        emptyMessage: "No seasons",
        disableExpandWhen: (row) => row.episodeFileCount === 0,
        get expandedRows() {
          return expandedRows;
        },
        set expandedRows($$value) {
          expandedRows = $$value;
          $$settled = false;
        },
        $$slots: {
          cell: ($$renderer4, { row, column }) => {
            if (column.key === "seasonNumber") {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="font-medium text-neutral-900 dark:text-neutral-100">${escape_html(getSeasonLabel(row.seasonNumber))}</span>`);
            } else if (column.key === "episodeFileCount") {
              $$renderer4.push("<!--[1-->");
              ProgressIndicator($$renderer4, {
                current: row.episodeFileCount,
                target: row.episodeCount,
                met: row.episodeFileCount === row.episodeCount,
                mode: "compact"
              });
            } else if (column.key === "sizeOnDisk") {
              $$renderer4.push("<!--[2-->");
              $$renderer4.push(`<span class="font-mono text-xs text-neutral-700 dark:text-neutral-300">${escape_html(formatSize2(row.sizeOnDisk))}</span>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          expanded: ($$renderer4, { row }) => {
            if (loadingSeasons.has(row.seasonNumber)) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="flex items-center gap-2 p-4 text-sm text-neutral-500 dark:text-neutral-400"><div class="h-4 w-4 animate-spin rounded-full border-2 border-neutral-300 border-t-accent-500"></div> Loading episodes...</div>`);
            } else {
              $$renderer4.push("<!--[-1-->");
              const seasonEpisodes = episodesBySeasonNumber.get(row.seasonNumber) ?? [];
              $$renderer4.push(`<div class="p-4">`);
              EpisodeTable($$renderer4, { episodes: seasonEpisodes });
              $$renderer4.push(`<!----></div>`);
            }
            $$renderer4.push(`<!--]-->`);
          }
        }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      seasons,
      episodesBySeasonNumber,
      loadingSeasons,
      onExpandSeason
    });
  });
}
function SonarrTableView($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let columns;
    let data = $$props["data"];
    let loading = fallback($$props["loading"], false);
    let baseUrl = fallback($$props["baseUrl"], "");
    let expandAll = fallback($$props["expandAll"], false);
    let instanceId = $$props["instanceId"];
    let emptyMessage = fallback($$props["emptyMessage"], "No series found");
    let visibleColumns = $$props["visibleColumns"];
    let highlightGroups = fallback($$props["highlightGroups"], () => [], true);
    const allColumns = [
      {
        key: "title",
        header: "Title",
        align: "left",
        sortable: true,
        sortAccessor: (row) => sortTitle(row.title)
      },
      {
        key: "status",
        header: "Status",
        align: "left",
        width: "w-28",
        sortable: true
      },
      {
        key: "qualityProfileName",
        header: "Profile",
        align: "left",
        width: "w-40",
        sortable: true
      },
      {
        key: "episodes",
        header: "Episodes",
        align: "right",
        width: "w-36",
        sortable: true,
        sortAccessor: (row) => row.percentOfEpisodes,
        defaultSortDirection: "desc"
      },
      {
        key: "sizeOnDisk",
        header: "Size",
        align: "right",
        width: "w-32",
        sortable: true,
        sortAccessor: (row) => row.sizeOnDisk,
        defaultSortDirection: "desc"
      },
      {
        key: "releaseGroups",
        header: "Release Group(s)",
        align: "left",
        width: "w-40",
        sortable: true,
        sortAccessor: (row) => row.releaseGroups?.[0] ?? ""
      },
      {
        key: "dateAdded",
        header: "Added",
        align: "right",
        width: "w-28",
        sortable: true,
        sortAccessor: (row) => row.dateAdded ? new Date(row.dateAdded).getTime() : 0,
        defaultSortDirection: "desc"
      },
      {
        key: "firstAired",
        header: "Series Premiere",
        align: "right",
        width: "w-36",
        sortable: true,
        sortAccessor: (row) => dateSortValue(row.firstAired),
        defaultSortDirection: "desc",
        sortNullsLast: true
      },
      {
        key: "previousAiring",
        header: "Latest Aired Episode",
        align: "right",
        width: "w-44",
        sortable: true,
        sortAccessor: (row) => dateSortValue(row.previousAiring),
        defaultSortDirection: "desc",
        sortNullsLast: true
      }
    ];
    const defaultSort = {
      key: "title",
      direction: "asc"
    };
    const skeletonData = Array.from({ length: 12 }, (_3, i) => ({
      id: i,
      title: "",
      year: 0,
      qualityProfileId: 0,
      qualityProfileName: "",
      monitored: true,
      monitoredState: "monitored",
      seasonCount: 0,
      episodeCount: 0,
      episodeFileCount: 0,
      totalEpisodeCount: 0,
      sizeOnDisk: 0,
      percentOfEpisodes: 0,
      dateAdded: "",
      isProfilarrProfile: false
    }));
    let seasonsCache = /* @__PURE__ */ new Map();
    let seasonsLoadingSet = /* @__PURE__ */ new Set();
    let episodeCache = /* @__PURE__ */ new Map();
    let episodeLoadingSet = /* @__PURE__ */ new Set();
    const episodeKey = (seriesId, seasonNumber) => `${seriesId}:${seasonNumber}`;
    async function loadSeasons(seriesId) {
      if (seasonsCache.has(seriesId) || seasonsLoadingSet.has(seriesId)) return;
      seasonsLoadingSet.add(seriesId);
      seasonsLoadingSet = seasonsLoadingSet;
      try {
        const response = await fetch(`/arr/${instanceId}/library/series/${seriesId}/seasons`);
        if (!response.ok) throw new Error("Failed to fetch seasons");
        const result = await response.json();
        seasonsCache.set(seriesId, result.seasons);
        seasonsCache = seasonsCache;
      } catch (err) {
        console.error(`Failed to load seasons for series ${seriesId}:`, err);
      } finally {
        seasonsLoadingSet.delete(seriesId);
        seasonsLoadingSet = seasonsLoadingSet;
      }
    }
    async function loadSeasonEpisodes(seriesId, seasonNumber) {
      const key2 = episodeKey(seriesId, seasonNumber);
      if (episodeCache.has(key2) || episodeLoadingSet.has(key2)) return;
      episodeLoadingSet.add(key2);
      episodeLoadingSet = episodeLoadingSet;
      try {
        const response = await fetch(`/arr/${instanceId}/library/series/${seriesId}/seasons/${seasonNumber}/episodes`);
        if (!response.ok) throw new Error("Failed to fetch episodes");
        const result = await response.json();
        episodeCache.set(key2, result.episodes);
        episodeCache = episodeCache;
      } catch (err) {
        console.error(`Failed to load episodes for series ${seriesId} season ${seasonNumber}:`, err);
      } finally {
        episodeLoadingSet.delete(key2);
        episodeLoadingSet = episodeLoadingSet;
      }
    }
    function episodesForSeries(cache3, seriesId) {
      const result = /* @__PURE__ */ new Map();
      const prefix = `${seriesId}:`;
      for (const [key2, episodes] of cache3) {
        if (!key2.startsWith(prefix)) continue;
        const seasonNumber = Number(key2.slice(prefix.length));
        result.set(seasonNumber, episodes);
      }
      return result;
    }
    function episodeLoadingForSeries(loadingSet, seriesId) {
      const result = /* @__PURE__ */ new Set();
      const prefix = `${seriesId}:`;
      for (const key2 of loadingSet) {
        if (!key2.startsWith(prefix)) continue;
        result.add(Number(key2.slice(prefix.length)));
      }
      return result;
    }
    let expandedRows = /* @__PURE__ */ new Set();
    let previousExpandAll = expandAll;
    function resetEpisodeCache() {
      seasonsCache = /* @__PURE__ */ new Map();
      seasonsLoadingSet = /* @__PURE__ */ new Set();
      episodeCache = /* @__PURE__ */ new Map();
      episodeLoadingSet = /* @__PURE__ */ new Set();
    }
    $: columns = allColumns.filter((col) => col.key === "title" || col.key === "qualityProfileName" || visibleColumns.has(col.key));
    $: if (expandAll !== previousExpandAll) {
      expandedRows = expandAll ? new Set(data.map((row) => row.id)) : /* @__PURE__ */ new Set();
      previousExpandAll = expandAll;
    }
    $: if (expandedRows.size > 0) for (const id of expandedRows) loadSeasons(typeof id === "string" ? parseInt(id) : id);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      ExpandableTable($$renderer3, {
        columns,
        data: loading ? skeletonData : data,
        getRowId: (row) => row.id,
        compact: true,
        defaultSort,
        pageSize: 25,
        responsive: true,
        flushExpanded: true,
        emptyMessage,
        get expandedRows() {
          return expandedRows;
        },
        set expandedRows($$value) {
          expandedRows = $$value;
          $$settled = false;
        },
        $$slots: {
          cell: ($$renderer4, { row, column }) => {
            if (loading) {
              $$renderer4.push("<!--[0-->");
              SeriesRowSkeleton($$renderer4, { column });
            } else if (column.key === "episodes") {
              $$renderer4.push("<!--[1-->");
              ProgressIndicator($$renderer4, {
                current: row.episodeFileCount,
                target: row.episodeCount,
                met: row.episodeFileCount === row.episodeCount,
                mode: "compact"
              });
            } else {
              $$renderer4.push("<!--[-1-->");
              SeriesRow($$renderer4, {
                row,
                column,
                highlightGroups
              });
            }
            $$renderer4.push(`<!--]-->`);
          },
          actions: ($$renderer4, { row }) => {
            if (!loading && row.tvdbId) {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                icon: External_link,
                size: "xs",
                variant: "secondary",
                href: `${stringify(baseUrl)}/series/${stringify(row.titleSlug ?? row.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""))}`,
                target: "_blank",
                rel: "noopener noreferrer",
                tooltip: "Open in Sonarr"
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          expanded: ($$renderer4, { row }) => {
            if (!loading) {
              $$renderer4.push("<!--[0-->");
              const seriesId = row.id;
              const isSeasonsLoading = seasonsLoadingSet.has(seriesId);
              const seasons = seasonsCache.get(seriesId) ?? [];
              const episodesBySeasonNumber = episodesForSeries(episodeCache, seriesId);
              const loadingSeasons = episodeLoadingForSeries(episodeLoadingSet, seriesId);
              if (isSeasonsLoading) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="flex items-center gap-2 p-4 text-sm text-neutral-500 dark:text-neutral-400"><div class="h-4 w-4 animate-spin rounded-full border-2 border-neutral-300 border-t-accent-500"></div> Loading seasons...</div>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<div class="p-4">`);
                SeasonTable($$renderer4, {
                  seasons,
                  episodesBySeasonNumber,
                  loadingSeasons,
                  onExpandSeason: (seasonNumber) => loadSeasonEpisodes(seriesId, seasonNumber)
                });
                $$renderer4.push(`<!----></div>`);
              }
              $$renderer4.push(`<!--]-->`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          }
        }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      data,
      loading,
      baseUrl,
      expandAll,
      instanceId,
      emptyMessage,
      visibleColumns,
      highlightGroups,
      resetEpisodeCache
    });
  });
}
function LibraryCardGrid($$renderer, $$props) {
  let minCardWidth;
  let columns = fallback($$props["columns"], 8);
  let gap = fallback($$props["gap"], "md");
  const gapClasses = {
    sm: "gap-2",
    md: "gap-4",
    lg: "gap-6"
  };
  $: minCardWidth = Math.max(100, Math.floor(1200 / Math.max(1, Math.floor(columns))));
  $$renderer.push(`<div${attr_class(`library-card-grid grid ${stringify(gapClasses[gap])}`, "svelte-j1uxno")}${attr_style(`--library-card-min-width: ${minCardWidth}px;`)}><!--[-->`);
  slot($$renderer, $$props, "default", {}, null);
  $$renderer.push(`<!--]--></div>`);
  bind_props($$props, {
    columns,
    gap
  });
}
function MovieCard($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let posterUrl;
    let movie = $$props["movie"];
    let baseUrl = fallback($$props["baseUrl"], "");
    let visibleFields = fallback($$props["visibleFields"], () => /* @__PURE__ */ new Set(), true);
    let detailOpen = false;
    function formatSize2(bytes) {
      if (!bytes) return "";
      const gb = bytes / 1073741824;
      if (gb >= 1) return `${gb.toFixed(1)} GB`;
      return `${(bytes / 1048576).toFixed(0)} MB`;
    }
    $: posterUrl = movie.images?.find((i) => i.coverType === "poster")?.remoteUrl;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="group flex flex-col overflow-hidden rounded-xl border border-neutral-300 bg-neutral-50 transition-colors dark:border-neutral-700/60 dark:bg-neutral-900"><a${attr("href", `${stringify(baseUrl)}/movie/${stringify(movie.tmdbId)}`)} target="_blank" rel="noopener noreferrer" class="relative aspect-[2/3] w-full overflow-hidden bg-neutral-200 dark:bg-neutral-800">`);
      if (posterUrl) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<img${attr("src", posterUrl)}${attr("alt", movie.title)} loading="lazy" class="h-full w-full object-cover"/>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<div class="flex h-full w-full items-center justify-center">`);
        Film($$renderer3, { class: "h-12 w-12 text-neutral-400 dark:text-neutral-600" });
        $$renderer3.push(`<!----></div>`);
      }
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("monitored")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="absolute top-2 left-2">`);
        IconCheckbox($$renderer3, {
          checked: movie.monitored,
          icon: Check,
          color: movie.monitored ? "green" : "neutral",
          shape: "circle"
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> <div class="absolute top-2 right-2 opacity-0 transition-opacity group-hover:opacity-100">`);
      Button($$renderer3, {
        icon: Info,
        size: "xs",
        variant: "secondary",
        tooltip: movie.hasFile ? "File details" : "Movie details"
      });
      $$renderer3.push(`<!----></div></a> <div class="flex flex-1 flex-col gap-2 p-3">`);
      if (!movie.hasFile) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div>`);
        MovieAvailabilityBadge($$renderer3, {
          hasFile: movie.hasFile,
          status: movie.status
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("title")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<h3 class="truncate text-sm font-semibold text-neutral-900 dark:text-neutral-100"${attr("title", movie.title)}>${escape_html(movie.title)}</h3>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("year") && movie.year) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(movie.year)}</span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("profile") || visibleFields.has("size")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="flex items-center justify-between gap-1.5">`);
        if (visibleFields.has("profile")) {
          $$renderer3.push("<!--[0-->");
          Tooltip($$renderer3, {
            text: movie.isProfilarrProfile ? "" : "Not managed by Profilarr",
            position: "top",
            children: ($$renderer4) => {
              Badge($$renderer4, {
                variant: movie.isProfilarrProfile ? "accent" : "warning",
                icon: movie.isProfilarrProfile ? null : Circle_alert,
                mono: true,
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->${escape_html(movie.qualityProfileName)}`);
                },
                $$slots: { default: true }
              });
            },
            $$slots: { default: true }
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        if (visibleFields.has("size") && movie.hasFile && movie.sizeOnDisk) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<span class="font-mono text-xs text-neutral-500 dark:text-neutral-400">${escape_html(formatSize2(movie.sizeOnDisk))}</span>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("status") && movie.status) {
        $$renderer3.push("<!--[0-->");
        if (movie.status === "released") {
          $$renderer3.push("<!--[0-->");
          Label($$renderer3, {
            variant: "success",
            size: "sm",
            children: ($$renderer4) => {
              if (Circle_check_big) {
                $$renderer4.push("<!--[-->");
                Circle_check_big($$renderer4, { size: 12 });
                $$renderer4.push("<!--]-->");
              } else {
                $$renderer4.push("<!--[!-->");
                $$renderer4.push("<!--]-->");
              }
              $$renderer4.push(` Released`);
            },
            $$slots: { default: true }
          });
        } else if (movie.status === "inCinemas") {
          $$renderer3.push("<!--[1-->");
          Label($$renderer3, {
            variant: "warning",
            size: "sm",
            children: ($$renderer4) => {
              if (Clapperboard) {
                $$renderer4.push("<!--[-->");
                Clapperboard($$renderer4, { size: 12 });
                $$renderer4.push("<!--]-->");
              } else {
                $$renderer4.push("<!--[!-->");
                $$renderer4.push("<!--]-->");
              }
              $$renderer4.push(` In Cinemas`);
            },
            $$slots: { default: true }
          });
        } else if (movie.status === "announced") {
          $$renderer3.push("<!--[2-->");
          Label($$renderer3, {
            variant: "info",
            size: "sm",
            children: ($$renderer4) => {
              if (Megaphone) {
                $$renderer4.push("<!--[-->");
                Megaphone($$renderer4, { size: 12 });
                $$renderer4.push("<!--]-->");
              } else {
                $$renderer4.push("<!--[!-->");
                $$renderer4.push("<!--]-->");
              }
              $$renderer4.push(` Announced`);
            },
            $$slots: { default: true }
          });
        } else {
          $$renderer3.push("<!--[-1-->");
          Label($$renderer3, {
            variant: "secondary",
            size: "sm",
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(movie.status)}`);
            },
            $$slots: { default: true }
          });
        }
        $$renderer3.push(`<!--]-->`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("quality") && movie.hasFile && movie.qualityName) {
        $$renderer3.push("<!--[0-->");
        Badge($$renderer3, {
          variant: "neutral",
          mono: true,
          children: ($$renderer4) => {
            $$renderer4.push(`<!---->${escape_html(movie.qualityName)}`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("releaseGroup") && movie.hasFile && movie.releaseGroup) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Users($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> <span class="truncate font-mono">${escape_html(movie.releaseGroup)}</span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("score") && movie.hasFile) {
        $$renderer3.push("<!--[0-->");
        ProgressIndicator($$renderer3, {
          current: movie.customFormatScore,
          target: movie.cutoffScore,
          met: movie.cutoffMet,
          mode: "compact"
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("popularity") && movie.popularity) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Flame($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> <span class="font-mono">${escape_html(movie.popularity.toFixed(1))}</span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("runtime") && movie.runtime) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Clock($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> ${escape_html(movie.runtime)} min</span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("rating") && movie.ratings) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="flex items-center gap-2 text-xs text-neutral-500 dark:text-neutral-400">`);
        if (movie.ratings.imdb) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<span class="flex items-center gap-1">`);
          Star($$renderer3, {
            size: 12,
            class: "text-yellow-500"
          });
          $$renderer3.push(`<!----> <span class="font-mono">${escape_html(movie.ratings.imdb.value)}</span></span>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        if (movie.ratings.tmdb) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<span class="flex items-center gap-1">`);
          Star($$renderer3, {
            size: 12,
            class: "text-blue-500"
          });
          $$renderer3.push(`<!----> <span class="font-mono">${escape_html(movie.ratings.tmdb.value)}</span></span>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("dateAdded")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Calendar($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> <span>Added:</span> <span class="font-mono">`);
        DateTime($$renderer3, {
          value: movie.dateAdded,
          date: true,
          options: {
            month: "short",
            day: "numeric",
            year: "numeric"
          }
        });
        $$renderer3.push(`<!----></span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("initialReleaseDate")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Calendar($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> <span>Initial:</span> <span class="font-mono">`);
        DateTime($$renderer3, {
          value: movie.initialReleaseDate,
          date: true,
          options: {
            month: "short",
            day: "numeric",
            year: "numeric"
          }
        });
        $$renderer3.push(`<!----></span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("theatricalReleaseDate")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Calendar($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> <span>Theatrical:</span> <span class="font-mono">`);
        DateTime($$renderer3, {
          value: movie.theatricalReleaseDate,
          date: true,
          options: {
            month: "short",
            day: "numeric",
            year: "numeric"
          }
        });
        $$renderer3.push(`<!----></span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("digitalReleaseDate")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Calendar($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> <span>Digital:</span> <span class="font-mono">`);
        DateTime($$renderer3, {
          value: movie.digitalReleaseDate,
          date: true,
          options: {
            month: "short",
            day: "numeric",
            year: "numeric"
          }
        });
        $$renderer3.push(`<!----></span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("physicalReleaseDate")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Calendar($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> <span>Physical:</span> <span class="font-mono">`);
        DateTime($$renderer3, {
          value: movie.physicalReleaseDate,
          date: true,
          options: {
            month: "short",
            day: "numeric",
            year: "numeric"
          }
        });
        $$renderer3.push(`<!----></span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div></div> `);
      InfoModal($$renderer3, {
        header: movie.title,
        size: "xl",
        get open() {
          return detailOpen;
        },
        set open($$value) {
          detailOpen = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          if (!movie.hasFile) {
            $$renderer4.push("<!--[0-->");
            $$renderer4.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">No file yet \u2014 this movie is still waiting for its big download debut.</p>`);
          } else {
            $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<div class="space-y-4">`);
            if (movie.fileName) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div><div class="mb-1 text-xs font-medium text-neutral-900 dark:text-neutral-100">File</div> <code class="block font-mono text-xs break-all text-neutral-600 dark:text-neutral-400">${escape_html(movie.fileName)}</code></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> <div><div class="mb-1.5 text-xs font-medium text-neutral-900 dark:text-neutral-100">Custom Formats</div> `);
            if (movie.scoreBreakdown.length > 0) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="flex flex-wrap gap-1.5"><!--[-->`);
              const each_array = ensure_array_like([...movie.scoreBreakdown].sort((a2, b3) => b3.score - a2.score));
              for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                let item = each_array[$$index];
                CustomFormatBadge($$renderer4, {
                  name: item.name,
                  score: item.score
                });
              }
              $$renderer4.push(`<!--]--></div>`);
            } else {
              $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<span class="text-xs text-neutral-500 dark:text-neutral-400">No custom formats matched</span>`);
            }
            $$renderer4.push(`<!--]--></div></div>`);
          }
          $$renderer4.push(`<!--]-->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      movie,
      baseUrl,
      visibleFields
    });
  });
}
function SeriesCard($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let posterUrl, monitoredState, slug, seasonRows;
    let series = $$props["series"];
    let baseUrl = fallback($$props["baseUrl"], "");
    let instanceId = $$props["instanceId"];
    let visibleFields = fallback($$props["visibleFields"], () => /* @__PURE__ */ new Set(), true);
    let highlightGroups = fallback($$props["highlightGroups"], () => [], true);
    function formatSize2(bytes) {
      if (!bytes) return "-";
      const gb = bytes / 1073741824;
      if (gb >= 1) return `${gb.toFixed(1)} GB`;
      return `${(bytes / 1048576).toFixed(0)} MB`;
    }
    let detailOpen = false;
    let seasons = [];
    let episodesBySeason = /* @__PURE__ */ new Map();
    let episodesLoading = /* @__PURE__ */ new Set();
    let seasonExpandedRows = /* @__PURE__ */ new Set();
    const seasonColumns = [{
      key: "label",
      header: "Season",
      align: "left",
      sortable: false
    }, {
      key: "episodes",
      header: "Episodes",
      align: "right",
      width: "w-28",
      sortable: false
    }];
    $: posterUrl = series.images?.find((i) => i.coverType === "poster")?.remoteUrl;
    $: monitoredState = series.monitoredState;
    $: slug = series.titleSlug ?? series.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
    $: seasonRows = seasons.filter((s3) => s3.totalEpisodeCount > 0).sort((a2, b3) => a2.seasonNumber === 0 ? 1 : b3.seasonNumber === 0 ? -1 : a2.seasonNumber - b3.seasonNumber).map((s3) => ({
      seasonNumber: s3.seasonNumber,
      label: s3.seasonNumber === 0 ? "Specials" : `Season ${s3.seasonNumber}`,
      episodeCount: s3.episodeCount,
      fileCount: s3.episodeFileCount
    }));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="group flex flex-col overflow-hidden rounded-xl border border-neutral-300 bg-neutral-50 transition-colors dark:border-neutral-700/60 dark:bg-neutral-900"><a${attr("href", `${stringify(baseUrl)}/series/${stringify(slug)}`)} target="_blank" rel="noopener noreferrer" class="relative aspect-[2/3] w-full overflow-hidden bg-neutral-200 dark:bg-neutral-800">`);
      if (posterUrl) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<img${attr("src", posterUrl)}${attr("alt", series.title)} loading="lazy" class="h-full w-full object-cover"/>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<div class="flex h-full w-full items-center justify-center">`);
        Tv($$renderer3, { class: "h-12 w-12 text-neutral-400 dark:text-neutral-600" });
        $$renderer3.push(`<!----></div>`);
      }
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("monitored")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="absolute top-2 left-2">`);
        IconCheckbox($$renderer3, {
          checked: monitoredState !== "unmonitored",
          icon: Check,
          color: monitoredState === "monitored" ? "green" : monitoredState === "partial" ? "#EAB308" : "neutral",
          shape: "circle"
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> <div class="absolute top-2 right-2 opacity-0 transition-opacity group-hover:opacity-100">`);
      Button($$renderer3, {
        icon: Info,
        size: "xs",
        variant: "secondary",
        tooltip: "Episode details"
      });
      $$renderer3.push(`<!----></div></a> <div class="flex flex-1 flex-col gap-2 p-3">`);
      if (visibleFields.has("title")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<h3 class="truncate text-sm font-semibold text-neutral-900 dark:text-neutral-100"${attr("title", series.title)}>${escape_html(series.title)}</h3>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("year") && series.year) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(series.year)}</span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("status") && series.status) {
        $$renderer3.push("<!--[0-->");
        if (series.status === "continuing") {
          $$renderer3.push("<!--[0-->");
          Label($$renderer3, {
            variant: "success",
            size: "sm",
            children: ($$renderer4) => {
              if (Play) {
                $$renderer4.push("<!--[-->");
                Play($$renderer4, { size: 12 });
                $$renderer4.push("<!--]-->");
              } else {
                $$renderer4.push("<!--[!-->");
                $$renderer4.push("<!--]-->");
              }
              $$renderer4.push(` Continuing`);
            },
            $$slots: { default: true }
          });
        } else if (series.status === "ended") {
          $$renderer3.push("<!--[1-->");
          Label($$renderer3, {
            variant: "secondary",
            size: "sm",
            children: ($$renderer4) => {
              if (Square) {
                $$renderer4.push("<!--[-->");
                Square($$renderer4, { size: 12 });
                $$renderer4.push("<!--]-->");
              } else {
                $$renderer4.push("<!--[!-->");
                $$renderer4.push("<!--]-->");
              }
              $$renderer4.push(` Ended`);
            },
            $$slots: { default: true }
          });
        } else if (series.status === "upcoming") {
          $$renderer3.push("<!--[2-->");
          Label($$renderer3, {
            variant: "info",
            size: "sm",
            children: ($$renderer4) => {
              if (Clock) {
                $$renderer4.push("<!--[-->");
                Clock($$renderer4, { size: 12 });
                $$renderer4.push("<!--]-->");
              } else {
                $$renderer4.push("<!--[!-->");
                $$renderer4.push("<!--]-->");
              }
              $$renderer4.push(` Upcoming`);
            },
            $$slots: { default: true }
          });
        } else {
          $$renderer3.push("<!--[-1-->");
          Label($$renderer3, {
            variant: "secondary",
            size: "sm",
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(series.status)}`);
            },
            $$slots: { default: true }
          });
        }
        $$renderer3.push(`<!--]-->`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("profile") || visibleFields.has("size")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="flex items-center justify-between gap-1.5">`);
        if (visibleFields.has("profile")) {
          $$renderer3.push("<!--[0-->");
          Tooltip($$renderer3, {
            text: series.isProfilarrProfile ? "" : "Not managed by Profilarr",
            position: "top",
            children: ($$renderer4) => {
              Badge($$renderer4, {
                variant: series.isProfilarrProfile ? "accent" : "warning",
                icon: series.isProfilarrProfile ? null : Circle_alert,
                mono: true,
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->${escape_html(series.qualityProfileName)}`);
                },
                $$slots: { default: true }
              });
            },
            $$slots: { default: true }
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        if (visibleFields.has("size") && series.sizeOnDisk) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<span class="font-mono text-xs text-neutral-500 dark:text-neutral-400">${escape_html(formatSize2(series.sizeOnDisk))}</span>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("releaseGroups") && series.releaseGroups?.length) {
        $$renderer3.push("<!--[0-->");
        const groups = series.releaseGroups;
        Tooltip($$renderer3, {
          text: groups.length > 1 ? groups.join(", ") : "",
          position: "top",
          children: ($$renderer4) => {
            $$renderer4.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
            Users($$renderer4, {
              size: 12,
              class: "flex-shrink-0"
            });
            $$renderer4.push(`<!----> <span class="truncate font-mono">${escape_html(primaryReleaseGroup(groups, highlightGroups))}</span> `);
            if (groups.length > 1) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="flex-shrink-0 font-mono text-neutral-400 dark:text-neutral-500">+${escape_html(groups.length - 1)}</span>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></span>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("episodes")) {
        $$renderer3.push("<!--[0-->");
        ProgressIndicator($$renderer3, {
          current: series.episodeFileCount,
          target: series.episodeCount,
          met: series.episodeFileCount === series.episodeCount,
          mode: "compact"
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("rating") && series.ratings) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Star($$renderer3, {
          size: 12,
          class: "text-yellow-500"
        });
        $$renderer3.push(`<!----> <span class="font-mono">${escape_html(series.ratings.value)}</span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("dateAdded")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Calendar($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> <span>Added:</span> <span class="font-mono">`);
        DateTime($$renderer3, {
          value: series.dateAdded,
          date: true,
          options: {
            month: "short",
            day: "numeric",
            year: "numeric"
          }
        });
        $$renderer3.push(`<!----></span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("firstAired")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Calendar($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> <span>Premiere:</span> <span class="font-mono">`);
        DateTime($$renderer3, {
          value: series.firstAired,
          date: true,
          options: {
            month: "short",
            day: "numeric",
            year: "numeric"
          }
        });
        $$renderer3.push(`<!----></span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleFields.has("previousAiring")) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="flex items-center gap-1 text-xs text-neutral-500 dark:text-neutral-400">`);
        Calendar($$renderer3, { size: 12 });
        $$renderer3.push(`<!----> <span>Latest aired:</span> <span class="font-mono">`);
        DateTime($$renderer3, {
          value: series.previousAiring,
          date: true,
          options: {
            month: "short",
            day: "numeric",
            year: "numeric"
          }
        });
        $$renderer3.push(`<!----></span></span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div></div> `);
      InfoModal($$renderer3, {
        header: series.title,
        size: "2xl",
        get open() {
          return detailOpen;
        },
        set open($$value) {
          detailOpen = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          if (seasonRows.length > 0) {
            $$renderer4.push("<!--[1-->");
            $$renderer4.push(`<div class="episode-table-wrapper w-full svelte-rfwuts">`);
            ExpandableTable($$renderer4, {
              columns: seasonColumns,
              data: seasonRows,
              getRowId: (row) => row.seasonNumber,
              compact: true,
              flushExpanded: true,
              get expandedRows() {
                return seasonExpandedRows;
              },
              set expandedRows($$value) {
                seasonExpandedRows = $$value;
                $$settled = false;
              },
              $$slots: {
                cell: ($$renderer5, { row, column }) => {
                  if (column.key === "label") {
                    $$renderer5.push("<!--[0-->");
                    $$renderer5.push(`<span class="font-medium text-neutral-900 dark:text-neutral-100">${escape_html(row.label)}</span>`);
                  } else if (column.key === "episodes") {
                    $$renderer5.push("<!--[1-->");
                    $$renderer5.push(`<span class="font-mono text-xs"><span${attr_class(clsx(row.fileCount === row.episodeCount ? "text-green-600 dark:text-green-400" : "text-neutral-700 dark:text-neutral-300"))}>${escape_html(row.fileCount)}</span> <span class="text-neutral-400 dark:text-neutral-500">/ ${escape_html(row.episodeCount)}</span></span>`);
                  } else $$renderer5.push("<!--[-1-->");
                  $$renderer5.push(`<!--]-->`);
                },
                expanded: ($$renderer5, { row }) => {
                  if (episodesLoading.has(row.seasonNumber)) {
                    $$renderer5.push("<!--[0-->");
                    $$renderer5.push(`<div class="flex items-center gap-2 px-3 py-3 text-sm text-neutral-500 dark:text-neutral-400"><div class="h-4 w-4 animate-spin rounded-full border-2 border-neutral-300 border-t-accent-500"></div> Loading episodes...</div>`);
                  } else {
                    $$renderer5.push("<!--[-1-->");
                    const seasonEpisodes = episodesBySeason.get(row.seasonNumber) ?? [];
                    $$renderer5.push(`<div class="divide-y divide-neutral-200 overflow-hidden dark:divide-neutral-700/40"><!--[-->`);
                    const each_array = ensure_array_like(seasonEpisodes);
                    for (let $$index_1 = 0, $$length = each_array.length; $$index_1 < $$length; $$index_1++) {
                      let ep = each_array[$$index_1];
                      $$renderer5.push(`<div class="space-y-2 px-3 py-3"><div class="flex items-center justify-between gap-2"><span class="truncate text-sm text-neutral-900 dark:text-neutral-100">${escape_html(ep.episodeNumber)}. ${escape_html(ep.title)}</span> `);
                      if (ep.hasFile) {
                        $$renderer5.push("<!--[0-->");
                        $$renderer5.push(`<div class="flex-shrink-0">`);
                        ProgressIndicator($$renderer5, {
                          current: ep.customFormatScore,
                          target: ep.cutoffScore,
                          met: ep.cutoffMet,
                          mode: "inline"
                        });
                        $$renderer5.push(`<!----></div>`);
                      } else {
                        $$renderer5.push("<!--[-1-->");
                        $$renderer5.push(`<span class="flex-shrink-0 text-xs text-neutral-400 dark:text-neutral-500">Missing</span>`);
                      }
                      $$renderer5.push(`<!--]--></div> `);
                      if (ep.fileName) {
                        $$renderer5.push("<!--[0-->");
                        $$renderer5.push(`<div class="font-mono text-xs break-all text-neutral-500 dark:text-neutral-400">${escape_html(ep.fileName)}</div>`);
                      } else $$renderer5.push("<!--[-1-->");
                      $$renderer5.push(`<!--]--> `);
                      if (ep.hasFile && ep.scoreBreakdown.length > 0) {
                        $$renderer5.push("<!--[0-->");
                        $$renderer5.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
                        const each_array_1 = ensure_array_like([...ep.scoreBreakdown].sort((a2, b3) => b3.score - a2.score));
                        for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
                          let item = each_array_1[$$index];
                          CustomFormatBadge($$renderer5, {
                            name: item.name,
                            score: item.score
                          });
                        }
                        $$renderer5.push(`<!--]--></div>`);
                      } else $$renderer5.push("<!--[-1-->");
                      $$renderer5.push(`<!--]--></div>`);
                    }
                    $$renderer5.push(`<!--]--></div>`);
                  }
                  $$renderer5.push(`<!--]-->`);
                }
              }
            });
            $$renderer4.push(`<!----></div>`);
          } else {
            $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<span class="text-sm text-neutral-500 dark:text-neutral-400">No seasons found</span>`);
          }
          $$renderer4.push(`<!--]-->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      series,
      baseUrl,
      instanceId,
      visibleFields,
      highlightGroups
    });
  });
}
function _page5($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let isRadarr, isSonarr, isSupported, simpleSearchStore, simpleQuery, activeFields, refreshStatusText, activeToggleableColumns, activeColumnLabels, activeVisibleColumns, activeCardFields, activeCardFieldLabels, activeVisibleCardFields, baseUrl, radarrLibrary, scopedMovies, filteredMovies, hasActiveMovieFilter, movieEmptyMessage, sonarrLibrary, filteredSeries, activeReleaseGroups, sortedMovies, sortedSeries, visibleMovieCards, visibleSeriesCards;
    let data = $$props["data"];
    let filterTags = [];
    let showFilterInfo = false;
    let useSimpleMode = false;
    let movieDownloadStatuses = /* @__PURE__ */ new Set(["downloaded", "missing"]);
    function handleMovieDownloadStatusToggle(status) {
      const next2 = new Set(movieDownloadStatuses);
      if (next2.has(status)) next2.delete(status);
      else next2.add(status);
      movieDownloadStatuses = next2;
    }
    const radarrFields = [
      {
        key: "title",
        label: "Title",
        type: "text",
        accessor: (m3) => m3.title,
        isDefault: true,
        suggestions: (items) => items.map((m3) => m3.title).sort()
      },
      {
        key: "quality",
        label: "Quality",
        type: "text",
        accessor: (m3) => m3.qualityName ?? "",
        suggestions: (items) => [...new Set(items.map((m3) => m3.qualityName).filter(Boolean))].sort()
      },
      {
        key: "releaseGroup",
        label: "Release Group",
        type: "text",
        accessor: (m3) => m3.releaseGroup ?? "",
        suggestions: (items) => [...new Set(items.map((m3) => m3.releaseGroup).filter(Boolean))].sort()
      },
      {
        key: "profile",
        label: "Profile",
        type: "text",
        accessor: (m3) => m3.qualityProfileName,
        suggestions: (items) => [...new Set(items.map((m3) => m3.qualityProfileName))].sort()
      },
      {
        key: "profileManagedBy",
        label: "Profile Managed By",
        type: "text",
        accessor: (m3) => m3.isProfilarrProfile ? "Profilarr" : "External",
        suggestions: () => ["Profilarr", "External"]
      },
      {
        key: "format",
        label: "Format",
        type: "text",
        accessor: (m3) => m3.scoreBreakdown.map((s3) => s3.name),
        suggestions: (items) => [...new Set(items.flatMap((m3) => m3.scoreBreakdown.map((s3) => s3.name)))].sort()
      },
      {
        key: "score",
        label: "Score",
        type: "number",
        accessor: (m3) => m3.customFormatScore
      },
      {
        key: "year",
        label: "Year",
        type: "number",
        accessor: (m3) => m3.year ?? 0
      },
      {
        key: "status",
        label: "Status",
        type: "text",
        accessor: (m3) => m3.status ?? "",
        suggestions: () => [
          "released",
          "announced",
          "inCinemas"
        ]
      },
      {
        key: "studio",
        label: "Studio",
        type: "text",
        accessor: (m3) => m3.studio ?? "",
        suggestions: (items) => [...new Set(items.map((m3) => m3.studio).filter(Boolean))].sort()
      },
      {
        key: "genre",
        label: "Genre",
        type: "text",
        accessor: (m3) => m3.genres ?? [],
        suggestions: (items) => [...new Set(items.flatMap((m3) => m3.genres ?? []))].sort()
      },
      {
        key: "monitored",
        label: "Monitored",
        type: "text",
        accessor: (m3) => m3.monitored ? "yes" : "no",
        suggestions: () => ["yes", "no"]
      }
    ];
    const sonarrFields = [
      {
        key: "title",
        label: "Title",
        type: "text",
        accessor: (s3) => s3.title,
        isDefault: true,
        suggestions: (items) => items.map((s3) => s3.title).sort()
      },
      {
        key: "releaseGroup",
        label: "Release Group(s)",
        type: "text",
        accessor: (s3) => s3.releaseGroups ?? [],
        suggestions: (items) => [...new Set(items.flatMap((s3) => s3.releaseGroups ?? []))].sort()
      },
      {
        key: "profile",
        label: "Profile",
        type: "text",
        accessor: (s3) => s3.qualityProfileName,
        suggestions: (items) => [...new Set(items.map((s3) => s3.qualityProfileName))].sort()
      },
      {
        key: "profileManagedBy",
        label: "Profile Managed By",
        type: "text",
        accessor: (s3) => s3.isProfilarrProfile ? "Profilarr" : "External",
        suggestions: () => ["Profilarr", "External"]
      },
      {
        key: "network",
        label: "Network",
        type: "text",
        accessor: (s3) => s3.network ?? "",
        suggestions: (items) => [...new Set(items.map((s3) => s3.network).filter(Boolean))].sort()
      },
      {
        key: "year",
        label: "Year",
        type: "number",
        accessor: (s3) => s3.year ?? 0
      },
      {
        key: "status",
        label: "Status",
        type: "text",
        accessor: (s3) => s3.status ?? "",
        suggestions: () => [
          "continuing",
          "ended",
          "upcoming"
        ]
      },
      {
        key: "genre",
        label: "Genre",
        type: "text",
        accessor: (s3) => s3.genres ?? [],
        suggestions: (items) => [...new Set(items.flatMap((s3) => s3.genres ?? []))].sort()
      },
      {
        key: "monitored",
        label: "Monitored",
        type: "text",
        accessor: (s3) => s3.monitored ? "yes" : "no",
        suggestions: () => ["yes", "no"]
      }
    ];
    const viewMode = createViewModeStore({ storageKey: "profilarr-library-view" });
    function loadExpandAll() {
      return false;
    }
    let expandAll = loadExpandAll();
    function toggleExpandAll() {
      expandAll = !expandAll;
    }
    let library = [];
    let libraryError = null;
    let loading = true;
    let refreshing = false;
    let refreshedAt = null;
    let nextRefreshAt = null;
    function formatElapsed(seconds) {
      if (seconds < 60) return `${seconds}s ago`;
      const minutes = Math.floor(seconds / 60);
      if (minutes < 60) return `${minutes}m ago`;
      const hours = Math.floor(minutes / 60);
      const remainingMinutes = minutes % 60;
      if (remainingMinutes === 0) return `${hours}h ago`;
      return `${hours}h ${remainingMinutes}m ago`;
    }
    function formatUntil(seconds) {
      if (seconds < 60) return `${seconds}s`;
      const minutes = Math.floor(seconds / 60);
      const remainingSeconds = seconds % 60;
      if (minutes < 60) return `${minutes}m ${remainingSeconds}s`;
      return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
    }
    function parseTimestamp(value2) {
      if (!value2) return null;
      const timestamp2 = Date.parse(value2);
      return Number.isFinite(timestamp2) ? timestamp2 : null;
    }
    async function fetchLibrary(force = false) {
      const instanceId = data.instance.id;
      const resourcePath = isRadarr ? "movies" : "series";
      try {
        if (force) {
          const refreshResponse = await fetch(`/arr/${instanceId}/library/refresh`, { method: "POST" });
          if (!refreshResponse.ok) throw new Error(`Failed to refresh library: ${refreshResponse.statusText}`);
        }
        const response = await fetch(`/arr/${instanceId}/library/${resourcePath}`);
        if (!response.ok) throw new Error(`Failed to fetch library: ${response.statusText}`);
        const result = await response.json();
        library = result.items;
        refreshedAt = result.refreshedAt;
        nextRefreshAt = result.nextRefreshAt;
        libraryError = null;
      } catch (err) {
        libraryError = err instanceof Error ? err.message : "Failed to fetch library";
      } finally {
        loading = false;
        refreshing = false;
      }
    }
    async function handleRefresh() {
      refreshing = true;
      if (isSonarr) sonarrTableView?.resetEpisodeCache();
      await fetchLibrary(true);
    }
    function handleOpen() {
      const baseUrl2 = getDisplayUrl(data.instance);
      window.open(baseUrl2, "_blank", "noopener,noreferrer");
    }
    onDestroy(() => {
    });
    const RADARR_RELEASE_DATE_KEYS = [
      "initialReleaseDate",
      "theatricalReleaseDate",
      "digitalReleaseDate",
      "physicalReleaseDate"
    ];
    const RADARR_TOGGLEABLE_COLUMNS = [
      "status",
      "qualityName",
      "score",
      "sizeOnDisk",
      "popularity",
      "dateAdded",
      ...RADARR_RELEASE_DATE_KEYS,
      "releaseGroup"
    ];
    const RADARR_DEFAULT_COLUMNS = RADARR_TOGGLEABLE_COLUMNS.filter((key2) => !RADARR_RELEASE_DATE_KEYS.includes(key2));
    function loadRadarrColumnVisibility() {
      return new Set(RADARR_DEFAULT_COLUMNS);
    }
    let radarrVisibleColumns = loadRadarrColumnVisibility();
    function toggleRadarrColumn(key2) {
      const colKey = key2;
      if (radarrVisibleColumns.has(colKey)) radarrVisibleColumns.delete(colKey);
      else radarrVisibleColumns.add(colKey);
      radarrVisibleColumns = radarrVisibleColumns;
    }
    const radarrColumnLabels = {
      qualityName: "Quality",
      score: "Score",
      releaseGroup: "Release Group",
      sizeOnDisk: "Size",
      status: "Status",
      popularity: "Popularity",
      dateAdded: "Added",
      initialReleaseDate: "Initial Release",
      theatricalReleaseDate: "Theatrical Release",
      digitalReleaseDate: "Digital Release",
      physicalReleaseDate: "Physical Release"
    };
    const SONARR_TOGGLEABLE_COLUMNS = [
      "status",
      "episodes",
      "sizeOnDisk",
      "releaseGroups",
      "dateAdded",
      "firstAired",
      "previousAiring"
    ];
    const SONARR_DEFAULT_COLUMNS = SONARR_TOGGLEABLE_COLUMNS.filter((key2) => key2 !== "firstAired" && key2 !== "previousAiring");
    function loadSonarrColumnVisibility() {
      return new Set(SONARR_DEFAULT_COLUMNS);
    }
    let sonarrVisibleColumns = loadSonarrColumnVisibility();
    function toggleSonarrColumn(key2) {
      const colKey = key2;
      if (sonarrVisibleColumns.has(colKey)) sonarrVisibleColumns.delete(colKey);
      else sonarrVisibleColumns.add(colKey);
      sonarrVisibleColumns = sonarrVisibleColumns;
    }
    const sonarrColumnLabels = {
      episodes: "Episodes",
      sizeOnDisk: "Size",
      releaseGroups: "Release Group(s)",
      status: "Status",
      dateAdded: "Added",
      firstAired: "Series Premiere",
      previousAiring: "Latest Aired Episode"
    };
    function toggleColumn(key2) {
      if (isRadarr) toggleRadarrColumn(key2);
      else toggleSonarrColumn(key2);
    }
    const RADARR_CARD_STORAGE_KEY = "profilarr-library-card-fields";
    const RADARR_CARD_FIELDS = [
      "monitored",
      "title",
      "profile",
      "size",
      "score",
      "quality",
      "year",
      "releaseGroup",
      "status",
      "popularity",
      "runtime",
      "rating",
      "dateAdded",
      ...RADARR_RELEASE_DATE_KEYS
    ];
    const RADARR_CARD_DEFAULTS = [
      "monitored",
      "profile",
      "size",
      "score"
    ];
    const radarrCardFieldLabels = {
      monitored: "Monitored",
      title: "Title",
      profile: "Profile",
      size: "Size",
      score: "Score",
      quality: "Quality",
      year: "Year",
      releaseGroup: "Release Group",
      status: "Status",
      popularity: "Popularity",
      runtime: "Runtime",
      rating: "Rating",
      dateAdded: "Date Added",
      initialReleaseDate: "Initial Release",
      theatricalReleaseDate: "Theatrical Release",
      digitalReleaseDate: "Digital Release",
      physicalReleaseDate: "Physical Release"
    };
    const SONARR_CARD_STORAGE_KEY = "profilarr-library-card-fields-sonarr";
    const SONARR_CARD_FIELDS = [
      "monitored",
      "title",
      "profile",
      "size",
      "episodes",
      "year",
      "releaseGroups",
      "status",
      "rating",
      "dateAdded",
      "firstAired",
      "previousAiring"
    ];
    const SONARR_CARD_DEFAULTS = [
      "monitored",
      "profile",
      "size",
      "episodes"
    ];
    const sonarrCardFieldLabels = {
      monitored: "Monitored",
      title: "Title",
      profile: "Profile",
      size: "Size",
      episodes: "Episodes",
      year: "Year",
      releaseGroups: "Release Group(s)",
      status: "Status",
      rating: "Rating",
      dateAdded: "Date Added",
      firstAired: "Series Premiere",
      previousAiring: "Latest Aired Episode"
    };
    function loadCardFields(key2, defaults) {
      return new Set(defaults);
    }
    let radarrCardFields = loadCardFields(RADARR_CARD_STORAGE_KEY, RADARR_CARD_DEFAULTS);
    let sonarrCardFields = loadCardFields(SONARR_CARD_STORAGE_KEY, SONARR_CARD_DEFAULTS);
    function toggleCardField(key2) {
      if (isRadarr) {
        const k2 = key2;
        if (radarrCardFields.has(k2)) radarrCardFields.delete(k2);
        else radarrCardFields.add(k2);
        radarrCardFields = radarrCardFields;
      } else {
        const k2 = key2;
        if (sonarrCardFields.has(k2)) sonarrCardFields.delete(k2);
        else sonarrCardFields.add(k2);
        sonarrCardFields = sonarrCardFields;
      }
    }
    let sonarrTableView;
    let cardSortKey = "title";
    let cardSortDirection = "asc";
    function handleCardSort(key2, direction) {
      cardSortKey = key2;
      cardSortDirection = direction;
    }
    function sortItems(items, key2, direction) {
      return [...items].sort((a2, b3) => {
        if (RADARR_RELEASE_DATE_KEYS.includes(key2) || key2 === "firstAired" || key2 === "previousAiring") return compareOptionalDates(a2[key2], b3[key2], direction);
        let aVal;
        let bVal;
        switch (key2) {
          case "title":
            aVal = sortTitle(a2.title);
            bVal = sortTitle(b3.title);
            break;
          case "size":
            aVal = a2.sizeOnDisk ?? 0;
            bVal = b3.sizeOnDisk ?? 0;
            break;
          case "dateAdded":
            aVal = a2.dateAdded ? new Date(a2.dateAdded).getTime() : 0;
            bVal = b3.dateAdded ? new Date(b3.dateAdded).getTime() : 0;
            break;
          case "year":
            aVal = a2.year ?? 0;
            bVal = b3.year ?? 0;
            break;
          case "score":
            aVal = a2.customFormatScore ?? a2.percentOfEpisodes ?? 0;
            bVal = b3.customFormatScore ?? b3.percentOfEpisodes ?? 0;
            break;
          default:
            return 0;
        }
        if (aVal < bVal) return direction === "asc" ? -1 : 1;
        if (aVal > bVal) return direction === "asc" ? 1 : -1;
        return 0;
      });
    }
    const { visibleCount: cardVisibleCount, sentinel: cardSentinel, reset: cardReset, setTotalCount: cardSetTotalCount } = createProgressiveList({ pageSize: 60 });
    $: isRadarr = data.instance.type === "radarr";
    $: isSonarr = data.instance.type === "sonarr";
    $: isSupported = isRadarr || isSonarr;
    $: simpleSearchStore = getPersistentSearchStore(`arrLibrarySearch:${data.instance.id}`, { debounceMs: 150 });
    $: simpleQuery = store_get($$store_subs ??= {}, "$simpleSearchStore", simpleSearchStore).query;
    $: activeFields = isRadarr ? radarrFields : sonarrFields;
    $: refreshStatusText = (() => {
      const refreshedTimestamp = parseTimestamp(refreshedAt);
      if (refreshedTimestamp === null) return null;
      const parts = [formatElapsed(Math.max(0, Math.floor((Date.now() - refreshedTimestamp) / 1e3)))];
      const nextRefreshTimestamp = parseTimestamp(nextRefreshAt);
      if (nextRefreshTimestamp === null) parts.push("Automatic refresh off");
      else {
        const secondsUntil = Math.ceil((nextRefreshTimestamp - Date.now()) / 1e3);
        parts.push(secondsUntil > 0 ? `Next in ${formatUntil(secondsUntil)}` : "Refresh due");
      }
      return parts.join(" \xB7 ");
    })();
    $: activeToggleableColumns = isRadarr ? RADARR_TOGGLEABLE_COLUMNS : SONARR_TOGGLEABLE_COLUMNS;
    $: activeColumnLabels = isRadarr ? radarrColumnLabels : sonarrColumnLabels;
    $: activeVisibleColumns = isRadarr ? /* @__PURE__ */ new Set([...radarrVisibleColumns]) : /* @__PURE__ */ new Set([...sonarrVisibleColumns]);
    $: activeCardFields = isRadarr ? RADARR_CARD_FIELDS : SONARR_CARD_FIELDS;
    $: activeCardFieldLabels = isRadarr ? radarrCardFieldLabels : sonarrCardFieldLabels;
    $: activeVisibleCardFields = isRadarr ? /* @__PURE__ */ new Set([...radarrCardFields]) : /* @__PURE__ */ new Set([...sonarrCardFields]);
    $: baseUrl = getDisplayUrl(data.instance);
    $: radarrLibrary = library;
    $: scopedMovies = isRadarr ? radarrLibrary.filter((movie) => {
      const status = movie.hasFile ? "downloaded" : "missing";
      return movieDownloadStatuses.has(status);
    }) : [];
    $: filteredMovies = (() => {
      if (useSimpleMode) {
        if (!simpleQuery) return scopedMovies;
        const q2 = simpleQuery.toLowerCase();
        return scopedMovies.filter((m3) => m3.title.toLowerCase().includes(q2));
      }
      return applySmartFilters(scopedMovies, filterTags, radarrFields);
    })();
    $: hasActiveMovieFilter = useSimpleMode ? simpleQuery.trim().length > 0 : filterTags.length > 0;
    $: movieEmptyMessage = hasActiveMovieFilter ? "No movies match the current filters" : movieDownloadStatuses.size === 0 ? "No download statuses selected" : movieDownloadStatuses.size === 1 && movieDownloadStatuses.has("downloaded") ? "No downloaded movies" : movieDownloadStatuses.size === 1 && movieDownloadStatuses.has("missing") ? "No missing movies" : "No movies found";
    $: sonarrLibrary = library;
    $: filteredSeries = (() => {
      if (!isSonarr) return [];
      if (useSimpleMode) {
        if (!simpleQuery) return sonarrLibrary;
        const q2 = simpleQuery.toLowerCase();
        return sonarrLibrary.filter((s3) => s3.title.toLowerCase().includes(q2));
      }
      return applySmartFilters(sonarrLibrary, filterTags, sonarrFields);
    })();
    $: activeReleaseGroups = useSimpleMode ? [] : filterTags.filter((t2) => t2.field === "releaseGroup" && !t2.negated).map((t2) => t2.value);
    $: if (isRadarr && (cardSortKey === "firstAired" || cardSortKey === "previousAiring") || isSonarr && RADARR_RELEASE_DATE_KEYS.includes(cardSortKey)) {
      cardSortKey = "title";
      cardSortDirection = "asc";
    }
    $: sortedMovies = sortItems(filteredMovies, cardSortKey, cardSortDirection);
    $: sortedSeries = sortItems(filteredSeries, cardSortKey, cardSortDirection);
    $: if (isRadarr) cardSetTotalCount(sortedMovies.length);
    else if (isSonarr) cardSetTotalCount(sortedSeries.length);
    $: cardReset();
    $: visibleMovieCards = sortedMovies.slice(0, store_get($$store_subs ??= {}, "$cardVisibleCount", cardVisibleCount));
    $: visibleSeriesCards = sortedSeries.slice(0, store_get($$store_subs ??= {}, "$cardVisibleCount", cardVisibleCount));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.instance.name} \xB7 Library` });
      $$renderer3.push(`<!----> <div class="mt-6 space-y-6">`);
      if (libraryError && !loading) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-red-200 bg-red-50 p-6 dark:border-red-800 dark:bg-red-950/40"><div class="flex items-center gap-3">`);
        Triangle_alert($$renderer3, { class: "h-5 w-5 text-red-600 dark:text-red-400" });
        $$renderer3.push(`<!----> <div><h3 class="font-medium text-red-800 dark:text-red-200">Failed to load library</h3> <p class="mt-1 text-sm text-red-600 dark:text-red-400">${escape_html(libraryError)}</p></div></div></div>`);
      } else if (!isSupported) {
        $$renderer3.push("<!--[1-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-6 dark:border-neutral-800 dark:bg-neutral-900"><div class="flex items-center gap-3">`);
        Film($$renderer3, { class: "h-5 w-5 text-neutral-400" });
        $$renderer3.push(`<!----> <div><h3 class="font-medium text-neutral-900 dark:text-neutral-50">Library view not yet available</h3> <p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400">Library view is currently only supported for Radarr and Sonarr instances.</p></div></div></div>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        LibraryActionBar($$renderer3, {
          fields: activeFields,
          items: isRadarr ? scopedMovies : sonarrLibrary,
          filterStorageKey: `smartFilter:${data.instance.id}`,
          searchStore: simpleSearchStore,
          visibleColumns: activeVisibleColumns,
          toggleableColumns: activeToggleableColumns,
          columnLabels: activeColumnLabels,
          refreshStatusText: loading ? null : refreshStatusText,
          refreshing,
          onToggleColumn: toggleColumn,
          onRefresh: handleRefresh,
          onOpen: handleOpen,
          instanceType: data.instance.type,
          movieDownloadStatuses,
          onMovieDownloadStatusToggle: handleMovieDownloadStatusToggle,
          expandAll,
          onToggleExpandAll: toggleExpandAll,
          sortKey: cardSortKey,
          sortDirection: cardSortDirection,
          onSort: handleCardSort,
          visibleCardFields: activeVisibleCardFields,
          toggleableCardFields: activeCardFields,
          cardFieldLabels: activeCardFieldLabels,
          onToggleCardField: toggleCardField,
          onFilterInfo: () => showFilterInfo = true,
          get tags() {
            return filterTags;
          },
          set tags($$value) {
            filterTags = $$value;
            $$settled = false;
          },
          get useSimpleMode() {
            return useSimpleMode;
          },
          set useSimpleMode($$value) {
            useSimpleMode = $$value;
            $$settled = false;
          },
          get viewMode() {
            return store_get($$store_subs ??= {}, "$viewMode", viewMode);
          },
          set viewMode($$value) {
            store_set(viewMode, $$value);
            $$settled = false;
          }
        });
        $$renderer3.push(`<!----> `);
        if (store_get($$store_subs ??= {}, "$viewMode", viewMode) === "table") {
          $$renderer3.push("<!--[0-->");
          if (isRadarr) {
            $$renderer3.push("<!--[0-->");
            if (radarrLibrary.length === 0 && !loading && !refreshing) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-6 dark:border-neutral-800 dark:bg-neutral-900"><div class="flex items-center gap-3">`);
              Film($$renderer3, { class: "h-5 w-5 text-neutral-400" });
              $$renderer3.push(`<!----> <div><h3 class="font-medium text-neutral-900 dark:text-neutral-50">No movies found</h3> <p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400">This Radarr instance has no movies in its library.</p></div></div></div>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              RadarrTableView($$renderer3, {
                data: filteredMovies,
                loading: loading || refreshing,
                baseUrl,
                expandAll,
                visibleColumns: activeVisibleColumns,
                emptyMessage: movieEmptyMessage
              });
            }
            $$renderer3.push(`<!--]-->`);
          } else if (isSonarr) {
            $$renderer3.push("<!--[1-->");
            if (sonarrLibrary.length === 0 && !loading && !refreshing) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-6 dark:border-neutral-800 dark:bg-neutral-900"><div class="flex items-center gap-3">`);
              Film($$renderer3, { class: "h-5 w-5 text-neutral-400" });
              $$renderer3.push(`<!----> <div><h3 class="font-medium text-neutral-900 dark:text-neutral-50">No series found</h3> <p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400">This Sonarr instance has no series in its library.</p></div></div></div>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              SonarrTableView($$renderer3, {
                data: filteredSeries,
                loading: loading || refreshing,
                baseUrl,
                expandAll,
                instanceId: data.instance.id,
                visibleColumns: activeVisibleColumns,
                highlightGroups: activeReleaseGroups,
                emptyMessage: filterTags.length > 0 ? "No series match the current filters" : "No series found"
              });
            }
            $$renderer3.push(`<!--]-->`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } else {
          $$renderer3.push("<!--[-1-->");
          if (loading || refreshing) {
            $$renderer3.push("<!--[0-->");
            LibraryCardGrid($$renderer3, {
              columns: 6,
              children: ($$renderer4) => {
                $$renderer4.push(`<!--[-->`);
                const each_array = ensure_array_like(Array(15));
                for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                  each_array[$$index];
                  $$renderer4.push(`<div class="animate-pulse overflow-hidden rounded-xl border border-neutral-300 bg-neutral-50 dark:border-neutral-700/60 dark:bg-neutral-900"><div class="aspect-[2/3] w-full bg-neutral-200 dark:bg-neutral-800"></div> <div class="space-y-2 p-3"><div class="h-4 w-3/4 rounded bg-neutral-200 dark:bg-neutral-700"></div> <div class="h-3 w-1/4 rounded bg-neutral-200 dark:bg-neutral-700"></div> <div class="h-5 w-1/2 rounded bg-neutral-200 dark:bg-neutral-700"></div></div></div>`);
                }
                $$renderer4.push(`<!--]-->`);
              },
              $$slots: { default: true }
            });
          } else if (isRadarr) {
            $$renderer3.push("<!--[1-->");
            if (filteredMovies.length === 0) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-6 dark:border-neutral-800 dark:bg-neutral-900"><p class="text-sm text-neutral-500 dark:text-neutral-400">${escape_html(movieEmptyMessage)}</p></div>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              LibraryCardGrid($$renderer3, {
                columns: 6,
                children: ($$renderer4) => {
                  $$renderer4.push(`<!--[-->`);
                  const each_array_1 = ensure_array_like(visibleMovieCards);
                  for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                    let movie = each_array_1[$$index_1];
                    MovieCard($$renderer4, {
                      movie,
                      baseUrl,
                      visibleFields: activeVisibleCardFields
                    });
                  }
                  $$renderer4.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
              $$renderer3.push(`<!----> <div></div>`);
            }
            $$renderer3.push(`<!--]-->`);
          } else if (isSonarr) {
            $$renderer3.push("<!--[2-->");
            if (filteredSeries.length === 0) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-6 dark:border-neutral-800 dark:bg-neutral-900"><p class="text-sm text-neutral-500 dark:text-neutral-400">${escape_html(filterTags.length > 0 ? "No series match the current filters" : "No series found")}</p></div>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              LibraryCardGrid($$renderer3, {
                columns: 6,
                children: ($$renderer4) => {
                  $$renderer4.push(`<!--[-->`);
                  const each_array_2 = ensure_array_like(visibleSeriesCards);
                  for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
                    let series = each_array_2[$$index_2];
                    SeriesCard($$renderer4, {
                      series,
                      baseUrl,
                      instanceId: data.instance.id,
                      visibleFields: activeVisibleCardFields,
                      highlightGroups: activeReleaseGroups
                    });
                  }
                  $$renderer4.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
              $$renderer3.push(`<!----> <div></div>`);
            }
            $$renderer3.push(`<!--]-->`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        }
        $$renderer3.push(`<!--]-->`);
      }
      $$renderer3.push(`<!--]--></div> `);
      InfoModal($$renderer3, {
        header: "How Filters Work",
        get open() {
          return showFilterInfo;
        },
        set open($$value) {
          showFilterInfo = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">Quick Search</div> <p class="mt-1">Start typing and press Enter to search by title. No need to select a field first.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Field Filters</div> <p class="mt-1">Click the input to see all available fields. Select one, then type or pick a value to create
				a filter.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Number Filters</div> <p class="mt-1">For numeric fields like Score or Year, use operators such as >1000, &lt;500, >=200, or
				ranges like 2020-2025.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Negation</div> <p class="mt-1">Click any filter tag to toggle it to NOT mode. Negated filters exclude matching items
				instead of including them.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Combining Filters</div> <p class="mt-1">Multiple filters use AND logic. All must match. Press Backspace on an empty input to remove
				the last filter, or click the X on any tag.</p></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte5 = __esm({
  "dist/build/server/entries/pages/arr/_id_/library/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_dates();
    init_sort();
    init_Dropdown();
    init_Icon();
    init_arrow_up_down();
    init_arrow_up();
    init_calendar();
    init_check();
    init_circle_alert();
    init_circle_check_big();
    init_hard_drive();
    init_clock();
    init_external_link();
    init_tv();
    init_info();
    init_Button();
    init_megaphone();
    init_play();
    init_refresh_cw();
    init_search();
    init_filterMode();
    init_star();
    init_ViewToggle();
    init_triangle_alert();
    init_users2();
    init_Label();
    init_dateFormat();
    init_timezone();
    init_IconCheckbox();
    init_DropdownItem();
    init_progressiveList();
    init_ExpandableTable();
    init_DateTime();
    init_ActionsBar();
    init_ActionButton();
    init_Badge();
    init_DropdownHeader();
    init_InfoModal();
    init_PageMeta();
    init_arrDisplayUrl();
    init_dataPage();
    init_ProgressIndicator();
    init_Score();
    init_CustomFormatBadge();
  }
});

// dist/build/server/nodes/12.js
var __exports13 = {};
__export(__exports13, {
  component: () => component12,
  fonts: () => fonts13,
  imports: () => imports13,
  index: () => index13,
  server: () => page_server_ts_exports6,
  server_id: () => server_id12,
  stylesheets: () => stylesheets13
});
var index13, component_cache12, component12, server_id12, imports13, stylesheets13, fonts13;
var init__13 = __esm({
  async "dist/build/server/nodes/12.js"() {
    "use strict";
    await init_page_server_ts6();
    index13 = 12;
    component12 = async () => component_cache12 ??= (await Promise.resolve().then(() => (init_page_svelte5(), page_svelte_exports5))).default;
    server_id12 = "src/routes/arr/[id]/library/+page.server.ts";
    imports13 = ["_app/immutable/nodes/12.BH5gXJsg.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/Cz3WzBYs.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/BGa_v0Jt2.js", "_app/immutable/chunks/C8Bmw0iK2.js", "_app/immutable/chunks/BqRH1fsh2.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/xCf7klJK.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/D8FWRTM5.js", "_app/immutable/chunks/BlAgBW4v.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/C_LFCSMn.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/MJc6__n-.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DuBlSUgq.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/C_Z5Pdot2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/unOv5SWI.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/BGwVTtPU.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/BaewglP2.js", "_app/immutable/chunks/sG_Q4rn7.js", "_app/immutable/chunks/Co6rAu4X.js", "_app/immutable/chunks/C5rtWVlZ.js"];
    stylesheets13 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/filterMode.DdGl7mkT.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/12.FB4Gt2sW.css"];
    fonts13 = [];
  }
});

// dist/build/server/entries/pages/arr/_id_/logs/_page.server.ts.js
var page_server_ts_exports7 = {};
__export(page_server_ts_exports7, {
  load: () => load12
});
var load12;
var init_page_server_ts7 = __esm({
  async "dist/build/server/entries/pages/arr/_id_/logs/_page.server.ts.js"() {
    "use strict";
    await init_arrInstances();
    init_exports();
    load12 = ({ params, url }) => {
      const id = parseInt(params.id || "", 10);
      if (isNaN(id)) error(404, `Invalid instance ID: ${params.id}`);
      const instance = arrInstancesQueries.getById(id);
      if (!instance) error(404, `Instance not found: ${id}`);
      const { api_key: _3, ...safeInstance } = instance;
      return {
        instance: safeInstance,
        filters: {
          page: parseInt(url.searchParams.get("page") || "1", 10),
          pageSize: parseInt(url.searchParams.get("pageSize") || "50", 10),
          level: url.searchParams.get("level") || void 0
        }
      };
    };
  }
});

// dist/build/server/chunks/copy.js
function Copy($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "copy" },
    props,
    { iconNode: [["rect", {
      "width": "14",
      "height": "14",
      "x": "8",
      "y": "8",
      "rx": "2",
      "ry": "2"
    }], ["path", { "d": "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" }]] }
  ]));
}
var init_copy = __esm({
  "dist/build/server/chunks/copy.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/Pagination.js
function Pagination($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let currentPage = $$props["currentPage"];
    let totalPages = $$props["totalPages"];
    let onPageChange = $$props["onPageChange"];
    $$renderer2.push(`<div class="flex items-center gap-2 text-sm text-neutral-600 dark:text-neutral-400">`);
    Button($$renderer2, {
      variant: "ghost",
      size: "sm",
      icon: Chevron_left,
      disabled: currentPage <= 1,
      ariaLabel: "Previous page"
    });
    $$renderer2.push(`<!----> <span>Page ${escape_html(currentPage)} of ${escape_html(totalPages)}</span> `);
    Button($$renderer2, {
      variant: "ghost",
      size: "sm",
      icon: Chevron_right,
      disabled: currentPage >= totalPages,
      ariaLabel: "Next page"
    });
    $$renderer2.push(`<!----></div>`);
    bind_props($$props, {
      currentPage,
      totalPages,
      onPageChange
    });
  });
}
var init_Pagination = __esm({
  "dist/build/server/chunks/Pagination.js"() {
    "use strict";
    init_server();
    init_chevron_left();
    init_chevron_right();
    init_Button();
  }
});

// dist/build/server/chunks/LogSourceCell.js
function LogLevelCell($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let normalizedLevel, labelClasses;
    let row = $$props["row"];
    const levelLabelClasses = {
      TRACE: "bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300",
      DEBUG: "bg-cyan-100 text-cyan-800 dark:bg-cyan-900 dark:text-cyan-200",
      INFO: "bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200",
      WARN: "bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200",
      ERROR: "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200",
      FATAL: "bg-red-200 text-red-900 dark:bg-red-950 dark:text-red-100"
    };
    $: normalizedLevel = row.level.toUpperCase();
    $: labelClasses = levelLabelClasses[normalizedLevel] || "bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300";
    Label($$renderer2, {
      customVariant: labelClasses,
      size: "sm",
      rounded: "md",
      children: ($$renderer3) => {
        $$renderer3.push(`<!---->${escape_html(normalizedLevel)}`);
      },
      $$slots: { default: true }
    });
    bind_props($$props, { row });
  });
}
function LogSourceCell($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let source2;
    let row = $$props["row"];
    $: source2 = row.source || row.logger || "-";
    Label($$renderer2, {
      variant: "secondary",
      size: "sm",
      rounded: "md",
      mono: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!---->${escape_html(source2)}`);
      },
      $$slots: { default: true }
    });
    bind_props($$props, { row });
  });
}
var init_LogSourceCell = __esm({
  "dist/build/server/chunks/LogSourceCell.js"() {
    "use strict";
    init_server();
    init_Label();
  }
});

// dist/build/server/entries/pages/arr/_id_/logs/_page.svelte.js
var page_svelte_exports6 = {};
__export(page_svelte_exports6, {
  default: () => _page6
});
function Rows_3($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "rows-3" },
    props,
    { iconNode: [
      ["rect", {
        "width": "18",
        "height": "18",
        "x": "3",
        "y": "3",
        "rx": "2"
      }],
      ["path", { "d": "M21 9H3" }],
      ["path", { "d": "M21 15H3" }]
    ] }
  ]));
}
function _page6($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    let searchStore;
    let selectedLevel = data.filters.level || "ALL";
    let pageSize = data.filters.pageSize;
    const logLevels = [
      "ALL",
      "Fatal",
      "Error",
      "Warn",
      "Info",
      "Debug",
      "Trace"
    ];
    const levelColors = {
      Trace: "text-neutral-500 dark:text-neutral-500",
      Debug: "text-cyan-600 dark:text-cyan-400",
      Info: "text-green-600 dark:text-green-400",
      Warn: "text-yellow-600 dark:text-yellow-400",
      Error: "text-red-600 dark:text-red-400",
      Fatal: "text-red-800 dark:text-red-300"
    };
    function updateParams(params) {
      const url = new URL(store_get($$store_subs ??= {}, "$page", page).url);
      for (const [key2, value2] of Object.entries(params)) if (value2 === void 0 || value2 === "ALL") url.searchParams.delete(key2);
      else url.searchParams.set(key2, String(value2));
      goto(url.toString(), { invalidateAll: true });
    }
    function changePageSize(newSize) {
      pageSize = newSize;
      updateParams({
        pageSize: newSize,
        page: 1
      });
    }
    $: searchStore = getPersistentSearchStore(`arrLogsSearch:${store_get($$store_subs ??= {}, "$page", page).params.id}`, { debounceMs: 300 });
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.instance.name} \xB7 Logs` });
      $$renderer3.push(`<!----> <div class="mt-6">`);
      ActionsBar($$renderer3, {
        className: "justify-end",
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore,
            placeholder: "Search logs..."
          });
          $$renderer4.push(`<!----> `);
          Tooltip($$renderer4, {
            text: "Refresh logs",
            children: ($$renderer5) => {
              ActionButton($$renderer5, {
                children: ($$renderer6) => {
                  Refresh_cw($$renderer6, {
                    size: 20,
                    class: `text-neutral-700 dark:text-neutral-300 animate-spin`
                  });
                },
                $$slots: { default: true }
              });
            },
            $$slots: { default: true }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Funnel,
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
              Dropdown($$renderer5, {
                position: dropdownPosition,
                minWidth: "8rem",
                children: ($$renderer6) => {
                  DropdownHeader($$renderer6, { label: "Level and Above" });
                  $$renderer6.push(`<!----> <!--[-->`);
                  const each_array = ensure_array_like(logLevels);
                  for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                    let level = each_array[$$index];
                    DropdownItem($$renderer6, {
                      label: level,
                      selected: selectedLevel === level,
                      checkColor: "blue",
                      labelClass: `font-mono font-medium ${level === "ALL" ? "text-neutral-600 dark:text-neutral-400" : levelColors[level]}`,
                      labelTransform: "uppercase"
                    });
                  }
                  $$renderer6.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Rows_3,
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
              Dropdown($$renderer5, {
                position: dropdownPosition,
                minWidth: "10rem",
                children: ($$renderer6) => {
                  $$renderer6.push(`<div class="p-3"><label for="pageSize" class="mb-2 block text-xs font-medium text-neutral-600 dark:text-neutral-400">Rows per page</label> `);
                  NumberInput($$renderer6, {
                    name: "pageSize",
                    min: 10,
                    max: 1e3,
                    step: 10,
                    onchange: changePageSize,
                    get value() {
                      return pageSize;
                    },
                    set value($$value) {
                      pageSize = $$value;
                      $$settled = false;
                    }
                  });
                  $$renderer6.push(`<!----></div>`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      $$renderer3.push("<!--[0-->");
      $$renderer3.push(`<div class="mt-12 flex flex-col items-center justify-center gap-3 text-neutral-500 dark:text-neutral-400">`);
      Loader_circle($$renderer3, {
        size: 24,
        class: "animate-spin"
      });
      $$renderer3.push(`<!----> <span class="text-sm">Loading logs...</span></div>`);
      $$renderer3.push(`<!--]--></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte6 = __esm({
  "dist/build/server/entries/pages/arr/_id_/logs/_page.svelte.js"() {
    "use strict";
    init_server();
    init_dates();
    init_Dropdown();
    init_Icon();
    init_copy();
    init_funnel();
    init_Button();
    init_refresh_cw();
    init_search();
    init_triangle_alert();
    init_client4();
    init_stores();
    init_store2();
    init_navigation();
    init_dateFormat();
    init_timezone();
    init_DropdownItem();
    init_ActionsBar();
    init_ActionButton();
    init_DropdownHeader();
    init_PageMeta();
    init_Table();
    init_NumberInput();
    init_Pagination();
    init_LogSourceCell();
  }
});

// dist/build/server/nodes/13.js
var __exports14 = {};
__export(__exports14, {
  component: () => component13,
  fonts: () => fonts14,
  imports: () => imports14,
  index: () => index14,
  server: () => page_server_ts_exports7,
  server_id: () => server_id13,
  stylesheets: () => stylesheets14
});
var index14, component_cache13, component13, server_id13, imports14, stylesheets14, fonts14;
var init__14 = __esm({
  async "dist/build/server/nodes/13.js"() {
    "use strict";
    await init_page_server_ts7();
    index14 = 13;
    component13 = async () => component_cache13 ??= (await Promise.resolve().then(() => (init_page_svelte6(), page_svelte_exports6))).default;
    server_id13 = "src/routes/arr/[id]/logs/+page.server.ts";
    imports14 = ["_app/immutable/nodes/13.DTv9gwED.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/MJc6__n-.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/DTxrEb2m.js", "_app/immutable/chunks/D1MpTH1m.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/Bhz_QMDT.js", "_app/immutable/chunks/BBtCGbx62.js"];
    stylesheets14 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts14 = [];
  }
});

// dist/build/server/entries/pages/arr/_id_/rename/_page.server.ts.js
var page_server_ts_exports8 = {};
__export(page_server_ts_exports8, {
  actions: () => actions5,
  load: () => load13
});
var load13, actions5;
var init_page_server_ts8 = __esm({
  async "dist/build/server/entries/pages/arr/_id_/rename/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_display();
    await init_queueService();
    await init_arrCleanupSettings();
    await init_init();
    init_exports();
    load13 = ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (isNaN(id)) error(404, `Invalid instance ID: ${params.id}`);
      const instance = arrInstancesQueries.getById(id);
      if (!instance) error(404, `Instance not found: ${id}`);
      const settings2 = arrRenameSettingsQueries.getByInstanceId(id);
      const renameRuns = renameRunsQueries.getByInstanceId(id);
      const { api_key: _3, ...safeInstance } = instance;
      return {
        instance: safeInstance,
        settings: settings2 ?? null,
        renameRuns
      };
    };
    actions5 = {
      save: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        const formData = await request.formData();
        try {
          const enabled3 = formData.get("enabled") === "true";
          const renameFolders = formData.get("renameFolders") === "true";
          const ignoreTag = formData.get("ignoreTag") || null;
          const cron = formData.get("cron") || "0 0 * * *";
          const summaryNotifications = formData.get("summaryNotifications") === "true";
          const cronError = validateCronExpression(cron, 10);
          if (cronError) return fail(400, { error: cronError });
          const settingsData = {
            enabled: enabled3,
            renameFolders,
            ignoreTag,
            cron,
            summaryNotifications
          };
          arrRenameSettingsQueries.upsert(id, settingsData);
          const nextRunAt = calculateNextRun(cron);
          if (nextRunAt) arrRenameSettingsQueries.updateNextRunAt(id, nextRunAt);
          scheduleRenameForInstance(id);
          await logger.info(`Rename settings saved for instance "${instance.name}"`, {
            source: "rename",
            meta: {
              instanceId: id,
              instanceName: instance.name
            }
          });
          await logger.debug("Rename settings details", {
            source: "rename",
            meta: {
              instanceId: id,
              ...settingsData
            }
          });
          return { success: true };
        } catch (err) {
          await logger.error("Failed to save rename settings", {
            source: "rename",
            meta: {
              instanceId: id,
              error: err
            }
          });
          return fail(500, { error: "Failed to save configuration" });
        }
      },
      update: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        if (!arrRenameSettingsQueries.getByInstanceId(id)) return fail(404, { error: "Configuration not found" });
        const formData = await request.formData();
        try {
          const enabled3 = formData.get("enabled") === "true";
          const renameFolders = formData.get("renameFolders") === "true";
          const ignoreTag = formData.get("ignoreTag") || null;
          const cron = formData.get("cron") || "0 0 * * *";
          const summaryNotifications = formData.get("summaryNotifications") === "true";
          const cronError = validateCronExpression(cron, 10);
          if (cronError) return fail(400, { error: cronError });
          const settingsData = {
            enabled: enabled3,
            renameFolders,
            ignoreTag,
            cron,
            summaryNotifications
          };
          arrRenameSettingsQueries.update(id, settingsData);
          const nextRunAt = calculateNextRun(cron);
          if (nextRunAt) arrRenameSettingsQueries.updateNextRunAt(id, nextRunAt);
          scheduleRenameForInstance(id);
          await logger.info(`Rename settings updated for instance "${instance.name}"`, {
            source: "rename",
            meta: {
              instanceId: id,
              instanceName: instance.name
            }
          });
          await logger.debug("Rename settings details", {
            source: "rename",
            meta: {
              instanceId: id,
              ...settingsData
            }
          });
          return { success: true };
        } catch (err) {
          await logger.error("Failed to update rename settings", {
            source: "rename",
            meta: {
              instanceId: id,
              error: err
            }
          });
          return fail(500, { error: "Failed to update configuration" });
        }
      },
      run: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        if (!arrRenameSettingsQueries.getByInstanceId(id)) return fail(404, { error: "No rename configuration found. Save a configuration first." });
        if (instance.type !== "radarr" && instance.type !== "sonarr") return fail(400, { error: `Rename not yet supported for ${instance.type}` });
        const dryRun = (await request.formData()).get("dryRun") === "true";
        try {
          const queued = enqueueJob({
            jobType: "arr.rename",
            runAt: (/* @__PURE__ */ new Date()).toISOString(),
            payload: {
              instanceId: id,
              dryRun
            },
            source: "manual"
          });
          await logger.info("Manual rename run queued", {
            source: "rename",
            meta: {
              jobId: queued.id,
              instanceId: id,
              instanceName: instance.name,
              displayName: buildJobDisplayName("arr.rename", { instanceId: id }),
              dryRun
            }
          });
          return {
            success: true,
            queued: true
          };
        } catch (err) {
          await logger.error("Manual rename run failed", {
            source: "rename",
            meta: {
              instanceId: id,
              error: err
            }
          });
          return fail(500, { error: "Rename run failed. Check logs for details." });
        }
      }
    };
  }
});

// dist/build/server/chunks/circle-dot.js
function Circle_dot($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "circle-dot" },
    props,
    { iconNode: [["circle", {
      "cx": "12",
      "cy": "12",
      "r": "10"
    }], ["circle", {
      "cx": "12",
      "cy": "12",
      "r": "1"
    }]] }
  ]));
}
var init_circle_dot = __esm({
  "dist/build/server/chunks/circle-dot.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/entries/pages/arr/_id_/rename/_page.svelte.js
var page_svelte_exports7 = {};
__export(page_svelte_exports7, {
  default: () => _page7
});
function RenameSettings($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let nextRunTime, timeUntilNext;
    let enabled3 = fallback($$props["enabled"], false);
    let renameFolders = fallback($$props["renameFolders"], false);
    let ignoreTag = fallback($$props["ignoreTag"], "");
    let cron = fallback($$props["cron"], "0 0 * * *");
    let summaryNotifications = fallback($$props["summaryNotifications"], true);
    let lastRunAt = fallback($$props["lastRunAt"], null);
    let nextRunAt = fallback($$props["nextRunAt"], null);
    let minIntervalMinutes = fallback($$props["minIntervalMinutes"], 10);
    let onEnabledChange = fallback($$props["onEnabledChange"], void 0);
    let onRenameFoldersChange = fallback($$props["onRenameFoldersChange"], void 0);
    let onIgnoreTagChange = fallback($$props["onIgnoreTagChange"], void 0);
    let onCronChange = fallback($$props["onCronChange"], void 0);
    let onSummaryNotificationsChange = fallback($$props["onSummaryNotificationsChange"], void 0);
    let onWarning = fallback($$props["onWarning"], void 0);
    let cronValue = cron;
    let now = Date.now();
    onDestroy(() => {
    });
    function formatTimeRemaining(ms) {
      if (ms <= 0) return "now";
      const seconds = Math.floor(ms / 1e3);
      const minutes = Math.floor(seconds / 60);
      const hours = Math.floor(minutes / 60);
      if (hours > 0) return `${hours}h ${minutes % 60}m`;
      if (minutes > 0) return `${minutes}m`;
      return `${seconds}s`;
    }
    $: cronValue = cron;
    $: if (cronValue !== cron) onCronChange?.(cronValue);
    $: nextRunTime = nextRunAt ? new Date(nextRunAt).getTime() : null;
    $: timeUntilNext = nextRunTime ? nextRunTime - now : null;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="flex flex-wrap gap-4 md:items-end md:gap-x-5 md:gap-y-3 md:px-4"><div><span class="mb-1 block text-[10px] font-medium tracking-wider text-neutral-400 uppercase dark:text-neutral-500">Status</span> `);
      Toggle($$renderer3, {
        checked: enabled3,
        label: enabled3 ? "Enabled" : "Disabled",
        color: enabled3 ? "green" : "red"
      });
      $$renderer3.push(`<!----></div> <div data-onboarding="rename-folders"><span class="mb-1 block text-[10px] font-medium tracking-wider text-neutral-400 uppercase dark:text-neutral-500">Folders</span> `);
      Toggle($$renderer3, {
        checked: renameFolders,
        label: renameFolders ? "On" : "Off",
        color: renameFolders ? "accent" : "neutral",
        disabled: !enabled3
      });
      $$renderer3.push(`<!----></div> <div data-onboarding="rename-summary"><span class="mb-1 block text-[10px] font-medium tracking-wider text-neutral-400 uppercase dark:text-neutral-500">Summary</span> `);
      Toggle($$renderer3, {
        checked: summaryNotifications,
        label: summaryNotifications ? "On" : "Off",
        color: summaryNotifications ? "accent" : "neutral",
        disabled: !enabled3
      });
      $$renderer3.push(`<!----></div> <div data-onboarding="rename-schedule"><span class="mb-1 block text-[10px] font-medium tracking-wider text-neutral-400 uppercase dark:text-neutral-500">Schedule</span> `);
      CronInput($$renderer3, {
        disabled: !enabled3,
        minIntervalMinutes,
        onWarning,
        get value() {
          return cronValue;
        },
        set value($$value) {
          cronValue = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----></div> <div data-onboarding="rename-ignore-tag"><span class="mb-1 block text-[10px] font-medium tracking-wider text-neutral-400 uppercase dark:text-neutral-500">Ignore Tag</span> `);
      FormInput($$renderer3, {
        label: "Ignore Tag",
        hideLabel: true,
        lowercase: true,
        name: "ignore-tag",
        size: "md",
        value: ignoreTag,
        placeholder: "no-rename",
        disabled: !enabled3
      });
      $$renderer3.push(`<!----></div> `);
      if (lastRunAt) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="flex w-full flex-wrap items-center gap-1.5 border-t border-neutral-200 pt-3 md:ml-auto md:w-auto md:border-0 md:pt-0 dark:border-neutral-800">`);
        if (!enabled3) {
          $$renderer3.push("<!--[0-->");
          Label($$renderer3, {
            variant: "warning",
            size: "md",
            rounded: "md",
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->Paused`);
            },
            $$slots: { default: true }
          });
        } else if (timeUntilNext !== null && timeUntilNext <= 0) {
          $$renderer3.push("<!--[1-->");
          Label($$renderer3, {
            variant: "success",
            size: "md",
            rounded: "md",
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->Ready`);
            },
            $$slots: { default: true }
          });
        } else if (timeUntilNext !== null) {
          $$renderer3.push("<!--[2-->");
          Label($$renderer3, {
            variant: "secondary",
            size: "md",
            rounded: "md",
            mono: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->Next ${escape_html(formatTimeRemaining(timeUntilNext))}`);
            },
            $$slots: { default: true }
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        Label($$renderer3, {
          variant: "secondary",
          size: "md",
          rounded: "md",
          mono: true,
          children: ($$renderer4) => {
            $$renderer4.push(`<!---->Last ${escape_html(formatSmartDateTime(lastRunAt, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat)))}`);
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      enabled: enabled3,
      renameFolders,
      ignoreTag,
      cron,
      summaryNotifications,
      lastRunAt,
      nextRunAt,
      minIntervalMinutes,
      onEnabledChange,
      onRenameFoldersChange,
      onIgnoreTagChange,
      onCronChange,
      onSummaryNotificationsChange,
      onWarning
    });
  });
}
function RenameRunHistory($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let filteredRuns, totalPages, paginatedRuns;
    let searchStore = createSearchStore();
    let debouncedQuery = searchStore.debouncedQuery;
    let runs = fallback($$props["runs"], () => [], true);
    let dateFilter = "all";
    let statusFilter = "all";
    function filterRuns(items, query, date, status) {
      let result = items;
      if (query) {
        const queryLower = query.toLowerCase();
        result = result.filter((item) => item.renamedItems.some((r2) => r2.title.toLowerCase().includes(queryLower)) || item.status.toLowerCase().includes(queryLower));
      }
      if (date !== "all") {
        const now = /* @__PURE__ */ new Date();
        const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
        const yesterday = new Date(today);
        yesterday.setDate(yesterday.getDate() - 1);
        const weekAgo = new Date(today);
        weekAgo.setDate(weekAgo.getDate() - 7);
        const monthAgo = new Date(today);
        monthAgo.setDate(monthAgo.getDate() - 30);
        result = result.filter((item) => {
          const itemDate = new Date(item.startedAt);
          switch (date) {
            case "today":
              return itemDate >= today;
            case "yesterday":
              return itemDate >= yesterday && itemDate < today;
            case "week":
              return itemDate >= weekAgo;
            case "month":
              return itemDate >= monthAgo;
            default:
              return true;
          }
        });
      }
      if (status !== "all") result = result.filter((item) => item.status === status);
      return result;
    }
    const pageSize = 20;
    let currentPage = 1;
    let expandedIds = /* @__PURE__ */ new Set();
    const columns = [
      {
        key: "runNumber",
        header: "#",
        sortable: false
      },
      {
        key: "date",
        header: "Date",
        sortable: true
      },
      {
        key: "duration",
        header: "Duration",
        sortable: false
      },
      {
        key: "status",
        header: "Status",
        sortable: true
      },
      {
        key: "summary",
        header: "Summary",
        sortable: false
      }
    ];
    const statusConfig = {
      success: {
        variant: "success",
        icon: Check
      },
      partial: {
        variant: "warning",
        icon: Triangle_alert
      },
      failed: {
        variant: "danger",
        icon: X2
      },
      skipped: {
        variant: "secondary",
        icon: X2
      }
    };
    function getRunNumber(row) {
      const originalIndex = runs.findIndex((r2) => r2.id === row.id);
      return runs.length - originalIndex;
    }
    function formatDuration2(startedAt, completedAt) {
      const ms = new Date(completedAt).getTime() - new Date(startedAt).getTime();
      if (ms < 1e3) return `${ms}ms`;
      if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
      return `${Math.floor(ms / 6e4)}m ${Math.floor(ms % 6e4 / 1e3)}s`;
    }
    function getFileName2(path) {
      return path.split("/").pop() || path;
    }
    $: if (store_get($$store_subs ??= {}, "$page", page)?.params?.id) {
      searchStore = getPersistentSearchStore(`renameRunHistorySearch:${store_get($$store_subs ??= {}, "$page", page).params.id}`);
      debouncedQuery = searchStore.debouncedQuery;
    }
    $: filteredRuns = filterRuns(runs, store_get($$store_subs ??= {}, "$debouncedQuery", debouncedQuery), dateFilter, statusFilter);
    $: totalPages = Math.max(1, Math.ceil(filteredRuns.length / pageSize));
    $: if (currentPage > totalPages) currentPage = 1;
    $: paginatedRuns = filteredRuns.slice((currentPage - 1) * pageSize, currentPage * pageSize);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="-mx-4 bg-neutral-50 px-4 pt-2 pb-6 md:-mx-8 md:px-8 dark:bg-neutral-900"><div class="mb-4">`);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore,
            placeholder: "Search runs..."
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Calendar,
            hasDropdown: true,
            square: true,
            title: "Filter by date",
            $$slots: { dropdown: ($$renderer5) => {
              Dropdown($$renderer5, {
                slot: "dropdown",
                position: "right",
                mobilePosition: "middle",
                children: ($$renderer6) => {
                  $$renderer6.push(`<!--[-->`);
                  const each_array = ensure_array_like([
                    {
                      value: "all",
                      label: "All time"
                    },
                    {
                      value: "today",
                      label: "Today"
                    },
                    {
                      value: "yesterday",
                      label: "Yesterday"
                    },
                    {
                      value: "week",
                      label: "Last 7 days"
                    },
                    {
                      value: "month",
                      label: "Last 30 days"
                    }
                  ]);
                  for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                    let option = each_array[$$index];
                    DropdownItem($$renderer6, {
                      label: option.label,
                      selected: dateFilter === option.value
                    });
                  }
                  $$renderer6.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Circle_dot,
            hasDropdown: true,
            square: true,
            title: "Filter by status",
            $$slots: { dropdown: ($$renderer5) => {
              Dropdown($$renderer5, {
                slot: "dropdown",
                position: "right",
                mobilePosition: "middle",
                children: ($$renderer6) => {
                  $$renderer6.push(`<!--[-->`);
                  const each_array_1 = ensure_array_like([
                    {
                      value: "all",
                      label: "All"
                    },
                    {
                      value: "success",
                      label: "Success"
                    },
                    {
                      value: "partial",
                      label: "Partial"
                    },
                    {
                      value: "failed",
                      label: "Failed"
                    },
                    {
                      value: "skipped",
                      label: "Skipped"
                    }
                  ]);
                  for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                    let option = each_array_1[$$index_1];
                    DropdownItem($$renderer6, {
                      label: option.label,
                      selected: statusFilter === option.value
                    });
                  }
                  $$renderer6.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----></div> `);
      ExpandableTable($$renderer3, {
        columns,
        data: paginatedRuns,
        getRowId: (row) => row.id,
        chevronPosition: "right",
        flushExpanded: true,
        emptyMessage: "No rename runs yet. Configure and enable rename to start.",
        responsive: true,
        get expandedRows() {
          return expandedIds;
        },
        set expandedRows($$value) {
          expandedIds = $$value;
          $$settled = false;
        },
        $$slots: {
          cell: ($$renderer4, { row, column }) => {
            if (column.key === "runNumber") {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="font-mono text-neutral-500 dark:text-neutral-500">#${escape_html(getRunNumber(row))}</span>`);
            } else if (column.key === "date") {
              $$renderer4.push("<!--[1-->");
              $$renderer4.push(`<div class="flex items-center gap-2"><span class="text-neutral-600 dark:text-neutral-400">${escape_html(formatSmartDateTime(row.startedAt, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat)))}</span> `);
              if (row.config.dryRun) {
                $$renderer4.push("<!--[0-->");
                Label($$renderer4, {
                  variant: "info",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer5) => {
                    Flask_conical($$renderer5, { size: 10 });
                    $$renderer5.push(`<!----> Dry Run`);
                  },
                  $$slots: { default: true }
                });
              } else if (row.config.manual) {
                $$renderer4.push("<!--[1-->");
                Label($$renderer4, {
                  variant: "success",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer5) => {
                    Play($$renderer5, { size: 10 });
                    $$renderer5.push(`<!----> Manual`);
                  },
                  $$slots: { default: true }
                });
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></div>`);
            } else if (column.key === "duration") {
              $$renderer4.push("<!--[2-->");
              $$renderer4.push(`<span class="font-mono text-xs text-neutral-600 dark:text-neutral-400">${escape_html(formatDuration2(row.startedAt, row.completedAt))}</span>`);
            } else if (column.key === "status") {
              $$renderer4.push("<!--[3-->");
              const config2 = statusConfig[row.status] || statusConfig.failed;
              Label($$renderer4, {
                variant: config2.variant,
                size: "sm",
                rounded: "md",
                children: ($$renderer5) => {
                  if (config2.icon) {
                    $$renderer5.push("<!--[-->");
                    config2.icon($$renderer5, { size: 10 });
                    $$renderer5.push("<!--]-->");
                  } else {
                    $$renderer5.push("<!--[!-->");
                    $$renderer5.push("<!--]-->");
                  }
                  $$renderer5.push(` ${escape_html(row.status.charAt(0).toUpperCase() + row.status.slice(1))}`);
                },
                $$slots: { default: true }
              });
            } else if (column.key === "summary") {
              $$renderer4.push("<!--[4-->");
              $$renderer4.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400"><span class="font-mono">${escape_html(row.library.totalItems.toLocaleString())}</span> scanned <span class="mx-1 text-neutral-300 dark:text-neutral-600">\u2192</span> `);
              if (row.config.dryRun) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<span class="font-mono">${escape_html(row.results.filesNeedingRename)}</span> would rename`);
              } else {
                $$renderer4.push("<!--[-1-->");
                if (row.results.filesRenamed > 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<span class="font-mono">${escape_html(row.results.filesRenamed)}</span> file${escape_html(row.results.filesRenamed !== 1 ? "s" : "")}`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                if (row.results.foldersRenamed > 0) {
                  $$renderer4.push("<!--[0-->");
                  if (row.results.filesRenamed > 0) {
                    $$renderer4.push("<!--[0-->");
                    $$renderer4.push(`,`);
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--> <span class="font-mono">${escape_html(row.results.foldersRenamed)}</span> folder${escape_html(row.results.foldersRenamed !== 1 ? "s" : "")}`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                if (row.results.filesRenamed > 0 || row.results.foldersRenamed > 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`renamed`);
                } else {
                  $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`no changes`);
                }
                $$renderer4.push(`<!--]-->`);
              }
              $$renderer4.push(`<!--]--></span>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          expanded: ($$renderer4, { row }) => {
            $$renderer4.push(`<div class="space-y-3 p-6"><div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Config</span> <span class="text-sm text-neutral-900 dark:text-neutral-100">`);
            if (row.config.renameFolders) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`Folders enabled`);
            } else {
              $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`Files only`);
            }
            $$renderer4.push(`<!--]--> `);
            if (row.config.ignoreTag) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`| Ignore tag: "${escape_html(row.config.ignoreTag)}"`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></span></div> <div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Library</span> <span class="text-sm text-neutral-900 dark:text-neutral-100"><span class="font-mono">${escape_html(row.library.totalItems.toLocaleString())}</span> items <span class="ml-1 font-mono text-xs text-neutral-500 dark:text-neutral-400">(${escape_html(row.library.fetchDurationMs)}ms)</span></span></div> `);
            if (row.filtering.skippedByTag > 0) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Filtered</span> <span class="text-sm text-neutral-900 dark:text-neutral-100"><span class="font-mono">${escape_html(row.filtering.skippedByTag)}</span> skipped by tag <span class="mx-1 text-neutral-400">\u2192</span> <span class="font-mono font-medium">${escape_html(row.filtering.afterIgnoreTag)}</span> remaining</span></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> <div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Results</span> <span class="text-sm text-neutral-900 dark:text-neutral-100">`);
            if (row.config.dryRun) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="font-mono">${escape_html(row.results.filesNeedingRename)}</span> files would be renamed `);
              if (row.config.renameFolders) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">Folder renames are not included in dry run previews.</div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]-->`);
            } else {
              $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<span class="font-mono">${escape_html(row.results.filesRenamed)}</span> file${escape_html(row.results.filesRenamed !== 1 ? "s" : "")} renamed `);
              if (row.results.foldersRenamed > 0) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`, <span class="font-mono">${escape_html(row.results.foldersRenamed)}</span> folder${escape_html(row.results.foldersRenamed !== 1 ? "s" : "")} renamed`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]-->`);
            }
            $$renderer4.push(`<!--]--> `);
            if (row.results.commandsFailed > 0) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="font-mono text-red-600 dark:text-red-400">, ${escape_html(row.results.commandsFailed)} failed</span>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></span></div> `);
            if (row.results.errors.length > 0) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-red-500 dark:text-red-400">Errors</span> <div class="space-y-1"><!--[-->`);
              const each_array_2 = ensure_array_like(row.results.errors);
              for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
                let error2 = each_array_2[$$index_2];
                $$renderer4.push(`<div class="text-sm text-red-600 dark:text-red-400">${escape_html(error2)}</div>`);
              }
              $$renderer4.push(`<!--]--></div></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            if (row.renamedItems.length > 0) {
              $$renderer4.push("<!--[0-->");
              const itemsColumns = [{
                key: "title",
                header: "Title",
                sortable: false
              }, {
                key: "changes",
                header: "Changes",
                sortable: false,
                align: "center"
              }];
              $$renderer4.push(`<div class="mt-4 border-t border-neutral-200 pt-4 dark:border-neutral-700"><div class="mb-3 flex items-center gap-1.5 text-sm font-medium text-neutral-700 dark:text-neutral-300">`);
              File_text($$renderer4, { size: 14 });
              $$renderer4.push(`<!----> Items ${escape_html(row.config.dryRun ? "Needing Rename" : "Renamed")}</div> `);
              ExpandableTable($$renderer4, {
                columns: itemsColumns,
                data: row.renamedItems,
                getRowId: (item) => item.id,
                compact: true,
                emptyMessage: "No items",
                responsive: true,
                $$slots: {
                  cell: ($$renderer5, { row: item, column }) => {
                    if (column.key === "title") {
                      $$renderer5.push("<!--[0-->");
                      $$renderer5.push(`<span class="text-neutral-900 dark:text-neutral-100">${escape_html(item.title)}</span>`);
                    } else if (column.key === "changes") {
                      $$renderer5.push("<!--[1-->");
                      $$renderer5.push(`<div class="flex gap-1">`);
                      if (item.folder) {
                        $$renderer5.push("<!--[0-->");
                        Badge($$renderer5, {
                          variant: "info",
                          mono: true,
                          children: ($$renderer6) => {
                            $$renderer6.push(`<!---->Folder`);
                          },
                          $$slots: { default: true }
                        });
                      } else $$renderer5.push("<!--[-1-->");
                      $$renderer5.push(`<!--]--> `);
                      if (item.files.length > 0) {
                        $$renderer5.push("<!--[0-->");
                        Badge($$renderer5, {
                          variant: "neutral",
                          mono: true,
                          children: ($$renderer6) => {
                            $$renderer6.push(`<!---->${escape_html(item.files.length)} file${escape_html(item.files.length !== 1 ? "s" : "")}`);
                          },
                          $$slots: { default: true }
                        });
                      } else $$renderer5.push("<!--[-1-->");
                      $$renderer5.push(`<!--]--></div>`);
                    } else $$renderer5.push("<!--[-1-->");
                    $$renderer5.push(`<!--]-->`);
                  },
                  expanded: ($$renderer5, { row: item }) => {
                    {
                      $$renderer5.push(`<div class="space-y-3 p-4">`);
                      if (item.folder) {
                        $$renderer5.push("<!--[0-->");
                        $$renderer5.push(`<div class="space-y-1 border-b border-neutral-200 pb-3 dark:border-neutral-700"><div class="mb-1 text-xs font-medium text-neutral-500 dark:text-neutral-400">Folder</div> <div class="flex gap-2"><span class="w-12 shrink-0 text-xs font-medium text-neutral-500 dark:text-neutral-400">From:</span> <span class="font-mono text-xs break-all text-neutral-700 dark:text-neutral-300">${escape_html(item.folder.existingPath)}</span></div> <div class="flex gap-2"><span class="w-12 shrink-0 text-xs font-medium text-emerald-600 dark:text-emerald-400">To:</span> <span class="font-mono text-xs break-all text-neutral-700 dark:text-neutral-300">${escape_html(item.folder.newPath)}</span></div></div>`);
                      } else $$renderer5.push("<!--[-1-->");
                      $$renderer5.push(`<!--]--> <!--[-->`);
                      const each_array_3 = ensure_array_like(item.files);
                      for (let $$index_3 = 0, $$length = each_array_3.length; $$index_3 < $$length; $$index_3++) {
                        let file = each_array_3[$$index_3];
                        $$renderer5.push(`<div class="space-y-1"><div class="flex gap-2"><span class="w-12 shrink-0 text-xs font-medium text-neutral-500 dark:text-neutral-400">From:</span> <span class="font-mono text-xs break-all text-neutral-700 dark:text-neutral-300">${escape_html(getFileName2(file.existingPath))}</span></div> <div class="flex gap-2"><span class="w-12 shrink-0 text-xs font-medium text-emerald-600 dark:text-emerald-400">To:</span> <span class="font-mono text-xs break-all text-neutral-700 dark:text-neutral-300">${escape_html(getFileName2(file.newPath))}</span></div></div>`);
                      }
                      $$renderer5.push(`<!--]--></div>`);
                    }
                  }
                }
              });
              $$renderer4.push(`<!----></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="mt-3 flex justify-center">`);
      Pagination($$renderer3, {
        currentPage,
        totalPages,
        onPageChange: (p2) => currentPage = p2
      });
      $$renderer3.push(`<!----></div></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { runs });
  });
}
function RenameInfoModal($$renderer, $$props) {
  let open = fallback($$props["open"], false);
  let $$settled = true;
  let $$inner_renderer;
  function $$render_inner($$renderer2) {
    InfoModal($$renderer2, {
      header: "How Rename Works",
      get open() {
        return open;
      },
      set open($$value) {
        open = $$value;
        $$settled = false;
      },
      children: ($$renderer3) => {
        $$renderer3.push(`<div class="space-y-6"><div><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Overview</h3> <p class="text-sm text-neutral-600 dark:text-neutral-400">The rename feature scans your library and renames files that don't match your Radarr/Sonarr
				naming format. This helps keep your library organized and consistent without manual
				intervention.</p></div> <div><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Process</h3> <ol class="list-decimal space-y-1 pl-5 text-sm text-neutral-600 dark:text-neutral-400"><li>Fetches all movies/series from your arr instance</li> <li>Excludes items with the ignore tag (if configured)</li> <li>Compares current file names against your naming format</li> <li>Triggers rename commands for files that need updating</li></ol></div> <div><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Settings</h3> <dl class="space-y-3 text-sm"><div><dt class="font-medium text-neutral-900 dark:text-neutral-100">Dry Run</dt> <dd class="text-neutral-600 dark:text-neutral-400">Shows what files would be renamed without making changes. Use this to preview before
						committing. Folder renames cannot be previewed because the Arr API does not support it,
						so a live run may also rename folders not shown here.</dd></div> <div><dt class="font-medium text-neutral-900 dark:text-neutral-100">Rename Folders</dt> <dd class="text-neutral-600 dark:text-neutral-400">Also rename movie/series folders to match the naming format. Requires a metadata refresh
						after completion.</dd></div> <div><dt class="font-medium text-neutral-900 dark:text-neutral-100">Ignore Tag</dt> <dd class="text-neutral-600 dark:text-neutral-400">Items with this tag in your arr will be skipped. Useful for items you want to keep with
						custom names.</dd></div> <div><dt class="font-medium text-neutral-900 dark:text-neutral-100">Schedule</dt> <dd class="text-neutral-600 dark:text-neutral-400">How often to check for files needing rename. Daily is usually sufficient for most
						libraries.</dd></div> <div><dt class="font-medium text-neutral-900 dark:text-neutral-100">Summary Notifications</dt> <dd class="text-neutral-600 dark:text-neutral-400">When enabled, sends a compact notification with the total count and one sample rename.
						When disabled, sends detailed notifications listing every renamed file.</dd></div></dl></div></div>`);
      },
      $$slots: { default: true }
    });
  }
  do {
    $$settled = true;
    $$inner_renderer = $$renderer.copy();
    $$render_inner($$inner_renderer);
  } while (!$$settled);
  $$renderer.subsume($$inner_renderer);
  bind_props($$props, { open });
}
function _page7($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let isNewConfig, enabled3, renameFolders, ignoreTag, cron, summaryNotifications;
    let data = $$props["data"];
    let form = $$props["form"];
    let showInfoModal = false;
    let lastFormId = null;
    $: isNewConfig = !data.settings;
    $: enabled3 = store_get($$store_subs ??= {}, "$current", current2).enabled ?? false;
    $: renameFolders = store_get($$store_subs ??= {}, "$current", current2).renameFolders ?? false;
    $: ignoreTag = store_get($$store_subs ??= {}, "$current", current2).ignoreTag ?? "";
    $: cron = store_get($$store_subs ??= {}, "$current", current2).cron ?? "0 0 * * *";
    $: summaryNotifications = store_get($$store_subs ??= {}, "$current", current2).summaryNotifications ?? true;
    $: if (form && form !== lastFormId) {
      lastFormId = form;
      if (form.success && !form.queued) {
        alertStore.add("success", "Configuration saved successfully");
        initEdit({
          enabled: enabled3,
          renameFolders,
          ignoreTag,
          cron,
          summaryNotifications
        });
      }
      if (form.success && form.queued) alertStore.add("success", "Rename run queued");
      if (form.error) {
        jobStatus.cancelOptimistic();
        alertStore.add("error", form.error);
      }
    }
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.instance.name} \xB7 Rename` });
      $$renderer3.push(`<!----> <!---->`);
      StickyCard($$renderer3, {
        position: "top",
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<div slot="left"><h1 class="text-xl font-semibold text-neutral-900 dark:text-neutral-50">Rename</h1> <p class="text-sm text-neutral-500 dark:text-neutral-400">Automatically rename files and folders to match your naming format.</p></div>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div slot="right" class="flex items-center gap-2">`);
            Button($$renderer4, {
              text: "How it works",
              icon: Info
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Dry Run",
              icon: Flask_conical,
              iconColor: "text-amber-600 dark:text-amber-400",
              disabled: isNewConfig || !enabled3 || store_get($$store_subs ??= {}, "$isDirty", isDirty),
              tooltip: "Preview which files would be renamed without making changes. Folder renames cannot be previewed.",
              tooltipPosition: "bottom",
              tooltipAlign: "right"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Run Now",
              icon: Play,
              iconColor: "text-green-600 dark:text-green-400",
              disabled: isNewConfig || !enabled3 || store_get($$store_subs ??= {}, "$isDirty", isDirty),
              tooltip: "Rename files and folders now",
              tooltipPosition: "bottom",
              tooltipAlign: "right"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Save",
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              disabled: !store_get($$store_subs ??= {}, "$isDirty", isDirty)
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="mt-4 space-y-6"><section class="border-b border-neutral-200 pb-5 dark:border-neutral-800">`);
      RenameSettings($$renderer3, {
        enabled: enabled3,
        renameFolders,
        ignoreTag,
        cron,
        summaryNotifications,
        lastRunAt: data.settings?.lastRunAt ?? null,
        nextRunAt: data.settings?.nextRunAt ?? null,
        onEnabledChange: (v3) => update3("enabled", v3),
        onRenameFoldersChange: (v3) => update3("renameFolders", v3),
        onIgnoreTagChange: (v3) => update3("ignoreTag", v3),
        onCronChange: (v3) => update3("cron", v3),
        onSummaryNotificationsChange: (v3) => update3("summaryNotifications", v3),
        onWarning: (msg) => alertStore.add("warning", msg)
      });
      $$renderer3.push(`<!----></section> `);
      if (enabled3) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<section class="md:px-4">`);
        RenameRunHistory($$renderer3, { runs: data.renameRuns });
        $$renderer3.push(`<!----></section>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<section class="md:px-4"><div class="rounded-xl border border-neutral-300 dark:border-neutral-700/60"><p class="px-4 py-4 text-center text-sm text-neutral-600 dark:text-neutral-400">Enable rename to view run history.</p></div></section>`);
      }
      $$renderer3.push(`<!--]--></div> <form id="save-form" method="POST"${attr("action", isNewConfig ? "?/save" : "?/update")} class="hidden"><input type="hidden" name="enabled"${attr("value", enabled3)}/> <input type="hidden" name="renameFolders"${attr("value", renameFolders)}/> <input type="hidden" name="ignoreTag"${attr("value", ignoreTag)}/> <input type="hidden" name="cron"${attr("value", cron)}/> <input type="hidden" name="summaryNotifications"${attr("value", summaryNotifications)}/></form> `);
      if (!isNewConfig) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form id="dry-run-form" method="POST" action="?/run" class="hidden"><input type="hidden" name="dryRun" value="true"/></form> <form id="live-run-form" method="POST" action="?/run" class="hidden"><input type="hidden" name="dryRun" value="false"/></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      RenameInfoModal($$renderer3, {
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      DirtyModal($$renderer3, {});
      $$renderer3.push(`<!---->`);
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      data,
      form
    });
  });
}
var init_page_svelte7 = __esm({
  "dist/build/server/entries/pages/arr/_id_/rename/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_dates();
    init_Dropdown();
    init_calendar();
    init_check();
    init_circle_dot();
    init_file_text();
    init_flask_conical();
    init_info();
    init_Button();
    init_play();
    init_save();
    init_search();
    init_triangle_alert();
    init_x();
    init_client4();
    init_stores();
    init_store2();
    init_Label();
    init_jobStatus();
    init_navigation();
    init_dateFormat();
    init_timezone();
    init_forms();
    init_DropdownItem();
    init_dirty();
    init_DirtyModal();
    init_ExpandableTable();
    init_ActionsBar();
    init_ActionButton();
    init_Badge();
    init_InfoModal();
    init_PageMeta();
    init_StickyCard();
    init_FormInput();
    init_CronInput();
    init_Toggle();
    init_Pagination();
  }
});

// dist/build/server/nodes/14.js
var __exports15 = {};
__export(__exports15, {
  component: () => component14,
  fonts: () => fonts15,
  imports: () => imports15,
  index: () => index15,
  server: () => page_server_ts_exports8,
  server_id: () => server_id14,
  stylesheets: () => stylesheets15
});
var index15, component_cache14, component14, server_id14, imports15, stylesheets15, fonts15;
var init__15 = __esm({
  async "dist/build/server/nodes/14.js"() {
    "use strict";
    await init_page_server_ts8();
    index15 = 14;
    component14 = async () => component_cache14 ??= (await Promise.resolve().then(() => (init_page_svelte7(), page_svelte_exports7))).default;
    server_id14 = "src/routes/arr/[id]/rename/+page.server.ts";
    imports15 = ["_app/immutable/nodes/14.C1CbpgUj.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/Cz3WzBYs.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/By4o5e8D2.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/SEZzcS_o.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/BlAgBW4v.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/COLvC_Ug.js", "_app/immutable/chunks/C47WFcPn.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/DTxrEb2m.js", "_app/immutable/chunks/D1MpTH1m.js"];
    stylesheets15 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css"];
    fonts15 = [];
  }
});

// dist/build/server/entries/pages/arr/_id_/settings/_page.server.ts.js
var page_server_ts_exports9 = {};
__export(page_server_ts_exports9, {
  actions: () => actions6,
  load: () => load14
});
var load14, actions6;
var init_page_server_ts9 = __esm({
  async "dist/build/server/entries/pages/arr/_id_/settings/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_queueService();
    await init_arrCleanupSettings();
    await init_cleanup();
    await init_init();
    init_exports();
    load14 = ({ params }) => {
      const id = parseInt(params.id || "", 10);
      return { cleanupSettings: arrCleanupSettingsQueries.getByInstanceId(id) ?? null };
    };
    actions6 = {
      update: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        const formData = await request.formData();
        const name = formData.get("name")?.toString().trim();
        const url = formData.get("url")?.toString().trim();
        const externalUrlRaw = formData.get("external_url")?.toString().trim() ?? "";
        const externalUrl = externalUrlRaw === "" ? null : externalUrlRaw;
        const apiKey = formData.get("api_key")?.toString().trim() || instance.api_key;
        const tagsJson = formData.get("tags")?.toString() || "";
        const libraryRefreshInterval = parseInt(formData.get("library_refresh_interval")?.toString() || "0", 10) || 0;
        if (!name) return fail(400, { error: "Name is required" });
        if (!url) return fail(400, { error: "URL is required" });
        if (arrInstancesQueries.nameExists(name, id)) return fail(400, { error: "An instance with this name already exists" });
        if (arrInstancesQueries.targetExists(instance.type, url, id)) return fail(400, { error: "This instance target is already configured" });
        let tags = [];
        if (tagsJson) try {
          tags = JSON.parse(tagsJson);
        } catch {
        }
        try {
          arrInstancesQueries.update(id, {
            name,
            url,
            externalUrl,
            apiKey,
            tags,
            libraryRefreshInterval
          });
          scheduleLibraryRefreshForInstance(id);
          const cleanup2 = arrCleanupSettingsQueries.getByInstanceId(id);
          await logger.info(`Updated arr instance: ${name}`, {
            source: "arr/[id]/settings",
            meta: {
              id,
              name,
              type: instance.type,
              url,
              externalUrl,
              libraryRefreshInterval,
              cleanup: cleanup2 ? {
                enabled: cleanup2.enabled,
                cron: cleanup2.cron
              } : null
            }
          });
          return { success: true };
        } catch (err) {
          await logger.error("Failed to update arr instance", {
            source: "arr/[id]/settings",
            meta: { error: err instanceof Error ? err.message : String(err) }
          });
          return fail(500, { error: "Failed to update instance" });
        }
      },
      updateCleanup: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const formData = await request.formData();
        const enabled3 = formData.get("enabled")?.toString() === "1";
        const cron = formData.get("cron")?.toString() || "0 0 * * 0";
        try {
          arrCleanupSettingsQueries.upsert(id, {
            enabled: enabled3,
            cron
          });
          const nextRunAt = calculateNextRun(cron);
          if (nextRunAt) arrCleanupSettingsQueries.updateNextRunAt(id, nextRunAt);
          scheduleCleanupForInstance(id);
          return { success: true };
        } catch (err) {
          await logger.error("Failed to save cleanup settings", {
            source: "arr/[id]/settings",
            meta: { error: err instanceof Error ? err.message : String(err) }
          });
          return fail(500, { error: "Failed to save cleanup settings" });
        }
      },
      runCleanupNow: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        if (instance.type !== "radarr" && instance.type !== "sonarr") return fail(400, { error: `Cleanup not supported for ${instance.type}` });
        const preScannedRaw = (await request.formData()).get("preScanned")?.toString();
        let preScanned;
        if (preScannedRaw) try {
          preScanned = JSON.parse(preScannedRaw);
        } catch {
          return fail(400, { error: "Invalid preScanned data" });
        }
        try {
          const queued = enqueueJob({
            jobType: "arr.cleanup",
            runAt: (/* @__PURE__ */ new Date()).toISOString(),
            payload: {
              instanceId: id,
              preScanned
            },
            source: "manual"
          });
          await logger.info("Manual cleanup run queued", {
            source: "arr/[id]/settings",
            meta: {
              jobId: queued.id,
              instanceId: id,
              instanceName: instance.name
            }
          });
          return {
            success: true,
            queued: true
          };
        } catch (err) {
          await logger.error("Manual cleanup run failed", {
            source: "arr/[id]/settings",
            meta: {
              instanceId: id,
              error: err instanceof Error ? err.message : String(err)
            }
          });
          return fail(500, { error: "Cleanup run failed. Check logs for details." });
        }
      },
      delete: async ({ params }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) {
          await logger.warn("Delete failed: Invalid instance ID", {
            source: "arr/[id]/settings",
            meta: { id: params.id }
          });
          return fail(400, { error: "Invalid instance ID" });
        }
        const instance = arrInstancesQueries.getById(id);
        if (!instance) {
          await logger.warn("Delete failed: Instance not found", {
            source: "arr/[id]/settings",
            meta: { id }
          });
          return fail(404, { error: "Instance not found" });
        }
        cleanupJobsForArrInstance(id);
        if (!arrInstancesQueries.delete(id)) {
          await logger.error("Failed to delete instance", {
            source: "arr/[id]/settings",
            meta: {
              id,
              name: instance.name,
              type: instance.type
            }
          });
          return fail(500, { error: "Failed to delete instance" });
        }
        await logger.info(`Deleted ${instance.type} instance: ${instance.name}`, {
          source: "arr/[id]/settings",
          meta: {
            id,
            name: instance.name,
            type: instance.type,
            url: instance.url
          }
        });
        redirect(303, "/arr");
      }
    };
  }
});

// dist/build/server/chunks/wifi.js
function Wifi($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "wifi" },
    props,
    { iconNode: [
      ["path", { "d": "M12 20h.01" }],
      ["path", { "d": "M2 8.82a15 15 0 0 1 20 0" }],
      ["path", { "d": "M5 12.859a10 10 0 0 1 14 0" }],
      ["path", { "d": "M8.5 16.429a5 5 0 0 1 7 0" }]
    ] }
  ]));
}
var init_wifi = __esm({
  "dist/build/server/chunks/wifi.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/TagInput.js
function TagInput($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let tags = fallback($$props["tags"], () => [], true);
    let placeholder = fallback($$props["placeholder"], "Type and press Enter to add tags");
    let onchange = fallback($$props["onchange"], void 0);
    let inputValue = "";
    function isNegated(tag2) {
      return tag2.toUpperCase().startsWith("NOT:");
    }
    function displayName(tag2) {
      if (isNegated(tag2)) return tag2.slice(4).trim();
      return tag2;
    }
    $$renderer2.push(`<div class="flex min-h-[2.5rem] flex-wrap items-center gap-2 rounded-xl border border-neutral-300 bg-white px-3 py-2 text-sm text-neutral-900 transition-colors dark:border-neutral-700/60 dark:bg-neutral-800/50 dark:text-neutral-50"><!--[-->`);
    const each_array = ensure_array_like(tags);
    for (let index88 = 0, $$length = each_array.length; index88 < $$length; index88++) {
      let tag2 = each_array[index88];
      $$renderer2.push(`<span class="inline-flex items-center gap-1">`);
      Label($$renderer2, {
        variant: isNegated(tag2) ? "danger" : "info",
        size: "md",
        rounded: "md",
        children: ($$renderer3) => {
          $$renderer3.push(`<!---->${escape_html(displayName(tag2))}`);
        },
        $$slots: { default: true }
      });
      $$renderer2.push(`<!----> <button type="button" class="text-neutral-400 hover:text-neutral-600 dark:hover:text-neutral-200" aria-label="Remove tag">`);
      X2($$renderer2, { size: 14 });
      $$renderer2.push(`<!----></button></span>`);
    }
    $$renderer2.push(`<!--]--> <input type="text" id="tags-input"${attr("value", inputValue)}${attr("placeholder", placeholder)} class="min-w-[120px] flex-1 border-0 bg-transparent text-sm text-neutral-900 outline-none placeholder:text-neutral-400 focus:ring-0 dark:text-neutral-50 dark:placeholder:text-neutral-500"/></div>`);
    bind_props($$props, {
      tags,
      placeholder,
      onchange
    });
  });
}
var init_TagInput = __esm({
  "dist/build/server/chunks/TagInput.js"() {
    "use strict";
    init_server();
    init_x();
    init_store2();
    init_Label();
  }
});

// dist/build/server/chunks/InstanceForm.js
function Eraser($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "eraser" },
    props,
    { iconNode: [["path", { "d": "M21 21H8a2 2 0 0 1-1.42-.587l-3.994-3.999a2 2 0 0 1 0-2.828l10-10a2 2 0 0 1 2.829 0l5.999 6a2 2 0 0 1 0 2.828L12.834 21" }], ["path", { "d": "m5.082 11.09 8.828 8.828" }]] }
  ]));
}
function CleanupModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let isLoading, configEmpty, entityEmpty, allEmpty, hasAnythingToClean, confirmText, confirmDanger, confirmDisabled, preScannedPayload, entityLabel2, externalDb;
    let open = fallback($$props["open"], false);
    let instanceId = $$props["instanceId"];
    let instanceType = fallback($$props["instanceType"], "");
    let phase = "idle";
    let configScan = null;
    let configError = null;
    let entityScan = null;
    let entityError = null;
    async function scanAll() {
      phase = "scanning";
      try {
        const res = await fetch(`/arr/${instanceId}/settings/cleanup/preview`);
        if (!res.ok) {
          const message2 = (await res.json().catch(() => ({})))?.error ?? "Preview failed";
          configError = message2;
          entityError = message2;
        } else {
          const body = await res.json();
          if (body.configs.ok) configScan = body.configs.data;
          else configError = body.configs.error;
          if (body.entities.ok) entityScan = body.entities.data;
          else entityError = body.entities.error;
        }
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Preview failed";
        configError = message2;
        entityError = message2;
      }
      phase = "preview";
    }
    $: isLoading = phase === "scanning" || phase === "submitting";
    $: configEmpty = configScan != null && configScan.staleCustomFormats.length === 0 && configScan.staleQualityProfiles.length === 0;
    $: entityEmpty = entityScan != null && entityScan.removedEntities.length === 0;
    $: allEmpty = configEmpty && entityEmpty;
    $: hasAnythingToClean = phase === "preview" && !allEmpty && !configError && !entityError;
    $: confirmText = (() => {
      if (phase === "scanning") return "Scanning...";
      if (phase === "submitting") return "Queueing...";
      if (hasAnythingToClean) return "Clean Up";
      return "Close";
    })();
    $: confirmDanger = hasAnythingToClean;
    $: confirmDisabled = phase === "scanning" || phase === "submitting";
    $: preScannedPayload = (() => {
      if (!configScan || !entityScan) return "";
      return JSON.stringify({
        staleConfigs: configScan,
        removedEntities: entityScan
      });
    })();
    $: if (open && phase === "idle") scanAll();
    $: entityLabel2 = instanceType === "radarr" ? "movies" : instanceType === "sonarr" ? "series" : "items";
    $: externalDb = instanceType === "radarr" ? "TMDB" : instanceType === "sonarr" ? "TVDB" : "external DB";
    $$renderer2.push(`<form method="POST" action="?/runCleanupNow" class="hidden"><input type="hidden" name="preScanned"${attr("value", preScannedPayload)}/></form> `);
    Modal($$renderer2, {
      open,
      header: "Cleanup",
      confirmText,
      confirmDanger,
      confirmDisabled,
      loading: isLoading,
      $$slots: { body: ($$renderer3) => {
        $$renderer3.push(`<div slot="body">`);
        if (phase === "scanning") {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="flex flex-col items-center gap-3 py-8">`);
          Loader_circle($$renderer3, {
            size: 32,
            class: "animate-spin text-neutral-400"
          });
          $$renderer3.push(`<!----> <p class="text-sm text-neutral-500 dark:text-neutral-400">Scanning for stale configs and removed media...</p></div>`);
        } else if (phase === "submitting") {
          $$renderer3.push("<!--[1-->");
          $$renderer3.push(`<div class="flex flex-col items-center gap-3 py-8">`);
          Loader_circle($$renderer3, {
            size: 32,
            class: "animate-spin text-neutral-400"
          });
          $$renderer3.push(`<!----> <p class="text-sm text-neutral-500 dark:text-neutral-400">Queueing cleanup job...</p></div>`);
        } else if (phase === "preview") {
          $$renderer3.push("<!--[2-->");
          if (allEmpty && !configError && !entityError) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex flex-col items-center gap-3 py-8">`);
            Check($$renderer3, {
              size: 32,
              class: "text-emerald-500"
            });
            $$renderer3.push(`<!----> <p class="text-sm text-neutral-600 dark:text-neutral-400">Nothing to clean up. Everything looks good.</p></div>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<div class="space-y-4">`);
            if (configError) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="flex items-start gap-3 rounded-lg border border-red-200 bg-red-50 p-3 dark:border-red-800 dark:bg-red-950">`);
              Triangle_alert($$renderer3, {
                size: 16,
                class: "mt-0.5 flex-shrink-0 text-red-500"
              });
              $$renderer3.push(`<!----> <div><p class="text-sm font-medium text-red-800 dark:text-red-200">Config scan failed</p> <p class="mt-0.5 text-xs text-red-600 dark:text-red-400">${escape_html(configError)}</p></div></div>`);
            } else if (!configEmpty && configScan) {
              $$renderer3.push("<!--[1-->");
              $$renderer3.push(`<div class="space-y-2"><p class="text-xs font-medium tracking-wide text-neutral-500 uppercase dark:text-neutral-400">Stale Configs</p> <div class="space-y-1">`);
              if (configScan.staleCustomFormats.length > 0) {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<p class="text-sm text-neutral-700 dark:text-neutral-300"><span class="font-medium">${escape_html(configScan.staleCustomFormats.length)}</span> custom
										format${escape_html(configScan.staleCustomFormats.length === 1 ? "" : "s")}</p>`);
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--> `);
              if (configScan.staleQualityProfiles.length > 0) {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<p class="text-sm text-neutral-700 dark:text-neutral-300"><span class="font-medium">${escape_html(configScan.staleQualityProfiles.length)}</span> quality profile${escape_html(configScan.staleQualityProfiles.length === 1 ? "" : "s")}</p>`);
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--></div></div>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--> `);
            if (entityError) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="flex items-start gap-3 rounded-lg border border-red-200 bg-red-50 p-3 dark:border-red-800 dark:bg-red-950">`);
              Triangle_alert($$renderer3, {
                size: 16,
                class: "mt-0.5 flex-shrink-0 text-red-500"
              });
              $$renderer3.push(`<!----> <div><p class="text-sm font-medium text-red-800 dark:text-red-200">Entity scan failed</p> <p class="mt-0.5 text-xs text-red-600 dark:text-red-400">${escape_html(entityError)}</p></div></div>`);
            } else if (!entityEmpty && entityScan) {
              $$renderer3.push("<!--[1-->");
              $$renderer3.push(`<div class="space-y-2"><p class="text-xs font-medium tracking-wide text-neutral-500 uppercase dark:text-neutral-400">Removed Media</p> <p class="text-sm text-neutral-700 dark:text-neutral-300"><span class="font-medium">${escape_html(entityScan.removedEntities.length)}</span> ${escape_html(entityLabel2)} removed from ${escape_html(externalDb)}</p> <div class="max-h-40 overflow-y-auto"><!--[-->`);
              const each_array = ensure_array_like(entityScan.removedEntities);
              for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                let entity = each_array[$$index];
                $$renderer3.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">${escape_html(entity.title)}</p>`);
              }
              $$renderer3.push(`<!--]--></div></div>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div>`);
          }
          $$renderer3.push(`<!--]-->`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      } }
    });
    $$renderer2.push(`<!---->`);
    bind_props($$props, {
      open,
      instanceId,
      instanceType
    });
  });
}
function InstanceForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let name, type, url, externalUrl, apiKey, tags, libraryRefreshInterval, cleanupEnabled, cleanupCron, canSubmit, title, description, cleanupNextRunTime, cleanupTimeUntilNext;
    let mode = $$props["mode"];
    let instance = fallback($$props["instance"], void 0);
    let initialType = fallback($$props["initialType"], "");
    let form = fallback($$props["form"], void 0);
    let cleanupSettings = fallback($$props["cleanupSettings"], null);
    let cronInputValue = cleanupSettings?.cron ?? "0 0 * * 0";
    let saving = false;
    let deleting = false;
    let showDeleteModal = false;
    let showCleanupModal = false;
    const typeOptions = [{
      value: "radarr",
      label: "Radarr"
    }, {
      value: "sonarr",
      label: "Sonarr"
    }];
    const libraryRefreshOptions = [
      {
        value: "0",
        label: "Manual"
      },
      {
        value: "10",
        label: "Every 10 minutes"
      },
      {
        value: "30",
        label: "Every 30 minutes"
      },
      {
        value: "60",
        label: "Every hour"
      },
      {
        value: "360",
        label: "Every 6 hours"
      },
      {
        value: "720",
        label: "Every 12 hours"
      },
      {
        value: "1440",
        label: "Every 24 hours"
      },
      {
        value: "10080",
        label: "Weekly"
      }
    ];
    let lastFormId = null;
    let now = Date.now();
    onDestroy(() => {
    });
    function formatTimeRemaining(ms) {
      if (ms <= 0) return "now";
      const seconds = Math.floor(ms / 1e3);
      const minutes = Math.floor(seconds / 60);
      const hours = Math.floor(minutes / 60);
      if (hours > 0) return `${hours}h ${minutes % 60}m`;
      if (minutes > 0) return `${minutes}m`;
      return `${seconds}s`;
    }
    $: name = store_get($$store_subs ??= {}, "$current", current2).name ?? "";
    $: type = store_get($$store_subs ??= {}, "$current", current2).type ?? "";
    $: url = store_get($$store_subs ??= {}, "$current", current2).url ?? "";
    $: externalUrl = store_get($$store_subs ??= {}, "$current", current2).externalUrl ?? "";
    $: apiKey = store_get($$store_subs ??= {}, "$current", current2).apiKey ?? "";
    $: tags = JSON.parse(store_get($$store_subs ??= {}, "$current", current2).tags ?? "[]");
    $: libraryRefreshInterval = store_get($$store_subs ??= {}, "$current", current2).libraryRefreshInterval ?? "0";
    $: cleanupEnabled = store_get($$store_subs ??= {}, "$current", current2).cleanupEnabled ?? false;
    $: cleanupCron = store_get($$store_subs ??= {}, "$current", current2).cleanupCron ?? "0 0 * * 0";
    $: cronInputValue = cleanupCron;
    $: if (cronInputValue !== cleanupCron) update3("cleanupCron", cronInputValue);
    $: canSubmit = store_get($$store_subs ??= {}, "$isDirty", isDirty) && !!name && !!url && (mode === "edit" || !!apiKey && !!type);
    $: if (form && form !== lastFormId) {
      lastFormId = form;
      if (form.success) {
        alertStore.add("success", "Settings saved successfully");
        initEdit({
          name,
          type,
          url,
          externalUrl,
          apiKey: "",
          tags: JSON.stringify(tags),
          libraryRefreshInterval,
          cleanupEnabled,
          cleanupCron
        });
      }
      if (form.error) alertStore.add("error", form.error);
    }
    $: title = mode === "create" ? "Add Instance" : "Settings";
    $: description = mode === "create" ? "Configure a new Radarr or Sonarr instance." : `Configure connection and sync settings for ${instance?.name || "this instance"}.`;
    $: cleanupNextRunTime = cleanupSettings?.nextRunAt ? new Date(cleanupSettings.nextRunAt).getTime() : null;
    $: cleanupTimeUntilNext = cleanupNextRunTime ? cleanupNextRunTime - now : null;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      StickyCard($$renderer3, {
        position: "top",
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<h1 class="text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h1> <p class="text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p>`);
          },
          right: ($$renderer4) => {
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                text: "Delete",
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                disabled: deleting
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> <div data-onboarding="arr-save">`);
            Button($$renderer4, {
              text: "Save",
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              disabled: !canSubmit
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="mt-4 space-y-6"><div class="space-y-4 rounded-lg border border-neutral-200 bg-white p-4 dark:border-neutral-800 dark:bg-neutral-900"><div data-onboarding="arr-connection" class="space-y-4"><div class="flex flex-col gap-4 2xl:flex-row"><div class="min-w-0 space-y-2 2xl:flex-[3]"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Name<span class="text-red-500">*</span></div> <p class="text-xs text-neutral-600 dark:text-neutral-400">The display name for this Arr instance</p> `);
      FormInput($$renderer3, {
        label: "Name",
        name: "name",
        value: name,
        placeholder: "e.g., Main Radarr, 4K Sonarr",
        required: true,
        hideLabel: true
      });
      $$renderer3.push(`<!----></div> <div class="min-w-0 space-y-2 2xl:flex-1" data-onboarding="arr-type"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Type`);
      if (mode === "create") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<span class="text-red-500">*</span>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Type cannot be changed after creation</p> `);
      DropdownSelect($$renderer3, {
        value: type,
        options: typeOptions,
        placeholder: "Select type...",
        disabled: mode === "edit",
        fullWidth: true,
        position: "right",
        menuOnboarding: "arr-type-menu"
      });
      $$renderer3.push(`<!----></div></div> `);
      FormInput($$renderer3, {
        label: "URL",
        name: "url",
        type: "url",
        value: url,
        placeholder: "http://localhost:7878",
        description: "Use container name if on the same Docker network, e.g. http://radarr:7878",
        required: true
      });
      $$renderer3.push(`<!----> `);
      FormInput($$renderer3, {
        label: "External URL",
        name: "external_url",
        type: "url",
        value: externalUrl,
        placeholder: "https://radarr.example.com",
        description: "Optional. Used for 'Open in Radarr/Sonarr' browser links. Leave blank to reuse the URL above. Set this when Profilarr reaches the instance internally but users reach it through a reverse proxy."
      });
      $$renderer3.push(`<!----> <div class="flex flex-col gap-4 md:flex-row md:items-end"><div class="flex-1">`);
      FormInput($$renderer3, {
        label: "API Key",
        name: "api_key",
        value: apiKey,
        placeholder: mode === "edit" ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : "Enter API key",
        description: mode === "edit" ? "Leave blank to keep existing key" : "",
        required: true,
        private_: true
      });
      $$renderer3.push(`<!----></div> `);
      Button($$renderer3, {
        text: "Test Connection",
        icon: Wifi,
        disabled: !apiKey || !url || mode === "create" && !type
      });
      $$renderer3.push(`<!----></div></div> <div class="space-y-2"><span class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Tags</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Press Enter to add a tag, Backspace to remove</p> `);
      TagInput($$renderer3, { tags });
      $$renderer3.push(`<!----></div> `);
      if (mode === "edit" && instance) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="space-y-2"><span class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Library Refresh</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">How often to refresh cached library data in the background</p> `);
        DropdownSelect($$renderer3, {
          value: libraryRefreshInterval,
          options: libraryRefreshOptions,
          fullWidth: true
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (mode === "edit" && instance) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="space-y-2"><span class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Cleanup</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Remove unused quality profiles, custom formats, and media flagged as removed from
					TMDB/TVDB</p> <div class="grid grid-cols-[auto_1fr] items-center gap-x-4 gap-y-3 md:flex md:flex-wrap md:gap-x-6"><div class="md:flex md:items-center md:gap-2">`);
        Toggle($$renderer3, {
          checked: cleanupEnabled,
          label: cleanupEnabled ? "Enabled" : "Disabled",
          color: cleanupEnabled ? "green" : "red"
        });
        $$renderer3.push(`<!----></div> `);
        if (cleanupEnabled) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="col-span-2 md:col-span-1 md:flex md:items-center md:gap-2"><span class="mb-1 block text-sm text-neutral-500 md:hidden dark:text-neutral-400">Schedule</span> <span class="hidden text-sm text-neutral-500 md:inline dark:text-neutral-400">Schedule:</span> `);
          CronInput($$renderer3, {
            fixed: true,
            minIntervalMinutes: 60,
            onWarning: (msg) => alertStore.add("warning", msg),
            get value() {
              return cronInputValue;
            },
            set value($$value) {
              cronInputValue = $$value;
              $$settled = false;
            }
          });
          $$renderer3.push(`<!----></div> <div class="col-span-2 flex flex-wrap items-center gap-3 md:ml-auto">`);
          if (cleanupSettings?.lastRunAt) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex flex-wrap items-center gap-3 border-t border-neutral-200 pt-3 text-xs text-neutral-500 md:border-0 md:pt-0 dark:border-neutral-700 dark:text-neutral-400">`);
            if (cleanupTimeUntilNext !== null && cleanupTimeUntilNext <= 0) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<span class="rounded bg-green-100 px-1.5 py-0.5 font-medium text-green-700 dark:bg-green-900/50 dark:text-green-400">Ready</span>`);
            } else if (cleanupTimeUntilNext !== null) {
              $$renderer3.push("<!--[1-->");
              $$renderer3.push(`<span>Next: <span class="rounded bg-neutral-100 px-1.5 py-0.5 font-mono text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300">${escape_html(formatTimeRemaining(cleanupTimeUntilNext))}</span></span>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--> <span>Last: <span class="rounded bg-neutral-100 px-1.5 py-0.5 font-mono text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300">${escape_html(formatSmartDateTime(cleanupSettings.lastRunAt, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat)))}</span></span></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          Button($$renderer3, {
            text: "Run Now",
            icon: Eraser,
            iconColor: "text-amber-600 dark:text-amber-400",
            disabled: store_get($$store_subs ??= {}, "$isDirty", isDirty) || saving
          });
          $$renderer3.push(`<!----></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div></div> <form id="save-form" method="POST"${attr("action", mode === "edit" ? "?/update" : void 0)} class="hidden"><input type="hidden" name="name"${attr("value", name)}/> <input type="hidden" name="type"${attr("value", type)}/> <input type="hidden" name="url"${attr("value", url)}/> <input type="hidden" name="external_url"${attr("value", externalUrl)}/> <input type="hidden" name="api_key"${attr("value", apiKey)}/> <input type="hidden" name="tags"${attr("value", JSON.stringify(tags))}/> <input type="hidden" name="library_refresh_interval"${attr("value", libraryRefreshInterval)}/></form> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form id="delete-form" method="POST" action="?/delete" class="hidden"></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        Modal($$renderer3, {
          open: showDeleteModal,
          header: "Delete Instance",
          bodyMessage: `Are you sure you want to delete "${instance?.name}"? This action cannot be undone.`,
          confirmText: "Delete",
          cancelText: "Cancel",
          confirmDanger: true
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      DirtyModal($$renderer3, {});
      $$renderer3.push(`<!----> `);
      if (mode === "edit" && instance) {
        $$renderer3.push("<!--[0-->");
        CleanupModal($$renderer3, {
          instanceId: instance.id,
          instanceType: type,
          get open() {
            return showCleanupModal;
          },
          set open($$value) {
            showCleanupModal = $$value;
            $$settled = false;
          }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]-->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      instance,
      initialType,
      form,
      cleanupSettings
    });
  });
}
var init_InstanceForm = __esm({
  "dist/build/server/chunks/InstanceForm.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_dates();
    init_Icon();
    init_check();
    init_Button();
    init_save();
    init_trash_2();
    init_triangle_alert();
    init_wifi();
    init_store2();
    init_jobStatus();
    init_Modal();
    init_dateFormat();
    init_timezone();
    init_forms();
    init_dirty();
    init_DirtyModal();
    init_StickyCard();
    init_DropdownSelect();
    init_FormInput();
    init_CronInput();
    init_Toggle();
    init_TagInput();
  }
});

// dist/build/server/entries/pages/arr/_id_/settings/_page.svelte.js
var page_svelte_exports8 = {};
__export(page_svelte_exports8, {
  default: () => _page8
});
function _page8($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let form = $$props["form"];
    let data = $$props["data"];
    PageMeta($$renderer2, { title: `${data.instance.name} \xB7 Settings` });
    $$renderer2.push(`<!----> `);
    InstanceForm($$renderer2, {
      mode: "edit",
      form,
      instance: data.instance,
      cleanupSettings: data.cleanupSettings
    });
    $$renderer2.push(`<!---->`);
    bind_props($$props, {
      form,
      data
    });
  });
}
var init_page_svelte8 = __esm({
  "dist/build/server/entries/pages/arr/_id_/settings/_page.svelte.js"() {
    "use strict";
    init_server();
    init_InstanceForm();
    init_PageMeta();
  }
});

// dist/build/server/nodes/15.js
var __exports16 = {};
__export(__exports16, {
  component: () => component15,
  fonts: () => fonts16,
  imports: () => imports16,
  index: () => index16,
  server: () => page_server_ts_exports9,
  server_id: () => server_id15,
  stylesheets: () => stylesheets16
});
var index16, component_cache15, component15, server_id15, imports16, stylesheets16, fonts16;
var init__16 = __esm({
  async "dist/build/server/nodes/15.js"() {
    "use strict";
    await init_page_server_ts9();
    index16 = 15;
    component15 = async () => component_cache15 ??= (await Promise.resolve().then(() => (init_page_svelte8(), page_svelte_exports8))).default;
    server_id15 = "src/routes/arr/[id]/settings/+page.server.ts";
    imports16 = ["_app/immutable/nodes/15.4zbxDibV.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/R2NcgasX2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/BJGxfzgf2.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/COLvC_Ug.js", "_app/immutable/chunks/C47WFcPn.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/CK2yQf0C.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets16 = [];
    fonts16 = [];
  }
});

// dist/build/server/chunks/naming.js
async function createRadarrNaming(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  if (await db2.selectFrom("radarr_naming").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) throw new Error(`A radarr naming config with name "${input.name}" already exists`);
  const insertQuery = db2.insertInto("radarr_naming").values({
    name: input.name,
    rename: input.rename ? 1 : 0,
    movie_format: input.movieFormat,
    movie_folder_format: input.movieFolderFormat,
    replace_illegal_characters: input.replaceIllegalCharacters ? 1 : 0,
    colon_replacement_format: input.colonReplacementFormat
  }).compile();
  return writeOperation({
    databaseId,
    layer,
    description: `create-radarr-naming-${input.name}`,
    queries: [insertQuery],
    desiredState: {
      name: input.name,
      rename: input.rename,
      movie_format: input.movieFormat,
      movie_folder_format: input.movieFolderFormat,
      replace_illegal_characters: input.replaceIllegalCharacters,
      colon_replacement_format: input.colonReplacementFormat
    },
    metadata: {
      operation: "create",
      entity: "radarr_naming",
      name: input.name,
      stableKey: {
        key: "radarr_naming_name",
        value: input.name
      },
      summary: "Create Radarr naming config",
      title: `Create Radarr naming "${input.name}"`
    }
  });
}
async function createSonarrNaming(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  if (await db2.selectFrom("sonarr_naming").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) throw new Error(`A sonarr naming config with name "${input.name}" already exists`);
  const insertQuery = db2.insertInto("sonarr_naming").values({
    name: input.name,
    rename: input.rename ? 1 : 0,
    standard_episode_format: input.standardEpisodeFormat,
    daily_episode_format: input.dailyEpisodeFormat,
    anime_episode_format: input.animeEpisodeFormat,
    series_folder_format: input.seriesFolderFormat,
    season_folder_format: input.seasonFolderFormat,
    replace_illegal_characters: input.replaceIllegalCharacters ? 1 : 0,
    colon_replacement_format: colonReplacementToDb(input.colonReplacementFormat),
    custom_colon_replacement_format: input.customColonReplacementFormat,
    multi_episode_style: multiEpisodeStyleToDb(input.multiEpisodeStyle)
  }).compile();
  return writeOperation({
    databaseId,
    layer,
    description: `create-sonarr-naming-${input.name}`,
    queries: [insertQuery],
    desiredState: {
      name: input.name,
      rename: input.rename,
      standard_episode_format: input.standardEpisodeFormat,
      daily_episode_format: input.dailyEpisodeFormat,
      anime_episode_format: input.animeEpisodeFormat,
      series_folder_format: input.seriesFolderFormat,
      season_folder_format: input.seasonFolderFormat,
      replace_illegal_characters: input.replaceIllegalCharacters,
      colon_replacement_format: input.colonReplacementFormat,
      custom_colon_replacement_format: input.customColonReplacementFormat,
      multi_episode_style: input.multiEpisodeStyle
    },
    metadata: {
      operation: "create",
      entity: "sonarr_naming",
      name: input.name,
      stableKey: {
        key: "sonarr_naming_name",
        value: input.name
      },
      summary: "Create Sonarr naming config",
      title: `Create Sonarr naming "${input.name}"`
    }
  });
}
async function removeRadarrNaming(options2) {
  const { databaseId, cache: cache3, layer, current: current3 } = options2;
  const deleteQuery = cache3.kb.deleteFrom("radarr_naming").where("name", "=", current3.name).compile();
  return writeOperation({
    databaseId,
    layer,
    description: `delete-radarr-naming-${current3.name}`,
    queries: [deleteQuery],
    desiredState: {
      deleted: true,
      name: current3.name,
      rename: current3.rename,
      movie_format: current3.movie_format,
      movie_folder_format: current3.movie_folder_format,
      replace_illegal_characters: current3.replace_illegal_characters,
      colon_replacement_format: current3.colon_replacement_format
    },
    metadata: {
      operation: "delete",
      entity: "radarr_naming",
      name: current3.name,
      stableKey: {
        key: "radarr_naming_name",
        value: current3.name
      },
      changedFields: ["deleted"],
      summary: "Delete Radarr naming config",
      title: `Delete Radarr naming "${current3.name}"`
    }
  });
}
async function removeSonarrNaming(options2) {
  const { databaseId, cache: cache3, layer, current: current3 } = options2;
  const deleteQuery = cache3.kb.deleteFrom("sonarr_naming").where("name", "=", current3.name).compile();
  return writeOperation({
    databaseId,
    layer,
    description: `delete-sonarr-naming-${current3.name}`,
    queries: [deleteQuery],
    desiredState: {
      deleted: true,
      name: current3.name,
      rename: current3.rename,
      standard_episode_format: current3.standard_episode_format,
      daily_episode_format: current3.daily_episode_format,
      anime_episode_format: current3.anime_episode_format,
      series_folder_format: current3.series_folder_format,
      season_folder_format: current3.season_folder_format,
      replace_illegal_characters: current3.replace_illegal_characters,
      colon_replacement_format: current3.colon_replacement_format,
      custom_colon_replacement_format: current3.custom_colon_replacement_format,
      multi_episode_style: current3.multi_episode_style
    },
    metadata: {
      operation: "delete",
      entity: "sonarr_naming",
      name: current3.name,
      stableKey: {
        key: "sonarr_naming_name",
        value: current3.name
      },
      changedFields: ["deleted"],
      summary: "Delete Sonarr naming config",
      title: `Delete Sonarr naming "${current3.name}"`
    }
  });
}
var init_naming = __esm({
  async "dist/build/server/chunks/naming.js"() {
    "use strict";
    await init_queueService();
    init_mediaManagement();
    await init_update();
  }
});

// dist/build/server/chunks/media-settings.js
async function createRadarrMediaSettings(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  if (await db2.selectFrom("radarr_media_settings").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) throw new Error(`A radarr media settings config with name "${input.name}" already exists`);
  const insertQuery = db2.insertInto("radarr_media_settings").values({
    name: input.name,
    propers_repacks: input.propersRepacks,
    enable_media_info: input.enableMediaInfo ? 1 : 0
  }).compile();
  return writeOperation({
    databaseId,
    layer,
    description: `create-radarr-media-settings-${input.name}`,
    queries: [insertQuery],
    desiredState: {
      name: input.name,
      propers_repacks: input.propersRepacks,
      enable_media_info: input.enableMediaInfo
    },
    metadata: {
      operation: "create",
      entity: "radarr_media_settings",
      name: input.name,
      stableKey: {
        key: "radarr_media_settings_name",
        value: input.name
      },
      summary: "Create Radarr media settings",
      title: `Create Radarr media settings "${input.name}"`
    }
  });
}
async function createSonarrMediaSettings(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  if (await db2.selectFrom("sonarr_media_settings").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) throw new Error(`A sonarr media settings config with name "${input.name}" already exists`);
  const insertQuery = db2.insertInto("sonarr_media_settings").values({
    name: input.name,
    propers_repacks: input.propersRepacks,
    enable_media_info: input.enableMediaInfo ? 1 : 0
  }).compile();
  return writeOperation({
    databaseId,
    layer,
    description: `create-sonarr-media-settings-${input.name}`,
    queries: [insertQuery],
    desiredState: {
      name: input.name,
      propers_repacks: input.propersRepacks,
      enable_media_info: input.enableMediaInfo
    },
    metadata: {
      operation: "create",
      entity: "sonarr_media_settings",
      name: input.name,
      stableKey: {
        key: "sonarr_media_settings_name",
        value: input.name
      },
      summary: "Create Sonarr media settings",
      title: `Create Sonarr media settings "${input.name}"`
    }
  });
}
async function removeRadarrMediaSettings(options2) {
  const { databaseId, cache: cache3, layer, current: current3 } = options2;
  const deleteQuery = cache3.kb.deleteFrom("radarr_media_settings").where("name", "=", current3.name).compile();
  return writeOperation({
    databaseId,
    layer,
    description: `delete-radarr-media-settings-${current3.name}`,
    queries: [deleteQuery],
    desiredState: {
      deleted: true,
      name: current3.name,
      propers_repacks: current3.propers_repacks,
      enable_media_info: current3.enable_media_info
    },
    metadata: {
      operation: "delete",
      entity: "radarr_media_settings",
      name: current3.name,
      stableKey: {
        key: "radarr_media_settings_name",
        value: current3.name
      },
      changedFields: ["deleted"],
      summary: "Delete Radarr media settings",
      title: `Delete Radarr media settings "${current3.name}"`
    }
  });
}
async function removeSonarrMediaSettings(options2) {
  const { databaseId, cache: cache3, layer, current: current3 } = options2;
  const deleteQuery = cache3.kb.deleteFrom("sonarr_media_settings").where("name", "=", current3.name).compile();
  return writeOperation({
    databaseId,
    layer,
    description: `delete-sonarr-media-settings-${current3.name}`,
    queries: [deleteQuery],
    desiredState: {
      deleted: true,
      name: current3.name,
      propers_repacks: current3.propers_repacks,
      enable_media_info: current3.enable_media_info
    },
    metadata: {
      operation: "delete",
      entity: "sonarr_media_settings",
      name: current3.name,
      stableKey: {
        key: "sonarr_media_settings_name",
        value: current3.name
      },
      changedFields: ["deleted"],
      summary: "Delete Sonarr media settings",
      title: `Delete Sonarr media settings "${current3.name}"`
    }
  });
}
var init_media_settings = __esm({
  async "dist/build/server/chunks/media-settings.js"() {
    "use strict";
    await init_queueService();
    await init_update2();
  }
});

// dist/build/server/chunks/quality-definitions.js
async function createRadarrQualityDefinitions(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  ensureUniqueEntries2(input.entries);
  if (await db2.selectFrom("radarr_quality_definitions").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) throw new Error(`A radarr quality definitions config with name "${input.name}" already exists`);
  const queries = input.entries.map((entry) => db2.insertInto("radarr_quality_definitions").values({
    name: input.name,
    quality_name: entry.quality_name,
    min_size: entry.min_size,
    max_size: entry.max_size,
    preferred_size: entry.preferred_size
  }).compile());
  return writeOperation({
    databaseId,
    layer,
    description: `create-radarr-quality-definitions-${input.name}`,
    queries,
    desiredState: {
      name: input.name,
      entries: input.entries
    },
    metadata: {
      operation: "create",
      entity: "radarr_quality_definitions",
      name: input.name,
      stableKey: {
        key: "radarr_quality_definitions_name",
        value: input.name
      },
      summary: "Create Radarr quality definitions",
      title: `Create Radarr quality definitions "${input.name}"`
    }
  });
}
async function createSonarrQualityDefinitions(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  ensureUniqueEntries2(input.entries);
  if (await db2.selectFrom("sonarr_quality_definitions").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) throw new Error(`A sonarr quality definitions config with name "${input.name}" already exists`);
  const queries = input.entries.map((entry) => db2.insertInto("sonarr_quality_definitions").values({
    name: input.name,
    quality_name: entry.quality_name,
    min_size: entry.min_size,
    max_size: entry.max_size,
    preferred_size: entry.preferred_size
  }).compile());
  return writeOperation({
    databaseId,
    layer,
    description: `create-sonarr-quality-definitions-${input.name}`,
    queries,
    desiredState: {
      name: input.name,
      entries: input.entries
    },
    metadata: {
      operation: "create",
      entity: "sonarr_quality_definitions",
      name: input.name,
      stableKey: {
        key: "sonarr_quality_definitions_name",
        value: input.name
      },
      summary: "Create Sonarr quality definitions",
      title: `Create Sonarr quality definitions "${input.name}"`
    }
  });
}
function ensureUniqueEntries2(entries) {
  const normalized = entries.map((entry) => entry.quality_name.trim().toLowerCase());
  if (new Set(normalized).size !== normalized.length) throw new Error("Quality definitions cannot contain duplicate quality names");
}
async function removeRadarrQualityDefinitions(options2) {
  const { databaseId, cache: cache3, layer, current: current3 } = options2;
  const deleteQuery = cache3.kb.deleteFrom("radarr_quality_definitions").where("name", "=", current3.name).compile();
  return writeOperation({
    databaseId,
    layer,
    description: `remove-radarr-quality-definitions-${current3.name}`,
    queries: [deleteQuery],
    desiredState: {
      deleted: true,
      name: current3.name,
      entries: current3.entries
    },
    metadata: {
      operation: "delete",
      entity: "radarr_quality_definitions",
      name: current3.name,
      stableKey: {
        key: "radarr_quality_definitions_name",
        value: current3.name
      },
      changedFields: ["deleted"],
      summary: "Delete Radarr quality definitions",
      title: `Delete Radarr quality definitions "${current3.name}"`
    }
  });
}
async function removeSonarrQualityDefinitions(options2) {
  const { databaseId, cache: cache3, layer, current: current3 } = options2;
  const deleteQuery = cache3.kb.deleteFrom("sonarr_quality_definitions").where("name", "=", current3.name).compile();
  return writeOperation({
    databaseId,
    layer,
    description: `remove-sonarr-quality-definitions-${current3.name}`,
    queries: [deleteQuery],
    desiredState: {
      deleted: true,
      name: current3.name,
      entries: current3.entries
    },
    metadata: {
      operation: "delete",
      entity: "sonarr_quality_definitions",
      name: current3.name,
      stableKey: {
        key: "sonarr_quality_definitions_name",
        value: current3.name
      },
      changedFields: ["deleted"],
      summary: "Delete Sonarr quality definitions",
      title: `Delete Sonarr quality definitions "${current3.name}"`
    }
  });
}
var init_quality_definitions = __esm({
  async "dist/build/server/chunks/quality-definitions.js"() {
    "use strict";
    await init_queueService();
    await init_update3();
  }
});

// dist/build/server/entries/pages/arr/_id_/sync/_page.server.ts.js
var page_server_ts_exports10 = {};
__export(page_server_ts_exports10, {
  actions: () => actions7,
  load: () => load15
});
function subConfigDrifted(sub) {
  return sub.missing.length > 0 || sub.modified.length > 0;
}
function fieldIsMissingCustomFormat(field) {
  if (!field.path.startsWith("formatItems[")) return false;
  const actual = field.actual;
  return actual !== null && typeof actual === "object" && "state" in actual && actual.state === "missing_custom_format";
}
function isTransitiveOnlyQp(modified) {
  if (modified.fields.length === 0) return false;
  return modified.fields.every(fieldIsMissingCustomFormat);
}
function extractQpDiffs(raw) {
  if (Array.isArray(raw)) return raw.filter((entry) => entry != null && typeof entry === "object" && "diff" in entry).map((entry) => entry.diff);
  if (raw != null && typeof raw === "object" && ("missing" in raw || "modified" in raw)) return [raw];
  return [];
}
function extractCfDiffs(raw) {
  if (Array.isArray(raw)) return raw.filter((entry) => entry != null && typeof entry === "object" && "diff" in entry).map((entry) => entry.diff);
  if (raw != null && typeof raw === "object" && ("missing" in raw || "modified" in raw)) return [raw];
  return [];
}
function classifyQpDrift(qpDiffs) {
  const result = {
    directNames: [],
    transitiveNames: [],
    affectedQpNames: /* @__PURE__ */ new Set()
  };
  for (const qpDiff of qpDiffs) {
    for (const m3 of qpDiff.missing) result.directNames.push(m3.name);
    for (const m3 of qpDiff.modified) if (isTransitiveOnlyQp(m3)) {
      result.transitiveNames.push(m3.name);
      result.affectedQpNames.add(m3.name);
    } else {
      result.directNames.push(m3.name);
      if (m3.fields.some(fieldIsMissingCustomFormat)) result.affectedQpNames.add(m3.name);
    }
  }
  return result;
}
function collectCfNames(cfDiffs) {
  const names2 = [];
  for (const cfDiff of cfDiffs) {
    for (const m3 of cfDiff.missing) names2.push(m3.name);
    for (const m3 of cfDiff.modified) names2.push(m3.name);
  }
  return names2;
}
function joinNames(names2) {
  if (names2.length <= NAME_LIST_CAP) return names2.join(", ");
  return `${names2.slice(0, NAME_LIST_CAP).join(", ")} +${names2.length - NAME_LIST_CAP} more`;
}
function buildQpMessage(directNames, transitiveNames) {
  if (directNames.length === 0 && transitiveNames.length === 0) return void 0;
  if (transitiveNames.length === 0) return `${joinNames(directNames)} drifted.`;
  if (directNames.length === 0) return `${joinNames(transitiveNames)} affected by drifted custom formats.`;
  return `${joinNames(directNames)} drifted; ${joinNames(transitiveNames)} also affected by drifted custom formats.`;
}
function buildCfMessage(cfNames, affectedQpNames) {
  if (cfNames.length === 0) return void 0;
  if (affectedQpNames.length === 0) return `${joinNames(cfNames)} drifted.`;
  return `${joinNames(cfNames)} drifted, used in ${joinNames(affectedQpNames)}.`;
}
async function loadDriftProgress(instanceId, arrType) {
  if (!FEATURES.drift) return null;
  if (!arrDriftSettingsQueries.getByInstanceId(instanceId)?.enabled) return null;
  const status = arrDriftStatusQueries.getByInstanceId(instanceId);
  if (!status) return null;
  if (status.status !== "clean" && status.status !== "drift_detected") return null;
  const qpSync = arrSyncQueries.getQualityProfilesSync(instanceId);
  const dpSync = arrSyncQueries.getDelayProfilesSync(instanceId);
  const mmSync = arrSyncQueries.getMediaManagementSync(instanceId);
  const qpTotal = qpSync.selections.length;
  const dpTotal = dpSync.databaseId && dpSync.profileName ? 1 : 0;
  let cfTotal = 0;
  if (qpTotal > 0) {
    const perDb = await buildExpectedCustomFormatsPerDatabase(instanceId, arrType);
    for (const { formats } of perDb.values()) cfTotal += formats.length;
  }
  const namingTotal = mmSync.namingDatabaseId !== null && mmSync.namingConfigName ? 1 : 0;
  const qualityDefinitionsTotal = mmSync.qualityDefinitionsDatabaseId !== null && mmSync.qualityDefinitionsConfigName ? 1 : 0;
  const mediaSettingsTotal = mmSync.mediaSettingsDatabaseId !== null && mmSync.mediaSettingsConfigName ? 1 : 0;
  const counts = status.counts ?? {};
  const diff = status.diff;
  const qpDiffs = extractQpDiffs(diff?.quality_profiles);
  const cfDiffsList = extractCfDiffs(diff?.custom_formats);
  const qpClass = classifyQpDrift(qpDiffs);
  const cfNames = collectCfNames(cfDiffsList);
  const mm = diff?.media_management;
  const progress = {};
  if (qpTotal > 0) progress.qualityProfiles = {
    total: qpTotal,
    drifted: qpClass.directNames.length,
    message: buildQpMessage(qpClass.directNames, qpClass.transitiveNames)
  };
  if (cfTotal > 0) {
    const cfDrifted = counts.custom_formats ?? 0;
    progress.customFormats = {
      total: cfTotal,
      drifted: cfDrifted,
      message: buildCfMessage(cfNames, [...qpClass.affectedQpNames])
    };
  }
  if (dpTotal > 0) {
    const dpDrifted = counts.delay_profiles ?? 0;
    const dpName = dpSync.profileName ?? "Default delay profile";
    progress.delayProfiles = {
      total: dpTotal,
      drifted: dpDrifted,
      message: dpDrifted > 0 ? `${dpName} drifted.` : void 0
    };
  }
  if (namingTotal > 0) {
    const drifted = mm?.naming && subConfigDrifted(mm.naming) ? 1 : 0;
    progress.naming = {
      total: namingTotal,
      drifted,
      message: drifted > 0 ? `${mmSync.namingConfigName} drifted.` : void 0
    };
  }
  if (qualityDefinitionsTotal > 0) {
    const drifted = mm?.quality_definitions && subConfigDrifted(mm.quality_definitions) ? 1 : 0;
    progress.qualityDefinitions = {
      total: qualityDefinitionsTotal,
      drifted,
      message: drifted > 0 ? `${mmSync.qualityDefinitionsConfigName} drifted.` : void 0
    };
  }
  if (mediaSettingsTotal > 0) {
    const drifted = mm?.media_settings && subConfigDrifted(mm.media_settings) ? 1 : 0;
    progress.mediaSettings = {
      total: mediaSettingsTotal,
      drifted,
      message: drifted > 0 ? `${mmSync.mediaSettingsConfigName} drifted.` : void 0
    };
  }
  if (!progress.qualityProfiles && !progress.delayProfiles && !progress.customFormats && !progress.naming && !progress.qualityDefinitions && !progress.mediaSettings) return null;
  return progress;
}
var NAME_LIST_CAP, load15, actions7;
var init_page_server_ts10 = __esm({
  async "dist/build/server/entries/pages/arr/_id_/sync/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrSync();
    await init_arrInstances();
    await init_queueService();
    await init_arrDriftStatus();
    init_features();
    await init_init();
    await init_naming();
    await init_media_settings();
    await init_quality_definitions();
    init_exports();
    NAME_LIST_CAP = 3;
    load15 = async ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (isNaN(id)) error(404, `Invalid instance ID: ${params.id}`);
      const instance = arrInstancesQueries.getById(id);
      if (!instance) error(404, `Instance not found: ${id}`);
      const databases = pcdManager.getAllPublic();
      const arrType = instance.type;
      const databasesWithProfiles = await Promise.all(databases.map(async (db2) => {
        const cache3 = pcdManager.getCache(db2.id);
        if (!cache3) return {
          id: db2.id,
          name: db2.name,
          qualityProfiles: [],
          delayProfiles: [],
          namingConfigs: [],
          qualityDefinitionsConfigs: [],
          mediaSettingsConfigs: []
        };
        const [qualityProfiles, delayProfiles, allNamingConfigs, allQualityDefinitionsConfigs, allMediaSettingsConfigs] = await Promise.all([
          list2(cache3),
          list$4(cache3),
          list$2(cache3),
          list$1(cache3),
          list$3(cache3)
        ]);
        const namingConfigs = allNamingConfigs.filter((c2) => c2.arr_type === arrType).map((c2) => ({ name: c2.name }));
        const qualityDefinitionsConfigs = allQualityDefinitionsConfigs.filter((c2) => c2.arr_type === arrType).map((c2) => ({ name: c2.name }));
        const mediaSettingsConfigs = allMediaSettingsConfigs.filter((c2) => c2.arr_type === arrType).map((c2) => ({ name: c2.name }));
        return {
          id: db2.id,
          name: db2.name,
          qualityProfiles,
          delayProfiles,
          namingConfigs,
          qualityDefinitionsConfigs,
          mediaSettingsConfigs
        };
      }));
      const syncData = arrSyncQueries.getFullSyncData(id);
      const driftProgress = await loadDriftProgress(id, arrType);
      const databasePriorities = arrSyncQueries.getDatabasePriorities(id);
      const { api_key: _3, ...safeInstance } = instance;
      return {
        instance: safeInstance,
        databases: databasesWithProfiles,
        syncData,
        driftProgress,
        databasePriorities
      };
    };
    actions7 = {
      saveQualityProfiles: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        const formData = await request.formData();
        const selectionsJson = formData.get("selections");
        const prioritiesJson = formData.get("priorities");
        const trigger = formData.get("trigger");
        const cron = formData.get("cron");
        try {
          const selections = JSON.parse(selectionsJson || "[]");
          const effectiveTrigger = trigger || "manual";
          const effectiveCron = cron || null;
          arrSyncQueries.saveQualityProfilesSync(id, selections, {
            trigger: effectiveTrigger,
            cron: effectiveCron,
            nextRunAt: effectiveTrigger === "schedule" ? calculateNextRun(effectiveCron) : null
          });
          const priorities = JSON.parse(prioritiesJson || "[]");
          if (priorities.length > 0) await arrSyncQueries.saveDatabasePriorities(id, priorities);
          await logger.info(`Quality profiles sync config saved for "${instance?.name}"`, {
            source: "sync",
            meta: {
              instanceId: id,
              profileCount: selections.length,
              trigger
            }
          });
          scheduleArrSyncForInstance(id);
          return { success: true };
        } catch (e) {
          await logger.error("Failed to save quality profiles sync config", {
            source: "sync",
            meta: {
              instanceId: id,
              error: e
            }
          });
          return fail(500, { error: "Failed to save quality profiles sync config" });
        }
      },
      saveDelayProfiles: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        const formData = await request.formData();
        const databaseId = formData.get("databaseId");
        const profileName2 = formData.get("profileName");
        const trigger = formData.get("trigger");
        const cron = formData.get("cron");
        try {
          const effectiveTrigger = trigger || "manual";
          const effectiveCron = cron || null;
          arrSyncQueries.saveDelayProfilesSync(id, {
            databaseId: databaseId ? parseInt(databaseId, 10) : null,
            profileName: profileName2 || null,
            trigger: effectiveTrigger,
            cron: effectiveCron,
            nextRunAt: effectiveTrigger === "schedule" ? calculateNextRun(effectiveCron) : null
          });
          await logger.info(`Delay profile sync config saved for "${instance?.name}"`, {
            source: "sync",
            meta: {
              instanceId: id,
              databaseId,
              profileName: profileName2,
              trigger
            }
          });
          scheduleArrSyncForInstance(id);
          return { success: true };
        } catch (e) {
          await logger.error("Failed to save delay profile sync config", {
            source: "sync",
            meta: {
              instanceId: id,
              error: e
            }
          });
          return fail(500, { error: "Failed to save delay profile sync config" });
        }
      },
      saveMediaManagement: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        const formData = await request.formData();
        const namingDatabaseId = formData.get("namingDatabaseId");
        const namingConfigName = formData.get("namingConfigName");
        const qualityDefinitionsDatabaseId = formData.get("qualityDefinitionsDatabaseId");
        const qualityDefinitionsConfigName = formData.get("qualityDefinitionsConfigName");
        const mediaSettingsDatabaseId = formData.get("mediaSettingsDatabaseId");
        const mediaSettingsConfigName = formData.get("mediaSettingsConfigName");
        const trigger = formData.get("trigger");
        const cron = formData.get("cron");
        try {
          const effectiveTrigger = trigger || "manual";
          const effectiveCron = cron || null;
          arrSyncQueries.saveMediaManagementSync(id, {
            namingDatabaseId: namingDatabaseId ? parseInt(namingDatabaseId, 10) : null,
            namingConfigName: namingConfigName || null,
            qualityDefinitionsDatabaseId: qualityDefinitionsDatabaseId ? parseInt(qualityDefinitionsDatabaseId, 10) : null,
            qualityDefinitionsConfigName: qualityDefinitionsConfigName || null,
            mediaSettingsDatabaseId: mediaSettingsDatabaseId ? parseInt(mediaSettingsDatabaseId, 10) : null,
            mediaSettingsConfigName: mediaSettingsConfigName || null,
            trigger: effectiveTrigger,
            cron: effectiveCron,
            nextRunAt: effectiveTrigger === "schedule" ? calculateNextRun(effectiveCron) : null
          });
          await logger.info(`Media management sync config saved for "${instance?.name}"`, {
            source: "sync",
            meta: {
              instanceId: id,
              trigger
            }
          });
          scheduleArrSyncForInstance(id);
          return { success: true };
        } catch (e) {
          await logger.error("Failed to save media management sync config", {
            source: "sync",
            meta: {
              instanceId: id,
              error: e
            }
          });
          return fail(500, { error: "Failed to save media management sync config" });
        }
      },
      syncDelayProfiles: async ({ params }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        const dpSync = arrSyncQueries.getDelayProfilesSync(id);
        if (!dpSync.databaseId || !dpSync.profileName) return fail(400, { error: "No delay profile configured" });
        const status = arrSyncQueries.getSyncConfigStatus(id);
        if (status.delayProfiles.syncStatus === "pending" || status.delayProfiles.syncStatus === "in_progress") return fail(409, { error: "Sync already in progress" });
        try {
          arrSyncQueries.setDelayProfilesStatusPending(id);
          enqueueJob({
            jobType: "arr.sync.delayProfiles",
            runAt: (/* @__PURE__ */ new Date()).toISOString(),
            payload: { instanceId: id },
            source: "manual"
          });
          return {
            success: true,
            message: "Delay profiles sync queued"
          };
        } catch (e) {
          const errorMsg = e instanceof Error ? e.message : "Unknown error";
          await logger.error(`Delay profiles sync enqueue failed for "${instance.name}"`, {
            source: "sync",
            meta: {
              instanceId: id,
              error: errorMsg
            }
          });
          return fail(500, { error: `Sync failed: ${errorMsg}` });
        }
      },
      syncQualityProfiles: async ({ params }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        if (arrSyncQueries.getQualityProfilesSync(id).selections.length === 0) return fail(400, { error: "No quality profiles configured" });
        const status = arrSyncQueries.getSyncConfigStatus(id);
        if (status.qualityProfiles.syncStatus === "pending" || status.qualityProfiles.syncStatus === "in_progress") return fail(409, { error: "Sync already in progress" });
        try {
          arrSyncQueries.setQualityProfilesStatusPending(id);
          enqueueJob({
            jobType: "arr.sync.qualityProfiles",
            runAt: (/* @__PURE__ */ new Date()).toISOString(),
            payload: { instanceId: id },
            source: "manual"
          });
          return {
            success: true,
            message: "Quality profiles sync queued"
          };
        } catch (e) {
          const errorMsg = e instanceof Error ? e.message : "Unknown error";
          await logger.error(`Quality profiles sync enqueue failed for "${instance.name}"`, {
            source: "sync",
            meta: {
              instanceId: id,
              error: errorMsg
            }
          });
          return fail(500, { error: `Sync failed: ${errorMsg}` });
        }
      },
      syncMediaManagement: async ({ params }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        const mmSync = arrSyncQueries.getMediaManagementSync(id);
        if (!mmSync.namingDatabaseId && !mmSync.qualityDefinitionsDatabaseId && !mmSync.mediaSettingsDatabaseId) return fail(400, { error: "No media management configured" });
        const status = arrSyncQueries.getSyncConfigStatus(id);
        if (status.mediaManagement.syncStatus === "pending" || status.mediaManagement.syncStatus === "in_progress") return fail(409, { error: "Sync already in progress" });
        try {
          arrSyncQueries.setMediaManagementStatusPending(id);
          enqueueJob({
            jobType: "arr.sync.mediaManagement",
            runAt: (/* @__PURE__ */ new Date()).toISOString(),
            payload: { instanceId: id },
            source: "manual"
          });
          return {
            success: true,
            message: "Media management sync queued"
          };
        } catch (e) {
          const errorMsg = e instanceof Error ? e.message : "Unknown error";
          await logger.error(`Media management sync enqueue failed for "${instance.name}"`, {
            source: "sync",
            meta: {
              instanceId: id,
              error: errorMsg
            }
          });
          return fail(500, { error: `Sync failed: ${errorMsg}` });
        }
      }
    };
  }
});

// dist/build/server/chunks/DraggableCard.js
function DraggableCard($$renderer, $$props) {
  const $$sanitized_props = sanitize_props($$props);
  const $$restProps = rest_props($$sanitized_props, [
    "isDragging",
    "onDragHandlePointerDown",
    "variant",
    "className",
    "contentClass",
    "dragHandleOnboarding"
  ]);
  let isDragging = fallback($$props["isDragging"], false);
  let onDragHandlePointerDown = fallback($$props["onDragHandlePointerDown"], void 0);
  let variant = fallback($$props["variant"], "ghost");
  let className = fallback($$props["className"], "");
  let contentClass = fallback($$props["contentClass"], "p-3");
  let dragHandleOnboarding = fallback($$props["dragHandleOnboarding"], void 0);
  $$renderer.push(`<div${attributes({
    class: `relative flex overflow-hidden rounded-xl select-none ${stringify({
      default: "border border-neutral-300 bg-white dark:border-neutral-700/60 dark:bg-neutral-800/50",
      ghost: "border border-neutral-300 bg-neutral-50 dark:border-neutral-700/60 dark:bg-neutral-800/40",
      outline: "border border-neutral-300 dark:border-neutral-700/60"
    }[variant])} ${isDragging ? "scale-[0.98] opacity-50" : ""} ${stringify(className)}`,
    style: "transition: opacity 100ms, transform 100ms;",
    ...$$restProps
  })}><div class="hidden shrink-0 items-center pl-2 md:flex"><div${attr_class(`flex h-7 w-7 items-center justify-center rounded-xl transition-colors ${isDragging ? "cursor-grabbing bg-neutral-100 dark:bg-neutral-700/50" : "cursor-grab hover:bg-neutral-100 dark:hover:bg-neutral-700/50"}`)} role="button" tabindex="-1" aria-label="Drag to reorder"${attr("data-onboarding", dragHandleOnboarding)}><svg width="8" height="14" viewBox="0 0 8 14" fill="currentColor" class="text-neutral-400 dark:text-neutral-500"><circle cx="2" cy="2" r="1.25"></circle><circle cx="6" cy="2" r="1.25"></circle><circle cx="2" cy="7" r="1.25"></circle><circle cx="6" cy="7" r="1.25"></circle><circle cx="2" cy="12" r="1.25"></circle><circle cx="6" cy="12" r="1.25"></circle></svg></div></div> <div${attr_class(`min-w-0 flex-1 ${stringify(contentClass)}`)}><!--[-->`);
  slot($$renderer, $$props, "default", {}, null);
  $$renderer.push(`<!--]--></div></div>`);
  bind_props($$props, {
    isDragging,
    onDragHandlePointerDown,
    variant,
    className,
    contentClass,
    dragHandleOnboarding
  });
}
var init_DraggableCard = __esm({
  "dist/build/server/chunks/DraggableCard.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/entries/pages/arr/_id_/sync/_page.svelte.js
var page_svelte_exports9 = {};
__export(page_svelte_exports9, {
  default: () => _page9
});
function SyncFooter($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let saveDisabled, syncDisabled;
    let syncTrigger = fallback($$props["syncTrigger"], "manual");
    let cronExpression = fallback($$props["cronExpression"], "0 * * * *");
    let saving = fallback($$props["saving"], false);
    let syncing = fallback($$props["syncing"], false);
    let isDirty2 = fallback($$props["isDirty"], false);
    let canSave = fallback($$props["canSave"], true);
    let hasConfig = fallback($$props["hasConfig"], true);
    let warning = fallback($$props["warning"], null);
    let onWarning = fallback($$props["onWarning"], void 0);
    let onboardingId = fallback($$props["onboardingId"], void 0);
    createEventDispatcher();
    const triggerOptions = [
      {
        value: "manual",
        label: "Manual"
      },
      {
        value: "on_pull",
        label: "On Pull"
      },
      {
        value: "schedule",
        label: "Schedule"
      }
    ];
    $: saveDisabled = saving || !isDirty2 || !canSave;
    $: syncDisabled = syncing || isDirty2 || !hasConfig;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="border-t border-neutral-200 px-4 py-4 md:px-6 dark:border-neutral-800"><div class="flex flex-col gap-3">`);
      if (warning) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="flex items-center gap-1.5 text-xs text-amber-600 sm:hidden dark:text-amber-400">`);
        Triangle_alert($$renderer3, {
          size: 14,
          class: "flex-shrink-0"
        });
        $$renderer3.push(`<!----> <span>${escape_html(warning)}</span></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> <div class="flex items-center justify-between gap-2"><div${attr("data-onboarding", onboardingId)}><span class="mb-1 block text-xs text-neutral-500 dark:text-neutral-400">Trigger</span> `);
      DropdownSelect($$renderer3, {
        value: syncTrigger,
        options: triggerOptions,
        buttonSize: "sm",
        width: "w-28",
        justify: "center"
      });
      $$renderer3.push(`<!----></div> <div><span class="mb-1 block text-xs text-transparent select-none">\xA0</span> <div class="flex items-center gap-3">`);
      if (warning) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="hidden items-center gap-1.5 text-xs text-amber-600 sm:flex dark:text-amber-400">`);
        Triangle_alert($$renderer3, {
          size: 14,
          class: "flex-shrink-0"
        });
        $$renderer3.push(`<!----> <span>${escape_html(warning)}</span></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      Button($$renderer3, {
        text: "Sync",
        variant: "secondary",
        disabled: syncDisabled,
        icon: syncing ? Loader_circle : Refresh_cw,
        iconColor: syncing ? "text-blue-600 dark:text-blue-400 animate-spin" : "text-blue-600 dark:text-blue-400",
        title: isDirty2 ? "Save changes before syncing" : ""
      });
      $$renderer3.push(`<!----> `);
      Button($$renderer3, {
        text: "Save",
        variant: "secondary",
        disabled: saveDisabled,
        icon: saving ? Loader_circle : Save,
        iconColor: saving ? "text-green-600 dark:text-green-400 animate-spin" : "text-green-600 dark:text-green-400"
      });
      $$renderer3.push(`<!----></div></div></div> `);
      if (syncTrigger === "schedule") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="border-t border-neutral-200 pt-3 dark:border-neutral-800"><span class="mb-1 block text-xs text-neutral-500 dark:text-neutral-400">Schedule</span> `);
        CronInput($$renderer3, {
          disabled: saving,
          minIntervalMinutes: 10,
          onWarning,
          get value() {
            return cronExpression;
          },
          set value($$value) {
            cronExpression = $$value;
            $$settled = false;
          }
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      syncTrigger,
      cronExpression,
      saving,
      syncing,
      isDirty: isDirty2,
      canSave,
      hasConfig,
      warning,
      onWarning,
      onboardingId
    });
  });
}
function QualityProfiles($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let currentState, orderedDatabases, selectedKeys, hasAnySelection;
    let databases = $$props["databases"];
    let databasePriorities = fallback($$props["databasePriorities"], () => [], true);
    let state2 = fallback($$props["state"], () => ({}), true);
    let syncTrigger = fallback($$props["syncTrigger"], "manual");
    let cronExpression = fallback($$props["cronExpression"], "0 * * * *");
    let canSave = fallback($$props["canSave"], true);
    let warning = fallback($$props["warning"], null);
    let qpProgress = fallback($$props["qpProgress"], void 0);
    let cfProgress = fallback($$props["cfProgress"], void 0);
    let saving = false;
    let syncing = false;
    let savedState = JSON.stringify({
      state: state2,
      syncTrigger,
      cronExpression,
      databasePriorities
    });
    let isDirty2 = fallback($$props["isDirty"], false);
    function isSelected(databaseId, profileName2) {
      return selectedKeys.has(`${databaseId}-${profileName2}`);
    }
    let draggedDb = null;
    let lastTargetIndex = null;
    function getTargetFromPoint(x3, y2) {
      const card = document.elementFromPoint(x3, y2)?.closest("[data-db-index]");
      if (!card) return null;
      const idx = parseInt(card.dataset.dbIndex, 10);
      if (isNaN(idx) || idx < 0 || idx >= orderedDatabases.length) return null;
      return { index: idx };
    }
    function handlePointerDown(e, database, index88) {
      e.preventDefault();
      document.body.classList.add("dragging");
      draggedDb = {
        id: database.id,
        index: index88
      };
      document.addEventListener("pointermove", handlePointerMove);
      document.addEventListener("pointerup", handlePointerUp);
    }
    function handlePointerMove(e) {
      if (!draggedDb) return;
      const target = getTargetFromPoint(e.clientX, e.clientY);
      if (!target || target.index === lastTargetIndex) return;
      lastTargetIndex = target.index;
      target.index;
      if (target.index !== draggedDb.index) {
        const newOrder = [...orderedDatabases];
        const [moved] = newOrder.splice(draggedDb.index, 1);
        newOrder.splice(target.index, 0, moved);
        orderedDatabases = newOrder;
        databasePriorities = newOrder.map((db2, i) => ({
          databaseId: db2.id,
          priority: i + 1
        }));
        draggedDb = {
          ...draggedDb,
          index: target.index
        };
      }
    }
    function handlePointerUp() {
      resetDragState();
    }
    function resetDragState() {
      draggedDb = null;
      lastTargetIndex = null;
      document.removeEventListener("pointermove", handlePointerMove);
      document.removeEventListener("pointerup", handlePointerUp);
      document.body.classList.remove("dragging");
    }
    $: currentState = JSON.stringify({
      state: state2,
      syncTrigger,
      cronExpression,
      databasePriorities
    });
    $: isDirty2 = currentState !== savedState;
    $: orderedDatabases = [...databases].sort((a2, b3) => {
      return (databasePriorities.find((p2) => p2.databaseId === a2.id)?.priority ?? Infinity) - (databasePriorities.find((p2) => p2.databaseId === b3.id)?.priority ?? Infinity);
    });
    $: for (const db2 of databases) {
      if (!state2[db2.id]) state2[db2.id] = {};
      for (const profile of db2.qualityProfiles) if (state2[db2.id][profile.name] === void 0) state2[db2.id][profile.name] = false;
    }
    $: selectedKeys = new Set(Object.entries(state2).flatMap(([dbId, profiles]) => Object.entries(profiles).filter(([, selected]) => selected).map(([profileName2]) => `${dbId}-${profileName2}`)));
    $: hasAnySelection = Object.values(state2).some((db2) => Object.values(db2).some((selected) => selected));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div data-onboarding="sync-quality-profiles" class="rounded-lg border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900"><div class="flex flex-col gap-4 border-b border-neutral-200 px-6 py-4 md:flex-row md:items-start md:justify-between md:gap-6 dark:border-neutral-800"><div class="min-w-0 md:flex-1"><h2 class="text-xl font-semibold text-neutral-900 dark:text-neutral-50">Quality Profiles</h2> <p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400">Select quality profiles to sync. Drag databases to set priority.</p></div> `);
      if (qpProgress || cfProgress) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="flex flex-col gap-3 md:flex-shrink-0 md:flex-row md:flex-wrap md:gap-5 md:pt-1">`);
        if (qpProgress) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="min-w-[9rem]"><div class="mb-1 text-xs font-medium text-neutral-500 dark:text-neutral-400">Quality Profiles</div> `);
          ProgressIndicator($$renderer3, {
            current: qpProgress.total - qpProgress.drifted,
            target: qpProgress.total,
            met: qpProgress.drifted === 0,
            mode: "compact",
            colorMode: "completion",
            tooltip: qpProgress.message ?? "",
            tooltipPosition: "bottom",
            tooltipAlign: "middle"
          });
          $$renderer3.push(`<!----></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        if (cfProgress) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="min-w-[9rem]"><div class="mb-1 text-xs font-medium text-neutral-500 dark:text-neutral-400">Custom Formats</div> `);
          ProgressIndicator($$renderer3, {
            current: cfProgress.total - cfProgress.drifted,
            target: cfProgress.total,
            met: cfProgress.drifted === 0,
            mode: "compact",
            colorMode: "completion",
            tooltip: cfProgress.message ?? "",
            tooltipPosition: "bottom",
            tooltipAlign: "middle"
          });
          $$renderer3.push(`<!----></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> <div class="p-6">`);
      if (orderedDatabases.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">No databases configured</p>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<div class="space-y-3"><!--[-->`);
        const each_array = ensure_array_like(orderedDatabases);
        for (let index88 = 0, $$length = each_array.length; index88 < $$length; index88++) {
          let database = each_array[index88];
          DraggableCard($$renderer3, {
            isDragging: draggedDb?.index === index88,
            onDragHandlePointerDown: (e) => handlePointerDown(e, database, index88),
            contentClass: "p-4",
            "data-db-index": index88,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="space-y-3"><div class="flex items-center justify-between"><div class="flex items-center gap-2"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(database.name)}</h3> <div class="flex gap-1 md:hidden">`);
              Button($$renderer4, {
                icon: Chevron_up,
                size: "xs",
                disabled: index88 === 0
              });
              $$renderer4.push(`<!----> `);
              Button($$renderer4, {
                icon: Chevron_down,
                size: "xs",
                disabled: index88 === orderedDatabases.length - 1
              });
              $$renderer4.push(`<!----></div></div> `);
              Label($$renderer4, {
                variant: "info",
                size: "sm",
                rounded: "md",
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->Priority #${escape_html(index88 + 1)}`);
                },
                $$slots: { default: true }
              });
              $$renderer4.push(`<!----></div> `);
              if (database.qualityProfiles.length === 0) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">No quality profiles</p>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<div class="grid grid-cols-1 gap-2 sm:grid-cols-3 md:grid-cols-5"><!--[-->`);
                const each_array_1 = ensure_array_like(database.qualityProfiles);
                for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
                  let profile = each_array_1[$$index];
                  Toggle($$renderer4, {
                    checked: isSelected(database.id, profile.name),
                    label: profile.name,
                    fullWidth: true,
                    ariaLabel: `Toggle quality profile ${profile.name} from ${database.name}`
                  });
                }
                $$renderer4.push(`<!--]--></div>`);
              }
              $$renderer4.push(`<!--]--></div>`);
            },
            $$slots: { default: true }
          });
        }
        $$renderer3.push(`<!--]--></div>`);
      }
      $$renderer3.push(`<!--]--></div> `);
      SyncFooter($$renderer3, {
        saving,
        syncing,
        isDirty: isDirty2,
        canSave,
        hasConfig: hasAnySelection,
        warning,
        onWarning: (msg) => alertStore.add("warning", msg),
        get syncTrigger() {
          return syncTrigger;
        },
        set syncTrigger($$value) {
          syncTrigger = $$value;
          $$settled = false;
        },
        get cronExpression() {
          return cronExpression;
        },
        set cronExpression($$value) {
          cronExpression = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      databases,
      databasePriorities,
      state: state2,
      syncTrigger,
      cronExpression,
      canSave,
      warning,
      qpProgress,
      cfProgress,
      isDirty: isDirty2
    });
  });
}
function DelayProfiles($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let currentState, selectedKey;
    let databases = $$props["databases"];
    let state2 = fallback($$props["state"], () => ({
      databaseId: null,
      profileName: null
    }), true);
    let syncTrigger = fallback($$props["syncTrigger"], "manual");
    let cronExpression = fallback($$props["cronExpression"], "0 * * * *");
    let progress = fallback($$props["progress"], void 0);
    let saving = false;
    let syncing = false;
    let savedState = JSON.stringify({
      state: state2,
      syncTrigger,
      cronExpression
    });
    let isDirty2 = fallback($$props["isDirty"], false);
    $: currentState = JSON.stringify({
      state: state2,
      syncTrigger,
      cronExpression
    });
    $: isDirty2 = currentState !== savedState;
    $: selectedKey = state2.databaseId !== null && state2.profileName !== null ? `${state2.databaseId}-${state2.profileName}` : null;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div data-onboarding="sync-delay-profiles" class="rounded-lg border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900"><div class="flex flex-col gap-4 border-b border-neutral-200 px-6 py-4 md:flex-row md:items-start md:justify-between md:gap-6 dark:border-neutral-800"><div class="min-w-0 md:flex-1"><h2 class="text-xl font-semibold text-neutral-900 dark:text-neutral-50">Delay Profiles</h2> <p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400">Select delay profiles to sync to this instance</p></div> `);
      if (progress) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="min-w-[9rem] md:flex-shrink-0 md:pt-1"><div class="mb-1 text-xs font-medium text-neutral-500 dark:text-neutral-400">Delay Profiles</div> `);
        ProgressIndicator($$renderer3, {
          current: progress.total - progress.drifted,
          target: progress.total,
          met: progress.drifted === 0,
          mode: "compact",
          colorMode: "completion",
          tooltip: progress.message ?? "",
          tooltipPosition: "bottom",
          tooltipAlign: "middle"
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> <div class="p-6">`);
      if (databases.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">No databases configured</p>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<div class="space-y-6"><!--[-->`);
        const each_array = ensure_array_like(databases);
        for (let $$index_1 = 0, $$length = each_array.length; $$index_1 < $$length; $$index_1++) {
          let database = each_array[$$index_1];
          $$renderer3.push(`<div class="space-y-3"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(database.name)}</h3> `);
          if (database.delayProfiles.length === 0) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">No delay profiles</p>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<div class="grid grid-cols-1 gap-2 sm:grid-cols-3 md:grid-cols-5"><!--[-->`);
            const each_array_1 = ensure_array_like(database.delayProfiles);
            for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
              let profile = each_array_1[$$index];
              Toggle($$renderer3, {
                checked: selectedKey === `${database.id}-${profile.name}`,
                label: profile.name,
                fullWidth: true,
                ariaLabel: `Toggle delay profile ${profile.name} from ${database.name}`
              });
            }
            $$renderer3.push(`<!--]--></div>`);
          }
          $$renderer3.push(`<!--]--></div>`);
        }
        $$renderer3.push(`<!--]--></div>`);
      }
      $$renderer3.push(`<!--]--></div> `);
      SyncFooter($$renderer3, {
        saving,
        syncing,
        isDirty: isDirty2,
        hasConfig: state2.databaseId !== null && state2.profileName !== null,
        onWarning: (msg) => alertStore.add("warning", msg),
        get syncTrigger() {
          return syncTrigger;
        },
        set syncTrigger($$value) {
          syncTrigger = $$value;
          $$settled = false;
        },
        get cronExpression() {
          return cronExpression;
        },
        set cronExpression($$value) {
          cronExpression = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      databases,
      state: state2,
      syncTrigger,
      cronExpression,
      progress,
      isDirty: isDirty2
    });
  });
}
function MediaManagement($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let namingOptions, qualityDefinitionsOptions, mediaSettingsOptions, namingValue, qualityDefinitionsValue, mediaSettingsValue, currentState;
    let databases = $$props["databases"];
    let state2 = fallback($$props["state"], () => ({
      namingDatabaseId: null,
      namingConfigName: null,
      qualityDefinitionsDatabaseId: null,
      qualityDefinitionsConfigName: null,
      mediaSettingsDatabaseId: null,
      mediaSettingsConfigName: null
    }), true);
    let namingProgress = fallback($$props["namingProgress"], void 0);
    let qualityDefinitionsProgress = fallback($$props["qualityDefinitionsProgress"], void 0);
    let mediaSettingsProgress = fallback($$props["mediaSettingsProgress"], void 0);
    function getNamingOptions() {
      const options2 = [];
      for (const db2 of databases) for (const config2 of db2.namingConfigs) options2.push({
        value: JSON.stringify([db2.id, config2.name]),
        label: `${db2.name} / ${config2.name}`
      });
      return options2;
    }
    function getQualityDefinitionsOptions() {
      const options2 = [];
      for (const db2 of databases) for (const config2 of db2.qualityDefinitionsConfigs) options2.push({
        value: JSON.stringify([db2.id, config2.name]),
        label: `${db2.name} / ${config2.name}`
      });
      return options2;
    }
    function getMediaSettingsOptions() {
      const options2 = [];
      for (const db2 of databases) for (const config2 of db2.mediaSettingsConfigs) options2.push({
        value: JSON.stringify([db2.id, config2.name]),
        label: `${db2.name} / ${config2.name}`
      });
      return options2;
    }
    let syncTrigger = fallback($$props["syncTrigger"], "manual");
    let cronExpression = fallback($$props["cronExpression"], "0 * * * *");
    let saving = false;
    let syncing = false;
    let savedState = JSON.stringify({
      state: state2,
      syncTrigger,
      cronExpression
    });
    let isDirty2 = fallback($$props["isDirty"], false);
    $: namingOptions = getNamingOptions();
    $: qualityDefinitionsOptions = getQualityDefinitionsOptions();
    $: mediaSettingsOptions = getMediaSettingsOptions();
    $: namingValue = state2.namingDatabaseId !== null && state2.namingConfigName ? JSON.stringify([state2.namingDatabaseId, state2.namingConfigName]) : "";
    $: qualityDefinitionsValue = state2.qualityDefinitionsDatabaseId !== null && state2.qualityDefinitionsConfigName ? JSON.stringify([state2.qualityDefinitionsDatabaseId, state2.qualityDefinitionsConfigName]) : "";
    $: mediaSettingsValue = state2.mediaSettingsDatabaseId !== null && state2.mediaSettingsConfigName ? JSON.stringify([state2.mediaSettingsDatabaseId, state2.mediaSettingsConfigName]) : "";
    $: currentState = JSON.stringify({
      state: state2,
      syncTrigger,
      cronExpression
    });
    $: isDirty2 = currentState !== savedState;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div data-onboarding="sync-media-management" class="rounded-lg border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900"><div class="flex flex-col gap-4 border-b border-neutral-200 px-6 py-4 md:flex-row md:items-start md:justify-between md:gap-6 dark:border-neutral-800"><div class="min-w-0 md:flex-1"><h2 class="text-xl font-semibold text-neutral-900 dark:text-neutral-50">Media Management</h2> <p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400">Select which database config to use for each media management setting</p></div> `);
      if (namingProgress || qualityDefinitionsProgress || mediaSettingsProgress) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="flex flex-col gap-3 md:flex-shrink-0 md:flex-row md:flex-wrap md:gap-5 md:pt-1">`);
        if (namingProgress) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="min-w-[9rem]"><div class="mb-1 text-xs font-medium text-neutral-500 dark:text-neutral-400">Naming</div> `);
          ProgressIndicator($$renderer3, {
            current: namingProgress.total - namingProgress.drifted,
            target: namingProgress.total,
            met: namingProgress.drifted === 0,
            mode: "compact",
            colorMode: "completion",
            tooltip: namingProgress.message ?? "",
            tooltipPosition: "bottom",
            tooltipAlign: "middle"
          });
          $$renderer3.push(`<!----></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        if (qualityDefinitionsProgress) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="min-w-[9rem]"><div class="mb-1 text-xs font-medium text-neutral-500 dark:text-neutral-400">Quality Definitions</div> `);
          ProgressIndicator($$renderer3, {
            current: qualityDefinitionsProgress.total - qualityDefinitionsProgress.drifted,
            target: qualityDefinitionsProgress.total,
            met: qualityDefinitionsProgress.drifted === 0,
            mode: "compact",
            colorMode: "completion",
            tooltip: qualityDefinitionsProgress.message ?? "",
            tooltipPosition: "bottom",
            tooltipAlign: "middle"
          });
          $$renderer3.push(`<!----></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        if (mediaSettingsProgress) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="min-w-[9rem]"><div class="mb-1 text-xs font-medium text-neutral-500 dark:text-neutral-400">Media Settings</div> `);
          ProgressIndicator($$renderer3, {
            current: mediaSettingsProgress.total - mediaSettingsProgress.drifted,
            target: mediaSettingsProgress.total,
            met: mediaSettingsProgress.drifted === 0,
            mode: "compact",
            colorMode: "completion",
            tooltip: mediaSettingsProgress.message ?? "",
            tooltipPosition: "bottom",
            tooltipAlign: "middle"
          });
          $$renderer3.push(`<!----></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> <div class="p-6"><div class="grid gap-6 sm:grid-cols-3"><div class="space-y-2"><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Naming</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Choose the naming config to sync.</p></div> `);
      DropdownCombobox($$renderer3, {
        fullWidth: true,
        minWidth: "0",
        dropdownWidth: "100%",
        limit: 6,
        clearable: true,
        options: namingOptions,
        value: namingValue,
        placeholder: namingOptions.length === 0 ? "No naming configs available" : "Select naming config...",
        disabled: namingOptions.length === 0
      });
      $$renderer3.push(`<!----></div> <div class="space-y-2"><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Quality Definitions</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Choose the quality definitions config to sync.</p></div> `);
      DropdownCombobox($$renderer3, {
        fullWidth: true,
        minWidth: "0",
        dropdownWidth: "100%",
        limit: 6,
        clearable: true,
        options: qualityDefinitionsOptions,
        value: qualityDefinitionsValue,
        placeholder: qualityDefinitionsOptions.length === 0 ? "No quality definitions configs available" : "Select quality definitions config...",
        disabled: qualityDefinitionsOptions.length === 0
      });
      $$renderer3.push(`<!----></div> <div class="space-y-2"><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Media Settings</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Choose the media settings config to sync.</p></div> `);
      DropdownCombobox($$renderer3, {
        fullWidth: true,
        minWidth: "0",
        dropdownWidth: "100%",
        limit: 6,
        clearable: true,
        options: mediaSettingsOptions,
        value: mediaSettingsValue,
        placeholder: mediaSettingsOptions.length === 0 ? "No media settings configs available" : "Select media settings config...",
        disabled: mediaSettingsOptions.length === 0
      });
      $$renderer3.push(`<!----></div></div></div> `);
      SyncFooter($$renderer3, {
        saving,
        syncing,
        isDirty: isDirty2,
        hasConfig: state2.namingDatabaseId !== null || state2.qualityDefinitionsDatabaseId !== null || state2.mediaSettingsDatabaseId !== null,
        onboardingId: "sync-trigger",
        onWarning: (msg) => alertStore.add("warning", msg),
        get syncTrigger() {
          return syncTrigger;
        },
        set syncTrigger($$value) {
          syncTrigger = $$value;
          $$settled = false;
        },
        get cronExpression() {
          return cronExpression;
        },
        set cronExpression($$value) {
          cronExpression = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      databases,
      state: state2,
      namingProgress,
      qualityDefinitionsProgress,
      mediaSettingsProgress,
      syncTrigger,
      cronExpression,
      isDirty: isDirty2
    });
  });
}
function _page9($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let anyDirty, hasQualityProfilesSelected, hasMediaManagement, hasDelayProfile, qualityProfilesCanSave, qualityProfilesWarning;
    let data = $$props["data"];
    let showInfoModal = false;
    function buildProfileState(selections) {
      const state2 = {};
      for (const sel of selections) {
        if (!state2[sel.databaseId]) state2[sel.databaseId] = {};
        state2[sel.databaseId][sel.profileName] = true;
      }
      return state2;
    }
    let qualityProfileState = buildProfileState(data.syncData.qualityProfiles.selections);
    let qualityProfileTrigger = data.syncData.qualityProfiles.config.trigger;
    let qualityProfileCron = qualityProfileTrigger === "schedule" && data.syncData.qualityProfiles.config.cron || "0 0 * * *";
    let delayProfileState = {
      databaseId: data.syncData.delayProfiles.databaseId,
      profileName: data.syncData.delayProfiles.profileName
    };
    let delayProfileTrigger = data.syncData.delayProfiles.trigger;
    let delayProfileCron = delayProfileTrigger === "schedule" && data.syncData.delayProfiles.cron || "0 0 * * 0";
    let mediaManagementState = {
      namingDatabaseId: data.syncData.mediaManagement.namingDatabaseId,
      namingConfigName: data.syncData.mediaManagement.namingConfigName,
      qualityDefinitionsDatabaseId: data.syncData.mediaManagement.qualityDefinitionsDatabaseId,
      qualityDefinitionsConfigName: data.syncData.mediaManagement.qualityDefinitionsConfigName,
      mediaSettingsDatabaseId: data.syncData.mediaManagement.mediaSettingsDatabaseId,
      mediaSettingsConfigName: data.syncData.mediaManagement.mediaSettingsConfigName
    };
    let mediaManagementTrigger = data.syncData.mediaManagement.trigger;
    let mediaManagementCron = mediaManagementTrigger === "schedule" && data.syncData.mediaManagement.cron || "0 0 * * 0";
    let qualityProfilesDirty = false;
    let delayProfilesDirty = false;
    let mediaManagementDirty = false;
    const unsubscribeDriftFinished = jobStatus.onJobFinished((data2) => {
      if (data2.jobType === "arr.drift") invalidateAll();
    });
    onDestroy(unsubscribeDriftFinished);
    $: anyDirty = qualityProfilesDirty || delayProfilesDirty || mediaManagementDirty;
    $: update3("anyDirty", anyDirty);
    $: hasQualityProfilesSelected = Object.values(qualityProfileState).some((db2) => Object.values(db2).some((selected) => selected));
    $: hasMediaManagement = typeof mediaManagementState.namingDatabaseId === "number" && typeof mediaManagementState.namingConfigName === "string" && typeof mediaManagementState.qualityDefinitionsDatabaseId === "number" && typeof mediaManagementState.qualityDefinitionsConfigName === "string" && typeof mediaManagementState.mediaSettingsDatabaseId === "number" && typeof mediaManagementState.mediaSettingsConfigName === "string";
    $: hasDelayProfile = typeof delayProfileState.databaseId === "number" && typeof delayProfileState.profileName === "string";
    $: qualityProfilesCanSave = !hasQualityProfilesSelected || hasMediaManagement && !mediaManagementDirty && hasDelayProfile && !delayProfilesDirty;
    $: qualityProfilesWarning = (() => {
      if (!hasQualityProfilesSelected) return null;
      const issues = [];
      if (!hasMediaManagement) issues.push("media management settings");
      else if (mediaManagementDirty) issues.push("media management settings to be saved");
      if (!hasDelayProfile) issues.push("a delay profile");
      else if (delayProfilesDirty) issues.push("delay profile settings to be saved");
      if (issues.length === 0) return null;
      return `Quality profiles require ${issues.join(" and ")}.`;
    })();
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.instance.name} \xB7 Sync` });
      $$renderer3.push(`<!----> <!---->`);
      StickyCard($$renderer3, {
        position: "top",
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<h1 class="text-neutral-900 dark:text-neutral-50">Sync Configuration</h1> <p class="text-neutral-600 dark:text-neutral-400">Configure which profiles and settings to sync to this instance.</p>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<span data-onboarding="sync-how-it-works">`);
            Button($$renderer4, {
              text: "How it works",
              icon: Info
            });
            $$renderer4.push(`<!----></span>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="mt-4 space-y-6 pb-32">`);
      MediaManagement($$renderer3, {
        databases: data.databases,
        namingProgress: data.driftProgress?.naming,
        qualityDefinitionsProgress: data.driftProgress?.qualityDefinitions,
        mediaSettingsProgress: data.driftProgress?.mediaSettings,
        get state() {
          return mediaManagementState;
        },
        set state($$value) {
          mediaManagementState = $$value;
          $$settled = false;
        },
        get syncTrigger() {
          return mediaManagementTrigger;
        },
        set syncTrigger($$value) {
          mediaManagementTrigger = $$value;
          $$settled = false;
        },
        get cronExpression() {
          return mediaManagementCron;
        },
        set cronExpression($$value) {
          mediaManagementCron = $$value;
          $$settled = false;
        },
        get isDirty() {
          return mediaManagementDirty;
        },
        set isDirty($$value) {
          mediaManagementDirty = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      DelayProfiles($$renderer3, {
        databases: data.databases,
        progress: data.driftProgress?.delayProfiles,
        get state() {
          return delayProfileState;
        },
        set state($$value) {
          delayProfileState = $$value;
          $$settled = false;
        },
        get syncTrigger() {
          return delayProfileTrigger;
        },
        set syncTrigger($$value) {
          delayProfileTrigger = $$value;
          $$settled = false;
        },
        get cronExpression() {
          return delayProfileCron;
        },
        set cronExpression($$value) {
          delayProfileCron = $$value;
          $$settled = false;
        },
        get isDirty() {
          return delayProfilesDirty;
        },
        set isDirty($$value) {
          delayProfilesDirty = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      QualityProfiles($$renderer3, {
        databases: data.databases,
        databasePriorities: data.databasePriorities,
        canSave: qualityProfilesCanSave,
        warning: qualityProfilesWarning,
        qpProgress: data.driftProgress?.qualityProfiles,
        cfProgress: data.driftProgress?.customFormats,
        get state() {
          return qualityProfileState;
        },
        set state($$value) {
          qualityProfileState = $$value;
          $$settled = false;
        },
        get syncTrigger() {
          return qualityProfileTrigger;
        },
        set syncTrigger($$value) {
          qualityProfileTrigger = $$value;
          $$settled = false;
        },
        get cronExpression() {
          return qualityProfileCron;
        },
        set cronExpression($$value) {
          qualityProfileCron = $$value;
          $$settled = false;
        },
        get isDirty() {
          return qualityProfilesDirty;
        },
        set isDirty($$value) {
          qualityProfilesDirty = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----></div> `);
      InfoModal($$renderer3, {
        header: "How Sync Works",
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">Automatic Dependencies</div> <p class="mt-1">Quality Profiles will automatically sync the custom formats they need - you don't need to
					select them separately.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Database Priority</div> <p class="mt-1">You can sync quality profiles from multiple databases. Drag to reorder databases by
					priority. The topmost database has the highest priority and its profiles will overwrite
					any matching profiles from lower-priority databases.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Setup Order</div> <p class="mt-1">Configure from top to bottom. Media management and delay profiles must be saved before
					quality profiles can be synced. Quality profiles depend on these settings to ensure your
					instance is configured consistently.</p></div> <div class="border-t border-neutral-200 pt-4 dark:border-neutral-700"><div class="mb-3 font-medium text-neutral-900 dark:text-neutral-100">Sync Methods</div> <div class="space-y-3"><div><div class="font-medium text-neutral-800 dark:text-neutral-200">Manual</div> <p class="mt-0.5">You manually click the sync button. Useful for media management settings that rarely
							get updates.</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Schedule</div> <p class="mt-0.5">Syncs on a defined schedule using cron expressions.</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">On Pull</div> <p class="mt-0.5">Syncs when the upstream database gets a change (when you pull from remote).</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">On Change</div> <p class="mt-0.5">Syncs when anything changes - whether you pull from upstream or change something
							yourself.</p></div></div></div> <div class="border-t border-neutral-200 pt-4 dark:border-neutral-700"><div class="mb-3 font-medium text-neutral-900 dark:text-neutral-100">Cron Expressions</div> <p class="mb-3">Schedule uses standard cron syntax: <code class="rounded bg-neutral-100 px-1.5 py-0.5 font-mono text-xs dark:bg-neutral-800">minute hour day month weekday</code></p> <div class="space-y-1.5 font-mono text-xs"><div class="flex gap-3"><code class="rounded bg-neutral-100 px-1.5 py-0.5 dark:bg-neutral-800">0 * * * *</code> <span class="font-sans">Every hour</span></div> <div class="flex gap-3"><code class="rounded bg-neutral-100 px-1.5 py-0.5 dark:bg-neutral-800">*/15 * * * *</code> <span class="font-sans">Every 15 minutes</span></div> <div class="flex gap-3"><code class="rounded bg-neutral-100 px-1.5 py-0.5 dark:bg-neutral-800">0 0 * * *</code> <span class="font-sans">Daily at midnight</span></div> <div class="flex gap-3"><code class="rounded bg-neutral-100 px-1.5 py-0.5 dark:bg-neutral-800">0 6 * * 1</code> <span class="font-sans">Every Monday at 6am</span></div></div></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      DirtyModal($$renderer3, {});
      $$renderer3.push(`<!---->`);
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, { data });
  });
}
var init_page_svelte9 = __esm({
  "dist/build/server/entries/pages/arr/_id_/sync/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_chevron_down();
    init_chevron_up();
    init_info();
    init_Button();
    init_refresh_cw();
    init_save();
    init_triangle_alert();
    init_client4();
    init_store2();
    init_Label();
    init_jobStatus();
    init_navigation();
    init_forms();
    init_dirty();
    init_DirtyModal();
    init_InfoModal();
    init_PageMeta();
    init_StickyCard();
    init_DropdownSelect();
    init_DropdownCombobox();
    init_CronInput();
    init_Toggle();
    init_ProgressIndicator();
    init_DraggableCard();
  }
});

// dist/build/server/nodes/16.js
var __exports17 = {};
__export(__exports17, {
  component: () => component16,
  fonts: () => fonts17,
  imports: () => imports17,
  index: () => index17,
  server: () => page_server_ts_exports10,
  server_id: () => server_id16,
  stylesheets: () => stylesheets17
});
var index17, component_cache16, component16, server_id16, imports17, stylesheets17, fonts17;
var init__17 = __esm({
  async "dist/build/server/nodes/16.js"() {
    "use strict";
    await init_page_server_ts10();
    index17 = 16;
    component16 = async () => component_cache16 ??= (await Promise.resolve().then(() => (init_page_svelte9(), page_svelte_exports9))).default;
    server_id16 = "src/routes/arr/[id]/sync/+page.server.ts";
    imports17 = ["_app/immutable/nodes/16.COEbQiuH.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/COLvC_Ug.js", "_app/immutable/chunks/C47WFcPn.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/sG_Q4rn7.js", "_app/immutable/chunks/Ks-0Do1f.js"];
    stylesheets17 = [];
    fonts17 = [];
  }
});

// dist/build/server/entries/pages/arr/_id_/upgrades/_page.server.ts.js
var page_server_ts_exports11 = {};
__export(page_server_ts_exports11, {
  actions: () => actions8,
  load: () => load16
});
function toOptions(values) {
  const unique = [...new Set([...values].map((v3) => v3?.trim()).filter(Boolean))];
  unique.sort((a2, b3) => a2.localeCompare(b3, void 0, { sensitivity: "base" }));
  return unique.map((value2) => ({
    value: value2,
    label: value2
  }));
}
async function loadOptional(load80) {
  try {
    return await load80();
  } catch {
    return null;
  }
}
function setOptions(options2, field, values) {
  options2[field] = toOptions(values);
}
async function loadDynamicFilterOptions(instance) {
  const options2 = createEmptyDynamicFilterOptions(instance.type);
  const isRadarr = instance.type === "radarr";
  const client2 = isRadarr ? new RadarrClient(instance.url, instance.api_key) : new SonarrClient(instance.url, instance.api_key);
  const [profiles, tags, libraryItems, customFormats] = await Promise.all([
    loadOptional(() => client2.getQualityProfiles()),
    loadOptional(() => client2.getTags()),
    isRadarr ? loadOptional(() => client2.getMovies()) : loadOptional(() => client2.getAllSeries()),
    isRadarr ? loadOptional(() => client2.getCustomFormats()) : Promise.resolve(null)
  ]);
  setOptions(options2, "quality_profile", profiles?.map((profile) => profile.name) ?? []);
  setOptions(options2, "tags", tags?.map((tag2) => tag2.label) ?? []);
  if (isRadarr) {
    const movies = libraryItems ?? [];
    const movieIdsWithFiles = movies.filter((movie) => movie.hasFile).map((movie) => movie.id);
    const movieFiles = await loadOptional(() => client2.getMovieFiles(movieIdsWithFiles));
    setOptions(options2, "original_language", movies.map((movie) => movie.originalLanguage?.name));
    setOptions(options2, "genres", movies.flatMap((movie) => movie.genres ?? []));
    setOptions(options2, "release_group", movieFiles?.map((file) => file.releaseGroup) ?? []);
    setOptions(options2, "custom_format", customFormats?.map((format) => format.name) ?? []);
    return options2;
  }
  const seriesList = libraryItems ?? [];
  setOptions(options2, "original_language", seriesList.map((series) => series.originalLanguage?.name));
  setOptions(options2, "genres", seriesList.flatMap((series) => series.genres ?? []));
  setOptions(options2, "network", seriesList.map((series) => series.network));
  setOptions(options2, "certification", seriesList.map((series) => series.certification));
  return options2;
}
var dryRunTimestamps, DRY_RUN_COOLDOWN_MS, load16, actions8;
var init_page_server_ts11 = __esm({
  async "dist/build/server/entries/pages/arr/_id_/upgrades/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_display();
    await init_queueService();
    await init_arrCleanupSettings();
    await init_radarr();
    await init_sonarr();
    init_selectors();
    await init_init();
    init_exports();
    dryRunTimestamps = /* @__PURE__ */ new Map();
    DRY_RUN_COOLDOWN_MS = 6e5;
    load16 = async ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (isNaN(id)) error(404, `Invalid instance ID: ${params.id}`);
      const instance = arrInstancesQueries.getById(id);
      if (!instance) error(404, `Instance not found: ${id}`);
      const config2 = upgradeConfigsQueries.getByArrInstanceId(id);
      const upgradeRuns = upgradeRunsQueries.getByInstanceId(id);
      const dynamicFilterOptions = loadDynamicFilterOptions(instance);
      const { api_key: _3, ...safeInstance } = instance;
      return {
        instance: safeInstance,
        config: config2 ?? null,
        upgradeRuns,
        dynamicFilterOptions
      };
    };
    actions8 = {
      save: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        const formData = await request.formData();
        try {
          const enabled3 = formData.get("enabled") === "true";
          const cron = formData.get("cron") || "0 */6 * * *";
          const filterMode2 = formData.get("filterMode") || "round_robin";
          const filtersJson = formData.get("filters");
          const filters = filtersJson ? JSON.parse(filtersJson) : [];
          const minInterval = searchRateLimits[instance.type]?.minIntervalMinutes ?? 10;
          const cronError = validateCronExpression(cron, minInterval);
          if (cronError) return fail(400, { error: cronError });
          const rph = getRunsPerHour(cron);
          if (rph !== null) {
            const maxCount = calculateMaxCount(instance.type, rph);
            for (const f2 of filters) if (f2.count > maxCount) return fail(400, { error: `Filter "${f2.name}" count (${f2.count}) exceeds max (${maxCount}) for this schedule.` });
          }
          const configData = {
            enabled: enabled3,
            cron,
            filterMode: filterMode2,
            filters
          };
          upgradeConfigsQueries.upsert(id, configData);
          const nextRunAt = calculateNextRun(cron);
          if (nextRunAt) upgradeConfigsQueries.updateNextRunAt(id, nextRunAt);
          await logger.info(`Upgrade config saved for instance "${instance.name}"`, {
            source: "upgrades",
            meta: {
              instanceId: id,
              instanceName: instance.name
            }
          });
          await logger.debug("Upgrade config details", {
            source: "upgrades",
            meta: {
              instanceId: id,
              enabled: enabled3,
              cron,
              filterMode: filterMode2,
              filterCount: filters.length,
              filters: filters.map((f2) => ({
                id: f2.id,
                name: f2.name,
                enabled: f2.enabled,
                selector: f2.selector,
                count: f2.count,
                cutoff: f2.cutoff
              }))
            }
          });
          await logger.debug("Filter rules", {
            source: "upgrades",
            meta: { filters: filters.map((f2) => ({
              name: f2.name,
              rules: f2.group
            })) }
          });
          scheduleUpgradeForInstance(id);
          return { success: true };
        } catch (err) {
          await logger.error("Failed to save upgrade config", {
            source: "upgrades",
            meta: {
              instanceId: id,
              error: err
            }
          });
          return fail(500, { error: "Failed to save configuration" });
        }
      },
      run: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instance = arrInstancesQueries.getById(id);
        if (!instance) return fail(404, { error: "Instance not found" });
        const config2 = upgradeConfigsQueries.getByArrInstanceId(id);
        if (!config2) return fail(404, { error: "No upgrade configuration found. Save a configuration first." });
        if (config2.filters.length === 0) return fail(400, { error: "No filters configured. Add at least one filter." });
        if (config2.filters.filter((f2) => f2.enabled).length === 0) return fail(400, { error: "No enabled filters. Enable at least one filter." });
        const dryRun = (await request.formData()).get("dryRun") === "true";
        if (dryRun) {
          const lastDryRun = dryRunTimestamps.get(id);
          if (lastDryRun && Date.now() - lastDryRun < DRY_RUN_COOLDOWN_MS) {
            const remainingMs = DRY_RUN_COOLDOWN_MS - (Date.now() - lastDryRun);
            const remainingMin = Math.ceil(remainingMs / 6e4);
            await logger.warn(`Dry run cooldown active for "${instance.name}" - ${remainingMin}m remaining`, {
              source: "upgrades",
              meta: {
                instanceId: id,
                instanceName: instance.name,
                remainingMin
              }
            });
            return fail(400, { error: `Dry run cooldown active. Try again in ${remainingMin} minute${remainingMin !== 1 ? "s" : ""}.` });
          }
        }
        try {
          const queued = upsertScheduledJob({
            jobType: "arr.upgrade",
            runAt: (/* @__PURE__ */ new Date()).toISOString(),
            payload: {
              instanceId: id,
              dryRun
            },
            source: "manual",
            dedupeKey: `arr.upgrade.manual:${id}`
          });
          if (dryRun) dryRunTimestamps.set(id, Date.now());
          await logger.info(`Manual upgrade run queued for "${instance.name}"`, {
            source: "upgrades",
            meta: {
              jobId: queued.id,
              instanceId: id,
              instanceName: instance.name,
              displayName: buildJobDisplayName("arr.upgrade", { instanceId: id }),
              dryRun
            }
          });
          return {
            success: true,
            queued: true
          };
        } catch (err) {
          await logger.error("Manual upgrade run failed", {
            source: "upgrades",
            meta: {
              instanceId: id,
              error: err
            }
          });
          return fail(500, { error: "Upgrade run failed. Check logs for details." });
        }
      },
      clearCache: async ({ params }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) return fail(400, { error: "Invalid instance ID" });
        const instanceName = arrInstancesQueries.getById(id)?.name ?? `Instance ${id}`;
        const clearedIds = clearDryRunExclusions(id);
        await logDryRunCacheCleared(id, instanceName, clearedIds);
        return {
          success: true,
          cacheCleared: true
        };
      }
    };
  }
});

// dist/build/server/chunks/pencil.js
function Pencil($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "pencil" },
    props,
    { iconNode: [["path", { "d": "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" }], ["path", { "d": "m15 5 4 4" }]] }
  ]));
}
var init_pencil = __esm({
  "dist/build/server/chunks/pencil.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/rotate-ccw.js
function Rotate_ccw($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "rotate-ccw" },
    props,
    { iconNode: [["path", { "d": "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }], ["path", { "d": "M3 3v5h5" }]] }
  ]));
}
var init_rotate_ccw = __esm({
  "dist/build/server/chunks/rotate-ccw.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/DateInput.js
function DateInput($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let monthOptions, effectiveMinYear, effectiveMaxYear, yearOptions, maxDay, dayOptions, containerClass, effectiveDisabled, fieldGapClass, monthWidthClass, monthMinWidth, dayWidthClass, dayMinWidth, yearWidthClass, yearMinWidth, datePartOrder;
    let label = $$props["label"];
    let description = fallback($$props["description"], "");
    let value2 = fallback($$props["value"], "");
    let required = fallback($$props["required"], false);
    let hideLabel = fallback($$props["hideLabel"], false);
    let name = fallback($$props["name"], "");
    let readonly = fallback($$props["readonly"], false);
    let disabled = fallback($$props["disabled"], false);
    let size = fallback($$props["size"], "md");
    let fixed = fallback($$props["fixed"], false);
    let minYear = fallback($$props["minYear"], void 0);
    let maxYear = fallback($$props["maxYear"], void 0);
    let compact2 = fallback($$props["compact"], false);
    let fullWidth = fallback($$props["fullWidth"], false);
    let responsive = fallback($$props["responsive"], false);
    let shortLabels = fallback($$props["shortLabels"], false);
    const dispatch = createEventDispatcher();
    const now = /* @__PURE__ */ new Date();
    const currentYear = now.getFullYear();
    const defaultMinYear = currentYear - 10;
    const defaultMaxYear = currentYear + 10;
    let year2 = String(currentYear);
    let month = String(now.getMonth() + 1).padStart(2, "0");
    let day2 = String(now.getDate()).padStart(2, "0");
    let lastValue = "";
    let comboboxButtonSize;
    let responsiveButtonSize;
    const baseMonthOptions = [
      {
        value: "01",
        label: "Jan"
      },
      {
        value: "02",
        label: "Feb"
      },
      {
        value: "03",
        label: "Mar"
      },
      {
        value: "04",
        label: "Apr"
      },
      {
        value: "05",
        label: "May"
      },
      {
        value: "06",
        label: "Jun"
      },
      {
        value: "07",
        label: "Jul"
      },
      {
        value: "08",
        label: "Aug"
      },
      {
        value: "09",
        label: "Sep"
      },
      {
        value: "10",
        label: "Oct"
      },
      {
        value: "11",
        label: "Nov"
      },
      {
        value: "12",
        label: "Dec"
      }
    ];
    function daysInMonth(yearNumber, monthNumber) {
      if (!Number.isFinite(yearNumber) || !Number.isFinite(monthNumber)) return 31;
      return new Date(yearNumber, monthNumber, 0).getDate();
    }
    function parseValue(nextValue) {
      if (/^\d{4}-\d{2}-\d{2}$/.test(nextValue)) {
        const [nextYear, nextMonth, nextDay] = nextValue.split("-");
        year2 = nextYear;
        month = nextMonth;
        day2 = nextDay;
        return;
      }
      year2 = String(currentYear);
      month = String(now.getMonth() + 1).padStart(2, "0");
      day2 = String(now.getDate()).padStart(2, "0");
    }
    function updateValue(nextYear = year2, nextMonth = month, nextDay = day2) {
      const maxForMonth = daysInMonth(Number(nextYear), Number(nextMonth));
      const safeDayValue = String(Math.min(Math.max(parseInt(nextDay, 10), 1), maxForMonth)).padStart(2, "0");
      year2 = nextYear;
      month = nextMonth;
      day2 = safeDayValue;
      const nextValue = `${year2}-${month}-${day2}`;
      if (nextValue === value2) {
        lastValue = nextValue;
        return;
      }
      value2 = nextValue;
      lastValue = nextValue;
      dispatch("input", nextValue);
      dispatch("change", nextValue);
    }
    $: monthOptions = baseMonthOptions.map((option) => shortLabels ? {
      ...option,
      shortLabel: option.value
    } : option);
    $: effectiveMinYear = Math.min(minYear ?? defaultMinYear, maxYear ?? defaultMaxYear);
    $: effectiveMaxYear = Math.max(maxYear ?? defaultMaxYear, minYear ?? defaultMinYear);
    $: yearOptions = Array.from({ length: effectiveMaxYear - effectiveMinYear + 1 }, (_3, idx) => {
      const nextYear = effectiveMinYear + idx;
      return {
        value: String(nextYear),
        label: String(nextYear)
      };
    });
    $: maxDay = daysInMonth(Number(year2), Number(month));
    $: dayOptions = Array.from({ length: maxDay }, (_3, idx) => {
      const value3 = String(idx + 1).padStart(2, "0");
      return {
        value: value3,
        label: value3
      };
    });
    $: containerClass = hideLabel && !description ? "space-y-0" : "space-y-2";
    $: effectiveDisabled = disabled || readonly;
    $: comboboxButtonSize = size === "sm" ? "xs" : size === "lg" ? "md" : "sm";
    $: responsiveButtonSize = responsive ? null : comboboxButtonSize;
    $: fieldGapClass = compact2 ? "gap-1" : "gap-2";
    $: monthWidthClass = fullWidth ? shortLabels ? "w-fit md:flex-1" : "flex-1" : "w-20";
    $: monthMinWidth = fullWidth ? "0" : "5rem";
    $: dayWidthClass = fullWidth ? shortLabels ? "w-fit md:flex-1" : "flex-1" : "w-16";
    $: dayMinWidth = fullWidth ? "0" : "4rem";
    $: yearWidthClass = fullWidth ? shortLabels ? "w-fit md:flex-1" : "flex-1" : "w-24";
    $: yearMinWidth = fullWidth ? "0" : "6rem";
    $: datePartOrder = getDatePartOrder(store_get($$store_subs ??= {}, "$dateFormat", dateFormat));
    $: if (value2 !== lastValue) {
      parseValue(value2);
      lastValue = value2;
    }
    $: if (value2 === "" && lastValue === "") updateValue(year2, month, day2);
    $$renderer2.push(`<div${attr_class(clsx(containerClass))}>`);
    if (!hideLabel) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<label${attr("for", name)} class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(label)}`);
      if (required) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<span class="text-red-500">*</span>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></label>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (description) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<p class="text-xs text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div${attr_class(`flex items-center ${stringify(fieldGapClass)}`, void 0, { "w-full": fullWidth })}><!--[-->`);
    const each_array = ensure_array_like(datePartOrder);
    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
      let part = each_array[$$index];
      if (part === "month") {
        $$renderer2.push("<!--[0-->");
        DropdownCombobox($$renderer2, {
          value: month,
          options: monthOptions,
          placeholder: "Month",
          minWidth: monthMinWidth,
          width: monthWidthClass,
          fullWidth: true,
          limit: 6,
          fixed,
          buttonSize: responsiveButtonSize,
          responsiveButton: responsive,
          responsiveDropdown: responsive,
          compactDropdown: compact2 ? true : void 0,
          disabled: effectiveDisabled
        });
      } else if (part === "day") {
        $$renderer2.push("<!--[1-->");
        DropdownCombobox($$renderer2, {
          value: day2,
          options: dayOptions,
          placeholder: "Day",
          minWidth: dayMinWidth,
          width: dayWidthClass,
          fullWidth: true,
          limit: 6,
          fixed,
          buttonSize: responsiveButtonSize,
          responsiveButton: responsive,
          responsiveDropdown: responsive,
          compactDropdown: compact2 ? true : void 0,
          disabled: effectiveDisabled
        });
      } else {
        $$renderer2.push("<!--[-1-->");
        DropdownCombobox($$renderer2, {
          value: year2,
          options: yearOptions,
          placeholder: "Year",
          minWidth: yearMinWidth,
          width: yearWidthClass,
          fullWidth: true,
          limit: 6,
          fixed,
          buttonSize: responsiveButtonSize,
          responsiveButton: responsive,
          responsiveDropdown: responsive,
          compactDropdown: compact2 ? true : void 0,
          disabled: effectiveDisabled
        });
      }
      $$renderer2.push(`<!--]-->`);
    }
    $$renderer2.push(`<!--]--></div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      label,
      description,
      value: value2,
      required,
      hideLabel,
      name,
      readonly,
      disabled,
      size,
      fixed,
      minYear,
      maxYear,
      compact: compact2,
      fullWidth,
      responsive,
      shortLabels
    });
  });
}
var init_DateInput = __esm({
  "dist/build/server/chunks/DateInput.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_dates();
    init_dateFormat();
    init_DropdownCombobox();
  }
});

// dist/build/server/chunks/themes.js
function scan(code3, patterns) {
  const tokens = [];
  let pos = 0;
  while (pos < code3.length) {
    let matched = false;
    const slice = code3.slice(pos);
    for (const [regex, type] of patterns) {
      const match = regex.exec(slice);
      if (match) {
        tokens.push({
          type,
          text: match[0]
        });
        pos += match[0].length;
        matched = true;
        break;
      }
    }
    if (!matched) {
      tokens.push({
        type: "text",
        text: code3[pos]
      });
      pos += 1;
    }
  }
  return tokens;
}
function tokenizeSql(code3) {
  return scan(code3, SQL_PATTERNS).map((token) => {
    if (token.type === "word") return {
      type: SQL_KEYWORDS.has(token.text.toUpperCase()) ? "keyword" : "identifier",
      text: token.text
    };
    return token;
  });
}
function tokenizeJson(code3) {
  return scan(code3, JSON_PATTERNS);
}
function tokenize(code3, language) {
  if (!code3) return [];
  switch (language) {
    case "sql":
      return tokenizeSql(code3);
    case "json":
      return tokenizeJson(code3);
    default:
      return [{
        type: "text",
        text: code3
      }];
  }
}
function getTheme(name) {
  return themes.find((t2) => t2.name === name) ?? themes[0];
}
var SQL_KEYWORDS, SQL_PATTERNS, JSON_PATTERNS, themes;
var init_themes = __esm({
  "dist/build/server/chunks/themes.js"() {
    "use strict";
    SQL_KEYWORDS = /* @__PURE__ */ new Set([
      "INSERT",
      "INTO",
      "UPDATE",
      "DELETE",
      "SET",
      "WHERE",
      "FROM",
      "AND",
      "OR",
      "NOT",
      "IN",
      "VALUES",
      "SELECT",
      "CREATE",
      "ALTER",
      "DROP",
      "TABLE",
      "INDEX",
      "ON",
      "AS",
      "IS",
      "NULL",
      "DEFAULT",
      "PRIMARY",
      "KEY",
      "FOREIGN",
      "REFERENCES",
      "CASCADE",
      "EXISTS",
      "IF",
      "BEGIN",
      "COMMIT",
      "REPLACE",
      "GROUP",
      "BY",
      "ORDER",
      "LIMIT",
      "HAVING",
      "JOIN",
      "LEFT",
      "RIGHT",
      "INNER",
      "LIKE",
      "BETWEEN",
      "DISTINCT",
      "UNION",
      "ALL",
      "CASE",
      "WHEN",
      "THEN",
      "ELSE",
      "END",
      "ASC",
      "DESC",
      "OFFSET",
      "ROLLBACK",
      "WITH"
    ]);
    SQL_PATTERNS = [
      [/^--[^\n]*/, "comment"],
      [/^'(?:[^']|'')*'/, "string"],
      [/^\d+(?:\.\d+)?/, "number"],
      [/^[a-zA-Z_]\w*/, "word"],
      [/^(?:<>|!=|<=|>=|\|\||[=<>])/, "operator"],
      [/^[(),;.]/, "punctuation"],
      [/^\s+/, "whitespace"]
    ];
    JSON_PATTERNS = [
      [/^"(?:[^"\\]|\\.)*"\s*(?=:)/, "key"],
      [/^"(?:[^"\\]|\\.)*"/, "string"],
      [/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/, "number"],
      [/^(?:true|false|null)\b/, "literal"],
      [/^[{}[\]:,]/, "punctuation"],
      [/^\s+/, "whitespace"]
    ];
    themes = [{
      name: "Default",
      dark: {
        bg: "#171717",
        text: "#cdd6f4",
        keyword: "#89b4fa",
        identifier: "#a6e3a1",
        string: "#cdd6f4",
        number: "#fab387",
        comment: "#6c7086",
        operator: "#89dceb",
        punctuation: "#7f849c",
        key: "#89b4fa",
        literal: "#89dceb"
      },
      light: {
        bg: "#ffffff",
        text: "#4c4f69",
        keyword: "#1e66f5",
        identifier: "#40a02b",
        string: "#4c4f69",
        number: "#fe640b",
        comment: "#9ca0b0",
        operator: "#04a5e5",
        punctuation: "#8c8fa1",
        key: "#1e66f5",
        literal: "#04a5e5"
      }
    }];
  }
});

// dist/build/server/entries/pages/arr/_id_/upgrades/_page.svelte.js
var page_svelte_exports10 = {};
__export(page_svelte_exports10, {
  default: () => _page10
});
function Clipboard_copy($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "clipboard-copy" },
    props,
    { iconNode: [
      ["rect", {
        "width": "8",
        "height": "4",
        "x": "8",
        "y": "2",
        "rx": "1",
        "ry": "1"
      }],
      ["path", { "d": "M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2" }],
      ["path", { "d": "M16 4h2a2 2 0 0 1 2 2v4" }],
      ["path", { "d": "M21 14H11" }],
      ["path", { "d": "m15 10-4 4 4 4" }]
    ] }
  ]));
}
function File_braces($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "file-braces" },
    props,
    { iconNode: [
      ["path", { "d": "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z" }],
      ["path", { "d": "M14 2v5a1 1 0 0 0 1 1h5" }],
      ["path", { "d": "M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1" }],
      ["path", { "d": "M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1" }]
    ] }
  ]));
}
function Folder_plus($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "folder-plus" },
    props,
    { iconNode: [
      ["path", { "d": "M12 10v6" }],
      ["path", { "d": "M9 13h6" }],
      ["path", { "d": "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" }]
    ] }
  ]));
}
function Message_square($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "message-square" },
    props,
    { iconNode: [["path", { "d": "M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z" }]] }
  ]));
}
function Octagon_alert($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "octagon-alert" },
    props,
    { iconNode: [
      ["path", { "d": "M12 16h.01" }],
      ["path", { "d": "M12 8v4" }],
      ["path", { "d": "M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z" }]
    ] }
  ]));
}
function Power($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "power" },
    props,
    { iconNode: [["path", { "d": "M12 2v10" }], ["path", { "d": "M18.4 6.6a9 9 0 1 1-12.77.04" }]] }
  ]));
}
function CoreSettings($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let modeOptions, nextRunTime, timeUntilNext;
    let enabled3 = fallback($$props["enabled"], true);
    let cron = fallback($$props["cron"], "0 */6 * * *");
    let filterMode2 = fallback($$props["filterMode"], "round_robin");
    let lastRunAt = fallback($$props["lastRunAt"], null);
    let nextRunAt = fallback($$props["nextRunAt"], null);
    let minIntervalMinutes = fallback($$props["minIntervalMinutes"], 10);
    let onEnabledChange = fallback($$props["onEnabledChange"], void 0);
    let onCronChange = fallback($$props["onCronChange"], void 0);
    let onFilterModeChange = fallback($$props["onFilterModeChange"], void 0);
    let onWarning = fallback($$props["onWarning"], void 0);
    let cronValue = cron;
    let now = Date.now();
    onDestroy(() => {
    });
    function formatTimeRemaining(ms) {
      if (ms <= 0) return "now";
      const seconds = Math.floor(ms / 1e3);
      const minutes = Math.floor(seconds / 60);
      const hours = Math.floor(minutes / 60);
      if (hours > 0) return `${hours}h ${minutes % 60}m`;
      if (minutes > 0) return `${minutes}m`;
      return `${seconds}s`;
    }
    $: modeOptions = filterModes.map((m3) => ({
      value: m3.id,
      label: m3.label
    }));
    $: cronValue = cron;
    $: if (cronValue !== cron) onCronChange?.(cronValue);
    $: nextRunTime = nextRunAt ? new Date(nextRunAt).getTime() : null;
    $: timeUntilNext = nextRunTime ? nextRunTime - now : null;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="flex flex-wrap gap-4 md:items-end md:gap-x-5 md:gap-y-3 md:px-4"><div><span class="mb-1 block text-[10px] font-medium tracking-wider text-neutral-400 uppercase dark:text-neutral-500">Status</span> `);
      Toggle($$renderer3, {
        checked: enabled3,
        label: enabled3 ? "Enabled" : "Disabled",
        color: enabled3 ? "green" : "red"
      });
      $$renderer3.push(`<!----></div> <div data-onboarding="upgrades-schedule"${attr("aria-disabled", !enabled3)}${attr_class("", void 0, {
        "pointer-events-none": !enabled3,
        "opacity-50": !enabled3
      })}><span class="mb-1 block text-[10px] font-medium tracking-wider text-neutral-400 uppercase dark:text-neutral-500">Schedule</span> `);
      CronInput($$renderer3, {
        minIntervalMinutes,
        onWarning,
        get value() {
          return cronValue;
        },
        set value($$value) {
          cronValue = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----></div> <div data-onboarding="upgrades-filter-mode"${attr("aria-disabled", !enabled3)}${attr_class("", void 0, {
        "pointer-events-none": !enabled3,
        "opacity-50": !enabled3
      })}><span class="mb-1 block text-[10px] font-medium tracking-wider text-neutral-400 uppercase dark:text-neutral-500">Mode</span> `);
      DropdownSelect($$renderer3, {
        value: filterMode2,
        options: modeOptions,
        minWidth: "10rem",
        responsiveDropdown: true
      });
      $$renderer3.push(`<!----></div> `);
      if (lastRunAt) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="flex w-full flex-wrap items-center gap-1.5 border-t border-neutral-200 pt-3 md:ml-auto md:w-auto md:border-0 md:pt-0 dark:border-neutral-800">`);
        if (!enabled3) {
          $$renderer3.push("<!--[0-->");
          Label($$renderer3, {
            variant: "warning",
            size: "md",
            rounded: "md",
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->Paused`);
            },
            $$slots: { default: true }
          });
        } else if (timeUntilNext !== null && timeUntilNext <= 0) {
          $$renderer3.push("<!--[1-->");
          Label($$renderer3, {
            variant: "success",
            size: "md",
            rounded: "md",
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->Ready`);
            },
            $$slots: { default: true }
          });
        } else if (timeUntilNext !== null) {
          $$renderer3.push("<!--[2-->");
          Label($$renderer3, {
            variant: "secondary",
            size: "md",
            rounded: "md",
            mono: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->Next ${escape_html(formatTimeRemaining(timeUntilNext))}`);
            },
            $$slots: { default: true }
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        Label($$renderer3, {
          variant: "secondary",
          size: "md",
          rounded: "md",
          mono: true,
          children: ($$renderer4) => {
            $$renderer4.push(`<!---->Last ${escape_html(formatSmartDateTime(lastRunAt, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat)))}`);
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      enabled: enabled3,
      cron,
      filterMode: filterMode2,
      lastRunAt,
      nextRunAt,
      minIntervalMinutes,
      onEnabledChange,
      onCronChange,
      onFilterModeChange,
      onWarning
    });
  });
}
function FilterGroup($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let fields;
    let group = $$props["group"];
    let appType = fallback($$props["appType"], "radarr");
    let dynamicFilterOptions = fallback($$props["dynamicFilterOptions"], () => ({}), true);
    let dynamicFilterOptionsLoading = fallback($$props["dynamicFilterOptionsLoading"], false);
    let dynamicFilterOptionsVersion = fallback($$props["dynamicFilterOptionsVersion"], 0);
    let onRemove = fallback($$props["onRemove"], null);
    let depth = fallback($$props["depth"], 0);
    const dynamicStringOperators = [{
      value: "eq",
      label: "is"
    }, {
      value: "neq",
      label: "is not"
    }];
    let normalizedRulesSignature = "";
    const dispatch = createEventDispatcher();
    function notifyChange() {
      group = group;
      dispatch("change");
    }
    function removeChild(index88) {
      group.children = group.children.filter((_3, i) => i !== index88);
      notifyChange();
    }
    function isDynamicStringField(fieldId) {
      return fieldId in dynamicFilterOptions && fieldId !== "custom_format" && !isMultiValueFilterField(fieldId);
    }
    function isValuelessOperator2(fieldId, operator) {
      return fieldId === "custom_format" && isCustomFormatUnaryOperator(operator) || isMultiValueFilterField(fieldId) && isMultiValueUnaryOperator(operator);
    }
    function ruleNeedsValue(rule) {
      return !isValuelessOperator2(rule.field, rule.operator);
    }
    function getDynamicOptions(fieldId, value2, optionsByField) {
      const options2 = optionsByField[fieldId] ?? [];
      const currentValue = typeof value2 === "string" ? value2.trim() : "";
      if (!currentValue || options2.some((option) => option.value === currentValue)) return options2;
      return [{
        value: currentValue,
        label: currentValue
      }, ...options2];
    }
    function normalizeDynamicOperators(targetGroup) {
      return normalizeFilterGroup(targetGroup, appType, { dynamicFilterOptions });
    }
    const keyWidthClass = "w-fit md:w-48";
    const operatorWidthClass = "w-fit md:w-40";
    const valueWidthClass = "w-fit md:w-72";
    const keyMinWidth = "0";
    const valueMinWidth = "0";
    $: fields = getFilterFields(appType);
    $: if (JSON.stringify({
      dynamicFields: Object.keys(dynamicFilterOptions).sort(),
      group
    }) !== normalizedRulesSignature) {
      if (normalizeDynamicOperators(group)) notifyChange();
      normalizedRulesSignature = JSON.stringify({
        dynamicFields: Object.keys(dynamicFilterOptions).sort(),
        group
      });
    }
    Card($$renderer2, {
      padding: depth === 0 ? "none" : "sm",
      flush: depth === 0,
      className: depth === 0 ? "!rounded-none !border-0" : "!border-neutral-200 dark:!border-neutral-700/60",
      children: ($$renderer3) => {
        $$renderer3.push(`<div class="mb-3 flex items-center justify-between"><div class="flex items-center gap-2"><span class="text-xs font-medium text-neutral-700 dark:text-neutral-300">Match</span> `);
        DropdownSelect($$renderer3, {
          value: group.match,
          options: [{
            value: "all",
            label: "All (AND)"
          }, {
            value: "any",
            label: "Any (OR)"
          }],
          minWidth: "7rem",
          responsiveButton: true,
          responsiveDropdown: true,
          fixed: true
        });
        $$renderer3.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">of the following rules</span></div> `);
        if (onRemove) {
          $$renderer3.push("<!--[0-->");
          Button($$renderer3, {
            icon: X2,
            variant: "ghost",
            size: "xs"
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div> `);
        if (group.children.length === 0) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="text-sm text-neutral-500 dark:text-neutral-400">No rules configured. Add a rule to start filtering.</div>`);
        } else {
          $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<div class="overflow-x-auto pb-3"><div class="min-w-max space-y-2"><!--[-->`);
          const each_array = ensure_array_like(group.children);
          for (let childIndex = 0, $$length = each_array.length; childIndex < $$length; childIndex++) {
            let child = each_array[childIndex];
            if (isRule(child)) {
              $$renderer3.push("<!--[0-->");
              const field = getFilterField(child.field, appType);
              const isDynamicField = child.field in dynamicFilterOptions;
              const isDynamicString = isDynamicStringField(child.field);
              $$renderer3.push(`<div class="rule-row flex items-center gap-1.5 md:gap-2"><div class="shrink-0">`);
              DropdownCombobox($$renderer3, {
                value: child.field,
                options: fields.map((f2) => ({
                  value: f2.id,
                  label: f2.label,
                  shortLabel: f2.shortLabel
                })),
                placeholder: "Select field",
                minWidth: keyMinWidth,
                width: keyWidthClass,
                fullWidth: true,
                limit: 6,
                responsiveButton: true,
                responsiveDropdown: true,
                fixed: true
              });
              $$renderer3.push(`<!----></div> `);
              if (field) {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<div class="shrink-0">`);
                DropdownSelect($$renderer3, {
                  value: child.operator,
                  options: isDynamicString ? dynamicStringOperators : field.operators.map((op) => ({
                    value: op.id,
                    label: op.label,
                    shortLabel: op.shortLabel
                  })),
                  minWidth: "7rem",
                  width: operatorWidthClass,
                  fullWidth: true,
                  responsiveButton: true,
                  responsiveDropdown: true,
                  fixed: true
                });
                $$renderer3.push(`<!----></div> `);
                if (ruleNeedsValue(child)) {
                  $$renderer3.push("<!--[0-->");
                  $$renderer3.push(`<div class="shrink-0">`);
                  if (field?.valueType === "boolean" || field?.valueType === "select") {
                    $$renderer3.push("<!--[0-->");
                    if (field.values) {
                      $$renderer3.push("<!--[0-->");
                      DropdownSelect($$renderer3, {
                        value: String(child.value),
                        options: field.values.map((v3) => ({
                          value: String(v3.value),
                          label: v3.label
                        })),
                        minWidth: valueMinWidth,
                        width: valueWidthClass,
                        fullWidth: true,
                        responsiveButton: true,
                        responsiveDropdown: true,
                        fixed: true
                      });
                    } else $$renderer3.push("<!--[-1-->");
                    $$renderer3.push(`<!--]-->`);
                  } else if (field?.valueType === "text") {
                    $$renderer3.push("<!--[1-->");
                    if (isDynamicField) {
                      $$renderer3.push("<!--[0-->");
                      $$renderer3.push(`<!---->`);
                      DropdownCombobox($$renderer3, {
                        value: String(child.value ?? ""),
                        options: getDynamicOptions(field.id, child.value, dynamicFilterOptions),
                        placeholder: dynamicFilterOptionsLoading ? "Loading values..." : "Select value",
                        minWidth: valueMinWidth,
                        width: valueWidthClass,
                        fullWidth: true,
                        limit: 6,
                        responsiveButton: true,
                        responsiveDropdown: true,
                        fixed: true
                      });
                      $$renderer3.push(`<!---->`);
                    } else {
                      $$renderer3.push("<!--[-1-->");
                      $$renderer3.push(`<div${attr_class(clsx(valueWidthClass))}>`);
                      FormInput($$renderer3, {
                        label: "Value",
                        hideLabel: true,
                        name: `filter-value-${stringify(childIndex)}`,
                        value: child.value,
                        responsive: true,
                        autoWidth: true
                      });
                      $$renderer3.push(`<!----></div>`);
                    }
                    $$renderer3.push(`<!--]-->`);
                  } else if (field?.valueType === "number") {
                    $$renderer3.push("<!--[2-->");
                    $$renderer3.push(`<div${attr_class(clsx(valueWidthClass))}>`);
                    NumberInput($$renderer3, {
                      name: `value-${stringify(childIndex)}`,
                      value: child.value,
                      font: "mono",
                      responsive: true,
                      autoWidth: true
                    });
                    $$renderer3.push(`<!----></div>`);
                  } else if (field?.valueType === "date") {
                    $$renderer3.push("<!--[3-->");
                    if (child.operator === "in_last" || child.operator === "not_in_last") {
                      $$renderer3.push("<!--[0-->");
                      $$renderer3.push(`<div class="w-fit md:w-72 flex items-center gap-2"><div class="min-w-0 flex-1">`);
                      NumberInput($$renderer3, {
                        name: `value-${stringify(childIndex)}`,
                        value: child.value,
                        min: 1,
                        font: "mono",
                        responsive: true,
                        autoWidth: true
                      });
                      $$renderer3.push(`<!----></div> <span class="text-xs text-neutral-500 dark:text-neutral-400">days</span></div>`);
                    } else {
                      $$renderer3.push("<!--[-1-->");
                      $$renderer3.push(`<div${attr_class(clsx(valueWidthClass))}>`);
                      DateInput($$renderer3, {
                        label: "Date",
                        hideLabel: true,
                        name: `value-${stringify(childIndex)}`,
                        value: child.value,
                        fullWidth: true,
                        responsive: true,
                        shortLabels: true,
                        fixed: true
                      });
                      $$renderer3.push(`<!----></div>`);
                    }
                    $$renderer3.push(`<!--]-->`);
                  } else $$renderer3.push("<!--[-1-->");
                  $$renderer3.push(`<!--]--></div>`);
                } else $$renderer3.push("<!--[-1-->");
                $$renderer3.push(`<!--]-->`);
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--> <div class="shrink-0">`);
              Button($$renderer3, {
                icon: X2,
                variant: "ghost",
                size: "xs"
              });
              $$renderer3.push(`<!----></div></div>`);
            } else if (isGroup(child)) {
              $$renderer3.push("<!--[1-->");
              $$renderer3.push(`<div class="ml-4">`);
              FilterGroup($$renderer3, {
                group: child,
                appType,
                dynamicFilterOptions,
                dynamicFilterOptionsLoading,
                dynamicFilterOptionsVersion,
                depth: depth + 1,
                onRemove: () => removeChild(childIndex)
              });
              $$renderer3.push(`<!----></div>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]-->`);
          }
          $$renderer3.push(`<!--]--></div></div>`);
        }
        $$renderer3.push(`<!--]--> <div class="mt-3 flex items-center gap-2">`);
        Button($$renderer3, {
          text: "Add Rule",
          icon: Plus,
          responsive: true
        });
        $$renderer3.push(`<!----> `);
        Button($$renderer3, {
          text: "Add Group",
          icon: Folder_plus,
          responsive: true
        });
        $$renderer3.push(`<!----></div>`);
      },
      $$slots: { default: true }
    });
    bind_props($$props, {
      group,
      appType,
      dynamicFilterOptions,
      dynamicFilterOptionsLoading,
      dynamicFilterOptionsVersion,
      onRemove,
      depth
    });
  });
}
function FilterPreviewModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let filteredItems, previewKey;
    let open = fallback($$props["open"], false);
    let filter = fallback($$props["filter"], null);
    let instanceId = fallback($$props["instanceId"], void 0);
    createEventDispatcher();
    let searchStore = createSearchStore();
    let debouncedQuery = searchStore.debouncedQuery;
    let loading = false;
    let loadingText = "Loading library data...";
    let error2 = null;
    let data = null;
    let statusFilters = /* @__PURE__ */ new Set();
    let expandedIds = /* @__PURE__ */ new Set();
    let requestId = 0;
    let stepTimer;
    let activePreviewKey = "";
    const columns = [
      {
        key: "title",
        header: "Title",
        sortable: true,
        width: "w-64"
      },
      {
        key: "status",
        header: "Status",
        width: "w-32"
      },
      {
        key: "reason",
        header: "Reason"
      }
    ];
    const statusMeta = {
      selected: {
        label: "Will search next",
        variant: "success"
      },
      selectable: {
        label: "Eligible later",
        variant: "info"
      },
      cooldown: {
        label: "Already searched",
        variant: "warning"
      },
      filtered_out: {
        label: "Doesn't match",
        variant: "secondary"
      }
    };
    const statusOptions = [
      {
        value: "selected",
        label: "Will search next"
      },
      {
        value: "selectable",
        label: "Eligible later"
      },
      {
        value: "cooldown",
        label: "Already searched"
      },
      {
        value: "filtered_out",
        label: "Doesn't match"
      }
    ];
    const skeletonRows = Array.from({ length: 8 });
    function clearStepTimer() {
      if (stepTimer) {
        clearTimeout(stepTimer);
        stepTimer = void 0;
      }
    }
    function resetFilters() {
      searchStore.clear();
      statusFilters = /* @__PURE__ */ new Set();
      expandedIds = /* @__PURE__ */ new Set();
    }
    function filterItems(items, query, statuses) {
      let result = items;
      const queryLower = query.trim().toLowerCase();
      if (queryLower) result = result.filter((item) => item.title.toLowerCase().includes(queryLower) || item.reason.toLowerCase().includes(queryLower) || statusMeta[item.status].label.toLowerCase().includes(queryLower));
      if (statuses.size > 0) result = result.filter((item) => statuses.has(item.status));
      return result;
    }
    async function loadPreview(targetFilter, targetInstanceId) {
      const currentRequestId = requestId + 1;
      requestId = currentRequestId;
      loading = true;
      loadingText = "Loading library data...";
      error2 = null;
      data = null;
      resetFilters();
      clearStepTimer();
      stepTimer = setTimeout(() => {
        if (currentRequestId === requestId) loadingText = "Evaluating filter...";
      }, 700);
      try {
        const response = await fetch(`/arr/${targetInstanceId}/upgrades/preview`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ filter: structuredClone(targetFilter) })
        });
        const result = await response.json().catch(() => ({}));
        if (currentRequestId !== requestId) return;
        if (!response.ok) throw new Error(result.error ?? "Failed to preview filter");
        data = result;
      } catch (err) {
        if (currentRequestId === requestId) error2 = err instanceof Error ? err.message : "Failed to preview filter";
      } finally {
        if (currentRequestId === requestId) {
          clearStepTimer();
          loading = false;
        }
      }
    }
    function formatSize2(sizeGb) {
      if (!sizeGb) return "None";
      if (sizeGb >= 1) return `${sizeGb.toFixed(1)} GB`;
      return `${Math.round(sizeGb * 1024)} MB`;
    }
    function formatDateValue(value2) {
      if (!value2) return "Unknown";
      const result = formatDate(value2, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone));
      return result === "-" ? "Unknown" : result;
    }
    function formatScore(score) {
      return score.toLocaleString();
    }
    function formatStatus(status) {
      if (!status) return "Unknown";
      return status.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/_/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
    }
    function statusVariant(status) {
      switch (status) {
        case "released":
        case "continuing":
          return "success";
        case "inCinemas":
        case "upcoming":
          return "info";
        default:
          return "secondary";
      }
    }
    function formatCount(value2) {
      return value2.toLocaleString();
    }
    function formatItemCount(count, singular, plural) {
      return `${formatCount(count)} ${count === 1 ? singular : plural}`;
    }
    function getSelectorLabel(selectorId) {
      return selectors.find((selector) => selector.id === selectorId)?.label ?? selectorId;
    }
    function getEligibleLaterCount(result) {
      return Math.max(0, result.selectableCount - result.selectedCount);
    }
    function getDoesNotMatchCount(result) {
      return Math.max(0, result.totalItems - result.matchedCount);
    }
    onDestroy(() => {
      clearStepTimer();
    });
    $: filteredItems = filterItems(data?.items ?? [], store_get($$store_subs ??= {}, "$debouncedQuery", debouncedQuery), statusFilters);
    $: previewKey = open && filter && instanceId ? `${instanceId}:${filter.id}` : "";
    $: if (previewKey && previewKey !== activePreviewKey && filter && instanceId) {
      activePreviewKey = previewKey;
      loadPreview(filter, instanceId);
    }
    $: if (!open && activePreviewKey) {
      activePreviewKey = "";
      requestId += 1;
      clearStepTimer();
      loading = false;
    }
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      Modal($$renderer3, {
        open,
        header: filter ? `Preview: ${filter.name}` : "Preview Filter",
        size: "2xl",
        height: "xl",
        $$slots: {
          body: ($$renderer4) => {
            if (loading) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="space-y-4"><div class="flex items-center gap-2 text-sm text-neutral-600 dark:text-neutral-300">`);
              Loader_circle($$renderer4, {
                size: 16,
                class: "animate-spin text-blue-600 dark:text-blue-400"
              });
              $$renderer4.push(`<!----> <span>${escape_html(loadingText)}</span></div> <div class="overflow-hidden rounded-lg border border-neutral-300 dark:border-neutral-700/60"><!--[-->`);
              const each_array = ensure_array_like(skeletonRows);
              for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                each_array[$$index];
                $$renderer4.push(`<div class="flex gap-4 border-b border-neutral-200 p-4 last:border-0 dark:border-neutral-800"><div class="h-4 w-2/5 animate-pulse rounded bg-neutral-200 dark:bg-neutral-800"></div> <div class="h-4 w-24 animate-pulse rounded bg-neutral-200 dark:bg-neutral-800"></div> <div class="h-4 w-28 animate-pulse rounded bg-neutral-200 dark:bg-neutral-800"></div> <div class="h-4 w-16 animate-pulse rounded bg-neutral-200 dark:bg-neutral-800"></div></div>`);
              }
              $$renderer4.push(`<!--]--></div></div>`);
            } else if (error2) {
              $$renderer4.push("<!--[1-->");
              $$renderer4.push(`<div class="rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-900/50 dark:bg-red-950/30 dark:text-red-300">${escape_html(error2)}</div>`);
            } else if (data) {
              $$renderer4.push("<!--[2-->");
              $$renderer4.push(`<div class="space-y-4"><div class="space-y-3 rounded-lg border border-neutral-300 bg-white p-4 dark:border-neutral-700/60 dark:bg-neutral-900"><div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Library</span> <span class="text-sm text-neutral-900 dark:text-neutral-100">${escape_html(formatItemCount(data.totalItems, "item", "items"))} checked</span></div> <div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Filter</span> <span class="text-sm text-neutral-900 dark:text-neutral-100">"${escape_html(data.filterName)}" <span class="mx-1 text-neutral-400">\u2192</span> <span class="font-mono font-medium">${escape_html(formatCount(data.matchedCount))}</span> matched <span class="mx-1 text-neutral-400">\u2192</span> <span class="font-mono font-medium">${escape_html(formatCount(data.selectableCount))}</span> after cooldown</span></div> <div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Selection</span> <span class="text-sm text-neutral-900 dark:text-neutral-100">${escape_html(getSelectorLabel(data.selector))} <span class="font-mono font-medium">${escape_html(formatCount(data.selectedCount))}</span> of <span class="font-mono">${escape_html(formatCount(data.requestedCount))}</span> will search next `);
              if (getEligibleLaterCount(data) > 0) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<span class="mx-1 text-neutral-400">\u2192</span> ${escape_html(formatItemCount(getEligibleLaterCount(data), "item", "items"))}
								eligible later`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></span></div> <div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Cooldown</span> <span class="text-sm text-neutral-900 dark:text-neutral-100">${escape_html(formatItemCount(data.cooldownCount, "item", "items"))} already searched,
							${escape_html(formatItemCount(getDoesNotMatchCount(data), "item does", "items do"))}
							not match</span></div></div> `);
              ActionsBar($$renderer4, {
                className: "md:justify-start",
                children: ($$renderer5) => {
                  SearchAction($$renderer5, {
                    searchStore,
                    placeholder: "Search items...",
                    responsive: true
                  });
                  $$renderer5.push(`<!----> `);
                  ActionButton($$renderer5, {
                    icon: Circle_dot,
                    hasDropdown: true,
                    square: true,
                    title: "Filter by status",
                    $$slots: { dropdown: ($$renderer6) => {
                      Dropdown($$renderer6, {
                        position: "right",
                        mobilePosition: "middle",
                        minWidth: "12rem",
                        children: ($$renderer7) => {
                          DropdownHeader($$renderer7, { label: "Status" });
                          $$renderer7.push(`<!----> `);
                          DropdownItem($$renderer7, {
                            label: "All statuses",
                            selected: statusFilters.size === 0
                          });
                          $$renderer7.push(`<!----> <!--[-->`);
                          const each_array_1 = ensure_array_like(statusOptions);
                          for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                            let option = each_array_1[$$index_1];
                            DropdownItem($$renderer7, {
                              label: option.label,
                              selected: statusFilters.has(option.value)
                            });
                          }
                          $$renderer7.push(`<!--]-->`);
                        },
                        $$slots: { default: true }
                      });
                    } }
                  });
                  $$renderer5.push(`<!---->`);
                },
                $$slots: { default: true }
              });
              $$renderer4.push(`<!----> `);
              ExpandableTable($$renderer4, {
                columns,
                data: filteredItems,
                getRowId: (row) => row.id,
                compact: true,
                responsive: true,
                flushExpanded: true,
                fixedLayout: true,
                pageSize: 100,
                emptyMessage: "No preview items match.",
                get expandedRows() {
                  return expandedIds;
                },
                set expandedRows($$value) {
                  expandedIds = $$value;
                  $$settled = false;
                },
                $$slots: {
                  cell: ($$renderer5, { row, column }) => {
                    if (column.key === "title") {
                      $$renderer5.push("<!--[0-->");
                      $$renderer5.push(`<div class="min-w-0"><div class="truncate font-medium">${escape_html(row.title)}</div> <div class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(row.year)}</div></div>`);
                    } else if (column.key === "status") {
                      $$renderer5.push("<!--[1-->");
                      Label($$renderer5, {
                        variant: statusMeta[row.status].variant,
                        size: "sm",
                        rounded: "md",
                        children: ($$renderer6) => {
                          $$renderer6.push(`<!---->${escape_html(statusMeta[row.status].label)}`);
                        },
                        $$slots: { default: true }
                      });
                    } else if (column.key === "reason") {
                      $$renderer5.push("<!--[2-->");
                      $$renderer5.push(`<span class="break-words text-neutral-600 dark:text-neutral-300">${escape_html(row.reason)}</span>`);
                    } else $$renderer5.push("<!--[-1-->");
                    $$renderer5.push(`<!--]-->`);
                  },
                  expanded: ($$renderer5, { row }) => {
                    $$renderer5.push(`<div class="min-w-0 overflow-hidden p-4"><div class="divide-y divide-neutral-200 dark:divide-neutral-800"><div class="grid grid-cols-1 gap-1 py-3 md:grid-cols-[10rem_minmax(0,1fr)] md:items-center"><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">File on Disk</div> <div class="min-w-0">`);
                    if (row.details.fileName) {
                      $$renderer5.push("<!--[0-->");
                      $$renderer5.push(`<code class="font-mono text-xs break-all text-neutral-600 dark:text-neutral-400">${escape_html(row.details.fileName)}</code>`);
                    } else {
                      $$renderer5.push("<!--[-1-->");
                      $$renderer5.push(`<div class="text-xs text-neutral-500 dark:text-neutral-400">No file</div>`);
                    }
                    $$renderer5.push(`<!--]--></div></div> <div class="grid grid-cols-1 gap-2 py-3 md:grid-cols-[10rem_minmax(0,1fr)] md:items-center"><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Custom Formats</div> <div class="min-w-0">`);
                    if (row.details.customFormats.length > 0) {
                      $$renderer5.push("<!--[0-->");
                      $$renderer5.push(`<div class="flex min-w-0 flex-wrap items-center gap-2"><!--[-->`);
                      const each_array_2 = ensure_array_like([...row.details.customFormats].sort((a2, b3) => b3.score - a2.score));
                      for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
                        let item = each_array_2[$$index_2];
                        CustomFormatBadge($$renderer5, {
                          name: item.name,
                          score: item.score
                        });
                      }
                      $$renderer5.push(`<!--]--></div>`);
                    } else {
                      $$renderer5.push("<!--[-1-->");
                      $$renderer5.push(`<div class="text-xs text-neutral-500 dark:text-neutral-400">No custom formats matched</div>`);
                    }
                    $$renderer5.push(`<!--]--></div></div> <div class="grid grid-cols-1 gap-1 py-3 md:grid-cols-[10rem_minmax(0,1fr)] md:items-center"><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Profile</div> <div class="min-w-0 text-sm break-words text-neutral-900 dark:text-neutral-100">${escape_html(row.details.qualityProfile)}</div></div> <div class="grid grid-cols-1 gap-1 py-3 md:grid-cols-[10rem_minmax(0,1fr)] md:items-center"><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Score</div> <div class="font-mono text-sm text-neutral-900 dark:text-neutral-100">${escape_html(formatScore(row.details.score))}</div></div> <div class="grid grid-cols-1 gap-1 py-3 md:grid-cols-[10rem_minmax(0,1fr)] md:items-center"><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Monitored</div> <div>`);
                    Label($$renderer5, {
                      variant: row.details.monitored ? "success" : "secondary",
                      size: "sm",
                      rounded: "md",
                      children: ($$renderer6) => {
                        $$renderer6.push(`<!---->${escape_html(row.details.monitored ? "Yes" : "No")}`);
                      },
                      $$slots: { default: true }
                    });
                    $$renderer5.push(`<!----></div></div> <div class="grid grid-cols-1 gap-1 py-3 md:grid-cols-[10rem_minmax(0,1fr)] md:items-center"><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Status</div> <div>`);
                    Label($$renderer5, {
                      variant: statusVariant(row.details.status),
                      size: "sm",
                      rounded: "md",
                      children: ($$renderer6) => {
                        $$renderer6.push(`<!---->${escape_html(formatStatus(row.details.status))}`);
                      },
                      $$slots: { default: true }
                    });
                    $$renderer5.push(`<!----></div></div> <div class="grid grid-cols-1 gap-1 py-3 md:grid-cols-[10rem_minmax(0,1fr)] md:items-center"><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Size</div> <div class="font-mono text-sm text-neutral-900 dark:text-neutral-100">${escape_html(formatSize2(row.details.sizeOnDisk))}</div></div> <div class="grid grid-cols-1 gap-1 py-3 md:grid-cols-[10rem_minmax(0,1fr)] md:items-center"><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Added</div> <div class="font-mono text-sm text-neutral-900 dark:text-neutral-100">${escape_html(formatDateValue(row.details.dateAdded))}</div></div> <div class="grid grid-cols-1 gap-1 py-3 md:grid-cols-[10rem_minmax(0,1fr)] md:items-center"><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Release Group</div> <div class="min-w-0 font-mono text-sm break-words text-neutral-900 dark:text-neutral-100">${escape_html(row.details.releaseGroup || "None")}</div></div> <div class="grid grid-cols-1 gap-2 py-3 md:grid-cols-[10rem_minmax(0,1fr)] md:items-center"><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Tags</div> <div class="min-w-0">`);
                    if (row.details.tags.length > 0) {
                      $$renderer5.push("<!--[0-->");
                      $$renderer5.push(`<div class="flex min-w-0 flex-wrap items-center gap-2"><!--[-->`);
                      const each_array_3 = ensure_array_like(row.details.tags);
                      for (let $$index_3 = 0, $$length = each_array_3.length; $$index_3 < $$length; $$index_3++) {
                        let tag2 = each_array_3[$$index_3];
                        Label($$renderer5, {
                          variant: "secondary",
                          size: "sm",
                          rounded: "md",
                          children: ($$renderer6) => {
                            $$renderer6.push(`<!---->${escape_html(tag2)}`);
                          },
                          $$slots: { default: true }
                        });
                      }
                      $$renderer5.push(`<!--]--></div>`);
                    } else {
                      $$renderer5.push("<!--[-1-->");
                      $$renderer5.push(`<div class="text-xs text-neutral-500 dark:text-neutral-400">No tags</div>`);
                    }
                    $$renderer5.push(`<!--]--></div></div></div></div>`);
                  }
                }
              });
              $$renderer4.push(`<!----></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          footer: ($$renderer4) => {
            $$renderer4.push(`<div class="flex w-full justify-end">`);
            Button($$renderer4, { text: "Close" });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      open,
      filter,
      instanceId
    });
  });
}
function CodeInput($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let theme, variant, tokens, displayTokens, placeholderClass, stateClass;
    let label = $$props["label"];
    let description = fallback($$props["description"], "");
    let placeholder = fallback($$props["placeholder"], "");
    let value2 = fallback($$props["value"], "");
    let name = fallback($$props["name"], "");
    let rows = fallback($$props["rows"], 10);
    let language = fallback($$props["language"], "json");
    let required = fallback($$props["required"], false);
    let disabled = fallback($$props["disabled"], false);
    let readonly = fallback($$props["readonly"], false);
    let inputElement = fallback($$props["inputElement"], null);
    createEventDispatcher();
    let themeName = "Default";
    function tokenColor(type, v3) {
      return v3[type] ?? void 0;
    }
    $: theme = getTheme(themeName);
    $: variant = store_get($$store_subs ??= {}, "$themeStore", themeStore) === "dark" ? theme.dark : theme.light;
    $: tokens = tokenize(value2, language);
    $: displayTokens = tokens.length > 0 ? tokens : [{
      type: "text",
      text: placeholder
    }];
    $: placeholderClass = value2 ? "" : "opacity-45";
    $: stateClass = readonly || disabled ? "cursor-not-allowed opacity-70" : "focus:border-neutral-300 dark:focus:border-neutral-600";
    $$renderer2.push(`<div class="space-y-2"><label${attr("for", name)} class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(label)}`);
    if (required) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span class="text-red-500">*</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></label> `);
    if (description) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<p class="text-xs text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div class="relative overflow-hidden rounded-xl border border-neutral-300 dark:border-neutral-700/60"><pre aria-hidden="true" class="pointer-events-none absolute inset-0 overflow-auto p-3 text-sm leading-5 whitespace-pre-wrap svelte-vzgiui"${attr_style(`background-color: ${stringify(variant.bg)}; color: ${stringify(variant.text)}; min-height: ${stringify(rows * 1.25 + 1.5)}rem;`)}><code${attr_class(clsx(placeholderClass), "svelte-vzgiui")}><!--[-->`);
    const each_array = ensure_array_like(displayTokens);
    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
      let t2 = each_array[$$index];
      $$renderer2.push(`<span${attr_style(tokenColor(t2.type, variant) ? `color: ${tokenColor(t2.type, variant)}` : "")} class="svelte-vzgiui">${escape_html(t2.text)}</span>`);
    }
    $$renderer2.push(`<!--]-->${escape_html(value2.endsWith("\n") ? " " : "")}</code></pre> <textarea${attr("id", name)}${attr("name", name)}${attr("required", required, true)}${attr("disabled", disabled, true)}${attr("readonly", readonly, true)}${attr("rows", rows)} spellcheck="false" autocomplete="off" autocapitalize="off"${attr_class(`relative block w-full resize-y overflow-auto border-0 bg-transparent p-3 text-sm leading-5 whitespace-pre-wrap text-transparent caret-neutral-900 outline-none selection:bg-accent-500/30 dark:caret-neutral-50 ${stringify(stateClass)}`, "svelte-vzgiui")}${attr_style(`min-height: ${stringify(rows * 1.25 + 1.5)}rem;`)}>`);
    const $$body = escape_html(value2);
    if ($$body) $$renderer2.push(`${$$body}`);
    $$renderer2.push(`</textarea></div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      label,
      description,
      placeholder,
      value: value2,
      name,
      rows,
      language,
      required,
      disabled,
      readonly,
      inputElement
    });
  });
}
function PasteModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let confirmDisabled;
    let open = fallback($$props["open"], false);
    let header = fallback($$props["header"], "Paste");
    let label = fallback($$props["label"], "Paste content");
    let description = fallback($$props["description"], "");
    let placeholder = fallback($$props["placeholder"], "");
    let confirmText = fallback($$props["confirmText"], "Paste");
    let cancelText = fallback($$props["cancelText"], "Cancel");
    let rows = fallback($$props["rows"], 10);
    let language = fallback($$props["language"], "json");
    createEventDispatcher();
    let content = "";
    let wasOpen = false;
    let inputElement = null;
    async function focusInput() {
      await tick();
      inputElement?.focus();
    }
    $: {
      if (open && !wasOpen) {
        content = "";
        focusInput();
      }
      wasOpen = open;
    }
    $: confirmDisabled = content.trim() === "";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      Modal($$renderer3, {
        open,
        header,
        confirmText,
        cancelText,
        confirmDisabled,
        size: "lg",
        $$slots: { body: ($$renderer4) => {
          $$renderer4.push(`<div slot="body">`);
          CodeInput($$renderer4, {
            label,
            description,
            placeholder,
            rows,
            language,
            name: "paste-modal-content",
            get value() {
              return content;
            },
            set value($$value) {
              content = $$value;
              $$settled = false;
            },
            get inputElement() {
              return inputElement;
            },
            set inputElement($$value) {
              inputElement = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----></div>`);
        } }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      open,
      header,
      label,
      description,
      placeholder,
      confirmText,
      cancelText,
      rows,
      language
    });
  });
}
function FilterSettings($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let resolvedAppType, countMax, filteredFilters;
    let searchStore = createSearchStore();
    let debouncedQuery = searchStore.debouncedQuery;
    let filters = fallback($$props["filters"], () => [], true);
    let appType = fallback($$props["appType"], "radarr");
    let runsPerHour = fallback($$props["runsPerHour"], 1);
    let dynamicFilterOptions = fallback($$props["dynamicFilterOptions"], () => ({}), true);
    let dynamicFilterOptionsLoading = fallback($$props["dynamicFilterOptionsLoading"], false);
    let dynamicFilterOptionsVersion = fallback($$props["dynamicFilterOptionsVersion"], 0);
    let onFiltersChange = fallback($$props["onFiltersChange"], void 0);
    const selectorShortDescriptions = {
      random: "Any order",
      oldest: "Oldest first",
      newest: "Newest first",
      lowest_score: "Lowest score",
      size_desc: "Largest first",
      size_asc: "Smallest first",
      most_popular: "Most popular",
      least_popular: "Least popular",
      alphabetical_asc: "A-Z",
      alphabetical_desc: "Z-A"
    };
    function notifyChange() {
      onFiltersChange?.(filters);
    }
    function filterByName(items, query) {
      if (!query) return items;
      const queryLower = query.toLowerCase();
      return items.filter((item) => item.name.toLowerCase().includes(queryLower));
    }
    let expandedIds = /* @__PURE__ */ new Set();
    const columns = [{
      key: "name",
      header: "Name",
      sortable: true
    }];
    let editingId = null;
    let editingName = "";
    let deleteModalOpen = false;
    let pasteModalOpen = false;
    let previewModalOpen = false;
    let previewFilter = null;
    function getSharedTagFilters(currentFilter) {
      const currentTag = resolveTagLabel(currentFilter);
      return filters.filter((f2) => f2.id !== currentFilter.id && resolveTagLabel(f2) === currentTag).map((f2) => f2.name);
    }
    $: if (store_get($$store_subs ??= {}, "$page", page)?.params?.id) {
      searchStore = getPersistentSearchStore(`upgradeFiltersSearch:${store_get($$store_subs ??= {}, "$page", page).params.id}`);
      debouncedQuery = searchStore.debouncedQuery;
    }
    $: resolvedAppType = appType === "radarr" || appType === "sonarr" ? appType : "radarr";
    $: countMax = calculateMaxCount(resolvedAppType, runsPerHour);
    $: {
      let clamped = false;
      for (const f2 of filters) if (f2.count > countMax) {
        f2.count = countMax;
        clamped = true;
      }
      if (clamped) {
        filters = filters;
        notifyChange();
      }
    }
    $: filteredFilters = filterByName(filters, store_get($$store_subs ??= {}, "$debouncedQuery", debouncedQuery));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="-mx-4 bg-neutral-50 px-4 pt-2 pb-2 md:-mx-8 md:px-8 dark:bg-neutral-900"><div class="mb-4">`);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore,
            placeholder: "Search filters..."
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Plus,
            title: "Add filter",
            onboarding: "upgrades-add-filter",
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5) => {
              Dropdown($$renderer5, {
                position: "right",
                minWidth: "12rem",
                children: ($$renderer6) => {
                  DropdownHeader($$renderer6, { label: "New filter" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, {
                    icon: File_text,
                    label: "Default"
                  });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, {
                    icon: File_braces,
                    label: "Import"
                  });
                  $$renderer6.push(`<!---->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----></div> `);
      ExpandableTable($$renderer3, {
        columns,
        data: filteredFilters,
        getRowId: (row) => row.id,
        chevronPosition: "right",
        flushExpanded: true,
        emptyMessage: "No filters configured. Add a filter to start.",
        responsive: true,
        get expandedRows() {
          return expandedIds;
        },
        set expandedRows($$value) {
          expandedIds = $$value;
          $$settled = false;
        },
        $$slots: {
          cell: ($$renderer4, { row, column }) => {
            if (column.key === "name") {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="flex flex-col gap-2"><div class="flex items-center gap-1.5">`);
              if (editingId === row.id) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="w-48">`);
                FormInput($$renderer4, {
                  label: "Filter name",
                  hideLabel: true,
                  name: `filter-name-${stringify(row.id)}`,
                  get value() {
                    return editingName;
                  },
                  set value($$value) {
                    editingName = $$value;
                    $$settled = false;
                  }
                });
                $$renderer4.push(`<!----></div>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<span${attr_class(clsx(row.enabled ? "text-neutral-900 dark:text-neutral-100" : "text-neutral-400 dark:text-neutral-500"))}>${escape_html(row.name)}</span> <div>`);
                Button($$renderer4, {
                  icon: Pencil,
                  size: "xs"
                });
                $$renderer4.push(`<!----></div> `);
                if (!row.enabled) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<span class="rounded bg-neutral-200 px-1.5 py-0.5 text-xs text-neutral-500 dark:bg-neutral-700 dark:text-neutral-400">Disabled</span>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]-->`);
              }
              $$renderer4.push(`<!--]--></div> <div class="flex flex-wrap items-center gap-1 md:hidden">`);
              Button($$renderer4, {
                icon: Eye,
                iconColor: "text-blue-600 dark:text-blue-400",
                tooltip: "Preview"
              });
              $$renderer4.push(`<!----> `);
              Button($$renderer4, {
                icon: Power,
                iconColor: row.enabled ? "text-green-600 dark:text-green-400" : "text-neutral-400 dark:text-neutral-500",
                tooltip: row.enabled ? "Disable" : "Enable"
              });
              $$renderer4.push(`<!----> `);
              Button($$renderer4, {
                icon: Clipboard_copy,
                iconColor: "text-amber-600 dark:text-amber-400",
                tooltip: "Copy"
              });
              $$renderer4.push(`<!----> `);
              Button($$renderer4, {
                icon: Copy,
                iconColor: "text-violet-600 dark:text-violet-400",
                tooltip: "Duplicate"
              });
              $$renderer4.push(`<!----> `);
              Button($$renderer4, {
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                tooltip: "Delete"
              });
              $$renderer4.push(`<!----></div></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          actions: ($$renderer4, { row }) => {
            $$renderer4.push(`<div class="hidden items-center gap-1 md:flex">`);
            Button($$renderer4, {
              icon: Eye,
              iconColor: "text-blue-600 dark:text-blue-400",
              tooltip: "Preview"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              icon: Power,
              iconColor: row.enabled ? "text-green-600 dark:text-green-400" : "text-neutral-400 dark:text-neutral-500",
              tooltip: row.enabled ? "Disable" : "Enable"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              icon: Clipboard_copy,
              iconColor: "text-amber-600 dark:text-amber-400",
              tooltip: "Copy"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              icon: Copy,
              iconColor: "text-violet-600 dark:text-violet-400",
              tooltip: "Duplicate"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              icon: Trash_2,
              iconColor: "text-red-600 dark:text-red-400",
              tooltip: "Delete"
            });
            $$renderer4.push(`<!----></div>`);
          },
          expanded: ($$renderer4, { row }) => {
            $$renderer4.push(`<div class="space-y-4 p-3 md:p-6"><div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-5"><div data-onboarding="upgrades-cutoff"><label${attr("for", `cutoff-${stringify(row.id)}`)} class="block text-sm font-medium text-neutral-600 dark:text-neutral-400">Cutoff %</label> <div class="mt-1">`);
            NumberInput($$renderer4, {
              name: `cutoff-${stringify(row.id)}`,
              min: 0,
              max: 100,
              font: "mono",
              responsive: true,
              get value() {
                return row.cutoff;
              },
              set value($$value) {
                row.cutoff = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div> <p class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">Score threshold for "cutoff met"</p></div> <div data-onboarding="upgrades-method"><label${attr("for", `selector-${stringify(row.id)}`)} class="mb-1 block text-sm font-medium text-neutral-600 dark:text-neutral-400">Method</label> <div class="mt-1">`);
            DropdownSelect($$renderer4, {
              value: row.selector,
              options: selectors.map((s3) => ({
                value: s3.id,
                label: s3.label
              })),
              minWidth: "14rem",
              fullWidth: true,
              responsiveButton: true,
              responsiveDropdown: true,
              fixed: true
            });
            $$renderer4.push(`<!----></div> <p class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">${escape_html(selectorShortDescriptions[row.selector] ?? "Selection order")}</p></div> <div data-onboarding="upgrades-count"><label${attr("for", `count-${stringify(row.id)}`)} class="block text-sm font-medium text-neutral-600 dark:text-neutral-400">Count</label> <div class="mt-1">`);
            NumberInput($$renderer4, {
              name: `count-${stringify(row.id)}`,
              min: 1,
              max: countMax,
              font: "mono",
              responsive: true,
              get value() {
                return row.count;
              },
              set value($$value) {
                row.count = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div> <p class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">Items per run (max ${escape_html(countMax)} at this schedule)</p></div> <div data-onboarding="upgrades-cooldown" class="lg:col-span-2"><label${attr("for", `tag-${stringify(row.id)}`)} class="block text-sm font-medium text-neutral-600 dark:text-neutral-400">Cooldown Tag</label> <div class="mt-1">`);
            FormInput($$renderer4, {
              label: "Cooldown tag",
              hideLabel: true,
              lowercase: true,
              name: `tag-${stringify(row.id)}`,
              placeholder: resolveTagLabel(row),
              responsive: true,
              get value() {
                return row.tag;
              },
              set value($$value) {
                row.tag = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div> `);
            if (getSharedTagFilters(row).length > 0) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<p class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">Shared with: ${escape_html(getSharedTagFilters(row).join(", "))}</p>`);
            } else {
              $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<p class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">Tag applied in your arr instance for cooldown tracking. Avoid reusing tags you use
								elsewhere.</p>`);
            }
            $$renderer4.push(`<!--]--></div></div> <hr class="-mx-3 border-t border-neutral-200 md:-mx-6 dark:border-neutral-800"/> <div data-onboarding="upgrades-filter-rules">`);
            FilterGroup($$renderer4, {
              group: row.group,
              appType: resolvedAppType,
              dynamicFilterOptions,
              dynamicFilterOptionsLoading,
              dynamicFilterOptionsVersion
            });
            $$renderer4.push(`<!----></div></div>`);
          }
        }
      });
      $$renderer3.push(`<!----></div> `);
      Modal($$renderer3, {
        header: "Delete Filter",
        bodyMessage: `Are you sure you want to delete "${stringify(void 0)}"? This action cannot be undone.`,
        confirmText: "Delete",
        confirmDanger: true,
        get open() {
          return deleteModalOpen;
        },
        set open($$value) {
          deleteModalOpen = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      FilterPreviewModal($$renderer3, {
        open: previewModalOpen,
        filter: previewFilter,
        instanceId: store_get($$store_subs ??= {}, "$page", page).params.id
      });
      $$renderer3.push(`<!----> `);
      PasteModal($$renderer3, {
        open: pasteModalOpen,
        header: "Import Filter",
        label: "Filter JSON",
        description: "Paste copied filter JSON to create a new filter.",
        placeholder: '{\n  "group": { ... }\n}',
        confirmText: "Import"
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      filters,
      appType,
      runsPerHour,
      dynamicFilterOptions,
      dynamicFilterOptionsLoading,
      dynamicFilterOptionsVersion,
      onFiltersChange
    });
  });
}
function RunHistory($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let uniqueFilters, filteredRuns, totalPages, paginatedRuns;
    let searchStore = createSearchStore();
    let debouncedQuery = searchStore.debouncedQuery;
    let runs = fallback($$props["runs"], () => [], true);
    let dateFilter = "all";
    let filterFilter = "all";
    let statusFilter = "all";
    function filterRuns(items, query, date, filter, status) {
      let result = items;
      if (query) {
        const queryLower = query.toLowerCase();
        result = result.filter((item) => item.config.selectedFilter.toLowerCase().includes(queryLower) || item.status.toLowerCase().includes(queryLower));
      }
      if (date !== "all") {
        const now = /* @__PURE__ */ new Date();
        const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
        const yesterday = new Date(today);
        yesterday.setDate(yesterday.getDate() - 1);
        const weekAgo = new Date(today);
        weekAgo.setDate(weekAgo.getDate() - 7);
        const monthAgo = new Date(today);
        monthAgo.setDate(monthAgo.getDate() - 30);
        result = result.filter((item) => {
          const itemDate = new Date(item.startedAt);
          switch (date) {
            case "today":
              return itemDate >= today;
            case "yesterday":
              return itemDate >= yesterday && itemDate < today;
            case "week":
              return itemDate >= weekAgo;
            case "month":
              return itemDate >= monthAgo;
            default:
              return true;
          }
        });
      }
      if (filter !== "all") result = result.filter((item) => item.config.selectedFilter === filter);
      if (status !== "all") result = result.filter((item) => item.status === status);
      return result;
    }
    const pageSize = 20;
    let currentPage = 1;
    let expandedIds = /* @__PURE__ */ new Set();
    const columns = [
      {
        key: "runNumber",
        header: "#",
        sortable: false
      },
      {
        key: "filter",
        header: "Filter",
        sortable: true
      },
      {
        key: "date",
        header: "Date",
        sortable: true
      },
      {
        key: "duration",
        header: "Duration",
        sortable: false
      },
      {
        key: "status",
        header: "Status",
        sortable: true
      },
      {
        key: "summary",
        header: "Summary",
        sortable: false
      }
    ];
    const statusConfig = {
      success: {
        variant: "success",
        icon: Check
      },
      partial: {
        variant: "warning",
        icon: Triangle_alert
      },
      failed: {
        variant: "danger",
        icon: X2
      },
      skipped: {
        variant: "secondary",
        icon: X2
      }
    };
    function getRunNumber(row) {
      const originalIndex = runs.findIndex((r2) => r2.id === row.id);
      return runs.length - originalIndex;
    }
    function formatDuration2(startedAt, completedAt) {
      const ms = new Date(completedAt).getTime() - new Date(startedAt).getTime();
      if (ms < 1e3) return `${ms}ms`;
      if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
      return `${Math.floor(ms / 6e4)}m ${Math.floor(ms % 6e4 / 1e3)}s`;
    }
    function formatSchedule(cron) {
      return cron || "-";
    }
    function formatFilterMode(mode) {
      return mode.split("_").map((w3) => w3.charAt(0).toUpperCase() + w3.slice(1)).join(" ");
    }
    function formatMethod(method) {
      return method.split("_").map((w3) => w3.charAt(0).toUpperCase() + w3.slice(1)).join(" ");
    }
    function flattenItems2(items) {
      const result = [];
      for (const item of items) {
        if (item.original.type === "movie") {
          result.push(item);
          continue;
        }
        const episodes = item.original.episodes ?? [];
        const seasonEpisodes = /* @__PURE__ */ new Map();
        for (const ep of episodes) {
          const eps = seasonEpisodes.get(ep.seasonNumber) ?? [];
          eps.push(ep);
          seasonEpisodes.set(ep.seasonNumber, eps);
        }
        const seasonUpgrades = /* @__PURE__ */ new Map();
        for (const u of item.upgrades) if (u.seasonNumber != null) {
          const ups = seasonUpgrades.get(u.seasonNumber) ?? [];
          ups.push(u);
          seasonUpgrades.set(u.seasonNumber, ups);
        }
        const allSeasons = /* @__PURE__ */ new Set([...seasonEpisodes.keys(), ...seasonUpgrades.keys()]);
        if (allSeasons.size === 0) {
          result.push(item);
          continue;
        }
        for (const season of [...allSeasons].sort((a2, b3) => a2 - b3)) {
          const wasSearched = item.searchedSeasonNumber == null || season === item.searchedSeasonNumber;
          result.push({
            id: item.id * 1e3 + season,
            title: `${item.title} - Season ${season}`,
            original: {
              type: "series",
              title: item.title,
              episodes: seasonEpisodes.get(season) ?? []
            },
            upgrades: seasonUpgrades.get(season) ?? [],
            searchedSeasonNumber: wasSearched ? season : -1
          });
        }
      }
      return result;
    }
    $: if (store_get($$store_subs ??= {}, "$page", page)?.params?.id) {
      searchStore = getPersistentSearchStore(`upgradeRunHistorySearch:${store_get($$store_subs ??= {}, "$page", page).params.id}`);
      debouncedQuery = searchStore.debouncedQuery;
    }
    $: uniqueFilters = [...new Set(runs.map((r2) => r2.config.selectedFilter).filter(Boolean))];
    $: filteredRuns = filterRuns(runs, store_get($$store_subs ??= {}, "$debouncedQuery", debouncedQuery), dateFilter, filterFilter, statusFilter);
    $: totalPages = Math.max(1, Math.ceil(filteredRuns.length / pageSize));
    $: if (currentPage > totalPages) currentPage = 1;
    $: paginatedRuns = filteredRuns.slice((currentPage - 1) * pageSize, currentPage * pageSize);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="-mx-4 bg-neutral-50 px-4 pt-2 pb-6 md:-mx-8 md:px-8 dark:bg-neutral-900"><div class="mb-4">`);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore,
            placeholder: "Search runs..."
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Calendar,
            hasDropdown: true,
            square: true,
            title: "Filter by date",
            $$slots: { dropdown: ($$renderer5) => {
              Dropdown($$renderer5, {
                slot: "dropdown",
                position: "right",
                mobilePosition: "middle",
                children: ($$renderer6) => {
                  $$renderer6.push(`<!--[-->`);
                  const each_array = ensure_array_like([
                    {
                      value: "all",
                      label: "All time"
                    },
                    {
                      value: "today",
                      label: "Today"
                    },
                    {
                      value: "yesterday",
                      label: "Yesterday"
                    },
                    {
                      value: "week",
                      label: "Last 7 days"
                    },
                    {
                      value: "month",
                      label: "Last 30 days"
                    }
                  ]);
                  for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                    let option = each_array[$$index];
                    DropdownItem($$renderer6, {
                      label: option.label,
                      selected: dateFilter === option.value
                    });
                  }
                  $$renderer6.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Funnel,
            hasDropdown: true,
            square: true,
            title: "Filter by filter name",
            $$slots: { dropdown: ($$renderer5) => {
              Dropdown($$renderer5, {
                slot: "dropdown",
                position: "right",
                mobilePosition: "middle",
                children: ($$renderer6) => {
                  DropdownItem($$renderer6, {
                    label: "All filters",
                    selected: true
                  });
                  $$renderer6.push(`<!----> <!--[-->`);
                  const each_array_1 = ensure_array_like(uniqueFilters);
                  for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                    let filter = each_array_1[$$index_1];
                    DropdownItem($$renderer6, {
                      label: filter,
                      selected: filterFilter === filter
                    });
                  }
                  $$renderer6.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Circle_dot,
            hasDropdown: true,
            square: true,
            title: "Filter by status",
            $$slots: { dropdown: ($$renderer5) => {
              Dropdown($$renderer5, {
                slot: "dropdown",
                position: "right",
                mobilePosition: "middle",
                children: ($$renderer6) => {
                  $$renderer6.push(`<!--[-->`);
                  const each_array_2 = ensure_array_like([
                    {
                      value: "all",
                      label: "All"
                    },
                    {
                      value: "success",
                      label: "Success"
                    },
                    {
                      value: "partial",
                      label: "Partial"
                    },
                    {
                      value: "failed",
                      label: "Failed"
                    },
                    {
                      value: "skipped",
                      label: "Skipped"
                    }
                  ]);
                  for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
                    let option = each_array_2[$$index_2];
                    DropdownItem($$renderer6, {
                      label: option.label,
                      selected: statusFilter === option.value
                    });
                  }
                  $$renderer6.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----></div> `);
      ExpandableTable($$renderer3, {
        columns,
        data: paginatedRuns,
        getRowId: (row) => row.id,
        chevronPosition: "right",
        flushExpanded: true,
        emptyMessage: "No upgrade runs yet. Configure and enable upgrades to start.",
        responsive: true,
        get expandedRows() {
          return expandedIds;
        },
        set expandedRows($$value) {
          expandedIds = $$value;
          $$settled = false;
        },
        $$slots: {
          cell: ($$renderer4, { row, column }) => {
            if (column.key === "runNumber") {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="font-mono text-neutral-500 dark:text-neutral-500">#${escape_html(getRunNumber(row))}</span>`);
            } else if (column.key === "filter") {
              $$renderer4.push("<!--[1-->");
              $$renderer4.push(`<div class="flex items-center gap-2"><span class="font-medium text-neutral-900 dark:text-neutral-100">${escape_html(row.config.selectedFilter || "Unknown")}</span> `);
              if (row.config.dryRun) {
                $$renderer4.push("<!--[0-->");
                Label($$renderer4, {
                  variant: "info",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer5) => {
                    Flask_conical($$renderer5, { size: 10 });
                    $$renderer5.push(`<!----> Dry Run`);
                  },
                  $$slots: { default: true }
                });
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></div>`);
            } else if (column.key === "date") {
              $$renderer4.push("<!--[2-->");
              $$renderer4.push(`<span class="text-neutral-600 dark:text-neutral-400">${escape_html(formatSmartDateTime(row.startedAt, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat)))}</span>`);
            } else if (column.key === "duration") {
              $$renderer4.push("<!--[3-->");
              $$renderer4.push(`<span class="font-mono text-xs text-neutral-600 dark:text-neutral-400">${escape_html(formatDuration2(row.startedAt, row.completedAt))}</span>`);
            } else if (column.key === "status") {
              $$renderer4.push("<!--[4-->");
              const config2 = statusConfig[row.status] || statusConfig.failed;
              Label($$renderer4, {
                variant: config2.variant,
                size: "sm",
                rounded: "md",
                children: ($$renderer5) => {
                  if (config2.icon) {
                    $$renderer5.push("<!--[-->");
                    config2.icon($$renderer5, { size: 10 });
                    $$renderer5.push("<!--]-->");
                  } else {
                    $$renderer5.push("<!--[!-->");
                    $$renderer5.push("<!--]-->");
                  }
                  $$renderer5.push(` ${escape_html(row.status.charAt(0).toUpperCase() + row.status.slice(1))}`);
                },
                $$slots: { default: true }
              });
            } else if (column.key === "summary") {
              $$renderer4.push("<!--[5-->");
              const upgradedItems = row.selection.items.filter((i) => i.upgrades.length > 0);
              const tooltipText = upgradedItems.length > 0 ? upgradedItems.map((i) => {
                const lines = [i.title];
                for (const u of i.upgrades) {
                  lines.push(`  ${u.release}`);
                  lines.push(`  CF Score: ${u.score}`);
                }
                return lines.join("\n");
              }).join("\n\n") : "No upgrades";
              $$renderer4.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400"><span class="font-mono">${escape_html(row.filter.matchedCount)}</span> filtered <span class="mx-1 text-neutral-300 dark:text-neutral-600">\u2192</span> <span class="font-mono">${escape_html(row.filter.afterCooldown)}</span> after cooldown <span class="mx-1 text-neutral-300 dark:text-neutral-600">\u2192</span> `);
              Tooltip($$renderer4, {
                text: tooltipText,
                mono: true,
                children: ($$renderer5) => {
                  $$renderer5.push(`<span${attr_class(`inline-flex items-center gap-1 font-mono ${row.results.successful > 0 ? "cursor-help" : ""}`)}><span${attr_class(clsx(row.results.successful > 0 ? "text-green-600 dark:text-green-400" : ""))}>${escape_html(row.results.successful)}</span> upgraded `);
                  if (row.results.successful > 0) {
                    $$renderer5.push("<!--[0-->");
                    Info($$renderer5, { size: 12 });
                  } else $$renderer5.push("<!--[-1-->");
                  $$renderer5.push(`<!--]--></span>`);
                },
                $$slots: { default: true }
              });
              $$renderer4.push(`<!----></span>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          expanded: ($$renderer4, { row }) => {
            $$renderer4.push(`<div class="space-y-3 p-6"><div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Config</span> <span class="text-sm text-neutral-900 dark:text-neutral-100">Schedule: ${escape_html(formatSchedule(row.config.cron))} | Mode: ${escape_html(formatFilterMode(row.config.filterMode))}</span></div> <div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Library</span> <span class="text-sm text-neutral-900 dark:text-neutral-100"><span class="font-mono">${escape_html(row.library.totalItems.toLocaleString())}</span> items `);
            if (row.library.fetchedFromCache) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="text-neutral-500 dark:text-neutral-400">(cached)</span>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> <span class="ml-1 font-mono text-xs text-neutral-500 dark:text-neutral-400">(${escape_html(row.library.fetchDurationMs)}ms)</span></span></div> <div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Filter</span> <span class="text-sm text-neutral-900 dark:text-neutral-100">"${escape_html(row.filter.name)}" <span class="mx-1 text-neutral-400">\u2192</span> <span class="font-mono font-medium">${escape_html(row.filter.matchedCount)}</span> filtered <span class="mx-1 text-neutral-400">\u2192</span> <span class="font-mono font-medium">${escape_html(row.filter.afterCooldown)}</span> after cooldown</span></div> <div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Selection</span> <span class="text-sm text-neutral-900 dark:text-neutral-100">${escape_html(formatMethod(row.selection.method))} <span class="font-mono font-medium">${escape_html(row.selection.actualCount)}</span> of <span class="font-mono">${escape_html(row.selection.requestedCount)}</span></span></div> <div class="flex"><span class="w-24 shrink-0 text-sm font-medium text-neutral-500 dark:text-neutral-400">Results</span> <span class="text-sm text-neutral-900 dark:text-neutral-100">`);
            if (row.config.dryRun) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="font-mono">${escape_html(row.results.searchesTriggered)}</span> previewed, <span${attr_class(`${row.results.successful > 0 ? "text-green-600 dark:text-green-400" : ""} font-mono`)}>${escape_html(row.results.successful)}</span> upgrades found`);
            } else {
              $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<span class="font-mono">${escape_html(row.results.searchesTriggered)}</span> searches triggered, <span${attr_class(`${row.results.successful > 0 ? "text-green-600 dark:text-green-400" : ""} font-mono`)}>${escape_html(row.results.successful)}</span> grabbed`);
            }
            $$renderer4.push(`<!--]--> `);
            if (row.results.failed > 0) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="font-mono text-red-600 dark:text-red-400">, ${escape_html(row.results.failed)} failed</span>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></span></div> `);
            if (row.selection.items.length > 0) {
              $$renderer4.push("<!--[0-->");
              const itemsColumns = [
                {
                  key: "title",
                  header: "Title",
                  sortable: false
                },
                {
                  key: "current",
                  header: "Current",
                  sortable: false,
                  align: "center"
                },
                {
                  key: "upgrade",
                  header: "Upgrade",
                  sortable: false,
                  align: "center"
                },
                {
                  key: "delta",
                  header: "Delta",
                  sortable: false,
                  align: "center"
                },
                {
                  key: "formats",
                  header: "Formats",
                  sortable: false
                }
              ];
              $$renderer4.push(`<div class="mt-4 border-t border-neutral-200 pt-4 dark:border-neutral-700"><div class="mb-3 flex items-center gap-1.5 text-sm font-medium text-neutral-700 dark:text-neutral-300">`);
              Search($$renderer4, { size: 14 });
              $$renderer4.push(`<!----> Items Searched</div> `);
              ExpandableTable($$renderer4, {
                columns: itemsColumns,
                data: flattenItems2(row.selection.items),
                getRowId: (item) => item.id,
                compact: true,
                emptyMessage: "No items",
                responsive: true,
                $$slots: {
                  cell: ($$renderer5, { row: item, column }) => {
                    if (column.key === "title") {
                      $$renderer5.push("<!--[0-->");
                      $$renderer5.push(`<span class="text-neutral-900 dark:text-neutral-100">${escape_html(item.title)}</span>`);
                    } else if (column.key === "current") {
                      $$renderer5.push("<!--[1-->");
                      if (item.original.type === "movie") {
                        $$renderer5.push("<!--[0-->");
                        Badge($$renderer5, {
                          variant: "neutral",
                          mono: true,
                          children: ($$renderer6) => {
                            $$renderer6.push(`<!---->${escape_html(item.original.score.toLocaleString())}`);
                          },
                          $$slots: { default: true }
                        });
                      } else {
                        $$renderer5.push("<!--[-1-->");
                        $$renderer5.push(`<span class="text-xs text-neutral-500">${escape_html(item.original.episodes?.length ?? 0)} episodes</span>`);
                      }
                      $$renderer5.push(`<!--]-->`);
                    } else if (column.key === "upgrade") {
                      $$renderer5.push("<!--[2-->");
                      if (item.upgrades.length > 0) {
                        $$renderer5.push("<!--[0-->");
                        $$renderer5.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
                        const each_array_3 = ensure_array_like(item.upgrades);
                        for (let $$index_3 = 0, $$length = each_array_3.length; $$index_3 < $$length; $$index_3++) {
                          let u = each_array_3[$$index_3];
                          Badge($$renderer5, {
                            variant: "neutral",
                            mono: true,
                            children: ($$renderer6) => {
                              $$renderer6.push(`<!---->${escape_html(u.score.toLocaleString())}`);
                            },
                            $$slots: { default: true }
                          });
                        }
                        $$renderer5.push(`<!--]--></div>`);
                      } else {
                        $$renderer5.push("<!--[-1-->");
                        $$renderer5.push(`<span class="text-neutral-400">\u2014</span>`);
                      }
                      $$renderer5.push(`<!--]-->`);
                    } else if (column.key === "delta") {
                      $$renderer5.push("<!--[3-->");
                      if (item.upgrades.length > 0 && item.original.type === "movie") {
                        $$renderer5.push("<!--[0-->");
                        const delta = item.upgrades[0].score - item.original.score;
                        Badge($$renderer5, {
                          variant: delta >= 0 ? "success" : "danger",
                          mono: true,
                          children: ($$renderer6) => {
                            $$renderer6.push(`<!---->${escape_html(delta >= 0 ? "+" : "")}${escape_html(delta.toLocaleString())}`);
                          },
                          $$slots: { default: true }
                        });
                      } else if (item.upgrades.length > 0) {
                        $$renderer5.push("<!--[1-->");
                        Badge($$renderer5, {
                          variant: "success",
                          mono: true,
                          children: ($$renderer6) => {
                            $$renderer6.push(`<!---->${escape_html(item.upgrades.length)} grab${escape_html(item.upgrades.length > 1 ? "s" : "")}`);
                          },
                          $$slots: { default: true }
                        });
                      } else {
                        $$renderer5.push("<!--[-1-->");
                        $$renderer5.push(`<span class="text-neutral-400">\u2014</span>`);
                      }
                      $$renderer5.push(`<!--]-->`);
                    } else if (column.key === "formats") {
                      $$renderer5.push("<!--[4-->");
                      if (item.upgrades.length > 0) {
                        $$renderer5.push("<!--[0-->");
                        const allFormats = item.upgrades.flatMap((u) => u.formats);
                        if (allFormats.length > 0) {
                          $$renderer5.push("<!--[0-->");
                          $$renderer5.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
                          const each_array_4 = ensure_array_like(allFormats);
                          for (let $$index_4 = 0, $$length = each_array_4.length; $$index_4 < $$length; $$index_4++) {
                            let format = each_array_4[$$index_4];
                            Badge($$renderer5, {
                              variant: "success",
                              size: "sm",
                              children: ($$renderer6) => {
                                $$renderer6.push(`<!---->${escape_html(format)}`);
                              },
                              $$slots: { default: true }
                            });
                          }
                          $$renderer5.push(`<!--]--></div>`);
                        } else {
                          $$renderer5.push("<!--[-1-->");
                          Badge($$renderer5, {
                            variant: "neutral",
                            size: "sm",
                            children: ($$renderer6) => {
                              $$renderer6.push(`<!---->No formats`);
                            },
                            $$slots: { default: true }
                          });
                        }
                        $$renderer5.push(`<!--]-->`);
                      } else if (item.searchedSeasonNumber === -1) {
                        $$renderer5.push("<!--[1-->");
                        Badge($$renderer5, {
                          variant: "neutral",
                          size: "sm",
                          children: ($$renderer6) => {
                            $$renderer6.push(`<!---->Not searched`);
                          },
                          $$slots: { default: true }
                        });
                      } else {
                        $$renderer5.push("<!--[-1-->");
                        Badge($$renderer5, {
                          variant: "neutral",
                          size: "sm",
                          children: ($$renderer6) => {
                            $$renderer6.push(`<!---->No upgrade`);
                          },
                          $$slots: { default: true }
                        });
                      }
                      $$renderer5.push(`<!--]-->`);
                    } else $$renderer5.push("<!--[-1-->");
                    $$renderer5.push(`<!--]-->`);
                  },
                  expanded: ($$renderer5, { row: item }) => {
                    $$renderer5.push(`<div class="space-y-2 py-2 pl-2">`);
                    if (item.original.type === "movie") {
                      $$renderer5.push("<!--[0-->");
                      $$renderer5.push(`<div class="flex gap-2"><span class="w-16 shrink-0 text-xs font-medium text-neutral-500 dark:text-neutral-400">Current:</span> <span class="truncate font-mono text-xs text-neutral-700 dark:text-neutral-300"${attr("title", item.original.fileName)}>${escape_html(item.original.fileName)}</span></div>`);
                    } else {
                      $$renderer5.push("<!--[-1-->");
                      $$renderer5.push(`<div><span class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Episodes on disk (${escape_html(item.original.episodes?.length ?? 0)}):</span> <div class="mt-1 space-y-0.5"><!--[-->`);
                      const each_array_5 = ensure_array_like(item.original.episodes ?? []);
                      for (let $$index_5 = 0, $$length = each_array_5.length; $$index_5 < $$length; $$index_5++) {
                        let ep = each_array_5[$$index_5];
                        $$renderer5.push(`<div class="flex items-center gap-2"><span class="truncate font-mono text-xs text-neutral-700 dark:text-neutral-300"${attr("title", ep.fileName)}>${escape_html(ep.fileName)}</span> `);
                        Badge($$renderer5, {
                          variant: "neutral",
                          size: "sm",
                          mono: true,
                          children: ($$renderer6) => {
                            $$renderer6.push(`<!---->${escape_html(ep.score)}`);
                          },
                          $$slots: { default: true }
                        });
                        $$renderer5.push(`<!----></div>`);
                      }
                      $$renderer5.push(`<!--]--></div></div>`);
                    }
                    $$renderer5.push(`<!--]--> `);
                    if (item.upgrades.length > 0) {
                      $$renderer5.push("<!--[0-->");
                      $$renderer5.push(`<!--[-->`);
                      const each_array_6 = ensure_array_like(item.upgrades);
                      for (let $$index_6 = 0, $$length = each_array_6.length; $$index_6 < $$length; $$index_6++) {
                        let u = each_array_6[$$index_6];
                        $$renderer5.push(`<div class="flex gap-2"><span class="w-16 shrink-0 text-xs font-medium text-emerald-600 dark:text-emerald-400">Upgrade:</span> <span class="truncate font-mono text-xs text-neutral-700 dark:text-neutral-300"${attr("title", u.release)}>${escape_html(u.release)}</span></div>`);
                      }
                      $$renderer5.push(`<!--]-->`);
                    } else if (item.searchedSeasonNumber === -1) {
                      $$renderer5.push("<!--[1-->");
                      $$renderer5.push(`<div class="text-xs text-neutral-500 italic dark:text-neutral-400">Not searched (dry run only searches latest monitored season)</div>`);
                    } else {
                      $$renderer5.push("<!--[-1-->");
                      $$renderer5.push(`<div class="text-xs text-neutral-500 italic dark:text-neutral-400">No upgrade available</div>`);
                    }
                    $$renderer5.push(`<!--]--></div>`);
                  }
                }
              });
              $$renderer4.push(`<!----></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="mt-3 flex justify-center">`);
      Pagination($$renderer3, {
        currentPage,
        totalPages,
        onPageChange: (p2) => currentPage = p2
      });
      $$renderer3.push(`<!----></div></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { runs });
  });
}
function Admonition($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let style, IconCmp;
    let variant = fallback($$props["variant"], "info");
    let title = fallback($$props["title"], void 0);
    let icon = fallback($$props["icon"], void 0);
    let dismissible = fallback($$props["dismissible"], false);
    let confirmDismiss = fallback($$props["confirmDismiss"], false);
    let confirmHeader = fallback($$props["confirmHeader"], "Are you sure?");
    let confirmMessage = fallback($$props["confirmMessage"], "This message will be permanently hidden.");
    let confirmText = fallback($$props["confirmText"], "Dismiss");
    let className = fallback($$props["className"], "");
    createEventDispatcher();
    const defaultIcons = {
      info: Info,
      warning: Triangle_alert,
      danger: Octagon_alert,
      success: Circle_check,
      note: Message_square
    };
    const variantStyles = {
      info: {
        accent: "text-blue-700 dark:text-blue-300",
        surface: "border-blue-200 bg-blue-50 dark:border-blue-800/50 dark:bg-blue-950/30",
        divider: "border-blue-200 dark:border-blue-800/50"
      },
      warning: {
        accent: "text-amber-700 dark:text-amber-300",
        surface: "border-amber-200 bg-amber-50 dark:border-amber-800/50 dark:bg-amber-950/30",
        divider: "border-amber-200 dark:border-amber-800/50"
      },
      danger: {
        accent: "text-red-700 dark:text-red-300",
        surface: "border-red-200 bg-red-50 dark:border-red-800/50 dark:bg-red-950/30",
        divider: "border-red-200 dark:border-red-800/50"
      },
      success: {
        accent: "text-green-700 dark:text-green-300",
        surface: "border-green-200 bg-green-50 dark:border-green-800/50 dark:bg-green-950/30",
        divider: "border-green-200 dark:border-green-800/50"
      },
      note: {
        accent: "text-neutral-700 dark:text-neutral-300",
        surface: "border-neutral-300 bg-neutral-50 dark:border-neutral-700/60 dark:bg-neutral-900",
        divider: "border-neutral-300 dark:border-neutral-700/60"
      }
    };
    let showConfirm = false;
    $: style = variantStyles[variant];
    $: IconCmp = icon ?? defaultIcons[variant];
    $$renderer2.push(`<div${attr_class(`overflow-hidden rounded-xl border ${stringify(style.surface)} ${stringify(className)}`)}><div${attr_class(`flex items-center gap-2 border-b px-4 py-2 ${stringify(style.divider)}`)}><div${attr_class(`shrink-0 ${stringify(style.accent)}`)}>`);
    if (IconCmp) {
      $$renderer2.push("<!--[-->");
      IconCmp($$renderer2, { size: 18 });
      $$renderer2.push("<!--]-->");
    } else {
      $$renderer2.push("<!--[!-->");
      $$renderer2.push("<!--]-->");
    }
    $$renderer2.push(`</div> `);
    if (title) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<h3 class="flex-1 text-sm font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h3>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="flex-1"></div>`);
    }
    $$renderer2.push(`<!--]--> `);
    if (dismissible) {
      $$renderer2.push("<!--[0-->");
      Button($$renderer2, {
        icon: X2,
        variant: "ghost",
        size: "xs",
        ariaLabel: "Dismiss"
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div> <div class="px-4 py-3 text-sm text-neutral-700 dark:text-neutral-300"><!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--></div></div> `);
    if (dismissible && confirmDismiss) {
      $$renderer2.push("<!--[0-->");
      Modal($$renderer2, {
        open: showConfirm,
        header: confirmHeader,
        bodyMessage: confirmMessage,
        confirmText,
        cancelText: "Cancel"
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      variant,
      title,
      icon,
      dismissible,
      confirmDismiss,
      confirmHeader,
      confirmMessage,
      confirmText,
      className
    });
  });
}
function _page10($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let isNewConfig, enabled3, cron, filterMode2, filters, hasEnabledFilter, runsPerHour, appMinInterval;
    let data = $$props["data"];
    let form = $$props["form"];
    let saving = false;
    let dynamicFilterOptions = createEmptyDynamicFilterOptions(data.instance.type);
    let dynamicFilterOptionsLoading = true;
    let dynamicFilterOptionsVersion = 0;
    let lastFormId = null;
    $: isNewConfig = !data.config;
    $: enabled3 = store_get($$store_subs ??= {}, "$current", current2).enabled ?? false;
    $: cron = store_get($$store_subs ??= {}, "$current", current2).cron ?? "0 */6 * * *";
    $: filterMode2 = store_get($$store_subs ??= {}, "$current", current2).filterMode ?? "round_robin";
    $: filters = JSON.parse(store_get($$store_subs ??= {}, "$current", current2).filters ?? "[]");
    $: hasEnabledFilter = filters.some((f2) => f2.enabled);
    $: runsPerHour = getRunsPerHour(cron) ?? 1;
    $: appMinInterval = searchRateLimits[data.instance.type]?.minIntervalMinutes ?? 10;
    $: if (form && form !== lastFormId) {
      lastFormId = form;
      if (form.success && !form.queued && !form.cacheCleared) {
        alertStore.add("success", "Configuration saved successfully");
        initEdit({
          enabled: enabled3,
          cron,
          filterMode: filterMode2,
          filters: JSON.stringify(filters)
        });
      }
      if (form.success && form.queued) alertStore.add("success", "Upgrade run queued");
      if (form.success && form.cacheCleared) alertStore.add("success", "Dry run cache cleared");
      if (form.error) {
        jobStatus.cancelOptimistic();
        alertStore.add("error", form.error);
      }
    }
    PageMeta($$renderer2, { title: `${data.instance.name} \xB7 Upgrades` });
    $$renderer2.push(`<!----> <!---->`);
    StickyCard($$renderer2, {
      position: "top",
      $$slots: {
        left: ($$renderer3) => {
          $$renderer3.push(`<div slot="left"><h1 class="text-xl font-semibold text-neutral-900 dark:text-neutral-50">Upgrades</h1> <p class="text-sm text-neutral-500 dark:text-neutral-400">Automatically search for better quality releases.</p></div>`);
        },
        right: ($$renderer3) => {
          $$renderer3.push(`<div slot="right" class="flex flex-wrap items-center gap-2">`);
          Button($$renderer3, {
            text: "Info",
            icon: Info,
            href: "/arr/upgrades/info"
          });
          $$renderer3.push(`<!----> `);
          Button($$renderer3, {
            text: "Reset Cache",
            icon: Rotate_ccw,
            disabled: isNewConfig || !enabled3 || !hasEnabledFilter || saving,
            tooltip: !hasEnabledFilter ? "Add and enable at least one filter before running" : "Clear dry run exclusion cache so items can be re-selected",
            tooltipPosition: "bottom",
            tooltipAlign: "right"
          });
          $$renderer3.push(`<!----> `);
          Button($$renderer3, {
            text: "Dry Run",
            icon: Flask_conical,
            iconColor: "text-amber-600 dark:text-amber-400",
            disabled: isNewConfig || !enabled3 || !hasEnabledFilter || store_get($$store_subs ??= {}, "$isDirty", isDirty),
            tooltip: !hasEnabledFilter ? "Add and enable at least one filter before running" : data.instance.type === "sonarr" ? "Search indexers without downloading. Only searches the latest monitored season per series (limited to once every 10 min)" : "Search indexers without downloading (limited to once every 10 min)",
            tooltipPosition: "bottom",
            tooltipAlign: "right"
          });
          $$renderer3.push(`<!----> `);
          $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          Button($$renderer3, {
            text: "Save",
            icon: Save,
            iconColor: "text-blue-600 dark:text-blue-400",
            disabled: !store_get($$store_subs ??= {}, "$isDirty", isDirty)
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    $$renderer2.push(`<!----> <div class="mt-4 space-y-6">`);
    $$renderer2.push("<!--[0-->");
    $$renderer2.push(`<div class="md:px-4">`);
    Admonition($$renderer2, {
      variant: "danger",
      title: "Indexer rate limits",
      dismissible: true,
      confirmDismiss: true,
      confirmMessage: "This warning will be permanently hidden. Make sure you have read it.",
      children: ($$renderer3) => {
        $$renderer3.push(`<p>Profilarr limits upgrade searches to at most one movie every 10 minutes (Radarr) and one
						series per hour (Sonarr). These are intentionally conservative defaults, but they don't
						override your indexer's own rules. Confirm what your indexer allows and stay within it.</p>`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----></div>`);
    $$renderer2.push(`<!--]--> `);
    $$renderer2.push("<!--[0-->");
    $$renderer2.push(`<div class="md:px-4">`);
    Admonition($$renderer2, {
      variant: "info",
      title: "When to use upgrades",
      dismissible: true,
      confirmDismiss: true,
      confirmMessage: "This message will be permanently hidden. Make sure you have read it.",
      children: ($$renderer3) => {
        $$renderer3.push(`<p class="mb-2">Most libraries don't need upgrades running. RSS already grabs better releases as they're
						posted; this feature only matters when your existing library has fallen behind your
						current config. Turn it on to catch up after a change, for example:</p> <ul class="list-disc space-y-1 pl-5"><li>You switched a library to a different quality profile</li> <li>Your custom format scores changed, often after a PCD update</li> <li>Your Arr instance was offline for a stretch (internet outage, downtime, updates)</li> <li>You added a new indexer with releases you couldn't reach before</li></ul> <p class="mt-2">If none of those apply, leaving it disabled is fine.</p>`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----></div>`);
    $$renderer2.push(`<!--]--> <section class="border-b border-neutral-200 pb-5 dark:border-neutral-800">`);
    CoreSettings($$renderer2, {
      enabled: enabled3,
      cron,
      filterMode: filterMode2,
      lastRunAt: data.config?.lastRunAt ?? null,
      nextRunAt: data.config?.nextRunAt ?? null,
      minIntervalMinutes: appMinInterval,
      onEnabledChange: (v3) => update3("enabled", v3),
      onCronChange: (v3) => update3("cron", v3),
      onFilterModeChange: (v3) => update3("filterMode", v3),
      onWarning: (msg) => alertStore.add("warning", msg)
    });
    $$renderer2.push(`<!----></section> `);
    if (enabled3) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<section class="md:px-4" data-onboarding="upgrades-filters">`);
      FilterSettings($$renderer2, {
        filters,
        appType: data.instance.type,
        runsPerHour,
        dynamicFilterOptions,
        dynamicFilterOptionsLoading,
        dynamicFilterOptionsVersion,
        onFiltersChange: (v3) => update3("filters", JSON.stringify(v3))
      });
      $$renderer2.push(`<!----></section> <section class="md:px-4">`);
      RunHistory($$renderer2, { runs: data.upgradeRuns });
      $$renderer2.push(`<!----></section>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<section class="md:px-4"><div class="rounded-xl border border-neutral-300 dark:border-neutral-700/60"><p class="px-4 py-4 text-center text-sm text-neutral-600 dark:text-neutral-400">Enable upgrades to configure filters and view run history.</p></div></section>`);
    }
    $$renderer2.push(`<!--]--></div> <form id="save-form" method="POST" action="?/save" class="hidden"><input type="hidden" name="enabled"${attr("value", enabled3)}/> <input type="hidden" name="cron"${attr("value", cron)}/> <input type="hidden" name="filterMode"${attr("value", filterMode2)}/> <input type="hidden" name="filters"${attr("value", JSON.stringify(filters))}/></form> `);
    if (!isNewConfig) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<form id="dry-run-form" method="POST" action="?/run" class="hidden"><input type="hidden" name="dryRun" value="true"/></form> <form id="live-run-form" method="POST" action="?/run" class="hidden"><input type="hidden" name="dryRun" value="false"/></form> <form id="clear-cache-form" method="POST" action="?/clearCache" class="hidden"></form>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      data,
      form
    });
  });
}
var init_page_svelte10 = __esm({
  "dist/build/server/entries/pages/arr/_id_/upgrades/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_dates();
    init_selectors();
    init_Dropdown();
    init_Icon();
    init_calendar();
    init_check();
    init_circle_check();
    init_circle_dot();
    init_copy();
    init_eye();
    init_file_text();
    init_flask_conical();
    init_funnel();
    init_info();
    init_Button();
    init_pencil();
    init_plus();
    init_rotate_ccw();
    init_save();
    init_search();
    init_trash_2();
    init_triangle_alert();
    init_x();
    init_theme();
    init_client4();
    init_stores();
    init_store2();
    init_Label();
    init_Card();
    init_jobStatus();
    init_navigation();
    init_Modal();
    init_dateFormat();
    init_timezone();
    init_forms();
    init_DropdownItem();
    init_dirty();
    init_DirtyModal();
    init_ExpandableTable();
    init_ActionsBar();
    init_ActionButton();
    init_Badge();
    init_DropdownHeader();
    init_PageMeta();
    init_StickyCard();
    init_DropdownSelect();
    init_FormInput();
    init_NumberInput();
    init_DropdownCombobox();
    init_CronInput();
    init_Toggle();
    init_Score();
    init_CustomFormatBadge();
    init_Pagination();
    init_DateInput();
    init_themes();
  }
});

// dist/build/server/nodes/17.js
var __exports18 = {};
__export(__exports18, {
  component: () => component17,
  fonts: () => fonts18,
  imports: () => imports18,
  index: () => index18,
  server: () => page_server_ts_exports11,
  server_id: () => server_id17,
  stylesheets: () => stylesheets18
});
var index18, component_cache17, component17, server_id17, imports18, stylesheets18, fonts18;
var init__18 = __esm({
  async "dist/build/server/nodes/17.js"() {
    "use strict";
    await init_page_server_ts11();
    index18 = 17;
    component17 = async () => component_cache17 ??= (await Promise.resolve().then(() => (init_page_svelte10(), page_svelte_exports10))).default;
    server_id17 = "src/routes/arr/[id]/upgrades/+page.server.ts";
    imports18 = ["_app/immutable/nodes/17.BOUyKKXv.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/Cz3WzBYs.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/uDCknttb2.js", "_app/immutable/chunks/By4o5e8D2.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/SEZzcS_o.js", "_app/immutable/chunks/MJc6__n-.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/B_FOzVLA.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/DvoiSP5r.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/DcKM5OzB2.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/COLvC_Ug.js", "_app/immutable/chunks/C47WFcPn.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/Co6rAu4X.js", "_app/immutable/chunks/C5rtWVlZ.js", "_app/immutable/chunks/DTxrEb2m.js", "_app/immutable/chunks/D1MpTH1m.js", "_app/immutable/chunks/9MSyFmmd.js", "_app/immutable/chunks/BaewglP2.js", "_app/immutable/chunks/CLCnMz_w.js", "_app/immutable/chunks/DSNLgKve.js"];
    stylesheets18 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/17.BO57kFZw.css"];
    fonts18 = [];
  }
});

// dist/build/server/entries/pages/arr/new/_page.server.ts.js
var page_server_ts_exports12 = {};
__export(page_server_ts_exports12, {
  actions: () => actions9
});
function getDefaultDelayProfile(arrType) {
  switch (arrType) {
    case "radarr":
      return RADARR_DEFAULT_DELAY_PROFILE;
    case "sonarr":
      return SONARR_DEFAULT_DELAY_PROFILE;
    default:
      throw new Error(`No default delay profile for arr type: ${arrType}`);
  }
}
var RADARR_DEFAULT_DELAY_PROFILE, SONARR_DEFAULT_DELAY_PROFILE, VALID_TYPES, actions9;
var init_page_server_ts12 = __esm({
  async "dist/build/server/entries/pages/arr/new/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_factory();
    await init_generalSettings();
    init_exports();
    RADARR_DEFAULT_DELAY_PROFILE = {
      enableUsenet: true,
      enableTorrent: true,
      preferredProtocol: "torrent",
      usenetDelay: 600,
      torrentDelay: 600,
      bypassIfHighestQuality: false,
      bypassIfAboveCustomFormatScore: false,
      minimumCustomFormatScore: 0,
      tags: []
    };
    SONARR_DEFAULT_DELAY_PROFILE = {
      enableUsenet: true,
      enableTorrent: true,
      preferredProtocol: "torrent",
      usenetDelay: 600,
      torrentDelay: 600,
      bypassIfHighestQuality: false,
      bypassIfAboveCustomFormatScore: false,
      minimumCustomFormatScore: 0,
      tags: []
    };
    VALID_TYPES = ["radarr", "sonarr"];
    actions9 = { default: async ({ request }) => {
      const formData = await request.formData();
      const name = formData.get("name")?.toString().trim();
      const type = formData.get("type")?.toString().trim();
      const url = formData.get("url")?.toString().trim();
      const externalUrlRaw = formData.get("external_url")?.toString().trim() ?? "";
      const externalUrl = externalUrlRaw === "" ? null : externalUrlRaw;
      const apiKey = formData.get("api_key")?.toString().trim();
      const tagsJson = formData.get("tags")?.toString().trim();
      if (!name || !type || !url || !apiKey) {
        await logger.warn("Attempted to create instance with missing required fields", {
          source: "arr/new",
          meta: {
            name,
            type,
            url,
            hasApiKey: !!apiKey
          }
        });
        return fail(400, {
          error: "Name, type, URL, and API key are required",
          values: {
            name,
            type,
            url
          }
        });
      }
      if (!VALID_TYPES.includes(type)) {
        await logger.warn("Attempted to create instance with invalid type", {
          source: "arr/new",
          meta: {
            name,
            type,
            url
          }
        });
        return fail(400, {
          error: "Invalid arr type",
          values: {
            name,
            type,
            url
          }
        });
      }
      if (arrInstancesQueries.nameExists(name)) {
        await logger.warn("Attempted to create instance with duplicate name", {
          source: "arr/new",
          meta: {
            name,
            type
          }
        });
        return fail(400, {
          error: "An instance with this name already exists",
          values: {
            name,
            type,
            url
          }
        });
      }
      if (arrInstancesQueries.targetExists(type, url)) {
        await logger.warn("Attempted to create duplicate instance", {
          source: "arr/new",
          meta: {
            name,
            type,
            url
          }
        });
        return fail(400, {
          error: "This instance target is already configured",
          values: {
            name,
            type,
            url
          }
        });
      }
      let tags = [];
      if (tagsJson) try {
        const parsed = JSON.parse(tagsJson);
        if (Array.isArray(parsed)) tags = parsed;
      } catch (error2) {
        await logger.warn("Failed to parse tags JSON", {
          source: "arr/new",
          meta: {
            tagsJson,
            error: error2
          }
        });
      }
      let id;
      try {
        id = arrInstancesQueries.create({
          name,
          type,
          url,
          externalUrl,
          apiKey,
          tags
        });
        await logger.info(`Created new ${type} instance: ${name}`, {
          source: "arr/new",
          meta: {
            id,
            name,
            type,
            url,
            externalUrl
          }
        });
        if ((type === "radarr" || type === "sonarr") && generalSettingsQueries.shouldApplyDefaultDelayProfiles()) try {
          const client2 = createArrClient(type, url, apiKey);
          const defaultProfile = getDefaultDelayProfile(type);
          await client2.updateDelayProfile(1, {
            ...defaultProfile,
            id: 1,
            order: 2147483647
          });
          await logger.info(`Applied default delay profile to ${name}`, {
            source: "arr/new",
            meta: {
              id,
              type,
              profile: defaultProfile
            }
          });
        } catch (error2) {
          await logger.warn(`Failed to apply default delay profile to ${name}`, {
            source: "arr/new",
            meta: {
              id,
              type,
              error: error2 instanceof Error ? error2.message : error2
            }
          });
        }
      } catch (error2) {
        await logger.error("Failed to create arr instance", {
          source: "arr/new",
          meta: error2
        });
        return fail(500, {
          error: "Failed to create instance",
          values: {
            name,
            type,
            url
          }
        });
      }
      redirect(303, "/arr");
    } };
  }
});

// dist/build/server/entries/pages/arr/new/_page.svelte.js
var page_svelte_exports11 = {};
__export(page_svelte_exports11, {
  default: () => _page11
});
function _page11($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let typeFromUrl;
    let form = $$props["form"];
    $: typeFromUrl = store_get($$store_subs ??= {}, "$page", page).url.searchParams.get("type") || "";
    PageMeta($$renderer2, { title: "Arr Instance \xB7 New" });
    $$renderer2.push(`<!----> <div class="p-8">`);
    InstanceForm($$renderer2, {
      mode: "create",
      form,
      initialType: typeFromUrl
    });
    $$renderer2.push(`<!----></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { form });
  });
}
var init_page_svelte11 = __esm({
  "dist/build/server/entries/pages/arr/new/_page.svelte.js"() {
    "use strict";
    init_server();
    init_InstanceForm();
    init_stores();
    init_PageMeta();
  }
});

// dist/build/server/nodes/18.js
var __exports19 = {};
__export(__exports19, {
  component: () => component18,
  fonts: () => fonts19,
  imports: () => imports19,
  index: () => index19,
  server: () => page_server_ts_exports12,
  server_id: () => server_id18,
  stylesheets: () => stylesheets19
});
var index19, component_cache18, component18, server_id18, imports19, stylesheets19, fonts19;
var init__19 = __esm({
  async "dist/build/server/nodes/18.js"() {
    "use strict";
    await init_page_server_ts12();
    index19 = 18;
    component18 = async () => component_cache18 ??= (await Promise.resolve().then(() => (init_page_svelte11(), page_svelte_exports11))).default;
    server_id18 = "src/routes/arr/new/+page.server.ts";
    imports19 = ["_app/immutable/nodes/18.CNBUTu5S.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/R2NcgasX2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/BJGxfzgf2.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/COLvC_Ug.js", "_app/immutable/chunks/C47WFcPn.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/CK2yQf0C.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets19 = [];
    fonts19 = [];
  }
});

// dist/build/server/entries/pages/arr/upgrades/info/_page.svelte.js
var page_svelte_exports12 = {};
__export(page_svelte_exports12, {
  default: () => _page12
});
function _page12($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    const radarrFields = getFilterFields("radarr");
    const sonarrFields = getFilterFields("sonarr");
    const typeLabels = {
      boolean: "Yes/No",
      select: "Selection",
      text: "Text",
      number: "Number",
      date: "Date"
    };
    const badgeBase = "inline-flex items-center rounded font-medium px-1.5 py-0.5 text-[10px]";
    const badgeAccent = "bg-accent-100 text-accent-800 dark:bg-accent-900 dark:text-accent-200";
    const badgeNeutral = "bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300";
    const fieldColumns = [
      {
        key: "label",
        header: "Field",
        sortable: false
      },
      {
        key: "valueType",
        header: "Type",
        sortable: false,
        cell: (row) => ({ html: `<span class="${badgeBase} ${badgeAccent}">${typeLabels[row.valueType] || row.valueType}</span>` })
      },
      {
        key: "description",
        header: "Description",
        sortable: false
      },
      {
        key: "operators",
        header: "Operators",
        sortable: false,
        cell: (row) => ({ html: row.operators.map((op) => `<span class="${badgeBase} ${badgeNeutral}">${op.label}</span>`).join(" ") })
      }
    ];
    const selectorColumns = [{
      key: "label",
      header: "Selector",
      sortable: false
    }, {
      key: "description",
      header: "Description",
      sortable: false
    }];
    const modeColumns = [{
      key: "label",
      header: "Mode",
      sortable: false
    }, {
      key: "description",
      header: "Description",
      sortable: false
    }];
    const concepts = [
      {
        id: "filters",
        name: "Filters",
        summary: "Rules that define what qualifies for upgrade",
        details: "Combine conditions with AND/OR logic. Example: monitored = true AND cutoff met = false AND (popularity > 30 OR year >= 2020). Rules can be nested into groups for complex logic."
      },
      {
        id: "selectors",
        name: "Selectors",
        summary: "How to prioritize from filtered results",
        details: "After filtering narrows the pool, the selector picks which items actually get searched. Random spreads searches evenly over time. Oldest/Newest prioritizes by when items were added. Lowest Score targets items most in need of upgrades. Most/Least Popular lets you prioritize based on TMDb popularity."
      },
      {
        id: "count-cooldown",
        name: "Count & Cooldown",
        summary: "Batch size and search throttling",
        details: "Count limits how many items get searched per run - prevents overwhelming your indexers. Cooldown (in hours) prevents re-searching the same item too soon. Items are tagged with the search date so they're skipped until the cooldown expires."
      },
      {
        id: "cutoff",
        name: "Cutoff %",
        summary: "Quality score threshold for the Cutoff Met field",
        details: `The Cutoff Met filter field checks if an item's custom format score has reached this percentage of the profile's cutoff score. Radarr uses the movie file score; Sonarr uses the average score across every episode file in the series. Set to 80% means items below 80% of their cutoff will have "Cutoff Met = false".`
      },
      {
        id: "multiple-filters",
        name: "Multiple Filters",
        summary: "Different strategies for different content",
        details: 'Create separate filters for different upgrade strategies. A "High Priority" filter for popular recent content, a "Backlog" filter for older items. The filter mode controls which runs each cycle - round robin cycles through in order, random shuffle picks one at random.'
      },
      {
        id: "dry-run",
        name: "Dry Run",
        summary: "Test without downloading",
        details: 'Click the "Dry Run" button to test your filters. The full filter/select pipeline runs and searches your indexers for releases, but skips downloading. Check the run history to see what would have been upgraded. Note: dry runs are rate-limited to once every 10 minutes since they still search indexers.'
      }
    ];
    const conceptColumns = [{
      key: "name",
      header: "Concept",
      sortable: false
    }, {
      key: "summary",
      header: "Summary",
      sortable: false
    }];
    PageMeta($$renderer2, { title: "Upgrades Help" });
    $$renderer2.push(`<!----> <div class="p-8">`);
    StickyCard($$renderer2, {
      position: "top",
      $$slots: {
        left: ($$renderer3) => {
          $$renderer3.push(`<div slot="left"><h1 class="text-xl font-semibold text-neutral-900 dark:text-neutral-50">How Upgrades Work</h1></div>`);
        },
        right: ($$renderer3) => {
          $$renderer3.push(`<div slot="right">`);
          Button($$renderer3, {
            text: "Back",
            icon: Arrow_left
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    $$renderer2.push(`<!----> <div class="mt-6 space-y-8 px-4"><div class="text-neutral-600 dark:text-neutral-400"><p>Radarr and Sonarr don't search for the best release. They monitor RSS feeds and grab the
				first thing that qualifies as an upgrade. To get optimal releases, you need manual searches.
				This module automates that: <span class="font-medium text-neutral-700 dark:text-neutral-300">Filter</span> your library, <span class="font-medium text-neutral-700 dark:text-neutral-300">Select</span> items to
				search, then <span class="font-medium text-neutral-700 dark:text-neutral-300">Search</span> for better releases.</p></div> <section><h2 class="mb-3 text-lg font-semibold text-neutral-900 dark:text-neutral-100">Concepts</h2> `);
    ExpandableTable($$renderer2, {
      columns: conceptColumns,
      data: concepts,
      getRowId: (row) => row.id,
      emptyMessage: "No concepts",
      chevronPosition: "right",
      flushExpanded: true,
      $$slots: { expanded: ($$renderer3, { row }) => {
        $$renderer3.push(`<div class="px-6 py-4"><p class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(row.details)}</p></div>`);
      } }
    });
    $$renderer2.push(`<!----></section> <section><h2 class="mb-3 text-lg font-semibold text-neutral-900 dark:text-neutral-100">Selectors</h2> `);
    Table2($$renderer2, {
      columns: selectorColumns,
      data: selectors,
      emptyMessage: "No selectors"
    });
    $$renderer2.push(`<!----></section> <section><h2 class="mb-3 text-lg font-semibold text-neutral-900 dark:text-neutral-100">Filter Modes</h2> `);
    Table2($$renderer2, {
      columns: modeColumns,
      data: filterModes,
      emptyMessage: "No modes"
    });
    $$renderer2.push(`<!----></section> <section><h2 class="mb-3 text-lg font-semibold text-neutral-900 dark:text-neutral-100">Radarr Filter Fields</h2> `);
    Table2($$renderer2, {
      columns: fieldColumns,
      data: radarrFields,
      emptyMessage: "No fields"
    });
    $$renderer2.push(`<!----></section> <section><h2 class="mb-3 text-lg font-semibold text-neutral-900 dark:text-neutral-100">Sonarr Filter Fields</h2> `);
    Table2($$renderer2, {
      columns: fieldColumns,
      data: sonarrFields,
      emptyMessage: "No fields"
    });
    $$renderer2.push(`<!----></section></div></div>`);
  });
}
var init_page_svelte12 = __esm({
  "dist/build/server/entries/pages/arr/upgrades/info/_page.svelte.js"() {
    "use strict";
    init_server();
    init_selectors();
    init_arrow_left();
    init_Button();
    init_ExpandableTable();
    init_PageMeta();
    init_Table();
    init_StickyCard();
  }
});

// dist/build/server/nodes/19.js
var __exports20 = {};
__export(__exports20, {
  component: () => component19,
  fonts: () => fonts20,
  imports: () => imports20,
  index: () => index20,
  stylesheets: () => stylesheets20
});
var index20, component_cache19, component19, imports20, stylesheets20, fonts20;
var init__20 = __esm({
  "dist/build/server/nodes/19.js"() {
    "use strict";
    index20 = 19;
    component19 = async () => component_cache19 ??= (await Promise.resolve().then(() => (init_page_svelte12(), page_svelte_exports12))).default;
    imports20 = ["_app/immutable/nodes/19.-8bUcQV9.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/9MSyFmmd.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/C47WFcPn.js", "_app/immutable/chunks/BaewglP2.js"];
    stylesheets20 = ["_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts20 = [];
  }
});

// dist/build/server/chunks/userAgent.js
function parseUserAgent(ua) {
  if (!ua) return {
    browser: "Unknown",
    os: "Unknown",
    deviceType: "Unknown"
  };
  return {
    browser: parseBrowser(ua),
    os: parseOS(ua),
    deviceType: parseDeviceType(ua)
  };
}
function parseBrowser(ua) {
  const edge = ua.match(/Edg(?:e|A|iOS)?\/(\d+)/);
  if (edge) return `Edge ${edge[1]}`;
  const opera = ua.match(/(?:OPR|Opera)\/(\d+)/);
  if (opera) return `Opera ${opera[1]}`;
  const firefox = ua.match(/Firefox\/(\d+)/);
  if (firefox) return `Firefox ${firefox[1]}`;
  if (ua.includes("Safari") && !ua.includes("Chrome") && !ua.includes("Chromium")) {
    const safari = ua.match(/Version\/(\d+)/);
    if (safari) return `Safari ${safari[1]}`;
    return "Safari";
  }
  const chrome = ua.match(/(?:Chrome|Chromium)\/(\d+)/);
  if (chrome) return `Chrome ${chrome[1]}`;
  const ie2 = ua.match(/(?:MSIE |rv:)(\d+)/);
  if (ie2) return `IE ${ie2[1]}`;
  const generic = ua.match(/(\w+)\/(\d+)/);
  if (generic) return `${generic[1]} ${generic[2]}`;
  return "Unknown";
}
function parseOS(ua) {
  const ios = ua.match(/(?:iPhone|iPad|iPod).*?OS (\d+)/);
  if (ios) return `iOS ${ios[1]}`;
  const android = ua.match(/Android (\d+(?:\.\d+)?)/);
  if (android) return `Android ${android[1]}`;
  if (ua.includes("Windows")) {
    if (ua.includes("Windows NT 10.0")) return "Windows";
    if (ua.includes("Windows NT 6.3")) return "Windows 8.1";
    if (ua.includes("Windows NT 6.2")) return "Windows 8";
    if (ua.includes("Windows NT 6.1")) return "Windows 7";
    if (ua.includes("Windows NT 6.0")) return "Windows Vista";
    if (ua.includes("Windows NT 5.1")) return "Windows XP";
    return "Windows";
  }
  const mac = ua.match(/Mac OS X (\d+)[_.](\d+)/);
  if (mac) {
    const major = parseInt(mac[1]);
    const minor = parseInt(mac[2]);
    if (major >= 11) return `macOS ${major}`;
    return `macOS ${major}.${minor}`;
  }
  if (ua.includes("Macintosh")) return "macOS";
  if (ua.includes("Ubuntu")) return "Ubuntu";
  if (ua.includes("Fedora")) return "Fedora";
  if (ua.includes("Debian")) return "Debian";
  if (ua.includes("Arch")) return "Arch Linux";
  if (ua.includes("CrOS")) return "Chrome OS";
  if (ua.includes("Linux")) return "Linux";
  if (ua.includes("FreeBSD")) return "FreeBSD";
  if (ua.includes("OpenBSD")) return "OpenBSD";
  return "Unknown";
}
function parseDeviceType(ua) {
  if (ua.includes("iPad") || ua.includes("Tablet") || ua.includes("Android") && !ua.includes("Mobile")) return "Tablet";
  if (ua.includes("Mobile") || ua.includes("iPhone") || ua.includes("iPod") || ua.includes("Android") || ua.includes("webOS") || ua.includes("BlackBerry") || ua.includes("Opera Mini") || ua.includes("IEMobile")) return "Mobile";
  return "Desktop";
}
var init_userAgent = __esm({
  "dist/build/server/chunks/userAgent.js"() {
    "use strict";
  }
});

// dist/build/server/chunks/password.js
function hashPassword(password) {
  return hash2(password);
}
function verifyPassword(password, storedHash) {
  return verify(password, storedHash);
}
var init_password = __esm({
  async "dist/build/server/chunks/password.js"() {
    "use strict";
    await init_authSettings();
  }
});

// dist/build/server/entries/pages/auth/login/_page.server.ts.js
var page_server_ts_exports13 = {};
__export(page_server_ts_exports13, {
  actions: () => actions10,
  load: () => load17
});
function isCommonAttackUsername(username) {
  return COMMON_ATTACK_USERNAMES.includes(username.toLowerCase());
}
function levenshteinDistance(a2, b3) {
  const matrix = [];
  for (let i = 0; i <= b3.length; i++) matrix[i] = [i];
  for (let j2 = 0; j2 <= a2.length; j2++) matrix[0][j2] = j2;
  for (let i = 1; i <= b3.length; i++) for (let j2 = 1; j2 <= a2.length; j2++) if (b3.charAt(i - 1) === a2.charAt(j2 - 1)) matrix[i][j2] = matrix[i - 1][j2 - 1];
  else matrix[i][j2] = Math.min(matrix[i - 1][j2 - 1] + 1, matrix[i][j2 - 1] + 1, matrix[i - 1][j2] + 1);
  return matrix[b3.length][a2.length];
}
function findSimilarUsername(attempted, existingUsernames) {
  const attemptedLower = attempted.toLowerCase();
  for (const existing of existingUsernames) {
    const distance = levenshteinDistance(attemptedLower, existing.toLowerCase());
    if (distance > 0 && distance <= 2) return existing;
  }
  return null;
}
function getAttemptCategory(analysis) {
  if (analysis.reason === "invalid_password" || analysis.similarUser) return "typo";
  if (analysis.isCommonAttack) return "suspicious";
  return "unknown";
}
function analyzeLoginFailure(username, existingUsernames, userExists) {
  if (userExists) return {
    reason: "invalid_password",
    similarUser: null,
    isCommonAttack: false
  };
  return {
    reason: "user_not_found",
    similarUser: findSimilarUsername(username, existingUsernames),
    isCommonAttack: isCommonAttackUsername(username)
  };
}
function formatLoginFailure(analysis) {
  if (analysis.reason === "invalid_password") return "invalid password";
  if (analysis.similarUser) return `unknown user (similar to '${analysis.similarUser}')`;
  if (analysis.isCommonAttack) return "unknown user (common attack username)";
  return "unknown user";
}
var COMMON_ATTACK_USERNAMES, load17, actions10;
var init_page_server_ts13 = __esm({
  async "dist/build/server/entries/pages/auth/login/_page.server.ts.js"() {
    "use strict";
    await init_db();
    init_config();
    await init_users();
    await init_authSettings();
    init_network();
    init_userAgent();
    await init_password();
    await init_rateLimit();
    init_exports();
    COMMON_ATTACK_USERNAMES = [
      "admin",
      "administrator",
      "root",
      "user",
      "test",
      "guest",
      "demo",
      "system",
      "operator",
      "superuser",
      "master",
      "default"
    ];
    load17 = () => {
      if (config.authMode === "oidc") return { authMode: "oidc" };
      if (!usersQueries.existsLocal()) throw redirect(303, "/auth/setup");
      return { authMode: config.authMode };
    };
    actions10 = { default: async (event) => {
      const { request, cookies } = event;
      const ip = getClientIp(event, false);
      const displayIp = getClientIp(event);
      const rateLimit = checkRateLimit(ip, "/auth/login");
      if (rateLimit.blocked) {
        await logger.warn("Login rate limited", {
          source: "Auth:RateLimit",
          meta: {
            ip,
            retryAfter: rateLimit.retryAfter
          }
        });
        return fail(429, {
          error: "Too many login attempts. Please try again later.",
          username: ""
        });
      }
      const formData = await request.formData();
      const username = formData.get("username")?.trim();
      const password = formData.get("password");
      if (!username || !password) return fail(400, {
        error: "Username and password are required",
        username
      });
      const user = usersQueries.getByUsername(username);
      if (!user) {
        const analysis = analyzeLoginFailure(username, usersQueries.getAllUsernames(), false);
        const category = getAttemptCategory(analysis);
        recordFailedAttempt(ip, "/auth/login", category);
        await logger.warn(`Login failed for '${username}': ${formatLoginFailure(analysis)}`, {
          source: "Auth:Login",
          meta: {
            username,
            ip,
            category,
            ...analysis
          }
        });
        return fail(400, {
          error: "Invalid username or password",
          username
        });
      }
      if (!await verifyPassword(password, user.password_hash)) {
        const analysis = analyzeLoginFailure(username, [], true);
        const category = getAttemptCategory(analysis);
        recordFailedAttempt(ip, "/auth/login", category);
        await logger.warn(`Login failed for '${username}': ${formatLoginFailure(analysis)}`, {
          source: "Auth:Login",
          meta: {
            username,
            ip,
            category,
            ...analysis
          }
        });
        return fail(400, {
          error: "Invalid username or password",
          username
        });
      }
      clearAttempts(ip);
      const userAgent = request.headers.get("user-agent") ?? "";
      const parsed = parseUserAgent(userAgent);
      const durationHours = authSettingsQueries.getSessionDurationHours();
      const sessionId = sessionsQueries.create(user.id, durationHours, {
        ipAddress: displayIp,
        userAgent,
        browser: parsed.browser,
        os: parsed.os,
        deviceType: parsed.deviceType
      });
      await logger.info(`Login successful for '${username}'`, {
        source: "Auth:Login",
        meta: {
          username,
          ip,
          browser: parsed.browser,
          device: parsed.deviceType
        }
      });
      const expires = new Date(Date.now() + durationHours * 60 * 60 * 1e3);
      cookies.set("session", sessionId, {
        path: "/",
        httpOnly: true,
        sameSite: "lax",
        secure: config.origin.startsWith("https://"),
        expires
      });
      throw redirect(303, "/");
    } };
  }
});

// dist/build/server/chunks/key-round.js
function Key_round($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "key-round" },
    props,
    { iconNode: [["path", { "d": "M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z" }], ["circle", {
      "cx": "16.5",
      "cy": "7.5",
      "r": ".5",
      "fill": "currentColor"
    }]] }
  ]));
}
var init_key_round = __esm({
  "dist/build/server/chunks/key-round.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/entries/pages/auth/login/_page.svelte.js
var page_svelte_exports13 = {};
__export(page_svelte_exports13, {
  default: () => _page13
});
function Log_in($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "log-in" },
    props,
    { iconNode: [
      ["path", { "d": "m10 17 5-5-5-5" }],
      ["path", { "d": "M15 12H3" }],
      ["path", { "d": "M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" }]
    ] }
  ]));
}
function _page13($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    let form = $$props["form"];
    let submitting = false;
    let username = form?.username ?? "";
    let password = "";
    $: if (form?.error) alertStore.add("error", form.error);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: "Login" });
      $$renderer3.push(`<!----> <div class="flex min-h-screen items-center justify-center bg-neutral-100 p-4 dark:bg-neutral-900"><div class="w-full max-w-sm"><div class="mb-8 flex items-center gap-4"><img${attr("src", logo_512_default)} alt="Profilarr logo" class="h-12 w-12"/> <div><h1 class="text-xl font-bold text-neutral-900 dark:text-neutral-50">Welcome back</h1> <p class="text-sm text-neutral-600 dark:text-neutral-400">Sign in to continue.</p></div></div> `);
      if (data.authMode === "oidc") {
        $$renderer3.push("<!--[0-->");
        Button($$renderer3, {
          href: "/auth/oidc/login",
          variant: "primary",
          size: "md",
          fullWidth: true,
          icon: Key_round,
          text: "Sign in with SSO"
        });
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<form method="POST" class="space-y-6">`);
        FormInput($$renderer3, {
          name: "username",
          label: "Username",
          hideLabel: true,
          type: "text",
          placeholder: "Username",
          autocomplete: "username",
          get value() {
            return username;
          },
          set value($$value) {
            username = $$value;
            $$settled = false;
          }
        });
        $$renderer3.push(`<!----> `);
        FormInput($$renderer3, {
          name: "password",
          label: "Password",
          hideLabel: true,
          type: "password",
          placeholder: "Password",
          autocomplete: "current-password",
          private_: true,
          get value() {
            return password;
          },
          set value($$value) {
            password = $$value;
            $$settled = false;
          }
        });
        $$renderer3.push(`<!----> `);
        Button($$renderer3, {
          type: "submit",
          variant: "primary",
          size: "md",
          fullWidth: true,
          icon: Log_in,
          text: "Sign In",
          disabled: submitting
        });
        $$renderer3.push(`<!----></form>`);
      }
      $$renderer3.push(`<!--]--></div></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      data,
      form
    });
  });
}
var init_page_svelte13 = __esm({
  "dist/build/server/entries/pages/auth/login/_page.svelte.js"() {
    "use strict";
    init_server();
    init_logo_512();
    init_Icon();
    init_key_round();
    init_Button();
    init_store2();
    init_forms();
    init_PageMeta();
    init_FormInput();
  }
});

// dist/build/server/nodes/20.js
var __exports21 = {};
__export(__exports21, {
  component: () => component20,
  fonts: () => fonts21,
  imports: () => imports21,
  index: () => index21,
  server: () => page_server_ts_exports13,
  server_id: () => server_id19,
  stylesheets: () => stylesheets21
});
var index21, component_cache20, component20, server_id19, imports21, stylesheets21, fonts21;
var init__21 = __esm({
  async "dist/build/server/nodes/20.js"() {
    "use strict";
    await init_page_server_ts13();
    index21 = 20;
    component20 = async () => component_cache20 ??= (await Promise.resolve().then(() => (init_page_svelte13(), page_svelte_exports13))).default;
    server_id19 = "src/routes/auth/login/+page.server.ts";
    imports21 = ["_app/immutable/nodes/20.D57Pecuo.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BDqLURZS.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BjTZeLXW.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js"];
    stylesheets21 = [];
    fonts21 = [];
  }
});

// dist/build/server/entries/pages/auth/setup/_page.server.ts.js
var page_server_ts_exports14 = {};
__export(page_server_ts_exports14, {
  actions: () => actions11,
  load: () => load18
});
var load18, actions11;
var init_page_server_ts14 = __esm({
  async "dist/build/server/entries/pages/auth/setup/_page.server.ts.js"() {
    "use strict";
    await init_db();
    init_config();
    await init_users();
    await init_authSettings();
    init_network();
    init_userAgent();
    await init_password();
    init_exports();
    load18 = () => {
      if (config.authMode === "off") throw redirect(303, "/");
      if (usersQueries.existsLocal()) throw redirect(303, "/");
      return {};
    };
    actions11 = { default: async (event) => {
      const { request, cookies } = event;
      if (config.authMode === "off") throw redirect(303, "/");
      if (usersQueries.existsLocal()) {
        logger.warn("Setup attempt after user already exists", {
          source: "Auth:Setup",
          meta: { ip: getClientIp(event, false) }
        });
        throw redirect(303, "/");
      }
      const formData = await request.formData();
      const username = formData.get("username")?.trim();
      const password = formData.get("password");
      const confirmPassword = formData.get("confirmPassword");
      if (!username) return fail(400, {
        error: "Username is required",
        username
      });
      if (username.length < 3) return fail(400, {
        error: "Username must be at least 3 characters",
        username
      });
      if (!password) return fail(400, {
        error: "Password is required",
        username
      });
      if (password.length < 8) return fail(400, {
        error: "Password must be at least 8 characters",
        username
      });
      if (password !== confirmPassword) return fail(400, {
        error: "Passwords do not match",
        username
      });
      try {
        const passwordHash = await hashPassword(password);
        const userId = usersQueries.create(username, passwordHash);
        if (!userId) return fail(500, {
          error: "Failed to create account",
          username
        });
        const ipAddress = getClientIp(event);
        const userAgent = request.headers.get("user-agent") ?? "";
        const parsed = parseUserAgent(userAgent);
        const durationHours = authSettingsQueries.getSessionDurationHours();
        const sessionId = sessionsQueries.create(userId, durationHours, {
          ipAddress,
          userAgent,
          browser: parsed.browser,
          os: parsed.os,
          deviceType: parsed.deviceType
        });
        await logger.info(`Account created: '${username}'`, {
          source: "Auth",
          meta: {
            username,
            ip: ipAddress
          }
        });
        const expires = new Date(Date.now() + durationHours * 60 * 60 * 1e3);
        cookies.set("session", sessionId, {
          path: "/",
          httpOnly: true,
          sameSite: "lax",
          secure: config.origin.startsWith("https://"),
          expires
        });
        throw redirect(303, "/");
      } catch (err) {
        if (err instanceof Response || err && typeof err === "object" && "status" in err) throw err;
        return fail(500, {
          error: "Failed to create account",
          username
        });
      }
    } };
  }
});

// dist/build/server/chunks/shield.js
function Shield($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "shield" },
    props,
    { iconNode: [["path", { "d": "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" }]] }
  ]));
}
var init_shield = __esm({
  "dist/build/server/chunks/shield.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/entries/pages/auth/setup/_page.svelte.js
var page_svelte_exports14 = {};
__export(page_svelte_exports14, {
  default: () => _page14
});
function Shield_off($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "shield-off" },
    props,
    { iconNode: [
      ["path", { "d": "m2 2 20 20" }],
      ["path", { "d": "M5 5a1 1 0 0 0-1 1v7c0 5 3.5 7.5 7.67 8.94a1 1 0 0 0 .67.01c2.35-.82 4.48-1.97 5.9-3.71" }],
      ["path", { "d": "M9.309 3.652A12.252 12.252 0 0 0 11.24 2.28a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1v7a9.784 9.784 0 0 1-.08 1.264" }]
    ] }
  ]));
}
function User_plus($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "user-plus" },
    props,
    { iconNode: [
      ["path", { "d": "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }],
      ["circle", {
        "cx": "9",
        "cy": "7",
        "r": "4"
      }],
      ["line", {
        "x1": "19",
        "x2": "19",
        "y1": "8",
        "y2": "14"
      }],
      ["line", {
        "x1": "22",
        "x2": "16",
        "y1": "11",
        "y2": "11"
      }]
    ] }
  ]));
}
function _page14($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let form = $$props["form"];
    let submitting = false;
    let username = form?.username ?? "";
    let password = "";
    let confirmPassword = "";
    $: if (form?.error) alertStore.add("error", form.error);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: "Setup" });
      $$renderer3.push(`<!----> <div class="flex min-h-screen items-center justify-center bg-neutral-100 p-4 dark:bg-neutral-900"><div class="flex w-full max-w-3xl flex-col gap-8 md:flex-row md:gap-12"><div class="flex flex-col space-y-6 md:flex-1"><div class="flex items-center gap-4"><img${attr("src", logo_512_default)} alt="Profilarr logo" class="h-12 w-12"/> <div><h1 class="text-xl font-bold text-neutral-900 dark:text-neutral-50">Welcome to Profilarr</h1> <p class="text-sm text-neutral-600 dark:text-neutral-400">Create your admin account to get started.</p></div></div> <div class="hidden rounded-xl border border-neutral-200/60 bg-white/50 p-5 shadow-sm backdrop-blur-sm md:block dark:border-neutral-700/60 dark:bg-neutral-800/50"><p class="text-xs font-medium text-neutral-700 dark:text-neutral-300">Configure authentication via the <code class="rounded bg-neutral-200 px-1 py-0.5 text-[11px] dark:bg-neutral-700">AUTH</code> environment variable:</p> <ul class="mt-3 space-y-2 text-xs text-neutral-600 dark:text-neutral-400"><li class="flex items-center gap-2">`);
      Shield($$renderer3, {
        size: 12,
        class: "text-neutral-400"
      });
      $$renderer3.push(`<!----> <code class="font-mono text-neutral-800 dark:text-neutral-200">on</code> <span>\u2014 Full authentication</span> <span class="text-neutral-400 dark:text-neutral-500">(default)</span></li> <li class="flex items-center gap-2">`);
      Wifi($$renderer3, {
        size: 12,
        class: "text-neutral-400"
      });
      $$renderer3.push(`<!----> <code class="font-mono text-neutral-800 dark:text-neutral-200">local</code> <span>\u2014 Skip auth for local network</span></li> <li class="flex items-center gap-2">`);
      Key_round($$renderer3, {
        size: 12,
        class: "text-neutral-400"
      });
      $$renderer3.push(`<!----> <code class="font-mono text-neutral-800 dark:text-neutral-200">oidc</code> <span>\u2014 Use external provider</span></li> <li class="flex items-center gap-2">`);
      Shield_off($$renderer3, {
        size: 12,
        class: "text-neutral-400"
      });
      $$renderer3.push(`<!----> <code class="font-mono text-neutral-800 dark:text-neutral-200">off</code> <span>\u2014 For reverse proxy setups</span></li></ul></div></div> <div class="w-full md:flex-1"><form method="POST" class="space-y-6">`);
      FormInput($$renderer3, {
        name: "username",
        label: "Username",
        hideLabel: true,
        type: "text",
        placeholder: "admin",
        autocomplete: "username",
        get value() {
          return username;
        },
        set value($$value) {
          username = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      FormInput($$renderer3, {
        name: "password",
        label: "Password",
        hideLabel: true,
        type: "password",
        placeholder: "Minimum 8 characters",
        autocomplete: "new-password",
        private_: true,
        get value() {
          return password;
        },
        set value($$value) {
          password = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      FormInput($$renderer3, {
        name: "confirmPassword",
        label: "Confirm Password",
        hideLabel: true,
        type: "password",
        placeholder: "Re-enter your password",
        autocomplete: "new-password",
        private_: true,
        get value() {
          return confirmPassword;
        },
        set value($$value) {
          confirmPassword = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      Button($$renderer3, {
        type: "submit",
        variant: "primary",
        size: "md",
        fullWidth: true,
        icon: User_plus,
        text: "Create Account",
        disabled: submitting
      });
      $$renderer3.push(`<!----></form></div></div></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, { form });
  });
}
var init_page_svelte14 = __esm({
  "dist/build/server/entries/pages/auth/setup/_page.svelte.js"() {
    "use strict";
    init_server();
    init_logo_512();
    init_Icon();
    init_key_round();
    init_Button();
    init_shield();
    init_wifi();
    init_store2();
    init_forms();
    init_PageMeta();
    init_FormInput();
  }
});

// dist/build/server/nodes/21.js
var __exports22 = {};
__export(__exports22, {
  component: () => component21,
  fonts: () => fonts22,
  imports: () => imports22,
  index: () => index22,
  server: () => page_server_ts_exports14,
  server_id: () => server_id20,
  stylesheets: () => stylesheets22
});
var index22, component_cache21, component21, server_id20, imports22, stylesheets22, fonts22;
var init__22 = __esm({
  async "dist/build/server/nodes/21.js"() {
    "use strict";
    await init_page_server_ts14();
    index22 = 21;
    component21 = async () => component_cache21 ??= (await Promise.resolve().then(() => (init_page_svelte14(), page_svelte_exports14))).default;
    server_id20 = "src/routes/auth/setup/+page.server.ts";
    imports22 = ["_app/immutable/nodes/21.g7EKAxvu.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BDqLURZS.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BjTZeLXW.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/BDIVGy2g.js", "_app/immutable/chunks/BJGxfzgf2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js"];
    stylesheets22 = [];
    fonts22 = [];
  }
});

// dist/build/server/entries/pages/custom-formats/_page.server.ts.js
var page_server_ts_exports15 = {};
__export(page_server_ts_exports15, {
  load: () => load19
});
var load19;
var init_page_server_ts15 = __esm({
  async "dist/build/server/entries/pages/custom-formats/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_lastDatabase();
    load19 = ({ cookies }) => {
      redirectToLastDatabase(cookies, "last_db_cf", "/custom-formats");
      return { databases: pcdManager.getAllPublic() };
    };
  }
});

// dist/build/server/entries/pages/custom-formats/_page.svelte.js
var page_svelte_exports15 = {};
__export(page_svelte_exports15, {
  default: () => _page15
});
function _page15($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: "Custom Formats" });
    $$renderer2.push(`<!----> `);
    if (data.databases.length === 0) {
      $$renderer2.push("<!--[0-->");
      EmptyState($$renderer2, {
        icon: Database2,
        title: "No Databases Linked",
        description: "Link a Profilarr Compliant Database to manage custom formats.",
        buttonText: "Link Database",
        buttonHref: "/databases/new",
        buttonIcon: Plus
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte15 = __esm({
  "dist/build/server/entries/pages/custom-formats/_page.svelte.js"() {
    "use strict";
    init_server();
    init_database2();
    init_plus();
    init_PageMeta();
    init_EmptyState();
  }
});

// dist/build/server/nodes/22.js
var __exports23 = {};
__export(__exports23, {
  component: () => component22,
  fonts: () => fonts23,
  imports: () => imports23,
  index: () => index23,
  server: () => page_server_ts_exports15,
  server_id: () => server_id21,
  stylesheets: () => stylesheets23
});
var index23, component_cache22, component22, server_id21, imports23, stylesheets23, fonts23;
var init__23 = __esm({
  async "dist/build/server/nodes/22.js"() {
    "use strict";
    await init_page_server_ts15();
    index23 = 22;
    component22 = async () => component_cache22 ??= (await Promise.resolve().then(() => (init_page_svelte15(), page_svelte_exports15))).default;
    server_id21 = "src/routes/custom-formats/+page.server.ts";
    imports23 = ["_app/immutable/nodes/22.BaFRlc6m.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D_awjkBZ.js", "_app/immutable/chunks/B66v-P2b.js"];
    stylesheets23 = [];
    fonts23 = [];
  }
});

// dist/build/server/chunks/customFormats.js
function esc5(value2) {
  return value2.replace(/'/g, "''");
}
async function deleteTest(options2) {
  const { databaseId, layer, formatName, current: current3 } = options2;
  const currentDescription = current3.description ?? null;
  const deleteTestQuery = {
    sql: `DELETE FROM custom_format_tests
WHERE custom_format_name = '${esc5(formatName)}'
  AND title = '${esc5(current3.title)}'
  AND type = '${esc5(current3.type)}'
  AND should_match = ${current3.should_match ? 1 : 0}
  AND description ${currentDescription === null ? "IS NULL" : `= '${esc5(currentDescription)}'`}`,
    parameters: [],
    query: {}
  };
  return await writeOperation({
    databaseId,
    layer,
    description: `delete-test-${formatName}`,
    queries: [deleteTestQuery],
    desiredState: {
      deleted: true,
      custom_format_name: formatName,
      title: current3.title,
      type: current3.type,
      should_match: current3.should_match,
      description: currentDescription,
      test_title: current3.title,
      test_type: current3.type,
      test_should_match: current3.should_match,
      test_description: currentDescription
    },
    metadata: {
      operation: "delete",
      entity: "custom_format",
      name: formatName,
      stableKey: {
        key: "custom_format_name",
        value: formatName
      },
      changedFields: ["deleted"],
      summary: "Delete custom format test",
      title: `Delete test for custom format "${formatName}"`
    }
  });
}
async function list3(cache3) {
  const db2 = cache3.kb;
  const formats = await db2.selectFrom("custom_formats").select([
    "id",
    "name",
    "description"
  ]).orderBy(sql`name COLLATE NOCASE`).execute();
  if (formats.length === 0) return [];
  const formatNames = formats.map((f2) => f2.name);
  const allTags = await db2.selectFrom("custom_format_tags as cft").innerJoin("tags as t", "t.name", "cft.tag_name").select([
    "cft.custom_format_name",
    "t.name as tag_name",
    "t.created_at as tag_created_at"
  ]).where("cft.custom_format_name", "in", formatNames).orderBy("cft.custom_format_name").orderBy("t.name").execute();
  const allConditions = await db2.selectFrom("custom_format_conditions").select([
    "custom_format_name",
    "name",
    "type",
    "required",
    "negate"
  ]).where("custom_format_name", "in", formatNames).execute();
  const testCounts = await db2.selectFrom("custom_format_tests").select(["custom_format_name"]).select((eb) => eb.fn.count("title").as("count")).where("custom_format_name", "in", formatNames).groupBy("custom_format_name").execute();
  const referenceCounts = await getProfileRefCountsForCustomFormats(cache3, formatNames);
  const testCountMap = /* @__PURE__ */ new Map();
  for (const tc of testCounts) testCountMap.set(tc.custom_format_name, Number(tc.count));
  const tagsMap = /* @__PURE__ */ new Map();
  for (const tag2 of allTags) {
    if (!tagsMap.has(tag2.custom_format_name)) tagsMap.set(tag2.custom_format_name, []);
    tagsMap.get(tag2.custom_format_name).push({
      name: tag2.tag_name,
      created_at: tag2.tag_created_at
    });
  }
  const conditionsMap = /* @__PURE__ */ new Map();
  for (const condition of allConditions) {
    if (!conditionsMap.has(condition.custom_format_name)) conditionsMap.set(condition.custom_format_name, []);
    conditionsMap.get(condition.custom_format_name).push({
      name: condition.name,
      type: condition.type,
      required: condition.required === 1,
      negate: condition.negate === 1
    });
  }
  return formats.map((format) => ({
    id: format.id,
    name: format.name,
    description: format.description,
    tags: tagsMap.get(format.name) || [],
    conditions: conditionsMap.get(format.name) || [],
    testCount: testCountMap.get(format.name) || 0,
    referenceCount: referenceCounts.get(format.name) || 0
  }));
}
async function remove2(options2) {
  const { databaseId, cache: cache3, layer, formatName } = options2;
  const db2 = cache3.kb;
  const queries = [];
  const groupId = uuid();
  if (generalSettingsQueries.shouldFailOnReferencedDelete()) {
    const profileRefs = await getProfileRefsForCustomFormat(cache3, formatName);
    if (profileRefs.length > 0) return {
      success: false,
      error: `Referenced by ${profileRefs.length} quality profile${profileRefs.length === 1 ? "" : "s"}`
    };
  }
  const dependentScores = await db2.selectFrom("quality_profile_custom_formats").select([
    "quality_profile_name",
    "custom_format_name",
    "arr_type",
    "score"
  ]).where("custom_format_name", "=", formatName).orderBy("quality_profile_name").orderBy("arr_type").execute();
  const scoresByProfile = /* @__PURE__ */ new Map();
  for (const score of dependentScores) {
    if (!scoresByProfile.has(score.quality_profile_name)) scoresByProfile.set(score.quality_profile_name, []);
    scoresByProfile.get(score.quality_profile_name).push({
      custom_format_name: score.custom_format_name,
      arr_type: score.arr_type,
      score: score.score
    });
  }
  const formatRow = await db2.selectFrom("custom_formats").select(["description", "include_in_rename"]).where("name", "=", formatName).executeTakeFirst();
  const conditionCountRow = await db2.selectFrom("custom_format_conditions").select(db2.fn.count("custom_format_name").as("count")).where("custom_format_name", "=", formatName).executeTakeFirst();
  const testCountRow = await db2.selectFrom("custom_format_tests").select(db2.fn.count("custom_format_name").as("count")).where("custom_format_name", "=", formatName).executeTakeFirst();
  const tagCountRow = await db2.selectFrom("custom_format_tags").select(db2.fn.count("custom_format_name").as("count")).where("custom_format_name", "=", formatName).executeTakeFirst();
  const deleteFormat = db2.deleteFrom("custom_formats").where("name", "=", formatName).compile();
  for (const [profileName2, scores] of scoresByProfile.entries()) {
    const scoreQueries = scores.map((score) => db2.deleteFrom("quality_profile_custom_formats").where("quality_profile_name", "=", profileName2).where("custom_format_name", "=", score.custom_format_name).where("arr_type", "=", score.arr_type).where("score", "=", score.score).compile());
    const result = await writeOperation({
      databaseId,
      layer,
      description: `update-quality-profile-scoring-${profileName2}`,
      queries: scoreQueries,
      desiredState: { custom_format_scores: scores.map((score) => ({
        custom_format_name: score.custom_format_name,
        arr_type: score.arr_type,
        from: score.score,
        to: null
      })) },
      metadata: {
        operation: "update",
        entity: "quality_profile",
        name: profileName2,
        stableKey: {
          key: "quality_profile_name",
          value: profileName2
        },
        groupId,
        generated: true,
        changedFields: ["custom_format_scores"],
        summary: "Update quality profile scoring",
        title: `Update scoring for quality profile "${profileName2}"`
      }
    });
    if (!result.success) return result;
  }
  queries.push(deleteFormat);
  return await writeOperation({
    databaseId,
    layer,
    description: `delete-custom-format-${formatName}`,
    queries,
    desiredState: {
      deleted: true,
      name: formatName,
      description: formatRow?.description ?? null,
      include_in_rename: formatRow?.include_in_rename === 1,
      counts: {
        conditions: conditionCountRow?.count ?? 0,
        tests: testCountRow?.count ?? 0,
        tags: tagCountRow?.count ?? 0
      }
    },
    metadata: {
      operation: "delete",
      entity: "custom_format",
      name: formatName,
      stableKey: {
        key: "custom_format_name",
        value: formatName
      },
      groupId,
      changedFields: ["deleted"],
      summary: "Delete custom format",
      title: `Delete custom format "${formatName}"`
    }
  });
}
function filterConditionsForArrType(conditions, arrType) {
  return conditions.filter((condition) => {
    if (condition.arrType !== "all" && condition.arrType !== arrType) return false;
    if (condition.type === "quality_modifier" && arrType === "sonarr") return false;
    if (condition.type === "release_type" && arrType === "radarr") return false;
    return true;
  });
}
function extractPatternsByType(customFormats) {
  const title = /* @__PURE__ */ new Set();
  const edition = /* @__PURE__ */ new Set();
  const releaseGroup = /* @__PURE__ */ new Set();
  for (const cf of customFormats) for (const condition of cf.conditions) {
    if (!condition.patterns) continue;
    const target = condition.type === "release_title" ? title : condition.type === "edition" ? edition : condition.type === "release_group" ? releaseGroup : null;
    if (!target) continue;
    for (const p2 of condition.patterns) if (p2.pattern) target.add(p2.pattern);
  }
  return {
    title: [...title],
    edition: [...edition],
    releaseGroup: [...releaseGroup]
  };
}
function normalize3(value2) {
  return value2.toLowerCase().replace(/[-_\s]/g, "");
}
function indexerLanguagesToEnum(names2) {
  const result = [];
  for (const name of names2) {
    const enumVal = languageNameToEnum.get(name);
    if (enumVal !== void 0) result.push(enumVal);
  }
  return result;
}
function getParsedInfo(parsed, indexerLangs) {
  const useIndexer = indexerLangs && indexerLangs.length > 0;
  const effectiveLangs = useIndexer ? indexerLanguagesToEnum(indexerLangs) : parsed.languages;
  return {
    source: sourceDisplayNames[parsed.source] || "Unknown",
    resolution: resolutionNames[parsed.resolution] || "Unknown",
    modifier: modifierDisplayNames[parsed.modifier] || "None",
    languages: effectiveLangs.map((l3) => languageNames[l3] || "Unknown"),
    languageSource: useIndexer ? "Indexer" : "Title",
    releaseGroup: parsed.releaseGroup,
    year: parsed.year,
    edition: parsed.edition,
    releaseType: parsed.episode ? releaseTypeNames[parsed.episode.releaseType] || "Unknown" : null
  };
}
function evaluateCondition(condition, parsed, title, patternMatchMaps, indexerLangs) {
  switch (condition.type) {
    case "release_title":
      return evaluatePattern(condition, title, patternMatchMaps?.title ?? null);
    case "language":
      return evaluateLanguage(condition, parsed, indexerLangs);
    case "source":
      return evaluateSource(condition, parsed);
    case "resolution":
      return evaluateResolution(condition, parsed);
    case "quality_modifier":
      return evaluateQualityModifier(condition, parsed);
    case "release_type":
      return evaluateReleaseType(condition, parsed);
    case "year":
      return evaluateYear(condition, parsed);
    case "edition":
      return evaluateEdition(condition, parsed, patternMatchMaps?.edition ?? null);
    case "release_group":
      return evaluateReleaseGroup(condition, parsed, patternMatchMaps?.releaseGroup ?? null);
    case "indexer_flag":
      return {
        matched: false,
        expected: "Indexer flags",
        actual: "N/A (no indexer data)"
      };
    case "size":
      return {
        matched: false,
        expected: "File size range",
        actual: "N/A (no file data)"
      };
    default:
      return {
        matched: false,
        expected: "Unknown",
        actual: "Unknown"
      };
  }
}
function evaluatePattern(condition, title, patternMatches) {
  if (!condition.patterns || condition.patterns.length === 0) return {
    matched: false,
    expected: "No patterns defined",
    actual: title
  };
  const expected = condition.patterns.map((p2) => p2.pattern).join(" OR ");
  if (!patternMatches) return {
    matched: false,
    expected,
    actual: "Parser unavailable"
  };
  for (const pattern2 of condition.patterns) if (patternMatches.get(pattern2.pattern)) return {
    matched: true,
    expected,
    actual: `Matched: ${pattern2.pattern}`
  };
  return {
    matched: false,
    expected,
    actual: "No match"
  };
}
function evaluateLanguage(condition, parsed, indexerLangs) {
  if (!condition.languages || condition.languages.length === 0) return {
    matched: false,
    expected: "No languages defined",
    actual: "N/A"
  };
  const effectiveLangs = indexerLangs && indexerLangs.length > 0 ? indexerLangs : parsed.languages;
  const langNames = effectiveLangs.map((l3) => languageNames[l3] || "Unknown");
  const actual = langNames.length > 0 ? langNames.join(", ") : "None detected";
  const expectedParts = [];
  for (const lang of condition.languages) if (lang.except) expectedParts.push(`NOT ${lang.name}`);
  else expectedParts.push(lang.name);
  const expected = expectedParts.join(" OR ");
  for (const lang of condition.languages) {
    const langEnum = languageNameToEnum.get(lang.name);
    if (langEnum === void 0) continue;
    const hasLanguage = effectiveLangs.includes(langEnum);
    if (lang.except) {
      if (hasLanguage) return {
        matched: false,
        expected,
        actual
      };
    } else if (hasLanguage) return {
      matched: true,
      expected,
      actual
    };
  }
  if (condition.languages.every((l3) => l3.except)) return {
    matched: true,
    expected,
    actual
  };
  return {
    matched: false,
    expected,
    actual
  };
}
function evaluateSource(condition, parsed) {
  if (!condition.sources || condition.sources.length === 0) return {
    matched: false,
    expected: "No sources defined",
    actual: "N/A"
  };
  const actual = sourceNames[parsed.source] || "unknown";
  const expected = condition.sources.join(" OR ");
  return {
    matched: condition.sources.some((s3) => normalize3(s3) === normalize3(actual)),
    expected,
    actual
  };
}
function evaluateResolution(condition, parsed) {
  if (!condition.resolutions || condition.resolutions.length === 0) return {
    matched: false,
    expected: "No resolutions defined",
    actual: "N/A"
  };
  const actual = resolutionNames[parsed.resolution] || "unknown";
  const expected = condition.resolutions.join(" OR ");
  return {
    matched: condition.resolutions.some((r2) => normalize3(r2) === normalize3(actual)),
    expected,
    actual
  };
}
function evaluateQualityModifier(condition, parsed) {
  if (!condition.qualityModifiers || condition.qualityModifiers.length === 0) return {
    matched: false,
    expected: "No modifiers defined",
    actual: "N/A"
  };
  const actual = modifierNames[parsed.modifier] || "none";
  const expected = condition.qualityModifiers.join(" OR ");
  return {
    matched: condition.qualityModifiers.some((m3) => normalize3(m3) === normalize3(actual)),
    expected,
    actual
  };
}
function evaluateReleaseType(condition, parsed) {
  if (!condition.releaseTypes || condition.releaseTypes.length === 0) return {
    matched: false,
    expected: "No release types defined",
    actual: "N/A"
  };
  const expected = condition.releaseTypes.join(" OR ");
  if (!parsed.episode) return {
    matched: false,
    expected,
    actual: "N/A (not a series)"
  };
  const actual = releaseTypeNames[parsed.episode.releaseType] || "unknown";
  return {
    matched: condition.releaseTypes.some((t2) => normalize3(t2) === normalize3(actual)),
    expected,
    actual
  };
}
function evaluateYear(condition, parsed) {
  if (!condition.years) return {
    matched: false,
    expected: "No year range defined",
    actual: "N/A"
  };
  const { minYear, maxYear } = condition.years;
  const expectedParts = [];
  if (minYear !== null) expectedParts.push(`>= ${minYear}`);
  if (maxYear !== null) expectedParts.push(`<= ${maxYear}`);
  const expected = expectedParts.join(" AND ") || "Any year";
  const year2 = parsed.year;
  if (!year2 || year2 === 0) return {
    matched: false,
    expected,
    actual: "No year detected"
  };
  const actual = String(year2);
  if (minYear !== null && year2 < minYear) return {
    matched: false,
    expected,
    actual
  };
  if (maxYear !== null && year2 > maxYear) return {
    matched: false,
    expected,
    actual
  };
  return {
    matched: true,
    expected,
    actual
  };
}
function evaluateEdition(condition, parsed, patternMatches) {
  if (!condition.patterns || condition.patterns.length === 0) return {
    matched: false,
    expected: "No patterns defined",
    actual: "N/A"
  };
  const actual = parsed.edition || "None detected";
  const expected = condition.patterns.map((p2) => p2.pattern).join(" OR ");
  if (!parsed.edition) return {
    matched: false,
    expected,
    actual
  };
  if (!patternMatches) return {
    matched: false,
    expected,
    actual: "Parser unavailable"
  };
  for (const pattern2 of condition.patterns) if (patternMatches.get(pattern2.pattern)) return {
    matched: true,
    expected,
    actual
  };
  return {
    matched: false,
    expected,
    actual
  };
}
function evaluateReleaseGroup(condition, parsed, patternMatches) {
  if (!condition.patterns || condition.patterns.length === 0) return {
    matched: false,
    expected: "No patterns defined",
    actual: "N/A"
  };
  const actual = parsed.releaseGroup || "None detected";
  const expected = condition.patterns.map((p2) => p2.pattern).join(" OR ");
  if (!parsed.releaseGroup) return {
    matched: false,
    expected,
    actual
  };
  if (!patternMatches) return {
    matched: false,
    expected,
    actual: "Parser unavailable"
  };
  for (const pattern2 of condition.patterns) if (patternMatches.get(pattern2.pattern)) return {
    matched: true,
    expected,
    actual
  };
  return {
    matched: false,
    expected,
    actual
  };
}
function evaluateCustomFormat(conditions, parsed, title, patternMatchMaps, indexerLangNames) {
  const indexerLangs = indexerLangNames && indexerLangNames.length > 0 ? indexerLanguagesToEnum(indexerLangNames) : void 0;
  const results = [];
  for (const condition of conditions) {
    const evalResult = evaluateCondition(condition, parsed, title, patternMatchMaps, indexerLangs);
    const passes = condition.negate ? !evalResult.matched : evalResult.matched;
    results.push({
      conditionName: condition.name,
      conditionType: condition.type,
      matched: evalResult.matched,
      required: condition.required,
      negate: condition.negate,
      passes,
      expected: evalResult.expected,
      actual: evalResult.actual
    });
  }
  const typeGroups = /* @__PURE__ */ new Map();
  for (const result of results) {
    if (!typeGroups.has(result.conditionType)) typeGroups.set(result.conditionType, []);
    typeGroups.get(result.conditionType).push(result);
  }
  let allTypesPass = true;
  for (const [, groupResults] of typeGroups) {
    const requiredInGroup = groupResults.filter((r2) => r2.required);
    let typeGroupPasses;
    if (requiredInGroup.length > 0) typeGroupPasses = requiredInGroup.every((r2) => r2.passes);
    else typeGroupPasses = groupResults.some((r2) => r2.passes);
    if (!typeGroupPasses) {
      allTypesPass = false;
      break;
    }
  }
  return {
    matches: allTypesPass,
    conditions: results
  };
}
var sourceNames, sourceDisplayNames, resolutionNames, modifierNames, modifierDisplayNames, releaseTypeNames, languageNames, languageNameToEnum;
var init_customFormats = __esm({
  async "dist/build/server/chunks/customFormats.js"() {
    "use strict";
    await init_queueService();
    init_uuid();
    await init_create();
    await init_generalSettings();
    init_types();
    init_esm();
    sourceNames = {
      [QualitySource.Unknown]: "unknown",
      [QualitySource.Cam]: "cam",
      [QualitySource.Telesync]: "telesync",
      [QualitySource.Telecine]: "telecine",
      [QualitySource.Workprint]: "workprint",
      [QualitySource.DVD]: "dvd",
      [QualitySource.TV]: "television",
      [QualitySource.WebDL]: "webdl",
      [QualitySource.WebRip]: "webrip",
      [QualitySource.Bluray]: "bluray"
    };
    sourceDisplayNames = {
      [QualitySource.Unknown]: "Unknown",
      [QualitySource.Cam]: "CAM",
      [QualitySource.Telesync]: "Telesync",
      [QualitySource.Telecine]: "Telecine",
      [QualitySource.Workprint]: "Workprint",
      [QualitySource.DVD]: "DVD",
      [QualitySource.TV]: "Television",
      [QualitySource.WebDL]: "WEB-DL",
      [QualitySource.WebRip]: "WEBRip",
      [QualitySource.Bluray]: "Blu-ray"
    };
    resolutionNames = {
      [Resolution.Unknown]: "unknown",
      [Resolution.R360p]: "360p",
      [Resolution.R480p]: "480p",
      [Resolution.R540p]: "540p",
      [Resolution.R576p]: "576p",
      [Resolution.R720p]: "720p",
      [Resolution.R1080p]: "1080p",
      [Resolution.R2160p]: "2160p"
    };
    modifierNames = {
      [QualityModifier.None]: "none",
      [QualityModifier.Regional]: "regional",
      [QualityModifier.Screener]: "screener",
      [QualityModifier.RawHD]: "rawhd",
      [QualityModifier.BRDisk]: "brdisk",
      [QualityModifier.Remux]: "remux"
    };
    modifierDisplayNames = {
      [QualityModifier.None]: "None",
      [QualityModifier.Regional]: "Regional",
      [QualityModifier.Screener]: "Screener",
      [QualityModifier.RawHD]: "Raw-HD",
      [QualityModifier.BRDisk]: "BR-DISK",
      [QualityModifier.Remux]: "Remux"
    };
    releaseTypeNames = {
      [ReleaseType.Unknown]: "unknown",
      [ReleaseType.SingleEpisode]: "single_episode",
      [ReleaseType.MultiEpisode]: "multi_episode",
      [ReleaseType.SeasonPack]: "season_pack"
    };
    languageNames = {
      [Language.Unknown]: "Unknown",
      [Language.English]: "English",
      [Language.French]: "French",
      [Language.Spanish]: "Spanish",
      [Language.German]: "German",
      [Language.Italian]: "Italian",
      [Language.Danish]: "Danish",
      [Language.Dutch]: "Dutch",
      [Language.Japanese]: "Japanese",
      [Language.Icelandic]: "Icelandic",
      [Language.Chinese]: "Chinese",
      [Language.Russian]: "Russian",
      [Language.Polish]: "Polish",
      [Language.Vietnamese]: "Vietnamese",
      [Language.Swedish]: "Swedish",
      [Language.Norwegian]: "Norwegian",
      [Language.Finnish]: "Finnish",
      [Language.Turkish]: "Turkish",
      [Language.Portuguese]: "Portuguese",
      [Language.Flemish]: "Flemish",
      [Language.Greek]: "Greek",
      [Language.Korean]: "Korean",
      [Language.Hungarian]: "Hungarian",
      [Language.Hebrew]: "Hebrew",
      [Language.Lithuanian]: "Lithuanian",
      [Language.Czech]: "Czech",
      [Language.Hindi]: "Hindi",
      [Language.Romanian]: "Romanian",
      [Language.Thai]: "Thai",
      [Language.Bulgarian]: "Bulgarian",
      [Language.PortugueseBR]: "Portuguese (BR)",
      [Language.Arabic]: "Arabic",
      [Language.Ukrainian]: "Ukrainian",
      [Language.Persian]: "Persian",
      [Language.Bengali]: "Bengali",
      [Language.Slovak]: "Slovak",
      [Language.Latvian]: "Latvian",
      [Language.SpanishLatino]: "Spanish (Latino)",
      [Language.Catalan]: "Catalan",
      [Language.Croatian]: "Croatian",
      [Language.Serbian]: "Serbian",
      [Language.Bosnian]: "Bosnian",
      [Language.Estonian]: "Estonian",
      [Language.Tamil]: "Tamil",
      [Language.Indonesian]: "Indonesian",
      [Language.Telugu]: "Telugu",
      [Language.Macedonian]: "Macedonian",
      [Language.Slovenian]: "Slovenian",
      [Language.Malayalam]: "Malayalam",
      [Language.Kannada]: "Kannada",
      [Language.Albanian]: "Albanian",
      [Language.Afrikaans]: "Afrikaans",
      [Language.Marathi]: "Marathi",
      [Language.Tagalog]: "Tagalog",
      [Language.Urdu]: "Urdu",
      [Language.Romansh]: "Romansh",
      [Language.Mongolian]: "Mongolian",
      [Language.Georgian]: "Georgian",
      [Language.Original]: "Original"
    };
    languageNameToEnum = new Map(Object.entries(languageNames).map(([enumVal, name]) => [name, Number(enumVal)]));
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_page.server.ts.js
var page_server_ts_exports16 = {};
__export(page_server_ts_exports16, {
  load: () => load20
});
var load20;
var init_page_server_ts16 = __esm({
  async "dist/build/server/entries/pages/custom-formats/_databaseId_/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_customFormats();
    await init_lastDatabase();
    init_exports();
    load20 = async ({ params, cookies }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const databases = pcdManager.getAllPublic();
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = databases.find((db2) => db2.id === currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      setLastDatabase(cookies, "last_db_cf", currentDatabaseId);
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      return {
        databases,
        currentDatabase,
        customFormats: await list3(cache3),
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
  }
});

// dist/build/server/chunks/download.js
function Download($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "download" },
    props,
    { iconNode: [
      ["path", { "d": "M12 15V3" }],
      ["path", { "d": "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }],
      ["path", { "d": "m7 10 5 5 5-5" }]
    ] }
  ]));
}
var init_download = __esm({
  "dist/build/server/chunks/download.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/CloneModal.js
function CloneModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let nameConflict, confirmDisabled;
    let open = fallback($$props["open"], false);
    let databaseId = $$props["databaseId"];
    let entityType = $$props["entityType"];
    let sourceName = fallback($$props["sourceName"], "");
    let existingNames = fallback($$props["existingNames"], () => [], true);
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let newName = "";
    let loading = false;
    $: if (open && sourceName) newName = `${sourceName} (Copy)`;
    $: nameConflict = existingNames.some((n) => n.toLowerCase() === newName.trim().toLowerCase());
    $: confirmDisabled = !newName.trim() || nameConflict || loading;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      Modal($$renderer3, {
        open,
        header: "Clone",
        confirmText: "Clone",
        loading,
        confirmDisabled,
        size: "sm",
        $$slots: { body: ($$renderer4) => {
          $$renderer4.push(`<div slot="body"><div class="space-y-4">`);
          FormInput($$renderer4, {
            label: "New Name",
            placeholder: "Enter a name for the clone",
            required: true,
            get value() {
              return newName;
            },
            set value($$value) {
              newName = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----> `);
          if (nameConflict) {
            $$renderer4.push("<!--[0-->");
            $$renderer4.push(`<p class="text-xs text-red-600 dark:text-red-400">An entity with this name already exists.</p>`);
          } else $$renderer4.push("<!--[-1-->");
          $$renderer4.push(`<!--]--></div></div>`);
        } }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      open,
      databaseId,
      entityType,
      sourceName,
      existingNames,
      canWriteToBase: canWriteToBase2
    });
  });
}
var init_CloneModal = __esm({
  "dist/build/server/chunks/CloneModal.js"() {
    "use strict";
    init_server();
    init_store2();
    init_navigation();
    init_Modal();
    init_FormInput();
  }
});

// dist/build/server/chunks/entitySearch.js
function nonEmpty(values) {
  return values.filter((value2) => Boolean(value2));
}
function customFormatSearchValues(item) {
  return nonEmpty([
    item.name,
    ...item.tags.map((tag2) => tag2.name),
    item.description,
    ...item.conditions.map((condition) => condition.name)
  ]);
}
function qualityProfileLanguageLabel(item) {
  if (!item.language || item.language.name === "Original") return "Any";
  return item.language.name;
}
function qualityProfileSearchValues(item) {
  return nonEmpty([
    item.name,
    ...item.tags.map((tag2) => tag2.name),
    item.description,
    qualityProfileLanguageLabel(item),
    ...item.qualities.map((quality) => quality.name)
  ]);
}
function regularExpressionSearchValues(item) {
  return nonEmpty([
    item.name,
    ...item.tags.map((tag2) => tag2.name),
    item.pattern,
    item.description,
    item.regex101_id
  ]);
}
var init_entitySearch = __esm({
  "dist/build/server/chunks/entitySearch.js"() {
    "use strict";
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_page.svelte.js
var page_svelte_exports16 = {};
__export(page_svelte_exports16, {
  default: () => _page16
});
function TableView2($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId;
    let formats = $$props["formats"];
    createEventDispatcher();
    function getRowHref(row) {
      return `/custom-formats/${databaseId}/${row.id}`;
    }
    function escapeHtml2(text2) {
      return text2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
    }
    function parseMarkdown2(text2) {
      if (!text2) return "";
      return sanitizeHtml(g2.parse(text2));
    }
    const columns = [
      {
        key: "name",
        header: "Name",
        headerIcon: Tag,
        align: "left",
        sortable: true,
        width: "w-48",
        cell: (row) => ({ html: `
					<div>
						<div class="font-medium">${escapeHtml2(row.name)}</div>
						${row.tags.length > 0 ? `
							<div class="mt-1 flex flex-wrap gap-1">
								${row.tags.map((tag2) => `
									<span class="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-medium bg-accent-100 text-accent-800 dark:bg-accent-900 dark:text-accent-200">
										${escapeHtml2(tag2.name)}
									</span>
								`).join("")}
							</div>
						` : ""}
					</div>
				` })
      },
      {
        key: "description",
        header: "Description",
        headerIcon: File_text,
        align: "left",
        cell: (row) => ({ html: row.description ? `<span class="text-sm text-neutral-600 dark:text-neutral-400 prose-inline">${parseMarkdown2(row.description)}</span>` : `<span class="text-neutral-400">-</span>` })
      },
      {
        key: "conditions",
        header: "Conditions",
        headerIcon: Layers,
        align: "left",
        cell: (row) => ({ html: row.conditions.length > 0 ? `<div class="flex flex-wrap gap-1">${sortConditions(row.conditions).map((c2) => {
          let colorClass;
          if (c2.required && c2.negate) colorClass = "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200";
          else if (c2.required) colorClass = "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200";
          else if (c2.negate) colorClass = "bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200";
          else colorClass = "bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300";
          return `<span class="inline-flex items-center px-1.5 py-0.5 rounded font-mono text-[10px] font-medium ${colorClass}">${escapeHtml2(c2.name)}</span>`;
        }).join("")}</div>` : `<span class="text-neutral-400 text-xs">None</span>` })
      },
      {
        key: "testCount",
        header: "Tests",
        headerIcon: Flask_conical,
        align: "center",
        width: "w-20",
        sortable: true,
        cell: (row) => ({ html: row.testCount > 0 ? `<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300">${row.testCount}</span>` : `<span class="text-neutral-400 text-xs">-</span>` })
      }
    ];
    $: databaseId = store_get($$store_subs ??= {}, "$page", page).params.databaseId;
    Table2($$renderer2, {
      data: formats,
      columns,
      emptyMessage: "No custom formats found",
      hoverable: true,
      compact: false,
      rowHref: getRowHref,
      pageSize: 50,
      $$slots: { actions: ($$renderer3, { row }) => {
        $$renderer3.push(`<div class="flex items-center justify-end gap-0.5">`);
        if (FEATURES.importExport) {
          $$renderer3.push("<!--[0-->");
          Button($$renderer3, {
            icon: Download,
            size: "xs",
            variant: "ghost",
            tooltip: "Export"
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        Button($$renderer3, {
          icon: Copy,
          size: "xs",
          variant: "secondary",
          tooltip: "Clone"
        });
        $$renderer3.push(`<!----></div>`);
      } }
    });
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { formats });
  });
}
function CardView2($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, visibleFormats;
    let formats = $$props["formats"];
    createEventDispatcher();
    const { visibleCount, sentinel, reset: reset2, setTotalCount } = createProgressiveList({ pageSize: 30 });
    function parseMarkdown2(text2) {
      if (!text2) return "";
      return sanitizeHtml(g2.parse(text2));
    }
    function getConditionVariant(condition) {
      if (condition.required && condition.negate) return "danger";
      if (condition.required) return "success";
      if (condition.negate) return "warning";
      return "secondary";
    }
    $: databaseId = store_get($$store_subs ??= {}, "$page", page).params.databaseId;
    $: setTotalCount(formats.length);
    $: reset2();
    $: visibleFormats = formats.slice(0, store_get($$store_subs ??= {}, "$visibleCount", visibleCount));
    CardGrid($$renderer2, {
      flush: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(visibleFormats);
        for (let $$index_2 = 0, $$length = each_array.length; $$index_2 < $$length; $$index_2++) {
          let format = each_array[$$index_2];
          Card($$renderer3, {
            href: `/custom-formats/${stringify(databaseId)}/${stringify(format.id)}`,
            hoverable: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="space-y-3">`);
              if (format.tags.length > 0) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
                const each_array_1 = ensure_array_like(format.tags);
                for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
                  let tag2 = each_array_1[$$index];
                  Label($$renderer4, {
                    variant: "info",
                    size: "sm",
                    rounded: "md",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->${escape_html(tag2.name)}`);
                    },
                    $$slots: { default: true }
                  });
                }
                $$renderer4.push(`<!--]--></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> `);
              if (format.description) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="prose-inline line-clamp-3 text-xs text-neutral-600 dark:text-neutral-400">${html(parseMarkdown2(format.description))}</div>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<div class="text-xs text-neutral-400 italic dark:text-neutral-500">No description</div>`);
              }
              $$renderer4.push(`<!--]--> `);
              if (format.conditions.length > 0) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
                const each_array_2 = ensure_array_like(sortConditions(format.conditions));
                for (let $$index_1 = 0, $$length2 = each_array_2.length; $$index_1 < $$length2; $$index_1++) {
                  let condition = each_array_2[$$index_1];
                  Label($$renderer4, {
                    variant: getConditionVariant(condition),
                    size: "sm",
                    rounded: "md",
                    mono: true,
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->${escape_html(condition.name)}`);
                    },
                    $$slots: { default: true }
                  });
                }
                $$renderer4.push(`<!--]--></div>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<div class="text-xs text-neutral-400">None</div>`);
              }
              $$renderer4.push(`<!--]--></div>`);
            },
            $$slots: {
              default: true,
              header: ($$renderer4) => {
                $$renderer4.push(`<div class="flex items-end justify-between gap-2"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(format.name)}</h3> <div class="flex shrink-0 items-center gap-0.5">`);
                if (format.testCount > 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="flex items-center gap-1 rounded bg-neutral-100 px-1.5 py-0.5 text-xs text-neutral-600 dark:bg-neutral-800 dark:text-neutral-400"${attr("title", `${stringify(format.testCount)} test${format.testCount !== 1 ? "s" : ""}`)}>`);
                  Flask_conical($$renderer4, { size: 12 });
                  $$renderer4.push(`<!----> <span>${escape_html(format.testCount)}</span></div>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                if (FEATURES.importExport) {
                  $$renderer4.push("<!--[0-->");
                  Button($$renderer4, {
                    icon: Download,
                    size: "xs",
                    variant: "ghost",
                    tooltip: "Export"
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                Button($$renderer4, {
                  icon: Copy,
                  size: "xs",
                  variant: "ghost",
                  tooltip: "Clone"
                });
                $$renderer4.push(`<!----></div></div>`);
              }
            }
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> <div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { formats });
  });
}
function _page16($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let simpleSearchStore, simpleQuery, useSimpleMode, filtered, tabs;
    let data = $$props["data"];
    let infoModalOpen = false;
    let cloneModalOpen = false;
    let cloneSourceName = "";
    let filterTags = [];
    const fields = [
      {
        key: "all",
        label: "All",
        description: "Name, tags, description and conditions",
        type: "text",
        accessor: customFormatSearchValues
      },
      {
        key: "name",
        label: "Name",
        description: "Custom format name",
        type: "text",
        isDefault: true,
        accessor: (item) => item.name,
        suggestions: (items) => items.map((i) => i.name).sort()
      },
      {
        key: "tag",
        label: "Tag",
        description: "Assigned tag names",
        type: "text",
        accessor: (item) => item.tags.map((t2) => t2.name),
        suggestions: (items) => [...new Set(items.flatMap((i) => i.tags.map((t2) => t2.name)))].sort()
      },
      {
        key: "tagged",
        label: "Tagged",
        description: "Whether any tags are assigned",
        type: "text",
        accessor: (item) => item.tags.length > 0 ? "yes" : "no",
        suggestions: () => ["yes", "no"]
      },
      {
        key: "referenced",
        label: "Referenced",
        description: "Whether a quality profile uses it",
        type: "text",
        accessor: (item) => item.referenceCount > 0 ? "yes" : "no",
        suggestions: () => ["yes", "no"]
      },
      {
        key: "description",
        label: "Description",
        description: "Custom format description",
        type: "text",
        accessor: (item) => item.description ?? null
      },
      {
        key: "condition",
        label: "Condition",
        description: "Condition names",
        type: "text",
        accessor: (item) => item.conditions.map((c2) => c2.name),
        suggestions: (items) => [...new Set(items.flatMap((i) => i.conditions.map((c2) => c2.name)))].sort()
      },
      {
        key: "tests",
        label: "Tests",
        description: "Number of configured test cases",
        type: "number",
        accessor: (item) => item.testCount
      }
    ];
    onDestroy(() => {
    });
    const viewMode = createViewModeStore({ storageKey: "customFormatsView" });
    $: simpleSearchStore = getPersistentSearchStore(`cfSearch:${data.currentDatabase.id}`, { debounceMs: 150 });
    $: simpleQuery = store_get($$store_subs ??= {}, "$simpleSearchStore", simpleSearchStore).query;
    $: useSimpleMode = store_get($$store_subs ??= {}, "$filterMode", filterMode) === "simple";
    $: filtered = (() => {
      if (useSimpleMode) {
        if (!simpleQuery) return data.customFormats;
        const q2 = simpleQuery.toLowerCase();
        return data.customFormats.filter((f2) => f2.name.toLowerCase().includes(q2));
      }
      return applySmartFilters(data.customFormats, filterTags, fields);
    })();
    $: tabs = data.databases.map((db2) => ({
      label: db2.name,
      href: `/custom-formats/${db2.id}`,
      active: db2.id === data.currentDatabase.id
    }));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.currentDatabase.name} \xB7 Custom Formats` });
      $$renderer3.push(`<!----> <div class="space-y-6 px-4 pb-8 md:px-8">`);
      Tabs($$renderer3, {
        tabs,
        responsive: true
      });
      $$renderer3.push(`<!----> `);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          if (useSimpleMode) {
            $$renderer4.push("<!--[0-->");
            SearchAction($$renderer4, {
              searchStore: simpleSearchStore,
              placeholder: "Search custom formats...",
              responsive: true
            });
          } else {
            $$renderer4.push("<!--[-1-->");
            SmartFilterBar($$renderer4, {
              fields,
              items: data.customFormats,
              storageKey: `smartFilter:customFormats:${data.currentDatabase.id}`,
              placeholder: "Filter custom formats...",
              get tags() {
                return filterTags;
              },
              set tags($$value) {
                filterTags = $$value;
                $$settled = false;
              }
            });
          }
          $$renderer4.push(`<!--]--> `);
          Tooltip($$renderer4, {
            text: "New",
            children: ($$renderer5) => {
              ActionButton($$renderer5, { icon: Plus });
            },
            $$slots: { default: true }
          });
          $$renderer4.push(`<!----> `);
          $$renderer4.push("<!--[0-->");
          FilterModeToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$filterMode", filterMode);
            },
            set value($$value) {
              store_set(filterMode, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!--]--> `);
          ViewToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$viewMode", viewMode);
            },
            set value($$value) {
              store_set(viewMode, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, { icon: Info });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> <div class="mt-6">`);
      if (data.customFormats.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No custom formats found for ${escape_html(data.currentDatabase?.name)}</p></div>`);
      } else if (filtered.length === 0) {
        $$renderer3.push("<!--[1-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No custom formats match the current filters</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$viewMode", viewMode) === "table") {
        $$renderer3.push("<!--[2-->");
        TableView2($$renderer3, { formats: filtered });
      } else {
        $$renderer3.push("<!--[-1-->");
        CardView2($$renderer3, { formats: filtered });
      }
      $$renderer3.push(`<!--]--></div></div> `);
      InfoModal($$renderer3, {
        header: "About Custom Formats",
        get open() {
          return infoModalOpen;
        },
        set open($$value) {
          infoModalOpen = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-700 dark:text-neutral-300"><section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">What Are Custom Formats?</h3> <p>Custom formats identify specific release characteristics \u2014 codec, resolution, source,
				release group, and more. When a release matches a format's conditions, quality profiles use
				its score to decide which releases are preferred.</p></section> <section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Conditions</h3> <p>Each custom format has one or more conditions grouped by type (Release Title, Release Group,
				Source, Resolution, etc.). Conditions use AND logic between types and OR logic within a
				type, with <strong>Required</strong> and <strong>Negate</strong> modifiers to change this behavior.
				Each condition type is explained in detail on the conditions tab when editing a format.</p></section> <section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Regular Expressions in Profilarr</h3> <p>Release Title conditions use regular expressions (regex) to match patterns in release names.
				In Profilarr, regex patterns are managed as their own reusable entity \u2014 a single
				pattern can be shared across multiple custom formats. When a pattern is updated, every
				format using it gets the change automatically.</p> <p class="mt-2">You can browse and manage patterns on the <a${attr("href", `/regular-expressions/${stringify(data.currentDatabase.id)}`)} class="font-medium text-accent-600 underline hover:text-accent-500 dark:text-accent-400 dark:hover:text-accent-300">Regular Expressions</a> page.</p></section></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      CloneModal($$renderer3, {
        databaseId: data.currentDatabase.id,
        entityType: "custom_format",
        sourceName: cloneSourceName,
        existingNames: data.customFormats.map((f2) => f2.name),
        canWriteToBase: data.canWriteToBase,
        get open() {
          return cloneModalOpen;
        },
        set open($$value) {
          cloneModalOpen = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte16 = __esm({
  "dist/build/server/entries/pages/custom-formats/_databaseId_/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_conditions();
    init_features();
    init_sanitize();
    init_copy();
    init_download();
    init_file_text();
    init_flask_conical();
    init_info();
    init_layers();
    init_Button();
    init_plus();
    init_search();
    init_filterMode();
    init_ViewToggle();
    init_tag();
    init_stores();
    init_store2();
    init_Label();
    init_Card();
    init_navigation();
    init_Tabs();
    init_progressiveList();
    init_ActionsBar();
    init_ActionButton();
    init_InfoModal();
    init_PageMeta();
    init_Table();
    init_CardGrid();
    init_dataPage();
    init_CloneModal();
    init_entitySearch();
    init_marked_esm();
  }
});

// dist/build/server/nodes/23.js
var __exports24 = {};
__export(__exports24, {
  component: () => component23,
  fonts: () => fonts24,
  imports: () => imports24,
  index: () => index24,
  server: () => page_server_ts_exports16,
  server_id: () => server_id22,
  stylesheets: () => stylesheets24
});
var index24, component_cache23, component23, server_id22, imports24, stylesheets24, fonts24;
var init__24 = __esm({
  async "dist/build/server/nodes/23.js"() {
    "use strict";
    await init_page_server_ts16();
    index24 = 23;
    component23 = async () => component_cache23 ??= (await Promise.resolve().then(() => (init_page_svelte16(), page_svelte_exports16))).default;
    server_id22 = "src/routes/custom-formats/[databaseId]/+page.server.ts";
    imports24 = ["_app/immutable/nodes/23.BttiH6Hl.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/D7OHFWTL2.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/SEZzcS_o.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DYf5Ixhg.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/C_LFCSMn.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/MJc6__n-.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/Cut3gr1-.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DxZIQ_tr2.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/DYe9q02k2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/DK-GnTaC2.js", "_app/immutable/chunks/VZQaB9P52.js"];
    stylesheets24 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/filterMode.DdGl7mkT.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts24 = [];
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/_page.server.ts.js
var page_server_ts_exports17 = {};
__export(page_server_ts_exports17, {
  load: () => load21
});
var load21;
var init_page_server_ts17 = __esm({
  "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/_page.server.ts.js"() {
    "use strict";
    init_exports();
    load21 = async ({ params }) => {
      throw redirect(303, `/custom-formats/${params.databaseId}/${params.id}/general`);
    };
  }
});

// dist/build/server/nodes/24.js
var __exports25 = {};
__export(__exports25, {
  fonts: () => fonts25,
  imports: () => imports25,
  index: () => index25,
  server: () => page_server_ts_exports17,
  server_id: () => server_id23,
  stylesheets: () => stylesheets25
});
var index25, server_id23, imports25, stylesheets25, fonts25;
var init__25 = __esm({
  "dist/build/server/nodes/24.js"() {
    "use strict";
    init_page_server_ts17();
    index25 = 24;
    server_id23 = "src/routes/custom-formats/[databaseId]/[id]/+page.server.ts";
    imports25 = [];
    stylesheets25 = [];
    fonts25 = [];
  }
});

// dist/build/server/chunks/regularExpressions.js
function esc$13(value2) {
  return value2.replace(/'/g, "''");
}
async function create3(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  const queries = [];
  if (await db2.selectFrom("regular_expressions").where((eb) => eb(eb.fn("lower", [eb.ref("name")]), "=", input.name.toLowerCase())).select("name").executeTakeFirst()) {
    await logger.warn(`Duplicate regular expression name "${input.name}"`, {
      source: "RegularExpression",
      meta: {
        databaseId,
        name: input.name
      }
    });
    throw new Error(`A regular expression with name "${input.name}" already exists`);
  }
  const insertRegex = db2.insertInto("regular_expressions").values({
    name: input.name,
    pattern: input.pattern,
    description: input.description,
    regex101_id: input.regex101Id
  }).compile();
  queries.push(insertRegex);
  const uniqueTags = Array.from(new Set(input.tags.map((tag2) => tag2.trim()).filter(Boolean)));
  for (const tagName of uniqueTags) {
    const insertTag = db2.insertInto("tags").values({ name: tagName }).onConflict((oc) => oc.column("name").doNothing()).compile();
    queries.push(insertTag);
    const linkTag = {
      sql: `INSERT INTO regular_expression_tags (regular_expression_name, tag_name) VALUES ('${esc$13(input.name)}', '${esc$13(tagName)}')`,
      parameters: [],
      query: {}
    };
    queries.push(linkTag);
  }
  return await writeOperation({
    databaseId,
    layer,
    description: `create-regular-expression-${input.name}`,
    queries,
    desiredState: {
      name: input.name,
      pattern: input.pattern,
      description: input.description ?? null,
      regex101_id: input.regex101Id ?? null,
      tags: uniqueTags
    },
    metadata: {
      operation: "create",
      entity: "regular_expression",
      name: input.name,
      stableKey: {
        key: "regular_expression_name",
        value: input.name
      },
      summary: "Create regular expression",
      title: `Create regular expression "${input.name}"`
    }
  });
}
function esc6(value2) {
  return value2.replace(/'/g, "''");
}
async function remove3(options2) {
  const { databaseId, cache: cache3, layer, current: current3 } = options2;
  const db2 = cache3.kb;
  const queries = [];
  const groupId = uuid();
  if (generalSettingsQueries.shouldFailOnReferencedDelete()) {
    const conditionRefs = await getConditionRefsForRegex(cache3, current3.name);
    const formatCount = new Set(conditionRefs.map((ref) => ref.cfId)).size;
    if (formatCount > 0) return {
      success: false,
      error: `Referenced by ${formatCount} custom format${formatCount === 1 ? "" : "s"}`
    };
  }
  const dependentConditions = await db2.selectFrom("condition_patterns as cp").innerJoin("custom_format_conditions as cfc", (join4) => join4.onRef("cfc.custom_format_name", "=", "cp.custom_format_name").onRef("cfc.name", "=", "cp.condition_name")).select([
    "cp.custom_format_name",
    "cp.condition_name",
    "cfc.type",
    "cfc.arr_type",
    "cfc.negate",
    "cfc.required"
  ]).where("cp.regular_expression_name", "=", current3.name).orderBy("cp.custom_format_name").orderBy("cp.condition_name").execute();
  const conditionsByFormat = /* @__PURE__ */ new Map();
  for (const condition of dependentConditions) {
    if (!conditionsByFormat.has(condition.custom_format_name)) conditionsByFormat.set(condition.custom_format_name, []);
    conditionsByFormat.get(condition.custom_format_name).push(condition);
  }
  const conditionOps = [];
  for (const [formatName, conditions] of conditionsByFormat.entries()) {
    const conditionQueries = conditions.map((condition) => db2.deleteFrom("custom_format_conditions").where("custom_format_name", "=", condition.custom_format_name).where("name", "=", condition.condition_name).where("type", "=", condition.type ?? "").where("arr_type", "=", condition.arr_type ?? "all").where("negate", "=", condition.negate ?? 0).where("required", "=", condition.required ?? 0).compile());
    const removedConditions = conditions.map((condition) => ({
      name: condition.condition_name,
      base: {
        type: condition.type,
        arrType: condition.arr_type,
        negate: !!condition.negate,
        required: !!condition.required
      },
      values: { patterns: [{
        name: current3.name,
        pattern: current3.pattern
      }] }
    }));
    conditionOps.push({
      formatName,
      queries: conditionQueries,
      removedConditions
    });
  }
  const deleteRegex = db2.deleteFrom("regular_expressions").where("name", "=", current3.name).compile();
  for (const conditionOp of conditionOps) {
    const result = await writeOperation({
      databaseId,
      layer,
      description: `update-conditions-${conditionOp.formatName}`,
      queries: conditionOp.queries,
      desiredState: { conditions: { removed: conditionOp.removedConditions } },
      metadata: {
        operation: "update",
        entity: "custom_format",
        name: conditionOp.formatName,
        stableKey: {
          key: "custom_format_name",
          value: conditionOp.formatName
        },
        groupId,
        generated: true,
        changedFields: ["conditions"],
        summary: "Update custom format conditions",
        title: `Update conditions for custom format "${conditionOp.formatName}"`
      }
    });
    if (!result.success) return result;
  }
  for (const tag2 of current3.tags) {
    const removeTagLink = {
      sql: `DELETE FROM regular_expression_tags WHERE regular_expression_name = '${esc6(current3.name)}' AND tag_name = '${esc6(tag2.name)}'`,
      parameters: [],
      query: {}
    };
    queries.push(removeTagLink);
  }
  queries.push(deleteRegex);
  return await writeOperation({
    databaseId,
    layer,
    description: `delete-regular-expression-${current3.name}`,
    queries,
    desiredState: {
      deleted: true,
      name: current3.name,
      pattern: current3.pattern,
      description: current3.description ?? null,
      regex101_id: current3.regex101_id ?? null,
      tags: current3.tags.map((tag2) => tag2.name)
    },
    metadata: {
      operation: "delete",
      entity: "regular_expression",
      name: current3.name,
      stableKey: {
        key: "regular_expression_name",
        value: current3.name
      },
      groupId,
      changedFields: ["deleted"],
      summary: "Delete regular expression",
      title: `Delete regular expression "${current3.name}"`
    }
  });
}
var init_regularExpressions = __esm({
  async "dist/build/server/chunks/regularExpressions.js"() {
    "use strict";
    await init_db();
    await init_queueService();
    init_uuid();
    await init_generalSettings();
    await init_update4();
  }
});

// dist/build/server/chunks/affectedArrs.js
function getAffectedArrs({ entityType, databaseId, entityName }) {
  try {
    if (!generalSettingsQueries.shouldShowSyncPrompt()) return [];
    switch (entityType) {
      case "qualityProfile":
        return getAffectedArrsForQualityProfile(databaseId, entityName);
      case "customFormat":
        return getAffectedArrsForCustomFormat(databaseId, entityName);
      case "regularExpression":
        return getAffectedArrsForRegularExpression(databaseId, entityName);
      case "delayProfile":
        return getAffectedArrsForDelayProfile(databaseId, entityName);
      case "naming":
        return getAffectedArrsForNaming(databaseId, entityName);
      case "qualityDefinitions":
        return getAffectedArrsForQualityDefinitions(databaseId, entityName);
      case "mediaSettings":
        return getAffectedArrsForMediaSettings(databaseId, entityName);
      default:
        return [];
    }
  } catch {
    return [];
  }
}
function getAffectedArrsForQualityProfile(databaseId, profileName2) {
  return arrSyncQueries.getInstancesForQualityProfile(databaseId, profileName2).map((row) => ({
    instanceId: row.instance_id,
    instanceName: row.instance_name,
    sections: [{
      section: "qualityProfiles",
      syncStatus: row.sync_status,
      lastSyncedAt: row.last_synced_at
    }]
  }));
}
function getAffectedArrsForCustomFormat(databaseId, cfName) {
  const cache3 = getCache(databaseId);
  if (!cache3) return [];
  const profileRows = cache3.query(`SELECT DISTINCT quality_profile_name FROM quality_profile_custom_formats WHERE custom_format_name = ?`, cfName);
  if (profileRows.length === 0) return [];
  return collectInstancesForProfiles(databaseId, profileRows.map((r2) => r2.quality_profile_name));
}
function getAffectedArrsForRegularExpression(databaseId, regexName) {
  const cache3 = getCache(databaseId);
  if (!cache3) return [];
  const cfRows = cache3.query(`SELECT DISTINCT custom_format_name FROM condition_patterns WHERE regular_expression_name = ?`, regexName);
  if (cfRows.length === 0) return [];
  const profileNames = /* @__PURE__ */ new Set();
  for (const row of cfRows) {
    const profileRows = cache3.query(`SELECT DISTINCT quality_profile_name FROM quality_profile_custom_formats WHERE custom_format_name = ?`, row.custom_format_name);
    for (const pr of profileRows) profileNames.add(pr.quality_profile_name);
  }
  if (profileNames.size === 0) return [];
  return collectInstancesForProfiles(databaseId, [...profileNames]);
}
function getAffectedArrsForNaming(databaseId, configName) {
  return arrSyncQueries.getInstancesForNaming(databaseId, configName).map((row) => ({
    instanceId: row.instance_id,
    instanceName: row.instance_name,
    sections: [{
      section: "mediaManagement",
      syncStatus: row.sync_status,
      lastSyncedAt: row.last_synced_at
    }]
  }));
}
function getAffectedArrsForDelayProfile(databaseId, profileName2) {
  return arrSyncQueries.getInstancesForDelayProfile(databaseId, profileName2).map((row) => ({
    instanceId: row.instance_id,
    instanceName: row.instance_name,
    sections: [{
      section: "delayProfiles",
      syncStatus: row.sync_status,
      lastSyncedAt: row.last_synced_at
    }]
  }));
}
function getAffectedArrsForMediaSettings(databaseId, configName) {
  return arrSyncQueries.getInstancesForMediaSettings(databaseId, configName).map((row) => ({
    instanceId: row.instance_id,
    instanceName: row.instance_name,
    sections: [{
      section: "mediaManagement",
      syncStatus: row.sync_status,
      lastSyncedAt: row.last_synced_at
    }]
  }));
}
function getAffectedArrsForQualityDefinitions(databaseId, configName) {
  return arrSyncQueries.getInstancesForQualityDefinitions(databaseId, configName).map((row) => ({
    instanceId: row.instance_id,
    instanceName: row.instance_name,
    sections: [{
      section: "mediaManagement",
      syncStatus: row.sync_status,
      lastSyncedAt: row.last_synced_at
    }]
  }));
}
function collectInstancesForProfiles(databaseId, profileNames) {
  const instanceMap = /* @__PURE__ */ new Map();
  for (const profileName2 of profileNames) {
    const instances = arrSyncQueries.getInstancesForQualityProfile(databaseId, profileName2);
    for (const inst of instances) if (!instanceMap.has(inst.instance_id)) instanceMap.set(inst.instance_id, {
      instanceId: inst.instance_id,
      instanceName: inst.instance_name,
      sections: [{
        section: "qualityProfiles",
        syncStatus: inst.sync_status,
        lastSyncedAt: inst.last_synced_at
      }]
    });
  }
  return [...instanceMap.values()];
}
var init_affectedArrs = __esm({
  async "dist/build/server/chunks/affectedArrs.js"() {
    "use strict";
    await init_arrSync();
    await init_queueService();
    init_registry();
    await init_generalSettings();
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/conditions/_page.server.ts.js
var page_server_ts_exports18 = {};
__export(page_server_ts_exports18, {
  actions: () => actions12,
  load: () => load22
});
var load22, actions12;
var init_page_server_ts18 = __esm({
  async "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/conditions/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    init_mappings();
    await init_create();
    await init_customFormats();
    init_read3();
    await init_update4();
    await init_regularExpressions();
    await init_affectedArrs();
    init_exports();
    load22 = async ({ params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) throw error(400, "Missing required parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const formatId = parseInt(id, 10);
      if (isNaN(formatId)) throw error(400, "Invalid format ID");
      const currentDatabase = pcdManager.getByIdPublic(currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const format = await getById(cache3, formatId);
      if (!format) throw error(404, "Custom format not found");
      const [conditions, patterns] = await Promise.all([getConditionsForEvaluation(cache3, format.name), list(cache3)]);
      const availableLanguages = getLanguagesWithSupport();
      return {
        currentDatabase,
        format,
        formatName: format.name,
        conditions,
        availablePatterns: patterns.map((p2) => ({
          id: p2.id,
          name: p2.name,
          pattern: p2.pattern
        })),
        availableLanguages,
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions12 = { update: async ({ request, params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) return fail(400, { error: "Missing parameters" });
      const currentDatabaseId = parseInt(databaseId, 10);
      const formatId = parseInt(id, 10);
      if (isNaN(currentDatabaseId) || isNaN(formatId)) return fail(400, { error: "Invalid parameters" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const format = await getById(cache3, formatId);
      if (!format) return fail(404, { error: "Custom format not found" });
      const originalConditions = await getConditionsForEvaluation(cache3, format.name);
      const formData = await request.formData();
      const conditionsJson = formData.get("conditions");
      const layer = formData.get("layer") || "user";
      let conditions = [];
      try {
        conditions = JSON.parse(conditionsJson || "[]");
      } catch {
        return fail(400, { error: "Invalid conditions format" });
      }
      const names2 = conditions.map((c2) => c2.name.trim().toLowerCase());
      if (new Set(names2).size !== names2.length) return fail(400, { error: "Condition names must be unique" });
      if (conditions.some((c2) => c2.arrType !== "all" && c2.arrType !== "radarr" && c2.arrType !== "sonarr")) return fail(400, { error: "Each condition must have at least one Arr type selected" });
      if (conditions.some((c2) => c2.type === "size" && (c2.size?.minBytes != null && c2.size.minBytes < 0 || c2.size?.maxBytes != null && c2.size.maxBytes < 0))) return fail(400, { error: "Size values must be zero or greater." });
      if (conditions.some((c2) => c2.type === "size" && c2.size?.minBytes != null && c2.size?.maxBytes != null && c2.size.maxBytes <= c2.size.minBytes)) return fail(400, { error: "Max size must be greater than min size." });
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      let result;
      try {
        result = await updateConditions({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          formatName: format.name,
          originalConditions,
          conditions
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to update conditions";
        if (message2.toLowerCase().includes("condition")) return fail(400, { error: message2 });
        return fail(500, { error: message2 });
      }
      if (!result.success) return fail(500, { error: result.error || "Failed to update conditions" });
      const affectedArrs = getAffectedArrs({
        entityType: "customFormat",
        databaseId: currentDatabaseId,
        entityName: format.name
      });
      return {
        success: true,
        redirectTo: `/custom-formats/${databaseId}/${id}/conditions`,
        affectedArrs
      };
    } };
  }
});

// dist/build/server/chunks/SyncPromptModal.js
function SyncPromptModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let allDone, anySyncing;
    let open = fallback($$props["open"], false);
    let redirectTo = $$props["redirectTo"];
    let affectedArrs = $$props["affectedArrs"];
    let databaseId = $$props["databaseId"];
    let entityName = $$props["entityName"];
    let entityType = fallback($$props["entityType"], "qualityProfile");
    let instanceStates = /* @__PURE__ */ new Map();
    let instanceErrors = /* @__PURE__ */ new Map();
    let instanceRetry = /* @__PURE__ */ new Map();
    function getStateVariant(state2) {
      switch (state2) {
        case "done":
          return "success";
        case "failed":
          return "danger";
        case "cooldown":
          return "warning";
        default:
          return "secondary";
      }
    }
    function getStateLabel(state2, instanceId) {
      switch (state2) {
        case "syncing":
          return "Syncing...";
        case "done":
          return "Synced";
        case "failed":
          return instanceErrors.get(instanceId) || "Failed";
        case "cooldown": {
          const retry = instanceRetry.get(instanceId);
          return retry ? `Wait ${retry}s` : instanceErrors.get(instanceId) || "Cooldown";
        }
        default:
          return "Pending";
      }
    }
    $: if (open) {
      instanceStates = new Map(affectedArrs.map((a2) => [a2.instanceId, "idle"]));
      instanceErrors = /* @__PURE__ */ new Map();
      instanceRetry = /* @__PURE__ */ new Map();
    }
    $: allDone = affectedArrs.length > 0 && affectedArrs.every((a2) => {
      const state2 = instanceStates.get(a2.instanceId);
      return state2 === "done" || state2 === "failed" || state2 === "cooldown";
    });
    $: anySyncing = affectedArrs.some((a2) => instanceStates.get(a2.instanceId) === "syncing");
    Modal($$renderer2, {
      open,
      header: "Sync Changes",
      $$slots: {
        body: ($$renderer3) => {
          {
            $$renderer3.push(`<div class="space-y-3"><p class="text-sm text-neutral-600 dark:text-neutral-400">The following instances sync this entity. Would you like to push your changes now?</p> <div class="space-y-2"><!--[-->`);
            const each_array = ensure_array_like(affectedArrs);
            for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
              let arr = each_array[$$index];
              const state2 = instanceStates.get(arr.instanceId) || "idle";
              $$renderer3.push(`<div class="rounded-xl border border-neutral-200 bg-white px-3 py-2.5 dark:border-neutral-700/60 dark:bg-neutral-800/50"><div class="flex items-center justify-between"><div><span class="text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(arr.instanceName)}</span> `);
              if (state2 !== "idle") {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<div class="mt-1">`);
                Label($$renderer3, {
                  variant: getStateVariant(state2),
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer4) => {
                    $$renderer4.push(`<!---->${escape_html(getStateLabel(state2, arr.instanceId))}`);
                  },
                  $$slots: { default: true }
                });
                $$renderer3.push(`<!----></div>`);
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--></div> <div class="flex items-center">`);
              if (affectedArrs.length > 1) {
                $$renderer3.push("<!--[0-->");
                if (state2 === "idle" || state2 === "failed") {
                  $$renderer3.push("<!--[0-->");
                  Button($$renderer3, {
                    text: "Sync",
                    icon: state2 === "failed" ? Refresh_cw : Arrow_right,
                    size: "xs",
                    variant: "primary"
                  });
                } else if (state2 === "syncing") {
                  $$renderer3.push("<!--[1-->");
                  Loader_circle($$renderer3, {
                    size: 16,
                    class: "animate-spin text-neutral-400"
                  });
                } else if (state2 === "done") {
                  $$renderer3.push("<!--[2-->");
                  Check($$renderer3, {
                    size: 16,
                    class: "text-green-500"
                  });
                } else $$renderer3.push("<!--[-1-->");
                $$renderer3.push(`<!--]-->`);
              } else if (state2 === "syncing") {
                $$renderer3.push("<!--[1-->");
                Loader_circle($$renderer3, {
                  size: 16,
                  class: "animate-spin text-neutral-400"
                });
              } else if (state2 === "done") {
                $$renderer3.push("<!--[2-->");
                Check($$renderer3, {
                  size: 16,
                  class: "text-green-500"
                });
              } else if (state2 === "failed" || state2 === "cooldown") {
                $$renderer3.push("<!--[3-->");
                Button($$renderer3, {
                  text: "Retry",
                  icon: Refresh_cw,
                  size: "xs",
                  variant: "primary"
                });
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--></div></div></div>`);
            }
            $$renderer3.push(`<!--]--></div></div>`);
          }
        },
        footer: ($$renderer3) => {
          Button($$renderer3, {
            text: "Skip",
            icon: X2,
            disabled: anySyncing
          });
          $$renderer3.push(`<!----> `);
          if (allDone) {
            $$renderer3.push("<!--[0-->");
            Button($$renderer3, {
              text: "Done",
              icon: Check,
              variant: "primary"
            });
          } else {
            $$renderer3.push("<!--[-1-->");
            Button($$renderer3, {
              text: "Sync All",
              icon: Refresh_cw,
              variant: "primary",
              disabled: anySyncing
            });
          }
          $$renderer3.push(`<!--]-->`);
        }
      }
    });
    bind_props($$props, {
      open,
      redirectTo,
      affectedArrs,
      databaseId,
      entityName,
      entityType
    });
  });
}
var init_SyncPromptModal = __esm({
  "dist/build/server/chunks/SyncPromptModal.js"() {
    "use strict";
    init_server();
    init_arrow_right();
    init_check();
    init_Button();
    init_refresh_cw();
    init_x();
    init_Label();
    init_navigation();
    init_Modal();
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/conditions/_page.svelte.js
var page_svelte_exports17 = {};
__export(page_svelte_exports17, {
  default: () => _page17
});
function ConditionCard($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let isDraft, rightPaddingClass, conditionNameId, nameError, radarrEnabled, sonarrEnabled, filteredConditionTypes, valueOptions, isPatternType, patternOptions, selectedValue, languageOptions, hasLanguage, languageExcept, typeOptions, minSizeGB, maxSizeGB, minSizeEmptyStepValue, maxSizeEmptyStepValue, hasInvalidSizeRange, invalidSizeWarning, minSizeWarning, maxSizeWarning, minYear, maxYear;
    createEventDispatcher();
    let mode = fallback($$props["mode"], "normal");
    let condition = $$props["condition"];
    let nameConflict = fallback($$props["nameConflict"], false);
    let availablePatterns = fallback($$props["availablePatterns"], () => [], true);
    let availableLanguages = fallback($$props["availableLanguages"], () => [], true);
    const BYTES_PER_GB2 = 1073741824;
    const SIZE_STEP_GB = 0.01;
    const SIZE_MAX_DECIMALS = 2;
    function getValueOptions(type) {
      switch (type) {
        case "source":
          return [...SOURCE_VALUES];
        case "resolution":
          return [...RESOLUTION_VALUES];
        case "quality_modifier":
          return [...QUALITY_MODIFIER_VALUES];
        case "release_type":
          return [...RELEASE_TYPE_VALUES];
        case "indexer_flag":
          return [...INDEXER_FLAG_VALUES];
        default:
          return [];
      }
    }
    function bytesToDisplayGb(bytes) {
      const factor = 10 ** SIZE_MAX_DECIMALS;
      return Math.round((bytes / BYTES_PER_GB2 + Number.EPSILON) * factor) / factor;
    }
    $: isDraft = mode === "draft";
    $: rightPaddingClass = "pr-3";
    $: conditionNameId = `condition-name-${(condition.name || "untitled").toLowerCase().replace(/[^a-z0-9]+/g, "-")}`;
    $: nameError = "";
    $: radarrEnabled = condition.arrType === "all" || condition.arrType === "radarr";
    $: sonarrEnabled = condition.arrType === "all" || condition.arrType === "sonarr";
    $: filteredConditionTypes = [...CONDITION_TYPES];
    $: valueOptions = getValueOptions(condition.type);
    $: isPatternType = PATTERN_TYPES.includes(condition.type);
    $: patternOptions = availablePatterns.map((p2) => ({
      value: p2.name,
      label: p2.name
    }));
    $: selectedValue = (() => {
      if (isPatternType) return condition.patterns?.[0]?.name ?? "";
      switch (condition.type) {
        case "source":
          return condition.sources?.[0] ?? "";
        case "resolution":
          return condition.resolutions?.[0] ?? "";
        case "quality_modifier":
          return condition.qualityModifiers?.[0] ?? "";
        case "release_type":
          return condition.releaseTypes?.[0] ?? "";
        case "indexer_flag":
          return condition.indexerFlags?.[0] ?? "";
        case "language":
          return condition.languages?.[0]?.name ?? "";
        default:
          return "";
      }
    })();
    $: languageOptions = availableLanguages.map((l3) => ({
      value: l3.name,
      label: l3.name,
      radarr: l3.radarr,
      sonarr: l3.sonarr
    }));
    $: hasLanguage = (condition.languages?.length ?? 0) > 0;
    $: languageExcept = condition.languages?.[0]?.except ?? false;
    $: typeOptions = filteredConditionTypes.map((t2) => ({
      value: t2.value,
      label: t2.label
    }));
    $: minSizeGB = condition.size?.minBytes != null ? bytesToDisplayGb(condition.size.minBytes) : void 0;
    $: maxSizeGB = condition.size?.maxBytes != null ? bytesToDisplayGb(condition.size.maxBytes) : void 0;
    $: minSizeEmptyStepValue = maxSizeGB == null ? void 0 : Math.max(0, maxSizeGB - SIZE_STEP_GB);
    $: maxSizeEmptyStepValue = minSizeGB == null ? void 0 : minSizeGB + SIZE_STEP_GB;
    $: hasInvalidSizeRange = condition.size?.minBytes != null && condition.size?.maxBytes != null && condition.size.maxBytes <= condition.size.minBytes;
    $: invalidSizeWarning = hasInvalidSizeRange ? "Max size must be greater than min size." : "";
    $: minSizeWarning = "";
    $: maxSizeWarning = hasInvalidSizeRange && true ? invalidSizeWarning : "";
    $: minYear = condition.years?.minYear ?? void 0;
    $: maxYear = condition.years?.maxYear ?? void 0;
    $$renderer2.push(`<div${attr_class(`relative flex flex-col gap-3 px-3 py-3 ${stringify(rightPaddingClass)} wide:flex-row wide:items-center`)}><div class="rounded-xl border border-neutral-200 bg-neutral-50/40 p-2 wide:contents wide:border-0 wide:bg-transparent wide:p-0 dark:border-neutral-800 dark:bg-neutral-900/40"><div class="mb-2 text-[11px] font-medium tracking-wide text-neutral-500 uppercase wide:hidden dark:text-neutral-400">Identity</div> <div class="grid gap-2 wide:contents"><div class="w-full min-w-0 shrink-0 wide:w-48"${attr("title", nameConflict ? "Duplicate condition name" : "")} data-onboarding="cf-cond-name">`);
    FormInput($$renderer2, {
      label: "Name",
      hideLabel: true,
      name: conditionNameId,
      value: condition.name,
      placeholder: "Condition name",
      description: nameError
    });
    $$renderer2.push(`<!----></div> <div class="w-full min-w-0 shrink-0 wide:w-52" data-onboarding="cf-cond-type">`);
    DropdownCombobox($$renderer2, {
      fullWidth: true,
      minWidth: "0",
      dropdownWidth: "100%",
      limit: 6,
      options: typeOptions,
      value: condition.type,
      placeholder: "Select type..."
    });
    $$renderer2.push(`<!----></div></div></div> <div class="rounded-xl border border-neutral-200 bg-neutral-50/40 p-2 wide:contents wide:border-0 wide:bg-transparent wide:p-0 dark:border-neutral-800 dark:bg-neutral-900/40"><div class="mb-2 text-[11px] font-medium tracking-wide text-neutral-500 uppercase wide:hidden dark:text-neutral-400">Value</div> <div class="min-w-0 wide:flex-1" data-onboarding="cf-cond-value">`);
    if (isPatternType) {
      $$renderer2.push("<!--[0-->");
      DropdownCombobox($$renderer2, {
        fullWidth: true,
        minWidth: "0",
        dropdownWidth: "100%",
        limit: 6,
        options: patternOptions,
        value: selectedValue,
        placeholder: "Select pattern..."
      });
    } else if (condition.type === "language") {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<div class="flex flex-col gap-2 wide:flex-row wide:items-center"><div class="min-w-0 flex-1">`);
      DropdownCombobox($$renderer2, {
        fullWidth: true,
        minWidth: "0",
        dropdownWidth: "100%",
        limit: 6,
        options: languageOptions,
        value: selectedValue,
        placeholder: "Select language...",
        $$slots: { item: ($$renderer3, { option }) => {
          $$renderer3.push(`<span class="flex w-full items-center justify-between"><span>${escape_html(option.label)}</span> <span class="flex gap-1">`);
          if (option.radarr) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<img${attr("src", Radarr_default)} alt="Radarr" class="h-3.5 w-3.5" title="Radarr"/>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          if (option.sonarr) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<img${attr("src", Sonarr_default)} alt="Sonarr" class="h-3.5 w-3.5" title="Sonarr"/>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--></span></span>`);
        } }
      });
      $$renderer2.push(`<!----></div> `);
      Toggle($$renderer2, {
        checked: languageExcept,
        ariaLabel: "Except language",
        label: "Except",
        color: "red",
        disabled: !hasLanguage
      });
      $$renderer2.push(`<!----></div>`);
    } else if (condition.type === "size") {
      $$renderer2.push("<!--[2-->");
      $$renderer2.push(`<div><div class="flex flex-col gap-2 wide:flex-row wide:items-center"><div class="w-full flex-1">`);
      NumberInput($$renderer2, {
        name: "minSize",
        value: minSizeGB,
        min: 0,
        step: SIZE_STEP_GB,
        maxDecimals: SIZE_MAX_DECIMALS,
        emptyStepValue: minSizeEmptyStepValue,
        warningTooltip: minSizeWarning,
        font: "mono",
        responsive: true,
        placeholder: "Min GB"
      });
      $$renderer2.push(`<!----></div> <span class="hidden text-sm text-neutral-500 wide:inline">-</span> <div class="w-full flex-1">`);
      NumberInput($$renderer2, {
        name: "maxSize",
        value: maxSizeGB,
        min: 0,
        step: SIZE_STEP_GB,
        maxDecimals: SIZE_MAX_DECIMALS,
        emptyStepValue: maxSizeEmptyStepValue,
        warningTooltip: maxSizeWarning,
        font: "mono",
        responsive: true,
        placeholder: "Max GB"
      });
      $$renderer2.push(`<!----></div></div></div>`);
    } else if (condition.type === "year") {
      $$renderer2.push("<!--[3-->");
      $$renderer2.push(`<div class="flex flex-col gap-2 wide:flex-row wide:items-center"><div class="w-full flex-1">`);
      NumberInput($$renderer2, {
        name: "minYear",
        value: minYear,
        min: 1900,
        max: 2100,
        step: 1,
        font: "mono",
        responsive: true,
        placeholder: "Min Year"
      });
      $$renderer2.push(`<!----></div> <span class="hidden text-sm text-neutral-500 wide:inline">-</span> <div class="w-full flex-1">`);
      NumberInput($$renderer2, {
        name: "maxYear",
        value: maxYear,
        min: 1900,
        max: 2100,
        step: 1,
        font: "mono",
        responsive: true,
        placeholder: "Max Year"
      });
      $$renderer2.push(`<!----></div></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      DropdownCombobox($$renderer2, {
        fullWidth: true,
        minWidth: "0",
        dropdownWidth: "100%",
        limit: 6,
        options: valueOptions,
        value: selectedValue,
        placeholder: "Select value..."
      });
    }
    $$renderer2.push(`<!--]--></div></div> <div class="rounded-xl border border-neutral-200 bg-neutral-50/40 p-2 wide:contents wide:border-0 wide:bg-transparent wide:p-0 dark:border-neutral-800 dark:bg-neutral-900/40"><div class="mb-2 text-[11px] font-medium tracking-wide text-neutral-500 uppercase wide:hidden dark:text-neutral-400">Flags</div> <div class="grid grid-cols-1 gap-2 wide:ml-auto wide:flex wide:shrink-0 wide:flex-wrap wide:items-center"><div class="grid grid-cols-1 gap-2 min-[480px]:grid-cols-2 wide:flex wide:flex-wrap wide:items-center wide:[&amp;>*]:w-fit wide:[&amp;>*]:justify-start" data-onboarding="cf-cond-flags-modifiers">`);
    Toggle($$renderer2, {
      checked: condition.negate,
      ariaLabel: "Negate",
      label: "Negate",
      color: "red",
      fullWidth: true
    });
    $$renderer2.push(`<!----> `);
    Toggle($$renderer2, {
      checked: condition.required,
      ariaLabel: "Required",
      label: "Required",
      color: "green",
      fullWidth: true
    });
    $$renderer2.push(`<!----></div> <div class="grid grid-cols-1 gap-2 min-[480px]:grid-cols-2 wide:flex wide:flex-wrap wide:items-center wide:[&amp;>*]:w-fit wide:[&amp;>*]:justify-start" data-onboarding="cf-cond-flags-arr">`);
    Toggle($$renderer2, {
      checked: radarrEnabled,
      ariaLabel: "Radarr",
      label: "Radarr",
      checkboxColor: "var(--arr-radarr-color)",
      fullWidth: true
    });
    $$renderer2.push(`<!----> `);
    Toggle($$renderer2, {
      checked: sonarrEnabled,
      ariaLabel: "Sonarr",
      label: "Sonarr",
      checkboxColor: "var(--arr-sonarr-color)",
      fullWidth: true
    });
    $$renderer2.push(`<!----></div></div></div> <div class="rounded-xl border border-neutral-200 bg-neutral-50/40 p-2 wide:contents wide:border-0 wide:bg-transparent wide:p-0 dark:border-neutral-800 dark:bg-neutral-900/40"><div class="mb-2 text-[11px] font-medium tracking-wide text-neutral-500 uppercase wide:hidden dark:text-neutral-400">Actions</div> `);
    if (isDraft) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="grid grid-cols-2 gap-2 wide:flex wide:flex-wrap wide:items-center wide:gap-2">`);
      Button($$renderer2, {
        text: "Discard",
        icon: Trash_2,
        iconColor: "text-red-600 dark:text-red-400",
        variant: "secondary",
        title: "Discard condition",
        ariaLabel: "Discard condition"
      });
      $$renderer2.push(`<!----> `);
      Button($$renderer2, {
        text: "Accept",
        icon: Check,
        iconColor: "text-green-600 dark:text-green-400",
        variant: "secondary",
        title: "Confirm condition",
        ariaLabel: "Confirm condition"
      });
      $$renderer2.push(`<!----></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="grid grid-cols-1 gap-2 wide:flex wide:flex-wrap wide:items-center wide:gap-2">`);
      Button($$renderer2, {
        text: "Remove",
        icon: Trash_2,
        iconColor: "text-red-600 dark:text-red-400",
        variant: "secondary",
        title: "Remove condition",
        ariaLabel: "Remove condition"
      });
      $$renderer2.push(`<!----></div>`);
    }
    $$renderer2.push(`<!--]--></div></div>`);
    bind_props($$props, {
      mode,
      condition,
      nameConflict,
      availablePatterns,
      availableLanguages
    });
  });
}
function _page17($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let cfDatabaseId, initialData, conditions, draftConditions, hasDrafts, invalidConditions, hasInvalidConditions, duplicateNames, hasDuplicateNames, hasMissingArrType, hasInvalidSizeRange, hasEmptyNames, saveBlocked, saveTooltip;
    let infoModalOpen = false;
    let showSyncModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    let data = $$props["data"];
    let nextKey = 0;
    function genKey() {
      return `cond-${nextKey++}`;
    }
    let selectedLayer = data.canWriteToBase ? "base" : "user";
    function hasNameConflict(condition) {
      return duplicateNames.has(condition.name.trim().toLowerCase());
    }
    function isInvalidSizeRange(condition) {
      return condition.type === "size" && condition.size?.minBytes != null && condition.size?.maxBytes != null && condition.size.maxBytes <= condition.size.minBytes;
    }
    function isConditionValid(condition) {
      switch (condition.type) {
        case "release_title":
        case "release_group":
        case "edition":
          return (condition.patterns?.length ?? 0) > 0;
        case "language":
          return (condition.languages?.length ?? 0) > 0;
        case "source":
          return (condition.sources?.length ?? 0) > 0;
        case "resolution":
          return (condition.resolutions?.length ?? 0) > 0;
        case "quality_modifier":
          return (condition.qualityModifiers?.length ?? 0) > 0;
        case "release_type":
          return (condition.releaseTypes?.length ?? 0) > 0;
        case "indexer_flag":
          return (condition.indexerFlags?.length ?? 0) > 0;
        case "size":
          return condition.size?.minBytes != null || condition.size?.maxBytes != null;
        case "year":
          return condition.years?.minYear != null || condition.years?.maxYear != null;
        default:
          return true;
      }
    }
    let sortSnapshot = [];
    let sortedConditions = [];
    function orderBySnapshot(items, order) {
      const map2 = new Map(items.map((item) => [item._key, item]));
      const ordered = [];
      for (const key2 of order) {
        const item = map2.get(key2);
        if (item) {
          ordered.push(item);
          map2.delete(key2);
        }
      }
      for (const item of map2.values()) ordered.push(item);
      return ordered;
    }
    $: cfDatabaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: initialData = {
      conditions: data.conditions.map((c2) => ({
        ...structuredClone(c2),
        _key: genKey()
      })),
      draftConditions: []
    };
    $: initEdit(initialData);
    $: conditions = store_get($$store_subs ??= {}, "$current", current2).conditions ?? [];
    $: draftConditions = store_get($$store_subs ??= {}, "$current", current2).draftConditions ?? [];
    $: hasDrafts = draftConditions.length > 0;
    $: invalidConditions = conditions.filter((c2) => !isConditionValid(c2));
    $: hasInvalidConditions = invalidConditions.length > 0;
    $: duplicateNames = (() => {
      const names2 = conditions.map((c2) => c2.name.trim().toLowerCase());
      const seen = /* @__PURE__ */ new Set();
      const dupes = /* @__PURE__ */ new Set();
      for (const name of names2) {
        if (seen.has(name)) dupes.add(name);
        seen.add(name);
      }
      return dupes;
    })();
    $: hasDuplicateNames = duplicateNames.size > 0;
    $: hasMissingArrType = conditions.some((c2) => c2.arrType === "");
    $: hasInvalidSizeRange = conditions.some((c2) => isInvalidSizeRange(c2));
    $: if (!store_get($$store_subs ??= {}, "$isDirty", isDirty)) {
      sortedConditions = sortConditions(conditions);
      sortSnapshot = sortedConditions.map((c2) => c2._key);
    } else sortedConditions = orderBySnapshot(conditions, sortSnapshot);
    $: hasEmptyNames = conditions.some((c2) => !c2.name.trim());
    $: saveBlocked = hasDrafts || hasEmptyNames || hasDuplicateNames || hasInvalidConditions || hasInvalidSizeRange || hasMissingArrType;
    $: saveTooltip = (() => {
      if (hasDrafts) return "Confirm or discard draft conditions before saving.";
      if (hasEmptyNames) return "All conditions must have a name.";
      if (hasDuplicateNames) return "Condition names must be unique.";
      if (hasInvalidConditions) return "Some conditions are missing required values.";
      if (hasInvalidSizeRange) return "Max size must be greater than min size.";
      if (hasMissingArrType) return "Each condition must have at least one Arr type selected.";
      return "";
    })();
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.format.name} \xB7 Conditions` });
      $$renderer3.push(`<!----> <form method="POST" action="?/update"><input type="hidden" name="conditions"${attr("value", JSON.stringify(conditions))}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/> `);
      StickyCard($$renderer3, {
        position: "top",
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<div><h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-100">Conditions</h2> <p class="text-sm text-neutral-600 dark:text-neutral-400">Define the conditions that must be met for this custom format to match a release.</p></div>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div class="flex items-center gap-2">`);
            Button($$renderer4, {
              text: "Info",
              icon: Info,
              variant: "secondary"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Add Condition",
              icon: Plus,
              iconColor: "text-blue-600 dark:text-blue-400",
              variant: "secondary",
              onboarding: "cf-conditions-add"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Save",
              icon: Save,
              iconColor: "text-green-600 dark:text-green-400",
              variant: "secondary",
              disabled: !store_get($$store_subs ??= {}, "$isDirty", isDirty) || saveBlocked,
              tooltip: saveTooltip
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="mt-6 space-y-6 pb-12">`);
      if (draftConditions.length > 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="space-y-2"><div class="flex items-center gap-2 px-3"><span class="text-sm font-medium text-neutral-600 dark:text-neutral-400">Drafts</span> `);
        Badge($$renderer3, {
          variant: "neutral",
          size: "sm",
          children: ($$renderer4) => {
            $$renderer4.push(`<!---->${escape_html(draftConditions.length)}`);
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----></div> <div class="space-y-2 wide:space-y-0 wide:divide-y wide:divide-neutral-200 wide:dark:divide-neutral-800"><!--[-->`);
        const each_array = ensure_array_like(draftConditions);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let draft = each_array[$$index];
          $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white px-2 py-1.5 wide:rounded-none wide:border-0 wide:bg-transparent wide:px-0 wide:py-0 dark:border-neutral-800 dark:bg-neutral-900">`);
          ConditionCard($$renderer3, {
            mode: "draft",
            condition: draft,
            availablePatterns: data.availablePatterns,
            availableLanguages: data.availableLanguages
          });
          $$renderer3.push(`<!----></div>`);
        }
        $$renderer3.push(`<!--]--></div></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (conditions.length === 0 && draftConditions.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<p class="px-3 text-sm text-neutral-500 dark:text-neutral-400">No conditions defined</p>`);
      } else if (conditions.length > 0) {
        $$renderer3.push("<!--[1-->");
        $$renderer3.push(`<div class="space-y-2"><div class="flex items-center gap-2 px-3"><span class="text-sm font-medium text-neutral-600 dark:text-neutral-400">Conditions</span> `);
        Badge($$renderer3, {
          variant: "neutral",
          size: "sm",
          children: ($$renderer4) => {
            $$renderer4.push(`<!---->${escape_html(conditions.length)}`);
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----></div> <div class="space-y-2 wide:space-y-0 wide:divide-y wide:divide-neutral-200 wide:dark:divide-neutral-800"><!--[-->`);
        const each_array_1 = ensure_array_like(sortedConditions);
        for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
          let condition = each_array_1[$$index_1];
          $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white px-2 py-1.5 wide:rounded-none wide:border-0 wide:bg-transparent wide:px-0 wide:py-0 dark:border-neutral-800 dark:bg-neutral-900">`);
          ConditionCard($$renderer3, {
            condition,
            availablePatterns: data.availablePatterns,
            availableLanguages: data.availableLanguages,
            nameConflict: hasNameConflict(condition)
          });
          $$renderer3.push(`<!----></div>`);
        }
        $$renderer3.push(`<!--]--></div></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div></form> `);
      InfoModal($$renderer3, {
        header: "Condition Types",
        get open() {
          return infoModalOpen;
        },
        set open($$value) {
          infoModalOpen = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-700 dark:text-neutral-300"><section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">How Conditions Work</h3> <p>Conditions are grouped by type. Between types, logic is <strong>AND</strong> \u2014 every
				type must pass. Within a type, logic is <strong>OR</strong> \u2014 any condition can satisfy
				it. Two modifiers change this:</p> <ul class="mt-2 list-inside list-disc space-y-1"><li><strong>Required</strong> \u2014 Changes the type's logic from OR to AND. All required conditions
					in that type must match.</li> <li><strong>Negate</strong> \u2014 Inverts the condition so it matches when the pattern is absent.</li></ul></section> <div class="border-t border-neutral-200 pt-4 dark:border-neutral-700"><h3 class="mb-3 font-semibold text-neutral-900 dark:text-neutral-100">Types</h3> <div class="space-y-3"><div><div class="font-medium text-neutral-800 dark:text-neutral-200">Release Title</div> <p class="mt-0.5">Matches regex patterns against the full release name. Uses reusable patterns managed on
						the Regular Expressions page.</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Release Group</div> <p class="mt-0.5">Matches regex patterns against the release group name (the tag after the final dash,
						e.g. FraMeSToR).</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Edition</div> <p class="mt-0.5">Matches regex patterns against the edition field (Director's Cut, Extended, etc.).
						Radarr only.</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Resolution</div> <p class="mt-0.5">Matches the parsed video resolution (360p, 480p, 576p, 720p, 1080p, 2160p).</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Source</div> <p class="mt-0.5">Matches the release source \u2014 where the content was captured from (BluRay, WEB-DL,
						WEBRip, DVD, Television, etc.).</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Quality Modifier</div> <p class="mt-0.5">Matches quality modifiers like REMUX, BRDISK, or Regional. Radarr only.</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Language</div> <p class="mt-0.5">Matches the detected audio language of the release.</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Release Type</div> <p class="mt-0.5">Matches the type of TV release (Season Pack, Single Episode, etc.). Sonarr only.</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Indexer Flag</div> <p class="mt-0.5">Matches flags set by the indexer (Freeleech, Halfleech, Internal, etc.).</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Size</div> <p class="mt-0.5">Matches the file size of the release. Set a minimum, maximum, or both (in GB).</p></div> <div><div class="font-medium text-neutral-800 dark:text-neutral-200">Year</div> <p class="mt-0.5">Matches the release year. Set a minimum, maximum, or both.</p></div></div></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      SyncPromptModal($$renderer3, {
        redirectTo: pendingRedirectTo,
        affectedArrs: pendingAffectedArrs,
        entityType: "customFormat",
        databaseId: cfDatabaseId,
        entityName: data.formatName,
        get open() {
          return showSyncModal;
        },
        set open($$value) {
          showSyncModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte17 = __esm({
  "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/conditions/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_conditions();
    init_check();
    init_info();
    init_Button();
    init_plus();
    init_save();
    init_trash_2();
    init_stores();
    init_store2();
    init_Sonarr2();
    init_navigation();
    init_forms();
    init_dirty();
    init_Badge();
    init_InfoModal();
    init_PageMeta();
    init_StickyCard();
    init_FormInput();
    init_NumberInput();
    init_DropdownCombobox();
    init_Toggle();
    init_SyncPromptModal();
  }
});

// dist/build/server/nodes/25.js
var __exports26 = {};
__export(__exports26, {
  component: () => component24,
  fonts: () => fonts26,
  imports: () => imports26,
  index: () => index26,
  server: () => page_server_ts_exports18,
  server_id: () => server_id24,
  stylesheets: () => stylesheets26
});
var index26, component_cache24, component24, server_id24, imports26, stylesheets26, fonts26;
var init__26 = __esm({
  async "dist/build/server/nodes/25.js"() {
    "use strict";
    await init_page_server_ts18();
    index26 = 25;
    component24 = async () => component_cache24 ??= (await Promise.resolve().then(() => (init_page_svelte17(), page_svelte_exports17))).default;
    server_id24 = "src/routes/custom-formats/[databaseId]/[id]/conditions/+page.server.ts";
    imports26 = ["_app/immutable/nodes/25.DMthuDYQ.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/Dg15A-ry2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/DK-GnTaC2.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/7yuvYLu22.js"];
    stylesheets26 = [];
    fonts26 = [];
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/general/_page.server.ts.js
var page_server_ts_exports19 = {};
__export(page_server_ts_exports19, {
  actions: () => actions13,
  load: () => load23
});
var load23, actions13;
var init_page_server_ts19 = __esm({
  async "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/general/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    init_read2();
    await init_create();
    await init_customFormats();
    await init_generalSettings();
    await init_affectedArrs();
    init_exports();
    load23 = async ({ params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) throw error(400, "Missing required parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const formatId = parseInt(id, 10);
      if (isNaN(formatId)) throw error(400, "Invalid format ID");
      const currentDatabase = pcdManager.getByIdPublic(currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const format = await general2(cache3, formatId);
      if (!format) throw error(404, "Custom format not found");
      return {
        currentDatabase,
        format,
        profileRefs: await getProfileRefsForCustomFormat(cache3, format.name),
        failOnReferencedDelete: generalSettingsQueries.shouldFailOnReferencedDelete(),
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions13 = {
      update: async ({ request, params }) => {
        const { databaseId, id } = params;
        if (!databaseId || !id) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        const formatId = parseInt(id, 10);
        if (isNaN(currentDatabaseId) || isNaN(formatId)) return fail(400, { error: "Invalid parameters" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await general2(cache3, formatId);
        if (!current3) return fail(404, { error: "Custom format not found" });
        const formData = await request.formData();
        const name = formData.get("name");
        const description = formData.get("description") || "";
        const tagsJson = formData.get("tags");
        const includeInRename = formData.get("includeInRename") === "true";
        const layer = formData.get("layer") || "user";
        if (!name?.trim()) return fail(400, { error: "Name is required" });
        let tags = [];
        try {
          tags = JSON.parse(tagsJson || "[]");
        } catch {
          return fail(400, { error: "Invalid tags format" });
        }
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        let result;
        try {
          result = await updateGeneral({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            current: current3,
            input: {
              name: name.trim(),
              description: description.trim(),
              includeInRename,
              tags
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update custom format";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update custom format" });
        const affectedArrs = getAffectedArrs({
          entityType: "customFormat",
          databaseId: currentDatabaseId,
          entityName: name.trim()
        });
        return {
          success: true,
          redirectTo: `/custom-formats/${databaseId}/${id}/general`,
          affectedArrs
        };
      },
      delete: async ({ request, params }) => {
        const { databaseId, id } = params;
        if (!databaseId || !id) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        const formatId = parseInt(id, 10);
        if (isNaN(currentDatabaseId) || isNaN(formatId)) return fail(400, { error: "Invalid parameters" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await general2(cache3, formatId);
        if (!current3) return fail(404, { error: "Custom format not found" });
        const layer = (await request.formData()).get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await remove2({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          formatId,
          formatName: current3.name
        });
        if (!result.success) {
          const status = result.error?.startsWith("Referenced by ") ? 400 : 500;
          return fail(status, { error: result.error || "Failed to delete custom format" });
        }
        throw redirect(303, `/custom-formats/${databaseId}`);
      }
    };
  }
});

// dist/build/server/chunks/code.js
function Code($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "code" },
    props,
    { iconNode: [["path", { "d": "m16 18 6-6-6-6" }], ["path", { "d": "m8 6-6 6 6 6" }]] }
  ]));
}
var init_code = __esm({
  "dist/build/server/chunks/code.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/list2.js
function List($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "list" },
    props,
    { iconNode: [
      ["path", { "d": "M3 5h.01" }],
      ["path", { "d": "M3 12h.01" }],
      ["path", { "d": "M3 19h.01" }],
      ["path", { "d": "M8 5h13" }],
      ["path", { "d": "M8 12h13" }],
      ["path", { "d": "M8 19h13" }]
    ] }
  ]));
}
var init_list2 = __esm({
  "dist/build/server/chunks/list2.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/MarkdownInput.js
function Bold($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "bold" },
    props,
    { iconNode: [["path", { "d": "M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8" }]] }
  ]));
}
function Italic($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "italic" },
    props,
    { iconNode: [
      ["line", {
        "x1": "19",
        "x2": "10",
        "y1": "4",
        "y2": "4"
      }],
      ["line", {
        "x1": "14",
        "x2": "5",
        "y1": "20",
        "y2": "20"
      }],
      ["line", {
        "x1": "15",
        "x2": "9",
        "y1": "4",
        "y2": "20"
      }]
    ] }
  ]));
}
function List_ordered($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "list-ordered" },
    props,
    { iconNode: [
      ["path", { "d": "M11 5h10" }],
      ["path", { "d": "M11 12h10" }],
      ["path", { "d": "M11 19h10" }],
      ["path", { "d": "M4 4h1v5" }],
      ["path", { "d": "M4 9h2" }],
      ["path", { "d": "M6.5 20H3.4c0-1 2.6-1.925 2.6-3.5a1.5 1.5 0 0 0-2.6-1.02" }]
    ] }
  ]));
}
function MarkdownInput($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let stateClass;
    let value2 = fallback($$props["value"], "");
    let placeholder = fallback($$props["placeholder"], "");
    let label = fallback($$props["label"], "");
    let description = fallback($$props["description"], "");
    let rows = fallback($$props["rows"], 8);
    let multiline = fallback($$props["multiline"], true);
    let markdown = fallback($$props["markdown"], true);
    let required = fallback($$props["required"], false);
    let disabled = fallback($$props["disabled"], false);
    let name = fallback($$props["name"], "");
    let id = fallback($$props["id"], name);
    let onchange = fallback($$props["onchange"], void 0);
    let showPreview = false;
    let textareaElement;
    let inputElement;
    function insertMarkdown(before, after = "") {
      const element2 = multiline ? textareaElement : inputElement;
      if (!element2) return;
      const start = element2.selectionStart ?? 0;
      const end = element2.selectionEnd ?? 0;
      const selectedText = value2.substring(start, end);
      value2 = value2.substring(0, start) + before + selectedText + after + value2.substring(end);
      onchange?.(value2);
      requestAnimationFrame(() => {
        element2.focus();
        element2.setSelectionRange(start + before.length, start + before.length + selectedText.length);
      });
    }
    function insertBold() {
      insertMarkdown("**", "**");
    }
    function insertItalic() {
      insertMarkdown("*", "*");
    }
    function insertCode() {
      insertMarkdown("`", "`");
    }
    function insertLink() {
      const element2 = multiline ? textareaElement : inputElement;
      if (!element2) return;
      const start = element2.selectionStart ?? 0;
      const end = element2.selectionEnd ?? 0;
      if (value2.substring(start, end)) insertMarkdown("[", "](url)");
      else insertMarkdown("[link text](url)");
    }
    function insertList() {
      const element2 = multiline ? textareaElement : inputElement;
      if (!element2) return;
      const start = element2.selectionStart ?? 0;
      const lines = value2.substring(0, start).split("\n");
      if (lines[lines.length - 1].length === 0 || start === 0) insertMarkdown("- ");
      else insertMarkdown("\n- ");
    }
    function insertOrderedList() {
      const element2 = multiline ? textareaElement : inputElement;
      if (!element2) return;
      const start = element2.selectionStart ?? 0;
      const lines = value2.substring(0, start).split("\n");
      if (lines[lines.length - 1].length === 0 || start === 0) insertMarkdown("1. ");
      else insertMarkdown("\n1. ");
    }
    const toolbarButtons = [
      {
        action: insertBold,
        icon: Bold,
        title: "Bold (Ctrl+B)",
        shortcut: "b"
      },
      {
        action: insertItalic,
        icon: Italic,
        title: "Italic (Ctrl+I)",
        shortcut: "i"
      },
      {
        action: insertCode,
        icon: Code,
        title: "Code",
        shortcut: null
      },
      {
        action: insertLink,
        icon: Link,
        title: "Link",
        shortcut: null
      },
      {
        action: insertList,
        icon: List,
        title: "Bullet List",
        shortcut: null
      },
      {
        action: insertOrderedList,
        icon: List_ordered,
        title: "Numbered List",
        shortcut: null
      }
    ];
    $: stateClass = disabled ? "bg-neutral-100 text-neutral-500 cursor-not-allowed dark:bg-neutral-800/40 dark:text-neutral-500" : "bg-white dark:bg-neutral-800/50";
    $$renderer2.push(`<div class="space-y-2">`);
    if (label) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<label${attr("for", id)} class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(label)} `);
      if (required) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<span class="text-red-500">*</span>`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></label>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (description) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<p class="text-xs text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div>`);
    if (markdown) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div${attr_class(`flex items-center justify-between rounded-t-xl border border-neutral-300 bg-neutral-50/80 px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/40 `)}><div class="flex items-center gap-1"><!--[-->`);
      const each_array = ensure_array_like(toolbarButtons);
      for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
        let btn = each_array[$$index];
        $$renderer2.push(`<button type="button"${attr("title", btn.title)}${attr("disabled", disabled || showPreview, true)} class="rounded-md p-1.5 text-neutral-600 transition-colors hover:bg-neutral-200 hover:text-neutral-900 disabled:cursor-not-allowed disabled:opacity-50 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-100">`);
        if (btn.icon) {
          $$renderer2.push("<!--[-->");
          btn.icon($$renderer2, { size: 16 });
          $$renderer2.push("<!--]-->");
        } else {
          $$renderer2.push("<!--[!-->");
          $$renderer2.push("<!--]-->");
        }
        $$renderer2.push(`</button>`);
      }
      $$renderer2.push(`<!--]--></div> <button type="button"${attr("title", "Preview")}${attr_class(`flex items-center gap-1.5 rounded-md px-2 py-1 text-xs font-medium transition-colors text-neutral-600 hover:bg-neutral-200 dark:text-neutral-400 dark:hover:bg-neutral-700`)}>`);
      $$renderer2.push("<!--[-1-->");
      Eye($$renderer2, { size: 14 });
      $$renderer2.push(`<!----> Preview`);
      $$renderer2.push(`<!--]--></button></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (multiline) {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<textarea${attr("id", id)}${attr("name", name)}${attr("placeholder", placeholder)}${attr("rows", rows)}${attr("disabled", disabled, true)}${attr("required", required, true)}${attr_class(`${markdown ? "rounded-t-none rounded-bl-xl border-t-0" : "rounded-tl-xl rounded-tr-xl rounded-bl-xl"} block w-full border border-neutral-300 px-3 py-2 text-sm text-neutral-900 placeholder-neutral-400 transition-colors focus:outline-none dark:border-neutral-700/60 dark:text-neutral-50 dark:placeholder-neutral-500 ${stringify(stateClass)}`)}>`);
      const $$body = escape_html(value2);
      if ($$body) $$renderer2.push(`${$$body}`);
      $$renderer2.push(`</textarea>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<input type="text"${attr("id", id)}${attr("name", name)}${attr("value", value2)}${attr("placeholder", placeholder)}${attr("disabled", disabled, true)}${attr("required", required, true)}${attr_class(`${markdown ? "rounded-t-none rounded-bl-xl border-t-0" : "rounded-tl-xl rounded-tr-xl rounded-bl-xl"} block w-full border border-neutral-300 px-3 py-2 text-sm text-neutral-900 placeholder-neutral-400 transition-colors focus:outline-none dark:border-neutral-700/60 dark:text-neutral-50 dark:placeholder-neutral-500 ${stringify(stateClass)}`)}/>`);
    }
    $$renderer2.push(`<!--]--></div></div>`);
    bind_props($$props, {
      value: value2,
      placeholder,
      label,
      description,
      rows,
      multiline,
      markdown,
      required,
      disabled,
      name,
      id,
      onchange
    });
  });
}
var init_MarkdownInput = __esm({
  "dist/build/server/chunks/MarkdownInput.js"() {
    "use strict";
    init_server();
    init_Icon();
    init_code();
    init_eye();
    init_link();
    init_list2();
    init_marked_esm();
  }
});

// dist/build/server/chunks/GeneralForm.js
function GeneralForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, title, description_, submitButtonText, deleteBlocked, deleteTooltip, name, tags, description, includeInRename, isValid;
    let mode = $$props["mode"];
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let actionUrl = fallback($$props["actionUrl"], "");
    let initialData = $$props["initialData"];
    let failOnReferencedDelete = fallback($$props["failOnReferencedDelete"], false);
    let referenceCount = fallback($$props["referenceCount"], 0);
    let onCancel = fallback($$props["onCancel"], void 0);
    const defaults = {
      name: "",
      tags: [],
      description: "",
      includeInRename: false
    };
    if (mode === "create") initCreate(initialData ?? defaults);
    else initEdit(initialData);
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    let deleteLayer = canWriteToBase2 ? "base" : "user";
    let showDeleteConfirmModal = false;
    let showSyncModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: title = mode === "create" ? "New Custom Format" : "General";
    $: description_ = mode === "create" ? `After saving, you'll be able to add conditions and tests.` : `Update custom format settings`;
    $: submitButtonText = mode === "create" ? "Create" : "Save Changes";
    $: deleteBlocked = mode === "edit" && failOnReferencedDelete && referenceCount > 0;
    $: deleteTooltip = deleteBlocked ? `Referenced by ${referenceCount} quality profile${referenceCount === 1 ? "" : "s"}` : "";
    $: name = store_get($$store_subs ??= {}, "$current", current2).name ?? "";
    $: tags = store_get($$store_subs ??= {}, "$current", current2).tags ?? [];
    $: description = store_get($$store_subs ??= {}, "$current", current2).description ?? "";
    $: includeInRename = store_get($$store_subs ??= {}, "$current", current2).includeInRename ?? false;
    $: isValid = name.trim() !== "";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="space-y-6">`);
      StickyCard($$renderer3, {
        position: "top",
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h2> <p class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(description_)}</p>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div class="flex items-center gap-2">`);
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                disabled: deleteBlocked,
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                text: "Delete",
                tooltip: deleteTooltip
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            if (onCancel) {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, { text: "Cancel" });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            Button($$renderer4, {
              disabled: !isValid || !store_get($$store_subs ??= {}, "$isDirty", isDirty),
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              text: submitButtonText
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <form method="POST"${attr("action", actionUrl)} class="md:px-4"><input type="hidden" name="tags"${attr("value", JSON.stringify(tags))}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/> <input type="hidden" name="includeInRename"${attr("value", includeInRename)}/> <div class="space-y-6"><div class="space-y-2"><div class="flex items-center justify-between"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Name<span class="text-red-500">*</span></div> <div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Include In Rename</div></div> <div class="flex items-center justify-between"><p class="text-xs text-neutral-600 dark:text-neutral-400">The name of this custom format</p> <p class="text-xs text-neutral-600 dark:text-neutral-400">When enabled, this custom format's name will be included in the renamed filename.</p></div> <div class="flex items-end gap-4"><div class="min-w-0 flex-[19]" data-onboarding="cf-general-name">`);
      FormInput($$renderer3, {
        label: "Name",
        name: "name",
        value: name,
        required: true,
        hideLabel: true,
        placeholder: "Enter custom format name"
      });
      $$renderer3.push(`<!----></div> <div class="flex-1" data-onboarding="cf-general-include-in-rename">`);
      Toggle($$renderer3, {
        checked: includeInRename,
        ariaLabel: "Include in rename",
        label: includeInRename ? "Enabled" : "Disabled",
        color: "accent",
        fullWidth: true
      });
      $$renderer3.push(`<!----></div></div></div> <div data-onboarding="cf-general-description-tags" class="space-y-6">`);
      MarkdownInput($$renderer3, {
        id: "description",
        name: "description",
        label: "Description",
        description: "Add any notes or details about this custom format's purpose and configuration.",
        value: description,
        onchange: (v3) => update3("description", v3)
      });
      $$renderer3.push(`<!----> <div class="space-y-2"><div class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Tags</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Add tags to organize and categorize this custom format.</p> `);
      TagInput($$renderer3, {
        tags,
        onchange: (newTags) => update3("tags", newTags)
      });
      $$renderer3.push(`<!----></div></div></div></form> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form method="POST" action="?/delete" class="hidden"><input type="hidden" name="layer"${attr("value", deleteLayer)}/></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        Modal($$renderer3, {
          open: showDeleteConfirmModal,
          header: "Delete Custom Format",
          bodyMessage: `Are you sure you want to delete "${name}"? This action cannot be undone.`,
          confirmText: "Delete",
          cancelText: "Cancel",
          confirmDanger: true
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      SyncPromptModal($$renderer3, {
        redirectTo: pendingRedirectTo,
        affectedArrs: pendingAffectedArrs,
        entityType: "customFormat",
        databaseId,
        entityName: name.trim(),
        get open() {
          return showSyncModal;
        },
        set open($$value) {
          showSyncModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      canWriteToBase: canWriteToBase2,
      actionUrl,
      initialData,
      failOnReferencedDelete,
      referenceCount,
      onCancel
    });
  });
}
var init_GeneralForm = __esm({
  "dist/build/server/chunks/GeneralForm.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_MarkdownInput();
    init_Button();
    init_save();
    init_trash_2();
    init_stores();
    init_store2();
    init_navigation();
    init_Modal();
    init_forms();
    init_dirty();
    init_StickyCard();
    init_FormInput();
    init_Toggle();
    init_TagInput();
    init_SyncPromptModal();
  }
});

// dist/build/server/chunks/InlineLink.js
function InlineLink($$renderer, $$props) {
  let href = $$props["href"];
  let text2 = $$props["text"];
  let external = fallback($$props["external"], false);
  $$renderer.push(`<a${attr("href", href)}${attr("target", external ? "_blank" : void 0)}${attr("rel", external ? "noopener noreferrer" : void 0)} class="text-neutral-900 transition-colors hover:text-accent-600 hover:underline dark:text-neutral-100 dark:hover:text-accent-400">${escape_html(text2)}</a>`);
  bind_props($$props, {
    href,
    text: text2,
    external
  });
}
var init_InlineLink = __esm({
  "dist/build/server/chunks/InlineLink.js"() {
    "use strict";
    init_server();
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/general/_page.svelte.js
var page_svelte_exports18 = {};
__export(page_svelte_exports18, {
  default: () => _page18
});
function _page18($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, initialData;
    let data = $$props["data"];
    const columns = [
      {
        key: "name",
        header: "Profile"
      },
      {
        key: "radarrScore",
        header: "Radarr",
        align: "center"
      },
      {
        key: "sonarrScore",
        header: "Sonarr",
        align: "center"
      }
    ];
    $: databaseId = store_get($$store_subs ??= {}, "$page", page).params.databaseId;
    $: initialData = {
      name: data.format.name,
      tags: data.format.tags.map((t2) => t2.name),
      description: data.format.description ?? "",
      includeInRename: data.format.include_in_rename
    };
    PageMeta($$renderer2, { title: `${data.format.name} \xB7 General` });
    $$renderer2.push(`<!----> `);
    GeneralForm($$renderer2, {
      mode: "edit",
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      initialData,
      failOnReferencedDelete: data.failOnReferencedDelete,
      referenceCount: data.profileRefs.length
    });
    $$renderer2.push(`<!----> <div class="space-y-3 md:px-4" data-onboarding="cf-general-references"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">References (${escape_html(data.profileRefs.length)})</div> `);
    if (data.profileRefs.length > 0) {
      $$renderer2.push("<!--[0-->");
      Table2($$renderer2, {
        data: data.profileRefs,
        columns,
        compact: true,
        responsive: true,
        $$slots: { cell: ($$renderer3, { row, column }) => {
          if (column.key === "name") {
            $$renderer3.push("<!--[0-->");
            InlineLink($$renderer3, {
              href: `/quality-profiles/${stringify(databaseId)}/${stringify(row.id)}/scoring`,
              text: row.name,
              external: true
            });
          } else if (column.key === "radarrScore") {
            $$renderer3.push("<!--[1-->");
            Score($$renderer3, {
              score: row.radarrScore,
              size: "sm"
            });
          } else if (column.key === "sonarrScore") {
            $$renderer3.push("<!--[2-->");
            Score($$renderer3, {
              score: row.sonarrScore,
              size: "sm"
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } }
      });
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">Not used in any quality profiles.</p>`);
    }
    $$renderer2.push(`<!--]--></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte18 = __esm({
  "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/general/_page.svelte.js"() {
    "use strict";
    init_server();
    init_stores();
    init_PageMeta();
    init_Table();
    init_Score();
    init_GeneralForm();
    init_InlineLink();
  }
});

// dist/build/server/nodes/26.js
var __exports27 = {};
__export(__exports27, {
  component: () => component25,
  fonts: () => fonts27,
  imports: () => imports27,
  index: () => index27,
  server: () => page_server_ts_exports19,
  server_id: () => server_id25,
  stylesheets: () => stylesheets27
});
var index27, component_cache25, component25, server_id25, imports27, stylesheets27, fonts27;
var init__27 = __esm({
  async "dist/build/server/nodes/26.js"() {
    "use strict";
    await init_page_server_ts19();
    index27 = 26;
    component25 = async () => component_cache25 ??= (await Promise.resolve().then(() => (init_page_svelte18(), page_svelte_exports18))).default;
    server_id25 = "src/routes/custom-formats/[databaseId]/[id]/general/+page.server.ts";
    imports27 = ["_app/immutable/nodes/26.CLR2qcqe.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/Co6rAu4X.js", "_app/immutable/chunks/D-q_ZSae2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/CK2yQf0C.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BhExzYrM2.js"];
    stylesheets27 = ["_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts27 = [];
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/_page.server.ts.js
var page_server_ts_exports20 = {};
__export(page_server_ts_exports20, {
  actions: () => actions14,
  load: () => load24
});
var load24, actions14;
var init_page_server_ts20 = __esm({
  async "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_create();
    await init_customFormats();
    init_read3();
    await init_client2();
    init_exports();
    load24 = async ({ params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) throw error(400, "Missing required parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const formatId = parseInt(id, 10);
      if (isNaN(formatId)) throw error(400, "Invalid format ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const format = await getById(cache3, formatId);
      if (!format) throw error(404, "Custom format not found");
      const tests = await listTests(cache3, format.name);
      const parserAvailable = await isParserHealthy();
      if (!parserAvailable || tests.length === 0) return {
        format,
        tests: tests.map((test2) => ({
          ...test2,
          actual_match: null,
          result: "unknown",
          parsed: null,
          conditions: []
        })),
        parserAvailable,
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
      const conditions = await getConditionsForEvaluation(cache3, format.name);
      const titlePatterns = /* @__PURE__ */ new Set();
      const editionPatterns = /* @__PURE__ */ new Set();
      const rgPatterns = /* @__PURE__ */ new Set();
      for (const cond of conditions) {
        if (!cond.patterns) continue;
        const target = cond.type === "release_title" ? titlePatterns : cond.type === "edition" ? editionPatterns : cond.type === "release_group" ? rgPatterns : null;
        if (!target) continue;
        for (const p2 of cond.patterns) if (p2.pattern) target.add(p2.pattern);
      }
      const uniqueTitle = [...titlePatterns];
      const uniqueEdition = [...editionPatterns];
      const uniqueRg = [...rgPatterns];
      return {
        format,
        tests: await Promise.all(tests.map(async (test2) => {
          try {
            const parsedResult = await parse3(test2.title, test2.type);
            const parsed = getParsedInfo(parsedResult);
            const [titleMatch, editionMatch, rgMatch] = await Promise.all([
              uniqueTitle.length > 0 ? matchPatterns(test2.title, uniqueTitle) : Promise.resolve(/* @__PURE__ */ new Map()),
              uniqueEdition.length > 0 && parsedResult.edition ? matchPatterns(parsedResult.edition, uniqueEdition) : Promise.resolve(/* @__PURE__ */ new Map()),
              uniqueRg.length > 0 && parsedResult.releaseGroup ? matchPatterns(parsedResult.releaseGroup, uniqueRg) : Promise.resolve(/* @__PURE__ */ new Map())
            ]);
            const patternMatchMaps = titleMatch === null || editionMatch === null || rgMatch === null ? null : {
              title: titleMatch ?? /* @__PURE__ */ new Map(),
              edition: editionMatch ?? /* @__PURE__ */ new Map(),
              releaseGroup: rgMatch ?? /* @__PURE__ */ new Map()
            };
            const evaluation = evaluateCustomFormat(conditions, parsedResult, test2.title, patternMatchMaps);
            const actual_match = evaluation.matches;
            const result = actual_match === test2.should_match ? "pass" : "fail";
            return {
              ...test2,
              actual_match,
              result,
              parsed,
              conditions: evaluation.conditions
            };
          } catch (e) {
            console.error(`Failed to evaluate test "${test2.title}":`, e);
            return {
              ...test2,
              actual_match: null,
              result: "unknown",
              parsed: null,
              conditions: []
            };
          }
        })),
        parserAvailable,
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions14 = { delete: async ({ request, params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) return fail(400, { error: "Missing required parameters" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
      if (!canWriteToBase(currentDatabaseId)) return fail(403, { error: "Entity tests are read-only for this database" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const formatName = formData.get("formatName");
      const testTitle = formData.get("testTitle");
      const testType = formData.get("testType");
      const layer = formData.get("layer") || "user";
      if (!formatName) return fail(400, { error: "Format name is required" });
      if (!testTitle || !testType) return fail(400, { error: "Test title and type are required" });
      const current3 = await getTest(cache3, formatName, testTitle, testType);
      if (!current3) return fail(404, { error: "Test not found" });
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      const result = await deleteTest({
        databaseId: currentDatabaseId,
        layer,
        formatName,
        current: current3
      });
      if (!result.success) return fail(500, { error: result.error || "Failed to delete test" });
      return { success: true };
    } };
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/_page.svelte.js
var page_svelte_exports19 = {};
__export(page_svelte_exports19, {
  default: () => _page19
});
function _page19($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    clear();
    const columns = [
      {
        key: "title",
        header: "Release Title",
        sortable: true
      },
      {
        key: "should_match",
        header: "Expected",
        width: "w-40",
        align: "center",
        sortable: true
      },
      {
        key: "type",
        header: "Type",
        width: "w-24",
        align: "center",
        sortable: true
      },
      {
        key: "result",
        header: "Result",
        width: "w-24",
        align: "center",
        sortable: true
      }
    ];
    function getRowId(test2) {
      return `${test2.title}:${test2.type}`;
    }
    let showDeleteModal = false;
    $: data.canWriteToBase;
    PageMeta($$renderer2, { title: `${data.format.name} \xB7 Testing` });
    $$renderer2.push(`<!----> <div class="space-y-6">`);
    StickyCard($$renderer2, {
      position: "top",
      $$slots: {
        left: ($$renderer3) => {
          $$renderer3.push(`<div><h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-100">Test Cases</h2> <p class="text-sm text-neutral-600 dark:text-neutral-400">Test release titles against this custom format</p></div>`);
        },
        right: ($$renderer3) => {
          Button($$renderer3, {
            text: "Add Test",
            icon: Plus,
            iconColor: "text-blue-600 dark:text-blue-400",
            variant: "secondary",
            onboarding: "cf-testing-add"
          });
        }
      }
    });
    $$renderer2.push(`<!----> <div class="mt-6 space-y-6 pb-12 md:px-4">`);
    if (!data.parserAvailable) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="flex items-center gap-3 rounded-lg border border-amber-200 bg-amber-50 p-4 dark:border-amber-800 dark:bg-amber-900/20">`);
      Triangle_alert($$renderer2, {
        size: 20,
        class: "text-amber-600 dark:text-amber-400"
      });
      $$renderer2.push(`<!----> <div><p class="text-sm font-medium text-amber-800 dark:text-amber-200">Parser service unavailable</p> <p class="text-xs text-amber-600 dark:text-amber-400">Test results cannot be evaluated. Start the parser microservice to see pass/fail status.</p></div></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (data.tests.length === 0) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No test cases yet. Add a test to verify this custom format works correctly.</p></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      ExpandableTable($$renderer2, {
        columns,
        data: data.tests,
        getRowId,
        emptyMessage: "No test cases found",
        flushExpanded: true,
        responsive: true,
        $$slots: {
          cell: ($$renderer3, { row, column }) => {
            if (column.key === "title") {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<code class="font-mono text-sm">${escape_html(row.title)}</code> `);
              if (row.description) {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<p class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">${escape_html(row.description)}</p>`);
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]-->`);
            } else if (column.key === "should_match") {
              $$renderer3.push("<!--[1-->");
              if (row.should_match) {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<span class="inline-flex items-center gap-1 rounded bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200">Should Match</span>`);
              } else {
                $$renderer3.push("<!--[-1-->");
                $$renderer3.push(`<span class="inline-flex items-center gap-1 rounded bg-red-100 px-2 py-0.5 text-xs font-medium text-red-800 dark:bg-red-900 dark:text-red-200">Shouldn't Match</span>`);
              }
              $$renderer3.push(`<!--]-->`);
            } else if (column.key === "type") {
              $$renderer3.push("<!--[2-->");
              $$renderer3.push(`<span class="inline-flex items-center gap-1 rounded bg-neutral-100 px-2 py-0.5 text-xs font-medium text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300">${escape_html(row.type)}</span>`);
            } else if (column.key === "result") {
              $$renderer3.push("<!--[3-->");
              if (row.result === "pass") {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<div class="flex items-center justify-center"><div class="flex h-6 w-6 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900">`);
                Check($$renderer3, {
                  size: 14,
                  class: "text-emerald-600 dark:text-emerald-400"
                });
                $$renderer3.push(`<!----></div></div>`);
              } else if (row.result === "fail") {
                $$renderer3.push("<!--[1-->");
                $$renderer3.push(`<div class="flex items-center justify-center"><div class="flex h-6 w-6 items-center justify-center rounded-full bg-red-100 dark:bg-red-900">`);
                X2($$renderer3, {
                  size: 14,
                  class: "text-red-600 dark:text-red-400"
                });
                $$renderer3.push(`<!----></div></div>`);
              } else {
                $$renderer3.push("<!--[-1-->");
                $$renderer3.push(`<div class="flex items-center justify-center"><div class="flex h-6 w-6 items-center justify-center rounded-full bg-amber-100 dark:bg-amber-900"><span class="text-sm font-medium text-amber-600 dark:text-amber-400">?</span></div></div>`);
              }
              $$renderer3.push(`<!--]-->`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]-->`);
          },
          expanded: ($$renderer3, { row }) => {
            {
              const conditionTypeLabels = {
                "release_title": "Release Title",
                "source": "Source",
                "resolution": "Resolution",
                "quality_modifier": "Quality Modifier",
                "language": "Language",
                "release_group": "Release Group",
                "release_type": "Release Type",
                "year": "Year",
                "edition": "Edition",
                "indexer_flag": "Indexer Flag",
                "size": "Size"
              };
              const groupedConditions = row.conditions.reduce((acc, c2) => {
                if (!acc[c2.conditionType]) acc[c2.conditionType] = [];
                acc[c2.conditionType].push(c2);
                return acc;
              }, {});
              const conditionTypes = Object.keys(groupedConditions);
              row.conditions.filter((c2) => c2.required).every((c2) => c2.passes);
              const optionalConditions = row.conditions.filter((c2) => !c2.required);
              optionalConditions.length === 0 || optionalConditions.some((c2) => c2.passes);
              $$renderer3.push(`<div class="px-4 py-3">`);
              if (row.conditions.length > 0) {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<div class="overflow-x-auto rounded-lg border border-neutral-200 dark:border-neutral-800"><table class="w-full text-sm"><thead class="border-b border-neutral-200 bg-neutral-50 dark:border-neutral-800 dark:bg-neutral-800"><tr><th class="px-3 py-2 text-left text-xs font-medium tracking-wider text-neutral-700 uppercase dark:text-neutral-300">Type</th><th class="px-3 py-2 text-left text-xs font-medium tracking-wider text-neutral-700 uppercase dark:text-neutral-300">Condition</th><th class="px-3 py-2 text-left text-xs font-medium tracking-wider text-neutral-700 uppercase dark:text-neutral-300">Expected</th><th class="px-3 py-2 text-left text-xs font-medium tracking-wider text-neutral-700 uppercase dark:text-neutral-300">Actual</th><th class="px-3 py-2 text-center text-xs font-medium tracking-wider text-neutral-700 uppercase dark:text-neutral-300">Pass</th><th class="px-3 py-2 text-center text-xs font-medium tracking-wider text-neutral-700 uppercase dark:text-neutral-300">Type Pass</th><th class="px-3 py-2 text-center text-xs font-medium tracking-wider text-neutral-700 uppercase dark:text-neutral-300">Expected</th><th class="px-3 py-2 text-center text-xs font-medium tracking-wider text-neutral-700 uppercase dark:text-neutral-300">Actual</th><th class="px-3 py-2 text-center text-xs font-medium tracking-wider text-neutral-700 uppercase dark:text-neutral-300">Result</th></tr></thead><tbody class="divide-y divide-neutral-200 bg-white dark:divide-neutral-800 dark:bg-neutral-900"><!--[-->`);
                const each_array = ensure_array_like(conditionTypes);
                for (let typeIndex = 0, $$length = each_array.length; typeIndex < $$length; typeIndex++) {
                  let conditionType = each_array[typeIndex];
                  const conditions = groupedConditions[conditionType];
                  $$renderer3.push(`<!--[-->`);
                  const each_array_1 = ensure_array_like(conditions);
                  for (let condIndex = 0, $$length2 = each_array_1.length; condIndex < $$length2; condIndex++) {
                    let condition = each_array_1[condIndex];
                    $$renderer3.push(`<tr>`);
                    if (condIndex === 0) {
                      $$renderer3.push("<!--[0-->");
                      $$renderer3.push(`<td${attr("rowspan", conditions.length)} class="border-r border-neutral-200 px-3 py-2 align-top font-medium text-neutral-900 dark:border-neutral-800 dark:text-neutral-100">${escape_html(conditionTypeLabels[conditionType] || conditionType)}</td>`);
                    } else $$renderer3.push("<!--[-1-->");
                    $$renderer3.push(`<!--]--><td class="px-3 py-2 text-neutral-700 dark:text-neutral-300"><div class="flex items-center gap-2"><span>${escape_html(condition.conditionName)}</span> `);
                    if (condition.required) {
                      $$renderer3.push("<!--[0-->");
                      Badge($$renderer3, {
                        variant: condition.negate ? "danger" : "success",
                        children: ($$renderer4) => {
                          $$renderer4.push(`<!---->Required`);
                        },
                        $$slots: { default: true }
                      });
                    } else $$renderer3.push("<!--[-1-->");
                    $$renderer3.push(`<!--]--></div></td><td class="max-w-48 truncate px-3 py-2 font-mono text-xs text-neutral-600 dark:text-neutral-400"${attr("title", condition.expected)}>${escape_html(condition.expected)}</td><td class="max-w-48 truncate px-3 py-2 font-mono text-xs text-neutral-600 dark:text-neutral-400"${attr("title", condition.actual)}>${escape_html(condition.actual)}</td><td class="px-3 py-2 text-center">`);
                    if (condition.passes) {
                      $$renderer3.push("<!--[0-->");
                      $$renderer3.push(`<div class="inline-flex h-5 w-5 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900">`);
                      Check($$renderer3, {
                        size: 12,
                        class: "text-emerald-600 dark:text-emerald-400"
                      });
                      $$renderer3.push(`<!----></div>`);
                    } else {
                      $$renderer3.push("<!--[-1-->");
                      $$renderer3.push(`<div class="inline-flex h-5 w-5 items-center justify-center rounded-full bg-red-100 dark:bg-red-900">`);
                      X2($$renderer3, {
                        size: 12,
                        class: "text-red-600 dark:text-red-400"
                      });
                      $$renderer3.push(`<!----></div>`);
                    }
                    $$renderer3.push(`<!--]--></td>`);
                    if (condIndex === 0) {
                      $$renderer3.push("<!--[0-->");
                      const requiredPass = conditions.filter((c2) => c2.required).every((c2) => c2.passes);
                      const optionalConditions2 = conditions.filter((c2) => !c2.required);
                      const optionalPass = optionalConditions2.length === 0 || optionalConditions2.some((c2) => c2.passes);
                      const typePass = requiredPass && optionalPass;
                      $$renderer3.push(`<td${attr("rowspan", conditions.length)} class="border-l border-neutral-200 px-3 py-2 text-center align-middle dark:border-neutral-800">`);
                      if (typePass) {
                        $$renderer3.push("<!--[0-->");
                        $$renderer3.push(`<div class="inline-flex h-6 w-6 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900">`);
                        Check($$renderer3, {
                          size: 14,
                          class: "text-emerald-600 dark:text-emerald-400"
                        });
                        $$renderer3.push(`<!----></div>`);
                      } else {
                        $$renderer3.push("<!--[-1-->");
                        $$renderer3.push(`<div class="inline-flex h-6 w-6 items-center justify-center rounded-full bg-red-100 dark:bg-red-900">`);
                        X2($$renderer3, {
                          size: 14,
                          class: "text-red-600 dark:text-red-400"
                        });
                        $$renderer3.push(`<!----></div>`);
                      }
                      $$renderer3.push(`<!--]--></td>`);
                    } else $$renderer3.push("<!--[-1-->");
                    $$renderer3.push(`<!--]-->`);
                    if (typeIndex === 0 && condIndex === 0) {
                      $$renderer3.push("<!--[0-->");
                      $$renderer3.push(`<td${attr("rowspan", row.conditions.length)} class="border-l border-neutral-200 px-3 py-2 text-center align-middle dark:border-neutral-800">`);
                      if (row.should_match) {
                        $$renderer3.push("<!--[0-->");
                        $$renderer3.push(`<div class="inline-flex h-10 w-10 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900">`);
                        Check($$renderer3, {
                          size: 24,
                          class: "text-emerald-600 dark:text-emerald-400"
                        });
                        $$renderer3.push(`<!----></div> <div class="mt-1 text-[10px] font-medium text-emerald-600 dark:text-emerald-400">MATCH</div>`);
                      } else {
                        $$renderer3.push("<!--[-1-->");
                        $$renderer3.push(`<div class="inline-flex h-10 w-10 items-center justify-center rounded-full bg-red-100 dark:bg-red-900">`);
                        X2($$renderer3, {
                          size: 24,
                          class: "text-red-600 dark:text-red-400"
                        });
                        $$renderer3.push(`<!----></div> <div class="mt-1 text-[10px] font-medium text-red-600 dark:text-red-400">NO MATCH</div>`);
                      }
                      $$renderer3.push(`<!--]--></td> <td${attr("rowspan", row.conditions.length)} class="border-l border-neutral-200 px-3 py-2 text-center align-middle dark:border-neutral-800">`);
                      if (row.actual_match) {
                        $$renderer3.push("<!--[0-->");
                        $$renderer3.push(`<div class="inline-flex h-10 w-10 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900">`);
                        Check($$renderer3, {
                          size: 24,
                          class: "text-emerald-600 dark:text-emerald-400"
                        });
                        $$renderer3.push(`<!----></div> <div class="mt-1 text-[10px] font-medium text-emerald-600 dark:text-emerald-400">MATCH</div>`);
                      } else {
                        $$renderer3.push("<!--[-1-->");
                        $$renderer3.push(`<div class="inline-flex h-10 w-10 items-center justify-center rounded-full bg-red-100 dark:bg-red-900">`);
                        X2($$renderer3, {
                          size: 24,
                          class: "text-red-600 dark:text-red-400"
                        });
                        $$renderer3.push(`<!----></div> <div class="mt-1 text-[10px] font-medium text-red-600 dark:text-red-400">NO MATCH</div>`);
                      }
                      $$renderer3.push(`<!--]--></td> <td${attr("rowspan", row.conditions.length)} class="border-l border-neutral-200 px-3 py-2 text-center align-middle dark:border-neutral-800">`);
                      if (row.result === "pass") {
                        $$renderer3.push("<!--[0-->");
                        $$renderer3.push(`<div class="inline-flex h-10 w-10 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900">`);
                        Check($$renderer3, {
                          size: 24,
                          class: "text-emerald-600 dark:text-emerald-400"
                        });
                        $$renderer3.push(`<!----></div> <div class="mt-1 text-[10px] font-medium text-emerald-600 dark:text-emerald-400">PASS</div>`);
                      } else if (row.result === "fail") {
                        $$renderer3.push("<!--[1-->");
                        $$renderer3.push(`<div class="inline-flex h-10 w-10 items-center justify-center rounded-full bg-red-100 dark:bg-red-900">`);
                        X2($$renderer3, {
                          size: 24,
                          class: "text-red-600 dark:text-red-400"
                        });
                        $$renderer3.push(`<!----></div> <div class="mt-1 text-[10px] font-medium text-red-600 dark:text-red-400">FAIL</div>`);
                      } else {
                        $$renderer3.push("<!--[-1-->");
                        $$renderer3.push(`<div class="inline-flex h-10 w-10 items-center justify-center rounded-full bg-amber-100 dark:bg-amber-900"><span class="text-lg font-medium text-amber-600 dark:text-amber-400">?</span></div> <div class="mt-1 text-[10px] font-medium text-amber-600 dark:text-amber-400">UNKNOWN</div>`);
                      }
                      $$renderer3.push(`<!--]--></td>`);
                    } else $$renderer3.push("<!--[-1-->");
                    $$renderer3.push(`<!--]--></tr>`);
                  }
                  $$renderer3.push(`<!--]-->`);
                }
                $$renderer3.push(`<!--]--></tbody></table></div> `);
                if (row.parsed) {
                  $$renderer3.push("<!--[0-->");
                  $$renderer3.push(`<details class="mt-4"><summary class="cursor-pointer text-xs font-semibold tracking-wider text-neutral-500 uppercase hover:text-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-300">Parsed Values</summary> <div class="mt-2 flex flex-wrap gap-2"><div class="flex items-center gap-1.5"><span class="text-xs text-neutral-500 dark:text-neutral-400">Source:</span> `);
                  Badge($$renderer3, {
                    variant: "neutral",
                    size: "md",
                    children: ($$renderer4) => {
                      $$renderer4.push(`<!---->${escape_html(row.parsed.source)}`);
                    },
                    $$slots: { default: true }
                  });
                  $$renderer3.push(`<!----></div> <div class="flex items-center gap-1.5"><span class="text-xs text-neutral-500 dark:text-neutral-400">Resolution:</span> `);
                  Badge($$renderer3, {
                    variant: "neutral",
                    size: "md",
                    children: ($$renderer4) => {
                      $$renderer4.push(`<!---->${escape_html(row.parsed.resolution)}`);
                    },
                    $$slots: { default: true }
                  });
                  $$renderer3.push(`<!----></div> <div class="flex items-center gap-1.5"><span class="text-xs text-neutral-500 dark:text-neutral-400">Modifier:</span> `);
                  Badge($$renderer3, {
                    variant: "neutral",
                    size: "md",
                    children: ($$renderer4) => {
                      $$renderer4.push(`<!---->${escape_html(row.parsed.modifier)}`);
                    },
                    $$slots: { default: true }
                  });
                  $$renderer3.push(`<!----></div> <div class="flex items-center gap-1.5"><span class="text-xs text-neutral-500 dark:text-neutral-400">Languages:</span> `);
                  Badge($$renderer3, {
                    variant: "neutral",
                    size: "md",
                    children: ($$renderer4) => {
                      $$renderer4.push(`<!---->${escape_html(row.parsed.languages.length > 0 ? row.parsed.languages.join(", ") : "None")}`);
                    },
                    $$slots: { default: true }
                  });
                  $$renderer3.push(`<!----></div> `);
                  if (row.parsed.releaseGroup) {
                    $$renderer3.push("<!--[0-->");
                    $$renderer3.push(`<div class="flex items-center gap-1.5"><span class="text-xs text-neutral-500 dark:text-neutral-400">Release Group:</span> `);
                    Badge($$renderer3, {
                      variant: "neutral",
                      size: "md",
                      children: ($$renderer4) => {
                        $$renderer4.push(`<!---->${escape_html(row.parsed.releaseGroup)}`);
                      },
                      $$slots: { default: true }
                    });
                    $$renderer3.push(`<!----></div>`);
                  } else $$renderer3.push("<!--[-1-->");
                  $$renderer3.push(`<!--]--> `);
                  if (row.parsed.year) {
                    $$renderer3.push("<!--[0-->");
                    $$renderer3.push(`<div class="flex items-center gap-1.5"><span class="text-xs text-neutral-500 dark:text-neutral-400">Year:</span> `);
                    Badge($$renderer3, {
                      variant: "neutral",
                      size: "md",
                      children: ($$renderer4) => {
                        $$renderer4.push(`<!---->${escape_html(row.parsed.year)}`);
                      },
                      $$slots: { default: true }
                    });
                    $$renderer3.push(`<!----></div>`);
                  } else $$renderer3.push("<!--[-1-->");
                  $$renderer3.push(`<!--]--> `);
                  if (row.parsed.edition) {
                    $$renderer3.push("<!--[0-->");
                    $$renderer3.push(`<div class="flex items-center gap-1.5"><span class="text-xs text-neutral-500 dark:text-neutral-400">Edition:</span> `);
                    Badge($$renderer3, {
                      variant: "neutral",
                      size: "md",
                      children: ($$renderer4) => {
                        $$renderer4.push(`<!---->${escape_html(row.parsed.edition)}`);
                      },
                      $$slots: { default: true }
                    });
                    $$renderer3.push(`<!----></div>`);
                  } else $$renderer3.push("<!--[-1-->");
                  $$renderer3.push(`<!--]--> `);
                  if (row.parsed.releaseType) {
                    $$renderer3.push("<!--[0-->");
                    $$renderer3.push(`<div class="flex items-center gap-1.5"><span class="text-xs text-neutral-500 dark:text-neutral-400">Release Type:</span> `);
                    Badge($$renderer3, {
                      variant: "neutral",
                      size: "md",
                      children: ($$renderer4) => {
                        $$renderer4.push(`<!---->${escape_html(row.parsed.releaseType)}`);
                      },
                      $$slots: { default: true }
                    });
                    $$renderer3.push(`<!----></div>`);
                  } else $$renderer3.push("<!--[-1-->");
                  $$renderer3.push(`<!--]--></div></details>`);
                } else $$renderer3.push("<!--[-1-->");
                $$renderer3.push(`<!--]-->`);
              } else if (!row.parsed) {
                $$renderer3.push("<!--[1-->");
                $$renderer3.push(`<div class="text-sm text-neutral-500 dark:text-neutral-400">Parser unavailable - unable to evaluate conditions</div>`);
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--></div>`);
            }
          },
          actions: ($$renderer3, { row }) => {
            $$renderer3.push(`<div class="flex items-center justify-end gap-1">`);
            Button($$renderer3, {
              icon: Pencil,
              title: "Edit test case",
              ariaLabel: "Edit test case",
              variant: "secondary",
              iconColor: "text-accent-600 dark:text-accent-400",
              size: "xs"
            });
            $$renderer3.push(`<!----> <form method="POST" action="?/delete"><input type="hidden" name="testTitle"${attr("value", row.title)}/> <input type="hidden" name="testType"${attr("value", row.type)}/> <input type="hidden" name="formatName"${attr("value", data.format.name)}/> <input type="hidden" name="layer"${attr("value", data.canWriteToBase ? "base" : "user")}/> `);
            Button($$renderer3, {
              icon: Trash_2,
              title: "Delete test case",
              ariaLabel: "Delete test case",
              variant: "secondary",
              iconColor: "text-red-600 dark:text-red-400",
              size: "xs"
            });
            $$renderer3.push(`<!----></form></div>`);
          }
        }
      });
    }
    $$renderer2.push(`<!--]--></div></div> `);
    Modal($$renderer2, {
      open: showDeleteModal,
      header: "Delete Test Case",
      bodyMessage: "",
      confirmText: "Delete",
      cancelText: "Cancel",
      confirmDanger: true
    });
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte19 = __esm({
  "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/_page.svelte.js"() {
    "use strict";
    init_server();
    init_check();
    init_Button();
    init_pencil();
    init_plus();
    init_trash_2();
    init_triangle_alert();
    init_x();
    init_stores();
    init_store2();
    init_navigation();
    init_Modal();
    init_forms();
    init_dirty();
    init_ExpandableTable();
    init_Badge();
    init_PageMeta();
    init_StickyCard();
  }
});

// dist/build/server/nodes/27.js
var __exports28 = {};
__export(__exports28, {
  component: () => component26,
  fonts: () => fonts28,
  imports: () => imports28,
  index: () => index28,
  server: () => page_server_ts_exports20,
  server_id: () => server_id26,
  stylesheets: () => stylesheets28
});
var index28, component_cache26, component26, server_id26, imports28, stylesheets28, fonts28;
var init__28 = __esm({
  async "dist/build/server/nodes/27.js"() {
    "use strict";
    await init_page_server_ts20();
    index28 = 27;
    component26 = async () => component_cache26 ??= (await Promise.resolve().then(() => (init_page_svelte19(), page_svelte_exports19))).default;
    server_id26 = "src/routes/custom-formats/[databaseId]/[id]/testing/+page.server.ts";
    imports28 = ["_app/immutable/nodes/27.V-X2ybcu.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/B_FOzVLA.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js"];
    stylesheets28 = [];
    fonts28 = [];
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/_testId_/_page.server.ts.js
var page_server_ts_exports21 = {};
__export(page_server_ts_exports21, {
  actions: () => actions15,
  load: () => load25
});
var load25, actions15;
var init_page_server_ts21 = __esm({
  async "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/_testId_/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_create();
    await init_customFormats();
    init_read3();
    init_exports();
    load25 = async ({ params, url }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) throw error(400, "Missing required parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      const formatId = parseInt(id, 10);
      if (isNaN(currentDatabaseId) || isNaN(formatId)) throw error(400, "Invalid parameters");
      const testTitle = url.searchParams.get("title");
      const testType = url.searchParams.get("type");
      if (!testTitle || !testType) throw error(400, "Missing test title or type");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const format = await getById(cache3, formatId);
      if (!format) throw error(404, "Custom format not found");
      const test2 = await getTest(cache3, format.name, testTitle, testType);
      if (!test2) throw error(404, "Test not found");
      return {
        format,
        test: test2,
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions15 = {
      update: async ({ request, params }) => {
        const { databaseId, id } = params;
        if (!databaseId || !id) return fail(400, { error: "Missing required parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid parameters" });
        if (!canWriteToBase(currentDatabaseId)) return fail(403, { error: "Entity tests are read-only for this database" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const formData = await request.formData();
        const formatName = formData.get("formatName");
        const currentTitle = formData.get("currentTitle");
        const currentType = formData.get("currentType");
        const layer = formData.get("layer") || "user";
        if (!formatName || !currentTitle || !currentType) return fail(400, { error: "Format name, current title and type are required" });
        const current3 = await getTest(cache3, formatName, currentTitle, currentType);
        if (!current3) return fail(404, { error: "Test not found" });
        const title = formData.get("title");
        const type = formData.get("type");
        const shouldMatch = formData.get("shouldMatch") === "1";
        const description = formData.get("description") || null;
        if (!title?.trim()) return fail(400, { error: "Title is required" });
        if (type !== "movie" && type !== "series") return fail(400, { error: "Invalid type" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        let result;
        try {
          result = await updateTest({
            databaseId: currentDatabaseId,
            layer,
            formatName,
            current: current3,
            input: {
              title: title.trim(),
              type,
              should_match: shouldMatch,
              description: description?.trim() || null
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update test";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update test" });
        throw redirect(303, `/custom-formats/${databaseId}/${id}/testing`);
      },
      delete: async ({ request, params }) => {
        const { databaseId, id } = params;
        if (!databaseId || !id) return fail(400, { error: "Missing required parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid parameters" });
        if (!canWriteToBase(currentDatabaseId)) return fail(403, { error: "Entity tests are read-only for this database" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const formData = await request.formData();
        const formatName = formData.get("formatName");
        const testTitle = formData.get("testTitle");
        const testType = formData.get("testType");
        const layer = formData.get("layer") || "user";
        if (!formatName || !testTitle || !testType) return fail(400, { error: "Format name, test title and type are required" });
        const current3 = await getTest(cache3, formatName, testTitle, testType);
        if (!current3) return fail(404, { error: "Test not found" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await deleteTest({
          databaseId: currentDatabaseId,
          layer,
          formatName,
          current: current3
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete test" });
        throw redirect(303, `/custom-formats/${databaseId}/${id}/testing`);
      }
    };
  }
});

// dist/build/server/chunks/TestForm.js
function TestForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let pageTitle, pageDescription, submitButtonText, isValid;
    let mode = $$props["mode"];
    let formatName = $$props["formatName"];
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let actionUrl = fallback($$props["actionUrl"], "");
    let initialData = $$props["initialData"];
    let onCancel = $$props["onCancel"];
    let title = initialData.title;
    let type = initialData.type;
    let shouldMatch = initialData.shouldMatch;
    let description = initialData.description;
    const originalTitle = initialData.title;
    const originalType = initialData.type;
    let deleting = false;
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    let deleteLayer = canWriteToBase2 ? "base" : "user";
    const typeOptions = [{
      value: "movie",
      label: "Movie",
      description: "Parse as a movie release"
    }, {
      value: "series",
      label: "Series",
      description: "Parse as a TV series release"
    }];
    const matchOptions = [{
      value: true,
      label: "Should Match",
      description: "This title should match the custom format"
    }, {
      value: false,
      label: "Should NOT Match",
      description: "This title should not match the custom format"
    }];
    $: update3("title", title);
    $: update3("type", type);
    $: update3("shouldMatch", shouldMatch);
    $: update3("description", description);
    $: pageTitle = mode === "create" ? "New Test Case" : "Edit Test Case";
    $: pageDescription = mode === "create" ? `Add a test case for ${formatName}` : `Update test case settings`;
    $: submitButtonText = mode === "create" ? "Create" : "Save Changes";
    $: isValid = title.trim() !== "";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="mt-6 space-y-6">`);
      StickyCard($$renderer3, {
        position: "top",
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(pageTitle)}</h2> <p class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(pageDescription)}</p>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div class="flex items-center gap-2">`);
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                disabled: deleting,
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                text: "Delete"
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            Button($$renderer4, {
              text: "Cancel",
              icon: X2
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              disabled: !isValid || mode === "edit" && !store_get($$store_subs ??= {}, "$isDirty", isDirty),
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              text: submitButtonText
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <form method="POST"${attr("action", actionUrl)}><input type="hidden" name="type"${attr("value", type)}/> <input type="hidden" name="shouldMatch"${attr("value", shouldMatch ? "1" : "0")}/> <input type="hidden" name="formatName"${attr("value", formatName)}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/> <input type="hidden" name="description"${attr("value", description)}/> <input type="hidden" name="currentTitle"${attr("value", originalTitle)}/> <input type="hidden" name="currentType"${attr("value", originalType)}/> <div class="rounded-lg border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900"><div class="space-y-6 p-4"><div data-onboarding="cf-test-title">`);
      FormInput($$renderer3, {
        label: "Release Title",
        name: "title",
        required: true,
        mono: true,
        placeholder: "e.g., Movie.Name.2024.1080p.BluRay.x264-GROUP",
        get value() {
          return title;
        },
        set value($$value) {
          title = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----></div> <div data-onboarding="cf-test-type"><div class="mb-3 block text-sm font-medium text-neutral-700 dark:text-neutral-300">Media Type</div> <div class="grid gap-2 sm:grid-cols-2"><!--[-->`);
      const each_array = ensure_array_like(typeOptions);
      for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
        let option = each_array[$$index];
        $$renderer3.push(`<div class="space-y-1">`);
        Toggle($$renderer3, {
          checked: type === option.value,
          label: option.label,
          ariaLabel: `Set media type to ${option.label}`,
          fullWidth: true
        });
        $$renderer3.push(`<!----> <p class="px-1 text-xs text-neutral-500 dark:text-neutral-400">${escape_html(option.description)}</p></div>`);
      }
      $$renderer3.push(`<!--]--></div></div> <div data-onboarding="cf-test-expected"><div class="mb-3 block text-sm font-medium text-neutral-700 dark:text-neutral-300">Expected Result</div> <div class="grid gap-2 sm:grid-cols-2"><!--[-->`);
      const each_array_1 = ensure_array_like(matchOptions);
      for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
        let option = each_array_1[$$index_1];
        $$renderer3.push(`<div class="space-y-1">`);
        Toggle($$renderer3, {
          checked: shouldMatch === option.value,
          label: option.label,
          ariaLabel: option.label,
          color: option.value ? "green" : "red",
          fullWidth: true
        });
        $$renderer3.push(`<!----> <p class="px-1 text-xs text-neutral-500 dark:text-neutral-400">${escape_html(option.description)}</p></div>`);
      }
      $$renderer3.push(`<!--]--></div></div> <div data-onboarding="cf-test-description">`);
      MarkdownInput($$renderer3, {
        label: "Description",
        placeholder: "Why this test exists or what edge case it covers",
        value: description,
        onchange: (v3) => description = v3,
        rows: 2
      });
      $$renderer3.push(`<!----></div></div></div></form> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form method="POST" action="?/delete" class="hidden"><input type="hidden" name="formatName"${attr("value", formatName)}/> <input type="hidden" name="layer"${attr("value", deleteLayer)}/> <input type="hidden" name="testTitle"${attr("value", originalTitle)}/> <input type="hidden" name="testType"${attr("value", originalType)}/></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      formatName,
      canWriteToBase: canWriteToBase2,
      actionUrl,
      initialData,
      onCancel
    });
  });
}
var init_TestForm = __esm({
  "dist/build/server/chunks/TestForm.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_MarkdownInput();
    init_Button();
    init_save();
    init_trash_2();
    init_x();
    init_store2();
    init_forms();
    init_dirty();
    init_StickyCard();
    init_FormInput();
    init_Toggle();
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/_testId_/_page.svelte.js
var page_svelte_exports20 = {};
__export(page_svelte_exports20, {
  default: () => _page20
});
function _page20($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    function handleCancel() {
      goto(`/custom-formats/${store_get($$store_subs ??= {}, "$page", page).params.databaseId}/${store_get($$store_subs ??= {}, "$page", page).params.id}/testing`);
    }
    PageMeta($$renderer2, { title: `${data.format.name} \xB7 Testing \xB7 Edit` });
    $$renderer2.push(`<!----> `);
    TestForm($$renderer2, {
      mode: "edit",
      formatName: data.format.name,
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      initialData: {
        title: data.test.title,
        type: data.test.type,
        shouldMatch: data.test.should_match,
        description: data.test.description ?? ""
      },
      onCancel: handleCancel
    });
    $$renderer2.push(`<!----> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte20 = __esm({
  "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/_testId_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_client4();
    init_stores();
    init_navigation();
    init_DirtyModal();
    init_PageMeta();
    init_TestForm();
  }
});

// dist/build/server/nodes/28.js
var __exports29 = {};
__export(__exports29, {
  component: () => component27,
  fonts: () => fonts29,
  imports: () => imports29,
  index: () => index29,
  server: () => page_server_ts_exports21,
  server_id: () => server_id27,
  stylesheets: () => stylesheets29
});
var index29, component_cache27, component27, server_id27, imports29, stylesheets29, fonts29;
var init__29 = __esm({
  async "dist/build/server/nodes/28.js"() {
    "use strict";
    await init_page_server_ts21();
    index29 = 28;
    component27 = async () => component_cache27 ??= (await Promise.resolve().then(() => (init_page_svelte20(), page_svelte_exports20))).default;
    server_id27 = "src/routes/custom-formats/[databaseId]/[id]/testing/[testId]/+page.server.ts";
    imports29 = ["_app/immutable/nodes/28.S2qrYUlI.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/BP5QNy2p2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/DGICnufN.js"];
    stylesheets29 = [];
    fonts29 = [];
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/new/_page.server.ts.js
var page_server_ts_exports22 = {};
__export(page_server_ts_exports22, {
  actions: () => actions16,
  load: () => load26
});
var load26, actions16;
var init_page_server_ts22 = __esm({
  async "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/new/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_create();
    await init_customFormats();
    init_read3();
    init_exports();
    load26 = async ({ params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) throw error(400, "Missing required parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      const formatId = parseInt(id, 10);
      if (isNaN(currentDatabaseId) || isNaN(formatId)) throw error(400, "Invalid parameters");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const format = await getById(cache3, formatId);
      if (!format) throw error(404, "Custom format not found");
      return {
        format,
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions16 = { default: async ({ request, params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) return fail(400, { error: "Missing required parameters" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid parameters" });
      if (!canWriteToBase(currentDatabaseId)) return fail(403, { error: "Entity tests are read-only for this database" });
      if (!pcdManager.getCache(currentDatabaseId)) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const title = formData.get("title");
      const type = formData.get("type");
      const shouldMatch = formData.get("shouldMatch") === "1";
      const description = formData.get("description") || null;
      const formatName = formData.get("formatName");
      const layer = formData.get("layer") || "user";
      if (!title?.trim()) return fail(400, { error: "Title is required" });
      if (type !== "movie" && type !== "series") return fail(400, { error: "Invalid type" });
      if (!formatName) return fail(400, { error: "Format name is required" });
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      let result;
      try {
        result = await createTest({
          databaseId: currentDatabaseId,
          layer,
          formatName,
          input: {
            title: title.trim(),
            type,
            should_match: shouldMatch,
            description: description?.trim() || null
          }
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to create test";
        if (message2.includes("already exists")) return fail(400, { error: message2 });
        return fail(500, { error: message2 });
      }
      if (!result.success) return fail(500, { error: result.error || "Failed to create test" });
      throw redirect(303, `/custom-formats/${databaseId}/${id}/testing`);
    } };
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/new/_page.svelte.js
var page_svelte_exports21 = {};
__export(page_svelte_exports21, {
  default: () => _page21
});
function _page21($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    function handleCancel() {
      goto(`/custom-formats/${store_get($$store_subs ??= {}, "$page", page).params.databaseId}/${store_get($$store_subs ??= {}, "$page", page).params.id}/testing`);
    }
    PageMeta($$renderer2, { title: `${data.format.name} \xB7 Testing \xB7 New` });
    $$renderer2.push(`<!----> `);
    TestForm($$renderer2, {
      mode: "create",
      formatName: data.format.name,
      canWriteToBase: data.canWriteToBase,
      initialData: {
        title: "",
        type: "movie",
        shouldMatch: true,
        description: ""
      },
      onCancel: handleCancel
    });
    $$renderer2.push(`<!----> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte21 = __esm({
  "dist/build/server/entries/pages/custom-formats/_databaseId_/_id_/testing/new/_page.svelte.js"() {
    "use strict";
    init_server();
    init_client4();
    init_stores();
    init_navigation();
    init_DirtyModal();
    init_PageMeta();
    init_TestForm();
  }
});

// dist/build/server/nodes/29.js
var __exports30 = {};
__export(__exports30, {
  component: () => component28,
  fonts: () => fonts30,
  imports: () => imports30,
  index: () => index30,
  server: () => page_server_ts_exports22,
  server_id: () => server_id28,
  stylesheets: () => stylesheets30
});
var index30, component_cache28, component28, server_id28, imports30, stylesheets30, fonts30;
var init__30 = __esm({
  async "dist/build/server/nodes/29.js"() {
    "use strict";
    await init_page_server_ts22();
    index30 = 29;
    component28 = async () => component_cache28 ??= (await Promise.resolve().then(() => (init_page_svelte21(), page_svelte_exports21))).default;
    server_id28 = "src/routes/custom-formats/[databaseId]/[id]/testing/new/+page.server.ts";
    imports30 = ["_app/immutable/nodes/29.CRWeh6eI.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/BP5QNy2p2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/DGICnufN.js"];
    stylesheets30 = [];
    fonts30 = [];
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/new/_page.server.ts.js
var page_server_ts_exports23 = {};
__export(page_server_ts_exports23, {
  actions: () => actions17,
  load: () => load27
});
var load27, actions17;
var init_page_server_ts23 = __esm({
  async "dist/build/server/entries/pages/custom-formats/_databaseId_/new/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_create();
    await init_customFormats();
    init_exports();
    load27 = ({ params }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = pcdManager.getByIdPublic(currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      return {
        currentDatabase,
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions17 = { default: async ({ request, params }) => {
      const { databaseId } = params;
      if (!databaseId) return fail(400, { error: "Missing database ID" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const name = formData.get("name");
      const description = formData.get("description") || null;
      const tagsJson = formData.get("tags");
      const includeInRename = formData.get("includeInRename") === "true";
      const layer = formData.get("layer") || "user";
      if (!name?.trim()) return fail(400, { error: "Name is required" });
      let tags = [];
      try {
        tags = JSON.parse(tagsJson || "[]");
      } catch {
        return fail(400, { error: "Invalid tags format" });
      }
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      let result;
      try {
        result = await create({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          input: {
            name: name.trim(),
            description: description?.trim() || null,
            includeInRename,
            tags
          }
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to create custom format";
        if (message2.includes("already exists")) return fail(400, { error: message2 });
        return fail(500, { error: message2 });
      }
      if (!result.success) return fail(500, { error: result.error || "Failed to create custom format" });
      const freshCache = pcdManager.getCache(currentDatabaseId);
      if (!freshCache) throw redirect(303, `/custom-formats/${databaseId}`);
      const newFormat = (await list3(freshCache)).find((f2) => f2.name === name.trim());
      if (newFormat) throw redirect(303, `/custom-formats/${databaseId}/${newFormat.id}/conditions`);
      throw redirect(303, `/custom-formats/${databaseId}`);
    } };
  }
});

// dist/build/server/entries/pages/custom-formats/_databaseId_/new/_page.svelte.js
var page_svelte_exports22 = {};
__export(page_svelte_exports22, {
  default: () => _page22
});
function _page22($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    const initialData = {
      name: "",
      tags: [],
      description: "",
      includeInRename: false
    };
    function handleCancel() {
      goto(`/custom-formats/${data.currentDatabase.id}`);
    }
    PageMeta($$renderer2, { title: `${data.currentDatabase.name} \xB7 Custom Format \xB7 New` });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8">`);
    GeneralForm($$renderer2, {
      mode: "create",
      canWriteToBase: data.canWriteToBase,
      initialData,
      onCancel: handleCancel
    });
    $$renderer2.push(`<!----></div> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte22 = __esm({
  "dist/build/server/entries/pages/custom-formats/_databaseId_/new/_page.svelte.js"() {
    "use strict";
    init_server();
    init_client4();
    init_navigation();
    init_DirtyModal();
    init_PageMeta();
    init_GeneralForm();
  }
});

// dist/build/server/nodes/30.js
var __exports31 = {};
__export(__exports31, {
  component: () => component29,
  fonts: () => fonts31,
  imports: () => imports31,
  index: () => index31,
  server: () => page_server_ts_exports23,
  server_id: () => server_id29,
  stylesheets: () => stylesheets31
});
var index31, component_cache29, component29, server_id29, imports31, stylesheets31, fonts31;
var init__31 = __esm({
  async "dist/build/server/nodes/30.js"() {
    "use strict";
    await init_page_server_ts23();
    index31 = 30;
    component29 = async () => component_cache29 ??= (await Promise.resolve().then(() => (init_page_svelte22(), page_svelte_exports22))).default;
    server_id29 = "src/routes/custom-formats/[databaseId]/new/+page.server.ts";
    imports31 = ["_app/immutable/nodes/30.BGlED2xM.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D-q_ZSae2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/CK2yQf0C.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js"];
    stylesheets31 = [];
    fonts31 = [];
  }
});

// dist/build/server/entries/pages/databases/_page.server.ts.js
var page_server_ts_exports24 = {};
__export(page_server_ts_exports24, {
  actions: () => actions18,
  load: () => load28
});
var load28, actions18;
var init_page_server_ts24 = __esm({
  async "dist/build/server/entries/pages/databases/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_queueService();
    init_exports();
    load28 = () => {
      return { databases: pcdManager.getAllPublic().map((database) => {
        const cache3 = pcdManager.getCache(database.id);
        let qualityProfileCount = 0;
        let customFormatCount = 0;
        let delayProfileCount = 0;
        if (cache3) {
          qualityProfileCount = cache3.queryOne("SELECT COUNT(*) as count FROM quality_profiles")?.count ?? 0;
          customFormatCount = cache3.queryOne("SELECT COUNT(*) as count FROM custom_formats")?.count ?? 0;
          delayProfileCount = cache3.queryOne("SELECT COUNT(*) as count FROM delay_profiles")?.count ?? 0;
        }
        const linkedArrCount = db.queryFirst(`SELECT COUNT(DISTINCT instance_id) as count FROM (
				SELECT instance_id FROM arr_sync_quality_profiles WHERE database_id = ?
				UNION
				SELECT instance_id FROM arr_sync_delay_profiles_config WHERE database_id = ?
				UNION
				SELECT instance_id FROM arr_sync_media_management
					WHERE naming_database_id = ?
					OR quality_definitions_database_id = ?
					OR media_settings_database_id = ?
			)`, database.id, database.id, database.id, database.id, database.id)?.count ?? 0;
        return {
          ...database,
          qualityProfileCount,
          customFormatCount,
          delayProfileCount,
          linkedArrCount
        };
      }) };
    };
    actions18 = { delete: async ({ request }) => {
      const formData = await request.formData();
      const id = parseInt(formData.get("id")?.toString() || "0", 10);
      if (!id) {
        await logger.warn("Attempted to unlink database without ID", { source: "databases" });
        return fail(400, { error: "Database ID is required" });
      }
      try {
        await pcdManager.unlink(id);
        await logger.info(`Unlinked database: ${id}`, {
          source: "databases",
          meta: { id }
        });
        redirect(303, "/databases");
      } catch (error2) {
        if (error2 && typeof error2 === "object" && "status" in error2 && "location" in error2) throw error2;
        await logger.error("Failed to unlink database", {
          source: "databases",
          meta: { error: error2 instanceof Error ? error2.message : String(error2) }
        });
        return fail(500, { error: error2 instanceof Error ? error2.message : "Failed to unlink database" });
      }
    } };
  }
});

// dist/build/server/entries/pages/databases/_page.svelte.js
var page_svelte_exports23 = {};
__export(page_svelte_exports23, {
  default: () => _page23
});
function Git_pull_request($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "git-pull-request" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "18",
        "cy": "18",
        "r": "3"
      }],
      ["circle", {
        "cx": "6",
        "cy": "6",
        "r": "3"
      }],
      ["path", { "d": "M13 6h3a2 2 0 0 1 2 2v7" }],
      ["line", {
        "x1": "6",
        "x2": "6",
        "y1": "9",
        "y2": "21"
      }]
    ] }
  ]));
}
function Lock($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "lock" },
    props,
    { iconNode: [["rect", {
      "width": "18",
      "height": "11",
      "x": "3",
      "y": "11",
      "rx": "2",
      "ry": "2"
    }], ["path", { "d": "M7 11V7a5 5 0 0 1 10 0v4" }]] }
  ]));
}
function TableView3($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databases = $$props["databases"];
    createEventDispatcher();
    function formatSyncStrategy(minutes) {
      if (minutes === 0) return "Manual";
      if (minutes < 60) return `Every ${minutes} min`;
      if (minutes === 60) return "Hourly";
      if (minutes < 1440) return `Every ${minutes / 60}h`;
      return `Every ${minutes / 1440}d`;
    }
    function formatLastSynced(date) {
      if (!date) return "Never";
      return formatDateTime(date, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat), {
        month: "short",
        day: "numeric",
        hour: "numeric",
        minute: "2-digit"
      });
    }
    function getRowHref(database) {
      return `/databases/${database.id}`;
    }
    Table2($$renderer2, {
      columns: [
        {
          key: "name",
          header: "Name",
          align: "left"
        },
        {
          key: "repository_url",
          header: "Repository",
          align: "left"
        },
        {
          key: "content",
          header: "Content",
          align: "left"
        },
        {
          key: "sync_strategy",
          header: "Sync",
          align: "left",
          width: "w-32"
        },
        {
          key: "last_synced_at",
          header: "Last Synced",
          align: "left",
          width: "w-40"
        }
      ],
      data: databases,
      hoverable: true,
      rowHref: getRowHref,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "name") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex items-center gap-3">`);
            DatabaseAvatar($$renderer3, {
              name: row.name,
              repoUrl: row.repository_url,
              size: "sm"
            });
            $$renderer3.push(`<!----> <div class="flex items-center gap-2"><div class="font-medium text-neutral-900 dark:text-neutral-50">${escape_html(row.name)}</div> `);
            if (row.is_private) {
              $$renderer3.push("<!--[0-->");
              Label($$renderer3, {
                variant: "secondary",
                size: "sm",
                rounded: "md",
                mono: true,
                children: ($$renderer4) => {
                  Lock($$renderer4, { size: 12 });
                  $$renderer4.push(`<!----> Private`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--> `);
            if (row.hasPat) {
              $$renderer3.push("<!--[0-->");
              Label($$renderer3, {
                variant: "info",
                size: "sm",
                rounded: "md",
                mono: true,
                children: ($$renderer4) => {
                  Code($$renderer4, { size: 12 });
                  $$renderer4.push(`<!----> Dev`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div></div>`);
          } else if (column.key === "repository_url") {
            $$renderer3.push("<!--[1-->");
            Label($$renderer3, {
              variant: "secondary",
              size: "sm",
              rounded: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.repository_url.replace("https://github.com/", ""))}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "content") {
            $$renderer3.push("<!--[2-->");
            $$renderer3.push(`<div class="flex flex-wrap gap-1">`);
            Label($$renderer3, {
              variant: "secondary",
              size: "sm",
              rounded: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.qualityProfileCount)} Profiles`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            Label($$renderer3, {
              variant: "secondary",
              size: "sm",
              rounded: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.customFormatCount)} Formats`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            Label($$renderer3, {
              variant: "secondary",
              size: "sm",
              rounded: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.delayProfileCount)} Delay`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----></div>`);
          } else if (column.key === "sync_strategy") {
            $$renderer3.push("<!--[3-->");
            Label($$renderer3, {
              variant: "secondary",
              size: "sm",
              rounded: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatSyncStrategy(row.sync_strategy))}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "last_synced_at") {
            $$renderer3.push("<!--[4-->");
            Label($$renderer3, {
              variant: "secondary",
              size: "sm",
              rounded: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatLastSynced(row.last_synced_at))}`);
              },
              $$slots: { default: true }
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        actions: ($$renderer3, { row }) => {
          $$renderer3.push(`<div class="relative z-10 flex items-center justify-end gap-1">`);
          Button($$renderer3, {
            icon: External_link,
            size: "xs",
            variant: "secondary",
            title: "View on GitHub",
            ariaLabel: "View on GitHub",
            href: row.repository_url,
            target: "_blank",
            rel: "noopener noreferrer"
          });
          $$renderer3.push(`<!----> `);
          Button($$renderer3, {
            icon: Unlink,
            size: "xs",
            title: "Unlink database",
            variant: "secondary",
            iconColor: "text-red-600 dark:text-red-400"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { databases });
  });
}
function CardView3($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databases = $$props["databases"];
    createEventDispatcher();
    function formatSyncStrategy(minutes) {
      if (minutes === 0) return "Manual";
      if (minutes < 60) return `Every ${minutes} min`;
      if (minutes === 60) return "Hourly";
      if (minutes < 1440) return `Every ${minutes / 60}h`;
      return `Every ${minutes / 1440}d`;
    }
    function formatLastSynced(date) {
      if (!date) return "Never";
      return formatDateTime(date, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat), {
        month: "short",
        day: "numeric",
        hour: "numeric",
        minute: "2-digit"
      });
    }
    CardGrid($$renderer2, {
      columns: 1,
      className: "xl:grid-cols-2 2xl:grid-cols-3",
      flush: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(databases);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let database = each_array[$$index];
          Card($$renderer3, {
            href: `/databases/${stringify(database.id)}`,
            hoverable: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="flex flex-wrap gap-1">`);
              Label($$renderer4, {
                variant: "secondary",
                size: "sm",
                rounded: "md",
                mono: true,
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->${escape_html(database.repository_url.replace("https://github.com/", ""))}`);
                },
                $$slots: { default: true }
              });
              $$renderer4.push(`<!----> `);
              Label($$renderer4, {
                variant: "secondary",
                size: "sm",
                rounded: "md",
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->${escape_html(database.qualityProfileCount)} Quality Profiles`);
                },
                $$slots: { default: true }
              });
              $$renderer4.push(`<!----> `);
              Label($$renderer4, {
                variant: "secondary",
                size: "sm",
                rounded: "md",
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->${escape_html(database.customFormatCount)} Custom Formats`);
                },
                $$slots: { default: true }
              });
              $$renderer4.push(`<!----> `);
              Label($$renderer4, {
                variant: "secondary",
                size: "sm",
                rounded: "md",
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->${escape_html(database.delayProfileCount)} Delay Profiles`);
                },
                $$slots: { default: true }
              });
              $$renderer4.push(`<!----></div>`);
            },
            $$slots: {
              default: true,
              header: ($$renderer4) => {
                $$renderer4.push(`<div class="flex items-center justify-between gap-2"><div class="flex min-w-0 items-center gap-2">`);
                DatabaseAvatar($$renderer4, {
                  name: database.name,
                  repoUrl: database.repository_url,
                  size: "sm"
                });
                $$renderer4.push(`<!----> <h3 class="truncate text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(database.name)}</h3> `);
                if (database.is_private) {
                  $$renderer4.push("<!--[0-->");
                  Label($$renderer4, {
                    variant: "secondary",
                    size: "sm",
                    rounded: "md",
                    mono: true,
                    children: ($$renderer5) => {
                      Lock($$renderer5, { size: 12 });
                      $$renderer5.push(`<!----> Private`);
                    },
                    $$slots: { default: true }
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                if (database.hasPat) {
                  $$renderer4.push("<!--[0-->");
                  Label($$renderer4, {
                    variant: "info",
                    size: "sm",
                    rounded: "md",
                    mono: true,
                    children: ($$renderer5) => {
                      Code($$renderer5, { size: 12 });
                      $$renderer5.push(`<!----> Dev`);
                    },
                    $$slots: { default: true }
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--></div> <div class="flex shrink-0 items-center gap-0.5">`);
                Button($$renderer4, {
                  icon: External_link,
                  size: "xs",
                  variant: "ghost",
                  tooltip: "View on GitHub"
                });
                $$renderer4.push(`<!----> `);
                Button($$renderer4, {
                  icon: Unlink,
                  size: "xs",
                  variant: "ghost",
                  iconColor: "text-red-600 dark:text-red-400",
                  tooltip: "Unlink database"
                });
                $$renderer4.push(`<!----></div></div>`);
              },
              footer: ($$renderer4) => {
                $$renderer4.push(`<div class="flex flex-col items-start gap-1.5 text-xs text-neutral-600 sm:flex-row sm:items-center sm:gap-3 dark:text-neutral-400"><div class="flex items-center gap-1">`);
                Refresh_cw($$renderer4, {
                  size: 12,
                  class: "text-blue-500 dark:text-blue-400"
                });
                $$renderer4.push(`<!----> <span>Sync Strategy: ${escape_html(formatSyncStrategy(database.sync_strategy))}</span></div> <span class="hidden text-neutral-300 sm:inline dark:text-neutral-600">\xB7</span> <div class="flex items-center gap-1">`);
                Clock($$renderer4, {
                  size: 12,
                  class: "text-amber-500 dark:text-amber-400"
                });
                $$renderer4.push(`<!----> <span>Last Synced: ${escape_html(formatLastSynced(database.last_synced_at))}</span></div> <span class="hidden text-neutral-300 sm:inline dark:text-neutral-600">\xB7</span> <div class="flex items-center gap-1">`);
                Git_pull_request($$renderer4, {
                  size: 12,
                  class: "text-violet-500 dark:text-violet-400"
                });
                $$renderer4.push(`<!----> <span>Auto Pull: ${escape_html(database.auto_pull ? "On" : "Off")}</span></div></div>`);
              }
            }
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { databases });
  });
}
function _page23($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    const { search, view, filtered, setItems } = createDataPageStore(data.databases, {
      storageKey: "databasesView",
      searchKeys: ["name", "repository_url"]
    });
    let showUnlinkModal = false;
    let showInfoModal = false;
    let unlinkLoading = false;
    $: setItems(data.databases);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: "Databases" });
      $$renderer3.push(`<!----> `);
      if (data.databases.length === 0) {
        $$renderer3.push("<!--[0-->");
        EmptyState($$renderer3, {
          icon: Database2,
          title: "No Databases Linked",
          description: "Link a Profilarr Compliant Database to get started with profile management.",
          buttonText: "Link Database",
          buttonHref: "/databases/new",
          buttonIcon: Plus,
          onboarding: "db-add"
        });
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<div class="space-y-6 px-4 pt-4 pb-8 md:px-8">`);
        ActionsBar($$renderer3, {
          children: ($$renderer4) => {
            SearchAction($$renderer4, {
              searchStore: search,
              placeholder: "Search databases..."
            });
            $$renderer4.push(`<!----> `);
            ActionButton($$renderer4, {
              icon: Plus,
              title: "Link Database",
              onboarding: "db-add"
            });
            $$renderer4.push(`<!----> `);
            ActionButton($$renderer4, {
              icon: Info,
              title: "Info"
            });
            $$renderer4.push(`<!----> `);
            ViewToggle($$renderer4, {
              get value() {
                return store_get($$store_subs ??= {}, "$view", view);
              },
              set value($$value) {
                store_set(view, $$value);
                $$settled = false;
              }
            });
            $$renderer4.push(`<!---->`);
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----> <div class="mt-6">`);
        if (store_get($$store_subs ??= {}, "$filtered", filtered).length === 0) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No databases match your search</p></div>`);
        } else if (store_get($$store_subs ??= {}, "$view", view) === "table") {
          $$renderer3.push("<!--[1-->");
          TableView3($$renderer3, { databases: store_get($$store_subs ??= {}, "$filtered", filtered) });
        } else {
          $$renderer3.push("<!--[-1-->");
          CardView3($$renderer3, { databases: store_get($$store_subs ??= {}, "$filtered", filtered) });
        }
        $$renderer3.push(`<!--]--></div></div>`);
      }
      $$renderer3.push(`<!--]--> `);
      Modal($$renderer3, {
        open: showUnlinkModal,
        header: "Unlink Database",
        bodyMessage: `Are you sure you want to unlink "undefined"? This action cannot be undone and all local data will be permanently removed.`,
        confirmText: "Unlink",
        cancelText: "Cancel",
        confirmDanger: true,
        loading: unlinkLoading
      });
      $$renderer3.push(`<!----> <form method="POST" action="?/delete" class="hidden"><input type="hidden" name="id"${attr("value", "")}/></form> `);
      InfoModal($$renderer3, {
        header: "Databases",
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">What are Databases?</div> <div class="mt-1">Databases are Profilarr Compliant Database (PCD) repositories containing quality profiles,
				custom formats, and other configurations. Link a database to import and sync configurations
				to your Arr instances.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Private &amp; Dev Badges</div> <div class="mt-1"><strong>Private</strong> indicates the repository requires authentication. <strong>Dev</strong> means you have a personal access token configured, allowing you to push changes
				back to the repository.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Sync Strategy</div> <div class="mt-1">Controls how often Profilarr checks for updates from the remote repository. Set to "Manual"
				to only sync when you explicitly trigger it, or choose an interval for automatic updates.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Unlinking</div> <div class="mt-1">Unlinking a database removes all local data associated with it. Your Arr instances will keep
				any configurations that were already synced, but you won't be able to sync updates until you
				re-link the database.</div></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte23 = __esm({
  "dist/build/server/entries/pages/databases/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_dates();
    init_Icon();
    init_clock();
    init_code();
    init_database2();
    init_external_link();
    init_info();
    init_Button();
    init_plus();
    init_refresh_cw();
    init_search();
    init_ViewToggle();
    init_unlink();
    init_client4();
    init_store2();
    init_Label();
    init_Card();
    init_jobStatus();
    init_navigation();
    init_Modal();
    init_dateFormat();
    init_timezone();
    init_forms();
    init_DatabaseAvatar();
    init_ActionsBar();
    init_ActionButton();
    init_InfoModal();
    init_PageMeta();
    init_EmptyState();
    init_Table();
    init_CardGrid();
    init_dataPage();
  }
});

// dist/build/server/nodes/31.js
var __exports32 = {};
__export(__exports32, {
  component: () => component30,
  fonts: () => fonts32,
  imports: () => imports32,
  index: () => index32,
  server: () => page_server_ts_exports24,
  server_id: () => server_id30,
  stylesheets: () => stylesheets32
});
var index32, component_cache30, component30, server_id30, imports32, stylesheets32, fonts32;
var init__32 = __esm({
  async "dist/build/server/nodes/31.js"() {
    "use strict";
    await init_page_server_ts24();
    index32 = 31;
    component30 = async () => component_cache30 ??= (await Promise.resolve().then(() => (init_page_svelte23(), page_svelte_exports23))).default;
    server_id30 = "src/routes/databases/+page.server.ts";
    imports32 = ["_app/immutable/nodes/31.CvvCssq7.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BqRH1fsh2.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/VS2JNRG_.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/gs7jR9Ta.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D_awjkBZ.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js"];
    stylesheets32 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts32 = [];
  }
});

// dist/build/server/entries/pages/databases/_id_/_page.server.ts.js
var page_server_ts_exports25 = {};
__export(page_server_ts_exports25, {
  load: () => load29
});
var load29;
var init_page_server_ts25 = __esm({
  "dist/build/server/entries/pages/databases/_id_/_page.server.ts.js"() {
    "use strict";
    init_exports();
    load29 = async ({ params }) => {
      redirect(302, `/databases/${params.id}/changes`);
    };
  }
});

// dist/build/server/entries/pages/databases/_id_/_page.svelte.js
var page_svelte_exports24 = {};
__export(page_svelte_exports24, {
  default: () => _page24
});
function _page24($$renderer) {
  PageMeta($$renderer, { title: "Database" });
}
var init_page_svelte24 = __esm({
  "dist/build/server/entries/pages/databases/_id_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_PageMeta();
  }
});

// dist/build/server/nodes/32.js
var __exports33 = {};
__export(__exports33, {
  component: () => component31,
  fonts: () => fonts33,
  imports: () => imports33,
  index: () => index33,
  server: () => page_server_ts_exports25,
  server_id: () => server_id31,
  stylesheets: () => stylesheets33
});
var index33, component_cache31, component31, server_id31, imports33, stylesheets33, fonts33;
var init__33 = __esm({
  "dist/build/server/nodes/32.js"() {
    "use strict";
    init_page_server_ts25();
    index33 = 32;
    component31 = async () => component_cache31 ??= (await Promise.resolve().then(() => (init_page_svelte24(), page_svelte_exports24))).default;
    server_id31 = "src/routes/databases/[id]/+page.server.ts";
    imports33 = ["_app/immutable/nodes/32.CpwV2l0P.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets33 = [];
    fonts33 = [];
  }
});

// dist/build/server/entries/pages/databases/_id_/announcements/_page.server.ts.js
var page_server_ts_exports26 = {};
__export(page_server_ts_exports26, {
  load: () => load30
});
var load30;
var init_page_server_ts26 = __esm({
  async "dist/build/server/entries/pages/databases/_id_/announcements/_page.server.ts.js"() {
    "use strict";
    await init_database();
    await init_databaseInstances();
    init_operations2();
    init_exports();
    load30 = async ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (Number.isNaN(id)) error(400, "Invalid database ID");
      const database = databaseInstancesQueries.getById(id);
      if (!database) error(404, "Database not found");
      const result = await parseAnnouncementsDir(getPCDPath(database.uuid));
      return {
        databaseId: id,
        announcements: result.parsed.map((p2) => ({
          id: p2.id,
          title: p2.title,
          severity: p2.severity,
          publishedAt: p2.published_at,
          expiresAt: p2.expires_at,
          link: p2.link,
          body: p2.body
        })).sort((a2, b3) => a2.publishedAt < b3.publishedAt ? 1 : a2.publishedAt > b3.publishedAt ? -1 : 0),
        parseErrors: result.errors
      };
    };
  }
});

// dist/build/server/chunks/WithdrawAnnouncementModal.js
function WithdrawAnnouncementModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let open = fallback($$props["open"], false);
    let databaseId = $$props["databaseId"];
    let announcementId = $$props["announcementId"];
    let withdrawing = fallback($$props["withdrawing"], false);
    createEventDispatcher();
    if (open && announcementId) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<form method="POST"${attr("action", `/databases/${databaseId}/announcements/${announcementId}?/delete`)} class="hidden"></form>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    Modal($$renderer2, {
      open,
      header: "Withdraw announcement",
      bodyMessage: "Withdrawing deletes the announcement file from the working copy. Linked databases will mark this announcement as withdrawn on their next sync. This cannot be undone unless you re-create the file.",
      confirmText: "Withdraw",
      cancelText: "Cancel",
      confirmDanger: true,
      confirmDisabled: withdrawing,
      loading: withdrawing
    });
    $$renderer2.push(`<!---->`);
    bind_props($$props, {
      open,
      databaseId,
      announcementId,
      withdrawing
    });
  });
}
var init_WithdrawAnnouncementModal = __esm({
  "dist/build/server/chunks/WithdrawAnnouncementModal.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_store2();
    init_Modal();
    init_forms();
  }
});

// dist/build/server/entries/pages/databases/_id_/announcements/_page.svelte.js
var page_svelte_exports25 = {};
__export(page_svelte_exports25, {
  default: () => _page25
});
function Pen_line($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "pen-line" },
    props,
    { iconNode: [["path", { "d": "M13 21h8" }], ["path", { "d": "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" }]] }
  ]));
}
function _page25($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let databaseId;
    function renderMarkdown(text2) {
      return sanitizeHtml(g2.parse(text2));
    }
    let data = $$props["data"];
    const columns = [
      {
        key: "title",
        header: "Title"
      },
      {
        key: "severity",
        header: "Severity",
        width: "w-32"
      },
      {
        key: "publishedAt",
        header: "Published",
        width: "w-40"
      },
      {
        key: "expiresAt",
        header: "Expires",
        width: "w-40"
      }
    ];
    const severityVariant = {
      info: "info",
      warning: "warning",
      critical: "danger"
    };
    $: databaseId = data.databaseId;
    PageMeta($$renderer2, { title: `${data.database.name} \xB7 Announcements` });
    $$renderer2.push(`<!----> <div class="space-y-5">`);
    if (data.announcements.length > 0) {
      $$renderer2.push("<!--[0-->");
      StickyCard($$renderer2, {
        position: "top",
        $$slots: {
          left: ($$renderer3) => {
            $$renderer3.push(`<h1 class="text-neutral-900 dark:text-neutral-50">Announcements</h1> <p class="text-neutral-600 dark:text-neutral-400">Author messages that linked instances of this database will see in their inbox.</p>`);
          },
          right: ($$renderer3) => {
            Button($$renderer3, {
              text: "New announcement",
              icon: Plus,
              variant: "secondary",
              iconColor: "text-blue-600 dark:text-blue-400"
            });
          }
        }
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (data.parseErrors.length > 0) {
      $$renderer2.push("<!--[0-->");
      Card($$renderer2, {
        padding: "md",
        children: ($$renderer3) => {
          $$renderer3.push(`<div class="flex items-start gap-3">`);
          Triangle_alert($$renderer3, { class: "h-5 w-5 flex-shrink-0 text-yellow-600 dark:text-yellow-400" });
          $$renderer3.push(`<!----> <div class="space-y-2 text-sm"><div class="font-medium text-neutral-900 dark:text-neutral-100">${escape_html(data.parseErrors.length)} file(s) could not be parsed</div> <ul class="space-y-1 text-xs text-neutral-600 dark:text-neutral-400"><!--[-->`);
          const each_array = ensure_array_like(data.parseErrors);
          for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
            let err = each_array[$$index];
            $$renderer3.push(`<li><code class="font-mono">${escape_html(err.filename)}</code> <span class="ml-2">${escape_html(err.reason)}</span></li>`);
          }
          $$renderer3.push(`<!--]--></ul></div></div>`);
        },
        $$slots: { default: true }
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (data.announcements.length === 0) {
      $$renderer2.push("<!--[0-->");
      EmptyState($$renderer2, {
        icon: Pen_line,
        title: "No announcements yet",
        description: "When you publish an announcement here, it ships with the next push of this database.",
        buttonText: "New announcement",
        buttonHref: `/databases/${databaseId}/announcements/new`,
        buttonIcon: Plus
      });
    } else {
      $$renderer2.push("<!--[-1-->");
      ExpandableTable($$renderer2, {
        data: data.announcements,
        columns,
        getRowId: (row) => row.id,
        emptyMessage: "No announcements",
        responsive: true,
        flushExpanded: true,
        chevronPosition: "right",
        $$slots: {
          actions: ($$renderer3, { row }) => {
            $$renderer3.push(`<div class="flex items-center justify-end gap-2">`);
            Button($$renderer3, {
              icon: Pen_line,
              size: "xs",
              variant: "secondary",
              iconColor: "text-blue-600 dark:text-blue-400",
              ariaLabel: "Edit",
              tooltip: "Edit"
            });
            $$renderer3.push(`<!----> `);
            Button($$renderer3, {
              icon: Trash_2,
              size: "xs",
              variant: "secondary",
              iconColor: "text-red-600 dark:text-red-400",
              ariaLabel: "Withdraw",
              tooltip: "Withdraw"
            });
            $$renderer3.push(`<!----></div>`);
          },
          cell: ($$renderer3, { row, column }) => {
            if (column.key === "title") {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<span class="text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(row.title)}</span> `);
              if (row.link) {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<a${attr("href", row.link)} target="_blank" rel="noopener noreferrer" class="ml-2 inline-flex items-center text-accent-600 hover:underline dark:text-accent-400" aria-label="External link">`);
                External_link($$renderer3, { class: "h-3 w-3" });
                $$renderer3.push(`<!----></a>`);
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]-->`);
            } else if (column.key === "severity") {
              $$renderer3.push("<!--[1-->");
              Label($$renderer3, {
                variant: severityVariant[row.severity],
                size: "md",
                rounded: "md",
                mono: true,
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(row.severity.toUpperCase())}`);
                },
                $$slots: { default: true }
              });
            } else if (column.key === "publishedAt") {
              $$renderer3.push("<!--[2-->");
              $$renderer3.push(`<span class="text-xs text-neutral-500 dark:text-neutral-500">`);
              DateTime($$renderer3, {
                value: row.publishedAt,
                date: true
              });
              $$renderer3.push(`<!----></span>`);
            } else if (column.key === "expiresAt") {
              $$renderer3.push("<!--[3-->");
              if (row.expiresAt) {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<span class="text-xs text-neutral-500 dark:text-neutral-500">`);
                DateTime($$renderer3, {
                  value: row.expiresAt,
                  date: true
                });
                $$renderer3.push(`<!----></span>`);
              } else {
                $$renderer3.push("<!--[-1-->");
                $$renderer3.push(`<span class="text-xs text-neutral-400 dark:text-neutral-600">never</span>`);
              }
              $$renderer3.push(`<!--]-->`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]-->`);
          },
          expanded: ($$renderer3, { row }) => {
            $$renderer3.push(`<div class="space-y-3 p-4">`);
            if (row.body) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="prose prose-sm prose-neutral dark:prose-invert max-w-none text-sm">${html(renderMarkdown(row.body))}</div>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<p class="text-sm text-neutral-500 dark:text-neutral-500">This announcement has no body.</p>`);
            }
            $$renderer3.push(`<!--]--></div>`);
          }
        }
      });
    }
    $$renderer2.push(`<!--]--></div> `);
    WithdrawAnnouncementModal($$renderer2, {
      open: false,
      databaseId,
      announcementId: null
    });
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte25 = __esm({
  "dist/build/server/entries/pages/databases/_id_/announcements/_page.svelte.js"() {
    "use strict";
    init_server();
    init_sanitize();
    init_Icon();
    init_external_link();
    init_Button();
    init_plus();
    init_trash_2();
    init_triangle_alert();
    init_Label();
    init_Card();
    init_navigation();
    init_ExpandableTable();
    init_DateTime();
    init_PageMeta();
    init_EmptyState();
    init_StickyCard();
    init_WithdrawAnnouncementModal();
    init_marked_esm();
  }
});

// dist/build/server/nodes/33.js
var __exports34 = {};
__export(__exports34, {
  component: () => component32,
  fonts: () => fonts34,
  imports: () => imports34,
  index: () => index34,
  server: () => page_server_ts_exports26,
  server_id: () => server_id32,
  stylesheets: () => stylesheets34
});
var index34, component_cache32, component32, server_id32, imports34, stylesheets34, fonts34;
var init__34 = __esm({
  async "dist/build/server/nodes/33.js"() {
    "use strict";
    await init_page_server_ts26();
    index34 = 33;
    component32 = async () => component_cache32 ??= (await Promise.resolve().then(() => (init_page_svelte25(), page_svelte_exports25))).default;
    server_id32 = "src/routes/databases/[id]/announcements/+page.server.ts";
    imports34 = ["_app/immutable/nodes/33.bsMYeoYV.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/unOv5SWI.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D_awjkBZ.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/eMbPZvhV2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCkiND_92.js"];
    stylesheets34 = [];
    fonts34 = [];
  }
});

// dist/build/server/entries/pages/databases/_id_/announcements/_ulid_/_page.server.ts.js
var page_server_ts_exports27 = {};
__export(page_server_ts_exports27, {
  actions: () => actions19,
  load: () => load31
});
function parseInput(form) {
  const title = form.get("title");
  const severity = form.get("severity");
  const publishedAt = form.get("publishedAt");
  const expiresAtRaw = form.get("expiresAt");
  const linkRaw = form.get("link");
  const body = form.get("body");
  if (typeof title !== "string" || title.trim() === "") return { error: "Title is required" };
  if (severity !== "info" && severity !== "warning" && severity !== "critical") return { error: "Severity must be info, warning, or critical" };
  if (typeof publishedAt !== "string" || publishedAt === "") return { error: "Published timestamp is required" };
  if (Number.isNaN(Date.parse(publishedAt))) return { error: "Published timestamp is not a valid date" };
  let expiresAt = null;
  if (typeof expiresAtRaw === "string" && expiresAtRaw !== "") {
    if (Number.isNaN(Date.parse(expiresAtRaw))) return { error: "Expires timestamp is not a valid date" };
    expiresAt = expiresAtRaw;
  }
  const link = typeof linkRaw === "string" && linkRaw.trim() !== "" ? linkRaw.trim() : null;
  const bodyText = typeof body === "string" ? body : "";
  return {
    title: title.trim(),
    severity,
    publishedAt,
    expiresAt,
    link,
    body: bodyText
  };
}
var load31, actions19;
var init_page_server_ts27 = __esm({
  async "dist/build/server/entries/pages/databases/_id_/announcements/_ulid_/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_database();
    await init_databaseInstances();
    init_operations2();
    init_exports();
    load31 = async ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (Number.isNaN(id)) error(400, "Invalid database ID");
      const database = databaseInstancesQueries.getById(id);
      if (!database) error(404, "Database not found");
      const ulid = params.ulid;
      if (!ulid) error(400, "Missing announcement id");
      const result = await parseAnnouncementFile(getPCDPath(database.uuid), ulid);
      if (result === null) error(404, "Announcement not found");
      if ("reason" in result) return {
        parseError: result.reason,
        announcement: {
          id: ulid,
          title: "",
          severity: "info",
          publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
          expiresAt: null,
          link: "",
          body: ""
        }
      };
      return {
        parseError: null,
        announcement: {
          id: result.id,
          title: result.title,
          severity: result.severity,
          publishedAt: result.published_at,
          expiresAt: result.expires_at,
          link: result.link ?? "",
          body: result.body
        }
      };
    };
    actions19 = {
      save: async ({ request, params }) => {
        const id = parseInt(params.id || "", 10);
        if (Number.isNaN(id)) return {
          success: false,
          error: "Invalid database id"
        };
        const database = databaseInstancesQueries.getById(id);
        if (!database) return {
          success: false,
          error: "Database not found"
        };
        const ulid = params.ulid;
        if (!ulid) return {
          success: false,
          error: "Missing announcement id"
        };
        const input = parseInput(await request.formData());
        if ("error" in input) return {
          success: false,
          error: input.error
        };
        try {
          await writeAnnouncement(getPCDPath(database.uuid), ulid, input);
        } catch (err) {
          await logger.error("Failed to write announcement file", {
            source: "announcements.authoring",
            meta: {
              databaseId: id,
              announcementId: ulid,
              error: String(err)
            }
          });
          return {
            success: false,
            error: err instanceof Error ? err.message : "Failed to write file"
          };
        }
        await reconcileFromWorkingCopy(id, { isFirstSync: false });
        throw redirect(303, `/databases/${id}/announcements`);
      },
      delete: async ({ params }) => {
        const id = parseInt(params.id || "", 10);
        if (Number.isNaN(id)) return {
          success: false,
          error: "Invalid database id"
        };
        const database = databaseInstancesQueries.getById(id);
        if (!database) return {
          success: false,
          error: "Database not found"
        };
        const ulid = params.ulid;
        if (!ulid) return {
          success: false,
          error: "Missing announcement id"
        };
        try {
          if (!await deleteAnnouncement(getPCDPath(database.uuid), ulid)) return {
            success: false,
            error: "Announcement file no longer exists"
          };
        } catch (err) {
          await logger.error("Failed to delete announcement file", {
            source: "announcements.authoring",
            meta: {
              databaseId: id,
              announcementId: ulid,
              error: String(err)
            }
          });
          return {
            success: false,
            error: err instanceof Error ? err.message : "Failed to delete file"
          };
        }
        await reconcileFromWorkingCopy(id, { isFirstSync: false });
        throw redirect(303, `/databases/${id}/announcements`);
      }
    };
  }
});

// dist/build/server/chunks/AnnouncementForm.js
function AnnouncementForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let title, severity, publishedDate, publishedTime, expiresDate, expiresTime, link, body, publishedIso, expiresIso, canSubmit;
    let mode = $$props["mode"];
    let databaseId = fallback($$props["databaseId"], 0);
    let initial2 = $$props["initial"];
    let form = fallback($$props["form"], void 0);
    const severityOptions = [
      {
        value: "info",
        label: "Info"
      },
      {
        value: "warning",
        label: "Warning"
      },
      {
        value: "critical",
        label: "Critical"
      }
    ];
    function splitIso(iso) {
      if (!iso) return {
        date: "",
        time: ""
      };
      const d2 = new Date(iso);
      if (Number.isNaN(d2.getTime())) return {
        date: "",
        time: ""
      };
      const yyyy = d2.getUTCFullYear();
      const mm = String(d2.getUTCMonth() + 1).padStart(2, "0");
      const dd = String(d2.getUTCDate()).padStart(2, "0");
      const hh = String(d2.getUTCHours()).padStart(2, "0");
      const min = String(d2.getUTCMinutes()).padStart(2, "0");
      return {
        date: `${yyyy}-${mm}-${dd}`,
        time: `${hh}:${min}`
      };
    }
    function combineIso(date, time) {
      if (!date) return null;
      const d2 = /* @__PURE__ */ new Date(`${date}T${time || "00:00"}:00.000Z`);
      if (Number.isNaN(d2.getTime())) return null;
      return d2.toISOString();
    }
    function oneYearFromNowIso() {
      const d2 = /* @__PURE__ */ new Date();
      d2.setUTCFullYear(d2.getUTCFullYear() + 1);
      return d2.toISOString();
    }
    splitIso(initial2.publishedAt);
    splitIso(initial2.expiresAt ?? oneYearFromNowIso());
    let saving = false;
    let showDeleteModal = false;
    let withdrawing = false;
    $: title = store_get($$store_subs ??= {}, "$current", current2).title ?? "";
    $: severity = store_get($$store_subs ??= {}, "$current", current2).severity ?? "info";
    $: publishedDate = store_get($$store_subs ??= {}, "$current", current2).publishedDate ?? "";
    $: publishedTime = store_get($$store_subs ??= {}, "$current", current2).publishedTime ?? "";
    $: expiresDate = store_get($$store_subs ??= {}, "$current", current2).expiresDate ?? "";
    $: expiresTime = store_get($$store_subs ??= {}, "$current", current2).expiresTime ?? "";
    $: link = store_get($$store_subs ??= {}, "$current", current2).link ?? "";
    $: body = store_get($$store_subs ??= {}, "$current", current2).body ?? "";
    $: publishedIso = combineIso(publishedDate, publishedTime);
    $: expiresIso = combineIso(expiresDate, expiresTime);
    $: canSubmit = store_get($$store_subs ??= {}, "$isDirty", isDirty) && !!title.trim() && !!body.trim() && publishedIso !== null && expiresIso !== null;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      DirtyModal($$renderer3, {});
      $$renderer3.push(`<!----> <div class="space-y-5">`);
      StickyCard($$renderer3, {
        position: "top",
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<h1 class="text-neutral-900 dark:text-neutral-50">${escape_html(mode === "create" ? "New announcement" : "Edit announcement")}</h1> <p class="text-neutral-600 dark:text-neutral-400">${escape_html(mode === "create" ? "Publish a message that linked instances of this database will see in their inbox." : "Edit, save, or withdraw this announcement.")}</p>`);
          },
          right: ($$renderer4) => {
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                text: "Withdraw",
                icon: Trash_2,
                variant: "secondary",
                iconColor: "text-red-600 dark:text-red-400",
                loading: withdrawing,
                disabled: withdrawing || saving
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            Button($$renderer4, {
              text: "Save",
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              disabled: !canSubmit || withdrawing
            });
            $$renderer4.push(`<!---->`);
          }
        }
      });
      $$renderer3.push(`<!----> <form id="announcement-save-form" method="POST" action="?/save"><input type="hidden" name="title"${attr("value", title)}/> <input type="hidden" name="severity"${attr("value", severity)}/> <input type="hidden" name="publishedAt"${attr("value", publishedIso ?? "")}/> <input type="hidden" name="expiresAt"${attr("value", expiresIso ?? "")}/> <input type="hidden" name="link"${attr("value", link)}/> <input type="hidden" name="body"${attr("value", body)}/> <div class="space-y-5 rounded-lg border border-neutral-200 bg-white p-4 dark:border-neutral-800 dark:bg-neutral-900"><div class="grid gap-4 md:grid-cols-10"><div class="md:col-span-9">`);
      FormInput($$renderer3, {
        label: "Title",
        required: true,
        value: title,
        placeholder: "Migration to v2"
      });
      $$renderer3.push(`<!----></div> <div class="space-y-2 md:col-span-1"><span class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Severity<span class="text-red-500">*</span></span> `);
      DropdownSelect($$renderer3, {
        value: severity,
        options: severityOptions,
        fullWidth: true
      });
      $$renderer3.push(`<!----></div></div> <div class="grid gap-4 md:flex md:items-start"><div class="min-w-0 space-y-2"><span class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Published<span class="text-red-500">*</span></span> `);
      DateInput($$renderer3, {
        label: "Published date",
        hideLabel: true,
        value: publishedDate
      });
      $$renderer3.push(`<!----></div> <div class="min-w-0 space-y-2"><span class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Expires<span class="text-red-500">*</span></span> `);
      DateInput($$renderer3, {
        label: "Expires date",
        hideLabel: true,
        value: expiresDate
      });
      $$renderer3.push(`<!----></div></div> `);
      FormInput($$renderer3, {
        label: "Link",
        value: link,
        type: "url",
        description: "Optional external URL surfaced as 'Read more' on the announcements page."
      });
      $$renderer3.push(`<!----> `);
      MarkdownInput($$renderer3, {
        label: "Body",
        required: true,
        value: body,
        description: "Markdown supported.",
        onchange: (next2) => update3("body", next2)
      });
      $$renderer3.push(`<!----></div></form></div> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        WithdrawAnnouncementModal($$renderer3, {
          open: showDeleteModal,
          databaseId,
          announcementId: initial2.id ?? null,
          get withdrawing() {
            return withdrawing;
          },
          set withdrawing($$value) {
            withdrawing = $$value;
            $$settled = false;
          }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]-->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      databaseId,
      initial: initial2,
      form
    });
  });
}
var init_AnnouncementForm = __esm({
  "dist/build/server/chunks/AnnouncementForm.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_MarkdownInput();
    init_Button();
    init_save();
    init_trash_2();
    init_store2();
    init_forms();
    init_dirty();
    init_DirtyModal();
    init_StickyCard();
    init_DropdownSelect();
    init_FormInput();
    init_DateInput();
    init_WithdrawAnnouncementModal();
  }
});

// dist/build/server/entries/pages/databases/_id_/announcements/_ulid_/_page.svelte.js
var page_svelte_exports26 = {};
__export(page_svelte_exports26, {
  default: () => _page26
});
function _page26($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, pageTitle;
    let data = $$props["data"];
    let form = $$props["form"];
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.id ?? "0", 10);
    $: pageTitle = data.announcement.title ? `${data.announcement.title} \xB7 Edit` : `${data.database.name} \xB7 Announcement \xB7 Edit`;
    PageMeta($$renderer2, { title: pageTitle });
    $$renderer2.push(`<!----> <div class="space-y-4">`);
    if (data.parseError) {
      $$renderer2.push("<!--[0-->");
      Card($$renderer2, {
        padding: "md",
        children: ($$renderer3) => {
          $$renderer3.push(`<div class="flex items-start gap-3">`);
          Triangle_alert($$renderer3, { class: "h-5 w-5 flex-shrink-0 text-yellow-600 dark:text-yellow-400" });
          $$renderer3.push(`<!----> <div class="text-sm"><div class="font-medium text-neutral-900 dark:text-neutral-100">The announcement file is malformed</div> <p class="mt-1 text-xs text-neutral-600 dark:text-neutral-400">${escape_html(data.parseError)}</p> <p class="mt-2 text-xs text-neutral-500 dark:text-neutral-500">Saving here will overwrite the broken file with the values below.</p></div></div>`);
        },
        $$slots: { default: true }
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    AnnouncementForm($$renderer2, {
      mode: "edit",
      databaseId,
      initial: data.announcement,
      form
    });
    $$renderer2.push(`<!----></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      data,
      form
    });
  });
}
var init_page_svelte26 = __esm({
  "dist/build/server/entries/pages/databases/_id_/announcements/_ulid_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_triangle_alert();
    init_stores();
    init_Card();
    init_PageMeta();
    init_AnnouncementForm();
  }
});

// dist/build/server/nodes/34.js
var __exports35 = {};
__export(__exports35, {
  component: () => component33,
  fonts: () => fonts35,
  imports: () => imports35,
  index: () => index35,
  server: () => page_server_ts_exports27,
  server_id: () => server_id33,
  stylesheets: () => stylesheets35
});
var index35, component_cache33, component33, server_id33, imports35, stylesheets35, fonts35;
var init__35 = __esm({
  async "dist/build/server/nodes/34.js"() {
    "use strict";
    await init_page_server_ts27();
    index35 = 34;
    component33 = async () => component_cache33 ??= (await Promise.resolve().then(() => (init_page_svelte26(), page_svelte_exports26))).default;
    server_id33 = "src/routes/databases/[id]/announcements/[ulid]/+page.server.ts";
    imports35 = ["_app/immutable/nodes/34.l5_kYop_.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D8GKXqGk2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/CLCnMz_w.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/eMbPZvhV2.js"];
    stylesheets35 = [];
    fonts35 = [];
  }
});

// dist/build/server/entries/pages/databases/_id_/announcements/new/_page.server.ts.js
var page_server_ts_exports28 = {};
__export(page_server_ts_exports28, {
  actions: () => actions20,
  load: () => load32
});
function parseInput2(form) {
  const title = form.get("title");
  const severity = form.get("severity");
  const publishedAt = form.get("publishedAt");
  const expiresAtRaw = form.get("expiresAt");
  const linkRaw = form.get("link");
  const body = form.get("body");
  if (typeof title !== "string" || title.trim() === "") return { error: "Title is required" };
  if (severity !== "info" && severity !== "warning" && severity !== "critical") return { error: "Severity must be info, warning, or critical" };
  if (typeof publishedAt !== "string" || publishedAt === "") return { error: "Published timestamp is required" };
  if (Number.isNaN(Date.parse(publishedAt))) return { error: "Published timestamp is not a valid date" };
  let expiresAt = null;
  if (typeof expiresAtRaw === "string" && expiresAtRaw !== "") {
    if (Number.isNaN(Date.parse(expiresAtRaw))) return { error: "Expires timestamp is not a valid date" };
    expiresAt = expiresAtRaw;
  }
  const link = typeof linkRaw === "string" && linkRaw.trim() !== "" ? linkRaw.trim() : null;
  const bodyText = typeof body === "string" ? body : "";
  return {
    title: title.trim(),
    severity,
    publishedAt,
    expiresAt,
    link,
    body: bodyText
  };
}
var load32, actions20;
var init_page_server_ts28 = __esm({
  async "dist/build/server/entries/pages/databases/_id_/announcements/new/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_database();
    await init_databaseInstances();
    init_operations2();
    init_exports();
    load32 = async ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (Number.isNaN(id)) error(400, "Invalid database ID");
      if (!databaseInstancesQueries.getById(id)) error(404, "Database not found");
      return {};
    };
    actions20 = { save: async ({ request, params }) => {
      const id = parseInt(params.id || "", 10);
      if (Number.isNaN(id)) return {
        success: false,
        error: "Invalid database id"
      };
      const database = databaseInstancesQueries.getById(id);
      if (!database) return {
        success: false,
        error: "Database not found"
      };
      const input = parseInput2(await request.formData());
      if ("error" in input) return {
        success: false,
        error: input.error
      };
      const announcementId = generateAnnouncementId();
      try {
        await writeAnnouncement(getPCDPath(database.uuid), announcementId, input);
      } catch (err) {
        await logger.error("Failed to write announcement file", {
          source: "announcements.authoring",
          meta: {
            databaseId: id,
            announcementId,
            error: String(err)
          }
        });
        return {
          success: false,
          error: err instanceof Error ? err.message : "Failed to write file"
        };
      }
      await reconcileFromWorkingCopy(id, { isFirstSync: false });
      throw redirect(303, `/databases/${id}/announcements`);
    } };
  }
});

// dist/build/server/entries/pages/databases/_id_/announcements/new/_page.svelte.js
var page_svelte_exports27 = {};
__export(page_svelte_exports27, {
  default: () => _page27
});
function _page27($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId;
    let data = $$props["data"];
    let form = $$props["form"];
    const initial2 = {
      title: "",
      severity: "info",
      publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
      expiresAt: null,
      link: "",
      body: ""
    };
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.id ?? "0", 10);
    PageMeta($$renderer2, { title: `${data.database.name} \xB7 Announcement \xB7 New` });
    $$renderer2.push(`<!----> `);
    AnnouncementForm($$renderer2, {
      mode: "create",
      databaseId,
      initial: initial2,
      form
    });
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      data,
      form
    });
  });
}
var init_page_svelte27 = __esm({
  "dist/build/server/entries/pages/databases/_id_/announcements/new/_page.svelte.js"() {
    "use strict";
    init_server();
    init_stores();
    init_PageMeta();
    init_AnnouncementForm();
  }
});

// dist/build/server/nodes/35.js
var __exports36 = {};
__export(__exports36, {
  component: () => component34,
  fonts: () => fonts36,
  imports: () => imports36,
  index: () => index36,
  server: () => page_server_ts_exports28,
  server_id: () => server_id34,
  stylesheets: () => stylesheets36
});
var index36, component_cache34, component34, server_id34, imports36, stylesheets36, fonts36;
var init__36 = __esm({
  async "dist/build/server/nodes/35.js"() {
    "use strict";
    await init_page_server_ts28();
    index36 = 35;
    component34 = async () => component_cache34 ??= (await Promise.resolve().then(() => (init_page_svelte27(), page_svelte_exports27))).default;
    server_id34 = "src/routes/databases/[id]/announcements/new/+page.server.ts";
    imports36 = ["_app/immutable/nodes/35.DAh0ykVj.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D8GKXqGk2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/CLCnMz_w.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/eMbPZvhV2.js"];
    stylesheets36 = [];
    fonts36 = [];
  }
});

// dist/build/server/chunks/draftChanges.js
function parseJson3(value2) {
  if (!value2) return null;
  try {
    return JSON.parse(value2);
  } catch {
    return null;
  }
}
function humanizeKey(value2) {
  return value2.replace(/[_-]+/g, " ").trim().replace(/\b\w/g, (char) => char.toUpperCase());
}
function formatFieldLabel(field) {
  return FIELD_LABELS[field] ?? humanizeKey(field);
}
function buildSummary(operation, fields) {
  if (operation === "create") return "Created";
  if (operation === "delete") return "Deleted";
  if (fields.length === 0) return "Updated";
  if (fields.length === 1) return `Updated ${formatFieldLabel(fields[0])}`;
  if (fields.length === 2) return `Updated ${formatFieldLabel(fields[0])} + ${formatFieldLabel(fields[1])}`;
  return `Updated ${fields.length} fields`;
}
function ensureField(map2, field) {
  const existing = map2.get(field);
  if (existing) return existing;
  const created = {
    field,
    label: formatFieldLabel(field)
  };
  map2.set(field, created);
  return created;
}
function mergeValues(target, value2) {
  if (target.field === "tags" && Array.isArray(value2)) {
    target.add = Array.from(new Set(value2.map((tag2) => String(tag2))));
    return;
  }
  if (value2 && typeof value2 === "object" && !Array.isArray(value2)) {
    const record = value2;
    if ("from" in record || "to" in record) {
      if (target.before === void 0 && record.from !== void 0) target.before = record.from;
      if (record.to !== void 0) target.after = record.to;
      return;
    }
    if ("add" in record || "remove" in record) {
      const addValues = Array.isArray(record.add) ? record.add : record.add ? [record.add] : [];
      const removeValues = Array.isArray(record.remove) ? record.remove : record.remove ? [record.remove] : [];
      target.add = Array.from(/* @__PURE__ */ new Set([...target.add ?? [], ...addValues]));
      target.remove = Array.from(/* @__PURE__ */ new Set([...target.remove ?? [], ...removeValues]));
      return;
    }
  }
  target.after = value2;
  if (target.before === void 0) target.before = void 0;
}
function mergeCustomFormatScores(target, value2) {
  if (!Array.isArray(value2)) return;
  const map2 = /* @__PURE__ */ new Map();
  if (Array.isArray(target.items)) for (const item of target.items) map2.set(`${item.custom_format_name}::${item.arr_type}`, { ...item });
  for (const entry of value2) {
    if (!entry || typeof entry !== "object") continue;
    const record = entry;
    if (!record.custom_format_name || !record.arr_type) continue;
    const key2 = `${record.custom_format_name}::${record.arr_type}`;
    const current3 = map2.get(key2);
    const next2 = {
      custom_format_name: record.custom_format_name,
      arr_type: record.arr_type,
      before: record.from ?? current3?.before ?? null,
      after: record.to ?? current3?.after ?? null
    };
    map2.set(key2, next2);
  }
  target.items = Array.from(map2.values());
}
function mergeOrderedItems(target, value2) {
  if (Array.isArray(value2)) {
    target.afterItems = value2;
    return;
  }
  if (value2 && typeof value2 === "object" && !Array.isArray(value2)) {
    const record = value2;
    if (Array.isArray(record.from)) target.beforeItems = record.from;
    if (Array.isArray(record.to)) target.afterItems = record.to;
  }
}
function isTestPayload(desiredState) {
  return "test_title" in desiredState || "test_type" in desiredState || "test_should_match" in desiredState || "test_description" in desiredState;
}
function extractChangeValue(value2, mode) {
  if (value2 && typeof value2 === "object" && !Array.isArray(value2)) {
    const record = value2;
    if ("from" in record || "to" in record) return {
      before: record.from,
      after: record.to
    };
  }
  if (value2 === void 0) return {};
  if (mode === "removed") return { before: value2 };
  return { after: value2 };
}
function mergeTests(target, value2) {
  const rowsMap = new Map((target.tests ?? []).map((row) => [row.name, row]));
  const mode = value2.deleted ? "removed" : Object.values(value2).some((entry) => entry && typeof entry === "object" && !Array.isArray(entry) && ("from" in entry || "to" in entry)) ? "updated" : "added";
  const titleValue = "title" in value2 ? value2.title : value2.test_title;
  const typeValue = "type" in value2 ? value2.type : value2.test_type;
  const matchValue = "should_match" in value2 ? value2.should_match : value2.test_should_match;
  const descriptionValue = "description" in value2 ? value2.description : value2.test_description;
  const titleChange = extractChangeValue(titleValue, mode);
  const typeChange = extractChangeValue(typeValue, mode);
  const matchChange = extractChangeValue(matchValue, mode);
  const descriptionChange = extractChangeValue(descriptionValue, mode);
  const before = {};
  const after = {};
  if (titleChange.before !== void 0) before.title = titleChange.before;
  if (titleChange.after !== void 0) after.title = titleChange.after;
  if (typeChange.before !== void 0) before.type = typeChange.before;
  if (typeChange.after !== void 0) after.type = typeChange.after;
  if (matchChange.before !== void 0) before.shouldMatch = matchChange.before;
  if (matchChange.after !== void 0) after.shouldMatch = matchChange.after;
  if (descriptionChange.before !== void 0) before.description = descriptionChange.before;
  if (descriptionChange.after !== void 0) after.description = descriptionChange.after;
  const name = String(titleChange.after ?? titleChange.before ?? "Test");
  rowsMap.set(name, {
    name,
    change: mode,
    before: Object.keys(before).length > 0 ? before : void 0,
    after: Object.keys(after).length > 0 ? after : void 0
  });
  target.tests = Array.from(rowsMap.values());
}
function extractConditionSnapshot(value2) {
  if (!value2 || typeof value2 !== "object") return void 0;
  const record = value2;
  const base2 = record.base ?? {};
  return {
    type: base2.type,
    arrType: base2.arrType,
    negate: base2.negate,
    required: base2.required,
    values: record.values ?? null
  };
}
function mergeConditions(target, value2) {
  if (!value2 || typeof value2 !== "object") return;
  const record = value2;
  const rowsMap = new Map((target.conditions ?? []).map((row) => [row.name, row]));
  const added = Array.isArray(record.added) ? record.added : [];
  for (const entry of added) {
    if (!entry) continue;
    if (typeof entry === "string") {
      rowsMap.set(entry, {
        name: entry,
        change: "added"
      });
      continue;
    }
    const snapshot = extractConditionSnapshot(entry);
    const name = entry.name;
    if (!name) continue;
    rowsMap.set(name, {
      name,
      change: "added",
      after: snapshot
    });
  }
  const removed = Array.isArray(record.removed) ? record.removed : [];
  for (const entry of removed) {
    if (!entry) continue;
    if (typeof entry === "string") {
      rowsMap.set(entry, {
        name: entry,
        change: "removed"
      });
      continue;
    }
    const snapshot = extractConditionSnapshot(entry);
    const name = entry.name;
    if (!name) continue;
    rowsMap.set(name, {
      name,
      change: "removed",
      before: snapshot
    });
  }
  const updated3 = Array.isArray(record.updated) ? record.updated : [];
  for (const entry of updated3) {
    if (!entry || typeof entry !== "object") continue;
    const name = entry.name;
    if (!name) continue;
    const existing = rowsMap.get(name);
    if (existing && (existing.change === "added" || existing.change === "removed")) continue;
    const base2 = entry.base;
    const values = entry.values;
    const before = {
      type: base2?.from?.type,
      arrType: base2?.from?.arrType,
      negate: base2?.from?.negate,
      required: base2?.from?.required,
      values: values?.from ?? null
    };
    const after = {
      type: base2?.to?.type,
      arrType: base2?.to?.arrType,
      negate: base2?.to?.negate,
      required: base2?.to?.required,
      values: values?.to ?? null
    };
    rowsMap.set(name, {
      name,
      change: "updated",
      before,
      after
    });
  }
  target.conditions = Array.from(rowsMap.values());
}
function buildSections(entity, aggregates) {
  if (aggregates.size === 0) return [];
  if (entity === "quality_profile") {
    const generalFields = [
      "name",
      "description",
      "tags",
      "language"
    ];
    const scoringFields = [
      "minimum_custom_format_score",
      "upgrade_until_score",
      "upgrade_score_increment",
      "custom_format_scores"
    ];
    const qualitiesFields = ["ordered_items"];
    const sections = [];
    const buildSectionRows = (fields) => {
      const rows = [];
      for (const field of fields) {
        const aggregate = aggregates.get(field);
        if (!aggregate) continue;
        if (field === "custom_format_scores") {
          rows.push({
            kind: "custom_format_scores",
            field,
            label: aggregate.label,
            rows: aggregate.items ?? []
          });
          continue;
        }
        if (field === "ordered_items") {
          rows.push({
            kind: "ordered_items",
            field,
            label: aggregate.label,
            beforeItems: aggregate.beforeItems ?? [],
            afterItems: aggregate.afterItems ?? []
          });
          continue;
        }
        rows.push({
          kind: "field",
          field,
          label: aggregate.label,
          before: aggregate.before,
          after: aggregate.after,
          add: aggregate.add,
          remove: aggregate.remove
        });
      }
      return rows;
    };
    const generalRows = buildSectionRows(generalFields);
    if (generalRows.length > 0) sections.push({
      id: "general",
      title: "General",
      rows: generalRows
    });
    const scoringRows = buildSectionRows(scoringFields);
    if (scoringRows.length > 0) sections.push({
      id: "scoring",
      title: "Scoring",
      rows: scoringRows
    });
    const qualitiesRows = buildSectionRows(qualitiesFields);
    if (qualitiesRows.length > 0) sections.push({
      id: "qualities",
      title: "Qualities",
      rows: qualitiesRows
    });
    return sections;
  }
  if (entity === "custom_format") {
    const generalFields = [
      "name",
      "description",
      "include_in_rename",
      "tags"
    ];
    const sections = [];
    const buildSectionRows = (fields) => {
      const rows = [];
      for (const field of fields) {
        const aggregate = aggregates.get(field);
        if (!aggregate) continue;
        rows.push({
          kind: "field",
          field,
          label: aggregate.label,
          before: aggregate.before,
          after: aggregate.after,
          add: aggregate.add,
          remove: aggregate.remove
        });
      }
      return rows;
    };
    const generalRows = buildSectionRows(generalFields);
    if (generalRows.length > 0) sections.push({
      id: "general",
      title: "General",
      rows: generalRows
    });
    const conditionsAggregate = aggregates.get("conditions");
    if (conditionsAggregate?.conditions && conditionsAggregate.conditions.length > 0) sections.push({
      id: "conditions",
      title: "Conditions",
      rows: [{
        kind: "conditions",
        field: "conditions",
        label: "Conditions",
        rows: conditionsAggregate.conditions
      }]
    });
    const testsAggregate = aggregates.get("tests");
    if (testsAggregate?.tests && testsAggregate.tests.length > 0) sections.push({
      id: "tests",
      title: "Tests",
      rows: [{
        kind: "tests",
        field: "tests",
        label: "Tests",
        rows: testsAggregate.tests
      }]
    });
    return sections;
  }
  if (entity === "regular_expression") {
    const sections = [];
    const generalFields = [
      "name",
      "pattern",
      "description",
      "regex101_id",
      "tags"
    ];
    const generalRows = [];
    for (const field of generalFields) {
      const aggregate = aggregates.get(field);
      if (!aggregate) continue;
      generalRows.push({
        kind: "field",
        field,
        label: aggregate.label,
        before: aggregate.before,
        after: aggregate.after,
        add: aggregate.add,
        remove: aggregate.remove
      });
    }
    if (generalRows.length > 0) sections.push({
      id: "general",
      title: "General",
      rows: generalRows
    });
    return sections;
  }
  if (entity === "radarr_quality_definitions" || entity === "sonarr_quality_definitions") {
    const sections = [];
    const generalFields = ["name"];
    const generalRows = [];
    for (const field of generalFields) {
      const aggregate = aggregates.get(field);
      if (!aggregate) continue;
      generalRows.push({
        kind: "field",
        field,
        label: aggregate.label,
        before: aggregate.before,
        after: aggregate.after,
        add: aggregate.add,
        remove: aggregate.remove
      });
    }
    if (generalRows.length > 0) sections.push({
      id: "general",
      title: "General",
      rows: generalRows
    });
    const entriesAggregate = aggregates.get("entries");
    if (entriesAggregate) sections.push({
      id: "entries",
      title: "Entries",
      rows: [{
        kind: "quality_definition_entries",
        field: "entries",
        label: entriesAggregate.label,
        beforeEntries: entriesAggregate.before,
        afterEntries: entriesAggregate.after
      }]
    });
    return sections;
  }
  const fallbackRows = [];
  for (const aggregate of aggregates.values()) fallbackRows.push({
    kind: "field",
    field: aggregate.field,
    label: aggregate.label,
    before: aggregate.before,
    after: aggregate.after,
    add: aggregate.add,
    remove: aggregate.remove
  });
  return [{
    id: "changes",
    title: "Changes",
    rows: fallbackRows
  }];
}
function listDraftEntityChanges(databaseId) {
  const parsedOps = pcdOpsQueries.listByDatabaseAndOrigin(databaseId, "base", { states: ["draft"] }).map((op) => ({
    op,
    metadata: parseJson3(op.metadata)
  }));
  const originalName = /* @__PURE__ */ new Map();
  for (const { metadata } of parsedOps) {
    if (!metadata?.name || !metadata?.entity || !metadata.previousName) continue;
    const key2 = (n) => `${metadata.entity}:${n}`;
    const origin = originalName.get(key2(metadata.previousName)) ?? metadata.previousName;
    originalName.set(key2(metadata.name), origin);
    originalName.set(key2(metadata.previousName), origin);
  }
  const resolveAlias = (entity, value2) => {
    return originalName.get(`${entity}:${value2}`) ?? value2;
  };
  const scopedGroupKey = (baseKey, groupId) => {
    return groupId ? `${baseKey}::${groupId}` : baseKey;
  };
  const groups = /* @__PURE__ */ new Map();
  const aggregates = /* @__PURE__ */ new Map();
  const entityCreates = /* @__PURE__ */ new Map();
  const entityDeletes = /* @__PURE__ */ new Map();
  const dependencies = /* @__PURE__ */ new Map();
  for (const { op, metadata } of parsedOps) {
    if (!metadata?.entity || !metadata?.name || !metadata.operation) continue;
    const desiredState = parseJson3(op.desired_state);
    const stableKey = metadata.stable_key?.value ?? metadata.name;
    const groupKey = scopedGroupKey(`${metadata.entity}:${resolveAlias(metadata.entity, stableKey)}`, metadata.group_id);
    if (metadata.depends_on && metadata.depends_on.length > 0) {
      const depSet = dependencies.get(groupKey) ?? /* @__PURE__ */ new Set();
      for (const dependency of metadata.depends_on) {
        const depEntity = dependency.entity ?? (dependency.key ? ENTITY_BY_STABLE_KEY[dependency.key] : void 0);
        const depValue = dependency.value;
        if (!depEntity || !depValue) continue;
        const depBaseKey = `${depEntity}:${resolveAlias(depEntity, depValue)}`;
        const depKeys = metadata.group_id ? [scopedGroupKey(depBaseKey, metadata.group_id), depBaseKey] : [depBaseKey];
        for (const depKey of depKeys) {
          if (depKey === groupKey) continue;
          depSet.add(depKey);
        }
      }
      if (depSet.size > 0) dependencies.set(groupKey, depSet);
    }
    const hasNameField = desiredState && Object.prototype.hasOwnProperty.call(desiredState, "name");
    if (metadata.operation === "create" && hasNameField) entityCreates.set(groupKey, true);
    if (metadata.operation === "delete" && hasNameField && desiredState?.deleted === true) entityDeletes.set(groupKey, true);
    const existing = groups.get(groupKey);
    const updatedAt = op.updated_at ?? op.created_at;
    const opDetails = {
      id: op.id,
      operation: metadata.operation,
      title: metadata.title ?? `${humanizeKey(metadata.operation)} ${metadata.entity}`,
      summary: metadata.summary ?? void 0,
      createdAt: op.created_at,
      sequence: op.sequence,
      groupId: metadata.group_id,
      generated: metadata.generated === true
    };
    if (!existing) groups.set(groupKey, {
      key: groupKey,
      entity: metadata.entity,
      name: metadata.name,
      operation: metadata.operation,
      summary: "",
      changedFields: [],
      updatedAt,
      ops: [opDetails],
      sections: []
    });
    else {
      existing.ops.push(opDetails);
      existing.updatedAt = existing.updatedAt > updatedAt ? existing.updatedAt : updatedAt;
      existing.name = metadata.name;
    }
    if (desiredState) {
      let fieldMap = aggregates.get(groupKey);
      if (!fieldMap) {
        fieldMap = /* @__PURE__ */ new Map();
        aggregates.set(groupKey, fieldMap);
      }
      if (isTestPayload(desiredState)) {
        mergeTests(ensureField(fieldMap, "tests"), desiredState);
        continue;
      }
      for (const [field, value2] of Object.entries(desiredState)) {
        const aggregate = ensureField(fieldMap, field);
        if (field === "conditions") {
          mergeConditions(aggregate, value2);
          continue;
        }
        if (field === "custom_format_scores") {
          mergeCustomFormatScores(aggregate, value2);
          continue;
        }
        if (field === "ordered_items") {
          mergeOrderedItems(aggregate, value2);
          continue;
        }
        mergeValues(aggregate, value2);
      }
    }
  }
  const results = [];
  for (const group of groups.values()) {
    group.ops.sort((a2, b3) => {
      return (a2.sequence ?? a2.id) - (b3.sequence ?? b3.id);
    });
    const groupIds = new Set(group.ops.map((op) => op.groupId).filter(Boolean));
    if (groupIds.size === 1) group.groupId = Array.from(groupIds)[0];
    group.generated = group.ops.length > 0 && group.ops.every((op) => op.generated);
    const hasCreate = entityCreates.get(group.key) ?? false;
    const hasDelete = entityDeletes.get(group.key) ?? false;
    group.operation = hasCreate ? "create" : hasDelete ? "delete" : "update";
    const fieldMap = aggregates.get(group.key);
    const fieldSet = /* @__PURE__ */ new Set();
    if (fieldMap) for (const field of fieldMap.keys()) fieldSet.add(field);
    group.changedFields = Array.from(fieldSet);
    group.summary = buildSummary(group.operation, group.changedFields);
    group.sections = buildSections(group.entity, fieldMap ?? /* @__PURE__ */ new Map());
    const depSet = dependencies.get(group.key);
    if (depSet) {
      const requires = [];
      for (const depKey of depSet) {
        const dependency = groups.get(depKey);
        if (!dependency) continue;
        requires.push({
          key: depKey,
          entity: dependency.entity,
          name: dependency.name
        });
      }
      requires.sort((a2, b3) => {
        if (a2.entity === b3.entity) return a2.name.localeCompare(b3.name);
        return a2.entity.localeCompare(b3.entity);
      });
      if (requires.length > 0) group.requires = requires;
    }
    results.push(group);
  }
  results.sort((a2, b3) => {
    if (a2.groupId && a2.groupId === b3.groupId && a2.generated !== b3.generated) return a2.generated ? 1 : -1;
    if (a2.updatedAt === b3.updatedAt) return a2.key.localeCompare(b3.key);
    return a2.updatedAt < b3.updatedAt ? 1 : -1;
  });
  return results;
}
function findDraftDropBlockers(databaseId, selectedOpIds) {
  const changes = listDraftEntityChanges(databaseId);
  const changeByKey = new Map(changes.map((change) => [change.key, change]));
  const keyByOpId = /* @__PURE__ */ new Map();
  for (const change of changes) for (const op of change.ops) keyByOpId.set(op.id, change.key);
  const selectedKeys = /* @__PURE__ */ new Set();
  for (const opId of selectedOpIds) {
    const key2 = keyByOpId.get(opId);
    if (key2) selectedKeys.add(key2);
  }
  const selectedCreateKeys = /* @__PURE__ */ new Set();
  for (const key2 of selectedKeys) if (changeByKey.get(key2)?.operation === "create") selectedCreateKeys.add(key2);
  if (selectedCreateKeys.size === 0) return [];
  const dependentsByKey = /* @__PURE__ */ new Map();
  for (const change of changes) for (const requirement of change.requires ?? []) {
    const dependents = dependentsByKey.get(requirement.key) ?? /* @__PURE__ */ new Set();
    dependents.add(change.key);
    dependentsByKey.set(requirement.key, dependents);
  }
  const blockerKeys = /* @__PURE__ */ new Set();
  const queue = Array.from(selectedCreateKeys);
  while (queue.length > 0) {
    const key2 = queue.shift();
    if (!key2) continue;
    for (const dependentKey of dependentsByKey.get(key2) ?? []) {
      if (selectedKeys.has(dependentKey) || blockerKeys.has(dependentKey)) continue;
      blockerKeys.add(dependentKey);
      if (changeByKey.get(dependentKey)?.operation === "create") queue.push(dependentKey);
    }
  }
  return Array.from(blockerKeys).map((key2) => {
    const change = changeByKey.get(key2);
    if (!change) return null;
    return {
      key: change.key,
      entity: change.entity,
      name: change.name,
      summary: change.summary
    };
  }).filter((blocker) => blocker !== null).sort((a2, b3) => {
    if (a2.entity === b3.entity) return a2.name.localeCompare(b3.name);
    return a2.entity.localeCompare(b3.entity);
  });
}
var FIELD_LABELS, ENTITY_BY_STABLE_KEY;
var init_draftChanges = __esm({
  async "dist/build/server/chunks/draftChanges.js"() {
    "use strict";
    await init_pcdOps();
    FIELD_LABELS = {
      quality_profile_name: "Quality profile",
      custom_format_name: "Custom format",
      delay_profile_name: "Delay profile",
      regular_expression_name: "Regular expression",
      regex101_id: "Regex101 ID",
      ordered_items: "Ordered items",
      conditions: "Conditions",
      tests: "Tests",
      tags: "Tags",
      include_in_rename: "Include in rename",
      preferred_protocol: "Preferred protocol",
      usenet_delay: "Usenet delay",
      torrent_delay: "Torrent delay",
      bypass_if_highest_quality: "Bypass if highest quality",
      bypass_if_above_custom_format_score: "Bypass if above score",
      minimum_custom_format_score: "Minimum score",
      upgrade_until_score: "Upgrade until score",
      upgrade_score_increment: "Upgrade score increment"
    };
    ENTITY_BY_STABLE_KEY = {
      custom_format_name: "custom_format",
      quality_profile_name: "quality_profile",
      regular_expression_name: "regular_expression"
    };
  }
});

// dist/build/server/entries/pages/databases/_id_/changes/_page.server.ts.js
var page_server_ts_exports29 = {};
__export(page_server_ts_exports29, {
  actions: () => actions21,
  load: () => load33
});
import { isAbsolute as isAbsolute3, resolve as resolve4 } from "node:path";
function validateFilePaths(rootPath, filePaths) {
  const root = resolve4(rootPath);
  let realRoot;
  try {
    realRoot = Deno.realPathSync(rootPath);
  } catch {
    realRoot = root;
  }
  for (const fp of filePaths) {
    if (isAbsolute3(fp)) throw new Error("Invalid file path: absolute paths not allowed");
    const resolved = resolve4(rootPath, fp);
    if (!resolved.startsWith(root + "/")) throw new Error("Invalid file path: path escapes repository boundary");
    try {
      if (!Deno.realPathSync(resolved).startsWith(realRoot + "/")) throw new Error("Invalid file path: path escapes repository boundary");
    } catch (e) {
      if (e instanceof Deno.errors.NotFound) continue;
      throw e;
    }
  }
}
async function getMaxOpNumber(repoPath) {
  let maxNum = 0;
  const output = await execGitSafe([
    "ls-tree",
    "--name-only",
    "HEAD",
    "ops/"
  ], repoPath);
  if (!output) return maxNum;
  for (const filename of output.split("\n")) {
    if (!filename.trim() || !filename.endsWith(".sql")) continue;
    const match = filename.replace("ops/", "").match(/^(\d+)\./);
    if (match) {
      const num = parseInt(match[1], 10);
      if (num > maxNum) maxNum = num;
    }
  }
  return maxNum;
}
function isCleanEnough(status) {
  if (!status.isDirty) return true;
  if (status.staged.length > 0) return false;
  return true;
}
function slugify2(value2) {
  const slug = value2.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60);
  return slug.length > 0 ? slug : "export-batch";
}
function buildHeader(message2, opIds, exportedAt) {
  const ids = opIds.join(", ");
  return [
    "-- @operation: export",
    "-- @entity: batch",
    `-- @name: ${message2}`,
    `-- @exportedAt: ${exportedAt}`,
    `-- @opIds: ${ids}`
  ].join("\n");
}
function buildMetadataJson2(message2, opIds, exportedAt) {
  return JSON.stringify({
    operation: "export",
    entity: "batch",
    name: message2,
    exported_at: exportedAt,
    op_ids: opIds
  });
}
function formatSqlValidationError(error2) {
  const errorStr = String(error2);
  if (errorStr.includes("FOREIGN KEY constraint failed")) return `Foreign key constraint failed. ${errorStr}`;
  if (errorStr.includes("UNIQUE constraint failed")) return `Unique constraint failed. ${errorStr}`;
  if (errorStr.includes("NOT NULL constraint failed")) return `Required field is missing. ${errorStr}`;
  if (errorStr.includes("CHECK constraint failed")) return `Value validation failed. ${errorStr}`;
  return errorStr;
}
async function validateExportPlan(databaseId, repoPath, plan) {
  const validationDb = new Database(":memory:", { int64: true });
  try {
    validationDb.exec("PRAGMA foreign_keys = ON");
    const schemaOps = await loadOperationsFromDir(`${repoPath}/deps/schema/ops`, "schema");
    for (const op of schemaOps) try {
      validationDb.exec(op.sql);
    } catch (error2) {
      return {
        valid: false,
        error: `Existing schema operation ${op.filename} failed validation: ${formatSqlValidationError(error2)}`
      };
    }
    const baseOps = pcdOpsQueries.listByDatabaseAndOrigin(databaseId, "base", { states: ["published"] }).sort((a2, b3) => (a2.sequence ?? a2.id) - (b3.sequence ?? b3.id));
    for (const op of baseOps) {
      const label = op.filename ?? `pcd_op_${op.id}.sql`;
      try {
        validationDb.exec(op.sql);
      } catch (error2) {
        return {
          valid: false,
          error: `Existing base operation ${label} failed validation: ${formatSqlValidationError(error2)}`
        };
      }
    }
    try {
      validationDb.exec(plan.dbSql);
    } catch (error2) {
      return {
        valid: false,
        error: `Export batch ${plan.filename} failed validation: ${formatSqlValidationError(error2)}`
      };
    }
    return { valid: true };
  } finally {
    validationDb.close();
  }
}
function opLabel(op) {
  if (!op.metadata) return null;
  try {
    const parsed = JSON.parse(op.metadata);
    if (!parsed.operation || !parsed.entity || !parsed.name) return null;
    return `${parsed.operation} ${parsed.entity} "${parsed.name}"`;
  } catch {
    return null;
  }
}
function formatOpBlock(op) {
  const label = opLabel(op);
  const trimmedSql = op.sql.trim().replace(/;\s*$/, "");
  const title = label ? ` ( ${label} )` : "";
  return [
    `-- --- BEGIN op ${op.id}${title}`,
    `${trimmedSql};`,
    `-- --- END op ${op.id}`
  ].join("\n");
}
function buildChangeMaps(databaseId) {
  const changes = listDraftEntityChanges(databaseId);
  const changeByKey = new Map(changes.map((change) => [change.key, change]));
  const changeByOpId = /* @__PURE__ */ new Map();
  const groupMap = /* @__PURE__ */ new Map();
  for (const change of changes) {
    for (const op of change.ops) changeByOpId.set(op.id, change.key);
    if (change.groupId) {
      const entries = groupMap.get(change.groupId) ?? [];
      entries.push(change.key);
      groupMap.set(change.groupId, entries);
    }
  }
  return {
    changes,
    changeByKey,
    changeByOpId,
    groupMap
  };
}
function buildRemoteUrl(repositoryUrl, personalAccessToken) {
  if (!personalAccessToken) return repositoryUrl;
  if (!repositoryUrl.startsWith("https://github.com")) return repositoryUrl;
  return repositoryUrl.replace("https://github.com", `https://${personalAccessToken}@github.com`);
}
async function fetchRemoteBranch(repoPath, remoteUrl, branch2) {
  await execGit([
    "fetch",
    "--quiet",
    remoteUrl,
    `${branch2}:refs/remotes/origin/${branch2}`
  ], repoPath);
}
async function getAheadBehind(repoPath, branch2) {
  const parts = (await execGit([
    "rev-list",
    "--left-right",
    "--count",
    `origin/${branch2}...HEAD`
  ], repoPath)).split("	").map((value2) => parseInt(value2, 10) || 0);
  return {
    behind: parts[0] || 0,
    ahead: parts[1] || 0
  };
}
async function runPreflight(databaseId) {
  const database = databaseInstancesQueries.getById(databaseId);
  const checks = {
    repoExists: false,
    manifestValid: false,
    remoteReachable: false,
    clean: false,
    upToDate: false,
    ahead: 0,
    behind: 0,
    identitySet: false,
    canWriteToBase: false,
    branch: null
  };
  const errors = [];
  let status = void 0;
  if (!database) return {
    ok: false,
    errors: ["Database not found"],
    checks,
    status
  };
  checks.canWriteToBase = canWriteToBase(databaseId);
  if (!checks.canWriteToBase) errors.push("This database cannot publish changes.");
  const gitUserName = database.git_user_name?.trim() ?? "";
  const gitUserEmail = database.git_user_email?.trim() ?? "";
  if (gitUserName && gitUserEmail) checks.identitySet = true;
  else errors.push("Git author name and email are required to export changes.");
  try {
    await Deno.stat(database.local_path);
    checks.repoExists = true;
  } catch {
    errors.push("Repository not found on disk.");
  }
  if (!checks.repoExists) return {
    ok: false,
    errors,
    checks,
    status
  };
  try {
    await loadManifest(database.local_path);
    checks.manifestValid = true;
  } catch (error2) {
    errors.push(error2 instanceof Error ? error2.message : "Manifest validation failed.");
  }
  try {
    const branch2 = await getBranch(database.local_path);
    checks.branch = branch2 || null;
    if (!branch2) errors.push("Repository is not on a branch.");
    else {
      const remoteUrl = buildRemoteUrl(database.repository_url, database.personal_access_token);
      await fetchRemoteBranch(database.local_path, remoteUrl, branch2);
      checks.remoteReachable = true;
      status = await getStatus(database.local_path);
      const { ahead, behind } = await getAheadBehind(database.local_path, branch2);
      status = {
        ...status,
        ahead,
        behind
      };
      checks.ahead = ahead;
      checks.behind = behind;
      checks.clean = isCleanEnough(status);
      if (!checks.clean) errors.push("Repository has uncommitted changes.");
      checks.upToDate = ahead === 0 && behind === 0;
      if (behind > 0) errors.push(`Repository is behind remote by ${behind} commit${behind === 1 ? "" : "s"}.`);
      if (ahead > 0) errors.push(`Repository has ${ahead} unpushed commit${ahead === 1 ? "" : "s"}.`);
    }
  } catch {
    errors.push("Failed to reach remote repository.");
  }
  return {
    ok: errors.length === 0,
    errors,
    checks,
    status
  };
}
function resolveSelectedOps(databaseId, opIds) {
  const { changeByKey, changeByOpId, groupMap } = buildChangeMaps(databaseId);
  const selectedKeys = /* @__PURE__ */ new Set();
  for (const opId of opIds) {
    const key2 = changeByOpId.get(opId);
    if (key2) selectedKeys.add(key2);
  }
  if (selectedKeys.size === 0) return {
    ops: [],
    selectedKeys
  };
  const queue = Array.from(selectedKeys);
  while (queue.length > 0) {
    const key2 = queue.shift();
    if (!key2) continue;
    const change = changeByKey.get(key2);
    if (!change) continue;
    if (change.groupId && groupMap.has(change.groupId)) {
      for (const groupKey of groupMap.get(change.groupId) ?? []) if (!selectedKeys.has(groupKey)) {
        selectedKeys.add(groupKey);
        queue.push(groupKey);
      }
    }
    if (change.requires && change.requires.length > 0) for (const requirement of change.requires) {
      const required = changeByKey.get(requirement.key);
      if (!required || required.operation !== "create") continue;
      if (!selectedKeys.has(required.key)) {
        selectedKeys.add(required.key);
        queue.push(required.key);
      }
    }
  }
  const opMap = /* @__PURE__ */ new Map();
  for (const key2 of selectedKeys) {
    const change = changeByKey.get(key2);
    if (!change) continue;
    for (const op of change.ops) {
      const row = pcdOpsQueries.getById(op.id);
      if (!row || row.database_id !== databaseId || row.origin !== "base" || row.state !== "draft") continue;
      opMap.set(row.id, row);
    }
  }
  return {
    ops: Array.from(opMap.values()).filter((op) => !!op).sort((a2, b3) => (a2.sequence ?? a2.id) - (b3.sequence ?? b3.id)),
    selectedKeys
  };
}
async function buildExportPlan(databaseId, opIds, message2, repoPath, exportedAtOverride) {
  const trimmedMessage = message2.trim();
  if (!trimmedMessage) return {
    success: false,
    error: "Commit message is required"
  };
  const { ops } = resolveSelectedOps(databaseId, opIds);
  if (ops.length === 0) return {
    success: false,
    error: "No draft operations selected"
  };
  const fallbackTimestamp = (/* @__PURE__ */ new Date()).toISOString();
  const exportedAt = exportedAtOverride && !Number.isNaN(Date.parse(exportedAtOverride)) ? new Date(exportedAtOverride).toISOString() : fallbackTimestamp;
  const opIdList = ops.map((op) => op.id);
  const header = buildHeader(trimmedMessage, opIdList, exportedAt);
  const body = ops.map((op) => formatOpBlock(op)).join("\n\n");
  const fileContent = `${header}

${body}
`;
  const dbSql = body.trim();
  const metadataJson = buildMetadataJson2(trimmedMessage, opIdList, exportedAt);
  const contentHash = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(`${dbSql}
${metadataJson}`)).then((hashBuffer) => Array.from(new Uint8Array(hashBuffer)).map((b3) => b3.toString(16).padStart(2, "0")).join(""));
  const opNumber = await getMaxOpNumber(repoPath) + 1;
  const filename = `${opNumber}.${slugify2(trimmedMessage)}.sql`;
  const plan = {
    filename,
    filepath: `ops/${filename}`,
    fileContent,
    dbSql,
    metadataJson,
    contentHash,
    opIds: opIdList,
    exportedAt,
    opNumber,
    ops
  };
  const validation = await validateExportPlan(databaseId, repoPath, plan);
  if (!validation.valid) return {
    success: false,
    error: validation.error
  };
  return {
    success: true,
    plan
  };
}
async function cloneForExport(sourcePath, targetPath, workdir) {
  await execGit([
    "clone",
    "--quiet",
    sourcePath,
    targetPath
  ], workdir);
}
async function pushHeadToBranch(repoPath, branch2) {
  await execGit([
    "push",
    "origin",
    `HEAD:refs/heads/${branch2}`
  ], repoPath);
}
async function previewDraftOps(databaseId, opIds, message2, filePaths = []) {
  const database = databaseInstancesQueries.getById(databaseId);
  if (!database) return {
    success: false,
    error: "Database not found"
  };
  if (opIds.length === 0 && filePaths.length === 0) return {
    success: false,
    error: "No changes selected"
  };
  if (filePaths.length > 0) try {
    validateFilePaths(database.local_path, filePaths);
  } catch {
    return {
      success: false,
      error: "Invalid file path"
    };
  }
  const trimmedMessage = message2.trim();
  if (!trimmedMessage) return {
    success: false,
    error: "Commit message is required"
  };
  const preflight = await runPreflight(databaseId);
  const gitIdentity = {
    name: database.git_user_name?.trim() ?? "",
    email: database.git_user_email?.trim() ?? ""
  };
  if (!preflight.ok) return {
    success: true,
    preview: {
      ok: false,
      errors: preflight.errors,
      checks: preflight.checks,
      status: preflight.status,
      commitMessage: trimmedMessage,
      gitIdentity
    }
  };
  let plan = null;
  if (opIds.length > 0) {
    const planResult = await buildExportPlan(databaseId, opIds, trimmedMessage, database.local_path);
    if (!planResult.success) return {
      success: false,
      error: planResult.error
    };
    plan = planResult.plan;
  }
  return {
    success: true,
    preview: {
      ok: true,
      errors: [],
      checks: preflight.checks,
      status: preflight.status,
      filename: plan?.filename,
      filepath: plan?.filepath,
      content: plan?.fileContent,
      contentHash: plan?.contentHash,
      opIds: plan?.opIds,
      opCount: plan?.opIds.length ?? 0,
      filePaths: filePaths.length > 0 ? filePaths : void 0,
      exportedAt: plan?.exportedAt,
      commitMessage: trimmedMessage,
      gitIdentity
    }
  };
}
async function exportDraftOps(databaseId, opIds, message2, exportedAtOverride, filePaths = []) {
  const database = databaseInstancesQueries.getById(databaseId);
  if (!database) return {
    success: false,
    error: "Database not found"
  };
  const trimmedMessage = message2.trim();
  if (!trimmedMessage) return {
    success: false,
    error: "Commit message is required"
  };
  if (opIds.length === 0 && filePaths.length === 0) return {
    success: false,
    error: "No changes selected"
  };
  if (filePaths.length > 0) try {
    validateFilePaths(database.local_path, filePaths);
  } catch {
    return {
      success: false,
      error: "Invalid file path"
    };
  }
  const preflight = await runPreflight(databaseId);
  if (!preflight.ok) return {
    success: false,
    error: preflight.errors.length > 0 ? preflight.errors[0] : "Export preflight failed"
  };
  let plan = null;
  if (opIds.length > 0) {
    const planResult = await buildExportPlan(databaseId, opIds, trimmedMessage, database.local_path, exportedAtOverride);
    if (!planResult.success) return {
      success: false,
      error: planResult.error
    };
    plan = planResult.plan;
  }
  const gitUserName = database.git_user_name?.trim() ?? "";
  const gitUserEmail = database.git_user_email?.trim() ?? "";
  const branch2 = preflight.checks.branch ?? "";
  if (!branch2) return {
    success: false,
    error: "Repository is not on a branch."
  };
  try {
    const tempDir = await Deno.makeTempDir({ prefix: "profilarr-export-" });
    const repoDir = `${tempDir}/repo`;
    const authUrl = buildRemoteUrl(database.repository_url, database.personal_access_token);
    let sourcePath = database.local_path;
    try {
      sourcePath = await Deno.realPath(database.local_path);
    } catch {
    }
    try {
      await cloneForExport(sourcePath, repoDir, tempDir);
      await execGit([
        "remote",
        "set-url",
        "origin",
        authUrl
      ], repoDir);
      const toStage = [];
      if (plan) {
        const filepath = `${repoDir}/ops/${plan.filename}`;
        await Deno.mkdir(`${repoDir}/ops`, { recursive: true });
        await Deno.writeTextFile(filepath, plan.fileContent);
        toStage.push(filepath);
      }
      if (filePaths.length > 0) for (const fp of filePaths) {
        const src = `${sourcePath}/${fp}`;
        const dest = `${repoDir}/${fp}`;
        let srcExists = true;
        try {
          await Deno.stat(src);
        } catch (err) {
          if (err instanceof Deno.errors.NotFound) srcExists = false;
          else throw err;
        }
        if (srcExists) {
          const destDir = dest.substring(0, dest.lastIndexOf("/"));
          if (destDir !== repoDir) await Deno.mkdir(destDir, { recursive: true });
          await Deno.copyFile(src, dest);
        } else try {
          await Deno.remove(dest);
        } catch (err) {
          if (!(err instanceof Deno.errors.NotFound)) throw err;
        }
        toStage.push(dest);
      }
      await stage(repoDir, toStage);
      await configureIdentity(repoDir, gitUserName, gitUserEmail);
      await commit(repoDir, trimmedMessage);
      await pushHeadToBranch(repoDir, branch2);
    } finally {
      try {
        await Deno.remove(tempDir, { recursive: true });
      } catch {
      }
    }
    try {
      if (filePaths.length > 0) {
        const trackedFiles = [];
        const untrackedFiles = [];
        const localStatus = await getStatus(database.local_path);
        const untrackedSet = new Set(localStatus.untracked);
        for (const fp of filePaths) if (untrackedSet.has(fp)) untrackedFiles.push(fp);
        else trackedFiles.push(fp);
        if (trackedFiles.length > 0) await execGit([
          "checkout",
          "--",
          ...trackedFiles
        ], database.local_path);
        for (const fp of untrackedFiles) try {
          await Deno.remove(`${database.local_path}/${fp}`);
        } catch {
        }
      }
      await execGit(["pull", "--ff-only"], database.local_path);
    } catch (error2) {
      await logger.warn("Failed to update local repo after export", {
        source: "PCDExporter",
        meta: {
          databaseId,
          error: String(error2)
        }
      });
    }
    let newOpId = null;
    if (plan) {
      newOpId = pcdOpsQueries.create({
        databaseId,
        origin: "base",
        state: "published",
        source: "repo",
        filename: plan.filename,
        opNumber: plan.opNumber,
        sequence: plan.opNumber,
        sql: plan.dbSql,
        metadata: plan.metadataJson,
        contentHash: plan.contentHash,
        lastSeenInRepoAt: plan.exportedAt
      });
      const batchId = uuid();
      for (const op of plan.ops) {
        pcdOpsQueries.update(op.id, {
          state: "superseded",
          supersededByOpId: newOpId
        });
        pcdOpHistoryQueries.create({
          opId: op.id,
          databaseId,
          batchId,
          status: "superseded"
        });
      }
    }
    if (database.enabled) await compile(database.local_path, databaseId);
    await logger.info("Exported changes to repository", {
      source: "PCDExporter",
      meta: {
        databaseId,
        databaseName: database.name,
        filename: plan?.filename ?? null,
        opId: newOpId,
        opsExported: plan?.opIds.length ?? 0,
        fileCount: filePaths.length
      }
    });
    return {
      success: true,
      filename: plan?.filename ?? null,
      opId: newOpId,
      dropped: plan?.opIds.length ?? 0,
      fileCount: filePaths.length
    };
  } catch (error2) {
    await logger.error("Failed to export changes", {
      source: "PCDExporter",
      meta: {
        databaseId,
        error: String(error2)
      }
    });
    return {
      success: false,
      error: String(error2)
    };
  }
}
function formatEntity(entity) {
  return entity.replace(/[_-]+/g, " ").trim().replace(/\b\w/g, (char) => char.toUpperCase());
}
var load33, actions21;
var init_page_server_ts29 = __esm({
  async "dist/build/server/entries/pages/databases/_id_/changes/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_database();
    await init_databaseInstances();
    init_operations2();
    await init_queueService();
    init_uuid();
    await init_git();
    await init_markdown();
    await init_pcdOps();
    await init_draftChanges();
    init_exports();
    load33 = async ({ parent }) => {
      const { database } = await parent();
      return { isDeveloper: database.hasPat };
    };
    actions21 = {
      drop: async ({ request, params }) => {
        const id = parseInt(params.id || "", 10);
        const database = databaseInstancesQueries.getById(id);
        if (!database) return {
          success: false,
          error: "Database not found"
        };
        try {
          const formData = await request.formData();
          const opIdsInput = formData.getAll("opIds").map((value2) => Number(value2)).filter((value2) => Number.isFinite(value2));
          const filePathsInput = formData.getAll("filePaths").filter(Boolean);
          const opIds = /* @__PURE__ */ new Set();
          const filePaths = /* @__PURE__ */ new Set();
          if (opIdsInput.length > 0 || filePathsInput.length > 0) {
            for (const opId of opIdsInput) opIds.add(opId);
            for (const filepath of filePathsInput) filePaths.add(filepath);
          } else {
            const keys = formData.getAll("keys").filter(Boolean);
            if (keys.length === 0) return {
              success: false,
              error: "No changes selected"
            };
            const changes = listDraftEntityChanges(id);
            const changeByKey = new Map(changes.map((change) => [change.key, change]));
            const groupMap = /* @__PURE__ */ new Map();
            for (const change of changes) {
              if (!change.groupId) continue;
              const entries = groupMap.get(change.groupId) ?? [];
              entries.push(change.key);
              groupMap.set(change.groupId, entries);
            }
            const keysToDrop = /* @__PURE__ */ new Set();
            for (const key2 of keys) {
              const change = changeByKey.get(key2);
              if (!change) continue;
              if (change.groupId && groupMap.has(change.groupId)) for (const groupKey of groupMap.get(change.groupId) ?? []) keysToDrop.add(groupKey);
              else keysToDrop.add(change.key);
            }
            for (const key2 of keysToDrop) {
              const change = changeByKey.get(key2);
              if (!change) continue;
              for (const op of change.ops) opIds.add(op.id);
              if (change.path) filePaths.add(change.path);
            }
          }
          if (opIds.size === 0 && filePaths.size === 0) {
            await logger.warn("Drop requested with no targets", {
              source: "changes",
              meta: { databaseId: id }
            });
            return {
              success: false,
              error: "No changes selected"
            };
          }
          const blockers = findDraftDropBlockers(id, opIds);
          if (blockers.length > 0) return {
            success: false,
            error: `Cannot drop selected changes because other outstanding changes depend on them. Select these changes too, then drop again: ${blockers.map((blocker) => `${formatEntity(blocker.entity)} "${blocker.name}" (${blocker.summary})`).join(", ")}`
          };
          let droppedFiles = 0;
          let touchedAnnouncementFiles = false;
          if (filePaths.size > 0) {
            const filePathsArray = Array.from(filePaths);
            try {
              validateFilePaths(database.local_path, filePathsArray);
            } catch {
              return fail(400, { error: "Invalid file path" });
            }
            const status = await getStatus(database.local_path);
            const untrackedSet = new Set(status.untracked);
            const modifiedSet = new Set(status.modified);
            const deletedSet = new Set(status.deleted);
            const toDelete = [];
            const toRestore = [];
            for (const filepath of filePathsArray) {
              if (untrackedSet.has(filepath)) toDelete.push(filepath);
              else if (modifiedSet.has(filepath) || deletedSet.has(filepath)) toRestore.push(filepath);
              if (filepath.startsWith("announcements/") && filepath.endsWith(".md")) touchedAnnouncementFiles = true;
            }
            for (const filepath of toDelete) try {
              await Deno.remove(`${database.local_path}/${filepath}`);
              droppedFiles += 1;
            } catch (err) {
              if (!(err instanceof Deno.errors.NotFound)) throw err;
            }
            if (toRestore.length > 0) {
              await restorePathsToHead(database.local_path, toRestore);
              droppedFiles += toRestore.length;
            }
            if (touchedAnnouncementFiles) try {
              await reconcileFromWorkingCopy(id, { isFirstSync: false });
            } catch (err) {
              await logger.error("Failed to reconcile announcements after drop", {
                source: "changes",
                meta: {
                  databaseId: id,
                  error: String(err)
                }
              });
            }
          }
          const batchId = uuid();
          let droppedOps = 0;
          for (const opId of opIds) {
            const op = pcdOpsQueries.getById(opId);
            if (!op || op.database_id !== id || op.state !== "draft") continue;
            if (!pcdOpsQueries.update(opId, { state: "dropped" })) continue;
            pcdOpHistoryQueries.create({
              opId,
              databaseId: id,
              batchId,
              status: "dropped"
            });
            droppedOps += 1;
          }
          if (droppedOps === 0 && droppedFiles === 0) {
            await logger.warn("Drop requested but nothing matched", {
              source: "changes",
              meta: {
                databaseId: id,
                requestedOps: opIds.size,
                requestedFiles: filePaths.size
              }
            });
            return {
              success: false,
              error: "No changes to drop"
            };
          }
          if (droppedOps > 0 && database.enabled) try {
            await compile(database.local_path, id);
          } catch (err) {
            await logger.error("Failed to recompile cache after drop", {
              source: "changes",
              meta: {
                databaseId: id,
                error: String(err)
              }
            });
          }
          await logger.info("Dropped draft changes", {
            source: "changes",
            meta: {
              databaseId: id,
              databaseName: database.name,
              batchId,
              requestedOps: opIds.size,
              droppedOps,
              requestedFiles: filePaths.size,
              droppedFiles,
              opIds: Array.from(opIds),
              filePaths: Array.from(filePaths)
            }
          });
          return {
            success: true,
            dropped: droppedOps + droppedFiles
          };
        } catch (err) {
          await logger.error("Failed to drop changes", {
            source: "changes",
            meta: {
              databaseId: id,
              error: String(err)
            }
          });
          return {
            success: false,
            error: err instanceof Error ? err.message : "Failed to drop changes"
          };
        }
      },
      commit: async ({ request, params }) => {
        const id = parseInt(params.id || "", 10);
        const database = databaseInstancesQueries.getById(id);
        if (!database) return {
          success: false,
          error: "Database not found"
        };
        const formData = await request.formData();
        const opIds = formData.getAll("opIds").map((value2) => Number(value2)).filter((value2) => Number.isFinite(value2));
        const filePaths = formData.getAll("filePaths").filter(Boolean);
        const message2 = formData.get("message") ?? "";
        const exportedAt = formData.get("exportedAt")?.toString().trim() || null;
        if (filePaths.length > 0) try {
          validateFilePaths(database.local_path, filePaths);
        } catch {
          return fail(400, { error: "Invalid file path" });
        }
        if (opIds.length === 0 && filePaths.length === 0) return {
          success: false,
          error: "No changes selected"
        };
        if (!message2.trim()) return fail(400, { error: "Commit message is required" });
        const result = await exportDraftOps(id, opIds, message2, exportedAt, filePaths);
        if (!result.success) return fail(500, { error: result.error || "Failed to export changes" });
        return {
          success: true,
          filename: result.filename,
          opId: result.opId,
          dropped: result.dropped,
          fileCount: result.fileCount
        };
      },
      preview: async ({ request, params }) => {
        const id = parseInt(params.id || "", 10);
        const database = databaseInstancesQueries.getById(id);
        if (!database) return {
          success: false,
          error: "Database not found"
        };
        const formData = await request.formData();
        const opIds = formData.getAll("opIds").map((value2) => Number(value2)).filter((value2) => Number.isFinite(value2));
        const filePaths = formData.getAll("filePaths").filter(Boolean);
        const message2 = formData.get("message") ?? "";
        if (filePaths.length > 0) try {
          validateFilePaths(database.local_path, filePaths);
        } catch {
          return fail(400, { error: "Invalid file path" });
        }
        if (opIds.length === 0 && filePaths.length === 0) return {
          success: false,
          error: "No changes selected"
        };
        if (!message2.trim()) return fail(400, { error: "Commit message is required" });
        const result = await previewDraftOps(id, opIds, message2, filePaths);
        if (!result.success) return fail(500, { error: result.error || "Failed to preview export" });
        return {
          success: true,
          preview: result.preview
        };
      },
      pull: async ({ params }) => {
        const id = parseInt(params.id || "", 10);
        const database = databaseInstancesQueries.getById(id);
        if (!database) return {
          success: false,
          error: "Database not found"
        };
        const isFirstSync = database.last_synced_at === null;
        try {
          const result = await pcdManager.sync(id, "manual-ui");
          if (result.success) await reconcileAndNotify(id, {
            source: "changes",
            isFirstSync
          });
          return result;
        } catch (err) {
          await logger.error("Failed to pull changes", {
            source: "changes",
            meta: {
              databaseId: id,
              error: String(err)
            }
          });
          return {
            success: false,
            error: err instanceof Error ? err.message : "Failed to pull"
          };
        }
      }
    };
  }
});

// dist/build/server/chunks/send.js
function Send($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "send" },
    props,
    { iconNode: [["path", { "d": "M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z" }], ["path", { "d": "m21.854 2.147-10.94 10.939" }]] }
  ]));
}
var init_send = __esm({
  "dist/build/server/chunks/send.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/upload.js
function Upload($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "upload" },
    props,
    { iconNode: [
      ["path", { "d": "M12 3v12" }],
      ["path", { "d": "m17 8-5-5-5 5" }],
      ["path", { "d": "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }]
    ] }
  ]));
}
var init_upload = __esm({
  "dist/build/server/chunks/upload.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/chunks/CodeBlock.js
function CodeBlock($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let theme, variant, tokens, langLabel, langVariant, langCustomVariant;
    let code3 = fallback($$props["code"], "");
    let language = fallback($$props["language"], "sql");
    let copyable = fallback($$props["copyable"], true);
    let themeName = "Default";
    function tokenColor(type, v3) {
      return v3[type] ?? void 0;
    }
    function selectTheme(name) {
      themeName = name;
    }
    $: theme = getTheme(themeName);
    $: variant = store_get($$store_subs ??= {}, "$themeStore", themeStore) === "dark" ? theme.dark : theme.light;
    $: tokens = tokenize(code3, language);
    $: langLabel = language === "sql" ? "SQL" : language === "json" ? "JSON" : language;
    $: langVariant = language === "sql" ? "info" : "secondary";
    $: langCustomVariant = language === "json" ? "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200" : "";
    $$renderer2.push(`<div class="code-block overflow-hidden rounded-xl border border-neutral-300 dark:border-neutral-700/60 svelte-q9zb38"><div class="flex flex-wrap items-center gap-2 border-b border-neutral-200 bg-neutral-50 px-3 py-2 dark:border-neutral-700/60 dark:bg-neutral-900">`);
    Label($$renderer2, {
      variant: langVariant,
      customVariant: langCustomVariant,
      size: "sm",
      rounded: "md",
      mono: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!---->${escape_html(langLabel)}`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> <!--[-->`);
    slot($$renderer2, $$props, "header", {}, null);
    $$renderer2.push(`<!--]--> <div class="ml-auto flex items-center gap-2">`);
    if (themes.length > 1) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="relative">`);
      $$renderer2.select({
        value: themeName,
        onchange: (e) => selectTheme(e.currentTarget.value),
        class: "appearance-none rounded bg-neutral-100 py-0.5 pr-5 pl-1.5 font-mono text-[10px] font-medium text-neutral-400 dark:bg-neutral-800 dark:text-neutral-500"
      }, ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(themes);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let t2 = each_array[$$index];
          $$renderer3.option({ value: t2.name }, ($$renderer4) => {
            $$renderer4.push(`${escape_html(t2.name)}`);
          });
        }
        $$renderer3.push(`<!--]-->`);
      });
      $$renderer2.push(` `);
      Chevron_down($$renderer2, {
        size: 10,
        class: "pointer-events-none absolute top-1/2 right-1 -translate-y-1/2 text-neutral-400 dark:text-neutral-500"
      });
      $$renderer2.push(`<!----></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (copyable) {
      $$renderer2.push("<!--[0-->");
      Button($$renderer2, {
        icon: Copy,
        iconColor: "",
        size: "xs",
        variant: "secondary",
        title: "Copy to clipboard"
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div></div> <div${attr_style(`background-color: ${stringify(variant.bg)}`)}><pre class="overflow-x-auto p-3 text-xs leading-5 whitespace-pre"${attr_style(`color: ${stringify(variant.text)}`)}><code><!--[-->`);
    const each_array_1 = ensure_array_like(tokens);
    for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
      let t2 = each_array_1[$$index_1];
      $$renderer2.push(`<span${attr_style(tokenColor(t2.type, variant) ? `color: ${tokenColor(t2.type, variant)}` : "")}>${escape_html(t2.text)}</span>`);
    }
    $$renderer2.push(`<!--]--></code></pre></div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      code: code3,
      language,
      copyable
    });
  });
}
var init_CodeBlock = __esm({
  "dist/build/server/chunks/CodeBlock.js"() {
    "use strict";
    init_server();
    init_chevron_down();
    init_copy();
    init_Button();
    init_theme();
    init_Label();
    init_themes();
  }
});

// dist/build/server/entries/pages/databases/_id_/changes/_page.svelte.js
var page_svelte_exports28 = {};
__export(page_svelte_exports28, {
  default: () => _page28
});
function Git_pull_request_create_arrow($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "git-pull-request-create-arrow" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "5",
        "cy": "6",
        "r": "3"
      }],
      ["path", { "d": "M5 9v12" }],
      ["path", { "d": "m15 9-3-3 3-3" }],
      ["path", { "d": "M12 6h5a2 2 0 0 1 2 2v3" }],
      ["path", { "d": "M19 15v6" }],
      ["path", { "d": "M22 18h-6" }]
    ] }
  ]));
}
function FieldDiffTable($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let columns;
    let rows = fallback($$props["rows"], () => [], true);
    let operation = fallback($$props["operation"], "update");
    function parseMarkdown2(text2) {
      return sanitizeHtml(g2.parse(text2));
    }
    function isMarkdownField(field) {
      return [
        "description",
        "readme",
        "notes"
      ].includes(field);
    }
    function isPatternField(field) {
      return field === "pattern";
    }
    function isRegex101Field(field) {
      return field === "regex101_id";
    }
    function isPreferredProtocolField(field) {
      return field === "preferred_protocol";
    }
    function isNamingTemplateField(field) {
      return [
        "movie_format",
        "movie_folder_format",
        "standard_episode_format",
        "daily_episode_format",
        "anime_episode_format",
        "series_folder_format",
        "season_folder_format"
      ].includes(field);
    }
    function isCustomColonFormatField(field) {
      return field === "custom_colon_replacement_format";
    }
    function isColonReplacementField(field) {
      return field === "colon_replacement_format";
    }
    function isMultiEpisodeStyleField(field) {
      return field === "multi_episode_style";
    }
    function isPropersRepacksField(field) {
      return field === "propers_repacks";
    }
    function formatColonReplacement(value2) {
      return getColonReplacementLabel(value2);
    }
    function formatMultiEpisodeStyle(value2) {
      return getMultiEpisodeStyleLabel(value2);
    }
    function formatPropersRepacks(value2) {
      switch (value2) {
        case "doNotPrefer":
          return "Do Not Prefer";
        case "preferAndUpgrade":
          return "Prefer and Upgrade";
        case "doNotUpgradeAutomatically":
          return "Do Not Upgrade Automatically";
        default:
          return value2;
      }
    }
    function formatPreferredProtocol(value2) {
      switch (value2) {
        case "prefer_usenet":
          return "Prefer Usenet";
        case "prefer_torrent":
          return "Prefer Torrent";
        case "only_usenet":
          return "Only Usenet";
        case "only_torrent":
          return "Only Torrent";
        default:
          return value2;
      }
    }
    function regex101Url(value2) {
      return `https://regex101.com/r/${value2}`;
    }
    function formatValue3(value2) {
      if (value2 === null) return "null";
      if (value2 === void 0) return "\u2014";
      if (Array.isArray(value2)) return value2.length === 0 ? "\u2014" : value2.join(", ");
      if (typeof value2 === "object") return JSON.stringify(value2);
      return String(value2);
    }
    function getFieldBefore(row) {
      if (row.before !== void 0) return row.before;
      if (row.remove && row.remove.length > 0) return row.remove;
    }
    function getFieldAfter(row) {
      if (row.after !== void 0) return row.after;
      if (row.add && row.add.length > 0) return row.add;
    }
    function getColumns(nextOperation) {
      switch (nextOperation) {
        case "create":
          return [{
            key: "label",
            header: "Field"
          }, {
            key: "after",
            header: "Value"
          }];
        case "delete":
          return [{
            key: "label",
            header: "Field"
          }, {
            key: "before",
            header: "Value"
          }];
        default:
          return [
            {
              key: "label",
              header: "Field"
            },
            {
              key: "before",
              header: "Before"
            },
            {
              key: "after",
              header: "After"
            }
          ];
      }
    }
    $: columns = getColumns(operation);
    Table2($$renderer2, {
      columns,
      data: rows,
      compact: true,
      hoverable: false,
      responsive: true,
      $$slots: { cell: ($$renderer3, { row, column }) => {
        if (column.key === "label") {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<span class="text-sm text-neutral-700 dark:text-neutral-200">${escape_html(row.label)}</span>`);
        } else if (column.key === "before") {
          $$renderer3.push("<!--[1-->");
          const beforeValue = getFieldBefore(row);
          if (row.field === "language" && typeof beforeValue === "string") {
            $$renderer3.push("<!--[0-->");
            Badge($$renderer3, {
              variant: "info",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(beforeValue)}`);
              },
              $$slots: { default: true }
            });
          } else if (isPropersRepacksField(row.field) && typeof beforeValue === "string") {
            $$renderer3.push("<!--[1-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatPropersRepacks(beforeValue))}`);
              },
              $$slots: { default: true }
            });
          } else if (isColonReplacementField(row.field) && typeof beforeValue === "string") {
            $$renderer3.push("<!--[2-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatColonReplacement(beforeValue))}`);
              },
              $$slots: { default: true }
            });
          } else if (isMultiEpisodeStyleField(row.field) && typeof beforeValue === "string") {
            $$renderer3.push("<!--[3-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatMultiEpisodeStyle(beforeValue))}`);
              },
              $$slots: { default: true }
            });
          } else if (isNamingTemplateField(row.field) && typeof beforeValue === "string") {
            $$renderer3.push("<!--[4-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(beforeValue)}`);
              },
              $$slots: { default: true }
            });
          } else if (isCustomColonFormatField(row.field) && typeof beforeValue === "string") {
            $$renderer3.push("<!--[5-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(beforeValue)}`);
              },
              $$slots: { default: true }
            });
          } else if (isPreferredProtocolField(row.field) && typeof beforeValue === "string") {
            $$renderer3.push("<!--[6-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatPreferredProtocol(beforeValue))}`);
              },
              $$slots: { default: true }
            });
          } else if (isRegex101Field(row.field) && typeof beforeValue === "string" && beforeValue.trim()) {
            $$renderer3.push("<!--[7-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<a${attr("href", regex101Url(beforeValue))} target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-1 text-accent-700 hover:underline dark:text-accent-300" title="Open on regex101">${escape_html(beforeValue)} `);
                External_link($$renderer4, { size: 12 });
                $$renderer4.push(`<!----></a>`);
              },
              $$slots: { default: true }
            });
          } else if (isPatternField(row.field) && typeof beforeValue === "string") {
            $$renderer3.push("<!--[8-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(beforeValue)}`);
              },
              $$slots: { default: true }
            });
          } else if (typeof beforeValue === "boolean") {
            $$renderer3.push("<!--[9-->");
            Badge($$renderer3, {
              variant: beforeValue ? "success" : "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(beforeValue ? "Yes" : "No")}`);
              },
              $$slots: { default: true }
            });
          } else if (isMarkdownField(row.field) && typeof beforeValue === "string") {
            $$renderer3.push("<!--[10-->");
            $$renderer3.push(`<div class="prose prose-sm prose-neutral dark:prose-invert text-sm">${html(parseMarkdown2(beforeValue))}</div>`);
          } else if (typeof beforeValue === "number") {
            $$renderer3.push("<!--[11-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(beforeValue)}`);
              },
              $$slots: { default: true }
            });
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(formatValue3(beforeValue))}</span>`);
          }
          $$renderer3.push(`<!--]-->`);
        } else if (column.key === "after") {
          $$renderer3.push("<!--[2-->");
          const afterValue = getFieldAfter(row);
          if (row.field === "language" && typeof afterValue === "string") {
            $$renderer3.push("<!--[0-->");
            Badge($$renderer3, {
              variant: "info",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(afterValue)}`);
              },
              $$slots: { default: true }
            });
          } else if (isPropersRepacksField(row.field) && typeof afterValue === "string") {
            $$renderer3.push("<!--[1-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatPropersRepacks(afterValue))}`);
              },
              $$slots: { default: true }
            });
          } else if (isColonReplacementField(row.field) && typeof afterValue === "string") {
            $$renderer3.push("<!--[2-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatColonReplacement(afterValue))}`);
              },
              $$slots: { default: true }
            });
          } else if (isMultiEpisodeStyleField(row.field) && typeof afterValue === "string") {
            $$renderer3.push("<!--[3-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatMultiEpisodeStyle(afterValue))}`);
              },
              $$slots: { default: true }
            });
          } else if (isNamingTemplateField(row.field) && typeof afterValue === "string") {
            $$renderer3.push("<!--[4-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(afterValue)}`);
              },
              $$slots: { default: true }
            });
          } else if (isCustomColonFormatField(row.field) && typeof afterValue === "string") {
            $$renderer3.push("<!--[5-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(afterValue)}`);
              },
              $$slots: { default: true }
            });
          } else if (isPreferredProtocolField(row.field) && typeof afterValue === "string") {
            $$renderer3.push("<!--[6-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatPreferredProtocol(afterValue))}`);
              },
              $$slots: { default: true }
            });
          } else if (isRegex101Field(row.field) && typeof afterValue === "string" && afterValue.trim()) {
            $$renderer3.push("<!--[7-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<a${attr("href", regex101Url(afterValue))} target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-1 text-accent-700 hover:underline dark:text-accent-300" title="Open on regex101">${escape_html(afterValue)} `);
                External_link($$renderer4, { size: 12 });
                $$renderer4.push(`<!----></a>`);
              },
              $$slots: { default: true }
            });
          } else if (isPatternField(row.field) && typeof afterValue === "string") {
            $$renderer3.push("<!--[8-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(afterValue)}`);
              },
              $$slots: { default: true }
            });
          } else if (typeof afterValue === "boolean") {
            $$renderer3.push("<!--[9-->");
            Badge($$renderer3, {
              variant: afterValue ? "success" : "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(afterValue ? "Yes" : "No")}`);
              },
              $$slots: { default: true }
            });
          } else if (isMarkdownField(row.field) && typeof afterValue === "string") {
            $$renderer3.push("<!--[10-->");
            $$renderer3.push(`<div class="prose prose-sm prose-neutral dark:prose-invert text-sm">${html(parseMarkdown2(afterValue))}</div>`);
          } else if (typeof afterValue === "number") {
            $$renderer3.push("<!--[11-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(afterValue)}`);
              },
              $$slots: { default: true }
            });
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<span class="text-sm text-neutral-700 dark:text-neutral-200">${escape_html(formatValue3(afterValue))}</span>`);
          }
          $$renderer3.push(`<!--]-->`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]-->`);
      } }
    });
    bind_props($$props, {
      rows,
      operation
    });
  });
}
function TagsDiffTable($$renderer, $$props) {
  let columns;
  let removed = fallback($$props["removed"], () => [], true);
  let added = fallback($$props["added"], () => [], true);
  let operation = fallback($$props["operation"], "update");
  function getColumns(nextOperation) {
    switch (nextOperation) {
      case "create":
        return [{
          key: "added",
          header: "Value"
        }];
      case "delete":
        return [{
          key: "removed",
          header: "Value"
        }];
      default:
        return [{
          key: "removed",
          header: "Removed"
        }, {
          key: "added",
          header: "Added"
        }];
    }
  }
  $: columns = getColumns(operation);
  Table2($$renderer, {
    columns,
    data: [{
      removed,
      added
    }],
    compact: true,
    hoverable: false,
    responsive: true,
    $$slots: { cell: ($$renderer2, { row, column }) => {
      if (column.key === "removed") {
        $$renderer2.push("<!--[0-->");
        if (row.removed.length > 0) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
          const each_array = ensure_array_like(row.removed);
          for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
            let tag2 = each_array[$$index];
            Badge($$renderer2, {
              variant: "neutral",
              size: "md",
              children: ($$renderer3) => {
                $$renderer3.push(`<!---->${escape_html(tag2)}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer2.push(`<!--]--></div>`);
        } else {
          $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<span class="text-sm text-neutral-400">\u2014</span>`);
        }
        $$renderer2.push(`<!--]-->`);
      } else if (column.key === "added") {
        $$renderer2.push("<!--[1-->");
        if (row.added.length > 0) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
          const each_array_1 = ensure_array_like(row.added);
          for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
            let tag2 = each_array_1[$$index_1];
            Badge($$renderer2, {
              variant: "neutral",
              size: "md",
              children: ($$renderer3) => {
                $$renderer3.push(`<!---->${escape_html(tag2)}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer2.push(`<!--]--></div>`);
        } else {
          $$renderer2.push("<!--[-1-->");
          $$renderer2.push(`<span class="text-sm text-neutral-400">\u2014</span>`);
        }
        $$renderer2.push(`<!--]-->`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]-->`);
    } }
  });
  bind_props($$props, {
    removed,
    added,
    operation
  });
}
function CustomFormatScoresTable($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let columns;
    let rows = fallback($$props["rows"], () => [], true);
    let operation = fallback($$props["operation"], "update");
    function formatTitle2(value2) {
      return value2.replace(/[_-]+/g, " ").trim().replace(/\b\w/g, (char) => char.toUpperCase());
    }
    function formatValue3(value2) {
      return value2 === null ? "\u2014" : String(value2);
    }
    function getColumns(nextOperation) {
      switch (nextOperation) {
        case "create":
          return [
            {
              key: "custom_format_name",
              header: "Custom Format"
            },
            {
              key: "arr_type",
              header: "Arr",
              width: "w-20"
            },
            {
              key: "after",
              header: "Value",
              width: "w-24"
            }
          ];
        case "delete":
          return [
            {
              key: "custom_format_name",
              header: "Custom Format"
            },
            {
              key: "arr_type",
              header: "Arr",
              width: "w-20"
            },
            {
              key: "before",
              header: "Value",
              width: "w-24"
            }
          ];
        default:
          return [
            {
              key: "custom_format_name",
              header: "Custom Format"
            },
            {
              key: "arr_type",
              header: "Arr",
              width: "w-20"
            },
            {
              key: "before",
              header: "Before",
              width: "w-24"
            },
            {
              key: "after",
              header: "After",
              width: "w-24"
            }
          ];
      }
    }
    $: columns = getColumns(operation);
    Table2($$renderer2, {
      columns,
      data: rows,
      compact: true,
      hoverable: false,
      responsive: true,
      $$slots: { cell: ($$renderer3, { row, column }) => {
        if (column.key === "custom_format_name") {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<span class="text-sm text-neutral-700 dark:text-neutral-200">${escape_html(row.custom_format_name)}</span>`);
        } else if (column.key === "arr_type") {
          $$renderer3.push("<!--[1-->");
          if (row.arr_type === "radarr") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<img${attr("src", Radarr_default)} alt="Radarr" class="h-5 w-5"/>`);
          } else if (row.arr_type === "sonarr") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<img${attr("src", Sonarr_default)} alt="Sonarr" class="h-5 w-5"/>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<span class="text-sm text-neutral-500 dark:text-neutral-400">${escape_html(formatTitle2(row.arr_type))}</span>`);
          }
          $$renderer3.push(`<!--]-->`);
        } else if (column.key === "before") {
          $$renderer3.push("<!--[2-->");
          if (row.before === null) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="text-sm text-neutral-400">\u2014</span>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatValue3(row.before))}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer3.push(`<!--]-->`);
        } else if (column.key === "after") {
          $$renderer3.push("<!--[3-->");
          if (row.after === null) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="text-sm text-neutral-400">\u2014</span>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatValue3(row.after))}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer3.push(`<!--]-->`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]-->`);
      } }
    });
    bind_props($$props, {
      rows,
      operation
    });
  });
}
function OrderedItemsDiff($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let beforeOffset, afterOffset;
    let beforeItems = fallback($$props["beforeItems"], () => [], true);
    let afterItems = fallback($$props["afterItems"], () => [], true);
    let operation = fallback($$props["operation"], "update");
    const columns = [{
      key: "position",
      header: "Pos",
      width: "w-14"
    }, {
      key: "name",
      header: "Name"
    }];
    function formatTitle2(value2) {
      return value2.replace(/[_-]+/g, " ").trim().replace(/\b\w/g, (char) => char.toUpperCase());
    }
    function getPositionOffset(items) {
      if (!items || items.length === 0) return 0;
      return items.reduce((min, item) => Math.min(min, item.position), items[0].position) === 0 ? 1 : 0;
    }
    function formatPosition(position, offset) {
      return position + offset;
    }
    $: beforeOffset = getPositionOffset(beforeItems);
    $: afterOffset = getPositionOffset(afterItems);
    if (operation === "create") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="space-y-2"><div class="text-sm font-medium text-neutral-500 dark:text-neutral-400">Value</div> `);
      Table2($$renderer2, {
        columns,
        data: afterItems,
        compact: true,
        hoverable: false,
        emptyMessage: "\u2014",
        responsive: true,
        $$slots: { cell: ($$renderer3, { row, column }) => {
          if (column.key === "position") {
            $$renderer3.push("<!--[0-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatPosition(row.position, afterOffset))}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "name") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="flex flex-wrap items-center gap-2"><span class="text-sm font-medium text-neutral-700 dark:text-neutral-200">${escape_html(row.name)}</span> <div class="flex flex-wrap gap-1">`);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatTitle2(row.type))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            Badge($$renderer3, {
              variant: row.enabled ? "success" : "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.enabled ? "Enabled" : "Disabled")}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            if (row.upgradeUntil) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "info",
                size: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Upgrade Until`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--> `);
            if (row.members && row.members.length > 0) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "neutral",
                size: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(row.members.map((member) => member.name).join(", "))}`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } }
      });
      $$renderer2.push(`<!----></div>`);
    } else if (operation === "delete") {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<div class="space-y-2"><div class="text-sm font-medium text-neutral-500 dark:text-neutral-400">Value</div> `);
      Table2($$renderer2, {
        columns,
        data: beforeItems,
        compact: true,
        hoverable: false,
        emptyMessage: "\u2014",
        responsive: true,
        $$slots: { cell: ($$renderer3, { row, column }) => {
          if (column.key === "position") {
            $$renderer3.push("<!--[0-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatPosition(row.position, beforeOffset))}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "name") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="flex flex-wrap items-center gap-2"><span class="text-sm font-medium text-neutral-700 dark:text-neutral-200">${escape_html(row.name)}</span> <div class="flex flex-wrap gap-1">`);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatTitle2(row.type))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            Badge($$renderer3, {
              variant: row.enabled ? "success" : "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.enabled ? "Enabled" : "Disabled")}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            if (row.upgradeUntil) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "info",
                size: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Upgrade Until`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--> `);
            if (row.members && row.members.length > 0) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "neutral",
                size: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(row.members.map((member) => member.name).join(", "))}`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } }
      });
      $$renderer2.push(`<!----></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="grid gap-4 md:grid-cols-2"><div class="space-y-2"><div class="text-sm font-medium text-neutral-500 dark:text-neutral-400">Before</div> `);
      Table2($$renderer2, {
        columns,
        data: beforeItems,
        compact: true,
        hoverable: false,
        emptyMessage: "\u2014",
        responsive: true,
        $$slots: { cell: ($$renderer3, { row, column }) => {
          if (column.key === "position") {
            $$renderer3.push("<!--[0-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatPosition(row.position, beforeOffset))}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "name") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="flex flex-wrap items-center gap-2"><span class="text-sm font-medium text-neutral-700 dark:text-neutral-200">${escape_html(row.name)}</span> <div class="flex flex-wrap gap-1">`);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatTitle2(row.type))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            Badge($$renderer3, {
              variant: row.enabled ? "success" : "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.enabled ? "Enabled" : "Disabled")}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            if (row.upgradeUntil) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "info",
                size: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Upgrade Until`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--> `);
            if (row.members && row.members.length > 0) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "neutral",
                size: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(row.members.map((member) => member.name).join(", "))}`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } }
      });
      $$renderer2.push(`<!----></div> <div class="space-y-2"><div class="text-sm font-medium text-neutral-500 dark:text-neutral-400">After</div> `);
      Table2($$renderer2, {
        columns,
        data: afterItems,
        compact: true,
        hoverable: false,
        emptyMessage: "\u2014",
        responsive: true,
        $$slots: { cell: ($$renderer3, { row, column }) => {
          if (column.key === "position") {
            $$renderer3.push("<!--[0-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatPosition(row.position, afterOffset))}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "name") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="flex flex-wrap items-center gap-2"><span class="text-sm font-medium text-neutral-700 dark:text-neutral-200">${escape_html(row.name)}</span> <div class="flex flex-wrap gap-1">`);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatTitle2(row.type))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            Badge($$renderer3, {
              variant: row.enabled ? "success" : "neutral",
              size: "md",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.enabled ? "Enabled" : "Disabled")}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            if (row.upgradeUntil) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "info",
                size: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Upgrade Until`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--> `);
            if (row.members && row.members.length > 0) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "neutral",
                size: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(row.members.map((member) => member.name).join(", "))}`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } }
      });
      $$renderer2.push(`<!----></div></div>`);
    }
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      beforeItems,
      afterItems,
      operation
    });
  });
}
function ConditionsDiffTable($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let rows = fallback($$props["rows"], () => [], true);
    const columns = [
      {
        key: "name",
        header: "Name"
      },
      {
        key: "type",
        header: "Type"
      },
      {
        key: "value",
        header: "Value"
      },
      {
        key: "arr",
        header: "Arr",
        width: "w-20"
      },
      {
        key: "required",
        header: "Required",
        width: "w-20"
      },
      {
        key: "negated",
        header: "Negated",
        width: "w-20"
      }
    ];
    function formatTitle2(value2) {
      return value2.replace(/[_-]+/g, " ").trim().replace(/\b\w/g, (char) => char.toUpperCase());
    }
    function extractConditionValue(values) {
      if (!values) return null;
      const entries = Object.entries(values).filter(([, val]) => {
        if (Array.isArray(val)) return val.length > 0;
        return val !== null && val !== void 0;
      });
      if (entries.length === 0) return null;
      return formatValue3(entries[0][1]);
    }
    function formatValueLabel(raw) {
      const normalized = raw.replace(/_/g, "-").toLowerCase();
      if (normalized === "web-dl" || normalized === "webdl") return "WEBDL";
      if (normalized === "web-rip" || normalized === "webrip") return "WEBRip";
      if (normalized === "blu-ray" || normalized === "bluray") return "Bluray";
      if (normalized === "hdtv") return "HDTV";
      if (normalized === "sd") return "SD";
      return formatTitle2(raw);
    }
    function formatValue3(value2) {
      if (value2 === null || value2 === void 0) return {
        value: "\u2014",
        mono: false
      };
      if (Array.isArray(value2)) {
        if (value2.length === 0) return {
          value: "\u2014",
          mono: false
        };
        const first = value2[0];
        if (first && typeof first === "object") {
          const record = first;
          const name = record.name ? String(record.name) : JSON.stringify(record);
          return {
            value: record.except === true ? `${name} (except)` : name,
            mono: false
          };
        }
        return {
          value: formatValueLabel(String(first)),
          mono: false
        };
      }
      if (typeof value2 === "object") {
        const record = value2;
        if ("minBytes" in record || "maxBytes" in record) return {
          value: `${record.minBytes ?? "\u2014"} -> ${record.maxBytes ?? "\u2014"}`,
          mono: true
        };
        if ("minYear" in record || "maxYear" in record) return {
          value: `${record.minYear ?? "\u2014"} -> ${record.maxYear ?? "\u2014"}`,
          mono: true
        };
        if ("name" in record && record.name != null) return {
          value: String(record.name),
          mono: false
        };
        return {
          value: JSON.stringify(record),
          mono: false
        };
      }
      if (typeof value2 === "number") return {
        value: String(value2),
        mono: true
      };
      return {
        value: formatValueLabel(String(value2)),
        mono: false
      };
    }
    function getConditionField(row, field) {
      return {
        before: row.before?.[field],
        after: row.after?.[field]
      };
    }
    function formatBoolean(value2) {
      if (value2 === void 0) return "\u2014";
      return value2 ? "Yes" : "No";
    }
    function changeBadgeVariant(change) {
      if (change === "added") return "success";
      if (change === "removed") return "danger";
      return "neutral";
    }
    Table2($$renderer2, {
      columns,
      data: rows,
      compact: true,
      hoverable: false,
      responsive: true,
      $$slots: { cell: ($$renderer3, { row, column }) => {
        if (column.key === "name") {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="flex flex-wrap items-center gap-2"><span class="text-sm text-neutral-700 dark:text-neutral-200">${escape_html(row.name)}</span> `);
          Badge($$renderer3, {
            variant: changeBadgeVariant(row.change),
            size: "sm",
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(formatTitle2(row.change))}`);
            },
            $$slots: { default: true }
          });
          $$renderer3.push(`<!----></div>`);
        } else if (column.key === "type") {
          $$renderer3.push("<!--[1-->");
          const change = getConditionField(row, "type");
          if (change.before !== void 0 && change.after !== void 0 && change.before !== change.after) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="text-sm text-neutral-600 dark:text-neutral-300">${escape_html(formatTitle2(String(change.before)))} -> ${escape_html(formatTitle2(String(change.after)))}</span>`);
          } else if (change.after !== void 0 || change.before !== void 0) {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<span class="text-sm text-neutral-600 dark:text-neutral-300">${escape_html(formatTitle2(String(change.after ?? change.before)))}</span>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<span class="text-sm text-neutral-400">\u2014</span>`);
          }
          $$renderer3.push(`<!--]-->`);
        } else if (column.key === "value") {
          $$renderer3.push("<!--[2-->");
          const beforeValue = row.before?.values ? extractConditionValue(row.before.values) : null;
          const afterValue = row.after?.values ? extractConditionValue(row.after.values) : null;
          if (beforeValue && afterValue && beforeValue.value !== afterValue.value) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex flex-wrap items-center gap-1">`);
            Badge($$renderer3, {
              variant: "neutral",
              size: "sm",
              mono: beforeValue.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(beforeValue.value)}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> <span class="text-neutral-400">-></span> `);
            Badge($$renderer3, {
              variant: "neutral",
              size: "sm",
              mono: afterValue.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(afterValue.value)}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----></div>`);
          } else if (afterValue || beforeValue) {
            $$renderer3.push("<!--[1-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "sm",
              mono: (afterValue ?? beforeValue)?.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html((afterValue ?? beforeValue)?.value)}`);
              },
              $$slots: { default: true }
            });
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<span class="text-sm text-neutral-400">\u2014</span>`);
          }
          $$renderer3.push(`<!--]-->`);
        } else if (column.key === "arr") {
          $$renderer3.push("<!--[3-->");
          const change = getConditionField(row, "arrType");
          const before = change.before;
          const after = change.after;
          if (before && after && before !== after) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex items-center gap-1">`);
            if (before === "all") {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="flex items-center gap-1"><img${attr("src", Radarr_default)} alt="Radarr" class="h-4 w-4"/> <img${attr("src", Sonarr_default)} alt="Sonarr" class="h-4 w-4"/></div>`);
            } else if (before === "radarr") {
              $$renderer3.push("<!--[1-->");
              $$renderer3.push(`<img${attr("src", Radarr_default)} alt="Radarr" class="h-4 w-4"/>`);
            } else if (before === "sonarr") {
              $$renderer3.push("<!--[2-->");
              $$renderer3.push(`<img${attr("src", Sonarr_default)} alt="Sonarr" class="h-4 w-4"/>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              Badge($$renderer3, {
                variant: "neutral",
                size: "sm",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(formatTitle2(before))}`);
                },
                $$slots: { default: true }
              });
            }
            $$renderer3.push(`<!--]--> <span class="text-neutral-400">-></span> `);
            if (after === "all") {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="flex items-center gap-1"><img${attr("src", Radarr_default)} alt="Radarr" class="h-4 w-4"/> <img${attr("src", Sonarr_default)} alt="Sonarr" class="h-4 w-4"/></div>`);
            } else if (after === "radarr") {
              $$renderer3.push("<!--[1-->");
              $$renderer3.push(`<img${attr("src", Radarr_default)} alt="Radarr" class="h-4 w-4"/>`);
            } else if (after === "sonarr") {
              $$renderer3.push("<!--[2-->");
              $$renderer3.push(`<img${attr("src", Sonarr_default)} alt="Sonarr" class="h-4 w-4"/>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              Badge($$renderer3, {
                variant: "neutral",
                size: "sm",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(formatTitle2(after))}`);
                },
                $$slots: { default: true }
              });
            }
            $$renderer3.push(`<!--]--></div>`);
          } else if (after === "all" || before === "all") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="flex items-center gap-1"><img${attr("src", Radarr_default)} alt="Radarr" class="h-4 w-4"/> <img${attr("src", Sonarr_default)} alt="Sonarr" class="h-4 w-4"/></div>`);
          } else if ((after ?? before) === "radarr") {
            $$renderer3.push("<!--[2-->");
            $$renderer3.push(`<img${attr("src", Radarr_default)} alt="Radarr" class="h-5 w-5"/>`);
          } else if ((after ?? before) === "sonarr") {
            $$renderer3.push("<!--[3-->");
            $$renderer3.push(`<img${attr("src", Sonarr_default)} alt="Sonarr" class="h-5 w-5"/>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatTitle2(String(after ?? before ?? "")))}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer3.push(`<!--]-->`);
        } else if (column.key === "required") {
          $$renderer3.push("<!--[4-->");
          const change = getConditionField(row, "required");
          if (change.before !== void 0 && change.after !== void 0 && change.before !== change.after) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex items-center gap-1 text-xs">`);
            Badge($$renderer3, {
              variant: change.before ? "success" : "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatBoolean(change.before))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> <span class="text-neutral-400">-></span> `);
            Badge($$renderer3, {
              variant: change.after ? "success" : "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatBoolean(change.after))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----></div>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            Badge($$renderer3, {
              variant: change.after ?? change.before ? "success" : "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatBoolean(change.after ?? change.before))}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer3.push(`<!--]-->`);
        } else if (column.key === "negated") {
          $$renderer3.push("<!--[5-->");
          const change = getConditionField(row, "negate");
          if (change.before !== void 0 && change.after !== void 0 && change.before !== change.after) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex items-center gap-1 text-xs">`);
            Badge($$renderer3, {
              variant: change.before ? "success" : "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatBoolean(change.before))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> <span class="text-neutral-400">-></span> `);
            Badge($$renderer3, {
              variant: change.after ? "success" : "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatBoolean(change.after))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----></div>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            Badge($$renderer3, {
              variant: change.after ?? change.before ? "success" : "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatBoolean(change.after ?? change.before))}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer3.push(`<!--]-->`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]-->`);
      } }
    });
    bind_props($$props, { rows });
  });
}
function TestsDiffTable($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let rows = fallback($$props["rows"], () => [], true);
    const columns = [
      {
        key: "name",
        header: "Name"
      },
      {
        key: "type",
        header: "Type",
        width: "w-28"
      },
      {
        key: "match",
        header: "Match",
        width: "w-40"
      },
      {
        key: "description",
        header: "Description"
      }
    ];
    function formatTitle2(value2) {
      return value2.replace(/[_-]+/g, " ").trim().replace(/\b\w/g, (char) => char.toUpperCase());
    }
    function formatTypeLabel(value2) {
      if (!value2) return "\u2014";
      const normalized = value2.toLowerCase();
      if (normalized === "movie") return "Movie";
      if (normalized === "series") return "Series";
      return formatTitle2(value2);
    }
    function formatBoolean(value2) {
      if (value2 === void 0) return "\u2014";
      return value2 ? "Should match" : "Should not match";
    }
    function getField(row, field) {
      return {
        before: row.before?.[field],
        after: row.after?.[field]
      };
    }
    function parseMarkdown2(text2) {
      return sanitizeHtml(g2.parse(text2));
    }
    function changeBadgeVariant(change) {
      if (change === "added") return "success";
      if (change === "removed") return "danger";
      return "neutral";
    }
    Table2($$renderer2, {
      columns,
      data: rows,
      compact: true,
      hoverable: false,
      responsive: true,
      $$slots: { cell: ($$renderer3, { row, column }) => {
        if (column.key === "name") {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="flex flex-wrap items-center gap-2"><span class="text-sm text-neutral-700 dark:text-neutral-200">${escape_html(row.name)}</span> `);
          Badge($$renderer3, {
            variant: changeBadgeVariant(row.change),
            size: "sm",
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(formatTitle2(row.change))}`);
            },
            $$slots: { default: true }
          });
          $$renderer3.push(`<!----></div>`);
        } else if (column.key === "type") {
          $$renderer3.push("<!--[1-->");
          const change = getField(row, "type");
          if (change.before !== void 0 && change.after !== void 0 && change.before !== change.after) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex flex-wrap items-center gap-1">`);
            Badge($$renderer3, {
              variant: "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatTypeLabel(change.before))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> <span class="text-neutral-400">-></span> `);
            Badge($$renderer3, {
              variant: "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatTypeLabel(change.after))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----></div>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            Badge($$renderer3, {
              variant: "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatTypeLabel(change.after ?? change.before))}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer3.push(`<!--]-->`);
        } else if (column.key === "match") {
          $$renderer3.push("<!--[2-->");
          const change = getField(row, "shouldMatch");
          if (change.before !== void 0 && change.after !== void 0 && change.before !== change.after) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex flex-wrap items-center gap-1">`);
            Badge($$renderer3, {
              variant: change.before ? "success" : "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatBoolean(change.before))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> <span class="text-neutral-400">-></span> `);
            Badge($$renderer3, {
              variant: change.after ? "success" : "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatBoolean(change.after))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----></div>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            Badge($$renderer3, {
              variant: change.after ?? change.before ? "success" : "neutral",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatBoolean(change.after ?? change.before))}`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer3.push(`<!--]-->`);
        } else if (column.key === "description") {
          $$renderer3.push("<!--[3-->");
          const change = getField(row, "description");
          if (change.before !== void 0 && change.after !== void 0 && change.before !== change.after) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="space-y-2"><div><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Before</div> <div class="prose prose-sm prose-neutral dark:prose-invert text-sm">${html(parseMarkdown2(String(change.before ?? "")))}</div></div> <div><div class="text-xs font-medium text-neutral-500 dark:text-neutral-400">After</div> <div class="prose prose-sm prose-neutral dark:prose-invert text-sm">${html(parseMarkdown2(String(change.after ?? "")))}</div></div></div>`);
          } else if (change.after !== void 0 || change.before !== void 0) {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="prose prose-sm prose-neutral dark:prose-invert text-sm">${html(parseMarkdown2(String(change.after ?? change.before ?? "")))}</div>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<span class="text-sm text-neutral-400">\u2014</span>`);
          }
          $$renderer3.push(`<!--]-->`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]-->`);
      } }
    });
    bind_props($$props, { rows });
  });
}
function QualityDefinitionEntriesTable($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let valueEntries;
    let beforeEntries = fallback($$props["beforeEntries"], () => [], true);
    let afterEntries = fallback($$props["afterEntries"], () => [], true);
    let operation = fallback($$props["operation"], "update");
    const columns = [
      {
        key: "quality_name",
        header: "Quality"
      },
      {
        key: "min_size",
        header: "Min",
        width: "w-24"
      },
      {
        key: "preferred_size",
        header: "Preferred",
        width: "w-28"
      },
      {
        key: "max_size",
        header: "Max",
        width: "w-24"
      }
    ];
    function formatValue3(value2) {
      if (value2 === null || value2 === void 0) return "\u2014";
      return String(value2);
    }
    function isUnlimitedColumn(columnKey) {
      return columnKey === "preferred_size" || columnKey === "max_size";
    }
    function renderSizeBadge(value2, columnKey) {
      if (value2 === null || value2 === void 0) return {
        text: "\u2014",
        mono: false
      };
      if (value2 === 0 && isUnlimitedColumn(columnKey)) return {
        text: "Unlimited",
        mono: false
      };
      return {
        text: formatValue3(value2),
        mono: true
      };
    }
    $: valueEntries = operation === "delete" ? beforeEntries.length > 0 ? beforeEntries : afterEntries : afterEntries;
    if (operation === "create" || operation === "delete") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="space-y-2"><div class="text-sm font-medium text-neutral-500 dark:text-neutral-400">Value</div> `);
      Table2($$renderer2, {
        columns,
        data: valueEntries,
        compact: true,
        hoverable: false,
        emptyMessage: "\u2014",
        responsive: true,
        $$slots: { cell: ($$renderer3, { row, column }) => {
          if (column.key === "quality_name") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="text-sm text-neutral-700 dark:text-neutral-200">${escape_html(row.quality_name)}</span>`);
          } else if (column.key === "min_size") {
            $$renderer3.push("<!--[1-->");
            const display = renderSizeBadge(row.min_size, column.key);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: display.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(display.text)}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "preferred_size") {
            $$renderer3.push("<!--[2-->");
            const display = renderSizeBadge(row.preferred_size, column.key);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: display.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(display.text)}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "max_size") {
            $$renderer3.push("<!--[3-->");
            const display = renderSizeBadge(row.max_size, column.key);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: display.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(display.text)}`);
              },
              $$slots: { default: true }
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } }
      });
      $$renderer2.push(`<!----></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="grid gap-4 md:grid-cols-2"><div class="space-y-2"><div class="text-sm font-medium text-neutral-500 dark:text-neutral-400">Before</div> `);
      Table2($$renderer2, {
        columns,
        data: beforeEntries,
        compact: true,
        hoverable: false,
        emptyMessage: "\u2014",
        responsive: true,
        $$slots: { cell: ($$renderer3, { row, column }) => {
          if (column.key === "quality_name") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="text-sm text-neutral-700 dark:text-neutral-200">${escape_html(row.quality_name)}</span>`);
          } else if (column.key === "min_size") {
            $$renderer3.push("<!--[1-->");
            const display = renderSizeBadge(row.min_size, column.key);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: display.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(display.text)}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "preferred_size") {
            $$renderer3.push("<!--[2-->");
            const display = renderSizeBadge(row.preferred_size, column.key);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: display.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(display.text)}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "max_size") {
            $$renderer3.push("<!--[3-->");
            const display = renderSizeBadge(row.max_size, column.key);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: display.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(display.text)}`);
              },
              $$slots: { default: true }
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } }
      });
      $$renderer2.push(`<!----></div> <div class="space-y-2"><div class="text-sm font-medium text-neutral-500 dark:text-neutral-400">After</div> `);
      Table2($$renderer2, {
        columns,
        data: afterEntries,
        compact: true,
        hoverable: false,
        emptyMessage: "\u2014",
        responsive: true,
        $$slots: { cell: ($$renderer3, { row, column }) => {
          if (column.key === "quality_name") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="text-sm text-neutral-700 dark:text-neutral-200">${escape_html(row.quality_name)}</span>`);
          } else if (column.key === "min_size") {
            $$renderer3.push("<!--[1-->");
            const display = renderSizeBadge(row.min_size, column.key);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: display.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(display.text)}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "preferred_size") {
            $$renderer3.push("<!--[2-->");
            const display = renderSizeBadge(row.preferred_size, column.key);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: display.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(display.text)}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "max_size") {
            $$renderer3.push("<!--[3-->");
            const display = renderSizeBadge(row.max_size, column.key);
            Badge($$renderer3, {
              variant: "neutral",
              size: "md",
              mono: display.mono,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(display.text)}`);
              },
              $$slots: { default: true }
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } }
      });
      $$renderer2.push(`<!----></div></div>`);
    }
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      beforeEntries,
      afterEntries,
      operation
    });
  });
}
function SectionRenderer($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let sections = fallback($$props["sections"], () => [], true);
    let operation = fallback($$props["operation"], "update");
    function hasRows(rows, kind) {
      return rows.some((row) => row.kind === kind);
    }
    function getRows(rows, kind) {
      return rows.filter((row) => row.kind === kind);
    }
    function getNonTagFieldRows(rows) {
      return getRows(rows, "field").filter((row) => row.field !== "tags");
    }
    function getTagsRow(rows) {
      return getRows(rows, "field").find((row) => row.field === "tags") ?? null;
    }
    $$renderer2.push(`<div class="space-y-5"><!--[-->`);
    const each_array = ensure_array_like(sections);
    for (let $$index_5 = 0, $$length = each_array.length; $$index_5 < $$length; $$index_5++) {
      let section = each_array[$$index_5];
      $$renderer2.push(`<div class="space-y-3"><div class="text-sm font-semibold text-neutral-500 dark:text-neutral-400">${escape_html(section.title)}</div> `);
      if (hasRows(section.rows, "field")) {
        $$renderer2.push("<!--[0-->");
        const fieldRows = getNonTagFieldRows(section.rows);
        const tagsRow = getTagsRow(section.rows);
        if (fieldRows.length > 0) {
          $$renderer2.push("<!--[0-->");
          FieldDiffTable($$renderer2, {
            rows: fieldRows,
            operation
          });
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]--> `);
        if (tagsRow) {
          $$renderer2.push("<!--[0-->");
          $$renderer2.push(`<div class="space-y-2"><div class="text-sm font-medium text-neutral-600 dark:text-neutral-300">Tags</div> `);
          TagsDiffTable($$renderer2, {
            removed: (tagsRow.remove ?? []).map((tag2) => String(tag2)),
            added: (tagsRow.add ?? []).map((tag2) => String(tag2)),
            operation
          });
          $$renderer2.push(`<!----></div>`);
        } else $$renderer2.push("<!--[-1-->");
        $$renderer2.push(`<!--]-->`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> `);
      if (hasRows(section.rows, "custom_format_scores")) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<!--[-->`);
        const each_array_1 = ensure_array_like(getRows(section.rows, "custom_format_scores"));
        for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
          let scoreRow = each_array_1[$$index];
          $$renderer2.push(`<div class="space-y-2"><div class="text-sm font-medium text-neutral-600 dark:text-neutral-300">${escape_html(scoreRow.label)}</div> `);
          CustomFormatScoresTable($$renderer2, {
            rows: scoreRow.rows,
            operation
          });
          $$renderer2.push(`<!----></div>`);
        }
        $$renderer2.push(`<!--]-->`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> `);
      if (hasRows(section.rows, "conditions")) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<!--[-->`);
        const each_array_2 = ensure_array_like(getRows(section.rows, "conditions"));
        for (let $$index_1 = 0, $$length2 = each_array_2.length; $$index_1 < $$length2; $$index_1++) {
          let conditionsRow = each_array_2[$$index_1];
          $$renderer2.push(`<div class="space-y-2">`);
          ConditionsDiffTable($$renderer2, { rows: conditionsRow.rows });
          $$renderer2.push(`<!----></div>`);
        }
        $$renderer2.push(`<!--]-->`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> `);
      if (hasRows(section.rows, "tests")) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<!--[-->`);
        const each_array_3 = ensure_array_like(getRows(section.rows, "tests"));
        for (let $$index_2 = 0, $$length2 = each_array_3.length; $$index_2 < $$length2; $$index_2++) {
          let testsRow = each_array_3[$$index_2];
          $$renderer2.push(`<div class="space-y-2">`);
          TestsDiffTable($$renderer2, { rows: testsRow.rows });
          $$renderer2.push(`<!----></div>`);
        }
        $$renderer2.push(`<!--]-->`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> `);
      if (hasRows(section.rows, "ordered_items")) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<!--[-->`);
        const each_array_4 = ensure_array_like(getRows(section.rows, "ordered_items"));
        for (let $$index_3 = 0, $$length2 = each_array_4.length; $$index_3 < $$length2; $$index_3++) {
          let itemsRow = each_array_4[$$index_3];
          OrderedItemsDiff($$renderer2, {
            beforeItems: itemsRow.beforeItems ?? [],
            afterItems: itemsRow.afterItems ?? [],
            operation
          });
        }
        $$renderer2.push(`<!--]-->`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> `);
      if (hasRows(section.rows, "quality_definition_entries")) {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<!--[-->`);
        const each_array_5 = ensure_array_like(getRows(section.rows, "quality_definition_entries"));
        for (let $$index_4 = 0, $$length2 = each_array_5.length; $$index_4 < $$length2; $$index_4++) {
          let entriesRow = each_array_5[$$index_4];
          QualityDefinitionEntriesTable($$renderer2, {
            beforeEntries: entriesRow.beforeEntries ?? [],
            afterEntries: entriesRow.afterEntries ?? [],
            operation
          });
        }
        $$renderer2.push(`<!--]-->`);
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--></div>`);
    }
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, {
      sections,
      operation
    });
  });
}
function QualityProfileDiff($$renderer, $$props) {
  let sections = fallback($$props["sections"], () => [], true);
  let operation = fallback($$props["operation"], "update");
  SectionRenderer($$renderer, {
    sections,
    operation
  });
  bind_props($$props, {
    sections,
    operation
  });
}
function ActionInput($$renderer, $$props) {
  let value2 = fallback($$props["value"], "");
  let placeholder = fallback($$props["placeholder"], "");
  let disabled = fallback($$props["disabled"], false);
  let mono = fallback($$props["mono"], false);
  let icon = fallback($$props["icon"], null);
  $$renderer.push(`<div${attr_class(`relative flex h-10 w-full items-center rounded-xl border border-neutral-300 bg-white transition-colors dark:border-neutral-700/60 dark:bg-neutral-800/50 ${disabled ? "cursor-not-allowed opacity-50" : ""}`)}>`);
  if (icon) {
    $$renderer.push("<!--[0-->");
    $$renderer.push(`<div class="pointer-events-none absolute left-3 flex items-center">`);
    if (icon) {
      $$renderer.push("<!--[-->");
      icon($$renderer, {
        size: 18,
        class: "text-neutral-500 dark:text-neutral-400"
      });
      $$renderer.push("<!--]-->");
    } else {
      $$renderer.push("<!--[!-->");
      $$renderer.push("<!--]-->");
    }
    $$renderer.push(`</div>`);
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--> <input type="text"${attr("value", value2)}${attr("placeholder", placeholder)}${attr("disabled", disabled, true)}${attr_class(`h-full w-full bg-transparent text-sm text-neutral-900 placeholder-neutral-400 outline-none disabled:cursor-not-allowed dark:text-neutral-100 dark:placeholder-neutral-500 ${mono ? "font-mono" : ""} ${icon ? "pr-3 pl-10" : "px-3"}`)}/></div>`);
  bind_props($$props, {
    value: value2,
    placeholder,
    disabled,
    mono,
    icon
  });
}
function _page28($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let isDeveloper, hasIncomingChanges, selectableChanges, selectableKeys, selectedPrimaryCount, allSelected, primaryKeys, selectedChanges, allQuiet, changeByKey, groupMap, dependencyMap, autoSelectedKeys;
    let data = $$props["data"];
    let loading = true;
    let pulling = false;
    let incomingChanges = null;
    let draftChanges = [];
    let primarySelected = /* @__PURE__ */ new Set();
    let selected = /* @__PURE__ */ new Set();
    let commitMessage = "";
    let committing = false;
    let dropping = false;
    let showDropModal = false;
    let showPreviewModal = false;
    let previewConfirmDisabled = true;
    async function fetchChanges() {
      loading = true;
      try {
        const response = await fetch(`/databases/${data.database.id}/changes/data`);
        if (response.ok) {
          const result = await response.json();
          result.status;
          incomingChanges = result.incomingChanges;
          draftChanges = result.draftChanges || [];
        }
      } finally {
        loading = false;
      }
    }
    afterNavigate(() => {
      fetchChanges();
    });
    function toggleRow(key2) {
      const change = changeByKey.get(key2);
      if (!change || change.generated) return;
      const groupKeys = getSelectableGroupKeys(change, groupMap);
      const newSelected = new Set(primarySelected);
      const isSelected = groupKeys.some((groupKey) => newSelected.has(groupKey));
      for (const groupKey of groupKeys) if (isSelected) newSelected.delete(groupKey);
      else newSelected.add(groupKey);
      if (!isSelected) {
        const expanded = expandSelection(newSelected);
        const primaryAdded = new Set(groupKeys);
        const autoAddedDetails = Array.from(expanded).filter((expandedKey) => !selected.has(expandedKey) && !primaryAdded.has(expandedKey)).map((depKey) => changeByKey.get(depKey)).filter((dep) => Boolean(dep) && !dep.generated);
        if (autoAddedDetails.length > 0) {
          const label = autoAddedDetails.map((dep) => `${formatEntity3(dep.entity)} "${dep.name}"`).join(", ");
          const noun = autoAddedDetails.length === 1 ? "dependency" : "dependencies";
          alertStore.add("info", `Auto-selected ${autoAddedDetails.length} ${noun}: ${label}`);
        }
      }
      primarySelected = newSelected;
    }
    function collectOpIds() {
      const opIds = /* @__PURE__ */ new Set();
      for (const change of selectedChanges) for (const op of change.ops) opIds.add(op.id);
      return Array.from(opIds).sort((a2, b3) => a2 - b3);
    }
    function collectFilePaths() {
      return selectedChanges.map((change) => change.path).filter((path) => typeof path === "string" && path.length > 0);
    }
    function buildSelectionKey(opIds) {
      return [...opIds].sort((a2, b3) => a2 - b3).join(",");
    }
    function buildGroupMap(changes) {
      const map2 = /* @__PURE__ */ new Map();
      for (const change of changes) {
        if (!change.groupId) continue;
        const list5 = map2.get(change.groupId) ?? [];
        list5.push(change.key);
        map2.set(change.groupId, list5);
      }
      return map2;
    }
    function getGroupKeys(change, map2) {
      if (!change.groupId) return [change.key];
      return map2.get(change.groupId) ?? [change.key];
    }
    function getSelectableGroupKeys(change, map2) {
      return getGroupKeys(change, map2).filter((key2) => {
        const entry = changeByKey.get(key2);
        return entry && !entry.generated;
      });
    }
    function buildDependencyMap(changes) {
      const map2 = /* @__PURE__ */ new Map();
      for (const change of changes) {
        if (!change.requires || change.requires.length === 0) continue;
        map2.set(change.key, change.requires.map((requirement) => requirement.key));
      }
      return map2;
    }
    function expandSelection(keys) {
      const expanded = /* @__PURE__ */ new Set();
      const queue = Array.from(keys);
      while (queue.length > 0) {
        const key2 = queue.pop();
        if (!key2 || expanded.has(key2)) continue;
        expanded.add(key2);
        const change = changeByKey.get(key2);
        if (!change) continue;
        for (const groupKey of getGroupKeys(change, groupMap)) if (!expanded.has(groupKey)) queue.push(groupKey);
        const deps = dependencyMap.get(key2) ?? [];
        for (const depKey of deps) if (!expanded.has(depKey)) queue.push(depKey);
      }
      return expanded;
    }
    function buildAutoSelectedKeys(currentSelected, primaryKeys2) {
      const autoSelected = /* @__PURE__ */ new Set();
      for (const key2 of currentSelected) if (!primaryKeys2.has(key2)) autoSelected.add(key2);
      return autoSelected;
    }
    function formatTitle2(value2) {
      return value2.replace(/[_-]+/g, " ").trim().replace(/\b\w/g, (char) => char.toUpperCase());
    }
    function formatOperation(op) {
      if (!op) return "-";
      return formatTitle2(op);
    }
    function getOperationClass(op) {
      switch (op) {
        case "create":
          return "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200";
        case "update":
          return "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200";
        case "delete":
          return "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200";
        default:
          return "bg-neutral-100 text-neutral-800 dark:bg-neutral-800 dark:text-neutral-200";
      }
    }
    function formatEntity3(entity) {
      if (!entity) return "-";
      return formatTitle2(entity);
    }
    function parseDate(dateStr) {
      const parsed = parseUTC(dateStr) ?? new Date(dateStr);
      if (Number.isNaN(parsed.getTime())) return null;
      return parsed;
    }
    function getDateSortValue(dateStr) {
      const parsed = parseDate(dateStr);
      return parsed ? parsed.getTime() : Number.NEGATIVE_INFINITY;
    }
    function fmtDate(dateStr) {
      const date = parseDate(dateStr);
      if (!date) return "-";
      const diffMs = (/* @__PURE__ */ new Date()).getTime() - date.getTime();
      const diffDays = Math.floor(diffMs / 864e5);
      if (diffMs < 0) return formatDate(dateStr, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat));
      if (diffDays === 0) {
        const diffHours = Math.floor(diffMs / 36e5);
        if (diffHours === 0) return `${Math.floor(diffMs / 6e4)}m ago`;
        return `${diffHours}h ago`;
      }
      if (diffDays === 1) return "Yesterday";
      if (diffDays < 7) return `${diffDays}d ago`;
      return formatDate(dateStr, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat));
    }
    function getCommitUrl(hash4) {
      return `${data.database.repository_url}/commit/${hash4}`;
    }
    const incomingColumns = [
      {
        key: "shortHash",
        header: "Commit",
        width: "w-24"
      },
      {
        key: "message",
        header: "Message"
      },
      {
        key: "author",
        header: "Author",
        width: "w-40"
      },
      {
        key: "date",
        header: "Date",
        width: "w-28",
        align: "right",
        sortable: true,
        sortAccessor: (row) => getDateSortValue(row.date)
      }
    ];
    const outgoingColumns = [
      {
        key: "select",
        header: "",
        width: "w-12",
        align: "center",
        hideOnMobile: true
      },
      {
        key: "operation",
        header: "Operation",
        width: "w-28"
      },
      {
        key: "entity",
        header: "Entity",
        width: "w-36"
      },
      {
        key: "name",
        header: "Name"
      },
      {
        key: "summary",
        header: "Summary"
      },
      {
        key: "updatedAt",
        header: "Updated",
        width: "w-28",
        align: "right"
      }
    ];
    $: isDeveloper = data.isDeveloper;
    $: hasIncomingChanges = incomingChanges?.hasUpdates ?? false;
    $: selectableChanges = draftChanges.filter((change) => !change.generated);
    $: selectableKeys = selectableChanges.map((change) => change.key);
    $: selectedPrimaryCount = selectableKeys.filter((key2) => primarySelected.has(key2)).length;
    $: selected = expandSelection(primarySelected);
    $: Array.from(selected).length;
    $: allSelected = selectableKeys.length > 0 && selectedPrimaryCount === selectableKeys.length;
    $: primaryKeys = Array.from(primarySelected);
    $: Array.from(selected);
    $: selectedChanges = draftChanges.filter((change) => selected.has(change.key));
    $: buildSelectionKey(collectOpIds()) + "" + collectFilePaths().sort().join(",");
    $: previewConfirmDisabled = true;
    $: collectOpIds().length;
    $: allQuiet = !loading && draftChanges.length === 0 && !hasIncomingChanges;
    $: changeByKey = new Map(draftChanges.map((change) => [change.key, change]));
    $: groupMap = buildGroupMap(draftChanges);
    $: dependencyMap = buildDependencyMap(draftChanges);
    $: autoSelectedKeys = buildAutoSelectedKeys(selected, primarySelected);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.database.name} \xB7 Changes` });
      $$renderer3.push(`<!----> `);
      if (allQuiet) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="mt-6 flex h-[calc(100vh-12rem)] flex-col items-center justify-center text-center"><img${attr("src", goOnGit_default)} alt="Go on, git!" class="mb-4 w-64 rounded-lg"/> <p class="text-sm text-neutral-400 dark:text-neutral-500">No changes to pull or publish right now.</p></div>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<div class="mt-6 space-y-6">`);
        if (isDeveloper) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<section><div class="mb-3 flex items-center gap-2"><h2 class="flex items-center gap-2 text-lg font-semibold text-neutral-900 dark:text-neutral-100">`);
          Send($$renderer3, { size: 20 });
          $$renderer3.push(`<!----> Outgoing Changes</h2> `);
          if (draftChanges.length > 0) {
            $$renderer3.push("<!--[0-->");
            Label($$renderer3, {
              variant: "info",
              size: "sm",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(draftChanges.length)}`);
              },
              $$slots: { default: true }
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--></div> `);
          if (loading) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="mb-4 animate-pulse rounded-lg border border-neutral-200 bg-white p-4 dark:border-neutral-700 dark:bg-neutral-800"><div class="flex items-center gap-4"><div class="h-9 w-48 rounded-md bg-neutral-200 dark:bg-neutral-700"></div> <div class="h-9 w-24 rounded-md bg-neutral-200 dark:bg-neutral-700"></div> <div class="h-9 w-24 rounded-md bg-neutral-200 dark:bg-neutral-700"></div></div></div>`);
          } else if (draftChanges.length > 0) {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="mb-4">`);
            ActionsBar($$renderer3, {
              className: "w-full",
              children: ($$renderer4) => {
                $$renderer4.push(`<div>`);
                ActionButton($$renderer4, {
                  square: false,
                  children: ($$renderer5) => {
                    $$renderer5.push(`<div class="flex items-center gap-2 text-sm font-medium text-neutral-700 dark:text-neutral-300">`);
                    IconCheckbox($$renderer5, {
                      checked: allSelected,
                      icon: Check,
                      color: "blue",
                      shape: "circle"
                    });
                    $$renderer5.push(`<!----> Select all (${escape_html(selectableKeys.length)})</div>`);
                  },
                  $$slots: { default: true }
                });
                $$renderer4.push(`<!----></div> <div class="flex-1">`);
                ActionInput($$renderer4, {
                  placeholder: hasIncomingChanges ? "Pull incoming changes first..." : "Commit message...",
                  disabled: hasIncomingChanges,
                  mono: true,
                  get value() {
                    return commitMessage;
                  },
                  set value($$value) {
                    commitMessage = $$value;
                    $$settled = false;
                  }
                });
                $$renderer4.push(`<!----></div> <div>`);
                ActionButton($$renderer4, {
                  icon: Upload,
                  iconClass: "",
                  title: "Preview export",
                  disabled: hasIncomingChanges || committing
                });
                $$renderer4.push(`<!----></div> <div class="flex">`);
                ActionButton($$renderer4, {
                  icon: Trash_2,
                  variant: "danger",
                  title: "Drop selected changes",
                  disabled: dropping
                });
                $$renderer4.push(`<!----></div>`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          ExpandableTable($$renderer3, {
            loading,
            columns: outgoingColumns,
            data: draftChanges,
            getRowId: (row) => row.key,
            emptyMessage: "Nothing to ship - go break something, then come back.",
            responsive: true,
            chevronPosition: "right",
            expandOnRowClick: false,
            flushExpanded: true,
            onRowClick: (row) => toggleRow(row.key),
            primaryColumnKey: "name",
            disableExpandWhen: (row) => row.operation === "delete",
            $$slots: {
              cell: ($$renderer4, { row, column }) => {
                if (column.key === "select") {
                  $$renderer4.push("<!--[0-->");
                  if (row.generated) {
                    $$renderer4.push("<!--[0-->");
                    $$renderer4.push(`<span class="inline-block h-5 w-5"></span>`);
                  } else {
                    $$renderer4.push("<!--[-1-->");
                    IconCheckbox($$renderer4, {
                      checked: selected.has(row.key),
                      icon: Check,
                      color: autoSelectedKeys.has(row.key) ? "#f59e0b" : "blue",
                      variant: autoSelectedKeys.has(row.key) ? "filled" : "filled",
                      shape: "circle",
                      stopPropagation: true,
                      title: autoSelectedKeys.has(row.key) ? "Auto-selected (required by other changes)" : "Selected"
                    });
                  }
                  $$renderer4.push(`<!--]-->`);
                } else if (column.key === "operation") {
                  $$renderer4.push("<!--[1-->");
                  $$renderer4.push(`<span${attr_class(`inline-flex rounded px-2 py-0.5 font-mono text-xs ${stringify(getOperationClass(row.operation))}`)}>${escape_html(formatOperation(row.operation))}</span>`);
                } else if (column.key === "entity") {
                  $$renderer4.push("<!--[2-->");
                  $$renderer4.push(`<span class="text-sm text-neutral-700 dark:text-neutral-300">${escape_html(formatEntity3(row.entity))}</span>`);
                } else if (column.key === "summary") {
                  $$renderer4.push("<!--[3-->");
                  $$renderer4.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(row.summary)}</span>`);
                } else if (column.key === "name") {
                  $$renderer4.push("<!--[4-->");
                  $$renderer4.push(`<div class="flex flex-col gap-1"><span class="text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(row.name)}</span> `);
                  if (row.requires && row.requires.length > 0) {
                    $$renderer4.push("<!--[0-->");
                    $$renderer4.push(`<span class="text-xs text-neutral-500 dark:text-neutral-400">Requires: 
										${escape_html(row.requires.map((requirement) => `${formatEntity3(requirement.entity)} "${requirement.name}"`).join(", "))}</span>`);
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--></div>`);
                } else if (column.key === "updatedAt") {
                  $$renderer4.push("<!--[5-->");
                  $$renderer4.push(`<span class="font-mono text-xs text-neutral-500 dark:text-neutral-400">${escape_html(fmtDate(row.updatedAt))}</span>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]-->`);
              },
              expanded: ($$renderer4, { row }) => {
                $$renderer4.push(`<div class="px-4 py-3 md:px-6 md:py-4">`);
                if (row.entity === "quality_profile") {
                  $$renderer4.push("<!--[0-->");
                  QualityProfileDiff($$renderer4, {
                    sections: row.sections,
                    operation: row.operation
                  });
                } else {
                  $$renderer4.push("<!--[-1-->");
                  SectionRenderer($$renderer4, {
                    sections: row.sections,
                    operation: row.operation
                  });
                }
                $$renderer4.push(`<!--]--></div>`);
              }
            }
          });
          $$renderer3.push(`<!----></section>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> <section><div class="mb-3 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between"><div class="flex items-center gap-2"><h2 class="flex items-center gap-2 text-lg font-semibold text-neutral-900 dark:text-neutral-100">`);
        Download($$renderer3, { size: 20 });
        $$renderer3.push(`<!----> Incoming Changes</h2> `);
        if (incomingChanges?.hasUpdates && incomingChanges.commitsBehind > 0) {
          $$renderer3.push("<!--[0-->");
          Label($$renderer3, {
            variant: "warning",
            size: "sm",
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(incomingChanges.commitsBehind)}`);
            },
            $$slots: { default: true }
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div> `);
        if (incomingChanges?.hasUpdates) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="w-full sm:w-auto">`);
          Button($$renderer3, {
            text: `Pull ${incomingChanges.commitsBehind} commit${incomingChanges.commitsBehind === 1 ? "" : "s"}`,
            variant: "secondary",
            icon: Git_pull_request_create_arrow,
            iconColor: "text-blue-500 dark:text-blue-400",
            loading: pulling,
            disabled: pulling,
            fullWidth: true
          });
          $$renderer3.push(`<!----></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div> `);
        if (loading) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="overflow-hidden rounded-lg border border-neutral-200 dark:border-neutral-800"><div class="animate-pulse p-8"><div class="h-4 w-48 rounded bg-neutral-200 dark:bg-neutral-700"></div></div></div>`);
        } else if (!incomingChanges?.hasUpdates) {
          $$renderer3.push("<!--[1-->");
          $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-neutral-50 px-4 py-3 dark:border-neutral-800 dark:bg-neutral-900"><p class="text-sm text-neutral-500 dark:text-neutral-400">`);
          if (data.database.auto_pull) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`All caught up. Auto-pull will grab updates for you.`);
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`All caught up. Nothing new from the remote.`);
          }
          $$renderer3.push(`<!--]--></p></div>`);
        } else {
          $$renderer3.push("<!--[-1-->");
          ExpandableTable($$renderer3, {
            columns: incomingColumns,
            data: incomingChanges.commits,
            getRowId: (row) => row.hash,
            emptyMessage: "No incoming changes",
            responsive: true,
            $$slots: {
              cell: ($$renderer4, { row, column }) => {
                if (column.key === "shortHash") {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<a${attr("href", getCommitUrl(row.hash))} target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-1.5 font-mono text-xs text-accent-600 hover:underline dark:text-accent-400">${escape_html(row.shortHash)} `);
                  External_link($$renderer4, { size: 12 });
                  $$renderer4.push(`<!----></a>`);
                } else if (column.key === "message") {
                  $$renderer4.push("<!--[1-->");
                  $$renderer4.push(`<span class="line-clamp-1 text-sm text-neutral-900 dark:text-neutral-100">${escape_html(row.message)}</span>`);
                } else if (column.key === "author") {
                  $$renderer4.push("<!--[2-->");
                  $$renderer4.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(row.author)}</span>`);
                } else if (column.key === "date") {
                  $$renderer4.push("<!--[3-->");
                  $$renderer4.push(`<span class="font-mono text-xs text-neutral-500 dark:text-neutral-400">${escape_html(fmtDate(row.date))}</span>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]-->`);
              },
              expanded: ($$renderer4, { row }) => {
                $$renderer4.push(`<div class="space-y-2"><div class="flex items-center gap-2 text-xs text-neutral-500 dark:text-neutral-400">`);
                File_text($$renderer4, { size: 14 });
                $$renderer4.push(`<!----> <span>${escape_html(row.files.length)} file${escape_html(row.files.length !== 1 ? "s" : "")} changed</span></div> `);
                if (row.files.length > 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="grid gap-1"><!--[-->`);
                  const each_array = ensure_array_like(row.files);
                  for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                    let file = each_array[$$index];
                    $$renderer4.push(`<code class="block rounded bg-neutral-100 px-2 py-1 font-mono text-xs text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300">${escape_html(file)}</code>`);
                  }
                  $$renderer4.push(`<!--]--></div>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--></div>`);
              }
            }
          });
        }
        $$renderer3.push(`<!--]--></section></div>`);
      }
      $$renderer3.push(`<!--]--> `);
      Modal($$renderer3, {
        open: showDropModal,
        header: "Drop changes",
        bodyMessage: `Drop ${primaryKeys.length} change${primaryKeys.length === 1 ? "" : "s"}? This cannot be undone.`,
        confirmText: "Drop",
        cancelText: "Cancel",
        confirmDanger: true,
        loading: dropping
      });
      $$renderer3.push(`<!----> `);
      Modal($$renderer3, {
        open: showPreviewModal,
        header: "Export preview",
        confirmText: "Approve & Export",
        cancelText: "Close",
        confirmDisabled: previewConfirmDisabled,
        loading: committing,
        size: "2xl",
        $$slots: {
          "header-extra": ($$renderer4) => {
            $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          body: ($$renderer4) => {
            $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">No preview data returned.</p>`);
            $$renderer4.push(`<!--]-->`);
          },
          footer: ($$renderer4) => {
            Button($$renderer4, {
              text: "Close",
              icon: X2,
              iconColor: "text-red-500",
              disabled: committing
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Approve & Export",
              icon: Check,
              iconColor: "text-blue-500",
              disabled: previewConfirmDisabled || committing,
              loading: committing
            });
            $$renderer4.push(`<!---->`);
          }
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var goOnGit_default;
var init_page_svelte28 = __esm({
  "dist/build/server/entries/pages/databases/_id_/changes/_page.svelte.js"() {
    "use strict";
    init_server();
    init_dates();
    init_mediaManagement();
    init_sanitize();
    init_Icon();
    init_check();
    init_download();
    init_external_link();
    init_file_text();
    init_Button();
    init_send();
    init_trash_2();
    init_upload();
    init_x();
    init_client4();
    init_store2();
    init_Label();
    init_Sonarr2();
    init_navigation();
    init_InlineCode();
    init_Modal();
    init_dateFormat();
    init_timezone();
    init_forms();
    init_IconCheckbox();
    init_ExpandableTable();
    init_ActionsBar();
    init_ActionButton();
    init_Badge();
    init_PageMeta();
    init_Table();
    init_CodeBlock();
    init_marked_esm();
    goOnGit_default = "/_app/immutable/assets/goOnGit.BmG8IoC5.gif";
  }
});

// dist/build/server/nodes/36.js
var __exports37 = {};
__export(__exports37, {
  component: () => component35,
  fonts: () => fonts37,
  imports: () => imports37,
  index: () => index37,
  server: () => page_server_ts_exports29,
  server_id: () => server_id35,
  stylesheets: () => stylesheets37
});
var index37, component_cache35, component35, server_id35, imports37, stylesheets37, fonts37;
var init__37 = __esm({
  async "dist/build/server/nodes/36.js"() {
    "use strict";
    await init_page_server_ts29();
    index37 = 36;
    component35 = async () => component_cache35 ??= (await Promise.resolve().then(() => (init_page_svelte28(), page_svelte_exports28))).default;
    server_id35 = "src/routes/databases/[id]/changes/+page.server.ts";
    imports37 = ["_app/immutable/nodes/36.DxHF8qsH.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CQskZlkd2.js", "_app/immutable/chunks/BqRH1fsh2.js", "_app/immutable/chunks/D7OHFWTL2.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/CqoQtmn5.js", "_app/immutable/chunks/DYf5Ixhg.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/R82tBOWO.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/XFcHCQ8-.js", "_app/immutable/chunks/KKGdICwf.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dg15A-ry2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/Baki32ro2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/CrAcgBQ22.js", "_app/immutable/chunks/ITepJp4A2.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/DcKM5OzB2.js", "_app/immutable/chunks/DSNLgKve.js"];
    stylesheets37 = ["_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css", "_app/immutable/assets/CodeBlock.Cn36jBaQ.css"];
    fonts37 = [];
  }
});

// dist/build/server/entries/pages/databases/_id_/commits/_page.server.ts.js
var page_server_ts_exports30 = {};
__export(page_server_ts_exports30, {
  load: () => load34
});
var load34;
var init_page_server_ts30 = __esm({
  "dist/build/server/entries/pages/databases/_id_/commits/_page.server.ts.js"() {
    "use strict";
    load34 = async () => {
      return {};
    };
  }
});

// dist/build/server/entries/pages/databases/_id_/commits/_page.svelte.js
var page_svelte_exports29 = {};
__export(page_svelte_exports29, {
  default: () => _page29
});
function _page29($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let totalPages;
    let data = $$props["data"];
    const pageSize = 20;
    let loading = true;
    let commits = [];
    let repositoryUrl = "";
    let currentPage = 1;
    let totalCount = 0;
    let fetchToken = 0;
    async function fetchCommits(page2) {
      const token = ++fetchToken;
      loading = true;
      try {
        const response = await fetch(`/databases/${data.database.id}/commits/data?page=${page2}&pageSize=${pageSize}`);
        if (token !== fetchToken) return;
        if (response.ok) {
          const result = await response.json();
          commits = result.commits;
          totalCount = result.totalCount;
          result.branch;
          repositoryUrl = result.repositoryUrl;
          currentPage = result.page;
        }
      } finally {
        if (token === fetchToken) loading = false;
      }
    }
    function handlePageChange(page2) {
      if (loading || page2 < 1 || page2 > totalPages) return;
      fetchCommits(page2);
    }
    afterNavigate(() => {
      currentPage = 1;
      totalCount = 0;
      fetchCommits(1);
    });
    function parseDate(dateStr) {
      const parsed = parseUTC(dateStr) ?? new Date(dateStr);
      if (Number.isNaN(parsed.getTime())) return null;
      return parsed;
    }
    function getDateSortValue(dateStr) {
      const parsed = parseDate(dateStr);
      return parsed ? parsed.getTime() : Number.NEGATIVE_INFINITY;
    }
    function fmtDate(dateStr) {
      const date = parseDate(dateStr);
      if (!date) return "-";
      const diffMs = (/* @__PURE__ */ new Date()).getTime() - date.getTime();
      const diffDays = Math.floor(diffMs / 864e5);
      if (diffMs < 0) return formatDate(dateStr, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat));
      if (diffDays === 0) {
        const diffHours = Math.floor(diffMs / 36e5);
        if (diffHours === 0) return `${Math.floor(diffMs / 6e4)}m ago`;
        return `${diffHours}h ago`;
      }
      if (diffDays === 1) return "Yesterday";
      if (diffDays < 7) return `${diffDays}d ago`;
      if (diffDays < 30) return `${Math.floor(diffDays / 7)}w ago`;
      return formatDate(dateStr, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat));
    }
    function getCommitUrl(hash4) {
      return `${repositoryUrl}/commit/${hash4}`;
    }
    const columns = [
      {
        key: "shortHash",
        header: "Commit",
        width: "w-24"
      },
      {
        key: "status",
        header: "Status",
        width: "w-28"
      },
      {
        key: "message",
        header: "Message"
      },
      {
        key: "author",
        header: "Author",
        width: "w-40"
      },
      {
        key: "date",
        header: "Date",
        width: "w-28",
        align: "right",
        sortable: true,
        defaultSortDirection: "desc",
        sortAccessor: (row) => getDateSortValue(row.date)
      }
    ];
    $: totalPages = Math.max(1, Math.ceil(totalCount / pageSize));
    PageMeta($$renderer2, { title: `${data.database.name} \xB7 Updates` });
    $$renderer2.push(`<!----> <div class="mt-6 space-y-6">`);
    ExpandableTable($$renderer2, {
      columns,
      data: commits,
      getRowId: (row) => row.hash,
      emptyMessage: "No commits found",
      defaultSort: {
        key: "date",
        direction: "desc"
      },
      chevronPosition: "right",
      responsive: true,
      loading,
      loadingRows: 10,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "shortHash") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<a${attr("href", getCommitUrl(row.hash))} target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-1.5 font-mono text-xs text-accent-600 hover:underline dark:text-accent-400">${escape_html(row.shortHash)} `);
            External_link($$renderer3, { size: 12 });
            $$renderer3.push(`<!----></a>`);
          } else if (column.key === "status") {
            $$renderer3.push("<!--[1-->");
            if (row.status === "installed") {
              $$renderer3.push("<!--[0-->");
              Label($$renderer3, {
                variant: "success",
                size: "sm",
                rounded: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Installed`);
                },
                $$slots: { default: true }
              });
            } else {
              $$renderer3.push("<!--[-1-->");
              Label($$renderer3, {
                variant: "info",
                size: "sm",
                rounded: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Available`);
                },
                $$slots: { default: true }
              });
            }
            $$renderer3.push(`<!--]-->`);
          } else if (column.key === "message") {
            $$renderer3.push("<!--[2-->");
            $$renderer3.push(`<span class="line-clamp-1 text-sm text-neutral-900 dark:text-neutral-100">${escape_html(row.message)}</span>`);
          } else if (column.key === "author") {
            $$renderer3.push("<!--[3-->");
            $$renderer3.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(row.author)}</span>`);
          } else if (column.key === "date") {
            $$renderer3.push("<!--[4-->");
            $$renderer3.push(`<span class="font-mono text-xs text-neutral-500 dark:text-neutral-400">${escape_html(fmtDate(row.date))}</span>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        expanded: ($$renderer3, { row }) => {
          $$renderer3.push(`<div class="space-y-2 p-4"><div class="flex items-center gap-2 text-xs text-neutral-500 dark:text-neutral-400">`);
          File_text($$renderer3, { size: 14 });
          $$renderer3.push(`<!----> <span>${escape_html(row.files.length)} file${escape_html(row.files.length !== 1 ? "s" : "")} changed</span></div> `);
          if (row.files.length > 0) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="grid gap-1"><!--[-->`);
            const each_array = ensure_array_like(row.files);
            for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
              let file = each_array[$$index];
              $$renderer3.push(`<code class="block rounded bg-neutral-100 px-2 py-1 font-mono text-xs text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300">${escape_html(file)}</code>`);
            }
            $$renderer3.push(`<!--]--></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--></div>`);
        }
      }
    });
    $$renderer2.push(`<!----> `);
    if (totalPages > 1) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="flex justify-center">`);
      Pagination($$renderer2, {
        currentPage,
        totalPages,
        onPageChange: handlePageChange
      });
      $$renderer2.push(`<!----></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte29 = __esm({
  "dist/build/server/entries/pages/databases/_id_/commits/_page.svelte.js"() {
    "use strict";
    init_server();
    init_dates();
    init_external_link();
    init_file_text();
    init_client4();
    init_Label();
    init_navigation();
    init_dateFormat();
    init_timezone();
    init_ExpandableTable();
    init_PageMeta();
    init_Pagination();
  }
});

// dist/build/server/nodes/37.js
var __exports38 = {};
__export(__exports38, {
  component: () => component36,
  fonts: () => fonts38,
  imports: () => imports38,
  index: () => index38,
  server: () => page_server_ts_exports30,
  server_id: () => server_id36,
  stylesheets: () => stylesheets38
});
var index38, component_cache36, component36, server_id36, imports38, stylesheets38, fonts38;
var init__38 = __esm({
  "dist/build/server/nodes/37.js"() {
    "use strict";
    init_page_server_ts30();
    index38 = 37;
    component36 = async () => component_cache36 ??= (await Promise.resolve().then(() => (init_page_svelte29(), page_svelte_exports29))).default;
    server_id36 = "src/routes/databases/[id]/commits/+page.server.ts";
    imports38 = ["_app/immutable/nodes/37.CnXJJxzW.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/DTxrEb2m.js", "_app/immutable/chunks/D1MpTH1m.js", "_app/immutable/chunks/DBUl7-VL.js"];
    stylesheets38 = [];
    fonts38 = [];
  }
});

// dist/build/server/entries/pages/databases/_id_/config/_page.server.ts.js
var page_server_ts_exports31 = {};
__export(page_server_ts_exports31, {
  actions: () => actions22,
  load: () => load35
});
var load35, actions22;
var init_page_server_ts31 = __esm({
  async "dist/build/server/entries/pages/databases/_id_/config/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_databaseInstances();
    await init_markdown();
    init_exports();
    load35 = async ({ parent }) => {
      const { database } = await parent();
      if (!database.hasPat) error(403, "Config page requires a personal access token");
      let manifest2 = null;
      let readmeRaw = null;
      let readmeHtml = null;
      try {
        manifest2 = await readManifest(database.local_path);
      } catch {
      }
      readmeRaw = await readReadme(database.local_path);
      if (readmeRaw) readmeHtml = parseMarkdown(readmeRaw);
      return {
        manifest: manifest2,
        readmeRaw,
        readmeHtml
      };
    };
    actions22 = { save: async ({ request, params }) => {
      const id = parseInt(params.id, 10);
      const database = databaseInstancesQueries.getById(id);
      if (!database) return fail(404, { error: "Database not found" });
      if (!database.personal_access_token) return fail(403, { error: "Personal access token required" });
      const formData = await request.formData();
      const manifestJson = formData.get("manifest");
      const readme = formData.get("readme");
      try {
        const manifest2 = JSON.parse(manifestJson);
        validateManifest(manifest2);
        await writeManifest(database.local_path, manifest2);
        await writeReadme(database.local_path, readme);
        let dependencySync;
        try {
          dependencySync = await syncDependencies(database.local_path, database.personal_access_token ?? void 0);
        } catch (error2) {
          const message2 = error2 instanceof Error ? error2.message : String(error2);
          return fail(500, { error: `Failed to sync dependencies: ${message2}` });
        }
        if (dependencySync.changed) {
          await logger.info("Dependencies changed, invalidating cache before rebuild", {
            source: "DatabaseConfig",
            meta: {
              databaseId: id,
              databaseName: database.name,
              repositories: dependencySync.repositories
            }
          });
          invalidate(id);
        }
        if (database.enabled) try {
          await compile(database.local_path, id);
          await logger.info("Rebuilt cache after config dependency sync", {
            source: "DatabaseConfig",
            meta: {
              databaseId: id,
              databaseName: database.name,
              dependenciesChanged: dependencySync.changed,
              repositories: dependencySync.repositories
            }
          });
        } catch (error2) {
          const message2 = error2 instanceof Error ? error2.message : String(error2);
          return fail(500, { error: `Failed to rebuild cache: ${message2}` });
        }
        return { success: true };
      } catch (err) {
        const message2 = err instanceof Error ? err.message : String(err);
        return fail(400, { error: message2 });
      }
    } };
  }
});

// dist/build/server/chunks/KeyValueList.js
function KeyValueList($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let value2 = fallback($$props["value"], () => ({}), true);
    let label = fallback($$props["label"], "");
    let description = fallback($$props["description"], "");
    let keyLabel = fallback($$props["keyLabel"], "Key");
    let valueLabel = fallback($$props["valueLabel"], "Value");
    let keyPlaceholder = fallback($$props["keyPlaceholder"], "Enter key");
    let valuePlaceholder = fallback($$props["valuePlaceholder"], "Enter value");
    let onchange = fallback($$props["onchange"], void 0);
    let lockedFirst = fallback($$props["lockedFirst"], void 0);
    let onLockedDeleteAttempt = fallback($$props["onLockedDeleteAttempt"], void 0);
    let onLockedEditAttempt = fallback($$props["onLockedEditAttempt"], void 0);
    let onLockedVersionMinBlocked = fallback($$props["onLockedVersionMinBlocked"], void 0);
    let valueType = fallback($$props["valueType"], "text");
    let versionMinMajor = fallback($$props["versionMinMajor"], 0);
    let addDisabled = fallback($$props["addDisabled"], false);
    let onAddBlocked = fallback($$props["onAddBlocked"], void 0);
    function parseVersion(v3) {
      const parts = v3.split(".").map((p2) => parseInt(p2, 10) || 0);
      return [
        parts[0] ?? 0,
        parts[1] ?? 0,
        parts[2] ?? 0
      ];
    }
    function updateVersionPart(current3, part, val) {
      const parts = parseVersion(current3);
      parts[part] = val;
      return parts.join(".");
    }
    function initEntries() {
      const arr = Object.entries(value2).map(([k2, v3]) => ({
        key: k2,
        value: v3
      }));
      if (lockedFirst) {
        const existingIndex = arr.findIndex((e) => e.key === lockedFirst.key);
        if (existingIndex === -1) arr.unshift({
          key: lockedFirst.key,
          value: lockedFirst.value ?? ""
        });
        else if (existingIndex !== 0) {
          const [item] = arr.splice(existingIndex, 1);
          arr.unshift(item);
        }
      }
      return arr;
    }
    let entries = initEntries();
    function syncToValue() {
      const newValue = {};
      for (const entry of entries) if (entry.key.trim()) newValue[entry.key.trim()] = entry.value;
      value2 = newValue;
      onchange?.(value2);
    }
    function updateValue(index88, newValue) {
      entries[index88].value = newValue;
      entries = entries;
      syncToValue();
    }
    $: {
      const externalEntries = Object.entries(value2);
      if (entries.filter((e) => e.key.trim()).map((e) => e.key).sort().join(",") !== externalEntries.map(([k2]) => k2).sort().join(",")) {
        const emptyKeyEntries = entries.filter((e) => !e.key.trim());
        entries = [...externalEntries.map(([k2, v3]) => ({
          key: k2,
          value: v3
        })), ...emptyKeyEntries];
        if (lockedFirst) {
          const existingIndex = entries.findIndex((e) => e.key === lockedFirst.key);
          if (existingIndex > 0) {
            const [item] = entries.splice(existingIndex, 1);
            entries.unshift(item);
          }
        }
      }
    }
    $$renderer2.push(`<div class="space-y-3">`);
    if (label) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">${escape_html(label)}</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (description) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(description)}</p>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div class="space-y-2">`);
    if (entries.length > 0) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="hidden text-xs font-medium text-neutral-500 md:grid md:grid-cols-[1fr_auto_auto] md:gap-2 dark:text-neutral-400"><span>${escape_html(keyLabel)}</span> <span>${escape_html(valueLabel)}</span> <span class="w-8"></span></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <!--[-->`);
    const each_array = ensure_array_like(entries);
    for (let index88 = 0, $$length = each_array.length; index88 < $$length; index88++) {
      let entry = each_array[index88];
      const isLocked = lockedFirst && index88 === 0;
      const [vMajor, vMinor, vPatch] = parseVersion(entry.value);
      $$renderer2.push(`<div class="space-y-2 rounded-lg border border-neutral-200 p-3 md:hidden dark:border-neutral-700"><div class="flex items-center justify-between"><span class="text-xs font-medium text-neutral-500 dark:text-neutral-400">${escape_html(keyLabel)}</span> <button type="button" class="flex h-8 w-8 items-center justify-center rounded-lg text-neutral-400 transition-colors hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-900/20 dark:hover:text-red-400" aria-label="Remove entry">`);
      Trash_2($$renderer2, { size: 16 });
      $$renderer2.push(`<!----></button></div> `);
      FormInput($$renderer2, {
        label: keyLabel,
        hideLabel: true,
        value: entry.key,
        placeholder: keyPlaceholder,
        readonly: !!isLocked
      });
      $$renderer2.push(`<!----> <span class="text-xs font-medium text-neutral-500 dark:text-neutral-400">${escape_html(valueLabel)}</span> `);
      if (valueType === "version") {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="flex items-center gap-1"><div class="w-16">`);
        NumberInput($$renderer2, {
          name: `version-major-${stringify(index88)}-mobile`,
          value: vMajor,
          min: isLocked && lockedFirst?.minMajor !== void 0 ? lockedFirst.minMajor : versionMinMajor,
          font: "mono",
          onchange: (v3) => updateValue(index88, updateVersionPart(entry.value, 0, v3)),
          onMinBlocked: isLocked ? onLockedVersionMinBlocked : void 0
        });
        $$renderer2.push(`<!----></div> <span class="text-lg font-medium text-neutral-400 dark:text-neutral-500">.</span> <div class="w-16">`);
        NumberInput($$renderer2, {
          name: `version-minor-${stringify(index88)}-mobile`,
          value: vMinor,
          min: 0,
          font: "mono",
          onchange: (v3) => updateValue(index88, updateVersionPart(entry.value, 1, v3))
        });
        $$renderer2.push(`<!----></div> <span class="text-lg font-medium text-neutral-400 dark:text-neutral-500">.</span> <div class="w-16">`);
        NumberInput($$renderer2, {
          name: `version-patch-${stringify(index88)}-mobile`,
          value: vPatch,
          min: 0,
          font: "mono",
          onchange: (v3) => updateValue(index88, updateVersionPart(entry.value, 2, v3))
        });
        $$renderer2.push(`<!----></div></div>`);
      } else {
        $$renderer2.push("<!--[-1-->");
        FormInput($$renderer2, {
          label: valueLabel,
          hideLabel: true,
          value: entry.value,
          placeholder: valuePlaceholder
        });
      }
      $$renderer2.push(`<!--]--></div> <div class="hidden md:grid md:grid-cols-[1fr_auto_auto] md:gap-2">`);
      FormInput($$renderer2, {
        label: keyLabel,
        hideLabel: true,
        value: entry.key,
        placeholder: keyPlaceholder,
        readonly: !!isLocked
      });
      $$renderer2.push(`<!----> `);
      if (valueType === "version") {
        $$renderer2.push("<!--[0-->");
        $$renderer2.push(`<div class="flex items-center gap-1"><div class="w-16">`);
        NumberInput($$renderer2, {
          name: `version-major-${stringify(index88)}`,
          value: vMajor,
          min: isLocked && lockedFirst?.minMajor !== void 0 ? lockedFirst.minMajor : versionMinMajor,
          font: "mono",
          onchange: (v3) => updateValue(index88, updateVersionPart(entry.value, 0, v3)),
          onMinBlocked: isLocked ? onLockedVersionMinBlocked : void 0
        });
        $$renderer2.push(`<!----></div> <span class="text-lg font-medium text-neutral-400 dark:text-neutral-500">.</span> <div class="w-16">`);
        NumberInput($$renderer2, {
          name: `version-minor-${stringify(index88)}`,
          value: vMinor,
          min: 0,
          font: "mono",
          onchange: (v3) => updateValue(index88, updateVersionPart(entry.value, 1, v3))
        });
        $$renderer2.push(`<!----></div> <span class="text-lg font-medium text-neutral-400 dark:text-neutral-500">.</span> <div class="w-16">`);
        NumberInput($$renderer2, {
          name: `version-patch-${stringify(index88)}`,
          value: vPatch,
          min: 0,
          font: "mono",
          onchange: (v3) => updateValue(index88, updateVersionPart(entry.value, 2, v3))
        });
        $$renderer2.push(`<!----></div></div>`);
      } else {
        $$renderer2.push("<!--[-1-->");
        FormInput($$renderer2, {
          label: valueLabel,
          hideLabel: true,
          value: entry.value,
          placeholder: valuePlaceholder
        });
      }
      $$renderer2.push(`<!--]--> <button type="button" class="flex h-[38px] w-8 items-center justify-center rounded-lg text-neutral-400 transition-colors hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-900/20 dark:hover:text-red-400" aria-label="Remove entry">`);
      Trash_2($$renderer2, { size: 16 });
      $$renderer2.push(`<!----></button></div>`);
    }
    $$renderer2.push(`<!--]--> <button type="button" class="flex items-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium text-neutral-600 transition-colors hover:bg-neutral-100 dark:text-neutral-400 dark:hover:bg-neutral-800">`);
    Plus($$renderer2, { size: 16 });
    $$renderer2.push(`<!----> Add entry</button></div></div>`);
    bind_props($$props, {
      value: value2,
      label,
      description,
      keyLabel,
      valueLabel,
      keyPlaceholder,
      valuePlaceholder,
      onchange,
      lockedFirst,
      onLockedDeleteAttempt,
      onLockedEditAttempt,
      onLockedVersionMinBlocked,
      valueType,
      versionMinMajor,
      addDisabled,
      onAddBlocked
    });
  });
}
var init_KeyValueList = __esm({
  "dist/build/server/chunks/KeyValueList.js"() {
    "use strict";
    init_server();
    init_plus();
    init_trash_2();
    init_FormInput();
    init_NumberInput();
  }
});

// dist/build/server/entries/pages/databases/_id_/config/_page.svelte.js
var page_svelte_exports30 = {};
__export(page_svelte_exports30, {
  default: () => _page30
});
function _page30($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let vMajor, vMinor, vPatch, pvMajor, pvMinor, pvPatch;
    let data = $$props["data"];
    let manifest2 = data.manifest;
    let readme = data.readmeRaw ?? "";
    onDestroy(() => {
      clear();
    });
    function updateManifest(key2, value2) {
      if (!manifest2) return;
      manifest2 = {
        ...manifest2,
        [key2]: value2
      };
      update3("manifest", manifest2);
    }
    function updateProfilarr(key2, value2) {
      if (!manifest2) return;
      manifest2 = {
        ...manifest2,
        profilarr: {
          ...manifest2.profilarr,
          [key2]: value2
        }
      };
      update3("manifest", manifest2);
    }
    function updateReadme(value2) {
      readme = value2;
      update3("readme", readme);
    }
    function parseVersion(v3) {
      const parts = v3.split(".").map((p2) => parseInt(p2, 10) || 0);
      return [
        parts[0] ?? 0,
        parts[1] ?? 0,
        parts[2] ?? 0
      ];
    }
    function updateVersionPart(current3, part, value2) {
      const parts = parseVersion(current3);
      parts[part] = value2;
      return parts.join(".");
    }
    $: [vMajor, vMinor, vPatch] = manifest2 ? parseVersion(manifest2.version) : [
      0,
      0,
      0
    ];
    $: [pvMajor, pvMinor, pvPatch] = manifest2 ? parseVersion(manifest2.profilarr.minimum_version) : [
      0,
      0,
      0
    ];
    PageMeta($$renderer2, { title: `${data.database.name} \xB7 Config` });
    $$renderer2.push(`<!----> <form method="POST" action="?/save"><input type="hidden" name="manifest"${attr("value", JSON.stringify(manifest2))}/> <input type="hidden" name="readme"${attr("value", readme)}/> `);
    if (manifest2) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="space-y-5">`);
      StickyCard($$renderer2, {
        position: "top",
        $$slots: {
          left: ($$renderer3) => {
            $$renderer3.push(`<h1 class="text-neutral-900 dark:text-neutral-50">Config</h1> <p class="text-neutral-600 dark:text-neutral-400">Edit the database manifest and README</p>`);
          },
          right: ($$renderer3) => {
            Button($$renderer3, {
              text: "Save",
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              disabled: !store_get($$store_subs ??= {}, "$isDirty", isDirty),
              type: "submit"
            });
          }
        }
      });
      $$renderer2.push(`<!----> <div class="space-y-5 rounded-lg border border-neutral-200 bg-white p-4 dark:border-neutral-800 dark:bg-neutral-900">`);
      FormInput($$renderer2, {
        label: "Name",
        name: "name",
        required: true,
        value: manifest2.name,
        description: "Unique identifier for the database (lowercase, hyphens preferred)",
        placeholder: "my-database"
      });
      $$renderer2.push(`<!----> `);
      FormInput($$renderer2, {
        label: "Description",
        name: "description",
        required: true,
        value: manifest2.description,
        description: "Short summary of what the database provides",
        placeholder: "My custom Arr configurations"
      });
      $$renderer2.push(`<!----> <div class="space-y-1"><span class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">Version <span class="text-red-500">*</span></span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Semantic version of the database (MAJOR.MINOR.PATCH)</p> <div class="mt-1 flex items-center gap-1"><div class="w-20">`);
      NumberInput($$renderer2, {
        name: "version-major",
        value: vMajor,
        min: 1,
        font: "mono",
        onchange: (v3) => updateManifest("version", updateVersionPart(manifest2.version, 0, v3)),
        onMinBlocked: () => alertStore.add("warning", "Database version must be at least 1.0.0")
      });
      $$renderer2.push(`<!----></div> <span class="text-lg font-medium text-neutral-400 dark:text-neutral-500">.</span> <div class="w-20">`);
      NumberInput($$renderer2, {
        name: "version-minor",
        value: vMinor,
        min: 0,
        font: "mono",
        onchange: (v3) => updateManifest("version", updateVersionPart(manifest2.version, 1, v3))
      });
      $$renderer2.push(`<!----></div> <span class="text-lg font-medium text-neutral-400 dark:text-neutral-500">.</span> <div class="w-20">`);
      NumberInput($$renderer2, {
        name: "version-patch",
        value: vPatch,
        min: 0,
        font: "mono",
        onchange: (v3) => updateManifest("version", updateVersionPart(manifest2.version, 2, v3))
      });
      $$renderer2.push(`<!----></div></div></div> <div class="space-y-1"><span class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">Minimum Profilarr Version <span class="text-red-500">*</span></span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Minimum Profilarr version required to use this database</p> <div class="mt-1 flex items-center gap-1"><div class="w-20">`);
      NumberInput($$renderer2, {
        name: "profilarr-version-major",
        value: pvMajor,
        min: 2,
        font: "mono",
        onchange: (v3) => updateProfilarr("minimum_version", updateVersionPart(manifest2.profilarr.minimum_version, 0, v3)),
        onMinBlocked: () => alertStore.add("warning", "Minimum Profilarr version must be at least 2.0.0")
      });
      $$renderer2.push(`<!----></div> <span class="text-lg font-medium text-neutral-400 dark:text-neutral-500">.</span> <div class="w-20">`);
      NumberInput($$renderer2, {
        name: "profilarr-version-minor",
        value: pvMinor,
        min: 0,
        font: "mono",
        onchange: (v3) => updateProfilarr("minimum_version", updateVersionPart(manifest2.profilarr.minimum_version, 1, v3))
      });
      $$renderer2.push(`<!----></div> <span class="text-lg font-medium text-neutral-400 dark:text-neutral-500">.</span> <div class="w-20">`);
      NumberInput($$renderer2, {
        name: "profilarr-version-patch",
        value: pvPatch,
        min: 0,
        font: "mono",
        onchange: (v3) => updateProfilarr("minimum_version", updateVersionPart(manifest2.profilarr.minimum_version, 2, v3))
      });
      $$renderer2.push(`<!----></div></div></div> <div class="space-y-1"><span class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">Arr Types</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Which arr applications this database supports. Leave empty if all are supported.</p> <div class="mt-1">`);
      TagInput($$renderer2, {
        tags: manifest2.arr_types ?? [],
        placeholder: "Add arr type (radarr, sonarr, etc.)",
        onchange: (tags) => updateManifest("arr_types", tags)
      });
      $$renderer2.push(`<!----></div></div> <div class="space-y-1"><span class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">Tags</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Descriptive keywords for discovery</p> <div class="mt-1">`);
      TagInput($$renderer2, {
        tags: manifest2.tags ?? [],
        placeholder: "Add tags...",
        onchange: (tags) => updateManifest("tags", tags)
      });
      $$renderer2.push(`<!----></div></div> `);
      FormInput($$renderer2, {
        label: "License",
        name: "license",
        value: manifest2.license ?? "",
        description: "SPDX license identifier (e.g., MIT, Apache-2.0)",
        placeholder: "MIT"
      });
      $$renderer2.push(`<!----> `);
      FormInput($$renderer2, {
        label: "Repository",
        name: "repository",
        type: "url",
        value: manifest2.repository ?? "",
        description: "Git repository URL",
        placeholder: "https://github.com/user/repo"
      });
      $$renderer2.push(`<!----> `);
      KeyValueList($$renderer2, {
        label: "Dependencies",
        description: "Dependencies this database requires. All PCDs must depend on schema at minimum. Additional dependencies coming in a future version.",
        keyLabel: "Package",
        valueLabel: "Version",
        keyPlaceholder: "package-name",
        valueType: "version",
        versionMinMajor: 1,
        value: manifest2.dependencies ?? {},
        onchange: (v3) => updateManifest("dependencies", v3),
        lockedFirst: {
          key: "https://github.com/Dictionarry-Hub/schema",
          value: "1.0.0",
          minMajor: 1
        },
        onLockedEditAttempt: () => alertStore.add("warning", "The schema package URL cannot be changed"),
        onLockedDeleteAttempt: () => alertStore.add("warning", "The schema dependency is required and cannot be removed"),
        onLockedVersionMinBlocked: () => alertStore.add("warning", "Schema version must be at least 1.0.0"),
        addDisabled: true,
        onAddBlocked: () => alertStore.add("info", "Additional dependencies are not available yet. Coming in a future version.")
      });
      $$renderer2.push(`<!----> <div class="space-y-1"><span class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">README</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Documentation for your database</p> <div class="mt-1">`);
      MarkdownInput($$renderer2, {
        value: readme,
        onchange: updateReadme,
        placeholder: "Write your README here...",
        rows: 12
      });
      $$renderer2.push(`<!----></div></div></div></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">No manifest found</p>`);
    }
    $$renderer2.push(`<!--]--></form> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte30 = __esm({
  "dist/build/server/entries/pages/databases/_id_/config/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_MarkdownInput();
    init_Button();
    init_save();
    init_store2();
    init_forms();
    init_dirty();
    init_DirtyModal();
    init_PageMeta();
    init_StickyCard();
    init_FormInput();
    init_NumberInput();
    init_TagInput();
    init_KeyValueList();
  }
});

// dist/build/server/nodes/38.js
var __exports39 = {};
__export(__exports39, {
  component: () => component37,
  fonts: () => fonts39,
  imports: () => imports39,
  index: () => index39,
  server: () => page_server_ts_exports31,
  server_id: () => server_id37,
  stylesheets: () => stylesheets39
});
var index39, component_cache37, component37, server_id37, imports39, stylesheets39, fonts39;
var init__39 = __esm({
  async "dist/build/server/nodes/38.js"() {
    "use strict";
    await init_page_server_ts31();
    index39 = 38;
    component37 = async () => component_cache37 ??= (await Promise.resolve().then(() => (init_page_svelte30(), page_svelte_exports30))).default;
    server_id37 = "src/routes/databases/[id]/config/+page.server.ts";
    imports39 = ["_app/immutable/nodes/38.COBuFbwH.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/CK2yQf0C.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Cjav3c1K2.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/B634VwR8.js"];
    stylesheets39 = [];
    fonts39 = [];
  }
});

// dist/build/server/entries/pages/databases/_id_/conflicts/_page.server.ts.js
var page_server_ts_exports32 = {};
__export(page_server_ts_exports32, {
  actions: () => actions23,
  load: () => load36
});
async function alignConflict(input) {
  const { databaseId, opId } = input;
  const op = pcdOpsQueries.getById(opId);
  if (!op || op.database_id !== databaseId) return {
    success: false,
    error: "Conflict operation not found"
  };
  if (op.origin !== "user" || op.state !== "published") return {
    success: false,
    error: "Only published user operations can be aligned"
  };
  if (!pcdOpsQueries.update(opId, { state: "dropped" })) return {
    success: false,
    error: "Failed to drop conflicting operation"
  };
  pcdOpHistoryQueries.create({
    opId,
    databaseId,
    batchId: uuid(),
    status: "dropped"
  });
  const instance = databaseInstancesQueries.getById(databaseId);
  if (instance?.enabled) await compile(instance.local_path, databaseId);
  await logger.info("Aligned conflict", {
    source: "PCDConflicts",
    meta: {
      databaseId,
      opId
    }
  });
  return { success: true };
}
function parseMetadata2(raw) {
  if (!raw) return null;
  try {
    return JSON.parse(raw);
  } catch {
    return null;
  }
}
function parseDesiredState2(raw) {
  if (!raw) return null;
  try {
    const parsed = JSON.parse(raw);
    if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
  } catch {
  }
  return null;
}
function isFromTo2(value2) {
  return value2 !== null && typeof value2 === "object" && "from" in value2 && "to" in value2;
}
function formatEntity2(entity) {
  return (entity ?? "operation").replace(/_/g, " ");
}
function formatTitle(metadata) {
  return `${metadata?.operation ?? "update"} ${formatEntity2(metadata?.entity)}${metadata?.name ? ` "${metadata.name}"` : ""}`;
}
function makeCurrentRowLookup(databaseId) {
  const cache3 = getCache(databaseId);
  const memo = /* @__PURE__ */ new Map();
  return (entity, lookupName) => {
    if (!cache3) return null;
    const config2 = AUTO_ALIGN_ENTITIES.get(entity);
    if (!config2) return null;
    const cacheKey = `${entity}::${lookupName}`;
    if (memo.has(cacheKey)) return memo.get(cacheKey) ?? null;
    try {
      const row = cache3.queryOne(`SELECT * FROM ${config2.table} WHERE ${config2.keyColumn} = ? LIMIT 1`, lookupName);
      memo.set(cacheKey, row ?? null);
      return row ?? null;
    } catch {
      memo.set(cacheKey, null);
      return null;
    }
  };
}
function buildFieldConflicts(databaseId, lookupRow, entity, metadata, desiredState) {
  if (!desiredState) return {
    fields: [],
    complex: false
  };
  const keys = Object.keys(desiredState);
  if (keys.length === 0) return {
    fields: [],
    complex: false
  };
  if (!keys.every((key2) => isFromTo2(desiredState[key2]))) return {
    fields: [],
    complex: true
  };
  const currentRow = resolveCurrentRow2(databaseId, lookupRow, entity, metadata, desiredState);
  return {
    fields: keys.map((field) => {
      const change = desiredState[field];
      return {
        field,
        was: change.from,
        you: change.to,
        upstreamNow: currentRow ? currentRow[field] ?? null : null
      };
    }),
    complex: false
  };
}
function resolveCurrentRow2(databaseId, lookupRow, entity, metadata, desiredState) {
  const candidates = lookupNameCandidates(metadata, desiredState);
  for (const name of candidates) {
    const row = lookupRow(entity, name);
    if (row) return row;
  }
  if (candidates.length === 0) return null;
  const resolvedName = followRenameChain(databaseId, entity, candidates[0]);
  if (resolvedName !== candidates[0]) return lookupRow(entity, resolvedName);
  return null;
}
function lookupNameCandidates(metadata, desiredState) {
  return uniqueStrings([
    stableKeyValue(metadata),
    metadata?.previousName,
    metadata?.name,
    desiredNameTo(desiredState),
    plainDesiredName(desiredState)
  ]);
}
function stableKeyValue(metadata) {
  const value2 = metadata?.stable_key?.value ?? metadata?.stableKey?.value;
  return typeof value2 === "string" && value2.length > 0 ? value2 : null;
}
function desiredNameTo(desiredState) {
  const name = desiredState?.name;
  if (!isFromTo2(name)) return null;
  return typeof name.to === "string" && name.to.length > 0 ? name.to : null;
}
function plainDesiredName(desiredState) {
  const name = desiredState?.name;
  return typeof name === "string" && name.length > 0 ? name : null;
}
function uniqueStrings(values) {
  const seen = /* @__PURE__ */ new Set();
  const strings = [];
  for (const value2 of values) {
    if (!value2 || seen.has(value2)) continue;
    seen.add(value2);
    strings.push(value2);
  }
  return strings;
}
function parseOpId2(formData) {
  const raw = formData.get("opId");
  const opId = Number(raw);
  return Number.isFinite(opId) ? opId : null;
}
var load36, actions23;
var init_page_server_ts32 = __esm({
  async "dist/build/server/entries/pages/databases/_id_/conflicts/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_databaseInstances();
    await init_queueService();
    init_uuid();
    await init_markdown();
    await init_pcdOps();
    init_registry();
    await init_override();
    init_exports();
    load36 = async ({ parent }) => {
      const { database } = await parent();
      const conflicts = pcdOpHistoryQueries.listLatestConflictsByDatabase(database.id);
      const lookupRow = makeCurrentRowLookup(database.id);
      const rows = conflicts.map(({ history, op }) => {
        const metadata = parseMetadata2(op.metadata ?? null);
        const desiredState = parseDesiredState2(op.desired_state ?? null);
        const title = metadata?.title ?? metadata?.summary ?? formatTitle(metadata);
        const entity = metadata?.entity ?? "operation";
        const { fields, complex } = buildFieldConflicts(database.id, lookupRow, entity, metadata, desiredState);
        return {
          opId: op.id,
          status: history.status,
          conflictReason: history.conflict_reason,
          appliedAt: history.applied_at,
          operation: metadata?.operation ?? "update",
          entity,
          name: metadata?.name ?? "",
          title,
          summary: metadata?.summary ?? null,
          origin: op.origin,
          groupId: typeof metadata?.group_id === "string" ? metadata.group_id : null,
          fields,
          complex
        };
      });
      return {
        conflictStrategy: database.conflict_strategy ?? "override",
        conflicts: rows
      };
    };
    actions23 = {
      align: async ({ request, params }) => {
        const databaseId = Number(params.id);
        if (!Number.isFinite(databaseId)) return fail(400, { error: "Invalid database id" });
        const opId = parseOpId2(await request.formData());
        if (opId === null) return fail(400, { error: "Invalid operation id" });
        const result = await alignConflict({
          databaseId,
          opId
        });
        if (!result.success) return fail(400, { error: result.error || "Failed to align conflict" });
        return { success: true };
      },
      override: async ({ request, params }) => {
        const databaseId = Number(params.id);
        if (!Number.isFinite(databaseId)) return fail(400, { error: "Invalid database id" });
        const opId = parseOpId2(await request.formData());
        if (opId === null) return fail(400, { error: "Invalid operation id" });
        const result = await overrideConflict({
          databaseId,
          opId
        });
        if (!result.success) return fail(400, { error: result.error || "Failed to override conflict" });
        return { success: true };
      }
    };
  }
});

// dist/build/server/chunks/ExpandableCard.js
function ExpandableCard($$renderer, $$props) {
  let title = $$props["title"];
  let description = fallback($$props["description"], "");
  let open = fallback($$props["open"], true);
  let onboardingId = fallback($$props["onboardingId"], void 0);
  $$renderer.push(`<div${attr("data-onboarding", onboardingId)} class="overflow-hidden rounded-lg border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900"><div class="flex cursor-pointer items-center justify-between bg-neutral-50 px-6 py-4 dark:bg-neutral-800/50"><div class="min-w-0 flex-1"><div class="flex items-center gap-3"><h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h2> <!--[-->`);
  slot($$renderer, $$props, "header-right", {}, null);
  $$renderer.push(`<!--]--></div> `);
  if (description) {
    $$renderer.push("<!--[0-->");
    $$renderer.push(`<p class="mt-1 text-sm text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p>`);
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--></div> `);
  Chevron_down($$renderer, {
    size: 18,
    class: `ml-4 shrink-0 text-neutral-400 transition-transform duration-200 ${open ? "" : "-rotate-90"}`
  });
  $$renderer.push(`<!----></div> `);
  if (open) {
    $$renderer.push("<!--[0-->");
    $$renderer.push(`<div class="border-t border-neutral-200 dark:border-neutral-800"><!--[-->`);
    slot($$renderer, $$props, "default", {}, null);
    $$renderer.push(`<!--]--></div>`);
  } else $$renderer.push("<!--[-1-->");
  $$renderer.push(`<!--]--></div>`);
  bind_props($$props, {
    title,
    description,
    open,
    onboardingId
  });
}
var init_ExpandableCard = __esm({
  "dist/build/server/chunks/ExpandableCard.js"() {
    "use strict";
    init_server();
    init_chevron_down();
  }
});

// dist/build/server/entries/pages/databases/_id_/conflicts/_page.svelte.js
var page_svelte_exports31 = {};
__export(page_svelte_exports31, {
  default: () => _page31
});
function Fingerprint_pattern($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "fingerprint-pattern" },
    props,
    { iconNode: [
      ["path", { "d": "M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4" }],
      ["path", { "d": "M14 13.12c0 2.38 0 6.38-1 8.88" }],
      ["path", { "d": "M17.29 21.02c.12-.6.43-2.3.5-3.02" }],
      ["path", { "d": "M2 12a10 10 0 0 1 18-6" }],
      ["path", { "d": "M2 16h.01" }],
      ["path", { "d": "M21.8 16c.2-2 .131-5.354 0-6" }],
      ["path", { "d": "M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2" }],
      ["path", { "d": "M8.65 22c.21-.66.45-1.32.57-2" }],
      ["path", { "d": "M9 6.8a6 6 0 0 1 9 5.2v2" }]
    ] }
  ]));
}
function Hand_metal($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "hand-metal" },
    props,
    { iconNode: [
      ["path", { "d": "M18 12.5V10a2 2 0 0 0-2-2a2 2 0 0 0-2 2v1.4" }],
      ["path", { "d": "M14 11V9a2 2 0 1 0-4 0v2" }],
      ["path", { "d": "M10 10.5V5a2 2 0 1 0-4 0v9" }],
      ["path", { "d": "m7 15-1.76-1.76a2 2 0 0 0-2.83 2.82l3.6 3.6C7.5 21.14 9.2 22 12 22h2a8 8 0 0 0 8-8V7a2 2 0 1 0-4 0v5" }]
    ] }
  ]));
}
function Heart_handshake($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "heart-handshake" },
    props,
    { iconNode: [["path", { "d": "M19.414 14.414C21 12.828 22 11.5 22 9.5a5.5 5.5 0 0 0-9.591-3.676.6.6 0 0 1-.818.001A5.5 5.5 0 0 0 2 9.5c0 2.3 1.5 4 3 5.5l5.535 5.362a2 2 0 0 0 2.879.052 2.12 2.12 0 0 0-.004-3 2.124 2.124 0 1 0 3-3 2.124 2.124 0 0 0 3.004 0 2 2 0 0 0 0-2.828l-1.881-1.882a2.41 2.41 0 0 0-3.409 0l-1.71 1.71a2 2 0 0 1-2.828 0 2 2 0 0 1 0-2.828l2.823-2.762" }]] }
  ]));
}
function ConflictField($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let field = $$props["field"];
    let was = $$props["was"];
    let you = $$props["you"];
    let upstreamNow = $$props["upstreamNow"];
    function titleCase(value2) {
      return value2.split(/[\s_]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
    }
    function formatValue3(value2) {
      if (value2 === null || value2 === void 0) return "\u2014";
      if (typeof value2 === "boolean") return value2 ? "Yes" : "No";
      if (typeof value2 === "string") {
        if (value2 === "") return "(empty)";
        return value2;
      }
      if (typeof value2 === "number") return String(value2);
      try {
        return JSON.stringify(value2);
      } catch {
        return String(value2);
      }
    }
    $$renderer2.push(`<div class="space-y-1.5"><h4 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(titleCase(field))}</h4> <dl class="flex flex-wrap items-baseline gap-x-6 gap-y-1 text-xs"><div class="flex items-baseline gap-1.5"><dt class="text-neutral-500 dark:text-neutral-400">Original:</dt> <dd class="font-mono text-neutral-900 dark:text-neutral-100">${escape_html(formatValue3(was))}</dd></div> <div class="flex items-baseline gap-1.5"><dt class="text-neutral-500 dark:text-neutral-400">You Set:</dt> <dd class="font-mono text-neutral-900 dark:text-neutral-100">${escape_html(formatValue3(you))}</dd></div> <div class="flex items-baseline gap-1.5"><dt class="text-neutral-500 dark:text-neutral-400">Upstream Set:</dt> <dd class="font-mono text-neutral-900 dark:text-neutral-100">${escape_html(formatValue3(upstreamNow))}</dd></div></dl></div>`);
    bind_props($$props, {
      field,
      was,
      you,
      upstreamNow
    });
  });
}
function _page31($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let filteredConflicts, filteredGroups;
    let data = $$props["data"];
    function groupKey(row) {
      return row.groupId ?? `op-${row.opId}`;
    }
    let searchStore;
    const entityKeys = Array.from(new Set(data.conflicts.map((row) => row.entity))).sort();
    const reasonKeys = Array.from(new Set(data.conflicts.map((row) => row.conflictReason || ""))).sort();
    let activeEntities = /* @__PURE__ */ new Set();
    let activeReasons = /* @__PURE__ */ new Set();
    let showInfoModal = false;
    const reasonLabels = {
      guard_mismatch: "Guard mismatch",
      duplicate_key: "Duplicate key",
      missing_target: "Missing target"
    };
    const reasonVariants = {
      guard_mismatch: "warning",
      duplicate_key: "danger",
      missing_target: "warning"
    };
    const entityLabels = {
      quality_profile: "Quality Profile",
      custom_format: "Custom Format",
      regular_expression: "Regular Expression",
      delay_profile: "Delay Profile",
      radarr_naming: "Radarr Naming",
      sonarr_naming: "Sonarr Naming",
      radarr_media_settings: "Radarr Media Settings",
      sonarr_media_settings: "Sonarr Media Settings",
      radarr_quality_definitions: "Radarr Quality Sizes",
      sonarr_quality_definitions: "Sonarr Quality Sizes",
      test_entity: "Test Entity",
      test_release: "Test Release"
    };
    const entityVariants = {
      quality_profile: "info",
      custom_format: "default",
      regular_expression: "warning",
      delay_profile: "success",
      radarr_naming: "secondary",
      sonarr_naming: "secondary",
      radarr_media_settings: "secondary",
      sonarr_media_settings: "secondary",
      radarr_quality_definitions: "secondary",
      sonarr_quality_definitions: "secondary",
      test_entity: "secondary",
      test_release: "secondary"
    };
    function titleCase(value2) {
      return value2.split(" ").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
    }
    function formatEntity3(entity) {
      return titleCase(entity.replace(/_/g, " "));
    }
    function formatValue3(value2) {
      if (value2 === null || value2 === void 0) return "\u2014";
      if (typeof value2 === "boolean") return value2 ? "Yes" : "No";
      if (typeof value2 === "string") {
        if (value2 === "") return "(empty)";
        return value2;
      }
      if (typeof value2 === "number") return String(value2);
      try {
        return JSON.stringify(value2);
      } catch {
        return String(value2);
      }
    }
    function reasonLabel(reason) {
      const key2 = reason ?? "guard_mismatch";
      return reasonLabels[key2] ?? key2;
    }
    function reasonVariant(reason) {
      return reasonVariants[reason ?? "guard_mismatch"] ?? "secondary";
    }
    function entityLabel2(entity) {
      return entityLabels[entity] ?? formatEntity3(entity);
    }
    function entityVariant(entity) {
      return entityVariants[entity] ?? "secondary";
    }
    function rowMatchesQuery(conflict, query) {
      if (!query) return true;
      return [
        conflict.title,
        conflict.entity,
        conflict.name,
        reasonLabels[conflict.conflictReason ?? "guard_mismatch"] ?? conflict.conflictReason ?? "",
        conflict.status,
        ...conflict.fields.flatMap((f2) => [
          f2.field,
          formatValue3(f2.was),
          formatValue3(f2.you),
          formatValue3(f2.upstreamNow)
        ])
      ].join(" ").toLowerCase().includes(query);
    }
    $: searchStore = getPersistentSearchStore(`databaseConflictsSearch:${store_get($$store_subs ??= {}, "$page", page).params.id}`, { debounceMs: 300 });
    $: filteredConflicts = data.conflicts.filter((conflict) => {
      const matchesQuery = rowMatchesQuery(conflict, store_get($$store_subs ??= {}, "$searchStore", searchStore).query?.trim().toLowerCase() ?? "");
      const matchesEntity = activeEntities.size === 0 ? true : activeEntities.has(conflict.entity);
      const matchesReason = activeReasons.size === 0 ? true : activeReasons.has(conflict.conflictReason ?? "");
      return matchesQuery && matchesEntity && matchesReason;
    });
    $: filteredGroups = (() => {
      const groups = /* @__PURE__ */ new Map();
      for (const conflict of filteredConflicts) {
        const key2 = groupKey(conflict);
        let group = groups.get(key2);
        if (!group) {
          group = {
            key: key2,
            title: conflict.title,
            entity: conflict.entity,
            name: conflict.name,
            conflicts: []
          };
          groups.set(key2, group);
        }
        group.conflicts.push(conflict);
      }
      for (const group of groups.values()) group.conflicts.sort((a2, b3) => a2.opId - b3.opId);
      return Array.from(groups.values());
    })();
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.database.name} \xB7 Conflicts` });
      $$renderer3.push(`<!----> `);
      ActionsBar($$renderer3, {
        className: "justify-end mt-6",
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore,
            placeholder: "Search conflicts..."
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Fingerprint_pattern,
            title: "Filter entity",
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
              Dropdown($$renderer5, {
                position: dropdownPosition,
                minWidth: "12rem",
                children: ($$renderer6) => {
                  $$renderer6.push(`<div class="max-h-64 overflow-y-auto">`);
                  DropdownHeader($$renderer6, { label: "Entity" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, {
                    label: "All",
                    selected: activeEntities.size === 0
                  });
                  $$renderer6.push(`<!----> <!--[-->`);
                  const each_array = ensure_array_like(entityKeys);
                  for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                    let entity = each_array[$$index];
                    DropdownItem($$renderer6, {
                      label: entityLabels[entity] ?? formatEntity3(entity),
                      selected: activeEntities.has(entity)
                    });
                  }
                  $$renderer6.push(`<!--]--></div>`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Triangle_alert,
            title: "Filter reason",
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
              Dropdown($$renderer5, {
                position: dropdownPosition,
                minWidth: "12rem",
                children: ($$renderer6) => {
                  $$renderer6.push(`<div class="max-h-64 overflow-y-auto">`);
                  DropdownHeader($$renderer6, { label: "Reason" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, {
                    label: "All",
                    selected: activeReasons.size === 0
                  });
                  $$renderer6.push(`<!----> <!--[-->`);
                  const each_array_1 = ensure_array_like(reasonKeys);
                  for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                    let reason = each_array_1[$$index_1];
                    const label = (reasonLabels[reason] ?? reason) || "Unknown";
                    DropdownItem($$renderer6, {
                      label,
                      selected: activeReasons.has(reason)
                    });
                  }
                  $$renderer6.push(`<!--]--></div>`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Info,
            title: "About conflict actions"
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> <div class="mt-6 space-y-4">`);
      if (filteredGroups.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center text-sm text-neutral-600 dark:border-neutral-800 dark:bg-neutral-900 dark:text-neutral-400">No conflicts detected</div>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--[-->`);
        const each_array_2 = ensure_array_like(filteredGroups);
        for (let $$index_4 = 0, $$length = each_array_2.length; $$index_4 < $$length; $$index_4++) {
          let group = each_array_2[$$index_4];
          ExpandableCard($$renderer3, {
            title: group.title,
            description: group.conflicts.length > 1 ? `${group.conflicts.length} fields conflicted` : "",
            open: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="divide-y divide-neutral-200 dark:divide-neutral-800"><!--[-->`);
              const each_array_3 = ensure_array_like(group.conflicts);
              for (let $$index_3 = 0, $$length2 = each_array_3.length; $$index_3 < $$length2; $$index_3++) {
                let row = each_array_3[$$index_3];
                $$renderer4.push(`<div class="flex flex-col gap-4 px-4 py-4 md:flex-row md:items-start md:justify-between"><div class="flex-1 space-y-3"><div class="flex flex-wrap items-center gap-2 text-xs"><span class="font-mono text-neutral-500 dark:text-neutral-400">#${escape_html(row.opId)}</span> `);
                Label($$renderer4, {
                  variant: reasonVariant(row.conflictReason),
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->${escape_html(reasonLabel(row.conflictReason))}`);
                  },
                  $$slots: { default: true }
                });
                $$renderer4.push(`<!----></div> `);
                if (row.complex) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">Complex change \xB7 ${escape_html(row.summary ?? row.title)}</p>`);
                } else if (row.fields.length === 0) {
                  $$renderer4.push("<!--[1-->");
                  $$renderer4.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(row.summary ?? row.title)}</p>`);
                } else {
                  $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<div class="space-y-4"><!--[-->`);
                  const each_array_4 = ensure_array_like(row.fields);
                  for (let $$index_2 = 0, $$length3 = each_array_4.length; $$index_2 < $$length3; $$index_2++) {
                    let field = each_array_4[$$index_2];
                    ConflictField($$renderer4, {
                      field: field.field,
                      was: field.was,
                      you: field.you,
                      upstreamNow: field.upstreamNow
                    });
                  }
                  $$renderer4.push(`<!--]--></div>`);
                }
                $$renderer4.push(`<!--]--></div> <div class="flex shrink-0 items-center gap-2"><form method="POST" action="?/align"><input type="hidden" name="opId"${attr("value", row.opId)}/> `);
                Button($$renderer4, {
                  icon: Heart_handshake,
                  text: "Align",
                  variant: "secondary",
                  iconColor: "text-emerald-600 dark:text-emerald-400",
                  size: "sm",
                  type: "submit"
                });
                $$renderer4.push(`<!----></form> <form method="POST" action="?/override"><input type="hidden" name="opId"${attr("value", row.opId)}/> `);
                Button($$renderer4, {
                  icon: Hand_metal,
                  text: "Override",
                  variant: "secondary",
                  iconColor: "text-accent-600 dark:text-accent-400",
                  size: "sm",
                  type: "submit"
                });
                $$renderer4.push(`<!----></form></div></div>`);
              }
              $$renderer4.push(`<!--]--></div>`);
            },
            $$slots: {
              default: true,
              "header-right": ($$renderer4) => {
                Label($$renderer4, {
                  variant: entityVariant(group.entity),
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->${escape_html(entityLabel2(group.entity))}`);
                  },
                  $$slots: { default: true }
                });
              }
            }
          });
        }
        $$renderer3.push(`<!--]-->`);
      }
      $$renderer3.push(`<!--]--></div> `);
      InfoModal($$renderer3, {
        header: "Conflict Actions",
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-700 dark:text-neutral-300"><section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Align</h3> <p>Align accepts the database version and discards your local change for this conflict.</p></section> <section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Override</h3> <p>Override keeps your local change and reapplies it on top of the new version.</p></section></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte31 = __esm({
  "dist/build/server/entries/pages/databases/_id_/conflicts/_page.svelte.js"() {
    "use strict";
    init_server();
    init_Dropdown();
    init_Icon();
    init_info();
    init_Button();
    init_search();
    init_triangle_alert();
    init_stores();
    init_store2();
    init_Label();
    init_forms();
    init_DropdownItem();
    init_ActionsBar();
    init_ActionButton();
    init_DropdownHeader();
    init_InfoModal();
    init_PageMeta();
    init_ExpandableCard();
  }
});

// dist/build/server/nodes/39.js
var __exports40 = {};
__export(__exports40, {
  component: () => component38,
  fonts: () => fonts40,
  imports: () => imports40,
  index: () => index40,
  server: () => page_server_ts_exports32,
  server_id: () => server_id38,
  stylesheets: () => stylesheets40
});
var index40, component_cache38, component38, server_id38, imports40, stylesheets40, fonts40;
var init__40 = __esm({
  async "dist/build/server/nodes/39.js"() {
    "use strict";
    await init_page_server_ts32();
    index40 = 39;
    component38 = async () => component_cache38 ??= (await Promise.resolve().then(() => (init_page_svelte31(), page_svelte_exports31))).default;
    server_id38 = "src/routes/databases/[id]/conflicts/+page.server.ts";
    imports40 = ["_app/immutable/nodes/39.cykWwFOt.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cf96lmLi2.js", "_app/immutable/chunks/_ZYKMtmp.js"];
    stylesheets40 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css"];
    fonts40 = [];
  }
});

// dist/build/server/chunks/validate.js
function normalizeGitHubRepoUrl(repositoryUrl) {
  const trimmed = repositoryUrl.trim();
  const withoutGitSuffix = trimmed.endsWith(".git") ? trimmed.slice(0, -4) : trimmed;
  if (withoutGitSuffix.startsWith("git@github.com:")) return `github.com/${withoutGitSuffix.slice(15)}`.toLowerCase();
  const withScheme = /^https?:\/\//i.test(withoutGitSuffix) ? withoutGitSuffix : `https://${withoutGitSuffix}`;
  try {
    const url = new URL(withScheme);
    const pathname = url.pathname.replace(/^\/+|\/+$/g, "");
    return `${url.hostname}/${pathname}`.toLowerCase();
  } catch {
    return null;
  }
}
function defaultBranchForRepository(repositoryUrl, branch2) {
  if (branch2) return branch2;
  return normalizeGitHubRepoUrl(repositoryUrl) === FIRST_PARTY_DATABASE_REPO ? FIRST_PARTY_DATABASE_BRANCH : void 0;
}
function validateLinkInput(body) {
  const name = typeof body.name === "string" ? body.name.trim() : "";
  const repositoryUrl = typeof body.repository_url === "string" ? body.repository_url.trim() : "";
  if (!name || !repositoryUrl) return {
    ok: false,
    error: "Name and repository URL are required"
  };
  const branch2 = defaultBranchForRepository(repositoryUrl, typeof body.branch === "string" && body.branch.trim() ? body.branch.trim() : void 0);
  const personalAccessToken = typeof body.personal_access_token === "string" && body.personal_access_token.trim() ? body.personal_access_token.trim() : void 0;
  const gitUserName = typeof body.git_user_name === "string" && body.git_user_name.trim() ? body.git_user_name.trim() : void 0;
  const gitUserEmail = typeof body.git_user_email === "string" && body.git_user_email.trim() ? body.git_user_email.trim() : void 0;
  if (personalAccessToken && (!gitUserName || !gitUserEmail)) return {
    ok: false,
    error: "Git author name and email are required when a personal access token is set"
  };
  const localOpsEnabled = body.local_ops_enabled === true || body.local_ops_enabled === 1;
  const autoPull = body.auto_pull === true || body.auto_pull === 1;
  if (localOpsEnabled && !personalAccessToken) return {
    ok: false,
    error: "local_ops_enabled requires a personal access token"
  };
  const rawConflictStrategy = typeof body.conflict_strategy === "string" ? body.conflict_strategy.trim() : void 0;
  let conflictStrategy = "override";
  if (rawConflictStrategy) {
    if (!VALID_CONFLICT_STRATEGIES.includes(rawConflictStrategy)) return {
      ok: false,
      error: `conflict_strategy must be one of: ${VALID_CONFLICT_STRATEGIES.join(", ")}`
    };
    conflictStrategy = rawConflictStrategy;
    if (personalAccessToken && !localOpsEnabled) return {
      ok: false,
      error: "conflict_strategy cannot be set when using a PAT without local_ops_enabled"
    };
  }
  return {
    ok: true,
    input: {
      name,
      repositoryUrl,
      branch: branch2,
      personalAccessToken,
      gitUserName,
      gitUserEmail,
      syncStrategy: typeof body.sync_strategy === "number" ? Math.floor(body.sync_strategy) : typeof body.sync_strategy === "string" ? parseInt(body.sync_strategy, 10) || 0 : 0,
      autoPull,
      localOpsEnabled,
      conflictStrategy
    }
  };
}
function validateUpdateInput(body) {
  const input = {};
  if (typeof body.name === "string") {
    const name = body.name.trim();
    if (!name) return {
      ok: false,
      error: "Name cannot be empty"
    };
    input.name = name;
  }
  if (typeof body.personal_access_token === "string") input.personalAccessToken = body.personal_access_token.trim() || void 0;
  if (typeof body.git_user_name === "string") input.gitUserName = body.git_user_name.trim() || null;
  if (typeof body.git_user_email === "string") input.gitUserEmail = body.git_user_email.trim() || null;
  if (body.sync_strategy !== void 0) input.syncStrategy = typeof body.sync_strategy === "number" ? Math.floor(body.sync_strategy) : typeof body.sync_strategy === "string" ? parseInt(body.sync_strategy, 10) || 0 : 0;
  if (body.auto_pull !== void 0) input.autoPull = body.auto_pull === true || body.auto_pull === 1;
  if (body.local_ops_enabled !== void 0) input.localOpsEnabled = body.local_ops_enabled === true || body.local_ops_enabled === 1;
  if (typeof body.conflict_strategy === "string") {
    const raw = body.conflict_strategy.trim();
    if (!VALID_CONFLICT_STRATEGIES.includes(raw)) return {
      ok: false,
      error: `conflict_strategy must be one of: ${VALID_CONFLICT_STRATEGIES.join(", ")}`
    };
    input.conflictStrategy = raw;
  }
  if (Object.keys(input).length === 0) return {
    ok: false,
    error: "No updatable fields provided"
  };
  if (input.personalAccessToken && !input.gitUserName && !input.gitUserEmail) return {
    ok: false,
    error: "Git author name and email are required when a personal access token is set"
  };
  if (input.localOpsEnabled && !input.personalAccessToken) return {
    ok: false,
    error: "local_ops_enabled requires a personal access token"
  };
  if (input.conflictStrategy && input.personalAccessToken && !input.localOpsEnabled) return {
    ok: false,
    error: "conflict_strategy cannot be set when using a PAT without local_ops_enabled"
  };
  return {
    ok: true,
    input
  };
}
function checkNameConflict(name, excludeId) {
  return databaseInstancesQueries.nameExists(name, excludeId);
}
var VALID_CONFLICT_STRATEGIES, FIRST_PARTY_DATABASE_BRANCH, FIRST_PARTY_DATABASE_REPO;
var init_validate = __esm({
  async "dist/build/server/chunks/validate.js"() {
    "use strict";
    await init_databaseInstances();
    VALID_CONFLICT_STRATEGIES = [
      "override",
      "align",
      "ask"
    ];
    FIRST_PARTY_DATABASE_BRANCH = "v2";
    FIRST_PARTY_DATABASE_REPO = "github.com/dictionarry-hub/database";
  }
});

// dist/build/server/entries/pages/databases/_id_/settings/_page.server.ts.js
var page_server_ts_exports33 = {};
__export(page_server_ts_exports33, {
  actions: () => actions24
});
var actions24;
var init_page_server_ts33 = __esm({
  async "dist/build/server/entries/pages/databases/_id_/settings/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_databaseInstances();
    await init_queueService();
    await init_validate();
    await init_init();
    init_exports();
    actions24 = {
      update: async ({ params, request }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) {
          await logger.warn("Update failed: Invalid database ID", {
            source: "databases/[id]/settings",
            meta: { id: params.id }
          });
          return fail(400, { error: "Invalid database ID" });
        }
        const instance = databaseInstancesQueries.getById(id);
        if (!instance) {
          await logger.warn("Update failed: Database not found", {
            source: "databases/[id]/settings",
            meta: { id }
          });
          return fail(404, { error: "Database not found" });
        }
        const formData = await request.formData();
        const raw = {};
        raw.name = formData.get("name")?.toString();
        raw.sync_strategy = formData.get("sync_strategy")?.toString();
        raw.auto_pull = formData.get("auto_pull") === "1";
        raw.local_ops_enabled = formData.get("local_ops_enabled") === "1";
        const pat = formData.get("personal_access_token")?.toString().trim();
        if (pat) raw.personal_access_token = pat;
        if (formData.has("git_user_name")) raw.git_user_name = formData.get("git_user_name")?.toString();
        if (formData.has("git_user_email")) raw.git_user_email = formData.get("git_user_email")?.toString();
        const cs = formData.get("conflict_strategy")?.toString().trim();
        if (cs) raw.conflict_strategy = cs;
        const result = validateUpdateInput(raw);
        if (!result.ok) return fail(400, {
          error: result.error,
          values: { name: raw.name }
        });
        const { input } = result;
        if (input.name && checkNameConflict(input.name, id)) {
          await logger.warn("Attempted to update database with duplicate name", {
            source: "databases/[id]/settings",
            meta: {
              id,
              name: input.name
            }
          });
          return fail(400, {
            error: "A database with this name already exists",
            values: { name: input.name }
          });
        }
        try {
          if (!databaseInstancesQueries.update(id, input)) throw new Error("Update returned false");
          await logger.info(`Updated database: ${input.name ?? instance.name}`, {
            source: "databases/[id]/settings",
            meta: {
              id,
              name: input.name ?? instance.name
            }
          });
          schedulePcdSyncForDatabase(id);
          return { success: true };
        } catch (err) {
          await logger.error("Failed to update database", {
            source: "databases/[id]/settings",
            meta: { error: err instanceof Error ? err.message : String(err) }
          });
          return fail(500, {
            error: "Failed to update database",
            values: { name: input.name }
          });
        }
      },
      delete: async ({ params }) => {
        const id = parseInt(params.id || "", 10);
        if (isNaN(id)) {
          await logger.warn("Delete failed: Invalid database ID", {
            source: "databases/[id]/settings",
            meta: { id: params.id }
          });
          return fail(400, { error: "Invalid database ID" });
        }
        const instance = databaseInstancesQueries.getById(id);
        if (!instance) {
          await logger.warn("Delete failed: Database not found", {
            source: "databases/[id]/settings",
            meta: { id }
          });
          return fail(404, { error: "Database not found" });
        }
        try {
          await pcdManager.unlink(id);
          await logger.info(`Unlinked database: ${instance.name}`, {
            source: "databases/[id]/settings",
            meta: {
              id,
              name: instance.name,
              repositoryUrl: instance.repository_url
            }
          });
          redirect(303, "/databases");
        } catch (err) {
          if (err && typeof err === "object" && "status" in err && "location" in err) throw err;
          await logger.error("Failed to unlink database", {
            source: "databases/[id]/settings",
            meta: { error: err instanceof Error ? err.message : String(err) }
          });
          return fail(500, { error: "Failed to unlink database" });
        }
      }
    };
  }
});

// dist/build/server/chunks/InstanceForm2.js
function Git_fork($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "git-fork" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "12",
        "cy": "18",
        "r": "3"
      }],
      ["circle", {
        "cx": "6",
        "cy": "6",
        "r": "3"
      }],
      ["circle", {
        "cx": "18",
        "cy": "6",
        "r": "3"
      }],
      ["path", { "d": "M18 9v2c0 .6-.4 1-1 1H7c-.6 0-1-.4-1-1V9" }],
      ["path", { "d": "M12 12v3" }]
    ] }
  ]));
}
function InstanceForm2($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let name, repositoryUrl, branch2, personalAccessToken, gitUserName, gitUserEmail, localOpsEnabled, conflictStrategy, syncStrategy, autoPull, showGitIdentity, requiresGitIdentity, canSubmit, title, description;
    let mode = $$props["mode"];
    let instance = fallback($$props["instance"], void 0);
    let repoInfo = fallback($$props["repoInfo"], null);
    let currentBranch = fallback($$props["currentBranch"], "");
    let form = fallback($$props["form"], void 0);
    let data = fallback($$props["data"], void 0);
    let deleting = false;
    let showDeleteModal = false;
    const syncStrategyOptions = [
      {
        value: "0",
        label: "Manual (no auto-sync)"
      },
      {
        value: "5",
        label: "Every 5 minutes"
      },
      {
        value: "15",
        label: "Every 15 minutes"
      },
      {
        value: "30",
        label: "Every 30 minutes"
      },
      {
        value: "60",
        label: "Every hour"
      },
      {
        value: "360",
        label: "Every 6 hours"
      },
      {
        value: "720",
        label: "Every 12 hours"
      },
      {
        value: "1440",
        label: "Every 24 hours"
      }
    ];
    const autoPullOptions = [{
      value: "true",
      label: "Enabled"
    }, {
      value: "false",
      label: "Disabled"
    }];
    const localOpsOptions = [{
      value: "false",
      label: "Disabled"
    }, {
      value: "true",
      label: "Enabled"
    }];
    const conflictStrategyOptions = [
      {
        value: "override",
        label: "Override (default)"
      },
      {
        value: "align",
        label: "Align"
      },
      {
        value: "ask",
        label: "Ask every time"
      }
    ];
    let lastFormId = null;
    $: name = store_get($$store_subs ??= {}, "$current", current2).name ?? "";
    $: repositoryUrl = store_get($$store_subs ??= {}, "$current", current2).repositoryUrl ?? "";
    $: branch2 = store_get($$store_subs ??= {}, "$current", current2).branch ?? "";
    $: personalAccessToken = store_get($$store_subs ??= {}, "$current", current2).personalAccessToken ?? "";
    $: gitUserName = store_get($$store_subs ??= {}, "$current", current2).gitUserName ?? "";
    $: gitUserEmail = store_get($$store_subs ??= {}, "$current", current2).gitUserEmail ?? "";
    $: localOpsEnabled = store_get($$store_subs ??= {}, "$current", current2).localOpsEnabled ?? "false";
    $: conflictStrategy = store_get($$store_subs ??= {}, "$current", current2).conflictStrategy ?? "override";
    $: syncStrategy = store_get($$store_subs ??= {}, "$current", current2).syncStrategy ?? "60";
    $: autoPull = store_get($$store_subs ??= {}, "$current", current2).autoPull ?? "true";
    $: showGitIdentity = !!personalAccessToken || mode === "edit" && !!instance?.hasPat;
    $: requiresGitIdentity = !!personalAccessToken;
    $: canSubmit = store_get($$store_subs ??= {}, "$isDirty", isDirty) && !!name && (mode === "edit" || !!repositoryUrl) && (!requiresGitIdentity || !!gitUserName && !!gitUserEmail);
    $: if (form && form !== lastFormId) {
      lastFormId = form;
      if (form.success) {
        alertStore.add("success", "Settings saved successfully");
        initEdit({
          name,
          repositoryUrl,
          personalAccessToken: "",
          gitUserName,
          gitUserEmail,
          localOpsEnabled,
          conflictStrategy,
          syncStrategy,
          autoPull
        });
      }
      if (form.error) alertStore.add("error", form.error);
    }
    $: title = mode === "create" ? "Link Database" : "Settings";
    $: description = mode === "create" ? "Link a Profilarr Compliant Database from a Git repository." : `Configure settings for ${instance?.name || "this database"}.`;
    $$renderer2.push(`<div class="space-y-6"><div data-onboarding="db-header">`);
    StickyCard($$renderer2, {
      position: "top",
      $$slots: {
        left: ($$renderer3) => {
          if (mode === "edit") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex items-center gap-3">`);
            if (repoInfo) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<img${attr("src", repoInfo.ownerAvatarUrl)}${attr("alt", repoInfo.owner)} class="h-8 w-8 rounded-lg"/> <div class="flex flex-col gap-1"><code class="text-sm text-neutral-700 dark:text-neutral-300" style="font-family: var(--font-code)">${escape_html(repoInfo.owner)}/${escape_html(repoInfo.repo)}</code> <div class="flex items-center gap-3 text-xs text-neutral-500 dark:text-neutral-400">`);
              if (currentBranch) {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<span class="flex items-center gap-1">`);
                Git_branch($$renderer3, { size: 12 });
                $$renderer3.push(`<!----> <code style="font-family: var(--font-code)">${escape_html(currentBranch)}</code></span>`);
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--> <span class="flex items-center gap-1">`);
              Star($$renderer3, { size: 12 });
              $$renderer3.push(`<!----> <code style="font-family: var(--font-code)">${escape_html(repoInfo.stars.toLocaleString())}</code></span> <span class="flex items-center gap-1">`);
              Git_fork($$renderer3, { size: 12 });
              $$renderer3.push(`<!----> <code style="font-family: var(--font-code)">${escape_html(repoInfo.forks.toLocaleString())}</code></span> <span class="flex items-center gap-1">`);
              Circle_dot($$renderer3, { size: 12 });
              $$renderer3.push(`<!----> <code style="font-family: var(--font-code)">${escape_html(repoInfo.openIssues.toLocaleString())}</code></span></div></div>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<div class="flex h-8 w-8 items-center justify-center rounded-lg bg-neutral-100 dark:bg-neutral-700">`);
              Database2($$renderer3, {
                size: 16,
                class: "text-neutral-500 dark:text-neutral-400"
              });
              $$renderer3.push(`<!----></div> <div class="flex flex-col gap-1"><span class="text-sm font-medium text-neutral-700 dark:text-neutral-300">${escape_html(instance?.name ?? "Database")}</span> `);
              if (instance?.repository_url) {
                $$renderer3.push("<!--[0-->");
                $$renderer3.push(`<code class="font-mono text-xs text-neutral-500 dark:text-neutral-400">${escape_html(instance.repository_url.replace("https://github.com/", ""))}</code>`);
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--></div>`);
            }
            $$renderer3.push(`<!--]--></div>`);
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<h1 class="text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h1> <p class="text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p>`);
          }
          $$renderer3.push(`<!--]-->`);
        },
        right: ($$renderer3) => {
          if (mode === "edit") {
            $$renderer3.push("<!--[0-->");
            Button($$renderer3, {
              text: "Unlink",
              icon: Trash_2,
              iconColor: "text-red-600 dark:text-red-400",
              disabled: deleting
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> <div data-onboarding="db-save">`);
          Button($$renderer3, {
            text: "Save",
            icon: Save,
            iconColor: "text-blue-600 dark:text-blue-400",
            disabled: !canSubmit
          });
          $$renderer3.push(`<!----></div> `);
          if (mode === "edit") {
            $$renderer3.push("<!--[0-->");
            Button($$renderer3, {
              href: repoInfo?.htmlUrl ?? instance?.repository_url,
              target: "_blank",
              rel: "noopener noreferrer",
              icon: External_link,
              iconColor: "text-blue-600 dark:text-blue-400",
              text: "GitHub"
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        }
      }
    });
    $$renderer2.push(`<!----></div> <div class="space-y-4 rounded-lg border border-neutral-200 bg-white p-4 dark:border-neutral-800 dark:bg-neutral-900"><div data-onboarding="db-name-repo-branch" class="space-y-4">`);
    FormInput($$renderer2, {
      label: "Name",
      name: "name",
      value: name,
      placeholder: "e.g., Main Database, 4K Profiles",
      description: "A friendly name to identify this database",
      required: true
    });
    $$renderer2.push(`<!----> `);
    FormInput($$renderer2, {
      label: "Repository URL",
      name: "repository_url",
      type: "url",
      value: repositoryUrl,
      placeholder: "https://github.com/username/database",
      description: mode === "edit" ? "Repository URL cannot be changed after linking" : "Git repository URL containing the PCD manifest",
      required: true,
      readonly: mode === "edit"
    });
    $$renderer2.push(`<!----> `);
    if (mode === "create") {
      $$renderer2.push("<!--[0-->");
      FormInput($$renderer2, {
        label: "Branch",
        name: "branch",
        value: branch2,
        placeholder: "main",
        description: "Branch to checkout on link. Cannot be changed after linking. Leave empty for the default branch."
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div> <div data-onboarding="db-pat">`);
    FormInput($$renderer2, {
      label: "Personal Access Token",
      name: "personal_access_token",
      value: personalAccessToken,
      placeholder: "ghp_...",
      description: mode === "edit" ? "Re-enter to update. Required for private repos and to push changes." : "Required for private repositories and to push changes back to GitHub.",
      private_: true
    });
    $$renderer2.push(`<!----></div> `);
    if (showGitIdentity) {
      $$renderer2.push("<!--[0-->");
      FormInput($$renderer2, {
        label: "Git Author Name",
        name: "git_user_name",
        value: gitUserName,
        placeholder: "e.g., Jane Doe",
        description: "Used for commits when exporting changes to Git.",
        required: requiresGitIdentity
      });
      $$renderer2.push(`<!----> `);
      FormInput($$renderer2, {
        label: "Git Author Email",
        name: "git_user_email",
        type: "email",
        value: gitUserEmail,
        placeholder: "jane@example.com",
        description: "Used for commits when exporting changes to Git.",
        required: requiresGitIdentity
      });
      $$renderer2.push(`<!---->`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (showGitIdentity) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="space-y-2"><span class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Local Ops Only</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Force changes to save as local user ops even when a personal access token is set.</p> `);
      DropdownSelect($$renderer2, {
        value: localOpsEnabled,
        options: localOpsOptions,
        fullWidth: true
      });
      $$renderer2.push(`<!----></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (!showGitIdentity || localOpsEnabled === "true") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div data-onboarding="db-conflict" class="space-y-2"><span class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Conflict Strategy</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">How to handle user ops that conflict with upstream changes.</p> <ul class="list-disc space-y-1 pl-5 text-xs text-neutral-500 dark:text-neutral-400"><li><span class="font-medium text-neutral-700 dark:text-neutral-200">Override:</span> reapply your local change with updated guards.</li> <li><span class="font-medium text-neutral-700 dark:text-neutral-200">Align:</span> drop the local op and accept upstream changes.</li> <li><span class="font-medium text-neutral-700 dark:text-neutral-200">Ask:</span> mark conflicts as pending for manual review.</li></ul> `);
      DropdownSelect($$renderer2, {
        value: conflictStrategy,
        options: conflictStrategyOptions,
        fullWidth: true
      });
      $$renderer2.push(`<!----></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div data-onboarding="db-sync" class="space-y-4"><div class="space-y-2"><span class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Sync Strategy</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">How often to check for updates from the remote repository</p> `);
    DropdownSelect($$renderer2, {
      value: syncStrategy,
      options: syncStrategyOptions,
      fullWidth: true
    });
    $$renderer2.push(`<!----></div> <div class="space-y-2"><span class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Auto Pull</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Automatically pull updates when available, or just receive notifications</p> `);
    DropdownSelect($$renderer2, {
      value: autoPull,
      options: autoPullOptions
    });
    $$renderer2.push(`<!----></div> `);
    if (autoPull === "false") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<p class="text-xs text-amber-600 dark:text-amber-400">You will receive notifications when updates are available but they won't be applied
					automatically</p>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div></div></div> <form id="save-form" method="POST"${attr("action", mode === "edit" ? "?/update" : void 0)} class="hidden"><input type="hidden" name="name"${attr("value", name)}/> <input type="hidden" name="repository_url"${attr("value", repositoryUrl)}/> `);
    if (mode === "create") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<input type="hidden" name="branch"${attr("value", branch2)}/>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <input type="hidden" name="personal_access_token"${attr("value", personalAccessToken)}/> <input type="hidden" name="git_user_name"${attr("value", gitUserName)}/> <input type="hidden" name="git_user_email"${attr("value", gitUserEmail)}/> <input type="hidden" name="local_ops_enabled"${attr("value", localOpsEnabled === "true" ? "1" : "0")}/> `);
    if (!showGitIdentity || localOpsEnabled === "true") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<input type="hidden" name="conflict_strategy"${attr("value", conflictStrategy)}/>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <input type="hidden" name="sync_strategy"${attr("value", syncStrategy)}/> <input type="hidden" name="auto_pull"${attr("value", autoPull === "true" ? "1" : "0")}/></form> `);
    if (mode === "edit") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<form id="delete-form" method="POST" action="?/delete" class="hidden"></form>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    if (mode === "edit") {
      $$renderer2.push("<!--[0-->");
      Modal($$renderer2, {
        open: showDeleteModal,
        header: "Unlink Database",
        bodyMessage: `Are you sure you want to unlink "${instance?.name}"? This action cannot be undone and all local data will be permanently removed.`,
        confirmText: "Unlink",
        cancelText: "Cancel",
        confirmDanger: true
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      instance,
      repoInfo,
      currentBranch,
      form,
      data
    });
  });
}
var init_InstanceForm2 = __esm({
  "dist/build/server/chunks/InstanceForm2.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Icon();
    init_circle_dot();
    init_database2();
    init_external_link();
    init_git_branch();
    init_Button();
    init_save();
    init_star();
    init_trash_2();
    init_store2();
    init_jobStatus();
    init_Modal();
    init_forms();
    init_dirty();
    init_DirtyModal();
    init_StickyCard();
    init_DropdownSelect();
    init_FormInput();
  }
});

// dist/build/server/entries/pages/databases/_id_/settings/_page.svelte.js
var page_svelte_exports32 = {};
__export(page_svelte_exports32, {
  default: () => _page32
});
function _page32($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let form = $$props["form"];
    let data = $$props["data"];
    PageMeta($$renderer2, { title: `${data.database.name} \xB7 Settings` });
    $$renderer2.push(`<!----> <div>`);
    InstanceForm2($$renderer2, {
      mode: "edit",
      form,
      instance: data.database,
      repoInfo: data.repoInfo,
      currentBranch: data.currentBranch
    });
    $$renderer2.push(`<!----></div>`);
    bind_props($$props, {
      form,
      data
    });
  });
}
var init_page_svelte32 = __esm({
  "dist/build/server/entries/pages/databases/_id_/settings/_page.svelte.js"() {
    "use strict";
    init_server();
    init_InstanceForm2();
    init_PageMeta();
  }
});

// dist/build/server/nodes/40.js
var __exports41 = {};
__export(__exports41, {
  component: () => component39,
  fonts: () => fonts41,
  imports: () => imports41,
  index: () => index41,
  server: () => page_server_ts_exports33,
  server_id: () => server_id39,
  stylesheets: () => stylesheets41
});
var index41, component_cache39, component39, server_id39, imports41, stylesheets41, fonts41;
var init__41 = __esm({
  async "dist/build/server/nodes/40.js"() {
    "use strict";
    await init_page_server_ts33();
    index41 = 40;
    component39 = async () => component_cache39 ??= (await Promise.resolve().then(() => (init_page_svelte32(), page_svelte_exports32))).default;
    server_id39 = "src/routes/databases/[id]/settings/+page.server.ts";
    imports41 = ["_app/immutable/nodes/40.BlPX3H4N.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/B4RcM6Xj.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/By4o5e8D2.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/CqoQtmn5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/DuBlSUgq.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets41 = [];
    fonts41 = [];
  }
});

// dist/build/server/entries/pages/databases/_id_/tweaks/_page.server.ts.js
var page_server_ts_exports34 = {};
__export(page_server_ts_exports34, {
  load: () => load37
});
var load37;
var init_page_server_ts34 = __esm({
  "dist/build/server/entries/pages/databases/_id_/tweaks/_page.server.ts.js"() {
    "use strict";
    load37 = () => {
      return {};
    };
  }
});

// dist/build/server/entries/pages/databases/_id_/tweaks/_page.svelte.js
var page_svelte_exports33 = {};
__export(page_svelte_exports33, {
  default: () => _page33
});
function _page33($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: `${data.database.name} \xB7 Tweaks` });
    $$renderer2.push(`<!----> <div class="mt-6"><div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-500 dark:text-neutral-400">No tweaks available for this database.</p></div></div>`);
    bind_props($$props, { data });
  });
}
var init_page_svelte33 = __esm({
  "dist/build/server/entries/pages/databases/_id_/tweaks/_page.svelte.js"() {
    "use strict";
    init_server();
    init_PageMeta();
  }
});

// dist/build/server/nodes/41.js
var __exports42 = {};
__export(__exports42, {
  component: () => component40,
  fonts: () => fonts42,
  imports: () => imports42,
  index: () => index42,
  server: () => page_server_ts_exports34,
  server_id: () => server_id40,
  stylesheets: () => stylesheets42
});
var index42, component_cache40, component40, server_id40, imports42, stylesheets42, fonts42;
var init__42 = __esm({
  "dist/build/server/nodes/41.js"() {
    "use strict";
    init_page_server_ts34();
    index42 = 41;
    component40 = async () => component_cache40 ??= (await Promise.resolve().then(() => (init_page_svelte33(), page_svelte_exports33))).default;
    server_id40 = "src/routes/databases/[id]/tweaks/+page.server.ts";
    imports42 = ["_app/immutable/nodes/41.HhiWNK4J.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets42 = [];
    fonts42 = [];
  }
});

// dist/build/server/entries/pages/databases/bruh/_page.server.ts.js
var page_server_ts_exports35 = {};
__export(page_server_ts_exports35, {
  load: () => load38
});
var load38;
var init_page_server_ts35 = __esm({
  "dist/build/server/entries/pages/databases/bruh/_page.server.ts.js"() {
    "use strict";
    load38 = ({ url }) => {
      return {
        url: url.searchParams.get("url") || "",
        type: url.searchParams.get("type") || "unknown",
        formData: {
          name: url.searchParams.get("name") || "",
          branch: url.searchParams.get("branch") || "",
          syncStrategy: url.searchParams.get("sync_strategy") || "",
          autoPull: url.searchParams.get("auto_pull") || "",
          localOpsEnabled: url.searchParams.get("local_ops_enabled") || ""
        }
      };
    };
  }
});

// dist/build/server/entries/pages/databases/bruh/_page.svelte.js
var page_svelte_exports34 = {};
__export(page_svelte_exports34, {
  default: () => _page34
});
function _page34($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let embedUrl;
    let data = $$props["data"];
    function getYouTubeEmbedUrl(url) {
      const videoIdMatch = url.match(/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&\n?#]+)/);
      if (videoIdMatch) return `https://www.youtube.com/embed/${videoIdMatch[1]}?autoplay=1`;
      return "";
    }
    $: embedUrl = data.type === "youtube" ? getYouTubeEmbedUrl(data.url) : "";
    PageMeta($$renderer2, { title: "Bruh" });
    $$renderer2.push(`<!----> <div class="flex min-h-screen items-center bg-white p-8 dark:bg-neutral-950"><div class="mx-auto w-full max-w-4xl space-y-6"><div class="text-center"><p class="text-2xl font-medium text-neutral-900 dark:text-neutral-50">If you insist...</p></div> <div class="overflow-hidden rounded-2xl border border-neutral-200 bg-white shadow-2xl dark:border-neutral-800 dark:bg-neutral-900">`);
    if (data.type === "youtube" && embedUrl) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="aspect-video w-full"><iframe${attr("src", embedUrl)} title="YouTube video" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" class="h-full w-full"></iframe></div>`);
    } else if (data.type === "twitter") {
      $$renderer2.push("<!--[1-->");
      $$renderer2.push(`<div class="p-12 text-center"><p class="mb-4 text-2xl text-neutral-700 dark:text-neutral-300">Here's your tweet:</p> <a${attr("href", data.url)} target="_blank" rel="noopener noreferrer" class="text-xl text-blue-600 hover:underline dark:text-blue-400">${escape_html(data.url)}</a></div>`);
    } else if (data.type === "reddit") {
      $$renderer2.push("<!--[2-->");
      $$renderer2.push(`<div class="p-12 text-center"><p class="mb-4 text-2xl text-neutral-700 dark:text-neutral-300">Here's your Reddit post:</p> <a${attr("href", data.url)} target="_blank" rel="noopener noreferrer" class="text-xl text-blue-600 hover:underline dark:text-blue-400">${escape_html(data.url)}</a></div>`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="p-12 text-center"><p class="mb-4 text-2xl text-neutral-700 dark:text-neutral-300">Here's what you tried to link:</p> <a${attr("href", data.url)} target="_blank" rel="noopener noreferrer" class="text-xl text-blue-600 hover:underline dark:text-blue-400">${escape_html(data.url)}</a></div>`);
    }
    $$renderer2.push(`<!--]--></div> <div class="flex flex-wrap items-center justify-center gap-4 text-center text-neutral-600 dark:text-neutral-400"><p>You need to link a <strong class="text-neutral-900 dark:text-neutral-50">GitHub repository</strong></p> <a${attr("href", `/databases/new?name=${stringify(encodeURIComponent(data.formData.name))}&branch=${stringify(encodeURIComponent(data.formData.branch))}&sync_strategy=${stringify(encodeURIComponent(data.formData.syncStrategy))}&auto_pull=${stringify(encodeURIComponent(data.formData.autoPull))}&local_ops_enabled=${stringify(encodeURIComponent(data.formData.localOpsEnabled))}`)} class="inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white transition-colors hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600">`);
    Rotate_ccw($$renderer2, { size: 16 });
    $$renderer2.push(`<!----> Try Again</a></div></div></div>`);
    bind_props($$props, { data });
  });
}
var init_page_svelte34 = __esm({
  "dist/build/server/entries/pages/databases/bruh/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_rotate_ccw();
    init_store2();
    init_PageMeta();
  }
});

// dist/build/server/nodes/42.js
var __exports43 = {};
__export(__exports43, {
  component: () => component41,
  fonts: () => fonts43,
  imports: () => imports43,
  index: () => index43,
  server: () => page_server_ts_exports35,
  server_id: () => server_id41,
  stylesheets: () => stylesheets43
});
var index43, component_cache41, component41, server_id41, imports43, stylesheets43, fonts43;
var init__43 = __esm({
  "dist/build/server/nodes/42.js"() {
    "use strict";
    init_page_server_ts35();
    index43 = 42;
    component41 = async () => component_cache41 ??= (await Promise.resolve().then(() => (init_page_svelte34(), page_svelte_exports34))).default;
    server_id41 = "src/routes/databases/bruh/+page.server.ts";
    imports43 = ["_app/immutable/nodes/42.DhjJKOSv.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/DvoiSP5r.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets43 = [];
    fonts43 = [];
  }
});

// dist/build/server/entries/pages/databases/new/_page.server.ts.js
var page_server_ts_exports36 = {};
__export(page_server_ts_exports36, {
  actions: () => actions25,
  load: () => load39
});
function getFirstNonEmptyFormValue(formData, key2) {
  const values = formData.getAll(key2).map((value2) => value2.toString().trim()).filter((value2) => value2.length > 0);
  return values.length > 0 ? values[0] : void 0;
}
var load39, actions25;
var init_page_server_ts36 = __esm({
  async "dist/build/server/entries/pages/databases/new/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_queueService();
    await init_validate();
    init_exports();
    load39 = ({ url }) => {
      return { formData: {
        name: url.searchParams.get("name") || "",
        branch: url.searchParams.get("branch") || "",
        syncStrategy: url.searchParams.get("sync_strategy") || "",
        autoPull: url.searchParams.get("auto_pull") || "",
        localOpsEnabled: url.searchParams.get("local_ops_enabled") || "",
        gitUserName: url.searchParams.get("git_user_name") || "",
        gitUserEmail: url.searchParams.get("git_user_email") || ""
      } };
    };
    actions25 = { default: async ({ request }) => {
      const formData = await request.formData();
      const raw = {
        name: getFirstNonEmptyFormValue(formData, "name"),
        repository_url: getFirstNonEmptyFormValue(formData, "repository_url"),
        branch: getFirstNonEmptyFormValue(formData, "branch"),
        personal_access_token: getFirstNonEmptyFormValue(formData, "personal_access_token"),
        git_user_name: getFirstNonEmptyFormValue(formData, "git_user_name"),
        git_user_email: getFirstNonEmptyFormValue(formData, "git_user_email"),
        sync_strategy: formData.get("sync_strategy")?.toString() || "0",
        auto_pull: formData.get("auto_pull") === "1",
        local_ops_enabled: formData.get("local_ops_enabled") === "1"
      };
      const cs = formData.get("conflict_strategy")?.toString().trim();
      if (cs) raw.conflict_strategy = cs;
      const result = validateLinkInput(raw);
      if (!result.ok) return fail(400, {
        error: result.error,
        values: {
          name: raw.name,
          repository_url: raw.repository_url
        }
      });
      const { input } = result;
      const bruhParams = new URLSearchParams({
        name: input.name,
        branch: input.branch || "",
        sync_strategy: input.syncStrategy.toString(),
        auto_pull: input.autoPull ? "1" : "0",
        local_ops_enabled: input.localOpsEnabled ? "1" : "0",
        git_user_name: input.gitUserName || "",
        git_user_email: input.gitUserEmail || ""
      });
      if (input.repositoryUrl.includes("youtube.com") || input.repositoryUrl.includes("youtu.be")) redirect(303, `/databases/bruh?url=${encodeURIComponent(input.repositoryUrl)}&type=youtube&${bruhParams.toString()}`);
      if (input.repositoryUrl.includes("twitter.com") || input.repositoryUrl.includes("x.com")) redirect(303, `/databases/bruh?url=${encodeURIComponent(input.repositoryUrl)}&type=twitter&${bruhParams.toString()}`);
      if (input.repositoryUrl.includes("reddit.com")) redirect(303, `/databases/bruh?url=${encodeURIComponent(input.repositoryUrl)}&type=reddit&${bruhParams.toString()}`);
      if (checkNameConflict(input.name)) return fail(400, {
        error: "A database with this name already exists",
        values: {
          name: input.name,
          repository_url: input.repositoryUrl
        }
      });
      const patToken = input.personalAccessToken ? stashLinkPat(input.personalAccessToken) : void 0;
      enqueueJob({
        jobType: "pcd.link",
        runAt: (/* @__PURE__ */ new Date()).toISOString(),
        source: "manual",
        payload: {
          name: input.name,
          repositoryUrl: input.repositoryUrl,
          branch: input.branch,
          syncStrategy: input.syncStrategy,
          autoPull: input.autoPull,
          localOpsEnabled: input.localOpsEnabled,
          gitUserName: input.gitUserName,
          gitUserEmail: input.gitUserEmail,
          conflictStrategy: input.conflictStrategy,
          patToken
        }
      });
      await logger.info(`Queued database link: ${input.name}`, {
        source: "databases/new",
        meta: {
          name: input.name,
          repositoryUrl: input.repositoryUrl
        }
      });
      redirect(303, "/databases");
    } };
  }
});

// dist/build/server/entries/pages/databases/new/_page.svelte.js
var page_svelte_exports35 = {};
__export(page_svelte_exports35, {
  default: () => _page35
});
function _page35($$renderer, $$props) {
  let form = $$props["form"];
  let data = $$props["data"];
  PageMeta($$renderer, { title: "Database \xB7 New" });
  $$renderer.push(`<!----> <div class="p-4 md:p-8">`);
  InstanceForm2($$renderer, {
    mode: "create",
    form,
    data
  });
  $$renderer.push(`<!----></div>`);
  bind_props($$props, {
    form,
    data
  });
}
var init_page_svelte35 = __esm({
  "dist/build/server/entries/pages/databases/new/_page.svelte.js"() {
    "use strict";
    init_server();
    init_InstanceForm2();
    init_PageMeta();
  }
});

// dist/build/server/nodes/43.js
var __exports44 = {};
__export(__exports44, {
  component: () => component42,
  fonts: () => fonts44,
  imports: () => imports44,
  index: () => index44,
  server: () => page_server_ts_exports36,
  server_id: () => server_id42,
  stylesheets: () => stylesheets44
});
var index44, component_cache42, component42, server_id42, imports44, stylesheets44, fonts44;
var init__44 = __esm({
  async "dist/build/server/nodes/43.js"() {
    "use strict";
    await init_page_server_ts36();
    index44 = 43;
    component42 = async () => component_cache42 ??= (await Promise.resolve().then(() => (init_page_svelte35(), page_svelte_exports35))).default;
    server_id42 = "src/routes/databases/new/+page.server.ts";
    imports44 = ["_app/immutable/nodes/43.C1gn_RDj.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/B4RcM6Xj.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/By4o5e8D2.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/CqoQtmn5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/DuBlSUgq.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets44 = [];
    fonts44 = [];
  }
});

// dist/build/server/entries/pages/delay-profiles/_page.server.ts.js
var page_server_ts_exports37 = {};
__export(page_server_ts_exports37, {
  load: () => load40
});
var load40;
var init_page_server_ts37 = __esm({
  async "dist/build/server/entries/pages/delay-profiles/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_lastDatabase();
    load40 = ({ cookies }) => {
      redirectToLastDatabase(cookies, "last_db_dp", "/delay-profiles");
      return { databases: pcdManager.getAllPublic() };
    };
  }
});

// dist/build/server/entries/pages/delay-profiles/_page.svelte.js
var page_svelte_exports36 = {};
__export(page_svelte_exports36, {
  default: () => _page36
});
function _page36($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: "Delay Profiles" });
    $$renderer2.push(`<!----> `);
    if (data.databases.length === 0) {
      $$renderer2.push("<!--[0-->");
      EmptyState($$renderer2, {
        icon: Database2,
        title: "No Databases Linked",
        description: "Link a Profilarr Compliant Database to manage delay profiles.",
        buttonText: "Link Database",
        buttonHref: "/databases/new",
        buttonIcon: Plus
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte36 = __esm({
  "dist/build/server/entries/pages/delay-profiles/_page.svelte.js"() {
    "use strict";
    init_server();
    init_database2();
    init_plus();
    init_PageMeta();
    init_EmptyState();
  }
});

// dist/build/server/nodes/44.js
var __exports45 = {};
__export(__exports45, {
  component: () => component43,
  fonts: () => fonts45,
  imports: () => imports45,
  index: () => index45,
  server: () => page_server_ts_exports37,
  server_id: () => server_id43,
  stylesheets: () => stylesheets45
});
var index45, component_cache43, component43, server_id43, imports45, stylesheets45, fonts45;
var init__45 = __esm({
  async "dist/build/server/nodes/44.js"() {
    "use strict";
    await init_page_server_ts37();
    index45 = 44;
    component43 = async () => component_cache43 ??= (await Promise.resolve().then(() => (init_page_svelte36(), page_svelte_exports36))).default;
    server_id43 = "src/routes/delay-profiles/+page.server.ts";
    imports45 = ["_app/immutable/nodes/44.CVVv-Jvi.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D_awjkBZ.js", "_app/immutable/chunks/B66v-P2b.js"];
    stylesheets45 = [];
    fonts45 = [];
  }
});

// dist/build/server/entries/pages/delay-profiles/_databaseId_/_page.server.ts.js
var page_server_ts_exports38 = {};
__export(page_server_ts_exports38, {
  load: () => load41
});
var load41;
var init_page_server_ts38 = __esm({
  async "dist/build/server/entries/pages/delay-profiles/_databaseId_/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_lastDatabase();
    init_exports();
    load41 = async ({ params, cookies }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const databases = pcdManager.getAllPublic();
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = databases.find((db2) => db2.id === currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      setLastDatabase(cookies, "last_db_dp", currentDatabaseId);
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      return {
        databases,
        currentDatabase,
        delayProfiles: await list$4(cache3),
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
  }
});

// dist/build/server/entries/pages/delay-profiles/_databaseId_/_page.svelte.js
var page_svelte_exports37 = {};
__export(page_svelte_exports37, {
  default: () => _page37
});
function Zap($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "zap" },
    props,
    { iconNode: [["path", { "d": "M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z" }]] }
  ]));
}
function TableView4($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId;
    let profiles = $$props["profiles"];
    createEventDispatcher();
    function getRowHref(row) {
      return `/delay-profiles/${databaseId}/${encodeURIComponent(row.name)}`;
    }
    function formatProtocol(protocol2) {
      switch (protocol2) {
        case "prefer_usenet":
          return "Prefer Usenet";
        case "prefer_torrent":
          return "Prefer Torrent";
        case "only_usenet":
          return "Only Usenet";
        case "only_torrent":
          return "Only Torrent";
        default:
          return protocol2;
      }
    }
    function formatDelay(minutes) {
      if (minutes === null) return "-";
      if (minutes === 0) return "No delay";
      if (minutes < 60) return `${minutes}m`;
      const hours = Math.floor(minutes / 60);
      const mins = minutes % 60;
      return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
    }
    const columns = [
      {
        key: "name",
        header: "Name",
        headerIcon: Tag,
        align: "left",
        sortable: true,
        cell: (row) => ({ html: `<div class="font-medium">${escapeHtml(row.name)}</div>` })
      },
      {
        key: "preferred_protocol",
        header: "Protocol",
        headerIcon: Zap,
        align: "left",
        width: "w-44",
        cell: (row) => ({ html: `<span class="font-mono text-xs bg-neutral-100 dark:bg-neutral-800 px-2 py-0.5 rounded">${formatProtocol(row.preferred_protocol)}</span>` })
      },
      {
        key: "delays",
        header: "Delays",
        headerIcon: Clock,
        align: "left",
        width: "w-48",
        cell: (row) => ({ html: `
					<div class="text-xs space-y-0.5">
						${row.usenet_delay !== null ? `<div>Usenet: <span class="font-mono text-[10px] bg-neutral-100 dark:bg-neutral-800 px-1 rounded">${formatDelay(row.usenet_delay)}</span></div>` : ""}
						${row.torrent_delay !== null ? `<div>Torrent: <span class="font-mono text-[10px] bg-neutral-100 dark:bg-neutral-800 px-1 rounded">${formatDelay(row.torrent_delay)}</span></div>` : ""}
					</div>
				` })
      },
      {
        key: "bypass",
        header: "Bypass",
        headerIcon: Shield,
        align: "left",
        width: "w-56",
        cell: (row) => {
          const bypasses = [];
          if (row.bypass_if_highest_quality) bypasses.push("Highest Quality");
          if (row.bypass_if_above_custom_format_score && row.minimum_custom_format_score !== null) bypasses.push(`CF Score \u2265 ${row.minimum_custom_format_score}`);
          if (bypasses.length === 0) return { html: '<span class="text-neutral-400">None</span>' };
          return { html: `
						<div class="text-xs space-y-0.5">
							${bypasses.map((b3) => `<div class="font-mono text-[10px] bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200 px-1.5 py-0.5 rounded inline-block">${b3}</div>`).join("")}
						</div>
					` };
        }
      }
    ];
    $: databaseId = store_get($$store_subs ??= {}, "$page", page).params.databaseId;
    Table2($$renderer2, {
      data: profiles,
      columns,
      emptyMessage: "No delay profiles found",
      hoverable: true,
      compact: false,
      rowHref: getRowHref,
      $$slots: { actions: ($$renderer3, { row }) => {
        $$renderer3.push(`<div class="flex items-center justify-end gap-0.5">`);
        if (FEATURES.importExport) {
          $$renderer3.push("<!--[0-->");
          Button($$renderer3, {
            icon: Download,
            size: "xs",
            variant: "ghost",
            tooltip: "Export"
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        Button($$renderer3, {
          icon: Copy,
          size: "xs",
          variant: "secondary",
          tooltip: "Clone"
        });
        $$renderer3.push(`<!----></div>`);
      } }
    });
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { profiles });
  });
}
function CardView4($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, visibleProfiles;
    let profiles = $$props["profiles"];
    createEventDispatcher();
    const { visibleCount, sentinel, reset: reset2, setTotalCount } = createProgressiveList({ pageSize: 30 });
    function formatProtocol(protocol2) {
      switch (protocol2) {
        case "prefer_usenet":
          return "Prefer Usenet";
        case "prefer_torrent":
          return "Prefer Torrent";
        case "only_usenet":
          return "Only Usenet";
        case "only_torrent":
          return "Only Torrent";
        default:
          return protocol2;
      }
    }
    function protocolVariant(protocol2) {
      if (protocol2.startsWith("prefer_")) return "info";
      if (protocol2.startsWith("only_")) return "warning";
      return "secondary";
    }
    function formatDelay(minutes) {
      if (minutes === null) return "-";
      if (minutes === 0) return "No delay";
      if (minutes < 60) return `${minutes}m`;
      const hours = Math.floor(minutes / 60);
      const mins = minutes % 60;
      return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
    }
    function getProfileHref(profile) {
      return `/delay-profiles/${databaseId}/${encodeURIComponent(profile.name)}`;
    }
    $: databaseId = store_get($$store_subs ??= {}, "$page", page).params.databaseId;
    $: setTotalCount(profiles.length);
    $: reset2();
    $: visibleProfiles = profiles.slice(0, store_get($$store_subs ??= {}, "$visibleCount", visibleCount));
    CardGrid($$renderer2, {
      columns: 5,
      flush: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(visibleProfiles);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let profile = each_array[$$index];
          Card($$renderer3, {
            href: getProfileHref(profile),
            hoverable: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="space-y-2.5"><div class="space-y-1">`);
              if (profile.usenet_delay !== null) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="flex items-center justify-between text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
                Clock($$renderer4, { size: 11 });
                $$renderer4.push(`<!---->Usenet</span> <span class="font-mono text-neutral-900 dark:text-neutral-100">${escape_html(formatDelay(profile.usenet_delay))}</span></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> `);
              if (profile.torrent_delay !== null) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="flex items-center justify-between text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
                Clock($$renderer4, { size: 11 });
                $$renderer4.push(`<!---->Torrent</span> <span class="font-mono text-neutral-900 dark:text-neutral-100">${escape_html(formatDelay(profile.torrent_delay))}</span></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></div> `);
              if (profile.bypass_if_highest_quality || profile.bypass_if_above_custom_format_score) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="space-y-1 border-t border-neutral-200 pt-2.5 dark:border-neutral-700/60">`);
                if (profile.bypass_if_highest_quality) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="flex items-center justify-between text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
                  Zap($$renderer4, { size: 11 });
                  $$renderer4.push(`<!---->Highest quality</span> <span class="font-mono text-neutral-900 dark:text-neutral-100">\u2713</span></div>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                if (profile.bypass_if_above_custom_format_score && profile.minimum_custom_format_score !== null) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="flex items-center justify-between text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
                  Zap($$renderer4, { size: 11 });
                  $$renderer4.push(`<!---->Min CF score</span> <span class="font-mono text-neutral-900 dark:text-neutral-100">\u2265 ${escape_html(profile.minimum_custom_format_score)}</span></div>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></div>`);
            },
            $$slots: {
              default: true,
              header: ($$renderer4) => {
                $$renderer4.push(`<div class="flex items-center justify-between gap-2"><div class="flex min-w-0 items-center gap-2"><h3 class="truncate text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(profile.name)}</h3> `);
                Label($$renderer4, {
                  variant: protocolVariant(profile.preferred_protocol),
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->${escape_html(formatProtocol(profile.preferred_protocol))}`);
                  },
                  $$slots: { default: true }
                });
                $$renderer4.push(`<!----></div> <div class="flex items-center gap-0.5">`);
                if (FEATURES.importExport) {
                  $$renderer4.push("<!--[0-->");
                  Button($$renderer4, {
                    icon: Download,
                    size: "xs",
                    variant: "ghost",
                    tooltip: "Export"
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                Button($$renderer4, {
                  icon: Copy,
                  size: "xs",
                  variant: "ghost",
                  tooltip: "Clone"
                });
                $$renderer4.push(`<!----></div></div>`);
              }
            }
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> <div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { profiles });
  });
}
function _page37($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let tabs;
    let data = $$props["data"];
    let showInfoModal = false;
    let cloneModalOpen = false;
    let cloneSourceName = "";
    const { search, view, filtered, setItems } = createDataPageStore(data.delayProfiles, {
      storageKey: "delayProfilesView",
      searchKeys: ["name"],
      searchKey: `delayProfilesSearch:${data.currentDatabase.id}`
    });
    $: setItems(data.delayProfiles);
    $: tabs = data.databases.map((db2) => ({
      label: db2.name,
      href: `/delay-profiles/${db2.id}`,
      active: db2.id === data.currentDatabase.id
    }));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.currentDatabase.name} \xB7 Delay Profiles` });
      $$renderer3.push(`<!----> <div class="space-y-6 px-4 pb-8 md:px-8">`);
      Tabs($$renderer3, {
        tabs,
        responsive: true
      });
      $$renderer3.push(`<!----> `);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore: search,
            placeholder: "Search delay profiles...",
            responsive: true
          });
          $$renderer4.push(`<!----> `);
          ViewToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$view", view);
            },
            set value($$value) {
              store_set(view, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, { icon: Info });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, { icon: Plus });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> <div class="mt-6">`);
      if (data.delayProfiles.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No delay profiles found for ${escape_html(data.currentDatabase?.name)}</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$filtered", filtered).length === 0) {
        $$renderer3.push("<!--[1-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No delay profiles match your search</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$view", view) === "table") {
        $$renderer3.push("<!--[2-->");
        TableView4($$renderer3, { profiles: store_get($$store_subs ??= {}, "$filtered", filtered) });
      } else {
        $$renderer3.push("<!--[-1-->");
        CardView4($$renderer3, { profiles: store_get($$store_subs ??= {}, "$filtered", filtered) });
      }
      $$renderer3.push(`<!--]--></div></div> `);
      InfoModal($$renderer3, {
        header: "How Delay Profile Sync Works",
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">Replaces Existing Profiles</div> <p class="mt-1">When syncing, all existing delay profiles on the arr instance are deleted and replaced with
				the ones you've selected. The default profile (which cannot be deleted) is preserved.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Selection Order = Priority</div> <p class="mt-1">The order you select profiles determines their priority. The first profile in your selection
				list gets the highest priority (order 1), the second gets order 2, and so on.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Tag-Based Matching</div> <p class="mt-1">Delay profiles use tags to apply to specific series/movies. When multiple profiles match
				(via tags), the one with the lowest order number takes precedence.</p></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      CloneModal($$renderer3, {
        databaseId: data.currentDatabase.id,
        entityType: "delay_profile",
        sourceName: cloneSourceName,
        existingNames: data.delayProfiles.map((p2) => p2.name),
        canWriteToBase: data.canWriteToBase,
        get open() {
          return cloneModalOpen;
        },
        set open($$value) {
          cloneModalOpen = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte37 = __esm({
  "dist/build/server/entries/pages/delay-profiles/_databaseId_/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_features();
    init_sanitize();
    init_Icon();
    init_clock();
    init_copy();
    init_download();
    init_info();
    init_Button();
    init_plus();
    init_search();
    init_shield();
    init_ViewToggle();
    init_tag();
    init_stores();
    init_store2();
    init_Label();
    init_Card();
    init_navigation();
    init_Tabs();
    init_progressiveList();
    init_ActionsBar();
    init_ActionButton();
    init_InfoModal();
    init_PageMeta();
    init_Table();
    init_CardGrid();
    init_dataPage();
    init_CloneModal();
  }
});

// dist/build/server/nodes/45.js
var __exports46 = {};
__export(__exports46, {
  component: () => component44,
  fonts: () => fonts46,
  imports: () => imports46,
  index: () => index46,
  server: () => page_server_ts_exports38,
  server_id: () => server_id44,
  stylesheets: () => stylesheets46
});
var index46, component_cache44, component44, server_id44, imports46, stylesheets46, fonts46;
var init__46 = __esm({
  async "dist/build/server/nodes/45.js"() {
    "use strict";
    await init_page_server_ts38();
    index46 = 45;
    component44 = async () => component_cache44 ??= (await Promise.resolve().then(() => (init_page_svelte37(), page_svelte_exports37))).default;
    server_id44 = "src/routes/delay-profiles/[databaseId]/+page.server.ts";
    imports46 = ["_app/immutable/nodes/45.DvYjvCIO.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BqRH1fsh2.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/D7OHFWTL2.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/BDIVGy2g.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/Cut3gr1-.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DxZIQ_tr2.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/DYe9q02k2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js"];
    stylesheets46 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts46 = [];
  }
});

// dist/build/server/entries/pages/delay-profiles/_databaseId_/_name_/_page.server.ts.js
var page_server_ts_exports39 = {};
__export(page_server_ts_exports39, {
  actions: () => actions26,
  load: () => load42
});
var load42, actions26;
var init_page_server_ts39 = __esm({
  async "dist/build/server/entries/pages/delay-profiles/_databaseId_/_name_/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrSync();
    await init_queueService();
    await init_affectedArrs();
    init_exports();
    load42 = async ({ params }) => {
      const { databaseId, name } = params;
      if (!databaseId || !name) throw error(400, "Missing parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = pcdManager.getByIdPublic(currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const delayProfile = await getByName(cache3, decodeURIComponent(name));
      if (!delayProfile) throw error(404, "Delay profile not found");
      return {
        currentDatabase,
        delayProfile,
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions26 = {
      update: async ({ request, params }) => {
        const { databaseId, name: paramName } = params;
        if (!databaseId || !paramName) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await getByName(cache3, decodeURIComponent(paramName));
        if (!current3) return fail(404, { error: "Delay profile not found" });
        const formData = await request.formData();
        const name = formData.get("name");
        const preferredProtocol = formData.get("preferredProtocol");
        const usenetDelay = parseInt(formData.get("usenetDelay"), 10) || 0;
        const torrentDelay = parseInt(formData.get("torrentDelay"), 10) || 0;
        const bypassIfHighestQuality = formData.get("bypassIfHighestQuality") === "true";
        const bypassIfAboveCfScore = formData.get("bypassIfAboveCfScore") === "true";
        const minimumCfScore = parseInt(formData.get("minimumCfScore"), 10) || 0;
        const layer = formData.get("layer") || "user";
        if (!name?.trim()) return fail(400, { error: "Name is required" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        let result;
        try {
          result = await update2({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            current: current3,
            input: {
              name: name.trim(),
              preferredProtocol,
              usenetDelay,
              torrentDelay,
              bypassIfHighestQuality,
              bypassIfAboveCfScore,
              minimumCfScore
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update delay profile";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update delay profile" });
        if (name.trim() !== current3.name) arrSyncQueries.updateDelayProfileName(current3.name, name.trim());
        const affectedArrs = getAffectedArrs({
          entityType: "delayProfile",
          databaseId: currentDatabaseId,
          entityName: name.trim()
        });
        return {
          success: true,
          redirectTo: `/delay-profiles/${databaseId}`,
          affectedArrs
        };
      },
      delete: async ({ request, params }) => {
        const { databaseId, name: paramName } = params;
        if (!databaseId || !paramName) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await getByName(cache3, decodeURIComponent(paramName));
        if (!current3) return fail(404, { error: "Delay profile not found" });
        const layerFromForm = (await request.formData()).get("layer");
        const layer = layerFromForm || "user";
        await logger.debug("Delete action received", {
          source: "DelayProfileDelete",
          meta: {
            profileName: current3.name,
            layerFromForm,
            layerUsed: layer
          }
        });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await remove$1({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          current: current3
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete delay profile" });
        throw redirect(303, `/delay-profiles/${databaseId}`);
      }
    };
  }
});

// dist/build/server/chunks/DelayProfileForm.js
function DelayProfileForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let formData, databaseId, title, description, submitButtonText, usenetEnabled, torrentEnabled, isValid, protocolDescription;
    let mode = $$props["mode"];
    let databaseName = $$props["databaseName"];
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let actionUrl = fallback($$props["actionUrl"], "");
    let breadcrumbItems = fallback($$props["breadcrumbItems"], () => [], true);
    let breadcrumbCurrent = fallback($$props["breadcrumbCurrent"], "");
    let initialData = $$props["initialData"];
    let onCancel = $$props["onCancel"];
    const defaults = {
      name: "",
      preferredProtocol: "prefer_usenet",
      usenetDelay: 0,
      torrentDelay: 0,
      bypassIfHighestQuality: false,
      bypassIfAboveCfScore: false,
      minimumCfScore: 0
    };
    if (mode === "create") initCreate(initialData ?? defaults);
    else initEdit(initialData);
    let deleting = false;
    let showDeleteModal = false;
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    let showSyncModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    let deleteLayer = canWriteToBase2 ? "base" : "user";
    const protocolOptions = [
      {
        value: "prefer_usenet",
        label: "Prefer Usenet",
        description: "Try Usenet first, fall back to Torrent"
      },
      {
        value: "prefer_torrent",
        label: "Prefer Torrent",
        description: "Try Torrent first, fall back to Usenet"
      },
      {
        value: "only_usenet",
        label: "Only Usenet",
        description: "Never use Torrent"
      },
      {
        value: "only_torrent",
        label: "Only Torrent",
        description: "Never use Usenet"
      }
    ];
    function updateField(field, value2) {
      update3(field, value2);
    }
    $: formData = store_get($$store_subs ??= {}, "$current", current2);
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: title = mode === "create" ? "New Delay Profile" : "Edit Delay Profile";
    $: description = mode === "create" ? `Create a new delay profile for ${databaseName}` : `Update delay profile settings`;
    $: submitButtonText = mode === "create" ? "Create Profile" : "Save Changes";
    $: usenetEnabled = formData.preferredProtocol !== "only_torrent";
    $: torrentEnabled = formData.preferredProtocol !== "only_usenet";
    $: isValid = formData.name.trim() !== "";
    $: protocolDescription = protocolOptions.find((o) => o.value === formData.preferredProtocol)?.description ?? "";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="space-y-6">`);
      StickyCard($$renderer3, {
        position: "top",
        breadcrumbItems,
        breadcrumbCurrent,
        stickyBreadcrumb: false,
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<div><h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h2> <p class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p></div>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div class="flex items-center gap-2">`);
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                disabled: deleting,
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                text: "Delete"
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            Button($$renderer4, { text: "Cancel" });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              disabled: !isValid || !store_get($$store_subs ??= {}, "$isDirty", isDirty),
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              text: submitButtonText
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <form method="POST"${attr("action", actionUrl)} class="md:px-4"><input type="hidden" name="preferredProtocol"${attr("value", formData.preferredProtocol)}/> <input type="hidden" name="usenetDelay"${attr("value", formData.usenetDelay)}/> <input type="hidden" name="torrentDelay"${attr("value", formData.torrentDelay)}/> <input type="hidden" name="bypassIfHighestQuality"${attr("value", formData.bypassIfHighestQuality)}/> <input type="hidden" name="bypassIfAboveCfScore"${attr("value", formData.bypassIfAboveCfScore)}/> <input type="hidden" name="minimumCfScore"${attr("value", formData.minimumCfScore)}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/> <div class="space-y-6"><div data-onboarding="delay-general-name">`);
      FormInput($$renderer3, {
        label: "Name",
        name: "name",
        placeholder: "e.g., Standard Delay",
        required: true,
        value: formData.name
      });
      $$renderer3.push(`<!----></div> <div class="space-y-2" data-onboarding="delay-general-protocol"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">Protocol Preference</h3> `);
      DropdownSelect($$renderer3, {
        value: formData.preferredProtocol,
        options: protocolOptions,
        fullWidth: true
      });
      $$renderer3.push(`<!----> `);
      if (protocolDescription) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(protocolDescription)}</p>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> <div data-onboarding="delay-general-delays"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">Delays</h3> <p class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">Time to wait before downloading from each source. Set to 0 for no delay.</p> <div class="mt-3 grid gap-4 sm:grid-cols-2"><div><label for="usenet-delay" class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">Usenet Delay (minutes)</label> <div class="mt-1">`);
      NumberInput($$renderer3, {
        name: "usenet-delay",
        id: "usenet-delay",
        value: formData.usenetDelay,
        onchange: (v3) => updateField("usenetDelay", v3),
        min: 0,
        font: "mono",
        disabled: !usenetEnabled
      });
      $$renderer3.push(`<!----></div></div> <div><label for="torrent-delay" class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">Torrent Delay (minutes)</label> <div class="mt-1">`);
      NumberInput($$renderer3, {
        name: "torrent-delay",
        id: "torrent-delay",
        value: formData.torrentDelay,
        onchange: (v3) => updateField("torrentDelay", v3),
        min: 0,
        font: "mono",
        disabled: !torrentEnabled
      });
      $$renderer3.push(`<!----></div></div></div></div> <div data-onboarding="delay-general-bypass"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">Bypass Conditions</h3> <p class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">Skip the delay when these conditions are met.</p> <div class="mt-3 space-y-3"><div>`);
      Toggle($$renderer3, {
        label: "Bypass if Highest Quality",
        checked: formData.bypassIfHighestQuality,
        fullWidth: true
      });
      $$renderer3.push(`<!----> <p class="mt-1 px-3 text-xs text-neutral-500 dark:text-neutral-400">Skip delay when release is already the highest quality in profile</p></div> <div><div class="grid grid-cols-1 items-center gap-3 sm:grid-cols-2">`);
      Toggle($$renderer3, {
        label: "Bypass if Above Custom Format Score",
        checked: formData.bypassIfAboveCfScore,
        fullWidth: true
      });
      $$renderer3.push(`<!----> `);
      NumberInput($$renderer3, {
        name: "min-cf-score",
        id: "min-cf-score",
        value: formData.minimumCfScore,
        onchange: (v3) => updateField("minimumCfScore", v3),
        disabled: !formData.bypassIfAboveCfScore,
        font: "mono"
      });
      $$renderer3.push(`<!----></div> <p class="mt-1 px-3 text-xs text-neutral-500 dark:text-neutral-400">Skip delay when release exceeds minimum score</p></div></div></div></div></form> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form method="POST" action="?/delete" class="hidden"><input type="hidden" name="layer"${attr("value", deleteLayer)}/></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> `);
      Modal($$renderer3, {
        open: showDeleteModal,
        header: "Delete delay profile",
        bodyMessage: "This will remove the delay profile and write a delete op. You can recreate it later if needed.",
        confirmText: "Delete",
        cancelText: "Cancel",
        confirmDanger: true,
        confirmDisabled: deleting,
        loading: deleting
      });
      $$renderer3.push(`<!----> `);
      SyncPromptModal($$renderer3, {
        redirectTo: pendingRedirectTo,
        affectedArrs: pendingAffectedArrs,
        entityType: "delayProfile",
        databaseId,
        entityName: formData.name.trim(),
        get open() {
          return showSyncModal;
        },
        set open($$value) {
          showSyncModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      databaseName,
      canWriteToBase: canWriteToBase2,
      actionUrl,
      breadcrumbItems,
      breadcrumbCurrent,
      initialData,
      onCancel
    });
  });
}
var init_DelayProfileForm = __esm({
  "dist/build/server/chunks/DelayProfileForm.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Button();
    init_save();
    init_trash_2();
    init_stores();
    init_store2();
    init_navigation();
    init_Modal();
    init_forms();
    init_dirty();
    init_StickyCard();
    init_DropdownSelect();
    init_FormInput();
    init_NumberInput();
    init_Toggle();
    init_SyncPromptModal();
  }
});

// dist/build/server/entries/pages/delay-profiles/_databaseId_/_name_/_page.svelte.js
var page_svelte_exports38 = {};
__export(page_svelte_exports38, {
  default: () => _page38
});
function _page38($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let initialData;
    let data = $$props["data"];
    function handleCancel() {
      goto(`/delay-profiles/${data.currentDatabase.id}`);
    }
    $: initialData = {
      name: data.delayProfile.name,
      preferredProtocol: data.delayProfile.preferred_protocol,
      usenetDelay: data.delayProfile.usenet_delay ?? 0,
      torrentDelay: data.delayProfile.torrent_delay ?? 0,
      bypassIfHighestQuality: data.delayProfile.bypass_if_highest_quality,
      bypassIfAboveCfScore: data.delayProfile.bypass_if_above_custom_format_score,
      minimumCfScore: data.delayProfile.minimum_custom_format_score ?? 0
    };
    PageMeta($$renderer2, { title: `${data.delayProfile.name} \xB7 General` });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8">`);
    DelayProfileForm($$renderer2, {
      mode: "edit",
      databaseName: data.currentDatabase?.name,
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      initialData,
      onCancel: handleCancel,
      breadcrumbItems: [{
        label: data.currentDatabase.name,
        href: `/delay-profiles/${data.currentDatabase.id}`
      }],
      breadcrumbCurrent: data.delayProfile.name
    });
    $$renderer2.push(`<!----></div> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte38 = __esm({
  "dist/build/server/entries/pages/delay-profiles/_databaseId_/_name_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_client4();
    init_navigation();
    init_DirtyModal();
    init_PageMeta();
    init_DelayProfileForm();
  }
});

// dist/build/server/nodes/46.js
var __exports47 = {};
__export(__exports47, {
  component: () => component45,
  fonts: () => fonts47,
  imports: () => imports47,
  index: () => index47,
  server: () => page_server_ts_exports39,
  server_id: () => server_id45,
  stylesheets: () => stylesheets47
});
var index47, component_cache45, component45, server_id45, imports47, stylesheets47, fonts47;
var init__47 = __esm({
  async "dist/build/server/nodes/46.js"() {
    "use strict";
    await init_page_server_ts39();
    index47 = 46;
    component45 = async () => component_cache45 ??= (await Promise.resolve().then(() => (init_page_svelte38(), page_svelte_exports38))).default;
    server_id45 = "src/routes/delay-profiles/[databaseId]/[name]/+page.server.ts";
    imports47 = ["_app/immutable/nodes/46.D8POaKfq.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/N3ty8_862.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js"];
    stylesheets47 = [];
    fonts47 = [];
  }
});

// dist/build/server/entries/pages/delay-profiles/_databaseId_/new/_page.server.ts.js
var page_server_ts_exports40 = {};
__export(page_server_ts_exports40, {
  actions: () => actions27,
  load: () => load43
});
var load43, actions27;
var init_page_server_ts40 = __esm({
  async "dist/build/server/entries/pages/delay-profiles/_databaseId_/new/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_queueService();
    init_exports();
    load43 = ({ params }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = pcdManager.getByIdPublic(currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      return {
        currentDatabase,
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions27 = { default: async ({ request, params }) => {
      const { databaseId } = params;
      if (!databaseId) return fail(400, { error: "Missing database ID" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const name = formData.get("name");
      const preferredProtocol = formData.get("preferredProtocol");
      const usenetDelay = parseInt(formData.get("usenetDelay"), 10) || 0;
      const torrentDelay = parseInt(formData.get("torrentDelay"), 10) || 0;
      const bypassIfHighestQuality = formData.get("bypassIfHighestQuality") === "true";
      const bypassIfAboveCfScore = formData.get("bypassIfAboveCfScore") === "true";
      const minimumCfScore = parseInt(formData.get("minimumCfScore"), 10) || 0;
      const layerFromForm = formData.get("layer");
      const layer = layerFromForm || "user";
      await logger.debug("Create action received", {
        source: "DelayProfileCreate",
        meta: {
          profileName: name,
          layerFromForm,
          layerUsed: layer
        }
      });
      if (!name?.trim()) return fail(400, { error: "Name is required" });
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      let result;
      try {
        result = await create$1({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          input: {
            name: name.trim(),
            preferredProtocol,
            usenetDelay,
            torrentDelay,
            bypassIfHighestQuality,
            bypassIfAboveCfScore,
            minimumCfScore
          }
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to create delay profile";
        if (message2.includes("already exists")) return fail(400, { error: message2 });
        return fail(500, { error: message2 });
      }
      if (!result.success) return fail(500, { error: result.error || "Failed to create delay profile" });
      throw redirect(303, `/delay-profiles/${databaseId}`);
    } };
  }
});

// dist/build/server/entries/pages/delay-profiles/_databaseId_/new/_page.svelte.js
var page_svelte_exports39 = {};
__export(page_svelte_exports39, {
  default: () => _page39
});
function _page39($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    const initialData = {
      name: "",
      preferredProtocol: "prefer_usenet",
      usenetDelay: 0,
      torrentDelay: 0,
      bypassIfHighestQuality: false,
      bypassIfAboveCfScore: false,
      minimumCfScore: 0
    };
    function handleCancel() {
      goto(`/delay-profiles/${data.currentDatabase.id}`);
    }
    PageMeta($$renderer2, { title: `${data.currentDatabase.name} \xB7 Delay Profile \xB7 New` });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8">`);
    DelayProfileForm($$renderer2, {
      mode: "create",
      databaseName: data.currentDatabase?.name,
      canWriteToBase: data.canWriteToBase,
      initialData,
      onCancel: handleCancel
    });
    $$renderer2.push(`<!----></div> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte39 = __esm({
  "dist/build/server/entries/pages/delay-profiles/_databaseId_/new/_page.svelte.js"() {
    "use strict";
    init_server();
    init_client4();
    init_navigation();
    init_DirtyModal();
    init_PageMeta();
    init_DelayProfileForm();
  }
});

// dist/build/server/nodes/47.js
var __exports48 = {};
__export(__exports48, {
  component: () => component46,
  fonts: () => fonts48,
  imports: () => imports48,
  index: () => index48,
  server: () => page_server_ts_exports40,
  server_id: () => server_id46,
  stylesheets: () => stylesheets48
});
var index48, component_cache46, component46, server_id46, imports48, stylesheets48, fonts48;
var init__48 = __esm({
  async "dist/build/server/nodes/47.js"() {
    "use strict";
    await init_page_server_ts40();
    index48 = 47;
    component46 = async () => component_cache46 ??= (await Promise.resolve().then(() => (init_page_svelte39(), page_svelte_exports39))).default;
    server_id46 = "src/routes/delay-profiles/[databaseId]/new/+page.server.ts";
    imports48 = ["_app/immutable/nodes/47.BKYDFylI.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/N3ty8_862.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js"];
    stylesheets48 = [];
    fonts48 = [];
  }
});

// dist/build/server/entries/pages/dev/_page.server.ts.js
var page_server_ts_exports41 = {};
__export(page_server_ts_exports41, {
  load: () => load44
});
var load44;
var init_page_server_ts41 = __esm({
  "dist/build/server/entries/pages/dev/_page.server.ts.js"() {
    "use strict";
    init_exports();
    load44 = async () => {
      throw redirect(302, "/dev/components");
    };
  }
});

// dist/build/server/nodes/48.js
var __exports49 = {};
__export(__exports49, {
  fonts: () => fonts49,
  imports: () => imports49,
  index: () => index49,
  server: () => page_server_ts_exports41,
  server_id: () => server_id47,
  stylesheets: () => stylesheets49
});
var index49, server_id47, imports49, stylesheets49, fonts49;
var init__49 = __esm({
  "dist/build/server/nodes/48.js"() {
    "use strict";
    init_page_server_ts41();
    index49 = 48;
    server_id47 = "src/routes/dev/+page.server.ts";
    imports49 = [];
    stylesheets49 = [];
    fonts49 = [];
  }
});

// dist/build/server/entries/pages/dev/components/_page.server.ts.js
var page_server_ts_exports42 = {};
__export(page_server_ts_exports42, {
  load: () => load45
});
var load45;
var init_page_server_ts42 = __esm({
  "dist/build/server/entries/pages/dev/components/_page.server.ts.js"() {
    "use strict";
    init_exports();
    load45 = async () => {
      throw redirect(302, "/");
    };
  }
});

// dist/build/server/chunks/RangeScale.js
function RangeScale($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let orientation = fallback($$props["orientation"], "horizontal");
    let direction = fallback($$props["direction"], "start");
    let min = fallback($$props["min"], 0);
    let max = fallback($$props["max"], 100);
    let step = fallback($$props["step"], 1);
    let minSeparation = fallback($$props["minSeparation"], 20);
    let markers = fallback($$props["markers"], () => [], true);
    let unit = fallback($$props["unit"], "");
    let unlimitedValue = fallback($$props["unlimitedValue"], null);
    let displayTransform = fallback($$props["displayTransform"], null);
    let disabled = fallback($$props["disabled"], false);
    createEventDispatcher();
    let draggingIndex = null;
    const colorClasses = {
      accent: {
        dot: "bg-accent-500",
        badge: "bg-accent-100 text-accent-700 dark:bg-accent-900/40 dark:text-accent-300"
      },
      blue: {
        dot: "bg-blue-500",
        badge: "bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300"
      },
      green: {
        dot: "bg-green-500",
        badge: "bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300"
      },
      orange: {
        dot: "bg-orange-500",
        badge: "bg-orange-100 text-orange-700 dark:bg-orange-900/40 dark:text-orange-300"
      },
      red: {
        dot: "bg-red-500",
        badge: "bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300"
      },
      purple: {
        dot: "bg-purple-500",
        badge: "bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-300"
      },
      neutral: {
        dot: "bg-neutral-500",
        badge: "bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300"
      }
    };
    function valueToPercent(value2) {
      const percent = (value2 - min) / (max - min) * 100;
      return direction === "start" ? percent : 100 - percent;
    }
    function getContainerSize() {
      return 0;
    }
    function getMarkerBounds(index88) {
      const containerSize = getContainerSize();
      const range = max - min;
      const separationValue = containerSize > 0 ? minSeparation / containerSize * range : 0;
      let minVal = min;
      let maxVal = max;
      if (index88 > 0) minVal = markers[index88 - 1].value + separationValue;
      if (index88 < markers.length - 1) maxVal = markers[index88 + 1].value - separationValue;
      return {
        minVal,
        maxVal
      };
    }
    $: {
      let needsUpdate = false;
      const updatedMarkers = markers.map((marker, index88) => {
        getMarkerBounds(index88);
        let value2 = marker.value;
        value2 = Math.max(min, Math.min(max, value2));
        if (value2 !== marker.value) {
          needsUpdate = true;
          return {
            ...marker,
            value: value2
          };
        }
        return marker;
      });
      if (needsUpdate) markers = updatedMarkers;
    }
    $$renderer2.push(`<div${attr_class("relative select-none", void 0, {
      "w-full": orientation === "horizontal",
      "h-full": orientation === "vertical",
      "opacity-50": disabled
    })}><div${attr_class("relative", void 0, {
      "h-2": orientation === "horizontal",
      "w-2": orientation === "vertical",
      "w-full": orientation === "horizontal",
      "h-full": orientation === "vertical"
    })}><div${attr_class(`absolute rounded-full bg-neutral-200 dark:bg-neutral-700 ${orientation === "horizontal" ? "top-1/2 h-1 w-full -translate-y-1/2" : "left-1/2 h-full w-1 -translate-x-1/2"}`)}></div> <!--[-->`);
    const each_array = ensure_array_like(markers);
    for (let index88 = 0, $$length = each_array.length; index88 < $$length; index88++) {
      let marker = each_array[index88];
      const percent = valueToPercent(marker.value);
      const colors2 = colorClasses[marker.color];
      $$renderer2.push(`<div${attr_class(`absolute ${orientation === "horizontal" ? "top-1/2 -translate-y-1/2" : "left-1/2 -translate-x-1/2"}`)}${attr_style(`${orientation === "horizontal" ? "left" : "top"}: ${stringify(percent)}%;`)}><button type="button"${attr("disabled", disabled, true)}${attr_class(`relative h-4 w-4 -translate-x-1/2 rounded-full shadow-sm transition-transform disabled:cursor-not-allowed ${disabled ? "" : "cursor-grab hover:scale-125"} ${stringify(colors2.dot)} ${orientation === "vertical" ? "-translate-y-1/2" : ""} ${draggingIndex === index88 && !disabled ? "scale-150 cursor-grabbing" : ""}`)}${attr("aria-label", `Drag to adjust ${stringify(marker.label)}`)}></button> <div${attr_class(`absolute whitespace-nowrap ${orientation === "horizontal" ? `left-0 -translate-x-1/2 ${index88 % 2 === 0 ? "top-6" : "bottom-6"}` : "left-6 translate-x-0"}`)}><span${attr_class(`inline-block rounded px-1.5 py-0.5 text-xs font-medium ${stringify(colors2.badge)}`)}>${escape_html(marker.label)}: ${escape_html(unlimitedValue !== null && marker.value >= unlimitedValue ? "Unlimited" : `${displayTransform ? displayTransform(marker.value).toFixed(1) : Math.round(marker.value)}${unit ? ` ${unit}` : ""}`)}</span></div></div>`);
    }
    $$renderer2.push(`<!--]--></div></div>`);
    bind_props($$props, {
      orientation,
      direction,
      min,
      max,
      step,
      minSeparation,
      markers,
      unit,
      unlimitedValue,
      displayTransform,
      disabled
    });
  });
}
var init_RangeScale = __esm({
  "dist/build/server/chunks/RangeScale.js"() {
    "use strict";
    init_index_server();
    init_server();
  }
});

// dist/build/server/entries/pages/dev/components/_page.svelte.js
var page_svelte_exports40 = {};
__export(page_svelte_exports40, {
  default: () => _page40
});
function TableActionButton($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let icon = $$props["icon"];
    let title = $$props["title"];
    let variant = fallback($$props["variant"], "neutral");
    let size = fallback($$props["size"], "md");
    let type = fallback($$props["type"], "button");
    let disabled = fallback($$props["disabled"], false);
    let stopPropagation = fallback($$props["stopPropagation"], false);
    createEventDispatcher();
    const sizeClasses = {
      sm: "h-6 w-6",
      md: "h-7 w-7"
    };
    const iconSizes = {
      sm: 12,
      md: 14
    };
    $$renderer2.push(`<button${attr("type", type)}${attr("disabled", disabled, true)}${attr_class(`inline-flex items-center justify-center rounded border transition-colors ${stringify(sizeClasses[size])} ${stringify({
      neutral: "border-neutral-300 bg-white text-neutral-700 hover:bg-neutral-50 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-300 dark:hover:bg-neutral-800",
      danger: "border-neutral-300 bg-white text-neutral-700 hover:border-red-300 hover:bg-red-50 hover:text-red-600 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-300 dark:hover:border-red-800 dark:hover:bg-red-900/20 dark:hover:text-red-400",
      accent: "border-neutral-300 bg-white text-neutral-700 hover:border-accent-300 hover:bg-accent-50 hover:text-accent-600 dark:border-neutral-700 dark:bg-neutral-900 dark:text-neutral-300 dark:hover:border-accent-700 dark:hover:bg-accent-900/20 dark:hover:text-accent-400"
    }[variant])} disabled:cursor-not-allowed disabled:opacity-50`)}${attr("title", title)}>`);
    if (icon) {
      $$renderer2.push("<!--[-->");
      icon($$renderer2, { size: iconSizes[size] });
      $$renderer2.push("<!--]-->");
    } else {
      $$renderer2.push("<!--[!-->");
      $$renderer2.push("<!--]-->");
    }
    $$renderer2.push(`</button>`);
    bind_props($$props, {
      icon,
      title,
      variant,
      size,
      type,
      disabled,
      stopPropagation
    });
  });
}
function ComponentCard($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let name = $$props["name"];
    let paths = $$props["paths"];
    let description = $$props["description"];
    $$renderer2.push(`<section class="rounded-lg border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900"><div class="space-y-2 border-b border-neutral-200 p-6 dark:border-neutral-800"><h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(name)}</h2> <p class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(paths.join(", "))}</p> <p class="text-sm text-neutral-600 dark:text-neutral-300">${escape_html(description)}</p></div> <div class="space-y-4 p-6"><!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--></div></section>`);
    bind_props($$props, {
      name,
      paths,
      description
    });
  });
}
function _page40($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let visibleIds;
    const search = createSearchStore();
    const debouncedQuery = search.debouncedQuery;
    const demoSearch = createSearchStore();
    let demoView = "table";
    let demoFormText = "";
    let demoFormPassword = "";
    let demoFormTextarea = "";
    let demoNumber = 50;
    let demoNumberCompact = 10;
    let demoTags = [
      "radarr",
      "sonarr",
      "1080p"
    ];
    const demoAutoOptions = [
      {
        value: "radarr",
        label: "Radarr"
      },
      {
        value: "sonarr",
        label: "Sonarr"
      },
      {
        value: "whisparr",
        label: "Whisparr"
      },
      {
        value: "prowlarr",
        label: "Prowlarr"
      },
      {
        value: "lidarr",
        label: "Lidarr"
      },
      {
        value: "readarr",
        label: "Readarr"
      }
    ];
    let demoComboboxValue = null;
    let demoCompactComboboxValue = null;
    let demoModalOpen = false;
    let demoModalDanger = false;
    let demoInfoModalOpen = false;
    let demoKV = {
      API_KEY: "abc123",
      BASE_URL: "https://example.com"
    };
    let demoKVVersion = {
      minimum: "2.0.0",
      current: "3.1.0"
    };
    let demoRangeMarkers = [
      {
        id: "min",
        label: "Min",
        color: "blue",
        value: 20
      },
      {
        id: "preferred",
        label: "Preferred",
        color: "accent",
        value: 50
      },
      {
        id: "max",
        label: "Max",
        color: "red",
        value: 80
      }
    ];
    let demoRangeSingle = [{
      id: "threshold",
      label: "Threshold",
      color: "green",
      value: 60
    }];
    let demoMarkdown = "**Bold** and *italic* text.\n\n- List item\n- Another item\n\n`inline code`";
    let demoMarkdownSingle = "A single-line **markdown** input";
    let checkedAccent = true;
    let checkedBlue = true;
    let checkedGreen = true;
    let checkedRed = true;
    let checkedNeutral = true;
    let checkedOutline = true;
    let unchecked = false;
    let checkedSquare = true;
    let checkedCircle = true;
    let demoSelectValue = "radarr";
    const demoSelectOptions = [
      {
        value: "radarr",
        label: "Radarr"
      },
      {
        value: "sonarr",
        label: "Sonarr"
      },
      {
        value: "whisparr",
        label: "Whisparr"
      }
    ];
    const demoTableData = [
      {
        id: 1,
        name: "HD-1080p",
        score: 150,
        status: "Active"
      },
      {
        id: 2,
        name: "Ultra-HD",
        score: 200,
        status: "Active"
      },
      {
        id: 3,
        name: "SD",
        score: -50,
        status: "Disabled"
      }
    ];
    const demoTableColumns = [
      {
        key: "name",
        header: "Name",
        sortable: true
      },
      {
        key: "score",
        header: "Score",
        sortable: true,
        align: "right"
      },
      {
        key: "status",
        header: "Status"
      }
    ];
    let demoToggleAccent = true;
    let demoToggleGreen = true;
    let demoToggleRed = false;
    let demoToggleAmber = false;
    const sections = [
      {
        id: "actions",
        name: "Actions",
        category: "actions"
      },
      {
        id: "arr",
        name: "Arr",
        category: "arr"
      },
      {
        id: "badge",
        name: "Badge",
        category: "badge"
      },
      {
        id: "button",
        name: "Button",
        category: "button"
      },
      {
        id: "card",
        name: "Card",
        category: "card"
      },
      {
        id: "card-grid",
        name: "CardGrid",
        category: "card"
      },
      {
        id: "dropdown",
        name: "Dropdown",
        category: "dropdown"
      },
      {
        id: "form-input",
        name: "FormInput",
        category: "form"
      },
      {
        id: "number-input",
        name: "NumberInput",
        category: "form"
      },
      {
        id: "icon-checkbox",
        name: "IconCheckbox",
        category: "form"
      },
      {
        id: "tag-input",
        name: "TagInput",
        category: "form"
      },
      {
        id: "dropdown-combobox",
        name: "DropdownCombobox",
        category: "dropdown"
      },
      {
        id: "markdown-input",
        name: "MarkdownInput",
        category: "form"
      },
      {
        id: "range-scale",
        name: "RangeScale",
        category: "form"
      },
      {
        id: "key-value-list",
        name: "KeyValueList",
        category: "form"
      },
      {
        id: "label",
        name: "Label",
        category: "label"
      },
      {
        id: "meta",
        name: "Meta",
        category: "meta"
      },
      {
        id: "modal",
        name: "Modal",
        category: "modal"
      },
      {
        id: "navigation",
        name: "Navigation",
        category: "navigation"
      },
      {
        id: "table",
        name: "Table",
        category: "table"
      },
      {
        id: "toggle",
        name: "Toggle",
        category: "toggle"
      }
    ];
    function getVisibleIds(items, query) {
      if (!query) return new Set(items.map((s3) => s3.id));
      const q2 = query.toLowerCase();
      return new Set(items.filter((s3) => s3.name.toLowerCase().includes(q2) || s3.category.toLowerCase().includes(q2)).map((s3) => s3.id));
    }
    $: visibleIds = getVisibleIds(sections, store_get($$store_subs ??= {}, "$debouncedQuery", debouncedQuery));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: "Dev \xB7 UI Preview" });
      $$renderer3.push(`<!----> <div class="space-y-6 px-4 pt-8 pb-8 md:px-8 md:pt-12"><h1 class="text-2xl font-bold text-neutral-900 dark:text-neutral-100">Component Library</h1> `);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore: search,
            placeholder: "Search components...",
            responsive: true
          });
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      if (visibleIds.size === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-500 dark:text-neutral-400">No components match your search.</p></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("actions")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Actions",
          paths: [
            "actions/ActionsBar",
            "actions/ActionButton",
            "actions/SearchAction",
            "actions/ViewToggle"
          ],
          description: "ActionsBar groups action items with collapsed borders and auto-rounding. ActionButton provides icon buttons with optional hover dropdowns. SearchAction is a search input with responsive mobile modal. ViewToggle switches between card/table views.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Full bar (search + buttons + view toggle)</p> `);
            ActionsBar($$renderer4, {
              children: ($$renderer5) => {
                SearchAction($$renderer5, {
                  searchStore: demoSearch,
                  placeholder: "Search...",
                  responsive: true
                });
                $$renderer5.push(`<!----> `);
                ActionButton($$renderer5, {
                  icon: Plus,
                  title: "Add"
                });
                $$renderer5.push(`<!----> `);
                ActionButton($$renderer5, {
                  icon: Funnel,
                  hasDropdown: true,
                  dropdownPosition: "right",
                  $$slots: { dropdown: ($$renderer6) => {
                    Dropdown($$renderer6, {
                      position: "right",
                      children: ($$renderer7) => {
                        DropdownItem($$renderer7, {
                          icon: File_text,
                          label: "Option A"
                        });
                        $$renderer7.push(`<!----> `);
                        DropdownItem($$renderer7, {
                          icon: File_text,
                          label: "Option B"
                        });
                        $$renderer7.push(`<!---->`);
                      },
                      $$slots: { default: true }
                    });
                  } }
                });
                $$renderer5.push(`<!----> `);
                ActionButton($$renderer5, {
                  icon: Info,
                  title: "Info"
                });
                $$renderer5.push(`<!----> `);
                ViewToggle($$renderer5, {
                  get value() {
                    return demoView;
                  },
                  set value($$value) {
                    demoView = $$value;
                    $$settled = false;
                  }
                });
                $$renderer5.push(`<!---->`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Search only (single item rounding)</p> `);
            ActionsBar($$renderer4, {
              children: ($$renderer5) => {
                SearchAction($$renderer5, {
                  searchStore: demoSearch,
                  placeholder: "Search items...",
                  responsive: true
                });
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Buttons only</p> `);
            ActionsBar($$renderer4, {
              className: "md:justify-start",
              children: ($$renderer5) => {
                ActionButton($$renderer5, {
                  icon: Plus,
                  title: "Add"
                });
                $$renderer5.push(`<!----> `);
                ActionButton($$renderer5, {
                  icon: Trash_2,
                  variant: "danger",
                  title: "Delete"
                });
                $$renderer5.push(`<!----> `);
                ActionButton($$renderer5, {
                  icon: Info,
                  title: "Info"
                });
                $$renderer5.push(`<!---->`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("arr")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Arr",
          paths: ["arr/Score", "arr/CustomFormatBadge"],
          description: "Score displays a numeric value with sign and color coding (positive green, negative red, zero neutral). CustomFormatBadge shows a CF name with its score as a pill.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Score variants</p> <div class="flex flex-wrap items-center gap-4"><div class="flex items-center gap-2"><span class="text-xs text-neutral-500 dark:text-neutral-400">Positive:</span> `);
            Score($$renderer4, { score: 150 });
            $$renderer4.push(`<!----></div> <div class="flex items-center gap-2"><span class="text-xs text-neutral-500 dark:text-neutral-400">Negative:</span> `);
            Score($$renderer4, { score: -50 });
            $$renderer4.push(`<!----></div> <div class="flex items-center gap-2"><span class="text-xs text-neutral-500 dark:text-neutral-400">Zero:</span> `);
            Score($$renderer4, { score: 0 });
            $$renderer4.push(`<!----></div> <div class="flex items-center gap-2"><span class="text-xs text-neutral-500 dark:text-neutral-400">Null:</span> `);
            Score($$renderer4, { score: null });
            $$renderer4.push(`<!----></div> <div class="flex items-center gap-2"><span class="text-xs text-neutral-500 dark:text-neutral-400">Uncolored:</span> `);
            Score($$renderer4, {
              score: 75,
              colored: false
            });
            $$renderer4.push(`<!----></div> <div class="flex items-center gap-2"><span class="text-xs text-neutral-500 dark:text-neutral-400">Small:</span> `);
            Score($$renderer4, {
              score: 42,
              size: "sm"
            });
            $$renderer4.push(`<!----></div></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Custom Format Badges</p> <div class="flex flex-wrap items-center gap-2">`);
            CustomFormatBadge($$renderer4, {
              name: "Remux",
              score: 150
            });
            $$renderer4.push(`<!----> `);
            CustomFormatBadge($$renderer4, {
              name: "BR-DISK",
              score: -1e4
            });
            $$renderer4.push(`<!----> `);
            CustomFormatBadge($$renderer4, {
              name: "x264",
              score: 0
            });
            $$renderer4.push(`<!----> `);
            CustomFormatBadge($$renderer4, {
              name: "DV HDR10+",
              score: 50
            });
            $$renderer4.push(`<!----></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("badge")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Badge",
          paths: ["badge/Badge"],
          description: "Status/label pill with six color variants, two sizes, optional icon, and mono font option.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Variants</p> <div class="flex flex-wrap items-center gap-2">`);
            Badge($$renderer4, {
              variant: "accent",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Accent`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Badge($$renderer4, {
              variant: "neutral",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Neutral`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Badge($$renderer4, {
              variant: "success",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Success`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Badge($$renderer4, {
              variant: "warning",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Warning`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Badge($$renderer4, {
              variant: "danger",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Danger`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Badge($$renderer4, {
              variant: "info",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Info`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Sizes</p> <div class="flex flex-wrap items-center gap-2">`);
            Badge($$renderer4, {
              variant: "accent",
              size: "sm",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Small`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Badge($$renderer4, {
              variant: "accent",
              size: "md",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Medium`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Mono + icon</p> <div class="flex flex-wrap items-center gap-2">`);
            Badge($$renderer4, {
              variant: "neutral",
              mono: true,
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->v2.0.0`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Badge($$renderer4, {
              variant: "success",
              icon: Info,
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->With icon`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("button")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Button",
          paths: ["button/Button"],
          description: "Multi-variant button with primary, secondary, danger, and ghost styles. Supports three sizes, icons (left/right), responsive sizing, full-width, hide-text-on-mobile, and renders as an anchor when href is provided.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Variants</p> <div class="flex flex-wrap items-center gap-2">`);
            Button($$renderer4, {
              text: "Primary",
              variant: "primary"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Secondary",
              variant: "secondary"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Danger",
              variant: "danger"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Ghost",
              variant: "ghost"
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Sizes</p> <div class="flex flex-wrap items-center gap-2">`);
            Button($$renderer4, {
              text: "Extra Small",
              variant: "primary",
              size: "xs"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Small",
              variant: "primary",
              size: "sm"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Medium",
              variant: "primary",
              size: "md"
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">With icons</p> <div class="flex flex-wrap items-center gap-2">`);
            Button($$renderer4, {
              text: "Add",
              variant: "primary",
              icon: Plus
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Delete",
              variant: "danger",
              icon: Trash_2
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Info",
              variant: "ghost",
              icon: Info
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Next",
              variant: "secondary",
              icon: Funnel,
              iconPosition: "right"
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Disabled</p> <div class="flex flex-wrap items-center gap-2">`);
            Button($$renderer4, {
              text: "Primary",
              variant: "primary",
              disabled: true
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Secondary",
              variant: "secondary",
              disabled: true
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Danger",
              variant: "danger",
              disabled: true
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Ghost",
              variant: "ghost",
              disabled: true
            });
            $$renderer4.push(`<!----></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("card")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Card",
          paths: ["card/Card", "card/StickyCard"],
          description: "Card is a structural container with optional header/body/footer slots separated by dividers. Supports padding sizes, hoverable state, click handler, and link mode (renders as anchor). StickyCard is a separate sticky header/footer bar with left/right slots.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Header + body + footer</p> <div class="max-w-sm">`);
            Card($$renderer4, {
              children: ($$renderer5) => {
                $$renderer5.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">A quality profile for 1080p content with remux preferences and HDR scoring.</p>`);
              },
              $$slots: {
                default: true,
                header: ($$renderer5) => {
                  $$renderer5.push(`<h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">HD-1080p</h3>`);
                },
                footer: ($$renderer5) => {
                  $$renderer5.push(`<div class="flex items-center justify-between">`);
                  Badge($$renderer5, {
                    variant: "success",
                    size: "sm",
                    children: ($$renderer6) => {
                      $$renderer6.push(`<!---->Active`);
                    },
                    $$slots: { default: true }
                  });
                  $$renderer5.push(`<!----> `);
                  Button($$renderer5, {
                    text: "Edit",
                    variant: "ghost",
                    size: "xs",
                    icon: Settings
                  });
                  $$renderer5.push(`<!----></div>`);
                }
              }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Body only (minimal)</p> <div class="max-w-sm">`);
            Card($$renderer4, {
              children: ($$renderer5) => {
                $$renderer5.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">A simple body-only card with no header or footer.</p>`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Hoverable + clickable</p> <div class="max-w-sm">`);
            Card($$renderer4, {
              hoverable: true,
              onclick: () => {
              },
              children: ($$renderer5) => {
                $$renderer5.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">Hover and click this card. Shows cursor and bg transition.</p>`);
              },
              $$slots: {
                default: true,
                header: ($$renderer5) => {
                  $$renderer5.push(`<h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">Clickable Card</h3>`);
                }
              }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Padding variants</p> <div class="grid gap-3 md:grid-cols-4">`);
            Card($$renderer4, {
              padding: "none",
              children: ($$renderer5) => {
                $$renderer5.push(`<div class="p-2 text-xs text-neutral-500 dark:text-neutral-400">none</div>`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Card($$renderer4, {
              padding: "sm",
              children: ($$renderer5) => {
                $$renderer5.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">sm</p>`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Card($$renderer4, {
              padding: "md",
              children: ($$renderer5) => {
                $$renderer5.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">md</p>`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Card($$renderer4, {
              padding: "lg",
              children: ($$renderer5) => {
                $$renderer5.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">lg</p>`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">StickyCard (scroll to see)</p> <div class="relative h-48 overflow-x-hidden overflow-y-auto rounded-lg border border-neutral-200 dark:border-neutral-700">`);
            StickyCard($$renderer4, {
              position: "top",
              variant: "default",
              $$slots: {
                left: ($$renderer5) => {
                  $$renderer5.push(`<h1 class="text-neutral-900 dark:text-neutral-100">Page Title</h1> <p class="text-neutral-500 dark:text-neutral-400">Subtitle text</p>`);
                },
                right: ($$renderer5) => {
                  Button($$renderer5, {
                    text: "Save",
                    variant: "primary",
                    size: "xs"
                  });
                  $$renderer5.push(`<!----> `);
                  Button($$renderer5, {
                    text: "Cancel",
                    variant: "ghost",
                    size: "xs"
                  });
                  $$renderer5.push(`<!---->`);
                }
              }
            });
            $$renderer4.push(`<!----> <div class="p-4 pt-20"><div class="space-y-2"><!--[-->`);
            const each_array = ensure_array_like(Array(15));
            for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
              each_array[$$index];
              $$renderer4.push(`<p class="text-sm text-neutral-400">Scroll content...</p>`);
            }
            $$renderer4.push(`<!--]--></div></div></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("card-grid")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "CardGrid",
          paths: ["card/CardGrid"],
          description: "Responsive grid container for Card components. Automatically adjusts columns by breakpoint: 1 on mobile, scaling up to the configured max. Supports 1\u20134 columns and three gap sizes. Uses CSS Grid so cards in the same row share equal height.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">3 columns (resize browser to see responsive)</p> `);
            CardGrid($$renderer4, {
              columns: 3,
              children: ($$renderer5) => {
                Card($$renderer5, {
                  children: ($$renderer6) => {
                    $$renderer6.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">Full disc remux with lossless audio. This card has more text to demonstrate equal row
							heights across the grid.</p>`);
                  },
                  $$slots: {
                    default: true,
                    header: ($$renderer6) => {
                      $$renderer6.push(`<h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">Remux</h3>`);
                    },
                    footer: ($$renderer6) => {
                      Badge($$renderer6, {
                        variant: "success",
                        size: "sm",
                        children: ($$renderer7) => {
                          $$renderer7.push(`<!---->+150`);
                        },
                        $$slots: { default: true }
                      });
                    }
                  }
                });
                $$renderer5.push(`<!----> `);
                Card($$renderer5, {
                  children: ($$renderer6) => {
                    $$renderer6.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">Raw disc image. Blocked.</p>`);
                  },
                  $$slots: {
                    default: true,
                    header: ($$renderer6) => {
                      $$renderer6.push(`<h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">BR-DISK</h3>`);
                    },
                    footer: ($$renderer6) => {
                      Badge($$renderer6, {
                        variant: "danger",
                        size: "sm",
                        children: ($$renderer7) => {
                          $$renderer7.push(`<!---->-10000`);
                        },
                        $$slots: { default: true }
                      });
                    }
                  }
                });
                $$renderer5.push(`<!----> `);
                Card($$renderer5, {
                  children: ($$renderer6) => {
                    $$renderer6.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">H.264 encode.</p>`);
                  },
                  $$slots: {
                    default: true,
                    header: ($$renderer6) => {
                      $$renderer6.push(`<h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">x264</h3>`);
                    },
                    footer: ($$renderer6) => {
                      Badge($$renderer6, {
                        variant: "neutral",
                        size: "sm",
                        children: ($$renderer7) => {
                          $$renderer7.push(`<!---->0`);
                        },
                        $$slots: { default: true }
                      });
                    }
                  }
                });
                $$renderer5.push(`<!---->`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">2 columns, small gap</p> `);
            CardGrid($$renderer4, {
              columns: 2,
              gap: "sm",
              children: ($$renderer5) => {
                Card($$renderer5, {
                  padding: "sm",
                  children: ($$renderer6) => {
                    $$renderer6.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">Left card</p>`);
                  },
                  $$slots: { default: true }
                });
                $$renderer5.push(`<!----> `);
                Card($$renderer5, {
                  padding: "sm",
                  children: ($$renderer6) => {
                    $$renderer6.push(`<p class="text-sm text-neutral-600 dark:text-neutral-400">Right card</p>`);
                  },
                  $$slots: { default: true }
                });
                $$renderer5.push(`<!---->`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">4 columns, large gap</p> `);
            CardGrid($$renderer4, {
              columns: 4,
              gap: "lg",
              children: ($$renderer5) => {
                $$renderer5.push(`<!--[-->`);
                const each_array_1 = ensure_array_like([
                  "A",
                  "B",
                  "C",
                  "D"
                ]);
                for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                  let label = each_array_1[$$index_1];
                  Card($$renderer5, {
                    hoverable: true,
                    onclick: () => {
                    },
                    children: ($$renderer6) => {
                      $$renderer6.push(`<p class="text-center text-sm font-medium text-neutral-700 dark:text-neutral-300">${escape_html(label)}</p>`);
                    },
                    $$slots: { default: true }
                  });
                }
                $$renderer5.push(`<!--]-->`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Flush (cards match page background)</p> `);
            CardGrid($$renderer4, {
              columns: 3,
              flush: true,
              children: ($$renderer5) => {
                $$renderer5.push(`<!--[-->`);
                const each_array_2 = ensure_array_like([
                  "Flush A",
                  "Flush B",
                  "Flush C"
                ]);
                for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
                  let label = each_array_2[$$index_2];
                  Card($$renderer5, {
                    children: ($$renderer6) => {
                      $$renderer6.push(`<p class="text-center text-sm font-medium text-neutral-700 dark:text-neutral-300">${escape_html(label)}</p>`);
                    },
                    $$slots: { default: true }
                  });
                }
                $$renderer5.push(`<!--]-->`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("dropdown")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Dropdown",
          paths: [
            "dropdown/Dropdown",
            "dropdown/DropdownItem",
            "dropdown/DropdownSelect",
            "dropdown/CustomGroupManager"
          ],
          description: "Dropdown is a positioned menu container. DropdownItem is a selectable row with optional icon, danger, and selected states. DropdownSelect composes Button + Dropdown into a select widget. CustomGroupManager is a specialized tag grouping form.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Dropdown + DropdownItem (hover to open)</p> `);
            ActionsBar($$renderer4, {
              className: "md:justify-start",
              children: ($$renderer5) => {
                ActionButton($$renderer5, {
                  icon: Funnel,
                  hasDropdown: true,
                  dropdownPosition: "left",
                  $$slots: { dropdown: ($$renderer6) => {
                    Dropdown($$renderer6, {
                      position: "left",
                      children: ($$renderer7) => {
                        DropdownItem($$renderer7, {
                          icon: File_text,
                          label: "Normal item"
                        });
                        $$renderer7.push(`<!----> `);
                        DropdownItem($$renderer7, {
                          icon: Info,
                          label: "Selected item",
                          selected: true
                        });
                        $$renderer7.push(`<!----> `);
                        DropdownItem($$renderer7, {
                          icon: Trash_2,
                          label: "Danger item",
                          danger: true
                        });
                        $$renderer7.push(`<!----> `);
                        DropdownItem($$renderer7, {
                          icon: Plus,
                          label: "Disabled item",
                          disabled: true
                        });
                        $$renderer7.push(`<!---->`);
                      },
                      $$slots: { default: true }
                    });
                  } }
                });
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">DropdownSelect</p> <div class="flex flex-wrap items-center gap-4">`);
            DropdownSelect($$renderer4, {
              label: "Arr type",
              options: demoSelectOptions,
              position: "left",
              get value() {
                return demoSelectValue;
              },
              set value($$value) {
                demoSelectValue = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            DropdownSelect($$renderer4, {
              options: demoSelectOptions,
              position: "left",
              compact: true,
              get value() {
                return demoSelectValue;
              },
              set value($$value) {
                demoSelectValue = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            DropdownSelect($$renderer4, {
              options: demoSelectOptions,
              position: "left",
              disabled: true,
              get value() {
                return demoSelectValue;
              },
              set value($$value) {
                demoSelectValue = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("form-input")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "FormInput",
          paths: ["form/FormInput"],
          description: "Labeled field wrapper supporting text, textarea, password (with visibility toggle), readonly, required, mono font, and sizing variants (sm/md/lg).",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Size variants</p> <div class="grid gap-3 md:grid-cols-3">`);
            FormInput($$renderer4, {
              label: "Small",
              size: "sm",
              placeholder: "Small input",
              get value() {
                return demoFormText;
              },
              set value($$value) {
                demoFormText = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            FormInput($$renderer4, {
              label: "Medium",
              size: "md",
              placeholder: "Medium input",
              get value() {
                return demoFormText;
              },
              set value($$value) {
                demoFormText = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            FormInput($$renderer4, {
              label: "Large",
              size: "lg",
              placeholder: "Large input",
              get value() {
                return demoFormText;
              },
              set value($$value) {
                demoFormText = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Text + textarea</p> <div class="grid gap-3 md:grid-cols-2">`);
            FormInput($$renderer4, {
              label: "Text",
              placeholder: "Enter text...",
              get value() {
                return demoFormText;
              },
              set value($$value) {
                demoFormText = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            FormInput($$renderer4, {
              label: "Textarea",
              textarea: true,
              placeholder: "Multi-line input...",
              get value() {
                return demoFormTextarea;
              },
              set value($$value) {
                demoFormTextarea = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Password (toggle visibility)</p> <div class="max-w-sm">`);
            FormInput($$renderer4, {
              label: "Password",
              private_: true,
              placeholder: "Enter password...",
              get value() {
                return demoFormPassword;
              },
              set value($$value) {
                demoFormPassword = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Readonly + required + mono</p> <div class="grid gap-3 md:grid-cols-3">`);
            FormInput($$renderer4, {
              label: "Readonly",
              value: "Cannot edit",
              readonly: true
            });
            $$renderer4.push(`<!----> `);
            FormInput($$renderer4, {
              label: "Required",
              placeholder: "Required field",
              required: true
            });
            $$renderer4.push(`<!----> `);
            FormInput($$renderer4, {
              label: "Mono",
              value: "font-mono text",
              mono: true
            });
            $$renderer4.push(`<!----></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("number-input")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "NumberInput",
          paths: ["form/NumberInput"],
          description: "Numeric input with custom increment/decrement stepper buttons. Supports min/max/step constraints, compact sizing, responsive auto-compact, mono/sans font, and disabled state. Hides steppers on mobile when responsive.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Default + compact</p> <div class="flex flex-wrap items-center gap-3"><div class="w-32">`);
            NumberInput($$renderer4, {
              name: "demo-num",
              min: 0,
              max: 100,
              placeholder: "0\u2013100",
              get value() {
                return demoNumber;
              },
              set value($$value) {
                demoNumber = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div> <div class="w-24">`);
            NumberInput($$renderer4, {
              name: "demo-num-compact",
              min: 0,
              max: 99,
              compact: true,
              placeholder: "0\u201399",
              get value() {
                return demoNumberCompact;
              },
              set value($$value) {
                demoNumberCompact = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Mono font + disabled</p> <div class="flex flex-wrap items-center gap-3"><div class="w-32">`);
            NumberInput($$renderer4, {
              name: "demo-num-mono",
              value: 42,
              font: "mono"
            });
            $$renderer4.push(`<!----></div> <div class="w-32">`);
            NumberInput($$renderer4, {
              name: "demo-num-disabled",
              value: 0,
              disabled: true
            });
            $$renderer4.push(`<!----></div></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("icon-checkbox")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "IconCheckbox",
          paths: ["form/IconCheckbox"],
          description: "Icon-based checkbox toggle with five named colors (accent, blue, green, red, neutral) plus hex color support. Two variants (filled/outline), three shapes (rounded, square, circle). Used for toggling custom formats, conditions, etc.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Colors (filled)</p> <div class="flex flex-wrap items-center gap-3"><div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              color: "accent",
              get checked() {
                return checkedAccent;
              },
              set checked($$value) {
                checkedAccent = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Accent</span></div> <div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              color: "blue",
              get checked() {
                return checkedBlue;
              },
              set checked($$value) {
                checkedBlue = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Blue</span></div> <div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              color: "green",
              get checked() {
                return checkedGreen;
              },
              set checked($$value) {
                checkedGreen = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Green</span></div> <div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              color: "red",
              get checked() {
                return checkedRed;
              },
              set checked($$value) {
                checkedRed = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Red</span></div> <div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              color: "neutral",
              get checked() {
                return checkedNeutral;
              },
              set checked($$value) {
                checkedNeutral = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Neutral</span></div> <div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Star,
              color: "#FFC230",
              checked: true
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Hex</span></div></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Outline variant</p> <div class="flex flex-wrap items-center gap-3">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              color: "accent",
              variant: "outline",
              get checked() {
                return checkedOutline;
              },
              set checked($$value) {
                checkedOutline = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            IconCheckbox($$renderer4, {
              icon: Check,
              color: "green",
              variant: "outline",
              checked: true
            });
            $$renderer4.push(`<!----> `);
            IconCheckbox($$renderer4, {
              icon: Check,
              color: "red",
              variant: "outline",
              checked: true
            });
            $$renderer4.push(`<!----> `);
            IconCheckbox($$renderer4, {
              icon: Check,
              color: "blue",
              variant: "outline",
              checked: true
            });
            $$renderer4.push(`<!----> `);
            IconCheckbox($$renderer4, {
              icon: Check,
              color: "neutral",
              variant: "outline",
              checked: true
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Shapes + unchecked + disabled</p> <div class="flex flex-wrap items-center gap-3"><div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              shape: "rounded",
              get checked() {
                return checkedSquare;
              },
              set checked($$value) {
                checkedSquare = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Rounded</span></div> <div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              shape: "square",
              get checked() {
                return checkedSquare;
              },
              set checked($$value) {
                checkedSquare = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Square</span></div> <div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              shape: "circle",
              get checked() {
                return checkedCircle;
              },
              set checked($$value) {
                checkedCircle = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Circle</span></div> <div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              get checked() {
                return unchecked;
              },
              set checked($$value) {
                unchecked = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Unchecked</span></div> <div class="flex items-center gap-1.5">`);
            IconCheckbox($$renderer4, {
              icon: Check,
              checked: true,
              disabled: true
            });
            $$renderer4.push(`<!----> <span class="text-xs text-neutral-500 dark:text-neutral-400">Disabled</span></div></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("tag-input")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "TagInput",
          paths: ["form/TagInput"],
          description: "Tag entry field with accent Badge chips. Type and press Enter to add, click X or Backspace to remove. Duplicate detection with alert toast. Tags render as Badge components inside a styled input container.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Interactive (try adding/removing)</p> <div class="max-w-lg">`);
            TagInput($$renderer4, {
              placeholder: "Add a tag...",
              get tags() {
                return demoTags;
              },
              set tags($$value) {
                demoTags = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("dropdown-combobox")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "DropdownCombobox",
          paths: ["dropdown/DropdownCombobox"],
          description: "Single-select searchable dropdown built from Button, Dropdown, and DropdownItem. Filters options as you type, supports compact modes, fixed positioning, item slots, and disabled state.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Default + compact + disabled</p> <div class="flex flex-wrap items-start gap-4"><div class="w-56">`);
            DropdownCombobox($$renderer4, {
              fullWidth: true,
              minWidth: "0",
              dropdownWidth: "100%",
              limit: 6,
              options: demoAutoOptions,
              placeholder: "Search arrs...",
              get value() {
                return demoComboboxValue;
              },
              set value($$value) {
                demoComboboxValue = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div> <div class="w-56">`);
            DropdownCombobox($$renderer4, {
              fullWidth: true,
              minWidth: "0",
              dropdownWidth: "100%",
              limit: 4,
              compact: true,
              options: demoAutoOptions,
              placeholder: "Compact",
              get value() {
                return demoCompactComboboxValue;
              },
              set value($$value) {
                demoCompactComboboxValue = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div> <div class="w-56">`);
            DropdownCombobox($$renderer4, {
              fullWidth: true,
              minWidth: "0",
              dropdownWidth: "100%",
              options: demoAutoOptions,
              placeholder: "Disabled",
              disabled: true
            });
            $$renderer4.push(`<!----></div></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("markdown-input")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "MarkdownInput",
          paths: ["form/MarkdownInput"],
          description: "Markdown-enabled textarea or single-line input with formatting toolbar (bold, italic, code, link, lists) and live preview toggle. Supports Ctrl+B/I shortcuts, label, description, required, and disabled states.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Multiline with toolbar</p> `);
            MarkdownInput($$renderer4, {
              label: "Description",
              description: "Supports **markdown** formatting",
              placeholder: "Write something...",
              rows: 4,
              get value() {
                return demoMarkdown;
              },
              set value($$value) {
                demoMarkdown = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Single-line</p> `);
            MarkdownInput($$renderer4, {
              label: "Title",
              placeholder: "Single-line markdown...",
              multiline: false,
              get value() {
                return demoMarkdownSingle;
              },
              set value($$value) {
                demoMarkdownSingle = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Disabled</p> `);
            MarkdownInput($$renderer4, {
              label: "Locked",
              value: "Cannot edit this",
              disabled: true,
              rows: 2
            });
            $$renderer4.push(`<!----></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("range-scale")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "RangeScale",
          paths: ["form/RangeScale"],
          description: "Draggable range slider with multiple color-coded markers and badge labels. Supports 7 marker colors (accent, blue, green, orange, red, purple, neutral), horizontal/vertical orientation, step snapping, min separation between markers, unit suffixes, and unlimited value display.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Multiple markers (drag to adjust)</p> <div class="px-4 py-8">`);
            RangeScale($$renderer4, {
              min: 0,
              max: 100,
              step: 5,
              unit: "%",
              get markers() {
                return demoRangeMarkers;
              },
              set markers($$value) {
                demoRangeMarkers = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Single marker</p> <div class="px-4 py-8">`);
            RangeScale($$renderer4, {
              min: 0,
              max: 100,
              step: 1,
              get markers() {
                return demoRangeSingle;
              },
              set markers($$value) {
                demoRangeSingle = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("key-value-list")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "KeyValueList",
          paths: ["form/KeyValueList"],
          description: "Dynamic key-value pair editor with add/remove. Supports text and version value types (version uses NumberInput steppers for major.minor.patch). Responsive layout: stacked cards on mobile, grid on desktop. Supports locked first entry, custom labels, and add-disabled state.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Text mode</p> `);
            KeyValueList($$renderer4, {
              label: "Environment Variables",
              description: "Add key-value pairs",
              keyPlaceholder: "Variable name",
              valuePlaceholder: "Value",
              get value() {
                return demoKV;
              },
              set value($$value) {
                demoKV = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Version mode</p> `);
            KeyValueList($$renderer4, {
              label: "Version Constraints",
              valueType: "version",
              keyPlaceholder: "Constraint name",
              get value() {
                return demoKVVersion;
              },
              set value($$value) {
                demoKVVersion = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("label")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Label",
          paths: ["label/Label"],
          description: "Inline label/tag pill with eight color variants (default, secondary, destructive, outline, ghost, success, warning, info), three sizes, three border-radius options, optional mono font, and optional href (renders as anchor).",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Variants</p> <div class="flex flex-wrap items-center gap-2">`);
            Label($$renderer4, {
              variant: "default",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Default`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              variant: "secondary",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Secondary`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              variant: "destructive",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Destructive`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              variant: "outline",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Outline`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              variant: "ghost",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Ghost`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              variant: "success",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Success`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              variant: "warning",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Warning`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              variant: "info",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Info`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Sizes</p> <div class="flex flex-wrap items-center gap-2">`);
            Label($$renderer4, {
              size: "sm",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Small`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              size: "md",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Medium`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              size: "lg",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Large`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Rounded</p> <div class="flex flex-wrap items-center gap-2">`);
            Label($$renderer4, {
              rounded: "sm",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Rounded SM`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              rounded: "md",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Rounded MD`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              rounded: "full",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Rounded Full`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Mono + link</p> <div class="flex flex-wrap items-center gap-2">`);
            Label($$renderer4, {
              variant: "ghost",
              mono: true,
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->v2.0.0`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              variant: "secondary",
              mono: true,
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->1080p`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            Label($$renderer4, {
              variant: "info",
              href: "#label",
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->Link label`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("meta")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Code",
          paths: ["code/CodeBlock", "code/InlineCode"],
          description: "CodeBlock renders syntax-highlighted code (SQL, JSON, plaintext) with a themed code area, header slot, and copy button. InlineCode renders inline code snippets with optional icon.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">CodeBlock (SQL)</p> `);
            CodeBlock($$renderer4, {
              code: "SELECT * FROM profiles\\nWHERE name = 'HD-1080p'\\nORDER BY id;",
              language: "sql"
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">CodeBlock (JSON)</p> `);
            CodeBlock($$renderer4, {
              code: '{\n  "name": "HD-1080p",\n  "cutoff": 7,\n  "items": [4, 7, 3]\n}',
              language: "json"
            });
            $$renderer4.push(`<!----></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("modal")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Modal",
          paths: [
            "modal/Modal",
            "modal/InfoModal",
            "modal/DirtyModal"
          ],
          description: "Modal is the base confirm/cancel dialog with header, body slot, footer buttons, size/height options, loading state, and danger variant. InfoModal is a read-only modal with close button and body slot. DirtyModal is a pre-configured Modal for unsaved changes warnings (no unique styling).",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Modal (confirm/cancel)</p> <div class="flex flex-wrap items-center gap-2">`);
            Button($$renderer4, {
              text: "Open Modal",
              variant: "primary",
              size: "sm"
            });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              text: "Open Danger Modal",
              variant: "danger",
              size: "sm"
            });
            $$renderer4.push(`<!----></div> `);
            Modal($$renderer4, {
              header: "Confirm Action",
              bodyMessage: "Are you sure you want to proceed with this action?",
              confirmText: "Confirm",
              confirmDanger: demoModalDanger,
              get open() {
                return demoModalOpen;
              },
              set open($$value) {
                demoModalOpen = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">InfoModal (read-only)</p> `);
            Button($$renderer4, {
              text: "Open Info Modal",
              variant: "secondary",
              size: "sm"
            });
            $$renderer4.push(`<!----> `);
            InfoModal($$renderer4, {
              header: "About Profiles",
              get open() {
                return demoInfoModalOpen;
              },
              set open($$value) {
                demoInfoModalOpen = $$value;
                $$settled = false;
              },
              children: ($$renderer5) => {
                $$renderer5.push(`<div class="space-y-2 text-sm text-neutral-600 dark:text-neutral-400"><p>Profiles define quality preferences for your media library.</p> <p>Each profile can have custom formats, quality cutoffs, and upgrade rules.</p></div>`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("navigation")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Tabs",
          paths: ["navigation/tabs/Tabs"],
          description: "Responsive tab bar with active state underline, optional icons, breadcrumb, and back button. On mobile (when responsive), collapses to a dropdown select. Navbar, pageNav, bottomNav, accentPicker, themeToggle are app chrome \u2014 visible in the live layout already.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">With icons + breadcrumb</p> `);
            Tabs($$renderer4, {
              tabs: [
                {
                  label: "Overview",
                  href: "#tab-overview",
                  active: true,
                  icon: Info
                },
                {
                  label: "Settings",
                  href: "#tab-settings",
                  active: false,
                  icon: Settings
                },
                {
                  label: "Logs",
                  href: "#tab-logs",
                  active: false,
                  icon: File_text
                }
              ],
              breadcrumb: {
                items: [{
                  label: "Dev",
                  href: "/dev"
                }],
                current: "Components"
              }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Plain tabs</p> `);
            Tabs($$renderer4, { tabs: [
              {
                label: "General",
                href: "#tab-general",
                active: true
              },
              {
                label: "Advanced",
                href: "#tab-advanced",
                active: false
              },
              {
                label: "Danger Zone",
                href: "#tab-danger",
                active: false
              }
            ] });
            $$renderer4.push(`<!----></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("table")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Table",
          paths: [
            "table/Table",
            "table/ExpandableTable",
            "table/TableActionButton"
          ],
          description: "Table is a generic sortable data table with responsive mobile card layout. ExpandableTable adds expandable rows with chevron toggles. TableActionButton is a compact icon button for table row actions.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Table (sortable, click headers)</p> `);
            Table2($$renderer4, {
              columns: demoTableColumns,
              data: demoTableData,
              compact: true,
              $$slots: { actions: ($$renderer5, { row }) => {
                TableActionButton($$renderer5, {
                  icon: Trash_2,
                  title: "Delete",
                  variant: "danger"
                });
              } }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">ExpandableTable (click rows to expand)</p> `);
            ExpandableTable($$renderer4, {
              columns: demoTableColumns,
              data: demoTableData,
              getRowId: (row) => row.id,
              compact: true,
              $$slots: { expanded: ($$renderer5, { row }) => {
                $$renderer5.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">Details for ${escape_html(row.name)} \u2014 score: ${escape_html(row.score)}, status: ${escape_html(row.status)}</p>`);
              } }
            });
            $$renderer4.push(`<!----></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">TableActionButton variants</p> <div class="flex items-center gap-2">`);
            TableActionButton($$renderer4, {
              icon: Info,
              title: "Info",
              variant: "neutral"
            });
            $$renderer4.push(`<!----> `);
            TableActionButton($$renderer4, {
              icon: Trash_2,
              title: "Delete",
              variant: "danger"
            });
            $$renderer4.push(`<!----> `);
            TableActionButton($$renderer4, {
              icon: Settings,
              title: "Settings",
              variant: "accent"
            });
            $$renderer4.push(`<!----> `);
            TableActionButton($$renderer4, {
              icon: Info,
              title: "Small",
              variant: "neutral",
              size: "sm"
            });
            $$renderer4.push(`<!----> `);
            TableActionButton($$renderer4, {
              icon: Info,
              title: "Disabled",
              variant: "neutral",
              disabled: true
            });
            $$renderer4.push(`<!----></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (visibleIds.has("toggle")) {
        $$renderer3.push("<!--[0-->");
        ComponentCard($$renderer3, {
          name: "Toggle",
          paths: ["toggle/Toggle"],
          description: "Card-style toggle with optional label text, info modal, and IconCheckbox on the right. Supports color variants, disabled state, and fires change events.",
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Colors</p> <div class="grid gap-3 md:grid-cols-2">`);
            Toggle($$renderer4, {
              color: "accent",
              label: "Accent",
              get checked() {
                return demoToggleAccent;
              },
              set checked($$value) {
                demoToggleAccent = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            Toggle($$renderer4, {
              color: "green",
              label: "Green",
              get checked() {
                return demoToggleGreen;
              },
              set checked($$value) {
                demoToggleGreen = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            Toggle($$renderer4, {
              color: "red",
              label: "Red",
              get checked() {
                return demoToggleRed;
              },
              set checked($$value) {
                demoToggleRed = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            Toggle($$renderer4, {
              color: "amber",
              label: "Amber",
              infoHeader: "Toggle Information",
              infoBody: "Optional info content can explain what a setting changes without taking the user away from the form.",
              get checked() {
                return demoToggleAmber;
              },
              set checked($$value) {
                demoToggleAmber = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">Disabled</p> <div class="flex flex-wrap items-center gap-4">`);
            Toggle($$renderer4, {
              color: "accent",
              checked: true,
              disabled: true,
              label: "Disabled on"
            });
            $$renderer4.push(`<!----> `);
            Toggle($$renderer4, {
              color: "accent",
              checked: false,
              disabled: true,
              label: "Disabled off"
            });
            $$renderer4.push(`<!----></div></div> <div class="space-y-3"><p class="text-xs font-medium text-neutral-500 uppercase dark:text-neutral-400">No label</p> <div class="flex flex-wrap items-center gap-4">`);
            Toggle($$renderer4, {
              color: "accent",
              ariaLabel: "Accent toggle",
              get checked() {
                return demoToggleAccent;
              },
              set checked($$value) {
                demoToggleAccent = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            Toggle($$renderer4, {
              color: "green",
              ariaLabel: "Green toggle",
              get checked() {
                return demoToggleGreen;
              },
              set checked($$value) {
                demoToggleGreen = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----></div></div>`);
          },
          $$slots: { default: true }
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
var init_page_svelte40 = __esm({
  "dist/build/server/entries/pages/dev/components/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Dropdown();
    init_MarkdownInput();
    init_check();
    init_file_text();
    init_funnel();
    init_info();
    init_Button();
    init_plus();
    init_search();
    init_settings();
    init_star();
    init_ViewToggle();
    init_trash_2();
    init_Label();
    init_Card();
    init_Modal();
    init_IconCheckbox();
    init_DropdownItem();
    init_Tabs();
    init_ExpandableTable();
    init_ActionsBar();
    init_ActionButton();
    init_Badge();
    init_InfoModal();
    init_PageMeta();
    init_Table();
    init_CardGrid();
    init_StickyCard();
    init_DropdownSelect();
    init_FormInput();
    init_NumberInput();
    init_DropdownCombobox();
    init_Toggle();
    init_Score();
    init_CustomFormatBadge();
    init_TagInput();
    init_CodeBlock();
    init_KeyValueList();
    init_RangeScale();
  }
});

// dist/build/server/nodes/49.js
var __exports50 = {};
__export(__exports50, {
  component: () => component47,
  fonts: () => fonts50,
  imports: () => imports50,
  index: () => index50,
  server: () => page_server_ts_exports42,
  server_id: () => server_id48,
  stylesheets: () => stylesheets50
});
var index50, component_cache47, component47, server_id48, imports50, stylesheets50, fonts50;
var init__50 = __esm({
  "dist/build/server/nodes/49.js"() {
    "use strict";
    init_page_server_ts42();
    index50 = 49;
    component47 = async () => component_cache47 ??= (await Promise.resolve().then(() => (init_page_svelte40(), page_svelte_exports40))).default;
    server_id48 = "src/routes/dev/components/+page.server.ts";
    imports50 = ["_app/immutable/nodes/49.8cqspXYW.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/MJc6__n-.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/e-haqc9Z.js", "_app/immutable/chunks/DuBlSUgq.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/Co6rAu4X.js", "_app/immutable/chunks/C5rtWVlZ.js", "_app/immutable/chunks/CK2yQf0C.js", "_app/immutable/chunks/ITepJp4A2.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/DcKM5OzB2.js", "_app/immutable/chunks/DSNLgKve.js", "_app/immutable/chunks/Cjav3c1K2.js", "_app/immutable/chunks/XMOYB6uZ2.js"];
    stylesheets50 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css", "_app/immutable/assets/CodeBlock.Cn36jBaQ.css"];
    fonts50 = [];
  }
});

// dist/build/server/entries/pages/media-management/_page.server.ts.js
var page_server_ts_exports43 = {};
__export(page_server_ts_exports43, {
  load: () => load46
});
var ALLOWED_SECTIONS2, load46;
var init_page_server_ts43 = __esm({
  async "dist/build/server/entries/pages/media-management/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_lastDatabase();
    ALLOWED_SECTIONS2 = /* @__PURE__ */ new Set([
      "naming",
      "media-settings",
      "quality-definitions"
    ]);
    load46 = ({ cookies, url }) => {
      const rawSection = url.searchParams.get("section");
      const section = (rawSection ? ALLOWED_SECTIONS2.has(rawSection) : false) ? rawSection : getLastSection(cookies, "last_section_mm", ALLOWED_SECTIONS2, "naming");
      redirectToLastDatabase(cookies, "last_db_mm", "/media-management", { suffix: `/${section}` });
      return { databases: pcdManager.getAllPublic() };
    };
  }
});

// dist/build/server/entries/pages/media-management/_page.svelte.js
var page_svelte_exports41 = {};
__export(page_svelte_exports41, {
  default: () => _page41
});
function _page41($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: "Media Management" });
    $$renderer2.push(`<!----> `);
    if (data.databases.length === 0) {
      $$renderer2.push("<!--[0-->");
      EmptyState($$renderer2, {
        icon: Database2,
        title: "No Databases Linked",
        description: "Link a Profilarr Compliant Database to manage media settings.",
        buttonText: "Link Database",
        buttonHref: "/databases/new",
        buttonIcon: Plus
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte41 = __esm({
  "dist/build/server/entries/pages/media-management/_page.svelte.js"() {
    "use strict";
    init_server();
    init_database2();
    init_plus();
    init_PageMeta();
    init_EmptyState();
  }
});

// dist/build/server/nodes/50.js
var __exports51 = {};
__export(__exports51, {
  component: () => component48,
  fonts: () => fonts51,
  imports: () => imports51,
  index: () => index51,
  server: () => page_server_ts_exports43,
  server_id: () => server_id49,
  stylesheets: () => stylesheets51
});
var index51, component_cache48, component48, server_id49, imports51, stylesheets51, fonts51;
var init__51 = __esm({
  async "dist/build/server/nodes/50.js"() {
    "use strict";
    await init_page_server_ts43();
    index51 = 50;
    component48 = async () => component_cache48 ??= (await Promise.resolve().then(() => (init_page_svelte41(), page_svelte_exports41))).default;
    server_id49 = "src/routes/media-management/+page.server.ts";
    imports51 = ["_app/immutable/nodes/50.sZhbi6_M.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D_awjkBZ.js", "_app/immutable/chunks/B66v-P2b.js"];
    stylesheets51 = [];
    fonts51 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/_page.server.ts.js
var page_server_ts_exports44 = {};
__export(page_server_ts_exports44, {
  load: () => load47
});
var load47;
var init_page_server_ts44 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/_page.server.ts.js"() {
    "use strict";
    init_exports();
    load47 = async ({ params }) => {
      throw redirect(302, `/media-management/${params.databaseId}/naming`);
    };
  }
});

// dist/build/server/nodes/51.js
var __exports52 = {};
__export(__exports52, {
  fonts: () => fonts52,
  imports: () => imports52,
  index: () => index52,
  server: () => page_server_ts_exports44,
  server_id: () => server_id50,
  stylesheets: () => stylesheets52
});
var index52, server_id50, imports52, stylesheets52, fonts52;
var init__52 = __esm({
  "dist/build/server/nodes/51.js"() {
    "use strict";
    init_page_server_ts44();
    index52 = 51;
    server_id50 = "src/routes/media-management/[databaseId]/+page.server.ts";
    imports52 = [];
    stylesheets52 = [];
    fonts52 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/media-settings/_page.server.ts.js
var page_server_ts_exports45 = {};
__export(page_server_ts_exports45, {
  load: () => load48
});
var load48;
var init_page_server_ts45 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/media-settings/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    init_exports();
    load48 = async ({ params }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      return { mediaSettingsConfigs: await list$3(cache3) };
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/media-settings/_page.svelte.js
var page_svelte_exports42 = {};
__export(page_svelte_exports42, {
  default: () => _page42
});
function TableView5($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let configs = $$props["configs"];
    let databaseId = $$props["databaseId"];
    createEventDispatcher();
    const logos = {
      radarr: Radarr_default,
      sonarr: Sonarr_default
    };
    const propersRepacksConfig = {
      doNotPrefer: {
        variant: "neutral",
        label: "Do Not Prefer"
      },
      preferAndUpgrade: {
        variant: "success",
        label: "Prefer & Upgrade"
      },
      doNotUpgradeAutomatically: {
        variant: "warning",
        label: "No Auto Upgrade"
      }
    };
    function getRowHref(config2) {
      return `/media-management/${databaseId}/media-settings/${config2.arr_type}/${encodeURIComponent(config2.name)}`;
    }
    Table2($$renderer2, {
      columns: [
        {
          key: "name",
          header: "Name",
          headerIcon: Tag,
          align: "left",
          sortable: true
        },
        {
          key: "arr_type",
          header: "Type",
          sortable: true
        },
        {
          key: "propers_repacks",
          header: "Propers & Repacks",
          headerIcon: Refresh_cw
        },
        {
          key: "enable_media_info",
          header: "Media Info",
          headerIcon: Info
        }
      ],
      data: configs,
      rowHref: getRowHref,
      hoverable: true,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "name") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="font-medium">${escape_html(row.name)}</span>`);
          } else if (column.key === "arr_type") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="flex items-center gap-2"><img${attr("src", logos[row.arr_type])}${attr("alt", row.arr_type)} class="h-5 w-5"/></div>`);
          } else if (column.key === "propers_repacks") {
            $$renderer3.push("<!--[2-->");
            const config2 = propersRepacksConfig[row.propers_repacks] || {
              variant: "neutral",
              label: row.propers_repacks
            };
            Badge($$renderer3, {
              variant: config2.variant,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(config2.label)}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "enable_media_info") {
            $$renderer3.push("<!--[3-->");
            if (row.enable_media_info) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "success",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Enabled`);
                },
                $$slots: { default: true }
              });
            } else {
              $$renderer3.push("<!--[-1-->");
              Badge($$renderer3, {
                variant: "neutral",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Disabled`);
                },
                $$slots: { default: true }
              });
            }
            $$renderer3.push(`<!--]-->`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        actions: ($$renderer3, { row }) => {
          $$renderer3.push(`<div class="flex items-center justify-end gap-0.5">`);
          if (FEATURES.importExport) {
            $$renderer3.push("<!--[0-->");
            Button($$renderer3, {
              icon: Download,
              size: "xs",
              variant: "ghost",
              tooltip: "Export"
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          Button($$renderer3, {
            icon: Copy,
            size: "xs",
            variant: "secondary",
            tooltip: "Clone"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    bind_props($$props, {
      configs,
      databaseId
    });
  });
}
function CardView5($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let configs = $$props["configs"];
    let databaseId = $$props["databaseId"];
    createEventDispatcher();
    const logos = {
      radarr: Radarr_default,
      sonarr: Sonarr_default
    };
    const propersRepacksConfig = {
      doNotPrefer: {
        variant: "secondary",
        label: "Do Not Prefer"
      },
      preferAndUpgrade: {
        variant: "success",
        label: "Prefer & Upgrade"
      },
      doNotUpgradeAutomatically: {
        variant: "warning",
        label: "No Auto Upgrade"
      }
    };
    let loadedImages = /* @__PURE__ */ new Set();
    function getConfigHref(config2) {
      return `/media-management/${databaseId}/media-settings/${config2.arr_type}/${encodeURIComponent(config2.name)}`;
    }
    CardGrid($$renderer2, {
      columns: 4,
      flush: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(configs);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let config2 = each_array[$$index];
          const prConfig = propersRepacksConfig[config2.propers_repacks] || {
            variant: "secondary",
            label: config2.propers_repacks
          };
          Card($$renderer3, {
            href: getConfigHref(config2),
            hoverable: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="space-y-1"><div class="flex items-center justify-between gap-2 text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
              Refresh_cw($$renderer4, { size: 11 });
              $$renderer4.push(`<!---->Propers / Repacks</span> `);
              Label($$renderer4, {
                variant: prConfig.variant,
                size: "sm",
                rounded: "md",
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->${escape_html(prConfig.label)}`);
                },
                $$slots: { default: true }
              });
              $$renderer4.push(`<!----></div> <div class="flex items-center justify-between text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
              Info($$renderer4, { size: 11 });
              $$renderer4.push(`<!---->Media info</span> <span class="font-mono text-neutral-900 dark:text-neutral-100">${escape_html(config2.enable_media_info ? "\u2713" : "\u2717")}</span></div></div>`);
            },
            $$slots: {
              default: true,
              header: ($$renderer4) => {
                $$renderer4.push(`<div class="flex items-center justify-between gap-2"><div class="flex min-w-0 items-center gap-2"><div class="relative h-6 w-6 flex-shrink-0">`);
                if (!loadedImages.has(config2.name)) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="absolute inset-0 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> <img${attr("src", logos[config2.arr_type])}${attr("alt", `${stringify(config2.arr_type)} logo`)}${attr_class(`h-6 w-6 rounded ${loadedImages.has(config2.name) ? "opacity-100" : "opacity-0"}`)}/></div> <h3 class="truncate text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(config2.name)}</h3></div> <div class="flex items-center gap-0.5">`);
                if (FEATURES.importExport) {
                  $$renderer4.push("<!--[0-->");
                  Button($$renderer4, {
                    icon: Download,
                    size: "xs",
                    variant: "ghost",
                    tooltip: "Export"
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                Button($$renderer4, {
                  icon: Copy,
                  size: "xs",
                  variant: "ghost",
                  tooltip: "Clone"
                });
                $$renderer4.push(`<!----></div></div>`);
              }
            }
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    bind_props($$props, {
      configs,
      databaseId
    });
  });
}
function _page42($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    let cloneModalOpen = false;
    let cloneSourceName = "";
    let cloneEntityType = "radarr_media_settings";
    const { search, view, filtered, setItems } = createDataPageStore(data.mediaSettingsConfigs, {
      storageKey: "mediaSettingsView",
      searchKeys: ["name"],
      searchKey: `mediaSettingsConfigsSearch:${data.currentDatabase.id}`
    });
    $: setItems(data.mediaSettingsConfigs);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.currentDatabase.name} \xB7 Media Settings` });
      $$renderer3.push(`<!----> `);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore: search,
            placeholder: "Search media settings...",
            responsive: true
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Plus,
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
              Dropdown($$renderer5, {
                position: dropdownPosition,
                minWidth: "10rem",
                children: ($$renderer6) => {
                  DropdownHeader($$renderer6, { label: "New config" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, { label: "Radarr" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, { label: "Sonarr" });
                  $$renderer6.push(`<!---->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          ViewToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$view", view);
            },
            set value($$value) {
              store_set(view, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> <div class="mt-6">`);
      if (data.mediaSettingsConfigs.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No media settings configs found for ${escape_html(data.currentDatabase?.name)}</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$filtered", filtered).length === 0) {
        $$renderer3.push("<!--[1-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No media settings configs match your search</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$view", view) === "table") {
        $$renderer3.push("<!--[2-->");
        TableView5($$renderer3, {
          configs: store_get($$store_subs ??= {}, "$filtered", filtered),
          databaseId: data.currentDatabase.id
        });
      } else {
        $$renderer3.push("<!--[-1-->");
        CardView5($$renderer3, {
          configs: store_get($$store_subs ??= {}, "$filtered", filtered),
          databaseId: data.currentDatabase.id
        });
      }
      $$renderer3.push(`<!--]--></div> `);
      CloneModal($$renderer3, {
        databaseId: data.currentDatabase.id,
        entityType: cloneEntityType,
        sourceName: cloneSourceName,
        existingNames: data.mediaSettingsConfigs.map((c2) => c2.name),
        canWriteToBase: data.canWriteToBase,
        get open() {
          return cloneModalOpen;
        },
        set open($$value) {
          cloneModalOpen = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte42 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/media-settings/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_features();
    init_Dropdown();
    init_copy();
    init_download();
    init_info();
    init_Button();
    init_plus();
    init_refresh_cw();
    init_search();
    init_ViewToggle();
    init_tag();
    init_store2();
    init_Label();
    init_Card();
    init_Sonarr2();
    init_navigation();
    init_DropdownItem();
    init_ActionsBar();
    init_ActionButton();
    init_Badge();
    init_DropdownHeader();
    init_PageMeta();
    init_Table();
    init_CardGrid();
    init_dataPage();
    init_CloneModal();
  }
});

// dist/build/server/nodes/52.js
var __exports53 = {};
__export(__exports53, {
  component: () => component49,
  fonts: () => fonts53,
  imports: () => imports53,
  index: () => index53,
  server: () => page_server_ts_exports45,
  server_id: () => server_id51,
  stylesheets: () => stylesheets53
});
var index53, component_cache49, component49, server_id51, imports53, stylesheets53, fonts53;
var init__53 = __esm({
  async "dist/build/server/nodes/52.js"() {
    "use strict";
    await init_page_server_ts45();
    index53 = 52;
    component49 = async () => component_cache49 ??= (await Promise.resolve().then(() => (init_page_svelte42(), page_svelte_exports42))).default;
    server_id51 = "src/routes/media-management/[databaseId]/media-settings/+page.server.ts";
    imports53 = ["_app/immutable/nodes/52.CNyqmFQx.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/D7OHFWTL2.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/Cut3gr1-.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/Dg15A-ry2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DxZIQ_tr2.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/DYe9q02k2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js"];
    stylesheets53 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts53 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/media-settings/new/_page.server.ts.js
var page_server_ts_exports46 = {};
__export(page_server_ts_exports46, {
  actions: () => actions28,
  load: () => load49
});
var load49, actions28;
var init_page_server_ts46 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/media-settings/new/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_media_settings();
    init_exports();
    load49 = async ({ parent }) => {
      return { canWriteToBase: (await parent()).canWriteToBase };
    };
    actions28 = { default: async ({ request, params }) => {
      const { databaseId } = params;
      if (!databaseId) return fail(400, { error: "Missing database ID" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const arrType = formData.get("arrType");
      const name = formData.get("name");
      const layer = formData.get("layer") || "user";
      if (!name?.trim()) return fail(400, { error: "Name is required" });
      if (!arrType || arrType !== "radarr" && arrType !== "sonarr") return fail(400, { error: "Invalid arr type" });
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      const propersRepacks = formData.get("propersRepacks");
      const enableMediaInfo = formData.get("enableMediaInfo") === "true";
      const createFn = arrType === "radarr" ? createRadarrMediaSettings : createSonarrMediaSettings;
      let result;
      try {
        result = await createFn({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          input: {
            name: name.trim(),
            propersRepacks: propersRepacks || "doNotPrefer",
            enableMediaInfo
          }
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : `Failed to create ${arrType} media settings`;
        if (message2.includes("already exists")) return fail(400, { error: message2 });
        return fail(500, { error: message2 });
      }
      if (!result.success) return fail(500, { error: result.error || `Failed to create ${arrType} media settings` });
      throw redirect(303, `/media-management/${databaseId}/media-settings`);
    } };
  }
});

// dist/build/server/chunks/MediaSettingsForm.js
function MediaSettingsForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let formData, databaseId, arrLabel, title, description, isValid, propersRepacksDescription, canConfirmPropersRepacks;
    let mode = $$props["mode"];
    let arrType = $$props["arrType"];
    let databaseName = $$props["databaseName"];
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let actionUrl = fallback($$props["actionUrl"], "");
    let breadcrumbItems = fallback($$props["breadcrumbItems"], () => [], true);
    let breadcrumbCurrent = fallback($$props["breadcrumbCurrent"], "");
    let initialData = $$props["initialData"];
    const defaults = {
      name: "",
      propersRepacks: "doNotPrefer",
      enableMediaInfo: true
    };
    function mapToFormData(data) {
      if (!data) return defaults;
      return {
        name: data.name,
        propersRepacks: data.propers_repacks,
        enableMediaInfo: data.enable_media_info
      };
    }
    if (mode === "create") initCreate(mapToFormData(initialData));
    else initEdit(mapToFormData(initialData));
    let saving = false;
    let deleting = false;
    let showDeleteModal = false;
    let showSyncModal = false;
    let showPropersRepacksModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    let propersRepacksConfirmation = "";
    let propersRepacksConfirmationElement = null;
    let propersRepacksPasteElement = null;
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    function blockPropersRepacksPaste(event) {
      event.preventDefault();
    }
    onDestroy(() => {
      propersRepacksPasteElement?.removeEventListener("paste", blockPropersRepacksPaste);
    });
    $: formData = store_get($$store_subs ??= {}, "$current", current2);
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: arrLabel = arrType === "radarr" ? "Radarr" : "Sonarr";
    $: title = mode === "create" ? `New ${arrLabel} Media Settings` : `Edit ${arrLabel} Media Settings`;
    $: description = mode === "create" ? `Create a new ${arrLabel} media settings configuration for ${databaseName}` : `Update ${arrLabel} media settings configuration`;
    $: isValid = formData.name.trim() !== "";
    $: propersRepacksDescription = PROPERS_REPACKS_OPTIONS.find((o) => o.value === formData.propersRepacks)?.description ?? "";
    $: canConfirmPropersRepacks = false;
    $: if (propersRepacksConfirmationElement !== propersRepacksPasteElement) {
      propersRepacksPasteElement?.removeEventListener("paste", blockPropersRepacksPaste);
      propersRepacksPasteElement = propersRepacksConfirmationElement;
      propersRepacksPasteElement?.addEventListener("paste", blockPropersRepacksPaste);
    }
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      StickyCard($$renderer3, {
        position: "top",
        breadcrumbItems,
        breadcrumbCurrent,
        stickyBreadcrumb: false,
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<div slot="left"><h1 class="text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h1> <p class="text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p></div>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div slot="right" class="flex items-center gap-2">`);
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                text: "Delete",
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                disabled: saving
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            Button($$renderer4, {
              text: mode === "create" ? "Create" : "Save",
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              disabled: !isValid || !store_get($$store_subs ??= {}, "$isDirty", isDirty)
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="md:px-4"><div class="space-y-6"><div data-onboarding="media-settings-name">`);
      FormInput($$renderer3, {
        label: "Name",
        name: "name",
        placeholder: "e.g., default",
        required: true,
        description: "The name of this media settings configuration.",
        value: formData.name
      });
      $$renderer3.push(`<!----></div> <div class="space-y-2" data-onboarding="media-settings-propers-repacks"><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Propers and Repacks</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Choose how ${escape_html(arrLabel)} handles proper and repack releases.</p></div> `);
      DropdownSelect($$renderer3, {
        value: formData.propersRepacks,
        options: PROPERS_REPACKS_OPTIONS,
        fullWidth: true
      });
      $$renderer3.push(`<!----> `);
      if (propersRepacksDescription) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<p class="text-xs text-neutral-600 dark:text-neutral-400">${escape_html(propersRepacksDescription)}</p>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> <div class="space-y-2" data-onboarding="media-settings-file-analysis"><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">File Analysis</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Scan files to extract media information such as codec, resolution, and audio tracks.</p></div> `);
      Toggle($$renderer3, {
        label: "Enable Media Info",
        checked: formData.enableMediaInfo
      });
      $$renderer3.push(`<!----></div></div></div> <form method="POST"${attr("action", actionUrl)} class="hidden"><input type="hidden" name="arrType"${attr("value", arrType)}/> <input type="hidden" name="name"${attr("value", formData.name)}/> <input type="hidden" name="propersRepacks"${attr("value", formData.propersRepacks)}/> <input type="hidden" name="enableMediaInfo"${attr("value", formData.enableMediaInfo)}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/></form> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form method="POST" action="?/delete" class="hidden"><input type="hidden" name="layer"${attr("value", selectedLayer)}/></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      Modal($$renderer3, {
        open: showDeleteModal,
        header: `Delete ${arrLabel} media settings`,
        bodyMessage: "This will remove the media settings config and write a delete op. You can recreate it later if needed.",
        confirmText: "Delete",
        cancelText: "Cancel",
        confirmDanger: true,
        confirmDisabled: deleting,
        loading: deleting
      });
      $$renderer3.push(`<!----> `);
      Modal($$renderer3, {
        open: showPropersRepacksModal,
        header: "Change propers and repacks",
        confirmText: "Change",
        cancelText: "Cancel",
        confirmDanger: true,
        confirmDisabled: !canConfirmPropersRepacks,
        $$slots: { body: ($$renderer4) => {
          $$renderer4.push(`<div slot="body" class="space-y-4"><p class="text-sm text-neutral-700 dark:text-neutral-300">Profilarr expects proper and repack preferences to be handled by custom formats. Changing this
			setting enables Arr's built-in preference system, which can override custom format scores and
			make grab decisions look wrong or inconsistent.</p> <p class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Type <span class="font-mono">I UNDERSTAND THIS CAN BREAK CUSTOM FORMAT SCORING AND CAUSE INCONSISTENT GRAB BEHAVIOR</span> to continue.</p> `);
          FormInput($$renderer4, {
            label: "Confirmation",
            name: "propers-repacks-confirmation",
            value: propersRepacksConfirmation,
            placeholder: "Type the confirmation text",
            description: "Type the confirmation text exactly to unlock this change.",
            get inputElement() {
              return propersRepacksConfirmationElement;
            },
            set inputElement($$value) {
              propersRepacksConfirmationElement = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----></div>`);
        } }
      });
      $$renderer3.push(`<!----> `);
      SyncPromptModal($$renderer3, {
        redirectTo: pendingRedirectTo,
        affectedArrs: pendingAffectedArrs,
        entityType: "mediaSettings",
        databaseId,
        entityName: formData.name.trim(),
        get open() {
          return showSyncModal;
        },
        set open($$value) {
          showSyncModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      arrType,
      databaseName,
      canWriteToBase: canWriteToBase2,
      actionUrl,
      breadcrumbItems,
      breadcrumbCurrent,
      initialData
    });
  });
}
var init_MediaSettingsForm = __esm({
  "dist/build/server/chunks/MediaSettingsForm.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_mediaManagement();
    init_Button();
    init_save();
    init_trash_2();
    init_stores();
    init_store2();
    init_navigation();
    init_Modal();
    init_forms();
    init_dirty();
    init_StickyCard();
    init_DropdownSelect();
    init_FormInput();
    init_Toggle();
    init_SyncPromptModal();
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/media-settings/new/_page.svelte.js
var page_svelte_exports43 = {};
__export(page_svelte_exports43, {
  default: () => _page43
});
function _page43($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    let selectedArrType = store_get($$store_subs ??= {}, "$page", page).url.searchParams.get("arrType");
    PageMeta($$renderer2, { title: `${data.currentDatabase.name} \xB7 Media Settings \xB7 New` });
    $$renderer2.push(`<!----> `);
    if (selectedArrType) {
      $$renderer2.push("<!--[0-->");
      MediaSettingsForm($$renderer2, {
        mode: "create",
        arrType: selectedArrType,
        databaseName: data.currentDatabase?.name,
        canWriteToBase: data.canWriteToBase,
        initialData: null
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte43 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/media-settings/new/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_client4();
    init_stores();
    init_navigation();
    init_DirtyModal();
    init_PageMeta();
    init_MediaSettingsForm();
  }
});

// dist/build/server/nodes/53.js
var __exports54 = {};
__export(__exports54, {
  component: () => component50,
  fonts: () => fonts54,
  imports: () => imports54,
  index: () => index54,
  server: () => page_server_ts_exports46,
  server_id: () => server_id52,
  stylesheets: () => stylesheets54
});
var index54, component_cache50, component50, server_id52, imports54, stylesheets54, fonts54;
var init__54 = __esm({
  async "dist/build/server/nodes/53.js"() {
    "use strict";
    await init_page_server_ts46();
    index54 = 53;
    component50 = async () => component_cache50 ??= (await Promise.resolve().then(() => (init_page_svelte43(), page_svelte_exports43))).default;
    server_id52 = "src/routes/media-management/[databaseId]/media-settings/new/+page.server.ts";
    imports54 = ["_app/immutable/nodes/53.B9zNSf4q.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/CZKMGon_2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CrAcgBQ22.js"];
    stylesheets54 = [];
    fonts54 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/media-settings/radarr/_name_/_page.server.ts.js
var page_server_ts_exports47 = {};
__export(page_server_ts_exports47, {
  actions: () => actions29,
  load: () => load50
});
var load50, actions29;
var init_page_server_ts47 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/media-settings/radarr/_name_/_page.server.ts.js"() {
    "use strict";
    await init_arrSync();
    await init_queueService();
    await init_media_settings();
    await init_update2();
    await init_affectedArrs();
    init_exports();
    load50 = async ({ params, parent }) => {
      const { databaseId, name } = params;
      if (!databaseId || !name) throw error(400, "Missing parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const mediaSettingsConfig = await getRadarrByName$2(cache3, decodeURIComponent(name));
      if (!mediaSettingsConfig) throw error(404, "Media settings config not found");
      return {
        mediaSettingsConfig,
        canWriteToBase: (await parent()).canWriteToBase
      };
    };
    actions29 = {
      update: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const decodedName = decodeURIComponent(name);
        const current3 = await getRadarrByName$2(cache3, decodedName);
        if (!current3) return fail(404, { error: "Media settings config not found" });
        const formData = await request.formData();
        const newName = formData.get("name");
        const layer = formData.get("layer") || "user";
        if (!newName?.trim()) return fail(400, { error: "Name is required" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const propersRepacks = formData.get("propersRepacks");
        const enableMediaInfo = formData.get("enableMediaInfo") === "true";
        let result;
        try {
          result = await updateRadarrMediaSettings({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            current: current3,
            input: {
              name: newName.trim(),
              propersRepacks: propersRepacks || "doNotPrefer",
              enableMediaInfo
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update media settings config";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update media settings config" });
        if (newName.trim() !== decodedName) arrSyncQueries.updateMediaSettingsConfigName(decodedName, newName.trim());
        const affectedArrs = getAffectedArrs({
          entityType: "mediaSettings",
          databaseId: currentDatabaseId,
          entityName: newName.trim()
        });
        return {
          success: true,
          redirectTo: `/media-management/${databaseId}/media-settings`,
          affectedArrs
        };
      },
      delete: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await getRadarrByName$2(cache3, decodeURIComponent(name));
        if (!current3) return fail(404, { error: "Media settings config not found" });
        const layer = (await request.formData()).get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await removeRadarrMediaSettings({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          current: current3
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete media settings config" });
        throw redirect(303, `/media-management/${databaseId}/media-settings`);
      }
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/media-settings/radarr/_name_/_page.svelte.js
var page_svelte_exports44 = {};
__export(page_svelte_exports44, {
  default: () => _page44
});
function _page44($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: `${data.mediaSettingsConfig.name} \xB7 Radarr Media Settings` });
    $$renderer2.push(`<!----> `);
    MediaSettingsForm($$renderer2, {
      mode: "edit",
      arrType: "radarr",
      databaseName: data.currentDatabase?.name,
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      initialData: data.mediaSettingsConfig,
      breadcrumbItems: [{
        label: data.currentDatabase.name,
        href: `/media-management/${data.currentDatabase.id}/media-settings`
      }],
      breadcrumbCurrent: data.mediaSettingsConfig.name
    });
    $$renderer2.push(`<!----> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte44 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/media-settings/radarr/_name_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_DirtyModal();
    init_PageMeta();
    init_MediaSettingsForm();
  }
});

// dist/build/server/nodes/54.js
var __exports55 = {};
__export(__exports55, {
  component: () => component51,
  fonts: () => fonts55,
  imports: () => imports55,
  index: () => index55,
  server: () => page_server_ts_exports47,
  server_id: () => server_id53,
  stylesheets: () => stylesheets55
});
var index55, component_cache51, component51, server_id53, imports55, stylesheets55, fonts55;
var init__55 = __esm({
  async "dist/build/server/nodes/54.js"() {
    "use strict";
    await init_page_server_ts47();
    index55 = 54;
    component51 = async () => component_cache51 ??= (await Promise.resolve().then(() => (init_page_svelte44(), page_svelte_exports44))).default;
    server_id53 = "src/routes/media-management/[databaseId]/media-settings/radarr/[name]/+page.server.ts";
    imports55 = ["_app/immutable/nodes/54.Dz-ORJhy.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/CZKMGon_2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CrAcgBQ22.js"];
    stylesheets55 = [];
    fonts55 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/media-settings/sonarr/_name_/_page.server.ts.js
var page_server_ts_exports48 = {};
__export(page_server_ts_exports48, {
  actions: () => actions30,
  load: () => load51
});
var load51, actions30;
var init_page_server_ts48 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/media-settings/sonarr/_name_/_page.server.ts.js"() {
    "use strict";
    await init_arrSync();
    await init_queueService();
    await init_media_settings();
    await init_update2();
    await init_affectedArrs();
    init_exports();
    load51 = async ({ params, parent }) => {
      const { databaseId, name } = params;
      if (!databaseId || !name) throw error(400, "Missing parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const mediaSettingsConfig = await getSonarrByName$2(cache3, decodeURIComponent(name));
      if (!mediaSettingsConfig) throw error(404, "Media settings config not found");
      return {
        mediaSettingsConfig,
        canWriteToBase: (await parent()).canWriteToBase
      };
    };
    actions30 = {
      update: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const decodedName = decodeURIComponent(name);
        const current3 = await getSonarrByName$2(cache3, decodedName);
        if (!current3) return fail(404, { error: "Media settings config not found" });
        const formData = await request.formData();
        const newName = formData.get("name");
        const layer = formData.get("layer") || "user";
        if (!newName?.trim()) return fail(400, { error: "Name is required" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const propersRepacks = formData.get("propersRepacks");
        const enableMediaInfo = formData.get("enableMediaInfo") === "true";
        let result;
        try {
          result = await updateSonarrMediaSettings({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            current: current3,
            input: {
              name: newName.trim(),
              propersRepacks: propersRepacks || "doNotPrefer",
              enableMediaInfo
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update media settings config";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update media settings config" });
        if (newName.trim() !== decodedName) arrSyncQueries.updateMediaSettingsConfigName(decodedName, newName.trim());
        const affectedArrs = getAffectedArrs({
          entityType: "mediaSettings",
          databaseId: currentDatabaseId,
          entityName: newName.trim()
        });
        return {
          success: true,
          redirectTo: `/media-management/${databaseId}/media-settings`,
          affectedArrs
        };
      },
      delete: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await getSonarrByName$2(cache3, decodeURIComponent(name));
        if (!current3) return fail(404, { error: "Media settings config not found" });
        const layer = (await request.formData()).get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await removeSonarrMediaSettings({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          current: current3
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete media settings config" });
        throw redirect(303, `/media-management/${databaseId}/media-settings`);
      }
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/media-settings/sonarr/_name_/_page.svelte.js
var page_svelte_exports45 = {};
__export(page_svelte_exports45, {
  default: () => _page45
});
function _page45($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: `${data.mediaSettingsConfig.name} \xB7 Sonarr Media Settings` });
    $$renderer2.push(`<!----> `);
    MediaSettingsForm($$renderer2, {
      mode: "edit",
      arrType: "sonarr",
      databaseName: data.currentDatabase?.name,
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      initialData: data.mediaSettingsConfig,
      breadcrumbItems: [{
        label: data.currentDatabase.name,
        href: `/media-management/${data.currentDatabase.id}/media-settings`
      }],
      breadcrumbCurrent: data.mediaSettingsConfig.name
    });
    $$renderer2.push(`<!----> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte45 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/media-settings/sonarr/_name_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_DirtyModal();
    init_PageMeta();
    init_MediaSettingsForm();
  }
});

// dist/build/server/nodes/55.js
var __exports56 = {};
__export(__exports56, {
  component: () => component52,
  fonts: () => fonts56,
  imports: () => imports56,
  index: () => index56,
  server: () => page_server_ts_exports48,
  server_id: () => server_id54,
  stylesheets: () => stylesheets56
});
var index56, component_cache52, component52, server_id54, imports56, stylesheets56, fonts56;
var init__56 = __esm({
  async "dist/build/server/nodes/55.js"() {
    "use strict";
    await init_page_server_ts48();
    index56 = 55;
    component52 = async () => component_cache52 ??= (await Promise.resolve().then(() => (init_page_svelte45(), page_svelte_exports45))).default;
    server_id54 = "src/routes/media-management/[databaseId]/media-settings/sonarr/[name]/+page.server.ts";
    imports56 = ["_app/immutable/nodes/55.BHklhwM5.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/CZKMGon_2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CrAcgBQ22.js"];
    stylesheets56 = [];
    fonts56 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/naming/_page.server.ts.js
var page_server_ts_exports49 = {};
__export(page_server_ts_exports49, {
  load: () => load52
});
var load52;
var init_page_server_ts49 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/naming/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    init_exports();
    load52 = async ({ params }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      return { namingConfigs: await list$2(cache3) };
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/naming/_page.svelte.js
var page_svelte_exports46 = {};
__export(page_svelte_exports46, {
  default: () => _page46
});
function Ban($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "ban" },
    props,
    { iconNode: [["circle", {
      "cx": "12",
      "cy": "12",
      "r": "10"
    }], ["path", { "d": "M4.929 4.929 19.07 19.071" }]] }
  ]));
}
function Replace($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "replace" },
    props,
    { iconNode: [
      ["path", { "d": "M14 4a1 1 0 0 1 1-1" }],
      ["path", { "d": "M15 10a1 1 0 0 1-1-1" }],
      ["path", { "d": "M21 4a1 1 0 0 0-1-1" }],
      ["path", { "d": "M21 9a1 1 0 0 1-1 1" }],
      ["path", { "d": "m3 7 3 3 3-3" }],
      ["path", { "d": "M6 10V5a2 2 0 0 1 2-2h2" }],
      ["rect", {
        "x": "3",
        "y": "14",
        "width": "7",
        "height": "7",
        "rx": "1"
      }]
    ] }
  ]));
}
function Toggle_right($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "toggle-right" },
    props,
    { iconNode: [["circle", {
      "cx": "15",
      "cy": "12",
      "r": "3"
    }], ["rect", {
      "width": "20",
      "height": "14",
      "x": "2",
      "y": "5",
      "rx": "7"
    }]] }
  ]));
}
function TableView6($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let configs = $$props["configs"];
    let databaseId = $$props["databaseId"];
    createEventDispatcher();
    const logos = {
      radarr: Radarr_default,
      sonarr: Sonarr_default
    };
    function getRowHref(config2) {
      return `/media-management/${databaseId}/naming/${config2.arr_type}/${encodeURIComponent(config2.name)}`;
    }
    Table2($$renderer2, {
      columns: [
        {
          key: "name",
          header: "Name",
          headerIcon: Tag,
          align: "left",
          sortable: true
        },
        {
          key: "arr_type",
          header: "Type",
          sortable: true
        },
        {
          key: "rename",
          header: "Rename",
          headerIcon: Toggle_right
        }
      ],
      data: configs,
      rowHref: getRowHref,
      hoverable: true,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "name") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="font-medium">${escape_html(row.name)}</span>`);
          } else if (column.key === "arr_type") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="flex items-center gap-2"><img${attr("src", logos[row.arr_type])}${attr("alt", row.arr_type)} class="h-5 w-5"/></div>`);
          } else if (column.key === "rename") {
            $$renderer3.push("<!--[2-->");
            if (row.rename) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "success",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Enabled`);
                },
                $$slots: { default: true }
              });
            } else {
              $$renderer3.push("<!--[-1-->");
              Badge($$renderer3, {
                variant: "neutral",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Disabled`);
                },
                $$slots: { default: true }
              });
            }
            $$renderer3.push(`<!--]-->`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        actions: ($$renderer3, { row }) => {
          $$renderer3.push(`<div class="flex items-center justify-end gap-0.5">`);
          if (FEATURES.importExport) {
            $$renderer3.push("<!--[0-->");
            Button($$renderer3, {
              icon: Download,
              size: "xs",
              variant: "ghost",
              tooltip: "Export"
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          Button($$renderer3, {
            icon: Copy,
            size: "xs",
            variant: "secondary",
            tooltip: "Clone"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    bind_props($$props, {
      configs,
      databaseId
    });
  });
}
function CardView6($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let configs = $$props["configs"];
    let databaseId = $$props["databaseId"];
    createEventDispatcher();
    const logos = {
      radarr: Radarr_default,
      sonarr: Sonarr_default
    };
    let loadedImages = /* @__PURE__ */ new Set();
    function getConfigHref(config2) {
      return `/media-management/${databaseId}/naming/${config2.arr_type}/${encodeURIComponent(config2.name)}`;
    }
    function formatColonReplacement(value2) {
      switch (value2) {
        case "delete":
          return "Delete";
        case "dash":
          return "Dash";
        case "spaceDash":
          return "Space dash";
        case "spaceDashSpace":
          return "Space dash space";
        case "smart":
          return "Smart";
        case "custom":
          return "Custom";
      }
    }
    CardGrid($$renderer2, {
      columns: 3,
      flush: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(configs);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let config2 = each_array[$$index];
          Card($$renderer3, {
            href: getConfigHref(config2),
            hoverable: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="space-y-1"><div class="flex items-center justify-between text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
              Pencil($$renderer4, { size: 11 });
              $$renderer4.push(`<!---->Rename</span> <span class="font-mono text-neutral-900 dark:text-neutral-100">${escape_html(config2.rename ? "\u2713" : "\u2717")}</span></div> <div class="flex items-center justify-between text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
              Ban($$renderer4, { size: 11 });
              $$renderer4.push(`<!---->Illegal characters</span> <span class="font-mono text-neutral-900 dark:text-neutral-100">${escape_html(config2.replace_illegal_characters ? "\u2713" : "\u2717")}</span></div> `);
              if (config2.replace_illegal_characters) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="flex items-center justify-between gap-2 text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
                Replace($$renderer4, { size: 11 });
                $$renderer4.push(`<!---->Colon replacement</span> <span class="truncate font-mono text-neutral-900 dark:text-neutral-100">${escape_html(formatColonReplacement(config2.colon_replacement_format))}</span></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> `);
              if (config2.arr_type === "sonarr" && config2.multi_episode_style !== null) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="flex items-center justify-between gap-2 text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
                List($$renderer4, { size: 11 });
                $$renderer4.push(`<!---->Multi-episode</span> <span class="truncate font-mono text-neutral-900 dark:text-neutral-100">${escape_html(getMultiEpisodeStyleLabel(config2.multi_episode_style))}</span></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></div>`);
            },
            $$slots: {
              default: true,
              header: ($$renderer4) => {
                $$renderer4.push(`<div class="flex items-center justify-between gap-2"><div class="flex min-w-0 items-center gap-2"><div class="relative h-6 w-6 flex-shrink-0">`);
                if (!loadedImages.has(config2.name)) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="absolute inset-0 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> <img${attr("src", logos[config2.arr_type])}${attr("alt", `${stringify(config2.arr_type)} logo`)}${attr_class(`h-6 w-6 rounded ${loadedImages.has(config2.name) ? "opacity-100" : "opacity-0"}`)}/></div> <h3 class="truncate text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(config2.name)}</h3></div> <div class="flex items-center gap-0.5">`);
                if (FEATURES.importExport) {
                  $$renderer4.push("<!--[0-->");
                  Button($$renderer4, {
                    icon: Download,
                    size: "xs",
                    variant: "ghost",
                    tooltip: "Export"
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                Button($$renderer4, {
                  icon: Copy,
                  size: "xs",
                  variant: "ghost",
                  tooltip: "Clone"
                });
                $$renderer4.push(`<!----></div></div>`);
              }
            }
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    bind_props($$props, {
      configs,
      databaseId
    });
  });
}
function _page46($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    let cloneModalOpen = false;
    let cloneSourceName = "";
    let cloneEntityType = "radarr_naming";
    const { search, view, filtered, setItems } = createDataPageStore(data.namingConfigs, {
      storageKey: "namingSettingsView",
      searchKeys: ["name"],
      searchKey: `namingConfigsSearch:${data.currentDatabase.id}`
    });
    $: setItems(data.namingConfigs);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.currentDatabase.name} \xB7 Naming` });
      $$renderer3.push(`<!----> `);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore: search,
            placeholder: "Search naming configs...",
            responsive: true
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Plus,
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
              Dropdown($$renderer5, {
                position: dropdownPosition,
                minWidth: "10rem",
                children: ($$renderer6) => {
                  DropdownHeader($$renderer6, { label: "New config" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, { label: "Radarr" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, { label: "Sonarr" });
                  $$renderer6.push(`<!---->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          ViewToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$view", view);
            },
            set value($$value) {
              store_set(view, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> <div class="mt-6">`);
      if (data.namingConfigs.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No naming configs found for ${escape_html(data.currentDatabase?.name)}</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$filtered", filtered).length === 0) {
        $$renderer3.push("<!--[1-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No naming configs match your search</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$view", view) === "table") {
        $$renderer3.push("<!--[2-->");
        TableView6($$renderer3, {
          configs: store_get($$store_subs ??= {}, "$filtered", filtered),
          databaseId: data.currentDatabase.id
        });
      } else {
        $$renderer3.push("<!--[-1-->");
        CardView6($$renderer3, {
          configs: store_get($$store_subs ??= {}, "$filtered", filtered),
          databaseId: data.currentDatabase.id
        });
      }
      $$renderer3.push(`<!--]--></div> `);
      CloneModal($$renderer3, {
        databaseId: data.currentDatabase.id,
        entityType: cloneEntityType,
        sourceName: cloneSourceName,
        existingNames: data.namingConfigs.map((c2) => c2.name),
        canWriteToBase: data.canWriteToBase,
        get open() {
          return cloneModalOpen;
        },
        set open($$value) {
          cloneModalOpen = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte46 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/naming/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_mediaManagement();
    init_features();
    init_Dropdown();
    init_Icon();
    init_copy();
    init_download();
    init_list2();
    init_Button();
    init_pencil();
    init_plus();
    init_search();
    init_ViewToggle();
    init_tag();
    init_store2();
    init_Card();
    init_Sonarr2();
    init_navigation();
    init_DropdownItem();
    init_ActionsBar();
    init_ActionButton();
    init_Badge();
    init_DropdownHeader();
    init_PageMeta();
    init_Table();
    init_CardGrid();
    init_dataPage();
    init_CloneModal();
  }
});

// dist/build/server/nodes/56.js
var __exports57 = {};
__export(__exports57, {
  component: () => component53,
  fonts: () => fonts57,
  imports: () => imports57,
  index: () => index57,
  server: () => page_server_ts_exports49,
  server_id: () => server_id55,
  stylesheets: () => stylesheets57
});
var index57, component_cache53, component53, server_id55, imports57, stylesheets57, fonts57;
var init__57 = __esm({
  async "dist/build/server/nodes/56.js"() {
    "use strict";
    await init_page_server_ts49();
    index57 = 56;
    component53 = async () => component_cache53 ??= (await Promise.resolve().then(() => (init_page_svelte46(), page_svelte_exports46))).default;
    server_id55 = "src/routes/media-management/[databaseId]/naming/+page.server.ts";
    imports57 = ["_app/immutable/nodes/56.V1jJa_kI.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/D7OHFWTL2.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/B_FOzVLA.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/Cut3gr1-.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/Dg15A-ry2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DxZIQ_tr2.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/DYe9q02k2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/CrAcgBQ22.js"];
    stylesheets57 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts57 = [];
  }
});

// dist/build/server/chunks/namingTokens.js
function normalizeTokenName(name) {
  return name.replace(/[\s_\W]/g, "").toLowerCase();
}
function parseTokenContent(raw, inner) {
  const prefix = inner.match(TOKEN_PREFIX_REGEX)?.[0] ?? "";
  const withoutPrefix = inner.slice(prefix.length);
  const suffix = withoutPrefix.match(TOKEN_SUFFIX_REGEX)?.[0] ?? "";
  const tokenWithParameter = withoutPrefix.slice(0, withoutPrefix.length - suffix.length).trim();
  if (!tokenWithParameter || !/^[A-Za-z]/.test(tokenWithParameter)) return null;
  const parameterIndex = tokenWithParameter.indexOf(":");
  const tokenName = parameterIndex >= 0 ? tokenWithParameter.slice(0, parameterIndex).trim() : tokenWithParameter;
  const parameter = parameterIndex >= 0 ? tokenWithParameter.slice(parameterIndex + 1) : null;
  if (!tokenName || !/^[A-Za-z]/.test(tokenName) || parameter === "") return null;
  return {
    raw,
    prefix,
    suffix,
    tokenName,
    parameter,
    canonicalName: normalizeTokenName(tokenName)
  };
}
function extractNamingTokens(format) {
  const errors = [];
  const tokens = [];
  let depth = 0;
  for (const ch of format) {
    if (ch === "{") depth++;
    if (ch === "}") depth--;
    if (depth < 0) {
      errors.push('Unmatched closing brace "}"');
      break;
    }
  }
  if (depth > 0) errors.push('Unmatched opening brace "{"');
  if (errors.length > 0) return {
    tokens,
    errors
  };
  const tokenRegex = /\{([^{}]*)\}/g;
  let match;
  while ((match = tokenRegex.exec(format)) !== null) {
    const parsed = parseTokenContent(match[0], match[1]);
    if (!parsed) {
      errors.push(`Invalid token: ${match[0]}`);
      continue;
    }
    tokens.push(parsed);
  }
  return {
    tokens,
    errors
  };
}
function getRadarrTokenCategories() {
  return [
    {
      name: "Movie",
      tokens: RADARR_MOVIE_TOKENS
    },
    {
      name: "Year",
      tokens: RADARR_YEAR_TOKENS
    },
    {
      name: "IDs",
      tokens: RADARR_ID_TOKENS
    },
    {
      name: "Quality",
      tokens: RADARR_QUALITY_TOKENS
    },
    {
      name: "Media Info",
      tokens: RADARR_MEDIAINFO_TOKENS
    },
    {
      name: "Release",
      tokens: RADARR_RELEASE_TOKENS
    },
    {
      name: "Custom Formats",
      tokens: RADARR_CF_TOKENS
    },
    {
      name: "Original",
      tokens: RADARR_ORIGINAL_TOKENS
    }
  ];
}
function getSonarrTokenCategories() {
  return [
    {
      name: "Series",
      tokens: SONARR_SERIES_TOKENS
    },
    {
      name: "IDs",
      tokens: SONARR_ID_TOKENS
    },
    {
      name: "Season & Episode",
      tokens: SONARR_SEASON_EPISODE_TOKENS
    },
    {
      name: "Air Date",
      tokens: SONARR_AIR_DATE_TOKENS
    },
    {
      name: "Absolute Episode",
      tokens: SONARR_ABSOLUTE_TOKENS
    },
    {
      name: "Episode Title",
      tokens: SONARR_EPISODE_TITLE_TOKENS
    },
    {
      name: "Quality",
      tokens: SONARR_QUALITY_TOKENS
    },
    {
      name: "Media Info",
      tokens: SONARR_MEDIAINFO_TOKENS
    },
    {
      name: "Release",
      tokens: SONARR_RELEASE_TOKENS
    },
    {
      name: "Custom Formats",
      tokens: SONARR_CF_TOKENS
    },
    {
      name: "Original",
      tokens: SONARR_ORIGINAL_TOKENS
    }
  ];
}
function buildSampleLookup(sampleValues) {
  const lookup = /* @__PURE__ */ new Map();
  for (const [key2, value2] of Object.entries(sampleValues)) lookup.set(normalizeTokenName(key2), value2);
  return lookup;
}
function getSampleValue(token, sampleValues, lookup) {
  if (token.parameter !== null) {
    const parameterSpecific = lookup.get(normalizeTokenName(`${token.tokenName}:${token.parameter}`));
    if (parameterSpecific !== void 0) return parameterSpecific;
  }
  return lookup.get(token.canonicalName) ?? sampleValues[token.tokenName];
}
function truncateValue(value2, parameter) {
  if (parameter === null || !/^-?\d+$/.test(parameter)) return value2;
  const maxLength = parseInt(parameter, 10);
  if (maxLength === 0 || value2.length <= Math.abs(maxLength)) return value2;
  const keepLength = Math.max(Math.abs(maxLength) - 3, 0);
  if (maxLength < 0) return `...${value2.slice(value2.length - keepLength).replace(/^[ .]+/, "")}`;
  return `${value2.slice(0, keepLength).replace(/[ .]+$/, "")}...`;
}
function filterLanguageValue(value2, parameter) {
  const bracketed = value2.match(/^\[([^\]]*)\]$/);
  const languages = (bracketed ? bracketed[1] : value2).split("+").filter(Boolean);
  let filtered = languages;
  if (parameter.startsWith("-")) {
    const excluded = parameter.slice(1).split("-");
    filtered = languages.filter((language) => !excluded.includes(language));
  } else filtered = parameter.split("+").filter(Boolean).filter((language) => languages.includes(language));
  if (parameter.endsWith("+") && filtered.length !== languages.length) filtered = [...filtered, "--"];
  const result = filtered.join("+");
  return bracketed && result ? `[${result}]` : result;
}
function applyMediaLanguageFilter(value2, parameter) {
  if (!parameter) return value2;
  if (value2.includes("[")) return value2.replace(/\[[^\]]*\]/g, (match) => filterLanguageValue(match, parameter));
  return filterLanguageValue(value2, parameter);
}
function getCustomFormats(sampleValues, options2) {
  if (options2.customFormats) return options2.customFormats;
  return (sampleValues["Custom Formats"] ?? "").split(/\s+/).filter(Boolean);
}
function resolveCustomFormatToken(token, sampleValues, options2) {
  const formats = getCustomFormats(sampleValues, options2);
  if (token.canonicalName === normalizeTokenName("Custom Format")) {
    if (!token.parameter) return "";
    return formats.find((format) => format === token.parameter) ?? "";
  }
  if (!token.parameter) return sampleValues["Custom Formats"] ?? formats.join(" ");
  if (token.parameter.startsWith("-")) {
    const excluded = token.parameter.slice(1).split(",");
    return formats.filter((format) => !excluded.includes(format)).join(" ");
  }
  const included = token.parameter.split(",");
  return formats.filter((format) => included.includes(format)).join(" ");
}
function resolveNumberToken(value2, parameter) {
  if (!parameter || !/^0+$/.test(parameter)) return value2;
  return value2.padStart(parameter.length, "0");
}
function resolveTokenValue(token, sampleValues, lookup, options2) {
  if (token.canonicalName === normalizeTokenName("Custom Format") || token.canonicalName === normalizeTokenName("Custom Formats")) return resolveCustomFormatToken(token, sampleValues, options2);
  const value2 = getSampleValue(token, sampleValues, lookup);
  if (value2 === void 0) return;
  if (SONARR_NUMBER_TOKEN_NAMES.has(token.canonicalName)) return resolveNumberToken(value2, token.parameter);
  if (MEDIA_LANGUAGE_TOKEN_NAMES.has(token.canonicalName)) return applyMediaLanguageFilter(value2, token.parameter);
  if (TRUNCATABLE_TOKEN_NAMES.has(token.canonicalName)) return truncateValue(value2, token.parameter);
  return value2;
}
function resolveFormat(format, sampleValues, options2 = {}) {
  if (!format) return "";
  const lookup = buildSampleLookup(sampleValues);
  return format.replace(/\{([^{}]*)\}/g, (match, inner) => {
    const parsed = parseTokenContent(match, inner);
    if (!parsed) return match;
    const value2 = resolveTokenValue(parsed, sampleValues, lookup, options2);
    if (value2 === void 0) return match;
    if (value2 === "") return "";
    return parsed.prefix + value2 + parsed.suffix;
  }).replace(/  +/g, " ").trim();
}
function resolveRadarrFormat(format) {
  return resolveFormat(format, RADARR_SAMPLE_VALUES, { customFormats: RADARR_SAMPLE_CUSTOM_FORMATS });
}
function resolveSonarrFormat(format) {
  return resolveFormat(format, SONARR_SAMPLE_VALUES, { customFormats: SONARR_SAMPLE_CUSTOM_FORMATS });
}
function addTokenName(names2, tokenName) {
  names2.set(normalizeTokenName(tokenName), tokenName);
}
function getTokenBaseName(token) {
  const inner = token.slice(1, -1);
  return parseTokenContent(token, inner)?.tokenName ?? inner.trim();
}
function getValidTokenNames(arrType) {
  const categories = arrType === "radarr" ? getRadarrTokenCategories() : getSonarrTokenCategories();
  const names2 = /* @__PURE__ */ new Map();
  for (const category of categories) for (const t2 of category.tokens) addTokenName(names2, getTokenBaseName(t2.token));
  const hiddenNames = arrType === "radarr" ? HIDDEN_RADARR_TOKEN_NAMES : HIDDEN_SONARR_TOKEN_NAMES;
  for (const name of hiddenNames) addTokenName(names2, name);
  return names2;
}
function hasToken(tokens, names2) {
  return tokens.some((token) => names2.has(token.canonicalName));
}
function getTokensByName(tokens, names2) {
  return tokens.filter((token) => names2.has(token.canonicalName)).map((token) => token.raw);
}
function addRadarrFieldErrors(tokens, field, errors) {
  const hasMovieTitle = hasToken(tokens, RADARR_MOVIE_TITLE_TOKEN_NAMES);
  const hasReleaseYear = hasToken(tokens, /* @__PURE__ */ new Set([normalizeTokenName("Release Year")]));
  const hasOriginalFileToken = hasToken(tokens, RADARR_ORIGINAL_FILE_TOKEN_NAMES);
  if (field === "movieFormat" && !hasOriginalFileToken && !(hasMovieTitle && hasReleaseYear)) {
    errors.push("Must contain either movie title and release year OR Original Title/Filename");
    return;
  }
  if (field === "movieFolderFormat") {
    if (!hasMovieTitle) errors.push("Must contain movie title");
    const disallowed = getTokensByName(tokens, RADARR_MOVIE_FOLDER_DISALLOWED_TOKEN_NAMES);
    if (disallowed.length > 0) errors.push(`Must not contain deprecated tokens derived from file properties: ${disallowed.join(", ")}`);
  }
}
function addSonarrFieldErrors(tokens, field, errors) {
  const seasonToken = /* @__PURE__ */ new Set([normalizeTokenName("season")]);
  const episodeToken = /* @__PURE__ */ new Set([normalizeTokenName("episode")]);
  const absoluteToken = /* @__PURE__ */ new Set([normalizeTokenName("absolute")]);
  const airDateToken = /* @__PURE__ */ new Set([normalizeTokenName("Air Date")]);
  const hasSeasonAndEpisode = hasToken(tokens, seasonToken) && hasToken(tokens, episodeToken);
  const hasOriginalFileToken = hasToken(tokens, RADARR_ORIGINAL_FILE_TOKEN_NAMES);
  if (field === "standardEpisodeFormat" && !hasSeasonAndEpisode && !hasOriginalFileToken) {
    errors.push("Must contain season and episode numbers OR Original Title");
    return;
  }
  if (field === "dailyEpisodeFormat" && !hasToken(tokens, airDateToken) && !hasSeasonAndEpisode && !hasOriginalFileToken) {
    errors.push("Must contain Air Date OR Season and Episode OR Original Title");
    return;
  }
  if (field === "animeEpisodeFormat" && !hasToken(tokens, absoluteToken) && !hasSeasonAndEpisode && !hasOriginalFileToken) {
    errors.push("Must contain Absolute Episode number OR Season and Episode OR Original Title");
    return;
  }
  if (field === "seriesFolderFormat" && !hasToken(tokens, SONARR_SERIES_TITLE_TOKEN_NAMES)) errors.push("Must contain series title");
  if (field === "seasonFolderFormat" && !hasToken(tokens, seasonToken)) errors.push("Must contain season number");
}
function validateNamingFormat(format, arrType, options2 = {}) {
  const errors = [];
  if (!format && !options2.field) return {
    valid: true,
    errors
  };
  const extracted = extractNamingTokens(format);
  errors.push(...extracted.errors);
  if (errors.length > 0) return {
    valid: false,
    errors
  };
  const validNames = getValidTokenNames(arrType);
  for (const token of extracted.tokens) if (!validNames.has(token.canonicalName)) errors.push(`Unknown token: {${token.tokenName}}`);
  if (errors.length === 0 && options2.field) if (arrType === "radarr") addRadarrFieldErrors(extracted.tokens, options2.field, errors);
  else addSonarrFieldErrors(extracted.tokens, options2.field, errors);
  return {
    valid: errors.length === 0,
    errors
  };
}
var TOKEN_PREFIX_REGEX, TOKEN_SUFFIX_REGEX, RADARR_MOVIE_TOKENS, RADARR_YEAR_TOKENS, RADARR_ID_TOKENS, RADARR_QUALITY_TOKENS, RADARR_MEDIAINFO_TOKENS, RADARR_RELEASE_TOKENS, RADARR_CF_TOKENS, RADARR_ORIGINAL_TOKENS, SONARR_SERIES_TOKENS, SONARR_ID_TOKENS, SONARR_SEASON_EPISODE_TOKENS, SONARR_AIR_DATE_TOKENS, SONARR_ABSOLUTE_TOKENS, SONARR_EPISODE_TITLE_TOKENS, SONARR_QUALITY_TOKENS, SONARR_MEDIAINFO_TOKENS, SONARR_RELEASE_TOKENS, SONARR_CF_TOKENS, SONARR_ORIGINAL_TOKENS, RADARR_SAMPLE_VALUES, SONARR_SAMPLE_VALUES, RADARR_SAMPLE_CUSTOM_FORMATS, SONARR_SAMPLE_CUSTOM_FORMATS, HIDDEN_RADARR_TOKEN_NAMES, HIDDEN_SONARR_TOKEN_NAMES, TRUNCATABLE_TOKEN_NAMES, MEDIA_LANGUAGE_TOKEN_NAMES, SONARR_NUMBER_TOKEN_NAMES, RADARR_MOVIE_TITLE_TOKEN_NAMES, RADARR_ORIGINAL_FILE_TOKEN_NAMES, RADARR_MOVIE_FOLDER_DISALLOWED_TOKEN_NAMES, SONARR_SERIES_TITLE_TOKEN_NAMES;
var init_namingTokens = __esm({
  "dist/build/server/chunks/namingTokens.js"() {
    "use strict";
    TOKEN_PREFIX_REGEX = /^[-\[( ._]*/;
    TOKEN_SUFFIX_REGEX = /[-\]) ._]*$/;
    RADARR_MOVIE_TOKENS = [
      {
        token: "{Movie Title}",
        description: "Full movie title as stored in your library",
        example: "The Movie Title"
      },
      {
        token: "{Movie CleanTitle}",
        description: "Title with special characters and diacritics removed",
        example: "The Movie Title"
      },
      {
        token: "{Movie TitleThe}",
        description: 'Title with leading "The/A/An" moved to the end',
        example: "Movie Title, The"
      },
      {
        token: "{Movie CleanTitleThe}",
        description: "Clean title with leading article moved to the end",
        example: "Movie Title, The"
      },
      {
        token: "{Movie OriginalTitle}",
        description: "Original title from metadata (may differ from English title)",
        example: "Le Titre du Film"
      },
      {
        token: "{Movie CleanOriginalTitle}",
        description: "Original title with special characters removed",
        example: "Le Titre du Film"
      },
      {
        token: "{Movie TitleFirstCharacter}",
        description: "First letter of the title (useful for folder sorting)",
        example: "T"
      },
      {
        token: "{Movie Collection}",
        description: 'Collection the movie belongs to (e.g. "Marvel Cinematic Universe")',
        example: "The Movie Collection"
      },
      {
        token: "{Movie CollectionThe}",
        description: 'Collection name with leading "The/A/An" moved to the end',
        example: "Movie Collection, The"
      },
      {
        token: "{Movie CleanCollectionThe}",
        description: "Clean collection name with leading article moved to the end",
        example: "Movie Collection, The"
      },
      {
        token: "{Movie Certification}",
        description: "Content rating (e.g. R, PG-13, TV-MA)",
        example: "R"
      }
    ];
    RADARR_YEAR_TOKENS = [{
      token: "{Release Year}",
      description: "Year the movie was released",
      example: "2010"
    }];
    RADARR_ID_TOKENS = [{
      token: "{ImdbId}",
      description: "IMDb identifier",
      example: "tt0066921"
    }, {
      token: "{TmdbId}",
      description: "The Movie Database identifier",
      example: "345691"
    }];
    RADARR_QUALITY_TOKENS = [
      {
        token: "{Quality Full}",
        description: 'Full quality string including revision (e.g. "Proper")',
        example: "Bluray-1080p Proper"
      },
      {
        token: "{Quality Title}",
        description: "Quality name without revision info",
        example: "Bluray-1080p"
      },
      {
        token: "{Quality Proper}",
        description: "Proper/repack marker when present",
        example: "Proper"
      },
      {
        token: "{Quality Real}",
        description: "REAL marker when present",
        example: "REAL"
      }
    ];
    RADARR_MEDIAINFO_TOKENS = [
      {
        token: "{MediaInfo Simple}",
        description: "Video and audio codec in short form",
        example: "x264 DTS"
      },
      {
        token: "{MediaInfo Full}",
        description: "Video codec, audio codec, and audio languages",
        example: "x264 DTS [EN+DE]"
      },
      {
        token: "{MediaInfo VideoCodec}",
        description: "Video codec name",
        example: "x264"
      },
      {
        token: "{MediaInfo VideoBitDepth}",
        description: "Video bit depth (8, 10, or 12)",
        example: "10"
      },
      {
        token: "{MediaInfo VideoDynamicRange}",
        description: "Dynamic range type (HDR or empty)",
        example: "HDR"
      },
      {
        token: "{MediaInfo VideoDynamicRangeType}",
        description: "Specific HDR format (e.g. DV, HDR10, HDR10+)",
        example: "DV HDR10"
      },
      {
        token: "{MediaInfo 3D}",
        description: '"3D" if the movie is 3D, empty otherwise',
        example: "3D"
      },
      {
        token: "{MediaInfo AudioCodec}",
        description: "Audio codec name",
        example: "DTS"
      },
      {
        token: "{MediaInfo AudioChannels}",
        description: "Audio channel layout",
        example: "5.1"
      },
      {
        token: "{MediaInfo AudioLanguages}",
        description: "Audio languages (English excluded when it is the only language)",
        example: "[EN+DE]"
      },
      {
        token: "{MediaInfo AudioLanguagesAll}",
        description: "All audio languages including English",
        example: "[EN+DE]"
      },
      {
        token: "{MediaInfo SubtitleLanguages}",
        description: "Subtitle languages present in the file",
        example: "[DE]"
      },
      {
        token: "{MediaInfo SubtitleLanguagesAll}",
        description: "All subtitle languages including English",
        example: "[EN+DE]"
      }
    ];
    RADARR_RELEASE_TOKENS = [{
      token: "{Release Group}",
      description: 'Release/scene group name (defaults to "Radarr")',
      example: "EVOLVE"
    }, {
      token: "{Edition Tags}",
      description: "Edition information (e.g. IMAX, Director's Cut)",
      example: "IMAX"
    }];
    RADARR_CF_TOKENS = [{
      token: "{Custom Formats}",
      description: 'All applied custom formats that have "Include When Renaming" enabled',
      example: "Surround Sound x264"
    }];
    RADARR_ORIGINAL_TOKENS = [{
      token: "{Original Title}",
      description: "Original release title as downloaded",
      example: "The.Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE"
    }, {
      token: "{Original Filename}",
      description: "Original filename without extension",
      example: "The.Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE"
    }];
    SONARR_SERIES_TOKENS = [
      {
        token: "{Series Title}",
        description: "Full series title as stored in your library",
        example: "The Series Title"
      },
      {
        token: "{Series CleanTitle}",
        description: "Title with special characters and diacritics removed",
        example: "The Series Title"
      },
      {
        token: "{Series TitleYear}",
        description: "Title with year appended in parentheses",
        example: "The Series Title (2022)"
      },
      {
        token: "{Series CleanTitleYear}",
        description: "Clean title with year appended",
        example: "The Series Title 2022"
      },
      {
        token: "{Series TitleWithoutYear}",
        description: "Series title with trailing year removed",
        example: "The Series Title"
      },
      {
        token: "{Series CleanTitleWithoutYear}",
        description: "Clean series title with trailing year removed",
        example: "The Series Title"
      },
      {
        token: "{Series TitleThe}",
        description: 'Title with leading "The/A/An" moved to the end',
        example: "Series Title, The"
      },
      {
        token: "{Series CleanTitleThe}",
        description: "Clean title with leading article moved to the end",
        example: "Series Title, The"
      },
      {
        token: "{Series TitleTheYear}",
        description: "Title with leading article moved to the end and year appended",
        example: "Series Title, The (2022)"
      },
      {
        token: "{Series CleanTitleTheYear}",
        description: "Clean title with leading article moved to the end and year appended",
        example: "Series Title, The 2022"
      },
      {
        token: "{Series TitleTheWithoutYear}",
        description: "Title with leading article moved to the end and trailing year removed",
        example: "Series Title, The"
      },
      {
        token: "{Series CleanTitleTheWithoutYear}",
        description: "Clean title with leading article moved to the end and trailing year removed",
        example: "Series Title, The"
      },
      {
        token: "{Series TitleFirstCharacter}",
        description: "First letter of the title (useful for folder sorting)",
        example: "S"
      },
      {
        token: "{Series Year}",
        description: "Year the series first aired",
        example: "2022"
      }
    ];
    SONARR_ID_TOKENS = [
      {
        token: "{ImdbId}",
        description: "IMDb identifier",
        example: "tt12345"
      },
      {
        token: "{TvdbId}",
        description: "TheTVDB identifier",
        example: "12345"
      },
      {
        token: "{TvMazeId}",
        description: "TVMaze identifier",
        example: "54321"
      },
      {
        token: "{TmdbId}",
        description: "The Movie Database identifier",
        example: "11223"
      }
    ];
    SONARR_SEASON_EPISODE_TOKENS = [
      {
        token: "{season:0}",
        description: "Season number without zero-padding",
        example: "1"
      },
      {
        token: "{season:00}",
        description: "Season number with zero-padding",
        example: "01"
      },
      {
        token: "{episode:0}",
        description: "Episode number without zero-padding",
        example: "1"
      },
      {
        token: "{episode:00}",
        description: "Episode number with zero-padding",
        example: "01"
      }
    ];
    SONARR_AIR_DATE_TOKENS = [{
      token: "{Air-Date}",
      description: "Air date with dashes (for daily shows)",
      example: "2022-03-20"
    }, {
      token: "{Air Date}",
      description: "Air date with spaces (for daily shows)",
      example: "2022 03 20"
    }];
    SONARR_ABSOLUTE_TOKENS = [
      {
        token: "{absolute:0}",
        description: "Absolute episode number without padding (anime)",
        example: "1"
      },
      {
        token: "{absolute:00}",
        description: "Absolute episode number with 2-digit padding (anime)",
        example: "01"
      },
      {
        token: "{absolute:000}",
        description: "Absolute episode number with 3-digit padding (anime)",
        example: "001"
      }
    ];
    SONARR_EPISODE_TITLE_TOKENS = [{
      token: "{Episode Title}",
      description: "Episode title as stored in metadata",
      example: "Pilot Episode"
    }, {
      token: "{Episode CleanTitle}",
      description: "Episode title with special characters removed",
      example: "Pilot Episode"
    }];
    SONARR_QUALITY_TOKENS = [
      {
        token: "{Quality Full}",
        description: 'Full quality string including revision (e.g. "Proper")',
        example: "WEBDL-1080p"
      },
      {
        token: "{Quality Title}",
        description: "Quality name without revision info",
        example: "WEBDL-1080p"
      },
      {
        token: "{Quality Proper}",
        description: "Proper/repack marker when present",
        example: "Proper"
      },
      {
        token: "{Quality Real}",
        description: "REAL marker when present",
        example: "REAL"
      }
    ];
    SONARR_MEDIAINFO_TOKENS = [
      {
        token: "{MediaInfo Simple}",
        description: "Video and audio codec in short form",
        example: "x265 AAC"
      },
      {
        token: "{MediaInfo Full}",
        description: "Video codec, audio codec, and audio languages",
        example: "x265 AAC [EN]"
      },
      {
        token: "{MediaInfo VideoCodec}",
        description: "Video codec name",
        example: "x265"
      },
      {
        token: "{MediaInfo VideoBitDepth}",
        description: "Video bit depth (8, 10, or 12)",
        example: "10"
      },
      {
        token: "{MediaInfo VideoDynamicRange}",
        description: "Dynamic range type (HDR or empty)",
        example: "HDR"
      },
      {
        token: "{MediaInfo VideoDynamicRangeType}",
        description: "Specific HDR format (e.g. DV, HDR10, HDR10+)",
        example: "DV HDR10"
      },
      {
        token: "{MediaInfo AudioCodec}",
        description: "Audio codec name",
        example: "AAC"
      },
      {
        token: "{MediaInfo AudioChannels}",
        description: "Audio channel layout",
        example: "2.0"
      },
      {
        token: "{MediaInfo AudioLanguages}",
        description: "Audio languages (English excluded when it is the only language)",
        example: "[EN]"
      },
      {
        token: "{MediaInfo AudioLanguagesAll}",
        description: "All audio languages including English",
        example: "[EN]"
      },
      {
        token: "{MediaInfo SubtitleLanguages}",
        description: "Subtitle languages present in the file",
        example: "[DE]"
      },
      {
        token: "{MediaInfo SubtitleLanguagesAll}",
        description: "All subtitle languages including English",
        example: "[EN+DE]"
      }
    ];
    SONARR_RELEASE_TOKENS = [{
      token: "{Release Group}",
      description: 'Release/scene group name (defaults to "Sonarr")',
      example: "NTb"
    }, {
      token: "{Release Hash}",
      description: "Anime release hash when present",
      example: "ABCDEFGH"
    }];
    SONARR_CF_TOKENS = [{
      token: "{Custom Formats}",
      description: 'All applied custom formats that have "Include When Renaming" enabled',
      example: "WEBDL-1080p"
    }];
    SONARR_ORIGINAL_TOKENS = [{
      token: "{Original Title}",
      description: "Original release title as downloaded",
      example: "The.Series.Title.S01E01.Pilot.Episode.1080p.WEBDL.AAC2.0.x265-NTb"
    }, {
      token: "{Original Filename}",
      description: "Original filename without extension",
      example: "The.Series.Title.S01E01.Pilot.Episode.1080p.WEBDL.AAC2.0.x265-NTb"
    }];
    RADARR_SAMPLE_VALUES = {
      "Movie Title": "The Movie Title",
      "Movie Title:DE": "Titel des Films",
      "Movie CleanTitle": "The Movie Title",
      "Movie CleanTitle:DE": "Titel des Films",
      "Movie TitleThe": "Movie Title, The",
      "Movie CleanTitleThe": "Movie Title, The",
      "Movie OriginalTitle": "Le Titre du Film",
      "Movie CleanOriginalTitle": "Le Titre du Film",
      "Movie TitleFirstCharacter": "T",
      "Movie TitleFirstCharacter:DE": "T",
      "Movie Collection": "The Movie Collection",
      "Movie CollectionThe": "Movie Collection, The",
      "Movie CleanCollectionThe": "Movie Collection, The",
      "Movie Certification": "R",
      "Release Year": "2010",
      ImdbId: "tt0066921",
      TmdbId: "345691",
      "Quality Full": "Bluray-1080p Proper",
      "Quality Title": "Bluray-1080p",
      "Quality Proper": "Proper",
      "Quality Real": "",
      "MediaInfo Simple": "x264 DTS",
      "MediaInfo Full": "x264 DTS [EN+DE]",
      "MediaInfo Video": "x264",
      "MediaInfo VideoCodec": "x264",
      "MediaInfo VideoBitDepth": "10",
      "MediaInfo VideoDynamicRange": "HDR",
      "MediaInfo VideoDynamicRangeType": "DV HDR10",
      "MediaInfo 3D": "",
      "MediaInfo Audio": "DTS",
      "MediaInfo AudioCodec": "DTS",
      "MediaInfo AudioChannels": "5.1",
      "MediaInfo AudioLanguages": "[EN+DE]",
      "MediaInfo AudioLanguagesAll": "[EN+DE]",
      "MediaInfo SubtitleLanguages": "[DE]",
      "MediaInfo SubtitleLanguagesAll": "[EN+DE]",
      "Release Group": "EVOLVE",
      "Edition Tags": "IMAX",
      "Custom Formats": "Surround Sound x264",
      "Original Title": "The.Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE",
      "Original Filename": "The.Movie.Title.2010.1080p.BluRay.DTS.x264-EVOLVE"
    };
    SONARR_SAMPLE_VALUES = {
      "Series Title": "The Series Title",
      "Series CleanTitle": "The Series Title",
      "Series TitleYear": "The Series Title (2022)",
      "Series CleanTitleYear": "The Series Title 2022",
      "Series TitleWithoutYear": "The Series Title",
      "Series CleanTitleWithoutYear": "The Series Title",
      "Series TitleThe": "Series Title, The",
      "Series CleanTitleThe": "Series Title, The",
      "Series TitleTheYear": "Series Title, The (2022)",
      "Series CleanTitleTheYear": "Series Title, The 2022",
      "Series TitleTheWithoutYear": "Series Title, The",
      "Series CleanTitleTheWithoutYear": "Series Title, The",
      "Series TitleFirstCharacter": "S",
      "Series Year": "2022",
      ImdbId: "tt12345",
      TvdbId: "12345",
      TvMazeId: "54321",
      TmdbId: "11223",
      season: "1",
      "season:0": "1",
      "season:00": "01",
      episode: "1",
      "episode:0": "1",
      "episode:00": "01",
      "Air-Date": "2022-03-20",
      "Air Date": "2022 03 20",
      absolute: "1",
      "absolute:0": "1",
      "absolute:00": "01",
      "absolute:000": "001",
      "Episode Title": "Pilot Episode",
      "Episode CleanTitle": "Pilot Episode",
      "Quality Full": "WEBDL-1080p",
      "Quality Title": "WEBDL-1080p",
      "Quality Proper": "",
      "Quality Real": "",
      "MediaInfo Simple": "x265 AAC",
      "MediaInfo Full": "x265 AAC [EN]",
      "MediaInfo Video": "x265",
      "MediaInfo VideoCodec": "x265",
      "MediaInfo VideoBitDepth": "10",
      "MediaInfo VideoDynamicRange": "HDR",
      "MediaInfo VideoDynamicRangeType": "DV HDR10",
      "MediaInfo Audio": "AAC",
      "MediaInfo AudioCodec": "AAC",
      "MediaInfo AudioChannels": "2.0",
      "MediaInfo AudioLanguages": "[EN]",
      "MediaInfo AudioLanguagesAll": "[EN]",
      "MediaInfo SubtitleLanguages": "[DE]",
      "MediaInfo SubtitleLanguagesAll": "[EN+DE]",
      "Release Group": "NTb",
      "Release Hash": "ABCDEFGH",
      "Custom Formats": "WEBDL-1080p",
      "Original Title": "The.Series.Title.S01E01.Pilot.Episode.1080p.WEBDL.AAC2.0.x265-NTb",
      "Original Filename": "The.Series.Title.S01E01.Pilot.Episode.1080p.WEBDL.AAC2.0.x265-NTb"
    };
    RADARR_SAMPLE_CUSTOM_FORMATS = [
      "Surround Sound",
      "x264",
      "AMZN",
      "WEB",
      "DV"
    ];
    SONARR_SAMPLE_CUSTOM_FORMATS = [
      "iNTERNAL",
      "AMZN",
      "WEB",
      "DV"
    ];
    HIDDEN_RADARR_TOKEN_NAMES = [
      "MediaInfo Video",
      "MediaInfo Audio",
      "Custom Format"
    ];
    HIDDEN_SONARR_TOKEN_NAMES = [
      "MediaInfo Video",
      "MediaInfo Audio",
      "Custom Format"
    ];
    TRUNCATABLE_TOKEN_NAMES = new Set([
      "Movie Title",
      "Movie CleanTitle",
      "Movie TitleThe",
      "Movie CleanTitleThe",
      "Movie OriginalTitle",
      "Movie CleanOriginalTitle",
      "Movie Collection",
      "Movie CollectionThe",
      "Movie CleanCollectionThe",
      "Series Title",
      "Series CleanTitle",
      "Series TitleYear",
      "Series CleanTitleYear",
      "Series TitleWithoutYear",
      "Series CleanTitleWithoutYear",
      "Series TitleThe",
      "Series CleanTitleThe",
      "Series TitleTheYear",
      "Series CleanTitleTheYear",
      "Series TitleTheWithoutYear",
      "Series CleanTitleTheWithoutYear",
      "Series TitleFirstCharacter",
      "Episode Title",
      "Episode CleanTitle",
      "Release Group",
      "Edition Tags"
    ].map(normalizeTokenName));
    MEDIA_LANGUAGE_TOKEN_NAMES = new Set([
      "MediaInfo Full",
      "MediaInfo AudioLanguages",
      "MediaInfo AudioLanguagesAll",
      "MediaInfo SubtitleLanguages",
      "MediaInfo SubtitleLanguagesAll"
    ].map(normalizeTokenName));
    SONARR_NUMBER_TOKEN_NAMES = new Set([
      "season",
      "episode",
      "absolute"
    ].map(normalizeTokenName));
    RADARR_MOVIE_TITLE_TOKEN_NAMES = new Set([
      "Movie Title",
      "Movie CleanTitle",
      "Movie TitleThe",
      "Movie CleanTitleThe",
      "Movie OriginalTitle",
      "Movie CleanOriginalTitle"
    ].map(normalizeTokenName));
    RADARR_ORIGINAL_FILE_TOKEN_NAMES = new Set(["Original Title", "Original Filename"].map(normalizeTokenName));
    RADARR_MOVIE_FOLDER_DISALLOWED_TOKEN_NAMES = new Set([
      "Original Title",
      "Original Filename",
      "Release Group",
      "Edition Tags",
      "Quality Full",
      "Quality Title",
      "Quality Proper",
      "Quality Real",
      "MediaInfo Video",
      "MediaInfo VideoCodec",
      "MediaInfo VideoBitDepth",
      "MediaInfo Audio",
      "MediaInfo AudioCodec",
      "MediaInfo AudioChannels",
      "MediaInfo AudioLanguages",
      "MediaInfo AudioLanguagesAll",
      "MediaInfo SubtitleLanguages",
      "MediaInfo SubtitleLanguagesAll",
      "MediaInfo 3D",
      "MediaInfo Simple",
      "MediaInfo Full",
      "MediaInfo VideoDynamicRange",
      "MediaInfo VideoDynamicRangeType"
    ].map(normalizeTokenName));
    SONARR_SERIES_TITLE_TOKEN_NAMES = new Set([
      "Series Title",
      "Series CleanTitle",
      "Series TitleYear",
      "Series CleanTitleYear",
      "Series TitleWithoutYear",
      "Series CleanTitleWithoutYear",
      "Series TitleThe",
      "Series CleanTitleThe",
      "Series TitleTheYear",
      "Series CleanTitleTheYear",
      "Series TitleTheWithoutYear",
      "Series CleanTitleTheWithoutYear"
    ].map(normalizeTokenName));
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/naming/new/_page.server.ts.js
var page_server_ts_exports50 = {};
__export(page_server_ts_exports50, {
  actions: () => actions31,
  load: () => load53
});
var load53, actions31;
var init_page_server_ts50 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/naming/new/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_naming();
    init_namingTokens();
    init_exports();
    load53 = async ({ parent }) => {
      return { canWriteToBase: (await parent()).canWriteToBase };
    };
    actions31 = { default: async ({ request, params }) => {
      const { databaseId } = params;
      if (!databaseId) return fail(400, { error: "Missing database ID" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const arrType = formData.get("arrType");
      const name = formData.get("name");
      const layer = formData.get("layer") || "user";
      if (!name?.trim()) return fail(400, { error: "Name is required" });
      if (!arrType || arrType !== "radarr" && arrType !== "sonarr") return fail(400, { error: "Invalid arr type" });
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      if (arrType === "radarr") {
        const rename2 = formData.get("rename") === "true";
        const movieFormat = formData.get("movieFormat");
        const movieFolderFormat = formData.get("movieFolderFormat");
        const replaceIllegalCharacters = formData.get("replaceIllegalCharacters") === "true";
        const colonReplacementFormat = formData.get("colonReplacementFormat");
        const movieFormatValidation = validateNamingFormat(movieFormat || "", "radarr", { field: "movieFormat" });
        if (!movieFormatValidation.valid) return fail(400, { error: `Movie format: ${movieFormatValidation.errors.join(", ")}` });
        const folderFormatValidation = validateNamingFormat(movieFolderFormat || "", "radarr", { field: "movieFolderFormat" });
        if (!folderFormatValidation.valid) return fail(400, { error: `Folder format: ${folderFormatValidation.errors.join(", ")}` });
        let result;
        try {
          result = await createRadarrNaming({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            input: {
              name: name.trim(),
              rename: rename2,
              movieFormat: movieFormat || "",
              movieFolderFormat: movieFolderFormat || "",
              replaceIllegalCharacters,
              colonReplacementFormat: colonReplacementFormat || "delete"
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to create radarr naming config";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to create radarr naming config" });
      } else {
        const rename2 = formData.get("rename") === "true";
        const standardEpisodeFormat = formData.get("standardEpisodeFormat");
        const dailyEpisodeFormat = formData.get("dailyEpisodeFormat");
        const animeEpisodeFormat = formData.get("animeEpisodeFormat");
        const seriesFolderFormat = formData.get("seriesFolderFormat");
        const seasonFolderFormat = formData.get("seasonFolderFormat");
        const replaceIllegalCharacters = formData.get("replaceIllegalCharacters") === "true";
        const colonReplacementFormat = formData.get("colonReplacementFormat");
        const customColonReplacementFormat = formData.get("customColonReplacementFormat");
        const multiEpisodeStyle = formData.get("multiEpisodeStyle");
        const formatFields = [
          {
            name: "Standard episode format",
            value: standardEpisodeFormat,
            field: "standardEpisodeFormat"
          },
          {
            name: "Daily episode format",
            value: dailyEpisodeFormat,
            field: "dailyEpisodeFormat"
          },
          {
            name: "Anime episode format",
            value: animeEpisodeFormat,
            field: "animeEpisodeFormat"
          },
          {
            name: "Series folder format",
            value: seriesFolderFormat,
            field: "seriesFolderFormat"
          },
          {
            name: "Season folder format",
            value: seasonFolderFormat,
            field: "seasonFolderFormat"
          }
        ];
        for (const field of formatFields) {
          const validation = validateNamingFormat(field.value || "", "sonarr", { field: field.field });
          if (!validation.valid) return fail(400, { error: `${field.name}: ${validation.errors.join(", ")}` });
        }
        let result;
        try {
          result = await createSonarrNaming({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            input: {
              name: name.trim(),
              rename: rename2,
              standardEpisodeFormat: standardEpisodeFormat || "",
              dailyEpisodeFormat: dailyEpisodeFormat || "",
              animeEpisodeFormat: animeEpisodeFormat || "",
              seriesFolderFormat: seriesFolderFormat || "",
              seasonFolderFormat: seasonFolderFormat || "",
              replaceIllegalCharacters,
              colonReplacementFormat: colonReplacementFormat || "delete",
              customColonReplacementFormat: customColonReplacementFormat || null,
              multiEpisodeStyle: multiEpisodeStyle || "extend"
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to create sonarr naming config";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to create sonarr naming config" });
      }
      throw redirect(303, `/media-management/${databaseId}/naming`);
    } };
  }
});

// dist/build/server/chunks/TokenAutocomplete.js
function NamingPreview($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let preview;
    let format = fallback($$props["format"], "");
    let resolver = $$props["resolver"];
    $: preview = format ? resolver(format) : "";
    if (preview) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<p class="mt-2 font-mono text-xs break-all text-neutral-500 dark:text-neutral-400">${escape_html(preview)}</p>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      format,
      resolver
    });
  });
}
function TokenAutocomplete($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let label = $$props["label"];
    let name = $$props["name"];
    let value2 = $$props["value"];
    let placeholder = fallback($$props["placeholder"], "");
    let categories = $$props["categories"];
    let inputElement = fallback($$props["inputElement"], null);
    let disabled = fallback($$props["disabled"], false);
    createEventDispatcher();
    $: categories.flatMap((cat) => cat.tokens.map((t2) => ({
      ...t2,
      category: cat.name
    })));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="relative">`);
      FormInput($$renderer3, {
        label,
        name,
        value: value2,
        placeholder,
        mono: true,
        wrap: true,
        inputClass: "text-xs",
        disabled,
        get inputElement() {
          return inputElement;
        },
        set inputElement($$value) {
          inputElement = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      label,
      name,
      value: value2,
      placeholder,
      categories,
      inputElement,
      disabled
    });
  });
}
var init_TokenAutocomplete = __esm({
  "dist/build/server/chunks/TokenAutocomplete.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_FormInput();
  }
});

// dist/build/server/chunks/RadarrNamingForm.js
function RadarrNamingForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let formData, databaseId, title, description, isValid;
    let mode = $$props["mode"];
    let databaseName = $$props["databaseName"];
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let actionUrl = fallback($$props["actionUrl"], "");
    let breadcrumbItems = fallback($$props["breadcrumbItems"], () => [], true);
    let breadcrumbCurrent = fallback($$props["breadcrumbCurrent"], "");
    let initialData = $$props["initialData"];
    const defaults = {
      name: "",
      rename: true,
      movieFormat: "{Movie Title} ({Release Year}) {Quality Full}",
      movieFolderFormat: "{Movie Title} ({Release Year})",
      replaceIllegalCharacters: false,
      colonReplacementFormat: "delete"
    };
    function mapToFormData(data) {
      if (!data) return defaults;
      return {
        name: data.name,
        rename: data.rename,
        movieFormat: data.movie_format,
        movieFolderFormat: data.movie_folder_format,
        replaceIllegalCharacters: data.replace_illegal_characters,
        colonReplacementFormat: data.colon_replacement_format
      };
    }
    if (mode === "create") initCreate(mapToFormData(initialData));
    else initEdit(mapToFormData(initialData));
    let saving = false;
    let deleting = false;
    let showDeleteModal = false;
    let showInfoModal = false;
    let showSyncModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    let movieFormatInput = null;
    let movieFolderFormatInput = null;
    const radarrTokenCategories = getRadarrTokenCategories();
    $: formData = store_get($$store_subs ??= {}, "$current", current2);
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: title = mode === "create" ? "New Radarr Naming Config" : "Edit Radarr Naming Config";
    $: description = mode === "create" ? `Create a new Radarr naming configuration for ${databaseName}` : `Update Radarr naming configuration`;
    $: isValid = formData.name.trim() !== "";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      StickyCard($$renderer3, {
        position: "top",
        breadcrumbItems,
        breadcrumbCurrent,
        stickyBreadcrumb: false,
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<div slot="left"><h1 class="text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h1> <p class="text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p></div>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div slot="right" class="flex items-center gap-2">`);
            Button($$renderer4, {
              text: "Info",
              icon: Info,
              iconColor: "text-blue-600 dark:text-blue-400"
            });
            $$renderer4.push(`<!----> `);
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                text: "Delete",
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                disabled: saving
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            Button($$renderer4, {
              text: mode === "create" ? "Create" : "Save",
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              disabled: !isValid || !store_get($$store_subs ??= {}, "$isDirty", isDirty)
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="md:px-4"><div class="space-y-6"><div class="space-y-2"><div class="flex items-center justify-between gap-4"><div><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Name<span class="text-red-500">*</span></div></div> <div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Rename Movies</div></div> <div class="flex items-center justify-between gap-4"><p class="text-xs text-neutral-600 dark:text-neutral-400">The name of this Radarr naming configuration.</p> <p class="text-right text-xs text-neutral-600 dark:text-neutral-400">Rename movie files to match the naming format.</p></div> <div class="grid gap-4 md:grid-cols-[minmax(0,1fr)_14rem] md:items-end">`);
      FormInput($$renderer3, {
        label: "Name",
        name: "name",
        required: true,
        hideLabel: true,
        value: formData.name,
        placeholder: "e.g., default"
      });
      $$renderer3.push(`<!----> `);
      Toggle($$renderer3, {
        checked: formData.rename,
        label: formData.rename ? "Enabled" : "Disabled",
        ariaLabel: "Rename Movies",
        color: formData.rename ? "green" : "neutral",
        fullWidth: true
      });
      $$renderer3.push(`<!----></div></div> <div${attr_class("space-y-4", void 0, { "opacity-60": !formData.rename })} data-onboarding="media-naming-formats"><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Naming Formats</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Control how Radarr names movie files and folders.</p></div> <div>`);
      TokenAutocomplete($$renderer3, {
        label: "Movie Format",
        name: "movieFormat",
        value: formData.movieFormat,
        placeholder: "e.g., Movie Title (Year) Quality",
        categories: radarrTokenCategories,
        disabled: !formData.rename,
        get inputElement() {
          return movieFormatInput;
        },
        set inputElement($$value) {
          movieFormatInput = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      NamingPreview($$renderer3, {
        format: formData.movieFormat,
        resolver: resolveRadarrFormat
      });
      $$renderer3.push(`<!----></div> <div>`);
      TokenAutocomplete($$renderer3, {
        label: "Movie Folder Format",
        name: "movieFolderFormat",
        value: formData.movieFolderFormat,
        placeholder: "e.g., Movie Title (Year)",
        categories: radarrTokenCategories,
        disabled: !formData.rename,
        get inputElement() {
          return movieFolderFormatInput;
        },
        set inputElement($$value) {
          movieFolderFormatInput = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      NamingPreview($$renderer3, {
        format: formData.movieFolderFormat,
        resolver: resolveRadarrFormat
      });
      $$renderer3.push(`<!----></div></div> <div${attr_class("space-y-4", void 0, { "opacity-60": !formData.rename })} data-onboarding="media-naming-character-replacement"><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Character Replacement</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Control how illegal filesystem characters are handled in generated names.</p></div> <div class="space-y-2">`);
      Toggle($$renderer3, {
        checked: formData.replaceIllegalCharacters,
        label: "Replace Illegal Characters",
        ariaLabel: "Replace Illegal Characters",
        color: formData.replaceIllegalCharacters ? "green" : "neutral",
        disabled: !formData.rename
      });
      $$renderer3.push(`<!----> <p class="text-xs text-neutral-600 dark:text-neutral-400">Replace characters that are not allowed in file names.</p></div> <div class="space-y-2"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Colon Replacement</div> `);
      DropdownSelect($$renderer3, {
        value: formData.colonReplacementFormat,
        options: RADARR_COLON_REPLACEMENT_OPTIONS,
        disabled: !formData.rename || !formData.replaceIllegalCharacters
      });
      $$renderer3.push(`<!----></div></div></div></div> <form method="POST"${attr("action", actionUrl)} class="hidden"><input type="hidden" name="arrType" value="radarr"/> <input type="hidden" name="name"${attr("value", formData.name)}/> <input type="hidden" name="rename"${attr("value", formData.rename)}/> <input type="hidden" name="movieFormat"${attr("value", formData.movieFormat)}/> <input type="hidden" name="movieFolderFormat"${attr("value", formData.movieFolderFormat)}/> <input type="hidden" name="replaceIllegalCharacters"${attr("value", formData.replaceIllegalCharacters)}/> <input type="hidden" name="colonReplacementFormat"${attr("value", formData.colonReplacementFormat)}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/></form> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form method="POST" action="?/delete" class="hidden"><input type="hidden" name="layer"${attr("value", selectedLayer)}/></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      Modal($$renderer3, {
        open: showDeleteModal,
        header: "Delete Radarr naming config",
        bodyMessage: "This will remove the naming config and write a delete op. You can recreate it later if needed.",
        confirmText: "Delete",
        cancelText: "Cancel",
        confirmDanger: true,
        confirmDisabled: deleting,
        loading: deleting
      });
      $$renderer3.push(`<!----> `);
      InfoModal($$renderer3, {
        header: "Radarr Naming Configuration",
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">Format Strings</div> <p class="mt-1">Format strings control how Radarr names movie files and folders. Use tokens like <code class="rounded bg-neutral-100 px-1 py-0.5 font-mono text-xs dark:bg-neutral-800">{Movie Title}</code> and <code class="rounded bg-neutral-100 px-1 py-0.5 font-mono text-xs dark:bg-neutral-800">{Release Year}</code> to build your naming pattern.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Token Autocomplete</div> <p class="mt-1">Type <code class="rounded bg-neutral-100 px-1 py-0.5 font-mono text-xs dark:bg-neutral-800">{</code> in any format field to open the token picker. Filter by typing, then use arrow keys and Enter
				or click to insert.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Live Preview</div> <p class="mt-1">A preview line below each format field shows how your pattern resolves with sample data, so
				you can see the result as you type.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Character Replacement</div> <p class="mt-1">When enabled, illegal filesystem characters are replaced automatically. The colon
				replacement option controls how colons specifically are handled (deleted, replaced with a
				dash, space, etc.).</p></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      SyncPromptModal($$renderer3, {
        redirectTo: pendingRedirectTo,
        affectedArrs: pendingAffectedArrs,
        entityType: "naming",
        databaseId,
        entityName: formData.name.trim(),
        get open() {
          return showSyncModal;
        },
        set open($$value) {
          showSyncModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      databaseName,
      canWriteToBase: canWriteToBase2,
      actionUrl,
      breadcrumbItems,
      breadcrumbCurrent,
      initialData
    });
  });
}
var init_RadarrNamingForm = __esm({
  "dist/build/server/chunks/RadarrNamingForm.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_mediaManagement();
    init_info();
    init_Button();
    init_save();
    init_trash_2();
    init_stores();
    init_store2();
    init_navigation();
    init_Modal();
    init_forms();
    init_dirty();
    init_InfoModal();
    init_StickyCard();
    init_DropdownSelect();
    init_FormInput();
    init_Toggle();
    init_SyncPromptModal();
    init_namingTokens();
    init_TokenAutocomplete();
  }
});

// dist/build/server/chunks/SonarrNamingForm.js
function SonarrNamingForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let formData, databaseId, title, description, isValid, showCustomColonInput;
    let mode = $$props["mode"];
    let databaseName = $$props["databaseName"];
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let actionUrl = fallback($$props["actionUrl"], "");
    let breadcrumbItems = fallback($$props["breadcrumbItems"], () => [], true);
    let breadcrumbCurrent = fallback($$props["breadcrumbCurrent"], "");
    let initialData = $$props["initialData"];
    const defaults = {
      name: "",
      rename: true,
      standardEpisodeFormat: "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Quality Full}",
      dailyEpisodeFormat: "{Series Title} - {Air-Date} - {Episode Title} {Quality Full}",
      animeEpisodeFormat: "{Series Title} - S{season:00}E{episode:00} - {Episode Title} {Quality Full}",
      seriesFolderFormat: "{Series Title}",
      seasonFolderFormat: "Season {season}",
      replaceIllegalCharacters: false,
      colonReplacementFormat: "delete",
      customColonReplacementFormat: "",
      multiEpisodeStyle: "extend"
    };
    function mapToFormData(data) {
      if (!data) return defaults;
      return {
        name: data.name,
        rename: data.rename,
        standardEpisodeFormat: data.standard_episode_format,
        dailyEpisodeFormat: data.daily_episode_format,
        animeEpisodeFormat: data.anime_episode_format,
        seriesFolderFormat: data.series_folder_format,
        seasonFolderFormat: data.season_folder_format,
        replaceIllegalCharacters: data.replace_illegal_characters,
        colonReplacementFormat: data.colon_replacement_format,
        customColonReplacementFormat: data.custom_colon_replacement_format || "",
        multiEpisodeStyle: data.multi_episode_style
      };
    }
    if (mode === "create") initCreate(mapToFormData(initialData));
    else initEdit(mapToFormData(initialData));
    let saving = false;
    let deleting = false;
    let showDeleteModal = false;
    let showInfoModal = false;
    let showSyncModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    let standardEpisodeFormatInput = null;
    let dailyEpisodeFormatInput = null;
    let animeEpisodeFormatInput = null;
    let seriesFolderFormatInput = null;
    let seasonFolderFormatInput = null;
    const sonarrTokenCategories = getSonarrTokenCategories();
    $: formData = store_get($$store_subs ??= {}, "$current", current2);
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: title = mode === "create" ? "New Sonarr Naming Config" : "Edit Sonarr Naming Config";
    $: description = mode === "create" ? `Create a new Sonarr naming configuration for ${databaseName}` : `Update Sonarr naming configuration`;
    $: isValid = formData.name.trim() !== "";
    $: showCustomColonInput = formData.colonReplacementFormat === "custom";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      StickyCard($$renderer3, {
        position: "top",
        breadcrumbItems,
        breadcrumbCurrent,
        stickyBreadcrumb: false,
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<div slot="left"><h1 class="text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h1> <p class="text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p></div>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div slot="right" class="flex items-center gap-2">`);
            Button($$renderer4, {
              text: "Info",
              icon: Info,
              iconColor: "text-blue-600 dark:text-blue-400"
            });
            $$renderer4.push(`<!----> `);
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                text: "Delete",
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                disabled: saving
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            Button($$renderer4, {
              text: mode === "create" ? "Create" : "Save",
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              disabled: !isValid || !store_get($$store_subs ??= {}, "$isDirty", isDirty)
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="md:px-4"><div class="space-y-6"><div class="space-y-2"><div class="flex items-center justify-between gap-4"><div><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Name<span class="text-red-500">*</span></div></div> <div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Rename Episodes</div></div> <div class="flex items-center justify-between gap-4"><p class="text-xs text-neutral-600 dark:text-neutral-400">The name of this Sonarr naming configuration.</p> <p class="text-right text-xs text-neutral-600 dark:text-neutral-400">Rename episode files to match the naming format.</p></div> <div class="grid gap-4 md:grid-cols-[minmax(0,1fr)_14rem] md:items-end">`);
      FormInput($$renderer3, {
        label: "Name",
        name: "name",
        required: true,
        hideLabel: true,
        value: formData.name,
        placeholder: "e.g., default"
      });
      $$renderer3.push(`<!----> `);
      Toggle($$renderer3, {
        checked: formData.rename,
        label: formData.rename ? "Enabled" : "Disabled",
        ariaLabel: "Rename Episodes",
        color: formData.rename ? "green" : "neutral",
        fullWidth: true
      });
      $$renderer3.push(`<!----></div></div> <div${attr_class("space-y-4", void 0, { "opacity-60": !formData.rename })} data-onboarding="media-naming-formats"><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Episode Formats</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Control how Sonarr names standard, daily, and anime episodes.</p></div> <div>`);
      TokenAutocomplete($$renderer3, {
        label: "Standard Episode Format",
        name: "standardEpisodeFormat",
        value: formData.standardEpisodeFormat,
        categories: sonarrTokenCategories,
        disabled: !formData.rename,
        get inputElement() {
          return standardEpisodeFormatInput;
        },
        set inputElement($$value) {
          standardEpisodeFormatInput = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      NamingPreview($$renderer3, {
        format: formData.standardEpisodeFormat,
        resolver: resolveSonarrFormat
      });
      $$renderer3.push(`<!----></div> <div>`);
      TokenAutocomplete($$renderer3, {
        label: "Daily Episode Format",
        name: "dailyEpisodeFormat",
        value: formData.dailyEpisodeFormat,
        categories: sonarrTokenCategories,
        disabled: !formData.rename,
        get inputElement() {
          return dailyEpisodeFormatInput;
        },
        set inputElement($$value) {
          dailyEpisodeFormatInput = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      NamingPreview($$renderer3, {
        format: formData.dailyEpisodeFormat,
        resolver: resolveSonarrFormat
      });
      $$renderer3.push(`<!----></div> <div>`);
      TokenAutocomplete($$renderer3, {
        label: "Anime Episode Format",
        name: "animeEpisodeFormat",
        value: formData.animeEpisodeFormat,
        categories: sonarrTokenCategories,
        disabled: !formData.rename,
        get inputElement() {
          return animeEpisodeFormatInput;
        },
        set inputElement($$value) {
          animeEpisodeFormatInput = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      NamingPreview($$renderer3, {
        format: formData.animeEpisodeFormat,
        resolver: resolveSonarrFormat
      });
      $$renderer3.push(`<!----></div></div> <div${attr_class("space-y-4", void 0, { "opacity-60": !formData.rename })}><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Folder Formats</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Control how Sonarr names series and season folders.</p></div> <div>`);
      TokenAutocomplete($$renderer3, {
        label: "Series Folder Format",
        name: "seriesFolderFormat",
        value: formData.seriesFolderFormat,
        categories: sonarrTokenCategories,
        disabled: !formData.rename,
        get inputElement() {
          return seriesFolderFormatInput;
        },
        set inputElement($$value) {
          seriesFolderFormatInput = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      NamingPreview($$renderer3, {
        format: formData.seriesFolderFormat,
        resolver: resolveSonarrFormat
      });
      $$renderer3.push(`<!----></div> <div>`);
      TokenAutocomplete($$renderer3, {
        label: "Season Folder Format",
        name: "seasonFolderFormat",
        value: formData.seasonFolderFormat,
        categories: sonarrTokenCategories,
        disabled: !formData.rename,
        get inputElement() {
          return seasonFolderFormatInput;
        },
        set inputElement($$value) {
          seasonFolderFormatInput = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      NamingPreview($$renderer3, {
        format: formData.seasonFolderFormat,
        resolver: resolveSonarrFormat
      });
      $$renderer3.push(`<!----></div></div> <div${attr_class("space-y-2", void 0, { "opacity-60": !formData.rename })}><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Multi-Episode Style</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Choose how multi-episode files are represented in generated names.</p></div> `);
      DropdownSelect($$renderer3, {
        value: formData.multiEpisodeStyle,
        options: MULTI_EPISODE_STYLE_OPTIONS,
        disabled: !formData.rename
      });
      $$renderer3.push(`<!----></div> <div${attr_class("space-y-4", void 0, { "opacity-60": !formData.rename })} data-onboarding="media-naming-character-replacement"><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Character Replacement</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Control how illegal filesystem characters are handled in generated names.</p></div> <div class="space-y-2">`);
      Toggle($$renderer3, {
        checked: formData.replaceIllegalCharacters,
        label: "Replace Illegal Characters",
        ariaLabel: "Replace Illegal Characters",
        color: formData.replaceIllegalCharacters ? "green" : "neutral",
        disabled: !formData.rename
      });
      $$renderer3.push(`<!----> <p class="text-xs text-neutral-600 dark:text-neutral-400">Replace characters that are not allowed in file names.</p></div> <div class="space-y-2"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Colon Replacement</div> `);
      DropdownSelect($$renderer3, {
        value: formData.colonReplacementFormat,
        options: SONARR_COLON_REPLACEMENT_OPTIONS,
        disabled: !formData.rename || !formData.replaceIllegalCharacters
      });
      $$renderer3.push(`<!----></div> `);
      if (showCustomColonInput) {
        $$renderer3.push("<!--[0-->");
        FormInput($$renderer3, {
          label: "Custom Replacement",
          name: "customColonReplacementFormat",
          value: formData.customColonReplacementFormat,
          placeholder: "Enter custom replacement character(s)",
          disabled: !formData.rename || !formData.replaceIllegalCharacters
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div></div></div> <form method="POST"${attr("action", actionUrl)} class="hidden"><input type="hidden" name="arrType" value="sonarr"/> <input type="hidden" name="name"${attr("value", formData.name)}/> <input type="hidden" name="rename"${attr("value", formData.rename)}/> <input type="hidden" name="standardEpisodeFormat"${attr("value", formData.standardEpisodeFormat)}/> <input type="hidden" name="dailyEpisodeFormat"${attr("value", formData.dailyEpisodeFormat)}/> <input type="hidden" name="animeEpisodeFormat"${attr("value", formData.animeEpisodeFormat)}/> <input type="hidden" name="seriesFolderFormat"${attr("value", formData.seriesFolderFormat)}/> <input type="hidden" name="seasonFolderFormat"${attr("value", formData.seasonFolderFormat)}/> <input type="hidden" name="replaceIllegalCharacters"${attr("value", formData.replaceIllegalCharacters)}/> <input type="hidden" name="colonReplacementFormat"${attr("value", formData.colonReplacementFormat)}/> <input type="hidden" name="customColonReplacementFormat"${attr("value", formData.customColonReplacementFormat)}/> <input type="hidden" name="multiEpisodeStyle"${attr("value", formData.multiEpisodeStyle)}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/></form> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form method="POST" action="?/delete" class="hidden"><input type="hidden" name="layer"${attr("value", selectedLayer)}/></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      Modal($$renderer3, {
        open: showDeleteModal,
        header: "Delete Sonarr naming config",
        bodyMessage: "This will remove the naming config and write a delete op. You can recreate it later if needed.",
        confirmText: "Delete",
        cancelText: "Cancel",
        confirmDanger: true,
        confirmDisabled: deleting,
        loading: deleting
      });
      $$renderer3.push(`<!----> `);
      InfoModal($$renderer3, {
        header: "Sonarr Naming Configuration",
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">Format Strings</div> <p class="mt-1">Format strings control how Sonarr names episode files and folders. Use tokens like <code class="rounded bg-neutral-100 px-1 py-0.5 font-mono text-xs dark:bg-neutral-800">{Series Title}</code> and <code class="rounded bg-neutral-100 px-1 py-0.5 font-mono text-xs dark:bg-neutral-800">{Episode Title}</code> to build your naming pattern. Sonarr has separate formats for standard, daily, and anime episodes.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Token Autocomplete</div> <p class="mt-1">Type <code class="rounded bg-neutral-100 px-1 py-0.5 font-mono text-xs dark:bg-neutral-800">{</code> in any format field to open the token picker. Filter by typing, then use arrow keys and Enter
				or click to insert.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Live Preview</div> <p class="mt-1">A preview line below each format field shows how your pattern resolves with sample data, so
				you can see the result as you type.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Multi-Episode Style</div> <p class="mt-1">Controls how multi-episode files are named. "Extend" appends additional episode numbers
				(S01E01-E02), while other styles use different separator patterns.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Character Replacement</div> <p class="mt-1">When enabled, illegal filesystem characters are replaced automatically. The colon
				replacement option controls how colons specifically are handled. Sonarr also supports a
				custom replacement string.</p></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      SyncPromptModal($$renderer3, {
        redirectTo: pendingRedirectTo,
        affectedArrs: pendingAffectedArrs,
        entityType: "naming",
        databaseId,
        entityName: formData.name.trim(),
        get open() {
          return showSyncModal;
        },
        set open($$value) {
          showSyncModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      databaseName,
      canWriteToBase: canWriteToBase2,
      actionUrl,
      breadcrumbItems,
      breadcrumbCurrent,
      initialData
    });
  });
}
var init_SonarrNamingForm = __esm({
  "dist/build/server/chunks/SonarrNamingForm.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_mediaManagement();
    init_info();
    init_Button();
    init_save();
    init_trash_2();
    init_stores();
    init_store2();
    init_navigation();
    init_Modal();
    init_forms();
    init_dirty();
    init_InfoModal();
    init_StickyCard();
    init_DropdownSelect();
    init_FormInput();
    init_Toggle();
    init_SyncPromptModal();
    init_namingTokens();
    init_TokenAutocomplete();
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/naming/new/_page.svelte.js
var page_svelte_exports47 = {};
__export(page_svelte_exports47, {
  default: () => _page47
});
function _page47($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    let selectedArrType = store_get($$store_subs ??= {}, "$page", page).url.searchParams.get("arrType");
    PageMeta($$renderer2, { title: `${data.currentDatabase.name} \xB7 Naming \xB7 New` });
    $$renderer2.push(`<!----> `);
    if (selectedArrType === "radarr") {
      $$renderer2.push("<!--[0-->");
      RadarrNamingForm($$renderer2, {
        mode: "create",
        databaseName: data.currentDatabase?.name,
        canWriteToBase: data.canWriteToBase,
        initialData: null
      });
    } else if (selectedArrType === "sonarr") {
      $$renderer2.push("<!--[1-->");
      SonarrNamingForm($$renderer2, {
        mode: "create",
        databaseName: data.currentDatabase?.name,
        canWriteToBase: data.canWriteToBase,
        initialData: null
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte47 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/naming/new/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_client4();
    init_stores();
    init_navigation();
    init_DirtyModal();
    init_PageMeta();
    init_RadarrNamingForm();
    init_SonarrNamingForm();
  }
});

// dist/build/server/nodes/57.js
var __exports58 = {};
__export(__exports58, {
  component: () => component54,
  fonts: () => fonts58,
  imports: () => imports58,
  index: () => index58,
  server: () => page_server_ts_exports50,
  server_id: () => server_id56,
  stylesheets: () => stylesheets58
});
var index58, component_cache54, component54, server_id56, imports58, stylesheets58, fonts58;
var init__58 = __esm({
  async "dist/build/server/nodes/57.js"() {
    "use strict";
    await init_page_server_ts50();
    index58 = 57;
    component54 = async () => component_cache54 ??= (await Promise.resolve().then(() => (init_page_svelte47(), page_svelte_exports47))).default;
    server_id56 = "src/routes/media-management/[databaseId]/naming/new/+page.server.ts";
    imports58 = ["_app/immutable/nodes/57.DDKi_yhQ.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cn82cK4Q2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CrAcgBQ22.js", "_app/immutable/chunks/B4flxdLz2.js", "_app/immutable/chunks/BeyNTdTZ2.js"];
    stylesheets58 = [];
    fonts58 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/naming/radarr/_name_/_page.server.ts.js
var page_server_ts_exports51 = {};
__export(page_server_ts_exports51, {
  actions: () => actions32,
  load: () => load54
});
var load54, actions32;
var init_page_server_ts51 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/naming/radarr/_name_/_page.server.ts.js"() {
    "use strict";
    await init_arrSync();
    await init_queueService();
    await init_naming();
    await init_update();
    await init_affectedArrs();
    init_namingTokens();
    init_exports();
    load54 = async ({ params, parent }) => {
      const { databaseId, name } = params;
      if (!databaseId || !name) throw error(400, "Missing parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const namingConfig = await getRadarrByName$1(cache3, decodeURIComponent(name));
      if (!namingConfig) throw error(404, "Naming config not found");
      return {
        namingConfig,
        canWriteToBase: (await parent()).canWriteToBase
      };
    };
    actions32 = {
      update: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const decodedName = decodeURIComponent(name);
        const current3 = await getRadarrByName$1(cache3, decodedName);
        if (!current3) return fail(404, { error: "Naming config not found" });
        const formData = await request.formData();
        const newName = formData.get("name");
        const layer = formData.get("layer") || "user";
        if (!newName?.trim()) return fail(400, { error: "Name is required" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const rename2 = formData.get("rename") === "true";
        const movieFormat = formData.get("movieFormat");
        const movieFolderFormat = formData.get("movieFolderFormat");
        const replaceIllegalCharacters = formData.get("replaceIllegalCharacters") === "true";
        const colonReplacementFormat = formData.get("colonReplacementFormat");
        const movieFormatValidation = validateNamingFormat(movieFormat || "", "radarr", { field: "movieFormat" });
        if (!movieFormatValidation.valid) return fail(400, { error: `Movie format: ${movieFormatValidation.errors.join(", ")}` });
        const folderFormatValidation = validateNamingFormat(movieFolderFormat || "", "radarr", { field: "movieFolderFormat" });
        if (!folderFormatValidation.valid) return fail(400, { error: `Folder format: ${folderFormatValidation.errors.join(", ")}` });
        let result;
        try {
          result = await updateRadarrNaming({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            current: current3,
            input: {
              name: newName.trim(),
              rename: rename2,
              movieFormat: movieFormat || "",
              movieFolderFormat: movieFolderFormat || "",
              replaceIllegalCharacters,
              colonReplacementFormat: colonReplacementFormat || "delete"
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update naming config";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update naming config" });
        if (newName.trim() !== decodedName) arrSyncQueries.updateNamingConfigName(decodedName, newName.trim());
        const affectedArrs = getAffectedArrs({
          entityType: "naming",
          databaseId: currentDatabaseId,
          entityName: newName.trim()
        });
        return {
          success: true,
          redirectTo: `/media-management/${databaseId}/naming`,
          affectedArrs
        };
      },
      delete: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await getRadarrByName$1(cache3, decodeURIComponent(name));
        if (!current3) return fail(404, { error: "Naming config not found" });
        const layer = (await request.formData()).get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await removeRadarrNaming({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          current: current3
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete naming config" });
        throw redirect(303, `/media-management/${databaseId}/naming`);
      }
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/naming/radarr/_name_/_page.svelte.js
var page_svelte_exports48 = {};
__export(page_svelte_exports48, {
  default: () => _page48
});
function _page48($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: `${data.namingConfig.name} \xB7 Radarr Naming` });
    $$renderer2.push(`<!----> `);
    RadarrNamingForm($$renderer2, {
      mode: "edit",
      databaseName: data.currentDatabase?.name,
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      initialData: data.namingConfig,
      breadcrumbItems: [{
        label: data.currentDatabase.name,
        href: `/media-management/${data.currentDatabase.id}/naming`
      }],
      breadcrumbCurrent: data.namingConfig.name
    });
    $$renderer2.push(`<!----> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte48 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/naming/radarr/_name_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_DirtyModal();
    init_PageMeta();
    init_RadarrNamingForm();
  }
});

// dist/build/server/nodes/58.js
var __exports59 = {};
__export(__exports59, {
  component: () => component55,
  fonts: () => fonts59,
  imports: () => imports59,
  index: () => index59,
  server: () => page_server_ts_exports51,
  server_id: () => server_id57,
  stylesheets: () => stylesheets59
});
var index59, component_cache55, component55, server_id57, imports59, stylesheets59, fonts59;
var init__59 = __esm({
  async "dist/build/server/nodes/58.js"() {
    "use strict";
    await init_page_server_ts51();
    index59 = 58;
    component55 = async () => component_cache55 ??= (await Promise.resolve().then(() => (init_page_svelte48(), page_svelte_exports48))).default;
    server_id57 = "src/routes/media-management/[databaseId]/naming/radarr/[name]/+page.server.ts";
    imports59 = ["_app/immutable/nodes/58.Ct4R2MMd.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cn82cK4Q2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CrAcgBQ22.js", "_app/immutable/chunks/B4flxdLz2.js"];
    stylesheets59 = [];
    fonts59 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/naming/sonarr/_name_/_page.server.ts.js
var page_server_ts_exports52 = {};
__export(page_server_ts_exports52, {
  actions: () => actions33,
  load: () => load55
});
var load55, actions33;
var init_page_server_ts52 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/naming/sonarr/_name_/_page.server.ts.js"() {
    "use strict";
    await init_arrSync();
    await init_queueService();
    await init_naming();
    await init_update();
    await init_affectedArrs();
    init_namingTokens();
    init_exports();
    load55 = async ({ params, parent }) => {
      const { databaseId, name } = params;
      if (!databaseId || !name) throw error(400, "Missing parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const namingConfig = await getSonarrByName$1(cache3, decodeURIComponent(name));
      if (!namingConfig) throw error(404, "Naming config not found");
      return {
        namingConfig,
        canWriteToBase: (await parent()).canWriteToBase
      };
    };
    actions33 = {
      update: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const decodedName = decodeURIComponent(name);
        const current3 = await getSonarrByName$1(cache3, decodedName);
        if (!current3) return fail(404, { error: "Naming config not found" });
        const formData = await request.formData();
        const newName = formData.get("name");
        const layer = formData.get("layer") || "user";
        if (!newName?.trim()) return fail(400, { error: "Name is required" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const rename2 = formData.get("rename") === "true";
        const standardEpisodeFormat = formData.get("standardEpisodeFormat");
        const dailyEpisodeFormat = formData.get("dailyEpisodeFormat");
        const animeEpisodeFormat = formData.get("animeEpisodeFormat");
        const seriesFolderFormat = formData.get("seriesFolderFormat");
        const seasonFolderFormat = formData.get("seasonFolderFormat");
        const replaceIllegalCharacters = formData.get("replaceIllegalCharacters") === "true";
        const colonReplacementFormat = formData.get("colonReplacementFormat");
        const customColonReplacementFormat = formData.get("customColonReplacementFormat");
        const multiEpisodeStyle = formData.get("multiEpisodeStyle");
        const formatFields = [
          {
            name: "Standard episode format",
            value: standardEpisodeFormat,
            field: "standardEpisodeFormat"
          },
          {
            name: "Daily episode format",
            value: dailyEpisodeFormat,
            field: "dailyEpisodeFormat"
          },
          {
            name: "Anime episode format",
            value: animeEpisodeFormat,
            field: "animeEpisodeFormat"
          },
          {
            name: "Series folder format",
            value: seriesFolderFormat,
            field: "seriesFolderFormat"
          },
          {
            name: "Season folder format",
            value: seasonFolderFormat,
            field: "seasonFolderFormat"
          }
        ];
        for (const field of formatFields) {
          const validation = validateNamingFormat(field.value || "", "sonarr", { field: field.field });
          if (!validation.valid) return fail(400, { error: `${field.name}: ${validation.errors.join(", ")}` });
        }
        let result;
        try {
          result = await updateSonarrNaming({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            current: current3,
            input: {
              name: newName.trim(),
              rename: rename2,
              standardEpisodeFormat: standardEpisodeFormat || "",
              dailyEpisodeFormat: dailyEpisodeFormat || "",
              animeEpisodeFormat: animeEpisodeFormat || "",
              seriesFolderFormat: seriesFolderFormat || "",
              seasonFolderFormat: seasonFolderFormat || "",
              replaceIllegalCharacters,
              colonReplacementFormat: colonReplacementFormat || "delete",
              customColonReplacementFormat: customColonReplacementFormat || null,
              multiEpisodeStyle: multiEpisodeStyle || "extend"
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update naming config";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update naming config" });
        if (newName.trim() !== decodedName) arrSyncQueries.updateNamingConfigName(decodedName, newName.trim());
        const affectedArrs = getAffectedArrs({
          entityType: "naming",
          databaseId: currentDatabaseId,
          entityName: newName.trim()
        });
        return {
          success: true,
          redirectTo: `/media-management/${databaseId}/naming`,
          affectedArrs
        };
      },
      delete: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await getSonarrByName$1(cache3, decodeURIComponent(name));
        if (!current3) return fail(404, { error: "Naming config not found" });
        const layer = (await request.formData()).get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await removeSonarrNaming({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          current: current3
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete naming config" });
        throw redirect(303, `/media-management/${databaseId}/naming`);
      }
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/naming/sonarr/_name_/_page.svelte.js
var page_svelte_exports49 = {};
__export(page_svelte_exports49, {
  default: () => _page49
});
function _page49($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: `${data.namingConfig.name} \xB7 Sonarr Naming` });
    $$renderer2.push(`<!----> `);
    SonarrNamingForm($$renderer2, {
      mode: "edit",
      databaseName: data.currentDatabase?.name,
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      initialData: data.namingConfig,
      breadcrumbItems: [{
        label: data.currentDatabase.name,
        href: `/media-management/${data.currentDatabase.id}/naming`
      }],
      breadcrumbCurrent: data.namingConfig.name
    });
    $$renderer2.push(`<!----> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte49 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/naming/sonarr/_name_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_DirtyModal();
    init_PageMeta();
    init_SonarrNamingForm();
  }
});

// dist/build/server/nodes/59.js
var __exports60 = {};
__export(__exports60, {
  component: () => component56,
  fonts: () => fonts60,
  imports: () => imports60,
  index: () => index60,
  server: () => page_server_ts_exports52,
  server_id: () => server_id58,
  stylesheets: () => stylesheets60
});
var index60, component_cache56, component56, server_id58, imports60, stylesheets60, fonts60;
var init__60 = __esm({
  async "dist/build/server/nodes/59.js"() {
    "use strict";
    await init_page_server_ts52();
    index60 = 59;
    component56 = async () => component_cache56 ??= (await Promise.resolve().then(() => (init_page_svelte49(), page_svelte_exports49))).default;
    server_id58 = "src/routes/media-management/[databaseId]/naming/sonarr/[name]/+page.server.ts";
    imports60 = ["_app/immutable/nodes/59.OOw5BxQO.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/BeyNTdTZ2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CrAcgBQ22.js", "_app/immutable/chunks/B4flxdLz2.js"];
    stylesheets60 = [];
    fonts60 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/_page.server.ts.js
var page_server_ts_exports53 = {};
__export(page_server_ts_exports53, {
  load: () => load56
});
var load56;
var init_page_server_ts53 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    init_exports();
    load56 = async ({ params }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      return { qualityDefinitionsConfigs: await list$1(cache3) };
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/_page.svelte.js
var page_svelte_exports50 = {};
__export(page_svelte_exports50, {
  default: () => _page50
});
function TableView7($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let configs = $$props["configs"];
    let databaseId = $$props["databaseId"];
    createEventDispatcher();
    const logos = {
      radarr: Radarr_default,
      sonarr: Sonarr_default
    };
    function getRowHref(config2) {
      return `/media-management/${databaseId}/quality-definitions/${config2.arr_type}/${encodeURIComponent(config2.name)}`;
    }
    Table2($$renderer2, {
      columns: [{
        key: "name",
        header: "Name",
        headerIcon: Tag,
        align: "left",
        sortable: true
      }, {
        key: "arr_type",
        header: "Type",
        sortable: true
      }],
      data: configs,
      rowHref: getRowHref,
      hoverable: true,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "name") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="font-medium">${escape_html(row.name)}</span>`);
          } else if (column.key === "arr_type") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="flex items-center gap-2"><img${attr("src", logos[row.arr_type])}${attr("alt", row.arr_type)} class="h-5 w-5"/></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        actions: ($$renderer3, { row }) => {
          $$renderer3.push(`<div class="flex items-center justify-end gap-0.5">`);
          if (FEATURES.importExport) {
            $$renderer3.push("<!--[0-->");
            Button($$renderer3, {
              icon: Download,
              size: "xs",
              variant: "ghost",
              tooltip: "Export"
            });
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> `);
          Button($$renderer3, {
            icon: Copy,
            size: "xs",
            variant: "secondary",
            tooltip: "Clone"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    bind_props($$props, {
      configs,
      databaseId
    });
  });
}
function CardView7($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let configs = $$props["configs"];
    let databaseId = $$props["databaseId"];
    createEventDispatcher();
    const logos = {
      radarr: Radarr_default,
      sonarr: Sonarr_default
    };
    let loadedImages = /* @__PURE__ */ new Set();
    function getConfigHref(config2) {
      return `/media-management/${databaseId}/quality-definitions/${config2.arr_type}/${encodeURIComponent(config2.name)}`;
    }
    CardGrid($$renderer2, {
      columns: 4,
      flush: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(configs);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let config2 = each_array[$$index];
          Card($$renderer3, {
            href: getConfigHref(config2),
            hoverable: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="flex items-center justify-between text-xs"><span class="flex items-center gap-1.5 text-neutral-500 dark:text-neutral-400">`);
              Layers($$renderer4, { size: 11 });
              $$renderer4.push(`<!---->Qualities</span> <span class="font-mono text-neutral-900 dark:text-neutral-100">${escape_html(config2.quality_count)}</span></div>`);
            },
            $$slots: {
              default: true,
              header: ($$renderer4) => {
                $$renderer4.push(`<div class="flex items-center justify-between gap-2"><div class="flex min-w-0 items-center gap-2"><div class="relative h-6 w-6 flex-shrink-0">`);
                if (!loadedImages.has(config2.name)) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="absolute inset-0 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> <img${attr("src", logos[config2.arr_type])}${attr("alt", `${stringify(config2.arr_type)} logo`)}${attr_class(`h-6 w-6 rounded ${loadedImages.has(config2.name) ? "opacity-100" : "opacity-0"}`)}/></div> <h3 class="truncate text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(config2.name)}</h3></div> <div class="flex items-center gap-0.5">`);
                if (FEATURES.importExport) {
                  $$renderer4.push("<!--[0-->");
                  Button($$renderer4, {
                    icon: Download,
                    size: "xs",
                    variant: "ghost",
                    tooltip: "Export"
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                Button($$renderer4, {
                  icon: Copy,
                  size: "xs",
                  variant: "ghost",
                  tooltip: "Clone"
                });
                $$renderer4.push(`<!----></div></div>`);
              }
            }
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    bind_props($$props, {
      configs,
      databaseId
    });
  });
}
function _page50($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    let cloneModalOpen = false;
    let cloneSourceName = "";
    let cloneEntityType = "radarr_quality_definitions";
    const { search, view, filtered, setItems } = createDataPageStore(data.qualityDefinitionsConfigs, {
      storageKey: "qualityDefinitionsView",
      searchKeys: ["name"],
      searchKey: `qualityDefinitionsConfigsSearch:${data.currentDatabase.id}`
    });
    $: setItems(data.qualityDefinitionsConfigs);
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.currentDatabase.name} \xB7 Quality Definitions` });
      $$renderer3.push(`<!----> `);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          SearchAction($$renderer4, {
            searchStore: search,
            placeholder: "Search quality definitions...",
            responsive: true
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Plus,
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
              Dropdown($$renderer5, {
                position: dropdownPosition,
                minWidth: "10rem",
                children: ($$renderer6) => {
                  DropdownHeader($$renderer6, { label: "New config" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, { label: "Radarr" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, { label: "Sonarr" });
                  $$renderer6.push(`<!---->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          ViewToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$view", view);
            },
            set value($$value) {
              store_set(view, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> <div class="mt-6">`);
      if (data.qualityDefinitionsConfigs.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No quality definitions configs found for ${escape_html(data.currentDatabase?.name)}</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$filtered", filtered).length === 0) {
        $$renderer3.push("<!--[1-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No quality definitions configs match your search</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$view", view) === "table") {
        $$renderer3.push("<!--[2-->");
        TableView7($$renderer3, {
          configs: store_get($$store_subs ??= {}, "$filtered", filtered),
          databaseId: data.currentDatabase.id
        });
      } else {
        $$renderer3.push("<!--[-1-->");
        CardView7($$renderer3, {
          configs: store_get($$store_subs ??= {}, "$filtered", filtered),
          databaseId: data.currentDatabase.id
        });
      }
      $$renderer3.push(`<!--]--></div> `);
      CloneModal($$renderer3, {
        databaseId: data.currentDatabase.id,
        entityType: cloneEntityType,
        sourceName: cloneSourceName,
        existingNames: data.qualityDefinitionsConfigs.map((c2) => c2.name),
        canWriteToBase: data.canWriteToBase,
        get open() {
          return cloneModalOpen;
        },
        set open($$value) {
          cloneModalOpen = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte50 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_features();
    init_Dropdown();
    init_copy();
    init_download();
    init_layers();
    init_Button();
    init_plus();
    init_search();
    init_ViewToggle();
    init_tag();
    init_store2();
    init_Card();
    init_Sonarr2();
    init_navigation();
    init_DropdownItem();
    init_ActionsBar();
    init_ActionButton();
    init_DropdownHeader();
    init_PageMeta();
    init_Table();
    init_CardGrid();
    init_dataPage();
    init_CloneModal();
  }
});

// dist/build/server/nodes/60.js
var __exports61 = {};
__export(__exports61, {
  component: () => component57,
  fonts: () => fonts61,
  imports: () => imports61,
  index: () => index61,
  server: () => page_server_ts_exports53,
  server_id: () => server_id59,
  stylesheets: () => stylesheets61
});
var index61, component_cache57, component57, server_id59, imports61, stylesheets61, fonts61;
var init__61 = __esm({
  async "dist/build/server/nodes/60.js"() {
    "use strict";
    await init_page_server_ts53();
    index61 = 60;
    component57 = async () => component_cache57 ??= (await Promise.resolve().then(() => (init_page_svelte50(), page_svelte_exports50))).default;
    server_id59 = "src/routes/media-management/[databaseId]/quality-definitions/+page.server.ts";
    imports61 = ["_app/immutable/nodes/60.CZE_X1Xc.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/D7OHFWTL2.js", "_app/immutable/chunks/DYf5Ixhg.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/Cut3gr1-.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/Dg15A-ry2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DxZIQ_tr2.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/DYe9q02k2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js"];
    stylesheets61 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts61 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/new/_page.server.ts.js
var page_server_ts_exports54 = {};
__export(page_server_ts_exports54, {
  actions: () => actions34,
  load: () => load57
});
var load57, actions34;
var init_page_server_ts54 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/new/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_quality_definitions();
    init_exports();
    load57 = async ({ params, parent }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const radarrQualities = await getAvailableQualities(cache3, "radarr");
      const sonarrQualities = await getAvailableQualities(cache3, "sonarr");
      return {
        canWriteToBase: (await parent()).canWriteToBase,
        radarrQualities,
        sonarrQualities
      };
    };
    actions34 = { default: async ({ request, params }) => {
      const { databaseId } = params;
      if (!databaseId) return fail(400, { error: "Missing database ID" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const arrType = formData.get("arrType");
      const name = formData.get("name");
      const layer = formData.get("layer") || "user";
      const entriesJson = formData.get("entries");
      if (!name?.trim()) return fail(400, { error: "Name is required" });
      if (!arrType || arrType !== "radarr" && arrType !== "sonarr") return fail(400, { error: "Invalid arr type" });
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      let entries;
      try {
        entries = JSON.parse(entriesJson || "[]");
      } catch {
        return fail(400, { error: "Invalid entries data" });
      }
      if (!Array.isArray(entries) || entries.length === 0) return fail(400, { error: "At least one quality definition is required" });
      const createFn = arrType === "radarr" ? createRadarrQualityDefinitions : createSonarrQualityDefinitions;
      let result;
      try {
        result = await createFn({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          input: {
            name: name.trim(),
            entries
          }
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : `Failed to create ${arrType} quality definitions`;
        if (message2.includes("already exists") || message2.toLowerCase().includes("duplicate")) return fail(400, { error: message2 });
        return fail(500, { error: message2 });
      }
      if (!result.success) return fail(500, { error: result.error || `Failed to create ${arrType} quality definitions` });
      throw redirect(303, `/media-management/${databaseId}/quality-definitions`);
    } };
  }
});

// dist/build/server/chunks/QualityDefinitionsForm.js
function QualityDefinitionsForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, arrLabel, title, description, isValid, unitOptions, defaultUnit, selectedUnit, groupedEntries, entriesForSubmit;
    let showInfoModal = false;
    const RESOLUTION_GROUP_ORDER = [
      "2160p",
      "1080p",
      "720p",
      "SD",
      "Prereleases",
      "Other"
    ];
    const RESOLUTION_GROUP_LABELS = {
      "2160p": "4K Ultra HD (2160p)",
      "1080p": "Full HD (1080p)",
      "720p": "HD (720p)",
      SD: "Standard Definition (SD)",
      Prereleases: "Prereleases",
      Other: "Other"
    };
    const PRERELEASE_QUALITIES = [
      "cam",
      "dvdscr",
      "regional",
      "telecine",
      "telesync",
      "workprint"
    ];
    const OTHER_QUALITIES = ["raw-hd", "unknown"];
    function getResolutionGroup(qualityName) {
      const name = qualityName.toLowerCase();
      if (PRERELEASE_QUALITIES.some((q2) => name === q2 || name.includes(q2))) return "Prereleases";
      if (OTHER_QUALITIES.some((q2) => name === q2 || name.includes(q2))) return "Other";
      if (name.includes("2160") || name.includes("4k") || name.includes("uhd")) return "2160p";
      if (name.includes("1080")) return "1080p";
      if (name.includes("720")) return "720p";
      return "SD";
    }
    let mode = $$props["mode"];
    let arrType = $$props["arrType"];
    let databaseName = $$props["databaseName"];
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let actionUrl = fallback($$props["actionUrl"], "");
    let breadcrumbItems = fallback($$props["breadcrumbItems"], () => [], true);
    let breadcrumbCurrent = fallback($$props["breadcrumbCurrent"], "");
    let availableQualities = fallback($$props["availableQualities"], () => [], true);
    let initialData = $$props["initialData"];
    const baseScaleMax = arrType === "radarr" ? 2e3 : 1e3;
    function normalizeEntries(raw, scaleMax) {
      return raw.map((e) => ({
        ...e,
        preferred_size: e.preferred_size === 0 ? scaleMax : e.preferred_size,
        max_size: e.max_size === 0 ? scaleMax : e.max_size
      }));
    }
    let configName = initialData?.name ?? "";
    let entries = normalizeEntries(initialData?.entries ?? [], baseScaleMax);
    function mapToFormData(data) {
      return {
        name: data?.name ?? "",
        entries: normalizeEntries(data?.entries ?? [], baseScaleMax)
      };
    }
    if (mode === "create") initCreate(mapToFormData(initialData));
    else initEdit(mapToFormData(initialData));
    let saving = false;
    let deleting = false;
    let showDeleteModal = false;
    let showSyncModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    let expandedRows = /* @__PURE__ */ new Set();
    const RADARR_UNITS = [
      {
        id: "mb-min",
        label: "MB per minute",
        short: "MB/m",
        multiplier: 1
      },
      {
        id: "gb-hr",
        label: "GB per hour",
        short: "GB/h",
        multiplier: 60 / 1024
      },
      {
        id: "gb-90",
        label: "GB per 90 min",
        short: "GB/90m",
        multiplier: 90 / 1024
      },
      {
        id: "gb-2hr",
        label: "GB per 2 hours",
        short: "GB/2h",
        multiplier: 120 / 1024
      }
    ];
    const SONARR_UNITS = [
      {
        id: "mb-min",
        label: "MB per minute",
        short: "MB/m",
        multiplier: 1
      },
      {
        id: "mb-30",
        label: "MB per 30 min",
        short: "MB/30m",
        multiplier: 30
      },
      {
        id: "gb-45",
        label: "GB per 45 min",
        short: "GB/45m",
        multiplier: 45 / 1024
      },
      {
        id: "gb-hr",
        label: "GB per hour",
        short: "GB/h",
        multiplier: 60 / 1024
      }
    ];
    let selectedUnitId = defaultUnit;
    function toDisplayUnit(value2) {
      return value2 * selectedUnit.multiplier;
    }
    const columns = [{
      key: "label",
      header: "Resolution",
      sortable: false
    }, {
      key: "count",
      header: "Qualities",
      align: "right",
      sortable: false
    }];
    function createMarkers(entry) {
      const scaleMax = baseScaleMax;
      return [
        {
          id: "min",
          label: "Min",
          color: "blue",
          value: entry.min_size
        },
        {
          id: "preferred",
          label: "Preferred",
          color: "green",
          value: entry.preferred_size === 0 ? scaleMax : entry.preferred_size
        },
        {
          id: "max",
          label: "Max",
          color: "orange",
          value: entry.max_size === 0 ? scaleMax : entry.max_size
        }
      ];
    }
    let markersMap = {};
    function syncToEntry(qualityName) {
      const markers = markersMap[qualityName];
      const entry = entries.find((e) => e.quality_name === qualityName);
      if (markers && entry) {
        entry.min_size = markers[0].value;
        entry.preferred_size = markers[1].value;
        entry.max_size = markers[2].value;
        entries = entries;
      }
    }
    $: if (mode === "create" && entries.length === 0 && availableQualities.length > 0) entries = availableQualities.map((quality_name) => ({
      quality_name,
      min_size: 0,
      max_size: baseScaleMax,
      preferred_size: baseScaleMax
    }));
    $: update3("name", configName);
    $: update3("entries", entries);
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: arrLabel = arrType === "radarr" ? "Radarr" : "Sonarr";
    $: title = mode === "create" ? `New ${arrLabel} Quality Definitions` : `Edit ${arrLabel} Quality Definitions`;
    $: description = mode === "create" ? `Create a new ${arrLabel} quality definitions configuration for ${databaseName}` : `Update ${arrLabel} quality definitions configuration`;
    $: isValid = configName.trim() !== "" && entries.length > 0;
    $: unitOptions = arrType === "radarr" ? RADARR_UNITS : SONARR_UNITS;
    $: defaultUnit = arrType === "radarr" ? "gb-2hr" : "gb-45";
    $: selectedUnit = unitOptions.find((u) => u.id === selectedUnitId) || unitOptions[0];
    $: groupedEntries = (() => {
      const groups = /* @__PURE__ */ new Map();
      for (const res of RESOLUTION_GROUP_ORDER) groups.set(res, []);
      for (const entry of entries) {
        const resolution = getResolutionGroup(entry.quality_name);
        groups.get(resolution)?.push(entry);
      }
      const result = [];
      for (const res of RESOLUTION_GROUP_ORDER) {
        const groupEntries = groups.get(res) || [];
        if (groupEntries.length > 0) result.push({
          resolution: res,
          label: RESOLUTION_GROUP_LABELS[res],
          entries: groupEntries
        });
      }
      return result;
    })();
    $: entries.forEach((entry) => {
      if (!markersMap[entry.quality_name]) markersMap[entry.quality_name] = createMarkers(entry);
    });
    $: entriesForSubmit = JSON.stringify(entries.map((e) => ({
      quality_name: e.quality_name,
      min_size: e.min_size,
      max_size: e.max_size >= baseScaleMax ? 0 : e.max_size,
      preferred_size: e.preferred_size >= baseScaleMax ? 0 : e.preferred_size
    })));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      StickyCard($$renderer3, {
        position: "top",
        breadcrumbItems,
        breadcrumbCurrent,
        stickyBreadcrumb: false,
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<div slot="left"><h1 class="text-xl font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h1> <p class="text-sm text-neutral-500 dark:text-neutral-400">${escape_html(description)}</p></div>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div slot="right" class="flex items-center gap-2"><div class="relative hidden qd:block">`);
            Button($$renderer4, {
              text: selectedUnit.label,
              icon: Chevron_down,
              iconPosition: "right"
            });
            $$renderer4.push(`<!----> `);
            $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></div> `);
            Button($$renderer4, {
              text: "Info",
              icon: Info,
              iconColor: "text-blue-600 dark:text-blue-400"
            });
            $$renderer4.push(`<!----> `);
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                text: "Delete",
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                disabled: saving
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            Button($$renderer4, {
              text: mode === "create" ? "Create" : "Save",
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              disabled: !isValid || !store_get($$store_subs ??= {}, "$isDirty", isDirty)
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <div class="space-y-6 md:px-4">`);
      FormInput($$renderer3, {
        label: "Name",
        name: "name",
        placeholder: "e.g., default",
        required: true,
        get value() {
          return configName;
        },
        set value($$value) {
          configName = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      if (entries.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No qualities available for ${escape_html(arrLabel)}</p></div>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        ExpandableTable($$renderer3, {
          columns,
          data: groupedEntries,
          getRowId: (group) => group.resolution,
          emptyMessage: "No quality definitions",
          flushExpanded: true,
          get expandedRows() {
            return expandedRows;
          },
          set expandedRows($$value) {
            expandedRows = $$value;
            $$settled = false;
          },
          $$slots: {
            cell: ($$renderer4, { row, column }) => {
              if (column.key === "label") {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`${escape_html(row.label)}`);
              } else if (column.key === "count") {
                $$renderer4.push("<!--[1-->");
                $$renderer4.push(`<span class="rounded-full bg-neutral-100 px-2 py-0.5 text-xs font-medium text-neutral-600 dark:bg-neutral-800 dark:text-neutral-400">${escape_html(row.entries.length)}</span>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]-->`);
            },
            expanded: ($$renderer4, { row }) => {
              {
                $$renderer4.push(`<div class="divide-y divide-neutral-200 dark:divide-neutral-700"><!--[-->`);
                const each_array_1 = ensure_array_like(row.entries);
                for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                  let entry = each_array_1[$$index_1];
                  const markers = markersMap[entry.quality_name] || createMarkers(entry);
                  $$renderer4.push(`<div class="flex flex-col gap-3 bg-white px-4 py-4 qd:flex-row qd:items-center qd:gap-3 qd:pt-5 qd:pr-4 qd:pb-8 qd:pl-8 dark:bg-neutral-900"><div class="text-sm font-medium text-neutral-900 qd:w-32 qd:shrink-0 dark:text-neutral-100">${escape_html(entry.quality_name)}</div> <div class="hidden min-w-0 flex-1 pt-4 pr-16 pl-2 qd:block">`);
                  RangeScale($$renderer4, {
                    orientation: "horizontal",
                    direction: "start",
                    min: 0,
                    max: baseScaleMax,
                    step: 1,
                    minSeparation: 5,
                    unit: selectedUnit.short,
                    unlimitedValue: baseScaleMax,
                    displayTransform: toDisplayUnit,
                    get markers() {
                      return markersMap[entry.quality_name];
                    },
                    set markers($$value) {
                      markersMap[entry.quality_name] = $$value;
                      $$settled = false;
                    }
                  });
                  $$renderer4.push(`<!----></div> <div class="flex gap-2 qd:contents"><div class="flex-1 qd:w-24 qd:flex-none qd:shrink-0"><div class="mb-1 flex items-center gap-1 text-xs font-medium text-blue-600 dark:text-blue-400">Min <span class="text-neutral-400 dark:text-neutral-500">(MB/m)</span></div> `);
                  NumberInput($$renderer4, {
                    id: `min-${stringify(entry.quality_name)}`,
                    name: `min-${stringify(entry.quality_name)}`,
                    min: 0,
                    max: markers[1].value,
                    step: 1,
                    responsive: true,
                    validateOn: "blur",
                    onchange: () => syncToEntry(entry.quality_name),
                    get value() {
                      return markers[0].value;
                    },
                    set value($$value) {
                      markers[0].value = $$value;
                      $$settled = false;
                    }
                  });
                  $$renderer4.push(`<!----></div> <div class="flex-1 qd:w-24 qd:flex-none qd:shrink-0"><div class="mb-1 flex items-center gap-1 text-xs font-medium text-green-600 dark:text-green-400">Pref <span class="text-neutral-400 dark:text-neutral-500">(MB/m)</span></div> `);
                  NumberInput($$renderer4, {
                    id: `preferred-${stringify(entry.quality_name)}`,
                    name: `preferred-${stringify(entry.quality_name)}`,
                    min: markers[0].value,
                    max: markers[2].value,
                    step: 1,
                    responsive: true,
                    validateOn: "blur",
                    onchange: () => syncToEntry(entry.quality_name),
                    get value() {
                      return markers[1].value;
                    },
                    set value($$value) {
                      markers[1].value = $$value;
                      $$settled = false;
                    }
                  });
                  $$renderer4.push(`<!----></div> <div class="flex-1 qd:w-24 qd:flex-none qd:shrink-0"><div class="mb-1 flex items-center gap-1 text-xs font-medium text-orange-600 dark:text-orange-400">Max <span class="text-neutral-400 dark:text-neutral-500">(MB/m)</span></div> `);
                  NumberInput($$renderer4, {
                    id: `max-${stringify(entry.quality_name)}`,
                    name: `max-${stringify(entry.quality_name)}`,
                    min: markers[1].value,
                    max: baseScaleMax,
                    step: 1,
                    responsive: true,
                    validateOn: "blur",
                    onchange: () => syncToEntry(entry.quality_name),
                    get value() {
                      return markers[2].value;
                    },
                    set value($$value) {
                      markers[2].value = $$value;
                      $$settled = false;
                    }
                  });
                  $$renderer4.push(`<!----></div></div></div>`);
                }
                $$renderer4.push(`<!--]--></div>`);
              }
            }
          }
        });
      }
      $$renderer3.push(`<!--]--></div> <form method="POST"${attr("action", actionUrl)} class="hidden"><input type="hidden" name="arrType"${attr("value", arrType)}/> <input type="hidden" name="name"${attr("value", configName)}/> <input type="hidden" name="entries"${attr("value", entriesForSubmit)}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/></form> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form method="POST" action="?/delete" class="hidden"><input type="hidden" name="layer"${attr("value", selectedLayer)}/></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      Modal($$renderer3, {
        open: showDeleteModal,
        header: `Delete ${arrLabel} quality definitions`,
        bodyMessage: "This will remove the quality definitions config and write a delete op. You can recreate it later if needed.",
        confirmText: "Delete",
        cancelText: "Cancel",
        confirmDanger: true,
        confirmDisabled: deleting,
        loading: deleting
      });
      $$renderer3.push(`<!----> `);
      SyncPromptModal($$renderer3, {
        redirectTo: pendingRedirectTo,
        affectedArrs: pendingAffectedArrs,
        entityType: "qualityDefinitions",
        databaseId,
        entityName: configName.trim(),
        get open() {
          return showSyncModal;
        },
        set open($$value) {
          showSyncModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      InfoModal($$renderer3, {
        header: "Quality Definitions",
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-3 text-sm text-neutral-700 dark:text-neutral-300"><p>Quality definitions control the acceptable file size range for each quality level. All values
			are stored in <strong>MB per minute</strong> of runtime.</p> <div class="space-y-1"><p><span class="font-medium text-blue-600 dark:text-blue-400">Min</span> \u2014 reject files smaller than
				this.</p> <p><span class="font-medium text-green-600 dark:text-green-400">Preferred</span> \u2014 ideal target size.
				Files closest to this are prioritized.</p> <p><span class="font-medium text-orange-600 dark:text-orange-400">Max</span> \u2014 reject files larger
				than this.</p></div> <p>The valid range is <strong>0\u2013${escape_html(baseScaleMax)}</strong> MB/min for ${escape_html(arrLabel)}. Setting preferred
			or max to ${escape_html(baseScaleMax)} means <strong>unlimited</strong> \u2014 no upper bound is enforced.</p></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      arrType,
      databaseName,
      canWriteToBase: canWriteToBase2,
      actionUrl,
      breadcrumbItems,
      breadcrumbCurrent,
      availableQualities,
      initialData
    });
  });
}
var init_QualityDefinitionsForm = __esm({
  "dist/build/server/chunks/QualityDefinitionsForm.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Dropdown();
    init_chevron_down();
    init_info();
    init_Button();
    init_save();
    init_trash_2();
    init_stores();
    init_store2();
    init_navigation();
    init_Modal();
    init_forms();
    init_DropdownItem();
    init_dirty();
    init_ExpandableTable();
    init_DropdownHeader();
    init_InfoModal();
    init_StickyCard();
    init_FormInput();
    init_NumberInput();
    init_SyncPromptModal();
    init_RangeScale();
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/new/_page.svelte.js
var page_svelte_exports51 = {};
__export(page_svelte_exports51, {
  default: () => _page51
});
function _page51($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let availableQualities;
    let data = $$props["data"];
    let selectedArrType = store_get($$store_subs ??= {}, "$page", page).url.searchParams.get("arrType");
    $: availableQualities = selectedArrType === "radarr" ? data.radarrQualities : data.sonarrQualities;
    PageMeta($$renderer2, { title: `${data.currentDatabase.name} \xB7 Quality Definition \xB7 New` });
    $$renderer2.push(`<!----> `);
    if (selectedArrType) {
      $$renderer2.push("<!--[0-->");
      QualityDefinitionsForm($$renderer2, {
        mode: "create",
        arrType: selectedArrType,
        databaseName: data.currentDatabase?.name,
        canWriteToBase: data.canWriteToBase,
        availableQualities,
        initialData: null
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte51 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/new/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_client4();
    init_stores();
    init_navigation();
    init_DirtyModal();
    init_PageMeta();
    init_QualityDefinitionsForm();
  }
});

// dist/build/server/nodes/61.js
var __exports62 = {};
__export(__exports62, {
  component: () => component58,
  fonts: () => fonts62,
  imports: () => imports62,
  index: () => index62,
  server: () => page_server_ts_exports54,
  server_id: () => server_id60,
  stylesheets: () => stylesheets62
});
var index62, component_cache58, component58, server_id60, imports62, stylesheets62, fonts62;
var init__62 = __esm({
  async "dist/build/server/nodes/61.js"() {
    "use strict";
    await init_page_server_ts54();
    index62 = 61;
    component58 = async () => component_cache58 ??= (await Promise.resolve().then(() => (init_page_svelte51(), page_svelte_exports51))).default;
    server_id60 = "src/routes/media-management/[databaseId]/quality-definitions/new/+page.server.ts";
    imports62 = ["_app/immutable/nodes/61.qxVUlkL8.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/BzUs4yJS2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/XMOYB6uZ2.js"];
    stylesheets62 = [];
    fonts62 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/radarr/_name_/_page.server.ts.js
var page_server_ts_exports55 = {};
__export(page_server_ts_exports55, {
  actions: () => actions35,
  load: () => load58
});
var load58, actions35;
var init_page_server_ts55 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/radarr/_name_/_page.server.ts.js"() {
    "use strict";
    await init_arrSync();
    await init_queueService();
    await init_quality_definitions();
    await init_update3();
    await init_affectedArrs();
    init_exports();
    load58 = async ({ params, parent }) => {
      const { databaseId, name } = params;
      if (!databaseId || !name) throw error(400, "Missing parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const qualityDefinitionsConfig = await getRadarrByName(cache3, decodeURIComponent(name));
      if (!qualityDefinitionsConfig) throw error(404, "Quality definitions config not found");
      return {
        qualityDefinitionsConfig,
        availableQualities: await getAvailableQualities(cache3, "radarr"),
        canWriteToBase: (await parent()).canWriteToBase
      };
    };
    actions35 = {
      update: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const decodedName = decodeURIComponent(name);
        const current3 = await getRadarrByName(cache3, decodedName);
        if (!current3) return fail(404, { error: "Quality definitions config not found" });
        const formData = await request.formData();
        const newName = formData.get("name");
        const layer = formData.get("layer") || "user";
        const entriesJson = formData.get("entries");
        if (!newName?.trim()) return fail(400, { error: "Name is required" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        let entries;
        try {
          entries = JSON.parse(entriesJson || "[]");
        } catch {
          return fail(400, { error: "Invalid entries data" });
        }
        let result;
        try {
          result = await updateRadarrQualityDefinitions({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            current: current3,
            input: {
              name: newName.trim(),
              entries
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update quality definitions config";
          if (message2.includes("already exists") || message2.toLowerCase().includes("duplicate")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update quality definitions config" });
        if (newName.trim() !== decodedName) arrSyncQueries.updateQualityDefinitionsConfigName(decodedName, newName.trim());
        const affectedArrs = getAffectedArrs({
          entityType: "qualityDefinitions",
          databaseId: currentDatabaseId,
          entityName: newName.trim()
        });
        return {
          success: true,
          redirectTo: `/media-management/${databaseId}/quality-definitions`,
          affectedArrs
        };
      },
      delete: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await getRadarrByName(cache3, decodeURIComponent(name));
        if (!current3) return fail(404, { error: "Quality definitions config not found" });
        const layer = (await request.formData()).get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await removeRadarrQualityDefinitions({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          current: current3
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete quality definitions config" });
        throw redirect(303, `/media-management/${databaseId}/quality-definitions`);
      }
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/radarr/_name_/_page.svelte.js
var page_svelte_exports52 = {};
__export(page_svelte_exports52, {
  default: () => _page52
});
function _page52($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: `${data.qualityDefinitionsConfig.name} \xB7 Radarr Quality Definition` });
    $$renderer2.push(`<!----> `);
    QualityDefinitionsForm($$renderer2, {
      mode: "edit",
      arrType: "radarr",
      databaseName: data.currentDatabase?.name,
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      availableQualities: data.availableQualities,
      initialData: data.qualityDefinitionsConfig,
      breadcrumbItems: [{
        label: data.currentDatabase.name,
        href: `/media-management/${data.currentDatabase.id}/quality-definitions`
      }],
      breadcrumbCurrent: data.qualityDefinitionsConfig.name
    });
    $$renderer2.push(`<!----> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte52 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/radarr/_name_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_DirtyModal();
    init_PageMeta();
    init_QualityDefinitionsForm();
  }
});

// dist/build/server/nodes/62.js
var __exports63 = {};
__export(__exports63, {
  component: () => component59,
  fonts: () => fonts63,
  imports: () => imports63,
  index: () => index63,
  server: () => page_server_ts_exports55,
  server_id: () => server_id61,
  stylesheets: () => stylesheets63
});
var index63, component_cache59, component59, server_id61, imports63, stylesheets63, fonts63;
var init__63 = __esm({
  async "dist/build/server/nodes/62.js"() {
    "use strict";
    await init_page_server_ts55();
    index63 = 62;
    component59 = async () => component_cache59 ??= (await Promise.resolve().then(() => (init_page_svelte52(), page_svelte_exports52))).default;
    server_id61 = "src/routes/media-management/[databaseId]/quality-definitions/radarr/[name]/+page.server.ts";
    imports63 = ["_app/immutable/nodes/62.BFU8YI9Z.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/BzUs4yJS2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/XMOYB6uZ2.js"];
    stylesheets63 = [];
    fonts63 = [];
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/sonarr/_name_/_page.server.ts.js
var page_server_ts_exports56 = {};
__export(page_server_ts_exports56, {
  actions: () => actions36,
  load: () => load59
});
var load59, actions36;
var init_page_server_ts56 = __esm({
  async "dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/sonarr/_name_/_page.server.ts.js"() {
    "use strict";
    await init_arrSync();
    await init_queueService();
    await init_quality_definitions();
    await init_update3();
    await init_affectedArrs();
    init_exports();
    load59 = async ({ params, parent }) => {
      const { databaseId, name } = params;
      if (!databaseId || !name) throw error(400, "Missing parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const qualityDefinitionsConfig = await getSonarrByName(cache3, decodeURIComponent(name));
      if (!qualityDefinitionsConfig) throw error(404, "Quality definitions config not found");
      return {
        qualityDefinitionsConfig,
        availableQualities: await getAvailableQualities(cache3, "sonarr"),
        canWriteToBase: (await parent()).canWriteToBase
      };
    };
    actions36 = {
      update: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const decodedName = decodeURIComponent(name);
        const current3 = await getSonarrByName(cache3, decodedName);
        if (!current3) return fail(404, { error: "Quality definitions config not found" });
        const formData = await request.formData();
        const newName = formData.get("name");
        const layer = formData.get("layer") || "user";
        const entriesJson = formData.get("entries");
        if (!newName?.trim()) return fail(400, { error: "Name is required" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        let entries;
        try {
          entries = JSON.parse(entriesJson || "[]");
        } catch {
          return fail(400, { error: "Invalid entries data" });
        }
        let result;
        try {
          result = await updateSonarrQualityDefinitions({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            current: current3,
            input: {
              name: newName.trim(),
              entries
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update quality definitions config";
          if (message2.includes("already exists") || message2.toLowerCase().includes("duplicate")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update quality definitions config" });
        if (newName.trim() !== decodedName) arrSyncQueries.updateQualityDefinitionsConfigName(decodedName, newName.trim());
        const affectedArrs = getAffectedArrs({
          entityType: "qualityDefinitions",
          databaseId: currentDatabaseId,
          entityName: newName.trim()
        });
        return {
          success: true,
          redirectTo: `/media-management/${databaseId}/quality-definitions`,
          affectedArrs
        };
      },
      delete: async ({ request, params }) => {
        const { databaseId, name } = params;
        if (!databaseId || !name) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await getSonarrByName(cache3, decodeURIComponent(name));
        if (!current3) return fail(404, { error: "Quality definitions config not found" });
        const layer = (await request.formData()).get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await removeSonarrQualityDefinitions({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          current: current3
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete quality definitions config" });
        throw redirect(303, `/media-management/${databaseId}/quality-definitions`);
      }
    };
  }
});

// dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/sonarr/_name_/_page.svelte.js
var page_svelte_exports53 = {};
__export(page_svelte_exports53, {
  default: () => _page53
});
function _page53($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: `${data.qualityDefinitionsConfig.name} \xB7 Sonarr Quality Definition` });
    $$renderer2.push(`<!----> `);
    QualityDefinitionsForm($$renderer2, {
      mode: "edit",
      arrType: "sonarr",
      databaseName: data.currentDatabase?.name,
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      availableQualities: data.availableQualities,
      initialData: data.qualityDefinitionsConfig,
      breadcrumbItems: [{
        label: data.currentDatabase.name,
        href: `/media-management/${data.currentDatabase.id}/quality-definitions`
      }],
      breadcrumbCurrent: data.qualityDefinitionsConfig.name
    });
    $$renderer2.push(`<!----> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte53 = __esm({
  "dist/build/server/entries/pages/media-management/_databaseId_/quality-definitions/sonarr/_name_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_DirtyModal();
    init_PageMeta();
    init_QualityDefinitionsForm();
  }
});

// dist/build/server/nodes/63.js
var __exports64 = {};
__export(__exports64, {
  component: () => component60,
  fonts: () => fonts64,
  imports: () => imports64,
  index: () => index64,
  server: () => page_server_ts_exports56,
  server_id: () => server_id62,
  stylesheets: () => stylesheets64
});
var index64, component_cache60, component60, server_id62, imports64, stylesheets64, fonts64;
var init__64 = __esm({
  async "dist/build/server/nodes/63.js"() {
    "use strict";
    await init_page_server_ts56();
    index64 = 63;
    component60 = async () => component_cache60 ??= (await Promise.resolve().then(() => (init_page_svelte53(), page_svelte_exports53))).default;
    server_id62 = "src/routes/media-management/[databaseId]/quality-definitions/sonarr/[name]/+page.server.ts";
    imports64 = ["_app/immutable/nodes/63.BfcK4iHt.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/BzUs4yJS2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/XMOYB6uZ2.js"];
    stylesheets64 = [];
    fonts64 = [];
  }
});

// dist/build/server/entries/pages/onboarding/_page.svelte.js
var page_svelte_exports54 = {};
__export(page_svelte_exports54, {
  default: () => _page54
});
function _page54($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let filteredIds, filteredGroups;
    const allStages = Object.entries(STAGES).map(([id, stage2]) => ({
      id,
      name: stage2.name,
      description: stage2.description,
      steps: stage2.steps.length
    }));
    const { search, filtered } = createDataPageStore(allStages, {
      storageKey: "onboardingView",
      searchKeys: ["name", "description"]
    });
    $: filteredIds = new Set(store_get($$store_subs ??= {}, "$filtered", filtered).map((s3) => s3.id));
    $: filteredGroups = GROUPS.map((group) => ({
      ...group,
      stages: group.stages.filter((id) => filteredIds.has(id))
    })).filter((group) => group.stages.length > 0);
    PageMeta($$renderer2, { title: "Onboarding" });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8"><div class="mb-8"><h1 class="text-2xl font-bold text-neutral-900 md:text-3xl dark:text-neutral-50">Onboarding</h1> <p class="mt-2 text-base text-neutral-600 md:mt-3 md:text-lg dark:text-neutral-400">Guided walkthroughs to help you get the most out of Profilarr. Run any stage at your own pace.</p></div> <div class="space-y-6">`);
    ActionsBar($$renderer2, {
      children: ($$renderer3) => {
        SearchAction($$renderer3, {
          searchStore: search,
          placeholder: "Search stages...",
          responsive: true
        });
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> <!--[-->`);
    const each_array = ensure_array_like(filteredGroups);
    for (let $$index_1 = 0, $$length = each_array.length; $$index_1 < $$length; $$index_1++) {
      let group = each_array[$$index_1];
      ExpandableCard($$renderer2, {
        title: group.name,
        description: group.description,
        children: ($$renderer3) => {
          $$renderer3.push(`<div class="divide-y divide-neutral-200 dark:divide-neutral-700/60"><!--[-->`);
          const each_array_1 = ensure_array_like(group.stages);
          for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
            let stageId = each_array_1[$$index];
            const stage2 = STAGES[stageId];
            if (stage2) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="flex items-center gap-4 px-6 py-4"><div class="min-w-0 flex-1"><div class="flex items-center gap-2"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(stage2.name)}</h3> `);
              Label($$renderer3, {
                variant: "secondary",
                size: "sm",
                rounded: "md",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(stage2.steps.length)}
											${escape_html(stage2.steps.length === 1 ? "step" : "steps")}`);
                },
                $$slots: { default: true }
              });
              $$renderer3.push(`<!----></div> <p class="mt-1 text-xs text-neutral-600 dark:text-neutral-400">${escape_html(stage2.description)}</p></div> `);
              Button($$renderer3, {
                text: "Start",
                icon: Play,
                iconColor: "text-accent-600 dark:text-accent-400",
                size: "sm"
              });
              $$renderer3.push(`<!----></div>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]-->`);
          }
          $$renderer3.push(`<!--]--></div>`);
        },
        $$slots: { default: true }
      });
    }
    $$renderer2.push(`<!--]--></div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
  });
}
var init_page_svelte54 = __esm({
  "dist/build/server/entries/pages/onboarding/_page.svelte.js"() {
    "use strict";
    init_server();
    init_Button();
    init_play();
    init_search();
    init_store();
    init_store2();
    init_Label();
    init_ActionsBar();
    init_PageMeta();
    init_dataPage();
    init_ExpandableCard();
  }
});

// dist/build/server/nodes/64.js
var __exports65 = {};
__export(__exports65, {
  component: () => component61,
  fonts: () => fonts65,
  imports: () => imports65,
  index: () => index65,
  stylesheets: () => stylesheets65
});
var index65, component_cache61, component61, imports65, stylesheets65, fonts65;
var init__65 = __esm({
  "dist/build/server/nodes/64.js"() {
    "use strict";
    index65 = 64;
    component61 = async () => component_cache61 ??= (await Promise.resolve().then(() => (init_page_svelte54(), page_svelte_exports54))).default;
    imports65 = ["_app/immutable/nodes/64.WESrRw43.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BlAgBW4v.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/CNiXNkto2.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/Cf96lmLi2.js", "_app/immutable/chunks/_ZYKMtmp.js"];
    stylesheets65 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css"];
    fonts65 = [];
  }
});

// dist/build/server/entries/pages/quality-profiles/_page.server.ts.js
var page_server_ts_exports57 = {};
__export(page_server_ts_exports57, {
  load: () => load60
});
var load60;
var init_page_server_ts57 = __esm({
  async "dist/build/server/entries/pages/quality-profiles/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_lastDatabase();
    load60 = ({ cookies }) => {
      redirectToLastDatabase(cookies, "last_db_qp", "/quality-profiles");
      return { databases: pcdManager.getAllPublic() };
    };
  }
});

// dist/build/server/entries/pages/quality-profiles/_page.svelte.js
var page_svelte_exports55 = {};
__export(page_svelte_exports55, {
  default: () => _page55
});
function _page55($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: "Quality Profiles" });
    $$renderer2.push(`<!----> `);
    if (data.databases.length === 0) {
      $$renderer2.push("<!--[0-->");
      EmptyState($$renderer2, {
        icon: Database2,
        title: "No Databases Linked",
        description: "Link a Profilarr Compliant Database to manage quality profiles.",
        buttonText: "Link Database",
        buttonHref: "/databases/new",
        buttonIcon: Plus
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte55 = __esm({
  "dist/build/server/entries/pages/quality-profiles/_page.svelte.js"() {
    "use strict";
    init_server();
    init_database2();
    init_plus();
    init_PageMeta();
    init_EmptyState();
  }
});

// dist/build/server/nodes/65.js
var __exports66 = {};
__export(__exports66, {
  component: () => component62,
  fonts: () => fonts66,
  imports: () => imports66,
  index: () => index66,
  server: () => page_server_ts_exports57,
  server_id: () => server_id63,
  stylesheets: () => stylesheets66
});
var index66, component_cache62, component62, server_id63, imports66, stylesheets66, fonts66;
var init__66 = __esm({
  async "dist/build/server/nodes/65.js"() {
    "use strict";
    await init_page_server_ts57();
    index66 = 65;
    component62 = async () => component_cache62 ??= (await Promise.resolve().then(() => (init_page_svelte55(), page_svelte_exports55))).default;
    server_id63 = "src/routes/quality-profiles/+page.server.ts";
    imports66 = ["_app/immutable/nodes/65.Bd0eXCKG.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D_awjkBZ.js", "_app/immutable/chunks/B66v-P2b.js"];
    stylesheets66 = [];
    fonts66 = [];
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/_page.server.ts.js
var page_server_ts_exports58 = {};
__export(page_server_ts_exports58, {
  load: () => load61
});
var load61;
var init_page_server_ts58 = __esm({
  async "dist/build/server/entries/pages/quality-profiles/_databaseId_/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_lastDatabase();
    init_exports();
    load61 = async ({ params, cookies }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const databases = pcdManager.getAllPublic();
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = databases.find((db2) => db2.id === currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      setLastDatabase(cookies, "last_db_qp", currentDatabaseId);
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      return {
        databases,
        currentDatabase,
        qualityProfiles: await list2(cache3),
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
  }
});

// dist/build/server/chunks/earth.js
function Earth($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "earth" },
    props,
    { iconNode: [
      ["path", { "d": "M21.54 15H17a2 2 0 0 0-2 2v4.54" }],
      ["path", { "d": "M7 3.34V5a3 3 0 0 0 3 3a2 2 0 0 1 2 2c0 1.1.9 2 2 2a2 2 0 0 0 2-2c0-1.1.9-2 2-2h3.17" }],
      ["path", { "d": "M11 21.95V18a2 2 0 0 0-2-2a2 2 0 0 1-2-2v-1a2 2 0 0 0-2-2H2.05" }],
      ["circle", {
        "cx": "12",
        "cy": "12",
        "r": "10"
      }]
    ] }
  ]));
}
var init_earth = __esm({
  "dist/build/server/chunks/earth.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/_page.svelte.js
var page_svelte_exports56 = {};
__export(page_svelte_exports56, {
  default: () => _page56
});
function Book_open_text($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "book-open-text" },
    props,
    { iconNode: [
      ["path", { "d": "M12 5v16" }],
      ["path", { "d": "M16 13h2" }],
      ["path", { "d": "M16 9h2" }],
      ["path", { "d": "M20.001 19A2 2 0 0022 17V5a2 2 0 00-1.999-2L16 3.002A5 5 0 0012 5a5 5 0 00-4-2H4a2 2 0 00-2 2v12a2 2 0 001.999 2H8a5 5 0 014 2 5 5 0 014-2z" }],
      ["path", { "d": "M6 13h2" }],
      ["path", { "d": "M6 9h2" }]
    ] }
  ]));
}
function Gauge($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "gauge" },
    props,
    { iconNode: [["path", { "d": "m12 14 4-4" }], ["path", { "d": "M3.34 19a10 10 0 1 1 17.32 0" }]] }
  ]));
}
function TableView8($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let profiles = $$props["profiles"];
    let databaseId = $$props["databaseId"];
    createEventDispatcher();
    function getRowHref(row) {
      return `/quality-profiles/${databaseId}/${row.id}/general`;
    }
    const qualitySecondary = "inline-flex items-center leading-none font-medium font-mono px-2.5 py-1 text-xs rounded-md bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300";
    const qualitySuccess = "inline-flex items-center leading-none font-medium font-mono px-2.5 py-1 text-xs rounded-md bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200";
    const labelSecondary = "inline-flex items-center leading-none font-medium font-mono px-2 py-1 text-[10px] rounded-md bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300";
    const labelSecondaryNoMono = "inline-flex items-center leading-none font-medium px-2 py-1 text-[10px] rounded-md bg-neutral-100 text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300";
    Table2($$renderer2, {
      data: profiles,
      columns: [
        {
          key: "name",
          header: "Name",
          headerIcon: Tag,
          align: "left",
          sortable: true,
          cell: (row) => ({ html: `
					<div>
						<div class="font-medium">${escapeHtml(row.name)}</div>
						${row.tags.length > 0 ? `
							<div class="mt-1 flex flex-wrap gap-1">
								${row.tags.map((tag2) => `
									<span class="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-medium bg-accent-100 text-accent-800 dark:bg-accent-900 dark:text-accent-200">
										${escapeHtml(tag2.name)}
									</span>
								`).join("")}
							</div>
						` : ""}
					</div>
				` })
        },
        {
          key: "description",
          header: "Description",
          headerIcon: File_text,
          align: "left",
          cell: (row) => ({ html: row.description ? sanitizeHtml(row.description) : '<span class="text-neutral-400">No description</span>' })
        },
        {
          key: "qualities",
          header: "Qualities",
          headerIcon: Layers,
          align: "left",
          width: "w-48",
          cell: (row) => {
            return { html: `
						<div class="flex flex-wrap gap-1 py-1">
							${row.qualities.map((q2) => `
								<span class="${q2.is_upgrade_until ? qualitySuccess : qualitySecondary}">${escapeHtml(q2.name)}</span>
							`).join("")}
						</div>
					` };
          }
        },
        {
          key: "custom_formats",
          header: "Custom Formats",
          headerIcon: Book_open_text,
          align: "left",
          width: "w-48",
          cell: (row) => ({ html: `
					<div class="text-xs space-y-1">
						<div class="flex items-center gap-1.5">All: <span class="${labelSecondary}">${row.custom_formats.all}</span></div>
						<div class="flex items-center gap-1.5">Radarr: <span class="${labelSecondary}">${row.custom_formats.radarr}</span></div>
						<div class="flex items-center gap-1.5">Sonarr: <span class="${labelSecondary}">${row.custom_formats.sonarr}</span></div>
					</div>
				` })
        },
        {
          key: "scores",
          header: "Scores",
          headerIcon: Gauge,
          align: "left",
          width: "w-52",
          cell: (row) => ({ html: `
					<div class="text-xs space-y-1">
						<div class="flex items-center gap-1.5">Minimum: <span class="${labelSecondary}">${row.minimum_custom_format_score}</span></div>
						${row.upgrades_allowed ? `
							<div class="flex items-center gap-1.5">Upgrade Until: <span class="${labelSecondary}">${row.upgrade_until_score}</span></div>
							<div class="flex items-center gap-1.5">Increment: <span class="${labelSecondary}">${row.upgrade_score_increment}</span></div>
						` : `
							<div class="text-neutral-500 dark:text-neutral-400">No Upgrades</div>
						`}
					</div>
				` })
        },
        {
          key: "language",
          header: "Language",
          headerIcon: Earth,
          align: "left",
          width: "w-40",
          cell: (row) => {
            return { html: `<span class="${labelSecondaryNoMono}">${row.language ? row.language.name === "Original" ? "Any" : escapeHtml(row.language.name) : "Any"}</span>` };
          }
        }
      ],
      emptyMessage: "No quality profiles found",
      hoverable: true,
      compact: false,
      rowHref: getRowHref,
      pageSize: 50,
      $$slots: { actions: ($$renderer3, { row }) => {
        $$renderer3.push(`<div class="flex items-center justify-end gap-0.5">`);
        if (FEATURES.importExport) {
          $$renderer3.push("<!--[0-->");
          Button($$renderer3, {
            icon: Download,
            size: "xs",
            variant: "ghost",
            tooltip: "Export"
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        Button($$renderer3, {
          icon: Copy,
          size: "xs",
          variant: "secondary",
          tooltip: "Clone"
        });
        $$renderer3.push(`<!----></div>`);
      } }
    });
    bind_props($$props, {
      profiles,
      databaseId
    });
  });
}
function CardView8($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let qualityLimit, visibleProfiles;
    let profiles = $$props["profiles"];
    let databaseId = $$props["databaseId"];
    createEventDispatcher();
    const { visibleCount, sentinel, reset: reset2, setTotalCount } = createProgressiveList({ pageSize: 30 });
    $: qualityLimit = 5;
    $: setTotalCount(profiles.length);
    $: reset2();
    $: visibleProfiles = profiles.slice(0, store_get($$store_subs ??= {}, "$visibleCount", visibleCount));
    CardGrid($$renderer2, {
      flush: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(visibleProfiles);
        for (let $$index_2 = 0, $$length = each_array.length; $$index_2 < $$length; $$index_2++) {
          let profile = each_array[$$index_2];
          const visibleQualities = profile.qualities.slice(0, qualityLimit);
          const hiddenCount = Math.max(0, profile.qualities.length - qualityLimit);
          Card($$renderer3, {
            href: `/quality-profiles/${stringify(databaseId)}/${stringify(profile.id)}/general`,
            hoverable: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="flex flex-1 flex-col gap-3">`);
              if (profile.tags.length > 0) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
                const each_array_1 = ensure_array_like(profile.tags);
                for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
                  let tag2 = each_array_1[$$index];
                  Label($$renderer4, {
                    variant: "info",
                    size: "sm",
                    rounded: "md",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->${escape_html(tag2.name)}`);
                    },
                    $$slots: { default: true }
                  });
                }
                $$renderer4.push(`<!--]--></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> `);
              if (profile.description) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="description text-xs text-neutral-600 dark:text-neutral-400 svelte-f4ox4y">${html(sanitizeHtml(profile.description))}</div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> <div class="mt-auto flex flex-wrap items-center gap-1"><!--[-->`);
              const each_array_2 = ensure_array_like(visibleQualities);
              for (let idx = 0, $$length2 = each_array_2.length; idx < $$length2; idx++) {
                let quality = each_array_2[idx];
                if (idx > 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<span class="text-xs text-neutral-400">\u203A</span>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                Label($$renderer4, {
                  variant: quality.is_upgrade_until ? "success" : "secondary",
                  size: "sm",
                  rounded: "md",
                  mono: true,
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->${escape_html(quality.name)}`);
                  },
                  $$slots: { default: true }
                });
                $$renderer4.push(`<!---->`);
              }
              $$renderer4.push(`<!--]--> `);
              if (hiddenCount > 0) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<span class="text-xs text-neutral-400">\u203A</span> `);
                Label($$renderer4, {
                  variant: "secondary",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->+${escape_html(hiddenCount)} more`);
                  },
                  $$slots: { default: true }
                });
                $$renderer4.push(`<!---->`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></div></div>`);
            },
            $$slots: {
              default: true,
              header: ($$renderer4) => {
                $$renderer4.push(`<div class="flex items-end justify-between gap-2"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(profile.name)}</h3> <div class="flex shrink-0 items-center gap-0.5">`);
                if (FEATURES.importExport) {
                  $$renderer4.push("<!--[0-->");
                  Button($$renderer4, {
                    icon: Download,
                    size: "xs",
                    variant: "ghost",
                    tooltip: "Export"
                  });
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                Button($$renderer4, {
                  icon: Copy,
                  size: "xs",
                  variant: "ghost",
                  tooltip: "Clone"
                });
                $$renderer4.push(`<!----></div></div>`);
              },
              footer: ($$renderer4) => {
                $$renderer4.push(`<div class="flex items-center gap-3 text-xs"><div class="flex items-center gap-1">`);
                Book_open_text($$renderer4, {
                  size: 12,
                  class: "text-neutral-400"
                });
                $$renderer4.push(`<!----> `);
                Label($$renderer4, {
                  variant: "secondary",
                  size: "sm",
                  rounded: "md",
                  mono: true,
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->${escape_html(profile.custom_formats.total)}`);
                  },
                  $$slots: { default: true }
                });
                $$renderer4.push(`<!----></div> <div class="flex items-center gap-1">`);
                Gauge($$renderer4, {
                  size: 12,
                  class: "text-neutral-400"
                });
                $$renderer4.push(`<!----> `);
                Label($$renderer4, {
                  variant: "secondary",
                  size: "sm",
                  rounded: "md",
                  mono: true,
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->${escape_html(profile.minimum_custom_format_score)}`);
                  },
                  $$slots: { default: true }
                });
                $$renderer4.push(`<!----></div> <div class="flex items-center gap-1">`);
                Earth($$renderer4, {
                  size: 12,
                  class: "text-neutral-400"
                });
                $$renderer4.push(`<!----> `);
                Label($$renderer4, {
                  variant: "secondary",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->${escape_html(profile.language ? profile.language.name : "Any")}`);
                  },
                  $$slots: { default: true }
                });
                $$renderer4.push(`<!----></div></div>`);
              }
            }
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> <div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      profiles,
      databaseId
    });
  });
}
function _page56($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let simpleSearchStore, simpleQuery, useSimpleMode, filtered, tabs;
    let data = $$props["data"];
    let cloneModalOpen = false;
    let cloneSourceName = "";
    let filterTags = [];
    const fields = [
      {
        key: "all",
        label: "All",
        description: "Name, tags, description, language and qualities",
        type: "text",
        accessor: qualityProfileSearchValues
      },
      {
        key: "name",
        label: "Name",
        description: "Quality profile name",
        type: "text",
        isDefault: true,
        accessor: (item) => item.name,
        suggestions: (items) => items.map((i) => i.name).sort()
      },
      {
        key: "tag",
        label: "Tag",
        description: "Assigned tag names",
        type: "text",
        accessor: (item) => item.tags.map((t2) => t2.name),
        suggestions: (items) => [...new Set(items.flatMap((i) => i.tags.map((t2) => t2.name)))].sort()
      },
      {
        key: "tagged",
        label: "Tagged",
        description: "Whether any tags are assigned",
        type: "text",
        accessor: (item) => item.tags.length > 0 ? "yes" : "no",
        suggestions: () => ["yes", "no"]
      },
      {
        key: "description",
        label: "Description",
        description: "Quality profile description",
        type: "text",
        accessor: (item) => item.description ?? null
      },
      {
        key: "language",
        label: "Language",
        description: "Configured profile language",
        type: "text",
        accessor: qualityProfileLanguageLabel,
        suggestions: (items) => [...new Set(items.map(qualityProfileLanguageLabel))].sort()
      },
      {
        key: "upgrades",
        label: "Upgrades",
        description: "Whether upgrades are allowed",
        type: "text",
        accessor: (item) => item.upgrades_allowed ? "yes" : "no",
        suggestions: () => ["yes", "no"]
      },
      {
        key: "formats",
        label: "Formats",
        description: "Number of scored custom formats",
        type: "number",
        accessor: (item) => item.custom_formats.total
      }
    ];
    onDestroy(() => {
    });
    const viewMode = createViewModeStore({ storageKey: "qualityProfilesView" });
    $: simpleSearchStore = getPersistentSearchStore(`qpSearch:${data.currentDatabase.id}`, { debounceMs: 150 });
    $: simpleQuery = store_get($$store_subs ??= {}, "$simpleSearchStore", simpleSearchStore).query;
    $: useSimpleMode = store_get($$store_subs ??= {}, "$filterMode", filterMode) === "simple";
    $: filtered = (() => {
      if (useSimpleMode) {
        if (!simpleQuery) return data.qualityProfiles;
        const q2 = simpleQuery.toLowerCase();
        return data.qualityProfiles.filter((p2) => p2.name.toLowerCase().includes(q2));
      }
      return applySmartFilters(data.qualityProfiles, filterTags, fields);
    })();
    $: tabs = data.databases.map((db2) => ({
      label: db2.name,
      href: `/quality-profiles/${db2.id}`,
      active: db2.id === data.currentDatabase.id
    }));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.currentDatabase.name} \xB7 Quality Profiles` });
      $$renderer3.push(`<!----> <div class="space-y-6 px-4 pb-8 md:px-8">`);
      Tabs($$renderer3, {
        tabs,
        responsive: true
      });
      $$renderer3.push(`<!----> `);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          if (useSimpleMode) {
            $$renderer4.push("<!--[0-->");
            SearchAction($$renderer4, {
              searchStore: simpleSearchStore,
              placeholder: "Search quality profiles...",
              responsive: true
            });
          } else {
            $$renderer4.push("<!--[-1-->");
            SmartFilterBar($$renderer4, {
              fields,
              items: data.qualityProfiles,
              storageKey: `smartFilter:qualityProfiles:${data.currentDatabase.id}`,
              placeholder: "Filter quality profiles...",
              get tags() {
                return filterTags;
              },
              set tags($$value) {
                filterTags = $$value;
                $$settled = false;
              }
            });
          }
          $$renderer4.push(`<!--]--> `);
          Tooltip($$renderer4, {
            text: "New",
            children: ($$renderer5) => {
              ActionButton($$renderer5, { icon: Plus });
            },
            $$slots: { default: true }
          });
          $$renderer4.push(`<!----> `);
          $$renderer4.push("<!--[0-->");
          FilterModeToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$filterMode", filterMode);
            },
            set value($$value) {
              store_set(filterMode, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!--]--> `);
          ViewToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$viewMode", viewMode);
            },
            set value($$value) {
              store_set(viewMode, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> <div class="mt-6">`);
      if (data.qualityProfiles.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No quality profiles found for ${escape_html(data.currentDatabase?.name)}</p></div>`);
      } else if (filtered.length === 0) {
        $$renderer3.push("<!--[1-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No quality profiles match the current filters</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$viewMode", viewMode) === "table") {
        $$renderer3.push("<!--[2-->");
        TableView8($$renderer3, {
          profiles: filtered,
          databaseId: data.currentDatabase.id
        });
      } else {
        $$renderer3.push("<!--[-1-->");
        CardView8($$renderer3, {
          profiles: filtered,
          databaseId: data.currentDatabase.id
        });
      }
      $$renderer3.push(`<!--]--></div></div> `);
      CloneModal($$renderer3, {
        databaseId: data.currentDatabase.id,
        entityType: "quality_profile",
        sourceName: cloneSourceName,
        existingNames: data.qualityProfiles.map((p2) => p2.name),
        canWriteToBase: data.canWriteToBase,
        get open() {
          return cloneModalOpen;
        },
        set open($$value) {
          cloneModalOpen = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte56 = __esm({
  "dist/build/server/entries/pages/quality-profiles/_databaseId_/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_features();
    init_sanitize();
    init_Icon();
    init_copy();
    init_download();
    init_earth();
    init_file_text();
    init_layers();
    init_Button();
    init_plus();
    init_search();
    init_filterMode();
    init_ViewToggle();
    init_tag();
    init_store2();
    init_Label();
    init_Card();
    init_navigation();
    init_Tabs();
    init_progressiveList();
    init_ActionsBar();
    init_ActionButton();
    init_PageMeta();
    init_Table();
    init_CardGrid();
    init_dataPage();
    init_CloneModal();
    init_entitySearch();
  }
});

// dist/build/server/nodes/66.js
var __exports67 = {};
__export(__exports67, {
  component: () => component63,
  fonts: () => fonts67,
  imports: () => imports67,
  index: () => index67,
  server: () => page_server_ts_exports58,
  server_id: () => server_id64,
  stylesheets: () => stylesheets67
});
var index67, component_cache63, component63, server_id64, imports67, stylesheets67, fonts67;
var init__67 = __esm({
  async "dist/build/server/nodes/66.js"() {
    "use strict";
    await init_page_server_ts58();
    index67 = 66;
    component63 = async () => component_cache63 ??= (await Promise.resolve().then(() => (init_page_svelte56(), page_svelte_exports56))).default;
    server_id64 = "src/routes/quality-profiles/[databaseId]/+page.server.ts";
    imports67 = ["_app/immutable/nodes/66.CzCC2FSv.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/D7OHFWTL2.js", "_app/immutable/chunks/CkDZnQpg2.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/DYf5Ixhg.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/C_LFCSMn.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/MJc6__n-.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/Cut3gr1-.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DxZIQ_tr2.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/DYe9q02k2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/VZQaB9P52.js"];
    stylesheets67 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/filterMode.DdGl7mkT.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css", "_app/immutable/assets/66.D39ru4nl.css"];
    fonts67 = [];
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/general/_page.server.ts.js
var page_server_ts_exports59 = {};
__export(page_server_ts_exports59, {
  actions: () => actions37,
  load: () => load62
});
var load62, actions37;
var init_page_server_ts59 = __esm({
  async "dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/general/_page.server.ts.js"() {
    "use strict";
    await init_arrSync();
    await init_queueService();
    init_mappings();
    init_read();
    await init_affectedArrs();
    init_exports();
    load62 = async ({ params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) throw error(400, "Missing required parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const profileId = parseInt(id, 10);
      if (isNaN(profileId)) throw error(400, "Invalid profile ID");
      const currentDatabase = pcdManager.getByIdPublic(currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const profile = await general(cache3, profileId);
      if (!profile) throw error(404, "Quality profile not found");
      return {
        currentDatabase,
        profile,
        availableLanguages: getRadarrLanguages(),
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions37 = {
      update: async ({ request, params }) => {
        const { databaseId, id } = params;
        if (!databaseId || !id) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        const profileId = parseInt(id, 10);
        if (isNaN(currentDatabaseId) || isNaN(profileId)) return fail(400, { error: "Invalid parameters" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await general(cache3, profileId);
        if (!current3) return fail(404, { error: "Quality profile not found" });
        const formData = await request.formData();
        const name = formData.get("name");
        const description = formData.get("description") || "";
        const tagsJson = formData.get("tags");
        const languageRaw = formData.get("language");
        const language = languageRaw && languageRaw.trim() !== "" ? languageRaw.trim() : null;
        const layer = formData.get("layer") || "user";
        if (!name?.trim()) return fail(400, { error: "Name is required" });
        let tags = [];
        try {
          tags = JSON.parse(tagsJson || "[]");
        } catch {
          return fail(400, { error: "Invalid tags format" });
        }
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        let result;
        try {
          result = await updateGeneral2({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            current: current3,
            input: {
              name: name.trim(),
              description: description.trim(),
              tags,
              language
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update quality profile";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update quality profile" });
        if (name.trim() !== current3.name) arrSyncQueries.updateQualityProfileName(current3.name, name.trim());
        const affectedArrs = getAffectedArrs({
          entityType: "qualityProfile",
          databaseId: currentDatabaseId,
          entityName: name.trim()
        });
        return {
          success: true,
          redirectTo: `/quality-profiles/${databaseId}/${id}/general`,
          affectedArrs
        };
      },
      delete: async ({ request, params }) => {
        const { databaseId, id } = params;
        if (!databaseId || !id) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        const profileId = parseInt(id, 10);
        if (isNaN(currentDatabaseId) || isNaN(profileId)) return fail(400, { error: "Invalid parameters" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await general(cache3, profileId);
        if (!current3) return fail(404, { error: "Quality profile not found" });
        const layer = (await request.formData()).get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await remove({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          profileId,
          profileName: current3.name
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete quality profile" });
        throw redirect(303, `/quality-profiles/${databaseId}`);
      }
    };
  }
});

// dist/build/server/chunks/GeneralForm2.js
function GeneralForm2($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, title, description_, submitButtonText, name, tags, description, selectedLanguageName, languageOptions, isValid;
    let mode = $$props["mode"];
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let actionUrl = fallback($$props["actionUrl"], "");
    let initialData = $$props["initialData"];
    let availableLanguages = fallback($$props["availableLanguages"], () => [], true);
    let onCancel = fallback($$props["onCancel"], void 0);
    const defaults = {
      name: "",
      tags: [],
      description: "",
      language: null
    };
    if (mode === "create") initCreate(initialData ?? defaults);
    else initEdit(initialData);
    let deleting = false;
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    let deleteLayer = canWriteToBase2 ? "base" : "user";
    let showDeleteConfirmModal = false;
    let showSyncModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    $: store_get($$store_subs ??= {}, "$current", current2);
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: title = mode === "create" ? "New Quality Profile" : "General";
    $: description_ = mode === "create" ? `After saving, you'll be able to configure qualities, scoring, and languages.` : `Update quality profile settings`;
    $: submitButtonText = mode === "create" ? "Create" : "Save";
    $: name = store_get($$store_subs ??= {}, "$current", current2).name ?? "";
    $: tags = store_get($$store_subs ??= {}, "$current", current2).tags ?? [];
    $: description = store_get($$store_subs ??= {}, "$current", current2).description ?? "";
    $: selectedLanguageName = store_get($$store_subs ??= {}, "$current", current2).language ?? null;
    $: languageOptions = availableLanguages.map((lang) => ({
      value: lang.name,
      label: lang.name
    }));
    $: isValid = name.trim() !== "";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="space-y-6">`);
      StickyCard($$renderer3, {
        position: "top",
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<h1 class="text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h1> <p class="text-neutral-600 dark:text-neutral-400">${escape_html(description_)}</p>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div class="flex items-center gap-2">`);
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                disabled: deleting,
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                text: "Delete"
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            if (onCancel) {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, { text: "Cancel" });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            Button($$renderer4, {
              disabled: !isValid || !store_get($$store_subs ??= {}, "$isDirty", isDirty),
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              text: submitButtonText
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <form method="POST"${attr("action", actionUrl)} class="md:px-4"><input type="hidden" name="description"${attr("value", description)}/> <input type="hidden" name="tags"${attr("value", JSON.stringify(tags))}/> <input type="hidden" name="language"${attr("value", selectedLanguageName ?? "")}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/> <div class="space-y-6"><div data-onboarding="qp-general-name">`);
      FormInput($$renderer3, {
        label: "Name",
        name: "name",
        value: name,
        required: true,
        description: "The name of this quality profile",
        placeholder: "Enter quality profile name"
      });
      $$renderer3.push(`<!----></div> <div data-onboarding="qp-general-description">`);
      MarkdownInput($$renderer3, {
        id: "description",
        label: "Description",
        description: "Add any notes or details about this profile's purpose and configuration.",
        value: description,
        onchange: (v3) => update3("description", v3)
      });
      $$renderer3.push(`<!----></div> <div class="space-y-2" data-onboarding="qp-general-tags"><div class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Tags</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Add tags to organize and categorize this quality profile.</p> `);
      TagInput($$renderer3, {
        tags,
        onchange: (newTags) => update3("tags", newTags)
      });
      $$renderer3.push(`<!----></div> `);
      if (availableLanguages.length > 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="space-y-2" data-onboarding="qp-general-language"><div class="space-y-1"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">Language</div> <p class="text-xs text-neutral-600 dark:text-neutral-400">Set the preferred language for this profile. Leave empty for "Any". Radarr only.
							Sonarr uses custom formats for language filtering.</p></div> `);
        DropdownCombobox($$renderer3, {
          fullWidth: true,
          minWidth: "0",
          dropdownWidth: "100%",
          limit: 6,
          placeholder: "Search for a language...",
          options: languageOptions,
          value: selectedLanguageName
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div></form> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form method="POST" action="?/delete" class="hidden"><input type="hidden" name="layer"${attr("value", deleteLayer)}/></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        Modal($$renderer3, {
          open: showDeleteConfirmModal,
          header: "Delete Quality Profile",
          bodyMessage: `Are you sure you want to delete "${name}"? This action cannot be undone.`,
          confirmText: "Delete",
          cancelText: "Cancel",
          confirmDanger: true
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      SyncPromptModal($$renderer3, {
        redirectTo: pendingRedirectTo,
        affectedArrs: pendingAffectedArrs,
        databaseId,
        entityName: name.trim(),
        get open() {
          return showSyncModal;
        },
        set open($$value) {
          showSyncModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      canWriteToBase: canWriteToBase2,
      actionUrl,
      initialData,
      availableLanguages,
      onCancel
    });
  });
}
var init_GeneralForm2 = __esm({
  "dist/build/server/chunks/GeneralForm2.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_MarkdownInput();
    init_Button();
    init_save();
    init_trash_2();
    init_stores();
    init_store2();
    init_navigation();
    init_Modal();
    init_forms();
    init_dirty();
    init_StickyCard();
    init_FormInput();
    init_DropdownCombobox();
    init_TagInput();
    init_SyncPromptModal();
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/general/_page.svelte.js
var page_svelte_exports57 = {};
__export(page_svelte_exports57, {
  default: () => _page57
});
function _page57($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let initialData;
    let data = $$props["data"];
    $: initialData = {
      name: data.profile.name,
      tags: data.profile.tags.map((t2) => t2.name),
      description: data.profile.description ?? "",
      language: data.profile.language ?? null
    };
    PageMeta($$renderer2, { title: `${data.profile.name} \xB7 General` });
    $$renderer2.push(`<!----> <div class="mt-6">`);
    GeneralForm2($$renderer2, {
      mode: "edit",
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      initialData,
      availableLanguages: data.availableLanguages
    });
    $$renderer2.push(`<!----></div>`);
    bind_props($$props, { data });
  });
}
var init_page_svelte57 = __esm({
  "dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/general/_page.svelte.js"() {
    "use strict";
    init_server();
    init_PageMeta();
    init_GeneralForm2();
  }
});

// dist/build/server/nodes/67.js
var __exports68 = {};
__export(__exports68, {
  component: () => component64,
  fonts: () => fonts68,
  imports: () => imports68,
  index: () => index68,
  server: () => page_server_ts_exports59,
  server_id: () => server_id65,
  stylesheets: () => stylesheets68
});
var index68, component_cache64, component64, server_id65, imports68, stylesheets68, fonts68;
var init__68 = __esm({
  async "dist/build/server/nodes/67.js"() {
    "use strict";
    await init_page_server_ts59();
    index68 = 67;
    component64 = async () => component_cache64 ??= (await Promise.resolve().then(() => (init_page_svelte57(), page_svelte_exports57))).default;
    server_id65 = "src/routes/quality-profiles/[databaseId]/[id]/general/+page.server.ts";
    imports68 = ["_app/immutable/nodes/67.DBzG55Wq.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/BW8V51c72.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/CK2yQf0C.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js"];
    stylesheets68 = [];
    fonts68 = [];
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/qualities/_page.server.ts.js
var page_server_ts_exports60 = {};
__export(page_server_ts_exports60, {
  actions: () => actions38,
  load: () => load63
});
function hasBlockedGroupMembershipChanges(currentItems, nextItems) {
  const currentGroups = new Map(currentItems.filter((item) => item.type === "group").map((item) => [item.name, (item.members ?? []).map((member) => member.name)]));
  const nextGroups = new Map(nextItems.filter((item) => item.type === "group").map((item) => [item.name, (item.members ?? []).map((member) => member.name)]));
  for (const [name, nextMembers] of nextGroups) {
    const currentMembers = currentGroups.get(name);
    if (!currentMembers) return true;
    if (currentMembers.length !== nextMembers.length) return true;
    if (currentMembers.some((member, index88) => member !== nextMembers[index88])) return true;
  }
  return false;
}
var load63, actions38;
var init_page_server_ts60 = __esm({
  async "dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/qualities/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_markdown();
    await init_affectedArrs();
    init_exports();
    load63 = async ({ params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) throw error(400, "Missing required parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const profileId = parseInt(id, 10);
      if (isNaN(profileId)) throw error(400, "Invalid profile ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const profile = await cache3.kb.selectFrom("quality_profiles").select("name").where("id", "=", profileId).executeTakeFirst();
      if (!profile) throw error(404, "Quality profile not found");
      const qualitiesData = await qualities(cache3, currentDatabaseId, profile.name);
      const canEditGroupMembers = hasQualityGroupMembersPositionInCache(cache3);
      return {
        qualities: qualitiesData,
        profileName: profile.name,
        canWriteToBase: canWriteToBase(currentDatabaseId),
        canEditGroupMembers
      };
    };
    actions38 = { update: async ({ request, params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) return fail(400, { error: "Missing required parameters" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
      const profileId = parseInt(id, 10);
      if (isNaN(profileId)) return fail(400, { error: "Invalid profile ID" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const layer = formData.get("layer") || "user";
      const orderedItemsJson = formData.get("orderedItems");
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      let orderedItems = [];
      try {
        orderedItems = JSON.parse(orderedItemsJson || "[]");
      } catch {
        return fail(400, { error: "Invalid ordered items format" });
      }
      if (orderedItems.filter((item) => item.upgradeUntil).length > 1) return fail(400, { error: 'Only one quality can be marked as "upgrade until"' });
      const profile = await cache3.kb.selectFrom("quality_profiles").select("name").where("id", "=", profileId).executeTakeFirst();
      if (!profile) return fail(404, { error: "Quality profile not found" });
      if (!hasQualityGroupMembersPositionInCache(cache3)) {
        if (hasBlockedGroupMembershipChanges((await qualities(cache3, currentDatabaseId, profile.name)).orderedItems, orderedItems)) return fail(400, { error: "This database uses an older schema. Update the schema dependency before editing quality group members." });
      }
      let result;
      try {
        result = await updateQualities({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          profileName: profile.name,
          input: { orderedItems }
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to update qualities";
        if (message2.toLowerCase().includes("upgrade until")) return fail(400, { error: message2 });
        return fail(500, { error: message2 });
      }
      if (!result.success) return fail(500, { error: result.error || "Failed to update qualities" });
      const affectedArrs = getAffectedArrs({
        entityType: "qualityProfile",
        databaseId: currentDatabaseId,
        entityName: profile.name
      });
      return {
        success: true,
        redirectTo: `/quality-profiles/${databaseId}/${id}/qualities`,
        affectedArrs
      };
    } };
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/qualities/_page.svelte.js
var page_svelte_exports58 = {};
__export(page_svelte_exports58, {
  default: () => _page58
});
function GroupModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let open = fallback($$props["open"], false);
    let title = fallback($$props["title"], "Create Group");
    let confirmText = fallback($$props["confirmText"], "Create Group");
    let confirmDisabled = fallback($$props["confirmDisabled"], false);
    let description = fallback($$props["description"], "Select at least two qualities to combine into a group. Groups share the same priority.");
    let groupName = fallback($$props["groupName"], "");
    let items = fallback($$props["items"], () => [], true);
    let selectedNames = fallback($$props["selectedNames"], () => /* @__PURE__ */ new Set(), true);
    let size = fallback($$props["size"], "lg");
    let height = fallback($$props["height"], "xl");
    const dispatch = createEventDispatcher();
    function handleReorder(nextItems) {
      dispatch("reorder", { items: nextItems });
    }
    let draggedItem = null;
    let lastTargetIndex = null;
    let pointerStartPoint = null;
    let pointerDidDrag = false;
    onDestroy(() => {
      if (typeof document !== "undefined") {
        document.removeEventListener("pointermove", handlePointerMove);
        document.removeEventListener("pointerup", handlePointerUp);
        document.body.classList.remove("dragging");
      }
    });
    function getTargetFromPoint(x3, y2) {
      const card = document.elementFromPoint(x3, y2)?.closest("[data-group-modal-index]");
      if (!card) return null;
      const index88 = parseInt(card.dataset.groupModalIndex ?? "", 10);
      if (isNaN(index88) || index88 < 0 || index88 >= items.length) return null;
      return {
        item: items[index88],
        index: index88
      };
    }
    function handlePointerDown(e, item, index88) {
      e.preventDefault();
      e.stopPropagation();
      document.body.classList.add("dragging");
      draggedItem = {
        item,
        index: index88
      };
      lastTargetIndex = index88;
      pointerStartPoint = {
        x: e.clientX,
        y: e.clientY
      };
      pointerDidDrag = false;
      document.addEventListener("pointermove", handlePointerMove);
      document.addEventListener("pointerup", handlePointerUp);
    }
    function handlePointerMove(e) {
      if (!draggedItem) return;
      if (pointerStartPoint) {
        const dx = Math.abs(e.clientX - pointerStartPoint.x);
        const dy = Math.abs(e.clientY - pointerStartPoint.y);
        if (dx > 4 || dy > 4) pointerDidDrag = true;
      }
      const target = getTargetFromPoint(e.clientX, e.clientY);
      if (!target || target.index === draggedItem.index) return;
      if (lastTargetIndex === target.index) return;
      lastTargetIndex = target.index;
      const nextItems = [...items];
      const sourceIndex = draggedItem.index;
      const [movedItem] = nextItems.splice(sourceIndex, 1);
      nextItems.splice(target.index, 0, movedItem);
      handleReorder(nextItems);
      draggedItem.index = target.index;
    }
    function handlePointerUp() {
      if (pointerDidDrag) Date.now() + 200;
      resetDragState();
    }
    function resetDragState() {
      draggedItem = null;
      lastTargetIndex = null;
      pointerStartPoint = null;
      pointerDidDrag = false;
      document.removeEventListener("pointermove", handlePointerMove);
      document.removeEventListener("pointerup", handlePointerUp);
      document.body.classList.remove("dragging");
    }
    Modal($$renderer2, {
      open,
      header: title,
      confirmText,
      cancelText: "Cancel",
      confirmDisabled,
      size,
      height,
      $$slots: { body: ($$renderer3) => {
        $$renderer3.push(`<div slot="body" class="flex h-full flex-col gap-4"><p class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p> `);
        FormInput($$renderer3, {
          label: "Group Name",
          name: "quality-group-name",
          placeholder: "e.g. Web + Bluray",
          required: true,
          value: groupName
        });
        $$renderer3.push(`<!----> `);
        if (items.length >= 2) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="px-1 text-xs text-neutral-500 dark:text-neutral-400">${escape_html("Drag to reorder selected members before saving the group.")}</div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> <div class="min-h-0 flex-1 scrollbar-gutter-stable overflow-y-auto pr-2">`);
        if (items.length < 2) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="px-3 py-2 text-sm text-neutral-500 dark:text-neutral-400">At least two qualities are required for a group.</div>`);
        } else {
          $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<div class="space-y-2 pb-1"><!--[-->`);
          const each_array = ensure_array_like(items);
          for (let index88 = 0, $$length = each_array.length; index88 < $$length; index88++) {
            let item = each_array[index88];
            DraggableCard($$renderer3, {
              isDragging: draggedItem?.index === index88,
              onDragHandlePointerDown: (e) => handlePointerDown(e, item, index88),
              "data-group-modal-index": index88,
              "data-group-modal-name": item.name,
              "data-group-modal-selected": selectedNames.has(item.name) ? "true" : "false",
              className: "cursor-pointer transition-colors hover:bg-neutral-100 dark:hover:bg-neutral-800",
              contentClass: "px-3 py-2.5",
              role: "button",
              tabindex: "0",
              children: ($$renderer4) => {
                $$renderer4.push(`<div class="flex min-w-0 flex-1 items-center justify-between gap-2.5"><div class="min-w-0 flex-1 text-left"><div class="truncate text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(item.name)}</div></div> <div class="flex items-center gap-2">`);
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                IconCheckbox($$renderer4, {
                  checked: selectedNames.has(item.name),
                  icon: Check,
                  color: "blue",
                  shape: "circle"
                });
                $$renderer4.push(`<!----></div></div>`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer3.push(`<!--]--></div>`);
        }
        $$renderer3.push(`<!--]--></div></div>`);
      } }
    });
    bind_props($$props, {
      open,
      title,
      confirmText,
      confirmDisabled,
      description,
      groupName,
      items,
      selectedNames,
      size,
      height
    });
  });
}
function _page58($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, initialData, mainBucket, hasEnabledItems, groupNameValid, canSaveGroup, groupModalTitle, groupModalConfirmText, groupModalDescription;
    let data = $$props["data"];
    let showSyncModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    let showInfoModal = false;
    function buildInitialData(qualities2) {
      return { orderedItems: structuredClone(qualities2.orderedItems) };
    }
    function buildMergedOrderedItems(qualities2) {
      const orderedItems = structuredClone(qualities2.orderedItems);
      const additional = qualities2.availableQualities.map((quality, index88) => ({
        type: "quality",
        name: quality.name,
        position: orderedItems.length + index88,
        enabled: false,
        upgradeUntil: false
      }));
      const merged = [...orderedItems, ...additional];
      merged.forEach((item, index88) => {
        item.position = index88;
      });
      return merged;
    }
    let lastAutoMergeKey = "";
    let lastQualitiesRef = null;
    let selectedLayer = data.canWriteToBase ? "base" : "user";
    let draggedQualityFromMain = null;
    let lastTargetIndex = null;
    let hoverTargetIndex = null;
    let willCreateGroup = false;
    let willAddToGroup = false;
    let groupingMode = false;
    let showGroupModal = false;
    let groupModalMode = "create";
    let groupNameInput = "";
    let selectedGroupNames = /* @__PURE__ */ new Set();
    let groupModalItems = [];
    let lastRouteStateKey = "";
    onDestroy(() => {
      if (typeof document !== "undefined") {
        document.removeEventListener("pointermove", handlePointerMove);
        document.removeEventListener("pointerup", handlePointerUp);
      }
    });
    function updateMainBucket(newBucket) {
      update3("orderedItems", newBucket);
    }
    function getTargetFromPoint(x3, y2) {
      const card = document.elementFromPoint(x3, y2)?.closest("[data-quality-index]");
      if (!card) return null;
      const idx = parseInt(card.dataset.qualityIndex, 10);
      if (isNaN(idx) || idx < 0 || idx >= mainBucket.length) return null;
      return {
        item: mainBucket[idx],
        index: idx
      };
    }
    function handlePointerDown(e, item, index88) {
      e.preventDefault();
      document.body.classList.add("dragging");
      draggedQualityFromMain = {
        item,
        index: index88
      };
      document.addEventListener("pointermove", handlePointerMove);
      document.addEventListener("pointerup", handlePointerUp);
    }
    function handlePointerMove(e) {
      if (!draggedQualityFromMain) return;
      const target = getTargetFromPoint(e.clientX, e.clientY);
      if (!target || target.index === draggedQualityFromMain.index) {
        hoverTargetIndex = null;
        willCreateGroup = false;
        willAddToGroup = false;
        return;
      }
      const draggedItem = draggedQualityFromMain.item;
      const isGroupingMode = data.canEditGroupMembers && (e.ctrlKey || e.metaKey || groupingMode);
      hoverTargetIndex = target.index;
      if (isGroupingMode && draggedItem.type === "quality") if (target.item.type === "quality") {
        willCreateGroup = true;
        willAddToGroup = false;
      } else if (target.item.type === "group") {
        willCreateGroup = false;
        willAddToGroup = true;
      } else {
        willCreateGroup = false;
        willAddToGroup = false;
      }
      else {
        willCreateGroup = false;
        willAddToGroup = false;
        if (lastTargetIndex === target.index) return;
        lastTargetIndex = target.index;
        const newBucket = [...mainBucket];
        const sourceIndex = draggedQualityFromMain.index;
        const [movedItem] = newBucket.splice(sourceIndex, 1);
        newBucket.splice(target.index, 0, movedItem);
        newBucket.forEach((item, index88) => {
          item.position = index88;
        });
        updateMainBucket(newBucket);
        draggedQualityFromMain.index = target.index;
      }
    }
    function handlePointerUp(e) {
      if (!draggedQualityFromMain) {
        resetDragState();
        return;
      }
      const target = getTargetFromPoint(e.clientX, e.clientY);
      if (target && target.index !== draggedQualityFromMain.index) {
        const draggedItem = draggedQualityFromMain.item;
        const sourceIndex = draggedQualityFromMain.index;
        if (data.canEditGroupMembers && (e.ctrlKey || e.metaKey || groupingMode) && draggedItem.type === "quality") {
          if (target.item.type === "quality") {
            const newGroup = {
              type: "group",
              name: `${draggedItem.name} + ${target.item.name}`,
              position: target.index,
              enabled: true,
              upgradeUntil: draggedItem.upgradeUntil || target.item.upgradeUntil,
              members: [{ name: draggedItem.name }, { name: target.item.name }]
            };
            const newBucket = [...mainBucket];
            [sourceIndex, target.index].sort((a2, b3) => b3 - a2).forEach((idx) => newBucket.splice(idx, 1));
            const insertPos = Math.min(sourceIndex, target.index);
            newBucket.splice(insertPos, 0, newGroup);
            newBucket.forEach((item, index88) => {
              item.position = index88;
            });
            updateMainBucket(newBucket);
          } else if (target.item.type === "group") {
            const newBucket = [...mainBucket];
            const targetGroup = { ...newBucket[target.index] };
            if (!targetGroup.members) targetGroup.members = [];
            targetGroup.members = [...targetGroup.members, { name: draggedItem.name }];
            newBucket[target.index] = targetGroup;
            newBucket.splice(sourceIndex, 1);
            newBucket.forEach((item, index88) => {
              item.position = index88;
            });
            updateMainBucket(newBucket);
          }
        }
      }
      resetDragState();
    }
    function resetDragState() {
      draggedQualityFromMain = null;
      lastTargetIndex = null;
      hoverTargetIndex = null;
      willCreateGroup = false;
      willAddToGroup = false;
      document.removeEventListener("pointermove", handlePointerMove);
      document.removeEventListener("pointerup", handlePointerUp);
      document.body.classList.remove("dragging");
    }
    function closeGroupModal() {
      showGroupModal = false;
      groupModalMode = "create";
      groupNameInput = "";
      selectedGroupNames = /* @__PURE__ */ new Set();
      groupModalItems = [];
    }
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: initialData = buildInitialData(data.qualities);
    $: initEdit(initialData);
    $: if (data.qualities) {
      if (data.qualities !== lastQualitiesRef) {
        lastAutoMergeKey = "";
        lastQualitiesRef = data.qualities;
      }
      const availableNames = data.qualities.availableQualities.map((q2) => q2.name).join("|");
      if (availableNames && availableNames !== lastAutoMergeKey) update3("orderedItems", buildMergedOrderedItems(data.qualities));
      lastAutoMergeKey = availableNames;
    }
    $: mainBucket = store_get($$store_subs ??= {}, "$current", current2).orderedItems ?? [];
    $: hasEnabledItems = mainBucket.some((item) => item.enabled);
    $: {
      const routeStateKey = `${store_get($$store_subs ??= {}, "$page", page).url.pathname}:${data.canEditGroupMembers ? 1 : 0}`;
      if (routeStateKey !== lastRouteStateKey) {
        lastRouteStateKey = routeStateKey;
        if (draggedQualityFromMain) resetDragState();
        showGroupModal = false;
        groupModalMode = "create";
        groupNameInput = "";
        selectedGroupNames = /* @__PURE__ */ new Set();
        groupModalItems = [];
        hoverTargetIndex = null;
        willCreateGroup = false;
        willAddToGroup = false;
        groupingMode = false;
      }
    }
    $: groupNameValid = groupNameInput.trim().length > 0;
    $: canSaveGroup = selectedGroupNames.size >= 2 && groupNameValid;
    $: groupModalTitle = groupModalMode === "edit" ? "Edit Group" : "Create Group";
    $: groupModalConfirmText = groupModalMode === "edit" ? "Save Group" : "Create Group";
    $: groupModalDescription = groupModalMode === "edit" ? "Select at least two qualities for this group. Groups share the same priority." : "Select at least two qualities to combine into a group. Groups share the same priority.";
    $: if (!data.canEditGroupMembers && showGroupModal) closeGroupModal();
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.profileName} \xB7 Qualities` });
      $$renderer3.push(`<!----> <!---->`);
      {
        StickyCard($$renderer3, {
          position: "top",
          $$slots: {
            left: ($$renderer4) => {
              $$renderer4.push(`<h1 class="text-neutral-900 dark:text-neutral-50">Qualities</h1> <p class="text-neutral-600 dark:text-neutral-400">Configure ordering, grouping, and upgrade behavior.</p>`);
            },
            right: ($$renderer4) => {
              $$renderer4.push(`<div class="flex items-center gap-2">`);
              Button($$renderer4, {
                text: "Info",
                icon: Info,
                iconColor: "text-blue-600 dark:text-blue-400"
              });
              $$renderer4.push(`<!----> <span data-onboarding="qp-qualities-group-button">`);
              Button($$renderer4, {
                text: "Create Group",
                icon: Layers,
                iconColor: "text-accent-600 dark:text-accent-400",
                disabled: !data.canEditGroupMembers,
                tooltip: !data.canEditGroupMembers ? "Update the linked schema dependency to edit quality group members." : ""
              });
              $$renderer4.push(`<!----></span> `);
              Button($$renderer4, {
                disabled: !store_get($$store_subs ??= {}, "$isDirty", isDirty) || !hasEnabledItems,
                icon: Save,
                iconColor: "text-blue-600 dark:text-blue-400",
                text: "Save"
              });
              $$renderer4.push(`<!----></div>`);
            }
          }
        });
        $$renderer3.push(`<!----> `);
        if (!data.canEditGroupMembers) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="mt-4 px-4 text-sm text-amber-700 dark:text-amber-300"><div class="flex items-start gap-2">`);
          Triangle_alert($$renderer3, {
            size: 16,
            class: "mt-0.5 shrink-0"
          });
          $$renderer3.push(`<!----> <p>This database uses an older schema. Quality group members can be viewed, but creating or
					editing groups is disabled until the schema dependency is updated.</p></div></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> <form method="POST" action="?/update" class="hidden"><input type="hidden" name="orderedItems"${attr("value", JSON.stringify(mainBucket))}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/></form> <div class="mt-6 space-y-6 md:px-4"><div class="space-y-4"><!--[-->`);
        const each_array = ensure_array_like(mainBucket);
        for (let index88 = 0, $$length = each_array.length; index88 < $$length; index88++) {
          let item = each_array[index88];
          DraggableCard($$renderer3, {
            isDragging: draggedQualityFromMain?.index === index88,
            onDragHandlePointerDown: (e) => handlePointerDown(e, item, index88),
            "data-quality-index": index88,
            "data-onboarding": index88 === 0 ? "qp-qualities-card" : void 0,
            dragHandleOnboarding: index88 === 0 ? "qp-qualities-drag" : void 0,
            className: "cursor-pointer",
            role: "button",
            tabindex: "0",
            children: ($$renderer4) => {
              if (hoverTargetIndex === index88 && willCreateGroup) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="pointer-events-none absolute inset-0 rounded-lg border-2 border-dashed border-green-500 bg-green-50/30 dark:border-green-400 dark:bg-green-950/30"></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> `);
              if (hoverTargetIndex === index88 && willAddToGroup) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="pointer-events-none absolute inset-0 rounded-lg border-2 border-dashed border-accent-500 bg-accent-50/30 dark:border-accent-400 dark:bg-accent-950/30"></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> <div class="relative flex items-center justify-between"><div class="flex-1"><div class="font-medium text-neutral-900 dark:text-neutral-100">${escape_html(item.name)}</div> `);
              if (item.type === "group" && item.members) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="mt-1 hidden flex-wrap gap-1 md:flex"><!--[-->`);
                const each_array_1 = ensure_array_like(item.members);
                for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
                  let member = each_array_1[$$index];
                  Label($$renderer4, {
                    customVariant: "bg-white text-neutral-700 shadow-sm dark:bg-neutral-900 dark:text-neutral-300 dark:shadow-black/10",
                    size: "sm",
                    rounded: "md",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->${escape_html(member.name)}`);
                    },
                    $$slots: { default: true }
                  });
                }
                $$renderer4.push(`<!--]--></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></div> <div class="flex items-center gap-3"><div class="flex items-center gap-1 md:hidden">`);
              if (item.type === "group") {
                $$renderer4.push("<!--[0-->");
                Button($$renderer4, {
                  icon: X2,
                  size: "xs",
                  title: "Collapse group into individual qualities"
                });
                $$renderer4.push(`<!----> `);
                Button($$renderer4, {
                  icon: Pencil,
                  size: "xs",
                  disabled: !data.canEditGroupMembers,
                  tooltip: !data.canEditGroupMembers ? "Update the linked schema dependency to edit quality group members." : "",
                  title: "Edit group"
                });
                $$renderer4.push(`<!---->`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> `);
              Button($$renderer4, {
                icon: Chevron_up,
                size: "xs",
                disabled: index88 === 0
              });
              $$renderer4.push(`<!----> `);
              Button($$renderer4, {
                icon: Chevron_down,
                size: "xs",
                disabled: index88 === mainBucket.length - 1
              });
              $$renderer4.push(`<!----></div> `);
              if (hoverTargetIndex === index88 && willCreateGroup) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="text-xs font-medium text-green-600 dark:text-green-400">Create Group</div>`);
              } else if (hoverTargetIndex === index88 && willAddToGroup) {
                $$renderer4.push("<!--[1-->");
                $$renderer4.push(`<div class="text-xs font-medium text-accent-600 dark:text-accent-400">Add to Group</div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> `);
              if (item.type === "group") {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<span class="hidden md:inline-flex">`);
                Button($$renderer4, {
                  icon: X2,
                  size: "xs",
                  title: "Collapse group into individual qualities"
                });
                $$renderer4.push(`<!----></span> <span class="hidden md:inline-flex">`);
                Button($$renderer4, {
                  icon: Pencil,
                  size: "xs",
                  disabled: !data.canEditGroupMembers,
                  tooltip: !data.canEditGroupMembers ? "Update the linked schema dependency to edit quality group members." : "",
                  title: "Edit group"
                });
                $$renderer4.push(`<!----></span>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> <span${attr("data-onboarding", index88 === 0 ? "qp-qualities-upgrade-until" : void 0)}>`);
              IconCheckbox($$renderer4, {
                checked: item.upgradeUntil,
                icon: Arrow_up,
                color: "#07CA07",
                shape: "circle",
                stopPropagation: true
              });
              $$renderer4.push(`<!----></span> <span${attr("data-onboarding", index88 === 0 ? "qp-qualities-enabled" : void 0)}>`);
              IconCheckbox($$renderer4, {
                checked: item.enabled,
                icon: Check,
                color: "blue",
                shape: "circle",
                stopPropagation: true
              });
              $$renderer4.push(`<!----></span></div></div> `);
              if (item.type === "group" && item.members) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="mt-3 flex flex-wrap gap-1 md:hidden"><!--[-->`);
                const each_array_2 = ensure_array_like(item.members);
                for (let $$index_1 = 0, $$length2 = each_array_2.length; $$index_1 < $$length2; $$index_1++) {
                  let member = each_array_2[$$index_1];
                  Label($$renderer4, {
                    customVariant: "bg-white text-neutral-700 shadow-sm dark:bg-neutral-900 dark:text-neutral-300 dark:shadow-black/10",
                    size: "sm",
                    rounded: "md",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->${escape_html(member.name)}`);
                    },
                    $$slots: { default: true }
                  });
                }
                $$renderer4.push(`<!--]--></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]-->`);
            },
            $$slots: { default: true }
          });
        }
        $$renderer3.push(`<!--]--> <div class="h-[30px]"></div></div></div> `);
        InfoModal($$renderer3, {
          header: "Qualities",
          get open() {
            return showInfoModal;
          },
          set open($$value) {
            showInfoModal = $$value;
            $$settled = false;
          },
          children: ($$renderer4) => {
            $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">Qualities</div> <div class="mt-1">Define the order, grouping, and configuration of qualities. In previous versions, only
					enabled qualities were tracked. The new system stores all qualities (enabled and disabled)
					to maintain proper ordering across your entire quality profile. Missing qualities are
					automatically appended as disabled.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Reordering</div> <div class="mt-1">Drag and drop qualities to change their priority. Higher positions indicate higher
					preference. The order determines which quality will be selected when multiple options are
					available.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Creating Groups</div> <div class="mt-1">On desktop, hold Ctrl (or Cmd on Mac) while dragging a quality onto another quality to
					create a group. Groups allow multiple qualities to be treated as equal priority. You can
					also drag a quality onto an existing group to add it to that group. On mobile, use the
					Create Group button in the header.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Group Names</div> <div class="mt-1">Click on a group name to edit it. Groups automatically get a default name when created,
					but you can customize this to better describe the qualities it contains.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Collapsing Groups</div> <div class="mt-1">Click the X button on a group to break it apart into individual qualities. The qualities
					will maintain their enabled state and position.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Enabled/Disabled</div> <div class="mt-1">The blue checkbox indicates whether a quality is enabled. Click anywhere on the quality
					row or the checkbox itself to toggle. Disabled qualities are still tracked for ordering
					purposes but won't be used for downloads.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Upgrade Until</div> <div class="mt-1">The green arrow checkbox marks a quality as the "upgrade until" threshold. Only one
					quality can have this flag at a time. When a file reaches this quality level, the system
					will stop looking for upgrades. This quality must be enabled.</div></div></div>`);
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----> `);
        GroupModal($$renderer3, {
          open: showGroupModal,
          title: groupModalTitle,
          confirmText: groupModalConfirmText,
          confirmDisabled: !canSaveGroup,
          description: groupModalDescription,
          items: groupModalItems,
          selectedNames: selectedGroupNames,
          get groupName() {
            return groupNameInput;
          },
          set groupName($$value) {
            groupNameInput = $$value;
            $$settled = false;
          }
        });
        $$renderer3.push(`<!----> `);
        SyncPromptModal($$renderer3, {
          redirectTo: pendingRedirectTo,
          affectedArrs: pendingAffectedArrs,
          databaseId,
          entityName: data.profileName,
          get open() {
            return showSyncModal;
          },
          set open($$value) {
            showSyncModal = $$value;
            $$settled = false;
          }
        });
        $$renderer3.push(`<!---->`);
      }
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte58 = __esm({
  "dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/qualities/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_arrow_up();
    init_check();
    init_chevron_down();
    init_chevron_up();
    init_info();
    init_layers();
    init_Button();
    init_pencil();
    init_save();
    init_triangle_alert();
    init_x();
    init_stores();
    init_store2();
    init_Label();
    init_navigation();
    init_Modal();
    init_forms();
    init_IconCheckbox();
    init_dirty();
    init_InfoModal();
    init_PageMeta();
    init_StickyCard();
    init_FormInput();
    init_DraggableCard();
    init_SyncPromptModal();
  }
});

// dist/build/server/nodes/68.js
var __exports69 = {};
__export(__exports69, {
  component: () => component65,
  fonts: () => fonts69,
  imports: () => imports69,
  index: () => index69,
  server: () => page_server_ts_exports60,
  server_id: () => server_id66,
  stylesheets: () => stylesheets69
});
var index69, component_cache65, component65, server_id66, imports69, stylesheets69, fonts69;
var init__69 = __esm({
  async "dist/build/server/nodes/68.js"() {
    "use strict";
    await init_page_server_ts60();
    index69 = 68;
    component65 = async () => component_cache65 ??= (await Promise.resolve().then(() => (init_page_svelte58(), page_svelte_exports58))).default;
    server_id66 = "src/routes/quality-profiles/[databaseId]/[id]/qualities/+page.server.ts";
    imports69 = ["_app/immutable/nodes/68.LKaNYCIt.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DYf5Ixhg.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/B_FOzVLA.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/Ks-0Do1f.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js"];
    stylesheets69 = ["_app/immutable/assets/68.B9CsPOBo.css"];
    fonts69 = [];
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/scoring/_page.server.ts.js
var page_server_ts_exports61 = {};
__export(page_server_ts_exports61, {
  actions: () => actions39,
  load: () => load64
});
var load64, actions39;
var init_page_server_ts61 = __esm({
  async "dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/scoring/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_affectedArrs();
    init_exports();
    load64 = async ({ params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) throw error(400, "Missing required parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const profileId = parseInt(id, 10);
      if (isNaN(profileId)) throw error(400, "Invalid profile ID");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const profile = await cache3.kb.selectFrom("quality_profiles").select("name").where("id", "=", profileId).executeTakeFirst();
      if (!profile) throw error(404, "Quality profile not found");
      return {
        scoring: await scoring(cache3, currentDatabaseId, profile.name),
        profileName: profile.name,
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions39 = { update: async ({ request, params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) return fail(400, { error: "Missing required parameters" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
      const profileId = parseInt(id, 10);
      if (isNaN(profileId)) return fail(400, { error: "Invalid profile ID" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const upgradesAllowed = formData.get("upgradesAllowed") !== "false";
      const minimumScore = parseInt(formData.get("minimumScore"), 10) || 0;
      const upgradeUntilScore = parseInt(formData.get("upgradeUntilScore"), 10) || 0;
      const upgradeScoreIncrement = parseInt(formData.get("upgradeScoreIncrement"), 10) || 1;
      const layer = formData.get("layer") || "user";
      const customFormatScoresJson = formData.get("customFormatScores");
      if (upgradeScoreIncrement < 1) return fail(400, { error: "Upgrade score increment must be at least 1" });
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      let customFormatScores = [];
      try {
        customFormatScores = JSON.parse(customFormatScoresJson || "[]");
      } catch {
        return fail(400, { error: "Invalid custom format scores format" });
      }
      const profile = await cache3.kb.selectFrom("quality_profiles").select("name").where("id", "=", profileId).executeTakeFirst();
      if (!profile) return fail(404, { error: "Quality profile not found" });
      let result;
      try {
        result = await updateScoring({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          profileName: profile.name,
          input: {
            upgradesAllowed,
            minimumScore,
            upgradeUntilScore,
            upgradeScoreIncrement,
            customFormatScores
          }
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to update scoring";
        if (message2.toLowerCase().includes("upgrade score increment")) return fail(400, { error: message2 });
        return fail(500, { error: message2 });
      }
      if (!result.success) return fail(500, { error: result.error || "Failed to update scoring" });
      const affectedArrs = getAffectedArrs({
        entityType: "qualityProfile",
        databaseId: currentDatabaseId,
        entityName: profile.name
      });
      return {
        success: true,
        redirectTo: `/quality-profiles/${databaseId}/${id}/scoring`,
        affectedArrs
      };
    } };
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/scoring/_page.svelte.js
var page_svelte_exports59 = {};
__export(page_svelte_exports59, {
  default: () => _page59
});
function User($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "user" },
    props,
    { iconNode: [["path", { "d": "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" }], ["circle", {
      "cx": "12",
      "cy": "7",
      "r": "4"
    }]] }
  ]));
}
function CustomGroupManager($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let customGroups = fallback($$props["customGroups"], () => [], true);
    let selectedGroups = $$props["selectedGroups"];
    let onAdd = $$props["onAdd"];
    let onDelete = $$props["onDelete"];
    let onToggle = $$props["onToggle"];
    let newGroupName = "";
    let newGroupTags = "";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="border-t border-neutral-200 px-4 py-3 dark:border-neutral-700"><div class="mb-2 text-xs font-medium text-neutral-700 dark:text-neutral-300">Add Custom Group</div> <form class="space-y-2">`);
      FormInput($$renderer3, {
        label: "Group name",
        name: "groupName",
        placeholder: "Group name",
        hideLabel: true,
        size: "sm",
        get value() {
          return newGroupName;
        },
        set value($$value) {
          newGroupName = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      FormInput($$renderer3, {
        label: "Tags",
        name: "groupTags",
        placeholder: "Tags (comma-separated)",
        hideLabel: true,
        size: "sm",
        get value() {
          return newGroupTags;
        },
        set value($$value) {
          newGroupTags = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      Button($$renderer3, {
        type: "submit",
        text: "Add Group",
        icon: Plus,
        variant: "primary",
        size: "xs",
        fullWidth: true,
        disabled: !newGroupName || !newGroupTags
      });
      $$renderer3.push(`<!----></form></div> `);
      if (customGroups.length > 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="border-t border-neutral-200 dark:border-neutral-700"><!--[-->`);
        const each_array = ensure_array_like(customGroups);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let group = each_array[$$index];
          $$renderer3.push(`<div class="group flex items-center justify-between gap-2 px-4 py-2 transition-colors hover:bg-neutral-100 dark:hover:bg-neutral-700"><button type="button" class="flex flex-1 items-center justify-between gap-3"><div class="flex-1 text-left"><div class="text-xs font-medium text-neutral-700 dark:text-neutral-300">${escape_html(group.name)}</div> <div class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(group.tags.join(", "))}</div></div> `);
          IconCheckbox($$renderer3, {
            checked: selectedGroups.has(group.key),
            icon: Check,
            color: "blue",
            shape: "circle"
          });
          $$renderer3.push(`<!----></button> <button type="button" class="flex h-5 w-5 items-center justify-center rounded text-neutral-400 transition-colors hover:bg-red-100 hover:text-red-600 dark:hover:bg-red-900/30 dark:hover:text-red-400">`);
          X2($$renderer3, { size: 12 });
          $$renderer3.push(`<!----></button></div>`);
        }
        $$renderer3.push(`<!--]--></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]-->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      customGroups,
      selectedGroups,
      onAdd,
      onDelete,
      onToggle
    });
  });
}
function ScoringTableDesktop($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let columns;
    let databaseId = $$props["databaseId"];
    let formats = $$props["formats"];
    let arrTypes = $$props["arrTypes"];
    let customFormatScores = $$props["customFormatScores"];
    let customFormatEnabled = $$props["customFormatEnabled"];
    let disabled = fallback($$props["disabled"], false);
    let getArrTypeColor = $$props["getArrTypeColor"];
    let firstRowOnboarding = fallback($$props["firstRowOnboarding"], void 0);
    const dispatch = createEventDispatcher();
    const rowClass = () => "transition-colors hover:bg-neutral-50 dark:hover:bg-neutral-900";
    function rowAttributes(_3, i) {
      return i === 0 && firstRowOnboarding ? { "data-onboarding": firstRowOnboarding } : {};
    }
    function handleScoreChange(formatName, arrType, score) {
      if (disabled) return;
      dispatch("scoreChange", {
        formatName,
        arrType,
        score
      });
    }
    $: columns = ((activeArrTypes) => [{
      key: "name",
      header: "Custom Format",
      tdClass: "sticky left-0 z-[1] bg-white font-medium dark:bg-neutral-900"
    }, ...activeArrTypes.map((arrType) => ({
      key: arrType,
      header: arrType.charAt(0).toUpperCase() + arrType.slice(1),
      align: "center",
      width: "w-64"
    }))])(arrTypes);
    Table2($$renderer2, {
      columns,
      data: formats,
      emptyMessage: "No custom formats found",
      pageSize: 50,
      hoverable: false,
      rowClass,
      rowAttributes,
      $$slots: { cell: ($$renderer3, { row, column }) => {
        if (column.key === "name") {
          $$renderer3.push("<!--[0-->");
          InlineLink($$renderer3, {
            href: `/custom-formats/${stringify(databaseId)}/${stringify(row.id)}/general`,
            text: row.name,
            external: true
          });
        } else {
          $$renderer3.push("<!--[-1-->");
          const arrType = column.key;
          $$renderer3.push(`<div class="flex items-center justify-center gap-2">`);
          IconCheckbox($$renderer3, {
            checked: customFormatEnabled[row.name]?.[arrType] ?? false,
            icon: Check,
            color: getArrTypeColor(arrType),
            shape: "circle",
            disabled
          });
          $$renderer3.push(`<!----> `);
          if (customFormatScores[row.name]) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="w-48">`);
            NumberInput($$renderer3, {
              name: `score-${stringify(row.name)}-${stringify(arrType)}`,
              value: customFormatScores[row.name][arrType] ?? 0,
              onchange: (newValue) => handleScoreChange(row.name, arrType, newValue),
              step: 1,
              disabled: disabled || !customFormatEnabled[row.name]?.[arrType],
              font: "mono"
            });
            $$renderer3.push(`<!----></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--></div>`);
        }
        $$renderer3.push(`<!--]-->`);
      } }
    });
    bind_props($$props, {
      databaseId,
      formats,
      arrTypes,
      customFormatScores,
      customFormatEnabled,
      disabled,
      getArrTypeColor,
      firstRowOnboarding
    });
  });
}
function ScoringTable($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let databaseId = $$props["databaseId"];
    let formats = $$props["formats"];
    let arrTypes = $$props["arrTypes"];
    let customFormatScores = $$props["customFormatScores"];
    let customFormatEnabled = $$props["customFormatEnabled"];
    let disabled = fallback($$props["disabled"], false);
    let getArrTypeColor = $$props["getArrTypeColor"];
    let title = fallback($$props["title"], null);
    let firstRowOnboarding = fallback($$props["firstRowOnboarding"], void 0);
    onDestroy(() => {
    });
    if (title) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="mb-3"><h3 class="text-lg font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(title)}</h3></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> `);
    $$renderer2.push("<!--[0-->");
    ScoringTableDesktop($$renderer2, {
      databaseId,
      formats,
      arrTypes,
      customFormatScores,
      customFormatEnabled,
      disabled,
      getArrTypeColor,
      firstRowOnboarding
    });
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      databaseId,
      formats,
      arrTypes,
      customFormatScores,
      customFormatEnabled,
      disabled,
      getArrTypeColor,
      title,
      firstRowOnboarding
    });
  });
}
function _page59($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, initialData, upgradesAllowed, minimumScore, upgradeUntilScore, upgradeScoreIncrement, customFormatScores, customFormatEnabled, groups, scoring2, visibleArrTypes, searchQuery, filteredCustomFormats, sortedCustomFormats, groupedFormats, customFormatScoresPayload;
    let data = $$props["data"];
    let showSyncModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    let searchStore;
    let showInfoModal = false;
    let showOptionsInfoModal = false;
    function buildInitialData(scoring3) {
      if (!scoring3) return {
        upgradesAllowed: true,
        minimumScore: 0,
        upgradeUntilScore: 0,
        upgradeScoreIncrement: 1,
        customFormatScores: {},
        customFormatEnabled: {}
      };
      const scores = {};
      const enabled3 = {};
      scoring3.customFormats.forEach((cf) => {
        scores[cf.name] = { ...cf.scores };
        enabled3[cf.name] = {};
        scoring3.arrTypes.forEach((arrType) => {
          enabled3[cf.name][arrType] = cf.scores[arrType] !== null;
        });
      });
      return {
        upgradesAllowed: scoring3.upgrades_allowed,
        minimumScore: scoring3.minimum_custom_format_score,
        upgradeUntilScore: scoring3.upgrade_until_score,
        upgradeScoreIncrement: scoring3.upgrade_score_increment,
        customFormatScores: scores,
        customFormatEnabled: enabled3
      };
    }
    let selectedLayer = data.canWriteToBase ? "base" : "user";
    let sortState = null;
    let tileColumns = 1;
    let hideUnscoredFormats = false;
    let hiddenArrTypes = /* @__PURE__ */ new Set();
    let selectedGroups = /* @__PURE__ */ new Set();
    const GROUPING_STORAGE_KEY = "scoring-selected-groups";
    const CUSTOM_GROUPS_STORAGE_KEY = "scoring-custom-groups";
    const builtInGroups = [
      {
        name: "Audio",
        key: "audio",
        tags: ["audio"],
        custom: false
      },
      {
        name: "HDR",
        key: "hdr",
        tags: ["hdr"],
        custom: false
      },
      {
        name: "Release Group",
        key: "release-group",
        tags: ["release group", "release groups"],
        custom: false
      },
      {
        name: "Release Group Tier",
        key: "release-group-tier",
        tags: ["release group tier", "release group tiers"],
        custom: false
      },
      {
        name: "Streaming Service",
        key: "streaming-service",
        tags: ["streaming service"],
        custom: false
      },
      {
        name: "Codec",
        key: "codec",
        tags: ["codec"],
        custom: false
      },
      {
        name: "Storage",
        key: "storage",
        tags: ["storage"],
        custom: false
      },
      {
        name: "Source",
        key: "source",
        tags: ["source"],
        custom: false
      },
      {
        name: "Resolution",
        key: "resolution",
        tags: [
          "sd",
          "480p",
          "576p",
          "720p",
          "1080p",
          "2160p",
          "4k",
          "8k",
          "resolution"
        ],
        custom: false
      },
      {
        name: "Indexer Flag",
        key: "indexer-flag",
        tags: ["flag"],
        custom: false
      },
      {
        name: "Edition",
        key: "edition",
        tags: ["edition", "colour grade"],
        custom: false
      },
      {
        name: "Enhancement",
        key: "enhancement",
        tags: ["enhancement", "enhancements"],
        custom: false
      },
      {
        name: "Languages",
        key: "languages",
        tags: [
          "language",
          "languages",
          "asl"
        ],
        custom: false
      }
    ];
    let customGroups = [];
    let profiles = [];
    let currentProfileId = null;
    let newProfileName = "";
    function saveGroupingPreference() {
      localStorage.setItem(GROUPING_STORAGE_KEY, JSON.stringify([...selectedGroups]));
    }
    function toggleGroup(key2) {
      if (selectedGroups.has(key2)) selectedGroups.delete(key2);
      else selectedGroups.add(key2);
      selectedGroups = selectedGroups;
      saveGroupingPreference();
    }
    function saveCustomGroups() {
      const toSave = customGroups.map(({ name, key: key2, tags }) => ({
        name,
        key: key2,
        tags
      }));
      localStorage.setItem(CUSTOM_GROUPS_STORAGE_KEY, JSON.stringify(toSave));
    }
    function addCustomGroup(name, tags) {
      const key2 = `custom-${Date.now()}`;
      customGroups = [...customGroups, {
        name,
        key: key2,
        tags,
        custom: true
      }];
      saveCustomGroups();
    }
    function deleteCustomGroup(key2) {
      customGroups = customGroups.filter((g3) => g3.key !== key2);
      selectedGroups.delete(key2);
      selectedGroups = selectedGroups;
      saveCustomGroups();
      saveGroupingPreference();
    }
    const arrTypeColors = {
      radarr: "var(--arr-radarr-color)",
      sonarr: "var(--arr-sonarr-color)"
    };
    function getArrTypeColor(arrType) {
      return arrTypeColors[arrType] || "#3b82f6";
    }
    function buildCustomFormatScoresArray(currentScores, initialScores) {
      const result = [];
      for (const [cfName, arrTypeScores] of Object.entries(currentScores)) {
        const initialScoresForFormat = initialScores[cfName] || {};
        for (const [arrType, score] of Object.entries(arrTypeScores)) if (score !== initialScoresForFormat[arrType]) result.push({
          customFormatName: cfName,
          arrType,
          score
        });
      }
      return result;
    }
    function sortFormats(formats, scores, sortState2) {
      if (!sortState2) return formats;
      return [...formats].sort((a2, b3) => {
        let aVal;
        let bVal;
        if (sortState2.key === "name") {
          aVal = a2.name?.toLowerCase() || "";
          bVal = b3.name?.toLowerCase() || "";
          return sortState2.direction === "asc" ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
        } else {
          aVal = scores[a2.name]?.[sortState2.key] ?? null;
          bVal = scores[b3.name]?.[sortState2.key] ?? null;
          if (aVal === null && bVal === null) return 0;
          if (aVal === null) return 1;
          if (bVal === null) return -1;
          return sortState2.direction === "desc" ? bVal - aVal : aVal - bVal;
        }
      });
    }
    function groupFormats(formats, selectedGroups2) {
      if (selectedGroups2.size === 0) return [{
        name: null,
        formats
      }];
      const result = [];
      const assigned = /* @__PURE__ */ new Set();
      for (const group of groups) {
        if (!selectedGroups2.has(group.key)) continue;
        const groupFormats2 = formats.filter((format) => {
          if (assigned.has(format.name)) return false;
          return format.tags?.some((tag2) => group.tags.includes(tag2.toLowerCase()));
        });
        groupFormats2.forEach((f2) => assigned.add(f2.name));
        result.push({
          name: group.name,
          formats: groupFormats2
        });
      }
      const otherFormats = formats.filter((f2) => !assigned.has(f2.name));
      if (otherFormats.length > 0) result.push({
        name: "Other",
        formats: otherFormats
      });
      return result;
    }
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: searchStore = getPersistentSearchStore(`qualityProfileScoringSearch:${store_get($$store_subs ??= {}, "$page", page).params.databaseId}:${store_get($$store_subs ??= {}, "$page", page).params.id}`, { debounceMs: 200 });
    $: initialData = buildInitialData(data.scoring);
    $: initEdit(initialData);
    $: upgradesAllowed = store_get($$store_subs ??= {}, "$current", current2).upgradesAllowed ?? true;
    $: minimumScore = store_get($$store_subs ??= {}, "$current", current2).minimumScore ?? 0;
    $: upgradeUntilScore = store_get($$store_subs ??= {}, "$current", current2).upgradeUntilScore ?? 0;
    $: upgradeScoreIncrement = store_get($$store_subs ??= {}, "$current", current2).upgradeScoreIncrement ?? 1;
    $: customFormatScores = store_get($$store_subs ??= {}, "$current", current2).customFormatScores ?? {};
    $: customFormatEnabled = store_get($$store_subs ??= {}, "$current", current2).customFormatEnabled ?? {};
    $: groups = [...builtInGroups, ...customGroups];
    $: scoring2 = data.scoring;
    $: if (scoring2 && !sortState) {
      const defaultSortKey = scoring2.arrTypes.includes("radarr") ? "radarr" : scoring2.arrTypes[0];
      if (defaultSortKey) sortState = {
        key: defaultSortKey,
        direction: "desc"
      };
    }
    $: if (currentProfileId && true) {
      const activeProfile = profiles.find((p2) => p2.id === currentProfileId);
      if (activeProfile) {
        const searchQuery2 = store_get($$store_subs ??= {}, "$searchStore", searchStore).query ?? "";
        const selectedGroupsArray = [...selectedGroups];
        const customGroupsClean = customGroups.map(({ name, key: key2, tags }) => ({
          name,
          key: key2,
          tags
        }));
        if (searchQuery2 !== activeProfile.searchQuery || JSON.stringify(sortState) !== JSON.stringify(activeProfile.sortState) || JSON.stringify(selectedGroupsArray) !== JSON.stringify(activeProfile.selectedGroups) || JSON.stringify(customGroupsClean) !== JSON.stringify(activeProfile.customGroups) || tileColumns !== activeProfile.tileColumns || hideUnscoredFormats !== activeProfile.hideUnscoredFormats) currentProfileId = null;
      }
    }
    $: visibleArrTypes = scoring2?.arrTypes.filter((t2) => !hiddenArrTypes.has(t2)) ?? [];
    $: searchQuery = (store_get($$store_subs ??= {}, "$searchStore", searchStore).query ?? "").trim().toLowerCase();
    $: filteredCustomFormats = scoring2?.customFormats.filter((format) => {
      if (searchQuery && !format.name?.toLowerCase().includes(searchQuery)) return false;
      return true;
    }) || [];
    $: sortedCustomFormats = sortFormats(filteredCustomFormats, initialData.customFormatScores, sortState);
    $: groupedFormats = groupFormats(sortedCustomFormats, selectedGroups);
    $: customFormatScoresPayload = JSON.stringify(buildCustomFormatScoresArray(customFormatScores, initialData.customFormatScores));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.profileName} \xB7 Scoring` });
      $$renderer3.push(`<!----> `);
      if (scoring2) {
        $$renderer3.push("<!--[0-->");
        StickyCard($$renderer3, {
          position: "top",
          $$slots: {
            left: ($$renderer4) => {
              $$renderer4.push(`<h1 class="text-neutral-900 dark:text-neutral-50">Scoring</h1> <p class="text-neutral-600 dark:text-neutral-400">Configure custom format scores</p>`);
            },
            right: ($$renderer4) => {
              $$renderer4.push(`<div class="flex items-center gap-2">`);
              Button($$renderer4, {
                text: "Scoring",
                icon: Info
              });
              $$renderer4.push(`<!----> `);
              Button($$renderer4, {
                text: "Options",
                icon: Info
              });
              $$renderer4.push(`<!----> `);
              Button($$renderer4, {
                disabled: !store_get($$store_subs ??= {}, "$isDirty", isDirty),
                icon: Save,
                iconColor: "text-blue-600 dark:text-blue-400",
                text: "Save"
              });
              $$renderer4.push(`<!----></div>`);
            }
          }
        });
        $$renderer3.push(`<!----> <form method="POST" action="?/update" class="hidden"><input type="hidden" name="upgradesAllowed"${attr("value", upgradesAllowed ? "true" : "false")}/> <input type="hidden" name="minimumScore"${attr("value", minimumScore)}/> <input type="hidden" name="upgradeUntilScore"${attr("value", upgradeUntilScore)}/> <input type="hidden" name="upgradeScoreIncrement"${attr("value", upgradeScoreIncrement)}/> <input type="hidden" name="customFormatScores"${attr("value", customFormatScoresPayload)}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/></form> <div class="mt-6 space-y-6 md:px-4"><div class="grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-4"><div class="space-y-2" data-onboarding="qp-scoring-upgrades-allowed"><label for="upgradesAllowed" class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Upgrades Allowed</label> <p class="text-xs text-neutral-600 dark:text-neutral-400">Allow this profile to upgrade existing media</p> `);
        Toggle($$renderer3, {
          checked: upgradesAllowed,
          label: upgradesAllowed ? "Enabled" : "Disabled",
          ariaLabel: "Upgrades allowed",
          fullWidth: true
        });
        $$renderer3.push(`<!----></div> <div class="space-y-2" data-onboarding="qp-scoring-minimum"><label for="minimumScore" class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Minimum Score</label> <p class="text-xs text-neutral-600 dark:text-neutral-400">Minimum custom format score required to download</p> `);
        NumberInput($$renderer3, {
          name: "minimumScore",
          value: minimumScore,
          onchange: (v3) => update3("minimumScore", v3),
          step: 1,
          font: "mono"
        });
        $$renderer3.push(`<!----></div> <div class="space-y-2" data-onboarding="qp-scoring-upgrade-until"><label for="upgradeUntilScore" class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Upgrade Until Score</label> <p class="text-xs text-neutral-600 dark:text-neutral-400">Stop upgrading when this score is reached</p> `);
        NumberInput($$renderer3, {
          name: "upgradeUntilScore",
          value: upgradeUntilScore,
          onchange: (v3) => update3("upgradeUntilScore", v3),
          step: 1,
          font: "mono",
          disabled: !upgradesAllowed
        });
        $$renderer3.push(`<!----></div> <div class="space-y-2" data-onboarding="qp-scoring-increment"><label for="upgradeScoreIncrement" class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Upgrade Score Increment</label> <p class="text-xs text-neutral-600 dark:text-neutral-400">Minimum score improvement needed to upgrade</p> `);
        NumberInput($$renderer3, {
          name: "upgradeScoreIncrement",
          value: upgradeScoreIncrement,
          onchange: (v3) => update3("upgradeScoreIncrement", v3),
          step: 1,
          font: "mono",
          disabled: !upgradesAllowed
        });
        $$renderer3.push(`<!----></div></div> `);
        ActionsBar($$renderer3, {
          className: "md:w-full",
          onboarding: "qp-scoring-actions",
          children: ($$renderer4) => {
            SearchAction($$renderer4, {
              searchStore,
              placeholder: "Search custom formats...",
              responsive: true
            });
            $$renderer4.push(`<!----> `);
            ActionButton($$renderer4, {
              icon: Arrow_up_down,
              hasDropdown: true,
              dropdownPosition: "right",
              $$slots: { dropdown: ($$renderer5, { dropdownPosition, open }) => {
                Dropdown($$renderer5, {
                  position: dropdownPosition,
                  mobilePosition: "middle",
                  minWidth: "10rem",
                  children: ($$renderer6) => {
                    DropdownHeader($$renderer6, { label: "Sort by" });
                    $$renderer6.push(`<!----> `);
                    DropdownItem($$renderer6, {
                      label: "Name",
                      selected: sortState?.key === "name",
                      checkIcon: sortState?.key === "name" && sortState.direction === "desc" ? Arrow_down : Arrow_up,
                      checkColor: "blue"
                    });
                    $$renderer6.push(`<!----> `);
                    DropdownItem($$renderer6, {
                      label: "Radarr",
                      selected: sortState?.key === "radarr",
                      checkIcon: sortState?.key === "radarr" && sortState.direction === "asc" ? Arrow_up : Arrow_down,
                      checkColor: getArrTypeColor("radarr")
                    });
                    $$renderer6.push(`<!----> `);
                    DropdownItem($$renderer6, {
                      label: "Sonarr",
                      selected: sortState?.key === "sonarr",
                      checkIcon: sortState?.key === "sonarr" && sortState.direction === "asc" ? Arrow_up : Arrow_down,
                      checkColor: getArrTypeColor("sonarr")
                    });
                    $$renderer6.push(`<!---->`);
                  },
                  $$slots: { default: true }
                });
              } }
            });
            $$renderer4.push(`<!----> `);
            ActionButton($$renderer4, {
              icon: Layers,
              hasDropdown: true,
              dropdownPosition: "right",
              $$slots: { dropdown: ($$renderer5, { dropdownPosition, open }) => {
                Dropdown($$renderer5, {
                  position: dropdownPosition,
                  mobilePosition: "middle",
                  minWidth: "14rem",
                  children: ($$renderer6) => {
                    DropdownHeader($$renderer6, { label: "Group by" });
                    $$renderer6.push(`<!----> `);
                    DropdownItem($$renderer6, {
                      label: "No Grouping",
                      selected: selectedGroups.size === 0,
                      checkColor: "blue"
                    });
                    $$renderer6.push(`<!----> <!--[-->`);
                    const each_array = ensure_array_like(builtInGroups);
                    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                      let group = each_array[$$index];
                      DropdownItem($$renderer6, {
                        label: group.name,
                        selected: selectedGroups.has(group.key),
                        checkColor: "blue"
                      });
                    }
                    $$renderer6.push(`<!--]--> `);
                    CustomGroupManager($$renderer6, {
                      customGroups,
                      selectedGroups,
                      onAdd: addCustomGroup,
                      onDelete: deleteCustomGroup,
                      onToggle: toggleGroup
                    });
                    $$renderer6.push(`<!---->`);
                  },
                  $$slots: { default: true }
                });
              } }
            });
            $$renderer4.push(`<!----> `);
            ActionButton($$renderer4, {
              icon: Layout_grid,
              hasDropdown: true,
              dropdownPosition: "right",
              $$slots: { dropdown: ($$renderer5, { dropdownPosition, open }) => {
                Dropdown($$renderer5, {
                  position: dropdownPosition,
                  mobilePosition: "middle",
                  minWidth: "10rem",
                  children: ($$renderer6) => {
                    DropdownHeader($$renderer6, { label: "Grid columns" });
                    $$renderer6.push(`<!----> <!--[-->`);
                    const each_array_1 = ensure_array_like([
                      1,
                      2,
                      3
                    ]);
                    for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                      let columns = each_array_1[$$index_1];
                      DropdownItem($$renderer6, {
                        label: `${columns} Column${columns > 1 ? "s" : ""}`,
                        selected: tileColumns === columns,
                        checkColor: "blue"
                      });
                    }
                    $$renderer6.push(`<!--]-->`);
                  },
                  $$slots: { default: true }
                });
              } }
            });
            $$renderer4.push(`<!----> `);
            if (scoring2.arrTypes.length > 1) {
              $$renderer4.push("<!--[0-->");
              ActionButton($$renderer4, {
                icon: Eye,
                hasDropdown: true,
                dropdownPosition: "right",
                $$slots: { dropdown: ($$renderer5, { dropdownPosition }) => {
                  Dropdown($$renderer5, {
                    position: dropdownPosition,
                    minWidth: "10rem",
                    children: ($$renderer6) => {
                      DropdownHeader($$renderer6, { label: "Columns" });
                      $$renderer6.push(`<!----> <!--[-->`);
                      const each_array_2 = ensure_array_like(scoring2.arrTypes);
                      for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
                        let arrType = each_array_2[$$index_2];
                        DropdownItem($$renderer6, {
                          label: arrType.charAt(0).toUpperCase() + arrType.slice(1),
                          selected: !hiddenArrTypes.has(arrType),
                          checkColor: getArrTypeColor(arrType)
                        });
                      }
                      $$renderer6.push(`<!--]-->`);
                    },
                    $$slots: { default: true }
                  });
                } }
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            ActionButton($$renderer4, {
              icon: Settings,
              hasDropdown: true,
              dropdownPosition: "right",
              $$slots: { dropdown: ($$renderer5, { dropdownPosition, open }) => {
                Dropdown($$renderer5, {
                  position: dropdownPosition,
                  minWidth: "14rem",
                  children: ($$renderer6) => {
                    DropdownHeader($$renderer6, { label: "Display" });
                    $$renderer6.push(`<!----> `);
                    DropdownItem($$renderer6, {
                      label: "Hide Unscored Formats",
                      selected: hideUnscoredFormats,
                      checkColor: "blue"
                    });
                    $$renderer6.push(`<!---->`);
                  },
                  $$slots: { default: true }
                });
              } }
            });
            $$renderer4.push(`<!----> `);
            ActionButton($$renderer4, {
              icon: User,
              hasDropdown: true,
              dropdownPosition: "right",
              $$slots: { dropdown: ($$renderer5, { dropdownPosition, open }) => {
                Dropdown($$renderer5, {
                  position: dropdownPosition,
                  minWidth: "16rem",
                  children: ($$renderer6) => {
                    $$renderer6.push(`<div class="border-b border-neutral-200 px-4 py-3 dark:border-neutral-700"><div class="mb-2 text-xs font-medium text-neutral-700 dark:text-neutral-300">Save Current Settings</div> <form class="space-y-2">`);
                    FormInput($$renderer6, {
                      label: "Profile name",
                      name: "profileName",
                      placeholder: "Profile name",
                      hideLabel: true,
                      size: "sm",
                      get value() {
                        return newProfileName;
                      },
                      set value($$value) {
                        newProfileName = $$value;
                        $$settled = false;
                      }
                    });
                    $$renderer6.push(`<!----> `);
                    Button($$renderer6, {
                      type: "submit",
                      text: "Save Profile",
                      icon: Plus,
                      variant: "primary",
                      size: "xs",
                      fullWidth: true,
                      disabled: !newProfileName.trim()
                    });
                    $$renderer6.push(`<!----></form></div> `);
                    DropdownHeader($$renderer6, { label: "Profiles" });
                    $$renderer6.push(`<!----> `);
                    DropdownItem($$renderer6, {
                      label: "Default",
                      selected: currentProfileId === null,
                      checkColor: "blue"
                    });
                    $$renderer6.push(`<!----> <!--[-->`);
                    const each_array_3 = ensure_array_like(profiles);
                    for (let $$index_3 = 0, $$length = each_array_3.length; $$index_3 < $$length; $$index_3++) {
                      let profile = each_array_3[$$index_3];
                      DropdownItem($$renderer6, {
                        label: profile.name,
                        selected: currentProfileId === profile.id,
                        checkColor: "blue",
                        $$slots: { actions: ($$renderer7) => {
                          Button($$renderer7, {
                            variant: "ghost",
                            size: "xs",
                            icon: X2,
                            ariaLabel: "Delete profile",
                            tooltip: "Delete profile"
                          });
                        } }
                      });
                    }
                    $$renderer6.push(`<!--]-->`);
                  },
                  $$slots: { default: true }
                });
              } }
            });
            $$renderer4.push(`<!---->`);
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----> `);
        if (searchQuery === "santiagoisthebest") {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="flex items-center justify-center rounded-lg border border-neutral-200 bg-white p-8 dark:border-neutral-800 dark:bg-neutral-900"><img src="/src/lib/client/assets/thanks.gif" alt="Thanks!" class="max-w-full"/></div>`);
        } else if (searchQuery === "rickroll" || searchQuery === "nevergonnagiveyouup") {
          $$renderer3.push("<!--[1-->");
          $$renderer3.push(`<div class="flex items-center justify-center rounded-lg border border-neutral-200 bg-white p-8 dark:border-neutral-800 dark:bg-neutral-900"><img src="/src/lib/client/assets/nggyu.gif" alt="Never gonna give you up" class="max-w-full"/></div>`);
        } else if (sortedCustomFormats.length === 0) {
          $$renderer3.push("<!--[2-->");
          $$renderer3.push(`<div class="overflow-x-auto rounded-lg border border-neutral-200 dark:border-neutral-800"><div class="px-6 py-8 text-center text-sm text-neutral-500 dark:text-neutral-400">`);
          if (scoring2.customFormats.length === 0) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`No custom formats found`);
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`No custom formats match your search`);
          }
          $$renderer3.push(`<!--]--></div></div>`);
        } else {
          $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<div${attr_class("grid gap-6", void 0, {
            "grid-cols-1": true,
            "grid-cols-2": false,
            "grid-cols-3": false
          })}><!--[-->`);
          const each_array_4 = ensure_array_like(groupedFormats);
          for (let groupIndex = 0, $$length = each_array_4.length; groupIndex < $$length; groupIndex++) {
            let group = each_array_4[groupIndex];
            if (group.formats.length > 0) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="min-w-0">`);
              ScoringTable($$renderer3, {
                databaseId,
                formats: group.formats,
                arrTypes: visibleArrTypes,
                customFormatScores,
                customFormatEnabled,
                getArrTypeColor,
                title: group.name,
                firstRowOnboarding: groupIndex === 0 ? "qp-scoring-row" : void 0
              });
              $$renderer3.push(`<!----></div>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]-->`);
          }
          $$renderer3.push(`<!--]--></div>`);
        }
        $$renderer3.push(`<!--]--></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      InfoModal($$renderer3, {
        header: "Custom Format Scoring",
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">Custom Format Scores</div> <div class="mt-1">Each custom format can have different scores for different Arr types (Radarr, Sonarr). The
				score determines how much a release is preferred when it matches the custom format.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Minimum Score</div> <div class="mt-1">The minimum total custom format score required for a release to be downloaded. Releases with
				scores below this threshold will be rejected.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Upgrade Until Score</div> <div class="mt-1">Once a release reaches this score, the system will stop looking for upgrades. This prevents
				unnecessary upgrades when you've already got a good quality release.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Upgrade Score Increment</div> <div class="mt-1">The minimum score improvement required to trigger an upgrade. This prevents minor upgrades
				that don't significantly improve quality.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Positive vs Negative Scores</div> <div class="mt-1">Positive scores increase preference for releases matching the custom format. Negative scores
				decrease preference or can block releases entirely when combined with the minimum score
				setting.</div></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      InfoModal($$renderer3, {
        header: "Display Options",
        get open() {
          return showOptionsInfoModal;
        },
        set open($$value) {
          showOptionsInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">Search</div> <div class="mt-1">Filter custom formats by name. The search is case-insensitive and matches any part of the
				format name.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Sort</div> <div class="mt-1">Sort custom formats by Name (A-Z), Radarr score, or Sonarr score. Click the same option
				again to reverse the sort direction (ascending \u2191 or descending \u2193). Formats with no score are
				always shown at the end.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Grouping</div> <div class="mt-1">Organize custom formats into separate tables based on their tags. You can select multiple
				groups at once. Available groups include Audio, HDR, Release Group, Codec, Resolution, and
				more. Formats that don't match any selected group appear in the "Other" table. If a format
				matches multiple groups, it appears in the first matching group only.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Custom Groups</div> <div class="mt-1">Create your own custom groups by entering a name and comma-separated tags at the bottom of
				the Grouping dropdown. Your custom groups are saved to your browser and can be deleted at
				any time. Custom groups work the same as built-in groups - formats are assigned to the first
				matching group based on their tags.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Tiling</div> <div class="mt-1">Display tables in 1, 2, or 3 columns. This is especially useful when using grouping to view
				multiple format categories side-by-side.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Hide Unscored Formats</div> <div class="mt-1">Hide custom formats that have no score assigned for any Arr type. This helps focus on
				formats that are currently being used in your quality profile.</div></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Profiles</div> <div class="mt-1">Save your current display configuration (search, sort, grouping, custom groups, tiling, and
				options) as a named profile. Load saved profiles to quickly switch between different views.
				The "Default" profile resets everything to the baseline configuration. Profiles are stored
				in your browser and automatically uncheck when you modify any settings.</div></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      SyncPromptModal($$renderer3, {
        redirectTo: pendingRedirectTo,
        affectedArrs: pendingAffectedArrs,
        databaseId,
        entityName: data.profileName,
        get open() {
          return showSyncModal;
        },
        set open($$value) {
          showSyncModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte59 = __esm({
  "dist/build/server/entries/pages/quality-profiles/_databaseId_/_id_/scoring/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_index_server2();
    init_Dropdown();
    init_Icon();
    init_arrow_up_down();
    init_arrow_up();
    init_check();
    init_eye();
    init_info();
    init_layers();
    init_layout_grid();
    init_Button();
    init_plus();
    init_save();
    init_search();
    init_settings();
    init_x();
    init_stores();
    init_store2();
    init_navigation();
    init_forms();
    init_IconCheckbox();
    init_DropdownItem();
    init_dirty();
    init_ActionsBar();
    init_ActionButton();
    init_DropdownHeader();
    init_InfoModal();
    init_PageMeta();
    init_Table();
    init_StickyCard();
    init_FormInput();
    init_NumberInput();
    init_Toggle();
    init_SyncPromptModal();
    init_InlineLink();
  }
});

// dist/build/server/nodes/69.js
var __exports70 = {};
__export(__exports70, {
  component: () => component66,
  fonts: () => fonts70,
  imports: () => imports70,
  index: () => index70,
  server: () => page_server_ts_exports61,
  server_id: () => server_id67,
  stylesheets: () => stylesheets70
});
var index70, component_cache66, component66, server_id67, imports70, stylesheets70, fonts70;
var init__70 = __esm({
  async "dist/build/server/nodes/69.js"() {
    "use strict";
    await init_page_server_ts61();
    index70 = 69;
    component66 = async () => component_cache66 ??= (await Promise.resolve().then(() => (init_page_svelte59(), page_svelte_exports59))).default;
    server_id67 = "src/routes/quality-profiles/[databaseId]/[id]/scoring/+page.server.ts";
    imports70 = ["_app/immutable/nodes/69.Bqkwi_Hf.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DYf5Ixhg.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/e-haqc9Z.js", "_app/immutable/chunks/KKGdICwf.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BhExzYrM2.js"];
    stylesheets70 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts70 = [];
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/new/_page.server.ts.js
var page_server_ts_exports62 = {};
__export(page_server_ts_exports62, {
  actions: () => actions40,
  load: () => load65
});
var load65, actions40;
var init_page_server_ts62 = __esm({
  async "dist/build/server/entries/pages/quality-profiles/_databaseId_/new/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    init_mappings();
    init_exports();
    load65 = ({ params }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = pcdManager.getByIdPublic(currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      return {
        currentDatabase,
        availableLanguages: getRadarrLanguages(),
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions40 = { default: async ({ request, params }) => {
      const { databaseId } = params;
      if (!databaseId) return fail(400, { error: "Missing database ID" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const name = formData.get("name");
      const description = formData.get("description") || null;
      const tagsJson = formData.get("tags");
      const languageRaw = formData.get("language");
      const language = languageRaw && languageRaw.trim() !== "" ? languageRaw.trim() : null;
      const layer = formData.get("layer") || "user";
      if (!name?.trim()) return fail(400, { error: "Name is required" });
      let tags = [];
      try {
        tags = JSON.parse(tagsJson || "[]");
      } catch {
        return fail(400, { error: "Invalid tags format" });
      }
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      let result;
      try {
        result = await create2({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          input: {
            name: name.trim(),
            description: description?.trim() || null,
            tags,
            language
          }
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to create quality profile";
        if (message2.includes("already exists")) return fail(400, { error: message2 });
        return fail(500, { error: message2 });
      }
      if (!result.success) return fail(500, { error: result.error || "Failed to create quality profile" });
      const freshCache = pcdManager.getCache(currentDatabaseId);
      if (!freshCache) throw redirect(303, `/quality-profiles/${databaseId}`);
      const newProfile = (await list2(freshCache)).find((p2) => p2.name === name.trim());
      if (newProfile) throw redirect(303, `/quality-profiles/${databaseId}/${newProfile.id}/scoring`);
      throw redirect(303, `/quality-profiles/${databaseId}`);
    } };
  }
});

// dist/build/server/entries/pages/quality-profiles/_databaseId_/new/_page.svelte.js
var page_svelte_exports60 = {};
__export(page_svelte_exports60, {
  default: () => _page60
});
function _page60($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    const initialData = {
      name: "",
      tags: [],
      description: "",
      language: null
    };
    function handleCancel() {
      goto(`/quality-profiles/${data.currentDatabase.id}`);
    }
    PageMeta($$renderer2, { title: `${data.currentDatabase.name} \xB7 Quality Profile \xB7 New` });
    $$renderer2.push(`<!----> <div class="p-8">`);
    GeneralForm2($$renderer2, {
      mode: "create",
      canWriteToBase: data.canWriteToBase,
      initialData,
      availableLanguages: data.availableLanguages,
      onCancel: handleCancel
    });
    $$renderer2.push(`<!----></div> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte60 = __esm({
  "dist/build/server/entries/pages/quality-profiles/_databaseId_/new/_page.svelte.js"() {
    "use strict";
    init_server();
    init_client4();
    init_navigation();
    init_DirtyModal();
    init_PageMeta();
    init_GeneralForm2();
  }
});

// dist/build/server/nodes/70.js
var __exports71 = {};
__export(__exports71, {
  component: () => component67,
  fonts: () => fonts71,
  imports: () => imports71,
  index: () => index71,
  server: () => page_server_ts_exports62,
  server_id: () => server_id68,
  stylesheets: () => stylesheets71
});
var index71, component_cache67, component67, server_id68, imports71, stylesheets71, fonts71;
var init__71 = __esm({
  async "dist/build/server/nodes/70.js"() {
    "use strict";
    await init_page_server_ts62();
    index71 = 70;
    component67 = async () => component_cache67 ??= (await Promise.resolve().then(() => (init_page_svelte60(), page_svelte_exports60))).default;
    server_id68 = "src/routes/quality-profiles/[databaseId]/new/+page.server.ts";
    imports71 = ["_app/immutable/nodes/70.CTmzJpil.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/BW8V51c72.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/BQ_6zcl8.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/CK2yQf0C.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js"];
    stylesheets71 = [];
    fonts71 = [];
  }
});

// dist/build/server/entries/pages/quality-profiles/entity-testing/_page.server.ts.js
var page_server_ts_exports63 = {};
__export(page_server_ts_exports63, {
  load: () => load66
});
var load66;
var init_page_server_ts63 = __esm({
  async "dist/build/server/entries/pages/quality-profiles/entity-testing/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_lastDatabase();
    load66 = ({ cookies }) => {
      redirectToLastDatabase(cookies, "last_db_et", "/quality-profiles/entity-testing");
      return { databases: pcdManager.getAllPublic() };
    };
  }
});

// dist/build/server/entries/pages/quality-profiles/entity-testing/_page.svelte.js
var page_svelte_exports61 = {};
__export(page_svelte_exports61, {
  default: () => _page61
});
function _page61($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: "Quality Profile Tests" });
    $$renderer2.push(`<!----> `);
    if (data.databases.length === 0) {
      $$renderer2.push("<!--[0-->");
      EmptyState($$renderer2, {
        icon: Database2,
        title: "No Databases Linked",
        description: "Link a Profilarr Compliant Database to test quality profiles.",
        buttonText: "Link Database",
        buttonHref: "/databases/new",
        buttonIcon: Plus
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte61 = __esm({
  "dist/build/server/entries/pages/quality-profiles/entity-testing/_page.svelte.js"() {
    "use strict";
    init_server();
    init_database2();
    init_plus();
    init_PageMeta();
    init_EmptyState();
  }
});

// dist/build/server/nodes/71.js
var __exports72 = {};
__export(__exports72, {
  component: () => component68,
  fonts: () => fonts72,
  imports: () => imports72,
  index: () => index72,
  server: () => page_server_ts_exports63,
  server_id: () => server_id69,
  stylesheets: () => stylesheets72
});
var index72, component_cache68, component68, server_id69, imports72, stylesheets72, fonts72;
var init__72 = __esm({
  async "dist/build/server/nodes/71.js"() {
    "use strict";
    await init_page_server_ts63();
    index72 = 71;
    component68 = async () => component_cache68 ??= (await Promise.resolve().then(() => (init_page_svelte61(), page_svelte_exports61))).default;
    server_id69 = "src/routes/quality-profiles/entity-testing/+page.server.ts";
    imports72 = ["_app/immutable/nodes/71.DEpq_8tg.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D_awjkBZ.js", "_app/immutable/chunks/B66v-P2b.js"];
    stylesheets72 = [];
    fonts72 = [];
  }
});

// dist/build/server/chunks/parser.js
var init_parser = __esm({
  async "dist/build/server/chunks/parser.js"() {
    "use strict";
    await init_client2();
  }
});

// dist/build/server/chunks/tmdbSettings.js
var tmdbSettingsQueries;
var init_tmdbSettings = __esm({
  async "dist/build/server/chunks/tmdbSettings.js"() {
    "use strict";
    await init_db();
    tmdbSettingsQueries = {
      /**
      * Get the TMDB settings (singleton)
      */
      get() {
        return db.queryFirst("SELECT * FROM tmdb_settings WHERE id = 1");
      },
      /**
      * Update TMDB settings
      */
      update(input) {
        const updates = [];
        const params = [];
        if (input.apiKey !== void 0) {
          updates.push("api_key = ?");
          params.push(input.apiKey);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(1);
        return db.execute(`UPDATE tmdb_settings SET ${updates.join(", ")} WHERE id = ?`, ...params) > 0;
      },
      /**
      * Reset TMDB settings to defaults
      */
      reset() {
        return db.execute(`
			UPDATE tmdb_settings SET
				api_key = '',
				updated_at = CURRENT_TIMESTAMP
			WHERE id = 1
		`) > 0;
      }
    };
  }
});

// dist/build/server/entries/pages/quality-profiles/entity-testing/_databaseId_/_page.server.ts.js
var page_server_ts_exports64 = {};
__export(page_server_ts_exports64, {
  actions: () => actions41,
  load: () => load67
});
async function list4(cache3) {
  const db2 = cache3.kb;
  const entities = await db2.selectFrom("test_entities").select([
    "id",
    "type",
    "tmdb_id",
    "title",
    "year",
    "poster_path",
    "created_at",
    "updated_at"
  ]).orderBy("title").execute();
  if (entities.length === 0) return [];
  const allReleases = await db2.selectFrom("test_releases").select([
    "id",
    "entity_type",
    "entity_tmdb_id",
    "title",
    "size_bytes",
    "languages",
    "indexers",
    "flags",
    "created_at",
    "updated_at"
  ]).orderBy("entity_type").orderBy("entity_tmdb_id").orderBy("title").execute();
  const releasesMap = /* @__PURE__ */ new Map();
  for (const release of allReleases) {
    const key2 = `${release.entity_type}-${release.entity_tmdb_id}`;
    if (!releasesMap.has(key2)) releasesMap.set(key2, []);
    releasesMap.get(key2).push(release);
  }
  return entities.map((entity) => ({
    ...entity,
    type: entity.type,
    releases: (releasesMap.get(`${entity.type}-${entity.tmdb_id}`) || []).map((r2) => ({
      id: r2.id,
      title: r2.title,
      size_bytes: r2.size_bytes !== null ? Number(r2.size_bytes) : null,
      languages: JSON.parse(r2.languages),
      indexers: JSON.parse(r2.indexers),
      flags: JSON.parse(r2.flags),
      created_at: r2.created_at,
      updated_at: r2.updated_at
    }))
  }));
}
async function getReleaseById(cache3, id) {
  const release = await cache3.kb.selectFrom("test_releases").select([
    "id",
    "entity_type",
    "entity_tmdb_id",
    "title",
    "size_bytes",
    "languages",
    "indexers",
    "flags",
    "created_at",
    "updated_at"
  ]).where("id", "=", id).executeTakeFirst();
  if (!release) return null;
  return {
    id: release.id,
    entity_type: release.entity_type,
    entity_tmdb_id: release.entity_tmdb_id,
    title: release.title,
    size_bytes: release.size_bytes !== null ? Number(release.size_bytes) : null,
    languages: JSON.parse(release.languages),
    indexers: JSON.parse(release.indexers),
    flags: JSON.parse(release.flags),
    created_at: release.created_at,
    updated_at: release.updated_at
  };
}
async function create4(options2) {
  const { databaseId, cache: cache3, layer, inputs } = options2;
  const db2 = cache3.kb;
  const existingEntities = await db2.selectFrom("test_entities").select(["type", "tmdb_id"]).execute();
  const existingKeys = new Set(existingEntities.map((e) => `${e.type}-${e.tmdb_id}`));
  const newInputs = inputs.filter((input) => !existingKeys.has(`${input.type}-${input.tmdbId}`));
  const skippedCount = inputs.length - newInputs.length;
  if (newInputs.length === 0) return {
    success: true,
    added: 0,
    skipped: skippedCount
  };
  const queries = [];
  for (const input of newInputs) {
    const insertEntity = db2.insertInto("test_entities").values({
      type: input.type,
      tmdb_id: input.tmdbId,
      title: input.title,
      year: input.year,
      poster_path: input.posterPath
    }).compile();
    queries.push(insertEntity);
  }
  const name = newInputs.length === 1 ? newInputs[0].title : `${newInputs.length} entities`;
  const entitiesState = newInputs.map((input) => ({
    type: input.type,
    tmdb_id: input.tmdbId,
    title: input.title,
    year: input.year,
    poster_path: input.posterPath
  }));
  return {
    ...await writeOperation({
      databaseId,
      layer,
      description: `create-test-entities`,
      queries,
      desiredState: { entities: entitiesState },
      metadata: {
        operation: "create",
        entity: "test_entity",
        name,
        ...newInputs.length === 1 && { stableKey: {
          key: "test_entity_key",
          value: `${newInputs[0].type}:${newInputs[0].tmdbId}`
        } },
        summary: "Create test entities",
        title: newInputs.length === 1 ? `Create test entity "${newInputs[0].title}"` : `Create ${newInputs.length} test entities`
      }
    }),
    added: newInputs.length,
    skipped: skippedCount
  };
}
async function remove4(options2) {
  const { databaseId, cache: cache3, layer, entityType, entityTmdbId, entityTitle } = options2;
  const db2 = cache3.kb;
  const current3 = await db2.selectFrom("test_entities").select([
    "type",
    "tmdb_id",
    "title",
    "year",
    "poster_path"
  ]).where("type", "=", entityType).where("tmdb_id", "=", entityTmdbId).executeTakeFirst();
  if (!current3) return {
    success: false,
    error: "Test entity not found"
  };
  const releaseCountRow = await db2.selectFrom("test_releases").select(db2.fn.count("id").as("count")).where("entity_type", "=", entityType).where("entity_tmdb_id", "=", entityTmdbId).executeTakeFirst();
  const deleteReleases = db2.deleteFrom("test_releases").where("entity_type", "=", entityType).where("entity_tmdb_id", "=", entityTmdbId).compile();
  let deleteEntity = db2.deleteFrom("test_entities").where("type", "=", entityType).where("tmdb_id", "=", entityTmdbId).where("title", "=", current3.title);
  if (current3.year === null) deleteEntity = deleteEntity.where("year", "is", null);
  else deleteEntity = deleteEntity.where("year", "=", current3.year);
  if (current3.poster_path === null) deleteEntity = deleteEntity.where("poster_path", "is", null);
  else deleteEntity = deleteEntity.where("poster_path", "=", current3.poster_path);
  const deleteEntityQuery = deleteEntity.compile();
  return await writeOperation({
    databaseId,
    layer,
    description: `delete-test-entity-${entityTitle.replace(/[^a-zA-Z0-9]/g, "-").toLowerCase()}`,
    queries: [deleteReleases, deleteEntityQuery],
    desiredState: {
      deleted: true,
      type: current3.type,
      tmdb_id: current3.tmdb_id,
      title: current3.title,
      year: current3.year,
      poster_path: current3.poster_path,
      release_count: releaseCountRow?.count ?? 0
    },
    metadata: {
      operation: "delete",
      entity: "test_entity",
      name: current3.title || entityTitle,
      stableKey: {
        key: "test_entity_key",
        value: `${entityType}:${entityTmdbId}`
      },
      changedFields: ["deleted"],
      summary: "Delete test entity",
      title: `Delete test entity "${current3.title || entityTitle}"`
    }
  });
}
async function createRelease(options2) {
  const { databaseId, cache: cache3, layer, input } = options2;
  const db2 = cache3.kb;
  const entityTitle = (await db2.selectFrom("test_entities").select(["title"]).where("type", "=", input.entityType).where("tmdb_id", "=", input.entityTmdbId).executeTakeFirst())?.title ?? `${input.entityType}:${input.entityTmdbId}`;
  const insertRelease = db2.insertInto("test_releases").values({
    entity_type: input.entityType,
    entity_tmdb_id: input.entityTmdbId,
    title: input.title,
    size_bytes: input.size_bytes,
    languages: JSON.stringify(input.languages),
    indexers: JSON.stringify(input.indexers),
    flags: JSON.stringify(input.flags)
  }).compile();
  return await writeOperation({
    databaseId,
    layer,
    description: `create-test-release`,
    queries: [insertRelease],
    desiredState: {
      entity_type: input.entityType,
      entity_tmdb_id: input.entityTmdbId,
      title: input.title,
      size_bytes: input.size_bytes,
      languages: input.languages,
      indexers: input.indexers,
      flags: input.flags
    },
    metadata: {
      operation: "create",
      entity: "test_release",
      name: input.title.substring(0, 50),
      stableKey: {
        key: "test_release_key",
        value: `${input.entityType}:${input.entityTmdbId}:${input.title}`
      },
      summary: "Create test release",
      title: `Create test release for "${entityTitle}"`
    }
  });
}
async function createReleases(options2) {
  const { databaseId, cache: cache3, layer, inputs } = options2;
  const db2 = cache3.kb;
  if (inputs.length === 0) return {
    success: true,
    added: 0,
    skipped: 0
  };
  const entityType = inputs[0].entityType;
  const entityTmdbId = inputs[0].entityTmdbId;
  const entityTitle = (await db2.selectFrom("test_entities").select(["title"]).where("type", "=", entityType).where("tmdb_id", "=", entityTmdbId).executeTakeFirst())?.title ?? `${entityType}:${entityTmdbId}`;
  const existingReleases = await db2.selectFrom("test_releases").select(["title"]).where("entity_type", "=", entityType).where("entity_tmdb_id", "=", entityTmdbId).execute();
  const existingTitles = new Set(existingReleases.map((r2) => r2.title));
  const newInputs = inputs.filter((input) => !existingTitles.has(input.title));
  const skippedCount = inputs.length - newInputs.length;
  if (newInputs.length === 0) return {
    success: true,
    added: 0,
    skipped: skippedCount
  };
  const queries = [];
  for (const input of newInputs) {
    const insertRelease = db2.insertInto("test_releases").values({
      entity_type: input.entityType,
      entity_tmdb_id: input.entityTmdbId,
      title: input.title,
      size_bytes: input.size_bytes,
      languages: JSON.stringify(input.languages),
      indexers: JSON.stringify(input.indexers),
      flags: JSON.stringify(input.flags)
    }).compile();
    queries.push(insertRelease);
  }
  return {
    ...await writeOperation({
      databaseId,
      layer,
      description: `import-test-releases`,
      queries,
      desiredState: {
        entity_type: entityType,
        entity_tmdb_id: entityTmdbId,
        releases: newInputs.map((input) => ({
          title: input.title,
          size_bytes: input.size_bytes,
          languages: input.languages,
          indexers: input.indexers,
          flags: input.flags
        }))
      },
      metadata: {
        operation: "create",
        entity: "test_release",
        name: `${newInputs.length} releases`,
        summary: "Import test releases",
        title: `Import ${newInputs.length} test releases for "${entityTitle}"`
      }
    }),
    added: newInputs.length,
    skipped: skippedCount
  };
}
async function updateRelease(options2) {
  const { databaseId, cache: cache3, layer, current: current3, input } = options2;
  const db2 = cache3.kb;
  const currentLanguages = JSON.stringify(current3.languages);
  const currentIndexers = JSON.stringify(current3.indexers);
  const currentFlags = JSON.stringify(current3.flags);
  const nextLanguages = JSON.stringify(input.languages);
  const nextIndexers = JSON.stringify(input.indexers);
  const nextFlags = JSON.stringify(input.flags);
  const setParts = {};
  if (current3.title !== input.title) setParts.title = input.title;
  if (current3.size_bytes !== input.size_bytes) setParts.size_bytes = input.size_bytes;
  if (currentLanguages !== nextLanguages) setParts.languages = nextLanguages;
  if (currentIndexers !== nextIndexers) setParts.indexers = nextIndexers;
  if (currentFlags !== nextFlags) setParts.flags = nextFlags;
  let updateQuery = db2.updateTable("test_releases").set(setParts).where("entity_type", "=", current3.entity_type).where("entity_tmdb_id", "=", current3.entity_tmdb_id).where("title", "=", current3.title);
  if (current3.size_bytes !== input.size_bytes) if (current3.size_bytes === null) updateQuery = updateQuery.where("size_bytes", "is", null);
  else updateQuery = updateQuery.where("size_bytes", "=", current3.size_bytes);
  if (currentLanguages !== nextLanguages) updateQuery = updateQuery.where("languages", "=", currentLanguages);
  if (currentIndexers !== nextIndexers) updateQuery = updateQuery.where("indexers", "=", currentIndexers);
  if (currentFlags !== nextFlags) updateQuery = updateQuery.where("flags", "=", currentFlags);
  if (Object.keys(setParts).length === 0) return { success: true };
  const updateQueryCompiled = updateQuery.compile();
  const changedFields = [];
  if (current3.title !== input.title) changedFields.push("title");
  if (current3.size_bytes !== input.size_bytes) changedFields.push("size_bytes");
  if (currentLanguages !== nextLanguages) changedFields.push("languages");
  if (currentIndexers !== nextIndexers) changedFields.push("indexers");
  if (currentFlags !== nextFlags) changedFields.push("flags");
  const desiredState = {};
  if (current3.title !== input.title) desiredState.title = {
    from: current3.title,
    to: input.title
  };
  if (current3.size_bytes !== input.size_bytes) desiredState.size_bytes = {
    from: current3.size_bytes,
    to: input.size_bytes
  };
  if (currentLanguages !== nextLanguages) desiredState.languages = {
    from: current3.languages,
    to: input.languages
  };
  if (currentIndexers !== nextIndexers) desiredState.indexers = {
    from: current3.indexers,
    to: input.indexers
  };
  if (currentFlags !== nextFlags) desiredState.flags = {
    from: current3.flags,
    to: input.flags
  };
  return await writeOperation({
    databaseId,
    layer,
    description: `update-test-release-${current3.id}`,
    queries: [updateQueryCompiled],
    desiredState,
    metadata: {
      operation: "update",
      entity: "test_release",
      name: input.title.substring(0, 50),
      ...current3.title !== input.title && { previousName: current3.title.substring(0, 50) },
      stableKey: {
        key: "test_release_key",
        value: `${current3.entity_type}:${current3.entity_tmdb_id}:${current3.title}`
      },
      changedFields,
      summary: "Update test release",
      title: `Update test release "${input.title.substring(0, 50)}"`
    }
  });
}
async function deleteRelease(options2) {
  const { databaseId, cache: cache3, layer, current: current3 } = options2;
  const db2 = cache3.kb;
  const currentLanguages = JSON.stringify(current3.languages);
  const currentIndexers = JSON.stringify(current3.indexers);
  const currentFlags = JSON.stringify(current3.flags);
  let deleteQuery = db2.deleteFrom("test_releases").where("entity_type", "=", current3.entity_type).where("entity_tmdb_id", "=", current3.entity_tmdb_id).where("title", "=", current3.title).where("languages", "=", currentLanguages).where("indexers", "=", currentIndexers).where("flags", "=", currentFlags);
  if (current3.size_bytes === null) deleteQuery = deleteQuery.where("size_bytes", "is", null);
  else deleteQuery = deleteQuery.where("size_bytes", "=", current3.size_bytes);
  const deleteQueryCompiled = deleteQuery.compile();
  return await writeOperation({
    databaseId,
    layer,
    description: `delete-test-release-${current3.id}`,
    queries: [deleteQueryCompiled],
    desiredState: {
      deleted: true,
      entity_type: current3.entity_type,
      entity_tmdb_id: current3.entity_tmdb_id,
      title: current3.title,
      size_bytes: current3.size_bytes,
      languages: current3.languages,
      indexers: current3.indexers,
      flags: current3.flags
    },
    metadata: {
      operation: "delete",
      entity: "test_release",
      name: current3.title.substring(0, 50),
      stableKey: {
        key: "test_release_key",
        value: `${current3.entity_type}:${current3.entity_tmdb_id}:${current3.title}`
      },
      changedFields: ["deleted"],
      summary: "Delete test release",
      title: `Delete test release "${current3.title.substring(0, 50)}"`
    }
  });
}
var load67, actions41;
var init_page_server_ts64 = __esm({
  async "dist/build/server/entries/pages/quality-profiles/entity-testing/_databaseId_/_page.server.ts.js"() {
    "use strict";
    await init_arrInstances();
    await init_queueService();
    await init_client2();
    await init_parser();
    await init_tmdbSettings();
    await init_lastDatabase();
    init_exports();
    load67 = async ({ params, cookies }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const databases = pcdManager.getAllPublic();
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = databases.find((db2) => db2.id === currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      setLastDatabase(cookies, "last_db_et", currentDatabaseId);
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const testEntities = await list4(cache3);
      const qualityProfiles = await select(cache3);
      const cfScoresData = await allCfScores(cache3);
      return {
        databases,
        currentDatabase,
        tmdbConfigured: !!tmdbSettingsQueries.get()?.api_key,
        parserAvailable: await isParserHealthy(),
        testEntities,
        qualityProfiles,
        cfScoresData,
        arrInstances: arrInstancesQueries.getEnabled().map((instance) => ({
          id: instance.id,
          name: instance.name,
          type: instance.type
        })),
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions41 = {
      addEntities: async ({ request, params }) => {
        const { databaseId } = params;
        if (!databaseId) return fail(400, { error: "Missing database ID" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        if (!canWriteToBase(currentDatabaseId)) return fail(403, { error: "Entity tests are read-only for this database" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const formData = await request.formData();
        const entitiesJson = formData.get("entities");
        const layer = formData.get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer for this database" });
        let entities;
        try {
          entities = JSON.parse(entitiesJson || "[]");
        } catch {
          return fail(400, { error: "Invalid entities format" });
        }
        if (entities.length === 0) return fail(400, { error: "No entities to add" });
        const result = await create4({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          inputs: entities
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to add entities" });
        return {
          success: true,
          added: result.added,
          skipped: result.skipped
        };
      },
      deleteEntity: async ({ request, params }) => {
        const { databaseId } = params;
        if (!databaseId) return fail(400, { error: "Missing database ID" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        if (!canWriteToBase(currentDatabaseId)) return fail(403, { error: "Entity tests are read-only for this database" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const formData = await request.formData();
        const entityType = formData.get("entityType");
        const entityTmdbId = parseInt(formData.get("entityTmdbId"), 10);
        const entityTitle = formData.get("entityTitle");
        const layer = formData.get("layer") || "user";
        if (!entityType || !["movie", "series"].includes(entityType)) return fail(400, { error: "Invalid entity type" });
        if (isNaN(entityTmdbId)) return fail(400, { error: "Invalid entity TMDB ID" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer for this database" });
        const result = await remove4({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          entityType,
          entityTmdbId,
          entityTitle: entityTitle || "Unknown"
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete entity" });
        return { success: true };
      },
      createRelease: async ({ request, params }) => {
        const { databaseId } = params;
        if (!databaseId) return fail(400, { error: "Missing database ID" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        if (!canWriteToBase(currentDatabaseId)) return fail(403, { error: "Entity tests are read-only for this database" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const formData = await request.formData();
        const releaseJson = formData.get("release");
        const layer = formData.get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer for this database" });
        let release;
        try {
          release = JSON.parse(releaseJson || "{}");
        } catch {
          return fail(400, { error: "Invalid release format" });
        }
        if (!release.title) return fail(400, { error: "Release title is required" });
        const result = await createRelease({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          input: release
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to create release" });
        return { success: true };
      },
      updateRelease: async ({ request, params }) => {
        const { databaseId } = params;
        if (!databaseId) return fail(400, { error: "Missing database ID" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        if (!canWriteToBase(currentDatabaseId)) return fail(403, { error: "Entity tests are read-only for this database" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const formData = await request.formData();
        const releaseJson = formData.get("release");
        const layer = formData.get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer for this database" });
        let release;
        try {
          release = JSON.parse(releaseJson || "{}");
        } catch {
          return fail(400, { error: "Invalid release format" });
        }
        if (!release.id) return fail(400, { error: "Release ID is required" });
        if (!release.title) return fail(400, { error: "Release title is required" });
        const currentRelease = await getReleaseById(cache3, release.id);
        if (!currentRelease) return fail(404, { error: "Release not found" });
        const result = await updateRelease({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          current: currentRelease,
          input: {
            title: release.title,
            size_bytes: release.size_bytes,
            languages: release.languages,
            indexers: release.indexers,
            flags: release.flags
          }
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to update release" });
        return { success: true };
      },
      deleteRelease: async ({ request, params }) => {
        const { databaseId } = params;
        if (!databaseId) return fail(400, { error: "Missing database ID" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        if (!canWriteToBase(currentDatabaseId)) return fail(403, { error: "Entity tests are read-only for this database" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const formData = await request.formData();
        const releaseId = parseInt(formData.get("releaseId"), 10);
        const layer = formData.get("layer") || "user";
        if (isNaN(releaseId)) return fail(400, { error: "Invalid release ID" });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer for this database" });
        const currentRelease = await getReleaseById(cache3, releaseId);
        if (!currentRelease) return fail(404, { error: "Release not found" });
        const result = await deleteRelease({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          current: currentRelease
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to delete release" });
        return { success: true };
      },
      importReleases: async ({ request, params }) => {
        const { databaseId } = params;
        if (!databaseId) return fail(400, { error: "Missing database ID" });
        const currentDatabaseId = parseInt(databaseId, 10);
        if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
        if (!canWriteToBase(currentDatabaseId)) return fail(403, { error: "Entity tests are read-only for this database" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const formData = await request.formData();
        const releasesJson = formData.get("releases");
        const layer = formData.get("layer") || "user";
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer for this database" });
        let releases;
        try {
          releases = JSON.parse(releasesJson || "[]");
        } catch {
          return fail(400, { error: "Invalid releases format" });
        }
        if (releases.length === 0) return fail(400, { error: "No releases to import" });
        const result = await createReleases({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          inputs: releases
        });
        if (!result.success) return fail(500, { error: result.error || "Failed to import releases" });
        return {
          success: true,
          added: result.added,
          skipped: result.skipped
        };
      }
    };
  }
});

// dist/build/server/entries/pages/quality-profiles/entity-testing/_databaseId_/_page.svelte.js
var page_svelte_exports62 = {};
__export(page_svelte_exports62, {
  default: () => _page62
});
function Arrow_down_a_z($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "arrow-down-a-z" },
    props,
    { iconNode: [
      ["path", { "d": "m3 16 4 4 4-4" }],
      ["path", { "d": "M7 20V4" }],
      ["path", { "d": "M20 8h-5" }],
      ["path", { "d": "M15 10V6.5a2.5 2.5 0 0 1 5 0V10" }],
      ["path", { "d": "M15 14h5l-5 6h5" }]
    ] }
  ]));
}
function Bookmark($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "bookmark" },
    props,
    { iconNode: [["path", { "d": "M17 3a2 2 0 0 1 2 2v15a1 1 0 0 1-1.496.868l-4.512-2.578a2 2 0 0 0-1.984 0l-4.512 2.578A1 1 0 0 1 5 20V5a2 2 0 0 1 2-2z" }]] }
  ]));
}
function Import($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "import" },
    props,
    { iconNode: [
      ["path", { "d": "M12 3v12" }],
      ["path", { "d": "m8 11 4 4 4-4" }],
      ["path", { "d": "M8 5H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-4" }]
    ] }
  ]));
}
function SelectableContainer($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let paddingClass;
    let padding = fallback($$props["padding"], "none");
    $: paddingClass = {
      none: "",
      sm: "p-2",
      md: "p-4"
    }[padding];
    $$renderer2.push(`<div${attr_class(`divide-y divide-neutral-200 overflow-hidden rounded-xl border border-neutral-300 dark:divide-neutral-700/40 dark:border-neutral-700/60 ${stringify(paddingClass)}`)}><!--[-->`);
    slot($$renderer2, $$props, "default", {}, null);
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, { padding });
  });
}
function SelectableRow($$renderer, $$props) {
  let checked = fallback($$props["checked"], false);
  let disabled = fallback($$props["disabled"], false);
  let icon = fallback($$props["icon"], Check);
  let checkColor = fallback($$props["checkColor"], "accent");
  $$renderer.push(`<button type="button"${attr_class(`flex w-full items-center justify-between gap-3 bg-white p-3 text-left transition-colors dark:bg-neutral-900/50 ${disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer hover:bg-neutral-50 dark:hover:bg-neutral-800"}`)}${attr("disabled", disabled, true)}><div class="min-w-0 flex-1"><!--[-->`);
  slot($$renderer, $$props, "default", {}, null);
  $$renderer.push(`<!--]--></div> `);
  IconCheckbox($$renderer, {
    checked,
    icon,
    color: checkColor
  });
  $$renderer.push(`<!----></button>`);
  bind_props($$props, {
    checked,
    disabled,
    icon,
    checkColor
  });
}
function AddEntityModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let existingKeys, sortedResults, entitiesJson;
    let open = fallback($$props["open"], false);
    let actionUrl = fallback($$props["actionUrl"], "?/addEntities");
    let existingEntities = fallback($$props["existingEntities"], () => [], true);
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let tmdbConfigured = fallback($$props["tmdbConfigured"], true);
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    function isAlreadyAdded(item) {
      return existingKeys.has(`${item.type}-${item.id}`);
    }
    let searchStore;
    let activeQuery = "";
    let results = [];
    let selectedItems = /* @__PURE__ */ new Map();
    let selectedKeys = /* @__PURE__ */ new Set();
    function getItemKey(item) {
      return `${item.type}-${item.id}`;
    }
    let moviesSelected = true;
    let seriesSelected = true;
    function getYear(dateString) {
      if (!dateString) return "";
      return dateString.split("-")[0];
    }
    function getPosterUrl2(path) {
      if (!path) return "";
      return `https://image.tmdb.org/t/p/w92${path}`;
    }
    $: existingKeys = new Set(existingEntities.map((e) => `${e.type}-${e.tmdb_id}`));
    $: searchStore = getPersistentSearchStore(`entityTestingAddEntitySearch:${store_get($$store_subs ??= {}, "$page", page).params.databaseId}`);
    $: sortedResults = (() => {
      const sorted = [...results];
      sorted.sort((a2, b3) => {
        let cmp = 0;
        cmp = a2.popularity - b3.popularity;
        return -cmp;
      });
      return sorted;
    })();
    $: entitiesJson = JSON.stringify(Array.from(selectedItems.values()).map((item) => ({
      type: item.type,
      tmdbId: item.id,
      title: item.title,
      year: item.releaseDate ? parseInt(item.releaseDate.split("-")[0], 10) : null,
      posterPath: item.posterPath
    })));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      Modal($$renderer3, {
        header: "Add Test Entity",
        confirmText: "Add",
        confirmDisabled: !tmdbConfigured,
        size: "xl",
        bodyOverflow: "visible",
        get open() {
          return open;
        },
        set open($$value) {
          open = $$value;
          $$settled = false;
        },
        $$slots: { body: ($$renderer4) => {
          $$renderer4.push(`<div slot="body" class="space-y-4">`);
          if (!tmdbConfigured) {
            $$renderer4.push("<!--[0-->");
            $$renderer4.push(`<div class="rounded-lg border border-neutral-200 bg-neutral-50 p-4 dark:border-neutral-700 dark:bg-neutral-800"><p class="text-sm text-neutral-600 dark:text-neutral-300">TMDB API key not configured. Please add your API key in <a href="/settings/general" class="font-medium text-accent-600 hover:underline dark:text-accent-400">Settings</a> to search for movies and TV series.</p></div>`);
          } else {
            $$renderer4.push("<!--[-1-->");
            ActionsBar($$renderer4, {
              children: ($$renderer5) => {
                SearchAction($$renderer5, {
                  searchStore,
                  placeholder: "Search TMDB... (press Enter)",
                  activeQuery
                });
                $$renderer5.push(`<!----> `);
                ActionButton($$renderer5, {
                  icon: Clapperboard,
                  hasDropdown: true,
                  dropdownPosition: "right",
                  $$slots: { dropdown: ($$renderer6, { dropdownPosition }) => {
                    Dropdown($$renderer6, {
                      position: dropdownPosition,
                      children: ($$renderer7) => {
                        DropdownHeader($$renderer7, { label: "Media type" });
                        $$renderer7.push(`<!----> `);
                        DropdownItem($$renderer7, {
                          icon: Film,
                          label: "Movies",
                          selected: moviesSelected
                        });
                        $$renderer7.push(`<!----> `);
                        DropdownItem($$renderer7, {
                          icon: Tv,
                          label: "TV Series",
                          selected: seriesSelected
                        });
                        $$renderer7.push(`<!---->`);
                      },
                      $$slots: { default: true }
                    });
                  } }
                });
                $$renderer5.push(`<!----> `);
                ActionButton($$renderer5, {
                  icon: Arrow_down_a_z,
                  hasDropdown: true,
                  dropdownPosition: "right",
                  $$slots: { dropdown: ($$renderer6, { dropdownPosition }) => {
                    Dropdown($$renderer6, {
                      position: dropdownPosition,
                      children: ($$renderer7) => {
                        DropdownHeader($$renderer7, { label: "Sort by" });
                        $$renderer7.push(`<!----> `);
                        DropdownItem($$renderer7, {
                          label: "Popularity",
                          selected: true
                        });
                        $$renderer7.push(`<!----> `);
                        DropdownItem($$renderer7, {
                          label: "Rating",
                          selected: false
                        });
                        $$renderer7.push(`<!----> `);
                        DropdownItem($$renderer7, {
                          label: "Title",
                          selected: false
                        });
                        $$renderer7.push(`<!----> `);
                        DropdownItem($$renderer7, {
                          label: "Year",
                          selected: false
                        });
                        $$renderer7.push(`<!---->`);
                      },
                      $$slots: { default: true }
                    });
                  } }
                });
                $$renderer5.push(`<!---->`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            if (results.length > 0) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="max-h-96 overflow-hidden overflow-y-auto rounded-xl border border-neutral-300 bg-white dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
              if (results.length === 0) {
                $$renderer4.push("<!--[1-->");
                $$renderer4.push(`<div class="p-8 text-center text-neutral-500 dark:text-neutral-400">No results found</div>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                SelectableContainer($$renderer4, {
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!--[-->`);
                    const each_array = ensure_array_like(sortedResults);
                    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                      let item = each_array[$$index];
                      const alreadyAdded = isAlreadyAdded(item);
                      SelectableRow($$renderer5, {
                        checked: selectedKeys.has(getItemKey(item)),
                        disabled: alreadyAdded,
                        children: ($$renderer6) => {
                          $$renderer6.push(`<div class="flex gap-3"><div class="h-24 w-16 flex-shrink-0 overflow-hidden rounded bg-neutral-200 dark:bg-neutral-700">`);
                          if (item.posterPath) {
                            $$renderer6.push("<!--[0-->");
                            $$renderer6.push(`<img${attr("src", getPosterUrl2(item.posterPath))}${attr("alt", item.title)} class="h-full w-full object-cover"/>`);
                          } else {
                            $$renderer6.push("<!--[-1-->");
                            $$renderer6.push(`<div class="flex h-full w-full items-center justify-center">`);
                            if (item.type === "movie") {
                              $$renderer6.push("<!--[0-->");
                              Film($$renderer6, {
                                size: 24,
                                class: "text-neutral-400"
                              });
                            } else {
                              $$renderer6.push("<!--[-1-->");
                              Tv($$renderer6, {
                                size: 24,
                                class: "text-neutral-400"
                              });
                            }
                            $$renderer6.push(`<!--]--></div>`);
                          }
                          $$renderer6.push(`<!--]--></div> <div class="flex min-w-0 flex-1 flex-col"><div class="flex items-start gap-2"><div class="min-w-0 flex-1"><h4 class="truncate font-medium text-neutral-900 dark:text-neutral-100">${escape_html(item.title)}</h4> <div class="flex items-center gap-2 text-xs text-neutral-500 dark:text-neutral-400"><span class="flex items-center gap-1">`);
                          if (item.type === "movie") {
                            $$renderer6.push("<!--[0-->");
                            Film($$renderer6, { size: 12 });
                            $$renderer6.push(`<!----> Movie`);
                          } else {
                            $$renderer6.push("<!--[-1-->");
                            Tv($$renderer6, { size: 12 });
                            $$renderer6.push(`<!----> TV Series`);
                          }
                          $$renderer6.push(`<!--]--></span> `);
                          if (getYear(item.releaseDate)) {
                            $$renderer6.push("<!--[0-->");
                            $$renderer6.push(`<span>\u2022</span> <span>${escape_html(getYear(item.releaseDate))}</span>`);
                          } else $$renderer6.push("<!--[-1-->");
                          $$renderer6.push(`<!--]--></div></div> `);
                          if (item.voteAverage > 0) {
                            $$renderer6.push("<!--[0-->");
                            Badge($$renderer6, {
                              variant: "accent",
                              size: "sm",
                              icon: Star,
                              children: ($$renderer7) => {
                                $$renderer7.push(`<!---->${escape_html(item.voteAverage.toFixed(1))}`);
                              },
                              $$slots: { default: true }
                            });
                          } else $$renderer6.push("<!--[-1-->");
                          $$renderer6.push(`<!--]--></div> <p class="mt-1 line-clamp-2 text-xs text-neutral-600 dark:text-neutral-400">${escape_html(item.overview || "No description available")}</p></div></div>`);
                        },
                        $$slots: { default: true }
                      });
                    }
                    $$renderer5.push(`<!--]-->`);
                  },
                  $$slots: { default: true }
                });
              }
              $$renderer4.push(`<!--]--></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> <div class="space-y-2"><div class="text-sm font-medium text-neutral-700 dark:text-neutral-300">Selected (${escape_html(selectedItems.size)})</div> <div class="flex flex-wrap gap-2"><!--[-->`);
            const each_array_1 = ensure_array_like(Array.from(selectedItems.values()));
            for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
              let item = each_array_1[$$index_1];
              $$renderer4.push(`<div class="cursor-pointer">`);
              Label($$renderer4, {
                variant: "secondary",
                size: "md",
                rounded: "md",
                children: ($$renderer5) => {
                  if (item.type === "movie") {
                    $$renderer5.push("<!--[0-->");
                    Film($$renderer5, { size: 12 });
                  } else {
                    $$renderer5.push("<!--[-1-->");
                    Tv($$renderer5, { size: 12 });
                  }
                  $$renderer5.push(`<!--]--> ${escape_html(item.title)} `);
                  X2($$renderer5, { size: 12 });
                  $$renderer5.push(`<!---->`);
                },
                $$slots: { default: true }
              });
              $$renderer4.push(`<!----></div>`);
            }
            $$renderer4.push(`<!--]--></div></div> <form method="POST"${attr("action", actionUrl)} class="hidden"><input type="hidden" name="entities"${attr("value", entitiesJson)}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/></form>`);
          }
          $$renderer4.push(`<!--]--></div>`);
        } }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      open,
      actionUrl,
      existingEntities,
      canWriteToBase: canWriteToBase2,
      tmdbConfigured
    });
  });
}
function QuickParseModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let profileOptions, releaseTypeOptions, releasePlaceholder, numericProfileId, score, matchingFormats;
    let open = fallback($$props["open"], false);
    let databaseId = $$props["databaseId"];
    let qualityProfiles = $$props["qualityProfiles"];
    let cfScoresData = $$props["cfScoresData"];
    let parserAvailable = $$props["parserAvailable"];
    let title = "";
    let selectedProfileId = "";
    let selectedReleaseType = "movie";
    let evaluation = null;
    let error2 = null;
    let selectedArrType = "radarr";
    let debounceTimer;
    async function parse4(value2, releaseType) {
      const trimmed = value2.trim();
      if (!trimmed || !parserAvailable) return;
      error2 = null;
      try {
        const response = await fetch(`/quality-profiles/entity-testing/${databaseId}/evaluate`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ releases: [{
            id: -1,
            title: trimmed,
            type: releaseType
          }] })
        });
        if (!response.ok) throw new Error("Failed to parse release");
        const result = await response.json();
        if (title.trim() !== trimmed || selectedReleaseType !== releaseType) return;
        evaluation = result.evaluations?.[0] ?? null;
      } catch (err) {
        if (title.trim() !== trimmed || selectedReleaseType !== releaseType) return;
        error2 = err instanceof Error ? err.message : "Failed to parse release";
      } finally {
        if (title.trim() === trimmed && selectedReleaseType === releaseType) {
        }
      }
    }
    function calculateScore() {
      if (!numericProfileId || !evaluation?.cfMatches) return null;
      const profile = qualityProfiles.find((p2) => p2.id === numericProfileId);
      if (!profile) return null;
      const profileScores = cfScoresData.profiles.find((p2) => p2.profileName === profile.name);
      if (!profileScores) return null;
      let totalScore = 0;
      for (const [cfName, matched] of Object.entries(evaluation.cfMatches)) {
        if (!matched) continue;
        const cfScore = profileScores.scores[cfName];
        if (cfScore) {
          const score2 = cfScore[selectedArrType];
          if (score2 !== null) totalScore += score2;
        }
      }
      return totalScore;
    }
    function getMatchingFormats() {
      if (!evaluation?.cfMatches || !numericProfileId) return [];
      const profile = qualityProfiles.find((p2) => p2.id === numericProfileId);
      if (!profile) return [];
      const profileScores = cfScoresData.profiles.find((p2) => p2.profileName === profile.name);
      if (!profileScores) return [];
      const matches = [];
      for (const [cfName, matched] of Object.entries(evaluation.cfMatches)) {
        if (!matched) continue;
        const cfScore = profileScores.scores[cfName];
        if (cfScore) {
          const score2 = cfScore[selectedArrType];
          if (score2 !== null && score2 !== 0) matches.push({
            name: cfName,
            score: score2
          });
        }
      }
      return matches.sort((a2, b3) => Math.abs(b3.score) - Math.abs(a2.score));
    }
    $: profileOptions = [{
      value: "",
      label: "No Profile"
    }, ...qualityProfiles.map((p2) => ({
      value: String(p2.id),
      label: p2.name
    }))];
    $: releaseTypeOptions = [{
      value: "movie",
      label: "Movie",
      icon: Film
    }, {
      value: "series",
      label: "Series",
      icon: Tv
    }];
    $: if (open) {
      title = "";
      selectedProfileId = "";
      evaluation = null;
      error2 = null;
    }
    $: {
      clearTimeout(debounceTimer);
      if (title) debounceTimer = setTimeout(() => {
        parse4(title, selectedReleaseType);
      }, 400);
      else {
        evaluation = null;
        error2 = null;
      }
    }
    $: selectedArrType = "radarr";
    $: releasePlaceholder = "Movie.2024.2160p.UHD.BluRay.REMUX.DV.HDR.DTS-HD.MA.7.1-GROUP";
    $: numericProfileId = selectedProfileId ? parseInt(selectedProfileId, 10) : null;
    $: score = evaluation ? calculateScore() : null;
    $: matchingFormats = evaluation ? getMatchingFormats() : [];
    $: if (selectedProfileId !== void 0) {
      score = evaluation ? calculateScore() : null;
      matchingFormats = evaluation ? getMatchingFormats() : [];
    }
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      Modal($$renderer3, {
        header: "Quick Parse",
        size: "xl",
        get open() {
          return open;
        },
        set open($$value) {
          open = $$value;
          $$settled = false;
        },
        $$slots: {
          "header-extra": ($$renderer4) => {
            $$renderer4.push(`<div class="ml-auto flex items-center gap-2">`);
            DropdownSelect($$renderer4, {
              value: selectedReleaseType,
              options: releaseTypeOptions,
              position: "right",
              minWidth: "8rem"
            });
            $$renderer4.push(`<!----> `);
            DropdownSelect($$renderer4, {
              value: selectedProfileId,
              options: profileOptions,
              placeholder: "No Profile",
              position: "right",
              minWidth: "16rem"
            });
            $$renderer4.push(`<!----></div>`);
          },
          body: ($$renderer4) => {
            $$renderer4.push(`<div slot="body" class="space-y-4">`);
            if (!parserAvailable) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="flex items-center gap-2 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-700 dark:border-amber-800/50 dark:bg-amber-900/20 dark:text-amber-400">`);
              Triangle_alert($$renderer4, { size: 16 });
              $$renderer4.push(`<!----> Parser service unavailable. Release parsing is disabled.</div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            FormInput($$renderer4, {
              label: "Release Title",
              description: "Paste a full release title to parse and score",
              placeholder: releasePlaceholder,
              mono: true,
              size: "sm",
              get value() {
                return title;
              },
              set value($$value) {
                title = $$value;
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            if (error2) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-red-800/50 dark:bg-red-900/20 dark:text-red-400">${escape_html(error2)}</div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            if (evaluation) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="space-y-3 rounded-lg border border-neutral-200 bg-neutral-50 p-4 dark:border-neutral-800 dark:bg-neutral-900/50">`);
              if (numericProfileId) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="flex items-center gap-2 text-sm"><span class="font-medium text-neutral-500 dark:text-neutral-400">Score</span> `);
                Score($$renderer4, { score });
                $$renderer4.push(`<!----></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> `);
              if (evaluation.parsed) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="space-y-2 text-xs"><div class="font-medium text-neutral-500 dark:text-neutral-400">Parsed</div> <div class="flex flex-wrap items-center gap-2"><span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                Hard_drive($$renderer4, {
                  size: 12,
                  class: "text-blue-500"
                });
                $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Source</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.source)}</span></span> <span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                Layers($$renderer4, {
                  size: 12,
                  class: "text-indigo-500"
                });
                $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Resolution</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.resolution)}</span></span> `);
                if (evaluation.parsed.modifier !== "None") {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                  Tag($$renderer4, {
                    size: 12,
                    class: "text-amber-500"
                  });
                  $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Modifier</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.modifier)}</span></span>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                if (evaluation.parsed.releaseGroup) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                  Users($$renderer4, {
                    size: 12,
                    class: "text-teal-500"
                  });
                  $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Group</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.releaseGroup)}</span></span>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                if (evaluation.parsed.edition) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                  Bookmark($$renderer4, {
                    size: 12,
                    class: "text-orange-500"
                  });
                  $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Edition</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.edition)}</span></span>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                if (evaluation.parsed.languages.length > 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                  Earth($$renderer4, {
                    size: 12,
                    class: "text-emerald-500"
                  });
                  $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Languages</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.languages.join(", "))}</span> <span class="text-[10px] text-neutral-400 dark:text-neutral-500">(${escape_html(evaluation.parsed.languageSource)})</span></span>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--></div></div>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--> <div class="space-y-2 text-xs"><div class="font-medium text-neutral-500 dark:text-neutral-400">Formats</div> <div>`);
              if (!numericProfileId) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<span class="text-neutral-400 italic">Select a quality profile to see scores.</span>`);
              } else if (matchingFormats.length === 0) {
                $$renderer4.push("<!--[1-->");
                $$renderer4.push(`<span class="text-neutral-400 italic">No custom formats matched with non-zero scores.</span>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<div class="flex flex-wrap gap-2"><!--[-->`);
                const each_array = ensure_array_like(matchingFormats);
                for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                  let cf = each_array[$$index];
                  CustomFormatBadge($$renderer4, {
                    name: cf.name,
                    score: cf.score
                  });
                }
                $$renderer4.push(`<!--]--></div>`);
              }
              $$renderer4.push(`<!--]--></div></div></div>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></div>`);
          },
          footer: ($$renderer4) => {
            $$renderer4.push(`<div></div> `);
            Button($$renderer4, {
              text: "Close",
              icon: X2
            });
            $$renderer4.push(`<!---->`);
          }
        }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      open,
      databaseId,
      qualityProfiles,
      cfScoresData,
      parserAvailable
    });
  });
}
function ReleaseModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let actionUrl, modalHeader, confirmText, releaseJson;
    let open = fallback($$props["open"], false);
    let mode = fallback($$props["mode"], "create");
    let entityType = $$props["entityType"];
    let entityTmdbId = $$props["entityTmdbId"];
    let release = fallback($$props["release"], null);
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    let title = "";
    let sizeGb = "";
    let languages = [];
    let indexers = [];
    let flags2 = [];
    function gbToBytes(gb) {
      const num = parseFloat(gb);
      if (isNaN(num) || num <= 0) return null;
      return Math.round(num * 1024 * 1024 * 1024);
    }
    $: if (open) if (mode === "edit" && release) {
      title = release.title;
      sizeGb = release.size_bytes ? (release.size_bytes / 1073741824).toFixed(2) : "";
      languages = [...release.languages];
      indexers = [...release.indexers];
      flags2 = [...release.flags];
    } else {
      title = "";
      sizeGb = "";
      languages = [];
      indexers = [];
      flags2 = [];
    }
    $: actionUrl = mode === "create" ? "?/createRelease" : "?/updateRelease";
    $: modalHeader = mode === "create" ? "Add Test Release" : "Edit Test Release";
    $: confirmText = mode === "create" ? "Add" : "Save";
    $: releaseJson = JSON.stringify({
      id: release?.id,
      entityType,
      entityTmdbId,
      title,
      size_bytes: gbToBytes(sizeGb),
      languages,
      indexers,
      flags: flags2
    });
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      Modal($$renderer3, {
        header: modalHeader,
        confirmText,
        size: "lg",
        get open() {
          return open;
        },
        set open($$value) {
          open = $$value;
          $$settled = false;
        },
        $$slots: { body: ($$renderer4) => {
          $$renderer4.push(`<div slot="body" class="space-y-4">`);
          FormInput($$renderer4, {
            label: "Release Title",
            description: "The full release title (e.g., Movie.2024.1080p.BluRay.REMUX-GROUP)",
            placeholder: "Movie.2024.1080p.BluRay.REMUX-GROUP",
            required: true,
            get value() {
              return title;
            },
            set value($$value) {
              title = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----> `);
          FormInput($$renderer4, {
            label: "Size (GB)",
            description: "File size in gigabytes",
            placeholder: "15.5",
            type: "number",
            get value() {
              return sizeGb;
            },
            set value($$value) {
              sizeGb = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----> <div class="space-y-1"><span class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">Languages</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Press Enter to add languages</p> `);
          TagInput($$renderer4, {
            placeholder: "Type language and press Enter",
            get tags() {
              return languages;
            },
            set tags($$value) {
              languages = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----></div> <div class="space-y-1"><span class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">Indexers</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Press Enter to add indexers</p> `);
          TagInput($$renderer4, {
            placeholder: "Type indexer and press Enter",
            get tags() {
              return indexers;
            },
            set tags($$value) {
              indexers = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----></div> <div class="space-y-1"><span class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">Flags</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">Press Enter to add flags (e.g., freeleech, scene)</p> `);
          TagInput($$renderer4, {
            placeholder: "Type flag and press Enter",
            get tags() {
              return flags2;
            },
            set tags($$value) {
              flags2 = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----></div> <form method="POST"${attr("action", actionUrl)} class="hidden"><input type="hidden" name="release"${attr("value", releaseJson)}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/></form></div>`);
        } }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      open,
      mode,
      entityType,
      entityTmdbId,
      release,
      canWriteToBase: canWriteToBase2
    });
  });
}
function ImportReleasesModal($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let filteredInstances, selectedInstance, filteredReleases, potentialMatches, matchIds, filteredLibrary, canConfirm, confirmText, headerText, releasesJson;
    let open = fallback($$props["open"], false);
    let entity = fallback($$props["entity"], null);
    let arrInstances = fallback($$props["arrInstances"], () => [], true);
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    let selectedInstanceId = null;
    let libraryItems = [];
    let loadingLibrary = false;
    let searchStore;
    let selectedItem = null;
    let releases = [];
    let selectedReleases = /* @__PURE__ */ new Set();
    let releaseSearchStore;
    async function loadLibrary() {
      if (!selectedInstanceId) return;
      loadingLibrary = true;
      libraryItems = [];
      selectedItem = null;
      const resourcePath = entity?.type === "series" ? "series" : "movies";
      try {
        const response = await fetch(`/arr/${selectedInstanceId}/library/${resourcePath}`);
        const data = await response.json();
        if (!response.ok || data.error) alertStore.add("error", data.error ?? "Failed to load library");
        else libraryItems = (data.items || []).map((item) => ({
          id: item.id,
          title: item.title,
          year: item.year,
          tmdbId: item.tmdbId,
          tvdbId: item.tvdbId
        }));
      } catch (err) {
        alertStore.add("error", "Failed to load library");
      } finally {
        loadingLibrary = false;
      }
    }
    async function loadSeasonsForSelectedItem() {
      if (!selectedInstanceId || !selectedItem || entity?.type !== "series") return;
      if (selectedItem.seasons !== void 0) return;
      try {
        const response = await fetch(`/arr/${selectedInstanceId}/library/series/${selectedItem.id}/seasons`);
        const data = await response.json();
        if (response.ok && !data.error) {
          const seasonNumbers = (data.seasons || []).map((s3) => s3.seasonNumber).filter((n) => n !== void 0);
          selectedItem = {
            ...selectedItem,
            seasons: seasonNumbers
          };
        }
      } catch {
      }
    }
    $: searchStore = getPersistentSearchStore(`entityTestingImportLibrarySearch:${store_get($$store_subs ??= {}, "$page", page).params.databaseId}`);
    $: releaseSearchStore = getPersistentSearchStore(`entityTestingImportReleaseSearch:${store_get($$store_subs ??= {}, "$page", page).params.databaseId}`);
    $: filteredInstances = arrInstances.filter((i) => entity?.type === "movie" ? i.type === "radarr" : i.type === "sonarr");
    $: if (open && entity && filteredInstances.length > 0 && selectedInstanceId === null) selectedInstanceId = filteredInstances[0].id;
    $: selectedInstance = filteredInstances.find((i) => i.id === selectedInstanceId);
    $: if (selectedInstanceId && true) loadLibrary();
    $: if (selectedItem && entity?.type === "series" && selectedItem.seasons === void 0) loadSeasonsForSelectedItem();
    $: filteredReleases = (() => {
      let result = store_get($$store_subs ??= {}, "$releaseSearchStore", releaseSearchStore).query ? releases.filter((r2) => r2.title.toLowerCase().includes(store_get($$store_subs ??= {}, "$releaseSearchStore", releaseSearchStore).query.toLowerCase())) : [...releases];
      result.sort((a2, b3) => {
        let cmp = 0;
        cmp = a2.size - b3.size;
        return -cmp;
      });
      return result;
    })();
    $: filteredReleases.length > 0 && filteredReleases.every((r2) => selectedReleases.has(r2.title));
    $: potentialMatches = entity ? libraryItems.filter((item) => {
      if (entity.type === "movie" && entity.tmdb_id && item.tmdbId) return item.tmdbId === entity.tmdb_id;
      return item.title.toLowerCase() === entity.title.toLowerCase();
    }) : [];
    $: matchIds = new Set(potentialMatches.map((m3) => m3.id));
    $: filteredLibrary = (store_get($$store_subs ??= {}, "$searchStore", searchStore).query ? libraryItems.filter((item) => !matchIds.has(item.id) && item.title.toLowerCase().includes(store_get($$store_subs ??= {}, "$searchStore", searchStore).query.toLowerCase())) : libraryItems.filter((item) => !matchIds.has(item.id))).sort((a2, b3) => a2.title.localeCompare(b3.title));
    $: canConfirm = selectedItem !== null;
    $: confirmText = "Next";
    $: headerText = "Import Releases";
    $: releasesJson = JSON.stringify(releases.filter((r2) => selectedReleases.has(r2.title)).map((r2) => ({
      entityType: entity?.type ?? "movie",
      entityTmdbId: entity?.tmdb_id ?? 0,
      title: r2.title,
      size_bytes: r2.size,
      languages: r2.languages,
      indexers: r2.indexers,
      flags: r2.flags
    })));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      Modal($$renderer3, {
        header: headerText,
        confirmText,
        confirmDisabled: !canConfirm,
        size: "xl",
        height: "lg",
        get open() {
          return open;
        },
        set open($$value) {
          open = $$value;
          $$settled = false;
        },
        $$slots: { body: ($$renderer4) => {
          $$renderer4.push(`<div slot="body" class="space-y-4">`);
          if (entity) {
            $$renderer4.push("<!--[0-->");
            Card($$renderer4, {
              padding: "sm",
              flush: true,
              children: ($$renderer5) => {
                $$renderer5.push(`<div class="flex items-center gap-3">`);
                if (entity.poster_path) {
                  $$renderer5.push("<!--[0-->");
                  $$renderer5.push(`<img${attr("src", `https://image.tmdb.org/t/p/w92${stringify(entity.poster_path)}`)}${attr("alt", entity.title)} class="h-16 w-11 rounded object-cover"/>`);
                } else {
                  $$renderer5.push("<!--[-1-->");
                  $$renderer5.push(`<div class="flex h-16 w-11 items-center justify-center rounded bg-neutral-200 dark:bg-neutral-700">`);
                  if (entity.type === "movie") {
                    $$renderer5.push("<!--[0-->");
                    Film($$renderer5, {
                      size: 20,
                      class: "text-neutral-400"
                    });
                  } else {
                    $$renderer5.push("<!--[-1-->");
                    Tv($$renderer5, {
                      size: 20,
                      class: "text-neutral-400"
                    });
                  }
                  $$renderer5.push(`<!--]--></div>`);
                }
                $$renderer5.push(`<!--]--> <div><h3 class="font-medium text-neutral-900 dark:text-neutral-100">${escape_html(entity.title)}</h3> <p class="text-sm text-neutral-500 dark:text-neutral-400">${escape_html(entity.type === "movie" ? "Movie" : "TV Series")} `);
                if (entity.year) {
                  $$renderer5.push("<!--[0-->");
                  $$renderer5.push(`\u2022 ${escape_html(entity.year)}`);
                } else $$renderer5.push("<!--[-1-->");
                $$renderer5.push(`<!--]--></p></div></div>`);
              },
              $$slots: { default: true }
            });
          } else $$renderer4.push("<!--[-1-->");
          $$renderer4.push(`<!--]--> `);
          $$renderer4.push("<!--[0-->");
          if (filteredInstances.length === 0) {
            $$renderer4.push("<!--[0-->");
            Card($$renderer4, {
              flush: true,
              children: ($$renderer5) => {
                $$renderer5.push(`<p class="text-sm text-neutral-600 dark:text-neutral-300">No ${escape_html(entity?.type === "movie" ? "Radarr" : "Sonarr")} instances configured. <a href="/settings/arr" class="font-medium text-accent-600 hover:underline dark:text-accent-400">Configure in Settings</a></p>`);
              },
              $$slots: { default: true }
            });
          } else {
            $$renderer4.push("<!--[-1-->");
            ActionsBar($$renderer4, {
              children: ($$renderer5) => {
                SearchAction($$renderer5, {
                  searchStore,
                  placeholder: "Search library..."
                });
                $$renderer5.push(`<!----> `);
                ActionButton($$renderer5, {
                  icon: Server2,
                  hasDropdown: true,
                  dropdownPosition: "right",
                  square: !selectedInstance,
                  children: ($$renderer6) => {
                    if (selectedInstance) {
                      $$renderer6.push("<!--[0-->");
                      $$renderer6.push(`<span class="ml-2 text-sm text-neutral-700 dark:text-neutral-300">${escape_html(selectedInstance.name)}</span>`);
                    } else $$renderer6.push("<!--[-1-->");
                    $$renderer6.push(`<!--]-->`);
                  },
                  $$slots: {
                    default: true,
                    dropdown: ($$renderer6, { dropdownPosition }) => {
                      Dropdown($$renderer6, {
                        position: dropdownPosition,
                        children: ($$renderer7) => {
                          DropdownHeader($$renderer7, { label: "Instance" });
                          $$renderer7.push(`<!----> <!--[-->`);
                          const each_array = ensure_array_like(filteredInstances);
                          for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                            let instance = each_array[$$index];
                            DropdownItem($$renderer7, {
                              label: instance.name,
                              selected: selectedInstanceId === instance.id
                            });
                          }
                          $$renderer7.push(`<!--]-->`);
                        },
                        $$slots: { default: true }
                      });
                    }
                  }
                });
                $$renderer5.push(`<!---->`);
              },
              $$slots: { default: true }
            });
            $$renderer4.push(`<!----> `);
            if (selectedInstanceId) {
              $$renderer4.push("<!--[0-->");
              if (loadingLibrary) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="flex items-center justify-center p-8">`);
                Loader_circle($$renderer4, {
                  size: 24,
                  class: "animate-spin text-neutral-400"
                });
                $$renderer4.push(`<!----></div>`);
              } else if (libraryItems.length === 0) {
                $$renderer4.push("<!--[1-->");
                Card($$renderer4, {
                  padding: "lg",
                  children: ($$renderer5) => {
                    $$renderer5.push(`<p class="text-center text-neutral-500 dark:text-neutral-400">No items found in library.</p>`);
                  },
                  $$slots: { default: true }
                });
              } else {
                $$renderer4.push("<!--[-1-->");
                if (potentialMatches.length > 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="space-y-2"><p class="text-xs font-medium text-neutral-500 dark:text-neutral-400">Suggested Match</p> `);
                  SelectableContainer($$renderer4, {
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!--[-->`);
                      const each_array_1 = ensure_array_like(potentialMatches);
                      for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                        let item = each_array_1[$$index_1];
                        SelectableRow($$renderer5, {
                          checked: selectedItem?.id === item.id,
                          children: ($$renderer6) => {
                            $$renderer6.push(`<p class="truncate text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(item.title)}</p> `);
                            if (item.year) {
                              $$renderer6.push("<!--[0-->");
                              $$renderer6.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(item.year)}</p>`);
                            } else $$renderer6.push("<!--[-1-->");
                            $$renderer6.push(`<!--]-->`);
                          },
                          $$slots: { default: true }
                        });
                      }
                      $$renderer5.push(`<!--]-->`);
                    },
                    $$slots: { default: true }
                  });
                  $$renderer4.push(`<!----></div>`);
                } else {
                  $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<p class="text-xs text-neutral-500 italic dark:text-neutral-400">This item might not be in your library. Select manually below.</p>`);
                }
                $$renderer4.push(`<!--]--> <div class="space-y-2">`);
                if (potentialMatches.length > 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<p class="text-xs font-medium text-neutral-500 dark:text-neutral-400">All Items</p>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> `);
                SelectableContainer($$renderer4, {
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!--[-->`);
                    const each_array_2 = ensure_array_like(filteredLibrary);
                    for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
                      let item = each_array_2[$$index_2];
                      SelectableRow($$renderer5, {
                        checked: selectedItem?.id === item.id,
                        children: ($$renderer6) => {
                          $$renderer6.push(`<p class="truncate text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(item.title)}</p> `);
                          if (item.year) {
                            $$renderer6.push("<!--[0-->");
                            $$renderer6.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(item.year)}</p>`);
                          } else $$renderer6.push("<!--[-1-->");
                          $$renderer6.push(`<!--]-->`);
                        },
                        $$slots: { default: true }
                      });
                    }
                    $$renderer5.push(`<!--]-->`);
                  },
                  $$slots: { default: true }
                });
                $$renderer4.push(`<!----></div>`);
              }
              $$renderer4.push(`<!--]-->`);
            } else {
              $$renderer4.push("<!--[-1-->");
              Card($$renderer4, {
                padding: "lg",
                children: ($$renderer5) => {
                  $$renderer5.push(`<p class="text-center text-neutral-500 dark:text-neutral-400">Select an instance to load library.</p>`);
                },
                $$slots: { default: true }
              });
            }
            $$renderer4.push(`<!--]-->`);
          }
          $$renderer4.push(`<!--]-->`);
          $$renderer4.push(`<!--]--> <form method="POST" action="?/importReleases" class="hidden"><input type="hidden" name="releases"${attr("value", releasesJson)}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/></form></div>`);
        } }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      open,
      entity,
      arrInstances,
      canWriteToBase: canWriteToBase2
    });
  });
}
function ReleaseTable($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let columns;
    let entityType = $$props["entityType"];
    let entityTmdbId = $$props["entityTmdbId"];
    let releases = $$props["releases"];
    let evaluations = $$props["evaluations"];
    let selectedProfileId = $$props["selectedProfileId"];
    let qualityProfiles = $$props["qualityProfiles"];
    let cfScoresData = $$props["cfScoresData"];
    let calculateScore = $$props["calculateScore"];
    let deleteLayer = fallback($$props["deleteLayer"], "user");
    let expandedRows = /* @__PURE__ */ new Set();
    function getMatchingFormats(releaseId) {
      const evaluation = evaluations[releaseId];
      if (!evaluation || !evaluation.cfMatches || !selectedProfileId) return [];
      const profile = qualityProfiles.find((p2) => p2.id === selectedProfileId);
      if (!profile) return [];
      const profileScores = cfScoresData.profiles.find((p2) => p2.profileName === profile.name);
      if (!profileScores) return [];
      const arrType = entityType === "movie" ? "radarr" : "sonarr";
      const matches = [];
      for (const [cfName, matched] of Object.entries(evaluation.cfMatches)) {
        if (!matched) continue;
        const cfScore = profileScores.scores[cfName];
        if (cfScore) {
          const score = cfScore[arrType];
          if (score !== null && score !== 0) matches.push({
            name: cfName,
            score
          });
        }
      }
      return matches.sort((a2, b3) => Math.abs(b3.score) - Math.abs(a2.score));
    }
    createEventDispatcher();
    function getRowId(row) {
      return row.id;
    }
    function formatSize2(bytes) {
      if (bytes === null) return "\u2014";
      const gb = bytes / 1073741824;
      if (gb >= 1) return `${gb.toFixed(1)} GB`;
      return `${(bytes / 1048576).toFixed(0)} MB`;
    }
    $: columns = [
      {
        key: "title",
        header: "Release Title",
        sortable: true
      },
      {
        key: "size_bytes",
        header: "Size",
        width: "w-24",
        align: "right",
        sortable: true
      },
      {
        key: "indexers",
        header: "Indexers",
        width: "w-48"
      },
      {
        key: "languages",
        header: "Languages",
        width: "w-32"
      },
      {
        key: "score",
        header: "Score",
        width: "w-20",
        align: "right",
        sortable: true,
        sortAccessor: (row) => calculateScore(row.id, entityType) ?? -Infinity
      }
    ];
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="space-y-3">`);
      if (releases.length > 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<!---->`);
        ExpandableTable($$renderer3, {
          columns,
          data: releases,
          getRowId,
          compact: true,
          flushExpanded: true,
          emptyMessage: "No releases",
          chevronPosition: "right",
          responsive: true,
          defaultSort: {
            key: "score",
            direction: "desc"
          },
          get expandedRows() {
            return expandedRows;
          },
          set expandedRows($$value) {
            expandedRows = $$value;
            $$settled = false;
          },
          $$slots: {
            cell: ($$renderer4, { row: release, column }) => {
              if (column.key === "title") {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<span class="font-mono text-[11px]">${escape_html(release.title)}</span>`);
              } else if (column.key === "size_bytes") {
                $$renderer4.push("<!--[1-->");
                $$renderer4.push(`<span class="font-mono text-[11px] text-neutral-600 dark:text-neutral-400">${escape_html(formatSize2(release.size_bytes))}</span>`);
              } else if (column.key === "indexers") {
                $$renderer4.push("<!--[2-->");
                if (release.indexers.length > 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
                  const each_array = ensure_array_like(release.indexers);
                  for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                    let indexer = each_array[$$index];
                    Label($$renderer4, {
                      variant: "secondary",
                      size: "sm",
                      rounded: "xl",
                      children: ($$renderer5) => {
                        $$renderer5.push(`<!---->${escape_html(indexer)}`);
                      },
                      $$slots: { default: true }
                    });
                  }
                  $$renderer4.push(`<!--]--></div>`);
                } else {
                  $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<span class="text-neutral-400">\u2014</span>`);
                }
                $$renderer4.push(`<!--]-->`);
              } else if (column.key === "languages") {
                $$renderer4.push("<!--[3-->");
                if (release.languages.length > 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="flex flex-wrap gap-1"><!--[-->`);
                  const each_array_1 = ensure_array_like(release.languages);
                  for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                    let lang = each_array_1[$$index_1];
                    Label($$renderer4, {
                      variant: "secondary",
                      size: "sm",
                      rounded: "xl",
                      children: ($$renderer5) => {
                        $$renderer5.push(`<!---->${escape_html(lang)}`);
                      },
                      $$slots: { default: true }
                    });
                  }
                  $$renderer4.push(`<!--]--></div>`);
                } else {
                  $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<span class="text-neutral-400">\u2014</span>`);
                }
                $$renderer4.push(`<!--]-->`);
              } else if (column.key === "score") {
                $$renderer4.push("<!--[4-->");
                Score($$renderer4, { score: calculateScore(release.id, entityType) });
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]-->`);
            },
            actions: ($$renderer4, { row: release }) => {
              {
                const releaseFormId = `delete-release-form-${release.id}`;
                $$renderer4.push(`<div class="flex items-center gap-1">`);
                Button($$renderer4, {
                  icon: Pencil,
                  tooltip: "Edit release",
                  variant: "secondary",
                  size: "xs"
                });
                $$renderer4.push(`<!----> <form${attr("id", releaseFormId)} method="POST" action="?/deleteRelease"><input type="hidden" name="releaseId"${attr("value", release.id)}/> <input type="hidden" name="layer"${attr("value", deleteLayer)}/> `);
                Button($$renderer4, {
                  icon: Trash_2,
                  tooltip: "Delete release",
                  variant: "secondary",
                  size: "xs",
                  iconColor: "group-hover:text-red-500 dark:group-hover:text-red-400"
                });
                $$renderer4.push(`<!----></form></div>`);
              }
            },
            expanded: ($$renderer4, { row: release }) => {
              {
                const evaluation = evaluations[release.id];
                const matchingFormats = getMatchingFormats(release.id);
                $$renderer4.push(`<div class="px-4 py-4"><div class="grid grid-cols-[auto_1fr] gap-x-6 gap-y-3 text-xs">`);
                if (evaluation?.parsed) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="pt-0.5 font-medium text-neutral-500 dark:text-neutral-400">Parsed</div> <div class="flex flex-wrap items-center gap-2"><span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                  Hard_drive($$renderer4, {
                    size: 12,
                    class: "text-blue-500"
                  });
                  $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Source</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.source)}</span></span> <span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                  Layers($$renderer4, {
                    size: 12,
                    class: "text-indigo-500"
                  });
                  $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Resolution</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.resolution)}</span></span> `);
                  if (evaluation.parsed.modifier !== "None") {
                    $$renderer4.push("<!--[0-->");
                    $$renderer4.push(`<span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                    Tag($$renderer4, {
                      size: 12,
                      class: "text-amber-500"
                    });
                    $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Modifier</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.modifier)}</span></span>`);
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--> `);
                  if (evaluation.parsed.releaseGroup) {
                    $$renderer4.push("<!--[0-->");
                    $$renderer4.push(`<span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                    Users($$renderer4, {
                      size: 12,
                      class: "text-teal-500"
                    });
                    $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Group</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.releaseGroup)}</span></span>`);
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--> `);
                  if (evaluation.parsed.edition) {
                    $$renderer4.push("<!--[0-->");
                    $$renderer4.push(`<span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                    Bookmark($$renderer4, {
                      size: 12,
                      class: "text-orange-500"
                    });
                    $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Edition</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.edition)}</span></span>`);
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--> `);
                  if (evaluation.parsed.languages.length > 0) {
                    $$renderer4.push("<!--[0-->");
                    $$renderer4.push(`<span class="inline-flex items-center gap-1.5 rounded-xl border border-neutral-300 bg-white px-2 py-1 dark:border-neutral-700/60 dark:bg-neutral-800/50">`);
                    Earth($$renderer4, {
                      size: 12,
                      class: "text-emerald-500"
                    });
                    $$renderer4.push(`<!----> <span class="text-neutral-500 dark:text-neutral-400">Languages</span> <span class="font-medium text-neutral-800 dark:text-neutral-100">${escape_html(evaluation.parsed.languages.join(", "))}</span> <span class="text-[10px] text-neutral-400 dark:text-neutral-500">(${escape_html(evaluation.parsed.languageSource)})</span></span>`);
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--></div>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]--> <div class="pt-0.5 font-medium text-neutral-500 dark:text-neutral-400">Formats</div> <div>`);
                if (!selectedProfileId) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<span class="text-neutral-400 italic">Select a quality profile to see scores.</span>`);
                } else if (matchingFormats.length === 0) {
                  $$renderer4.push("<!--[1-->");
                  $$renderer4.push(`<span class="text-neutral-400 italic">No custom formats matched with non-zero scores.</span>`);
                } else {
                  $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<div class="flex flex-wrap gap-2"><!--[-->`);
                  const each_array_2 = ensure_array_like(matchingFormats);
                  for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
                    let cf = each_array_2[$$index_2];
                    CustomFormatBadge($$renderer4, {
                      name: cf.name,
                      score: cf.score
                    });
                  }
                  $$renderer4.push(`<!--]--></div>`);
                }
                $$renderer4.push(`<!--]--></div></div></div>`);
              }
            }
          }
        });
        $$renderer3.push(`<!---->`);
      } else {
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<p class="py-4 text-sm text-neutral-500 dark:text-neutral-400">No releases yet. Import from an Arr instance to get started.</p>`);
      }
      $$renderer3.push(`<!--]--></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      entityType,
      entityTmdbId,
      releases,
      evaluations,
      selectedProfileId,
      qualityProfiles,
      cfScoresData,
      calculateScore,
      deleteLayer
    });
  });
}
function EntityTable($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let entities = $$props["entities"];
    let evaluations = $$props["evaluations"];
    let loadingEntityIds = fallback($$props["loadingEntityIds"], () => /* @__PURE__ */ new Set(), true);
    let selectedProfileId = $$props["selectedProfileId"];
    let qualityProfiles = $$props["qualityProfiles"];
    let cfScoresData = $$props["cfScoresData"];
    let calculateScore = $$props["calculateScore"];
    let deleteLayer = fallback($$props["deleteLayer"], "user");
    let deleteReleaseLayer = fallback($$props["deleteReleaseLayer"], "user");
    let expandedRows = fallback($$props["expandedRows"], () => /* @__PURE__ */ new Set(), true);
    const dispatch = createEventDispatcher();
    let prevExpandedRows = /* @__PURE__ */ new Set();
    const columns = [
      {
        key: "poster_path",
        header: "",
        width: "w-12"
      },
      {
        key: "title",
        header: "Title",
        sortable: true
      },
      {
        key: "type",
        header: "Type",
        width: "w-24",
        sortable: true
      },
      {
        key: "releases",
        header: "Releases",
        width: "w-28",
        align: "center",
        sortable: true,
        sortAccessor: (row) => row.releases.length
      }
    ];
    function getRowId(row) {
      return row.id;
    }
    $: {
      for (const id of expandedRows) if (!prevExpandedRows.has(id)) {
        const entity = entities.find((e) => e.id === id);
        if (entity) dispatch("expand", { entity });
      }
      prevExpandedRows = new Set(expandedRows);
    }
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      ExpandableTable($$renderer3, {
        columns,
        data: entities,
        getRowId,
        compact: true,
        flushExpanded: true,
        emptyMessage: "No entities match your search",
        chevronPosition: "right",
        responsive: true,
        get expandedRows() {
          return expandedRows;
        },
        set expandedRows($$value) {
          expandedRows = $$value;
          $$settled = false;
        },
        $$slots: {
          cell: ($$renderer4, { row, column }) => {
            if (column.key === "poster_path") {
              $$renderer4.push("<!--[0-->");
              if (row.poster_path) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<div class="h-12 w-8"><img${attr("src", `https://image.tmdb.org/t/p/w92${stringify(row.poster_path)}`)}${attr("alt", row.title)} class="h-full w-full rounded object-cover"/></div>`);
              } else {
                $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<div class="flex h-12 w-8 items-center justify-center rounded bg-neutral-200 dark:bg-neutral-700">`);
                if (row.type === "movie") {
                  $$renderer4.push("<!--[0-->");
                  Film($$renderer4, {
                    size: 16,
                    class: "text-neutral-400"
                  });
                } else {
                  $$renderer4.push("<!--[-1-->");
                  Tv($$renderer4, {
                    size: 16,
                    class: "text-neutral-400"
                  });
                }
                $$renderer4.push(`<!--]--></div>`);
              }
              $$renderer4.push(`<!--]-->`);
            } else if (column.key === "title") {
              $$renderer4.push("<!--[1-->");
              $$renderer4.push(`<div class="flex flex-col"><span class="font-medium">${escape_html(row.title)}</span> `);
              if (row.year) {
                $$renderer4.push("<!--[0-->");
                $$renderer4.push(`<span class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(row.year)}</span>`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></div>`);
            } else if (column.key === "type") {
              $$renderer4.push("<!--[2-->");
              Label($$renderer4, {
                variant: "secondary",
                size: "sm",
                rounded: "xl",
                children: ($$renderer5) => {
                  if (row.type === "movie") {
                    $$renderer5.push("<!--[0-->");
                    Film($$renderer5, {
                      size: 12,
                      class: "text-amber-500"
                    });
                    $$renderer5.push(`<!----> Movie`);
                  } else {
                    $$renderer5.push("<!--[-1-->");
                    Tv($$renderer5, {
                      size: 12,
                      class: "text-cyan-500"
                    });
                    $$renderer5.push(`<!----> Series`);
                  }
                  $$renderer5.push(`<!--]-->`);
                },
                $$slots: { default: true }
              });
            } else if (column.key === "releases") {
              $$renderer4.push("<!--[3-->");
              $$renderer4.push(`<span class="text-neutral-600 dark:text-neutral-400">${escape_html(row.releases.length)}</span>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          actions: ($$renderer4, { row }) => {
            {
              const formId = `delete-form-${row.id}`;
              $$renderer4.push(`<div class="flex items-center gap-1">`);
              Button($$renderer4, {
                icon: Plus,
                tooltip: "Add release",
                variant: "secondary",
                size: "xs"
              });
              $$renderer4.push(`<!----> `);
              Button($$renderer4, {
                icon: Import,
                tooltip: "Import releases from Arr",
                variant: "secondary",
                size: "xs"
              });
              $$renderer4.push(`<!----> <form${attr("id", formId)} method="POST" action="?/deleteEntity"><input type="hidden" name="entityType"${attr("value", row.type)}/> <input type="hidden" name="entityTmdbId"${attr("value", row.tmdb_id)}/> <input type="hidden" name="entityTitle"${attr("value", row.title)}/> <input type="hidden" name="layer"${attr("value", deleteLayer)}/> `);
              Button($$renderer4, {
                icon: Trash_2,
                tooltip: "Delete entity",
                variant: "secondary",
                size: "xs",
                iconColor: "group-hover:text-red-500 dark:group-hover:text-red-400"
              });
              $$renderer4.push(`<!----></form></div>`);
            }
          },
          expanded: ($$renderer4, { row }) => {
            $$renderer4.push(`<div class="px-4 py-3">`);
            if (loadingEntityIds.has(row.id)) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<div class="flex items-center justify-center py-8 text-neutral-500 dark:text-neutral-400"><svg class="mr-2 h-5 w-5 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg> Evaluating releases...</div>`);
            } else {
              $$renderer4.push("<!--[-1-->");
              ReleaseTable($$renderer4, {
                entityType: row.type,
                entityTmdbId: row.tmdb_id,
                releases: row.releases,
                evaluations,
                selectedProfileId,
                qualityProfiles,
                cfScoresData,
                calculateScore,
                deleteLayer: deleteReleaseLayer
              });
            }
            $$renderer4.push(`<!--]--></div>`);
          }
        }
      });
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, {
      entities,
      evaluations,
      loadingEntityIds,
      selectedProfileId,
      qualityProfiles,
      cfScoresData,
      calculateScore,
      deleteLayer,
      deleteReleaseLayer,
      expandedRows
    });
  });
}
function _page62($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let calculateScore, selectedProfile, searchPlaceholder, typeFilteredEntities, tabs;
    let data = $$props["data"];
    let evaluations = {};
    let loadingEntityIds = /* @__PURE__ */ new Set();
    let expandedRows = /* @__PURE__ */ new Set();
    let selectedProfileId = null;
    let showInfoModal = false;
    let showAddModal = false;
    let showQuickParseModal = false;
    let showDeleteModal = false;
    let showReleaseModal = false;
    let releaseModalMode = "create";
    let releaseEntityType = "movie";
    let releaseEntityTmdbId = 0;
    let currentRelease = null;
    let showDeleteReleaseModal = false;
    let showImportModal = false;
    let importEntity = null;
    let deleteLayer = data.canWriteToBase ? "base" : "user";
    let deleteReleaseLayer = data.canWriteToBase ? "base" : "user";
    let moviesSelected = true;
    let seriesSelected = true;
    const { search, filtered, setItems } = createDataPageStore(data.testEntities, {
      storageKey: "entityTestingView",
      searchKeys: ["title"],
      searchKey: `entityTestingSearch:${data.currentDatabase.id}`
    });
    $: if (data.currentDatabase) {
      evaluations = {};
      loadingEntityIds = /* @__PURE__ */ new Set();
      expandedRows = /* @__PURE__ */ new Set();
    }
    $: calculateScore = (releaseId, entityType) => {
      return null;
    };
    $: selectedProfile = null;
    $: searchPlaceholder = /* @__PURE__ */ (() => {
      return "Search movies, TV series...";
    })();
    $: setItems(data.testEntities);
    $: typeFilteredEntities = store_get($$store_subs ??= {}, "$filtered", filtered).filter((entity) => {
      return true;
    });
    $: tabs = data.databases.map((db2) => ({
      label: db2.name,
      href: `/quality-profiles/entity-testing/${db2.id}`,
      active: db2.id === data.currentDatabase.id
    }));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.currentDatabase.name} \xB7 Quality Profile Tests` });
      $$renderer3.push(`<!----> <div class="space-y-6 px-4 pb-8 md:px-8">`);
      Tabs($$renderer3, {
        tabs,
        responsive: true
      });
      $$renderer3.push(`<!----> `);
      ActionsBar($$renderer3, {
        className: "w-full justify-center md:w-full md:mx-auto",
        children: ($$renderer4) => {
          Tooltip($$renderer4, {
            text: "How It Works",
            children: ($$renderer5) => {
              ActionButton($$renderer5, { icon: Info });
            },
            $$slots: { default: true }
          });
          $$renderer4.push(`<!----> `);
          SearchAction($$renderer4, {
            searchStore: search,
            placeholder: searchPlaceholder,
            responsive: true
          });
          $$renderer4.push(`<!----> `);
          Tooltip($$renderer4, {
            text: "Add Entity",
            children: ($$renderer5) => {
              ActionButton($$renderer5, { icon: Plus });
            },
            $$slots: { default: true }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Sliders_vertical,
            hasDropdown: true,
            dropdownPosition: "right",
            square: !selectedProfile,
            children: ($$renderer5) => {
              if (selectedProfile) {
                $$renderer5.push("<!--[0-->");
                $$renderer5.push(`<span class="ml-2 text-sm text-neutral-700 dark:text-neutral-300">${escape_html(selectedProfile.name)}</span>`);
              } else $$renderer5.push("<!--[-1-->");
              $$renderer5.push(`<!--]-->`);
            },
            $$slots: {
              default: true,
              dropdown: ($$renderer5) => {
                Dropdown($$renderer5, {
                  slot: "dropdown",
                  position: "right",
                  children: ($$renderer6) => {
                    DropdownHeader($$renderer6, { label: "Quality Profile" });
                    $$renderer6.push(`<!----> `);
                    DropdownItem($$renderer6, {
                      label: "No Profile",
                      selected: true
                    });
                    $$renderer6.push(`<!----> <!--[-->`);
                    const each_array = ensure_array_like(data.qualityProfiles);
                    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                      let profile = each_array[$$index];
                      DropdownItem($$renderer6, {
                        label: profile.name,
                        selected: selectedProfileId === profile.id
                      });
                    }
                    $$renderer6.push(`<!--]-->`);
                  },
                  $$slots: { default: true }
                });
              }
            }
          });
          $$renderer4.push(`<!----> `);
          Tooltip($$renderer4, {
            text: "Quick Parse",
            children: ($$renderer5) => {
              ActionButton($$renderer5, { icon: Flask_conical });
            },
            $$slots: { default: true }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, {
            icon: Clapperboard,
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5) => {
              Dropdown($$renderer5, {
                slot: "dropdown",
                position: "right",
                children: ($$renderer6) => {
                  DropdownHeader($$renderer6, { label: "Entity Type" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, {
                    icon: Film,
                    label: "Movies",
                    selected: moviesSelected
                  });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, {
                    icon: Tv,
                    label: "TV Series",
                    selected: seriesSelected
                  });
                  $$renderer6.push(`<!---->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> <div class="mt-6">`);
      if (data.testEntities.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900">`);
        if (!data.tmdbConfigured) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="flex flex-col items-center gap-2">`);
          Triangle_alert($$renderer3, {
            size: 24,
            class: "text-amber-500"
          });
          $$renderer3.push(`<!----> <p class="text-neutral-600 dark:text-neutral-400">TMDB API key not configured. <a href="/settings/general" class="text-accent-600 hover:underline dark:text-accent-400">Configure in Settings</a></p></div>`);
        } else {
          $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<p class="text-neutral-600 dark:text-neutral-400">No entity tests found for ${escape_html(data.currentDatabase?.name)}</p>`);
        }
        $$renderer3.push(`<!--]--></div>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        EntityTable($$renderer3, {
          entities: typeFilteredEntities,
          evaluations,
          loadingEntityIds,
          selectedProfileId,
          qualityProfiles: data.qualityProfiles,
          cfScoresData: data.cfScoresData,
          calculateScore,
          deleteLayer,
          deleteReleaseLayer,
          get expandedRows() {
            return expandedRows;
          },
          set expandedRows($$value) {
            expandedRows = $$value;
            $$settled = false;
          }
        });
      }
      $$renderer3.push(`<!--]--></div></div> `);
      InfoModal($$renderer3, {
        header: "How Entity Testing Works",
        get open() {
          return showInfoModal;
        },
        set open($$value) {
          showInfoModal = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-600 dark:text-neutral-400"><div><div class="font-medium text-neutral-900 dark:text-neutral-100">Adding Entities</div> <p class="mt-1">Add movies or TV series from TMDB to use as test cases. These represent the media you want
				to simulate release matching for.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Test Releases</div> <p class="mt-1">For each entity, add test releases with realistic release titles (e.g.,
				"Movie.2024.1080p.BluRay.REMUX-GROUP"). You can also specify size, languages, indexers, and
				flags.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Quality Profile Scoring</div> <p class="mt-1">Select a quality profile from the dropdown to see how each release would score. The score is
				calculated by matching custom formats and summing their configured point values.</p></div> <div><div class="font-medium text-neutral-900 dark:text-neutral-100">Custom Format Matching</div> <p class="mt-1">Expand a release row to see parsed metadata and which custom formats matched. Each matched
				format shows its score contribution, helping you understand why a release scored the way it
				did.</p></div></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      AddEntityModal($$renderer3, {
        existingEntities: data.testEntities,
        canWriteToBase: data.canWriteToBase,
        tmdbConfigured: data.tmdbConfigured,
        get open() {
          return showAddModal;
        },
        set open($$value) {
          showAddModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      Modal($$renderer3, {
        header: "Delete Entity",
        bodyMessage: `Are you sure you want to delete ${stringify(void 0)}? This will also remove all associated test releases.`,
        confirmText: "Delete",
        confirmDanger: true,
        size: "sm",
        get open() {
          return showDeleteModal;
        },
        set open($$value) {
          showDeleteModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      ReleaseModal($$renderer3, {
        mode: releaseModalMode,
        entityType: releaseEntityType,
        entityTmdbId: releaseEntityTmdbId,
        release: currentRelease,
        canWriteToBase: data.canWriteToBase,
        get open() {
          return showReleaseModal;
        },
        set open($$value) {
          showReleaseModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      Modal($$renderer3, {
        header: "Delete Release",
        bodyMessage: "Are you sure you want to delete this test release?",
        confirmText: "Delete",
        confirmDanger: true,
        size: "sm",
        get open() {
          return showDeleteReleaseModal;
        },
        set open($$value) {
          showDeleteReleaseModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      ImportReleasesModal($$renderer3, {
        entity: importEntity,
        arrInstances: data.arrInstances,
        canWriteToBase: data.canWriteToBase,
        get open() {
          return showImportModal;
        },
        set open($$value) {
          showImportModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!----> `);
      QuickParseModal($$renderer3, {
        databaseId: data.currentDatabase.id,
        qualityProfiles: data.qualityProfiles,
        cfScoresData: data.cfScoresData,
        parserAvailable: data.parserAvailable,
        get open() {
          return showQuickParseModal;
        },
        set open($$value) {
          showQuickParseModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte62 = __esm({
  "dist/build/server/entries/pages/quality-profiles/entity-testing/_databaseId_/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Dropdown();
    init_Icon();
    init_check();
    init_hard_drive();
    init_earth();
    init_tv();
    init_flask_conical();
    init_info();
    init_layers();
    init_Button();
    init_pencil();
    init_plus();
    init_search();
    init_server22();
    init_sliders_vertical();
    init_star();
    init_tag();
    init_trash_2();
    init_triangle_alert();
    init_users2();
    init_x();
    init_stores();
    init_store2();
    init_Label();
    init_Card();
    init_Modal();
    init_forms();
    init_IconCheckbox();
    init_DropdownItem();
    init_Tabs();
    init_ExpandableTable();
    init_ActionsBar();
    init_ActionButton();
    init_Badge();
    init_DropdownHeader();
    init_InfoModal();
    init_PageMeta();
    init_dataPage();
    init_DropdownSelect();
    init_FormInput();
    init_Score();
    init_CustomFormatBadge();
    init_TagInput();
  }
});

// dist/build/server/nodes/72.js
var __exports73 = {};
__export(__exports73, {
  component: () => component69,
  fonts: () => fonts73,
  imports: () => imports73,
  index: () => index73,
  server: () => page_server_ts_exports64,
  server_id: () => server_id70,
  stylesheets: () => stylesheets73
});
var index73, component_cache69, component69, server_id70, imports73, stylesheets73, fonts73;
var init__73 = __esm({
  async "dist/build/server/nodes/72.js"() {
    "use strict";
    await init_page_server_ts64();
    index73 = 72;
    component69 = async () => component_cache69 ??= (await Promise.resolve().then(() => (init_page_svelte62(), page_svelte_exports62))).default;
    server_id70 = "src/routes/quality-profiles/entity-testing/[databaseId]/+page.server.ts";
    imports73 = ["_app/immutable/nodes/72.CPfJzY2b.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/C8Bmw0iK2.js", "_app/immutable/chunks/CkDZnQpg2.js", "_app/immutable/chunks/xCf7klJK.js", "_app/immutable/chunks/SEZzcS_o.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DYf5Ixhg.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/B_FOzVLA.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/CRKwypWu.js", "_app/immutable/chunks/B8c7VBJ4.js", "_app/immutable/chunks/DuBlSUgq.js", "_app/immutable/chunks/Cut3gr1-.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/C_Z5Pdot2.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/Co6rAu4X.js", "_app/immutable/chunks/C5rtWVlZ.js", "_app/immutable/chunks/CK2yQf0C.js"];
    stylesheets73 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css"];
    fonts73 = [];
  }
});

// dist/build/server/entries/pages/regular-expressions/_page.server.ts.js
var page_server_ts_exports65 = {};
__export(page_server_ts_exports65, {
  load: () => load68
});
var load68;
var init_page_server_ts65 = __esm({
  async "dist/build/server/entries/pages/regular-expressions/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_lastDatabase();
    load68 = ({ cookies }) => {
      redirectToLastDatabase(cookies, "last_db_re", "/regular-expressions");
      return { databases: pcdManager.getAllPublic() };
    };
  }
});

// dist/build/server/entries/pages/regular-expressions/_page.svelte.js
var page_svelte_exports63 = {};
__export(page_svelte_exports63, {
  default: () => _page63
});
function _page63($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: "Regular Expressions" });
    $$renderer2.push(`<!----> `);
    if (data.databases.length === 0) {
      $$renderer2.push("<!--[0-->");
      EmptyState($$renderer2, {
        icon: Database2,
        title: "No Databases Linked",
        description: "Link a Profilarr Compliant Database to manage regular expressions.",
        buttonText: "Link Database",
        buttonHref: "/databases/new",
        buttonIcon: Plus
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte63 = __esm({
  "dist/build/server/entries/pages/regular-expressions/_page.svelte.js"() {
    "use strict";
    init_server();
    init_database2();
    init_plus();
    init_PageMeta();
    init_EmptyState();
  }
});

// dist/build/server/nodes/73.js
var __exports74 = {};
__export(__exports74, {
  component: () => component70,
  fonts: () => fonts74,
  imports: () => imports74,
  index: () => index74,
  server: () => page_server_ts_exports65,
  server_id: () => server_id71,
  stylesheets: () => stylesheets74
});
var index74, component_cache70, component70, server_id71, imports74, stylesheets74, fonts74;
var init__74 = __esm({
  async "dist/build/server/nodes/73.js"() {
    "use strict";
    await init_page_server_ts65();
    index74 = 73;
    component70 = async () => component_cache70 ??= (await Promise.resolve().then(() => (init_page_svelte63(), page_svelte_exports63))).default;
    server_id71 = "src/routes/regular-expressions/+page.server.ts";
    imports74 = ["_app/immutable/nodes/73.BzkPQEPH.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/D_awjkBZ.js", "_app/immutable/chunks/B66v-P2b.js"];
    stylesheets74 = [];
    fonts74 = [];
  }
});

// dist/build/server/entries/pages/regular-expressions/_databaseId_/_page.server.ts.js
var page_server_ts_exports66 = {};
__export(page_server_ts_exports66, {
  load: () => load69
});
var load69;
var init_page_server_ts66 = __esm({
  async "dist/build/server/entries/pages/regular-expressions/_databaseId_/_page.server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_update4();
    await init_regularExpressions();
    await init_lastDatabase();
    init_exports();
    load69 = async ({ params, cookies }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const databases = pcdManager.getAllPublic();
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = databases.find((db2) => db2.id === currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      setLastDatabase(cookies, "last_db_re", currentDatabaseId);
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      return {
        databases,
        currentDatabase,
        regularExpressions: await list(cache3),
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
  }
});

// dist/build/server/entries/pages/regular-expressions/_databaseId_/_page.svelte.js
var page_svelte_exports64 = {};
__export(page_svelte_exports64, {
  default: () => _page64
});
function TableView9($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId;
    let expressions = $$props["expressions"];
    createEventDispatcher();
    function getRowHref(row) {
      return `/regular-expressions/${databaseId}/${row.id}`;
    }
    function escapeHtml2(text2) {
      return text2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
    }
    function parseMarkdown2(text2) {
      if (!text2) return "";
      return sanitizeHtml(g2.parse(text2));
    }
    const columns = [
      {
        key: "name",
        header: "Name",
        headerIcon: Tag,
        align: "left",
        sortable: true,
        width: "w-48",
        cell: (row) => ({ html: `
					<div>
						<div class="font-medium">${escapeHtml2(row.name)}</div>
						${row.tags.length > 0 ? `
							<div class="mt-1 flex flex-wrap gap-1">
								${row.tags.map((tag2) => `
									<span class="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-medium bg-accent-100 text-accent-800 dark:bg-accent-900 dark:text-accent-200">
										${escapeHtml2(tag2.name)}
									</span>
								`).join("")}
							</div>
						` : ""}
					</div>
				` })
      },
      {
        key: "pattern",
        header: "Pattern",
        headerIcon: Code,
        align: "left",
        width: "w-[40%]",
        cell: (row) => ({ html: `<code class="font-mono text-xs bg-neutral-100 dark:bg-neutral-800 px-2 py-1 rounded break-all">${escapeHtml2(row.pattern)}</code>` })
      },
      {
        key: "description",
        header: "Description",
        headerIcon: File_text,
        align: "left",
        width: "w-[30%]",
        cell: (row) => ({ html: row.description ? `<span class="text-sm text-neutral-600 dark:text-neutral-400 prose-inline">${parseMarkdown2(row.description)}</span>` : `<span class="text-neutral-400">-</span>` })
      },
      {
        key: "regex101_id",
        header: "Regex101",
        headerIcon: Link,
        align: "left",
        width: "w-24",
        cell: (row) => ({ html: row.regex101_id ? `<a href="https://regex101.com/r/${escapeHtml2(row.regex101_id)}" target="_blank" rel="noopener noreferrer" class="inline-flex items-center gap-1 font-mono text-xs text-accent-600 hover:text-accent-700 dark:text-accent-400 dark:hover:text-accent-300 hover:underline">${escapeHtml2(row.regex101_id)}<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg></a>` : `<span class="text-neutral-400">-</span>` })
      }
    ];
    $: databaseId = store_get($$store_subs ??= {}, "$page", page).params.databaseId;
    Table2($$renderer2, {
      data: expressions,
      columns,
      emptyMessage: "No regular expressions found",
      hoverable: true,
      compact: false,
      rowHref: getRowHref,
      pageSize: 50,
      $$slots: { actions: ($$renderer3, { row }) => {
        $$renderer3.push(`<div class="flex items-center justify-end gap-0.5">`);
        if (FEATURES.importExport) {
          $$renderer3.push("<!--[0-->");
          Button($$renderer3, {
            icon: Download,
            size: "xs",
            variant: "ghost",
            tooltip: "Export"
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> `);
        Button($$renderer3, {
          icon: Copy,
          size: "xs",
          variant: "secondary",
          tooltip: "Clone"
        });
        $$renderer3.push(`<!----></div>`);
      } }
    });
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { expressions });
  });
}
function CodeBlock2($$renderer, $$props) {
  let code3 = $$props["code"];
  let maxLines = fallback($$props["maxLines"], void 0);
  $$renderer.push(`<pre class="rounded bg-neutral-100 p-2 text-xs dark:bg-neutral-800"><code class="block font-mono break-all whitespace-pre-wrap text-neutral-900 dark:text-neutral-100"${attr_style(maxLines ? `display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: ${maxLines}; overflow: hidden;` : "")}>${escape_html(code3)}</code></pre>`);
  bind_props($$props, {
    code: code3,
    maxLines
  });
}
function Markdown($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let html$1;
    let content = fallback($$props["content"], null);
    let inline = fallback($$props["inline"], true);
    let maxLines = fallback($$props["maxLines"], void 0);
    $: html$1 = content ? sanitizeHtml(inline ? g2.parseInline(content) : g2.parse(content)) : "";
    if (html$1) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span class="markdown text-xs text-neutral-600 dark:text-neutral-400 svelte-e4di6a"${attr_style(maxLines ? `display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: ${maxLines}; overflow: hidden;` : "")}>${html(html$1)}</span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]-->`);
    bind_props($$props, {
      content,
      inline,
      maxLines
    });
  });
}
function CardView9($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let databaseId, visibleExpressions;
    let expressions = $$props["expressions"];
    createEventDispatcher();
    const { visibleCount, sentinel, reset: reset2, setTotalCount } = createProgressiveList({ pageSize: 30 });
    $: databaseId = store_get($$store_subs ??= {}, "$page", page).params.databaseId;
    $: setTotalCount(expressions.length);
    $: reset2();
    $: visibleExpressions = expressions.slice(0, store_get($$store_subs ??= {}, "$visibleCount", visibleCount));
    CardGrid($$renderer2, {
      flush: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!--[-->`);
        const each_array = ensure_array_like(visibleExpressions);
        for (let $$index_1 = 0, $$length = each_array.length; $$index_1 < $$length; $$index_1++) {
          let expression = each_array[$$index_1];
          Card($$renderer3, {
            href: `/regular-expressions/${stringify(databaseId)}/${stringify(expression.id)}`,
            hoverable: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="space-y-3">`);
              CodeBlock2($$renderer4, { code: expression.pattern });
              $$renderer4.push(`<!----> `);
              if (expression.description) {
                $$renderer4.push("<!--[0-->");
                Markdown($$renderer4, {
                  content: expression.description,
                  inline: false,
                  maxLines: 3
                });
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]--></div>`);
            },
            $$slots: {
              default: true,
              header: ($$renderer4) => {
                {
                  $$renderer4.push(`<div class="flex items-end justify-between gap-2"><div class="flex min-w-0 flex-wrap items-center gap-1.5"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">${escape_html(expression.name)}</h3> <!--[-->`);
                  const each_array_1 = ensure_array_like(expression.tags);
                  for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
                    let tag2 = each_array_1[$$index];
                    Label($$renderer4, {
                      variant: "info",
                      size: "sm",
                      rounded: "md",
                      children: ($$renderer5) => {
                        $$renderer5.push(`<!---->${escape_html(tag2.name)}`);
                      },
                      $$slots: { default: true }
                    });
                  }
                  $$renderer4.push(`<!--]--></div> <div class="flex shrink-0 items-center gap-0.5">`);
                  if (expression.regex101_id) {
                    $$renderer4.push("<!--[0-->");
                    Button($$renderer4, {
                      icon: External_link,
                      size: "xs",
                      variant: "ghost",
                      tooltip: "View on regex101"
                    });
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--> `);
                  if (FEATURES.importExport) {
                    $$renderer4.push("<!--[0-->");
                    Button($$renderer4, {
                      icon: Download,
                      size: "xs",
                      variant: "ghost",
                      tooltip: "Export"
                    });
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--> `);
                  Button($$renderer4, {
                    icon: Copy,
                    size: "xs",
                    variant: "ghost",
                    tooltip: "Clone"
                  });
                  $$renderer4.push(`<!----></div></div>`);
                }
              }
            }
          });
        }
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> <div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { expressions });
  });
}
function _page64($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let simpleSearchStore, simpleQuery, useSimpleMode, filtered, tabs;
    let data = $$props["data"];
    let infoModalOpen = false;
    let cloneModalOpen = false;
    let cloneSourceName = "";
    let filterTags = [];
    const fields = [
      {
        key: "all",
        label: "All",
        description: "Name, tags, pattern, description and Regex101 ID",
        type: "text",
        accessor: regularExpressionSearchValues
      },
      {
        key: "name",
        label: "Name",
        description: "Regular expression name",
        type: "text",
        isDefault: true,
        accessor: (item) => item.name,
        suggestions: (items) => items.map((i) => i.name).sort()
      },
      {
        key: "tag",
        label: "Tag",
        description: "Assigned tag names",
        type: "text",
        accessor: (item) => item.tags.map((t2) => t2.name),
        suggestions: (items) => [...new Set(items.flatMap((i) => i.tags.map((t2) => t2.name)))].sort()
      },
      {
        key: "tagged",
        label: "Tagged",
        description: "Whether any tags are assigned",
        type: "text",
        accessor: (item) => item.tags.length > 0 ? "yes" : "no",
        suggestions: () => ["yes", "no"]
      },
      {
        key: "referenced",
        label: "Referenced",
        description: "Whether a custom format uses it",
        type: "text",
        accessor: (item) => item.referenceCount > 0 ? "yes" : "no",
        suggestions: () => ["yes", "no"]
      },
      {
        key: "pattern",
        label: "Pattern",
        description: "Regular expression pattern",
        type: "text",
        accessor: (item) => item.pattern
      },
      {
        key: "description",
        label: "Description",
        description: "Regular expression description",
        type: "text",
        accessor: (item) => item.description ?? null
      },
      {
        key: "regex101_id",
        label: "Regex101 ID",
        description: "Linked Regex101 identifier",
        type: "text",
        accessor: (item) => item.regex101_id ?? null
      }
    ];
    onDestroy(() => {
    });
    const viewMode = createViewModeStore({ storageKey: "regularExpressionsView" });
    $: simpleSearchStore = getPersistentSearchStore(`reSearch:${data.currentDatabase.id}`, { debounceMs: 150 });
    $: simpleQuery = store_get($$store_subs ??= {}, "$simpleSearchStore", simpleSearchStore).query;
    $: useSimpleMode = store_get($$store_subs ??= {}, "$filterMode", filterMode) === "simple";
    $: filtered = (() => {
      if (useSimpleMode) {
        if (!simpleQuery) return data.regularExpressions;
        const q2 = simpleQuery.toLowerCase();
        return data.regularExpressions.filter((r2) => r2.name.toLowerCase().includes(q2));
      }
      return applySmartFilters(data.regularExpressions, filterTags, fields);
    })();
    $: tabs = data.databases.map((db2) => ({
      label: db2.name,
      href: `/regular-expressions/${db2.id}`,
      active: db2.id === data.currentDatabase.id
    }));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: `${data.currentDatabase.name} \xB7 Regular Expressions` });
      $$renderer3.push(`<!----> <div class="space-y-6 px-4 pb-8 md:px-8">`);
      Tabs($$renderer3, {
        tabs,
        responsive: true
      });
      $$renderer3.push(`<!----> `);
      ActionsBar($$renderer3, {
        children: ($$renderer4) => {
          if (useSimpleMode) {
            $$renderer4.push("<!--[0-->");
            SearchAction($$renderer4, {
              searchStore: simpleSearchStore,
              placeholder: "Search regular expressions...",
              responsive: true
            });
          } else {
            $$renderer4.push("<!--[-1-->");
            SmartFilterBar($$renderer4, {
              fields,
              items: data.regularExpressions,
              storageKey: `smartFilter:regularExpressions:${data.currentDatabase.id}`,
              placeholder: "Filter regular expressions...",
              get tags() {
                return filterTags;
              },
              set tags($$value) {
                filterTags = $$value;
                $$settled = false;
              }
            });
          }
          $$renderer4.push(`<!--]--> `);
          ActionButton($$renderer4, {
            icon: Plus,
            hasDropdown: true,
            dropdownPosition: "right",
            $$slots: { dropdown: ($$renderer5) => {
              Dropdown($$renderer5, {
                position: "right",
                minWidth: "14rem",
                children: ($$renderer6) => {
                  DropdownHeader($$renderer6, { label: "New expression" });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, {
                    icon: File_text,
                    label: "Blank"
                  });
                  $$renderer6.push(`<!----> `);
                  DropdownItem($$renderer6, {
                    icon: Users,
                    label: "Release Group"
                  });
                  $$renderer6.push(`<!---->`);
                },
                $$slots: { default: true }
              });
            } }
          });
          $$renderer4.push(`<!----> `);
          $$renderer4.push("<!--[0-->");
          FilterModeToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$filterMode", filterMode);
            },
            set value($$value) {
              store_set(filterMode, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!--]--> `);
          ViewToggle($$renderer4, {
            get value() {
              return store_get($$store_subs ??= {}, "$viewMode", viewMode);
            },
            set value($$value) {
              store_set(viewMode, $$value);
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----> `);
          ActionButton($$renderer4, { icon: Info });
          $$renderer4.push(`<!---->`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> <div class="mt-6">`);
      if (data.regularExpressions.length === 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No regular expressions found for ${escape_html(data.currentDatabase?.name)}</p></div>`);
      } else if (filtered.length === 0) {
        $$renderer3.push("<!--[1-->");
        $$renderer3.push(`<div class="rounded-lg border border-neutral-200 bg-white p-8 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-neutral-600 dark:text-neutral-400">No regular expressions match the current filters</p></div>`);
      } else if (store_get($$store_subs ??= {}, "$viewMode", viewMode) === "table") {
        $$renderer3.push("<!--[2-->");
        TableView9($$renderer3, { expressions: filtered });
      } else {
        $$renderer3.push("<!--[-1-->");
        CardView9($$renderer3, { expressions: filtered });
      }
      $$renderer3.push(`<!--]--></div></div> `);
      InfoModal($$renderer3, {
        header: "About Regular Expressions",
        get open() {
          return infoModalOpen;
        },
        set open($$value) {
          infoModalOpen = $$value;
          $$settled = false;
        },
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="space-y-4 text-sm text-neutral-700 dark:text-neutral-300"><section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">How It Works</h3> <p>Regular expressions in Profilarr are separated from custom formats to make them reusable.
				When multiple custom formats share the same pattern, you only need to update it in one
				place.</p> <p class="mt-2">When custom formats are synced to your Arr instances, Profilarr compiles the referenced
				patterns into the format each Arr expects. The regular expressions themselves are <strong>not</strong> synced directly\u2014only the compiled custom formats are.</p></section> <section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Regex Flavor</h3> <p>Radarr and Sonarr use the <strong>.NET regex engine</strong> (specifically .NET 6+). Patterns
				are matched case-insensitively by default.</p></section> <section><h3 class="mb-2 font-semibold text-neutral-900 dark:text-neutral-100">Testing Patterns</h3> <p>Use <a href="https://regex101.com" target="_blank" rel="noopener noreferrer" class="text-accent-600 hover:underline dark:text-accent-400">regex101.com</a> to test your patterns. Make sure to select the <strong>.NET</strong> flavor from the dropdown
				for accurate results.</p> <p class="mt-2 text-xs text-neutral-500 dark:text-neutral-400">Tip: When saving a regex101 link, include the version number (e.g., <code class="rounded bg-neutral-100 px-1 dark:bg-neutral-800">ABC123/1</code>) to ensure it always points to your specific version.</p></section></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      CloneModal($$renderer3, {
        databaseId: data.currentDatabase.id,
        entityType: "regular_expression",
        sourceName: cloneSourceName,
        existingNames: data.regularExpressions.map((r2) => r2.name),
        canWriteToBase: data.canWriteToBase,
        get open() {
          return cloneModalOpen;
        },
        set open($$value) {
          cloneModalOpen = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte64 = __esm({
  "dist/build/server/entries/pages/regular-expressions/_databaseId_/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_features();
    init_sanitize();
    init_Dropdown();
    init_code();
    init_copy();
    init_download();
    init_external_link();
    init_file_text();
    init_info();
    init_link();
    init_Button();
    init_plus();
    init_search();
    init_filterMode();
    init_ViewToggle();
    init_tag();
    init_users2();
    init_stores();
    init_store2();
    init_Label();
    init_Card();
    init_navigation();
    init_DropdownItem();
    init_Tabs();
    init_progressiveList();
    init_ActionsBar();
    init_ActionButton();
    init_DropdownHeader();
    init_InfoModal();
    init_PageMeta();
    init_Table();
    init_CardGrid();
    init_dataPage();
    init_CloneModal();
    init_entitySearch();
    init_marked_esm();
  }
});

// dist/build/server/nodes/74.js
var __exports75 = {};
__export(__exports75, {
  component: () => component71,
  fonts: () => fonts75,
  imports: () => imports75,
  index: () => index75,
  server: () => page_server_ts_exports66,
  server_id: () => server_id72,
  stylesheets: () => stylesheets75
});
var index75, component_cache71, component71, server_id72, imports75, stylesheets75, fonts75;
var init__75 = __esm({
  async "dist/build/server/nodes/74.js"() {
    "use strict";
    await init_page_server_ts66();
    index75 = 74;
    component71 = async () => component_cache71 ??= (await Promise.resolve().then(() => (init_page_svelte64(), page_svelte_exports64))).default;
    server_id72 = "src/routes/regular-expressions/[databaseId]/+page.server.ts";
    imports75 = ["_app/immutable/nodes/74.DUiiCkLh.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/D7OHFWTL2.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/C_LFCSMn.js", "_app/immutable/chunks/MJc6__n-.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/Cut3gr1-.js", "_app/immutable/chunks/C_Z5Pdot2.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/DxZIQ_tr2.js", "_app/immutable/chunks/DSmeX4VS2.js", "_app/immutable/chunks/D1zkFcXr.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/DYe9q02k2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/VZQaB9P52.js"];
    stylesheets75 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/filterMode.DdGl7mkT.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css", "_app/immutable/assets/74.DTgmkoUS.css"];
    fonts75 = [];
  }
});

// dist/build/server/entries/pages/regular-expressions/_databaseId_/_id_/_page.server.ts.js
var page_server_ts_exports67 = {};
__export(page_server_ts_exports67, {
  actions: () => actions42,
  load: () => load70
});
var load70, actions42;
var init_page_server_ts67 = __esm({
  async "dist/build/server/entries/pages/regular-expressions/_databaseId_/_id_/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_queueService();
    await init_generalSettings();
    await init_update4();
    await init_regularExpressions();
    await init_client2();
    await init_parser();
    await init_affectedArrs();
    init_exports();
    load70 = async ({ params }) => {
      const { databaseId, id } = params;
      if (!databaseId || !id) throw error(400, "Missing parameters");
      const currentDatabaseId = parseInt(databaseId, 10);
      const regexId = parseInt(id, 10);
      if (isNaN(currentDatabaseId) || isNaN(regexId)) throw error(400, "Invalid parameters");
      const currentDatabase = pcdManager.getByIdPublic(currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) throw error(500, "Database cache not available");
      const regularExpression = await get2(cache3, regexId);
      if (!regularExpression) throw error(404, "Regular expression not found");
      return {
        currentDatabase,
        regularExpression,
        conditionRefs: await getConditionRefsForRegex(cache3, regularExpression.name),
        failOnReferencedDelete: generalSettingsQueries.shouldFailOnReferencedDelete(),
        canWriteToBase: canWriteToBase(currentDatabaseId)
      };
    };
    actions42 = {
      update: async ({ request, params }) => {
        const { databaseId, id } = params;
        if (!databaseId || !id) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        const regexId = parseInt(id, 10);
        if (isNaN(currentDatabaseId) || isNaN(regexId)) return fail(400, { error: "Invalid parameters" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await get2(cache3, regexId);
        if (!current3) return fail(404, { error: "Regular expression not found" });
        const formData = await request.formData();
        const name = formData.get("name");
        const tagsJson = formData.get("tags");
        const pattern2 = formData.get("pattern");
        const description = formData.get("description") || null;
        const regex101Id = formData.get("regex101Id") || null;
        const layer = formData.get("layer") || "user";
        if (!name?.trim()) return fail(400, { error: "Name is required" });
        if (!pattern2?.trim()) return fail(400, { error: "Pattern is required" });
        const regexValidation = await validateRegex(pattern2.trim());
        if (regexValidation && !regexValidation.valid) return fail(400, { error: `Invalid regex: ${regexValidation.error}` });
        let tags = [];
        try {
          tags = JSON.parse(tagsJson || "[]");
        } catch {
          return fail(400, { error: "Invalid tags format" });
        }
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        let result;
        try {
          result = await update({
            databaseId: currentDatabaseId,
            cache: cache3,
            layer,
            current: current3,
            input: {
              name: name.trim(),
              pattern: pattern2.trim(),
              tags,
              description: description?.trim() || null,
              regex101Id: regex101Id?.trim() || null
            }
          });
        } catch (err) {
          const message2 = err instanceof Error ? err.message : "Failed to update regular expression";
          if (message2.includes("already exists")) return fail(400, { error: message2 });
          return fail(500, { error: message2 });
        }
        if (!result.success) return fail(500, { error: result.error || "Failed to update regular expression" });
        const affectedArrs = getAffectedArrs({
          entityType: "regularExpression",
          databaseId: currentDatabaseId,
          entityName: name.trim()
        });
        return {
          success: true,
          redirectTo: `/regular-expressions/${databaseId}`,
          affectedArrs
        };
      },
      delete: async ({ request, params }) => {
        const { databaseId, id } = params;
        if (!databaseId || !id) return fail(400, { error: "Missing parameters" });
        const currentDatabaseId = parseInt(databaseId, 10);
        const regexId = parseInt(id, 10);
        if (isNaN(currentDatabaseId) || isNaN(regexId)) return fail(400, { error: "Invalid parameters" });
        const cache3 = pcdManager.getCache(currentDatabaseId);
        if (!cache3) return fail(500, { error: "Database cache not available" });
        const current3 = await get2(cache3, regexId);
        if (!current3) return fail(404, { error: "Regular expression not found" });
        const layerFromForm = (await request.formData()).get("layer");
        const layer = layerFromForm || "user";
        await logger.debug("Delete action received", {
          source: "RegularExpressionDelete",
          meta: {
            regexId,
            regexName: current3.name,
            layerFromForm,
            layerUsed: layer
          }
        });
        if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
        const result = await remove3({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          current: current3
        });
        if (!result.success) {
          const status = result.error?.startsWith("Referenced by ") ? 400 : 500;
          return fail(status, { error: result.error || "Failed to delete regular expression" });
        }
        throw redirect(303, `/regular-expressions/${databaseId}`);
      }
    };
  }
});

// dist/build/server/chunks/RegularExpressionForm.js
function RegexPatternField($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let pattern2 = fallback($$props["pattern"], "");
    let regex101Id = fallback($$props["regex101Id"], "");
    let onPatternChange = fallback($$props["onPatternChange"], void 0);
    let onRegex101IdChange = fallback($$props["onRegex101IdChange"], void 0);
    let onValidationStateChange = fallback($$props["onValidationStateChange"], void 0);
    let validationState = "idle";
    $: onValidationStateChange?.(validationState);
    $$renderer2.push(`<div class="space-y-4"><div data-onboarding="regex-pattern" class="space-y-2"><div class="flex items-center justify-between gap-2"><label for="pattern" class="block text-sm font-medium text-neutral-900 dark:text-neutral-100">Regular Expression<span class="text-red-500">*</span></label> `);
    $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div> `);
    FormInput($$renderer2, {
      label: "Regular Expression",
      hideLabel: true,
      description: "Uses .NET regex flavor (case-insensitive by default)",
      name: "pattern",
      value: pattern2,
      placeholder: "e.g., \\b(SPARKS)\\b",
      required: true,
      textarea: true,
      rows: 3,
      mono: true
    });
    $$renderer2.push(`<!----> `);
    $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div> <div data-onboarding="regex101-id">`);
    FormInput($$renderer2, {
      label: "Regex101 ID",
      description: "Link to regex101.com for testing (include version, e.g., ABC123/1)",
      name: "regex101Id",
      value: regex101Id,
      placeholder: "e.g., GMV8jd/1",
      mono: true
    });
    $$renderer2.push(`<!----></div></div>`);
    bind_props($$props, {
      pattern: pattern2,
      regex101Id,
      onPatternChange,
      onRegex101IdChange,
      onValidationStateChange
    });
  });
}
function UnitTests($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let unitTests = fallback($$props["unitTests"], () => [], true);
    let loading = fallback($$props["loading"], false);
    let error2 = fallback($$props["error"], null);
    let regex101Url = fallback($$props["regex101Url"], "");
    const { search, view, filtered, setItems } = createDataPageStore(unitTests, {
      storageKey: "regexUnitTestsView",
      searchKeys: ["testString", "description"],
      defaultView: "table"
    });
    function applyFilters(tests) {
      return tests.filter((test2) => {
        return true;
      });
    }
    const columns = [
      {
        key: "testString",
        header: "Test String",
        align: "left"
      },
      {
        key: "description",
        header: "Description",
        align: "left"
      },
      {
        key: "criteria",
        header: "Should Match",
        width: "w-36",
        align: "center"
      },
      {
        key: "passed",
        header: "Result",
        width: "w-20",
        align: "center"
      }
    ];
    const skeletonTests = Array.from({ length: 3 }, (_3, i) => ({ id: i }));
    $: unitTests.filter((t2) => t2.passed === true).length;
    $: unitTests.filter((t2) => t2.passed === false).length;
    $: unitTests.filter((t2) => t2.criteria === "DOES_MATCH").length;
    $: unitTests.filter((t2) => t2.criteria === "DOES_NOT_MATCH").length;
    $: setItems(applyFilters(unitTests));
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      if (loading) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="space-y-2"><!--[-->`);
        const each_array = ensure_array_like(skeletonTests);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          each_array[$$index];
          Card($$renderer3, {
            padding: "sm",
            flush: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<div class="flex items-center gap-3"><div class="h-5 w-5 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div> <div class="flex-1 space-y-1.5"><div class="h-3 w-24 animate-pulse rounded bg-neutral-200 dark:bg-neutral-700"></div> <div class="h-4 w-48 animate-pulse rounded bg-neutral-100 dark:bg-neutral-800"></div></div> <div class="h-5 w-16 animate-pulse rounded-full bg-neutral-200 dark:bg-neutral-700"></div></div>`);
            },
            $$slots: { default: true }
          });
        }
        $$renderer3.push(`<!--]--></div>`);
      } else if (error2) {
        $$renderer3.push("<!--[1-->");
        $$renderer3.push(`<div class="flex items-center gap-2 rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-700 dark:border-red-800 dark:bg-red-950/40 dark:text-red-300">`);
        Circle_alert($$renderer3, { size: 16 });
        $$renderer3.push(`<!----> <span>${escape_html(error2)}</span></div>`);
      } else if (unitTests.length === 0) {
        $$renderer3.push("<!--[2-->");
        $$renderer3.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">No unit tests found for this regex.</p>`);
      } else {
        $$renderer3.push("<!--[-1-->");
        ActionsBar($$renderer3, {
          children: ($$renderer4) => {
            SearchAction($$renderer4, {
              searchStore: search,
              placeholder: "Search tests...",
              responsive: true
            });
            $$renderer4.push(`<!----> <div class="group relative flex" role="group">`);
            ActionButton($$renderer4, {
              icon: Circle_check,
              title: "Filter by result"
            });
            $$renderer4.push(`<!----> `);
            $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></div> <div class="group relative flex" role="group">`);
            ActionButton($$renderer4, {
              icon: Circle_x,
              title: "Filter by expected"
            });
            $$renderer4.push(`<!----> `);
            $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--></div> `);
            ViewToggle($$renderer4, {
              get value() {
                return store_get($$store_subs ??= {}, "$view", view);
              },
              set value($$value) {
                store_set(view, $$value);
                $$settled = false;
              }
            });
            $$renderer4.push(`<!----> `);
            if (regex101Url) {
              $$renderer4.push("<!--[0-->");
              Tooltip($$renderer4, {
                text: "Regex101",
                children: ($$renderer5) => {
                  ActionButton($$renderer5, {
                    icon: External_link,
                    iconClass: "text-blue-600 dark:text-blue-400"
                  });
                },
                $$slots: { default: true }
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----> `);
        if (store_get($$store_subs ??= {}, "$filtered", filtered).length === 0) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="mt-4 rounded-lg border border-neutral-200 bg-white p-6 text-center dark:border-neutral-800 dark:bg-neutral-900"><p class="text-sm text-neutral-500 dark:text-neutral-400">No tests match the current filters.</p></div>`);
        } else if (store_get($$store_subs ??= {}, "$view", view) === "table") {
          $$renderer3.push("<!--[1-->");
          $$renderer3.push(`<div class="mt-4">`);
          Table2($$renderer3, {
            data: store_get($$store_subs ??= {}, "$filtered", filtered),
            columns,
            emptyMessage: "No tests found",
            hoverable: false,
            compact: true,
            $$slots: { cell: ($$renderer4, { row, column }) => {
              if (column.key === "testString") {
                $$renderer4.push("<!--[0-->");
                Label($$renderer4, {
                  variant: "secondary",
                  size: "md",
                  rounded: "md",
                  mono: true,
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->${escape_html(row.testString)}`);
                  },
                  $$slots: { default: true }
                });
              } else if (column.key === "description") {
                $$renderer4.push("<!--[1-->");
                if (row.description) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(row.description)}</span>`);
                } else {
                  $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<span class="text-neutral-400 dark:text-neutral-500">\u2014</span>`);
                }
                $$renderer4.push(`<!--]-->`);
              } else if (column.key === "criteria") {
                $$renderer4.push("<!--[2-->");
                Label($$renderer4, {
                  variant: row.criteria === "DOES_MATCH" ? "success" : "danger",
                  size: "sm",
                  rounded: "md",
                  children: ($$renderer5) => {
                    $$renderer5.push(`<!---->${escape_html(row.criteria === "DOES_MATCH" ? "Should Match" : "Shouldn't Match")}`);
                  },
                  $$slots: { default: true }
                });
              } else if (column.key === "passed") {
                $$renderer4.push("<!--[3-->");
                if (row.passed === void 0) {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="flex items-center justify-center"><div class="flex h-6 w-6 items-center justify-center rounded-full bg-neutral-100 dark:bg-neutral-800"><span class="text-xs font-medium text-neutral-400 dark:text-neutral-500">?</span></div></div>`);
                } else if (row.passed) {
                  $$renderer4.push("<!--[1-->");
                  $$renderer4.push(`<div class="flex items-center justify-center"><div class="flex h-6 w-6 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900">`);
                  Check($$renderer4, {
                    size: 14,
                    class: "text-emerald-600 dark:text-emerald-400"
                  });
                  $$renderer4.push(`<!----></div></div>`);
                } else {
                  $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<div class="flex items-center justify-center"><div class="flex h-6 w-6 items-center justify-center rounded-full bg-red-100 dark:bg-red-900">`);
                  X2($$renderer4, {
                    size: 14,
                    class: "text-red-600 dark:text-red-400"
                  });
                  $$renderer4.push(`<!----></div></div>`);
                }
                $$renderer4.push(`<!--]-->`);
              } else $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<!--]-->`);
            } }
          });
          $$renderer3.push(`<!----></div>`);
        } else {
          $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<div class="mt-4">`);
          CardGrid($$renderer3, {
            columns: 1,
            gap: "sm",
            children: ($$renderer4) => {
              $$renderer4.push(`<!--[-->`);
              const each_array_1 = ensure_array_like(store_get($$store_subs ??= {}, "$filtered", filtered));
              for (let idx = 0, $$length = each_array_1.length; idx < $$length; idx++) {
                let test2 = each_array_1[idx];
                Card($$renderer4, {
                  padding: "sm",
                  flush: true,
                  children: ($$renderer5) => {
                    $$renderer5.push(`<div class="hidden space-y-2 md:block"><div class="flex items-start gap-2"><div class="min-w-0 flex-1"><span class="inline-flex flex-wrap items-center gap-1 rounded-md bg-neutral-100 px-2.5 py-1 font-mono text-xs font-medium break-all text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300">${escape_html(test2.testString)}</span></div> <div class="shrink-0">`);
                    Label($$renderer5, {
                      variant: test2.criteria === "DOES_MATCH" ? "success" : "danger",
                      size: "sm",
                      rounded: "md",
                      children: ($$renderer6) => {
                        $$renderer6.push(`<!---->${escape_html(test2.criteria === "DOES_MATCH" ? "Should Match" : "Shouldn't Match")}`);
                      },
                      $$slots: { default: true }
                    });
                    $$renderer5.push(`<!----></div></div> <div class="flex items-start gap-2"><div class="min-w-0 flex-1">`);
                    if (test2.description) {
                      $$renderer5.push("<!--[0-->");
                      $$renderer5.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(test2.description)}</p>`);
                    } else $$renderer5.push("<!--[-1-->");
                    $$renderer5.push(`<!--]--></div> <div class="shrink-0">`);
                    if (test2.passed === void 0) {
                      $$renderer5.push("<!--[0-->");
                      Label($$renderer5, {
                        variant: "warning",
                        size: "sm",
                        rounded: "md",
                        children: ($$renderer6) => {
                          $$renderer6.push(`<!---->Unknown`);
                        },
                        $$slots: { default: true }
                      });
                    } else if (test2.passed) {
                      $$renderer5.push("<!--[1-->");
                      Label($$renderer5, {
                        variant: "success",
                        size: "sm",
                        rounded: "md",
                        children: ($$renderer6) => {
                          Check($$renderer6, { size: 10 });
                          $$renderer6.push(`<!----> Passed`);
                        },
                        $$slots: { default: true }
                      });
                    } else {
                      $$renderer5.push("<!--[-1-->");
                      Label($$renderer5, {
                        variant: "danger",
                        size: "sm",
                        rounded: "md",
                        children: ($$renderer6) => {
                          X2($$renderer6, { size: 10 });
                          $$renderer6.push(`<!----> Failed`);
                        },
                        $$slots: { default: true }
                      });
                    }
                    $$renderer5.push(`<!--]--></div></div></div> <div class="space-y-2 md:hidden"><span class="inline-flex flex-wrap items-center gap-1 rounded-md bg-neutral-100 px-2.5 py-1 font-mono text-xs font-medium break-all text-neutral-700 dark:bg-neutral-800 dark:text-neutral-300">${escape_html(test2.testString)}</span> `);
                    if (test2.description) {
                      $$renderer5.push("<!--[0-->");
                      $$renderer5.push(`<p class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(test2.description)}</p>`);
                    } else $$renderer5.push("<!--[-1-->");
                    $$renderer5.push(`<!--]--> <div class="flex items-center gap-2">`);
                    Label($$renderer5, {
                      variant: test2.criteria === "DOES_MATCH" ? "success" : "danger",
                      size: "sm",
                      rounded: "md",
                      children: ($$renderer6) => {
                        $$renderer6.push(`<!---->${escape_html(test2.criteria === "DOES_MATCH" ? "Should Match" : "Shouldn't Match")}`);
                      },
                      $$slots: { default: true }
                    });
                    $$renderer5.push(`<!----> `);
                    if (test2.passed === void 0) {
                      $$renderer5.push("<!--[0-->");
                      Label($$renderer5, {
                        variant: "warning",
                        size: "sm",
                        rounded: "md",
                        children: ($$renderer6) => {
                          $$renderer6.push(`<!---->Unknown`);
                        },
                        $$slots: { default: true }
                      });
                    } else if (test2.passed) {
                      $$renderer5.push("<!--[1-->");
                      Label($$renderer5, {
                        variant: "success",
                        size: "sm",
                        rounded: "md",
                        children: ($$renderer6) => {
                          Check($$renderer6, { size: 10 });
                          $$renderer6.push(`<!----> Passed`);
                        },
                        $$slots: { default: true }
                      });
                    } else {
                      $$renderer5.push("<!--[-1-->");
                      Label($$renderer5, {
                        variant: "danger",
                        size: "sm",
                        rounded: "md",
                        children: ($$renderer6) => {
                          X2($$renderer6, { size: 10 });
                          $$renderer6.push(`<!----> Failed`);
                        },
                        $$slots: { default: true }
                      });
                    }
                    $$renderer5.push(`<!--]--></div></div>`);
                  },
                  $$slots: { default: true }
                });
              }
              $$renderer4.push(`<!--]-->`);
            },
            $$slots: { default: true }
          });
          $$renderer3.push(`<!----></div>`);
        }
        $$renderer3.push(`<!--]-->`);
      }
      $$renderer3.push(`<!--]-->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      unitTests,
      loading,
      error: error2,
      regex101Url
    });
  });
}
function RegularExpressionForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let formData, databaseId, title, description_, submitButtonText, deleteBlocked, deleteTooltip, isValid, saveTooltip;
    let mode = $$props["mode"];
    let databaseName = $$props["databaseName"];
    let canWriteToBase2 = fallback($$props["canWriteToBase"], false);
    let actionUrl = fallback($$props["actionUrl"], "");
    let initialData = $$props["initialData"];
    let failOnReferencedDelete = fallback($$props["failOnReferencedDelete"], false);
    let referenceCount = fallback($$props["referenceCount"], 0);
    let breadcrumbItems = fallback($$props["breadcrumbItems"], () => [], true);
    let breadcrumbCurrent = fallback($$props["breadcrumbCurrent"], "");
    let onCancel = $$props["onCancel"];
    const defaults = {
      name: "",
      tags: [],
      pattern: "",
      description: "",
      regex101Id: ""
    };
    if (mode === "create") initCreate(initialData ?? defaults);
    else initEdit(initialData);
    let selectedLayer = canWriteToBase2 ? "base" : "user";
    let showDeleteConfirmModal = false;
    let showSyncModal = false;
    let pendingRedirectTo = "";
    let pendingAffectedArrs = [];
    let deleteLayer = canWriteToBase2 ? "base" : "user";
    let unitTests = [];
    let unitTestsLoading = false;
    let unitTestsError = null;
    let patternValidationState = "idle";
    $: formData = store_get($$store_subs ??= {}, "$current", current2);
    $: databaseId = parseInt(store_get($$store_subs ??= {}, "$page", page).params.databaseId ?? "0", 10);
    $: title = mode === "create" ? "New Regular Expression" : "Edit Regular Expression";
    $: description_ = mode === "create" ? `Create a new regular expression for ${databaseName}` : `Update regular expression settings`;
    $: submitButtonText = mode === "create" ? "Create" : "Save Changes";
    $: deleteBlocked = mode === "edit" && failOnReferencedDelete && referenceCount > 0;
    $: deleteTooltip = deleteBlocked ? `Referenced by ${referenceCount} custom format${referenceCount === 1 ? "" : "s"}` : "";
    $: if (!formData.regex101Id) {
      unitTests = [];
      unitTestsError = null;
    }
    $: isValid = formData.name.trim() !== "" && formData.pattern.trim() !== "" && patternValidationState !== "invalid";
    $: saveTooltip = patternValidationState === "invalid" ? "Pattern is not a valid .NET regex" : "";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="space-y-6">`);
      StickyCard($$renderer3, {
        position: "top",
        breadcrumbItems,
        breadcrumbCurrent,
        $$slots: {
          left: ($$renderer4) => {
            $$renderer4.push(`<div><h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h2> <p class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(description_)}</p></div>`);
          },
          right: ($$renderer4) => {
            $$renderer4.push(`<div class="flex items-center gap-2">`);
            if (mode === "edit") {
              $$renderer4.push("<!--[0-->");
              Button($$renderer4, {
                disabled: deleteBlocked,
                icon: Trash_2,
                iconColor: "text-red-600 dark:text-red-400",
                text: "Delete",
                tooltip: deleteTooltip
              });
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]--> `);
            Button($$renderer4, { text: "Cancel" });
            $$renderer4.push(`<!----> `);
            Button($$renderer4, {
              disabled: !isValid || !store_get($$store_subs ??= {}, "$isDirty", isDirty),
              icon: Save,
              iconColor: "text-blue-600 dark:text-blue-400",
              text: submitButtonText,
              tooltip: saveTooltip,
              tooltipPosition: "bottom"
            });
            $$renderer4.push(`<!----></div>`);
          }
        }
      });
      $$renderer3.push(`<!----> <form method="POST"${attr("action", actionUrl)} class="md:px-4"><input type="hidden" name="tags"${attr("value", JSON.stringify(formData.tags))}/> <input type="hidden" name="layer"${attr("value", selectedLayer)}/> <div class="space-y-6"><div data-onboarding="regex-metadata" class="space-y-6">`);
      FormInput($$renderer3, {
        label: "Name",
        name: "name",
        required: true,
        value: formData.name,
        placeholder: "e.g., Release Group - SPARKS"
      });
      $$renderer3.push(`<!----> <div><div class="block text-sm font-medium text-neutral-700 dark:text-neutral-300">Tags</div> <p class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">Categorize this pattern for easier filtering</p> <div class="mt-2">`);
      TagInput($$renderer3, {
        tags: formData.tags,
        onchange: (newTags) => update3("tags", newTags),
        placeholder: "Add tags..."
      });
      $$renderer3.push(`<!----></div></div> <div>`);
      MarkdownInput($$renderer3, {
        id: "description",
        name: "description",
        label: "Description",
        description: "Describe what this pattern matches",
        value: formData.description,
        onchange: (v3) => update3("description", v3),
        placeholder: "What does this pattern match?"
      });
      $$renderer3.push(`<!----></div></div> `);
      RegexPatternField($$renderer3, {
        pattern: formData.pattern,
        regex101Id: formData.regex101Id,
        onPatternChange: (v3) => update3("pattern", v3),
        onRegex101IdChange: (v3) => update3("regex101Id", v3),
        onValidationStateChange: (s3) => patternValidationState = s3
      });
      $$renderer3.push(`<!----></div></form> `);
      if (formData.regex101Id) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="md:px-4"><h4 class="mb-3 text-sm font-medium text-neutral-700 dark:text-neutral-300">Unit Tests `);
        if (unitTests.length > 0) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<span class="ml-1 text-xs font-normal text-neutral-500">(${escape_html(unitTests.length)})</span>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></h4> `);
        UnitTests($$renderer3, {
          unitTests,
          loading: unitTestsLoading,
          error: unitTestsError,
          regex101Url: formData.regex101Id ? `https://regex101.com/r/${formData.regex101Id}` : ""
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<form method="POST" action="?/delete" class="hidden"><input type="hidden" name="layer"${attr("value", deleteLayer)}/></form>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> `);
      if (mode === "edit") {
        $$renderer3.push("<!--[0-->");
        Modal($$renderer3, {
          open: showDeleteConfirmModal,
          header: "Delete Regular Expression",
          bodyMessage: `Are you sure you want to delete "${formData.name}"? This action cannot be undone.`,
          confirmText: "Delete",
          cancelText: "Cancel",
          confirmDanger: true
        });
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--> `);
      SyncPromptModal($$renderer3, {
        redirectTo: pendingRedirectTo,
        affectedArrs: pendingAffectedArrs,
        entityType: "regularExpression",
        databaseId,
        entityName: formData.name.trim(),
        get open() {
          return showSyncModal;
        },
        set open($$value) {
          showSyncModal = $$value;
          $$settled = false;
        }
      });
      $$renderer3.push(`<!---->`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      mode,
      databaseName,
      canWriteToBase: canWriteToBase2,
      actionUrl,
      initialData,
      failOnReferencedDelete,
      referenceCount,
      breadcrumbItems,
      breadcrumbCurrent,
      onCancel
    });
  });
}
var init_RegularExpressionForm = __esm({
  "dist/build/server/chunks/RegularExpressionForm.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_Dropdown();
    init_MarkdownInput();
    init_check();
    init_circle_alert();
    init_circle_check();
    init_circle_x();
    init_external_link();
    init_Button();
    init_save();
    init_search();
    init_ViewToggle();
    init_trash_2();
    init_x();
    init_stores();
    init_store2();
    init_Label();
    init_Card();
    init_navigation();
    init_Modal();
    init_forms();
    init_DropdownItem();
    init_dirty();
    init_ActionsBar();
    init_ActionButton();
    init_DropdownHeader();
    init_Table();
    init_CardGrid();
    init_dataPage();
    init_StickyCard();
    init_FormInput();
    init_TagInput();
    init_SyncPromptModal();
  }
});

// dist/build/server/entries/pages/regular-expressions/_databaseId_/_id_/_page.svelte.js
var page_svelte_exports65 = {};
__export(page_svelte_exports65, {
  default: () => _page65
});
function _page65($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let initialData, referencedFormatCount;
    let data = $$props["data"];
    function handleCancel() {
      goto(`/regular-expressions/${data.currentDatabase.id}`);
    }
    const columns = [
      {
        key: "cfName",
        header: "Custom Format"
      },
      {
        key: "conditionName",
        header: "Condition"
      },
      {
        key: "flags",
        header: "Flags",
        align: "center"
      }
    ];
    $: initialData = {
      name: data.regularExpression.name,
      tags: data.regularExpression.tags.map((t2) => t2.name),
      pattern: data.regularExpression.pattern,
      description: data.regularExpression.description ?? "",
      regex101Id: data.regularExpression.regex101_id ?? ""
    };
    $: referencedFormatCount = new Set(data.conditionRefs.map((ref) => ref.cfId)).size;
    PageMeta($$renderer2, { title: `${data.regularExpression.name} \xB7 General` });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8">`);
    RegularExpressionForm($$renderer2, {
      mode: "edit",
      databaseName: data.currentDatabase?.name,
      canWriteToBase: data.canWriteToBase,
      actionUrl: "?/update",
      initialData,
      failOnReferencedDelete: data.failOnReferencedDelete,
      referenceCount: referencedFormatCount,
      onCancel: handleCancel,
      breadcrumbItems: [{
        label: data.currentDatabase.name,
        href: `/regular-expressions/${data.currentDatabase.id}`
      }],
      breadcrumbCurrent: data.regularExpression.name
    });
    $$renderer2.push(`<!----> <div data-onboarding="regex-references" class="mt-6 space-y-3 md:px-4"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">References (${escape_html(data.conditionRefs.length)})</div> `);
    if (data.conditionRefs.length > 0) {
      $$renderer2.push("<!--[0-->");
      Table2($$renderer2, {
        data: data.conditionRefs,
        columns,
        compact: true,
        responsive: true,
        $$slots: { cell: ($$renderer3, { row, column }) => {
          if (column.key === "cfName") {
            $$renderer3.push("<!--[0-->");
            InlineLink($$renderer3, {
              href: `/custom-formats/${stringify(data.currentDatabase.id)}/${stringify(row.cfId)}/conditions`,
              text: row.cfName,
              external: true
            });
          } else if (column.key === "conditionName") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`${escape_html(row.conditionName)}`);
          } else if (column.key === "flags") {
            $$renderer3.push("<!--[2-->");
            $$renderer3.push(`<div class="flex items-center justify-center gap-1">`);
            if (row.negate) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "warning",
                size: "sm",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Negate`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--> `);
            if (row.required) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "info",
                size: "sm",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Required`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } }
      });
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">Not used in any custom formats.</p>`);
    }
    $$renderer2.push(`<!--]--></div></div> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte65 = __esm({
  "dist/build/server/entries/pages/regular-expressions/_databaseId_/_id_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_client4();
    init_navigation();
    init_DirtyModal();
    init_Badge();
    init_PageMeta();
    init_Table();
    init_InlineLink();
    init_RegularExpressionForm();
  }
});

// dist/build/server/nodes/75.js
var __exports76 = {};
__export(__exports76, {
  component: () => component72,
  fonts: () => fonts76,
  imports: () => imports76,
  index: () => index76,
  server: () => page_server_ts_exports67,
  server_id: () => server_id73,
  stylesheets: () => stylesheets76
});
var index76, component_cache72, component72, server_id73, imports76, stylesheets76, fonts76;
var init__76 = __esm({
  async "dist/build/server/nodes/75.js"() {
    "use strict";
    await init_page_server_ts67();
    index76 = 75;
    component72 = async () => component_cache72 ??= (await Promise.resolve().then(() => (init_page_svelte65(), page_svelte_exports65))).default;
    server_id73 = "src/routes/regular-expressions/[databaseId]/[id]/+page.server.ts";
    imports76 = ["_app/immutable/nodes/75.MfpC0zJc.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/BhExzYrM2.js", "_app/immutable/chunks/rAXfrEzK2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/uDCknttb2.js", "_app/immutable/chunks/CQskZlkd2.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/CK2yQf0C.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js"];
    stylesheets76 = ["_app/immutable/assets/Table.aVDhXS1A.css", "_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css"];
    fonts76 = [];
  }
});

// dist/build/server/entries/pages/regular-expressions/_databaseId_/new/_page.server.ts.js
var page_server_ts_exports68 = {};
__export(page_server_ts_exports68, {
  actions: () => actions43,
  load: () => load71
});
var load71, actions43;
var init_page_server_ts68 = __esm({
  async "dist/build/server/entries/pages/regular-expressions/_databaseId_/new/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_queueService();
    await init_regularExpressions();
    await init_client2();
    await init_parser();
    init_exports();
    load71 = ({ params, url }) => {
      const { databaseId } = params;
      if (!databaseId) throw error(400, "Missing database ID");
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) throw error(400, "Invalid database ID");
      const currentDatabase = pcdManager.getByIdPublic(currentDatabaseId);
      if (!currentDatabase) throw error(404, "Database not found");
      const preset = url.searchParams.get("preset");
      let presetData = {
        name: "",
        tags: [],
        pattern: "",
        description: "",
        regex101Id: ""
      };
      if (preset === "release-group") presetData = {
        name: "",
        tags: ["Release Group"],
        pattern: "(?<=^|[\\s.-])<group>\\b",
        description: 'Matches "<group>" when preceded by whitespace, a hyphen or dot',
        regex101Id: ""
      };
      return {
        currentDatabase,
        canWriteToBase: canWriteToBase(currentDatabaseId),
        preset: presetData
      };
    };
    actions43 = { default: async ({ request, params }) => {
      const { databaseId } = params;
      if (!databaseId) return fail(400, { error: "Missing database ID" });
      const currentDatabaseId = parseInt(databaseId, 10);
      if (isNaN(currentDatabaseId)) return fail(400, { error: "Invalid database ID" });
      const cache3 = pcdManager.getCache(currentDatabaseId);
      if (!cache3) return fail(500, { error: "Database cache not available" });
      const formData = await request.formData();
      const name = formData.get("name");
      const tagsJson = formData.get("tags");
      const pattern2 = formData.get("pattern");
      const description = formData.get("description") || null;
      const regex101Id = formData.get("regex101Id") || null;
      const layerFromForm = formData.get("layer");
      const layer = layerFromForm || "user";
      await logger.debug("Create action received", {
        source: "RegularExpressionCreate",
        meta: {
          regexName: name,
          layerFromForm,
          layerUsed: layer
        }
      });
      if (!name?.trim()) return fail(400, { error: "Name is required" });
      if (!pattern2?.trim()) return fail(400, { error: "Pattern is required" });
      const regexValidation = await validateRegex(pattern2.trim());
      if (regexValidation && !regexValidation.valid) return fail(400, { error: `Invalid regex: ${regexValidation.error}` });
      let tags = [];
      try {
        tags = JSON.parse(tagsJson || "[]");
      } catch {
        return fail(400, { error: "Invalid tags format" });
      }
      if (layer === "base" && !canWriteToBase(currentDatabaseId)) return fail(403, { error: "Cannot write to base layer without personal access token" });
      let result;
      try {
        result = await create3({
          databaseId: currentDatabaseId,
          cache: cache3,
          layer,
          input: {
            name: name.trim(),
            pattern: pattern2.trim(),
            tags,
            description: description?.trim() || null,
            regex101Id: regex101Id?.trim() || null
          }
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to create regular expression";
        if (message2.includes("already exists")) return fail(400, { error: message2 });
        return fail(500, { error: message2 });
      }
      if (!result.success) return fail(500, { error: result.error || "Failed to create regular expression" });
      throw redirect(303, `/regular-expressions/${databaseId}`);
    } };
  }
});

// dist/build/server/entries/pages/regular-expressions/_databaseId_/new/_page.svelte.js
var page_svelte_exports66 = {};
__export(page_svelte_exports66, {
  default: () => _page66
});
function _page66($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    const initialData = {
      name: data.preset.name,
      tags: data.preset.tags,
      pattern: data.preset.pattern,
      description: data.preset.description,
      regex101Id: data.preset.regex101Id
    };
    function handleCancel() {
      goto(`/regular-expressions/${data.currentDatabase.id}`);
    }
    PageMeta($$renderer2, { title: `${data.currentDatabase.name} \xB7 Regular Expression \xB7 New` });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8">`);
    RegularExpressionForm($$renderer2, {
      mode: "create",
      databaseName: data.currentDatabase?.name,
      canWriteToBase: data.canWriteToBase,
      initialData,
      onCancel: handleCancel
    });
    $$renderer2.push(`<!----></div> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte66 = __esm({
  "dist/build/server/entries/pages/regular-expressions/_databaseId_/new/_page.svelte.js"() {
    "use strict";
    init_server();
    init_client4();
    init_navigation();
    init_DirtyModal();
    init_PageMeta();
    init_RegularExpressionForm();
  }
});

// dist/build/server/nodes/76.js
var __exports77 = {};
__export(__exports77, {
  component: () => component73,
  fonts: () => fonts77,
  imports: () => imports77,
  index: () => index77,
  server: () => page_server_ts_exports68,
  server_id: () => server_id74,
  stylesheets: () => stylesheets77
});
var index77, component_cache73, component73, server_id74, imports77, stylesheets77, fonts77;
var init__77 = __esm({
  async "dist/build/server/nodes/76.js"() {
    "use strict";
    await init_page_server_ts68();
    index77 = 76;
    component73 = async () => component_cache73 ??= (await Promise.resolve().then(() => (init_page_svelte66(), page_svelte_exports66))).default;
    server_id74 = "src/routes/regular-expressions/[databaseId]/new/+page.server.ts";
    imports77 = ["_app/immutable/nodes/76.hTEbVYFi.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/rAXfrEzK2.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/BOf7qRE7.js", "_app/immutable/chunks/CCK5X2n32.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BHkcdQFQ.js", "_app/immutable/chunks/r1twnwGx.js", "_app/immutable/chunks/CfXOj6DR.js", "_app/immutable/chunks/CT9uUPGn.js", "_app/immutable/chunks/DsOfWPM4.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/uDCknttb2.js", "_app/immutable/chunks/CQskZlkd2.js", "_app/immutable/chunks/CBPqn9zD2.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DLVOwqGo.js", "_app/immutable/chunks/CVQm0Ols.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/BfBgZfCV2.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/Dat55klv2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/BWZVzKif.js", "_app/immutable/chunks/CWc174af.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/CK2yQf0C.js", "_app/immutable/chunks/CHsDHO_G2.js", "_app/immutable/chunks/BKqLjepE.js", "_app/immutable/chunks/D-E0nZEG.js"];
    stylesheets77 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts77 = [];
  }
});

// dist/build/server/chunks/bell.js
function Bell($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "bell" },
    props,
    { iconNode: [["path", { "d": "M10.268 21a2 2 0 0 0 3.464 0" }], ["path", { "d": "M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326" }]] }
  ]));
}
var init_bell = __esm({
  "dist/build/server/chunks/bell.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/entries/pages/settings/_page.svelte.js
var page_svelte_exports67 = {};
__export(page_svelte_exports67, {
  default: () => _page67
});
function Archive($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "archive" },
    props,
    { iconNode: [
      ["rect", {
        "width": "20",
        "height": "5",
        "x": "2",
        "y": "3",
        "rx": "1"
      }],
      ["path", { "d": "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8" }],
      ["path", { "d": "M10 12h4" }]
    ] }
  ]));
}
function Graduation_cap($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "graduation-cap" },
    props,
    { iconNode: [
      ["path", { "d": "M21.42 10.922a1 1 0 0 0-.019-1.838L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.832l8.57 3.908a2 2 0 0 0 1.66 0z" }],
      ["path", { "d": "M22 10v6" }],
      ["path", { "d": "M6 12.5V16a6 3 0 0 0 12 0v-3.5" }]
    ] }
  ]));
}
function Shield_check($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "shield-check" },
    props,
    { iconNode: [["path", { "d": "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" }], ["path", { "d": "m9 12 2 2 4-4" }]] }
  ]));
}
function _page67($$renderer) {
  const settingsItems = [
    {
      label: "General",
      href: "/settings/general",
      description: "Application defaults, preferences, and behaviors",
      icon: Sliders_vertical,
      iconClass: "text-blue-600 dark:text-blue-400"
    },
    {
      label: "Security",
      href: "/settings/security",
      description: "Access control and sensitive operations",
      icon: Shield_check,
      iconClass: "text-rose-600 dark:text-rose-400"
    },
    {
      label: "Onboarding",
      href: "/onboarding",
      description: "Guided walkthroughs and interactive tutorials",
      icon: Graduation_cap,
      iconClass: "text-violet-600 dark:text-violet-400"
    },
    {
      label: "Notifications",
      href: "/settings/notifications",
      description: "Alerts, webhooks, and delivery settings",
      icon: Bell,
      iconClass: "text-amber-600 dark:text-amber-400"
    },
    {
      label: "Jobs",
      href: "/settings/jobs",
      description: "Scheduled tasks and automation workflows",
      icon: Clock,
      iconClass: "text-emerald-600 dark:text-emerald-400"
    },
    {
      label: "Logs",
      href: "/settings/logs",
      description: "System logs and error history",
      icon: File_text,
      iconClass: "text-neutral-700 dark:text-neutral-300"
    },
    {
      label: "Backups",
      href: "/settings/backups",
      description: "Snapshots, restore, and retention",
      icon: Archive,
      iconClass: "text-blue-600 dark:text-blue-400"
    },
    {
      label: "About",
      href: "/settings/about",
      description: "Build info, status, and diagnostics",
      icon: Info,
      iconClass: "text-neutral-700 dark:text-neutral-300"
    }
  ];
  PageMeta($$renderer, { title: "Settings" });
  $$renderer.push(`<!----> <div class="px-4 pt-4 pb-8 md:px-8"><div class="mb-8"><h1 class="text-2xl font-semibold text-neutral-900 md:text-3xl dark:text-neutral-50">Settings</h1> <p class="mt-2 text-sm text-neutral-600 md:text-base dark:text-neutral-400">Configure and manage your Profilarr application</p></div> <div class="overflow-hidden rounded-xl border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900"><div class="divide-y divide-neutral-200 dark:divide-neutral-800"><!--[-->`);
  const each_array = ensure_array_like(settingsItems);
  for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
    let item = each_array[$$index];
    $$renderer.push(`<a${attr("href", item.href)} class="flex items-start gap-4 px-4 py-3 transition hover:bg-neutral-50 dark:hover:bg-neutral-900/70">`);
    if (item.icon) {
      $$renderer.push("<!--[-->");
      item.icon($$renderer, {
        size: 18,
        class: `mt-0.5 ${stringify(item.iconClass)}`
      });
      $$renderer.push("<!--]-->");
    } else {
      $$renderer.push("<!--[!-->");
      $$renderer.push("<!--]-->");
    }
    $$renderer.push(` <div class="min-w-0"><div class="text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(item.label)}</div> <div class="text-xs text-neutral-500 dark:text-neutral-400">${escape_html(item.description)}</div></div></a>`);
  }
  $$renderer.push(`<!--]--></div></div></div>`);
}
var init_page_svelte67 = __esm({
  "dist/build/server/entries/pages/settings/_page.svelte.js"() {
    "use strict";
    init_server();
    init_Icon();
    init_bell();
    init_clock();
    init_file_text();
    init_info();
    init_sliders_vertical();
    init_PageMeta();
  }
});

// dist/build/server/nodes/77.js
var __exports78 = {};
__export(__exports78, {
  component: () => component74,
  fonts: () => fonts78,
  imports: () => imports78,
  index: () => index78,
  stylesheets: () => stylesheets78
});
var index78, component_cache74, component74, imports78, stylesheets78, fonts78;
var init__78 = __esm({
  "dist/build/server/nodes/77.js"() {
    "use strict";
    index78 = 77;
    component74 = async () => component_cache74 ??= (await Promise.resolve().then(() => (init_page_svelte67(), page_svelte_exports67))).default;
    imports78 = ["_app/immutable/nodes/77.D2710fIp.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/hatDe6ao.js", "_app/immutable/chunks/BqRH1fsh2.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B8c7VBJ4.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets78 = [];
    fonts78 = [];
  }
});

// dist/build/server/entries/pages/settings/about/_page.server.ts.js
var page_server_ts_exports69 = {};
__export(page_server_ts_exports69, {
  load: () => load72
});
var load72;
var init_page_server_ts69 = __esm({
  async "dist/build/server/entries/pages/settings/about/_page.server.ts.js"() {
    "use strict";
    init_config();
    await init_announcements();
    init_build();
    await init_migrations();
    load72 = () => {
      const currentMigrationVersion = migrationRunner.getCurrentVersion();
      const migrationsWithLatest = migrationRunner.getAppliedMigrations().map((migration2) => ({
        ...migration2,
        latest: migration2.version === currentMigrationVersion
      }));
      const snapshot = getVersionsSnapshot();
      const releases = (snapshot?.payload.channels.stable.releases ?? []).slice(0, 10).map((r2) => ({
        tag_name: `v${r2.tag}`,
        html_url: r2.url,
        published_at: r2.published_at,
        prerelease: false
      }));
      return {
        version: build.version,
        timezone: config.timezone,
        paths: {
          base: config.paths.base,
          data: config.paths.data,
          logs: config.paths.logs,
          database: config.paths.database
        },
        migration: {
          current: currentMigrationVersion,
          applied: migrationsWithLatest
        },
        releases,
        cachedAt: snapshot?.fetchedAt ?? null
      };
    };
  }
});

// dist/build/server/entries/pages/settings/about/_page.svelte.js
var page_svelte_exports68 = {};
__export(page_svelte_exports68, {
  default: () => _page68
});
function Circle_question_mark($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "circle-question-mark" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "12",
        "cy": "12",
        "r": "10"
      }],
      ["path", { "d": "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" }],
      ["path", { "d": "M12 17h.01" }]
    ] }
  ]));
}
function Folder_open($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "folder-open" },
    props,
    { iconNode: [["path", { "d": "m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2" }]] }
  ]));
}
function Heart($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "heart" },
    props,
    { iconNode: [["path", { "d": "M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5" }]] }
  ]));
}
function Package($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "package" },
    props,
    { iconNode: [
      ["path", { "d": "M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z" }],
      ["path", { "d": "M12 22V12" }],
      ["polyline", { "points": "3.29 7 12 12 20.71 7" }],
      ["path", { "d": "m7.5 4.27 9 5.15" }]
    ] }
  ]));
}
function BuildIdentity($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let channelLabel, buildString, kind;
    let status = fallback($$props["status"], null);
    const CHANNEL_LABELS = {
      stable: "Stable",
      develop: "Develop",
      dev: "Unstable"
    };
    $: channelLabel = CHANNEL_LABELS[build.channel];
    $: buildString = build.channel === "stable" ? `v${build.version}` : build.channel === "develop" ? build.version : null;
    $: kind = status?.status ?? null;
    $$renderer2.push(`<div class="flex flex-wrap items-center gap-2">`);
    Label($$renderer2, {
      variant: "secondary",
      size: "md",
      rounded: "md",
      mono: true,
      children: ($$renderer3) => {
        $$renderer3.push(`<!---->${escape_html(buildString ? `${channelLabel} \xB7 ${buildString}` : channelLabel)}`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> `);
    if (kind === "up-to-date") {
      $$renderer2.push("<!--[0-->");
      Label($$renderer2, {
        variant: "success",
        size: "md",
        rounded: "md",
        children: ($$renderer3) => {
          $$renderer3.push(`<!---->Up to date`);
        },
        $$slots: { default: true }
      });
    } else if (kind === "out-of-date" && status?.latestVersion) {
      $$renderer2.push("<!--[1-->");
      Label($$renderer2, {
        variant: "secondary",
        size: "md",
        rounded: "md",
        href: status.releaseUrl ?? void 0,
        target: status.releaseUrl ? "_blank" : void 0,
        rel: status.releaseUrl ? "noopener noreferrer" : void 0,
        children: ($$renderer3) => {
          Arrow_up($$renderer3, { class: "h-3.5 w-3.5 text-emerald-600 dark:text-emerald-400" });
          $$renderer3.push(`<!----> Update Available: ${escape_html(status.latestVersion)}`);
        },
        $$slots: { default: true }
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div>`);
    bind_props($$props, { status });
  });
}
function _page68($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    const appRows = [{
      key: "version",
      label: "Version",
      value: data.version,
      type: "code"
    }, {
      key: "timezone",
      label: "Timezone",
      value: data.timezone,
      type: "code"
    }];
    const sections = [
      {
        title: "Paths",
        icon: Folder_open,
        rows: [
          {
            key: "base",
            label: "Base Path",
            value: data.paths.base,
            type: "code"
          },
          {
            key: "data",
            label: "Data Directory",
            value: data.paths.data,
            type: "code"
          },
          {
            key: "logs",
            label: "Logs Directory",
            value: data.paths.logs,
            type: "code"
          },
          {
            key: "database",
            label: "Database Path",
            value: data.paths.database,
            type: "code"
          }
        ]
      },
      {
        title: "Getting Support",
        icon: Circle_question_mark,
        rows: [
          {
            key: "docs",
            label: "Documentation",
            value: "https://dictionarry.dev/",
            type: "link",
            href: "https://dictionarry.dev/"
          },
          {
            key: "github",
            label: "GitHub",
            value: "https://github.com/Dictionarry-Hub",
            type: "link",
            href: "https://github.com/Dictionarry-Hub"
          },
          {
            key: "discord",
            label: "Discord",
            value: "https://discord.gg/XGdTJP5G8a",
            type: "link",
            href: "https://discord.gg/XGdTJP5G8a"
          }
        ]
      },
      {
        title: "Support",
        icon: Heart,
        rows: [{
          key: "sponsors",
          label: "GitHub Sponsors",
          value: "https://github.com/sponsors/Dictionarry-Hub",
          type: "link",
          href: "https://github.com/sponsors/Dictionarry-Hub"
        }, {
          key: "coffee",
          label: "Buy Me a Coffee",
          value: "https://www.buymeacoffee.com/santiagosayshey",
          type: "link",
          href: "https://www.buymeacoffee.com/santiagosayshey"
        }]
      }
    ];
    const infoColumns = [{
      key: "label",
      header: "Label",
      width: "w-40"
    }, {
      key: "value",
      header: "Value"
    }];
    const migrationColumns = [
      {
        key: "version",
        header: "Version",
        sortable: true,
        width: "w-32"
      },
      {
        key: "name",
        header: "Name",
        sortable: true
      },
      {
        key: "applied_at",
        header: "Applied",
        sortable: true,
        width: "w-32"
      }
    ];
    const releaseColumns = [
      {
        key: "tag_name",
        header: "Release"
      },
      {
        key: "published_at",
        header: "Published",
        width: "w-32"
      },
      {
        key: "prerelease",
        header: "Type",
        width: "w-24"
      }
    ];
    PageMeta($$renderer2, { title: "About" });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8"><h1 class="mb-6 text-3xl font-bold text-neutral-900 dark:text-neutral-50">About Profilarr</h1> <div class="space-y-6"><div class="space-y-2"><div class="flex items-center gap-2">`);
    Info($$renderer2, { class: "h-4 w-4 text-neutral-600 dark:text-neutral-400" });
    $$renderer2.push(`<!----> <h2 class="text-sm font-semibold text-neutral-900 dark:text-neutral-50">Application</h2></div> `);
    Table2($$renderer2, {
      columns: infoColumns,
      data: appRows,
      responsive: true,
      $$slots: { cell: ($$renderer3, { row, column }) => {
        if (column.key === "label") {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<span class="text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(row.label)}</span>`);
        } else if (column.key === "value") {
          $$renderer3.push("<!--[1-->");
          if (row.key === "version") {
            $$renderer3.push("<!--[0-->");
            BuildIdentity($$renderer3, { status: data.versionStatus });
          } else if (row.type === "code") {
            $$renderer3.push("<!--[1-->");
            Label($$renderer3, {
              variant: "secondary",
              size: "md",
              rounded: "md",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.value)}`);
              },
              $$slots: { default: true }
            });
          } else if (row.type === "link") {
            $$renderer3.push("<!--[2-->");
            Label($$renderer3, {
              variant: "link",
              size: "md",
              rounded: "md",
              mono: true,
              href: row.href,
              target: "_blank",
              rel: "noopener noreferrer",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.value)}`);
              },
              $$slots: { default: true }
            });
          } else {
            $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(row.value)}</span>`);
          }
          $$renderer3.push(`<!--]-->`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]-->`);
      } }
    });
    $$renderer2.push(`<!----></div> <!--[-->`);
    const each_array = ensure_array_like(sections);
    for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
      let section = each_array[$$index];
      $$renderer2.push(`<div class="space-y-2"><div class="flex items-center gap-2">`);
      if (section.icon) {
        $$renderer2.push("<!--[0-->");
        if (section.icon) {
          $$renderer2.push("<!--[-->");
          section.icon($$renderer2, { class: "h-4 w-4 text-neutral-600 dark:text-neutral-400" });
          $$renderer2.push("<!--]-->");
        } else {
          $$renderer2.push("<!--[!-->");
          $$renderer2.push("<!--]-->");
        }
      } else $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<!--]--> <h2 class="text-sm font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(section.title)}</h2></div> `);
      Table2($$renderer2, {
        columns: infoColumns,
        data: section.rows,
        responsive: true,
        $$slots: { cell: ($$renderer3, { row, column }) => {
          if (column.key === "label") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="text-sm font-medium text-neutral-900 dark:text-neutral-100">${escape_html(row.label)}</span>`);
          } else if (column.key === "value") {
            $$renderer3.push("<!--[1-->");
            if (row.type === "code") {
              $$renderer3.push("<!--[0-->");
              Label($$renderer3, {
                variant: "secondary",
                size: "md",
                rounded: "md",
                mono: true,
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(row.value)}`);
                },
                $$slots: { default: true }
              });
            } else if (row.type === "link") {
              $$renderer3.push("<!--[1-->");
              Label($$renderer3, {
                variant: "link",
                size: "md",
                rounded: "md",
                mono: true,
                href: row.href,
                target: "_blank",
                rel: "noopener noreferrer",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(row.value)}`);
                },
                $$slots: { default: true }
              });
            } else {
              $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(row.value)}</span>`);
            }
            $$renderer3.push(`<!--]-->`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        } }
      });
      $$renderer2.push(`<!----></div>`);
    }
    $$renderer2.push(`<!--]--> `);
    if (data.migration.applied.length > 0) {
      $$renderer2.push("<!--[0-->");
      const currentMigration = data.migration.applied.find((m3) => m3.latest) ?? data.migration.applied[0];
      $$renderer2.push(`<div class="space-y-2"><div class="flex items-center gap-2">`);
      Database2($$renderer2, { class: "h-4 w-4 text-neutral-600 dark:text-neutral-400" });
      $$renderer2.push(`<!----> <h2 class="text-sm font-semibold text-neutral-900 dark:text-neutral-50">Database</h2></div> `);
      ExpandableTable($$renderer2, {
        columns: migrationColumns,
        data: currentMigration ? [currentMigration] : [],
        getRowId: (row) => row.version,
        emptyMessage: "No migrations applied",
        responsive: true,
        flushExpanded: true,
        chevronPosition: "right",
        $$slots: {
          cell: ($$renderer3, { row, column }) => {
            if (column.key === "version") {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="flex items-center gap-2">`);
              Label($$renderer3, {
                variant: "secondary",
                size: "md",
                rounded: "md",
                mono: true,
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->v${escape_html(row.version)}`);
                },
                $$slots: { default: true }
              });
              $$renderer3.push(`<!----> `);
              if (row.latest) {
                $$renderer3.push("<!--[0-->");
                Label($$renderer3, {
                  size: "md",
                  rounded: "md",
                  customVariant: "bg-accent-100 text-accent-800 dark:bg-accent-900 dark:text-accent-200",
                  children: ($$renderer4) => {
                    $$renderer4.push(`<!---->Latest`);
                  },
                  $$slots: { default: true }
                });
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--></div>`);
            } else if (column.key === "name") {
              $$renderer3.push("<!--[1-->");
              $$renderer3.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(row.name)}</span>`);
            } else if (column.key === "applied_at") {
              $$renderer3.push("<!--[2-->");
              $$renderer3.push(`<span class="text-xs text-neutral-500">`);
              DateTime($$renderer3, {
                value: row.applied_at,
                date: true
              });
              $$renderer3.push(`<!----></span>`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]-->`);
          },
          expanded: ($$renderer3) => {
            $$renderer3.push(`<div class="p-3">`);
            Table2($$renderer3, {
              columns: migrationColumns,
              data: data.migration.applied,
              responsive: true,
              $$slots: { cell: ($$renderer4, { row, column }) => {
                if (column.key === "version") {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="flex items-center gap-2">`);
                  Label($$renderer4, {
                    variant: "secondary",
                    size: "md",
                    rounded: "md",
                    mono: true,
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->v${escape_html(row.version)}`);
                    },
                    $$slots: { default: true }
                  });
                  $$renderer4.push(`<!----> `);
                  if (row.latest) {
                    $$renderer4.push("<!--[0-->");
                    Label($$renderer4, {
                      size: "md",
                      rounded: "md",
                      customVariant: "bg-accent-100 text-accent-800 dark:bg-accent-900 dark:text-accent-200",
                      children: ($$renderer5) => {
                        $$renderer5.push(`<!---->Latest`);
                      },
                      $$slots: { default: true }
                    });
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--></div>`);
                } else if (column.key === "name") {
                  $$renderer4.push("<!--[1-->");
                  $$renderer4.push(`<span class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(row.name)}</span>`);
                } else if (column.key === "applied_at") {
                  $$renderer4.push("<!--[2-->");
                  $$renderer4.push(`<span class="text-xs text-neutral-500">`);
                  DateTime($$renderer4, {
                    value: row.applied_at,
                    date: true
                  });
                  $$renderer4.push(`<!----></span>`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]-->`);
              } }
            });
            $$renderer3.push(`<!----></div>`);
          }
        }
      });
      $$renderer2.push(`<!----></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div class="space-y-2"><div class="flex items-center gap-2">`);
    Package($$renderer2, { class: "h-4 w-4 text-neutral-600 dark:text-neutral-400" });
    $$renderer2.push(`<!----> <h2 class="text-sm font-semibold text-neutral-900 dark:text-neutral-50">Releases</h2> `);
    if (data.cachedAt) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<span class="ml-auto text-xs text-neutral-500 dark:text-neutral-500">Updated `);
      DateTime($$renderer2, { value: data.cachedAt });
      $$renderer2.push(`<!----></span>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div> `);
    if (data.releases.length > 0) {
      $$renderer2.push("<!--[0-->");
      const currentRelease = data.releases[0];
      ExpandableTable($$renderer2, {
        columns: releaseColumns,
        data: currentRelease ? [currentRelease] : [],
        getRowId: (row) => row.tag_name,
        emptyMessage: "No releases found",
        responsive: true,
        flushExpanded: true,
        chevronPosition: "right",
        $$slots: {
          cell: ($$renderer3, { row, column, index: index88 }) => {
            if (column.key === "tag_name") {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<div class="flex items-center gap-2">`);
              Label($$renderer3, {
                variant: "link",
                size: "md",
                rounded: "md",
                mono: true,
                href: row.html_url,
                target: "_blank",
                rel: "noopener noreferrer",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(row.tag_name)}`);
                },
                $$slots: { default: true }
              });
              $$renderer3.push(`<!----> `);
              if (index88 === 0) {
                $$renderer3.push("<!--[0-->");
                Label($$renderer3, {
                  size: "md",
                  rounded: "md",
                  customVariant: "bg-accent-100 text-accent-800 dark:bg-accent-900 dark:text-accent-200",
                  children: ($$renderer4) => {
                    $$renderer4.push(`<!---->Latest`);
                  },
                  $$slots: { default: true }
                });
              } else $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<!--]--></div>`);
            } else if (column.key === "published_at") {
              $$renderer3.push("<!--[1-->");
              $$renderer3.push(`<span class="text-xs text-neutral-500 dark:text-neutral-500">`);
              DateTime($$renderer3, {
                value: row.published_at,
                date: true
              });
              $$renderer3.push(`<!----></span>`);
            } else if (column.key === "prerelease") {
              $$renderer3.push("<!--[2-->");
              if (row.prerelease) {
                $$renderer3.push("<!--[0-->");
                Label($$renderer3, {
                  variant: "warning",
                  size: "md",
                  rounded: "md",
                  children: ($$renderer4) => {
                    $$renderer4.push(`<!---->Pre-release`);
                  },
                  $$slots: { default: true }
                });
              } else {
                $$renderer3.push("<!--[-1-->");
                Label($$renderer3, {
                  variant: "secondary",
                  size: "md",
                  rounded: "md",
                  children: ($$renderer4) => {
                    $$renderer4.push(`<!---->Stable`);
                  },
                  $$slots: { default: true }
                });
              }
              $$renderer3.push(`<!--]-->`);
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]-->`);
          },
          expanded: ($$renderer3) => {
            $$renderer3.push(`<div class="p-3">`);
            Table2($$renderer3, {
              columns: releaseColumns,
              data: data.releases,
              responsive: true,
              $$slots: { cell: ($$renderer4, { row, column, rowIndex }) => {
                if (column.key === "tag_name") {
                  $$renderer4.push("<!--[0-->");
                  $$renderer4.push(`<div class="flex items-center gap-2">`);
                  Label($$renderer4, {
                    variant: "link",
                    size: "md",
                    rounded: "md",
                    mono: true,
                    href: row.html_url,
                    target: "_blank",
                    rel: "noopener noreferrer",
                    children: ($$renderer5) => {
                      $$renderer5.push(`<!---->${escape_html(row.tag_name)}`);
                    },
                    $$slots: { default: true }
                  });
                  $$renderer4.push(`<!----> `);
                  if (rowIndex === 0) {
                    $$renderer4.push("<!--[0-->");
                    Label($$renderer4, {
                      size: "md",
                      rounded: "md",
                      customVariant: "bg-accent-100 text-accent-800 dark:bg-accent-900 dark:text-accent-200",
                      children: ($$renderer5) => {
                        $$renderer5.push(`<!---->Latest`);
                      },
                      $$slots: { default: true }
                    });
                  } else $$renderer4.push("<!--[-1-->");
                  $$renderer4.push(`<!--]--></div>`);
                } else if (column.key === "published_at") {
                  $$renderer4.push("<!--[1-->");
                  $$renderer4.push(`<span class="text-xs text-neutral-500 dark:text-neutral-500">`);
                  DateTime($$renderer4, {
                    value: row.published_at,
                    date: true
                  });
                  $$renderer4.push(`<!----></span>`);
                } else if (column.key === "prerelease") {
                  $$renderer4.push("<!--[2-->");
                  if (row.prerelease) {
                    $$renderer4.push("<!--[0-->");
                    Label($$renderer4, {
                      variant: "warning",
                      size: "md",
                      rounded: "md",
                      children: ($$renderer5) => {
                        $$renderer5.push(`<!---->Pre-release`);
                      },
                      $$slots: { default: true }
                    });
                  } else {
                    $$renderer4.push("<!--[-1-->");
                    Label($$renderer4, {
                      variant: "secondary",
                      size: "md",
                      rounded: "md",
                      children: ($$renderer5) => {
                        $$renderer5.push(`<!---->Stable`);
                      },
                      $$slots: { default: true }
                    });
                  }
                  $$renderer4.push(`<!--]-->`);
                } else $$renderer4.push("<!--[-1-->");
                $$renderer4.push(`<!--]-->`);
              } }
            });
            $$renderer3.push(`<!----></div>`);
          }
        }
      });
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`<div class="rounded-lg border border-neutral-200 bg-white p-4 text-sm text-neutral-500 dark:border-neutral-800 dark:bg-neutral-900 dark:text-neutral-400">Release data not yet available. The next scheduled sync will populate it.</div>`);
    }
    $$renderer2.push(`<!--]--></div></div></div>`);
    bind_props($$props, { data });
  });
}
var init_page_svelte68 = __esm({
  "dist/build/server/entries/pages/settings/about/_page.svelte.js"() {
    "use strict";
    init_server();
    init_build();
    init_Icon();
    init_arrow_up();
    init_database2();
    init_info();
    init_Label();
    init_ExpandableTable();
    init_DateTime();
    init_PageMeta();
    init_Table();
  }
});

// dist/build/server/nodes/78.js
var __exports79 = {};
__export(__exports79, {
  component: () => component75,
  fonts: () => fonts79,
  imports: () => imports79,
  index: () => index79,
  server: () => page_server_ts_exports69,
  server_id: () => server_id75,
  stylesheets: () => stylesheets79
});
var index79, component_cache75, component75, server_id75, imports79, stylesheets79, fonts79;
var init__79 = __esm({
  async "dist/build/server/nodes/78.js"() {
    "use strict";
    await init_page_server_ts69();
    index79 = 78;
    component75 = async () => component_cache75 ??= (await Promise.resolve().then(() => (init_page_svelte68(), page_svelte_exports68))).default;
    server_id75 = "src/routes/settings/about/+page.server.ts";
    imports79 = ["_app/immutable/nodes/78.CB2kBhE-.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/lj9q7Hod2.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/KgSkRyiu2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/unOv5SWI.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js"];
    stylesheets79 = ["_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts79 = [];
  }
});

// dist/build/server/chunks/validation.js
import { join as join3, resolve as resolve5 } from "node:path";
function isValidBackupFilename(filename) {
  if (!filename) return false;
  if (filename.includes("\0")) return false;
  if (filename.includes("/")) return false;
  if (filename.includes("\\")) return false;
  if (filename.includes("..")) return false;
  return VALID_FILENAME_RE.test(filename);
}
function resolveBackupPath(filename, backupsDir) {
  if (!isValidBackupFilename(filename)) return null;
  const resolved = resolve5(join3(backupsDir, filename));
  const normalizedDir = resolve5(backupsDir);
  if (!resolved.startsWith(normalizedDir + "/") && resolved !== normalizedDir) return null;
  return resolved;
}
function formatFileSize(bytes) {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
  if (bytes < 1073741824) return `${(bytes / 1048576).toFixed(2)} MB`;
  return `${(bytes / 1073741824).toFixed(2)} GB`;
}
var VALID_FILENAME_RE;
var init_validation = __esm({
  "dist/build/server/chunks/validation.js"() {
    "use strict";
    VALID_FILENAME_RE = /^backup-[\w-]+\.tar\.gz$/;
  }
});

// dist/build/server/chunks/list.js
async function listBackups(backupsDir) {
  const backups = [];
  try {
    for await (const entry of Deno.readDir(backupsDir)) {
      if (!entry.isFile) continue;
      if (!entry.name.startsWith("backup-") || !entry.name.endsWith(".tar.gz")) continue;
      const filePath = `${backupsDir}/${entry.name}`;
      const stat = await Deno.stat(filePath);
      const mtime = stat.mtime || /* @__PURE__ */ new Date();
      backups.push({
        filename: entry.name,
        created: mtime.toISOString(),
        size: stat.size,
        sizeFormatted: formatFileSize(stat.size)
      });
    }
  } catch {
  }
  backups.sort((a2, b3) => new Date(b3.created).getTime() - new Date(a2.created).getTime());
  return backups;
}
var init_list = __esm({
  "dist/build/server/chunks/list.js"() {
    "use strict";
    init_validation();
  }
});

// dist/build/server/chunks/sanitize2.js
function sanitizeGitConfigContent(content) {
  return content.replace(/^(\s*url\s*=\s*)(\S+)(.*)$/gm, (match, prefix, rawUrl, suffix) => {
    try {
      const url = new URL(rawUrl);
      if (url.protocol !== "http:" && url.protocol !== "https:") return match;
      if (!url.username && !url.password) return match;
      url.username = "";
      url.password = "";
      return `${prefix}${url.toString()}${suffix}`;
    } catch {
      return match;
    }
  });
}
async function sanitizeGitConfigs(rootDir) {
  async function walk(dir) {
    for await (const entry of Deno.readDir(dir)) {
      const path = `${dir}/${entry.name}`;
      if (entry.isDirectory) {
        if (entry.name === ".git") {
          const configPath = `${path}/config`;
          try {
            const content = await Deno.readTextFile(configPath);
            const sanitized = sanitizeGitConfigContent(content);
            if (sanitized !== content) await Deno.writeTextFile(configPath, sanitized);
          } catch (err) {
            if (!(err instanceof Deno.errors.NotFound)) throw err;
          }
          continue;
        }
        await walk(path);
      }
    }
  }
  try {
    await walk(rootDir);
  } catch (err) {
    if (!(err instanceof Deno.errors.NotFound)) throw err;
  }
}
function applySanitize(db2) {
  for (const sql2 of SANITIZE_SQL) db2.exec(sql2);
}
async function buildSanitizedArchive(archivePath) {
  const tmpDir = await Deno.makeTempDir({ prefix: "profilarr-backup-egress-" });
  try {
    const extractResult = await new Deno.Command("tar", {
      args: [
        "-xzf",
        archivePath,
        "-C",
        tmpDir
      ],
      stdout: "piped",
      stderr: "piped"
    }).output();
    if (extractResult.code !== 0) {
      const stderr = new TextDecoder().decode(extractResult.stderr).trim();
      throw new Error(`Failed to extract archive: ${stderr}`);
    }
    const dataDir = `${tmpDir}/data`;
    const dbPath = `${dataDir}/profilarr.db`;
    if (await Deno.stat(dbPath).then(() => true, (err) => {
      if (err instanceof Deno.errors.NotFound) return false;
      throw err;
    })) {
      const dest = new Database(dbPath);
      try {
        applySanitize(dest);
        dest.exec("PRAGMA wal_checkpoint(TRUNCATE)");
        dest.exec("PRAGMA journal_mode = DELETE");
      } finally {
        dest.close();
      }
    }
    await sanitizeGitConfigs(`${dataDir}/databases`);
    const infoPath = `${dataDir}/INFO.json`;
    try {
      const raw = await Deno.readTextFile(infoPath);
      const info = JSON.parse(raw);
      info.sanitized = true;
      await Deno.writeTextFile(infoPath, JSON.stringify(info, null, 2));
    } catch (err) {
      if (!(err instanceof Deno.errors.NotFound)) throw err;
    }
    const archive = `${tmpDir}/sanitized.tar.gz`;
    const tarResult = await new Deno.Command("tar", {
      args: [
        "-czf",
        archive,
        "-C",
        tmpDir,
        "data"
      ],
      stdout: "piped",
      stderr: "piped"
    }).output();
    if (tarResult.code !== 0) {
      const stderr = new TextDecoder().decode(tarResult.stderr).trim();
      throw new Error(`Failed to re-archive after sanitize: ${stderr}`);
    }
    return await Deno.readFile(archive);
  } finally {
    try {
      await Deno.remove(tmpDir, { recursive: true });
    } catch {
    }
  }
}
var SANITIZE_SQL, SANITIZED_CATEGORIES;
var init_sanitize2 = __esm({
  async "dist/build/server/chunks/sanitize2.js"() {
    "use strict";
    await init_db();
    SANITIZE_SQL = [
      "DELETE FROM arr_instances",
      "DELETE FROM notification_services",
      "DELETE FROM users",
      "DELETE FROM sessions",
      "DELETE FROM login_attempts",
      "UPDATE database_instances SET personal_access_token = NULL",
      "UPDATE ai_settings SET api_key = ''",
      "UPDATE tmdb_settings SET api_key = ''"
    ];
    SANITIZED_CATEGORIES = [
      "Arr instances (URLs, API keys, sync configs, drift state, rename and cleanup history)",
      "Notification services (webhook URLs, tokens, history)",
      "User accounts and active sessions",
      "Personal access tokens for linked databases",
      "Credentials embedded in cloned database Git remote URLs",
      "AI and TMDB API keys"
    ];
  }
});

// dist/build/server/entries/pages/settings/backups/_page.server.ts.js
var page_server_ts_exports70 = {};
__export(page_server_ts_exports70, {
  actions: () => actions44,
  load: () => load73
});
var load73, actions44;
var init_page_server_ts70 = __esm({
  async "dist/build/server/entries/pages/settings/backups/_page.server.ts.js"() {
    "use strict";
    await init_db();
    init_config();
    init_validation();
    init_list();
    await init_display();
    await init_queueService();
    await init_sanitize2();
    init_exports();
    load73 = async () => {
      return {
        backups: await listBackups(config.paths.backups),
        sanitizedCategories: SANITIZED_CATEGORIES
      };
    };
    actions44 = {
      cleanupBackups: async () => {
        try {
          const queued = enqueueJob({
            jobType: "backup.cleanup",
            runAt: (/* @__PURE__ */ new Date()).toISOString(),
            payload: {},
            source: "manual"
          });
          await logger.info("Manual backup cleanup queued", {
            source: "settings/backups",
            meta: {
              jobId: queued.id,
              displayName: buildJobDisplayName("backup.cleanup", {})
            }
          });
          return {
            success: true,
            message: "Backup cleanup queued"
          };
        } catch (err) {
          await logger.error("Failed to trigger backup cleanup", {
            source: "settings/backups",
            meta: { error: err }
          });
          return fail(500, { error: "Failed to trigger backup cleanup" });
        }
      },
      restoreBackup: async ({ request }) => {
        const filename = (await request.formData()).get("filename");
        if (!filename || !isValidBackupFilename(filename)) return fail(400, { error: "Invalid filename" });
        const backupPath = resolveBackupPath(filename, config.paths.backups);
        if (!backupPath) return fail(400, { error: "Invalid filename" });
        try {
          await Deno.stat(backupPath);
          const sentinelPath = `${config.paths.base}/.restore-pending`;
          await Deno.writeTextFile(sentinelPath, backupPath);
          await logger.warn(`Restore staged: ${filename}`, {
            source: "settings/backups",
            meta: {
              filename,
              archivePath: backupPath
            }
          });
          return {
            success: true,
            restartRequired: true,
            message: "Backup staged. Restart Profilarr to apply."
          };
        } catch (err) {
          await logger.error(`Failed to stage restore: ${filename}`, {
            source: "settings/backups",
            meta: {
              filename,
              error: err
            }
          });
          return fail(500, { error: "Failed to stage restore" });
        }
      },
      cancelRestore: async () => {
        const sentinelPath = `${config.paths.base}/.restore-pending`;
        try {
          await Deno.remove(sentinelPath);
          await logger.info("Pending restore cancelled", { source: "settings/backups" });
          return {
            success: true,
            message: "Pending restore cancelled."
          };
        } catch (err) {
          if (err instanceof Deno.errors.NotFound) return {
            success: true,
            message: "No pending restore to cancel."
          };
          await logger.error("Failed to cancel pending restore", {
            source: "settings/backups",
            meta: { error: err }
          });
          return fail(500, { error: "Failed to cancel pending restore" });
        }
      }
    };
  }
});

// dist/build/server/chunks/brush-cleaning.js
function Brush_cleaning($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "brush-cleaning" },
    props,
    { iconNode: [
      ["path", { "d": "m16 22-1-4" }],
      ["path", { "d": "M19 14a1 1 0 0 0 1-1v-1a2 2 0 0 0-2-2h-3a1 1 0 0 1-1-1V4a2 2 0 0 0-4 0v5a1 1 0 0 1-1 1H6a2 2 0 0 0-2 2v1a1 1 0 0 0 1 1" }],
      ["path", { "d": "M19 14H5l-1.973 6.767A1 1 0 0 0 4 22h16a1 1 0 0 0 .973-1.233z" }],
      ["path", { "d": "m8 22 1-4" }]
    ] }
  ]));
}
var init_brush_cleaning = __esm({
  "dist/build/server/chunks/brush-cleaning.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// dist/build/server/entries/pages/settings/backups/_page.svelte.js
var page_svelte_exports69 = {};
__export(page_svelte_exports69, {
  default: () => _page69
});
function Folder_archive($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "folder-archive" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "15",
        "cy": "19",
        "r": "2"
      }],
      ["path", { "d": "M20.9 19.8A2 2 0 0 0 22 18V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h5.1" }],
      ["path", { "d": "M15 11v-1" }],
      ["path", { "d": "M15 17v-2" }]
    ] }
  ]));
}
function _page69($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let filteredBackups;
    let data = $$props["data"];
    const searchStore = getPersistentSearchStore("settingsBackupsSearch");
    const columns = [
      {
        key: "created",
        header: "Date",
        sortable: true
      },
      {
        key: "filename",
        header: "Filename",
        sortable: true
      },
      {
        key: "sizeFormatted",
        header: "Size",
        sortable: true,
        width: "w-28"
      }
    ];
    let showDeleteModal = false;
    let showRestoreModal = false;
    let showDownloadModal = false;
    $: filteredBackups = searchStore.filterItems(data.backups, ["filename"]);
    PageMeta($$renderer2, { title: "Backups" });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8"><div class="mb-8"><h1 class="text-2xl font-bold text-neutral-900 md:text-3xl dark:text-neutral-50">Backups</h1> <p class="mt-3 text-base text-neutral-600 md:text-lg dark:text-neutral-400">Manage database and configuration backups</p></div>  <input type="file" accept=".tar.gz" class="hidden"/> <form method="POST" action="?/cleanupBackups" class="hidden"></form> <div class="mb-4" data-onboarding="backups-actions">`);
    ActionsBar($$renderer2, {
      children: ($$renderer3) => {
        SearchAction($$renderer3, {
          searchStore,
          placeholder: "Search backups..."
        });
        $$renderer3.push(`<!----> `);
        Tooltip($$renderer3, {
          text: "Upload Backup",
          children: ($$renderer4) => {
            ActionButton($$renderer4, { icon: Upload });
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----> `);
        Tooltip($$renderer3, {
          text: "Create Backup",
          children: ($$renderer4) => {
            ActionButton($$renderer4, { icon: Folder_archive });
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----> `);
        Tooltip($$renderer3, {
          text: "Cleanup",
          children: ($$renderer4) => {
            ActionButton($$renderer4, { icon: Brush_cleaning });
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!---->`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----></div> <div data-onboarding="backups-table">`);
    Table2($$renderer2, {
      columns,
      data: filteredBackups,
      emptyMessage: "No backups found. Create your first backup to get started.",
      actionsHeaderAlign: "center",
      compact: true,
      responsive: true,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "created") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="font-medium">${escape_html(formatDateTime(row.created, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat)))}</span>`);
          } else if (column.key === "filename") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<span class="font-mono text-neutral-500 dark:text-neutral-400">${escape_html(row.filename)}</span>`);
          } else if (column.key === "sizeFormatted") {
            $$renderer3.push("<!--[2-->");
            $$renderer3.push(`<span class="text-neutral-500 dark:text-neutral-400">${escape_html(row.sizeFormatted)}</span>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        actions: ($$renderer3, { row }) => {
          $$renderer3.push(`<div class="flex items-center justify-center gap-1">`);
          Button($$renderer3, {
            icon: Download,
            size: "xs",
            tooltip: "Download"
          });
          $$renderer3.push(`<!----> <form method="POST" action="?/restoreBackup"><input type="hidden" name="filename"${attr("value", row.filename)}/> `);
          Button($$renderer3, {
            icon: Rotate_ccw,
            size: "xs",
            tooltip: "Restore"
          });
          $$renderer3.push(`<!----></form> `);
          Button($$renderer3, {
            icon: Trash_2,
            size: "xs",
            iconColor: "text-red-600 dark:text-red-400",
            tooltip: "Delete"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    $$renderer2.push(`<!----></div></div> `);
    Modal($$renderer2, {
      open: showDeleteModal,
      header: "Delete Backup",
      bodyMessage: `Are you sure you want to delete this backup? This action cannot be undone.`,
      confirmText: "Delete Backup",
      cancelText: "Cancel",
      confirmDanger: true
    });
    $$renderer2.push(`<!----> `);
    Modal($$renderer2, {
      open: showRestoreModal,
      header: "Restore Backup",
      bodyMessage: `This will stage the backup to be applied on the next restart. When Profilarr restarts, all current data will be replaced with the contents of this backup. The replacement cannot be undone after restart.`,
      confirmText: "Restore Backup",
      cancelText: "Cancel"
    });
    $$renderer2.push(`<!----> `);
    Modal($$renderer2, {
      open: showDownloadModal,
      header: "Download Backup",
      confirmText: "Download",
      cancelText: "Cancel",
      $$slots: { body: ($$renderer3) => {
        $$renderer3.push(`<div slot="body" class="space-y-3 text-sm text-neutral-600 dark:text-neutral-400"><p>The local copy on this server includes everything needed for restore, including secrets. The
			downloaded file is sanitized so it's safer to share. The following will be removed before
			download:</p> <ul class="list-disc space-y-1 pl-5"><!--[-->`);
        const each_array = ensure_array_like(data.sanitizedCategories);
        for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
          let category = each_array[$$index];
          $$renderer3.push(`<li>${escape_html(category)}</li>`);
        }
        $$renderer3.push(`<!--]--></ul> <p>Restoring the downloaded file on a different host will require re-adding the removed items.
			Linked databases (PCD repos), AI/TMDB settings rows, and your backup schedule are preserved
			(with their secret values blanked).</p> `);
        $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      } }
    });
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte69 = __esm({
  "dist/build/server/entries/pages/settings/backups/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_dates();
    init_Icon();
    init_brush_cleaning();
    init_download();
    init_Button();
    init_rotate_ccw();
    init_search();
    init_trash_2();
    init_upload();
    init_client4();
    init_store2();
    init_jobStatus();
    init_navigation();
    init_Modal();
    init_dateFormat();
    init_timezone();
    init_forms();
    init_ActionsBar();
    init_ActionButton();
    init_PageMeta();
    init_Table();
  }
});

// dist/build/server/nodes/79.js
var __exports80 = {};
__export(__exports80, {
  component: () => component76,
  fonts: () => fonts80,
  imports: () => imports80,
  index: () => index80,
  server: () => page_server_ts_exports70,
  server_id: () => server_id76,
  stylesheets: () => stylesheets80
});
var index80, component_cache76, component76, server_id76, imports80, stylesheets80, fonts80;
var init__80 = __esm({
  async "dist/build/server/nodes/79.js"() {
    "use strict";
    await init_page_server_ts70();
    index80 = 79;
    component76 = async () => component_cache76 ??= (await Promise.resolve().then(() => (init_page_svelte69(), page_svelte_exports69))).default;
    server_id76 = "src/routes/settings/backups/+page.server.ts";
    imports80 = ["_app/immutable/nodes/79.Bs4bSKnR.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BKz1xBLr.js", "_app/immutable/chunks/D7OHFWTL2.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvoiSP5r.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/XFcHCQ8-.js", "_app/immutable/chunks/C8nbuSgl2.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js"];
    stylesheets80 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts80 = [];
  }
});

// dist/build/server/entries/pages/settings/general/_page.server.ts.js
var page_server_ts_exports71 = {};
__export(page_server_ts_exports71, {
  actions: () => actions45,
  load: () => load74
});
var aiSettingsQueries, DATE_FORMATS, load74, actions45;
var init_page_server_ts71 = __esm({
  async "dist/build/server/entries/pages/settings/general/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_queueService();
    init_features();
    await init_backupSettings();
    await init_init();
    await init_generalSettings();
    await init_tmdbSettings();
    init_exports();
    aiSettingsQueries = {
      /**
      * Get the AI settings (singleton)
      */
      get() {
        return db.queryFirst("SELECT * FROM ai_settings WHERE id = 1");
      },
      /**
      * Update AI settings
      */
      update(input) {
        const updates = [];
        const params = [];
        if (input.enabled !== void 0) {
          updates.push("enabled = ?");
          params.push(input.enabled ? 1 : 0);
        }
        if (input.apiUrl !== void 0) {
          updates.push("api_url = ?");
          params.push(input.apiUrl);
        }
        if (input.apiKey !== void 0) {
          updates.push("api_key = ?");
          params.push(input.apiKey);
        }
        if (input.model !== void 0) {
          updates.push("model = ?");
          params.push(input.model);
        }
        if (updates.length === 0) return false;
        updates.push("updated_at = CURRENT_TIMESTAMP");
        params.push(1);
        return db.execute(`UPDATE ai_settings SET ${updates.join(", ")} WHERE id = ?`, ...params) > 0;
      },
      /**
      * Reset AI settings to defaults
      */
      reset() {
        return db.execute(`
			UPDATE ai_settings SET
				enabled = 0,
				api_url = 'https://api.openai.com/v1',
				api_key = '',
				model = 'gpt-4o-mini',
				updated_at = CURRENT_TIMESTAMP
			WHERE id = 1
		`) > 0;
      }
    };
    DATE_FORMATS = [
      "auto",
      "mdy",
      "dmy",
      "ymd"
    ];
    load74 = () => {
      const logSetting = logSettingsQueries.get();
      const backupSetting = backupSettingsQueries.get();
      const tmdbSetting = tmdbSettingsQueries.get();
      const generalSetting = generalSettingsQueries.get();
      if (!logSetting) throw new Error("Log settings not found in database");
      if (!backupSetting) throw new Error("Backup settings not found in database");
      if (!tmdbSetting) throw new Error("TMDB settings not found in database");
      if (!generalSetting) throw new Error("General settings not found in database");
      let aiSettings = {
        enabled: false,
        api_url: "",
        hasApiKey: false,
        model: ""
      };
      if (FEATURES.ai) {
        const aiSetting = aiSettingsQueries.get();
        if (!aiSetting) throw new Error("AI settings not found in database");
        aiSettings = {
          enabled: aiSetting.enabled === 1,
          api_url: aiSetting.api_url,
          hasApiKey: !!aiSetting.api_key,
          model: aiSetting.model
        };
      }
      return {
        logSettings: {
          retention_days: logSetting.retention_days,
          min_level: logSetting.min_level,
          enabled: logSetting.enabled === 1,
          file_logging: logSetting.file_logging === 1,
          console_logging: logSetting.console_logging === 1
        },
        backupSettings: {
          schedule: backupSetting.schedule,
          retention_days: backupSetting.retention_days,
          enabled: backupSetting.enabled === 1,
          include_database: backupSetting.include_database === 1
        },
        aiSettings,
        tmdbSettings: { hasApiKey: !!tmdbSetting.api_key },
        generalSettings: {
          date_format: generalSetting.date_format,
          apply_default_delay_profiles: generalSetting.apply_default_delay_profiles === 1,
          fail_on_referenced_delete: generalSetting.fail_on_referenced_delete === 1,
          sync_prompt_enabled: generalSetting.sync_prompt_enabled === 1
        }
      };
    };
    actions45 = { save: async ({ request }) => {
      const formData = await request.formData();
      const logRetentionDays = parseInt(formData.get("log_retention_days"));
      const logMinLevel = formData.get("log_min_level");
      const logEnabled = formData.get("log_enabled") === "on";
      const logFileLogging = formData.get("log_file_logging") === "on";
      const logConsoleLogging = formData.get("log_console_logging") === "on";
      if (isNaN(logRetentionDays) || logRetentionDays < 1 || logRetentionDays > 365) return fail(400, { error: "Log retention days must be between 1 and 365" });
      if (!logMinLevel || ![
        "DEBUG",
        "INFO",
        "WARN",
        "ERROR"
      ].includes(logMinLevel)) return fail(400, { error: "Invalid minimum log level" });
      const backupSchedule = formData.get("backup_schedule");
      const backupRetentionDays = parseInt(formData.get("backup_retention_days"));
      const backupEnabled = formData.get("backup_enabled") === "on";
      if (!backupSchedule) return fail(400, { error: "Backup schedule is required" });
      if (isNaN(backupRetentionDays) || backupRetentionDays < 1 || backupRetentionDays > 365) return fail(400, { error: "Backup retention days must be between 1 and 365" });
      const currentBackupSettings = backupSettingsQueries.get();
      if (!currentBackupSettings) return fail(500, { error: "Backup settings not found" });
      const backupScheduleChanged = currentBackupSettings.schedule !== backupSchedule;
      let aiEnabled = false;
      let aiApiUrl = "";
      let aiApiKey = "";
      let aiModel = "";
      if (FEATURES.ai) {
        aiEnabled = formData.get("ai_enabled") === "on";
        aiApiUrl = formData.get("ai_api_url");
        aiApiKey = formData.get("ai_api_key") || aiSettingsQueries.get()?.api_key || "";
        aiModel = formData.get("ai_model");
        if (aiEnabled && !aiApiUrl) return fail(400, { error: "API URL is required when AI is enabled" });
        if (aiEnabled && !aiModel) return fail(400, { error: "Model is required when AI is enabled" });
      }
      const tmdbApiKey = formData.get("tmdb_api_key") || tmdbSettingsQueries.get()?.api_key || "";
      const dateFormat2 = formData.get("date_format");
      if (!DATE_FORMATS.includes(dateFormat2)) return fail(400, { error: "Invalid date format" });
      const arrApplyDefaultDelayProfiles = formData.get("arr_apply_default_delay_profiles") === "on";
      const failOnReferencedDelete = formData.get("fail_on_referenced_delete") === "on";
      const syncPromptEnabled = formData.get("sync_prompt_enabled") === "on";
      if (!logSettingsQueries.update({
        retentionDays: logRetentionDays,
        minLevel: logMinLevel,
        enabled: logEnabled,
        fileLogging: logFileLogging,
        consoleLogging: logConsoleLogging
      })) {
        await logger.error("Failed to update log settings", { source: "settings/general" });
        return fail(500, { error: "Failed to update log settings" });
      }
      if (!backupSettingsQueries.update({
        schedule: backupSchedule,
        retentionDays: backupRetentionDays,
        enabled: backupEnabled
      })) {
        await logger.error("Failed to update backup settings", { source: "settings/general" });
        return fail(500, { error: "Failed to update backup settings" });
      }
      if (FEATURES.ai) {
        if (!aiSettingsQueries.update({
          enabled: aiEnabled,
          apiUrl: aiApiUrl || "https://api.openai.com/v1",
          apiKey: aiApiKey || "",
          model: aiModel || "gpt-4o-mini"
        })) {
          await logger.error("Failed to update AI settings", { source: "settings/general" });
          return fail(500, { error: "Failed to update AI settings" });
        }
      }
      if (!tmdbSettingsQueries.update({ apiKey: tmdbApiKey || "" })) {
        await logger.error("Failed to update TMDB settings", { source: "settings/general" });
        return fail(500, { error: "Failed to update TMDB settings" });
      }
      if (!generalSettingsQueries.update({
        dateFormat: dateFormat2,
        applyDefaultDelayProfiles: arrApplyDefaultDelayProfiles,
        failOnReferencedDelete,
        syncPromptEnabled
      })) {
        await logger.error("Failed to update behavior settings", { source: "settings/general" });
        return fail(500, { error: "Failed to update behavior settings" });
      }
      logSettings.reload();
      scheduleLogCleanup();
      scheduleBackupJobs({ forceBackup: backupScheduleChanged });
      await logger.info("General settings saved", {
        source: "settings/general",
        meta: {
          logRetentionDays,
          logMinLevel,
          logEnabled,
          backupSchedule,
          backupRetentionDays,
          backupEnabled,
          aiEnabled,
          aiApiUrl,
          aiModel,
          dateFormat: dateFormat2,
          arrApplyDefaultDelayProfiles,
          failOnReferencedDelete,
          syncPromptEnabled
        }
      });
      return { success: true };
    } };
  }
});

// dist/build/server/entries/pages/settings/general/_page.svelte.js
var page_svelte_exports70 = {};
__export(page_svelte_exports70, {
  default: () => _page70
});
function _page70($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    let saving = false;
    let logEnabled = data.logSettings.enabled;
    let logFileLogging = data.logSettings.file_logging;
    let logConsoleLogging = data.logSettings.console_logging;
    let logMinLevel = data.logSettings.min_level;
    let logRetentionDays = data.logSettings.retention_days;
    let backupEnabled = data.backupSettings.enabled;
    let backupSchedule = data.backupSettings.schedule;
    let backupRetentionDays = data.backupSettings.retention_days;
    let aiEnabled = data.aiSettings.enabled;
    let aiApiUrl = data.aiSettings.api_url;
    let aiApiKey = "";
    let aiModel = data.aiSettings.model;
    let tmdbApiKey = "";
    let tmdbTesting = false;
    let arrApplyDefaultDelayProfiles = data.generalSettings.apply_default_delay_profiles;
    let failOnReferencedDelete = data.generalSettings.fail_on_referenced_delete;
    let syncPromptEnabled = data.generalSettings.sync_prompt_enabled;
    let uiAlertPosition = DEFAULT_ALERT_SETTINGS.position;
    let uiAlertDurationSeconds = Math.round(DEFAULT_ALERT_SETTINGS.durationMs / 1e3);
    let dateFormat2 = data.generalSettings.date_format;
    let uiFontSans = "dm-sans";
    let uiFontMono = "geist-mono";
    const logLevelOptions = [
      {
        value: "DEBUG",
        label: "DEBUG"
      },
      {
        value: "INFO",
        label: "INFO"
      },
      {
        value: "WARN",
        label: "WARN"
      },
      {
        value: "ERROR",
        label: "ERROR"
      }
    ];
    const backupScheduleOptions = [
      {
        value: "daily",
        label: "Daily"
      },
      {
        value: "weekly",
        label: "Weekly"
      },
      {
        value: "monthly",
        label: "Monthly"
      },
      {
        value: "hourly",
        label: "Hourly"
      },
      {
        value: "*/6 hours",
        label: "Every 6 hours"
      },
      {
        value: "*/12 hours",
        label: "Every 12 hours"
      }
    ];
    const alertPositionOptions = [
      {
        value: "top-left",
        label: "Top left"
      },
      {
        value: "top-center",
        label: "Top center"
      },
      {
        value: "top-right",
        label: "Top right"
      },
      {
        value: "bottom-left",
        label: "Bottom left"
      },
      {
        value: "bottom-center",
        label: "Bottom center"
      },
      {
        value: "bottom-right",
        label: "Bottom right"
      }
    ];
    const dateFormatOptions = [
      {
        value: "auto",
        label: "Auto"
      },
      {
        value: "mdy",
        label: "MM/DD/YYYY"
      },
      {
        value: "dmy",
        label: "DD/MM/YYYY"
      },
      {
        value: "ymd",
        label: "YYYY-MM-DD"
      }
    ];
    PageMeta($$renderer2, { title: "General" });
    $$renderer2.push(`<!----> <form id="general-settings-form" method="POST" action="?/save"><div class="p-4 md:p-8"><div class="mb-8 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"><div><h1 class="text-2xl font-bold text-neutral-900 md:text-3xl dark:text-neutral-50">General Settings</h1> <p class="mt-2 text-base text-neutral-600 md:mt-3 md:text-lg dark:text-neutral-400">Configure general application settings and preferences</p></div> `);
    Button($$renderer2, {
      text: "Save",
      icon: Save,
      iconColor: "text-blue-600 dark:text-blue-400",
      loading: saving,
      disabled: !store_get($$store_subs ??= {}, "$isDirty", isDirty),
      type: "submit"
    });
    $$renderer2.push(`<!----></div> <div class="space-y-6">`);
    ExpandableCard($$renderer2, {
      title: "Interface",
      description: "Customize the look and feel of the application",
      onboardingId: "general-interface",
      children: ($$renderer3) => {
        $$renderer3.push(`<div class="px-6 py-4"><div class="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-5"><div><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Emoji Icons</span> `);
        Toggle($$renderer3, {
          label: "Disabled",
          checked: false,
          fullWidth: true
        });
        $$renderer3.push(`<!----></div> <div class="xl:col-span-2"><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Alert Position</span> `);
        DropdownSelect($$renderer3, {
          value: uiAlertPosition,
          options: alertPositionOptions,
          fullWidth: true,
          fixed: true
        });
        $$renderer3.push(`<!----></div> <div class="xl:col-span-2"><label for="ui_alert_duration" class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Alert Duration (seconds)</label> `);
        NumberInput($$renderer3, {
          name: "ui_alert_duration",
          id: "ui_alert_duration",
          value: uiAlertDurationSeconds,
          min: 0,
          step: 1,
          onchange: (v3) => {
            uiAlertDurationSeconds = v3;
            update3("ui_alert_duration_seconds", v3);
          }
        });
        $$renderer3.push(`<!----></div> <div><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Date Format</span> `);
        DropdownSelect($$renderer3, {
          value: dateFormat2,
          options: dateFormatOptions,
          fullWidth: true,
          fixed: true
        });
        $$renderer3.push(`<!----> <input type="hidden" name="date_format"${attr("value", dateFormat2)}/></div> <div><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Sans Font</span> `);
        DropdownSelect($$renderer3, {
          value: uiFontSans,
          options: sansFontOptions,
          fullWidth: true,
          fixed: true
        });
        $$renderer3.push(`<!----></div> <div><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Mono Font</span> `);
        DropdownSelect($$renderer3, {
          value: uiFontMono,
          options: monoFontOptions,
          fullWidth: true,
          fixed: true
        });
        $$renderer3.push(`<!----></div></div></div>`);
      },
      $$slots: {
        default: true,
        "header-right": ($$renderer3) => {
          $$renderer3.push(`<div class="flex items-center gap-1">`);
          Button($$renderer3, {
            icon: Circle_check_big,
            iconColor: "text-green-600 dark:text-green-400",
            size: "xs"
          });
          $$renderer3.push(`<!----> `);
          Button($$renderer3, {
            icon: Circle_x,
            iconColor: "text-red-600 dark:text-red-400",
            size: "xs"
          });
          $$renderer3.push(`<!----> `);
          Button($$renderer3, {
            icon: Triangle_alert,
            iconColor: "text-yellow-500 dark:text-yellow-400",
            size: "xs"
          });
          $$renderer3.push(`<!----> `);
          Button($$renderer3, {
            icon: Info,
            iconColor: "text-blue-600 dark:text-blue-400",
            size: "xs"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    $$renderer2.push(`<!----> `);
    ExpandableCard($$renderer2, {
      title: "Behavior",
      description: "Configure application defaults and safeguards",
      onboardingId: "general-behavior",
      children: ($$renderer3) => {
        $$renderer3.push(`<div class="grid gap-4 px-6 py-4 sm:grid-cols-2 xl:grid-cols-5">`);
        Toggle($$renderer3, {
          label: "Apply Default Delay Profile",
          checked: arrApplyDefaultDelayProfiles,
          infoHeader: "Apply Default Delay Profile",
          infoBody: "When enabled, Profilarr applies a default delay profile when adding a new Radarr or Sonarr instance. Disable this if you want new instances to keep their existing delay profile setup.",
          fullWidth: true
        });
        $$renderer3.push(`<!----> `);
        Toggle($$renderer3, {
          label: "Block Referenced Deletes",
          checked: failOnReferencedDelete,
          infoHeader: "Block Referenced Deletes",
          infoBody: "When enabled, Profilarr blocks deleting custom formats and regular expressions that are still referenced by other PCD entities. Disable this to allow deletes to generate cleanup operations for those references.",
          fullWidth: true
        });
        $$renderer3.push(`<!----> `);
        Toggle($$renderer3, {
          label: "Prompt to Sync Changes",
          checked: syncPromptEnabled,
          infoHeader: "Prompt to Sync Changes",
          infoBody: "When enabled, Profilarr prompts you to sync affected Arr instances after saving an entity. Disable this to return normally without offering an immediate sync.",
          fullWidth: true
        });
        $$renderer3.push(`<!----> <input type="hidden" name="arr_apply_default_delay_profiles"${attr("value", arrApplyDefaultDelayProfiles ? "on" : "")}/> <input type="hidden" name="fail_on_referenced_delete"${attr("value", failOnReferencedDelete ? "on" : "")}/> <input type="hidden" name="sync_prompt_enabled"${attr("value", syncPromptEnabled ? "on" : "")}/></div>`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> `);
    ExpandableCard($$renderer2, {
      title: "Backups",
      description: "Configure automatic backups, schedule, and retention policy",
      onboardingId: "general-backups",
      children: ($$renderer3) => {
        $$renderer3.push(`<div${attr_class("grid gap-4 px-6 py-4", void 0, {
          "sm:grid-cols-2": backupEnabled,
          "xl:grid-cols-5": backupEnabled
        })}><div><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Automatic Backups</span> `);
        Toggle($$renderer3, {
          label: backupEnabled ? "Enabled" : "Disabled",
          checked: backupEnabled,
          fullWidth: backupEnabled
        });
        $$renderer3.push(`<!----></div> <input type="hidden" name="backup_enabled"${attr("value", backupEnabled ? "on" : "")}/> `);
        if (backupEnabled) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div class="xl:col-span-2"><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Schedule</span> `);
          DropdownSelect($$renderer3, {
            value: backupSchedule,
            options: backupScheduleOptions,
            fullWidth: true,
            fixed: true
          });
          $$renderer3.push(`<!----></div> <div class="xl:col-span-2"><label for="backup_retention_days" class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Retention Period (days)</label> `);
          NumberInput($$renderer3, {
            name: "backup_retention_days",
            id: "backup_retention_days",
            value: backupRetentionDays,
            min: 1,
            max: 365,
            onchange: (v3) => {
              backupRetentionDays = v3;
              update3("backup_retention_days", v3);
            }
          });
          $$renderer3.push(`<!----></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--> <input type="hidden" name="backup_schedule"${attr("value", backupSchedule)}/></div>`);
      },
      $$slots: { default: true }
    });
    $$renderer2.push(`<!----> `);
    ExpandableCard($$renderer2, {
      title: "Logging",
      description: "Configure application logs, rotation, and retention",
      onboardingId: "general-logging",
      children: ($$renderer3) => {
        $$renderer3.push(`<div class="space-y-4 px-6 py-4"><div${attr_class("grid gap-4", void 0, {
          "sm:grid-cols-2": logEnabled,
          "xl:grid-cols-7": logEnabled
        })}><div><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Logging</span> `);
        Toggle($$renderer3, {
          label: logEnabled ? "Enabled" : "Disabled",
          checked: logEnabled,
          fullWidth: logEnabled
        });
        $$renderer3.push(`<!----></div> <input type="hidden" name="log_enabled"${attr("value", logEnabled ? "on" : "")}/> `);
        if (logEnabled) {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<div><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">File Logging</span> `);
          Toggle($$renderer3, {
            label: logFileLogging ? "Enabled" : "Disabled",
            checked: logFileLogging,
            fullWidth: true
          });
          $$renderer3.push(`<!----></div> <div><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Console Logging</span> `);
          Toggle($$renderer3, {
            label: logConsoleLogging ? "Enabled" : "Disabled",
            checked: logConsoleLogging,
            fullWidth: true
          });
          $$renderer3.push(`<!----></div> <div class="xl:col-span-2"><span class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Minimum Level</span> <div class="font-mono">`);
          DropdownSelect($$renderer3, {
            value: logMinLevel,
            options: logLevelOptions,
            fullWidth: true,
            fixed: true
          });
          $$renderer3.push(`<!----></div></div> <div class="xl:col-span-2"><label for="log_retention_days" class="mb-1 block text-sm font-medium text-neutral-900 dark:text-neutral-50">Retention Period (days)</label> `);
          NumberInput($$renderer3, {
            name: "log_retention_days",
            id: "log_retention_days",
            value: logRetentionDays,
            min: 1,
            max: 365,
            onchange: (v3) => {
              logRetentionDays = v3;
              update3("log_retention_days", v3);
            }
          });
          $$renderer3.push(`<!----></div>`);
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div> <input type="hidden" name="log_file_logging"${attr("value", logFileLogging ? "on" : "")}/> <input type="hidden" name="log_console_logging"${attr("value", logConsoleLogging ? "on" : "")}/> <input type="hidden" name="log_min_level"${attr("value", logMinLevel)}/></div>`);
      },
      $$slots: {
        default: true,
        "header-right": ($$renderer3) => {
          $$renderer3.push(`<div>`);
          Button($$renderer3, {
            text: "Reset",
            icon: Rotate_ccw,
            size: "xs"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    $$renderer2.push(`<!----> `);
    ExpandableCard($$renderer2, {
      title: "TMDB Configuration",
      description: "Configure TMDB API access for searching movies and TV series",
      onboardingId: "general-tmdb",
      children: ($$renderer3) => {
        $$renderer3.push(`<div class="space-y-4 px-6 py-4">`);
        FormInput($$renderer3, {
          label: "API Read Access Token",
          name: "tmdb_api_key",
          value: tmdbApiKey,
          private_: true,
          mono: true,
          placeholder: data.tmdbSettings.hasApiKey ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : "",
          description: data.tmdbSettings.hasApiKey ? "Leave blank to keep existing key" : "Use the API Read Access Token (not API Key) from themoviedb.org"
        });
        $$renderer3.push(`<!----></div>`);
      },
      $$slots: {
        default: true,
        "header-right": ($$renderer3) => {
          $$renderer3.push(`<div class="flex items-center gap-2">`);
          Button($$renderer3, {
            text: "Test",
            icon: Flask_conical,
            loading: tmdbTesting,
            disabled: tmdbTesting,
            size: "xs"
          });
          $$renderer3.push(`<!----> `);
          Button($$renderer3, {
            text: "Reset",
            icon: Rotate_ccw,
            size: "xs"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    $$renderer2.push(`<!----> `);
    if (FEATURES.ai) {
      $$renderer2.push("<!--[0-->");
      ExpandableCard($$renderer2, {
        title: "AI Configuration",
        description: "Configure AI-powered features. Works with OpenAI, Ollama, LM Studio, or any OpenAI-compatible API.",
        children: ($$renderer3) => {
          $$renderer3.push(`<div class="space-y-4 px-6 py-4">`);
          Toggle($$renderer3, {
            label: "Enable AI Features",
            checked: aiEnabled
          });
          $$renderer3.push(`<!----> <input type="hidden" name="ai_enabled"${attr("value", aiEnabled ? "on" : "")}/> `);
          if (aiEnabled) {
            $$renderer3.push("<!--[0-->");
            FormInput($$renderer3, {
              label: "API URL",
              name: "ai_api_url",
              value: aiApiUrl,
              type: "url",
              mono: true,
              description: "OpenAI-compatible endpoint (e.g., Ollama: http://localhost:11434/v1)"
            });
            $$renderer3.push(`<!----> `);
            FormInput($$renderer3, {
              label: "API Key",
              name: "ai_api_key",
              value: aiApiKey,
              private_: true,
              mono: true,
              placeholder: data.aiSettings.hasApiKey ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : "",
              description: data.aiSettings.hasApiKey ? "Leave blank to keep existing key" : "Required for cloud providers. Leave empty for local APIs."
            });
            $$renderer3.push(`<!----> `);
            FormInput($$renderer3, {
              label: "Model",
              name: "ai_model",
              value: aiModel,
              mono: true,
              description: "e.g., gpt-4o-mini, llama3.2, claude-3-haiku"
            });
            $$renderer3.push(`<!---->`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--></div>`);
        },
        $$slots: {
          default: true,
          "header-right": ($$renderer3) => {
            $$renderer3.push(`<div>`);
            Button($$renderer3, {
              text: "Reset",
              icon: Rotate_ccw,
              size: "xs"
            });
            $$renderer3.push(`<!----></div>`);
          }
        }
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div></div> `);
    DirtyModal($$renderer2, {});
    $$renderer2.push(`<!----></form>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte70 = __esm({
  "dist/build/server/entries/pages/settings/general/_page.svelte.js"() {
    "use strict";
    init_index_server();
    init_server();
    init_index_server2();
    init_features();
    init_navIcons();
    init_circle_check_big();
    init_circle_x();
    init_flask_conical();
    init_info();
    init_Button();
    init_rotate_ccw();
    init_save();
    init_triangle_alert();
    init_store2();
    init_dateFormat();
    init_forms();
    init_dirty();
    init_DirtyModal();
    init_PageMeta();
    init_DropdownSelect();
    init_FormInput();
    init_NumberInput();
    init_Toggle();
    init_ExpandableCard();
  }
});

// dist/build/server/nodes/80.js
var __exports81 = {};
__export(__exports81, {
  component: () => component77,
  fonts: () => fonts81,
  imports: () => imports81,
  index: () => index81,
  server: () => page_server_ts_exports71,
  server_id: () => server_id77,
  stylesheets: () => stylesheets81
});
var index81, component_cache77, component77, server_id77, imports81, stylesheets81, fonts81;
var init__81 = __esm({
  async "dist/build/server/nodes/80.js"() {
    "use strict";
    await init_page_server_ts71();
    index81 = 80;
    component77 = async () => component_cache77 ??= (await Promise.resolve().then(() => (init_page_svelte70(), page_svelte_exports70))).default;
    server_id77 = "src/routes/settings/general/+page.server.ts";
    imports81 = ["_app/immutable/nodes/80.Cu5X_1Ps.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/BUYotPgW.js", "_app/immutable/chunks/BGa_v0Jt2.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/CQskZlkd2.js", "_app/immutable/chunks/SEZzcS_o.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/DvoiSP5r.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/CrqGeVR2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/DxZIQ_tr2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAuEC8Ja2.js", "_app/immutable/chunks/CEQEwD8g.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/Cf96lmLi2.js"];
    stylesheets81 = [];
    fonts81 = [];
  }
});

// dist/build/server/entries/pages/settings/jobs/_page.server.ts.js
var page_server_ts_exports72 = {};
__export(page_server_ts_exports72, {
  actions: () => actions46,
  load: () => load75
});
var load75, actions46;
var init_page_server_ts72 = __esm({
  async "dist/build/server/entries/pages/settings/jobs/_page.server.ts.js"() {
    "use strict";
    await init_databaseInstances();
    await init_arrInstances();
    await init_jobQueue();
    await init_jobRunHistory();
    await init_display();
    load75 = () => {
      const arrInstances = arrInstancesQueries.getAll();
      const databases = databaseInstancesQueries.getAll();
      const lookups = {
        arrNameById: new Map(arrInstances.map((instance) => [instance.id, instance.name])),
        databaseNameById: new Map(databases.map((db2) => [db2.id, db2.name]))
      };
      const jobsWithRuns = jobQueueQueries.listScheduled().map((job) => {
        const lastRun = jobRunHistoryQueries.getByQueueId(job.id, 1)[0] || null;
        const displayName = buildJobDisplayName(job.jobType, job.payload, lookups);
        return {
          id: job.id,
          name: job.jobType,
          displayName,
          description: job.dedupeKey || "Scheduled job",
          enabled: job.status !== "cancelled",
          status: job.status,
          last_run_at: lastRun?.startedAt ?? null,
          next_run_at: job.runAt,
          last_run_status: lastRun?.status ?? null,
          last_run_duration: lastRun?.durationMs ?? null,
          last_run_error: lastRun?.error ?? null
        };
      });
      const recentRuns = jobRunHistoryQueries.getRecent(50);
      const queueIds = Array.from(new Set(recentRuns.map((run5) => run5.queueId).filter((id) => typeof id === "number")));
      const queueById = /* @__PURE__ */ new Map();
      for (const queueId of queueIds) {
        const queue = jobQueueQueries.getById(queueId);
        if (queue) queueById.set(queueId, queue);
      }
      return {
        jobs: jobsWithRuns,
        jobRuns: recentRuns.map((run5) => ({
          ...run5,
          jobName: run5.jobType,
          displayName: buildJobDisplayName(run5.jobType, queueById.get(run5.queueId ?? -1)?.payload ?? {}, lookups)
        }))
      };
    };
    actions46 = {};
  }
});

// dist/build/server/entries/pages/settings/jobs/_page.svelte.js
var page_svelte_exports71 = {};
__export(page_svelte_exports71, {
  default: () => _page71
});
function Circle_minus($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "circle-minus" },
    props,
    { iconNode: [["circle", {
      "cx": "12",
      "cy": "12",
      "r": "10"
    }], ["path", { "d": "M8 12h8" }]] }
  ]));
}
function JobHistory($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let filteredRuns, skippedCount;
    let jobRuns = $$props["jobRuns"];
    let showSkipped = false;
    const columns = [
      {
        key: "jobName",
        header: "Job",
        sortable: true
      },
      {
        key: "status",
        header: "Status",
        sortable: true,
        width: "w-28"
      },
      {
        key: "startedAt",
        header: "Started",
        sortable: true
      },
      {
        key: "durationMs",
        header: "Duration",
        sortable: true,
        width: "w-28"
      },
      {
        key: "output",
        header: "Output"
      }
    ];
    function formatDuration2(ms) {
      if (ms < 1e3) return `${ms}ms`;
      if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
      return `${(ms / 6e4).toFixed(1)}m`;
    }
    function formatJobName(name) {
      return name.replace(/\./g, " ").split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
    }
    function getRelativeTime(dateStr) {
      const date = parseUTC(dateStr);
      if (!date) return "-";
      const diff = (/* @__PURE__ */ new Date()).getTime() - date.getTime();
      const seconds = Math.floor(diff / 1e3);
      const minutes = Math.floor(seconds / 60);
      const hours = Math.floor(minutes / 60);
      const days = Math.floor(hours / 24);
      if (days > 0) return `${days}d ago`;
      if (hours > 0) return `${hours}h ago`;
      if (minutes > 0) return `${minutes}m ago`;
      return `${seconds}s ago`;
    }
    $: filteredRuns = showSkipped ? jobRuns : jobRuns.filter((run5) => run5.status !== "skipped");
    $: skippedCount = jobRuns.filter((run5) => run5.status === "skipped").length;
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      $$renderer3.push(`<div class="space-y-4"><div class="flex items-center justify-between"><div class="flex items-center gap-2">`);
      Clock($$renderer3, {
        size: 18,
        class: "text-neutral-600 dark:text-neutral-400"
      });
      $$renderer3.push(`<!----> <h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-50">Recent Job Runs</h2></div> `);
      if (skippedCount > 0) {
        $$renderer3.push("<!--[0-->");
        $$renderer3.push(`<div class="flex items-center gap-2"><span class="text-sm text-neutral-500 dark:text-neutral-400">${escape_html(skippedCount)} skipped</span> `);
        Toggle($$renderer3, {
          label: "Show skipped runs",
          get checked() {
            return showSkipped;
          },
          set checked($$value) {
            showSkipped = $$value;
            $$settled = false;
          }
        });
        $$renderer3.push(`<!----></div>`);
      } else $$renderer3.push("<!--[-1-->");
      $$renderer3.push(`<!--]--></div> `);
      Table2($$renderer3, {
        columns,
        data: filteredRuns,
        emptyMessage: "No job runs yet",
        compact: true,
        responsive: true,
        $$slots: { cell: ($$renderer4, { row, column }) => {
          if (column.key === "jobName") {
            $$renderer4.push("<!--[0-->");
            $$renderer4.push(`<span class="text-xs font-medium">${escape_html(row.displayName ?? formatJobName(row.jobName))}</span>`);
          } else if (column.key === "status") {
            $$renderer4.push("<!--[1-->");
            if (row.status === "success") {
              $$renderer4.push("<!--[0-->");
              Badge($$renderer4, {
                variant: "success",
                icon: Circle_check_big,
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->Success`);
                },
                $$slots: { default: true }
              });
            } else if (row.status === "skipped") {
              $$renderer4.push("<!--[1-->");
              Badge($$renderer4, {
                variant: "neutral",
                icon: Circle_minus,
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->Skipped`);
                },
                $$slots: { default: true }
              });
            } else if (row.status === "cancelled") {
              $$renderer4.push("<!--[2-->");
              Badge($$renderer4, {
                variant: "neutral",
                icon: Circle_minus,
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->Cancelled`);
                },
                $$slots: { default: true }
              });
            } else {
              $$renderer4.push("<!--[-1-->");
              Badge($$renderer4, {
                variant: "danger",
                icon: Circle_x,
                children: ($$renderer5) => {
                  $$renderer5.push(`<!---->Failed`);
                },
                $$slots: { default: true }
              });
            }
            $$renderer4.push(`<!--]-->`);
          } else if (column.key === "startedAt") {
            $$renderer4.push("<!--[2-->");
            Badge($$renderer4, {
              variant: "neutral",
              mono: true,
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->${escape_html(getRelativeTime(row.startedAt))}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "durationMs") {
            $$renderer4.push("<!--[3-->");
            Badge($$renderer4, {
              variant: "neutral",
              mono: true,
              children: ($$renderer5) => {
                $$renderer5.push(`<!---->${escape_html(formatDuration2(row.durationMs))}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "output") {
            $$renderer4.push("<!--[4-->");
            if (row.error) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<span class="line-clamp-1 font-mono text-xs text-red-600 dark:text-red-400">${escape_html(row.error)}</span>`);
            } else if (row.output) {
              $$renderer4.push("<!--[1-->");
              $$renderer4.push(`<span class="line-clamp-1 font-mono text-xs text-neutral-600 dark:text-neutral-400">${escape_html(row.output)}</span>`);
            } else {
              $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`<span class="text-neutral-400 dark:text-neutral-600">-</span>`);
            }
            $$renderer4.push(`<!--]-->`);
          } else $$renderer4.push("<!--[-1-->");
          $$renderer4.push(`<!--]-->`);
        } }
      });
      $$renderer3.push(`<!----></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    bind_props($$props, { jobRuns });
  });
}
function _page71($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let data = $$props["data"];
    const columns = [
      {
        key: "name",
        header: "Job",
        sortable: true
      },
      {
        key: "status",
        header: "Status",
        sortable: true,
        width: "w-28"
      },
      {
        key: "last_run_at",
        header: "Last Run",
        sortable: true
      },
      {
        key: "next_run_at",
        header: "Next Run",
        sortable: true
      }
    ];
    function formatJobName(name) {
      return name.replace(/\./g, " ").split("_").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
    }
    function getJobLabel(job) {
      return job.displayName ?? formatJobName(job.name);
    }
    function formatDuration2(ms) {
      if (!ms) return "-";
      if (ms < 1e3) return `${ms}ms`;
      if (ms < 6e4) return `${(ms / 1e3).toFixed(1)}s`;
      return `${(ms / 6e4).toFixed(1)}m`;
    }
    function formatDateTime$1(dateStr) {
      if (!dateStr) return "Never";
      return formatDateTime(dateStr, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat));
    }
    PageMeta($$renderer2, { title: "Jobs" });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8"><div class="mb-8"><h1 class="text-2xl font-bold text-neutral-900 md:text-3xl dark:text-neutral-50">Background Jobs</h1> <p class="mt-3 text-base text-neutral-600 md:text-lg dark:text-neutral-400">Manage scheduled tasks and automation workflows</p></div> <div class="mb-8" data-onboarding="jobs-table">`);
    ExpandableTable($$renderer2, {
      columns,
      data: data.jobs,
      getRowId: (job) => job.id,
      emptyMessage: "No background jobs configured",
      flushExpanded: true,
      chevronPosition: "right",
      responsive: true,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "name") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="font-medium">${escape_html(getJobLabel(row))}</span>`);
          } else if (column.key === "status") {
            $$renderer3.push("<!--[1-->");
            if (row.status === "running") {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "accent",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Running`);
                },
                $$slots: { default: true }
              });
            } else if (row.status === "queued") {
              $$renderer3.push("<!--[1-->");
              Badge($$renderer3, {
                variant: "neutral",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Queued`);
                },
                $$slots: { default: true }
              });
            } else if (row.status === "cancelled") {
              $$renderer3.push("<!--[2-->");
              Badge($$renderer3, {
                variant: "danger",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Cancelled`);
                },
                $$slots: { default: true }
              });
            } else {
              $$renderer3.push("<!--[-1-->");
              Badge($$renderer3, {
                variant: "neutral",
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(row.status)}`);
                },
                $$slots: { default: true }
              });
            }
            $$renderer3.push(`<!--]-->`);
          } else if (column.key === "last_run_at") {
            $$renderer3.push("<!--[2-->");
            $$renderer3.push(`<div class="flex items-center gap-2">`);
            Badge($$renderer3, {
              variant: "neutral",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatRelative(row.last_run_at))}`);
              },
              $$slots: { default: true }
            });
            $$renderer3.push(`<!----> `);
            if (row.last_run_status === "success") {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "success",
                icon: Circle_check_big,
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Success`);
                },
                $$slots: { default: true }
              });
            } else if (row.last_run_status === "skipped") {
              $$renderer3.push("<!--[1-->");
              Badge($$renderer3, {
                variant: "neutral",
                icon: Circle_minus,
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Skipped`);
                },
                $$slots: { default: true }
              });
            } else if (row.last_run_status === "failure") {
              $$renderer3.push("<!--[2-->");
              Badge($$renderer3, {
                variant: "danger",
                icon: Circle_x,
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->Failed`);
                },
                $$slots: { default: true }
              });
            } else $$renderer3.push("<!--[-1-->");
            $$renderer3.push(`<!--]--></div>`);
          } else if (column.key === "next_run_at") {
            $$renderer3.push("<!--[3-->");
            if (row.enabled) {
              $$renderer3.push("<!--[0-->");
              Badge($$renderer3, {
                variant: "neutral",
                mono: true,
                children: ($$renderer4) => {
                  $$renderer4.push(`<!---->${escape_html(formatRelative(row.next_run_at))}`);
                },
                $$slots: { default: true }
              });
            } else {
              $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<span class="text-neutral-400 dark:text-neutral-600">-</span>`);
            }
            $$renderer3.push(`<!--]-->`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        expanded: ($$renderer3, { row }) => {
          $$renderer3.push(`<div class="space-y-3 px-6 py-4 text-sm">`);
          if (row.description) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<p class="text-neutral-600 dark:text-neutral-400">${escape_html(row.description)}</p>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--> <div class="grid grid-cols-3 gap-4"><div><div class="text-xs font-medium tracking-wider text-neutral-500 uppercase dark:text-neutral-500">Last Run</div> <div class="mt-1">`);
          Badge($$renderer3, {
            variant: "neutral",
            mono: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(formatDateTime$1(row.last_run_at))}`);
            },
            $$slots: { default: true }
          });
          $$renderer3.push(`<!----></div></div> <div><div class="text-xs font-medium tracking-wider text-neutral-500 uppercase dark:text-neutral-500">Duration</div> <div class="mt-1">`);
          Badge($$renderer3, {
            variant: "neutral",
            mono: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(formatDuration2(row.last_run_duration))}`);
            },
            $$slots: { default: true }
          });
          $$renderer3.push(`<!----></div></div> <div><div class="text-xs font-medium tracking-wider text-neutral-500 uppercase dark:text-neutral-500">Next Run</div> <div class="mt-1">`);
          if (row.enabled) {
            $$renderer3.push("<!--[0-->");
            Badge($$renderer3, {
              variant: "neutral",
              mono: true,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(formatDateTime$1(row.next_run_at))}`);
              },
              $$slots: { default: true }
            });
          } else {
            $$renderer3.push("<!--[-1-->");
            Badge($$renderer3, {
              variant: "neutral",
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->Disabled`);
              },
              $$slots: { default: true }
            });
          }
          $$renderer3.push(`<!--]--></div></div></div> `);
          if (row.last_run_error) {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<div class="flex items-start gap-2 rounded-lg border border-red-200 bg-red-50 p-3 dark:border-red-800 dark:bg-red-900/20">`);
            Circle_alert($$renderer3, {
              size: 16,
              class: "mt-0.5 flex-shrink-0 text-red-600 dark:text-red-400"
            });
            $$renderer3.push(`<!----> <div><div class="text-xs font-medium text-red-800 dark:text-red-200">Last Run Error</div> <div class="mt-1 text-sm text-red-700 dark:text-red-300">${escape_html(row.last_run_error)}</div></div></div>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]--></div>`);
        }
      }
    });
    $$renderer2.push(`<!----></div> <div data-onboarding="jobs-history">`);
    JobHistory($$renderer2, { jobRuns: data.jobRuns });
    $$renderer2.push(`<!----></div></div>`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte71 = __esm({
  "dist/build/server/entries/pages/settings/jobs/_page.svelte.js"() {
    "use strict";
    init_server();
    init_dates();
    init_Icon();
    init_circle_alert();
    init_circle_check_big();
    init_circle_x();
    init_clock();
    init_dateFormat();
    init_timezone();
    init_ExpandableTable();
    init_Badge();
    init_PageMeta();
    init_Table();
    init_Toggle();
  }
});

// dist/build/server/nodes/81.js
var __exports82 = {};
__export(__exports82, {
  component: () => component78,
  fonts: () => fonts82,
  imports: () => imports82,
  index: () => index82,
  server: () => page_server_ts_exports72,
  server_id: () => server_id78,
  stylesheets: () => stylesheets82
});
var index82, component_cache78, component78, server_id78, imports82, stylesheets82, fonts82;
var init__82 = __esm({
  async "dist/build/server/nodes/81.js"() {
    "use strict";
    await init_page_server_ts72();
    index82 = 81;
    component78 = async () => component_cache78 ??= (await Promise.resolve().then(() => (init_page_svelte71(), page_svelte_exports71))).default;
    server_id78 = "src/routes/settings/jobs/+page.server.ts";
    imports82 = ["_app/immutable/nodes/81.DDdddJsD.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/BGa_v0Jt2.js", "_app/immutable/chunks/CQskZlkd2.js", "_app/immutable/chunks/BqRH1fsh2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js"];
    stylesheets82 = ["_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts82 = [];
  }
});

// dist/build/server/entries/pages/settings/logs/_page.server.ts.js
var page_server_ts_exports73 = {};
__export(page_server_ts_exports73, {
  actions: () => actions47,
  load: () => load76
});
async function getLogFiles() {
  const logsDir = config.paths.logs;
  const logFiles = [];
  try {
    for await (const entry of Deno.readDir(logsDir)) if (entry.isFile && entry.name.endsWith(".log")) {
      const filePath = `${logsDir}/${entry.name}`;
      try {
        const stat = await Deno.stat(filePath);
        if (stat.mtime) logFiles.push({
          path: filePath,
          mtime: stat.mtime
        });
      } catch {
      }
    }
  } catch {
    return [];
  }
  logFiles.sort((a2, b3) => b3.mtime.getTime() - a2.mtime.getTime());
  return logFiles.map((f2) => f2.path);
}
async function getLogFilesList() {
  const logsDir = config.paths.logs;
  const logFiles = [];
  try {
    for await (const entry of Deno.readDir(logsDir)) if (entry.isFile && entry.name.endsWith(".log")) {
      const filePath = `${logsDir}/${entry.name}`;
      try {
        const stat = await Deno.stat(filePath);
        if (stat.mtime) logFiles.push({
          filename: entry.name,
          path: filePath,
          size: stat.size,
          modified: stat.mtime
        });
      } catch {
      }
    }
  } catch {
    return [];
  }
  logFiles.sort((a2, b3) => b3.modified.getTime() - a2.modified.getTime());
  return logFiles;
}
async function readLogsFromFile(filename) {
  try {
    const filePath = `${config.paths.logs}/${filename}`;
    const logs = [];
    const lines = (await Deno.readTextFile(filePath)).split("\n").filter((line) => line.trim());
    for (const line of lines) try {
      const entry = JSON.parse(line);
      logs.push(entry);
    } catch {
    }
    logs.sort((a2, b3) => new Date(a2.timestamp).getTime() - new Date(b3.timestamp).getTime());
    return logs;
  } catch (_error2) {
    return [];
  }
}
async function readLastLogs() {
  try {
    const logFiles = await getLogFiles();
    const logs = [];
    for (const filePath of logFiles) try {
      const lines = (await Deno.readTextFile(filePath)).split("\n").filter((line) => line.trim());
      for (const line of lines) try {
        const entry = JSON.parse(line);
        logs.push(entry);
      } catch {
      }
    } catch {
    }
    logs.sort((a2, b3) => new Date(a2.timestamp).getTime() - new Date(b3.timestamp).getTime());
    return logs;
  } catch (_error2) {
    return [];
  }
}
var load76, actions47;
var init_page_server_ts73 = __esm({
  async "dist/build/server/entries/pages/settings/logs/_page.server.ts.js"() {
    "use strict";
    await init_db();
    init_config();
    await init_display();
    await init_queueService();
    init_exports();
    load76 = async ({ url }) => {
      const logFiles = await getLogFilesList();
      const selectedFile = url.searchParams.get("file") || logFiles[0]?.filename || "";
      return {
        logs: selectedFile ? await readLogsFromFile(selectedFile) : await readLastLogs(),
        logFiles,
        selectedFile
      };
    };
    actions47 = { cleanupLogs: async () => {
      try {
        const queued = enqueueJob({
          jobType: "logs.cleanup",
          runAt: (/* @__PURE__ */ new Date()).toISOString(),
          payload: {},
          source: "manual"
        });
        await logger.info("Manual logs cleanup queued", {
          source: "settings/logs",
          meta: {
            jobId: queued.id,
            displayName: buildJobDisplayName("logs.cleanup", {})
          }
        });
        return { success: true };
      } catch (error2) {
        await logger.error("Failed to trigger logs cleanup", {
          source: "settings/logs",
          meta: { error: error2 }
        });
        return fail(500, { error: "Failed to trigger logs cleanup" });
      }
    } };
  }
});

// dist/build/server/entries/pages/settings/logs/_page.svelte.js
var page_svelte_exports72 = {};
__export(page_svelte_exports72, {
  default: () => _page72
});
function LogsActionsBar($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let searchStore = $$props["searchStore"];
    let logFiles = $$props["logFiles"];
    let selectedFile = $$props["selectedFile"];
    let selectedLevel = $$props["selectedLevel"];
    let selectedSources = $$props["selectedSources"];
    let uniqueSources = $$props["uniqueSources"];
    let isRefreshing = fallback($$props["isRefreshing"], false);
    let onChangeFile = $$props["onChangeFile"];
    let onChangeLevel = $$props["onChangeLevel"];
    let onToggleSource = $$props["onToggleSource"];
    let onRefresh = $$props["onRefresh"];
    let onDownload = $$props["onDownload"];
    let onCleanup = fallback($$props["onCleanup"], void 0);
    const logLevels = [
      "ALL",
      "DEBUG",
      "INFO",
      "WARN",
      "ERROR"
    ];
    const levelColors = {
      ALL: "text-neutral-600 dark:text-neutral-400",
      DEBUG: "text-cyan-600 dark:text-cyan-400",
      INFO: "text-green-600 dark:text-green-400",
      WARN: "text-yellow-600 dark:text-yellow-400",
      ERROR: "text-red-600 dark:text-red-400"
    };
    function formatFileSize2(bytes) {
      if (bytes < 1024) return `${bytes} B`;
      if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
      return `${(bytes / 1048576).toFixed(1)} MB`;
    }
    ActionsBar($$renderer2, {
      className: "justify-end",
      children: ($$renderer3) => {
        SearchAction($$renderer3, {
          searchStore,
          placeholder: "Search logs...",
          responsive: true
        });
        $$renderer3.push(`<!----> `);
        ActionButton($$renderer3, {
          icon: File_text,
          hasDropdown: true,
          dropdownPosition: "right",
          $$slots: { dropdown: ($$renderer4, { dropdownPosition }) => {
            Dropdown($$renderer4, {
              position: dropdownPosition,
              minWidth: "16rem",
              children: ($$renderer5) => {
                DropdownHeader($$renderer5, { label: "Log Files" });
                $$renderer5.push(`<!----> <div class="max-h-64 overflow-y-auto"><!--[-->`);
                const each_array = ensure_array_like(logFiles);
                for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
                  let file = each_array[$$index];
                  DropdownItem($$renderer5, {
                    label: file.filename,
                    secondaryText: formatFileSize2(file.size),
                    selected: selectedFile === file.filename
                  });
                }
                $$renderer5.push(`<!--]--></div>`);
              },
              $$slots: { default: true }
            });
          } }
        });
        $$renderer3.push(`<!----> `);
        Tooltip($$renderer3, {
          text: "Download",
          children: ($$renderer4) => {
            ActionButton($$renderer4, { icon: Download });
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----> `);
        ActionButton($$renderer3, {
          icon: Funnel,
          hasDropdown: true,
          dropdownPosition: "right",
          $$slots: { dropdown: ($$renderer4, { dropdownPosition }) => {
            Dropdown($$renderer4, {
              position: dropdownPosition,
              minWidth: "8rem",
              children: ($$renderer5) => {
                DropdownHeader($$renderer5, { label: "Level" });
                $$renderer5.push(`<!----> <!--[-->`);
                const each_array_1 = ensure_array_like(logLevels);
                for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
                  let level = each_array_1[$$index_1];
                  DropdownItem($$renderer5, {
                    label: level,
                    selected: selectedLevel === level,
                    labelClass: `font-mono ${stringify(levelColors[level])}`
                  });
                }
                $$renderer5.push(`<!--]-->`);
              },
              $$slots: { default: true }
            });
          } }
        });
        $$renderer3.push(`<!----> `);
        ActionButton($$renderer3, {
          icon: Layers,
          hasDropdown: true,
          dropdownPosition: "right",
          $$slots: { dropdown: ($$renderer4, { dropdownPosition }) => {
            Dropdown($$renderer4, {
              position: dropdownPosition,
              minWidth: "12rem",
              children: ($$renderer5) => {
                DropdownHeader($$renderer5, { label: "Source" });
                $$renderer5.push(`<!----> <div class="max-h-64 overflow-y-auto"><!--[-->`);
                const each_array_2 = ensure_array_like(uniqueSources);
                for (let $$index_2 = 0, $$length = each_array_2.length; $$index_2 < $$length; $$index_2++) {
                  let source2 = each_array_2[$$index_2];
                  DropdownItem($$renderer5, {
                    label: source2,
                    labelClass: "font-mono",
                    selected: selectedSources.has(source2)
                  });
                }
                $$renderer5.push(`<!--]--></div>`);
              },
              $$slots: { default: true }
            });
          } }
        });
        $$renderer3.push(`<!----> `);
        Tooltip($$renderer3, {
          text: "Refresh",
          children: ($$renderer4) => {
            ActionButton($$renderer4, {
              children: ($$renderer5) => {
                Refresh_cw($$renderer5, {
                  size: 20,
                  class: `text-neutral-700 dark:text-neutral-300 ${isRefreshing ? "animate-spin" : ""}`
                });
              },
              $$slots: { default: true }
            });
          },
          $$slots: { default: true }
        });
        $$renderer3.push(`<!----> `);
        if (onCleanup) {
          $$renderer3.push("<!--[0-->");
          Tooltip($$renderer3, {
            text: "Cleanup",
            children: ($$renderer4) => {
              ActionButton($$renderer4, { icon: Brush_cleaning });
            },
            $$slots: { default: true }
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]-->`);
      },
      $$slots: { default: true }
    });
    bind_props($$props, {
      searchStore,
      logFiles,
      selectedFile,
      selectedLevel,
      selectedSources,
      uniqueSources,
      isRefreshing,
      onChangeFile,
      onChangeLevel,
      onToggleSource,
      onRefresh,
      onDownload,
      onCleanup
    });
  });
}
function _page72($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let uniqueSources, filteredLogs, sortedLogs, totalPages, startIndex, endIndex, paginatedLogs;
    let data = $$props["data"];
    const levelCellComponent = LogLevelCell;
    const sourceCellComponent = LogSourceCell;
    const searchStore = getPersistentSearchStore("settingsLogsSearch", { debounceMs: 300 });
    let selectedLevel = "ALL";
    let selectedSources = /* @__PURE__ */ new Set();
    let isRefreshing = false;
    let currentPage = 1;
    let itemsPerPage = 100;
    let sortState = {
      key: "timestamp",
      direction: "desc"
    };
    function toggleSource(source2) {
      selectedSources = new Set(selectedSources);
      if (selectedSources.has(source2)) selectedSources.delete(source2);
      else selectedSources.add(source2);
    }
    const columns = [
      {
        key: "timestamp",
        header: "Timestamp",
        sortable: true,
        sortAccessor: (row) => new Date(row.timestamp).getTime(),
        cell: (row) => ({ html: `<span class="font-mono text-xs text-neutral-600 dark:text-neutral-400">${formatDateTime(row.timestamp, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat))}</span>` })
      },
      {
        key: "level",
        header: "Level",
        sortable: true,
        cell: () => levelCellComponent
      },
      {
        key: "source",
        header: "Source",
        sortable: true,
        cell: () => sourceCellComponent
      },
      {
        key: "message",
        header: "Message",
        cell: (row) => row.message
      }
    ];
    let showMetaModal = false;
    let selectedMeta = null;
    function downloadLogs() {
      const dataStr = JSON.stringify(filteredLogs, null, 2);
      const dataBlob = new Blob([dataStr], { type: "application/json" });
      const url = URL.createObjectURL(dataBlob);
      const link = document.createElement("a");
      link.href = url;
      link.download = `profilarr-logs-${(/* @__PURE__ */ new Date()).toISOString()}.json`;
      link.click();
      URL.revokeObjectURL(url);
    }
    function triggerCleanupLogs() {
    }
    async function refreshLogs() {
      isRefreshing = true;
      await invalidateAll();
      isRefreshing = false;
    }
    function changeLogFile(filename) {
      const url = new URL(window.location.href);
      url.searchParams.set("file", filename);
      window.location.href = url.toString();
    }
    function getCellValue(row, key2) {
      return key2.split(".").reduce((obj, k2) => obj?.[k2], row);
    }
    function compareValues(a2, b3) {
      if (a2 == null && b3 == null) return 0;
      if (a2 == null) return -1;
      if (b3 == null) return 1;
      if (typeof a2 === "number" && typeof b3 === "number") return a2 - b3;
      if (a2 instanceof Date && b3 instanceof Date) return a2.getTime() - b3.getTime();
      return String(a2).localeCompare(String(b3));
    }
    function getSortValue(row, column) {
      if (column.sortAccessor) return column.sortAccessor(row);
      return getCellValue(row, column.key);
    }
    function sortLogs(rows, state2, fallbackDirection) {
      const baseSorted = [...rows].sort((a2, b3) => new Date(b3.timestamp).getTime() - new Date(a2.timestamp).getTime());
      if (!state2) return baseSorted;
      if (state2.key === "timestamp" && state2.direction === fallbackDirection) return baseSorted;
      const column = columns.find((col) => col.key === state2.key);
      if (!column) return baseSorted;
      const sorted = [...rows].sort((a2, b3) => {
        if (column.sortComparator) return column.sortComparator(a2, b3);
        return compareValues(getSortValue(a2, column), getSortValue(b3, column));
      });
      return state2.direction === "desc" ? sorted.reverse() : sorted;
    }
    const defaultSortDirection = "desc";
    function handlePageChange(page2) {
      currentPage = page2;
    }
    function handleSortChange(nextSort) {
      sortState = nextSort;
      currentPage = 1;
    }
    $: uniqueSources = [...new Set(data.logs.map((log) => log.source).filter(Boolean))];
    $: filteredLogs = data.logs.filter((log) => {
      if (selectedLevel !== "ALL" && log.level !== selectedLevel) return false;
      if (selectedSources.size > 0 && !selectedSources.has(log.source || "")) return false;
      const query = store_get($$store_subs ??= {}, "$searchStore", searchStore).query;
      if (query) {
        const searchLower = query.toLowerCase();
        const matchMessage = log.message.toLowerCase().includes(searchLower);
        const matchSource = log.source?.toLowerCase().includes(searchLower);
        return matchMessage || matchSource;
      }
      return true;
    });
    $: sortedLogs = sortLogs(filteredLogs, sortState, defaultSortDirection);
    $: if (selectedLevel || selectedSources || store_get($$store_subs ??= {}, "$searchStore", searchStore).query) currentPage = 1;
    $: totalPages = Math.max(1, Math.ceil(sortedLogs.length / itemsPerPage));
    $: if (currentPage > totalPages) currentPage = totalPages;
    $: startIndex = (currentPage - 1) * itemsPerPage;
    $: endIndex = Math.min(startIndex + itemsPerPage, sortedLogs.length);
    $: paginatedLogs = sortedLogs.slice(startIndex, endIndex);
    PageMeta($$renderer2, { title: "Logs" });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8"><div class="mb-8"><h1 class="text-2xl font-bold text-neutral-900 md:text-3xl dark:text-neutral-50">Logs</h1> <p class="mt-3 text-base text-neutral-600 md:text-lg dark:text-neutral-400">Application logs with filtering and search</p></div> <div data-onboarding="logs-actions">`);
    LogsActionsBar($$renderer2, {
      searchStore,
      logFiles: data.logFiles,
      selectedFile: data.selectedFile,
      selectedLevel,
      selectedSources,
      uniqueSources,
      isRefreshing,
      onChangeFile: changeLogFile,
      onChangeLevel: (level) => selectedLevel = level,
      onToggleSource: toggleSource,
      onRefresh: refreshLogs,
      onDownload: downloadLogs,
      onCleanup: triggerCleanupLogs
    });
    $$renderer2.push(`<!----></div> <form method="POST" action="?/cleanupLogs" class="hidden"></form> <div class="mt-6 mb-4 flex items-center justify-between text-sm text-neutral-600 dark:text-neutral-400"><span>Showing ${escape_html(startIndex + 1)}-${escape_html(endIndex)} of ${escape_html(filteredLogs.length)} logs `);
    if (filteredLogs.length !== data.logs.length) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`(filtered from ${escape_html(data.logs.length)})`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></span> `);
    if (totalPages > 1) {
      $$renderer2.push("<!--[0-->");
      Pagination($$renderer2, {
        currentPage,
        totalPages,
        onPageChange: handlePageChange
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div> <div data-onboarding="logs-table">`);
    Table2($$renderer2, {
      data: paginatedLogs,
      columns,
      emptyMessage: "No logs found",
      hoverable: true,
      compact: true,
      responsive: true,
      initialSort: {
        key: "timestamp",
        direction: defaultSortDirection
      },
      onSortChange: handleSortChange,
      $$slots: { actions: ($$renderer3, { row }) => {
        $$renderer3.push(`<div class="flex items-center justify-end gap-1">`);
        Button($$renderer3, {
          icon: Copy,
          size: "xs",
          variant: "secondary",
          title: "Copy log entry",
          ariaLabel: "Copy log entry"
        });
        $$renderer3.push(`<!----> `);
        if (row.meta) {
          $$renderer3.push("<!--[0-->");
          Button($$renderer3, {
            icon: Eye,
            size: "xs",
            variant: "secondary",
            title: "View metadata",
            ariaLabel: "View metadata"
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]--></div>`);
      } }
    });
    $$renderer2.push(`<!----></div> `);
    if (totalPages > 1) {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`<div class="mt-4 flex justify-center">`);
      Pagination($$renderer2, {
        currentPage,
        totalPages,
        onPageChange: handlePageChange
      });
      $$renderer2.push(`<!----></div>`);
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--></div> `);
    Modal($$renderer2, {
      open: showMetaModal,
      header: "Log Metadata",
      bodyMessage: "",
      confirmText: "Close",
      cancelText: "Close",
      size: "2xl",
      $$slots: { body: ($$renderer3) => {
        $$renderer3.push(`<div slot="body" class="space-y-3">`);
        CodeBlock($$renderer3, {
          code: JSON.stringify(selectedMeta, null, 2),
          language: "json"
        });
        $$renderer3.push(`<!----></div>`);
      } }
    });
    $$renderer2.push(`<!---->`);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, { data });
  });
}
var init_page_svelte72 = __esm({
  "dist/build/server/entries/pages/settings/logs/_page.svelte.js"() {
    "use strict";
    init_server();
    init_dates();
    init_Dropdown();
    init_brush_cleaning();
    init_copy();
    init_download();
    init_eye();
    init_file_text();
    init_funnel();
    init_layers();
    init_Button();
    init_refresh_cw();
    init_search();
    init_client4();
    init_store2();
    init_navigation();
    init_Modal();
    init_dateFormat();
    init_timezone();
    init_forms();
    init_DropdownItem();
    init_ActionsBar();
    init_ActionButton();
    init_DropdownHeader();
    init_PageMeta();
    init_Table();
    init_NumberInput();
    init_Pagination();
    init_LogSourceCell();
    init_CodeBlock();
  }
});

// dist/build/server/nodes/82.js
var __exports83 = {};
__export(__exports83, {
  component: () => component79,
  fonts: () => fonts83,
  imports: () => imports83,
  index: () => index83,
  server: () => page_server_ts_exports73,
  server_id: () => server_id79,
  stylesheets: () => stylesheets83
});
var index83, component_cache79, component79, server_id79, imports83, stylesheets83, fonts83;
var init__83 = __esm({
  async "dist/build/server/nodes/82.js"() {
    "use strict";
    await init_page_server_ts73();
    index83 = 82;
    component79 = async () => component_cache79 ??= (await Promise.resolve().then(() => (init_page_svelte72(), page_svelte_exports72))).default;
    server_id79 = "src/routes/settings/logs/+page.server.ts";
    imports83 = ["_app/immutable/nodes/82.Ctzu25ea.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/BKz1xBLr.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/D7OHFWTL2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/BtIghOBA.js", "_app/immutable/chunks/MJc6__n-.js", "_app/immutable/chunks/DYf5Ixhg.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/Da9e11Mg.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/CNfB0kJd.js", "_app/immutable/chunks/BTzQwcpc.js", "_app/immutable/chunks/BdjudyaY.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/CEJJceQ-.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/chhknG0q.js", "_app/immutable/chunks/DTxrEb2m.js", "_app/immutable/chunks/D1MpTH1m.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/Bhz_QMDT.js", "_app/immutable/chunks/BBtCGbx62.js", "_app/immutable/chunks/ITepJp4A2.js", "_app/immutable/chunks/DcKM5OzB2.js", "_app/immutable/chunks/DSNLgKve.js"];
    stylesheets83 = ["_app/immutable/assets/search.Dg-fBjb8.css", "_app/immutable/assets/ActionsBar.B10fFJmL.css", "_app/immutable/assets/Table.aVDhXS1A.css", "_app/immutable/assets/CodeBlock.Cn36jBaQ.css"];
    fonts83 = [];
  }
});

// dist/build/server/chunks/NotificationManager2.js
var NotificationManager2_exports = {};
__export(NotificationManager2_exports, {
  notificationManager: () => notificationManager
});
var init_NotificationManager2 = __esm({
  async "dist/build/server/chunks/NotificationManager2.js"() {
    "use strict";
    await init_NotificationManager();
  }
});

// dist/build/server/chunks/test.js
var test_exports = {};
__export(test_exports, {
  test: () => test
});
var init_test = __esm({
  "dist/build/server/chunks/test.js"() {
    "use strict";
    init_test2();
  }
});

// dist/build/server/entries/pages/settings/notifications/_page.server.ts.js
var page_server_ts_exports74 = {};
__export(page_server_ts_exports74, {
  actions: () => actions48,
  load: () => load77
});
var load77, actions48;
var init_page_server_ts74 = __esm({
  async "dist/build/server/entries/pages/settings/notifications/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_notificationServices();
    await init_notificationHistory();
    init_exports();
    load77 = () => {
      return {
        services: notificationServicesQueries.getAll().map((service) => {
          const stats = notificationHistoryQueries.getStats(service.id);
          let safeConfig = service.config;
          try {
            const { webhook_url: _3, access_token: __, auth_header: ___, ...rest } = JSON.parse(service.config);
            safeConfig = JSON.stringify(rest);
          } catch {
          }
          return {
            ...service,
            config: safeConfig,
            successCount: stats.success,
            failedCount: stats.failed,
            successRate: stats.successRate
          };
        }),
        history: notificationHistoryQueries.getRecent(50)
      };
    };
    actions48 = {
      toggleEnabled: async ({ request }) => {
        const formData = await request.formData();
        const id = formData.get("id");
        const enabled3 = formData.get("enabled") === "true";
        if (!id) return fail(400, { error: "Service ID is required" });
        try {
          if (!notificationServicesQueries.update(id, { enabled: enabled3 })) return fail(400, { error: "Failed to update service" });
          await logger.info(`Notification service ${enabled3 ? "enabled" : "disabled"}`, {
            source: "settings/notifications",
            meta: {
              serviceId: id,
              enabled: enabled3
            }
          });
          return { success: true };
        } catch (err) {
          await logger.error("Failed to toggle notification service", {
            source: "settings/notifications",
            meta: {
              serviceId: id,
              error: err
            }
          });
          return fail(500, { error: "Failed to update service" });
        }
      },
      delete: async ({ request }) => {
        const id = (await request.formData()).get("id");
        if (!id) return fail(400, { error: "Service ID is required" });
        try {
          if (!notificationServicesQueries.delete(id)) return fail(400, { error: "Failed to delete service" });
          await logger.info("Notification service deleted", {
            source: "settings/notifications",
            meta: { serviceId: id }
          });
          return { success: true };
        } catch (err) {
          await logger.error("Failed to delete notification service", {
            source: "settings/notifications",
            meta: {
              serviceId: id,
              error: err
            }
          });
          return fail(500, { error: "Failed to delete service" });
        }
      },
      testNotification: async ({ request }) => {
        const id = (await request.formData()).get("id");
        if (!id) return fail(400, { error: "Service ID is required" });
        try {
          const { notificationManager: notificationManager2 } = await init_NotificationManager2().then(() => NotificationManager2_exports);
          const { test: test2 } = await Promise.resolve().then(() => (init_test(), test_exports));
          await notificationManager2.sendToService(id, test2());
          return { success: true };
        } catch (err) {
          await logger.error("Failed to send test notification", {
            source: "settings/notifications",
            meta: {
              serviceId: id,
              error: err
            }
          });
          return fail(500, { error: "Failed to send test notification" });
        }
      }
    };
  }
});

// dist/build/server/chunks/rss.js
function Rss($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "rss" },
    props,
    { iconNode: [
      ["path", { "d": "M4 11a9 9 0 0 1 9 9" }],
      ["path", { "d": "M4 4a16 16 0 0 1 16 16" }],
      ["circle", {
        "cx": "5",
        "cy": "19",
        "r": "1"
      }]
    ] }
  ]));
}
var init_rss = __esm({
  "dist/build/server/chunks/rss.js"() {
    "use strict";
    init_server();
    init_Icon();
  }
});

// node_modules/.deno/simple-icons@16.27.1/node_modules/simple-icons/index.mjs
var c, t, a, siDiscord, siNtfy, siTelegram;
var init_simple_icons = __esm({
  "node_modules/.deno/simple-icons@16.27.1/node_modules/simple-icons/index.mjs"() {
    c = '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>';
    t = '</title><path d="';
    a = '"/></svg>';
    siDiscord = { title: "Discord", slug: "discord", get svg() {
      return c + "Discord" + t + this.path + a;
    }, path: "M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z", source: "https://discord.com/branding", hex: "5865F2", guidelines: "https://discord.com/branding" };
    siNtfy = { title: "ntfy", slug: "ntfy", get svg() {
      return c + "ntfy" + t + this.path + a;
    }, path: "M12.597 13.693v2.156h6.205v-2.156ZM5.183 6.549v2.363l3.591 1.901.023.01-.023.009-3.591 1.901v2.35l.386-.211 5.456-2.969V9.729ZM3.659 2.037C1.915 2.037.42 3.41.42 5.154v.002L.438 18.73 0 21.963l5.956-1.583h14.806c1.744 0 3.238-1.374 3.238-3.118V5.154c0-1.744-1.493-3.116-3.237-3.117h-.001zm0 2.2h17.104c.613.001 1.037.447 1.037.917v12.108c0 .47-.424.916-1.038.916H5.633l-3.026.915.031-.179-.017-13.76c0-.47.424-.917 1.038-.917z", source: "https://ntfy.sh", hex: "317F6F" };
    siTelegram = { title: "Telegram", slug: "telegram", get svg() {
      return c + "Telegram" + t + this.path + a;
    }, path: "M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z", source: "https://telegram.org/tour/screenshots", hex: "26A5E4" };
  }
});

// dist/build/server/entries/pages/settings/notifications/_page.svelte.js
var page_svelte_exports73 = {};
__export(page_svelte_exports73, {
  default: () => _page73
});
function Bell_off($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "bell-off" },
    props,
    { iconNode: [
      ["path", { "d": "M10.268 21a2 2 0 0 0 3.464 0" }],
      ["path", { "d": "M17 17H4a1 1 0 0 1-.74-1.673C4.59 13.956 6 12.499 6 8a6 6 0 0 1 .258-1.742" }],
      ["path", { "d": "m2 2 20 20" }],
      ["path", { "d": "M8.668 3.01A6 6 0 0 1 18 8c0 2.687.77 4.653 1.707 6.05" }]
    ] }
  ]));
}
function NotificationHistory($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let history = $$props["history"];
    let services = $$props["services"];
    const columns = [
      {
        key: "title",
        header: "Title",
        sortable: true
      },
      {
        key: "service_id",
        header: "Service",
        sortable: true
      },
      {
        key: "notification_type",
        header: "Type",
        sortable: true
      },
      {
        key: "status",
        header: "Status",
        sortable: true
      },
      {
        key: "sent_at",
        header: "Time",
        sortable: true
      }
    ];
    function getServiceName(serviceId) {
      return services.find((s3) => s3.id === serviceId)?.name || "Unknown";
    }
    function formatNotificationType(type) {
      const parts = type.split(".");
      if (parts.length >= 3) {
        const action = parts[1].replace(/_/g, " ");
        const status = parts[2];
        return `${action.charAt(0).toUpperCase() + action.slice(1)} ${status.charAt(0).toUpperCase() + status.slice(1)}`;
      }
      return type;
    }
    $$renderer2.push(`<div class="space-y-4"><div class="flex items-center gap-2">`);
    Bell($$renderer2, {
      size: 18,
      class: "text-neutral-600 dark:text-neutral-400"
    });
    $$renderer2.push(`<!----> <h2 class="text-lg font-semibold text-neutral-900 md:text-xl dark:text-neutral-50">Recent Notifications</h2></div> `);
    Table2($$renderer2, {
      columns,
      data: history,
      emptyMessage: "No notification history available yet.",
      compact: true,
      responsive: true,
      $$slots: { cell: ($$renderer3, { row, column }) => {
        if (column.key === "title") {
          $$renderer3.push("<!--[0-->");
          $$renderer3.push(`<span class="font-medium">${escape_html(row.title)}</span>`);
        } else if (column.key === "service_id") {
          $$renderer3.push("<!--[1-->");
          $$renderer3.push(`${escape_html(getServiceName(row.service_id))}`);
        } else if (column.key === "notification_type") {
          $$renderer3.push("<!--[2-->");
          Badge($$renderer3, {
            variant: "neutral",
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(formatNotificationType(row.notification_type))}`);
            },
            $$slots: { default: true }
          });
        } else if (column.key === "status") {
          $$renderer3.push("<!--[3-->");
          Badge($$renderer3, {
            variant: row.status === "success" ? "success" : "danger",
            icon: row.status === "success" ? Circle_check_big : Circle_x,
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(row.status === "success" ? "Success" : "Failed")}`);
            },
            $$slots: { default: true }
          });
        } else if (column.key === "sent_at") {
          $$renderer3.push("<!--[4-->");
          Badge($$renderer3, {
            variant: "neutral",
            mono: true,
            children: ($$renderer4) => {
              $$renderer4.push(`<!---->${escape_html(formatRelative(row.sent_at))}`);
            },
            $$slots: { default: true }
          });
        } else $$renderer3.push("<!--[-1-->");
        $$renderer3.push(`<!--]-->`);
      } }
    });
    $$renderer2.push(`<!----></div>`);
    bind_props($$props, {
      history,
      services
    });
  });
}
function _page73($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    const columns = [
      {
        key: "name",
        header: "Service",
        sortable: true
      },
      {
        key: "service_type",
        header: "Type",
        sortable: true
      },
      {
        key: "enabled",
        header: "Status",
        sortable: true
      },
      {
        key: "stats",
        header: "Stats"
      }
    ];
    let showDeleteModal = false;
    let testingServiceId = null;
    const serviceInfo = {
      discord: {
        label: "Discord",
        icon: siDiscord
      },
      ntfy: {
        label: "Ntfy",
        icon: siNtfy
      },
      webhook: {
        label: "Webhook",
        icon: null
      },
      telegram: {
        label: "Telegram",
        icon: siTelegram
      }
    };
    function getServiceTypeName(serviceType) {
      return serviceInfo[serviceType]?.label ?? serviceType;
    }
    PageMeta($$renderer2, { title: "Notifications" });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8"><div class="mb-8"><div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"><div><h1 class="text-2xl font-bold text-neutral-900 md:text-3xl dark:text-neutral-50">Notifications</h1> <p class="mt-2 text-base text-neutral-600 md:mt-3 md:text-lg dark:text-neutral-400">Manage notification services and delivery settings</p></div> <div data-onboarding="notifications-add">`);
    Button($$renderer2, {
      href: "/settings/notifications/new",
      icon: Plus,
      iconColor: "text-blue-600 dark:text-blue-400",
      text: "Add Service",
      variant: "secondary"
    });
    $$renderer2.push(`<!----></div></div></div> <div data-onboarding="notifications-table">`);
    Table2($$renderer2, {
      columns,
      data: data.services,
      emptyMessage: "No notification services configured. Click 'Add Service' to get started.",
      compact: true,
      responsive: true,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "name") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="font-medium">${escape_html(row.name)}</span>`);
          } else if (column.key === "service_type") {
            $$renderer3.push("<!--[1-->");
            $$renderer3.push(`<div class="flex items-center gap-2">`);
            if (serviceInfo[row.service_type]?.icon) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<svg role="img" viewBox="0 0 24 24" class="h-4 w-4 text-neutral-600 dark:text-neutral-400" fill="currentColor"><path${attr("d", serviceInfo[row.service_type].icon.path)}></path></svg>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              Rss($$renderer3, {
                size: 16,
                class: "text-neutral-600 dark:text-neutral-400"
              });
            }
            $$renderer3.push(`<!--]--> <span>${escape_html(getServiceTypeName(row.service_type))}</span></div>`);
          } else if (column.key === "enabled") {
            $$renderer3.push("<!--[2-->");
            Badge($$renderer3, {
              variant: row.enabled ? "success" : "neutral",
              icon: row.enabled ? Bell : Bell_off,
              children: ($$renderer4) => {
                $$renderer4.push(`<!---->${escape_html(row.enabled ? "Enabled" : "Disabled")}`);
              },
              $$slots: { default: true }
            });
          } else if (column.key === "stats") {
            $$renderer3.push("<!--[3-->");
            if (row.successCount + row.failedCount > 0) {
              $$renderer3.push("<!--[0-->");
              $$renderer3.push(`<span class="text-xs"><span class="text-green-600 dark:text-green-400">${escape_html(row.successCount)}</span> / <span class="text-red-600 dark:text-red-400">${escape_html(row.failedCount)}</span></span>`);
            } else {
              $$renderer3.push("<!--[-1-->");
              $$renderer3.push(`<span class="text-neutral-400 dark:text-neutral-500">-</span>`);
            }
            $$renderer3.push(`<!--]-->`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        actions: ($$renderer3, { row }) => {
          $$renderer3.push(`<div class="flex items-center gap-1"><form method="POST" action="?/testNotification"><input type="hidden" name="id"${attr("value", row.id)}/> `);
          Button($$renderer3, {
            icon: Send,
            iconColor: "text-accent-600 dark:text-accent-400",
            size: "xs",
            type: "submit",
            disabled: testingServiceId === row.id,
            loading: testingServiceId === row.id,
            tooltip: "Send test notification"
          });
          $$renderer3.push(`<!----></form> `);
          Button($$renderer3, {
            icon: Pencil,
            size: "xs",
            href: `/settings/notifications/edit/${stringify(row.id)}`,
            tooltip: "Edit service"
          });
          $$renderer3.push(`<!----> <form method="POST" action="?/delete"><input type="hidden" name="id"${attr("value", row.id)}/> `);
          Button($$renderer3, {
            icon: Trash_2,
            iconColor: "text-red-600 dark:text-red-400",
            size: "xs",
            tooltip: "Delete service"
          });
          $$renderer3.push(`<!----></form></div>`);
        }
      }
    });
    $$renderer2.push(`<!----></div> <div class="mt-8" data-onboarding="notifications-history">`);
    NotificationHistory($$renderer2, {
      history: data.history,
      services: data.services
    });
    $$renderer2.push(`<!----></div></div> `);
    Modal($$renderer2, {
      open: showDeleteModal,
      header: "Delete Service",
      bodyMessage: `Are you sure you want to delete this notification service? This action cannot be undone.`,
      confirmText: "Delete Service",
      cancelText: "Cancel",
      confirmDanger: true
    });
    $$renderer2.push(`<!---->`);
    bind_props($$props, { data });
  });
}
var init_page_svelte73 = __esm({
  "dist/build/server/entries/pages/settings/notifications/_page.svelte.js"() {
    "use strict";
    init_server();
    init_dates();
    init_Icon();
    init_bell();
    init_circle_check_big();
    init_circle_x();
    init_Button();
    init_pencil();
    init_plus();
    init_rss();
    init_send();
    init_trash_2();
    init_store2();
    init_Modal();
    init_forms();
    init_Badge();
    init_PageMeta();
    init_Table();
    init_simple_icons();
  }
});

// dist/build/server/nodes/83.js
var __exports84 = {};
__export(__exports84, {
  component: () => component80,
  fonts: () => fonts84,
  imports: () => imports84,
  index: () => index84,
  server: () => page_server_ts_exports74,
  server_id: () => server_id80,
  stylesheets: () => stylesheets84
});
var index84, component_cache80, component80, server_id80, imports84, stylesheets84, fonts84;
var init__84 = __esm({
  async "dist/build/server/nodes/83.js"() {
    "use strict";
    await init_page_server_ts74();
    index84 = 83;
    component80 = async () => component_cache80 ??= (await Promise.resolve().then(() => (init_page_svelte73(), page_svelte_exports73))).default;
    server_id80 = "src/routes/settings/notifications/+page.server.ts";
    imports84 = ["_app/immutable/nodes/83.BfMEsPAN.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/hatDe6ao.js", "_app/immutable/chunks/BGa_v0Jt2.js", "_app/immutable/chunks/CQskZlkd2.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/B_FOzVLA.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/WF6iu-kq.js", "_app/immutable/chunks/R82tBOWO.js", "_app/immutable/chunks/B634VwR8.js", "_app/immutable/chunks/7yuvYLu22.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/CSUcPJXH.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js"];
    stylesheets84 = ["_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts84 = [];
  }
});

// dist/build/server/chunks/types2.js
function groupNotificationTypesByCategory() {
  return notificationTypes.reduce((acc, type) => {
    if (!acc[type.category]) acc[type.category] = [];
    acc[type.category].push(type);
    return acc;
  }, {});
}
function getAllNotificationTypeIds() {
  return notificationTypes.map((type) => type.id);
}
var notificationTypes;
var init_types2 = __esm({
  "dist/build/server/chunks/types2.js"() {
    "use strict";
    notificationTypes = [
      {
        id: "backup.success",
        label: "Backup Completed (Success)",
        category: "Backups",
        description: "Notification when a backup is created successfully"
      },
      {
        id: "backup.failed",
        label: "Backup Failed",
        category: "Backups",
        description: "Notification when backup creation fails"
      },
      {
        id: "pcd.linked",
        label: "Database Linked",
        category: "Databases",
        description: "Notification when a new database is linked"
      },
      {
        id: "pcd.unlinked",
        label: "Database Unlinked",
        category: "Databases",
        description: "Notification when a database is removed"
      },
      {
        id: "pcd.updates_available",
        label: "Database Updates Available",
        category: "Databases",
        description: "Notification when database updates are available but auto-pull is disabled"
      },
      {
        id: "pcd.sync_success",
        label: "Database Synced (Success)",
        category: "Databases",
        description: "Notification when a database is synced successfully"
      },
      {
        id: "pcd.sync_failed",
        label: "Database Sync (Failed)",
        category: "Databases",
        description: "Notification when database sync fails"
      },
      {
        id: "pcd.link_failed",
        label: "Database Link (Failed)",
        category: "Databases",
        description: "Notification when linking a new database fails"
      },
      {
        id: "arr.sync.success",
        label: "Arr Sync Completed (Success)",
        category: "Arr Sync",
        description: "Notification when all sections sync successfully to an Arr instance"
      },
      {
        id: "arr.sync.partial",
        label: "Arr Sync Completed (Partial)",
        category: "Arr Sync",
        description: "Notification when some sections fail to sync to an Arr instance"
      },
      {
        id: "arr.sync.failed",
        label: "Arr Sync Failed",
        category: "Arr Sync",
        description: "Notification when all sections fail to sync to an Arr instance"
      },
      {
        id: "arr.cleanup.success",
        label: "Arr Cleanup Completed (Success)",
        category: "Arr Cleanup",
        description: "Notification when stale configs and removed entities are all cleaned up successfully"
      },
      {
        id: "arr.cleanup.partial",
        label: "Arr Cleanup Completed (Partial)",
        category: "Arr Cleanup",
        description: "Notification when some items could not be deleted (skipped quality profiles or failed entity deletions)"
      },
      {
        id: "arr.cleanup.failed",
        label: "Arr Cleanup Failed",
        category: "Arr Cleanup",
        description: "Notification when cleanup cannot complete or no items could be deleted"
      },
      {
        id: "arr.drift.detected",
        label: "Arr Drift Detected",
        category: "Arr Drift",
        description: "Notification when drift is detected on an Arr instance"
      },
      {
        id: "arr.drift.failed",
        label: "Arr Drift Failed",
        category: "Arr Drift",
        description: "Notification when an Arr drift check fails"
      },
      {
        id: "upgrade.success",
        label: "Upgrade Completed (Success)",
        category: "Upgrades",
        description: "Notification when all upgrade searches complete successfully"
      },
      {
        id: "upgrade.partial",
        label: "Upgrade Completed (Partial)",
        category: "Upgrades",
        description: "Notification when some upgrade searches succeed and some fail"
      },
      {
        id: "upgrade.failed",
        label: "Upgrade Failed",
        category: "Upgrades",
        description: "Notification when all upgrade searches fail"
      },
      {
        id: "rename.success",
        label: "Rename Completed (Success)",
        category: "Renames",
        description: "Notification when all file renames complete successfully"
      },
      {
        id: "rename.partial",
        label: "Rename Completed (Partial)",
        category: "Renames",
        description: "Notification when some file renames succeed and some fail"
      },
      {
        id: "rename.failed",
        label: "Rename Failed",
        category: "Renames",
        description: "Notification when all file renames fail"
      },
      {
        id: "announcement.new",
        label: "New Announcement",
        category: "Announcements",
        description: "Notification when a new announcement is published by the Profilarr team and has not yet been read"
      }
    ];
  }
});

// dist/build/server/entries/pages/settings/notifications/edit/_id_/_page.server.ts.js
var page_server_ts_exports75 = {};
__export(page_server_ts_exports75, {
  actions: () => actions49,
  load: () => load78
});
var load78, actions49;
var init_page_server_ts75 = __esm({
  async "dist/build/server/entries/pages/settings/notifications/edit/_id_/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_notificationServices();
    init_types2();
    init_exports();
    load78 = ({ params }) => {
      const { id } = params;
      if (!id) throw error(400, "Service ID is required");
      const service = notificationServicesQueries.getById(id);
      if (!service) throw error(404, "Notification service not found");
      const config2 = JSON.parse(service.config);
      const enabledTypes = JSON.parse(service.enabled_types);
      const { webhook_url: _webhookUrl, access_token: _accessToken, auth_header: _authHeader, bot_token: _botToken, ...safeConfig } = config2;
      return { service: {
        id: service.id,
        name: service.name,
        serviceType: service.service_type,
        enabled: service.enabled === 1,
        config: safeConfig,
        enabledTypes
      } };
    };
    actions49 = { edit: async ({ request, params }) => {
      const { id } = params;
      if (!id) return fail(400, { error: "Service ID is required" });
      const service = notificationServicesQueries.getById(id);
      if (!service) return fail(404, { error: "Service not found" });
      const formData = await request.formData();
      const name = formData.get("name");
      if (!name) return fail(400, { error: "Service name is required" });
      if (notificationServicesQueries.getAll().find((s3) => s3.name === name && s3.id !== id)) return fail(400, { error: "A service with this name already exists" });
      let config2 = {};
      let enabledTypes = [];
      const existingConfig = JSON.parse(service.config);
      if (service.service_type === "discord") {
        const webhookUrl = formData.get("webhook_url");
        const username = formData.get("username");
        const avatarUrl = formData.get("avatar_url");
        const enableMentions = formData.get("enable_mentions") === "on";
        config2 = {
          webhook_url: webhookUrl || existingConfig.webhook_url,
          ...username && { username },
          ...avatarUrl && { avatar_url: avatarUrl },
          enable_mentions: enableMentions
        };
      } else if (service.service_type === "ntfy") {
        const serverUrl = formData.get("server_url");
        const topic = formData.get("topic");
        const accessToken = formData.get("access_token");
        if (!serverUrl || !topic) return fail(400, { error: "Server URL and topic are required for Ntfy" });
        config2 = {
          server_url: serverUrl,
          topic,
          ...accessToken ? { access_token: accessToken } : existingConfig.access_token ? { access_token: existingConfig.access_token } : {}
        };
      } else if (service.service_type === "webhook") {
        const webhookUrl = formData.get("webhook_url");
        const authHeader = formData.get("auth_header");
        config2 = {
          webhook_url: webhookUrl || existingConfig.webhook_url,
          ...authHeader ? { auth_header: authHeader } : existingConfig.auth_header ? { auth_header: existingConfig.auth_header } : {}
        };
      } else if (service.service_type === "telegram") {
        const botToken = formData.get("bot_token");
        const chatId = formData.get("chat_id");
        if (!chatId) return fail(400, { error: "Chat ID is required for Telegram" });
        config2 = {
          bot_token: botToken || existingConfig.bot_token,
          chat_id: chatId
        };
      }
      enabledTypes = getAllNotificationTypeIds().filter((typeId) => formData.get(typeId) === "on");
      if (!notificationServicesQueries.update(id, {
        name,
        config: config2,
        enabledTypes
      })) return fail(500, { error: "Failed to update notification service" });
      await logger.info("Notification service updated", {
        source: "settings/notifications/edit",
        meta: {
          serviceId: id,
          serviceType: service.service_type,
          name
        }
      });
      throw redirect(303, "/settings/notifications");
    } };
  }
});

// dist/build/server/chunks/NotificationServiceForm.js
function List_checks($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "list-checks" },
    props,
    { iconNode: [
      ["path", { "d": "M13 5h8" }],
      ["path", { "d": "M13 12h8" }],
      ["path", { "d": "M13 19h8" }],
      ["path", { "d": "m3 17 2 2 4-4" }],
      ["path", { "d": "m3 7 2 2 4-4" }]
    ] }
  ]));
}
function DiscordConfiguration($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let config2 = fallback($$props["config"], () => ({}), true);
    let mode = fallback($$props["mode"], "create");
    let webhookUrl = config2.webhook_url || "";
    let username = config2.username || "";
    let avatarUrl = config2.avatar_url || "";
    let enableMentions = config2.enable_mentions || false;
    $$renderer2.push(`<div class="space-y-4"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">Discord Configuration</h3> `);
    FormInput($$renderer2, {
      label: "Webhook URL",
      name: "webhook_url",
      type: "url",
      value: webhookUrl,
      placeholder: mode === "edit" ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : "https://discord.com/api/webhooks/...",
      description: mode === "edit" ? "Leave blank to keep existing webhook URL" : "Get this from Server Settings \u2192 Integrations \u2192 Webhooks in Discord",
      required: mode === "create",
      private_: true
    });
    $$renderer2.push(`<!----> `);
    FormInput($$renderer2, {
      label: "Bot Username",
      name: "username",
      value: username,
      placeholder: "Profilarr",
      description: "Custom username for the webhook bot (optional)"
    });
    $$renderer2.push(`<!----> `);
    FormInput($$renderer2, {
      label: "Avatar URL",
      name: "avatar_url",
      type: "url",
      value: avatarUrl,
      placeholder: "https://example.com/avatar.png",
      description: "Custom avatar image for the webhook bot (optional)"
    });
    $$renderer2.push(`<!----> <div>`);
    Toggle($$renderer2, {
      label: "Enable @here mentions",
      checked: enableMentions
    });
    $$renderer2.push(`<!----> <input type="hidden" name="enable_mentions"${attr("value", enableMentions ? "on" : "")}/> <p class="mt-1 px-3 text-xs text-neutral-500 dark:text-neutral-400">Mention @here in notifications to alert online users</p></div></div>`);
    bind_props($$props, {
      config: config2,
      mode
    });
  });
}
function NtfyConfiguration($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let config2 = fallback($$props["config"], () => ({}), true);
    let mode = fallback($$props["mode"], "create");
    let serverUrl = config2.server_url || "https://ntfy.sh";
    let topic = config2.topic || "";
    let accessToken = config2.access_token || "";
    $$renderer2.push(`<div class="space-y-4"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">Ntfy Configuration</h3> `);
    FormInput($$renderer2, {
      label: "Server URL",
      name: "server_url",
      type: "url",
      value: serverUrl,
      placeholder: "https://ntfy.sh",
      description: "The ntfy server URL. Use https://ntfy.sh for the public instance or your self-hosted URL",
      required: true
    });
    $$renderer2.push(`<!----> `);
    FormInput($$renderer2, {
      label: "Topic",
      name: "topic",
      value: topic,
      placeholder: "profilarr",
      description: "The ntfy topic to publish notifications to",
      required: true
    });
    $$renderer2.push(`<!----> `);
    FormInput($$renderer2, {
      label: "Access Token",
      name: "access_token",
      value: accessToken,
      placeholder: mode === "edit" ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : "tk_...",
      description: mode === "edit" ? "Leave blank to keep existing token" : "Required if your ntfy server has access control enabled. Generate a token via your server's admin interface or ntfy token add",
      private_: true
    });
    $$renderer2.push(`<!----></div>`);
    bind_props($$props, {
      config: config2,
      mode
    });
  });
}
function WebhookConfiguration($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let config2 = fallback($$props["config"], () => ({}), true);
    let mode = fallback($$props["mode"], "create");
    let webhookUrl = config2.webhook_url || "";
    let authHeader = config2.auth_header || "";
    $$renderer2.push(`<div class="space-y-4"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">Webhook Configuration</h3> `);
    FormInput($$renderer2, {
      label: "Webhook URL",
      name: "webhook_url",
      type: "url",
      value: webhookUrl,
      placeholder: mode === "edit" ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : "https://example.com/webhook",
      description: mode === "edit" ? "Leave blank to keep existing URL" : "The URL to POST notification JSON to",
      required: mode === "create",
      private_: true
    });
    $$renderer2.push(`<!----> `);
    FormInput($$renderer2, {
      label: "Authorization Header",
      name: "auth_header",
      value: authHeader,
      placeholder: mode === "edit" ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : "Bearer your-token",
      description: mode === "edit" ? "Leave blank to keep existing value" : "Raw value for the Authorization header (e.g., Bearer token, Basic base64). Optional",
      private_: true
    });
    $$renderer2.push(`<!----></div>`);
    bind_props($$props, {
      config: config2,
      mode
    });
  });
}
function TelegramConfiguration($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let config2 = fallback($$props["config"], () => ({}), true);
    let mode = fallback($$props["mode"], "create");
    let botToken = config2.bot_token || "";
    let chatId = config2.chat_id || "";
    $$renderer2.push(`<div class="space-y-4"><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">Telegram Configuration</h3> `);
    FormInput($$renderer2, {
      label: "Bot Token",
      name: "bot_token",
      value: botToken,
      placeholder: mode === "edit" ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : "123456789:ABCdefGHI...",
      description: mode === "edit" ? "Leave blank to keep existing token" : "Create a bot via @BotFather on Telegram to get a token",
      private_: true
    });
    $$renderer2.push(`<!----> `);
    FormInput($$renderer2, {
      label: "Chat ID",
      name: "chat_id",
      value: chatId,
      placeholder: "e.g., 123456789",
      description: "Your user or group chat ID. Message @userinfobot on Telegram to find yours",
      required: true
    });
    $$renderer2.push(`<!----></div>`);
    bind_props($$props, {
      config: config2,
      mode
    });
  });
}
function NotificationServiceForm($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let title, description, submitText;
    let mode = fallback($$props["mode"], "create");
    let initialData = fallback($$props["initialData"], () => ({}), true);
    let selectedType = initialData.serviceType || "discord";
    let serviceName = initialData.name || "";
    const groupedTypes = groupNotificationTypesByCategory();
    let enabledTypesState = {};
    const categoryRows = Object.entries(groupedTypes).map(([category, types]) => ({
      category,
      types
    }));
    const typeColumns = [{
      key: "category",
      header: "Category"
    }];
    let expandedCategories = new Set(categoryRows.map((r2) => r2.category));
    const typeOptions = [
      {
        value: "discord",
        label: "Discord",
        icon: siDiscord
      },
      {
        value: "ntfy",
        label: "Ntfy",
        icon: siNtfy
      },
      {
        value: "webhook",
        label: "Webhook",
        icon: Rss
      },
      {
        value: "telegram",
        label: "Telegram",
        icon: siTelegram
      }
    ];
    $: for (const [, types] of Object.entries(groupedTypes)) for (const type of types) if (enabledTypesState[type.id] === void 0) enabledTypesState[type.id] = initialData.enabledTypes?.includes(type.id) || false;
    $: title = mode === "create" ? "New Notification Service" : "Edit Notification Service";
    $: description = mode === "create" ? "Configure a new notification service" : "Update notification service configuration";
    $: submitText = mode === "create" ? "Create Service" : "Save Changes";
    $$renderer2.push(`<form method="POST"${attr("action", `?/${stringify(mode)}`)} class="space-y-6">`);
    StickyCard($$renderer2, {
      position: "top",
      breadcrumbItems: [{
        label: "Notifications",
        href: "/settings/notifications"
      }],
      breadcrumbCurrent: mode === "edit" ? initialData.name ?? "Edit" : "New",
      $$slots: {
        left: ($$renderer3) => {
          $$renderer3.push(`<div><h2 class="text-lg font-semibold text-neutral-900 dark:text-neutral-50">${escape_html(title)}</h2> <p class="text-sm text-neutral-600 dark:text-neutral-400">${escape_html(description)}</p></div>`);
        },
        right: ($$renderer3) => {
          $$renderer3.push(`<div class="flex items-center gap-2">`);
          Button($$renderer3, {
            text: "Cancel",
            variant: "secondary",
            href: "/settings/notifications"
          });
          $$renderer3.push(`<!----> `);
          Button($$renderer3, {
            text: submitText,
            icon: mode === "create" ? Plus : Save,
            iconColor: "text-blue-600 dark:text-blue-400",
            disabled: !serviceName,
            type: "submit"
          });
          $$renderer3.push(`<!----></div>`);
        }
      }
    });
    $$renderer2.push(`<!----> <input type="hidden" name="type"${attr("value", selectedType)}/> <input type="hidden" name="name"${attr("value", serviceName)}/> <div class="space-y-6 md:px-4"><div class="grid grid-cols-8 gap-4"><div class="col-span-2 space-y-2"><span class="block text-sm font-semibold text-neutral-900 dark:text-neutral-100">Service Type</span> <p class="text-xs text-neutral-500 dark:text-neutral-400">`);
    if (mode === "edit") {
      $$renderer2.push("<!--[0-->");
      $$renderer2.push(`Type cannot be changed after creation`);
    } else {
      $$renderer2.push("<!--[-1-->");
      $$renderer2.push(`The platform to send notifications to`);
    }
    $$renderer2.push(`<!--]--></p> `);
    DropdownSelect($$renderer2, {
      value: selectedType,
      options: typeOptions,
      disabled: mode === "edit",
      fullWidth: true
    });
    $$renderer2.push(`<!----></div> <div class="col-span-6">`);
    FormInput($$renderer2, {
      label: "Service Name",
      name: "service_name",
      value: serviceName,
      placeholder: selectedType === "ntfy" ? "e.g., Phone Alerts" : selectedType === "webhook" ? "e.g., Home Assistant" : selectedType === "telegram" ? "e.g., Personal Bot" : "e.g., Main Discord Server",
      description: "A friendly name to identify this notification service",
      required: true
    });
    $$renderer2.push(`<!----></div></div> `);
    if (selectedType === "discord") {
      $$renderer2.push("<!--[0-->");
      DiscordConfiguration($$renderer2, {
        config: initialData.config,
        mode
      });
    } else if (selectedType === "ntfy") {
      $$renderer2.push("<!--[1-->");
      NtfyConfiguration($$renderer2, {
        config: initialData.config,
        mode
      });
    } else if (selectedType === "webhook") {
      $$renderer2.push("<!--[2-->");
      WebhookConfiguration($$renderer2, {
        config: initialData.config,
        mode
      });
    } else if (selectedType === "telegram") {
      $$renderer2.push("<!--[3-->");
      TelegramConfiguration($$renderer2, {
        config: initialData.config,
        mode
      });
    } else $$renderer2.push("<!--[-1-->");
    $$renderer2.push(`<!--]--> <div class="space-y-4"><div class="flex items-start justify-between"><div><h3 class="text-sm font-semibold text-neutral-900 dark:text-neutral-100">Notification Types</h3> <p class="mt-1 text-xs text-neutral-500 dark:text-neutral-400">Select which types of notifications should be sent to this service</p></div> <div class="flex items-center gap-1">`);
    Button($$renderer2, {
      text: "All",
      icon: List_checks,
      iconColor: "text-blue-500 dark:text-blue-400",
      size: "sm",
      variant: "secondary"
    });
    $$renderer2.push(`<!----> `);
    Button($$renderer2, {
      text: "Success",
      icon: Circle_check_big,
      iconColor: "text-green-500 dark:text-green-400",
      size: "sm",
      variant: "secondary"
    });
    $$renderer2.push(`<!----> `);
    Button($$renderer2, {
      text: "Failed",
      icon: Circle_x,
      iconColor: "text-red-500 dark:text-red-400",
      size: "sm",
      variant: "secondary"
    });
    $$renderer2.push(`<!----></div></div> `);
    ExpandableTable($$renderer2, {
      columns: typeColumns,
      data: categoryRows,
      getRowId: (row) => row.category,
      expandedRows: expandedCategories,
      chevronPosition: "right",
      flushExpanded: true,
      compact: true,
      $$slots: {
        cell: ($$renderer3, { row, column }) => {
          if (column.key === "category") {
            $$renderer3.push("<!--[0-->");
            $$renderer3.push(`<span class="text-xs font-semibold tracking-wide text-neutral-500 uppercase dark:text-neutral-400">${escape_html(row.category)}</span>`);
          } else $$renderer3.push("<!--[-1-->");
          $$renderer3.push(`<!--]-->`);
        },
        expanded: ($$renderer3, { row }) => {
          {
            $$renderer3.push(`<div class="grid gap-2 px-4 py-3" style="grid-template-columns: repeat(5, 1fr);"><!--[-->`);
            const each_array = ensure_array_like(row.types);
            for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
              let type = each_array[$$index];
              $$renderer3.push(`<div>`);
              Toggle($$renderer3, {
                label: type.label,
                checked: enabledTypesState[type.id],
                fullWidth: true
              });
              $$renderer3.push(`<!----> <input type="hidden"${attr("name", type.id)}${attr("value", enabledTypesState[type.id] ? "on" : "")}/></div>`);
            }
            $$renderer3.push(`<!--]--></div>`);
          }
        }
      }
    });
    $$renderer2.push(`<!----></div></div></form>`);
    bind_props($$props, {
      mode,
      initialData
    });
  });
}
var init_NotificationServiceForm = __esm({
  "dist/build/server/chunks/NotificationServiceForm.js"() {
    "use strict";
    init_server();
    init_Icon();
    init_circle_check_big();
    init_circle_x();
    init_Button();
    init_plus();
    init_rss();
    init_save();
    init_store2();
    init_forms();
    init_ExpandableTable();
    init_StickyCard();
    init_DropdownSelect();
    init_FormInput();
    init_Toggle();
    init_types2();
    init_simple_icons();
  }
});

// dist/build/server/entries/pages/settings/notifications/edit/_id_/_page.svelte.js
var page_svelte_exports74 = {};
__export(page_svelte_exports74, {
  default: () => _page74
});
function _page74($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    let data = $$props["data"];
    PageMeta($$renderer2, { title: `${data.service.name} \xB7 Edit` });
    $$renderer2.push(`<!----> <div class="p-4 md:p-8">`);
    NotificationServiceForm($$renderer2, {
      mode: "edit",
      initialData: {
        name: data.service.name,
        serviceType: data.service.serviceType,
        config: data.service.config,
        enabledTypes: data.service.enabledTypes
      }
    });
    $$renderer2.push(`<!----></div>`);
    bind_props($$props, { data });
  });
}
var init_page_svelte74 = __esm({
  "dist/build/server/entries/pages/settings/notifications/edit/_id_/_page.svelte.js"() {
    "use strict";
    init_server();
    init_NotificationServiceForm();
    init_PageMeta();
  }
});

// dist/build/server/nodes/84.js
var __exports85 = {};
__export(__exports85, {
  component: () => component81,
  fonts: () => fonts85,
  imports: () => imports85,
  index: () => index85,
  server: () => page_server_ts_exports75,
  server_id: () => server_id81,
  stylesheets: () => stylesheets85
});
var index85, component_cache81, component81, server_id81, imports85, stylesheets85, fonts85;
var init__85 = __esm({
  async "dist/build/server/nodes/84.js"() {
    "use strict";
    await init_page_server_ts75();
    index85 = 84;
    component81 = async () => component_cache81 ??= (await Promise.resolve().then(() => (init_page_svelte74(), page_svelte_exports74))).default;
    server_id81 = "src/routes/settings/notifications/edit/[id]/+page.server.ts";
    imports85 = ["_app/immutable/nodes/84.CZ0qnPKk.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/Bzj4N0Au.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BGa_v0Jt2.js", "_app/immutable/chunks/CQskZlkd2.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/WF6iu-kq.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets85 = [];
    fonts85 = [];
  }
});

// dist/build/server/entries/pages/settings/notifications/new/_page.server.ts.js
var page_server_ts_exports76 = {};
__export(page_server_ts_exports76, {
  actions: () => actions50
});
var actions50;
var init_page_server_ts76 = __esm({
  async "dist/build/server/entries/pages/settings/notifications/new/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_notificationServices();
    init_types2();
    init_exports();
    actions50 = { create: async ({ request }) => {
      const formData = await request.formData();
      const serviceType = formData.get("type");
      const name = formData.get("name");
      if (!serviceType || !name) return fail(400, { error: "Service type and name are required" });
      if (notificationServicesQueries.existsByName(name)) return fail(400, { error: "A service with this name already exists" });
      let config2 = {};
      let enabledTypes = [];
      if (serviceType === "discord") {
        const webhookUrl = formData.get("webhook_url");
        const username = formData.get("username");
        const avatarUrl = formData.get("avatar_url");
        const enableMentions = formData.get("enable_mentions") === "on";
        if (!webhookUrl) return fail(400, { error: "Webhook URL is required for Discord" });
        config2 = {
          webhook_url: webhookUrl,
          ...username && { username },
          ...avatarUrl && { avatar_url: avatarUrl },
          enable_mentions: enableMentions
        };
      } else if (serviceType === "ntfy") {
        const serverUrl = formData.get("server_url");
        const topic = formData.get("topic");
        const accessToken = formData.get("access_token");
        if (!serverUrl || !topic) return fail(400, { error: "Server URL and topic are required for Ntfy" });
        config2 = {
          server_url: serverUrl,
          topic,
          ...accessToken && { access_token: accessToken }
        };
      } else if (serviceType === "webhook") {
        const webhookUrl = formData.get("webhook_url");
        const authHeader = formData.get("auth_header");
        if (!webhookUrl) return fail(400, { error: "Webhook URL is required" });
        config2 = {
          webhook_url: webhookUrl,
          ...authHeader && { auth_header: authHeader }
        };
      } else if (serviceType === "telegram") {
        const botToken = formData.get("bot_token");
        const chatId = formData.get("chat_id");
        if (!botToken || !chatId) return fail(400, { error: "Bot token and chat ID are required for Telegram" });
        config2 = {
          bot_token: botToken,
          chat_id: chatId
        };
      }
      enabledTypes = getAllNotificationTypeIds().filter((typeId) => formData.get(typeId) === "on");
      const id = crypto.randomUUID();
      if (!notificationServicesQueries.create({
        id,
        name,
        serviceType,
        enabled: true,
        config: config2,
        enabledTypes
      })) return fail(500, { error: "Failed to create notification service" });
      await logger.info("Notification service created", {
        source: "settings/notifications/new",
        meta: {
          serviceId: id,
          serviceType,
          name
        }
      });
      throw redirect(303, "/settings/notifications");
    } };
  }
});

// dist/build/server/entries/pages/settings/notifications/new/_page.svelte.js
var page_svelte_exports75 = {};
__export(page_svelte_exports75, {
  default: () => _page75
});
function _page75($$renderer) {
  PageMeta($$renderer, { title: "Notification Service \xB7 New" });
  $$renderer.push(`<!----> <div class="p-4 md:p-8">`);
  NotificationServiceForm($$renderer, { mode: "create" });
  $$renderer.push(`<!----></div>`);
}
var init_page_svelte75 = __esm({
  "dist/build/server/entries/pages/settings/notifications/new/_page.svelte.js"() {
    "use strict";
    init_server();
    init_NotificationServiceForm();
    init_PageMeta();
  }
});

// dist/build/server/nodes/85.js
var __exports86 = {};
__export(__exports86, {
  component: () => component82,
  fonts: () => fonts86,
  imports: () => imports86,
  index: () => index86,
  server: () => page_server_ts_exports76,
  server_id: () => server_id82,
  stylesheets: () => stylesheets86
});
var index86, component_cache82, component82, server_id82, imports86, stylesheets86, fonts86;
var init__86 = __esm({
  async "dist/build/server/nodes/85.js"() {
    "use strict";
    await init_page_server_ts76();
    index86 = 85;
    component82 = async () => component_cache82 ??= (await Promise.resolve().then(() => (init_page_svelte75(), page_svelte_exports75))).default;
    server_id82 = "src/routes/settings/notifications/new/+page.server.ts";
    imports86 = ["_app/immutable/nodes/85.jdQLomht.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/Bzj4N0Au.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BGa_v0Jt2.js", "_app/immutable/chunks/CQskZlkd2.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/Aq-7zSc_.js", "_app/immutable/chunks/WF6iu-kq.js", "_app/immutable/chunks/Cm59NaPk.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/CeT8iFb4.js", "_app/immutable/chunks/BV_dpPls.js", "_app/immutable/chunks/BPl_Mdu8.js", "_app/immutable/chunks/_ZYKMtmp.js", "_app/immutable/chunks/CBnPEgB1.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/D85sx3Na.js", "_app/immutable/chunks/DKiI-c2_2.js", "_app/immutable/chunks/DBUl7-VL.js", "_app/immutable/chunks/B6VnVRhH.js", "_app/immutable/chunks/ELQnUoYO.js", "_app/immutable/chunks/B_SLuu8u2.js", "_app/immutable/chunks/C3FImjIr2.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/DCohNkHF.js"];
    stylesheets86 = [];
    fonts86 = [];
  }
});

// dist/build/server/entries/pages/settings/security/_page.server.ts.js
var page_server_ts_exports77 = {};
__export(page_server_ts_exports77, {
  actions: () => actions51,
  load: () => load79
});
var load79, actions51;
var init_page_server_ts77 = __esm({
  async "dist/build/server/entries/pages/settings/security/_page.server.ts.js"() {
    "use strict";
    await init_db();
    await init_users();
    await init_authSettings();
    await init_password();
    init_exports();
    load79 = async ({ cookies }) => {
      const currentSessionId = cookies.get("session");
      const user = usersQueries.getByUsername("admin") ?? usersQueries.getById(1);
      if (!user) return {
        sessions: [],
        hasApiKey: false,
        canRegenerateApiKey: true,
        currentSessionId: null,
        localBypassEnabled: false
      };
      const sessions = sessionsQueries.getByUserId(user.id);
      const hasApiKey = authSettingsQueries.hasApiKey();
      const canRegenerateApiKey = authSettingsQueries.canRegenerateApiKey();
      const localBypassEnabled = authSettingsQueries.isLocalBypassEnabled();
      return {
        sessions: sessions.map((s3) => ({
          id: s3.id,
          created_at: s3.created_at,
          expires_at: s3.expires_at,
          last_active_at: s3.last_active_at,
          ip_address: s3.ip_address,
          browser: s3.browser,
          os: s3.os,
          device_type: s3.device_type,
          isCurrent: s3.id === currentSessionId
        })),
        hasApiKey,
        canRegenerateApiKey,
        currentSessionId,
        localBypassEnabled
      };
    };
    actions51 = {
      changePassword: async ({ request, cookies }) => {
        const formData = await request.formData();
        const currentPassword = formData.get("currentPassword");
        const newPassword = formData.get("newPassword");
        const confirmPassword = formData.get("confirmPassword");
        if (!currentPassword || !newPassword || !confirmPassword) return fail(400, { passwordError: "All fields are required" });
        if (newPassword.length < 8) return fail(400, { passwordError: "New password must be at least 8 characters" });
        if (newPassword !== confirmPassword) return fail(400, { passwordError: "Passwords do not match" });
        const sessionId = cookies.get("session");
        if (!sessionId) return fail(401, { passwordError: "Not authenticated" });
        const session = sessionsQueries.getValidById(sessionId);
        if (!session) return fail(401, { passwordError: "Invalid session" });
        const user = usersQueries.getById(session.user_id);
        if (!user) return fail(401, { passwordError: "User not found" });
        if (!await verifyPassword(currentPassword, user.password_hash)) return fail(400, { passwordError: "Current password is incorrect" });
        const newHash = await hashPassword(newPassword);
        usersQueries.updatePassword(user.id, newHash);
        await logger.info(`Password changed for '${user.username}'`, {
          source: "Auth",
          meta: {
            userId: user.id,
            username: user.username
          }
        });
        return { passwordSuccess: true };
      },
      regenerateApiKey: async () => {
        if (!authSettingsQueries.canRegenerateApiKey()) return fail(400, { apiKeyError: "API key is managed by PROFILARR_API_KEY and cannot be regenerated" });
        const newKey = await authSettingsQueries.regenerateApiKey();
        await logger.info("API key regenerated", { source: "Auth:APIKey" });
        return {
          apiKey: newKey,
          apiKeyRegenerated: true
        };
      },
      revokeSession: async ({ request, cookies }) => {
        const sessionId = (await request.formData()).get("sessionId");
        const currentSessionId = cookies.get("session");
        if (!sessionId) return fail(400, { sessionError: "Session ID required" });
        if (sessionId === currentSessionId) return fail(400, { sessionError: "Cannot revoke current session" });
        sessionsQueries.deleteById(sessionId);
        await logger.info("Session revoked", {
          source: "Auth:Session",
          meta: { revokedSessionId: sessionId.slice(0, 8) + "..." }
        });
        return { sessionRevoked: true };
      },
      toggleLocalBypass: async () => {
        const current3 = authSettingsQueries.isLocalBypassEnabled();
        authSettingsQueries.setLocalBypass(!current3);
        const state2 = !current3 ? "enabled" : "disabled";
        await logger.info(`Local bypass ${state2}`, { source: "Auth:Settings" });
        return {
          localBypassToggled: true,
          localBypassEnabled: !current3
        };
      },
      revokeOtherSessions: async ({ cookies }) => {
        const currentSessionId = cookies.get("session");
        if (!currentSessionId) return fail(401, { sessionError: "Not authenticated" });
        const session = sessionsQueries.getValidById(currentSessionId);
        if (!session) return fail(401, { sessionError: "Invalid session" });
        const count = sessionsQueries.deleteOthersByUserId(session.user_id, currentSessionId);
        if (count > 0) await logger.info(`Revoked ${count} other session${count === 1 ? "" : "s"}`, {
          source: "Auth:Session",
          meta: {
            userId: session.user_id,
            count
          }
        });
        return { sessionsRevoked: count };
      }
    };
  }
});

// dist/build/server/entries/pages/settings/security/_page.svelte.js
var page_svelte_exports76 = {};
__export(page_svelte_exports76, {
  default: () => _page76
});
function Globe($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "globe" },
    props,
    { iconNode: [
      ["circle", {
        "cx": "12",
        "cy": "12",
        "r": "10"
      }],
      ["path", { "d": "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" }],
      ["path", { "d": "M2 12h20" }]
    ] }
  ]));
}
function Log_out($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "log-out" },
    props,
    { iconNode: [
      ["path", { "d": "m16 17 5-5-5-5" }],
      ["path", { "d": "M21 12H9" }],
      ["path", { "d": "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" }]
    ] }
  ]));
}
function Monitor($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "monitor" },
    props,
    { iconNode: [
      ["rect", {
        "width": "20",
        "height": "14",
        "x": "2",
        "y": "3",
        "rx": "2"
      }],
      ["line", {
        "x1": "8",
        "x2": "16",
        "y1": "21",
        "y2": "21"
      }],
      ["line", {
        "x1": "12",
        "x2": "12",
        "y1": "17",
        "y2": "21"
      }]
    ] }
  ]));
}
function Network($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "network" },
    props,
    { iconNode: [
      ["rect", {
        "x": "16",
        "y": "16",
        "width": "6",
        "height": "6",
        "rx": "1"
      }],
      ["rect", {
        "x": "2",
        "y": "16",
        "width": "6",
        "height": "6",
        "rx": "1"
      }],
      ["rect", {
        "x": "9",
        "y": "2",
        "width": "6",
        "height": "6",
        "rx": "1"
      }],
      ["path", { "d": "M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3" }],
      ["path", { "d": "M12 12V8" }]
    ] }
  ]));
}
function Smartphone($$renderer, $$props) {
  let { $$slots, $$events, ...props } = $$props;
  Icon($$renderer, spread_props([
    { name: "smartphone" },
    props,
    { iconNode: [["rect", {
      "width": "14",
      "height": "20",
      "x": "5",
      "y": "2",
      "rx": "2",
      "ry": "2"
    }], ["path", { "d": "M12 18h.01" }]] }
  ]));
}
function _page76($$renderer, $$props) {
  $$renderer.component(($$renderer2) => {
    var $$store_subs;
    let apiKey, apiKeyRegenerationDisabled, apiKeyRegenerationTooltip;
    let data = $$props["data"];
    let form = $$props["form"];
    let changingPassword = false;
    let currentPassword = "";
    let newPassword = "";
    let confirmPassword = "";
    let togglingBypass = false;
    function formatRelativeTime(dateStr) {
      if (!dateStr) return "Never";
      const date = parseUTC(dateStr);
      if (!date) return "Unknown";
      const diffMs = (/* @__PURE__ */ new Date()).getTime() - date.getTime();
      const diffSecs = Math.floor(diffMs / 1e3);
      const diffMins = Math.floor(diffSecs / 60);
      const diffHours = Math.floor(diffMins / 60);
      const diffDays = Math.floor(diffHours / 24);
      if (diffSecs < 60) return "Just now";
      if (diffMins < 60) return `${diffMins}m ago`;
      if (diffHours < 24) return `${diffHours}h ago`;
      if (diffDays < 7) return `${diffDays}d ago`;
      return formatDate(dateStr, store_get($$store_subs ??= {}, "$serverTimezone", serverTimezone), store_get($$store_subs ??= {}, "$dateFormat", dateFormat));
    }
    const sessionColumns = [
      {
        key: "browser",
        header: "Browser",
        headerIcon: Globe,
        cell: (row) => row.browser ?? "Unknown"
      },
      {
        key: "os",
        header: "OS",
        headerIcon: Monitor,
        cell: (row) => row.os ?? "Unknown"
      },
      {
        key: "device_type",
        header: "Device",
        headerIcon: Smartphone,
        cell: (row) => row.device_type ?? "Unknown"
      },
      {
        key: "ip_address",
        header: "IP",
        headerIcon: Network,
        cell: (row) => ({ html: `<span class="font-mono text-xs text-neutral-500 dark:text-neutral-400">${row.ip_address ?? "Unknown"}</span>` })
      },
      {
        key: "last_active_at",
        header: "Last Active",
        headerIcon: Clock,
        cell: (row) => ({ html: `<span class="text-xs text-neutral-500 dark:text-neutral-400">${formatRelativeTime(row.last_active_at)}</span>` })
      }
    ];
    $: if (form?.passwordSuccess) {
      alertStore.add("success", "Password changed successfully");
      currentPassword = "";
      newPassword = "";
      confirmPassword = "";
    }
    $: if (form?.passwordError) alertStore.add("error", form.passwordError);
    $: if (form?.apiKeyRegenerated) alertStore.add("success", "API key regenerated");
    $: if (form?.apiKeyError) alertStore.add("error", form.apiKeyError);
    $: if (form?.sessionRevoked) alertStore.add("success", "Session revoked");
    $: if (form?.sessionsRevoked !== void 0) alertStore.add("success", `Revoked ${form.sessionsRevoked} session(s)`);
    $: if (form?.sessionError) alertStore.add("error", form.sessionError);
    $: if (form?.localBypassToggled) alertStore.add("success", `Local bypass ${form.localBypassEnabled ? "enabled" : "disabled"}`);
    $: apiKey = form?.apiKey ?? null;
    $: apiKeyRegenerationDisabled = !data.canRegenerateApiKey;
    $: apiKeyRegenerationTooltip = data.canRegenerateApiKey ? "" : "API key is managed by PROFILARR_API_KEY";
    let $$settled = true;
    let $$inner_renderer;
    function $$render_inner($$renderer3) {
      PageMeta($$renderer3, { title: "Security" });
      $$renderer3.push(`<!----> <div class="p-4 md:p-8"><div class="mb-8"><h1 class="text-2xl font-bold text-neutral-900 md:text-3xl dark:text-neutral-50">Security</h1> <p class="mt-2 text-base text-neutral-600 md:mt-3 md:text-lg dark:text-neutral-400">Manage your password, API key, and active sessions</p></div> <div class="space-y-8">`);
      ExpandableCard($$renderer3, {
        title: "Change Password",
        description: "Update your account password",
        onboardingId: "security-password",
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="p-6"><form method="POST" action="?/changePassword" class="space-y-4">`);
          FormInput($$renderer4, {
            name: "currentPassword",
            label: "Current Password",
            type: "password",
            placeholder: "Enter current password",
            autocomplete: "current-password",
            private_: true,
            get value() {
              return currentPassword;
            },
            set value($$value) {
              currentPassword = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----> `);
          FormInput($$renderer4, {
            name: "newPassword",
            label: "New Password",
            type: "password",
            placeholder: "Minimum 8 characters",
            autocomplete: "new-password",
            private_: true,
            get value() {
              return newPassword;
            },
            set value($$value) {
              newPassword = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----> `);
          FormInput($$renderer4, {
            name: "confirmPassword",
            label: "Confirm New Password",
            type: "password",
            placeholder: "Re-enter new password",
            autocomplete: "new-password",
            private_: true,
            get value() {
              return confirmPassword;
            },
            set value($$value) {
              confirmPassword = $$value;
              $$settled = false;
            }
          });
          $$renderer4.push(`<!----> <div class="flex justify-end">`);
          Button($$renderer4, {
            type: "submit",
            variant: "secondary",
            size: "sm",
            icon: Check,
            iconColor: "text-accent-500",
            text: "Change Password",
            disabled: changingPassword
          });
          $$renderer4.push(`<!----></div></form></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      ExpandableCard($$renderer3, {
        title: "Local Bypass",
        description: "Skip authentication for requests from local network addresses",
        onboardingId: "security-local-bypass",
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="p-6"><form method="POST" action="?/toggleLocalBypass">`);
          Toggle($$renderer4, {
            label: data.localBypassEnabled ? "Enabled" : "Disabled",
            checked: data.localBypassEnabled,
            disabled: togglingBypass
          });
          $$renderer4.push(`<!----></form></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      ExpandableCard($$renderer3, {
        title: "API Key",
        description: "Authenticate API requests via the X-Api-Key header",
        onboardingId: "security-api-key",
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="p-6">`);
          if (apiKey) {
            $$renderer4.push("<!--[0-->");
            $$renderer4.push(`<div class="space-y-3"><div class="flex items-center gap-2"><div class="flex-1">`);
            FormInput($$renderer4, {
              name: "apiKey",
              label: "",
              type: "text",
              value: apiKey,
              readonly: true
            });
            $$renderer4.push(`<!----></div> `);
            Button($$renderer4, {
              type: "button",
              variant: "ghost",
              size: "sm",
              icon: Copy,
              title: "Copy",
              ariaLabel: "Copy API key"
            });
            $$renderer4.push(`<!----></div> <p class="text-sm text-amber-600 dark:text-amber-400">This key is shown only once \u2014 copy it now.</p> <form method="POST" action="?/regenerateApiKey">`);
            Button($$renderer4, {
              type: "submit",
              variant: "secondary",
              size: "sm",
              icon: Refresh_cw,
              text: "Regenerate",
              disabled: apiKeyRegenerationDisabled,
              tooltip: apiKeyRegenerationTooltip
            });
            $$renderer4.push(`<!----></form></div>`);
          } else if (data.hasApiKey) {
            $$renderer4.push("<!--[1-->");
            $$renderer4.push(`<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"><p class="text-sm text-neutral-500 dark:text-neutral-400">`);
            if (data.canRegenerateApiKey) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`Your API key is hashed and cannot be displayed. Regenerating will replace the
								current key.`);
            } else {
              $$renderer4.push("<!--[-1-->");
              $$renderer4.push(`Your API key is managed by the PROFILARR_API_KEY environment variable.`);
            }
            $$renderer4.push(`<!--]--></p> <form method="POST" action="?/regenerateApiKey">`);
            Button($$renderer4, {
              type: "submit",
              variant: "secondary",
              size: "sm",
              icon: Refresh_cw,
              iconColor: "text-emerald-500",
              text: "Regenerate",
              disabled: apiKeyRegenerationDisabled,
              tooltip: apiKeyRegenerationTooltip
            });
            $$renderer4.push(`<!----></form></div>`);
          } else {
            $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<div class="flex items-center gap-4"><p class="text-sm text-neutral-500 dark:text-neutral-400">No API key configured</p> <form method="POST" action="?/regenerateApiKey">`);
            Button($$renderer4, {
              type: "submit",
              variant: "secondary",
              size: "sm",
              text: "Generate Key"
            });
            $$renderer4.push(`<!----></form></div>`);
          }
          $$renderer4.push(`<!--]--></div>`);
        },
        $$slots: { default: true }
      });
      $$renderer3.push(`<!----> `);
      ExpandableCard($$renderer3, {
        title: "Active Sessions",
        description: "Manage your logged-in sessions across devices",
        onboardingId: "security-sessions",
        children: ($$renderer4) => {
          $$renderer4.push(`<div class="p-6">`);
          if (data.sessions.length > 0) {
            $$renderer4.push("<!--[0-->");
            Table2($$renderer4, {
              columns: sessionColumns,
              data: data.sessions,
              compact: true,
              responsive: true,
              actionsHeader: "Status",
              $$slots: { actions: ($$renderer5, { row }) => {
                if (row.isCurrent) {
                  $$renderer5.push("<!--[0-->");
                  $$renderer5.push(`<span class="inline-flex items-center rounded bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-800 dark:bg-emerald-900 dark:text-emerald-200">Current</span>`);
                } else {
                  $$renderer5.push("<!--[-1-->");
                  $$renderer5.push(`<form method="POST" action="?/revokeSession"><input type="hidden" name="sessionId"${attr("value", row.id)}/> `);
                  Button($$renderer5, {
                    icon: Log_out,
                    title: "Revoke session",
                    ariaLabel: "Revoke session",
                    variant: "secondary",
                    iconColor: "text-red-600 dark:text-red-400",
                    size: "xs",
                    type: "submit"
                  });
                  $$renderer5.push(`<!----></form>`);
                }
                $$renderer5.push(`<!--]-->`);
              } }
            });
          } else {
            $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<p class="text-sm text-neutral-500 dark:text-neutral-400">No active sessions</p>`);
          }
          $$renderer4.push(`<!--]--></div>`);
        },
        $$slots: {
          default: true,
          "header-right": ($$renderer4) => {
            if (data.sessions.length > 1) {
              $$renderer4.push("<!--[0-->");
              $$renderer4.push(`<form method="POST" action="?/revokeOtherSessions">`);
              Button($$renderer4, {
                type: "submit",
                variant: "secondary",
                size: "xs",
                icon: Log_out,
                iconColor: "text-red-500",
                text: "Revoke Others"
              });
              $$renderer4.push(`<!----></form>`);
            } else $$renderer4.push("<!--[-1-->");
            $$renderer4.push(`<!--]-->`);
          }
        }
      });
      $$renderer3.push(`<!----></div></div>`);
    }
    do {
      $$settled = true;
      $$inner_renderer = $$renderer2.copy();
      $$render_inner($$inner_renderer);
    } while (!$$settled);
    $$renderer2.subsume($$inner_renderer);
    if ($$store_subs) unsubscribe_stores($$store_subs);
    bind_props($$props, {
      data,
      form
    });
  });
}
var init_page_svelte76 = __esm({
  "dist/build/server/entries/pages/settings/security/_page.svelte.js"() {
    "use strict";
    init_server();
    init_dates();
    init_Icon();
    init_check();
    init_clock();
    init_copy();
    init_Button();
    init_refresh_cw();
    init_store2();
    init_navigation();
    init_dateFormat();
    init_timezone();
    init_forms();
    init_PageMeta();
    init_Table();
    init_FormInput();
    init_Toggle();
    init_ExpandableCard();
  }
});

// dist/build/server/nodes/86.js
var __exports87 = {};
__export(__exports87, {
  component: () => component83,
  fonts: () => fonts87,
  imports: () => imports87,
  index: () => index87,
  server: () => page_server_ts_exports77,
  server_id: () => server_id83,
  stylesheets: () => stylesheets87
});
var index87, component_cache83, component83, server_id83, imports87, stylesheets87, fonts87;
var init__87 = __esm({
  async "dist/build/server/nodes/86.js"() {
    "use strict";
    await init_page_server_ts77();
    index87 = 86;
    component83 = async () => component_cache83 ??= (await Promise.resolve().then(() => (init_page_svelte76(), page_svelte_exports76))).default;
    server_id83 = "src/routes/settings/security/+page.server.ts";
    imports87 = ["_app/immutable/nodes/86.CsEHBJ6e.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js", "_app/immutable/chunks/DGo8yE5j.js", "_app/immutable/chunks/3rupxGJ5.js", "_app/immutable/chunks/BB59mDRy.js", "_app/immutable/chunks/BqRH1fsh2.js", "_app/immutable/chunks/DC11RaJ72.js", "_app/immutable/chunks/B66v-P2b.js", "_app/immutable/chunks/D-E0nZEG.js", "_app/immutable/chunks/BymfG72d2.js", "_app/immutable/chunks/BAdiU3ne2.js", "_app/immutable/chunks/C81q2Yt32.js", "_app/immutable/chunks/DCkiND_92.js", "_app/immutable/chunks/ChzvQw1N.js", "_app/immutable/chunks/DCohNkHF.js", "_app/immutable/chunks/Cme17KJK.js", "_app/immutable/chunks/vB0UVZBU.js", "_app/immutable/chunks/qMgSkqkC.js", "_app/immutable/chunks/CXOgR4bI2.js", "_app/immutable/chunks/Bv3FroHu2.js", "_app/immutable/chunks/bjLtLtyj.js", "_app/immutable/chunks/CmTUQ0et.js", "_app/immutable/chunks/CfTYE2PK2.js", "_app/immutable/chunks/DGICnufN.js", "_app/immutable/chunks/DvT-Y1N62.js", "_app/immutable/chunks/C73dJ-MR2.js", "_app/immutable/chunks/Cf96lmLi2.js", "_app/immutable/chunks/_ZYKMtmp.js"];
    stylesheets87 = ["_app/immutable/assets/Table.aVDhXS1A.css"];
    fonts87 = [];
  }
});

// dist/build/server/entries/endpoints/api/v1/announcements/_server.ts.js
var server_ts_exports = {};
__export(server_ts_exports, {
  GET: () => GET
});
function toSummary(a2) {
  return {
    id: a2.id,
    title: a2.title,
    severity: a2.severity,
    publishedAt: a2.publishedAt,
    expiresAt: a2.expiresAt,
    minVersion: a2.minVersion,
    maxVersion: a2.maxVersion,
    link: a2.link,
    readAt: a2.readAt
  };
}
var GET;
var init_server_ts = __esm({
  async "dist/build/server/entries/endpoints/api/v1/announcements/_server.ts.js"() {
    "use strict";
    await init_announcements();
    init_exports();
    GET = () => {
      return json(listVisible().map(toSummary));
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/announcements/_id_/_server.ts.js
var server_ts_exports2 = {};
__export(server_ts_exports2, {
  GET: () => GET2
});
function toDetail(a2) {
  return {
    id: a2.id,
    title: a2.title,
    severity: a2.severity,
    publishedAt: a2.publishedAt,
    expiresAt: a2.expiresAt,
    minVersion: a2.minVersion,
    maxVersion: a2.maxVersion,
    link: a2.link,
    readAt: a2.readAt,
    body: a2.body
  };
}
var GET2;
var init_server_ts2 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/announcements/_id_/_server.ts.js"() {
    "use strict";
    await init_announcements();
    init_exports();
    GET2 = async ({ params }) => {
      const id = params.id;
      if (!id) return json({ error: "id is required" }, { status: 400 });
      const record = await getDetail$1(id, { loadBody: true });
      if (!record) return json({ error: "Announcement not found" }, { status: 404 });
      return json(toDetail(record));
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/arr/_server.ts.js
var server_ts_exports3 = {};
__export(server_ts_exports3, {
  GET: () => GET3
});
var GET3;
var init_server_ts3 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/arr/_server.ts.js"() {
    "use strict";
    await init_arrInstances();
    init_exports();
    GET3 = async () => {
      const instances = arrInstancesQueries.getAll().map(({ api_key, ...safe }) => safe);
      return json(instances);
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/backups/_server.ts.js
var server_ts_exports4 = {};
__export(server_ts_exports4, {
  GET: () => GET4,
  POST: () => POST
});
var GET4, POST;
var init_server_ts4 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/backups/_server.ts.js"() {
    "use strict";
    init_config();
    init_list();
    await init_queueService();
    init_exports();
    GET4 = async () => {
      const backups = await listBackups(config.paths.backups);
      return json(backups);
    };
    POST = async () => {
      const response = { jobId: enqueueJob({
        jobType: "backup.create",
        runAt: (/* @__PURE__ */ new Date()).toISOString(),
        payload: {},
        source: "manual"
      }).id };
      return json(response, { status: 202 });
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/backups/settings/_server.ts.js
var server_ts_exports5 = {};
__export(server_ts_exports5, {
  GET: () => GET5,
  PATCH: () => PATCH
});
var VALID_SCHEDULES, GET5, PATCH;
var init_server_ts5 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/backups/settings/_server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_backupSettings();
    init_exports();
    VALID_SCHEDULES = /* @__PURE__ */ new Set([
      "hourly",
      "daily",
      "weekly",
      "monthly"
    ]);
    GET5 = async () => {
      const settings2 = backupSettingsQueries.get();
      if (!settings2) return json({ error: "Backup settings not found" }, { status: 500 });
      const response = {
        schedule: settings2.schedule,
        retentionDays: settings2.retention_days,
        enabled: settings2.enabled === 1,
        includeDatabase: settings2.include_database === 1,
        compressionEnabled: settings2.compression_enabled === 1
      };
      return json(response);
    };
    PATCH = async ({ request }) => {
      const { schedule, retentionDays, enabled: enabled3 } = await request.json();
      if (schedule === void 0 && retentionDays === void 0 && enabled3 === void 0) return json({ error: "No fields to update" }, { status: 400 });
      if (schedule !== void 0 && !VALID_SCHEDULES.has(schedule)) {
        const error2 = { error: `Invalid schedule. Must be one of: ${[...VALID_SCHEDULES].join(", ")}` };
        return json(error2, { status: 400 });
      }
      if (retentionDays !== void 0) {
        if (typeof retentionDays !== "number" || retentionDays < 1 || retentionDays > 365) return json({ error: "retentionDays must be between 1 and 365" }, { status: 400 });
      }
      if (enabled3 !== void 0 && typeof enabled3 !== "boolean") return json({ error: "enabled must be a boolean" }, { status: 400 });
      const current3 = backupSettingsQueries.get();
      if (!current3) return json({ error: "Backup settings not found" }, { status: 500 });
      const scheduleChanged = schedule !== void 0 && schedule !== current3.schedule;
      const updateInput = {};
      if (schedule !== void 0) updateInput.schedule = schedule;
      if (retentionDays !== void 0) updateInput.retentionDays = retentionDays;
      if (enabled3 !== void 0) updateInput.enabled = enabled3;
      backupSettingsQueries.update(updateInput);
      await scheduleBackupJobs({ forceBackup: scheduleChanged });
      const updated3 = backupSettingsQueries.get();
      const response = {
        schedule: updated3.schedule,
        retentionDays: updated3.retention_days,
        enabled: updated3.enabled === 1,
        includeDatabase: updated3.include_database === 1,
        compressionEnabled: updated3.compression_enabled === 1
      };
      return json(response);
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/backups/upload/_server.ts.js
var server_ts_exports6 = {};
__export(server_ts_exports6, {
  POST: () => POST2
});
async function validateArchiveEntries(filePath) {
  const result = await new Deno.Command("tar", {
    args: ["-tzf", filePath],
    stdout: "piped",
    stderr: "piped"
  }).output();
  if (!result.success) return {
    valid: false,
    error: `Failed to read archive: ${new TextDecoder().decode(result.stderr).trim()}`
  };
  const entries = new TextDecoder().decode(result.stdout).split("\n").filter((line) => line.trim());
  for (const entry of entries) {
    if (entry.split("/").some((s3) => s3 === "..")) return {
      valid: false,
      error: `Archive contains path traversal entry: ${entry}`
    };
    if (entry.startsWith("/")) return {
      valid: false,
      error: `Archive contains absolute path entry: ${entry}`
    };
  }
  return { valid: true };
}
var MAX_SIZE, POST2;
var init_server_ts6 = __esm({
  "dist/build/server/entries/endpoints/api/v1/backups/upload/_server.ts.js"() {
    "use strict";
    init_config();
    init_validation();
    init_exports();
    MAX_SIZE = 1073741824;
    POST2 = async ({ request }) => {
      const file = (await request.formData()).get("file");
      if (!file) return json({ error: "No file provided" }, { status: 400 });
      if (!file.name.endsWith(".tar.gz")) return json({ error: "Invalid file type. Only .tar.gz files are allowed." }, { status: 400 });
      if (file.size > MAX_SIZE) return json({ error: "File too large. Maximum size is 1GB." }, { status: 400 });
      const backupsDir = config.paths.backups;
      const filename = file.name.startsWith("backup-") ? file.name : `backup-uploaded-${Date.now()}.tar.gz`;
      const backupPath = `${backupsDir}/${filename}`;
      try {
        await Deno.stat(backupPath);
        return json({ error: "A backup with this name already exists" }, { status: 400 });
      } catch {
      }
      const tmpPath = `${backupsDir}/.upload-${Date.now()}.tmp.tar.gz`;
      const arrayBuffer = await file.arrayBuffer();
      const uint8Array = new Uint8Array(arrayBuffer);
      try {
        await Deno.writeFile(tmpPath, uint8Array);
        if (!(await validateArchiveEntries(tmpPath)).valid) {
          await Deno.remove(tmpPath);
          return json({ error: "Archive contains path traversal entries and was rejected" }, { status: 400 });
        }
        await Deno.rename(tmpPath, backupPath);
        const stat = await Deno.stat(backupPath);
        const response = {
          filename,
          size: stat.size,
          sizeFormatted: formatFileSize(stat.size)
        };
        return json(response, { status: 201 });
      } catch (err) {
        try {
          await Deno.remove(tmpPath);
        } catch {
        }
        const error2 = { error: err instanceof Error ? err.message : "Upload failed" };
        return json(error2, { status: 500 });
      }
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/backups/_filename_/_server.ts.js
var server_ts_exports7 = {};
__export(server_ts_exports7, {
  DELETE: () => DELETE,
  GET: () => GET6
});
var GET6, DELETE;
var init_server_ts7 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/backups/_filename_/_server.ts.js"() {
    "use strict";
    await init_db();
    init_config();
    init_validation();
    await init_sanitize2();
    init_exports();
    GET6 = async ({ params }) => {
      const { filename } = params;
      if (!filename || !isValidBackupFilename(filename)) return json({ error: "Invalid filename" }, { status: 400 });
      const backupPath = resolveBackupPath(filename, config.paths.backups);
      if (!backupPath) return json({ error: "Invalid filename" }, { status: 400 });
      try {
        await Deno.stat(backupPath);
      } catch {
        return json({ error: "Backup file not found" }, { status: 404 });
      }
      let bytes;
      try {
        bytes = await buildSanitizedArchive(backupPath);
      } catch (err) {
        const message2 = err instanceof Error ? err.message : String(err);
        await logger.error("Failed to sanitize backup for download", {
          source: "api/v1/backups/download",
          meta: {
            filename,
            error: message2
          }
        });
        return json({ error: "Failed to prepare backup for download" }, { status: 500 });
      }
      return new Response(bytes, { headers: {
        "Content-Type": "application/gzip",
        "Content-Disposition": `attachment; filename="${filename}"`
      } });
    };
    DELETE = async ({ params }) => {
      const { filename } = params;
      if (!filename || !isValidBackupFilename(filename)) return json({ error: "Invalid filename" }, { status: 400 });
      const backupPath = resolveBackupPath(filename, config.paths.backups);
      if (!backupPath) return json({ error: "Invalid filename" }, { status: 400 });
      try {
        await Deno.stat(backupPath);
      } catch {
        return json({ error: "Backup file not found" }, { status: 404 });
      }
      await Deno.remove(backupPath);
      return json({ success: true });
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/databases/_server.ts.js
var server_ts_exports8 = {};
__export(server_ts_exports8, {
  GET: () => GET7,
  POST: () => POST3
});
var GET7, POST3;
var init_server_ts8 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/databases/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_queueService();
    await init_validate();
    await init_init();
    init_exports();
    GET7 = async () => {
      const databases = pcdManager.getAllPublic().map(({ local_path, ...rest }) => rest);
      return json(databases);
    };
    POST3 = async ({ request }) => {
      let body;
      try {
        body = await request.json();
      } catch {
        return json({ error: "Invalid JSON body" }, { status: 400 });
      }
      const result = validateLinkInput(body);
      if (!result.ok) return json({ error: result.error }, { status: 400 });
      const { input } = result;
      if (checkNameConflict(input.name)) return json({ error: "A database with this name already exists" }, { status: 409 });
      try {
        const instance = await pcdManager.link(input);
        schedulePcdSyncForDatabase(instance.id);
        const { personal_access_token, local_path, ...safe } = instance;
        const response = {
          ...safe,
          hasPat: personal_access_token !== null
        };
        return json(response, { status: 201 });
      } catch (error2) {
        await logger.error("Failed to link database", {
          source: "POST /api/v1/databases",
          meta: {
            error: error2 instanceof Error ? error2.message : String(error2),
            name: input.name,
            repositoryUrl: input.repositoryUrl
          }
        });
        return json({ error: error2 instanceof Error ? error2.message : "Failed to link database" }, { status: 422 });
      }
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/databases/_id_/_server.ts.js
var server_ts_exports9 = {};
__export(server_ts_exports9, {
  DELETE: () => DELETE2,
  GET: () => GET8,
  PATCH: () => PATCH2
});
function parseId(params) {
  const id = parseInt(params.id || "", 10);
  return Number.isFinite(id) ? id : null;
}
var GET8, PATCH2, DELETE2;
var init_server_ts9 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/databases/_id_/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_databaseInstances();
    await init_queueService();
    await init_validate();
    await init_init();
    init_exports();
    GET8 = async ({ params }) => {
      const id = parseId(params);
      if (id === null) return json({ error: "Invalid database ID" }, { status: 400 });
      const instance = pcdManager.getByIdPublic(id);
      if (!instance) return json({ error: "Database not found" }, { status: 404 });
      const { local_path, ...safe } = instance;
      return json(safe);
    };
    PATCH2 = async ({ params, request }) => {
      const id = parseId(params);
      if (id === null) return json({ error: "Invalid database ID" }, { status: 400 });
      if (!databaseInstancesQueries.getById(id)) return json({ error: "Database not found" }, { status: 404 });
      let body;
      try {
        body = await request.json();
      } catch {
        return json({ error: "Invalid JSON body" }, { status: 400 });
      }
      const result = validateUpdateInput(body);
      if (!result.ok) return json({ error: result.error }, { status: 400 });
      const { input } = result;
      if (input.name && checkNameConflict(input.name, id)) return json({ error: "A database with this name already exists" }, { status: 409 });
      try {
        databaseInstancesQueries.update(id, input);
        schedulePcdSyncForDatabase(id);
        const updated3 = pcdManager.getByIdPublic(id);
        if (!updated3) return json({ error: "Database not found" }, { status: 404 });
        const { local_path, ...safe } = updated3;
        return json(safe);
      } catch (error2) {
        await logger.error("Failed to update database", {
          source: "PATCH /api/v1/databases/{id}",
          meta: {
            error: error2 instanceof Error ? error2.message : String(error2),
            id
          }
        });
        return json({ error: error2 instanceof Error ? error2.message : "Failed to update database" }, { status: 422 });
      }
    };
    DELETE2 = async ({ params }) => {
      const id = parseId(params);
      if (id === null) return json({ error: "Invalid database ID" }, { status: 400 });
      if (!databaseInstancesQueries.getById(id)) return json({ error: "Database not found" }, { status: 404 });
      try {
        await pcdManager.unlink(id);
        return new Response(null, { status: 204 });
      } catch (error2) {
        await logger.error("Failed to unlink database", {
          source: "DELETE /api/v1/databases/{id}",
          meta: {
            error: error2 instanceof Error ? error2.message : String(error2),
            id
          }
        });
        return json({ error: error2 instanceof Error ? error2.message : "Failed to unlink database" }, { status: 422 });
      }
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/databases/_id_/sync/_server.ts.js
var server_ts_exports10 = {};
__export(server_ts_exports10, {
  POST: () => POST4
});
var POST4;
var init_server_ts10 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/databases/_id_/sync/_server.ts.js"() {
    "use strict";
    await init_databaseInstances();
    await init_queueService();
    init_exports();
    POST4 = async ({ params }) => {
      const id = parseInt(params.id || "", 10);
      if (!Number.isFinite(id)) return json({ error: "Invalid database ID" }, { status: 400 });
      const instance = databaseInstancesQueries.getById(id);
      if (!instance) return json({ error: "Database not found" }, { status: 404 });
      if (instance.enabled === 0) return json({ error: "Database is disabled" }, { status: 400 });
      const response = { jobId: enqueueJob({
        jobType: "pcd.sync",
        runAt: (/* @__PURE__ */ new Date()).toISOString(),
        payload: { databaseId: id },
        source: "manual"
      }).id };
      return json(response, { status: 202 });
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/health/_server.ts.js
var server_ts_exports11 = {};
__export(server_ts_exports11, {
  GET: () => GET9
});
function determineStatus() {
  try {
    db.queryFirst("SELECT 1");
  } catch {
    return "unhealthy";
  }
  try {
    const allDatabases = databaseInstancesQueries.getAll();
    const enabled3 = allDatabases.filter((d2) => d2.enabled === 1);
    if (allDatabases.length > 0 && enabled3.length === 0) return "unhealthy";
    if (enabled3.length > 0) {
      if (allDatabases.filter((d2) => d2.enabled === 0).length > 0) return "degraded";
      let cachedCount = 0;
      for (const dbInstance of enabled3) if (getCache(dbInstance.id)?.isBuilt()) cachedCount++;
      if (cachedCount < enabled3.length) return "degraded";
    }
  } catch {
    return "unhealthy";
  }
  return "healthy";
}
var GET9;
var init_server_ts11 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/health/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_databaseInstances();
    init_registry();
    init_exports();
    GET9 = async () => {
      const status = determineStatus();
      const response = {
        status,
        timestamp: (/* @__PURE__ */ new Date()).toISOString()
      };
      return json(response, { status: status === "unhealthy" ? 503 : 200 });
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/jobs/_id_/_server.ts.js
var server_ts_exports12 = {};
__export(server_ts_exports12, {
  GET: () => GET10
});
var GET10;
var init_server_ts12 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/jobs/_id_/_server.ts.js"() {
    "use strict";
    await init_jobQueue();
    await init_jobRunHistory();
    init_exports();
    GET10 = async ({ params }) => {
      const id = parseInt(params.id, 10);
      if (isNaN(id) || id < 1) return json({ error: "Invalid job ID" }, { status: 400 });
      const job = jobQueueQueries.getById(id);
      if (!job) return json({ error: "Job not found" }, { status: 404 });
      const runs = jobRunHistoryQueries.getByQueueId(id, 1);
      const latestRun = runs.length > 0 ? runs[0] : null;
      const response = {
        id: job.id,
        jobType: job.jobType,
        status: job.status,
        source: job.source,
        createdAt: job.createdAt,
        startedAt: job.startedAt ?? null,
        finishedAt: job.finishedAt ?? null,
        result: latestRun ? {
          status: latestRun.status,
          output: latestRun.output ?? null,
          error: latestRun.error ?? null,
          durationMs: latestRun.durationMs
        } : null
      };
      return json(response);
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/openapi.json/_server.ts.js
var server_ts_exports13 = {};
__export(server_ts_exports13, {
  GET: () => GET11
});
var v1_openapi_default, GET11;
var init_server_ts13 = __esm({
  "dist/build/server/entries/endpoints/api/v1/openapi.json/_server.ts.js"() {
    "use strict";
    init_exports();
    v1_openapi_default = {
      openapi: "3.1.0",
      info: {
        "title": "Profilarr API",
        "version": "1.0.0",
        "license": {
          "name": "MIT",
          "url": "https://opensource.org/licenses/MIT"
        },
        "contact": {
          "name": "Profilarr",
          "url": "https://github.com/Dictionarry-Hub/profilarr"
        },
        "description": "Profilarr manages configuration for Radarr and Sonarr by syncing\ncurated configuration databases into Arr instances.\n"
      },
      servers: [{
        "url": "/api/v1",
        "description": "API v1"
      }],
      tags: [
        {
          "name": "System",
          "description": "Health checks, system status, and API metadata."
        },
        {
          "name": "Jobs",
          "description": "Job queue status and polling"
        },
        {
          "name": "Backups",
          "description": "Backup creation, listing, download, upload, and settings"
        },
        {
          "name": "Arr",
          "description": "Arr instance management, library, and sync endpoints"
        },
        {
          "name": "Databases",
          "description": "Linked database instance management"
        },
        {
          "name": "Announcements",
          "description": "In-app announcements fed from the bulletin repo"
        }
      ],
      security: [{ "apiKey": [] }, { "session": [] }],
      paths: /* @__PURE__ */ JSON.parse('{"/arr":{"get":{"operationId":"listArrInstances","summary":"List Arr Instances","description":"Returns all Arr instances (Radarr/Sonarr) with secrets stripped.\\n\\n**Use cases:**\\n- Dashboard widgets showing connected instances\\n- Automation scripts checking instance state\\n- Prerequisite checks (e.g. onboarding)\\n\\n**Behavior:**\\n- Returns an empty array if no instances are connected\\n- The `api_key` field is never included\\n","tags":["Arr"],"responses":{"200":{"description":"List of Arr instances","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["id","name","type","url","enabled","library_refresh_interval","created_at","updated_at"],"properties":{"id":{"type":"integer","description":"Instance ID"},"name":{"type":"string","description":"Display name"},"type":{"type":"string","enum":["radarr","sonarr"],"description":"Type of Arr instance"},"url":{"type":"string","description":"Instance URL used by Profilarr\'s backend for API calls"},"external_url":{"type":"string","nullable":true,"description":"Optional external/browser-facing URL. When set, the UI uses this for\\n\\"Open in Radarr/Sonarr\\" browser links while Profilarr\'s backend continues\\nto call the instance using `url`. Useful for reverse-proxied deployments\\nwhere the internal and external hostnames differ.\\n","example":"https://radarr.example.com"},"tags":{"type":"string","nullable":true,"description":"JSON array of tags"},"enabled":{"type":"integer","description":"Whether the instance is active (0 or 1)"},"library_refresh_interval":{"type":"integer","description":"Library cache refresh interval in minutes (0 = manual)"},"library_last_refreshed_at":{"type":"string","nullable":true,"description":"Last library refresh timestamp"},"created_at":{"type":"string","description":"Creation timestamp"},"updated_at":{"type":"string","description":"Last update timestamp"}}}}}}},"401":{"description":"Not authenticated"}}}},"/databases":{"get":{"operationId":"listDatabases","summary":"List Databases","description":"Secrets are stripped: `personal_access_token` is replaced by `hasPat` (boolean)\\nand `local_path` is excluded.\\n","tags":["Databases"],"responses":{"200":{"description":"List of linked databases","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["id","uuid","name","repository_url","sync_strategy","auto_pull","enabled","is_private","local_ops_enabled","conflict_strategy","hasPat","created_at","updated_at"],"properties":{"id":{"type":"integer","description":"Database instance ID"},"uuid":{"type":"string","format":"uuid","description":"Unique identifier"},"name":{"type":"string","description":"Display name"},"repository_url":{"type":"string","description":"GitHub repository URL"},"sync_strategy":{"type":"integer","description":"Auto-sync interval in minutes (0 = manual only)"},"auto_pull":{"type":"integer","description":"Whether to automatically pull updates (0 or 1)"},"enabled":{"type":"integer","description":"Whether the database is active (0 or 1)"},"is_private":{"type":"integer","description":"Whether the repository is private (0 or 1)"},"local_ops_enabled":{"type":"integer","description":"Whether local ops editing is enabled (0 or 1)"},"git_user_name":{"type":"string","nullable":true,"description":"Git user name for commits"},"git_user_email":{"type":"string","nullable":true,"description":"Git user email for commits"},"conflict_strategy":{"type":"string","enum":["override","align","ask"],"description":"How to handle conflicts between local tweaks and upstream updates"},"last_synced_at":{"type":"string","nullable":true,"description":"Last successful sync timestamp"},"created_at":{"type":"string","description":"Creation timestamp"},"updated_at":{"type":"string","description":"Last update timestamp"},"hasPat":{"type":"boolean","description":"Whether a personal access token is configured"}}}}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}}}}}}},"post":{"operationId":"createDatabase","summary":"Link Database","description":"Clones the repository, validates its PCD manifest, and processes dependencies.\\nThis is synchronous and may take several seconds for large repositories.\\n\\nField dependencies:\\n- `personal_access_token` requires `git_user_name` and `git_user_email`\\n- `local_ops_enabled` requires `personal_access_token`\\n- `conflict_strategy` is only accepted without a PAT, or with PAT + `local_ops_enabled`\\n","tags":["Databases"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","repository_url"],"properties":{"name":{"type":"string","description":"Display name (must be unique)"},"repository_url":{"type":"string","description":"GitHub repository URL"},"branch":{"type":"string","description":"Git branch to clone (defaults to remote\'s default branch)"},"personal_access_token":{"type":"string","description":"GitHub PAT for private repos and push access"},"git_user_name":{"type":"string","description":"Required when personal_access_token is set"},"git_user_email":{"type":"string","description":"Required when personal_access_token is set"},"sync_strategy":{"type":"integer","default":0,"description":"Auto-sync interval in minutes (0 = manual only)"},"auto_pull":{"type":"boolean","default":false,"description":"Whether to automatically pull updates"},"local_ops_enabled":{"type":"boolean","default":false,"description":"Force writes to local user ops even with a PAT (requires personal_access_token)"},"conflict_strategy":{"type":"string","enum":["override","align","ask"],"default":"override","description":"How to handle conflicts (only valid without a PAT, or with PAT + local_ops_enabled)"}}}}}},"responses":{"201":{"description":"Database linked","content":{"application/json":{"schema":{"type":"object","required":["id","uuid","name","repository_url","sync_strategy","auto_pull","enabled","is_private","local_ops_enabled","conflict_strategy","hasPat","created_at","updated_at"],"properties":{"id":{"type":"integer","description":"Database instance ID"},"uuid":{"type":"string","format":"uuid","description":"Unique identifier"},"name":{"type":"string","description":"Display name"},"repository_url":{"type":"string","description":"GitHub repository URL"},"sync_strategy":{"type":"integer","description":"Auto-sync interval in minutes (0 = manual only)"},"auto_pull":{"type":"integer","description":"Whether to automatically pull updates (0 or 1)"},"enabled":{"type":"integer","description":"Whether the database is active (0 or 1)"},"is_private":{"type":"integer","description":"Whether the repository is private (0 or 1)"},"local_ops_enabled":{"type":"integer","description":"Whether local ops editing is enabled (0 or 1)"},"git_user_name":{"type":"string","nullable":true,"description":"Git user name for commits"},"git_user_email":{"type":"string","nullable":true,"description":"Git user email for commits"},"conflict_strategy":{"type":"string","enum":["override","align","ask"],"description":"How to handle conflicts between local tweaks and upstream updates"},"last_synced_at":{"type":"string","nullable":true,"description":"Last successful sync timestamp"},"created_at":{"type":"string","description":"Creation timestamp"},"updated_at":{"type":"string","description":"Last update timestamp"},"hasPat":{"type":"boolean","description":"Whether a personal access token is configured"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Name and repository URL are required"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}},"409":{"description":"A database with this name already exists","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"A database with this name already exists"}}}},"422":{"description":"Link failed (invalid URL, clone failure, bad manifest)","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Repository not found or inaccessible"}}}}}}},"/databases/{id}":{"parameters":[{"name":"id","in":"path","required":true,"description":"Database instance ID","schema":{"type":"integer"}}],"get":{"operationId":"getDatabase","summary":"Get Database","description":"Secrets are stripped: `personal_access_token` is replaced by `hasPat` (boolean)\\nand `local_path` is excluded.\\n","tags":["Databases"],"responses":{"200":{"description":"Database detail","content":{"application/json":{"schema":{"type":"object","required":["id","uuid","name","repository_url","sync_strategy","auto_pull","enabled","is_private","local_ops_enabled","conflict_strategy","hasPat","created_at","updated_at"],"properties":{"id":{"type":"integer","description":"Database instance ID"},"uuid":{"type":"string","format":"uuid","description":"Unique identifier"},"name":{"type":"string","description":"Display name"},"repository_url":{"type":"string","description":"GitHub repository URL"},"sync_strategy":{"type":"integer","description":"Auto-sync interval in minutes (0 = manual only)"},"auto_pull":{"type":"integer","description":"Whether to automatically pull updates (0 or 1)"},"enabled":{"type":"integer","description":"Whether the database is active (0 or 1)"},"is_private":{"type":"integer","description":"Whether the repository is private (0 or 1)"},"local_ops_enabled":{"type":"integer","description":"Whether local ops editing is enabled (0 or 1)"},"git_user_name":{"type":"string","nullable":true,"description":"Git user name for commits"},"git_user_email":{"type":"string","nullable":true,"description":"Git user email for commits"},"conflict_strategy":{"type":"string","enum":["override","align","ask"],"description":"How to handle conflicts between local tweaks and upstream updates"},"last_synced_at":{"type":"string","nullable":true,"description":"Last successful sync timestamp"},"created_at":{"type":"string","description":"Creation timestamp"},"updated_at":{"type":"string","description":"Last update timestamp"},"hasPat":{"type":"boolean","description":"Whether a personal access token is configured"}}}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}},"404":{"description":"Database not found","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Database not found"}}}}}},"patch":{"operationId":"updateDatabase","summary":"Update Database","description":"Partial update. Only the provided fields are changed. Unknown fields\\nare silently ignored.\\n\\nField dependencies:\\n- `personal_access_token` requires `git_user_name` and `git_user_email`\\n- `local_ops_enabled` requires `personal_access_token`\\n- `conflict_strategy` is only accepted without a PAT, or with PAT + `local_ops_enabled`\\n","tags":["Databases"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"All fields are optional. Unknown fields are silently ignored.","properties":{"name":{"type":"string","description":"Display name (must be unique)"},"personal_access_token":{"type":"string","description":"GitHub PAT for private repos and push access"},"git_user_name":{"type":"string","description":"Required when personal_access_token is set"},"git_user_email":{"type":"string","description":"Required when personal_access_token is set"},"sync_strategy":{"type":"integer","description":"Auto-sync interval in minutes (0 = manual only)"},"auto_pull":{"type":"boolean","description":"Whether to automatically pull updates"},"local_ops_enabled":{"type":"boolean","description":"Force writes to local user ops even with a PAT (requires personal_access_token)"},"conflict_strategy":{"type":"string","enum":["override","align","ask"],"description":"How to handle conflicts (only valid without a PAT, or with PAT + local_ops_enabled)"}}}}}},"responses":{"200":{"description":"Database updated","content":{"application/json":{"schema":{"type":"object","required":["id","uuid","name","repository_url","sync_strategy","auto_pull","enabled","is_private","local_ops_enabled","conflict_strategy","hasPat","created_at","updated_at"],"properties":{"id":{"type":"integer","description":"Database instance ID"},"uuid":{"type":"string","format":"uuid","description":"Unique identifier"},"name":{"type":"string","description":"Display name"},"repository_url":{"type":"string","description":"GitHub repository URL"},"sync_strategy":{"type":"integer","description":"Auto-sync interval in minutes (0 = manual only)"},"auto_pull":{"type":"integer","description":"Whether to automatically pull updates (0 or 1)"},"enabled":{"type":"integer","description":"Whether the database is active (0 or 1)"},"is_private":{"type":"integer","description":"Whether the repository is private (0 or 1)"},"local_ops_enabled":{"type":"integer","description":"Whether local ops editing is enabled (0 or 1)"},"git_user_name":{"type":"string","nullable":true,"description":"Git user name for commits"},"git_user_email":{"type":"string","nullable":true,"description":"Git user email for commits"},"conflict_strategy":{"type":"string","enum":["override","align","ask"],"description":"How to handle conflicts between local tweaks and upstream updates"},"last_synced_at":{"type":"string","nullable":true,"description":"Last successful sync timestamp"},"created_at":{"type":"string","description":"Creation timestamp"},"updated_at":{"type":"string","description":"Last update timestamp"},"hasPat":{"type":"boolean","description":"Whether a personal access token is configured"}}}}}},"400":{"description":"Validation error or empty body","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"No updatable fields provided"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}},"404":{"description":"Database not found","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Database not found"}}}},"409":{"description":"A database with this name already exists","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"A database with this name already exists"}}}}}},"delete":{"operationId":"deleteDatabase","summary":"Unlink Database","description":"Removes the database row, deletes the cloned repository from disk,\\nand cancels any scheduled sync jobs.\\n","tags":["Databases"],"responses":{"204":{"description":"Database unlinked"},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}},"404":{"description":"Database not found","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Database not found"}}}}}}},"/databases/{id}/sync":{"parameters":[{"name":"id","in":"path","required":true,"description":"Database instance ID","schema":{"type":"integer"}}],"post":{"operationId":"syncDatabase","summary":"Trigger Sync","description":"Async. Enqueues a `pcd.sync` job and returns 202 with the job ID.\\nPoll `GET /api/v1/jobs/{jobId}` for completion.\\n","tags":["Databases"],"responses":{"202":{"description":"Sync job enqueued","content":{"application/json":{"schema":{"type":"object","required":["jobId"],"properties":{"jobId":{"type":"integer","description":"Job queue ID to poll via GET /api/v1/jobs/{jobId}"}}},"example":{"jobId":42}}}},"400":{"description":"Database is disabled","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Database is disabled"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}},"404":{"description":"Database not found","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Database not found"}}}}}}},"/health":{"get":{"operationId":"getHealth","summary":"Health Check","description":"Public endpoint, no authentication required. Use this for uptime monitors\\nand load balancers. Returns 200 for healthy or degraded, 503 for unhealthy.\\n","tags":["System"],"security":[],"responses":{"200":{"description":"System is healthy or degraded (status field indicates which)","content":{"application/json":{"schema":{"type":"object","required":["status","timestamp"],"properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"],"description":"Overall health status"},"timestamp":{"type":"string","format":"date-time","description":"Current server time"}}},"example":{"status":"healthy","timestamp":"2026-03-09T12:00:00.000Z"}}}},"503":{"description":"System is unhealthy (status field will be \\"unhealthy\\")","content":{"application/json":{"schema":{"type":"object","required":["status","timestamp"],"properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"],"description":"Overall health status"},"timestamp":{"type":"string","format":"date-time","description":"Current server time"}}},"example":{"status":"unhealthy","timestamp":"2026-03-09T12:00:00.000Z"}}}}}}},"/status":{"get":{"operationId":"getStatus","summary":"System Status","description":"Single-call overview designed for dashboard integrations (e.g. Homepage).\\nThe `drift` field on each arr is reserved for future use and always null.\\n","tags":["System"],"responses":{"200":{"description":"System status","content":{"application/json":{"schema":{"type":"object","required":["version","uptime","timezone","databases","arrs","jobs","backups","announcements"],"properties":{"version":{"type":"string","description":"Application version"},"uptime":{"type":"integer","description":"Server uptime in seconds"},"timezone":{"type":"string","description":"Server timezone (IANA, e.g. \\"America/New_York\\")"},"databases":{"type":"array","items":{"type":"object","required":["id","name","enabled","lastSyncedAt","syncStrategy","counts"],"properties":{"id":{"type":"integer","description":"Database instance ID"},"name":{"type":"string","description":"Display name"},"enabled":{"type":"boolean","description":"Whether the database is active"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync check timestamp"},"syncStrategy":{"type":"string","enum":["manual","auto"],"description":"Sync strategy"},"counts":{"type":"object","required":["customFormats","qualityProfiles","regularExpressions","delayProfiles"],"properties":{"customFormats":{"type":"integer","description":"Number of custom formats"},"qualityProfiles":{"type":"integer","description":"Number of quality profiles"},"regularExpressions":{"type":"integer","description":"Number of regular expressions"},"delayProfiles":{"type":"integer","description":"Number of delay profiles"}}}}}},"arrs":{"type":"array","items":{"type":"object","required":["id","name","type","enabled","sync","drift"],"properties":{"id":{"type":"integer","description":"Arr instance ID"},"name":{"type":"string","description":"Display name"},"type":{"type":"string","enum":["radarr","sonarr"],"description":"Arr application type"},"enabled":{"type":"boolean","description":"Whether the instance is active"},"sync":{"type":"object","required":["qualityProfiles","delayProfiles","mediaManagement"],"properties":{"qualityProfiles":{"type":"object","required":["count","status","lastSyncedAt"],"properties":{"count":{"type":"integer","description":"Number of synced quality profiles"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}},"delayProfiles":{"type":"object","required":["configured","status","lastSyncedAt"],"properties":{"configured":{"type":"boolean","description":"Whether this sync section has been configured"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}},"mediaManagement":{"type":"object","required":["configured","status","lastSyncedAt"],"properties":{"configured":{"type":"boolean","description":"Whether this sync section has been configured"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}}}},"drift":{"oneOf":[{"type":"object","required":["lastCheckedAt","drifted","details"],"properties":{"lastCheckedAt":{"type":"string","format":"date-time","description":"When drift was last checked"},"drifted":{"type":"boolean","description":"Whether any section has drifted"},"details":{"type":"object","required":["qualityProfiles","delayProfiles","mediaManagement"],"properties":{"qualityProfiles":{"type":"integer","description":"Number of drifted quality profiles"},"delayProfiles":{"type":"integer","description":"Number of drifted delay profiles"},"mediaManagement":{"type":"integer","description":"Number of drifted media management configs"}}}}},{"type":"null"}],"description":"Drift detection result (null until implemented)"}}}},"jobs":{"type":"object","required":["active","queued","nextRunAt"],"properties":{"active":{"type":"integer","description":"Number of currently running jobs"},"queued":{"type":"integer","description":"Number of queued jobs"},"nextRunAt":{"type":"string","format":"date-time","nullable":true,"description":"Earliest scheduled job run time"}}},"backups":{"type":"object","required":["enabled","lastBackupAt"],"properties":{"enabled":{"type":"boolean","description":"Whether automatic backups are enabled"},"lastBackupAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of last backup"}}},"announcements":{"type":"object","required":["unread"],"properties":{"unread":{"type":"integer","description":"Number of unread, visible announcements. Visibility honours\\n`withdrawn`, `expires_at`, and the running build\'s version bounds\\n(`min_version` / `max_version`).\\n"}}}}},"example":{"version":"2.0.0","uptime":86400,"timezone":"America/New_York","databases":[{"id":1,"name":"Dictionarry","enabled":true,"lastSyncedAt":"2026-04-09T12:00:00Z","syncStrategy":"auto","counts":{"customFormats":52,"qualityProfiles":3,"regularExpressions":120,"delayProfiles":1}}],"arrs":[{"id":1,"name":"Radarr","type":"radarr","enabled":true,"sync":{"qualityProfiles":{"count":2,"status":"idle","lastSyncedAt":"2026-04-09T12:00:00Z"},"delayProfiles":{"configured":true,"status":"idle","lastSyncedAt":"2026-04-09T12:00:00Z"},"mediaManagement":{"configured":true,"status":"idle","lastSyncedAt":"2026-04-09T12:00:00Z"}},"drift":null}],"jobs":{"active":0,"queued":2,"nextRunAt":"2026-04-09T13:00:00Z"},"backups":{"enabled":true,"lastBackupAt":"2026-04-09T00:00:00Z"},"announcements":{"unread":2}}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}}}}}}}},"/openapi.json":{"get":{"operationId":"getOpenApiSpec","summary":"OpenAPI Specification","description":"Returns the resolved OpenAPI 3.1 spec as a single JSON document.\\nUseful for generating client SDKs or feeding to documentation tools.\\n","tags":["System"],"responses":{"200":{"description":"OpenAPI specification","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/jobs/{id}":{"get":{"operationId":"getJob","summary":"Get Job Status","description":"Returns the current status of a job queue entry.\\n\\n**Use cases:**\\n- Polling for completion after creating a backup\\n- Checking if a scheduled job has run\\n- Inspecting job errors after failure\\n\\n**Behavior:**\\n- Returns the job queue record with its current status\\n- If the job has executed, `result` includes the latest run history\\n- If the job is still queued or running, `result` is null\\n","tags":["Jobs"],"parameters":[{"name":"id","in":"path","required":true,"description":"Job queue ID (returned by endpoints that create jobs)","schema":{"type":"integer"}}],"responses":{"200":{"description":"Job found","content":{"application/json":{"schema":{"type":"object","required":["id","jobType","status","source","createdAt","startedAt","finishedAt","result"],"properties":{"id":{"type":"integer","description":"Job queue ID"},"jobType":{"type":"string","description":"Job type identifier (e.g. backup.create, arr.sync)"},"status":{"type":"string","enum":["queued","running","success","failed","cancelled"],"description":"Current state of the job in the queue"},"source":{"type":"string","enum":["manual","schedule","system"],"description":"How the job was triggered"},"createdAt":{"type":"string","description":"When the job was enqueued"},"startedAt":{"type":"string","nullable":true,"description":"When execution started (null if still queued)"},"finishedAt":{"type":"string","nullable":true,"description":"When execution finished (null if not yet complete)"},"result":{"oneOf":[{"type":"object","required":["status","output","error","durationMs"],"properties":{"status":{"type":"string","enum":["success","failure","skipped","cancelled"],"description":"Outcome of the job execution"},"output":{"type":"string","nullable":true,"description":"Human-readable output from the handler"},"error":{"type":"string","nullable":true,"description":"Error message if the job failed"},"durationMs":{"type":"integer","description":"Execution time in milliseconds"}}},{"type":"null"}],"description":"Latest run result, or null if the job has not executed yet"}}},"example":{"id":42,"jobType":"backup.create","status":"success","source":"manual","createdAt":"2026-03-15T10:00:00.000Z","startedAt":"2026-03-15T10:00:01.000Z","finishedAt":"2026-03-15T10:00:05.000Z","result":{"status":"success","output":"Backup created: backup-2026-03-15-100005.tar.gz (12.34 MB)","error":null,"durationMs":4000}}}}},"400":{"description":"Invalid job ID (non-numeric or less than 1)","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Invalid job ID"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}},"404":{"description":"Job not found","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Job not found"}}}}}}},"/backups":{"get":{"operationId":"listBackups","summary":"List Backups","tags":["Backups"],"responses":{"200":{"description":"List of backup files, sorted newest first","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["filename","created","size","sizeFormatted"],"properties":{"filename":{"type":"string","description":"Backup archive filename","example":"backup-2026-03-15-100005.tar.gz"},"created":{"type":"string","format":"date-time","description":"File modification time (when the backup was created)"},"size":{"type":"integer","description":"File size in bytes"},"sizeFormatted":{"type":"string","description":"Human-readable file size","example":"12.34 MB"}}}}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}}}},"post":{"operationId":"createBackup","summary":"Create Backup","description":"Async. Enqueues a `backup.create` job and returns 202 with the job ID.\\nPoll `GET /api/v1/jobs/{jobId}` for completion. The backup includes a\\nsanitized database copy with all secrets stripped.\\n","tags":["Backups"],"responses":{"202":{"description":"Backup job enqueued","content":{"application/json":{"schema":{"type":"object","required":["jobId"],"properties":{"jobId":{"type":"integer","description":"Job queue ID. Poll GET /api/v1/jobs/{jobId} for status."}}},"example":{"jobId":42}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}}}}},"/backups/{filename}":{"get":{"operationId":"downloadBackup","summary":"Download Backup","description":"Download a backup archive. The local file on disk is full-fidelity, but\\nthe downloaded copy is sanitized on the fly so it is safer to share.\\nThe following are removed from the downloaded archive:\\n\\n- Arr instances (URLs, API keys, sync configs, drift state, rename and\\n  cleanup history)\\n- Notification services (webhook URLs, tokens, history)\\n- User accounts and active sessions\\n- Personal access tokens for linked databases\\n- AI and TMDB API keys\\n\\nThe local archive on the server is not modified. Restoring the\\ndownloaded file on a different host will require re-adding the removed\\nitems.\\n","tags":["Backups"],"parameters":[{"name":"filename","in":"path","required":true,"description":"Backup filename (must match `backup-*.tar.gz`)","schema":{"type":"string"}}],"responses":{"200":{"description":"Sanitized backup file download","headers":{"Content-Disposition":{"schema":{"type":"string"},"example":"attachment; filename=\\"backup-2026-03-15-100005.tar.gz\\""}},"content":{"application/gzip":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Invalid filename or path traversal attempt","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Invalid filename"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}},"404":{"description":"Backup file not found","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Backup file not found"}}}}}},"delete":{"operationId":"deleteBackup","summary":"Delete Backup","tags":["Backups"],"parameters":[{"name":"filename","in":"path","required":true,"description":"Backup filename","schema":{"type":"string"}}],"responses":{"200":{"description":"Backup deleted","content":{"application/json":{"schema":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean","example":true}}}}}},"400":{"description":"Invalid filename or path traversal attempt","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Invalid filename"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}},"404":{"description":"Backup file not found","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Backup file not found"}}}}}}},"/backups/upload":{"post":{"operationId":"uploadBackup","summary":"Upload Backup","description":"Only `.tar.gz` files, max 1GB. Archive contents are scanned for path\\ntraversal entries (zip slip protection). Files without a `backup-` prefix\\nare renamed to `backup-uploaded-{timestamp}.tar.gz`. Duplicates rejected.\\n","tags":["Backups"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"The `.tar.gz` backup archive to upload"}}}}}},"responses":{"201":{"description":"Backup uploaded","content":{"application/json":{"schema":{"type":"object","required":["filename","size","sizeFormatted"],"properties":{"filename":{"type":"string","description":"Stored filename (may differ from upload name)"},"size":{"type":"integer","description":"File size in bytes"},"sizeFormatted":{"type":"string","description":"Human-readable file size"}}},"example":{"filename":"backup-uploaded-1710504000000.tar.gz","size":12345678,"sizeFormatted":"11.77 MB"}}}},"400":{"description":"Invalid file (wrong type, too large, zip slip, or duplicate)","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Invalid file type. Only .tar.gz files are allowed."}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}}}}},"/backups/settings":{"get":{"operationId":"getBackupSettings","summary":"Get Backup Settings","tags":["Backups"],"responses":{"200":{"description":"Current backup settings","content":{"application/json":{"schema":{"type":"object","required":["schedule","retentionDays","enabled","includeDatabase","compressionEnabled"],"properties":{"schedule":{"type":"string","enum":["hourly","daily","weekly","monthly"],"description":"How often automatic backups run"},"retentionDays":{"type":"integer","minimum":1,"maximum":365,"description":"Days to keep backups before cleanup deletes them"},"enabled":{"type":"boolean","description":"Whether automatic backups are enabled"},"includeDatabase":{"type":"boolean","description":"Whether to include the database in backups"},"compressionEnabled":{"type":"boolean","description":"Whether backup compression is enabled"}}},"example":{"schedule":"daily","retentionDays":30,"enabled":true,"includeDatabase":true,"compressionEnabled":true}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}}}},"patch":{"operationId":"updateBackupSettings","summary":"Update Backup Settings","description":"Partial update. After saving, backup jobs are rescheduled to match the\\nnew settings.\\n","tags":["Backups"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"All fields are optional. Only provided fields are updated.","properties":{"schedule":{"type":"string","enum":["hourly","daily","weekly","monthly"]},"retentionDays":{"type":"integer","minimum":1,"maximum":365},"enabled":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated backup settings","content":{"application/json":{"schema":{"type":"object","required":["schedule","retentionDays","enabled","includeDatabase","compressionEnabled"],"properties":{"schedule":{"type":"string","enum":["hourly","daily","weekly","monthly"],"description":"How often automatic backups run"},"retentionDays":{"type":"integer","minimum":1,"maximum":365,"description":"Days to keep backups before cleanup deletes them"},"enabled":{"type":"boolean","description":"Whether automatic backups are enabled"},"includeDatabase":{"type":"boolean","description":"Whether to include the database in backups"},"compressionEnabled":{"type":"boolean","description":"Whether backup compression is enabled"}}}}}},"400":{"description":"Invalid input (bad schedule, retention out of range, empty body)","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"retentionDays must be between 1 and 365"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}}}}},"/announcements":{"get":{"operationId":"listAnnouncements","summary":"List Announcements","description":"Visible announcements only: withdrawn, expired, and version-incompatible\\nentries are filtered out server-side. Bodies are not included; use the\\ndetail endpoint to fetch one.\\n","tags":["Announcements"],"responses":{"200":{"description":"Visible announcements, newest first.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","description":"Announcement without body. Returned by the list endpoint.","required":["id","title","severity","publishedAt","expiresAt","minVersion","maxVersion","link","readAt"],"properties":{"id":{"type":"string","description":"ULID, immutable once published."},"title":{"type":"string"},"severity":{"type":"string","enum":["info","warning","critical"],"description":"Severity level. `critical` is reserved for genuine break-glass messages."},"publishedAt":{"type":"string","format":"date-time","description":"ISO-8601 UTC. Drives sort order."},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"Null = no expiry."},"minVersion":{"type":"string","nullable":true,"description":"Minimum running version for this announcement to apply."},"maxVersion":{"type":"string","nullable":true,"description":"Maximum running version for this announcement to apply."},"link":{"type":"string","format":"uri","nullable":true,"description":"Optional external \\"Read more\\" URL."},"readAt":{"type":"string","format":"date-time","nullable":true,"description":"When the announcement was opened in the app. Null = unread."}}}},"example":[{"id":"01HXYZ0000000000000000000A","title":"API v1 migration landing in 2.4","severity":"warning","publishedAt":"2026-04-10T10:00:00Z","expiresAt":null,"minVersion":"2.0.0","maxVersion":null,"link":"https://github.com/Dictionarry-Hub/profilarr/discussions/999","readAt":null}]}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}}}}},"/announcements/{id}":{"get":{"operationId":"getAnnouncement","summary":"Get Announcement","description":"Returns the full announcement including its markdown body. The body\\nis lazy-fetched from the bulletin repo on first call and cached\\nlocally; subsequent calls read from cache.\\n\\n404 is returned for unknown ids and for ids that have not yet been\\ningested by the fetch job (e.g. calling the API between a new\\nbulletin PR merging and the next scheduled reconcile).\\n","tags":["Announcements"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ULID of the announcement."}],"responses":{"200":{"description":"Announcement detail with body.","content":{"application/json":{"schema":{"type":"object","description":"Announcement with the full markdown body. Returned by the detail endpoint.","required":["id","title","severity","publishedAt","expiresAt","minVersion","maxVersion","link","readAt","body"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"severity":{"type":"string","enum":["info","warning","critical"],"description":"Severity level. `critical` is reserved for genuine break-glass messages."},"publishedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time","nullable":true},"minVersion":{"type":"string","nullable":true},"maxVersion":{"type":"string","nullable":true},"link":{"type":"string","format":"uri","nullable":true},"readAt":{"type":"string","format":"date-time","nullable":true},"body":{"type":"string","nullable":true,"description":"Raw markdown body. Lazy-fetched from the bulletin on first call.\\nMay be null briefly if the lazy fetch fails; subsequent calls retry.\\n"}}}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Unauthorized"}}}},"404":{"description":"Announcement not found.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"example":{"error":"Announcement not found"}}}}}}}}'),
      components: /* @__PURE__ */ JSON.parse('{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"API key for programmatic access. Generate in Settings > Security."},"session":{"type":"apiKey","in":"cookie","name":"session","description":"Session cookie set after browser login."}},"schemas":{"HealthStatus":{"type":"string","enum":["healthy","degraded","unhealthy"],"description":"Overall health status"},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message","example":"Unauthorized"}}},"HealthCheckResponse":{"type":"object","required":["status","timestamp"],"properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"],"description":"Overall health status"},"timestamp":{"type":"string","format":"date-time","description":"Current server time"}}},"StatusResponse":{"type":"object","required":["version","uptime","timezone","databases","arrs","jobs","backups","announcements"],"properties":{"version":{"type":"string","description":"Application version"},"uptime":{"type":"integer","description":"Server uptime in seconds"},"timezone":{"type":"string","description":"Server timezone (IANA, e.g. \\"America/New_York\\")"},"databases":{"type":"array","items":{"type":"object","required":["id","name","enabled","lastSyncedAt","syncStrategy","counts"],"properties":{"id":{"type":"integer","description":"Database instance ID"},"name":{"type":"string","description":"Display name"},"enabled":{"type":"boolean","description":"Whether the database is active"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync check timestamp"},"syncStrategy":{"type":"string","enum":["manual","auto"],"description":"Sync strategy"},"counts":{"type":"object","required":["customFormats","qualityProfiles","regularExpressions","delayProfiles"],"properties":{"customFormats":{"type":"integer","description":"Number of custom formats"},"qualityProfiles":{"type":"integer","description":"Number of quality profiles"},"regularExpressions":{"type":"integer","description":"Number of regular expressions"},"delayProfiles":{"type":"integer","description":"Number of delay profiles"}}}}}},"arrs":{"type":"array","items":{"type":"object","required":["id","name","type","enabled","sync","drift"],"properties":{"id":{"type":"integer","description":"Arr instance ID"},"name":{"type":"string","description":"Display name"},"type":{"type":"string","enum":["radarr","sonarr"],"description":"Arr application type"},"enabled":{"type":"boolean","description":"Whether the instance is active"},"sync":{"type":"object","required":["qualityProfiles","delayProfiles","mediaManagement"],"properties":{"qualityProfiles":{"type":"object","required":["count","status","lastSyncedAt"],"properties":{"count":{"type":"integer","description":"Number of synced quality profiles"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}},"delayProfiles":{"type":"object","required":["configured","status","lastSyncedAt"],"properties":{"configured":{"type":"boolean","description":"Whether this sync section has been configured"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}},"mediaManagement":{"type":"object","required":["configured","status","lastSyncedAt"],"properties":{"configured":{"type":"boolean","description":"Whether this sync section has been configured"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}}}},"drift":{"oneOf":[{"type":"object","required":["lastCheckedAt","drifted","details"],"properties":{"lastCheckedAt":{"type":"string","format":"date-time","description":"When drift was last checked"},"drifted":{"type":"boolean","description":"Whether any section has drifted"},"details":{"type":"object","required":["qualityProfiles","delayProfiles","mediaManagement"],"properties":{"qualityProfiles":{"type":"integer","description":"Number of drifted quality profiles"},"delayProfiles":{"type":"integer","description":"Number of drifted delay profiles"},"mediaManagement":{"type":"integer","description":"Number of drifted media management configs"}}}}},{"type":"null"}],"description":"Drift detection result (null until implemented)"}}}},"jobs":{"type":"object","required":["active","queued","nextRunAt"],"properties":{"active":{"type":"integer","description":"Number of currently running jobs"},"queued":{"type":"integer","description":"Number of queued jobs"},"nextRunAt":{"type":"string","format":"date-time","nullable":true,"description":"Earliest scheduled job run time"}}},"backups":{"type":"object","required":["enabled","lastBackupAt"],"properties":{"enabled":{"type":"boolean","description":"Whether automatic backups are enabled"},"lastBackupAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of last backup"}}},"announcements":{"type":"object","required":["unread"],"properties":{"unread":{"type":"integer","description":"Number of unread, visible announcements. Visibility honours\\n`withdrawn`, `expires_at`, and the running build\'s version bounds\\n(`min_version` / `max_version`).\\n"}}}}},"StatusDatabase":{"type":"object","required":["id","name","enabled","lastSyncedAt","syncStrategy","counts"],"properties":{"id":{"type":"integer","description":"Database instance ID"},"name":{"type":"string","description":"Display name"},"enabled":{"type":"boolean","description":"Whether the database is active"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync check timestamp"},"syncStrategy":{"type":"string","enum":["manual","auto"],"description":"Sync strategy"},"counts":{"type":"object","required":["customFormats","qualityProfiles","regularExpressions","delayProfiles"],"properties":{"customFormats":{"type":"integer","description":"Number of custom formats"},"qualityProfiles":{"type":"integer","description":"Number of quality profiles"},"regularExpressions":{"type":"integer","description":"Number of regular expressions"},"delayProfiles":{"type":"integer","description":"Number of delay profiles"}}}}},"StatusDatabaseCounts":{"type":"object","required":["customFormats","qualityProfiles","regularExpressions","delayProfiles"],"properties":{"customFormats":{"type":"integer","description":"Number of custom formats"},"qualityProfiles":{"type":"integer","description":"Number of quality profiles"},"regularExpressions":{"type":"integer","description":"Number of regular expressions"},"delayProfiles":{"type":"integer","description":"Number of delay profiles"}}},"StatusArr":{"type":"object","required":["id","name","type","enabled","sync","drift"],"properties":{"id":{"type":"integer","description":"Arr instance ID"},"name":{"type":"string","description":"Display name"},"type":{"type":"string","enum":["radarr","sonarr"],"description":"Arr application type"},"enabled":{"type":"boolean","description":"Whether the instance is active"},"sync":{"type":"object","required":["qualityProfiles","delayProfiles","mediaManagement"],"properties":{"qualityProfiles":{"type":"object","required":["count","status","lastSyncedAt"],"properties":{"count":{"type":"integer","description":"Number of synced quality profiles"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}},"delayProfiles":{"type":"object","required":["configured","status","lastSyncedAt"],"properties":{"configured":{"type":"boolean","description":"Whether this sync section has been configured"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}},"mediaManagement":{"type":"object","required":["configured","status","lastSyncedAt"],"properties":{"configured":{"type":"boolean","description":"Whether this sync section has been configured"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}}}},"drift":{"oneOf":[{"type":"object","required":["lastCheckedAt","drifted","details"],"properties":{"lastCheckedAt":{"type":"string","format":"date-time","description":"When drift was last checked"},"drifted":{"type":"boolean","description":"Whether any section has drifted"},"details":{"type":"object","required":["qualityProfiles","delayProfiles","mediaManagement"],"properties":{"qualityProfiles":{"type":"integer","description":"Number of drifted quality profiles"},"delayProfiles":{"type":"integer","description":"Number of drifted delay profiles"},"mediaManagement":{"type":"integer","description":"Number of drifted media management configs"}}}}},{"type":"null"}],"description":"Drift detection result (null until implemented)"}}},"StatusArrSync":{"type":"object","required":["qualityProfiles","delayProfiles","mediaManagement"],"properties":{"qualityProfiles":{"type":"object","required":["count","status","lastSyncedAt"],"properties":{"count":{"type":"integer","description":"Number of synced quality profiles"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}},"delayProfiles":{"type":"object","required":["configured","status","lastSyncedAt"],"properties":{"configured":{"type":"boolean","description":"Whether this sync section has been configured"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}},"mediaManagement":{"type":"object","required":["configured","status","lastSyncedAt"],"properties":{"configured":{"type":"boolean","description":"Whether this sync section has been configured"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}}}},"StatusArrSyncQualityProfiles":{"type":"object","required":["count","status","lastSyncedAt"],"properties":{"count":{"type":"integer","description":"Number of synced quality profiles"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}},"StatusArrSyncSection":{"type":"object","required":["configured","status","lastSyncedAt"],"properties":{"configured":{"type":"boolean","description":"Whether this sync section has been configured"},"status":{"type":"string","description":"Sync status (idle, pending, in_progress, failed)"},"lastSyncedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last successful sync timestamp"}}},"StatusArrDrift":{"type":"object","required":["lastCheckedAt","drifted","details"],"properties":{"lastCheckedAt":{"type":"string","format":"date-time","description":"When drift was last checked"},"drifted":{"type":"boolean","description":"Whether any section has drifted"},"details":{"type":"object","required":["qualityProfiles","delayProfiles","mediaManagement"],"properties":{"qualityProfiles":{"type":"integer","description":"Number of drifted quality profiles"},"delayProfiles":{"type":"integer","description":"Number of drifted delay profiles"},"mediaManagement":{"type":"integer","description":"Number of drifted media management configs"}}}}},"StatusJobs":{"type":"object","required":["active","queued","nextRunAt"],"properties":{"active":{"type":"integer","description":"Number of currently running jobs"},"queued":{"type":"integer","description":"Number of queued jobs"},"nextRunAt":{"type":"string","format":"date-time","nullable":true,"description":"Earliest scheduled job run time"}}},"StatusBackups":{"type":"object","required":["enabled","lastBackupAt"],"properties":{"enabled":{"type":"boolean","description":"Whether automatic backups are enabled"},"lastBackupAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of last backup"}}},"StatusAnnouncements":{"type":"object","required":["unread"],"properties":{"unread":{"type":"integer","description":"Number of unread, visible announcements. Visibility honours\\n`withdrawn`, `expires_at`, and the running build\'s version bounds\\n(`min_version` / `max_version`).\\n"}}},"AnnouncementSeverity":{"type":"string","enum":["info","warning","critical"],"description":"Severity level. `critical` is reserved for genuine break-glass messages."},"AnnouncementSummary":{"type":"object","description":"Announcement without body. Returned by the list endpoint.","required":["id","title","severity","publishedAt","expiresAt","minVersion","maxVersion","link","readAt"],"properties":{"id":{"type":"string","description":"ULID, immutable once published."},"title":{"type":"string"},"severity":{"type":"string","enum":["info","warning","critical"],"description":"Severity level. `critical` is reserved for genuine break-glass messages."},"publishedAt":{"type":"string","format":"date-time","description":"ISO-8601 UTC. Drives sort order."},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"Null = no expiry."},"minVersion":{"type":"string","nullable":true,"description":"Minimum running version for this announcement to apply."},"maxVersion":{"type":"string","nullable":true,"description":"Maximum running version for this announcement to apply."},"link":{"type":"string","format":"uri","nullable":true,"description":"Optional external \\"Read more\\" URL."},"readAt":{"type":"string","format":"date-time","nullable":true,"description":"When the announcement was opened in the app. Null = unread."}}},"AnnouncementDetail":{"type":"object","description":"Announcement with the full markdown body. Returned by the detail endpoint.","required":["id","title","severity","publishedAt","expiresAt","minVersion","maxVersion","link","readAt","body"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"severity":{"type":"string","enum":["info","warning","critical"],"description":"Severity level. `critical` is reserved for genuine break-glass messages."},"publishedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time","nullable":true},"minVersion":{"type":"string","nullable":true},"maxVersion":{"type":"string","nullable":true},"link":{"type":"string","format":"uri","nullable":true},"readAt":{"type":"string","format":"date-time","nullable":true},"body":{"type":"string","nullable":true,"description":"Raw markdown body. Lazy-fetched from the bulletin on first call.\\nMay be null briefly if the lazy fetch fails; subsequent calls retry.\\n"}}},"ArrType":{"type":"string","enum":["radarr","sonarr"],"description":"Type of Arr instance"},"CustomFormatRef":{"type":"object","required":["id","name"],"properties":{"id":{"type":"integer","description":"Custom format ID"},"name":{"type":"string","description":"Custom format name"}}},"ScoreBreakdownItem":{"type":"object","required":["name","score"],"properties":{"name":{"type":"string","description":"Custom format name"},"score":{"type":"integer","description":"Score assigned by the quality profile"}}},"ArrInstance":{"type":"object","required":["id","name","type","url","enabled","library_refresh_interval","created_at","updated_at"],"properties":{"id":{"type":"integer","description":"Instance ID"},"name":{"type":"string","description":"Display name"},"type":{"type":"string","enum":["radarr","sonarr"],"description":"Type of Arr instance"},"url":{"type":"string","description":"Instance URL used by Profilarr\'s backend for API calls"},"external_url":{"type":"string","nullable":true,"description":"Optional external/browser-facing URL. When set, the UI uses this for\\n\\"Open in Radarr/Sonarr\\" browser links while Profilarr\'s backend continues\\nto call the instance using `url`. Useful for reverse-proxied deployments\\nwhere the internal and external hostnames differ.\\n","example":"https://radarr.example.com"},"tags":{"type":"string","nullable":true,"description":"JSON array of tags"},"enabled":{"type":"integer","description":"Whether the instance is active (0 or 1)"},"library_refresh_interval":{"type":"integer","description":"Library cache refresh interval in minutes (0 = manual)"},"library_last_refreshed_at":{"type":"string","nullable":true,"description":"Last library refresh timestamp"},"created_at":{"type":"string","description":"Creation timestamp"},"updated_at":{"type":"string","description":"Last update timestamp"}}},"DatabaseInstance":{"type":"object","required":["id","uuid","name","repository_url","sync_strategy","auto_pull","enabled","is_private","local_ops_enabled","conflict_strategy","hasPat","created_at","updated_at"],"properties":{"id":{"type":"integer","description":"Database instance ID"},"uuid":{"type":"string","format":"uuid","description":"Unique identifier"},"name":{"type":"string","description":"Display name"},"repository_url":{"type":"string","description":"GitHub repository URL"},"sync_strategy":{"type":"integer","description":"Auto-sync interval in minutes (0 = manual only)"},"auto_pull":{"type":"integer","description":"Whether to automatically pull updates (0 or 1)"},"enabled":{"type":"integer","description":"Whether the database is active (0 or 1)"},"is_private":{"type":"integer","description":"Whether the repository is private (0 or 1)"},"local_ops_enabled":{"type":"integer","description":"Whether local ops editing is enabled (0 or 1)"},"git_user_name":{"type":"string","nullable":true,"description":"Git user name for commits"},"git_user_email":{"type":"string","nullable":true,"description":"Git user email for commits"},"conflict_strategy":{"type":"string","enum":["override","align","ask"],"description":"How to handle conflicts between local tweaks and upstream updates"},"last_synced_at":{"type":"string","nullable":true,"description":"Last successful sync timestamp"},"created_at":{"type":"string","description":"Creation timestamp"},"updated_at":{"type":"string","description":"Last update timestamp"},"hasPat":{"type":"boolean","description":"Whether a personal access token is configured"}}},"CreateDatabaseInput":{"type":"object","required":["name","repository_url"],"properties":{"name":{"type":"string","description":"Display name (must be unique)"},"repository_url":{"type":"string","description":"GitHub repository URL"},"branch":{"type":"string","description":"Git branch to clone (defaults to remote\'s default branch)"},"personal_access_token":{"type":"string","description":"GitHub PAT for private repos and push access"},"git_user_name":{"type":"string","description":"Required when personal_access_token is set"},"git_user_email":{"type":"string","description":"Required when personal_access_token is set"},"sync_strategy":{"type":"integer","default":0,"description":"Auto-sync interval in minutes (0 = manual only)"},"auto_pull":{"type":"boolean","default":false,"description":"Whether to automatically pull updates"},"local_ops_enabled":{"type":"boolean","default":false,"description":"Force writes to local user ops even with a PAT (requires personal_access_token)"},"conflict_strategy":{"type":"string","enum":["override","align","ask"],"default":"override","description":"How to handle conflicts (only valid without a PAT, or with PAT + local_ops_enabled)"}}},"UpdateDatabaseInput":{"type":"object","description":"All fields are optional. Unknown fields are silently ignored.","properties":{"name":{"type":"string","description":"Display name (must be unique)"},"personal_access_token":{"type":"string","description":"GitHub PAT for private repos and push access"},"git_user_name":{"type":"string","description":"Required when personal_access_token is set"},"git_user_email":{"type":"string","description":"Required when personal_access_token is set"},"sync_strategy":{"type":"integer","description":"Auto-sync interval in minutes (0 = manual only)"},"auto_pull":{"type":"boolean","description":"Whether to automatically pull updates"},"local_ops_enabled":{"type":"boolean","description":"Force writes to local user ops even with a PAT (requires personal_access_token)"},"conflict_strategy":{"type":"string","enum":["override","align","ask"],"description":"How to handle conflicts (only valid without a PAT, or with PAT + local_ops_enabled)"}}},"SyncTriggerResponse":{"type":"object","required":["jobId"],"properties":{"jobId":{"type":"integer","description":"Job queue ID to poll via GET /api/v1/jobs/{jobId}"}}},"JobStatus":{"type":"string","enum":["queued","running","success","failed","cancelled"],"description":"Current state of the job in the queue"},"JobSource":{"type":"string","enum":["manual","schedule","system"],"description":"How the job was triggered"},"JobRunResult":{"type":"object","required":["status","output","error","durationMs"],"properties":{"status":{"type":"string","enum":["success","failure","skipped","cancelled"],"description":"Outcome of the job execution"},"output":{"type":"string","nullable":true,"description":"Human-readable output from the handler"},"error":{"type":"string","nullable":true,"description":"Error message if the job failed"},"durationMs":{"type":"integer","description":"Execution time in milliseconds"}}},"JobResponse":{"type":"object","required":["id","jobType","status","source","createdAt","startedAt","finishedAt","result"],"properties":{"id":{"type":"integer","description":"Job queue ID"},"jobType":{"type":"string","description":"Job type identifier (e.g. backup.create, arr.sync)"},"status":{"type":"string","enum":["queued","running","success","failed","cancelled"],"description":"Current state of the job in the queue"},"source":{"type":"string","enum":["manual","schedule","system"],"description":"How the job was triggered"},"createdAt":{"type":"string","description":"When the job was enqueued"},"startedAt":{"type":"string","nullable":true,"description":"When execution started (null if still queued)"},"finishedAt":{"type":"string","nullable":true,"description":"When execution finished (null if not yet complete)"},"result":{"oneOf":[{"type":"object","required":["status","output","error","durationMs"],"properties":{"status":{"type":"string","enum":["success","failure","skipped","cancelled"],"description":"Outcome of the job execution"},"output":{"type":"string","nullable":true,"description":"Human-readable output from the handler"},"error":{"type":"string","nullable":true,"description":"Error message if the job failed"},"durationMs":{"type":"integer","description":"Execution time in milliseconds"}}},{"type":"null"}],"description":"Latest run result, or null if the job has not executed yet"}}},"BackupFile":{"type":"object","required":["filename","created","size","sizeFormatted"],"properties":{"filename":{"type":"string","description":"Backup archive filename","example":"backup-2026-03-15-100005.tar.gz"},"created":{"type":"string","format":"date-time","description":"File modification time (when the backup was created)"},"size":{"type":"integer","description":"File size in bytes"},"sizeFormatted":{"type":"string","description":"Human-readable file size","example":"12.34 MB"}}},"BackupCreateResponse":{"type":"object","required":["jobId"],"properties":{"jobId":{"type":"integer","description":"Job queue ID. Poll GET /api/v1/jobs/{jobId} for status."}}},"BackupUploadResponse":{"type":"object","required":["filename","size","sizeFormatted"],"properties":{"filename":{"type":"string","description":"Stored filename (may differ from upload name)"},"size":{"type":"integer","description":"File size in bytes"},"sizeFormatted":{"type":"string","description":"Human-readable file size"}}},"BackupSettings":{"type":"object","required":["schedule","retentionDays","enabled","includeDatabase","compressionEnabled"],"properties":{"schedule":{"type":"string","enum":["hourly","daily","weekly","monthly"],"description":"How often automatic backups run"},"retentionDays":{"type":"integer","minimum":1,"maximum":365,"description":"Days to keep backups before cleanup deletes them"},"enabled":{"type":"boolean","description":"Whether automatic backups are enabled"},"includeDatabase":{"type":"boolean","description":"Whether to include the database in backups"},"compressionEnabled":{"type":"boolean","description":"Whether backup compression is enabled"}}},"BackupSettingsUpdate":{"type":"object","description":"All fields are optional. Only provided fields are updated.","properties":{"schedule":{"type":"string","enum":["hourly","daily","weekly","monthly"]},"retentionDays":{"type":"integer","minimum":1,"maximum":365},"enabled":{"type":"boolean"}}}}}')
    };
    GET11 = async () => {
      return json(v1_openapi_default);
    };
  }
});

// dist/build/server/entries/endpoints/api/v1/status/_server.ts.js
var server_ts_exports14 = {};
__export(server_ts_exports14, {
  GET: () => GET12
});
function buildDatabases() {
  return databaseInstancesQueries.getAll().map((inst) => {
    const cache3 = getCache(inst.id);
    const counts = cache3?.isBuilt() ?? false ? {
      customFormats: cache3.queryOne("SELECT COUNT(*) as c FROM custom_formats")?.c ?? 0,
      qualityProfiles: cache3.queryOne("SELECT COUNT(*) as c FROM quality_profiles")?.c ?? 0,
      regularExpressions: cache3.queryOne("SELECT COUNT(*) as c FROM regular_expressions")?.c ?? 0,
      delayProfiles: cache3.queryOne("SELECT COUNT(*) as c FROM delay_profiles")?.c ?? 0
    } : {
      customFormats: 0,
      qualityProfiles: 0,
      regularExpressions: 0,
      delayProfiles: 0
    };
    return {
      id: inst.id,
      name: inst.name,
      enabled: inst.enabled === 1,
      lastSyncedAt: inst.last_synced_at,
      syncStrategy: inst.sync_strategy === 0 ? "manual" : "auto",
      counts
    };
  });
}
function buildArrs() {
  return arrInstancesQueries.getAll().map((inst) => {
    const qpSync = arrSyncQueries.getQualityProfilesSync(inst.id);
    const qpStatus = arrSyncQueries.getSectionSyncStatus(inst.id, "qualityProfiles");
    const dpSync = arrSyncQueries.getDelayProfilesSync(inst.id);
    const dpStatus = arrSyncQueries.getSectionSyncStatus(inst.id, "delayProfiles");
    const mmSync = arrSyncQueries.getMediaManagementSync(inst.id);
    const mmStatus = arrSyncQueries.getSectionSyncStatus(inst.id, "mediaManagement");
    const mmConfigured = mmSync.namingDatabaseId !== null || mmSync.qualityDefinitionsDatabaseId !== null || mmSync.mediaSettingsDatabaseId !== null;
    return {
      id: inst.id,
      name: inst.name,
      type: inst.type,
      enabled: inst.enabled === 1,
      sync: {
        qualityProfiles: {
          count: qpSync.selections.length,
          status: qpStatus?.sync_status ?? "idle",
          lastSyncedAt: qpStatus?.last_synced_at ?? null
        },
        delayProfiles: {
          configured: dpSync.databaseId !== null,
          status: dpStatus?.sync_status ?? "idle",
          lastSyncedAt: dpStatus?.last_synced_at ?? null
        },
        mediaManagement: {
          configured: mmConfigured,
          status: mmStatus?.sync_status ?? "idle",
          lastSyncedAt: mmStatus?.last_synced_at ?? null
        }
      },
      drift: null
    };
  });
}
function buildJobs() {
  return {
    active: db.queryFirst("SELECT COUNT(*) as c FROM job_queue WHERE status = 'running'")?.c ?? 0,
    queued: db.queryFirst("SELECT COUNT(*) as c FROM job_queue WHERE status = 'queued'")?.c ?? 0,
    nextRunAt: db.queryFirst("SELECT run_at FROM job_queue WHERE status = 'queued' ORDER BY run_at ASC LIMIT 1")?.run_at ?? null
  };
}
async function buildBackups() {
  const enabled3 = backupSettingsQueries.get()?.enabled === 1;
  let lastBackupAt = null;
  if (enabled3) {
    const backupPath = config.paths.backups;
    let latestTime = null;
    try {
      for await (const entry of Deno.readDir(backupPath)) if (entry.isFile && entry.name.startsWith("backup-") && entry.name.endsWith(".tar.gz")) {
        const stat = await Deno.stat(`${backupPath}/${entry.name}`);
        if (!latestTime || stat.mtime.getTime() > latestTime) {
          latestTime = stat.mtime.getTime();
          lastBackupAt = stat.mtime.toISOString();
        }
      }
    } catch {
    }
  }
  return {
    enabled: enabled3,
    lastBackupAt
  };
}
var startupTime, GET12;
var init_server_ts14 = __esm({
  async "dist/build/server/entries/endpoints/api/v1/status/_server.ts.js"() {
    "use strict";
    await init_db();
    init_config();
    await init_announcements();
    init_build();
    await init_arrSync();
    await init_databaseInstances();
    await init_arrInstances();
    init_registry();
    await init_backupSettings();
    init_exports();
    startupTime = Date.now();
    GET12 = async () => {
      const response = {
        version: build.version,
        uptime: Math.floor((Date.now() - startupTime) / 1e3),
        timezone: config.timezone,
        databases: buildDatabases(),
        arrs: buildArrs(),
        jobs: buildJobs(),
        backups: await buildBackups(),
        announcements: { unread: getUnreadCount$1() }
      };
      return json(response);
    };
  }
});

// dist/build/server/entries/endpoints/arr/validate/_server.ts.js
var server_ts_exports15 = {};
__export(server_ts_exports15, {
  POST: () => POST5
});
var VALID_TYPES2, POST5;
var init_server_ts15 = __esm({
  async "dist/build/server/entries/endpoints/arr/validate/_server.ts.js"() {
    "use strict";
    await init_factory();
    init_exports();
    VALID_TYPES2 = ["radarr", "sonarr"];
    POST5 = async ({ request }) => {
      try {
        const { type, url, apiKey } = await request.json();
        if (!type || !url || !apiKey) return json({
          success: false,
          error: "Missing required fields"
        }, { status: 400 });
        if (!VALID_TYPES2.includes(type)) return json({
          success: false,
          error: "Invalid arr type"
        }, { status: 400 });
        const client2 = createArrClient(type, url, apiKey, {
          timeout: 3e3,
          retries: 0
        });
        const isConnected = await client2.testConnection();
        client2.close();
        if (isConnected) return json({ success: true });
        else return json({
          success: false,
          error: "Connection test failed"
        }, { status: 400 });
      } catch (error2) {
        return json({
          success: false,
          error: error2 instanceof Error ? error2.message : "Unknown error"
        }, { status: 500 });
      }
    };
  }
});

// dist/build/server/entries/endpoints/arr/_id_/library/movies/_server.ts.js
var server_ts_exports16 = {};
__export(server_ts_exports16, {
  GET: () => GET13
});
function getNextRefreshAt(instanceId) {
  return jobQueueQueries.getByDedupeKey(`arr.library.refresh:${instanceId}`)?.runAt ?? null;
}
var MANUAL_CACHE_TTL, GET13;
var init_server_ts16 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/library/movies/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_jobQueue();
    await init_queueService();
    await init_base();
    await init_radarr();
    init_cache2();
    init_exports();
    MANUAL_CACHE_TTL = 86400;
    GET13 = async ({ params }) => {
      const instanceId = parseInt(params.id ?? "", 10);
      if (!Number.isFinite(instanceId)) return json({ error: "Invalid instance ID" }, { status: 400 });
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return json({ error: "Instance not found" }, { status: 404 });
      if (instance.type !== "radarr") return json({ error: `Movies are only available for Radarr instances` }, { status: 400 });
      const cacheKey = `library:${instanceId}`;
      const cached2 = cache.get(cacheKey);
      if (cached2) return json({
        items: cached2,
        refreshedAt: instance.library_last_refreshed_at,
        nextRefreshAt: getNextRefreshAt(instanceId)
      });
      const ttl = instance.library_refresh_interval > 0 ? instance.library_refresh_interval * 60 : MANUAL_CACHE_TTL;
      const profilarrProfileNames = await getProfilarrProfileNames();
      const client2 = new RadarrClient(instance.url, instance.api_key, { timeout: LIBRARY_REQUEST_TIMEOUT_MS });
      try {
        const items = await client2.getLibrary(profilarrProfileNames);
        const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
        cache.set(cacheKey, items, ttl);
        arrInstancesQueries.updateLibraryRefreshedAt(instanceId, refreshedAt);
        scheduleLibraryRefreshForInstance(instanceId);
        await logger.info(`Fetched library for ${instance.name}`, {
          source: "arr/library/movies",
          meta: {
            instanceId,
            movieCount: items.length
          }
        });
        return json({
          items,
          refreshedAt,
          nextRefreshAt: getNextRefreshAt(instanceId)
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to fetch library";
        await logger.error(`Failed to fetch library for ${instance.name}`, {
          source: "arr/library/movies",
          meta: {
            instanceId,
            error: message2
          }
        });
        return json({ error: message2 }, { status: 500 });
      } finally {
        client2.close();
      }
    };
  }
});

// dist/build/server/chunks/releaseImport.js
function normalizeRadarrFlags(flags2) {
  return flags2.map((f2) => f2.replace(/^G_/i, "").toLowerCase().replace(/_/g, " "));
}
function decodeSonarrFlags(bitmask) {
  const flags2 = [];
  const sonarrFlags = INDEXER_FLAGS.sonarr;
  for (const [name, value2] of Object.entries(sonarrFlags)) if (bitmask & value2) flags2.push(name.replace(/_/g, " "));
  return flags2;
}
function sanitizeIndexerName(name) {
  return name.replace(/\s*\(Prowlarr\)$/i, "").replace(/\s*\(Jackett\)$/i, "").trim();
}
function normalizeTitle(title) {
  return title.toLowerCase().replace(/[._]/g, " ").replace(/\s+/g, " ").trim();
}
function titleSimilarity(title1, title2) {
  const norm1 = normalizeTitle(title1);
  const norm2 = normalizeTitle(title2);
  if (norm1 === norm2) return 1;
  const bigrams1 = getBigrams(norm1);
  const bigrams2 = getBigrams(norm2);
  return 2 * new Set([...bigrams1].filter((b3) => bigrams2.has(b3))).size / (bigrams1.size + bigrams2.size);
}
function getBigrams(str2) {
  const bigrams = /* @__PURE__ */ new Set();
  for (let i = 0; i < str2.length - 1; i++) bigrams.add(str2.slice(i, i + 2));
  return bigrams;
}
function union(arr1, arr2) {
  return [.../* @__PURE__ */ new Set([...arr1, ...arr2])];
}
function groupRadarrReleases(releases, titleThreshold = 0.9, sizeTolerance = 0.05) {
  const groups = [];
  for (const release of releases) {
    const match = groups.find((g3) => {
      const similarity = titleSimilarity(g3.title, release.title);
      const sizeDiff = Math.abs(g3.size - release.size) / Math.max(g3.size, 1);
      return similarity > titleThreshold && sizeDiff < sizeTolerance;
    });
    const languages = release.languages.map((l3) => l3.name);
    const flags2 = normalizeRadarrFlags(release.indexerFlags);
    const indexer = sanitizeIndexerName(release.indexer);
    if (match) {
      match.indexers = union(match.indexers, [indexer]);
      match.languages = union(match.languages, languages);
      match.flags = union(match.flags, flags2);
      match.occurrences++;
    } else groups.push({
      title: release.title,
      size: release.size,
      indexers: [indexer],
      languages,
      flags: flags2,
      occurrences: 1
    });
  }
  return groups;
}
function groupSonarrReleases(releases, titleThreshold = 0.9, sizeTolerance = 0.05) {
  const groups = [];
  for (const release of releases) {
    const match = groups.find((g3) => {
      const similarity = titleSimilarity(g3.title, release.title);
      const sizeDiff = Math.abs(g3.size - release.size) / Math.max(g3.size, 1);
      return similarity > titleThreshold && sizeDiff < sizeTolerance;
    });
    const languages = release.languages.map((l3) => l3.name);
    const flags2 = decodeSonarrFlags(release.indexerFlags);
    const indexer = sanitizeIndexerName(release.indexer);
    if (match) {
      match.indexers = union(match.indexers, [indexer]);
      match.languages = union(match.languages, languages);
      match.flags = union(match.flags, flags2);
      match.occurrences++;
    } else groups.push({
      title: release.title,
      size: release.size,
      indexers: [indexer],
      languages,
      flags: flags2,
      occurrences: 1
    });
  }
  return groups;
}
var init_releaseImport = __esm({
  "dist/build/server/chunks/releaseImport.js"() {
    "use strict";
    init_mappings();
  }
});

// dist/build/server/entries/endpoints/arr/_id_/library/movies/_movieId_/releases/_server.ts.js
var server_ts_exports17 = {};
__export(server_ts_exports17, {
  GET: () => GET14
});
var GET14;
var init_server_ts17 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/library/movies/_movieId_/releases/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_radarr();
    init_releaseImport();
    init_exports();
    GET14 = async ({ params }) => {
      const instanceId = parseInt(params.id ?? "", 10);
      const movieId = parseInt(params.movieId ?? "", 10);
      if (!Number.isFinite(instanceId) || !Number.isFinite(movieId)) return json({ error: "Invalid instance or movie ID" }, { status: 400 });
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return json({ error: "Instance not found" }, { status: 404 });
      if (instance.type !== "radarr") return json({ error: "Movie releases are only available for Radarr instances" }, { status: 400 });
      const client2 = new RadarrClient(instance.url, instance.api_key);
      try {
        const releases = await client2.getReleases(movieId);
        const grouped = groupRadarrReleases(releases);
        return json({
          rawCount: releases.length,
          releases: grouped
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to fetch releases";
        await logger.error(`Failed to fetch releases for movie ${movieId}`, {
          source: "arr/library/movies/releases",
          meta: {
            instanceId,
            movieId,
            error: message2
          }
        });
        return json({ error: message2 }, { status: 500 });
      } finally {
        client2.close();
      }
    };
  }
});

// dist/build/server/entries/endpoints/arr/_id_/library/refresh/_server.ts.js
var server_ts_exports18 = {};
__export(server_ts_exports18, {
  POST: () => POST6
});
var POST6;
var init_server_ts18 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/library/refresh/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    init_cache2();
    init_exports();
    POST6 = async ({ params }) => {
      const instanceId = parseInt(params.id ?? "", 10);
      if (!Number.isFinite(instanceId)) return json({ error: "Invalid instance ID" }, { status: 400 });
      if (!arrInstancesQueries.getById(instanceId)) return json({ error: "Instance not found" }, { status: 404 });
      cache.delete(`library:${instanceId}`);
      cache.deleteByPrefix(`library-episodes:${instanceId}:`);
      await logger.debug(`Manual library refresh triggered`, {
        source: "arr/library/refresh",
        meta: { instanceId }
      });
      return json({ success: true });
    };
  }
});

// dist/build/server/entries/endpoints/arr/_id_/library/series/_server.ts.js
var server_ts_exports19 = {};
__export(server_ts_exports19, {
  GET: () => GET15
});
function getNextRefreshAt2(instanceId) {
  return jobQueueQueries.getByDedupeKey(`arr.library.refresh:${instanceId}`)?.runAt ?? null;
}
function stripSeasons(items) {
  return items.map(({ seasons: _seasons, ...rest }) => rest);
}
var MANUAL_CACHE_TTL2, GET15;
var init_server_ts19 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/library/series/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_jobQueue();
    await init_queueService();
    await init_base();
    await init_sonarr();
    init_cache2();
    init_exports();
    MANUAL_CACHE_TTL2 = 86400;
    GET15 = async ({ params }) => {
      const instanceId = parseInt(params.id ?? "", 10);
      if (!Number.isFinite(instanceId)) return json({ error: "Invalid instance ID" }, { status: 400 });
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return json({ error: "Instance not found" }, { status: 404 });
      if (instance.type !== "sonarr") return json({ error: `Series are only available for Sonarr instances` }, { status: 400 });
      const cacheKey = `library:${instanceId}`;
      const cached2 = cache.get(cacheKey);
      if (cached2) return json({
        items: stripSeasons(cached2),
        refreshedAt: instance.library_last_refreshed_at,
        nextRefreshAt: getNextRefreshAt2(instanceId)
      });
      const ttl = instance.library_refresh_interval > 0 ? instance.library_refresh_interval * 60 : MANUAL_CACHE_TTL2;
      const profilarrProfileNames = await getProfilarrProfileNames();
      const client2 = new SonarrClient(instance.url, instance.api_key, { timeout: LIBRARY_REQUEST_TIMEOUT_MS });
      try {
        const items = await client2.getLibrary(profilarrProfileNames);
        const refreshedAt = (/* @__PURE__ */ new Date()).toISOString();
        cache.set(cacheKey, items, ttl);
        arrInstancesQueries.updateLibraryRefreshedAt(instanceId, refreshedAt);
        scheduleLibraryRefreshForInstance(instanceId);
        await logger.info(`Fetched library for ${instance.name}`, {
          source: "arr/library/series",
          meta: {
            instanceId,
            seriesCount: items.length
          }
        });
        return json({
          items: stripSeasons(items),
          refreshedAt,
          nextRefreshAt: getNextRefreshAt2(instanceId)
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to fetch library";
        await logger.error(`Failed to fetch library for ${instance.name}`, {
          source: "arr/library/series",
          meta: {
            instanceId,
            error: message2
          }
        });
        return json({ error: message2 }, { status: 500 });
      } finally {
        client2.close();
      }
    };
  }
});

// dist/build/server/entries/endpoints/arr/_id_/library/series/_seriesId_/seasons/_server.ts.js
var server_ts_exports20 = {};
__export(server_ts_exports20, {
  GET: () => GET16
});
async function getLibraryCached(instanceId) {
  const cacheKey = `library:${instanceId}`;
  const cached2 = cache.get(cacheKey);
  if (cached2) return cached2;
  const instance = arrInstancesQueries.getById(instanceId);
  if (!instance) throw new Error("Instance not found");
  const ttl = instance.library_refresh_interval > 0 ? instance.library_refresh_interval * 60 : MANUAL_CACHE_TTL3;
  const profilarrProfileNames = await getProfilarrProfileNames();
  const client2 = new SonarrClient(instance.url, instance.api_key);
  try {
    const items = await client2.getLibrary(profilarrProfileNames);
    cache.set(cacheKey, items, ttl);
    return items;
  } finally {
    client2.close();
  }
}
var MANUAL_CACHE_TTL3, GET16;
var init_server_ts20 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/library/series/_seriesId_/seasons/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_queueService();
    await init_sonarr();
    init_cache2();
    init_exports();
    MANUAL_CACHE_TTL3 = 86400;
    GET16 = async ({ params }) => {
      const instanceId = parseInt(params.id ?? "", 10);
      const seriesId = parseInt(params.seriesId ?? "", 10);
      if (!Number.isFinite(instanceId) || !Number.isFinite(seriesId)) return json({ error: "Invalid instance or series ID" }, { status: 400 });
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return json({ error: "Instance not found" }, { status: 404 });
      if (instance.type !== "sonarr") return json({ error: "Seasons are only available for Sonarr instances" }, { status: 400 });
      try {
        const series = (await getLibraryCached(instanceId)).find((s3) => s3.id === seriesId);
        if (!series) return json({ error: "Series not found" }, { status: 404 });
        return json({ seasons: series.seasons });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to fetch seasons";
        await logger.error(`Failed to fetch seasons for series ${seriesId}`, {
          source: "arr/library/seasons",
          meta: {
            instanceId,
            seriesId,
            error: message2
          }
        });
        return json({ error: message2 }, { status: 500 });
      }
    };
  }
});

// dist/build/server/entries/endpoints/arr/_id_/library/series/_seriesId_/seasons/_seasonNumber_/episodes/_server.ts.js
var server_ts_exports21 = {};
__export(server_ts_exports21, {
  GET: () => GET17
});
async function getSeriesEpisodesCached(instance, seriesId) {
  const cacheKey = `library-episodes:${instance.id}:${seriesId}`;
  const cached2 = cache.get(cacheKey);
  if (cached2) return cached2;
  const client2 = new SonarrClient(instance.url, instance.api_key);
  try {
    const profiles = await client2.getQualityProfiles();
    const series = await client2.getSeries(seriesId);
    const profile = profiles.find((p2) => p2.id === series.qualityProfileId);
    if (!profile) throw new Error(`Quality profile not found for series ${seriesId}`);
    const episodes = await client2.getSeriesEpisodeDetails(seriesId, profile);
    cache.set(cacheKey, episodes, EPISODE_CACHE_TTL);
    return episodes;
  } finally {
    client2.close();
  }
}
var EPISODE_CACHE_TTL, GET17;
var init_server_ts21 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/library/series/_seriesId_/seasons/_seasonNumber_/episodes/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_sonarr();
    init_cache2();
    init_exports();
    EPISODE_CACHE_TTL = 300;
    GET17 = async ({ params }) => {
      const instanceId = parseInt(params.id ?? "", 10);
      const seriesId = parseInt(params.seriesId ?? "", 10);
      const seasonNumber = parseInt(params.seasonNumber ?? "", 10);
      if (!Number.isFinite(instanceId) || !Number.isFinite(seriesId) || !Number.isFinite(seasonNumber)) return json({ error: "Invalid instance, series, or season number" }, { status: 400 });
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return json({ error: "Instance not found" }, { status: 404 });
      if (instance.type !== "sonarr") return json({ error: "Episodes are only available for Sonarr instances" }, { status: 400 });
      try {
        const episodes = (await getSeriesEpisodesCached(instance, seriesId)).filter((ep) => ep.seasonNumber === seasonNumber);
        await logger.info(`Fetched episodes for series ${seriesId} season ${seasonNumber}`, {
          source: "arr/library/episodes",
          meta: {
            instanceId,
            seriesId,
            seasonNumber,
            episodeCount: episodes.length
          }
        });
        return json({ episodes });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to fetch episodes";
        await logger.error(`Failed to fetch episodes for series ${seriesId} season ${seasonNumber}`, {
          source: "arr/library/episodes",
          meta: {
            instanceId,
            seriesId,
            seasonNumber,
            error: message2
          }
        });
        return json({ error: message2 }, { status: 500 });
      }
    };
  }
});

// dist/build/server/entries/endpoints/arr/_id_/library/series/_seriesId_/seasons/_seasonNumber_/releases/_server.ts.js
var server_ts_exports22 = {};
__export(server_ts_exports22, {
  GET: () => GET18
});
var GET18;
var init_server_ts22 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/library/series/_seriesId_/seasons/_seasonNumber_/releases/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrInstances();
    await init_sonarr();
    init_releaseImport();
    init_exports();
    GET18 = async ({ params }) => {
      const instanceId = parseInt(params.id ?? "", 10);
      const seriesId = parseInt(params.seriesId ?? "", 10);
      const seasonNumber = parseInt(params.seasonNumber ?? "", 10);
      if (!Number.isFinite(instanceId) || !Number.isFinite(seriesId) || !Number.isFinite(seasonNumber)) return json({ error: "Invalid instance, series, or season number" }, { status: 400 });
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return json({ error: "Instance not found" }, { status: 404 });
      if (instance.type !== "sonarr") return json({ error: "Season releases are only available for Sonarr instances" }, { status: 400 });
      const client2 = new SonarrClient(instance.url, instance.api_key);
      try {
        const releases = await client2.getSeasonPackReleases(seriesId, seasonNumber);
        const grouped = groupSonarrReleases(releases);
        return json({
          rawCount: releases.length,
          releases: grouped
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to fetch releases";
        await logger.error(`Failed to fetch releases for series ${seriesId} season ${seasonNumber}`, {
          source: "arr/library/series/seasons/releases",
          meta: {
            instanceId,
            seriesId,
            seasonNumber,
            error: message2
          }
        });
        return json({ error: message2 }, { status: 500 });
      } finally {
        client2.close();
      }
    };
  }
});

// dist/build/server/entries/endpoints/arr/_id_/logs/_server.ts.js
var server_ts_exports23 = {};
__export(server_ts_exports23, {
  GET: () => GET19
});
var GET19;
var init_server_ts23 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/logs/_server.ts.js"() {
    "use strict";
    await init_arrInstances();
    await init_factory();
    init_exports();
    GET19 = async ({ params, url }) => {
      const id = parseInt(params.id || "", 10);
      if (isNaN(id)) error(400, "Invalid instance ID");
      const instance = arrInstancesQueries.getById(id);
      if (!instance) error(404, "Instance not found");
      const page2 = parseInt(url.searchParams.get("page") || "1", 10);
      const pageSize = parseInt(url.searchParams.get("pageSize") || "50", 10);
      const level = url.searchParams.get("level") || void 0;
      const client2 = createArrClient(instance.type, instance.url, instance.api_key);
      try {
        const logs = await client2.getLogs({
          page: page2,
          pageSize,
          sortKey: "time",
          sortDirection: "descending",
          level
        });
        return json(logs);
      } catch (err) {
        error(502, `Failed to fetch logs: ${err instanceof Error ? err.message : "Unknown error"}`);
      } finally {
        client2.close();
      }
    };
  }
});

// dist/build/server/entries/endpoints/arr/_id_/resync/_server.ts.js
var server_ts_exports24 = {};
__export(server_ts_exports24, {
  POST: () => POST7
});
async function syncQualityProfile(instanceId, databaseId, profileName2) {
  const instance = arrInstancesQueries.getById(instanceId);
  if (!instance) return {
    success: false,
    error: "Instance not found"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: `PCD cache not found for database ${databaseId}`
  };
  const instanceType = instance.type;
  const client2 = createArrClient(instance.type, instance.url, instance.api_key);
  try {
    const pcdProfile = await fetchQualityProfileFromPcd(cache3, profileName2, instanceType);
    if (!pcdProfile) return {
      success: false,
      error: `Quality profile "${profileName2}" not found in PCD`
    };
    const existingProfile = (await client2.getQualityProfiles()).find((p2) => p2.name === profileName2);
    const referencedNames = await getCustomFormatsForProfile(cache3, profileName2, instanceType);
    const pcdFormats = /* @__PURE__ */ new Map();
    for (const name of referencedNames) {
      const pcdFormat = await fetchCustomFormatFromPcd(cache3, name);
      if (pcdFormat) pcdFormats.set(name, pcdFormat);
    }
    const formatIdMap = await syncCustomFormats(client2, instanceId, instanceType, pcdFormats);
    const qualityMappings = await getQualityApiMappings(cache3, instanceType);
    const arrProfile = transformQualityProfile(pcdProfile, instanceType, qualityMappings, formatIdMap);
    arrProfile.name = profileName2;
    if (existingProfile) {
      arrProfile.id = existingProfile.id;
      await client2.updateQualityProfile(existingProfile.id, arrProfile);
      await logger.info(`Entity sync: updated quality profile "${profileName2}"`, {
        source: "EntitySync:QualityProfile",
        meta: {
          instanceId,
          databaseId,
          profileName: profileName2,
          action: "updated"
        }
      });
    } else {
      await client2.createQualityProfile(arrProfile);
      await logger.info(`Entity sync: created quality profile "${profileName2}"`, {
        source: "EntitySync:QualityProfile",
        meta: {
          instanceId,
          databaseId,
          profileName: profileName2,
          action: "created"
        }
      });
    }
    arrSyncQueries.touchSectionLastSynced(instanceId, "qualityProfiles");
    return { success: true };
  } catch (error2) {
    const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
    await logger.error(`Entity sync failed for quality profile "${profileName2}"`, {
      source: "EntitySync:QualityProfile",
      meta: {
        instanceId,
        databaseId,
        profileName: profileName2,
        error: errorMsg
      }
    });
    return {
      success: false,
      error: errorMsg
    };
  } finally {
    client2.close();
  }
}
async function syncCustomFormat(instanceId, databaseId, formatName) {
  const instance = arrInstancesQueries.getById(instanceId);
  if (!instance) return {
    success: false,
    error: "Instance not found"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: `PCD cache not found for database ${databaseId}`
  };
  const instanceType = instance.type;
  const client2 = createArrClient(instance.type, instance.url, instance.api_key);
  try {
    const pcdFormat = await fetchCustomFormatFromPcd(cache3, formatName);
    if (!pcdFormat) return {
      success: false,
      error: `Custom format "${formatName}" not found in PCD`
    };
    const existing = (await client2.getCustomFormats()).find((f2) => f2.name === formatName);
    const arrFormat = transformCustomFormat(pcdFormat, instanceType);
    arrFormat.name = formatName;
    if (existing) {
      arrFormat.id = existing.id;
      await client2.updateCustomFormat(existing.id, arrFormat);
      await logger.info(`Entity sync: updated custom format "${formatName}"`, {
        source: "EntitySync:CustomFormat",
        meta: {
          instanceId,
          databaseId,
          formatName,
          action: "updated"
        }
      });
    } else {
      await client2.createCustomFormat(arrFormat);
      await logger.info(`Entity sync: created custom format "${formatName}"`, {
        source: "EntitySync:CustomFormat",
        meta: {
          instanceId,
          databaseId,
          formatName,
          action: "created"
        }
      });
    }
    arrSyncQueries.touchSectionLastSynced(instanceId, "qualityProfiles");
    return { success: true };
  } catch (error2) {
    const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
    await logger.error(`Entity sync failed for custom format "${formatName}"`, {
      source: "EntitySync:CustomFormat",
      meta: {
        instanceId,
        databaseId,
        formatName,
        error: errorMsg
      }
    });
    return {
      success: false,
      error: errorMsg
    };
  } finally {
    client2.close();
  }
}
async function syncRegularExpression(instanceId, databaseId, regexName) {
  const instance = arrInstancesQueries.getById(instanceId);
  if (!instance) return {
    success: false,
    error: "Instance not found"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: `PCD cache not found for database ${databaseId}`
  };
  const instanceType = instance.type;
  const client2 = createArrClient(instance.type, instance.url, instance.api_key);
  try {
    const cfNames = await getCustomFormatsForRegex(cache3, regexName);
    if (cfNames.length === 0) return { success: true };
    const existingFormats = await client2.getCustomFormats();
    const existingMap = new Map(existingFormats.map((f2) => [f2.name, f2]));
    let synced = 0;
    for (const cfName of cfNames) {
      const pcdFormat = await fetchCustomFormatFromPcd(cache3, cfName);
      if (!pcdFormat) continue;
      const arrFormat = transformCustomFormat(pcdFormat, instanceType);
      arrFormat.name = cfName;
      const existing = existingMap.get(cfName);
      if (existing) {
        arrFormat.id = existing.id;
        await client2.updateCustomFormat(existing.id, arrFormat);
      } else await client2.createCustomFormat(arrFormat);
      synced++;
    }
    await logger.info(`Entity sync: synced ${synced} custom format(s) for regex "${regexName}"`, {
      source: "EntitySync:RegularExpression",
      meta: {
        instanceId,
        databaseId,
        regexName,
        cfNames,
        synced
      }
    });
    arrSyncQueries.touchSectionLastSynced(instanceId, "qualityProfiles");
    return { success: true };
  } catch (error2) {
    const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
    await logger.error(`Entity sync failed for regex "${regexName}"`, {
      source: "EntitySync:RegularExpression",
      meta: {
        instanceId,
        databaseId,
        regexName,
        error: errorMsg
      }
    });
    return {
      success: false,
      error: errorMsg
    };
  } finally {
    client2.close();
  }
}
async function syncDelayProfile(instanceId, databaseId, profileName2) {
  const instance = arrInstancesQueries.getById(instanceId);
  if (!instance) return {
    success: false,
    error: "Instance not found"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: `PCD cache not found for database ${databaseId}`
  };
  const client2 = createArrClient(instance.type, instance.url, instance.api_key);
  try {
    const profile = await getByName(cache3, profileName2);
    if (!profile) return {
      success: false,
      error: `Delay profile "${profileName2}" not found in PCD`
    };
    const transformed = transformDelayProfile(profile);
    await client2.updateDelayProfile(1, transformed);
    await logger.info(`Entity sync: updated delay profile "${profileName2}"`, {
      source: "EntitySync:DelayProfile",
      meta: {
        instanceId,
        databaseId,
        profileName: profileName2
      }
    });
    arrSyncQueries.touchSectionLastSynced(instanceId, "delayProfiles");
    return { success: true };
  } catch (error2) {
    const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
    await logger.error(`Entity sync failed for delay profile "${profileName2}"`, {
      source: "EntitySync:DelayProfile",
      meta: {
        instanceId,
        databaseId,
        profileName: profileName2,
        error: errorMsg
      }
    });
    return {
      success: false,
      error: errorMsg
    };
  } finally {
    client2.close();
  }
}
async function syncNaming(instanceId, databaseId, configName) {
  const instance = arrInstancesQueries.getById(instanceId);
  if (!instance) return {
    success: false,
    error: "Instance not found"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: `PCD cache not found for database ${databaseId}`
  };
  const client2 = createArrClient(instance.type, instance.url, instance.api_key);
  try {
    if (instance.type === "radarr") {
      const naming = await getRadarrByName$1(cache3, configName);
      if (!naming) return {
        success: false,
        error: `Radarr naming config "${configName}" not found in PCD`
      };
      const existing = await client2.getNamingConfig();
      const updated3 = mergeRadarrNamingConfig(existing, naming);
      await client2.updateNamingConfig(updated3);
    } else if (instance.type === "sonarr") {
      const naming = await getSonarrByName$1(cache3, configName);
      if (!naming) return {
        success: false,
        error: `Sonarr naming config "${configName}" not found in PCD`
      };
      const existing = await client2.getNamingConfig();
      const updated3 = mergeSonarrNamingConfig(existing, naming);
      await client2.updateNamingConfig(updated3);
    } else return {
      success: false,
      error: `Unsupported instance type: ${instance.type}`
    };
    await logger.info(`Entity sync: updated naming config "${configName}"`, {
      source: "EntitySync:Naming",
      meta: {
        instanceId,
        databaseId,
        configName,
        arrType: instance.type
      }
    });
    arrSyncQueries.touchSectionLastSynced(instanceId, "mediaManagement");
    return { success: true };
  } catch (error2) {
    const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
    await logger.error(`Entity sync failed for naming config "${configName}"`, {
      source: "EntitySync:Naming",
      meta: {
        instanceId,
        databaseId,
        configName,
        error: errorMsg
      }
    });
    return {
      success: false,
      error: errorMsg
    };
  } finally {
    client2.close();
  }
}
async function syncQualityDefinitions(instanceId, databaseId, configName) {
  const instance = arrInstancesQueries.getById(instanceId);
  if (!instance) return {
    success: false,
    error: "Instance not found"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: `PCD cache not found for database ${databaseId}`
  };
  const instanceType = instance.type;
  const client2 = createArrClient(instance.type, instance.url, instance.api_key);
  try {
    const qualityDefsConfig = await (instanceType === "radarr" ? getRadarrByName : getSonarrByName)(cache3, configName);
    if (!qualityDefsConfig) return {
      success: false,
      error: `Quality definitions config "${configName}" not found in PCD`
    };
    if (qualityDefsConfig.entries.length === 0) return {
      success: false,
      error: `Quality definitions config "${configName}" has no entries`
    };
    const apiMappings = await getQualityApiMappings(cache3, instanceType);
    const arrDefinitions = await client2.getQualityDefinitions();
    const transformed = transformQualityDefinitionsForArr(qualityDefsConfig.entries, apiMappings);
    const { updatedCount } = applyQualityDefinitionsToArr(arrDefinitions, transformed.definitions);
    if (updatedCount === 0) return {
      success: false,
      error: "No quality definitions matched for update"
    };
    await client2.updateQualityDefinitions(arrDefinitions);
    await logger.info(`Entity sync: updated ${updatedCount} quality definitions for "${configName}"`, {
      source: "EntitySync:QualityDefinitions",
      meta: {
        instanceId,
        databaseId,
        configName,
        updatedCount
      }
    });
    arrSyncQueries.touchSectionLastSynced(instanceId, "mediaManagement");
    return { success: true };
  } catch (error2) {
    const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
    await logger.error(`Entity sync failed for quality definitions "${configName}"`, {
      source: "EntitySync:QualityDefinitions",
      meta: {
        instanceId,
        databaseId,
        configName,
        error: errorMsg
      }
    });
    return {
      success: false,
      error: errorMsg
    };
  } finally {
    client2.close();
  }
}
async function syncMediaSettings(instanceId, databaseId, configName) {
  const instance = arrInstancesQueries.getById(instanceId);
  if (!instance) return {
    success: false,
    error: "Instance not found"
  };
  const cache3 = getCache(databaseId);
  if (!cache3) return {
    success: false,
    error: `PCD cache not found for database ${databaseId}`
  };
  const client2 = createArrClient(instance.type, instance.url, instance.api_key);
  try {
    const mediaSettings = await (instance.type === "radarr" ? getRadarrByName$2 : getSonarrByName$2)(cache3, configName);
    if (!mediaSettings) return {
      success: false,
      error: `Media settings config "${configName}" not found in PCD`
    };
    const existing = await client2.getMediaManagementConfig();
    const updated3 = mergeMediaSettingsConfig(existing, mediaSettings);
    await client2.updateMediaManagementConfig(updated3);
    await logger.info(`Entity sync: updated media settings "${configName}"`, {
      source: "EntitySync:MediaSettings",
      meta: {
        instanceId,
        databaseId,
        configName,
        arrType: instance.type
      }
    });
    arrSyncQueries.touchSectionLastSynced(instanceId, "mediaManagement");
    return { success: true };
  } catch (error2) {
    const errorMsg = error2 instanceof Error ? error2.message : "Unknown error";
    await logger.error(`Entity sync failed for media settings "${configName}"`, {
      source: "EntitySync:MediaSettings",
      meta: {
        instanceId,
        databaseId,
        configName,
        error: errorMsg
      }
    });
    return {
      success: false,
      error: errorMsg
    };
  } finally {
    client2.close();
  }
}
var ENTITY_TYPE_TO_SECTION, COOLDOWN_MS, POST7;
var init_server_ts24 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/resync/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_arrSync();
    await init_arrInstances();
    await init_queueService();
    await init_factory();
    init_registry();
    init_exports();
    ENTITY_TYPE_TO_SECTION = {
      qualityProfile: "qualityProfiles",
      customFormat: "qualityProfiles",
      regularExpression: "qualityProfiles",
      delayProfile: "delayProfiles",
      naming: "mediaManagement",
      qualityDefinitions: "mediaManagement",
      mediaSettings: "mediaManagement"
    };
    COOLDOWN_MS = 5e3;
    POST7 = async ({ params, request }) => {
      const instanceId = parseInt(params.id ?? "", 10);
      if (!Number.isFinite(instanceId)) return json({ error: "Invalid instance ID" }, { status: 400 });
      const { databaseId, entityName, entityType } = await request.json();
      if (!entityType || !ENTITY_TYPE_TO_SECTION[entityType]) return json({ error: `entityType must be one of: ${Object.keys(ENTITY_TYPE_TO_SECTION).join(", ")}` }, { status: 400 });
      if (!databaseId || typeof databaseId !== "number") return json({ error: "databaseId is required" }, { status: 400 });
      if (!entityName || typeof entityName !== "string") return json({ error: "entityName is required" }, { status: 400 });
      if (!arrInstancesQueries.getById(instanceId)) return json({ error: "Instance not found" }, { status: 404 });
      const section = ENTITY_TYPE_TO_SECTION[entityType];
      const status = arrSyncQueries.getSectionSyncStatus(instanceId, section);
      if (status) {
        if (status.sync_status === "pending" || status.sync_status === "in_progress") {
          await logger.debug(`Entity sync blocked: ${section} already ${status.sync_status}`, {
            source: "EntitySync:Cooldown",
            meta: {
              instanceId,
              section,
              syncStatus: status.sync_status
            }
          });
          return json({ error: "Sync already in progress" }, { status: 409 });
        }
        if (status.last_synced_at) {
          const elapsed = Date.now() - new Date(status.last_synced_at).getTime();
          if (elapsed < COOLDOWN_MS) {
            const retryAfter = Math.ceil((COOLDOWN_MS - elapsed) / 1e3);
            await logger.debug(`Entity sync cooldown: ${retryAfter}s remaining for ${section}`, {
              source: "EntitySync:Cooldown",
              meta: {
                instanceId,
                section,
                retryAfter,
                lastSyncedAt: status.last_synced_at
              }
            });
            return json({
              error: "Cooldown active",
              retryAfter
            }, { status: 409 });
          }
        }
      }
      try {
        let result;
        switch (entityType) {
          case "qualityProfile":
            result = await syncQualityProfile(instanceId, databaseId, entityName);
            break;
          case "customFormat":
            result = await syncCustomFormat(instanceId, databaseId, entityName);
            break;
          case "regularExpression":
            result = await syncRegularExpression(instanceId, databaseId, entityName);
            break;
          case "delayProfile":
            result = await syncDelayProfile(instanceId, databaseId, entityName);
            break;
          case "naming":
            result = await syncNaming(instanceId, databaseId, entityName);
            break;
          case "qualityDefinitions":
            result = await syncQualityDefinitions(instanceId, databaseId, entityName);
            break;
          case "mediaSettings":
            result = await syncMediaSettings(instanceId, databaseId, entityName);
        }
        if (result.success) return json({ success: true });
        return json({ error: result.error ?? "Sync failed" }, { status: 500 });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Sync failed";
        return json({ error: message2 }, { status: 500 });
      }
    };
  }
});

// dist/build/server/entries/endpoints/arr/_id_/settings/cleanup/preview/_server.ts.js
var server_ts_exports25 = {};
__export(server_ts_exports25, {
  GET: () => GET20
});
var GET20;
var init_server_ts25 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/settings/cleanup/preview/_server.ts.js"() {
    "use strict";
    await init_arrInstances();
    await init_queueService();
    await init_factory();
    init_exports();
    GET20 = async ({ params }) => {
      const instanceId = parseInt(params.id ?? "", 10);
      if (!Number.isFinite(instanceId)) return json({ error: "Invalid instance ID" }, { status: 400 });
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return json({ error: "Instance not found" }, { status: 404 });
      if (instance.type !== "radarr" && instance.type !== "sonarr") return json({ error: `Cleanup not supported for ${instance.type}` }, { status: 400 });
      const instanceType = instance.type;
      const client2 = createArrClient(instance.type, instance.url, instance.api_key, { retries: 0 });
      try {
        const [configs, entities] = await Promise.all([scanForStaleItems(client2, instanceId).then((data) => ({
          ok: true,
          data
        })).catch((err) => ({
          ok: false,
          error: err instanceof Error ? err.message : "Config scan failed"
        })), scanForRemovedEntities(client2, instanceType).then((data) => ({
          ok: true,
          data
        })).catch((err) => ({
          ok: false,
          error: err instanceof Error ? err.message : "Entity scan failed"
        }))]);
        return json({
          configs,
          entities
        });
      } finally {
        client2.close();
      }
    };
  }
});

// dist/build/server/entries/endpoints/arr/_id_/upgrades/preview/_server.ts.js
var server_ts_exports26 = {};
__export(server_ts_exports26, {
  POST: () => POST8
});
function toPreviewItem(item, status, reason) {
  return {
    id: item.id,
    title: item.title,
    year: item.year,
    status,
    reason,
    details: {
      qualityProfile: item.quality_profile,
      fileName: item.file_name,
      customFormats: item.score_breakdown,
      score: item.score,
      tags: item.tags,
      monitored: item.monitored,
      dateAdded: item.date_added,
      sizeOnDisk: item.size_on_disk,
      releaseGroup: item.release_group,
      status: item.status
    }
  };
}
function formatValue2(value2, field) {
  if (value2 === null || value2 === void 0 || value2 === "") return "empty";
  const matchingValue = field?.values?.find((option) => Object.is(option.value, value2));
  if (matchingValue) return matchingValue.label;
  if (Array.isArray(value2)) return value2.length > 0 ? value2.join(", ") : "none";
  if (typeof value2 === "boolean") return value2 ? "True" : "False";
  return String(value2);
}
function pluralize(count, singular, plural = `${singular}s`) {
  return `${count} ${count === 1 ? singular : plural}`;
}
function formatFailedRule(item, rule, appType) {
  const field = getFilterField(rule.field, appType);
  const fieldLabel2 = field?.label ?? rule.field;
  const actualValue = rule.field === "custom_format" ? item.custom_formats : item[rule.field];
  const expectedValue = formatValue2(rule.value, field);
  const actualLabel = formatValue2(actualValue, field);
  switch (rule.operator) {
    case "is":
    case "eq":
      return `${fieldLabel2} is ${actualLabel}, not ${expectedValue}`;
    case "is_not":
    case "neq":
      return `${fieldLabel2} is ${expectedValue}`;
    case "contains":
    case "includes":
      return `${fieldLabel2} does not contain ${expectedValue}`;
    case "not_contains":
    case "does_not_include":
      return `${fieldLabel2} contains ${expectedValue}`;
    case "starts_with":
      return `${fieldLabel2} does not start with ${expectedValue}`;
    case "ends_with":
      return `${fieldLabel2} does not end with ${expectedValue}`;
    case "is_only":
      return `${fieldLabel2} is not only ${expectedValue}`;
    case "has_any":
      return `${fieldLabel2} has none`;
    case "has_none":
      return `${fieldLabel2} has values`;
    case "gte":
      return field?.valueType === "number" ? `${fieldLabel2} is below ${expectedValue}` : `${fieldLabel2} has not reached ${expectedValue}`;
    case "lte":
      return field?.valueType === "number" ? `${fieldLabel2} is above ${expectedValue}` : `${fieldLabel2} has passed ${expectedValue}`;
    case "gt":
      return `${fieldLabel2} is not above ${expectedValue}`;
    case "lt":
      return `${fieldLabel2} is not below ${expectedValue}`;
    case "before":
      return `${fieldLabel2} is not before ${expectedValue}`;
    case "after":
      return `${fieldLabel2} is not after ${expectedValue}`;
    case "in_last":
      return `${fieldLabel2} is not in the last ${expectedValue} days`;
    case "not_in_last":
      return `${fieldLabel2} is in the last ${expectedValue} days`;
    default:
      return `${fieldLabel2} did not match`;
  }
}
function explainGroupMismatch(item, group, appType) {
  const record = item;
  if (group.match === "all") for (const child of group.children) {
    if (isRule(child) && !evaluateRule(record, child)) return formatFailedRule(item, child, appType);
    if (isGroup(child) && !evaluateGroup(record, child)) return explainGroupMismatch(item, child, appType);
  }
  if (group.match === "any" && group.children.length > 0) for (const child of group.children) {
    if (isRule(child) && !evaluateRule(record, child)) return `No option matched: ${formatFailedRule(item, child, appType)}`;
    if (isGroup(child) && !evaluateGroup(record, child)) return `No option matched: ${explainGroupMismatch(item, child, appType)}`;
  }
  return "Filter rules did not match";
}
async function loadRadarrItems(instanceId, client2, filter) {
  const cached2 = radarrPreviewCache.get(instanceId);
  const now = Date.now();
  let movies;
  let profiles;
  let movieFiles;
  let tags;
  if (cached2 && cached2.expiresAt > now) {
    movies = cached2.movies;
    profiles = cached2.profiles;
    movieFiles = cached2.movieFiles;
    tags = cached2.tags;
  } else {
    const [loadedMovies, loadedProfiles] = await Promise.all([client2.getMovies(), client2.getQualityProfiles()]);
    const movieIdsWithFiles = loadedMovies.filter((movie) => movie.hasFile).map((movie) => movie.id);
    const loadedMovieFiles = await client2.getMovieFiles(movieIdsWithFiles);
    const loadedTags = await client2.getTags();
    movies = loadedMovies;
    profiles = loadedProfiles;
    movieFiles = loadedMovieFiles;
    tags = loadedTags;
    radarrPreviewCache.set(instanceId, {
      expiresAt: Date.now() + PREVIEW_CACHE_TTL_MS,
      movies,
      profiles,
      movieFiles,
      tags
    });
  }
  const movieFileMap = new Map(movieFiles.map((movieFile) => [movieFile.movieId, movieFile]));
  const profileMap = new Map(profiles.map((profile) => [profile.id, profile]));
  const tagMap = new Map(tags.map((tag2) => [tag2.id, tag2.label]));
  return {
    items: normalizeRadarrItems(movies, movieFileMap, profileMap, filter.cutoff, tagMap),
    tags
  };
}
async function loadSonarrItems(instanceId, client2, filter) {
  const cached2 = sonarrPreviewCache.get(instanceId);
  const now = Date.now();
  let cacheEntry;
  if (cached2 && cached2.expiresAt > now) cacheEntry = cached2;
  else {
    const [loadedSeries, loadedProfiles] = await Promise.all([client2.getAllSeries(), client2.getQualityProfiles()]);
    const loadedTags = await client2.getTags();
    cacheEntry = {
      expiresAt: Date.now() + PREVIEW_CACHE_TTL_MS,
      series: loadedSeries,
      profiles: loadedProfiles,
      tags: loadedTags
    };
    sonarrPreviewCache.set(instanceId, cacheEntry);
  }
  const { series, profiles, tags } = cacheEntry;
  let episodeFiles;
  if (filterNeedsSonarrScores(filter)) {
    episodeFiles = await loadSonarrEpisodeFiles(client2, series, cacheEntry.episodeFiles);
    cacheEntry.episodeFiles = episodeFiles;
  }
  const profileMap = new Map(profiles.map((profile) => [profile.id, profile]));
  const tagMap = new Map(tags.map((tag2) => [tag2.id, tag2.label]));
  return {
    items: normalizeSonarrItems(series, profileMap, filter.cutoff, episodeFiles, tagMap),
    tags
  };
}
function buildPreview(filter, normalizedItems2, tags, appType) {
  const matchedItems = normalizedItems2.filter((item) => evaluateGroup(item, filter.group));
  const matchedIds = new Set(matchedItems.map((item) => item.id));
  const tagLabel = resolveTagLabel(filter);
  const cooldownItems = matchedItems.filter((item) => hasFilterTag(item._tags, tags, tagLabel));
  const cooldownIds = new Set(cooldownItems.map((item) => item.id));
  const selectableItems = matchedItems.filter((item) => !cooldownIds.has(item.id));
  const selector = getSelector(filter.selector);
  const orderedSelectableItems = selector ? selector.select(selectableItems, selectableItems.length) : selectableItems;
  const selectedItems = orderedSelectableItems.slice(0, Math.max(0, filter.count));
  const selectedIds = new Set(selectedItems.map((item) => item.id));
  const remainingSelectableItems = orderedSelectableItems.filter((item) => !selectedIds.has(item.id));
  const filteredOutItems = normalizedItems2.filter((item) => !matchedIds.has(item.id));
  const selectorLabel = selector?.label ?? filter.selector;
  const cooldownRemaining = pluralize(selectableItems.length, "item");
  const cooldownReason = selectableItems.length > 0 ? `Already searched by this filter. ${cooldownRemaining} still eligible before the cooldown resets.` : "Already searched by this filter. Cooldown will reset on the next run.";
  return {
    filterName: filter.name,
    totalItems: normalizedItems2.length,
    matchedCount: matchedItems.length,
    cooldownCount: cooldownItems.length,
    selectableCount: selectableItems.length,
    selectedCount: selectedItems.length,
    requestedCount: filter.count,
    selector: filter.selector,
    items: [
      ...selectedItems.map((item) => toPreviewItem(item, "selected", `Will search next using ${selectorLabel}`)),
      ...remainingSelectableItems.map((item) => toPreviewItem(item, "selectable", "Matches this filter and is waiting for a later run")),
      ...cooldownItems.map((item) => toPreviewItem(item, "cooldown", cooldownReason)),
      ...filteredOutItems.map((item) => toPreviewItem(item, "filtered_out", explainGroupMismatch(item, filter.group, appType)))
    ]
  };
}
async function previewUpgradeFilter(instance, filter) {
  if (instance.type !== "radarr" && instance.type !== "sonarr") throw new Error(`Upgrade preview is not supported for ${instance.type}`);
  const appType = instance.type;
  const client2 = instance.type === "radarr" ? new RadarrClient(instance.url, instance.api_key, { timeout: 12e4 }) : new SonarrClient(instance.url, instance.api_key, { timeout: 12e4 });
  try {
    const { items, tags } = instance.type === "radarr" ? await loadRadarrItems(instance.id, client2, filter) : await loadSonarrItems(instance.id, client2, filter);
    return buildPreview(filter, items, tags, appType);
  } finally {
    client2.close();
  }
}
function isFilterConfig(value2) {
  if (!value2 || typeof value2 !== "object") return false;
  const filter = value2;
  return typeof filter.id === "string" && typeof filter.name === "string" && typeof filter.enabled === "boolean" && typeof filter.selector === "string" && typeof filter.count === "number" && typeof filter.cutoff === "number" && !!filter.group && typeof filter.group === "object";
}
var PREVIEW_CACHE_TTL_MS, radarrPreviewCache, sonarrPreviewCache, POST8;
var init_server_ts26 = __esm({
  async "dist/build/server/entries/endpoints/arr/_id_/upgrades/preview/_server.ts.js"() {
    "use strict";
    await init_arrInstances();
    await init_radarr();
    await init_sonarr();
    init_selectors();
    init_cooldown();
    init_exports();
    PREVIEW_CACHE_TTL_MS = 3e5;
    radarrPreviewCache = /* @__PURE__ */ new Map();
    sonarrPreviewCache = /* @__PURE__ */ new Map();
    POST8 = async ({ params, request }) => {
      const instanceId = parseInt(params.id ?? "", 10);
      if (!Number.isFinite(instanceId)) return json({ error: "Invalid instance ID" }, { status: 400 });
      const instance = arrInstancesQueries.getById(instanceId);
      if (!instance) return json({ error: "Instance not found" }, { status: 404 });
      if (instance.type !== "radarr" && instance.type !== "sonarr") return json({ error: `Upgrade preview is not supported for ${instance.type}` }, { status: 400 });
      const body = await request.json().catch(() => null);
      if (!body || typeof body !== "object" || !("filter" in body) || !isFilterConfig(body.filter)) return json({ error: "Invalid filter" }, { status: 400 });
      try {
        const preview = await previewUpgradeFilter(instance, body.filter);
        return json(preview);
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Failed to preview filter";
        return json({ error: message2 }, { status: 500 });
      }
    };
  }
});

// dist/build/server/entries/endpoints/auth/logout/_server.ts.js
var server_ts_exports27 = {};
__export(server_ts_exports27, {
  POST: () => POST9
});
var POST9;
var init_server_ts27 = __esm({
  async "dist/build/server/entries/endpoints/auth/logout/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_users();
    init_exports();
    POST9 = async ({ cookies }) => {
      const sessionId = cookies.get("session");
      if (sessionId) {
        const session = sessionsQueries.getById(sessionId);
        if (session) {
          const user = usersQueries.getById(session.user_id);
          await logger.info(`User '${user?.username ?? "unknown"}' logged out`, {
            source: "Auth:Session",
            meta: {
              userId: session.user_id,
              username: user?.username
            }
          });
        }
        sessionsQueries.deleteById(sessionId);
      }
      cookies.delete("session", { path: "/" });
      throw redirect(303, "/auth/login");
    };
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/buffer_utils.js
function concat(...buffers) {
  const size = buffers.reduce((acc, { length }) => acc + length, 0);
  const buf = new Uint8Array(size);
  let i = 0;
  for (const buffer2 of buffers) {
    buf.set(buffer2, i);
    i += buffer2.length;
  }
  return buf;
}
function encode5(string) {
  const bytes = new Uint8Array(string.length);
  for (let i = 0; i < string.length; i++) {
    const code3 = string.charCodeAt(i);
    if (code3 > 127) {
      throw new TypeError("non-ASCII string encountered in encode()");
    }
    bytes[i] = code3;
  }
  return bytes;
}
var encoder3, decoder3, strictDecoder, MAX_INT32;
var init_buffer_utils = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/buffer_utils.js"() {
    encoder3 = new TextEncoder();
    decoder3 = new TextDecoder();
    strictDecoder = new TextDecoder("utf-8", { fatal: true });
    MAX_INT32 = 2 ** 32;
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/crypto_key.js
function checkUsage(key2, usage) {
  if (usage && !key2.usages.includes(usage)) {
    throw new TypeError(`CryptoKey does not support this operation, its usages must include ${usage}.`);
  }
}
function checkCryptoKey(key2, expected, usage) {
  const algorithm = key2.algorithm;
  if (algorithm.name !== expected.name) {
    throw unusable(expected.name);
  }
  if (expected.hash && algorithm.hash?.name !== expected.hash) {
    throw unusable(expected.hash, "algorithm.hash");
  }
  if (expected.namedCurve && algorithm.namedCurve !== expected.namedCurve) {
    throw unusable(expected.namedCurve, "algorithm.namedCurve");
  }
  if (expected.length !== void 0 && algorithm.length !== expected.length) {
    throw unusable(expected.length, "algorithm.length");
  }
  checkUsage(key2, usage);
}
var unusable;
var init_crypto_key = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/crypto_key.js"() {
    unusable = (name, prop = "algorithm.name") => new TypeError(`CryptoKey does not support this operation, its ${prop} must be ${name}`);
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/invalid_key_input.js
function message(msg, actual, ...types) {
  types = types.filter(Boolean);
  if (types.length > 2) {
    const last = types.pop();
    msg += `one of type ${types.join(", ")}, or ${last}.`;
  } else if (types.length === 2) {
    msg += `one of type ${types[0]} or ${types[1]}.`;
  } else {
    msg += `of type ${types[0]}.`;
  }
  if (actual == null) {
    msg += ` Received ${actual}`;
  } else if (typeof actual === "function" && actual.name) {
    msg += ` Received function ${actual.name}`;
  } else if (typeof actual === "object" && actual != null) {
    if (actual.constructor?.name) {
      msg += ` Received an instance of ${actual.constructor.name}`;
    }
  }
  return msg;
}
var withAlg;
var init_invalid_key_input = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/invalid_key_input.js"() {
    withAlg = (alg, actual, ...types) => message(`Key for the ${alg} algorithm must be `, actual, ...types);
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/util/errors.js
var JOSEError, JWTClaimValidationFailed, JWTExpired, JOSEAlgNotAllowed, JOSENotSupported, JWSInvalid, JWTInvalid, JWKSInvalid, JWKSNoMatchingKey, JWKSMultipleMatchingKeys, JWKSTimeout, JWSSignatureVerificationFailed;
var init_errors = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/util/errors.js"() {
    JOSEError = class extends Error {
      static code = "ERR_JOSE_GENERIC";
      code = "ERR_JOSE_GENERIC";
      constructor(message2, options2) {
        super(message2, options2);
        this.name = this.constructor.name;
        Error.captureStackTrace?.(this, this.constructor);
      }
    };
    JWTClaimValidationFailed = class extends JOSEError {
      static code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
      code = "ERR_JWT_CLAIM_VALIDATION_FAILED";
      claim;
      reason;
      payload;
      constructor(message2, payload2, claim = "unspecified", reason = "unspecified") {
        super(message2, { cause: { claim, reason, payload: payload2 } });
        this.claim = claim;
        this.reason = reason;
        this.payload = payload2;
      }
    };
    JWTExpired = class extends JOSEError {
      static code = "ERR_JWT_EXPIRED";
      code = "ERR_JWT_EXPIRED";
      claim;
      reason;
      payload;
      constructor(message2, payload2, claim = "unspecified", reason = "unspecified") {
        super(message2, { cause: { claim, reason, payload: payload2 } });
        this.claim = claim;
        this.reason = reason;
        this.payload = payload2;
      }
    };
    JOSEAlgNotAllowed = class extends JOSEError {
      static code = "ERR_JOSE_ALG_NOT_ALLOWED";
      code = "ERR_JOSE_ALG_NOT_ALLOWED";
    };
    JOSENotSupported = class extends JOSEError {
      static code = "ERR_JOSE_NOT_SUPPORTED";
      code = "ERR_JOSE_NOT_SUPPORTED";
    };
    JWSInvalid = class extends JOSEError {
      static code = "ERR_JWS_INVALID";
      code = "ERR_JWS_INVALID";
    };
    JWTInvalid = class extends JOSEError {
      static code = "ERR_JWT_INVALID";
      code = "ERR_JWT_INVALID";
    };
    JWKSInvalid = class extends JOSEError {
      static code = "ERR_JWKS_INVALID";
      code = "ERR_JWKS_INVALID";
    };
    JWKSNoMatchingKey = class extends JOSEError {
      static code = "ERR_JWKS_NO_MATCHING_KEY";
      code = "ERR_JWKS_NO_MATCHING_KEY";
      constructor(message2 = "no applicable key found in the JSON Web Key Set", options2) {
        super(message2, options2);
      }
    };
    JWKSMultipleMatchingKeys = class extends JOSEError {
      [Symbol.asyncIterator] = async function* () {
      };
      static code = "ERR_JWKS_MULTIPLE_MATCHING_KEYS";
      code = "ERR_JWKS_MULTIPLE_MATCHING_KEYS";
      constructor(message2 = "multiple matching keys found in the JSON Web Key Set", options2) {
        super(message2, options2);
      }
    };
    JWKSTimeout = class extends JOSEError {
      static code = "ERR_JWKS_TIMEOUT";
      code = "ERR_JWKS_TIMEOUT";
      constructor(message2 = "request timed out", options2) {
        super(message2, options2);
      }
    };
    JWSSignatureVerificationFailed = class extends JOSEError {
      static code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
      code = "ERR_JWS_SIGNATURE_VERIFICATION_FAILED";
      constructor(message2 = "signature verification failed", options2) {
        super(message2, options2);
      }
    };
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/is_key_like.js
var isCryptoKey, isKeyObject, isKeyLike;
var init_is_key_like = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/is_key_like.js"() {
    isCryptoKey = (key2) => {
      if (key2?.[Symbol.toStringTag] === "CryptoKey")
        return true;
      try {
        return key2 instanceof CryptoKey;
      } catch {
        return false;
      }
    };
    isKeyObject = (key2) => key2?.[Symbol.toStringTag] === "KeyObject";
    isKeyLike = (key2) => isCryptoKey(key2) || isKeyObject(key2);
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/base64.js
function decodeBase64(encoded) {
  if (Uint8Array.fromBase64) {
    return Uint8Array.fromBase64(encoded);
  }
  const binary2 = atob(encoded);
  const bytes = new Uint8Array(binary2.length);
  for (let i = 0; i < binary2.length; i++) {
    bytes[i] = binary2.charCodeAt(i);
  }
  return bytes;
}
var init_base64 = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/base64.js"() {
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/util/base64url.js
function decode(input) {
  if (Uint8Array.fromBase64) {
    try {
      return Uint8Array.fromBase64(typeof input === "string" ? input : decoder3.decode(input), {
        alphabet: "base64url"
      });
    } catch (cause) {
      throw new TypeError("The input to be decoded is not correctly encoded.", { cause });
    }
  }
  let encoded = input;
  if (encoded instanceof Uint8Array) {
    encoded = decoder3.decode(encoded);
  }
  if (encoded.includes("+") || encoded.includes("/")) {
    throw new TypeError("The input to be decoded is not correctly encoded.");
  }
  encoded = encoded.replace(/-/g, "+").replace(/_/g, "/");
  try {
    return decodeBase64(encoded);
  } catch {
    throw new TypeError("The input to be decoded is not correctly encoded.");
  }
}
var init_base64url = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/util/base64url.js"() {
    init_buffer_utils();
    init_base64();
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/type_checks.js
function isObject3(input) {
  if (!isObjectLike(input) || Object.prototype.toString.call(input) !== "[object Object]") {
    return false;
  }
  if (Object.getPrototypeOf(input) === null) {
    return true;
  }
  let proto = input;
  while (Object.getPrototypeOf(proto) !== null) {
    proto = Object.getPrototypeOf(proto);
  }
  return Object.getPrototypeOf(input) === proto;
}
function isDisjoint(...headers2) {
  const sources = headers2.filter(Boolean);
  if (sources.length === 0 || sources.length === 1) {
    return true;
  }
  let acc;
  for (const header of sources) {
    const parameters = Object.keys(header);
    if (!acc || acc.size === 0) {
      acc = new Set(parameters);
      continue;
    }
    for (const parameter of parameters) {
      if (acc.has(parameter)) {
        return false;
      }
      acc.add(parameter);
    }
  }
  return true;
}
var isObjectLike, isJWK, isPrivateJWK, isPublicJWK, isSecretJWK;
var init_type_checks = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/type_checks.js"() {
    isObjectLike = (value2) => typeof value2 === "object" && value2 !== null;
    isJWK = (key2) => isObject3(key2) && typeof key2.kty === "string";
    isPrivateJWK = (key2) => key2.kty !== "oct" && (key2.kty === "AKP" && typeof key2.priv === "string" || typeof key2.d === "string");
    isPublicJWK = (key2) => key2.kty !== "oct" && key2.d === void 0 && key2.priv === void 0;
    isSecretJWK = (key2) => key2.kty === "oct" && typeof key2.k === "string";
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/helpers.js
function decodeBase64url(value2, label, ErrorClass) {
  try {
    return decode(value2);
  } catch {
    throw new ErrorClass(`Failed to base64url decode the ${label}`);
  }
}
function encodeBase64url(value2, label, ErrorClass) {
  try {
    return encode5(value2);
  } catch {
    throw new ErrorClass(`The ${label} is not a valid base64url string`);
  }
}
function parseJoseHeader(b64, ErrorClass, message2) {
  let parsed;
  try {
    parsed = JSON.parse(strictDecoder.decode(decode(b64)));
  } catch {
    throw new ErrorClass(message2);
  }
  if (!isObject3(parsed)) {
    throw new ErrorClass(message2);
  }
  return parsed;
}
var init_helpers = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/helpers.js"() {
    init_base64url();
    init_buffer_utils();
    init_type_checks();
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/jwk_to_key.js
function subtleParams(entry, jwk) {
  if (!entry.kty.includes(jwk.kty)) {
    throw new JOSENotSupported(unsupportedAlg);
  }
  return entry.subtleFor?.({ kty: jwk.kty, crv: jwk.crv }) ?? entry.subtle;
}
async function jwkToKey(entry, jwk) {
  if (jwk.kty === "RSA" && "oth" in jwk && jwk.oth !== void 0) {
    throw new JOSENotSupported('RSA JWK "oth" (Other Primes Info) Parameter value is not supported');
  }
  const algorithm = subtleParams(entry, jwk);
  const isPrivate = !!(jwk.d || jwk.priv);
  const keyUsages = isPrivate ? entry.usages.private : entry.usages.public;
  const keyData = { ...jwk };
  if (keyData.kty !== "AKP") {
    delete keyData.alg;
  }
  delete keyData.use;
  return crypto.subtle.importKey("jwk", keyData, algorithm, jwk.ext ?? (isPrivate ? false : true), jwk.key_ops ?? keyUsages);
}
var unsupportedAlg;
var init_jwk_to_key = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/jwk_to_key.js"() {
    init_errors();
    unsupportedAlg = 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value';
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/key.js
function checkKeyType(entry, key2, usage) {
  return entry.symmetric ? symmetricTypeCheck(entry, key2, usage) : asymmetricTypeCheck(entry, key2, usage);
}
function cached(key2, alg) {
  cache2 ||= /* @__PURE__ */ new WeakMap();
  return cache2.get(key2)?.[alg];
}
function store(key2, alg, cryptoKey) {
  const entry = cache2.get(key2);
  if (entry) {
    entry[alg] = cryptoKey;
  } else {
    cache2.set(key2, { [alg]: cryptoKey });
  }
  return cryptoKey;
}
async function prepareKey(entry, key2, usage) {
  const tagged = checkKeyType(entry, key2, usage);
  switch (tagged.kind) {
    case BYTES:
    case CRYPTO:
      return tagged.key;
    case JWK: {
      if (tagged.key.k) {
        return decode(tagged.key.k);
      }
      if (!Object.isFrozen(tagged.key)) {
        const { key_ops } = tagged.key;
        if (Array.isArray(key_ops))
          Object.freeze(key_ops);
        Object.freeze(tagged.key);
      }
      return handleJWK(tagged.key, tagged.key, entry);
    }
    case KEYOBJECT: {
      const keyObject = tagged.key;
      if (keyObject.type === "secret") {
        return keyObject.export();
      }
      if ("toCryptoKey" in keyObject && typeof keyObject.toCryptoKey === "function") {
        return handleKeyObject(keyObject, entry);
      }
      return handleJWK(keyObject, keyObject.export({ format: "jwk" }), entry);
    }
  }
}
var tag, jwkMatchesOp, symmetricTypeCheck, asymmetricTypeCheck, BYTES, CRYPTO, KEYOBJECT, JWK, cache2, nist, handleJWK, handleKeyObject;
var init_key = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/key.js"() {
    init_invalid_key_input();
    init_is_key_like();
    init_type_checks();
    init_base64url();
    init_jwk_to_key();
    tag = (key2) => key2[Symbol.toStringTag];
    jwkMatchesOp = (entry, key2, usage) => {
      const { alg } = entry;
      if (key2.use !== void 0) {
        let expected;
        switch (usage) {
          case "sign":
          case "verify":
            expected = "sig";
            break;
          case "encrypt":
          case "decrypt":
            expected = "enc";
            break;
        }
        if (key2.use !== expected) {
          throw new TypeError(`Invalid key for this operation, its "use" must be "${expected}" when present`);
        }
      }
      if (key2.alg !== void 0 && key2.alg !== alg) {
        throw new TypeError(`Invalid key for this operation, its "alg" must be "${alg}" when present`);
      }
      if (Array.isArray(key2.key_ops)) {
        const expectedKeyOp = usage === "encrypt" || usage === "decrypt" ? entry.keyOps?.[usage] : usage;
        if (expectedKeyOp && key2.key_ops?.includes?.(expectedKeyOp) === false) {
          throw new TypeError(`Invalid key for this operation, its "key_ops" must include "${expectedKeyOp}" when present`);
        }
      }
      return true;
    };
    symmetricTypeCheck = (entry, key2, usage) => {
      const { alg } = entry;
      if (key2 instanceof Uint8Array)
        return { kind: BYTES, key: key2 };
      if (isJWK(key2)) {
        if (isSecretJWK(key2) && jwkMatchesOp(entry, key2, usage))
          return { kind: JWK, key: key2 };
        throw new TypeError(`JSON Web Key for symmetric algorithms must have JWK "kty" (Key Type) equal to "oct" and the JWK "k" (Key Value) present`);
      }
      if (!isKeyLike(key2)) {
        throw new TypeError(withAlg(alg, key2, "CryptoKey", "KeyObject", "JSON Web Key", "Uint8Array"));
      }
      if (key2.type !== "secret") {
        throw new TypeError(`${tag(key2)} instances for symmetric algorithms must be of type "secret"`);
      }
      return isCryptoKey(key2) ? { kind: CRYPTO, key: key2 } : { kind: KEYOBJECT, key: key2 };
    };
    asymmetricTypeCheck = (entry, key2, usage) => {
      const { alg } = entry;
      if (isJWK(key2)) {
        switch (usage) {
          case "decrypt":
          case "sign":
            if (isPrivateJWK(key2) && jwkMatchesOp(entry, key2, usage))
              return { kind: JWK, key: key2 };
            throw new TypeError(`JSON Web Key for this operation must be a private JWK`);
          case "encrypt":
          case "verify":
            if (isPublicJWK(key2) && jwkMatchesOp(entry, key2, usage))
              return { kind: JWK, key: key2 };
            throw new TypeError(`JSON Web Key for this operation must be a public JWK`);
        }
      }
      if (!isKeyLike(key2)) {
        throw new TypeError(withAlg(alg, key2, "CryptoKey", "KeyObject", "JSON Web Key"));
      }
      if (key2.type === "secret") {
        throw new TypeError(`${tag(key2)} instances for asymmetric algorithms must not be of type "secret"`);
      }
      if (key2.type === "public") {
        switch (usage) {
          case "sign":
            throw new TypeError(`${tag(key2)} instances for asymmetric algorithm signing must be of type "private"`);
          case "decrypt":
            throw new TypeError(`${tag(key2)} instances for asymmetric algorithm decryption must be of type "private"`);
        }
      }
      if (key2.type === "private") {
        switch (usage) {
          case "verify":
            throw new TypeError(`${tag(key2)} instances for asymmetric algorithm verifying must be of type "public"`);
          case "encrypt":
            throw new TypeError(`${tag(key2)} instances for asymmetric algorithm encryption must be of type "public"`);
        }
      }
      return isCryptoKey(key2) ? { kind: CRYPTO, key: key2 } : { kind: KEYOBJECT, key: key2 };
    };
    BYTES = /* @__PURE__ */ Symbol();
    CRYPTO = /* @__PURE__ */ Symbol();
    KEYOBJECT = /* @__PURE__ */ Symbol();
    JWK = /* @__PURE__ */ Symbol();
    nist = {
      __proto__: null,
      prime256v1: "P-256",
      secp384r1: "P-384",
      secp521r1: "P-521"
    };
    handleJWK = async (key2, jwk, entry) => {
      const hit = cached(key2, entry.alg);
      if (hit)
        return hit;
      const cryptoKey = await jwkToKey(entry, { ...jwk, alg: entry.alg });
      return store(key2, entry.alg, cryptoKey);
    };
    handleKeyObject = (keyObject, entry) => {
      const hit = cached(keyObject, entry.alg);
      if (hit)
        return hit;
      const isPublic = keyObject.type === "public";
      const usages = isPublic ? entry.usages.public : entry.usages.private;
      const { asymmetricKeyType } = keyObject;
      const crv = nist[keyObject.asymmetricKeyDetails?.namedCurve];
      const params = entry.subtleFor?.({ crv, asymmetricKeyType }) ?? entry.subtle;
      return store(keyObject, entry.alg, keyObject.toCryptoKey(params, isPublic, usages));
    };
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/key_descriptor.js
function table(entries) {
  const out = { __proto__: null };
  for (const alg of Object.keys(entries)) {
    out[alg] = { ...entries[alg], alg };
  }
  return out;
}
var init_key_descriptor = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/key_descriptor.js"() {
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/signing.js
function checkModulusLength(alg, key2) {
  const { modulusLength } = key2.algorithm;
  if (typeof modulusLength !== "number" || modulusLength < 2048) {
    throw new TypeError(`${alg} requires key modulusLength to be 2048 bits or larger`);
  }
}
function checkSigCryptoKey(entry, key2, usage) {
  checkCryptoKey(key2, entry.subtle, usage);
  if (entry.minModulusLength) {
    checkModulusLength(entry.alg, key2);
  }
}
async function getSigKey(entry, key2, usage) {
  if (key2 instanceof Uint8Array) {
    return crypto.subtle.importKey("raw", key2, entry.subtle, false, [
      usage
    ]);
  }
  checkSigCryptoKey(entry, key2, usage);
  return key2;
}
async function verify2(entry, key2, signature, data) {
  const cryptoKey = await getSigKey(entry, key2, "verify");
  try {
    return await crypto.subtle.verify(entry.operation, cryptoKey, signature, data);
  } catch {
    return false;
  }
}
var init_signing = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/signing.js"() {
    init_crypto_key();
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/options.js
function validateAlgorithms(option, algorithms) {
  if (algorithms !== void 0 && (!Array.isArray(algorithms) || algorithms.some((s3) => typeof s3 !== "string"))) {
    throw new TypeError(`"${option}" option must be an array of strings`);
  }
  if (!algorithms) {
    return void 0;
  }
  return new Set(algorithms);
}
function validateCrit(Err, recognizedDefault, recognizedOption, protectedHeader, joseHeader) {
  if (joseHeader.crit !== void 0 && protectedHeader?.crit === void 0) {
    throw new Err('"crit" (Critical) Header Parameter MUST be integrity protected');
  }
  if (!protectedHeader || protectedHeader.crit === void 0) {
    return /* @__PURE__ */ new Set();
  }
  if (!Array.isArray(protectedHeader.crit) || protectedHeader.crit.length === 0 || protectedHeader.crit.some((input) => typeof input !== "string" || input.length === 0)) {
    throw new Err('"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present');
  }
  let recognized;
  if (recognizedOption !== void 0) {
    recognized = new Map([...Object.entries(recognizedOption), ...recognizedDefault.entries()]);
  } else {
    recognized = recognizedDefault;
  }
  for (const parameter of protectedHeader.crit) {
    if (!recognized.has(parameter)) {
      throw new JOSENotSupported(`Extension Header Parameter "${parameter}" is not recognized`);
    }
    if (joseHeader[parameter] === void 0) {
      throw new Err(`Extension Header Parameter "${parameter}" is missing`);
    }
    if (recognized.get(parameter) && protectedHeader[parameter] === void 0) {
      throw new Err(`Extension Header Parameter "${parameter}" MUST be integrity protected`);
    }
  }
  return new Set(protectedHeader.crit);
}
var JWS_RECOGNIZED;
var init_options = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/options.js"() {
    init_errors();
    JWS_RECOGNIZED = /* @__PURE__ */ new Map([["b64", true]]);
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/jws_algorithms.js
function hmac(bits) {
  const subtle = { name: "HMAC", hash: `SHA-${bits}` };
  return { kty: ["oct"], symmetric: true, subtle, operation: subtle, usages: sig };
}
function rsa(name, bits, saltLength) {
  const subtle = { name, hash: `SHA-${bits}` };
  return {
    kty: ["RSA"],
    subtle,
    operation: saltLength ? { ...subtle, saltLength } : subtle,
    usages: sig,
    minModulusLength: 2048
  };
}
function ecdsa(crv, bits) {
  return {
    kty: ["EC"],
    crv,
    subtle: { name: "ECDSA", namedCurve: crv },
    operation: { name: "ECDSA", hash: `SHA-${bits}` },
    usages: sig
  };
}
function eddsa() {
  const subtle = { name: "Ed25519" };
  return {
    kty: ["OKP"],
    crv: "Ed25519",
    subtle,
    operation: subtle,
    usages: sig
  };
}
function mldsa(name) {
  const subtle = { name };
  return {
    kty: ["AKP"],
    subtle,
    operation: subtle,
    usages: sig
  };
}
function jwsAlgorithm(alg) {
  const entry = JWS[alg];
  if (!entry) {
    throw new JOSENotSupported(`alg ${alg} is not supported either by JOSE or your javascript runtime`);
  }
  return entry;
}
function maybeJWSAlgorithm(alg) {
  return JWS[alg];
}
var sig, JWS;
var init_jws_algorithms = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/jws_algorithms.js"() {
    init_errors();
    init_key_descriptor();
    sig = { public: ["verify"], private: ["sign"] };
    JWS = table({
      HS256: hmac(256),
      HS384: hmac(384),
      HS512: hmac(512),
      RS256: rsa("RSASSA-PKCS1-v1_5", 256),
      RS384: rsa("RSASSA-PKCS1-v1_5", 384),
      RS512: rsa("RSASSA-PKCS1-v1_5", 512),
      PS256: rsa("RSA-PSS", 256, 32),
      PS384: rsa("RSA-PSS", 384, 48),
      PS512: rsa("RSA-PSS", 512, 64),
      ES256: ecdsa("P-256", 256),
      ES384: ecdsa("P-384", 384),
      ES512: ecdsa("P-521", 512),
      EdDSA: eddsa(),
      Ed25519: eddsa(),
      "ML-DSA-44": mldsa("ML-DSA-44"),
      "ML-DSA-65": mldsa("ML-DSA-65"),
      "ML-DSA-87": mldsa("ML-DSA-87")
    });
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/jws_verify.js
function prepareVerify(options2) {
  return {
    algorithms: options2 && validateAlgorithms("algorithms", options2.algorithms),
    crit: options2?.crit
  };
}
async function verifySignature(jws, shared, key2) {
  let parsedProt = {};
  if (jws.protected) {
    parsedProt = parseJoseHeader(jws.protected, JWSInvalid, "JWS Protected Header is invalid");
  }
  let joseHeader;
  if (jws.header !== void 0) {
    if (!isDisjoint(parsedProt, jws.header)) {
      throw new JWSInvalid("JWS Protected and JWS Unprotected Header Parameter names must be disjoint");
    }
    joseHeader = { ...parsedProt, ...jws.header };
  } else {
    joseHeader = parsedProt;
  }
  const extensions = validateCrit(JWSInvalid, JWS_RECOGNIZED, shared.crit, parsedProt, joseHeader);
  let b64 = true;
  if (extensions.has("b64")) {
    b64 = parsedProt.b64;
    if (typeof b64 !== "boolean") {
      throw new JWSInvalid('The "b64" (base64url-encode payload) Header Parameter must be a boolean');
    }
  }
  const { alg } = joseHeader;
  if (typeof alg !== "string" || !alg) {
    throw new JWSInvalid('JWS "alg" (Algorithm) Header Parameter missing or invalid');
  }
  if (shared.algorithms && !shared.algorithms.has(alg)) {
    throw new JOSEAlgNotAllowed('"alg" (Algorithm) Header Parameter value not allowed');
  }
  if (b64) {
    if (typeof jws.payload !== "string") {
      throw new JWSInvalid("JWS Payload must be a string");
    }
  } else if (typeof jws.payload !== "string" && !(jws.payload instanceof Uint8Array)) {
    throw new JWSInvalid("JWS Payload must be a string or an Uint8Array instance");
  }
  let resolvedKey = false;
  if (typeof key2 === "function") {
    key2 = await key2(parsedProt, jws);
    resolvedKey = true;
  }
  const entry = jwsAlgorithm(alg);
  const data = concat(jws.protected !== void 0 ? encode5(jws.protected) : new Uint8Array(), encode5("."), typeof jws.payload === "string" ? b64 ? shared.b64p ??= encodeBase64url(jws.payload, "payload", JWSInvalid) : encoder3.encode(jws.payload) : jws.payload);
  const signature = decodeBase64url(jws.signature, "signature", JWSInvalid);
  const k2 = await prepareKey(entry, key2, "verify");
  const verified = await verify2(entry, k2, signature, data);
  if (!verified) {
    throw new JWSSignatureVerificationFailed();
  }
  let payload2;
  if (b64) {
    payload2 = decodeBase64url(jws.payload, "payload", JWSInvalid);
  } else if (typeof jws.payload === "string") {
    payload2 = encoder3.encode(jws.payload);
  } else {
    payload2 = jws.payload;
  }
  return { payload: payload2, parsedProt, b64, key: k2, resolvedKey };
}
async function verifyCompact(jws, shared, key2) {
  if (jws instanceof Uint8Array) {
    jws = decoder3.decode(jws);
  }
  if (typeof jws !== "string") {
    throw new JWSInvalid("Compact JWS must be a string or Uint8Array");
  }
  const { 0: protectedHeader, 1: payload2, 2: signature, length } = jws.split(".");
  if (length !== 3) {
    throw new JWSInvalid("Invalid Compact JWS");
  }
  return verifySignature({ payload: payload2, protected: protectedHeader, signature }, shared, key2);
}
var init_jws_verify = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/jws_verify.js"() {
    init_signing();
    init_jws_algorithms();
    init_errors();
    init_buffer_utils();
    init_helpers();
    init_type_checks();
    init_options();
    init_key();
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/jwt_claims_set.js
function secs(str2) {
  const matched = REGEX.exec(str2);
  if (!matched || matched[4] && matched[1]) {
    throw new TypeError("Invalid time period format");
  }
  const value2 = parseFloat(matched[2]);
  const unit = matched[3].toLowerCase();
  let numericDate;
  switch (unit) {
    case "sec":
    case "secs":
    case "second":
    case "seconds":
    case "s":
      numericDate = Math.round(value2);
      break;
    case "minute":
    case "minutes":
    case "min":
    case "mins":
    case "m":
      numericDate = Math.round(value2 * minute);
      break;
    case "hour":
    case "hours":
    case "hr":
    case "hrs":
    case "h":
      numericDate = Math.round(value2 * hour);
      break;
    case "day":
    case "days":
    case "d":
      numericDate = Math.round(value2 * day);
      break;
    case "week":
    case "weeks":
    case "w":
      numericDate = Math.round(value2 * week);
      break;
    default:
      numericDate = Math.round(value2 * year);
      break;
  }
  if (matched[1] === "-" || matched[4] === "ago") {
    return -numericDate;
  }
  return numericDate;
}
function validateInput(label, input) {
  if (!Number.isFinite(input)) {
    throw new TypeError(`Invalid ${label} input`);
  }
  return input;
}
function validateClaimsSet(protectedHeader, encodedPayload, options2 = {}) {
  let payload2;
  try {
    payload2 = JSON.parse(strictDecoder.decode(encodedPayload));
  } catch {
  }
  if (!isObject3(payload2)) {
    throw new JWTInvalid("JWT Claims Set must be a top-level JSON object");
  }
  const { typ } = options2;
  if (typ && (typeof protectedHeader.typ !== "string" || normalizeTyp(protectedHeader.typ) !== normalizeTyp(typ))) {
    throw new JWTClaimValidationFailed('unexpected "typ" JWT header value', payload2, "typ", "check_failed");
  }
  const { requiredClaims = [], issuer, subject, audience, maxTokenAge } = options2;
  const presenceCheck = [...requiredClaims];
  if (maxTokenAge !== void 0)
    presenceCheck.push("iat");
  if (audience !== void 0)
    presenceCheck.push("aud");
  if (subject !== void 0)
    presenceCheck.push("sub");
  if (issuer !== void 0)
    presenceCheck.push("iss");
  for (const claim of new Set(presenceCheck.reverse())) {
    if (!(claim in payload2)) {
      throw new JWTClaimValidationFailed(`missing required "${claim}" claim`, payload2, claim, "missing");
    }
  }
  if (issuer !== void 0 && !(Array.isArray(issuer) ? issuer : [issuer]).includes(payload2.iss)) {
    throw new JWTClaimValidationFailed('unexpected "iss" claim value', payload2, "iss", "check_failed");
  }
  if (subject !== void 0 && payload2.sub !== subject) {
    throw new JWTClaimValidationFailed('unexpected "sub" claim value', payload2, "sub", "check_failed");
  }
  if (audience !== void 0 && !checkAudiencePresence(payload2.aud, typeof audience === "string" ? [audience] : audience)) {
    throw new JWTClaimValidationFailed('unexpected "aud" claim value', payload2, "aud", "check_failed");
  }
  let tolerance;
  switch (typeof options2.clockTolerance) {
    case "string":
      tolerance = secs(options2.clockTolerance);
      break;
    case "number":
      tolerance = options2.clockTolerance;
      break;
    case "undefined":
      tolerance = 0;
      break;
    default:
      throw new TypeError("Invalid clockTolerance option type");
  }
  validateInput("clockTolerance option", tolerance);
  const { currentDate } = options2;
  const now = validateInput("currentDate option", epoch(currentDate || /* @__PURE__ */ new Date()));
  if ((payload2.iat !== void 0 || maxTokenAge !== void 0) && typeof payload2.iat !== "number") {
    throw new JWTClaimValidationFailed('"iat" claim must be a number', payload2, "iat", "invalid");
  }
  if (payload2.nbf !== void 0) {
    if (typeof payload2.nbf !== "number") {
      throw new JWTClaimValidationFailed('"nbf" claim must be a number', payload2, "nbf", "invalid");
    }
    if (payload2.nbf > now + tolerance) {
      throw new JWTClaimValidationFailed('"nbf" claim timestamp check failed', payload2, "nbf", "check_failed");
    }
  }
  if (payload2.exp !== void 0) {
    if (typeof payload2.exp !== "number") {
      throw new JWTClaimValidationFailed('"exp" claim must be a number', payload2, "exp", "invalid");
    }
    if (payload2.exp <= now - tolerance) {
      throw new JWTExpired('"exp" claim timestamp check failed', payload2, "exp", "check_failed");
    }
  }
  if (maxTokenAge !== void 0) {
    const age = now - payload2.iat;
    const max = typeof maxTokenAge === "number" ? maxTokenAge : secs(maxTokenAge);
    if (age - tolerance > max) {
      throw new JWTExpired('"iat" claim timestamp check failed (too far in the past)', payload2, "iat", "check_failed");
    }
    if (age < 0 - tolerance) {
      throw new JWTClaimValidationFailed('"iat" claim timestamp check failed (it should be in the past)', payload2, "iat", "check_failed");
    }
  }
  return payload2;
}
var epoch, minute, hour, day, week, year, REGEX, normalizeTyp, checkAudiencePresence;
var init_jwt_claims_set = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/lib/jwt_claims_set.js"() {
    init_errors();
    init_buffer_utils();
    init_type_checks();
    epoch = (date) => Math.floor(date.getTime() / 1e3);
    minute = 60;
    hour = minute * 60;
    day = hour * 24;
    week = day * 7;
    year = day * 365.25;
    REGEX = /^(\+|\-)? ?(\d+|\d+\.\d+) ?(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)(?: (ago|from now))?$/i;
    normalizeTyp = (value2) => {
      if (value2.includes("/")) {
        return value2.toLowerCase();
      }
      return `application/${value2.toLowerCase()}`;
    };
    checkAudiencePresence = (audPayload, audOption) => {
      if (typeof audPayload === "string") {
        return audOption.includes(audPayload);
      }
      if (Array.isArray(audPayload)) {
        return audOption.some(Set.prototype.has.bind(new Set(audPayload)));
      }
      return false;
    };
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/jwt/verify.js
async function jwtVerify(jwt, key2, options2) {
  const verified = await verifyCompact(jwt, prepareVerify(options2), key2);
  if (!verified.b64) {
    throw new JWTInvalid("JWTs MUST NOT use unencoded payload");
  }
  const payload2 = validateClaimsSet(verified.parsedProt, verified.payload, options2);
  const result = { payload: payload2, protectedHeader: verified.parsedProt };
  if (typeof key2 === "function") {
    return { ...result, key: verified.key };
  }
  return result;
}
var init_verify = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/jwt/verify.js"() {
    init_jws_verify();
    init_jwt_claims_set();
    init_errors();
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/jwks/local.js
function signatureAlgorithm(alg) {
  const entry = typeof alg === "string" ? maybeJWSAlgorithm(alg) : void 0;
  if (!entry || entry.symmetric) {
    throw new JOSENotSupported('Unsupported "alg" value for a JSON Web Key Set');
  }
  return entry;
}
function isJWKSLike(jwks) {
  if (!jwks || typeof jwks !== "object") {
    return false;
  }
  const { keys } = jwks;
  return Array.isArray(keys) && keys.every(isJWKLike);
}
function isJWKLike(key2) {
  return isObject3(key2);
}
async function importWithAlgCache(cache3, jwk, entry) {
  const cached2 = cache3.get(jwk) || cache3.set(jwk, {}).get(jwk);
  if (cached2[entry.alg] === void 0) {
    const key2 = await jwkToKey(entry, { ...jwk, alg: entry.alg, ext: true });
    if (key2.type !== "public") {
      throw new JWKSInvalid("JSON Web Key Set members must be public keys");
    }
    cached2[entry.alg] = key2;
  }
  return cached2[entry.alg];
}
function createLocalJWKSet(jwks) {
  const set3 = new LocalJWKSetImpl(jwks);
  const localJWKSet = async (protectedHeader, token) => set3.getKey(protectedHeader, token);
  Object.defineProperties(localJWKSet, {
    jwks: {
      value: () => structuredClone(set3.jwks()),
      enumerable: false,
      configurable: false,
      writable: false
    }
  });
  return localJWKSet;
}
var LocalJWKSetImpl;
var init_local = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/jwks/local.js"() {
    init_jwk_to_key();
    init_jws_algorithms();
    init_errors();
    init_type_checks();
    LocalJWKSetImpl = class {
      #jwks;
      #cached = /* @__PURE__ */ new WeakMap();
      constructor(jwks) {
        if (!isJWKSLike(jwks)) {
          throw new JWKSInvalid("JSON Web Key Set malformed");
        }
        this.#jwks = structuredClone(jwks);
      }
      jwks() {
        return this.#jwks;
      }
      async getKey(protectedHeader, token) {
        const { alg, kid } = { ...protectedHeader, ...token?.header };
        const entry = signatureAlgorithm(alg);
        const candidates = this.#jwks.keys.filter((jwk2) => {
          let candidate = entry.kty.includes(jwk2.kty);
          if (candidate && typeof kid === "string") {
            candidate = kid === jwk2.kid;
          }
          if (candidate && (typeof jwk2.alg === "string" || jwk2.kty === "AKP")) {
            candidate = alg === jwk2.alg;
          }
          if (candidate && typeof jwk2.use === "string") {
            candidate = jwk2.use === "sig";
          }
          if (candidate && Array.isArray(jwk2.key_ops)) {
            candidate = jwk2.key_ops.includes("verify");
          }
          if (candidate && entry.crv) {
            candidate = jwk2.crv === entry.crv;
          }
          return candidate;
        });
        const { 0: jwk, length } = candidates;
        if (length === 0) {
          throw new JWKSNoMatchingKey();
        }
        if (length !== 1) {
          const error2 = new JWKSMultipleMatchingKeys();
          const _cached = this.#cached;
          error2[Symbol.asyncIterator] = async function* () {
            for (const jwk2 of candidates) {
              try {
                yield await importWithAlgCache(_cached, jwk2, entry);
              } catch {
              }
            }
          };
          throw error2;
        }
        return importWithAlgCache(this.#cached, jwk, entry);
      }
    };
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/jwks/remote.js
function isCloudflareWorkers() {
  return typeof WebSocketPair !== "undefined" || typeof navigator !== "undefined" && navigator.userAgent === "Cloudflare-Workers" || typeof EdgeRuntime !== "undefined" && EdgeRuntime === "vercel";
}
async function fetchJwks(url, headers2, signal, fetchImpl = fetch) {
  const response = await fetchImpl(url, {
    method: "GET",
    signal,
    redirect: "manual",
    headers: headers2
  }).catch((err) => {
    if (err.name === "TimeoutError") {
      throw new JWKSTimeout();
    }
    throw err;
  });
  if (response.status !== 200) {
    throw new JOSEError("Expected 200 OK from the JSON Web Key Set HTTP response");
  }
  try {
    return await response.json();
  } catch {
    throw new JOSEError("Failed to parse the JSON Web Key Set HTTP response as JSON");
  }
}
function isFreshJwksCache(input, cacheMaxAge) {
  if (typeof input !== "object" || input === null) {
    return false;
  }
  if (!("uat" in input) || typeof input.uat !== "number" || Date.now() - input.uat >= cacheMaxAge) {
    return false;
  }
  if (!("jwks" in input) || !isObject3(input.jwks) || !Array.isArray(input.jwks.keys) || !Array.prototype.every.call(input.jwks.keys, isObject3)) {
    return false;
  }
  return true;
}
function createRemoteJWKSet(url, options2) {
  const set3 = new RemoteJWKSetImpl(url, options2);
  const remoteJWKSet = async (protectedHeader, token) => set3.getKey(protectedHeader, token);
  Object.defineProperties(remoteJWKSet, {
    coolingDown: {
      get: () => set3.coolingDown(),
      enumerable: true,
      configurable: false
    },
    fresh: {
      get: () => set3.fresh(),
      enumerable: true,
      configurable: false
    },
    reload: {
      value: () => set3.reload(),
      enumerable: true,
      configurable: false,
      writable: false
    },
    reloading: {
      get: () => set3.pendingFetch(),
      enumerable: true,
      configurable: false
    },
    jwks: {
      value: () => set3.jwks(),
      enumerable: true,
      configurable: false,
      writable: false
    }
  });
  return remoteJWKSet;
}
var USER_AGENT, customFetch, jwksCache, RemoteJWKSetImpl;
var init_remote = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/jwks/remote.js"() {
    init_errors();
    init_local();
    init_type_checks();
    if (typeof navigator === "undefined" || !navigator.userAgent?.startsWith?.("Mozilla/5.0 ")) {
      const NAME = "jose";
      const VERSION3 = "v6.2.6";
      USER_AGENT = `${NAME}/${VERSION3}`;
    }
    customFetch = /* @__PURE__ */ Symbol();
    jwksCache = /* @__PURE__ */ Symbol();
    RemoteJWKSetImpl = class {
      #url;
      #timeoutDuration;
      #cooldownDuration;
      #cacheMaxAge;
      #jwksTimestamp;
      #pendingFetch;
      #headers;
      #customFetch;
      #local;
      #cache;
      constructor(url, options2) {
        if (!(url instanceof URL)) {
          throw new TypeError("url must be an instance of URL");
        }
        this.#url = new URL(url.href);
        this.#timeoutDuration = typeof options2?.timeoutDuration === "number" ? options2?.timeoutDuration : 5e3;
        this.#cooldownDuration = typeof options2?.cooldownDuration === "number" ? options2?.cooldownDuration : 3e4;
        this.#cacheMaxAge = typeof options2?.cacheMaxAge === "number" ? options2?.cacheMaxAge : 6e5;
        this.#headers = new Headers(options2?.headers);
        if (USER_AGENT && !this.#headers.has("User-Agent")) {
          this.#headers.set("User-Agent", USER_AGENT);
        }
        if (!this.#headers.has("accept")) {
          this.#headers.set("accept", "application/json");
          this.#headers.append("accept", "application/jwk-set+json");
        }
        this.#customFetch = options2?.[customFetch];
        if (options2?.[jwksCache] !== void 0) {
          this.#cache = options2?.[jwksCache];
          if (isFreshJwksCache(options2?.[jwksCache], this.#cacheMaxAge)) {
            this.#jwksTimestamp = this.#cache.uat;
            this.#local = createLocalJWKSet(this.#cache.jwks);
          }
        }
      }
      pendingFetch() {
        return !!this.#pendingFetch;
      }
      coolingDown() {
        return typeof this.#jwksTimestamp === "number" ? Date.now() < this.#jwksTimestamp + this.#cooldownDuration : false;
      }
      fresh() {
        return typeof this.#jwksTimestamp === "number" ? Date.now() < this.#jwksTimestamp + this.#cacheMaxAge : false;
      }
      jwks() {
        return this.#local?.jwks();
      }
      async getKey(protectedHeader, token) {
        if (!this.#local || !this.fresh()) {
          await this.reload();
        }
        try {
          return await this.#local(protectedHeader, token);
        } catch (err) {
          if (err instanceof JWKSNoMatchingKey) {
            if (this.coolingDown() === false) {
              await this.reload();
              return this.#local(protectedHeader, token);
            }
          }
          throw err;
        }
      }
      async reload() {
        if (this.#pendingFetch && isCloudflareWorkers()) {
          this.#pendingFetch = void 0;
        }
        this.#pendingFetch ||= fetchJwks(this.#url.href, this.#headers, AbortSignal.timeout(this.#timeoutDuration), this.#customFetch).then((json2) => {
          this.#local = createLocalJWKSet(json2);
          if (this.#cache) {
            this.#cache.uat = Date.now();
            this.#cache.jwks = json2;
          }
          this.#jwksTimestamp = Date.now();
          this.#pendingFetch = void 0;
        }).catch((err) => {
          this.#pendingFetch = void 0;
          throw err;
        });
        await this.#pendingFetch;
      }
    };
  }
});

// node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/index.js
var init_webapi = __esm({
  "node_modules/.deno/jose@6.2.6/node_modules/jose/dist/webapi/index.js"() {
    init_verify();
    init_remote();
  }
});

// dist/build/server/chunks/oidc.js
async function getDiscoveryDocument(url) {
  if (cachedDiscovery && cachedDiscovery.url === url && Date.now() < cachedDiscovery.expires) return cachedDiscovery.doc;
  const response = await fetch(url);
  if (!response.ok) throw new Error(`Failed to fetch OIDC discovery: ${response.status}`);
  const doc = await response.json();
  if (!doc.authorization_endpoint || !doc.token_endpoint) throw new Error("Invalid OIDC discovery document");
  cachedDiscovery = {
    url,
    doc,
    expires: Date.now() + 36e5
  };
  return doc;
}
function generateState() {
  return crypto.randomUUID();
}
function buildAuthorizationUrl(authorizationEndpoint, opts) {
  return `${authorizationEndpoint}?${new URLSearchParams({
    client_id: opts.clientId,
    redirect_uri: opts.redirectUri,
    response_type: "code",
    scope: opts.scope || "openid email profile",
    state: opts.state,
    nonce: opts.nonce
  }).toString()}`;
}
async function exchangeCode(tokenEndpoint, code3, opts) {
  const response = await fetch(tokenEndpoint, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "authorization_code",
      code: code3,
      client_id: opts.clientId,
      client_secret: opts.clientSecret,
      redirect_uri: opts.redirectUri
    })
  });
  if (!response.ok) {
    const error2 = await response.text();
    throw new Error(`Token exchange failed: ${response.status} - ${error2}`);
  }
  const data = await response.json();
  if (data.error) throw new Error(`Token exchange error: ${data.error}`);
  return data;
}
async function verifyAndDecodeIdToken(idToken, jwksUri, opts) {
  const jwks = createRemoteJWKSet(new URL(jwksUri));
  const { payload: payload2 } = await jwtVerify(idToken, jwks, {
    issuer: opts.issuer,
    audience: opts.clientId
  });
  return payload2;
}
var cachedDiscovery;
var init_oidc = __esm({
  "dist/build/server/chunks/oidc.js"() {
    "use strict";
    init_webapi();
    cachedDiscovery = null;
  }
});

// dist/build/server/entries/endpoints/auth/oidc/callback/_server.ts.js
var server_ts_exports28 = {};
__export(server_ts_exports28, {
  GET: () => GET21
});
var GET21;
var init_server_ts28 = __esm({
  async "dist/build/server/entries/endpoints/auth/oidc/callback/_server.ts.js"() {
    "use strict";
    await init_db();
    init_config();
    await init_users();
    init_oidc();
    await init_authSettings();
    init_network();
    init_userAgent();
    init_exports();
    GET21 = async (event) => {
      const { url, cookies, request } = event;
      const code3 = url.searchParams.get("code");
      const state2 = url.searchParams.get("state");
      const errorParam = url.searchParams.get("error");
      const errorDescription = url.searchParams.get("error_description");
      if (errorParam) throw error(400, `OIDC error: ${errorParam} - ${errorDescription || "Unknown error"}`);
      const savedState = cookies.get("oidc_state");
      if (!state2 || state2 !== savedState) {
        const ip2 = getClientIp(event, false);
        await logger.warn("OIDC state mismatch (possible CSRF attempt)", {
          source: "Auth:OIDC",
          meta: { ip: ip2 }
        });
        throw error(400, "Invalid state parameter");
      }
      const savedNonce = cookies.get("oidc_nonce");
      cookies.delete("oidc_state", { path: "/" });
      cookies.delete("oidc_nonce", { path: "/" });
      if (!code3) throw error(400, "No authorization code provided");
      if (!config.oidc.discoveryUrl || !config.oidc.clientId || !config.oidc.clientSecret) throw error(500, "OIDC is not configured");
      const discovery = await getDiscoveryDocument(config.oidc.discoveryUrl);
      const ip = getClientIp(event, false);
      let tokens;
      try {
        tokens = await exchangeCode(discovery.token_endpoint, code3, {
          clientId: config.oidc.clientId,
          clientSecret: config.oidc.clientSecret,
          redirectUri: `${config.origin}/auth/oidc/callback`
        });
      } catch (err) {
        await logger.warn("OIDC token exchange failed", {
          source: "Auth:OIDC",
          meta: {
            ip,
            error: err instanceof Error ? err.message : String(err)
          }
        });
        throw error(500, "Failed to exchange authorization code");
      }
      let claims;
      try {
        claims = await verifyAndDecodeIdToken(tokens.id_token, discovery.jwks_uri, {
          clientId: config.oidc.clientId,
          issuer: discovery.issuer
        });
      } catch (err) {
        await logger.error("OIDC ID token verification failed", {
          source: "Auth:OIDC",
          meta: {
            ip,
            error: err instanceof Error ? err.message : String(err)
          }
        });
        throw error(500, "Failed to verify ID token");
      }
      if (!savedNonce || claims.nonce !== savedNonce) {
        await logger.warn("OIDC nonce mismatch (possible token replay)", {
          source: "Auth:OIDC",
          meta: { ip }
        });
        throw error(400, "Invalid nonce parameter");
      }
      const userId = usersQueries.getOrCreateOidcUser(claims.sub);
      const ipAddress = getClientIp(event);
      const userAgent = request.headers.get("user-agent") ?? "";
      const parsed = parseUserAgent(userAgent);
      const durationHours = authSettingsQueries.getSessionDurationHours();
      const sessionId = sessionsQueries.create(userId, durationHours, {
        ipAddress,
        userAgent,
        browser: parsed.browser,
        os: parsed.os,
        deviceType: parsed.deviceType
      });
      await logger.info(`OIDC login successful for '${claims.sub}'`, {
        source: "Auth:OIDC",
        meta: {
          sub: claims.sub,
          ip: ipAddress,
          browser: parsed.browser,
          device: parsed.deviceType
        }
      });
      const expires = new Date(Date.now() + durationHours * 60 * 60 * 1e3);
      cookies.set("session", sessionId, {
        path: "/",
        httpOnly: true,
        sameSite: "lax",
        secure: config.origin.startsWith("https://"),
        expires
      });
      throw redirect(303, "/");
    };
  }
});

// dist/build/server/entries/endpoints/auth/oidc/login/_server.ts.js
var server_ts_exports29 = {};
__export(server_ts_exports29, {
  GET: () => GET22
});
var GET22;
var init_server_ts29 = __esm({
  async "dist/build/server/entries/endpoints/auth/oidc/login/_server.ts.js"() {
    "use strict";
    await init_db();
    init_config();
    init_oidc();
    init_network();
    init_exports();
    GET22 = async (event) => {
      const { cookies } = event;
      const ip = getClientIp(event, false);
      if (config.authMode !== "oidc") throw error(400, "OIDC authentication is not enabled");
      if (!config.oidc.discoveryUrl || !config.oidc.clientId || !config.oidc.clientSecret) {
        const missing = [
          !config.oidc.discoveryUrl && "OIDC_DISCOVERY_URL",
          !config.oidc.clientId && "OIDC_CLIENT_ID",
          !config.oidc.clientSecret && "OIDC_CLIENT_SECRET"
        ].filter(Boolean);
        await logger.error(`OIDC config missing: ${missing.join(", ")}`, {
          source: "Auth:OIDC",
          meta: { missing }
        });
        throw error(500, "OIDC is not configured. Set OIDC_DISCOVERY_URL, OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET");
      }
      await logger.debug("OIDC flow started", {
        source: "Auth:OIDC",
        meta: { ip }
      });
      const discovery = await getDiscoveryDocument(config.oidc.discoveryUrl);
      const state2 = generateState();
      const nonce = crypto.randomUUID();
      const cookieOpts = {
        path: "/",
        httpOnly: true,
        sameSite: "lax",
        secure: config.origin.startsWith("https://"),
        maxAge: 600
      };
      cookies.set("oidc_state", state2, cookieOpts);
      cookies.set("oidc_nonce", nonce, cookieOpts);
      const authUrl = buildAuthorizationUrl(discovery.authorization_endpoint, {
        clientId: config.oidc.clientId,
        redirectUri: `${config.origin}/auth/oidc/callback`,
        state: state2,
        nonce
      });
      throw redirect(302, authUrl);
    };
  }
});

// dist/build/server/entries/endpoints/custom-formats/_databaseId_/first/_tab_/_server.ts.js
var server_ts_exports30 = {};
__export(server_ts_exports30, {
  GET: () => GET23
});
var TABS, GET23;
var init_server_ts30 = __esm({
  async "dist/build/server/entries/endpoints/custom-formats/_databaseId_/first/_tab_/_server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_customFormats();
    init_exports();
    TABS = /* @__PURE__ */ new Set([
      "general",
      "conditions",
      "testing"
    ]);
    GET23 = async ({ params }) => {
      const dbId = parseInt(params.databaseId, 10);
      if (isNaN(dbId)) error(400, "Invalid database ID");
      if (!TABS.has(params.tab)) error(400, "Invalid tab");
      const cache3 = pcdManager.getCache(dbId);
      if (!cache3) error(404, "Database cache not available");
      const cfs = await list3(cache3);
      const path = cfs.length ? `/custom-formats/${dbId}/${cfs[0].id}/${params.tab}` : `/custom-formats/${dbId}`;
      return json({ path });
    };
  }
});

// dist/build/server/entries/endpoints/databases/avatar/_owner_/_server.ts.js
var server_ts_exports31 = {};
__export(server_ts_exports31, {
  GET: () => GET24
});
async function hashBytes(bytes) {
  const hashBuffer = await crypto.subtle.digest("SHA-256", bytes);
  return Array.from(new Uint8Array(hashBuffer)).map((b3) => b3.toString(16).padStart(2, "0")).join("");
}
var GET24;
var init_server_ts31 = __esm({
  async "dist/build/server/entries/endpoints/databases/avatar/_owner_/_server.ts.js"() {
    "use strict";
    await init_cache();
    GET24 = async ({ params, request }) => {
      const { owner } = params;
      if (!owner) return new Response("Missing owner parameter", {
        status: 400,
        headers: { "Cache-Control": "no-store" }
      });
      const dataUrl = await getCachedAvatar(owner);
      if (!dataUrl) return new Response("Avatar not found", {
        status: 404,
        headers: { "Cache-Control": "no-store" }
      });
      const match = dataUrl.match(/^data:([^;]+);base64,(.+)$/);
      if (!match) return new Response("Invalid cached avatar data", {
        status: 500,
        headers: { "Cache-Control": "no-store" }
      });
      const [, contentType, base64Data] = match;
      const binaryString = atob(base64Data);
      const bytes = new Uint8Array(binaryString.length);
      for (let i = 0; i < binaryString.length; i++) bytes[i] = binaryString.charCodeAt(i);
      const etag2 = `"${await hashBytes(bytes)}"`;
      const ifNoneMatch = request.headers.get("if-none-match");
      if (ifNoneMatch && ifNoneMatch === etag2) return new Response(null, {
        status: 304,
        headers: {
          "Cache-Control": "private, max-age=0, must-revalidate",
          ETag: etag2
        }
      });
      return new Response(bytes, { headers: {
        "Content-Type": contentType,
        "Cache-Control": "private, max-age=0, must-revalidate",
        ETag: etag2
      } });
    };
  }
});

// dist/build/server/entries/endpoints/databases/_id_/changes/data/_server.ts.js
var server_ts_exports32 = {};
__export(server_ts_exports32, {
  GET: () => GET25
});
async function buildFileChange(filepath, op, databaseId, pcdPath, now) {
  const base2 = {
    key: `file:${filepath}`,
    path: filepath,
    operation: op,
    changedFields: [],
    updatedAt: now,
    ops: [],
    sections: []
  };
  const announcementMatch = filepath.match(ANNOUNCEMENT_PATH_RE);
  if (!announcementMatch) return {
    ...base2,
    entity: "file",
    name: filepath,
    summary: FILE_SUMMARY[op]
  };
  const ulid = announcementMatch[1];
  if (op === "delete") {
    const cached2 = databaseAnnouncementQueries.getById(ulid, databaseId);
    return {
      ...base2,
      entity: "announcement",
      name: cached2?.title ?? ulid,
      summary: ANNOUNCEMENT_SUMMARY.delete
    };
  }
  const parsed = await parseAnnouncementFile(pcdPath, ulid);
  if (parsed && !("reason" in parsed)) return {
    ...base2,
    entity: "announcement",
    name: parsed.title,
    summary: ANNOUNCEMENT_SUMMARY[op]
  };
  return {
    ...base2,
    entity: "announcement",
    name: ulid,
    summary: `${ANNOUNCEMENT_SUMMARY[op]} (malformed)`
  };
}
var FILE_CHANGE_EXCLUDED_PREFIXES, ANNOUNCEMENT_PATH_RE, FILE_SUMMARY, ANNOUNCEMENT_SUMMARY, GET25;
var init_server_ts32 = __esm({
  async "dist/build/server/entries/endpoints/databases/_id_/changes/data/_server.ts.js"() {
    "use strict";
    await init_database();
    await init_databaseInstances();
    await init_git();
    await init_draftChanges();
    init_exports();
    FILE_CHANGE_EXCLUDED_PREFIXES = ["deps/", "ops/"];
    ANNOUNCEMENT_PATH_RE = /^announcements\/([^/]+)\.md$/;
    FILE_SUMMARY = {
      create: "New file",
      update: "Modified on disk",
      delete: "Deleted on disk"
    };
    ANNOUNCEMENT_SUMMARY = {
      create: "New announcement",
      update: "Edited announcement",
      delete: "Withdrawn announcement"
    };
    GET25 = async ({ params }) => {
      const id = parseInt(params.id || "", 10);
      const database = databaseInstancesQueries.getById(id);
      if (!database) error(404, "Database not found");
      const [status, incomingChanges, branches, repoInfo] = await Promise.all([
        getStatus(database.local_path),
        getIncomingChanges(database.local_path),
        getBranches(database.local_path),
        getRepoInfo(database.repository_url, database.personal_access_token)
      ]);
      let draftChanges = null;
      if (database.personal_access_token) {
        draftChanges = listDraftEntityChanges(id);
        const now = (/* @__PURE__ */ new Date()).toISOString();
        const buckets = [
          [status.untracked, "create"],
          [status.modified, "update"],
          [status.deleted, "delete"]
        ];
        for (const [paths, op] of buckets) for (const filepath of paths) {
          if (FILE_CHANGE_EXCLUDED_PREFIXES.some((prefix) => filepath.startsWith(prefix))) continue;
          draftChanges.push(await buildFileChange(filepath, op, id, database.local_path, now));
        }
      }
      return json({
        status,
        incomingChanges,
        branches,
        repoInfo,
        draftChanges
      });
    };
  }
});

// dist/build/server/entries/endpoints/databases/_id_/commits/data/_server.ts.js
var server_ts_exports33 = {};
__export(server_ts_exports33, {
  GET: () => GET26
});
var DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE, GET26;
var init_server_ts33 = __esm({
  async "dist/build/server/entries/endpoints/databases/_id_/commits/data/_server.ts.js"() {
    "use strict";
    await init_databaseInstances();
    await init_git();
    init_exports();
    DEFAULT_PAGE_SIZE = 20;
    MAX_PAGE_SIZE = 200;
    GET26 = async ({ params, url }) => {
      const id = parseInt(params.id || "", 10);
      const database = databaseInstancesQueries.getById(id);
      if (!database) error(404, "Database not found");
      const page2 = Math.max(1, parseInt(url.searchParams.get("page") || "1", 10) || 1);
      const rawPageSize = parseInt(url.searchParams.get("pageSize") || String(DEFAULT_PAGE_SIZE), 10) || DEFAULT_PAGE_SIZE;
      const pageSize = Math.min(MAX_PAGE_SIZE, Math.max(1, rawPageSize));
      const branch2 = (await getStatus(database.local_path, { fetch: true })).branch;
      const availableRef = branch2 ? `HEAD..origin/${branch2}` : null;
      const availableCount = availableRef ? await countCommits(database.local_path, availableRef) : 0;
      const installedCount = await countCommits(database.local_path, "HEAD");
      const totalCount = installedCount + availableCount;
      const skip = (page2 - 1) * pageSize;
      const commits = [];
      if (skip < availableCount && availableRef) {
        const availableLimit = Math.min(pageSize, availableCount - skip);
        const availableSlice = await getCommits(database.local_path, availableLimit, availableRef, "available", skip);
        commits.push(...availableSlice);
        const remaining = pageSize - availableSlice.length;
        if (remaining > 0 && installedCount > 0) {
          const installedSlice = await getCommits(database.local_path, remaining, "HEAD", "installed", 0);
          commits.push(...installedSlice);
        }
      } else if (installedCount > 0) {
        const installedSkip = skip - availableCount;
        const installedSlice = await getCommits(database.local_path, pageSize, "HEAD", "installed", installedSkip);
        commits.push(...installedSlice);
      }
      return json({
        commits,
        totalCount,
        page: page2,
        pageSize,
        branch: branch2,
        repositoryUrl: database.repository_url
      });
    };
  }
});

// dist/build/server/chunks/portable.js
var ENTITY_TYPES;
var init_portable = __esm({
  "dist/build/server/chunks/portable.js"() {
    "use strict";
    ENTITY_TYPES = [
      "delay_profile",
      "regular_expression",
      "custom_format",
      "quality_profile",
      "radarr_naming",
      "sonarr_naming",
      "radarr_media_settings",
      "sonarr_media_settings",
      "radarr_quality_definitions",
      "sonarr_quality_definitions"
    ];
  }
});

// dist/build/server/entries/endpoints/databases/_id_/export/_server.ts.js
var server_ts_exports34 = {};
__export(server_ts_exports34, {
  GET: () => GET27
});
async function serializeDelayProfile(cache3, name) {
  const row = await getByName(cache3, name);
  if (!row) throw new Error(`Delay profile "${name}" not found`);
  return {
    name: row.name,
    preferredProtocol: row.preferred_protocol,
    usenetDelay: row.usenet_delay ?? 0,
    torrentDelay: row.torrent_delay ?? 0,
    bypassIfHighestQuality: row.bypass_if_highest_quality,
    bypassIfAboveCfScore: row.bypass_if_above_custom_format_score,
    minimumCfScore: row.minimum_custom_format_score ?? 0
  };
}
async function serializeRegularExpression(cache3, name) {
  const db2 = cache3.kb;
  const regex = await db2.selectFrom("regular_expressions").select([
    "name",
    "pattern",
    "description",
    "regex101_id"
  ]).where("name", "=", name).executeTakeFirst();
  if (!regex) throw new Error(`Regular expression "${name}" not found`);
  const tags = await db2.selectFrom("regular_expression_tags as ret").innerJoin("tags as t", "t.name", "ret.tag_name").select(["t.name"]).where("ret.regular_expression_name", "=", name).orderBy("t.name").execute();
  return {
    name: regex.name,
    pattern: regex.pattern,
    tags: tags.map((t2) => t2.name),
    description: regex.description || null,
    regex101Id: regex.regex101_id || null
  };
}
async function serializeCustomFormat(cache3, name) {
  const db2 = cache3.kb;
  const format = await db2.selectFrom("custom_formats").select([
    "name",
    "description",
    "include_in_rename"
  ]).where("name", "=", name).executeTakeFirst();
  if (!format) throw new Error(`Custom format "${name}" not found`);
  const tags = await db2.selectFrom("custom_format_tags as cft").innerJoin("tags as t", "t.name", "cft.tag_name").select(["t.name"]).where("cft.custom_format_name", "=", name).orderBy("t.name").execute();
  const conditions = await getConditionsForEvaluation(cache3, name);
  const tests = await listTests(cache3, name);
  return {
    name: format.name,
    description: format.description || null,
    includeInRename: format.include_in_rename === 1,
    tags: tags.map((t2) => t2.name),
    conditions,
    tests: tests.map((t2) => ({
      title: t2.title,
      type: t2.type,
      shouldMatch: t2.should_match,
      description: t2.description
    }))
  };
}
async function serializeQualityProfile(cache3, name) {
  const db2 = cache3.kb;
  const profile = await db2.selectFrom("quality_profiles").select([
    "name",
    "description",
    "upgrades_allowed",
    "minimum_custom_format_score",
    "upgrade_until_score",
    "upgrade_score_increment"
  ]).where("name", "=", name).executeTakeFirst();
  if (!profile) throw new Error(`Quality profile "${name}" not found`);
  const tags = await db2.selectFrom("quality_profile_tags as qpt").innerJoin("tags as t", "t.name", "qpt.tag_name").select(["t.name"]).where("qpt.quality_profile_name", "=", name).orderBy("t.name").execute();
  const languageRow = await db2.selectFrom("quality_profile_languages as qpl").select(["qpl.language_name"]).where("qpl.quality_profile_name", "=", name).executeTakeFirst();
  const qualitiesData = await qualities(cache3, 0, name);
  const scores = await db2.selectFrom("quality_profile_custom_formats").select([
    "custom_format_name",
    "arr_type",
    "score"
  ]).where("quality_profile_name", "=", name).execute();
  return {
    name: profile.name,
    description: profile.description || null,
    tags: tags.map((t2) => t2.name),
    language: languageRow?.language_name ?? null,
    orderedItems: qualitiesData.orderedItems,
    upgradesAllowed: profile.upgrades_allowed === 1,
    minimumScore: profile.minimum_custom_format_score,
    upgradeUntilScore: profile.upgrade_until_score,
    upgradeScoreIncrement: profile.upgrade_score_increment,
    customFormatScores: scores.map((s3) => ({
      customFormatName: s3.custom_format_name,
      arrType: s3.arr_type,
      score: s3.score
    }))
  };
}
async function serializeRadarrNaming(cache3, name) {
  const row = await getRadarrByName$1(cache3, name);
  if (!row) throw new Error(`Radarr naming "${name}" not found`);
  return {
    name: row.name,
    rename: row.rename,
    movieFormat: row.movie_format,
    movieFolderFormat: row.movie_folder_format,
    replaceIllegalCharacters: row.replace_illegal_characters,
    colonReplacementFormat: row.colon_replacement_format
  };
}
async function serializeSonarrNaming(cache3, name) {
  const row = await getSonarrByName$1(cache3, name);
  if (!row) throw new Error(`Sonarr naming "${name}" not found`);
  return {
    name: row.name,
    rename: row.rename,
    standardEpisodeFormat: row.standard_episode_format,
    dailyEpisodeFormat: row.daily_episode_format,
    animeEpisodeFormat: row.anime_episode_format,
    seriesFolderFormat: row.series_folder_format,
    seasonFolderFormat: row.season_folder_format,
    replaceIllegalCharacters: row.replace_illegal_characters,
    colonReplacementFormat: row.colon_replacement_format,
    customColonReplacementFormat: row.custom_colon_replacement_format,
    multiEpisodeStyle: row.multi_episode_style
  };
}
async function serializeRadarrMediaSettings(cache3, name) {
  const row = await getRadarrByName$2(cache3, name);
  if (!row) throw new Error(`Radarr media settings "${name}" not found`);
  return {
    name: row.name,
    propersRepacks: row.propers_repacks,
    enableMediaInfo: row.enable_media_info
  };
}
async function serializeSonarrMediaSettings(cache3, name) {
  const row = await getSonarrByName$2(cache3, name);
  if (!row) throw new Error(`Sonarr media settings "${name}" not found`);
  return {
    name: row.name,
    propersRepacks: row.propers_repacks,
    enableMediaInfo: row.enable_media_info
  };
}
async function serializeRadarrQualityDefinitions(cache3, name) {
  const config2 = await getRadarrByName(cache3, name);
  if (!config2) throw new Error(`Radarr quality definitions "${name}" not found`);
  return {
    name: config2.name,
    entries: config2.entries
  };
}
async function serializeSonarrQualityDefinitions(cache3, name) {
  const config2 = await getSonarrByName(cache3, name);
  if (!config2) throw new Error(`Sonarr quality definitions "${name}" not found`);
  return {
    name: config2.name,
    entries: config2.entries
  };
}
async function serializeEntity(cache3, entityType, name) {
  switch (entityType) {
    case "delay_profile":
      return serializeDelayProfile(cache3, name);
    case "regular_expression":
      return serializeRegularExpression(cache3, name);
    case "custom_format":
      return serializeCustomFormat(cache3, name);
    case "quality_profile":
      return serializeQualityProfile(cache3, name);
    case "radarr_naming":
      return serializeRadarrNaming(cache3, name);
    case "sonarr_naming":
      return serializeSonarrNaming(cache3, name);
    case "radarr_media_settings":
      return serializeRadarrMediaSettings(cache3, name);
    case "sonarr_media_settings":
      return serializeSonarrMediaSettings(cache3, name);
    case "radarr_quality_definitions":
      return serializeRadarrQualityDefinitions(cache3, name);
    case "sonarr_quality_definitions":
      return serializeSonarrQualityDefinitions(cache3, name);
  }
}
var VALID_ENTITY_TYPES, GET27;
var init_server_ts34 = __esm({
  async "dist/build/server/entries/endpoints/databases/_id_/export/_server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_create();
    await init_customFormats();
    init_read3();
    init_portable();
    await init_naming();
    await init_media_settings();
    await init_quality_definitions();
    init_exports();
    VALID_ENTITY_TYPES = new Set(ENTITY_TYPES);
    GET27 = async ({ params, url }) => {
      const databaseId = parseInt(params.id ?? "", 10);
      if (isNaN(databaseId)) return json({ error: "Invalid database ID" }, { status: 400 });
      const entityType = url.searchParams.get("entityType");
      const name = url.searchParams.get("name");
      if (!entityType || !name) return json({ error: "Missing required parameters: entityType, name" }, { status: 400 });
      if (!VALID_ENTITY_TYPES.has(entityType)) return json({ error: `Invalid entityType: ${entityType}` }, { status: 400 });
      const cache3 = pcdManager.getCache(databaseId);
      if (!cache3) return json({ error: "Database not found" }, { status: 404 });
      try {
        const data = await serializeEntity(cache3, entityType, name);
        return json({
          entityType,
          data
        });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Export failed";
        if (message2.includes("not found")) return json({ error: message2 }, { status: 404 });
        return json({ error: message2 }, { status: 400 });
      }
    };
  }
});

// dist/build/server/entries/endpoints/databases/_id_/import/_server.ts.js
var server_ts_exports35 = {};
__export(server_ts_exports35, {
  POST: () => POST10
});
async function deserializeDelayProfile(options2) {
  const { databaseId, cache: cache3, layer, portable } = options2;
  return create$1({
    databaseId,
    cache: cache3,
    layer,
    input: portable
  });
}
async function deserializeRegularExpression(options2) {
  const { databaseId, cache: cache3, layer, portable } = options2;
  return create3({
    databaseId,
    cache: cache3,
    layer,
    input: portable
  });
}
async function deserializeCustomFormat(options2) {
  const { databaseId, cache: cache3, layer, portable } = options2;
  const createResult = await create({
    databaseId,
    cache: cache3,
    layer,
    input: {
      name: portable.name,
      description: portable.description,
      includeInRename: portable.includeInRename,
      tags: portable.tags
    }
  });
  if (portable.conditions.length > 0) {
    const freshCache = getCache(databaseId);
    if (!freshCache) throw new Error("Database cache not available");
    await updateConditions({
      databaseId,
      cache: freshCache,
      layer,
      formatName: portable.name,
      originalConditions: [],
      conditions: portable.conditions
    });
  }
  for (const test2 of portable.tests) await createTest({
    databaseId,
    layer,
    formatName: portable.name,
    skipRecompile: true,
    input: {
      title: test2.title,
      type: test2.type,
      should_match: test2.shouldMatch,
      description: test2.description
    }
  });
  if (portable.tests.length > 0) await recompileCache(databaseId);
  return createResult;
}
async function deserializeQualityProfile(options2) {
  const { databaseId, cache: cache3, layer, portable } = options2;
  const createResult = await create2({
    databaseId,
    cache: cache3,
    layer,
    input: {
      name: portable.name,
      description: portable.description,
      tags: portable.tags,
      language: portable.language,
      orderedItems: portable.orderedItems
    }
  });
  if (!createResult.success) throw new Error(createResult.error ?? "Failed to create quality profile");
  const freshCache = getCache(databaseId);
  if (!freshCache) throw new Error("Database cache not available");
  await updateScoring({
    databaseId,
    cache: freshCache,
    layer,
    profileName: portable.name,
    input: {
      upgradesAllowed: portable.upgradesAllowed ?? true,
      minimumScore: portable.minimumScore,
      upgradeUntilScore: portable.upgradeUntilScore,
      upgradeScoreIncrement: portable.upgradeScoreIncrement,
      customFormatScores: portable.customFormatScores
    }
  });
  return createResult;
}
async function deserializeRadarrNaming(options2) {
  const { databaseId, cache: cache3, layer, portable } = options2;
  return createRadarrNaming({
    databaseId,
    cache: cache3,
    layer,
    input: portable
  });
}
async function deserializeSonarrNaming(options2) {
  const { databaseId, cache: cache3, layer, portable } = options2;
  return createSonarrNaming({
    databaseId,
    cache: cache3,
    layer,
    input: portable
  });
}
async function deserializeRadarrMediaSettings(options2) {
  const { databaseId, cache: cache3, layer, portable } = options2;
  return createRadarrMediaSettings({
    databaseId,
    cache: cache3,
    layer,
    input: portable
  });
}
async function deserializeSonarrMediaSettings(options2) {
  const { databaseId, cache: cache3, layer, portable } = options2;
  return createSonarrMediaSettings({
    databaseId,
    cache: cache3,
    layer,
    input: portable
  });
}
async function deserializeRadarrQualityDefinitions(options2) {
  const { databaseId, cache: cache3, layer, portable } = options2;
  return createRadarrQualityDefinitions({
    databaseId,
    cache: cache3,
    layer,
    input: portable
  });
}
async function deserializeSonarrQualityDefinitions(options2) {
  const { databaseId, cache: cache3, layer, portable } = options2;
  return createSonarrQualityDefinitions({
    databaseId,
    cache: cache3,
    layer,
    input: portable
  });
}
function validatePortableData(entityType, data) {
  switch (entityType) {
    case "delay_profile":
      return validateDelayProfile(data);
    case "regular_expression":
      return validateRegularExpression(data);
    case "custom_format":
      return validateCustomFormat(data);
    case "quality_profile":
      return validateQualityProfile(data);
    case "radarr_naming":
      return validateRadarrNaming(data);
    case "sonarr_naming":
      return validateSonarrNaming(data);
    case "radarr_media_settings":
    case "sonarr_media_settings":
      return validateMediaSettings(data);
    case "radarr_quality_definitions":
    case "sonarr_quality_definitions":
      return validateQualityDefinitions(data);
    default:
      return null;
  }
}
function requireName(data) {
  if (typeof data.name !== "string" || !data.name.trim()) return "data.name is required and must be a non-empty string";
  return null;
}
function validateDelayProfile(data) {
  const nameError = requireName(data);
  if (nameError) return nameError;
  if (!VALID_PROTOCOLS.has(data.preferredProtocol)) return `data.preferredProtocol must be one of: ${[...VALID_PROTOCOLS].join(", ")}`;
  if (typeof data.usenetDelay !== "number") return "data.usenetDelay must be a number";
  if (typeof data.torrentDelay !== "number") return "data.torrentDelay must be a number";
  if (typeof data.bypassIfHighestQuality !== "boolean") return "data.bypassIfHighestQuality must be a boolean";
  if (typeof data.bypassIfAboveCfScore !== "boolean") return "data.bypassIfAboveCfScore must be a boolean";
  if (typeof data.minimumCfScore !== "number") return "data.minimumCfScore must be a number";
  return null;
}
function validateRegularExpression(data) {
  const nameError = requireName(data);
  if (nameError) return nameError;
  if (typeof data.pattern !== "string") return "data.pattern must be a string";
  if (!Array.isArray(data.tags)) return "data.tags must be an array";
  if (data.description !== null && typeof data.description !== "string") return "data.description must be a string or null";
  if (data.regex101Id !== null && typeof data.regex101Id !== "string") return "data.regex101Id must be a string or null";
  return null;
}
function validateCustomFormat(data) {
  const nameError = requireName(data);
  if (nameError) return nameError;
  if (data.description !== null && typeof data.description !== "string") return "data.description must be a string or null";
  if (typeof data.includeInRename !== "boolean") return "data.includeInRename must be a boolean";
  if (!Array.isArray(data.tags)) return "data.tags must be an array";
  if (!Array.isArray(data.conditions)) return "data.conditions must be an array";
  if (!Array.isArray(data.tests)) return "data.tests must be an array";
  return null;
}
function validateQualityProfile(data) {
  const nameError = requireName(data);
  if (nameError) return nameError;
  if (data.description !== null && typeof data.description !== "string") return "data.description must be a string or null";
  if (!Array.isArray(data.tags)) return "data.tags must be an array";
  if (data.language !== null && typeof data.language !== "string") return "data.language must be a string or null";
  if (!Array.isArray(data.orderedItems)) return "data.orderedItems must be an array";
  if (data.upgradesAllowed !== void 0 && typeof data.upgradesAllowed !== "boolean") return "data.upgradesAllowed must be a boolean";
  if (typeof data.minimumScore !== "number") return "data.minimumScore must be a number";
  if (typeof data.upgradeUntilScore !== "number") return "data.upgradeUntilScore must be a number";
  if (typeof data.upgradeScoreIncrement !== "number") return "data.upgradeScoreIncrement must be a number";
  if (!Array.isArray(data.customFormatScores)) return "data.customFormatScores must be an array";
  return null;
}
function validateRadarrNaming(data) {
  const nameError = requireName(data);
  if (nameError) return nameError;
  if (typeof data.rename !== "boolean") return "data.rename must be a boolean";
  if (typeof data.movieFormat !== "string") return "data.movieFormat must be a string";
  if (typeof data.movieFolderFormat !== "string") return "data.movieFolderFormat must be a string";
  if (typeof data.replaceIllegalCharacters !== "boolean") return "data.replaceIllegalCharacters must be a boolean";
  if (!VALID_COLON_FORMATS.has(data.colonReplacementFormat)) return `data.colonReplacementFormat must be one of: ${[...VALID_COLON_FORMATS].join(", ")}`;
  return null;
}
function validateSonarrNaming(data) {
  const nameError = requireName(data);
  if (nameError) return nameError;
  if (typeof data.rename !== "boolean") return "data.rename must be a boolean";
  if (typeof data.standardEpisodeFormat !== "string") return "data.standardEpisodeFormat must be a string";
  if (typeof data.dailyEpisodeFormat !== "string") return "data.dailyEpisodeFormat must be a string";
  if (typeof data.animeEpisodeFormat !== "string") return "data.animeEpisodeFormat must be a string";
  if (typeof data.seriesFolderFormat !== "string") return "data.seriesFolderFormat must be a string";
  if (typeof data.seasonFolderFormat !== "string") return "data.seasonFolderFormat must be a string";
  if (typeof data.replaceIllegalCharacters !== "boolean") return "data.replaceIllegalCharacters must be a boolean";
  if (!VALID_COLON_FORMATS.has(data.colonReplacementFormat)) return `data.colonReplacementFormat must be one of: ${[...VALID_COLON_FORMATS].join(", ")}`;
  if (data.customColonReplacementFormat !== null && typeof data.customColonReplacementFormat !== "string") return "data.customColonReplacementFormat must be a string or null";
  if (!VALID_MULTI_EPISODE_STYLES.has(data.multiEpisodeStyle)) return `data.multiEpisodeStyle must be one of: ${[...VALID_MULTI_EPISODE_STYLES].join(", ")}`;
  return null;
}
function validateMediaSettings(data) {
  const nameError = requireName(data);
  if (nameError) return nameError;
  if (!VALID_PROPERS_REPACKS.has(data.propersRepacks)) return `data.propersRepacks must be one of: ${[...VALID_PROPERS_REPACKS].join(", ")}`;
  if (typeof data.enableMediaInfo !== "boolean") return "data.enableMediaInfo must be a boolean";
  return null;
}
function validateQualityDefinitions(data) {
  const nameError = requireName(data);
  if (nameError) return nameError;
  if (!Array.isArray(data.entries)) return "data.entries must be an array";
  for (const entry of data.entries) {
    if (typeof entry.quality_name !== "string") return "Each entry must have a quality_name string";
    if (typeof entry.min_size !== "number") return "Each entry must have a min_size number";
    if (typeof entry.max_size !== "number") return "Each entry must have a max_size number";
    if (typeof entry.preferred_size !== "number") return "Each entry must have a preferred_size number";
  }
  return null;
}
async function deserializeEntity({ databaseId, cache: cache3, layer, entityType, data }) {
  const opts = {
    databaseId,
    cache: cache3,
    layer
  };
  switch (entityType) {
    case "delay_profile":
      return deserializeDelayProfile({
        ...opts,
        portable: data
      });
    case "regular_expression":
      return deserializeRegularExpression({
        ...opts,
        portable: data
      });
    case "custom_format":
      return deserializeCustomFormat({
        ...opts,
        portable: data
      });
    case "quality_profile":
      return deserializeQualityProfile({
        ...opts,
        portable: data
      });
    case "radarr_naming":
      return deserializeRadarrNaming({
        ...opts,
        portable: data
      });
    case "sonarr_naming":
      return deserializeSonarrNaming({
        ...opts,
        portable: data
      });
    case "radarr_media_settings":
      return deserializeRadarrMediaSettings({
        ...opts,
        portable: data
      });
    case "sonarr_media_settings":
      return deserializeSonarrMediaSettings({
        ...opts,
        portable: data
      });
    case "radarr_quality_definitions":
      return deserializeRadarrQualityDefinitions({
        ...opts,
        portable: data
      });
    case "sonarr_quality_definitions":
      return deserializeSonarrQualityDefinitions({
        ...opts,
        portable: data
      });
  }
}
var VALID_PROTOCOLS, VALID_COLON_FORMATS, VALID_MULTI_EPISODE_STYLES, VALID_PROPERS_REPACKS, VALID_ENTITY_TYPES2, VALID_LAYERS, POST10;
var init_server_ts35 = __esm({
  async "dist/build/server/entries/endpoints/databases/_id_/import/_server.ts.js"() {
    "use strict";
    await init_queueService();
    init_registry();
    await init_create();
    await init_customFormats();
    init_portable();
    await init_naming();
    await init_media_settings();
    await init_quality_definitions();
    await init_regularExpressions();
    init_exports();
    VALID_PROTOCOLS = /* @__PURE__ */ new Set([
      "prefer_usenet",
      "prefer_torrent",
      "only_usenet",
      "only_torrent"
    ]);
    VALID_COLON_FORMATS = /* @__PURE__ */ new Set([
      "delete",
      "dash",
      "spaceDash",
      "spaceDashSpace",
      "smart",
      "custom"
    ]);
    VALID_MULTI_EPISODE_STYLES = /* @__PURE__ */ new Set([
      "extend",
      "duplicate",
      "repeat",
      "scene",
      "range",
      "prefixedRange"
    ]);
    VALID_PROPERS_REPACKS = /* @__PURE__ */ new Set([
      "doNotPrefer",
      "preferAndUpgrade",
      "doNotUpgradeAutomatically"
    ]);
    VALID_ENTITY_TYPES2 = new Set(ENTITY_TYPES);
    VALID_LAYERS = /* @__PURE__ */ new Set(["user", "base"]);
    POST10 = async ({ params, request }) => {
      const databaseId = parseInt(params.id ?? "", 10);
      if (isNaN(databaseId)) return json({ error: "Invalid database ID" }, { status: 400 });
      let body;
      try {
        body = await request.json();
      } catch {
        return json({ error: "Invalid JSON body" }, { status: 400 });
      }
      const { layer, entityType, data } = body;
      if (!layer || !entityType || !data) return json({ error: "Missing required fields: layer, entityType, data" }, { status: 400 });
      if (!VALID_LAYERS.has(layer)) return json({ error: `Invalid layer: ${layer}` }, { status: 400 });
      if (!VALID_ENTITY_TYPES2.has(entityType)) return json({ error: `Invalid entityType: ${entityType}` }, { status: 400 });
      if (layer === "base" && !canWriteToBase(databaseId)) return json({ error: "Cannot write to base layer" }, { status: 403 });
      const cache3 = pcdManager.getCache(databaseId);
      if (!cache3) return json({ error: "Database not found" }, { status: 404 });
      const validationError = validatePortableData(entityType, data);
      if (validationError) return json({ error: validationError }, { status: 400 });
      try {
        await deserializeEntity({
          databaseId,
          cache: cache3,
          layer,
          entityType,
          data
        });
        return json({ success: true });
      } catch (err) {
        const message2 = err instanceof Error ? err.message : "Import failed";
        const status = message2.includes("already exists") ? 409 : 400;
        return json({ error: message2 }, { status });
      }
    };
  }
});

// dist/build/server/entries/endpoints/delay-profiles/_databaseId_/first/_server.ts.js
var server_ts_exports36 = {};
__export(server_ts_exports36, {
  GET: () => GET28
});
var GET28;
var init_server_ts36 = __esm({
  async "dist/build/server/entries/endpoints/delay-profiles/_databaseId_/first/_server.ts.js"() {
    "use strict";
    await init_queueService();
    init_exports();
    GET28 = async ({ params }) => {
      const dbId = parseInt(params.databaseId, 10);
      if (isNaN(dbId)) error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(dbId);
      if (!cache3) error(404, "Database cache not available");
      const profiles = await list$4(cache3);
      const path = profiles.length ? `/delay-profiles/${dbId}/${encodeURIComponent(profiles[0].name)}` : `/delay-profiles/${dbId}/new`;
      return json({ path });
    };
  }
});

// dist/build/server/entries/endpoints/dev/api/_server.ts.js
var server_ts_exports37 = {};
__export(server_ts_exports37, {
  GET: () => GET29
});
var GET29;
var init_server_ts37 = __esm({
  "dist/build/server/entries/endpoints/dev/api/_server.ts.js"() {
    "use strict";
    init_exports();
    GET29 = async ({ url }) => {
      throw redirect(302, "/");
    };
  }
});

// dist/build/server/entries/endpoints/jobs/events/_server.ts.js
var server_ts_exports38 = {};
__export(server_ts_exports38, {
  GET: () => GET30
});
var GET30;
var init_server_ts38 = __esm({
  "dist/build/server/entries/endpoints/jobs/events/_server.ts.js"() {
    "use strict";
    init_jobEvents();
    GET30 = () => {
      const encoder4 = new TextEncoder();
      let unsubscribe;
      let keepalive;
      const stream = new ReadableStream({
        start(controller2) {
          unsubscribe = jobEvents.subscribe((event) => {
            const line = `event: ${event.type}
data: ${JSON.stringify(event)}

`;
            try {
              controller2.enqueue(encoder4.encode(line));
            } catch {
            }
          });
          keepalive = setInterval(() => {
            try {
              controller2.enqueue(encoder4.encode(": keepalive\n\n"));
            } catch {
              clearInterval(keepalive);
            }
          }, 3e4);
        },
        cancel() {
          unsubscribe?.();
          if (keepalive) clearInterval(keepalive);
        }
      });
      return new Response(stream, { headers: {
        "Content-Type": "text/event-stream",
        "Cache-Control": "no-cache, no-transform",
        Connection: "keep-alive",
        "X-Accel-Buffering": "no"
      } });
    };
  }
});

// dist/build/server/entries/endpoints/media-management/_databaseId_/media-settings/first/_server.ts.js
var server_ts_exports39 = {};
__export(server_ts_exports39, {
  GET: () => GET31
});
var GET31;
var init_server_ts39 = __esm({
  async "dist/build/server/entries/endpoints/media-management/_databaseId_/media-settings/first/_server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_media_settings();
    init_exports();
    GET31 = async ({ params }) => {
      const dbId = parseInt(params.databaseId, 10);
      if (isNaN(dbId)) error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(dbId);
      if (!cache3) error(404, "Database cache not available");
      const items = await list$3(cache3);
      const path = items.length ? `/media-management/${dbId}/media-settings/${items[0].arr_type}/${encodeURIComponent(items[0].name)}` : `/media-management/${dbId}/media-settings`;
      return json({ path });
    };
  }
});

// dist/build/server/entries/endpoints/media-management/_databaseId_/naming/first/_server.ts.js
var server_ts_exports40 = {};
__export(server_ts_exports40, {
  GET: () => GET32
});
var GET32;
var init_server_ts40 = __esm({
  async "dist/build/server/entries/endpoints/media-management/_databaseId_/naming/first/_server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_naming();
    init_exports();
    GET32 = async ({ params }) => {
      const dbId = parseInt(params.databaseId, 10);
      if (isNaN(dbId)) error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(dbId);
      if (!cache3) error(404, "Database cache not available");
      const items = await list$2(cache3);
      const path = items.length ? `/media-management/${dbId}/naming/${items[0].arr_type}/${encodeURIComponent(items[0].name)}` : `/media-management/${dbId}/naming`;
      return json({ path });
    };
  }
});

// dist/build/server/entries/endpoints/media-management/_databaseId_/quality-definitions/first/_server.ts.js
var server_ts_exports41 = {};
__export(server_ts_exports41, {
  GET: () => GET33
});
var GET33;
var init_server_ts41 = __esm({
  async "dist/build/server/entries/endpoints/media-management/_databaseId_/quality-definitions/first/_server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_quality_definitions();
    init_exports();
    GET33 = async ({ params }) => {
      const dbId = parseInt(params.databaseId, 10);
      if (isNaN(dbId)) error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(dbId);
      if (!cache3) error(404, "Database cache not available");
      const items = await list$1(cache3);
      const path = items.length ? `/media-management/${dbId}/quality-definitions/${items[0].arr_type}/${encodeURIComponent(items[0].name)}` : `/media-management/${dbId}/quality-definitions`;
      return json({ path });
    };
  }
});

// dist/build/server/entries/endpoints/quality-profiles/entity-testing/_databaseId_/evaluate/_server.ts.js
var server_ts_exports42 = {};
__export(server_ts_exports42, {
  POST: () => POST11
});
function getArrTypeForRelease(type) {
  return type === "movie" ? "radarr" : "sonarr";
}
var POST11;
var init_server_ts42 = __esm({
  async "dist/build/server/entries/endpoints/quality-profiles/entity-testing/_databaseId_/evaluate/_server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_create();
    await init_customFormats();
    await init_client2();
    await init_parser();
    init_exports();
    POST11 = async ({ params, request }) => {
      const databaseId = Number(params.databaseId);
      if (!Number.isFinite(databaseId)) throw error(400, "Invalid databaseId");
      const { releases } = await request.json();
      if (!releases || !Array.isArray(releases) || releases.length === 0) throw error(400, "Missing or empty releases array");
      if (!await isParserHealthy()) return json({
        parserAvailable: false,
        evaluations: releases.map((r2) => ({
          releaseId: r2.id,
          title: r2.title,
          cfMatches: {}
        }))
      });
      const parseItems = releases.map((r2) => ({
        title: r2.title,
        type: r2.type
      }));
      const parseResults = await parseWithCacheBatch(parseItems);
      const cache3 = pcdManager.getCache(databaseId);
      if (!cache3) throw error(404, "Database not found or cache not available");
      const customFormats = await getAllConditionsForEvaluation(cache3);
      const releaseArrTypes = new Set(releases.map((release) => getArrTypeForRelease(release.type)));
      const customFormatsForPatternMatching = customFormats.map((cf) => {
        const conditions = /* @__PURE__ */ new Set();
        for (const arrType of releaseArrTypes) for (const condition of filterConditionsForArrType(cf.conditions, arrType)) conditions.add(condition);
        return {
          name: cf.name,
          conditions: [...conditions]
        };
      });
      const patternsByType = extractPatternsByType(customFormatsForPatternMatching);
      const releaseTitles = releases.map((r2) => r2.title);
      const editionTexts = /* @__PURE__ */ new Set();
      const releaseGroupTexts = /* @__PURE__ */ new Set();
      for (const release of releases) {
        const parsed = parseResults.get(`${release.title}:${release.type}`);
        if (parsed?.edition) editionTexts.add(parsed.edition);
        if (parsed?.releaseGroup) releaseGroupTexts.add(parsed.releaseGroup);
      }
      const [titleMatches, editionMatches, rgMatches] = await Promise.all([
        patternsByType.title.length > 0 ? matchPatternsBatch(releaseTitles, patternsByType.title) : Promise.resolve(/* @__PURE__ */ new Map()),
        patternsByType.edition.length > 0 && editionTexts.size > 0 ? matchPatternsBatch([...editionTexts], patternsByType.edition) : Promise.resolve(/* @__PURE__ */ new Map()),
        patternsByType.releaseGroup.length > 0 && releaseGroupTexts.size > 0 ? matchPatternsBatch([...releaseGroupTexts], patternsByType.releaseGroup) : Promise.resolve(/* @__PURE__ */ new Map())
      ]);
      const parserFailed = titleMatches === null || editionMatches === null || rgMatches === null;
      const evaluations = releases.map((release) => {
        const cacheKey = `${release.title}:${release.type}`;
        const parsed = parseResults.get(cacheKey);
        if (!parsed) return {
          releaseId: release.id,
          title: release.title,
          cfMatches: {}
        };
        const patternMatchMaps = parserFailed ? null : {
          title: titleMatches?.get(release.title) ?? /* @__PURE__ */ new Map(),
          edition: parsed.edition ? editionMatches?.get(parsed.edition) ?? /* @__PURE__ */ new Map() : /* @__PURE__ */ new Map(),
          releaseGroup: parsed.releaseGroup ? rgMatches?.get(parsed.releaseGroup) ?? /* @__PURE__ */ new Map() : /* @__PURE__ */ new Map()
        };
        const cfMatches = {};
        const arrType = getArrTypeForRelease(release.type);
        for (const cf of customFormats) {
          const conditions = filterConditionsForArrType(cf.conditions, arrType);
          if (conditions.length === 0) {
            cfMatches[cf.name] = false;
            continue;
          }
          const result = evaluateCustomFormat(conditions, parsed, release.title, patternMatchMaps, release.languages);
          cfMatches[cf.name] = result.matches;
        }
        return {
          releaseId: release.id,
          title: release.title,
          parsed: getParsedInfo(parsed, release.languages),
          cfMatches
        };
      });
      return json({
        parserAvailable: true,
        evaluations
      });
    };
  }
});

// dist/build/server/entries/endpoints/quality-profiles/_databaseId_/first/_tab_/_server.ts.js
var server_ts_exports43 = {};
__export(server_ts_exports43, {
  GET: () => GET34
});
var TABS2, GET34;
var init_server_ts43 = __esm({
  async "dist/build/server/entries/endpoints/quality-profiles/_databaseId_/first/_tab_/_server.ts.js"() {
    "use strict";
    await init_queueService();
    init_exports();
    TABS2 = /* @__PURE__ */ new Set([
      "general",
      "scoring",
      "qualities"
    ]);
    GET34 = async ({ params }) => {
      const dbId = parseInt(params.databaseId, 10);
      if (isNaN(dbId)) error(400, "Invalid database ID");
      if (!TABS2.has(params.tab)) error(400, "Invalid tab");
      const cache3 = pcdManager.getCache(dbId);
      if (!cache3) error(404, "Database cache not available");
      const profiles = await list2(cache3);
      const path = profiles.length ? `/quality-profiles/${dbId}/${profiles[0].id}/${params.tab}` : `/quality-profiles/${dbId}`;
      return json({ path });
    };
  }
});

// dist/build/server/entries/endpoints/regular-expressions/regex101/_...id_/_server.ts.js
var server_ts_exports44 = {};
__export(server_ts_exports44, {
  GET: () => GET35
});
async function runRegexTests(pattern2, tests) {
  if (tests.length === 0) return tests;
  try {
    return await Promise.all(tests.map(async (test2) => {
      try {
        const response = await fetch(`${config.parserUrl}/match`, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            text: test2.testString,
            patterns: [pattern2]
          })
        });
        if (!response.ok) {
          await logger.warn("Parser match request failed", {
            source: "Regex101API",
            meta: {
              status: response.status,
              testString: test2.testString
            }
          });
          return { ...test2 };
        }
        const matched = (await response.json()).results?.[pattern2] ?? false;
        const shouldMatch = test2.criteria === "DOES_MATCH";
        return {
          ...test2,
          actual: matched,
          passed: matched === shouldMatch
        };
      } catch {
        return { ...test2 };
      }
    }));
  } catch (err) {
    await logger.error("Failed to run regex tests", {
      source: "Regex101API",
      meta: { error: String(err) }
    });
    return tests;
  }
}
var regex101CacheQueries, GET35;
var init_server_ts44 = __esm({
  async "dist/build/server/entries/endpoints/regular-expressions/regex101/_...id_/_server.ts.js"() {
    "use strict";
    await init_db();
    init_config();
    init_exports();
    regex101CacheQueries = {
      /**
      * Get cached response by regex101 ID
      */
      get(regex101Id) {
        return db.queryFirst("SELECT * FROM regex101_cache WHERE regex101_id = ?", regex101Id);
      },
      /**
      * Store response in cache (insert or replace)
      */
      set(regex101Id, response) {
        db.execute("INSERT OR REPLACE INTO regex101_cache (regex101_id, response) VALUES (?, ?)", regex101Id, response);
      },
      /**
      * Delete a cached entry
      */
      delete(regex101Id) {
        return db.execute("DELETE FROM regex101_cache WHERE regex101_id = ?", regex101Id) > 0;
      },
      /**
      * Clear all cached entries
      */
      clear() {
        return db.execute("DELETE FROM regex101_cache");
      }
    };
    GET35 = async ({ params, fetch: fetch3 }) => {
      const { id } = params;
      if (!id) throw error(400, "Missing regex101 ID");
      const cached2 = regex101CacheQueries.get(id);
      if (cached2) return json(JSON.parse(cached2.response));
      const [regexId, version] = id.split("/");
      try {
        const response = await fetch3(version ? `https://regex101.com/api/regex/${regexId}/${version}` : `https://regex101.com/api/regex/${regexId}`, { headers: {
          Accept: "application/json",
          "User-Agent": "Profilarr/1.0"
        } });
        if (!response.ok) {
          if (response.status === 404) throw error(404, "Regex not found on regex101");
          throw error(response.status, `Failed to fetch from regex101: ${response.statusText}`);
        }
        const data = await response.json();
        const unitTests = (data.unitTests || []).map((test2) => ({
          description: test2.description || "",
          testString: test2.testString || "",
          criteria: test2.criteria || "DOES_MATCH"
        }));
        const testedUnitTests = await runRegexTests(data.regex, unitTests);
        const result = {
          permalinkFragment: data.permalinkFragment,
          version: data.version,
          regex: data.regex,
          flags: data.flags || "",
          flavor: data.flavor || "pcre2",
          unitTests: testedUnitTests
        };
        regex101CacheQueries.set(id, JSON.stringify(result));
        return json(result);
      } catch (err) {
        if (err && typeof err === "object" && "status" in err) throw err;
        throw error(500, `Failed to fetch regex101 data: ${err instanceof Error ? err.message : "Unknown error"}`);
      }
    };
  }
});

// dist/build/server/entries/endpoints/regular-expressions/validate/_server.ts.js
var server_ts_exports45 = {};
__export(server_ts_exports45, {
  POST: () => POST12
});
var POST12;
var init_server_ts45 = __esm({
  async "dist/build/server/entries/endpoints/regular-expressions/validate/_server.ts.js"() {
    "use strict";
    await init_client2();
    await init_parser();
    init_exports();
    POST12 = async ({ request }) => {
      const { pattern: pattern2 } = await request.json();
      if (!pattern2?.trim()) return json({
        valid: false,
        error: "Pattern is required"
      });
      const result = await validateRegex(pattern2.trim());
      if (result === null) return json({
        valid: true,
        available: false
      });
      return json({
        ...result,
        available: true
      });
    };
  }
});

// dist/build/server/entries/endpoints/regular-expressions/_databaseId_/first/_server.ts.js
var server_ts_exports46 = {};
__export(server_ts_exports46, {
  GET: () => GET36
});
var GET36;
var init_server_ts46 = __esm({
  async "dist/build/server/entries/endpoints/regular-expressions/_databaseId_/first/_server.ts.js"() {
    "use strict";
    await init_queueService();
    await init_update4();
    await init_regularExpressions();
    init_exports();
    GET36 = async ({ params }) => {
      const dbId = parseInt(params.databaseId, 10);
      if (isNaN(dbId)) error(400, "Invalid database ID");
      const cache3 = pcdManager.getCache(dbId);
      if (!cache3) error(404, "Database cache not available");
      const regexes = await list(cache3);
      const path = regexes.length ? `/regular-expressions/${dbId}/${regexes[0].id}` : `/regular-expressions/${dbId}`;
      return json({ path });
    };
  }
});

// dist/build/server/chunks/client3.js
var TMDB_BASE_URL, TMDBClient;
var init_client3 = __esm({
  async "dist/build/server/chunks/client3.js"() {
    "use strict";
    await init_db();
    init_client();
    TMDB_BASE_URL = "https://api.themoviedb.org/3";
    TMDBClient = class extends BaseHttpClient {
      constructor(apiKey) {
        super(TMDB_BASE_URL, { headers: { Authorization: `Bearer ${apiKey}` } });
      }
      /**
      * Validate the API key
      */
      async validateKey() {
        return this.get("/authentication");
      }
      /**
      * Search for movies
      */
      async searchMovies(query, page2 = 1) {
        logger.debug(`Searching movies: "${query}"`, { source: "TMDB" });
        const params = new URLSearchParams({
          query,
          include_adult: "false",
          language: "en-US",
          page: String(page2)
        });
        return this.get(`/search/movie?${params}`);
      }
      /**
      * Search for TV shows
      */
      async searchTVShows(query, page2 = 1) {
        logger.debug(`Searching TV shows: "${query}"`, { source: "TMDB" });
        const params = new URLSearchParams({
          query,
          include_adult: "false",
          language: "en-US",
          page: String(page2)
        });
        return this.get(`/search/tv?${params}`);
      }
    };
  }
});

// dist/build/server/entries/endpoints/tmdb/search/_server.ts.js
var server_ts_exports47 = {};
__export(server_ts_exports47, {
  GET: () => GET37
});
var GET37;
var init_server_ts47 = __esm({
  async "dist/build/server/entries/endpoints/tmdb/search/_server.ts.js"() {
    "use strict";
    await init_db();
    await init_client3();
    await init_tmdbSettings();
    init_exports();
    GET37 = async ({ url }) => {
      const query = url.searchParams.get("query");
      const type = url.searchParams.get("type") || "both";
      const page2 = parseInt(url.searchParams.get("page") || "1", 10);
      if (!query) return json({ error: "Query is required" }, { status: 400 });
      const settings2 = tmdbSettingsQueries.get();
      if (!settings2?.api_key) return json({ error: "TMDB API key not configured" }, { status: 400 });
      try {
        const client2 = new TMDBClient(settings2.api_key);
        if (type === "movie") {
          const result = await client2.searchMovies(query, page2);
          return json({
            results: result.results.map((m3) => ({
              id: m3.id,
              type: "movie",
              title: m3.title,
              overview: m3.overview,
              posterPath: m3.poster_path,
              releaseDate: m3.release_date,
              voteAverage: m3.vote_average,
              popularity: m3.popularity
            })),
            totalPages: result.total_pages,
            totalResults: result.total_results,
            page: result.page
          });
        } else if (type === "tv") {
          const result = await client2.searchTVShows(query, page2);
          return json({
            results: result.results.map((t2) => ({
              id: t2.id,
              type: "series",
              title: t2.name,
              overview: t2.overview,
              posterPath: t2.poster_path,
              releaseDate: t2.first_air_date,
              voteAverage: t2.vote_average,
              popularity: t2.popularity
            })),
            totalPages: result.total_pages,
            totalResults: result.total_results,
            page: result.page
          });
        } else {
          const [movies, tvShows] = await Promise.all([client2.searchMovies(query, page2), client2.searchTVShows(query, page2)]);
          const combined = [...movies.results.map((m3) => ({
            id: m3.id,
            type: "movie",
            title: m3.title,
            overview: m3.overview,
            posterPath: m3.poster_path,
            releaseDate: m3.release_date,
            voteAverage: m3.vote_average,
            popularity: m3.popularity
          })), ...tvShows.results.map((t2) => ({
            id: t2.id,
            type: "series",
            title: t2.name,
            overview: t2.overview,
            posterPath: t2.poster_path,
            releaseDate: t2.first_air_date,
            voteAverage: t2.vote_average,
            popularity: t2.popularity
          }))].sort((a2, b3) => b3.popularity - a2.popularity);
          return json({
            results: combined,
            totalPages: Math.max(movies.total_pages, tvShows.total_pages),
            totalResults: movies.total_results + tvShows.total_results,
            page: page2
          });
        }
      } catch (error2) {
        logger.error(`TMDB search failed: ${error2 instanceof Error ? error2.message : "Unknown error"}`, { source: "TMDB" });
        return json({ error: error2 instanceof Error ? error2.message : "Search failed" }, { status: 500 });
      }
    };
  }
});

// dist/build/server/entries/endpoints/tmdb/validate/_server.ts.js
var server_ts_exports48 = {};
__export(server_ts_exports48, {
  POST: () => POST13
});
var POST13;
var init_server_ts48 = __esm({
  async "dist/build/server/entries/endpoints/tmdb/validate/_server.ts.js"() {
    "use strict";
    await init_client3();
    await init_tmdbSettings();
    init_exports();
    POST13 = async ({ request }) => {
      const { apiKey: providedKey } = await request.json();
      const apiKey = providedKey || tmdbSettingsQueries.get()?.api_key;
      if (!apiKey) return json({
        success: false,
        error: "API key is required"
      }, { status: 400 });
      try {
        const result = await new TMDBClient(apiKey).validateKey();
        if (result.success) return json({ success: true });
        else return json({
          success: false,
          error: result.status_message
        }, { status: 400 });
      } catch (error2) {
        return json({
          success: false,
          error: error2 instanceof Error ? error2.message : "Connection failed"
        }, { status: 400 });
      }
    };
  }
});

// dist/build/server/index.js
init_index_server();
init_shared();
init_internal2();

// dist/build/server/chunks/utils.js
init_shared();
init_uneval();
init_exports();
init_internal();
init_server2();
var ENDPOINT_METHODS = [
  "GET",
  "POST",
  "PUT",
  "PATCH",
  "DELETE",
  "OPTIONS",
  "HEAD"
];
var PAGE_METHODS = [
  "GET",
  "POST",
  "HEAD"
];
var defaultParseOptions = {
  decodeValues: true,
  map: false,
  silent: false,
  split: "auto"
};
function isForbiddenKey(key2) {
  return typeof key2 !== "string" || key2 in {};
}
function createNullObj() {
  return /* @__PURE__ */ Object.create(null);
}
function isNonEmptyString(str2) {
  return typeof str2 === "string" && !!str2.trim();
}
function parseString(setCookieValue, options2) {
  var parts = setCookieValue.split(";").filter(isNonEmptyString);
  var nameValuePairStr = parts.shift();
  if (!nameValuePairStr) return null;
  var parsed = parseNameValuePair(nameValuePairStr);
  var name = parsed.name;
  var value2 = parsed.value;
  options2 = options2 ? Object.assign({}, defaultParseOptions, options2) : defaultParseOptions;
  if (isForbiddenKey(name)) return null;
  try {
    value2 = options2.decodeValues ? decodeURIComponent(value2) : value2;
  } catch (e) {
    console.error("set-cookie-parser: failed to decode cookie value. Set options.decodeValues=false to disable decoding.", e);
  }
  var cookie = createNullObj();
  cookie.name = name;
  cookie.value = value2;
  parts.forEach(function(part) {
    var sides = part.split("=");
    var key2 = sides.shift().trim().toLowerCase();
    if (isForbiddenKey(key2)) return;
    var value3 = sides.join("=").trim();
    if (key2 === "expires") cookie.expires = new Date(value3);
    else if (key2 === "max-age") {
      var n = parseInt(value3, 10);
      if (!Number.isNaN(n)) cookie.maxAge = n;
    } else if (key2 === "secure") cookie.secure = true;
    else if (key2 === "httponly") cookie.httpOnly = true;
    else if (key2 === "samesite") cookie.sameSite = value3;
    else if (key2 === "partitioned") cookie.partitioned = true;
    else if (key2) cookie[key2] = value3;
  });
  return cookie;
}
function parseNameValuePair(nameValuePairStr) {
  var name = "";
  var value2 = "";
  var nameValueArr = nameValuePairStr.split("=");
  if (nameValueArr.length > 1) {
    name = nameValueArr.shift();
    value2 = nameValueArr.join("=");
  } else value2 = nameValuePairStr;
  return {
    name,
    value: value2
  };
}
function parseSetCookie(input, options2) {
  options2 = options2 ? Object.assign({}, defaultParseOptions, options2) : defaultParseOptions;
  if (!input) if (!options2.map) return [];
  else return createNullObj();
  if (input.headers) if (typeof input.headers.getSetCookie === "function") input = input.headers.getSetCookie();
  else if (input.headers["set-cookie"]) input = input.headers["set-cookie"];
  else {
    var sch = input.headers[Object.keys(input.headers).find(function(key2) {
      return key2.toLowerCase() === "set-cookie";
    })];
    if (!sch && input.headers.cookie && !options2.silent) console.warn("Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning.");
    input = sch;
  }
  var split = options2.split;
  var isArray = Array.isArray(input);
  if (split === "auto") split = !isArray;
  if (!isArray) input = [input];
  input = input.filter(isNonEmptyString);
  if (split) input = input.map(splitCookiesString).flat();
  if (!options2.map) return input.map(function(str2) {
    return parseString(str2, options2);
  }).filter(Boolean);
  else {
    var cookies = createNullObj();
    return input.reduce(function(cookies2, str2) {
      var cookie = parseString(str2, options2);
      if (cookie && !isForbiddenKey(cookie.name)) cookies2[cookie.name] = cookie;
      return cookies2;
    }, cookies);
  }
}
function splitCookiesString(cookiesString) {
  if (Array.isArray(cookiesString)) return cookiesString;
  if (typeof cookiesString !== "string") return [];
  var cookiesStrings = [];
  var pos = 0;
  var start;
  var ch;
  var lastComma;
  var nextStart;
  var cookiesSeparatorFound;
  function skipWhitespace() {
    while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) pos += 1;
    return pos < cookiesString.length;
  }
  function notSpecialChar() {
    ch = cookiesString.charAt(pos);
    return ch !== "=" && ch !== ";" && ch !== ",";
  }
  while (pos < cookiesString.length) {
    start = pos;
    cookiesSeparatorFound = false;
    while (skipWhitespace()) {
      ch = cookiesString.charAt(pos);
      if (ch === ",") {
        lastComma = pos;
        pos += 1;
        skipWhitespace();
        nextStart = pos;
        while (pos < cookiesString.length && notSpecialChar()) pos += 1;
        if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
          cookiesSeparatorFound = true;
          pos = nextStart;
          cookiesStrings.push(cookiesString.substring(start, lastComma));
          start = pos;
        } else pos = lastComma + 1;
      } else pos += 1;
    }
    if (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.substring(start, cookiesString.length));
  }
  return cookiesStrings;
}
parseSetCookie.parseSetCookie = parseSetCookie;
parseSetCookie.parse = parseSetCookie;
parseSetCookie.parseString = parseString;
parseSetCookie.splitCookiesString = splitCookiesString;
var decoder = new TextDecoder();
function set_nested_value(object, path_string, value2) {
  if (path_string.startsWith("n:")) {
    path_string = path_string.slice(2);
    value2 = value2 === "" ? void 0 : parseFloat(value2);
  } else if (path_string.startsWith("b:")) {
    path_string = path_string.slice(2);
    value2 = value2 === "on";
  }
  deep_set(object, split_path(path_string), value2);
}
var DELETE_KEY = {};
function convert_formdata(data) {
  const result = {};
  for (let key2 of data.keys()) {
    const is_array2 = key2.endsWith("[]");
    let values = data.getAll(key2);
    if (is_array2) key2 = key2.slice(0, -2);
    values = values.filter((entry) => typeof entry === "string" || entry.name !== "" || entry.size > 0);
    if (values.length === 0 && !is_array2) continue;
    if (key2.startsWith("n:")) {
      key2 = key2.slice(2);
      values = values.map((v3) => v3 === "" ? void 0 : parseFloat(v3));
    } else if (key2.startsWith("b:")) {
      key2 = key2.slice(2);
      values = values.map((v3) => v3 === "on");
    }
    if (values.length > 1 && !is_array2) throw new Error(`Form cannot contain duplicated keys \u2014 "${key2}" has ${values.length} values`);
    set_nested_value(result, key2, is_array2 ? values : values[0]);
  }
  return result;
}
var BINARY_FORM_CONTENT_TYPE = "application/x-sveltekit-formdata";
var BINARY_FORM_VERSION = 0;
var HEADER_BYTES = 7;
async function deserialize_binary_form(request) {
  if (request.headers.get("content-type") !== "application/x-sveltekit-formdata") {
    const form_data = await request.formData();
    return {
      data: convert_formdata(form_data),
      meta: {},
      form_data
    };
  }
  if (!request.body) throw deserialize_error("no body");
  const reader = request.body.getReader();
  const chunks = [];
  function get_chunk(index88) {
    if (index88 in chunks) return chunks[index88];
    let i = chunks.length;
    while (i <= index88) {
      chunks[i] = reader.read().then((chunk) => chunk.value);
      i++;
    }
    return chunks[index88];
  }
  async function get_buffer(offset, length) {
    let start_chunk;
    let chunk_start = 0;
    let chunk_index;
    for (chunk_index = 0; ; chunk_index++) {
      const chunk = await get_chunk(chunk_index);
      if (!chunk) return null;
      const chunk_end = chunk_start + chunk.byteLength;
      if (offset >= chunk_start && offset < chunk_end) {
        start_chunk = chunk;
        break;
      }
      chunk_start = chunk_end;
    }
    if (offset + length <= chunk_start + start_chunk.byteLength) return start_chunk.subarray(offset - chunk_start, offset + length - chunk_start);
    const chunks2 = [start_chunk.subarray(offset - chunk_start)];
    let cursor = start_chunk.byteLength - offset + chunk_start;
    while (cursor < length) {
      chunk_index++;
      let chunk = await get_chunk(chunk_index);
      if (!chunk) return null;
      if (chunk.byteLength > length - cursor) chunk = chunk.subarray(0, length - cursor);
      chunks2.push(chunk);
      cursor += chunk.byteLength;
    }
    const buffer2 = new Uint8Array(length);
    cursor = 0;
    for (const chunk of chunks2) {
      buffer2.set(chunk, cursor);
      cursor += chunk.byteLength;
    }
    return buffer2;
  }
  const header = await get_buffer(0, HEADER_BYTES);
  if (!header) throw deserialize_error("too short");
  if (header[0] !== BINARY_FORM_VERSION) throw deserialize_error(`got version ${header[0]}, expected version ${BINARY_FORM_VERSION}`);
  const header_view = new DataView(header.buffer, header.byteOffset, header.byteLength);
  const data_length = header_view.getUint32(1, true);
  const file_offsets_length = header_view.getUint16(5, true);
  const data_buffer = await get_buffer(HEADER_BYTES, data_length);
  if (!data_buffer) throw deserialize_error("data too short");
  let file_offsets;
  let files_start_offset;
  if (file_offsets_length > 0) {
    const file_offsets_buffer = await get_buffer(HEADER_BYTES + data_length, file_offsets_length);
    if (!file_offsets_buffer) throw deserialize_error("file offset table too short");
    const parsed_offsets = JSON.parse(decoder.decode(file_offsets_buffer));
    if (!Array.isArray(parsed_offsets) || parsed_offsets.some((n) => typeof n !== "number" || !Number.isInteger(n) || n < 0)) throw deserialize_error("invalid file offset table");
    file_offsets = parsed_offsets;
    files_start_offset = HEADER_BYTES + data_length + file_offsets_length;
  }
  const file_spans = [];
  const [data, meta] = parse(decoder.decode(data_buffer), { File: ([name, type, size, last_modified, index88]) => {
    if (typeof name !== "string" || typeof type !== "string" || typeof size !== "number" || typeof last_modified !== "number" || typeof index88 !== "number") throw deserialize_error("invalid file metadata");
    let offset = file_offsets[index88];
    if (offset === void 0) throw deserialize_error("duplicate file offset table index");
    file_offsets[index88] = void 0;
    offset += files_start_offset;
    file_spans.push({
      offset,
      size
    });
    return new Proxy(new LazyFile(name, type, size, last_modified, get_chunk, offset), { getPrototypeOf() {
      return File.prototype;
    } });
  } });
  file_spans.sort((a2, b3) => a2.offset - b3.offset || a2.size - b3.size);
  for (let i = 1; i < file_spans.length; i++) {
    const previous = file_spans[i - 1];
    const current3 = file_spans[i];
    const previous_end = previous.offset + previous.size;
    if (previous_end < current3.offset) throw deserialize_error("gaps in file data");
    if (previous_end > current3.offset) throw deserialize_error("overlapping file data");
  }
  (async () => {
    let has_more = true;
    while (has_more) has_more = !!await get_chunk(chunks.length);
  })().catch(noop2);
  return {
    data,
    meta,
    form_data: null
  };
}
function deserialize_error(message2) {
  return new SvelteKitError(400, "Bad Request", `Could not deserialize binary form: ${message2}`);
}
var LazyFile = class LazyFile2 {
  /** @type {(index: number) => Promise<Uint8Array<ArrayBuffer> | undefined>} */
  #get_chunk;
  /** @type {number} */
  #offset;
  /**
  * @param {string} name
  * @param {string} type
  * @param {number} size
  * @param {number} last_modified
  * @param {(index: number) => Promise<Uint8Array<ArrayBuffer> | undefined>} get_chunk
  * @param {number} offset
  */
  constructor(name, type, size, last_modified, get_chunk, offset) {
    this.name = name;
    this.type = type;
    this.size = size;
    this.lastModified = last_modified;
    this.webkitRelativePath = "";
    this.#get_chunk = get_chunk;
    this.#offset = offset;
    this.arrayBuffer = this.arrayBuffer.bind(this);
    this.bytes = this.bytes.bind(this);
    this.slice = this.slice.bind(this);
    this.stream = this.stream.bind(this);
    this.text = this.text.bind(this);
  }
  /** @type {ArrayBuffer | undefined} */
  #buffer;
  async arrayBuffer() {
    this.#buffer ??= await new Response(this.stream()).arrayBuffer();
    return this.#buffer;
  }
  async bytes() {
    return new Uint8Array(await this.arrayBuffer());
  }
  /**
  * @param {number=} start
  * @param {number=} end
  * @param {string=} contentType
  */
  slice(start = 0, end = this.size, contentType = this.type) {
    if (start < 0) start = Math.max(this.size + start, 0);
    else start = Math.min(start, this.size);
    if (end < 0) end = Math.max(this.size + end, 0);
    else end = Math.min(end, this.size);
    const size = Math.max(end - start, 0);
    return new LazyFile2(this.name, contentType, size, this.lastModified, this.#get_chunk, this.#offset + start);
  }
  stream() {
    let cursor = 0;
    let chunk_index = 0;
    return new ReadableStream({
      start: async (controller2) => {
        let chunk_start = 0;
        let start_chunk;
        for (chunk_index = 0; ; chunk_index++) {
          const chunk = await this.#get_chunk(chunk_index);
          if (!chunk) return null;
          const chunk_end = chunk_start + chunk.byteLength;
          if (this.#offset >= chunk_start && this.#offset < chunk_end) {
            start_chunk = chunk;
            break;
          }
          chunk_start = chunk_end;
        }
        if (this.#offset + this.size <= chunk_start + start_chunk.byteLength) {
          controller2.enqueue(start_chunk.subarray(this.#offset - chunk_start, this.#offset + this.size - chunk_start));
          controller2.close();
        } else {
          controller2.enqueue(start_chunk.subarray(this.#offset - chunk_start));
          cursor = start_chunk.byteLength - this.#offset + chunk_start;
        }
      },
      pull: async (controller2) => {
        chunk_index++;
        let chunk = await this.#get_chunk(chunk_index);
        if (!chunk) {
          controller2.error("incomplete file data");
          controller2.close();
          return;
        }
        if (chunk.byteLength > this.size - cursor) chunk = chunk.subarray(0, this.size - cursor);
        controller2.enqueue(chunk);
        cursor += chunk.byteLength;
        if (cursor >= this.size) controller2.close();
      }
    });
  }
  async text() {
    return decoder.decode(await this.arrayBuffer());
  }
};
var path_regex = /^[a-zA-Z_$]\w*(\.[a-zA-Z_$]\w*|\[\d+\])*$/;
function split_path(path) {
  if (!path_regex.test(path)) throw new Error(`Invalid path ${path}`);
  return path.split(/\.|\[|\]/).filter(Boolean);
}
function check_prototype_pollution(key2) {
  if (key2 === "__proto__" || key2 === "constructor" || key2 === "prototype") throw new Error(`Invalid key "${key2}"`);
}
function deep_set(object, keys, value2) {
  let current3 = object;
  for (let i = 0; i < keys.length - 1; i += 1) {
    const key2 = keys[i];
    check_prototype_pollution(key2);
    const is_array2 = /^\d+$/.test(keys[i + 1]);
    const inner = Object.hasOwn(current3, key2) ? current3[key2] : void 0;
    const exists = inner != null;
    if (exists && is_array2 !== Array.isArray(inner)) throw new Error(`Invalid array key ${keys[i + 1]}`);
    if (!exists) {
      if (value2 === DELETE_KEY) return;
      current3[key2] = is_array2 ? [] : {};
    }
    current3 = current3[key2];
  }
  const final_key = keys[keys.length - 1];
  check_prototype_pollution(final_key);
  if (value2 === DELETE_KEY) delete current3[final_key];
  else current3[final_key] = value2;
}
function negotiate(accept, types) {
  const parts = [];
  accept.split(",").forEach((str2, i) => {
    const match = /^[ \t]*([^/ \t]+)\/([^; \t]+)[ \t]*(?:;[ \t]*q=([0-9.]+))?/.exec(str2);
    if (match) {
      const [, type, subtype, q2 = "1"] = match;
      parts.push({
        type,
        subtype,
        q: +q2,
        i
      });
    }
  });
  parts.sort((a2, b3) => {
    if (a2.q !== b3.q) return b3.q - a2.q;
    if (a2.subtype === "*" !== (b3.subtype === "*")) return a2.subtype === "*" ? 1 : -1;
    if (a2.type === "*" !== (b3.type === "*")) return a2.type === "*" ? 1 : -1;
    return a2.i - b3.i;
  });
  let accepted;
  let min_priority = Infinity;
  for (const mimetype of types) {
    const [type, subtype] = mimetype.split("/");
    const priority = parts.findIndex((part) => (part.type === type || part.type === "*") && (part.subtype === subtype || part.subtype === "*"));
    if (priority !== -1 && priority < min_priority) {
      accepted = mimetype;
      min_priority = priority;
    }
  }
  return accepted;
}
function get_set_cookies(headers2) {
  if (typeof headers2.getSetCookie === "function") return headers2.getSetCookie();
  const set_cookie = headers2.get("set-cookie");
  return set_cookie ? splitCookiesString(set_cookie) : [];
}
function is_content_type(request, ...types) {
  const type = request.headers.get("content-type")?.split(";", 1)[0].trim() ?? "";
  return types.includes(type.toLowerCase());
}
function is_form_content_type(request) {
  return is_content_type(request, "application/x-www-form-urlencoded", "multipart/form-data", "text/plain", BINARY_FORM_CONTENT_TYPE);
}
var escape_html_attr_dict = {
  "&": "&amp;",
  '"': "&quot;"
};
var escape_html_dict = {
  "&": "&amp;",
  "<": "&lt;"
};
var escape_html_attr_regex = new RegExp(`[${Object.keys(escape_html_attr_dict).join("")}]|[\\ud800-\\udbff](?![\\udc00-\\udfff])|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\udc00-\\udfff]`, "g");
var escape_html_regex = new RegExp(`[${Object.keys(escape_html_dict).join("")}]|[\\ud800-\\udbff](?![\\udc00-\\udfff])|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\udc00-\\udfff]`, "g");
function escape_html2(str2, is_attr) {
  const dict = is_attr ? escape_html_attr_dict : escape_html_dict;
  return str2.replace(is_attr ? escape_html_attr_regex : escape_html_regex, (match) => {
    if (match.length === 2) return match;
    return dict[match] ?? `&#${match.charCodeAt(0)};`;
  });
}
function method_not_allowed(mod, method) {
  return text(`${method} method not allowed`, {
    status: 405,
    headers: { allow: allowed_methods(mod).join(", ") }
  });
}
function allowed_methods(mod) {
  const allowed = ENDPOINT_METHODS.filter((method) => method in mod);
  if ("GET" in mod && !("HEAD" in mod)) allowed.push("HEAD");
  return allowed;
}
function get_global_name(options2) {
  return `__sveltekit_${options2.version_hash}`;
}
function static_error_page(options2, status, message2) {
  let page2 = options2.templates.error({
    status,
    message: escape_html2(message2)
  });
  return text(page2, {
    headers: { "content-type": "text/html; charset=utf-8" },
    status
  });
}
async function handle_fatal_error(event, state2, options2, error2) {
  error2 = error2 instanceof HttpError ? error2 : coalesce_to_error(error2);
  const status = get_status(error2);
  const body = await handle_error_and_jsonify(event, state2, options2, error2);
  const type = negotiate(event.request.headers.get("accept") || "text/html", ["application/json", "text/html"]);
  if (event.isDataRequest || type === "application/json") return json(body, { status });
  return static_error_page(options2, status, body.message);
}
async function handle_error_and_jsonify(event, state2, options2, error2) {
  if (error2 instanceof HttpError) return {
    message: "Unknown Error",
    ...error2.body
  };
  const status = get_status(error2);
  const message2 = get_message(error2);
  return await with_request_store({
    event,
    state: state2
  }, () => options2.hooks.handleError({
    error: error2,
    event,
    status,
    message: message2
  })) ?? { message: message2 };
}
function redirect_response(status, location) {
  return new Response(void 0, {
    status,
    headers: { location }
  });
}
function clarify_devalue_error(event, error2) {
  if (error2.path) return `Data returned from \`load\` while rendering ${event.route.id} is not serializable: ${error2.message} (${error2.path}). If you need to serialize/deserialize custom types, use transport hooks: https://svelte.dev/docs/kit/hooks#transport.`;
  if (error2.path === "") return `Data returned from \`load\` while rendering ${event.route.id} is not a plain object`;
  return error2.message;
}
function serialize_uses(node) {
  const uses = {};
  if (node.uses && node.uses.dependencies.size > 0) uses.dependencies = Array.from(node.uses.dependencies);
  if (node.uses && node.uses.search_params.size > 0) uses.search_params = Array.from(node.uses.search_params);
  if (node.uses && node.uses.params.size > 0) uses.params = Array.from(node.uses.params);
  if (node.uses?.parent) uses.parent = 1;
  if (node.uses?.route) uses.route = 1;
  if (node.uses?.url) uses.url = 1;
  return uses;
}
function has_prerendered_path(manifest2, pathname) {
  return manifest2._.prerendered_routes.has(pathname) || pathname.at(-1) === "/" && manifest2._.prerendered_routes.has(pathname.slice(0, -1));
}
function format_server_error(status, error2, event) {
  const formatted_text = `
\x1B[1;31m[${status}] ${event.request.method} ${event.url.pathname}\x1B[0m`;
  if (status === 404) return formatted_text;
  return `${formatted_text}
${error2.stack}`;
}
function get_node_type(node_id) {
  const filename = node_id?.split("/")?.at(-1);
  if (!filename) return "unknown";
  return filename.split(".").slice(0, -1).join(".");
}
function create_replacer(transport) {
  const replacer = (thing) => {
    for (const key2 in transport) {
      const encoded = transport[key2].encode(thing);
      if (encoded) return `app.decode('${key2}', ${uneval(encoded, replacer)})`;
    }
  };
  return replacer;
}

// dist/build/server/index.js
init_uneval();
init_internal22();
init_exports2();
init_server();
init_index_server2();
init_exports();
init_internal();
init_server2();
function with_resolvers() {
  let resolve6;
  let reject;
  return {
    promise: new Promise((res, rej) => {
      resolve6 = res;
      reject = rej;
    }),
    resolve: resolve6,
    reject
  };
}
var NULL_BODY_STATUS = [
  101,
  103,
  204,
  205,
  304
];
var IN_WEBCONTAINER2 = !!globalThis.process?.versions?.webcontainer;
var s2 = JSON.stringify;
async function render_endpoint(event, event_state, mod, state2) {
  const method = event.request.method;
  let handler = mod[method] || mod.fallback;
  if (method === "HEAD" && !mod.HEAD && mod.GET) handler = mod.GET;
  if (!handler) return method_not_allowed(mod, method);
  const prerender = mod.prerender ?? state2.prerender_default;
  if (prerender && (mod.POST || mod.PATCH || mod.PUT || mod.DELETE)) throw new Error("Cannot prerender endpoints that have mutative methods");
  if (state2.prerendering && !state2.prerendering.inside_reroute && !prerender) if (state2.depth > 0) throw new Error(`${event.route.id} is not prerenderable`);
  else return new Response(void 0, { status: 204 });
  try {
    const response = await with_request_store({
      event,
      state: event_state
    }, () => handler(event));
    if (!(response instanceof Response)) throw new Error(`Invalid response from route ${event.url.pathname}: handler should return a Response object`);
    if (state2.prerendering && (!state2.prerendering.inside_reroute || prerender)) {
      const cloned = new Response(response.clone().body, {
        status: response.status,
        statusText: response.statusText,
        headers: new Headers(response.headers)
      });
      cloned.headers.set("x-sveltekit-prerender", String(prerender));
      if (state2.prerendering.inside_reroute && prerender) {
        cloned.headers.set("x-sveltekit-routeid", encodeURI(event.route.id));
        state2.prerendering.dependencies.set(event.url.pathname, {
          response: cloned,
          body: null
        });
      } else return cloned;
    }
    return response;
  } catch (e) {
    if (e instanceof Redirect) return new Response(void 0, {
      status: e.status,
      headers: { location: e.location }
    });
    throw e;
  }
}
function is_endpoint_request(event) {
  const { method, headers: headers2 } = event.request;
  if (ENDPOINT_METHODS.includes(method) && !PAGE_METHODS.includes(method)) return true;
  if (method === "POST" && headers2.get("x-sveltekit-action") === "true") return false;
  const accept = event.request.headers.get("accept") ?? "*/*";
  return negotiate(accept, ["*", "text/html"]) !== "text/html";
}
async function record_span({ name, attributes: attributes2, fn }) {
  return fn(noop_span);
}
function is_action_json_request(event) {
  return negotiate(event.request.headers.get("accept") ?? "*/*", ["application/json", "text/html"]) === "application/json" && event.request.method === "POST";
}
async function handle_action_json_request(event, event_state, options2, server2) {
  const actions52 = server2?.actions;
  if (!actions52) {
    const no_actions_error = new SvelteKitError(405, "Method Not Allowed", `POST method not allowed. No form actions exist for this page`);
    return action_json({
      type: "error",
      error: await handle_error_and_jsonify(event, event_state, options2, no_actions_error)
    }, {
      status: no_actions_error.status,
      headers: { allow: "GET" }
    });
  }
  check_named_default_separate(actions52);
  try {
    const data = await call_action(event, event_state, actions52);
    if (data instanceof ActionFailure) return action_json({
      type: "failure",
      status: data.status,
      data: stringify_action_response(data.data, event.route.id, options2.hooks.transport)
    });
    else return action_json({
      type: "success",
      status: data ? 200 : 204,
      data: stringify_action_response(data, event.route.id, options2.hooks.transport)
    });
  } catch (e) {
    const err = normalize_error(e);
    if (err instanceof Redirect) return action_json_redirect(err);
    return action_json({
      type: "error",
      error: await handle_error_and_jsonify(event, event_state, options2, check_incorrect_fail_use(err))
    }, { status: get_status(err) });
  }
}
function check_incorrect_fail_use(error2) {
  return error2 instanceof ActionFailure ? /* @__PURE__ */ new Error('Cannot "throw fail()". Use "return fail()"') : error2;
}
function action_json_redirect(redirect2) {
  return action_json({
    type: "redirect",
    status: redirect2.status,
    location: redirect2.location
  });
}
function action_json(data, init3) {
  return json(data, init3);
}
function is_action_request(event) {
  return event.request.method === "POST";
}
async function handle_action_request(event, event_state, server2) {
  const actions52 = server2?.actions;
  if (!actions52) {
    event.setHeaders({ allow: "GET" });
    return {
      type: "error",
      error: new SvelteKitError(405, "Method Not Allowed", `POST method not allowed. No form actions exist for this page`)
    };
  }
  check_named_default_separate(actions52);
  try {
    const data = await call_action(event, event_state, actions52);
    if (data instanceof ActionFailure) return {
      type: "failure",
      status: data.status,
      data: data.data
    };
    else return {
      type: "success",
      status: 200,
      data
    };
  } catch (e) {
    const err = normalize_error(e);
    if (err instanceof Redirect) return {
      type: "redirect",
      status: err.status,
      location: err.location
    };
    return {
      type: "error",
      error: check_incorrect_fail_use(err)
    };
  }
}
function check_named_default_separate(actions52) {
  if (actions52.default && Object.keys(actions52).length > 1) throw new Error("When using named actions, the default action cannot be used. See the docs for more info: https://svelte.dev/docs/kit/form-actions#named-actions");
}
async function call_action(event, event_state, actions52) {
  const url = new URL(event.request.url);
  let name = "default";
  for (const param of url.searchParams) if (param[0].startsWith("/")) {
    name = param[0].slice(1);
    if (name === "default") throw new Error('Cannot use reserved action name "default"');
    break;
  }
  const action = actions52[name];
  if (!action) throw new SvelteKitError(404, "Not Found", `No action with name '${name}' found`);
  if (!is_form_content_type(event.request)) throw new SvelteKitError(415, "Unsupported Media Type", `Form actions expect form-encoded data \u2014 received ${event.request.headers.get("content-type")}`);
  return record_span({
    name: "sveltekit.form_action",
    attributes: {
      "sveltekit.form_action.name": name,
      "http.route": event.route.id || "unknown"
    },
    fn: async (current3) => {
      const traced_event = merge_tracing(event, current3);
      const result = await with_request_store({
        event: traced_event,
        state: event_state
      }, () => action(traced_event));
      if (result instanceof ActionFailure) current3.setAttributes({
        "sveltekit.form_action.result.type": "failure",
        "sveltekit.form_action.result.status": result.status
      });
      return result;
    }
  });
}
function uneval_action_response(data, route_id, transport) {
  const replacer = create_replacer(transport);
  return try_serialize(data, (value2) => uneval(value2, replacer), route_id);
}
function stringify_action_response(data, route_id, transport) {
  const encoders = Object.fromEntries(Object.entries(transport).map(([key2, value2]) => [key2, value2.encode]));
  return try_serialize(data, (value2) => stringify$1(value2, encoders), route_id);
}
function try_serialize(data, fn, route_id) {
  try {
    return fn(data);
  } catch (e) {
    const error2 = e;
    if (data instanceof Response) throw new Error(`Data returned from action inside ${route_id} is not serializable. Form actions need to return plain objects or fail(). E.g. return { success: true } or return fail(400, { message: "invalid" });`, { cause: e });
    if ("path" in error2) {
      let message2 = `Data returned from action inside ${route_id} is not serializable: ${error2.message}`;
      if (error2.path !== "") message2 += ` (data.${error2.path})`;
      throw new Error(message2, { cause: e });
    }
    throw error2;
  }
}
function create_async_iterator() {
  let resolved = -1;
  let returned = -1;
  const deferred2 = [];
  return {
    iterate: (transform = (x3) => x3) => {
      return { [Symbol.asyncIterator]() {
        return { next: async () => {
          const next2 = deferred2[++returned];
          if (!next2) return {
            value: null,
            done: true
          };
          return {
            value: transform(await next2.promise),
            done: false
          };
        } };
      } };
    },
    add: (promise) => {
      const next2 = with_resolvers();
      next2.promise.catch(noop2);
      deferred2.push(next2);
      promise.then((value2) => {
        deferred2[++resolved].resolve(value2);
      }, (error2) => {
        deferred2[++resolved].reject(error2);
      });
    }
  };
}
function server_data_serializer(event, event_state, options2) {
  let promise_id = 1;
  let max_nodes = -1;
  const iterator = create_async_iterator();
  const global = get_global_name(options2);
  function get_replacer(index88) {
    return function replacer(thing) {
      if (typeof thing?.then === "function") {
        const id = promise_id++;
        const promise = thing.then(
          /** @param {any} data */
          (data) => ({ data })
        ).catch(
          /** @param {any} error */
          async (error2) => ({ error: await handle_error_and_jsonify(event, event_state, options2, error2) })
        ).then(
          /**
          * @param {{data: any; error: any}} result
          */
          async ({ data, error: error2 }) => {
            let str2;
            try {
              str2 = uneval(error2 ? [, error2] : [data], replacer);
            } catch {
              error2 = await handle_error_and_jsonify(event, event_state, options2, /* @__PURE__ */ new Error(`Failed to serialize promise while rendering ${event.route.id}`));
              str2 = uneval([, error2], replacer);
            }
            return {
              index: index88,
              str: `${global}.resolve(${id}, ${str2.includes("app.decode") ? `(app) => ${str2}` : `() => ${str2}`})`
            };
          }
        );
        iterator.add(promise);
        return `${global}.defer(${id})`;
      } else for (const key2 in options2.hooks.transport) {
        const encoded = options2.hooks.transport[key2].encode(thing);
        if (encoded) return `app.decode('${key2}', ${uneval(encoded, replacer)})`;
      }
    };
  }
  const strings = [];
  return {
    set_max_nodes(i) {
      max_nodes = i;
    },
    add_node(i, node) {
      try {
        if (!node) {
          strings[i] = "null";
          return;
        }
        const payload2 = {
          type: "data",
          data: node.data,
          uses: serialize_uses(node)
        };
        if (node.slash) payload2.slash = node.slash;
        strings[i] = uneval(payload2, get_replacer(i));
      } catch (e) {
        e.path = e.path.slice(1);
        throw new Error(clarify_devalue_error(event, e), { cause: e });
      }
    },
    get_data(csp) {
      const open = `<script${csp.script_needs_nonce ? ` nonce="${csp.nonce}"` : ""}>`;
      const close = `</script>
`;
      return {
        data: `[${compact(max_nodes > -1 ? strings.slice(0, max_nodes) : strings).join(",")}]`,
        chunks: promise_id > 1 ? iterator.iterate(({ index: index88, str: str2 }) => {
          if (max_nodes > -1 && index88 >= max_nodes) return "";
          return open + str2 + close;
        }) : null
      };
    }
  };
}
function server_data_serializer_json(event, event_state, options2) {
  let promise_id = 1;
  const iterator = create_async_iterator();
  const reducers = {
    ...Object.fromEntries(Object.entries(options2.hooks.transport).map(([key2, value2]) => [key2, value2.encode])),
    /** @param {any} thing */
    Promise: (thing) => {
      if (typeof thing?.then !== "function") return;
      const id = promise_id++;
      let key2 = "data";
      const promise = thing.catch(
        /** @param {any} e */
        async (e) => {
          key2 = "error";
          return handle_error_and_jsonify(event, event_state, options2, e);
        }
      ).then(
        /** @param {any} value */
        async (value2) => {
          let str2;
          try {
            str2 = stringify$1(value2, reducers);
          } catch {
            const error2 = await handle_error_and_jsonify(event, event_state, options2, /* @__PURE__ */ new Error(`Failed to serialize promise while rendering ${event.route.id}`));
            key2 = "error";
            str2 = stringify$1(error2, reducers);
          }
          return `{"type":"chunk","id":${id},"${key2}":${str2}}
`;
        }
      );
      iterator.add(promise);
      return id;
    }
  };
  const strings = [];
  return {
    add_node(i, node) {
      try {
        if (!node) {
          strings[i] = "null";
          return;
        }
        if (node.type === "error" || node.type === "skip") {
          strings[i] = JSON.stringify(node);
          return;
        }
        strings[i] = `{"type":"data","data":${stringify$1(node.data, reducers)},"uses":${JSON.stringify(serialize_uses(node))}${node.slash ? `,"slash":${JSON.stringify(node.slash)}` : ""}}`;
      } catch (e) {
        e.path = "data" + e.path;
        throw new Error(clarify_devalue_error(event, e), { cause: e });
      }
    },
    get_data() {
      return {
        data: `{"type":"data","nodes":[${strings.join(",")}]}
`,
        chunks: promise_id > 1 ? iterator.iterate() : null
      };
    }
  };
}
async function load_server_data({ event, event_state, state: state2, node, parent }) {
  if (!node?.server) return null;
  let is_tracking = true;
  const uses = {
    dependencies: /* @__PURE__ */ new Set(),
    params: /* @__PURE__ */ new Set(),
    parent: false,
    route: false,
    url: false,
    search_params: /* @__PURE__ */ new Set()
  };
  const load80 = node.server.load;
  const slash = node.server.trailingSlash;
  if (!load80) return {
    type: "data",
    data: null,
    uses,
    slash
  };
  const url = make_trackable(event.url, () => {
    if (is_tracking) uses.url = true;
  }, (param) => {
    if (is_tracking) uses.search_params.add(param);
  });
  if (state2.prerendering) disable_search(url);
  return {
    type: "data",
    data: await record_span({
      name: "sveltekit.load",
      attributes: {
        "sveltekit.load.node_id": node.server_id || "unknown",
        "sveltekit.load.node_type": get_node_type(node.server_id),
        "sveltekit.load.environment": "server",
        "http.route": event.route.id || "unknown"
      },
      fn: async (current3) => {
        const traced_event = merge_tracing(event, current3);
        return await with_request_store({
          event: traced_event,
          state: event_state
        }, () => load80.call(null, {
          ...traced_event,
          fetch: (info, init3) => {
            new URL(info instanceof Request ? info.url : info, event.url);
            return event.fetch(info, init3);
          },
          /** @param {string[]} deps */
          depends: (...deps) => {
            for (const dep of deps) {
              const { href } = new URL(dep, event.url);
              uses.dependencies.add(href);
            }
          },
          params: new Proxy(event.params, { get: (target, key2) => {
            if (is_tracking) uses.params.add(key2);
            return target[key2];
          } }),
          parent: async () => {
            if (is_tracking) uses.parent = true;
            return parent();
          },
          route: new Proxy(event.route, { get: (target, key2) => {
            if (is_tracking) uses.route = true;
            return target[key2];
          } }),
          url,
          untrack(fn) {
            is_tracking = false;
            try {
              return fn();
            } finally {
              is_tracking = true;
            }
          }
        }));
      }
    }) ?? null,
    uses,
    slash
  };
}
async function load_data({ event, event_state, fetched, node, parent, server_data_promise, state: state2, resolve_opts, csr }) {
  const server_data_node = await server_data_promise;
  const load80 = node?.universal?.load;
  if (!load80) return server_data_node?.data ?? null;
  return await record_span({
    name: "sveltekit.load",
    attributes: {
      "sveltekit.load.node_id": node.universal_id || "unknown",
      "sveltekit.load.node_type": get_node_type(node.universal_id),
      "sveltekit.load.environment": "server",
      "http.route": event.route.id || "unknown"
    },
    fn: async (current3) => {
      const traced_event = merge_tracing(event, current3);
      const child_state = {
        ...event_state,
        is_in_universal_load: true
      };
      return await with_request_store({
        event: traced_event,
        state: child_state
      }, () => load80.call(null, {
        url: event.url,
        params: event.params,
        data: server_data_node?.data ?? null,
        route: event.route,
        fetch: create_universal_fetch(event, state2, fetched, csr, resolve_opts),
        setHeaders: event.setHeaders,
        depends: noop2,
        parent,
        untrack: (fn) => fn(),
        tracing: traced_event.tracing
      }));
    }
  }) ?? null;
}
function create_universal_fetch(event, state2, fetched, csr, resolve_opts) {
  const universal_fetch = async (input, init3) => {
    const cloned_body = input instanceof Request && input.body ? input.clone().body : null;
    const cloned_headers = input instanceof Request && [...input.headers].length ? new Headers(input.headers) : init3?.headers;
    let response = await event.fetch(input, init3);
    const url = new URL(input instanceof Request ? input.url : input, event.url);
    const same_origin = url.origin === event.url.origin;
    let dependency;
    if (same_origin) {
      if (state2.prerendering) {
        dependency = {
          response,
          body: null
        };
        state2.prerendering.dependencies.set(url.pathname, dependency);
      }
    } else if (url.protocol === "https:" || url.protocol === "http:") if ((input instanceof Request ? input.mode : init3?.mode ?? "cors") === "no-cors") response = new Response("", {
      status: response.status,
      statusText: response.statusText,
      headers: response.headers
    });
    else {
      const acao = response.headers.get("access-control-allow-origin");
      if (!acao || acao !== event.url.origin && acao !== "*") throw new Error(`CORS error: ${acao ? "Incorrect" : "No"} 'Access-Control-Allow-Origin' header is present on the requested resource`);
    }
    let teed_body;
    const proxy2 = new Proxy(response, { get(response2, key2, receiver) {
      async function push_fetched(body, is_b64) {
        const status_number = Number(response2.status);
        if (isNaN(status_number)) throw new Error(`response.status is not a number. value: "${response2.status}" type: ${typeof response2.status}`);
        fetched.push({
          url: same_origin ? url.href.slice(event.url.origin.length) : url.href,
          method: event.request.method,
          request_body: input instanceof Request && cloned_body ? await stream_to_string(cloned_body) : init3?.body,
          request_headers: cloned_headers,
          response_body: body,
          response: response2,
          is_b64
        });
      }
      if (key2 === "body") {
        if (response2.body === null) return null;
        if (teed_body) return teed_body;
        const [a2, b3] = response2.body.tee();
        (async () => {
          let result = /* @__PURE__ */ new Uint8Array();
          for await (const chunk of a2) {
            const combined = new Uint8Array(result.length + chunk.length);
            combined.set(result, 0);
            combined.set(chunk, result.length);
            result = combined;
          }
          if (dependency) dependency.body = new Uint8Array(result);
          push_fetched(base64_encode2(result), true);
        })().catch(noop2);
        return teed_body = b3;
      }
      if (key2 === "arrayBuffer") return async () => {
        const buffer2 = await response2.arrayBuffer();
        const bytes = new Uint8Array(buffer2);
        if (dependency) dependency.body = bytes;
        if (buffer2 instanceof ArrayBuffer) await push_fetched(base64_encode2(bytes), true);
        return buffer2;
      };
      async function text2() {
        const body = await response2.text();
        if (body === "" && NULL_BODY_STATUS.includes(response2.status)) {
          await push_fetched(void 0, false);
          return;
        }
        if (!body || typeof body === "string") await push_fetched(body, false);
        if (dependency) dependency.body = body;
        return body;
      }
      if (key2 === "text") return text2;
      if (key2 === "json") return async () => {
        const body = await text2();
        return body ? JSON.parse(body) : void 0;
      };
      const value2 = Reflect.get(response2, key2, response2);
      if (value2 instanceof Function) return Object.defineProperties(
        /**
        * @this {any}
        */
        function() {
          return Reflect.apply(value2, this === receiver ? response2 : this, arguments);
        },
        {
          name: { value: value2.name },
          length: { value: value2.length }
        }
      );
      return value2;
    } });
    if (csr) {
      const get4 = response.headers.get;
      response.headers.get = (key2) => {
        const lower = key2.toLowerCase();
        const value2 = get4.call(response.headers, lower);
        if (value2 && !lower.startsWith("x-sveltekit-")) {
          if (!resolve_opts.filterSerializedResponseHeaders(lower, value2)) throw new Error(`Failed to get response header "${lower}" \u2014 it must be included by the \`filterSerializedResponseHeaders\` option: https://svelte.dev/docs/kit/hooks#handle (at ${event.route.id})`);
        }
        return value2;
      };
    }
    return proxy2;
  };
  return (input, init3) => {
    const response = universal_fetch(input, init3);
    response.catch(noop2);
    return response;
  };
}
async function stream_to_string(stream) {
  let result = "";
  const reader = stream.getReader();
  const decoder4 = new TextDecoder();
  while (true) {
    const { done, value: value2 } = await reader.read();
    if (done) {
      result += decoder4.decode();
      break;
    }
    result += decoder4.decode(value2, { stream: true });
  }
  return result;
}
var replacements2 = {
  "<": "\\u003C",
  "\u2028": "\\u2028",
  "\u2029": "\\u2029"
};
var pattern = new RegExp(`[${Object.keys(replacements2).join("")}]`, "g");
function serialize_data(fetched, filter, prerendering = false) {
  const headers2 = {};
  let cache_control = null;
  let age = null;
  let varyAny = false;
  for (const [key2, value2] of fetched.response.headers) {
    if (filter(key2, value2)) headers2[key2] = value2;
    if (key2 === "cache-control") cache_control = value2;
    else if (key2 === "age") age = value2;
    else if (key2 === "vary" && value2.trim() === "*") varyAny = true;
  }
  const payload2 = {
    status: fetched.response.status,
    statusText: fetched.response.statusText,
    headers: headers2,
    body: fetched.response_body
  };
  const safe_payload = JSON.stringify(payload2).replace(pattern, (match) => replacements2[match]);
  const attrs = [
    'type="application/json"',
    "data-sveltekit-fetched",
    `data-url="${escape_html2(fetched.url, true)}"`
  ];
  if (fetched.is_b64) attrs.push("data-b64");
  if (fetched.request_headers || fetched.request_body) {
    const values = [];
    if (fetched.request_headers) values.push([...new Headers(fetched.request_headers)].join(","));
    if (fetched.request_body) values.push(fetched.request_body);
    attrs.push(`data-hash="${hash3(...values)}"`);
  }
  if (!prerendering && fetched.method === "GET" && cache_control && !varyAny) {
    const match = /s-maxage=(\d+)/g.exec(cache_control) ?? /max-age=(\d+)/g.exec(cache_control);
    if (match) {
      const ttl = +match[1] - +(age ?? "0");
      attrs.push(`data-ttl="${ttl}"`);
    }
  }
  return `<script ${attrs.join(" ")}>${safe_payload}</script>`;
}
function sha2562(data) {
  if (!key[0]) precompute();
  const out = init2.slice(0);
  const array2 = encode4(data);
  for (let i = 0; i < array2.length; i += 16) {
    const w3 = array2.subarray(i, i + 16);
    let tmp;
    let a2;
    let b3;
    let out0 = out[0];
    let out1 = out[1];
    let out2 = out[2];
    let out3 = out[3];
    let out4 = out[4];
    let out5 = out[5];
    let out6 = out[6];
    let out7 = out[7];
    for (let i2 = 0; i2 < 64; i2++) {
      if (i2 < 16) tmp = w3[i2];
      else {
        a2 = w3[i2 + 1 & 15];
        b3 = w3[i2 + 14 & 15];
        tmp = w3[i2 & 15] = (a2 >>> 7 ^ a2 >>> 18 ^ a2 >>> 3 ^ a2 << 25 ^ a2 << 14) + (b3 >>> 17 ^ b3 >>> 19 ^ b3 >>> 10 ^ b3 << 15 ^ b3 << 13) + w3[i2 & 15] + w3[i2 + 9 & 15] | 0;
      }
      tmp = tmp + out7 + (out4 >>> 6 ^ out4 >>> 11 ^ out4 >>> 25 ^ out4 << 26 ^ out4 << 21 ^ out4 << 7) + (out6 ^ out4 & (out5 ^ out6)) + key[i2];
      out7 = out6;
      out6 = out5;
      out5 = out4;
      out4 = out3 + tmp | 0;
      out3 = out2;
      out2 = out1;
      out1 = out0;
      out0 = tmp + (out1 & out2 ^ out3 & (out1 ^ out2)) + (out1 >>> 2 ^ out1 >>> 13 ^ out1 >>> 22 ^ out1 << 30 ^ out1 << 19 ^ out1 << 10) | 0;
    }
    out[0] = out[0] + out0 | 0;
    out[1] = out[1] + out1 | 0;
    out[2] = out[2] + out2 | 0;
    out[3] = out[3] + out3 | 0;
    out[4] = out[4] + out4 | 0;
    out[5] = out[5] + out5 | 0;
    out[6] = out[6] + out6 | 0;
    out[7] = out[7] + out7 | 0;
  }
  const bytes = new Uint8Array(out.buffer);
  reverse_endianness(bytes);
  return btoa(String.fromCharCode(...bytes));
}
var init2 = /* @__PURE__ */ new Uint32Array(8);
var key = /* @__PURE__ */ new Uint32Array(64);
function precompute() {
  function frac(x3) {
    return (x3 - Math.floor(x3)) * 4294967296;
  }
  let prime = 2;
  for (let i = 0; i < 64; prime++) {
    let is_prime = true;
    for (let factor = 2; factor * factor <= prime; factor++) if (prime % factor === 0) {
      is_prime = false;
      break;
    }
    if (is_prime) {
      if (i < 8) init2[i] = frac(prime ** (1 / 2));
      key[i] = frac(prime ** (1 / 3));
      i++;
    }
  }
}
function reverse_endianness(bytes) {
  for (let i = 0; i < bytes.length; i += 4) {
    const a2 = bytes[i + 0];
    const b3 = bytes[i + 1];
    const c2 = bytes[i + 2];
    const d2 = bytes[i + 3];
    bytes[i + 0] = d2;
    bytes[i + 1] = c2;
    bytes[i + 2] = b3;
    bytes[i + 3] = a2;
  }
}
function encode4(str2) {
  const encoded = text_encoder2.encode(str2);
  const length = encoded.length * 8;
  const size = 512 * Math.ceil((length + 65) / 512);
  const bytes = new Uint8Array(size / 8);
  bytes.set(encoded);
  bytes[encoded.length] = 128;
  reverse_endianness(bytes);
  const words = new Uint32Array(bytes.buffer);
  words[words.length - 2] = Math.floor(length / 4294967296);
  words[words.length - 1] = length;
  return words;
}
var array = /* @__PURE__ */ new Uint8Array(16);
function generate_nonce() {
  crypto.getRandomValues(array);
  return btoa(String.fromCharCode(...array));
}
var quoted = /* @__PURE__ */ new Set([
  "self",
  "unsafe-eval",
  "unsafe-hashes",
  "unsafe-inline",
  "none",
  "strict-dynamic",
  "report-sample",
  "wasm-unsafe-eval",
  "script"
]);
var crypto_pattern = /^(nonce|sha\d\d\d)-/;
var BaseProvider = class {
  /** @type {boolean} */
  #use_hashes;
  /** @type {boolean} */
  #script_needs_csp;
  /** @type {boolean} */
  #script_src_needs_csp;
  /** @type {boolean} */
  #script_src_elem_needs_csp;
  /** @type {boolean} */
  #style_needs_csp;
  /** @type {boolean} */
  #style_src_needs_csp;
  /** @type {boolean} */
  #style_src_attr_needs_csp;
  /** @type {boolean} */
  #style_src_elem_needs_csp;
  /** @type {import('types').CspDirectives} */
  #directives;
  /** @type {Set<import('types').Csp.Source>} */
  #script_src;
  /** @type {Set<import('types').Csp.Source>} */
  #script_src_elem;
  /** @type {Set<import('types').Csp.Source>} */
  #style_src;
  /** @type {Set<import('types').Csp.Source>} */
  #style_src_attr;
  /** @type {Set<import('types').Csp.Source>} */
  #style_src_elem;
  /** @type {boolean} */
  script_needs_nonce;
  /** @type {boolean} */
  style_needs_nonce;
  /** @type {boolean} */
  script_needs_hash;
  /** @type {string} */
  #nonce;
  /**
  * @param {boolean} use_hashes
  * @param {import('types').CspDirectives} directives
  * @param {string} nonce
  */
  constructor(use_hashes, directives, nonce) {
    this.#use_hashes = use_hashes;
    this.#directives = directives;
    const d2 = this.#directives;
    this.#script_src = /* @__PURE__ */ new Set();
    this.#script_src_elem = /* @__PURE__ */ new Set();
    this.#style_src = /* @__PURE__ */ new Set();
    this.#style_src_attr = /* @__PURE__ */ new Set();
    this.#style_src_elem = /* @__PURE__ */ new Set();
    const effective_script_src = d2["script-src"] || d2["default-src"];
    const script_src_elem = d2["script-src-elem"];
    const effective_style_src = d2["style-src"] || d2["default-src"];
    const style_src_attr = d2["style-src-attr"];
    const style_src_elem = d2["style-src-elem"];
    const style_needs_csp = (directive) => !!directive && !directive.some((value2) => value2 === "unsafe-inline");
    const script_needs_csp = (directive) => !!directive && (!directive.some((value2) => value2 === "unsafe-inline") || directive.some((value2) => value2 === "strict-dynamic"));
    this.#script_src_needs_csp = script_needs_csp(effective_script_src);
    this.#script_src_elem_needs_csp = script_needs_csp(script_src_elem);
    this.#style_src_needs_csp = style_needs_csp(effective_style_src);
    this.#style_src_attr_needs_csp = style_needs_csp(style_src_attr);
    this.#style_src_elem_needs_csp = style_needs_csp(style_src_elem);
    this.#script_needs_csp = this.#script_src_needs_csp || this.#script_src_elem_needs_csp;
    this.#style_needs_csp = this.#style_src_needs_csp || this.#style_src_attr_needs_csp || this.#style_src_elem_needs_csp;
    this.script_needs_nonce = this.#script_needs_csp && !this.#use_hashes;
    this.style_needs_nonce = this.#style_needs_csp && !this.#use_hashes;
    this.script_needs_hash = this.#script_needs_csp && this.#use_hashes;
    this.#nonce = nonce;
  }
  /** @param {string} content */
  add_script(content) {
    if (!this.#script_needs_csp) return;
    const source2 = this.#use_hashes ? `sha256-${sha2562(content)}` : `nonce-${this.#nonce}`;
    if (this.#script_src_needs_csp) this.#script_src.add(source2);
    if (this.#script_src_elem_needs_csp) this.#script_src_elem.add(source2);
  }
  /** @param {`sha256-${string}`[]} hashes */
  add_script_hashes(hashes) {
    for (const hash4 of hashes) {
      if (this.#script_src_needs_csp) this.#script_src.add(hash4);
      if (this.#script_src_elem_needs_csp) this.#script_src_elem.add(hash4);
    }
  }
  /** @param {string} content */
  add_style(content) {
    if (!this.#style_needs_csp) return;
    const source2 = this.#use_hashes ? `sha256-${sha2562(content)}` : `nonce-${this.#nonce}`;
    if (this.#style_src_needs_csp) this.#style_src.add(source2);
    if (this.#style_src_attr_needs_csp) this.#style_src_attr.add(source2);
    if (this.#style_src_elem_needs_csp) {
      const sha256_empty_comment_hash = "sha256-9OlNO0DNEeaVzHL4RZwCLsBHA8WBQ8toBp/4F5XV2nc=";
      const d2 = this.#directives;
      if (d2["style-src-elem"] && !d2["style-src-elem"].includes(sha256_empty_comment_hash) && !this.#style_src_elem.has(sha256_empty_comment_hash)) this.#style_src_elem.add(sha256_empty_comment_hash);
      if (source2 !== sha256_empty_comment_hash) this.#style_src_elem.add(source2);
    }
  }
  /**
  * @param {boolean} [is_meta]
  */
  get_header(is_meta = false) {
    const header = [];
    const directives = { ...this.#directives };
    if (this.#style_src.size > 0) directives["style-src"] = [...directives["style-src"] || directives["default-src"] || [], ...this.#style_src];
    if (this.#style_src_attr.size > 0) directives["style-src-attr"] = [...directives["style-src-attr"] || [], ...this.#style_src_attr];
    if (this.#style_src_elem.size > 0) directives["style-src-elem"] = [...directives["style-src-elem"] || [], ...this.#style_src_elem];
    if (this.#script_src.size > 0) directives["script-src"] = [...directives["script-src"] || directives["default-src"] || [], ...this.#script_src];
    if (this.#script_src_elem.size > 0) directives["script-src-elem"] = [...directives["script-src-elem"] || [], ...this.#script_src_elem];
    for (const key2 in directives) {
      if (is_meta && (key2 === "frame-ancestors" || key2 === "report-uri" || key2 === "sandbox")) continue;
      const value2 = directives[key2];
      if (!value2) continue;
      const directive = [key2];
      if (Array.isArray(value2)) value2.forEach((value3) => {
        if (quoted.has(value3) || crypto_pattern.test(value3)) directive.push(`'${value3}'`);
        else directive.push(value3);
      });
      header.push(directive.join(" "));
    }
    return header.join("; ");
  }
};
var CspProvider = class extends BaseProvider {
  get_meta() {
    const content = this.get_header(true);
    if (!content) return;
    return `<meta http-equiv="content-security-policy" content="${escape_html2(content, true)}">`;
  }
};
var CspReportOnlyProvider = class extends BaseProvider {
  /**
  * @param {boolean} use_hashes
  * @param {import('types').CspDirectives} directives
  * @param {string} nonce
  */
  constructor(use_hashes, directives, nonce) {
    super(use_hashes, directives, nonce);
    if (Object.values(directives).filter((v3) => !!v3).length > 0) {
      const has_report_to = directives["report-to"]?.length ?? false;
      const has_report_uri = directives["report-uri"]?.length ?? false;
      if (!has_report_to && !has_report_uri) throw Error("`content-security-policy-report-only` must be specified with either the `report-to` or `report-uri` directives, or both");
    }
  }
};
var Csp = class {
  /** @readonly */
  nonce = generate_nonce();
  /** @type {CspProvider} */
  csp_provider;
  /** @type {CspReportOnlyProvider} */
  report_only_provider;
  /**
  * @param {import('./types.js').CspConfig} config
  * @param {import('./types.js').CspOpts} opts
  */
  constructor({ mode, directives, reportOnly }, { prerender }) {
    const use_hashes = mode === "hash" || mode === "auto" && prerender;
    this.csp_provider = new CspProvider(use_hashes, directives, this.nonce);
    this.report_only_provider = new CspReportOnlyProvider(use_hashes, reportOnly, this.nonce);
  }
  get script_needs_hash() {
    return this.csp_provider.script_needs_hash || this.report_only_provider.script_needs_hash;
  }
  get script_needs_nonce() {
    return this.csp_provider.script_needs_nonce || this.report_only_provider.script_needs_nonce;
  }
  get style_needs_nonce() {
    return this.csp_provider.style_needs_nonce || this.report_only_provider.style_needs_nonce;
  }
  /** @param {string} content */
  add_script(content) {
    this.csp_provider.add_script(content);
    this.report_only_provider.add_script(content);
  }
  /** @param {`sha256-${string}`[]} hashes */
  add_script_hashes(hashes) {
    this.csp_provider.add_script_hashes(hashes);
    this.report_only_provider.add_script_hashes(hashes);
  }
  /** @param {string} content */
  add_style(content) {
    this.csp_provider.add_style(content);
    this.report_only_provider.add_style(content);
  }
};
function generate_route_object(route, url, client2) {
  const { errors, layouts, leaf } = route;
  const nodes = [
    ...errors,
    ...layouts.map((l3) => l3?.[1]),
    leaf[1]
  ].filter((n) => typeof n === "number").map((n) => `'${n}': () => ${create_client_import(client2.nodes?.[n], url)}`).join(",\n		");
  return [
    `{
	id: ${s2(route.id)}`,
    `errors: ${s2(route.errors)}`,
    `layouts: ${s2(route.layouts)}`,
    `leaf: ${s2(route.leaf)}`,
    `nodes: {
		${nodes}
	}
}`
  ].join(",\n	");
}
function create_client_import(import_path, url) {
  if (!import_path) return "Promise.resolve({})";
  if (import_path[0] === "/") return `import('${import_path}')`;
  if (assets !== "") return `import('${assets}/${import_path}')`;
  let path = get_relative_path(url.pathname, `${base}/${import_path}`);
  if (path[0] !== ".") path = `./${path}`;
  return `import('${path}')`;
}
async function resolve_route(resolved_path, url, manifest2) {
  if (!manifest2._.client?.routes) return text("Server-side route resolution disabled", { status: 400 });
  const matchers = await manifest2._.matchers();
  const result = find_route(resolved_path, manifest2._.client.routes, matchers);
  return create_server_routing_response(result?.route ?? null, result?.params ?? {}, url, manifest2._.client).response;
}
function create_server_routing_response(route, params, url, client2) {
  const headers2 = new Headers({ "content-type": "application/javascript; charset=utf-8" });
  if (route) {
    const csr_route = generate_route_object(route, url, client2);
    const body = `${create_css_import(route, url, client2)}
export const route = ${csr_route}; export const params = ${JSON.stringify(params)};`;
    return {
      response: text(body, { headers: headers2 }),
      body
    };
  } else return {
    response: text("", { headers: headers2 }),
    body: ""
  };
}
function create_css_import(route, url, client2) {
  const { errors, layouts, leaf } = route;
  let css = "";
  for (const node of [
    ...errors,
    ...layouts.map((l3) => l3?.[1]),
    leaf[1]
  ]) {
    if (typeof node !== "number") continue;
    const node_css = client2.css?.[node];
    for (const css_path of node_css ?? []) css += `'${assets || base}/${css_path}',`;
  }
  if (!css) return "";
  return `${create_client_import(client2.start, url)}.then(x => x.load_css([${css}]));`;
}
async function handle_remote_call(event, state2, options2, manifest2, id) {
  return record_span({
    name: "sveltekit.remote.call",
    attributes: { "sveltekit.remote.call.id": id },
    fn: (current3) => {
      const traced_event = merge_tracing(event, current3);
      return with_request_store({
        event: traced_event,
        state: state2
      }, () => handle_remote_call_internal(traced_event, state2, options2, manifest2, id));
    }
  });
}
async function handle_remote_call_internal(event, state2, options2, manifest2, id) {
  const [hash4, name, additional_args] = id.split("/");
  const remotes = manifest2._.remotes;
  if (!remotes[hash4]) error(404);
  const fn = (await remotes[hash4]()).default[name];
  if (!fn) error(404);
  const internals = fn.__;
  const transport = options2.hooks.transport;
  event.tracing.current.setAttributes({
    "sveltekit.remote.call.type": internals.type,
    "sveltekit.remote.call.name": internals.name
  });
  const headers2 = state2.prerendering ? void 0 : { "cache-control": "private, no-store" };
  try {
    const data = {};
    switch (internals.type) {
      case "query_live": {
        let send2 = function(controller2, payload3) {
          controller2.enqueue(encoder4.encode("data: " + JSON.stringify(payload3) + "\n\n"));
        };
        var send = send2;
        if (event.request.method !== "GET") throw new SvelteKitError(405, "Method Not Allowed", `\`query.live\` functions must be invoked via GET request, not ${event.request.method}`);
        const payload2 = new URL(event.request.url).searchParams.get("payload");
        const generator = internals.run(event, state2, parse_remote_arg(payload2, transport));
        const encoder4 = new TextEncoder();
        let closed = false;
        let result = void 0;
        async function cancel() {
          if (closed) return;
          closed = true;
          await generator.return(void 0);
        }
        event.request.signal.addEventListener("abort", cancel, { once: true });
        return new Response(new ReadableStream({
          async pull(controller2) {
            if (event.request.signal.aborted) {
              await cancel();
              controller2.close();
              return;
            }
            try {
              while (true) {
                const { value: value2, done } = await generator.next();
                if (done) {
                  await cancel();
                  controller2.close();
                  return;
                }
                if (result !== (result = stringify2(value2, transport))) {
                  send2(controller2, {
                    type: "result",
                    result
                  });
                  return;
                }
              }
            } catch (error2) {
              if (!event.request.signal.aborted) if (error2 instanceof Redirect) send2(controller2, {
                type: "redirect",
                location: error2.location
              });
              else {
                const status = error2 instanceof HttpError || error2 instanceof SvelteKitError ? error2.status : 500;
                send2(controller2, {
                  type: "error",
                  error: await handle_error_and_jsonify(event, state2, options2, error2),
                  status
                });
              }
              await cancel();
              controller2.close();
            }
          },
          cancel
        }), { headers: {
          "cache-control": "private, no-store",
          "content-type": "text/event-stream"
        } });
      }
      case "query_batch": {
        if (event.request.method !== "POST") throw new SvelteKitError(405, "Method Not Allowed", `\`query.batch\` functions must be invoked via POST request, not ${event.request.method}`);
        const { payloads } = await event.request.json();
        const args = await Promise.all(payloads.map((payload2) => parse_remote_arg(payload2, transport)));
        data._ = await with_request_store({
          event,
          state: state2
        }, () => internals.run(args, options2));
        break;
      }
      case "form": {
        if (event.request.method !== "POST") throw new SvelteKitError(405, "Method Not Allowed", `\`form\` functions must be invoked via POST request, not ${event.request.method}`);
        if (!is_form_content_type(event.request)) throw new SvelteKitError(415, "Unsupported Media Type", `\`form\` functions expect form-encoded data \u2014 received ${event.request.headers.get("content-type")}`);
        const { data: input, meta, form_data } = await deserialize_binary_form(event.request);
        state2.remote.requested = create_requested_map(meta.remote_refreshes);
        if (additional_args && !("id" in input)) input.id = JSON.parse(decodeURIComponent(additional_args));
        const fn2 = internals.fn;
        data._ = await with_request_store({
          event,
          state: {
            ...state2,
            is_in_remote_form_or_command: true
          }
        }, () => fn2(input, meta, form_data));
        if (data._.issues) return json({
          type: "result",
          data: stringify2(data, transport)
        }, { headers: headers2 });
        break;
      }
      case "command": {
        const { payload: payload2, refreshes } = await event.request.json();
        state2.remote.requested = create_requested_map(refreshes);
        const arg = parse_remote_arg(payload2, transport);
        data._ = await with_request_store({
          event,
          state: {
            ...state2,
            is_in_remote_form_or_command: true
          }
        }, () => fn(arg));
        break;
      }
      case "prerender":
        data._ = await with_request_store({
          event,
          state: state2
        }, () => fn(parse_remote_arg(additional_args, transport)));
        break;
      case "query": {
        const payload2 = new URL(event.request.url).searchParams.get("payload");
        data._ = await with_request_store({
          event,
          state: state2
        }, () => fn(parse_remote_arg(payload2, transport)));
        break;
      }
    }
    await collect_remote_data(data, event, state2, options2);
    return json({
      type: "result",
      data: stringify2(data, transport)
    }, { headers: headers2 });
  } catch (error2) {
    if (error2 instanceof Redirect) {
      const data = await collect_remote_data({ redirect: error2.location }, event, state2, options2);
      return json({
        type: "result",
        data: stringify2(data, transport)
      }, { headers: headers2 });
    }
    const status = error2 instanceof HttpError || error2 instanceof SvelteKitError ? error2.status : 500;
    return json({
      type: "error",
      error: await handle_error_and_jsonify(event, state2, options2, error2),
      status
    }, {
      status: state2.prerendering ? status : void 0,
      headers: { "cache-control": "private, no-store" }
    });
  }
}
async function collect_remote_data(data, event, state2, options2) {
  async function convert_error(error2) {
    return [error2 instanceof HttpError || error2 instanceof SvelteKitError ? error2.status : 500, await handle_error_and_jsonify(event, state2, options2, error2)];
  }
  const promises = [];
  if (state2.remote.explicit) for (const [remote_key, { internals, promise }] of state2.remote.explicit) {
    data.r = true;
    const type = internals.type === "query_live" ? "l" : internals.type[0];
    await promise.then((v3) => {
      ((data[type] ??= {})[remote_key] ??= {}).v = v3;
    }, async (e) => {
      if (e instanceof Redirect) return;
      ((data[type] ??= {})[remote_key] ??= {}).e = await convert_error(e);
    });
  }
  await Promise.all(promises);
  if (state2.remote.implicit) for (const [internals, record] of state2.remote.implicit) {
    if (!internals.id) continue;
    for (const key2 in record) {
      const remote_key = internals.type === "form" ? key2 : create_remote_key(internals.id, key2);
      const type = internals.type === "query_live" ? "l" : internals.type[0];
      const promise = state2.remote.data?.get(internals)?.[key2] ?? record[key2]();
      let resolved = true;
      await Promise.race([Promise.resolve(promise).then((v3) => {
        if (resolved) ((data[type] ??= {})[remote_key] ??= {}).v = v3;
      }, (e) => {
        if (e instanceof Redirect) return;
        if (resolved) promises.push(convert_error(e).then((e2) => {
          ((data[type] ??= {})[remote_key] ??= {}).e = e2;
        }));
      }), Promise.resolve().then(() => resolved = false)]);
    }
  }
  await Promise.all(promises);
  return data;
}
function create_requested_map(refreshes) {
  const requested = /* @__PURE__ */ new Map();
  for (const key2 of refreshes ?? []) {
    const parts = split_remote_key(key2);
    const existing = requested.get(parts.id);
    if (existing) existing.push(parts.payload);
    else requested.set(parts.id, [parts.payload]);
  }
  return requested;
}
async function handle_remote_form_post(event, state2, manifest2, id) {
  return record_span({
    name: "sveltekit.remote.form.post",
    attributes: { "sveltekit.remote.form.post.id": id },
    fn: (current3) => {
      const traced_event = merge_tracing(event, current3);
      return with_request_store({
        event: traced_event,
        state: state2
      }, () => handle_remote_form_post_internal(traced_event, state2, manifest2, id));
    }
  });
}
async function handle_remote_form_post_internal(event, state2, manifest2, id) {
  const [hash4, name, ...rest] = id.split("/");
  const action_id = rest.join("/");
  let form = (await manifest2._.remotes[hash4]?.())?.default[name];
  if (!form) {
    event.setHeaders({ allow: "GET" });
    return {
      type: "error",
      error: new SvelteKitError(405, "Method Not Allowed", `POST method not allowed. No form actions exist for this page`)
    };
  }
  if (action_id) form = with_request_store({
    event,
    state: state2
  }, () => form.for(JSON.parse(action_id)));
  try {
    const fn = form.__.fn;
    const { data, meta, form_data } = await deserialize_binary_form(event.request);
    if (action_id && !("id" in data)) data.id = JSON.parse(decodeURIComponent(action_id));
    await with_request_store({
      event,
      state: {
        ...state2,
        is_in_remote_form_or_command: true
      }
    }, () => fn(data, meta, form_data));
    return {
      type: "success",
      status: 200
    };
  } catch (e) {
    const err = normalize_error(e);
    if (err instanceof Redirect) return {
      type: "redirect",
      status: err.status,
      location: err.location
    };
    return {
      type: "error",
      error: check_incorrect_fail_use(err)
    };
  }
}
function get_remote_id(url) {
  return url.pathname.startsWith(`${base}/_app/remote/`) && url.pathname.replace(`${base}/_app/remote/`, "");
}
function get_remote_action(url) {
  return url.searchParams.get("/remote");
}
var updated = {
  ...readable(false),
  check: () => false
};
async function render_response({ branch: branch2, fetched, options: options2, manifest: manifest2, state: state2, page_config, status, error: error2 = null, event, event_state, resolve_opts, action_result, data_serializer, error_components }) {
  if (state2.prerendering) {
    if (options2.csp.mode === "nonce") throw new Error('Cannot use prerendering if config.kit.csp.mode === "nonce"');
    if (options2.app_template_contains_nonce) throw new Error("Cannot use prerendering if page template contains %sveltekit.nonce%");
  }
  const { client: client2 } = manifest2._;
  const modulepreloads = new Set(client2?.imports);
  const stylesheets88 = new Set(client2?.stylesheets);
  const fonts88 = new Set(client2?.fonts);
  const link_headers = /* @__PURE__ */ new Set();
  const inline_styles = /* @__PURE__ */ new Map();
  let rendered;
  const form_value = action_result?.type === "success" || action_result?.type === "failure" ? action_result.data ?? null : null;
  let base$1 = base;
  let assets$1 = assets;
  let base_expression = s2(base);
  const csp = new Csp(options2.csp, { prerender: !!state2.prerendering });
  if (!state2.prerendering?.fallback) {
    base$1 = (event.isDataRequest ? add_data_suffix2(event.url.pathname) : event.url.pathname).slice(base.length).split("/").slice(2).map(() => "..").join("/") || ".";
    base_expression = `new URL(${s2(base$1)}, location).pathname.slice(0, -1)`;
    if (!assets || assets[0] === "/" && assets !== "/_svelte_kit_assets") assets$1 = base$1;
  } else if (options2.hash_routing) base_expression = "new URL('.', location).pathname.slice(0, -1)";
  if (page_config.ssr) {
    const props = {
      stores: {
        page: writable(null),
        navigating: writable(null),
        updated
      },
      constructors: await Promise.all(branch2.map(({ node }) => {
        if (!node.component) throw new Error(`Missing +page.svelte component for route ${event.route.id}`);
        return node.component();
      })),
      form: form_value
    };
    if (error_components) {
      if (error2) props.error = error2;
      props.errors = error_components;
    }
    let data2 = {};
    for (let i = 0; i < branch2.length; i += 1) {
      data2 = {
        ...data2,
        ...branch2[i].data
      };
      props[`data_${i}`] = data2;
    }
    props.page = {
      error: error2,
      params: event.params,
      route: event.route,
      status,
      url: event.url,
      data: data2,
      form: form_value,
      state: {}
    };
    const render_opts = {
      context: /* @__PURE__ */ new Map([["__request__", { page: props.page }]]),
      csp: csp.script_needs_nonce ? { nonce: csp.nonce } : { hash: csp.script_needs_hash },
      transformError: error_components ? async (e) => {
        if (isRedirect(e)) throw e;
        const transformed2 = await handle_error_and_jsonify(event, event_state, options2, e);
        props.page.error = props.error = error2 = transformed2;
        props.page.status = status = get_status(e);
        return transformed2;
      } : void 0
    };
    globalThis.fetch;
    try {
      const state3 = {
        ...event_state,
        is_in_render: true
      };
      rendered = await with_request_store({
        event,
        state: state3
      }, async () => {
        override({
          base: base$1,
          assets: assets$1
        });
        const maybe_promise = options2.root.render(props, render_opts);
        const rendered2 = options2.async && "then" in maybe_promise ? maybe_promise.then((r2) => r2) : maybe_promise;
        if (options2.async) reset();
        const { head: head3, html: html3, css, hashes } = options2.async ? await rendered2 : rendered2;
        if (hashes) csp.add_script_hashes(hashes.script);
        return {
          head: head3,
          html: html3,
          css,
          hashes
        };
      });
    } finally {
      reset();
    }
  } else rendered = {
    head: "",
    html: "",
    css: {
      code: "",
      map: null
    },
    hashes: { script: [] }
  };
  for (const { node } of branch2) {
    for (const url of node.imports) modulepreloads.add(url);
    for (const url of node.stylesheets) stylesheets88.add(url);
    for (const url of node.fonts) fonts88.add(url);
    if (node.inline_styles && !client2?.inline) Object.entries(await node.inline_styles()).forEach(([filename, css]) => {
      if (typeof css === "string") {
        inline_styles.set(filename, css);
        return;
      }
      inline_styles.set(filename, css(`${assets$1}/${app_dir}/immutable/assets`, assets$1));
    });
  }
  const head2 = new Head(rendered.head, !!state2.prerendering);
  let body = rendered.html;
  const prefixed = (path) => {
    if (path.startsWith("/")) return base + path;
    return `${assets$1}/${path}`;
  };
  const style = client2?.inline ? client2.inline?.style : Array.from(inline_styles.values()).join("\n");
  if (style) {
    const attributes2 = [];
    if (csp.style_needs_nonce) attributes2.push(`nonce="${csp.nonce}"`);
    csp.add_style(style);
    head2.add_style(style, attributes2);
  }
  for (const dep of stylesheets88) {
    const path = prefixed(dep);
    const attributes2 = ['rel="stylesheet"'];
    if (inline_styles.has(dep)) attributes2.push("disabled", 'media="(max-width: 0)"');
    else if (resolve_opts.preload({
      type: "css",
      path
    })) link_headers.add(`<${encodeURI(path)}>; rel="preload"; as="style"; nopush`);
    head2.add_stylesheet(path, attributes2);
  }
  for (const dep of fonts88) {
    const path = prefixed(dep);
    if (resolve_opts.preload({
      type: "font",
      path
    })) {
      const ext = dep.slice(dep.lastIndexOf(".") + 1);
      head2.add_link_tag(path, [
        'rel="preload"',
        'as="font"',
        `type="font/${ext}"`,
        "crossorigin"
      ]);
      link_headers.add(`<${encodeURI(path)}>; rel="preload"; as="font"; type="font/${ext}"; crossorigin; nopush`);
    }
  }
  const global = get_global_name(options2);
  const { data, chunks } = data_serializer.get_data(csp);
  if (page_config.ssr && page_config.csr) body += `
			${fetched.map((item) => serialize_data(item, resolve_opts.filterSerializedResponseHeaders, !!state2.prerendering)).join("\n			")}`;
  if (page_config.csr && client2) {
    const route = client2.routes?.find((r2) => r2.id === event.route.id) ?? null;
    const load_env_eagerly = client2.uses_env_dynamic_public && !!state2.prerendering;
    if (load_env_eagerly) modulepreloads.add(`${app_dir}/env.js`);
    if (!client2.inline) {
      const included_modulepreloads = Array.from(modulepreloads, (dep) => prefixed(dep)).filter((path) => resolve_opts.preload({
        type: "js",
        path
      }));
      for (const path of included_modulepreloads) {
        link_headers.add(`<${encodeURI(path)}>; rel="modulepreload"; nopush`);
        if (options2.preload_strategy !== "modulepreload") head2.add_script_preload(path);
        else head2.add_link_tag(path, ['rel="modulepreload"']);
      }
    }
    if (client2.routes && state2.prerendering && !state2.prerendering.fallback) {
      const pathname = add_resolution_suffix2(event.url.pathname);
      state2.prerendering.dependencies.set(pathname, create_server_routing_response(route, event.params, new URL(pathname, event.url), client2));
    }
    const blocks = [];
    const properties = [`base: ${base_expression}`];
    if (assets) properties.push(`assets: ${s2(assets)}`);
    if (client2.uses_env_dynamic_public) properties.push(`env: ${load_env_eagerly ? "null" : s2(public_env)}`);
    if (chunks) {
      blocks.push("const deferred = new Map();");
      properties.push(`defer: (id) => new Promise((fulfil, reject) => {
							deferred.set(id, { fulfil, reject });
						})`);
      let app_declaration = "";
      if (Object.keys(options2.hooks.transport).length > 0) if (client2.inline) app_declaration = `const app = ${global}.app.app;`;
      else if (client2.app) app_declaration = `const app = await import(${s2(prefixed(client2.app))});`;
      else app_declaration = `const { app } = await import(${s2(prefixed(client2.start))});`;
      const prelude = app_declaration ? `${app_declaration}
							const [data, error] = fn(app);` : `const [data, error] = fn();`;
      properties.push(`resolve: async (id, fn) => {
							${prelude}

							const try_to_resolve = () => {
								if (!deferred.has(id)) {
									setTimeout(try_to_resolve, 0);
									return;
								}
								const { fulfil, reject } = deferred.get(id);
								deferred.delete(id);
								if (error) reject(error);
								else fulfil(data);
							}
							try_to_resolve();
						}`);
    }
    blocks.push(`${global} = {
						${properties.join(",\n						")}
					};`);
    const args = ["element"];
    blocks.push("const element = document.currentScript.parentElement;");
    if (page_config.ssr) {
      const serialized = {
        form: "null",
        error: "null"
      };
      if (form_value) serialized.form = uneval_action_response(form_value, event.route.id, options2.hooks.transport);
      if (error2) serialized.error = uneval(error2);
      const hydrate3 = [
        `node_ids: [${branch2.map(({ node }) => node.index).join(", ")}]`,
        `data: ${data}`,
        `form: ${serialized.form}`,
        `error: ${serialized.error}`
      ];
      if (status !== 200) hydrate3.push(`status: ${status}`);
      if (client2.routes) {
        if (route) {
          const stringified = generate_route_object(route, event.url, client2).replaceAll("\n", "\n							");
          hydrate3.push(`params: ${uneval(event.params)}`, `server_route: ${stringified}`);
        }
      } else if (options2.embedded) hydrate3.push(`params: ${uneval(event.params)}`, `route: ${s2(event.route)}`);
      const indent = "	".repeat(load_env_eagerly ? 7 : 6);
      args.push(`{
${indent}	${hydrate3.join(`,
${indent}	`)}
${indent}}`);
    }
    const remote_data = await collect_remote_data({}, event, event_state, options2);
    const serialized_data = Object.keys(remote_data).length > 0 ? `${global}.data = ${uneval(remote_data, create_replacer(options2.hooks.transport))};

						` : "";
    const boot = client2.inline ? `${client2.inline.script}

					${serialized_data}${global}.app.start(${args.join(", ")});` : client2.app ? `Promise.all([
						import(${s2(prefixed(client2.start))}),
						import(${s2(prefixed(client2.app))})
					]).then(([kit, app]) => {
						${serialized_data}kit.start(app, ${args.join(", ")});
					});` : `import(${s2(prefixed(client2.start))}).then((app) => {
						${serialized_data}app.start(${args.join(", ")})
					});`;
    if (load_env_eagerly) blocks.push(`import(${s2(`${base$1}/${app_dir}/env.js`)}).then(({ env }) => {
						${global}.env = env;

						${boot.replace(/\n/g, "\n	")}
					});`);
    else blocks.push(boot);
    if (options2.service_worker) {
      let opts = "";
      if (options2.service_worker_options != null) opts = `, ${s2({ ...options2.service_worker_options })}`;
      blocks.push(`if ('serviceWorker' in navigator) {
						const script_url = '${prefixed("service-worker.js")}';
						const policy = globalThis?.window?.trustedTypes?.createPolicy(
							'sveltekit-trusted-url',
							{ createScriptURL(url) { return url; } }
						);
						const sanitised = policy?.createScriptURL(script_url) ?? script_url;
						addEventListener('load', function () {
							navigator.serviceWorker.register(sanitised${opts});
						});
					}`);
    }
    const init_app = `
				{
					${blocks.join("\n\n					")}
				}
			`;
    csp.add_script(init_app);
    body += `
			<script${csp.script_needs_nonce ? ` nonce="${csp.nonce}"` : ""}>${init_app}</script>
		`;
  }
  const headers2 = new Headers({
    "x-sveltekit-page": "true",
    "content-type": "text/html"
  });
  if (state2.prerendering) {
    const csp_headers = csp.csp_provider.get_meta();
    if (csp_headers) head2.add_http_equiv(csp_headers);
    if (state2.prerendering.cache) head2.add_http_equiv(`<meta http-equiv="cache-control" content="${state2.prerendering.cache}">`);
  } else {
    const csp_header = csp.csp_provider.get_header();
    if (csp_header) headers2.set("content-security-policy", csp_header);
    const report_only_header = csp.report_only_provider.get_header();
    if (report_only_header) headers2.set("content-security-policy-report-only", report_only_header);
    if (link_headers.size) headers2.set("link", Array.from(link_headers).join(", "));
  }
  const html2 = options2.templates.app({
    head: head2.build(),
    body,
    assets: assets$1,
    nonce: csp.nonce,
    env: public_env
  });
  const transformed = await resolve_opts.transformPageChunk({
    html: html2,
    done: true
  }) || "";
  if (!chunks) headers2.set("etag", `"${hash3(transformed)}"`);
  return !chunks ? text(transformed, {
    status,
    headers: headers2
  }) : new Response(new ReadableStream({
    async start(controller2) {
      controller2.enqueue(text_encoder2.encode(transformed + "\n"));
      for await (const chunk of chunks) if (chunk.length) controller2.enqueue(text_encoder2.encode(chunk));
      controller2.close();
    },
    type: "bytes"
  }), { headers: headers2 });
}
var Head = class {
  #rendered;
  #prerendering;
  /** @type {string[]} */
  #http_equiv = [];
  /** @type {string[]} */
  #link_tags = [];
  /** @type {string[]} */
  #script_preloads = [];
  /** @type {string[]} */
  #style_tags = [];
  /** @type {string[]} */
  #stylesheet_links = [];
  /**
  * @param {string} rendered
  * @param {boolean} prerendering
  */
  constructor(rendered, prerendering) {
    this.#rendered = rendered;
    this.#prerendering = prerendering;
  }
  build() {
    return [
      ...this.#http_equiv,
      ...this.#link_tags,
      ...this.#script_preloads,
      this.#rendered,
      ...this.#style_tags,
      ...this.#stylesheet_links
    ].join("\n		");
  }
  /**
  * @param {string} style
  * @param {string[]} attributes
  */
  add_style(style, attributes2) {
    this.#style_tags.push(`<style${attributes2.length ? " " + attributes2.join(" ") : ""}>${style}</style>`);
  }
  /**
  * @param {string} href
  * @param {string[]} attributes
  */
  add_stylesheet(href, attributes2) {
    this.#stylesheet_links.push(`<link href="${href}" ${attributes2.join(" ")}>`);
  }
  /** @param {string} href */
  add_script_preload(href) {
    this.#script_preloads.push(`<link rel="preload" as="script" crossorigin="anonymous" href="${href}">`);
  }
  /**
  * @param {string} href
  * @param {string[]} attributes
  */
  add_link_tag(href, attributes2) {
    if (!this.#prerendering) return;
    this.#link_tags.push(`<link href="${href}" ${attributes2.join(" ")}>`);
  }
  /** @param {string} tag */
  add_http_equiv(tag2) {
    if (!this.#prerendering) return;
    this.#http_equiv.push(tag2);
  }
};
var PageNodes = class {
  /** All layout nodes and the page node, if any */
  data;
  /**
  * @param {Array<import('types').SSRNode | undefined>} nodes
  */
  constructor(nodes) {
    this.data = nodes;
  }
  layouts() {
    return this.data.slice(0, -1);
  }
  page() {
    return this.data.at(-1);
  }
  validate() {
    for (const layout of this.layouts()) if (layout) {
      validate_layout_server_exports(layout.server, layout.server_id);
      validate_layout_exports(layout.universal, layout.universal_id);
    }
    const page2 = this.page();
    if (page2) {
      validate_page_server_exports(page2.server, page2.server_id);
      validate_page_exports(page2.universal, page2.universal_id);
    }
  }
  /**
  * @template {'prerender' | 'ssr' | 'csr' | 'trailingSlash'} Option
  * @param {Option} option
  * @returns {Value | undefined}
  */
  #get_option(option) {
    return this.data.reduce((value2, node) => {
      return node?.universal?.[option] ?? node?.server?.[option] ?? value2;
    }, void 0);
  }
  csr() {
    return this.#get_option("csr") ?? true;
  }
  ssr() {
    return this.#get_option("ssr") ?? true;
  }
  prerender() {
    return this.#get_option("prerender") ?? false;
  }
  trailing_slash() {
    return this.#get_option("trailingSlash") ?? "never";
  }
  get_config() {
    let current3 = {};
    for (const node of this.data) {
      if (!node?.universal?.config && !node?.server?.config) continue;
      current3 = {
        ...current3,
        ...node?.universal?.config,
        ...node?.server?.config
      };
    }
    return Object.keys(current3).length ? current3 : void 0;
  }
  should_prerender_data() {
    return this.data.some((node) => node?.server?.load || node?.server?.trailingSlash !== void 0);
  }
};
async function respond_with_error({ event, event_state, options: options2, manifest: manifest2, state: state2, status, error: error2, resolve_opts }) {
  if (event.request.headers.get("x-sveltekit-error")) return static_error_page(
    options2,
    status,
    /** @type {Error} */
    error2.message
  );
  const fetched = [];
  try {
    const branch2 = [];
    const default_layout = await manifest2._.nodes[0]();
    const nodes = new PageNodes([default_layout]);
    const ssr = nodes.ssr();
    const csr = nodes.csr();
    const data_serializer = server_data_serializer(event, event_state, options2);
    if (ssr) {
      state2.error = true;
      const server_data_promise = load_server_data({
        event,
        event_state,
        state: state2,
        node: default_layout,
        parent: async () => ({})
      });
      const server_data = await server_data_promise;
      data_serializer.add_node(0, server_data);
      const data = await load_data({
        event,
        event_state,
        fetched,
        node: default_layout,
        parent: async () => ({}),
        resolve_opts,
        server_data_promise,
        state: state2,
        csr
      });
      branch2.push({
        node: default_layout,
        server_data,
        data
      }, {
        node: await manifest2._.nodes[1](),
        data: null,
        server_data: null
      });
    }
    return await render_response({
      options: options2,
      manifest: manifest2,
      state: state2,
      page_config: {
        ssr,
        csr
      },
      status,
      error: await handle_error_and_jsonify(event, event_state, options2, error2),
      branch: branch2,
      error_components: [],
      fetched,
      event,
      event_state,
      resolve_opts,
      data_serializer
    });
  } catch (e) {
    if (e instanceof Redirect) return redirect_response(e.status, e.location);
    return static_error_page(options2, get_status(e), (await handle_error_and_jsonify(event, event_state, options2, e)).message);
  }
}
var MAX_DEPTH = 10;
async function render_page(event, event_state, page2, options2, manifest2, state2, nodes, resolve_opts) {
  if (state2.depth > MAX_DEPTH) return text(`Not found: ${event.url.pathname}`, { status: 404 });
  if (is_action_json_request(event)) return handle_action_json_request(event, event_state, options2, (await manifest2._.nodes[page2.leaf]())?.server);
  try {
    const leaf_node = nodes.page();
    let status = 200;
    let action_result = void 0;
    if (is_action_request(event)) {
      const remote_id = get_remote_action(event.url);
      if (remote_id) action_result = await handle_remote_form_post(event, event_state, manifest2, remote_id);
      else action_result = await handle_action_request(event, event_state, leaf_node.server);
      if (action_result?.type === "redirect") return redirect_response(action_result.status, action_result.location);
      if (action_result?.type === "error") status = get_status(action_result.error);
      if (action_result?.type === "failure") status = action_result.status;
    }
    const should_prerender = nodes.prerender();
    if (should_prerender) {
      if (leaf_node.server?.actions) throw new Error("Cannot prerender pages with actions");
    } else if (state2.prerendering) return new Response(void 0, { status: 204 });
    state2.prerender_default = should_prerender;
    const should_prerender_data = nodes.should_prerender_data();
    const data_pathname = add_data_suffix2(event.url.pathname);
    const fetched = [];
    const ssr = nodes.ssr();
    const csr = nodes.csr();
    if (ssr === false && !(state2.prerendering && should_prerender_data)) return await render_response({
      branch: compact(nodes.data).map((node) => {
        return {
          node,
          data: null,
          server_data: null
        };
      }),
      fetched,
      page_config: {
        ssr: false,
        csr
      },
      status,
      error: null,
      event,
      event_state,
      options: options2,
      manifest: manifest2,
      state: state2,
      resolve_opts,
      data_serializer: server_data_serializer(event, event_state, options2)
    });
    const branch2 = [];
    let load_error = null;
    const data_serializer = server_data_serializer(event, event_state, options2);
    const data_serializer_json = state2.prerendering && should_prerender_data ? server_data_serializer_json(event, event_state, options2) : null;
    const server_promises = nodes.data.map((node, i) => {
      if (load_error) throw load_error;
      return Promise.resolve().then(async () => {
        try {
          if (node === leaf_node && action_result?.type === "error") throw action_result.error;
          const server_data = await load_server_data({
            event,
            event_state,
            state: state2,
            node,
            parent: async () => {
              const data = {};
              for (let j2 = 0; j2 < i; j2 += 1) {
                const parent = await server_promises[j2];
                if (parent) Object.assign(data, parent.data);
              }
              return data;
            }
          });
          if (node) data_serializer.add_node(i, server_data);
          data_serializer_json?.add_node(i, server_data);
          return server_data;
        } catch (e) {
          load_error = e;
          throw load_error;
        }
      });
    });
    const load_promises = nodes.data.map((node, i) => {
      if (load_error) throw load_error;
      return Promise.resolve().then(async () => {
        try {
          return await load_data({
            event,
            event_state,
            fetched,
            node,
            parent: async () => {
              const data = {};
              for (let j2 = 0; j2 < i; j2 += 1) Object.assign(data, await load_promises[j2]);
              return data;
            },
            resolve_opts,
            server_data_promise: server_promises[i],
            state: state2,
            csr
          });
        } catch (e) {
          load_error = e;
          throw load_error;
        }
      });
    });
    for (const p2 of server_promises) p2.catch(noop2);
    for (const p2 of load_promises) p2.catch(noop2);
    for (let i = 0; i < nodes.data.length; i += 1) {
      const node = nodes.data[i];
      if (node) try {
        const server_data = await server_promises[i];
        const data = await load_promises[i];
        branch2.push({
          node,
          server_data,
          data
        });
      } catch (e) {
        const err = normalize_error(e);
        if (err instanceof Redirect) {
          if (state2.prerendering && should_prerender_data) {
            const body = JSON.stringify({
              type: "redirect",
              location: err.location
            });
            state2.prerendering.dependencies.set(data_pathname, {
              response: text(body),
              body
            });
          }
          return redirect_response(err.status, err.location);
        }
        const status2 = get_status(err);
        const error2 = await handle_error_and_jsonify(event, event_state, options2, err);
        while (i--) if (page2.errors[i]) {
          const index88 = page2.errors[i];
          const node2 = await manifest2._.nodes[index88]();
          let j2 = i;
          while (!branch2[j2]) j2 -= 1;
          data_serializer.set_max_nodes(j2 + 1);
          const layouts = compact(branch2.slice(0, j2 + 1));
          const nodes2 = new PageNodes(layouts.map((layout) => layout.node));
          const error_branch = layouts.concat({
            node: node2,
            data: null,
            server_data: null
          });
          return await render_response({
            event,
            event_state,
            options: options2,
            manifest: manifest2,
            state: state2,
            resolve_opts,
            page_config: {
              ssr: nodes2.ssr(),
              csr: nodes2.csr()
            },
            status: status2,
            error: error2,
            error_components: await load_error_components(options2, ssr, error_branch, page2, manifest2),
            branch: error_branch,
            fetched,
            data_serializer
          });
        }
        return static_error_page(options2, status2, error2.message);
      }
      else branch2.push(null);
    }
    if (state2.prerendering && data_serializer_json) {
      let { data, chunks } = data_serializer_json.get_data();
      if (chunks) for await (const chunk of chunks) data += chunk;
      state2.prerendering.dependencies.set(data_pathname, {
        response: text(data),
        body: data
      });
    }
    return await render_response({
      event,
      event_state,
      options: options2,
      manifest: manifest2,
      state: state2,
      resolve_opts,
      page_config: {
        csr,
        ssr
      },
      status,
      error: null,
      branch: compact(branch2),
      action_result,
      fetched,
      data_serializer: !ssr ? server_data_serializer(event, event_state, options2) : data_serializer,
      error_components: await load_error_components(options2, ssr, branch2, page2, manifest2)
    });
  } catch (e) {
    if (e instanceof Redirect) return redirect_response(e.status, e.location);
    return await respond_with_error({
      event,
      event_state,
      options: options2,
      manifest: manifest2,
      state: state2,
      status: e instanceof HttpError ? e.status : 500,
      error: e,
      resolve_opts
    });
  }
}
async function load_error_components(options2, ssr, branch2, page2, manifest2) {
  let error_components;
  if (options2.server_error_boundaries && ssr) {
    let last_idx = -1;
    error_components = await Promise.all(branch2.map((b3, i) => {
      if (i === 0) return void 0;
      if (!b3) return null;
      i--;
      while (i > last_idx + 1 && page2.errors[i] === void 0) i -= 1;
      last_idx = i;
      const idx = page2.errors[i];
      if (idx == null) return void 0;
      return manifest2._.nodes[idx]?.().then((e) => e.component?.()).catch(() => void 0);
    }).filter((e) => e !== null));
  }
  return error_components;
}
async function render_data(event, event_state, route, options2, manifest2, state2, invalidated_data_nodes, trailing_slash) {
  if (!route.page) return new Response(void 0, { status: 404 });
  try {
    const node_ids = [...route.page.layouts, route.page.leaf];
    const invalidated = invalidated_data_nodes ?? node_ids.map(() => true);
    let aborted = false;
    const url = new URL(event.url);
    url.pathname = normalize_path(url.pathname, trailing_slash);
    const new_event = {
      ...event,
      url
    };
    const functions = node_ids.map((n, i) => {
      return once2(async () => {
        try {
          if (aborted) return { type: "skip" };
          const node = n == void 0 ? n : await manifest2._.nodes[n]();
          return load_server_data({
            event: new_event,
            event_state,
            state: state2,
            node,
            parent: async () => {
              const data2 = {};
              for (let j2 = 0; j2 < i; j2 += 1) {
                const parent = await functions[j2]();
                if (parent) Object.assign(data2, parent.data);
              }
              return data2;
            }
          });
        } catch (e) {
          aborted = true;
          throw e;
        }
      });
    });
    const promises = functions.map(async (fn, i) => {
      if (!invalidated[i]) return { type: "skip" };
      return fn();
    });
    let length = promises.length;
    const nodes = await Promise.all(promises.map((p2, i) => p2.catch(async (error2) => {
      if (error2 instanceof Redirect) throw error2;
      length = Math.min(length, i + 1);
      return {
        type: "error",
        error: await handle_error_and_jsonify(event, event_state, options2, error2),
        status: error2 instanceof HttpError || error2 instanceof SvelteKitError ? error2.status : void 0
      };
    })));
    const data_serializer = server_data_serializer_json(event, event_state, options2);
    for (let i = 0; i < nodes.length; i++) data_serializer.add_node(i, nodes[i]);
    const { data, chunks } = data_serializer.get_data();
    if (!chunks) return json_response(data);
    return new Response(new ReadableStream({
      async start(controller2) {
        controller2.enqueue(text_encoder2.encode(data));
        for await (const chunk of chunks) controller2.enqueue(text_encoder2.encode(chunk));
        controller2.close();
      },
      type: "bytes"
    }), { headers: {
      "content-type": "text/sveltekit-data",
      "cache-control": "private, no-store"
    } });
  } catch (e) {
    const error2 = normalize_error(e);
    if (error2 instanceof Redirect) return redirect_json_response(error2);
    else return json_response(await handle_error_and_jsonify(event, event_state, options2, error2), 500);
  }
}
function json_response(json2, status = 200) {
  return text(typeof json2 === "string" ? json2 : JSON.stringify(json2), {
    status,
    headers: {
      "content-type": "application/json",
      "cache-control": "private, no-store"
    }
  });
}
function redirect_json_response(redirect2) {
  return json_response({
    type: "redirect",
    location: redirect2.location
  });
}
var import_cookie = (/* @__PURE__ */ __commonJSMin(((exports) => {
  exports.parse = parse4;
  exports.serialize = serialize;
  var __toString = Object.prototype.toString;
  var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
  function parse4(str2, options2) {
    if (typeof str2 !== "string") throw new TypeError("argument str must be a string");
    var obj = {};
    var dec = (options2 || {}).decode || decode2;
    var index88 = 0;
    while (index88 < str2.length) {
      var eqIdx = str2.indexOf("=", index88);
      if (eqIdx === -1) break;
      var endIdx = str2.indexOf(";", index88);
      if (endIdx === -1) endIdx = str2.length;
      else if (endIdx < eqIdx) {
        index88 = str2.lastIndexOf(";", eqIdx - 1) + 1;
        continue;
      }
      var key2 = str2.slice(index88, eqIdx).trim();
      if (void 0 === obj[key2]) {
        var val = str2.slice(eqIdx + 1, endIdx).trim();
        if (val.charCodeAt(0) === 34) val = val.slice(1, -1);
        obj[key2] = tryDecode(val, dec);
      }
      index88 = endIdx + 1;
    }
    return obj;
  }
  function serialize(name, val, options2) {
    var opt = options2 || {};
    var enc = opt.encode || encode6;
    if (typeof enc !== "function") throw new TypeError("option encode is invalid");
    if (!fieldContentRegExp.test(name)) throw new TypeError("argument name is invalid");
    var value2 = enc(val);
    if (value2 && !fieldContentRegExp.test(value2)) throw new TypeError("argument val is invalid");
    var str2 = name + "=" + value2;
    if (null != opt.maxAge) {
      var maxAge = opt.maxAge - 0;
      if (isNaN(maxAge) || !isFinite(maxAge)) throw new TypeError("option maxAge is invalid");
      str2 += "; Max-Age=" + Math.floor(maxAge);
    }
    if (opt.domain) {
      if (!fieldContentRegExp.test(opt.domain)) throw new TypeError("option domain is invalid");
      str2 += "; Domain=" + opt.domain;
    }
    if (opt.path) {
      if (!fieldContentRegExp.test(opt.path)) throw new TypeError("option path is invalid");
      str2 += "; Path=" + opt.path;
    }
    if (opt.expires) {
      var expires = opt.expires;
      if (!isDate2(expires) || isNaN(expires.valueOf())) throw new TypeError("option expires is invalid");
      str2 += "; Expires=" + expires.toUTCString();
    }
    if (opt.httpOnly) str2 += "; HttpOnly";
    if (opt.secure) str2 += "; Secure";
    if (opt.partitioned) str2 += "; Partitioned";
    if (opt.priority) switch (typeof opt.priority === "string" ? opt.priority.toLowerCase() : opt.priority) {
      case "low":
        str2 += "; Priority=Low";
        break;
      case "medium":
        str2 += "; Priority=Medium";
        break;
      case "high":
        str2 += "; Priority=High";
        break;
      default:
        throw new TypeError("option priority is invalid");
    }
    if (opt.sameSite) switch (typeof opt.sameSite === "string" ? opt.sameSite.toLowerCase() : opt.sameSite) {
      case true:
        str2 += "; SameSite=Strict";
        break;
      case "lax":
        str2 += "; SameSite=Lax";
        break;
      case "strict":
        str2 += "; SameSite=Strict";
        break;
      case "none":
        str2 += "; SameSite=None";
        break;
      default:
        throw new TypeError("option sameSite is invalid");
    }
    return str2;
  }
  function decode2(str2) {
    return str2.indexOf("%") !== -1 ? decodeURIComponent(str2) : str2;
  }
  function encode6(val) {
    return encodeURIComponent(val);
  }
  function isDate2(val) {
    return __toString.call(val) === "[object Date]" || val instanceof Date;
  }
  function tryDecode(str2, decode3) {
    try {
      return decode3(str2);
    } catch (e) {
      return str2;
    }
  }
})))();
var INVALID_COOKIE_CHARACTER_REGEX = /[\x00-\x1F\x7F()<>@,;:"/[\]?={} \t]/;
function validate_options(options2) {
  if (options2?.path === void 0) throw new Error("You must specify a `path` when setting, deleting or serializing cookies");
}
function generate_cookie_key(domain, path, name) {
  return `${domain || ""}${path}?${encodeURIComponent(name)}`;
}
function get_cookies(request, url) {
  const header = request.headers.get("cookie") ?? "";
  const initial_cookies = (0, import_cookie.parse)(header, { decode: (value2) => value2 });
  let normalized_url;
  const new_cookies = /* @__PURE__ */ new Map();
  const defaults = {
    httpOnly: true,
    sameSite: "lax",
    secure: url.hostname === "localhost" && url.protocol === "http:" ? false : true
  };
  const cookies = {
    /**
    * @param {string} name
    * @param {import('cookie').CookieParseOptions} [opts]
    */
    get(name, opts) {
      const best_match = Array.from(new_cookies.values()).filter((c2) => {
        return c2.name === name && domain_matches(url.hostname, c2.options.domain) && path_matches(url.pathname, c2.options.path);
      }).sort((a2, b3) => b3.options.path.length - a2.options.path.length)[0];
      if (best_match) return best_match.options.maxAge === 0 ? void 0 : best_match.value;
      return (0, import_cookie.parse)(header, { decode: opts?.decode })[name];
    },
    /**
    * @param {import('cookie').CookieParseOptions} [opts]
    */
    getAll(opts) {
      const cookies2 = (0, import_cookie.parse)(header, { decode: opts?.decode });
      const lookup = /* @__PURE__ */ new Map();
      for (const c2 of new_cookies.values()) if (domain_matches(url.hostname, c2.options.domain) && path_matches(url.pathname, c2.options.path)) {
        const existing = lookup.get(c2.name);
        if (!existing || c2.options.path.length > existing.options.path.length) lookup.set(c2.name, c2);
      }
      for (const c2 of lookup.values()) cookies2[c2.name] = c2.value;
      return Object.entries(cookies2).map(([name, value2]) => ({
        name,
        value: value2
      }));
    },
    /**
    * @param {string} name
    * @param {string} value
    * @param {import('./page/types.js').Cookie['options']} options
    */
    set(name, value2, options2) {
      const illegal_characters = name.match(INVALID_COOKIE_CHARACTER_REGEX);
      if (illegal_characters) console.warn(`The cookie name "${name}" will be invalid in SvelteKit 3.0 as it contains ${illegal_characters.join(" and ")}. See RFC 2616 for more details https://datatracker.ietf.org/doc/html/rfc2616#section-2.2`);
      validate_options(options2);
      set_internal(name, value2, {
        ...defaults,
        ...options2
      });
    },
    /**
    * @param {string} name
    *  @param {import('./page/types.js').Cookie['options']} options
    */
    delete(name, options2) {
      validate_options(options2);
      cookies.set(name, "", {
        ...options2,
        maxAge: 0
      });
    },
    /**
    * @param {string} name
    * @param {string} value
    *  @param {import('./page/types.js').Cookie['options']} options
    */
    serialize(name, value2, options2) {
      validate_options(options2);
      let path = options2.path;
      if (!options2.domain || options2.domain === url.hostname) {
        if (!normalized_url) throw new Error("Cannot serialize cookies until after the route is determined");
        path = resolve3(normalized_url, path);
      }
      return (0, import_cookie.serialize)(name, value2, {
        ...defaults,
        ...options2,
        path
      });
    }
  };
  function get_cookie_header(destination, header2) {
    const combined_cookies = { ...initial_cookies };
    for (const cookie of new_cookies.values()) {
      if (!domain_matches(destination.hostname, cookie.options.domain)) continue;
      if (!path_matches(destination.pathname, cookie.options.path)) continue;
      const encoder4 = cookie.options.encode || encodeURIComponent;
      combined_cookies[cookie.name] = encoder4(cookie.value);
    }
    if (header2) {
      const parsed = (0, import_cookie.parse)(header2, { decode: (value2) => value2 });
      for (const name in parsed) combined_cookies[name] = parsed[name];
    }
    return Object.entries(combined_cookies).map(([name, value2]) => `${name}=${value2}`).join("; ");
  }
  const internal_queue = [];
  function set_internal(name, value2, options2) {
    if (!normalized_url) {
      internal_queue.push(() => set_internal(name, value2, options2));
      return;
    }
    let path = options2.path;
    if (!options2.domain || options2.domain === url.hostname) path = resolve3(normalized_url, path);
    const cookie_key = generate_cookie_key(options2.domain, path, name);
    const cookie = {
      name,
      value: value2,
      options: {
        ...options2,
        path
      }
    };
    new_cookies.set(cookie_key, cookie);
  }
  function set_trailing_slash(trailing_slash) {
    normalized_url = normalize_path(url.pathname, trailing_slash);
    internal_queue.forEach((fn) => fn());
  }
  return {
    cookies,
    new_cookies,
    get_cookie_header,
    set_internal,
    set_trailing_slash
  };
}
function domain_matches(hostname, constraint) {
  if (!constraint) return true;
  const normalized = constraint[0] === "." ? constraint.slice(1) : constraint;
  if (hostname === normalized) return true;
  return hostname.endsWith("." + normalized);
}
function path_matches(path, constraint) {
  if (!constraint) return true;
  const normalized = constraint.endsWith("/") ? constraint.slice(0, -1) : constraint;
  if (path === normalized) return true;
  return path.startsWith(normalized + "/");
}
function add_cookies_to_headers(headers2, cookies) {
  for (const new_cookie of cookies) {
    const { name, value: value2, options: options2 } = new_cookie;
    headers2.append("set-cookie", (0, import_cookie.serialize)(name, value2, options2));
    if (options2.path.endsWith(".html")) {
      const path = add_data_suffix2(options2.path);
      headers2.append("set-cookie", (0, import_cookie.serialize)(name, value2, {
        ...options2,
        path
      }));
    }
  }
}
function create_fetch({ event, options: options2, manifest: manifest2, state: state2, get_cookie_header, set_internal }) {
  const server_fetch = async (info, init3) => {
    const original_request = normalize_fetch_input(info, init3, event.url);
    let mode = (info instanceof Request ? info.mode : init3?.mode) ?? "cors";
    let credentials = (info instanceof Request ? info.credentials : init3?.credentials) ?? "same-origin";
    return options2.hooks.handleFetch({
      event,
      request: original_request,
      fetch: async (info2, init4) => {
        const request = normalize_fetch_input(info2, init4, event.url);
        const url = new URL(request.url);
        if (!request.headers.has("origin")) request.headers.set("origin", event.url.origin);
        if (info2 !== original_request) {
          mode = (info2 instanceof Request ? info2.mode : init4?.mode) ?? "cors";
          credentials = (info2 instanceof Request ? info2.credentials : init4?.credentials) ?? "same-origin";
        }
        if ((request.method === "GET" || request.method === "HEAD") && (mode === "no-cors" && url.origin !== event.url.origin || url.origin === event.url.origin)) request.headers.delete("origin");
        const decoded = decodeURIComponent(url.pathname);
        if (url.origin !== event.url.origin || base && decoded !== base && !decoded.startsWith(`${base}/`)) {
          if (`.${url.hostname}`.endsWith(`.${event.url.hostname}`) && credentials !== "omit") {
            const cookie = get_cookie_header(url, request.headers.get("cookie"));
            if (cookie) request.headers.set("cookie", cookie);
          }
          return fetch(request);
        }
        const prefix = assets || base;
        const filename = (decoded.startsWith(prefix) ? decoded.slice(prefix.length) : decoded).slice(1);
        const filename_html = `${filename}/index.html`;
        const is_asset = manifest2.assets.has(filename) || filename in manifest2._.server_assets;
        const is_asset_html = manifest2.assets.has(filename_html) || filename_html in manifest2._.server_assets;
        if (is_asset || is_asset_html) {
          const file = is_asset ? filename : filename_html;
          if (state2.read) {
            const type = is_asset ? manifest2.mimeTypes[filename.slice(filename.lastIndexOf("."))] : "text/html";
            return new Response(state2.read(file), { headers: type ? { "content-type": type } : {} });
          } else if (read_implementation && file in manifest2._.server_assets) {
            const length = manifest2._.server_assets[file];
            const type = manifest2.mimeTypes[file.slice(file.lastIndexOf("."))];
            return new Response(read_implementation(file), { headers: {
              "Content-Length": "" + length,
              "Content-Type": type
            } });
          }
          return await fetch(request);
        }
        if (has_prerendered_path(manifest2, base + decoded)) return await fetch(request);
        if (credentials !== "omit") {
          const cookie = get_cookie_header(url, request.headers.get("cookie"));
          if (cookie) request.headers.set("cookie", cookie);
          const authorization = event.request.headers.get("authorization");
          if (authorization && !request.headers.has("authorization")) request.headers.set("authorization", authorization);
        }
        if (!request.headers.has("accept")) request.headers.set("accept", "*/*");
        if (!request.headers.has("accept-language")) request.headers.set("accept-language", event.request.headers.get("accept-language"));
        const response = await internal_fetch(request, options2, manifest2, state2);
        for (const str2 of get_set_cookies(response.headers)) {
          const { name, value: value2, ...options3 } = parseString(str2, { decodeValues: false });
          set_internal(name, value2, {
            path: options3.path ?? (url.pathname.split("/").slice(0, -1).join("/") || "/"),
            encode: (value3) => value3,
            ...options3
          });
        }
        return response;
      }
    });
  };
  return (input, init3) => {
    const response = server_fetch(input, init3);
    response.catch(noop2);
    return response;
  };
}
function normalize_fetch_input(info, init3, url) {
  if (info instanceof Request) return info;
  return new Request(typeof info === "string" ? new URL(info, url) : info, init3);
}
async function internal_fetch(request, options2, manifest2, state2) {
  if (request.signal) {
    if (request.signal.aborted) throw new DOMException("The operation was aborted.", "AbortError");
    let remove_abort_listener = noop2;
    const abort_promise = new Promise((_3, reject) => {
      const on_abort = () => {
        reject(new DOMException("The operation was aborted.", "AbortError"));
      };
      request.signal.addEventListener("abort", on_abort, { once: true });
      remove_abort_listener = () => request.signal.removeEventListener("abort", on_abort);
    });
    const result = await Promise.race([respond(request, options2, manifest2, {
      ...state2,
      depth: state2.depth + 1
    }), abort_promise]);
    remove_abort_listener();
    return result;
  } else return await respond(request, options2, manifest2, {
    ...state2,
    depth: state2.depth + 1
  });
}
var payload;
var etag;
var headers;
function get_public_env(request) {
  const script = request.url.endsWith(".script.js");
  payload ??= uneval(public_env);
  etag ??= `W/${Date.now()}`;
  headers ??= new Headers({
    "content-type": "application/javascript; charset=utf-8",
    etag
  });
  if (request.headers.get("if-none-match") === etag) return new Response(void 0, {
    status: 304,
    headers
  });
  if (script) return new Response(`globalThis.__sveltekit_sw={env:${payload}}`, { headers });
  return new Response(`export const env=${payload}`, { headers });
}
var default_transform = ({ html: html2 }) => html2;
var default_filter = () => false;
var default_preload = ({ type }) => type === "js" || type === "css";
var page_methods = /* @__PURE__ */ new Set([
  "GET",
  "HEAD",
  "POST"
]);
var allowed_page_methods = /* @__PURE__ */ new Set([
  "GET",
  "HEAD",
  "OPTIONS"
]);
var respond = propagate_context(internal_respond);
async function internal_respond(request, options2, manifest2, state2) {
  const url = new URL(request.url);
  const is_route_resolution_request = has_resolution_suffix2(url.pathname);
  const is_data_request = has_data_suffix2(url.pathname);
  const remote_id = get_remote_id(url);
  {
    const request_origin = request.headers.get("origin");
    if (remote_id) {
      if (request.method !== "GET" && request_origin !== url.origin) return json({ message: "Cross-site remote requests are forbidden" }, { status: 403 });
    } else if (options2.csrf_check_origin) {
      if (is_form_content_type(request) && (request.method === "POST" || request.method === "PUT" || request.method === "PATCH" || request.method === "DELETE") && request_origin !== url.origin && (!request_origin || !options2.csrf_trusted_origins.includes(request_origin))) {
        const message2 = `Cross-site ${request.method} form submissions are forbidden`;
        const opts = { status: 403 };
        if (request.headers.get("accept") === "application/json") return json({ message: message2 }, opts);
        return text(message2, opts);
      }
    }
  }
  if (options2.hash_routing && url.pathname !== base + "/" && url.pathname !== "/[fallback]") return text("Not found", { status: 404 });
  let invalidated_data_nodes;
  if (is_route_resolution_request)
    url.pathname = strip_resolution_suffix2(url.pathname);
  else if (is_data_request) {
    url.pathname = strip_data_suffix2(url.pathname) + (url.searchParams.get("x-sveltekit-trailing-slash") === "1" ? "/" : "") || "/";
    url.searchParams.delete(TRAILING_SLASH_PARAM);
    invalidated_data_nodes = url.searchParams.get(INVALIDATED_PARAM)?.split("").map((node) => node === "1");
    url.searchParams.delete(INVALIDATED_PARAM);
  } else if (remote_id) {
    url.pathname = request.headers.get("x-sveltekit-pathname") ?? base;
    url.search = request.headers.get("x-sveltekit-search") ?? "";
  }
  const headers2 = {};
  const { cookies, new_cookies, get_cookie_header, set_internal, set_trailing_slash } = get_cookies(request, url);
  const event_state = {
    prerendering: state2.prerendering,
    transport: options2.hooks.transport,
    handleValidationError: options2.hooks.handleValidationError,
    tracing: { record_span },
    remote: {
      data: null,
      explicit: null,
      implicit: null,
      forms: null,
      requested: null,
      batches: null,
      live_iterators: null
    },
    is_in_remote_function: false,
    is_in_remote_form_or_command: false,
    is_in_remote_query: false,
    is_in_render: false,
    is_in_universal_load: false
  };
  const event = {
    cookies,
    fetch: null,
    getClientAddress: state2.getClientAddress || (() => {
      throw new Error(`deno-adapter does not specify getClientAddress. Please raise an issue`);
    }),
    locals: {},
    params: {},
    platform: state2.platform,
    request,
    route: { id: null },
    setHeaders: (new_headers) => {
      for (const key2 in new_headers) {
        const lower = key2.toLowerCase();
        const value2 = new_headers[key2];
        if (lower === "set-cookie") throw new Error("Use `event.cookies.set(name, value, options)` instead of `event.setHeaders` to set cookies");
        else if (lower in headers2) if (lower === "server-timing") headers2[lower] += ", " + value2;
        else throw new Error(`"${key2}" header is already set`);
        else {
          headers2[lower] = value2;
          if (state2.prerendering && lower === "cache-control") state2.prerendering.cache = value2;
        }
      }
    },
    url,
    isDataRequest: is_data_request,
    isSubRequest: state2.depth > 0,
    isRemoteRequest: !!remote_id
  };
  event.fetch = create_fetch({
    event,
    options: options2,
    manifest: manifest2,
    state: state2,
    get_cookie_header,
    set_internal
  });
  if (state2.emulator?.platform) event.platform = await state2.emulator.platform({
    config: {},
    prerender: !!state2.prerendering?.fallback
  });
  let resolved_path = url.pathname;
  if (!remote_id) {
    const prerendering_reroute_state = state2.prerendering?.inside_reroute;
    try {
      if (state2.prerendering) state2.prerendering.inside_reroute = true;
      resolved_path = await options2.hooks.reroute({
        url: new URL(url),
        fetch: event.fetch
      }) ?? url.pathname;
    } catch {
      return text("Internal Server Error", { status: 500 });
    } finally {
      if (state2.prerendering) state2.prerendering.inside_reroute = prerendering_reroute_state;
    }
  }
  let resolve_opts = {
    transformPageChunk: default_transform,
    filterSerializedResponseHeaders: default_filter,
    preload: default_preload
  };
  let trailing_slash = "never";
  let page_nodes;
  try {
    resolved_path = decode_pathname(resolved_path);
  } catch {
    resolved_path = null;
    return await handle2();
  }
  if (resolved_path !== decode_pathname(url.pathname) && !state2.prerendering?.fallback && has_prerendered_path(manifest2, resolved_path)) {
    const url2 = new URL(request.url);
    url2.pathname = is_data_request ? add_data_suffix2(resolved_path) : is_route_resolution_request ? add_resolution_suffix2(resolved_path) : resolved_path;
    try {
      const response = await fetch(url2, request);
      const headers3 = new Headers(response.headers);
      if (headers3.has("content-encoding")) {
        headers3.delete("content-encoding");
        headers3.delete("content-length");
      }
      return new Response(response.body, {
        headers: headers3,
        status: response.status,
        statusText: response.statusText
      });
    } catch (error2) {
      return await handle_fatal_error(event, event_state, options2, error2);
    }
  }
  let route = null;
  if (base && !state2.prerendering?.fallback) {
    if (!resolved_path.startsWith(base)) return text("Not found", { status: 404 });
    resolved_path = resolved_path.slice(base.length) || "/";
  }
  if (is_route_resolution_request) return resolve_route(resolved_path, new URL(request.url), manifest2);
  if (resolved_path === `/_app/env.js` || resolved_path === `/_app/env.script.js`) return get_public_env(request);
  if (!remote_id && resolved_path.startsWith(`/_app`)) {
    const headers3 = new Headers();
    headers3.set("cache-control", "public, max-age=0, must-revalidate");
    return text("Not found", {
      status: 404,
      headers: headers3
    });
  }
  if (!state2.prerendering?.fallback) {
    const matchers = await manifest2._.matchers();
    const result = find_route(resolved_path, manifest2._.routes, matchers);
    if (result) {
      route = result.route;
      event.route = { id: route.id };
      event.params = result.params;
    }
  }
  try {
    page_nodes = route?.page ? new PageNodes(await load_page_nodes(route.page, manifest2)) : void 0;
    if (route && !remote_id) {
      if (url.pathname === base || url.pathname === base + "/") trailing_slash = "always";
      else if (page_nodes) trailing_slash = page_nodes.trailing_slash();
      else if (route.endpoint) trailing_slash = (await route.endpoint()).trailingSlash ?? "never";
      if (!is_data_request) {
        const normalized = normalize_path(url.pathname, trailing_slash);
        if (normalized !== url.pathname && !state2.prerendering?.fallback) return new Response(void 0, {
          status: 308,
          headers: {
            "x-sveltekit-normalize": "1",
            location: (normalized.startsWith("//") ? url.origin + normalized : normalized) + (url.search === "?" ? "" : url.search)
          }
        });
      }
      if (state2.before_handle || state2.emulator?.platform) {
        let config2 = {};
        let prerender = false;
        if (route.endpoint) {
          const node = await route.endpoint();
          config2 = node.config ?? config2;
          prerender = node.prerender ?? prerender;
        } else if (page_nodes) {
          config2 = page_nodes.get_config() ?? config2;
          prerender = page_nodes.prerender();
        }
        if (state2.emulator?.platform) event.platform = await state2.emulator.platform({
          config: config2,
          prerender
        });
        if (state2.before_handle) return await state2.before_handle(event, config2, prerender, handle2);
      }
    }
    return await handle2();
  } catch (e) {
    if (e instanceof Redirect) try {
      const response = is_data_request || remote_id ? redirect_json_response(e) : route?.page && is_action_json_request(event) ? action_json_redirect(e) : redirect_response(e.status, e.location);
      add_cookies_to_headers(response.headers, new_cookies.values());
      return response;
    } catch (err) {
      return await handle_fatal_error(event, event_state, options2, err);
    }
    return await handle_fatal_error(event, event_state, options2, e);
  }
  async function handle2() {
    set_trailing_slash(trailing_slash);
    if (state2.prerendering && !state2.prerendering.fallback && !state2.prerendering.inside_reroute) disable_search(url);
    const response = await record_span({
      name: "sveltekit.handle.root",
      attributes: {
        "http.route": event.route.id || "unknown",
        "http.method": event.request.method,
        "http.url": event.url.href,
        "sveltekit.is_data_request": is_data_request,
        "sveltekit.is_sub_request": event.isSubRequest
      },
      fn: async (root_span) => {
        const traced_event = {
          ...event,
          tracing: {
            enabled: false,
            root: root_span,
            current: root_span
          }
        };
        return await with_request_store({
          event: traced_event,
          state: event_state
        }, () => options2.hooks.handle({
          event: traced_event,
          resolve: (event2, opts) => {
            return record_span({
              name: "sveltekit.resolve",
              attributes: { "http.route": event2.route.id || "unknown" },
              fn: (resolve_span) => {
                return with_request_store(null, () => resolve6(merge_tracing(event2, resolve_span), page_nodes, opts).then((response2) => {
                  for (const key2 in headers2) {
                    const value2 = headers2[key2];
                    response2.headers.set(key2, value2);
                  }
                  add_cookies_to_headers(response2.headers, new_cookies.values());
                  if (state2.prerendering && event2.route.id !== null) response2.headers.set("x-sveltekit-routeid", encodeURI(event2.route.id));
                  resolve_span.setAttributes({
                    "http.response.status_code": response2.status,
                    "http.response.body.size": response2.headers.get("content-length") || "unknown"
                  });
                  return response2;
                }));
              }
            });
          }
        }));
      }
    });
    if (response.status === 200 && response.headers.has("etag")) {
      let if_none_match_value = request.headers.get("if-none-match");
      if (if_none_match_value?.startsWith('W/"')) if_none_match_value = if_none_match_value.substring(2);
      const etag2 = response.headers.get("etag");
      if (if_none_match_value === etag2) {
        const headers3 = new Headers({ etag: etag2 });
        for (const key2 of [
          "cache-control",
          "content-location",
          "date",
          "expires",
          "vary"
        ]) {
          const value2 = response.headers.get(key2);
          if (value2) headers3.set(key2, value2);
        }
        for (const cookie of get_set_cookies(response.headers)) headers3.append("set-cookie", cookie);
        return new Response(void 0, {
          status: 304,
          headers: headers3
        });
      }
    }
    if (is_data_request && response.status >= 300 && response.status <= 308) {
      const location = response.headers.get("location");
      if (location) return redirect_json_response(new Redirect(response.status, location));
    }
    return response;
  }
  async function resolve6(event2, page_nodes2, opts) {
    try {
      if (opts) resolve_opts = {
        transformPageChunk: opts.transformPageChunk || default_transform,
        filterSerializedResponseHeaders: opts.filterSerializedResponseHeaders || default_filter,
        preload: opts.preload || default_preload
      };
      if (resolved_path === null) return await respond_with_error({
        event: event2,
        event_state,
        options: options2,
        manifest: manifest2,
        state: state2,
        status: 400,
        error: new SvelteKitError(400, "Malformed URI", `Failed to decode URI: ${event2.url.pathname}`),
        resolve_opts
      });
      if (options2.hash_routing || state2.prerendering?.fallback) return await render_response({
        event: event2,
        event_state,
        options: options2,
        manifest: manifest2,
        state: state2,
        page_config: {
          ssr: false,
          csr: true
        },
        status: 200,
        error: null,
        branch: [{
          node: await manifest2._.nodes[0](),
          data: null,
          server_data: null
        }],
        fetched: [],
        resolve_opts,
        data_serializer: server_data_serializer(event2, event_state, options2)
      });
      if (remote_id) return await handle_remote_call(event2, event_state, options2, manifest2, remote_id);
      if (route) {
        const method = event2.request.method;
        let response2;
        if (is_data_request) response2 = await render_data(event2, event_state, route, options2, manifest2, state2, invalidated_data_nodes, trailing_slash);
        else if (route.endpoint && (!route.page || !state2.prerendering && is_endpoint_request(event2))) response2 = await render_endpoint(event2, event_state, await route.endpoint(), state2);
        else if (route.page) if (!page_nodes2) throw new Error("page_nodes not found. This should never happen");
        else if (page_methods.has(method)) response2 = await render_page(event2, event_state, route.page, options2, manifest2, state2, page_nodes2, resolve_opts);
        else {
          const allowed_methods2 = new Set(allowed_page_methods);
          if ((await manifest2._.nodes[route.page.leaf]())?.server?.actions) allowed_methods2.add("POST");
          if (method === "OPTIONS") response2 = new Response(null, {
            status: 204,
            headers: { allow: Array.from(allowed_methods2.values()).join(", ") }
          });
          else {
            const mod = [...allowed_methods2].reduce((acc, curr) => {
              acc[curr] = true;
              return acc;
            }, {});
            response2 = method_not_allowed(mod, method);
          }
        }
        else throw new Error("Route is neither page nor endpoint. This should never happen");
        if (request.method === "GET" && route.page && route.endpoint) {
          const vary = response2.headers.get("vary")?.split(",")?.map((v3) => v3.trim().toLowerCase());
          if (!(vary?.includes("accept") || vary?.includes("*"))) {
            response2 = new Response(response2.body, {
              status: response2.status,
              statusText: response2.statusText,
              headers: new Headers(response2.headers)
            });
            response2.headers.append("Vary", "Accept");
          }
        }
        return response2;
      }
      if (state2.error && event2.isSubRequest) {
        const headers3 = new Headers(request.headers);
        headers3.set("x-sveltekit-error", "true");
        return await fetch(request, { headers: headers3 });
      }
      if (state2.error) return text("Internal Server Error", { status: 500 });
      if (state2.depth === 0) return await respond_with_error({
        event: event2,
        event_state,
        options: options2,
        manifest: manifest2,
        state: state2,
        status: 404,
        error: new SvelteKitError(404, "Not Found", `Not found: ${event2.url.pathname}`),
        resolve_opts
      });
      if (state2.prerendering) return text("not found", { status: 404 });
      const response = await fetch(request);
      return new Response(response.body, response);
    } catch (e) {
      return await handle_fatal_error(event2, event_state, options2, e);
    } finally {
      event2.cookies.set = () => {
        throw new Error("Cannot use `cookies.set(...)` after the response has been generated");
      };
      event2.setHeaders = () => {
        throw new Error("Cannot use `setHeaders(...)` after the response has been generated");
      };
    }
  }
}
function load_page_nodes(page2, manifest2) {
  return Promise.all([...page2.layouts.map((n) => n == void 0 ? n : manifest2._.nodes[n]()), manifest2._.nodes[page2.leaf]()]);
}
function propagate_context(fn) {
  return async (req, ...rest) => {
    return fn(req, ...rest);
  };
}
function filter_env(env, allowed, disallowed) {
  return Object.fromEntries(Object.entries(env).filter(([k2]) => k2.startsWith(allowed) && (disallowed === "" || !k2.startsWith(disallowed))));
}
var init_promise;
var current = null;
var Server = class {
  /** @type {import('types').SSROptions} */
  #options;
  /** @type {import('@sveltejs/kit').SSRManifest} */
  #manifest;
  /** @param {import('@sveltejs/kit').SSRManifest} manifest */
  constructor(manifest2) {
    this.#options = options;
    this.#manifest = manifest2;
    if (IN_WEBCONTAINER2) {
      const respond2 = this.respond.bind(this);
      this.respond = async (...args) => {
        const { promise, resolve: resolve6 } = with_resolvers();
        const previous = current;
        current = promise;
        await previous;
        return respond2(...args).finally(resolve6);
      };
    }
    set_manifest(manifest2);
  }
  /**
  * @param {import('@sveltejs/kit').ServerInitOptions} opts
  */
  async init({ env, read }) {
    const { env_public_prefix, env_private_prefix } = this.#options;
    set_private_env(filter_env(env, env_private_prefix, env_public_prefix));
    set_public_env(filter_env(env, env_public_prefix, env_private_prefix));
    if (read) {
      const wrapped_read = (file) => {
        const result = read(file);
        if (result instanceof ReadableStream) return result;
        else return new ReadableStream({ async start(controller2) {
          try {
            const stream = await Promise.resolve(result);
            if (!stream) {
              controller2.close();
              return;
            }
            const reader = stream.getReader();
            while (true) {
              const { done, value: value2 } = await reader.read();
              if (done) break;
              controller2.enqueue(value2);
            }
            controller2.close();
          } catch (error2) {
            controller2.error(error2);
          }
        } });
      };
      set_read_implementation(wrapped_read);
    }
    await (init_promise ??= (async () => {
      try {
        const module = await get_hooks();
        this.#options.hooks = {
          handle: module.handle || (({ event, resolve: resolve6 }) => resolve6(event)),
          handleError: module.handleError || (({ status, error: error2, event }) => {
            const error_message = format_server_error(status, error2, event);
            console.error(error_message);
          }),
          handleFetch: module.handleFetch || (({ request, fetch: fetch3 }) => fetch3(request)),
          handleValidationError: module.handleValidationError || (({ issues }) => {
            console.error("Remote function schema validation failed:", issues);
            return { message: "Bad Request" };
          }),
          reroute: module.reroute || noop2,
          transport: module.transport || {}
        };
        module.transport && Object.fromEntries(Object.entries(module.transport).map(([k2, v3]) => [k2, v3.decode]));
        if (module.init) await module.init();
      } catch (e) {
        throw e;
      }
    })());
  }
  /**
  * @param {Request} request
  * @param {import('types').RequestOptions} options
  */
  async respond(request, options2) {
    return respond(request, this.#options, this.#manifest, {
      ...options2,
      error: false,
      depth: 0
    });
  }
};

// dist/build/server/manifest.js
var manifest = (() => {
  function __memo(fn) {
    let value2;
    return () => value2 ??= value2 = fn();
  }
  return {
    appDir: "_app",
    appPath: "_app",
    assets: /* @__PURE__ */ new Set(["fonts/DMSans-Latin.woff2", "fonts/GeistMono-Latin.woff2", "fonts/IBMPlexMono-Bold.woff2", "fonts/IBMPlexMono-Regular.woff2", "fonts/IBMPlexSans-Latin.woff2", "fonts/Inter-Latin.woff2", "fonts/JetBrainsMono-Bold.woff2", "fonts/JetBrainsMono-Regular.woff2"]),
    mimeTypes: { ".woff2": "font/woff2" },
    _: {
      client: { start: "_app/immutable/entry/start.D8gUFKrB.js", app: "_app/immutable/entry/app.qHd1dNwu.js", imports: ["_app/immutable/entry/start.D8gUFKrB.js", "_app/immutable/chunks/DP37y6wO.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/entry/app.qHd1dNwu.js", "_app/immutable/chunks/BA99CCI5.js", "_app/immutable/chunks/BJ4akexL.js", "_app/immutable/chunks/D7pSEO6W.js", "_app/immutable/chunks/3-kIKBFx.js", "_app/immutable/chunks/xihTtKlq.js"], stylesheets: [], fonts: [], uses_env_dynamic_public: false },
      nodes: [
        __memo(() => init__().then(() => __exports)),
        __memo(() => Promise.resolve().then(() => (init__2(), __exports2))),
        __memo(() => init__3().then(() => __exports3)),
        __memo(() => init__4().then(() => __exports4)),
        __memo(() => init__5().then(() => __exports5)),
        __memo(() => init__6().then(() => __exports6)),
        __memo(() => init__7().then(() => __exports7)),
        __memo(() => Promise.resolve().then(() => (init__8(), __exports8))),
        __memo(() => init__9().then(() => __exports9)),
        __memo(() => init__10().then(() => __exports10)),
        __memo(() => init__11().then(() => __exports11)),
        __memo(() => init__12().then(() => __exports12)),
        __memo(() => init__13().then(() => __exports13)),
        __memo(() => init__14().then(() => __exports14)),
        __memo(() => init__15().then(() => __exports15)),
        __memo(() => init__16().then(() => __exports16)),
        __memo(() => init__17().then(() => __exports17)),
        __memo(() => init__18().then(() => __exports18)),
        __memo(() => init__19().then(() => __exports19)),
        __memo(() => Promise.resolve().then(() => (init__20(), __exports20))),
        __memo(() => init__21().then(() => __exports21)),
        __memo(() => init__22().then(() => __exports22)),
        __memo(() => init__23().then(() => __exports23)),
        __memo(() => init__24().then(() => __exports24)),
        __memo(() => Promise.resolve().then(() => (init__25(), __exports25))),
        __memo(() => init__26().then(() => __exports26)),
        __memo(() => init__27().then(() => __exports27)),
        __memo(() => init__28().then(() => __exports28)),
        __memo(() => init__29().then(() => __exports29)),
        __memo(() => init__30().then(() => __exports30)),
        __memo(() => init__31().then(() => __exports31)),
        __memo(() => init__32().then(() => __exports32)),
        __memo(() => Promise.resolve().then(() => (init__33(), __exports33))),
        __memo(() => init__34().then(() => __exports34)),
        __memo(() => init__35().then(() => __exports35)),
        __memo(() => init__36().then(() => __exports36)),
        __memo(() => init__37().then(() => __exports37)),
        __memo(() => Promise.resolve().then(() => (init__38(), __exports38))),
        __memo(() => init__39().then(() => __exports39)),
        __memo(() => init__40().then(() => __exports40)),
        __memo(() => init__41().then(() => __exports41)),
        __memo(() => Promise.resolve().then(() => (init__42(), __exports42))),
        __memo(() => Promise.resolve().then(() => (init__43(), __exports43))),
        __memo(() => init__44().then(() => __exports44)),
        __memo(() => init__45().then(() => __exports45)),
        __memo(() => init__46().then(() => __exports46)),
        __memo(() => init__47().then(() => __exports47)),
        __memo(() => init__48().then(() => __exports48)),
        __memo(() => Promise.resolve().then(() => (init__49(), __exports49))),
        __memo(() => Promise.resolve().then(() => (init__50(), __exports50))),
        __memo(() => init__51().then(() => __exports51)),
        __memo(() => Promise.resolve().then(() => (init__52(), __exports52))),
        __memo(() => init__53().then(() => __exports53)),
        __memo(() => init__54().then(() => __exports54)),
        __memo(() => init__55().then(() => __exports55)),
        __memo(() => init__56().then(() => __exports56)),
        __memo(() => init__57().then(() => __exports57)),
        __memo(() => init__58().then(() => __exports58)),
        __memo(() => init__59().then(() => __exports59)),
        __memo(() => init__60().then(() => __exports60)),
        __memo(() => init__61().then(() => __exports61)),
        __memo(() => init__62().then(() => __exports62)),
        __memo(() => init__63().then(() => __exports63)),
        __memo(() => init__64().then(() => __exports64)),
        __memo(() => Promise.resolve().then(() => (init__65(), __exports65))),
        __memo(() => init__66().then(() => __exports66)),
        __memo(() => init__67().then(() => __exports67)),
        __memo(() => init__68().then(() => __exports68)),
        __memo(() => init__69().then(() => __exports69)),
        __memo(() => init__70().then(() => __exports70)),
        __memo(() => init__71().then(() => __exports71)),
        __memo(() => init__72().then(() => __exports72)),
        __memo(() => init__73().then(() => __exports73)),
        __memo(() => init__74().then(() => __exports74)),
        __memo(() => init__75().then(() => __exports75)),
        __memo(() => init__76().then(() => __exports76)),
        __memo(() => init__77().then(() => __exports77)),
        __memo(() => Promise.resolve().then(() => (init__78(), __exports78))),
        __memo(() => init__79().then(() => __exports79)),
        __memo(() => init__80().then(() => __exports80)),
        __memo(() => init__81().then(() => __exports81)),
        __memo(() => init__82().then(() => __exports82)),
        __memo(() => init__83().then(() => __exports83)),
        __memo(() => init__84().then(() => __exports84)),
        __memo(() => init__85().then(() => __exports85)),
        __memo(() => init__86().then(() => __exports86)),
        __memo(() => init__87().then(() => __exports87))
      ],
      remotes: {},
      routes: [
        {
          id: "/",
          pattern: /^\/$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 7 },
          endpoint: null
        },
        {
          id: "/announcements",
          pattern: /^\/announcements\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 8 },
          endpoint: null
        },
        {
          id: "/api/v1/announcements",
          pattern: /^\/api\/v1\/announcements\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts().then(() => server_ts_exports))
        },
        {
          id: "/api/v1/announcements/[id]",
          pattern: /^\/api\/v1\/announcements\/([^/]+?)\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts2().then(() => server_ts_exports2))
        },
        {
          id: "/api/v1/arr",
          pattern: /^\/api\/v1\/arr\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts3().then(() => server_ts_exports3))
        },
        {
          id: "/api/v1/backups",
          pattern: /^\/api\/v1\/backups\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts4().then(() => server_ts_exports4))
        },
        {
          id: "/api/v1/backups/settings",
          pattern: /^\/api\/v1\/backups\/settings\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts5().then(() => server_ts_exports5))
        },
        {
          id: "/api/v1/backups/upload",
          pattern: /^\/api\/v1\/backups\/upload\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => Promise.resolve().then(() => (init_server_ts6(), server_ts_exports6)))
        },
        {
          id: "/api/v1/backups/[filename]",
          pattern: /^\/api\/v1\/backups\/([^/]+?)\/?$/,
          params: [{ "name": "filename", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts7().then(() => server_ts_exports7))
        },
        {
          id: "/api/v1/databases",
          pattern: /^\/api\/v1\/databases\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts8().then(() => server_ts_exports8))
        },
        {
          id: "/api/v1/databases/[id]",
          pattern: /^\/api\/v1\/databases\/([^/]+?)\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts9().then(() => server_ts_exports9))
        },
        {
          id: "/api/v1/databases/[id]/sync",
          pattern: /^\/api\/v1\/databases\/([^/]+?)\/sync\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts10().then(() => server_ts_exports10))
        },
        {
          id: "/api/v1/health",
          pattern: /^\/api\/v1\/health\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts11().then(() => server_ts_exports11))
        },
        {
          id: "/api/v1/jobs/[id]",
          pattern: /^\/api\/v1\/jobs\/([^/]+?)\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts12().then(() => server_ts_exports12))
        },
        {
          id: "/api/v1/openapi.json",
          pattern: /^\/api\/v1\/openapi\.json\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => Promise.resolve().then(() => (init_server_ts13(), server_ts_exports13)))
        },
        {
          id: "/api/v1/status",
          pattern: /^\/api\/v1\/status\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts14().then(() => server_ts_exports14))
        },
        {
          id: "/arr",
          pattern: /^\/arr\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 9 },
          endpoint: null
        },
        {
          id: "/arr/new",
          pattern: /^\/arr\/new\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 18 },
          endpoint: null
        },
        {
          id: "/arr/upgrades/info",
          pattern: /^\/arr\/upgrades\/info\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 19 },
          endpoint: null
        },
        {
          id: "/arr/validate",
          pattern: /^\/arr\/validate\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts15().then(() => server_ts_exports15))
        },
        {
          id: "/arr/[id]",
          pattern: /^\/arr\/([^/]+?)\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 2], errors: [1, ,], leaf: 10 },
          endpoint: null
        },
        {
          id: "/arr/[id]/drift",
          pattern: /^\/arr\/([^/]+?)\/drift\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 2], errors: [1, ,], leaf: 11 },
          endpoint: null
        },
        {
          id: "/arr/[id]/library",
          pattern: /^\/arr\/([^/]+?)\/library\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 2], errors: [1, ,], leaf: 12 },
          endpoint: null
        },
        {
          id: "/arr/[id]/library/movies",
          pattern: /^\/arr\/([^/]+?)\/library\/movies\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts16().then(() => server_ts_exports16))
        },
        {
          id: "/arr/[id]/library/movies/[movieId]/releases",
          pattern: /^\/arr\/([^/]+?)\/library\/movies\/([^/]+?)\/releases\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }, { "name": "movieId", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts17().then(() => server_ts_exports17))
        },
        {
          id: "/arr/[id]/library/refresh",
          pattern: /^\/arr\/([^/]+?)\/library\/refresh\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts18().then(() => server_ts_exports18))
        },
        {
          id: "/arr/[id]/library/series",
          pattern: /^\/arr\/([^/]+?)\/library\/series\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts19().then(() => server_ts_exports19))
        },
        {
          id: "/arr/[id]/library/series/[seriesId]/seasons",
          pattern: /^\/arr\/([^/]+?)\/library\/series\/([^/]+?)\/seasons\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }, { "name": "seriesId", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts20().then(() => server_ts_exports20))
        },
        {
          id: "/arr/[id]/library/series/[seriesId]/seasons/[seasonNumber]/episodes",
          pattern: /^\/arr\/([^/]+?)\/library\/series\/([^/]+?)\/seasons\/([^/]+?)\/episodes\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }, { "name": "seriesId", "optional": false, "rest": false, "chained": false }, { "name": "seasonNumber", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts21().then(() => server_ts_exports21))
        },
        {
          id: "/arr/[id]/library/series/[seriesId]/seasons/[seasonNumber]/releases",
          pattern: /^\/arr\/([^/]+?)\/library\/series\/([^/]+?)\/seasons\/([^/]+?)\/releases\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }, { "name": "seriesId", "optional": false, "rest": false, "chained": false }, { "name": "seasonNumber", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts22().then(() => server_ts_exports22))
        },
        {
          id: "/arr/[id]/logs",
          pattern: /^\/arr\/([^/]+?)\/logs\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 2], errors: [1, ,], leaf: 13 },
          endpoint: __memo(() => init_server_ts23().then(() => server_ts_exports23))
        },
        {
          id: "/arr/[id]/rename",
          pattern: /^\/arr\/([^/]+?)\/rename\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 2], errors: [1, ,], leaf: 14 },
          endpoint: null
        },
        {
          id: "/arr/[id]/resync",
          pattern: /^\/arr\/([^/]+?)\/resync\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts24().then(() => server_ts_exports24))
        },
        {
          id: "/arr/[id]/settings",
          pattern: /^\/arr\/([^/]+?)\/settings\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 2], errors: [1, ,], leaf: 15 },
          endpoint: null
        },
        {
          id: "/arr/[id]/settings/cleanup/preview",
          pattern: /^\/arr\/([^/]+?)\/settings\/cleanup\/preview\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts25().then(() => server_ts_exports25))
        },
        {
          id: "/arr/[id]/sync",
          pattern: /^\/arr\/([^/]+?)\/sync\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 2], errors: [1, ,], leaf: 16 },
          endpoint: null
        },
        {
          id: "/arr/[id]/upgrades",
          pattern: /^\/arr\/([^/]+?)\/upgrades\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 2], errors: [1, ,], leaf: 17 },
          endpoint: null
        },
        {
          id: "/arr/[id]/upgrades/preview",
          pattern: /^\/arr\/([^/]+?)\/upgrades\/preview\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts26().then(() => server_ts_exports26))
        },
        {
          id: "/auth/login",
          pattern: /^\/auth\/login\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 20 },
          endpoint: null
        },
        {
          id: "/auth/logout",
          pattern: /^\/auth\/logout\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts27().then(() => server_ts_exports27))
        },
        {
          id: "/auth/oidc/callback",
          pattern: /^\/auth\/oidc\/callback\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts28().then(() => server_ts_exports28))
        },
        {
          id: "/auth/oidc/login",
          pattern: /^\/auth\/oidc\/login\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts29().then(() => server_ts_exports29))
        },
        {
          id: "/auth/setup",
          pattern: /^\/auth\/setup\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 21 },
          endpoint: null
        },
        {
          id: "/custom-formats",
          pattern: /^\/custom-formats\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 22 },
          endpoint: null
        },
        {
          id: "/custom-formats/[databaseId]",
          pattern: /^\/custom-formats\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 23 },
          endpoint: null
        },
        {
          id: "/custom-formats/[databaseId]/first/[tab]",
          pattern: /^\/custom-formats\/([^/]+?)\/first\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "tab", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts30().then(() => server_ts_exports30))
        },
        {
          id: "/custom-formats/[databaseId]/new",
          pattern: /^\/custom-formats\/([^/]+?)\/new\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 30 },
          endpoint: null
        },
        {
          id: "/custom-formats/[databaseId]/[id]",
          pattern: /^\/custom-formats\/([^/]+?)\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 3], errors: [1, ,], leaf: 24 },
          endpoint: null
        },
        {
          id: "/custom-formats/[databaseId]/[id]/conditions",
          pattern: /^\/custom-formats\/([^/]+?)\/([^/]+?)\/conditions\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 3], errors: [1, ,], leaf: 25 },
          endpoint: null
        },
        {
          id: "/custom-formats/[databaseId]/[id]/general",
          pattern: /^\/custom-formats\/([^/]+?)\/([^/]+?)\/general\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 3], errors: [1, ,], leaf: 26 },
          endpoint: null
        },
        {
          id: "/custom-formats/[databaseId]/[id]/testing",
          pattern: /^\/custom-formats\/([^/]+?)\/([^/]+?)\/testing\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 3], errors: [1, ,], leaf: 27 },
          endpoint: null
        },
        {
          id: "/custom-formats/[databaseId]/[id]/testing/new",
          pattern: /^\/custom-formats\/([^/]+?)\/([^/]+?)\/testing\/new\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 3], errors: [1, ,], leaf: 29 },
          endpoint: null
        },
        {
          id: "/custom-formats/[databaseId]/[id]/testing/[testId]",
          pattern: /^\/custom-formats\/([^/]+?)\/([^/]+?)\/testing\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "id", "optional": false, "rest": false, "chained": false }, { "name": "testId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 3], errors: [1, ,], leaf: 28 },
          endpoint: null
        },
        {
          id: "/databases",
          pattern: /^\/databases\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 31 },
          endpoint: null
        },
        {
          id: "/databases/avatar/[owner]",
          pattern: /^\/databases\/avatar\/([^/]+?)\/?$/,
          params: [{ "name": "owner", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts31().then(() => server_ts_exports31))
        },
        {
          id: "/databases/bruh",
          pattern: /^\/databases\/bruh\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 42 },
          endpoint: null
        },
        {
          id: "/databases/new",
          pattern: /^\/databases\/new\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 43 },
          endpoint: null
        },
        {
          id: "/databases/[id]",
          pattern: /^\/databases\/([^/]+?)\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 4], errors: [1, ,], leaf: 32 },
          endpoint: null
        },
        {
          id: "/databases/[id]/announcements",
          pattern: /^\/databases\/([^/]+?)\/announcements\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 4], errors: [1, ,], leaf: 33 },
          endpoint: null
        },
        {
          id: "/databases/[id]/announcements/new",
          pattern: /^\/databases\/([^/]+?)\/announcements\/new\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 4], errors: [1, ,], leaf: 35 },
          endpoint: null
        },
        {
          id: "/databases/[id]/announcements/[ulid]",
          pattern: /^\/databases\/([^/]+?)\/announcements\/([^/]+?)\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }, { "name": "ulid", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 4], errors: [1, ,], leaf: 34 },
          endpoint: null
        },
        {
          id: "/databases/[id]/changes",
          pattern: /^\/databases\/([^/]+?)\/changes\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 4], errors: [1, ,], leaf: 36 },
          endpoint: null
        },
        {
          id: "/databases/[id]/changes/data",
          pattern: /^\/databases\/([^/]+?)\/changes\/data\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts32().then(() => server_ts_exports32))
        },
        {
          id: "/databases/[id]/commits",
          pattern: /^\/databases\/([^/]+?)\/commits\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 4], errors: [1, ,], leaf: 37 },
          endpoint: null
        },
        {
          id: "/databases/[id]/commits/data",
          pattern: /^\/databases\/([^/]+?)\/commits\/data\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts33().then(() => server_ts_exports33))
        },
        {
          id: "/databases/[id]/config",
          pattern: /^\/databases\/([^/]+?)\/config\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 4], errors: [1, ,], leaf: 38 },
          endpoint: null
        },
        {
          id: "/databases/[id]/conflicts",
          pattern: /^\/databases\/([^/]+?)\/conflicts\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 4], errors: [1, ,], leaf: 39 },
          endpoint: null
        },
        {
          id: "/databases/[id]/export",
          pattern: /^\/databases\/([^/]+?)\/export\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts34().then(() => server_ts_exports34))
        },
        {
          id: "/databases/[id]/import",
          pattern: /^\/databases\/([^/]+?)\/import\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts35().then(() => server_ts_exports35))
        },
        {
          id: "/databases/[id]/settings",
          pattern: /^\/databases\/([^/]+?)\/settings\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 4], errors: [1, ,], leaf: 40 },
          endpoint: null
        },
        {
          id: "/databases/[id]/tweaks",
          pattern: /^\/databases\/([^/]+?)\/tweaks\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 4], errors: [1, ,], leaf: 41 },
          endpoint: null
        },
        {
          id: "/delay-profiles",
          pattern: /^\/delay-profiles\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 44 },
          endpoint: null
        },
        {
          id: "/delay-profiles/[databaseId]",
          pattern: /^\/delay-profiles\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 45 },
          endpoint: null
        },
        {
          id: "/delay-profiles/[databaseId]/first",
          pattern: /^\/delay-profiles\/([^/]+?)\/first\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts36().then(() => server_ts_exports36))
        },
        {
          id: "/delay-profiles/[databaseId]/new",
          pattern: /^\/delay-profiles\/([^/]+?)\/new\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 47 },
          endpoint: null
        },
        {
          id: "/delay-profiles/[databaseId]/[name]",
          pattern: /^\/delay-profiles\/([^/]+?)\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "name", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 46 },
          endpoint: null
        },
        {
          id: "/dev",
          pattern: /^\/dev\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 48 },
          endpoint: null
        },
        {
          id: "/dev/api",
          pattern: /^\/dev\/api\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => Promise.resolve().then(() => (init_server_ts37(), server_ts_exports37)))
        },
        {
          id: "/dev/components",
          pattern: /^\/dev\/components\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 49 },
          endpoint: null
        },
        {
          id: "/jobs/events",
          pattern: /^\/jobs\/events\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => Promise.resolve().then(() => (init_server_ts38(), server_ts_exports38)))
        },
        {
          id: "/media-management",
          pattern: /^\/media-management\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 50 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]",
          pattern: /^\/media-management\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 51 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/media-settings",
          pattern: /^\/media-management\/([^/]+?)\/media-settings\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 52 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/media-settings/first",
          pattern: /^\/media-management\/([^/]+?)\/media-settings\/first\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts39().then(() => server_ts_exports39))
        },
        {
          id: "/media-management/[databaseId]/media-settings/new",
          pattern: /^\/media-management\/([^/]+?)\/media-settings\/new\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 53 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/media-settings/radarr/[name]",
          pattern: /^\/media-management\/([^/]+?)\/media-settings\/radarr\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "name", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 54 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/media-settings/sonarr/[name]",
          pattern: /^\/media-management\/([^/]+?)\/media-settings\/sonarr\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "name", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 55 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/naming",
          pattern: /^\/media-management\/([^/]+?)\/naming\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 56 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/naming/first",
          pattern: /^\/media-management\/([^/]+?)\/naming\/first\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts40().then(() => server_ts_exports40))
        },
        {
          id: "/media-management/[databaseId]/naming/new",
          pattern: /^\/media-management\/([^/]+?)\/naming\/new\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 57 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/naming/radarr/[name]",
          pattern: /^\/media-management\/([^/]+?)\/naming\/radarr\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "name", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 58 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/naming/sonarr/[name]",
          pattern: /^\/media-management\/([^/]+?)\/naming\/sonarr\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "name", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 59 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/quality-definitions",
          pattern: /^\/media-management\/([^/]+?)\/quality-definitions\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 60 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/quality-definitions/first",
          pattern: /^\/media-management\/([^/]+?)\/quality-definitions\/first\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts41().then(() => server_ts_exports41))
        },
        {
          id: "/media-management/[databaseId]/quality-definitions/new",
          pattern: /^\/media-management\/([^/]+?)\/quality-definitions\/new\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 61 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/quality-definitions/radarr/[name]",
          pattern: /^\/media-management\/([^/]+?)\/quality-definitions\/radarr\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "name", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 62 },
          endpoint: null
        },
        {
          id: "/media-management/[databaseId]/quality-definitions/sonarr/[name]",
          pattern: /^\/media-management\/([^/]+?)\/quality-definitions\/sonarr\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "name", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 5], errors: [1, ,], leaf: 63 },
          endpoint: null
        },
        {
          id: "/onboarding",
          pattern: /^\/onboarding\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 64 },
          endpoint: null
        },
        {
          id: "/quality-profiles",
          pattern: /^\/quality-profiles\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 65 },
          endpoint: null
        },
        {
          id: "/quality-profiles/entity-testing",
          pattern: /^\/quality-profiles\/entity-testing\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 71 },
          endpoint: null
        },
        {
          id: "/quality-profiles/entity-testing/[databaseId]",
          pattern: /^\/quality-profiles\/entity-testing\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 72 },
          endpoint: null
        },
        {
          id: "/quality-profiles/entity-testing/[databaseId]/evaluate",
          pattern: /^\/quality-profiles\/entity-testing\/([^/]+?)\/evaluate\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts42().then(() => server_ts_exports42))
        },
        {
          id: "/quality-profiles/[databaseId]",
          pattern: /^\/quality-profiles\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 66 },
          endpoint: null
        },
        {
          id: "/quality-profiles/[databaseId]/first/[tab]",
          pattern: /^\/quality-profiles\/([^/]+?)\/first\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "tab", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts43().then(() => server_ts_exports43))
        },
        {
          id: "/quality-profiles/[databaseId]/new",
          pattern: /^\/quality-profiles\/([^/]+?)\/new\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 70 },
          endpoint: null
        },
        {
          id: "/quality-profiles/[databaseId]/[id]/general",
          pattern: /^\/quality-profiles\/([^/]+?)\/([^/]+?)\/general\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 6], errors: [1, ,], leaf: 67 },
          endpoint: null
        },
        {
          id: "/quality-profiles/[databaseId]/[id]/qualities",
          pattern: /^\/quality-profiles\/([^/]+?)\/([^/]+?)\/qualities\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 6], errors: [1, ,], leaf: 68 },
          endpoint: null
        },
        {
          id: "/quality-profiles/[databaseId]/[id]/scoring",
          pattern: /^\/quality-profiles\/([^/]+?)\/([^/]+?)\/scoring\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0, 6], errors: [1, ,], leaf: 69 },
          endpoint: null
        },
        {
          id: "/regular-expressions",
          pattern: /^\/regular-expressions\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 73 },
          endpoint: null
        },
        {
          id: "/regular-expressions/regex101/[...id]",
          pattern: /^\/regular-expressions\/regex101(?:\/([^]*))?\/?$/,
          params: [{ "name": "id", "optional": false, "rest": true, "chained": true }],
          page: null,
          endpoint: __memo(() => init_server_ts44().then(() => server_ts_exports44))
        },
        {
          id: "/regular-expressions/validate",
          pattern: /^\/regular-expressions\/validate\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts45().then(() => server_ts_exports45))
        },
        {
          id: "/regular-expressions/[databaseId]",
          pattern: /^\/regular-expressions\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 74 },
          endpoint: null
        },
        {
          id: "/regular-expressions/[databaseId]/first",
          pattern: /^\/regular-expressions\/([^/]+?)\/first\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: null,
          endpoint: __memo(() => init_server_ts46().then(() => server_ts_exports46))
        },
        {
          id: "/regular-expressions/[databaseId]/new",
          pattern: /^\/regular-expressions\/([^/]+?)\/new\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 76 },
          endpoint: null
        },
        {
          id: "/regular-expressions/[databaseId]/[id]",
          pattern: /^\/regular-expressions\/([^/]+?)\/([^/]+?)\/?$/,
          params: [{ "name": "databaseId", "optional": false, "rest": false, "chained": false }, { "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 75 },
          endpoint: null
        },
        {
          id: "/settings",
          pattern: /^\/settings\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 77 },
          endpoint: null
        },
        {
          id: "/settings/about",
          pattern: /^\/settings\/about\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 78 },
          endpoint: null
        },
        {
          id: "/settings/backups",
          pattern: /^\/settings\/backups\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 79 },
          endpoint: null
        },
        {
          id: "/settings/general",
          pattern: /^\/settings\/general\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 80 },
          endpoint: null
        },
        {
          id: "/settings/jobs",
          pattern: /^\/settings\/jobs\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 81 },
          endpoint: null
        },
        {
          id: "/settings/logs",
          pattern: /^\/settings\/logs\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 82 },
          endpoint: null
        },
        {
          id: "/settings/notifications",
          pattern: /^\/settings\/notifications\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 83 },
          endpoint: null
        },
        {
          id: "/settings/notifications/edit/[id]",
          pattern: /^\/settings\/notifications\/edit\/([^/]+?)\/?$/,
          params: [{ "name": "id", "optional": false, "rest": false, "chained": false }],
          page: { layouts: [0], errors: [1], leaf: 84 },
          endpoint: null
        },
        {
          id: "/settings/notifications/new",
          pattern: /^\/settings\/notifications\/new\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 85 },
          endpoint: null
        },
        {
          id: "/settings/security",
          pattern: /^\/settings\/security\/?$/,
          params: [],
          page: { layouts: [0], errors: [1], leaf: 86 },
          endpoint: null
        },
        {
          id: "/tmdb/search",
          pattern: /^\/tmdb\/search\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts47().then(() => server_ts_exports47))
        },
        {
          id: "/tmdb/validate",
          pattern: /^\/tmdb\/validate\/?$/,
          params: [],
          page: null,
          endpoint: __memo(() => init_server_ts48().then(() => server_ts_exports48))
        }
      ],
      prerendered_routes: /* @__PURE__ */ new Set([]),
      matchers: async () => {
        return {};
      },
      server_assets: {}
    }
  };
})();

// dist/build/server.js
var server = new Server(manifest);
var server_default = server;
export {
  server_default as default
};
/**
* @file
* @license @lucide/svelte v1.28.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
/*!
* cookie
* Copyright(c) 2012-2014 Roman Shtylman
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
