/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// node_modules/tslib/tslib.js
var require_tslib = __commonJS({
"node_modules/tslib/tslib.js"(exports, module2) {
var __extends2;
var __assign2;
var __rest2;
var __decorate2;
var __param2;
var __metadata2;
var __awaiter2;
var __generator2;
var __exportStar2;
var __values2;
var __read2;
var __spread2;
var __spreadArrays2;
var __spreadArray2;
var __await2;
var __asyncGenerator2;
var __asyncDelegator2;
var __asyncValues2;
var __makeTemplateObject2;
var __importStar2;
var __importDefault2;
var __classPrivateFieldGet7;
var __classPrivateFieldSet7;
var __classPrivateFieldIn2;
var __createBinding2;
(function(factory) {
var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {};
if (typeof define === "function" && define.amd) {
define("tslib", ["exports"], function(exports2) {
factory(createExporter(root, createExporter(exports2)));
});
} else if (typeof module2 === "object" && typeof module2.exports === "object") {
factory(createExporter(root, createExporter(module2.exports)));
} else {
factory(createExporter(root));
}
function createExporter(exports2, previous) {
if (exports2 !== root) {
if (typeof Object.create === "function") {
Object.defineProperty(exports2, "__esModule", { value: true });
} else {
exports2.__esModule = true;
}
}
return function(id, v) {
return exports2[id] = previous ? previous(id, v) : v;
};
}
})(function(exporter) {
var extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d, b) {
d.__proto__ = b;
} || function(d, b) {
for (var p in b)
if (Object.prototype.hasOwnProperty.call(b, p))
d[p] = b[p];
};
__extends2 = function(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
__assign2 = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
__rest2 = function(s, e) {
var t = {};
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
__decorate2 = function(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
r = Reflect.decorate(decorators, target, key, desc);
else
for (var i = decorators.length - 1; i >= 0; i--)
if (d = decorators[i])
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
__param2 = function(paramIndex, decorator) {
return function(target, key) {
decorator(target, key, paramIndex);
};
};
__metadata2 = function(metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
return Reflect.metadata(metadataKey, metadataValue);
};
__awaiter2 = function(thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function(resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function(resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
__generator2 = function(thisArg, body) {
var _ = { label: 0, sent: function() {
if (t[0] & 1)
throw t[1];
return t[1];
}, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() {
return this;
}), g;
function verb(n) {
return function(v) {
return step([n, v]);
};
}
function step(op) {
if (f)
throw new TypeError("Generator is already executing.");
while (_)
try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
return t;
if (y = 0, t)
op = [op[0] & 2, t.value];
switch (op[0]) {
case 0:
case 1:
t = op;
break;
case 4:
_.label++;
return { value: op[1], done: false };
case 5:
_.label++;
y = op[1];
op = [0];
continue;
case 7:
op = _.ops.pop();
_.trys.pop();
continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
_ = 0;
continue;
}
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
_.label = op[1];
break;
}
if (op[0] === 6 && _.label < t[1]) {
_.label = t[1];
t = op;
break;
}
if (t && _.label < t[2]) {
_.label = t[2];
_.ops.push(op);
break;
}
if (t[2])
_.ops.pop();
_.trys.pop();
continue;
}
op = body.call(thisArg, _);
} catch (e) {
op = [6, e];
y = 0;
} finally {
f = t = 0;
}
if (op[0] & 5)
throw op[1];
return { value: op[0] ? op[1] : void 0, done: true };
}
};
__exportStar2 = function(m, o) {
for (var p in m)
if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p))
__createBinding2(o, m, p);
};
__createBinding2 = Object.create ? function(o, m, k, k2) {
if (k2 === void 0)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() {
return m[k];
} };
}
Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
if (k2 === void 0)
k2 = k;
o[k2] = m[k];
};
__values2 = function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m)
return m.call(o);
if (o && typeof o.length === "number")
return {
next: function() {
if (o && i >= o.length)
o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
__read2 = function(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m)
return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
ar.push(r.value);
} catch (error) {
e = { error };
} finally {
try {
if (r && !r.done && (m = i["return"]))
m.call(i);
} finally {
if (e)
throw e.error;
}
}
return ar;
};
__spread2 = function() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read2(arguments[i]));
return ar;
};
__spreadArrays2 = function() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++)
s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
__spreadArray2 = function(to, from, pack) {
if (pack || arguments.length === 2)
for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar)
ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
__await2 = function(v) {
return this instanceof __await2 ? (this.v = v, this) : new __await2(v);
};
__asyncGenerator2 = function(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator)
throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
return this;
}, i;
function verb(n) {
if (g[n])
i[n] = function(v) {
return new Promise(function(a, b) {
q.push([n, v, a, b]) > 1 || resume(n, v);
});
};
}
function resume(n, v) {
try {
step(g[n](v));
} catch (e) {
settle(q[0][3], e);
}
}
function step(r) {
r.value instanceof __await2 ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);
}
function fulfill(value) {
resume("next", value);
}
function reject(value) {
resume("throw", value);
}
function settle(f, v) {
if (f(v), q.shift(), q.length)
resume(q[0][0], q[0][1]);
}
};
__asyncDelegator2 = function(o) {
var i, p;
return i = {}, verb("next"), verb("throw", function(e) {
throw e;
}), verb("return"), i[Symbol.iterator] = function() {
return this;
}, i;
function verb(n, f) {
i[n] = o[n] ? function(v) {
return (p = !p) ? { value: __await2(o[n](v)), done: n === "return" } : f ? f(v) : v;
} : f;
}
};
__asyncValues2 = function(o) {
if (!Symbol.asyncIterator)
throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values2 === "function" ? __values2(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() {
return this;
}, i);
function verb(n) {
i[n] = o[n] && function(v) {
return new Promise(function(resolve, reject) {
v = o[n](v), settle(resolve, reject, v.done, v.value);
});
};
}
function settle(resolve, reject, d, v) {
Promise.resolve(v).then(function(v2) {
resolve({ value: v2, done: d });
}, reject);
}
};
__makeTemplateObject2 = function(cooked, raw) {
if (Object.defineProperty) {
Object.defineProperty(cooked, "raw", { value: raw });
} else {
cooked.raw = raw;
}
return cooked;
};
var __setModuleDefault = Object.create ? function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
} : function(o, v) {
o["default"] = v;
};
__importStar2 = function(mod) {
if (mod && mod.__esModule)
return mod;
var result = {};
if (mod != null) {
for (var k in mod)
if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
__createBinding2(result, mod, k);
}
__setModuleDefault(result, mod);
return result;
};
__importDefault2 = function(mod) {
return mod && mod.__esModule ? mod : { "default": mod };
};
__classPrivateFieldGet7 = function(receiver, state, kind2, f) {
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
__classPrivateFieldSet7 = function(receiver, state, value, kind2, f) {
if (kind2 === "m")
throw new TypeError("Private method is not writable");
if (kind2 === "a" && !f)
throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot write private member to an object whose class did not declare it");
return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value;
};
__classPrivateFieldIn2 = function(state, receiver) {
if (receiver === null || typeof receiver !== "object" && typeof receiver !== "function")
throw new TypeError("Cannot use 'in' operator on non-object");
return typeof state === "function" ? receiver === state : state.has(receiver);
};
exporter("__extends", __extends2);
exporter("__assign", __assign2);
exporter("__rest", __rest2);
exporter("__decorate", __decorate2);
exporter("__param", __param2);
exporter("__metadata", __metadata2);
exporter("__awaiter", __awaiter2);
exporter("__generator", __generator2);
exporter("__exportStar", __exportStar2);
exporter("__createBinding", __createBinding2);
exporter("__values", __values2);
exporter("__read", __read2);
exporter("__spread", __spread2);
exporter("__spreadArrays", __spreadArrays2);
exporter("__spreadArray", __spreadArray2);
exporter("__await", __await2);
exporter("__asyncGenerator", __asyncGenerator2);
exporter("__asyncDelegator", __asyncDelegator2);
exporter("__asyncValues", __asyncValues2);
exporter("__makeTemplateObject", __makeTemplateObject2);
exporter("__importStar", __importStar2);
exporter("__importDefault", __importDefault2);
exporter("__classPrivateFieldGet", __classPrivateFieldGet7);
exporter("__classPrivateFieldSet", __classPrivateFieldSet7);
exporter("__classPrivateFieldIn", __classPrivateFieldIn2);
});
}
});
// src/main.ts
var main_exports = {};
__export(main_exports, {
default: () => PodNotes
});
module.exports = __toCommonJS(main_exports);
// node_modules/svelte/internal/index.mjs
function noop() {
}
var identity = (x) => x;
function assign(tar, src) {
for (const k in src)
tar[k] = src[k];
return tar;
}
function is_promise(value) {
return value && typeof value === "object" && typeof value.then === "function";
}
function run(fn) {
return fn();
}
function blank_object() {
return /* @__PURE__ */ Object.create(null);
}
function run_all(fns) {
fns.forEach(run);
}
function is_function(thing) {
return typeof thing === "function";
}
function safe_not_equal(a, b) {
return a != a ? b == b : a !== b || (a && typeof a === "object" || typeof a === "function");
}
var src_url_equal_anchor;
function src_url_equal(element_src, url) {
if (!src_url_equal_anchor) {
src_url_equal_anchor = document.createElement("a");
}
src_url_equal_anchor.href = url;
return element_src === src_url_equal_anchor.href;
}
function is_empty(obj) {
return Object.keys(obj).length === 0;
}
function subscribe(store, ...callbacks) {
if (store == null) {
return noop;
}
const unsub = store.subscribe(...callbacks);
return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
}
function get_store_value(store) {
let value;
subscribe(store, (_) => value = _)();
return value;
}
function component_subscribe(component, store, callback) {
component.$$.on_destroy.push(subscribe(store, callback));
}
function create_slot(definition, ctx, $$scope, fn) {
if (definition) {
const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);
return definition[0](slot_ctx);
}
}
function get_slot_context(definition, ctx, $$scope, fn) {
return definition[1] && fn ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) : $$scope.ctx;
}
function get_slot_changes(definition, $$scope, dirty, fn) {
if (definition[2] && fn) {
const lets = definition[2](fn(dirty));
if ($$scope.dirty === void 0) {
return lets;
}
if (typeof lets === "object") {
const merged = [];
const len = Math.max($$scope.dirty.length, lets.length);
for (let i = 0; i < len; i += 1) {
merged[i] = $$scope.dirty[i] | lets[i];
}
return merged;
}
return $$scope.dirty | lets;
}
return $$scope.dirty;
}
function update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn) {
if (slot_changes) {
const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);
slot.p(slot_context, slot_changes);
}
}
function get_all_dirty_from_scope($$scope) {
if ($$scope.ctx.length > 32) {
const dirty = [];
const length = $$scope.ctx.length / 32;
for (let i = 0; i < length; i++) {
dirty[i] = -1;
}
return dirty;
}
return -1;
}
function null_to_empty(value) {
return value == null ? "" : value;
}
var is_client = typeof window !== "undefined";
var now = is_client ? () => window.performance.now() : () => Date.now();
var raf = is_client ? (cb) => requestAnimationFrame(cb) : noop;
var tasks = /* @__PURE__ */ new Set();
function run_tasks(now2) {
tasks.forEach((task) => {
if (!task.c(now2)) {
tasks.delete(task);
task.f();
}
});
if (tasks.size !== 0)
raf(run_tasks);
}
function loop(callback) {
let task;
if (tasks.size === 0)
raf(run_tasks);
return {
promise: new Promise((fulfill) => {
tasks.add(task = { c: callback, f: fulfill });
}),
abort() {
tasks.delete(task);
}
};
}
var is_hydrating = false;
function start_hydrating() {
is_hydrating = true;
}
function end_hydrating() {
is_hydrating = false;
}
function append(target, node) {
target.appendChild(node);
}
function append_styles(target, style_sheet_id, styles) {
const append_styles_to = get_root_for_style(target);
if (!append_styles_to.getElementById(style_sheet_id)) {
const style = element("style");
style.id = style_sheet_id;
style.textContent = styles;
append_stylesheet(append_styles_to, style);
}
}
function get_root_for_style(node) {
if (!node)
return document;
const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
if (root && root.host) {
return root;
}
return node.ownerDocument;
}
function append_empty_stylesheet(node) {
const style_element = element("style");
append_stylesheet(get_root_for_style(node), style_element);
return style_element.sheet;
}
function append_stylesheet(node, style) {
append(node.head || node, style);
}
function insert(target, node, anchor) {
target.insertBefore(node, anchor || null);
}
function detach(node) {
node.parentNode.removeChild(node);
}
function destroy_each(iterations, detaching) {
for (let i = 0; i < iterations.length; i += 1) {
if (iterations[i])
iterations[i].d(detaching);
}
}
function element(name) {
return document.createElement(name);
}
function text(data) {
return document.createTextNode(data);
}
function space() {
return text(" ");
}
function empty() {
return text("");
}
function listen(node, event, handler, options) {
node.addEventListener(event, handler, options);
return () => node.removeEventListener(event, handler, options);
}
function prevent_default(fn) {
return function(event) {
event.preventDefault();
return fn.call(this, event);
};
}
function attr(node, attribute, value) {
if (value == null)
node.removeAttribute(attribute);
else if (node.getAttribute(attribute) !== value)
node.setAttribute(attribute, value);
}
function children(element2) {
return Array.from(element2.childNodes);
}
function set_data(text2, data) {
data = "" + data;
if (text2.wholeText !== data)
text2.data = data;
}
function set_style(node, key, value, important) {
if (value === null) {
node.style.removeProperty(key);
} else {
node.style.setProperty(key, value, important ? "important" : "");
}
}
function custom_event(type, detail, { bubbles = false, cancelable = false } = {}) {
const e = document.createEvent("CustomEvent");
e.initCustomEvent(type, bubbles, cancelable, detail);
return e;
}
var managed_styles = /* @__PURE__ */ new Map();
var active = 0;
function hash(str2) {
let hash2 = 5381;
let i = str2.length;
while (i--)
hash2 = (hash2 << 5) - hash2 ^ str2.charCodeAt(i);
return hash2 >>> 0;
}
function create_style_information(doc, node) {
const info = { stylesheet: append_empty_stylesheet(node), rules: {} };
managed_styles.set(doc, info);
return info;
}
function create_rule(node, a, b, duration2, delay, ease, fn, uid = 0) {
const step = 16.666 / duration2;
let keyframes = "{\n";
for (let p = 0; p <= 1; p += step) {
const t = a + (b - a) * ease(p);
keyframes += p * 100 + `%{${fn(t, 1 - t)}}
`;
}
const rule = keyframes + `100% {${fn(b, 1 - b)}}
}`;
const name = `__svelte_${hash(rule)}_${uid}`;
const doc = get_root_for_style(node);
const { stylesheet, rules } = managed_styles.get(doc) || create_style_information(doc, node);
if (!rules[name]) {
rules[name] = true;
stylesheet.insertRule(`@keyframes ${name} ${rule}`, stylesheet.cssRules.length);
}
const animation = node.style.animation || "";
node.style.animation = `${animation ? `${animation}, ` : ""}${name} ${duration2}ms linear ${delay}ms 1 both`;
active += 1;
return name;
}
function delete_rule(node, name) {
const previous = (node.style.animation || "").split(", ");
const next = previous.filter(name ? (anim) => anim.indexOf(name) < 0 : (anim) => anim.indexOf("__svelte") === -1);
const deleted = previous.length - next.length;
if (deleted) {
node.style.animation = next.join(", ");
active -= deleted;
if (!active)
clear_rules();
}
}
function clear_rules() {
raf(() => {
if (active)
return;
managed_styles.forEach((info) => {
const { stylesheet } = info;
let i = stylesheet.cssRules.length;
while (i--)
stylesheet.deleteRule(i);
info.rules = {};
});
managed_styles.clear();
});
}
var current_component;
function set_current_component(component) {
current_component = component;
}
function get_current_component() {
if (!current_component)
throw new Error("Function called outside component initialization");
return current_component;
}
function onMount(fn) {
get_current_component().$$.on_mount.push(fn);
}
function afterUpdate(fn) {
get_current_component().$$.after_update.push(fn);
}
function onDestroy(fn) {
get_current_component().$$.on_destroy.push(fn);
}
function createEventDispatcher() {
const component = get_current_component();
return (type, detail, { cancelable = false } = {}) => {
const callbacks = component.$$.callbacks[type];
if (callbacks) {
const event = custom_event(type, detail, { cancelable });
callbacks.slice().forEach((fn) => {
fn.call(component, event);
});
return !event.defaultPrevented;
}
return true;
};
}
function bubble(component, event) {
const callbacks = component.$$.callbacks[event.type];
if (callbacks) {
callbacks.slice().forEach((fn) => fn.call(this, event));
}
}
var dirty_components = [];
var binding_callbacks = [];
var render_callbacks = [];
var flush_callbacks = [];
var resolved_promise = Promise.resolve();
var update_scheduled = false;
function schedule_update() {
if (!update_scheduled) {
update_scheduled = true;
resolved_promise.then(flush);
}
}
function add_render_callback(fn) {
render_callbacks.push(fn);
}
function add_flush_callback(fn) {
flush_callbacks.push(fn);
}
var seen_callbacks = /* @__PURE__ */ new Set();
var flushidx = 0;
function flush() {
const saved_component = current_component;
do {
while (flushidx < dirty_components.length) {
const component = dirty_components[flushidx];
flushidx++;
set_current_component(component);
update(component.$$);
}
set_current_component(null);
dirty_components.length = 0;
flushidx = 0;
while (binding_callbacks.length)
binding_callbacks.pop()();
for (let i = 0; i < render_callbacks.length; i += 1) {
const callback = render_callbacks[i];
if (!seen_callbacks.has(callback)) {
seen_callbacks.add(callback);
callback();
}
}
render_callbacks.length = 0;
} while (dirty_components.length);
while (flush_callbacks.length) {
flush_callbacks.pop()();
}
update_scheduled = false;
seen_callbacks.clear();
set_current_component(saved_component);
}
function update($$) {
if ($$.fragment !== null) {
$$.update();
run_all($$.before_update);
const dirty = $$.dirty;
$$.dirty = [-1];
$$.fragment && $$.fragment.p($$.ctx, dirty);
$$.after_update.forEach(add_render_callback);
}
}
var promise;
function wait() {
if (!promise) {
promise = Promise.resolve();
promise.then(() => {
promise = null;
});
}
return promise;
}
function dispatch(node, direction, kind2) {
node.dispatchEvent(custom_event(`${direction ? "intro" : "outro"}${kind2}`));
}
var outroing = /* @__PURE__ */ new Set();
var outros;
function group_outros() {
outros = {
r: 0,
c: [],
p: outros
};
}
function check_outros() {
if (!outros.r) {
run_all(outros.c);
}
outros = outros.p;
}
function transition_in(block, local) {
if (block && block.i) {
outroing.delete(block);
block.i(local);
}
}
function transition_out(block, local, detach2, callback) {
if (block && block.o) {
if (outroing.has(block))
return;
outroing.add(block);
outros.c.push(() => {
outroing.delete(block);
if (callback) {
if (detach2)
block.d(1);
callback();
}
});
block.o(local);
} else if (callback) {
callback();
}
}
var null_transition = { duration: 0 };
function create_bidirectional_transition(node, fn, params, intro) {
let config = fn(node, params);
let t = intro ? 0 : 1;
let running_program = null;
let pending_program = null;
let animation_name = null;
function clear_animation() {
if (animation_name)
delete_rule(node, animation_name);
}
function init2(program, duration2) {
const d = program.b - t;
duration2 *= Math.abs(d);
return {
a: t,
b: program.b,
d,
duration: duration2,
start: program.start,
end: program.start + duration2,
group: program.group
};
}
function go(b) {
const { delay = 0, duration: duration2 = 300, easing = identity, tick: tick2 = noop, css } = config || null_transition;
const program = {
start: now() + delay,
b
};
if (!b) {
program.group = outros;
outros.r += 1;
}
if (running_program || pending_program) {
pending_program = program;
} else {
if (css) {
clear_animation();
animation_name = create_rule(node, t, b, duration2, delay, easing, css);
}
if (b)
tick2(0, 1);
running_program = init2(program, duration2);
add_render_callback(() => dispatch(node, b, "start"));
loop((now2) => {
if (pending_program && now2 > pending_program.start) {
running_program = init2(pending_program, duration2);
pending_program = null;
dispatch(node, running_program.b, "start");
if (css) {
clear_animation();
animation_name = create_rule(node, t, running_program.b, running_program.duration, 0, easing, config.css);
}
}
if (running_program) {
if (now2 >= running_program.end) {
tick2(t = running_program.b, 1 - t);
dispatch(node, running_program.b, "end");
if (!pending_program) {
if (running_program.b) {
clear_animation();
} else {
if (!--running_program.group.r)
run_all(running_program.group.c);
}
}
running_program = null;
} else if (now2 >= running_program.start) {
const p = now2 - running_program.start;
t = running_program.a + running_program.d * easing(p / running_program.duration);
tick2(t, 1 - t);
}
}
return !!(running_program || pending_program);
});
}
}
return {
run(b) {
if (is_function(config)) {
wait().then(() => {
config = config();
go(b);
});
} else {
go(b);
}
},
end() {
clear_animation();
running_program = pending_program = null;
}
};
}
function handle_promise(promise2, info) {
const token = info.token = {};
function update2(type, index, key, value) {
if (info.token !== token)
return;
info.resolved = value;
let child_ctx = info.ctx;
if (key !== void 0) {
child_ctx = child_ctx.slice();
child_ctx[key] = value;
}
const block = type && (info.current = type)(child_ctx);
let needs_flush = false;
if (info.block) {
if (info.blocks) {
info.blocks.forEach((block2, i) => {
if (i !== index && block2) {
group_outros();
transition_out(block2, 1, 1, () => {
if (info.blocks[i] === block2) {
info.blocks[i] = null;
}
});
check_outros();
}
});
} else {
info.block.d(1);
}
block.c();
transition_in(block, 1);
block.m(info.mount(), info.anchor);
needs_flush = true;
}
info.block = block;
if (info.blocks)
info.blocks[index] = block;
if (needs_flush) {
flush();
}
}
if (is_promise(promise2)) {
const current_component2 = get_current_component();
promise2.then((value) => {
set_current_component(current_component2);
update2(info.then, 1, info.value, value);
set_current_component(null);
}, (error) => {
set_current_component(current_component2);
update2(info.catch, 2, info.error, error);
set_current_component(null);
if (!info.hasCatch) {
throw error;
}
});
if (info.current !== info.pending) {
update2(info.pending, 0);
return true;
}
} else {
if (info.current !== info.then) {
update2(info.then, 1, info.value, promise2);
return true;
}
info.resolved = promise2;
}
}
function update_await_block_branch(info, ctx, dirty) {
const child_ctx = ctx.slice();
const { resolved } = info;
if (info.current === info.then) {
child_ctx[info.value] = resolved;
}
if (info.current === info.catch) {
child_ctx[info.error] = resolved;
}
info.block.p(child_ctx, dirty);
}
var globals = typeof window !== "undefined" ? window : typeof globalThis !== "undefined" ? globalThis : global;
function outro_and_destroy_block(block, lookup) {
transition_out(block, 1, 1, () => {
lookup.delete(block.key);
});
}
function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block5, next, get_context) {
let o = old_blocks.length;
let n = list.length;
let i = o;
const old_indexes = {};
while (i--)
old_indexes[old_blocks[i].key] = i;
const new_blocks = [];
const new_lookup = /* @__PURE__ */ new Map();
const deltas = /* @__PURE__ */ new Map();
i = n;
while (i--) {
const child_ctx = get_context(ctx, list, i);
const key = get_key(child_ctx);
let block = lookup.get(key);
if (!block) {
block = create_each_block5(key, child_ctx);
block.c();
} else if (dynamic) {
block.p(child_ctx, dirty);
}
new_lookup.set(key, new_blocks[i] = block);
if (key in old_indexes)
deltas.set(key, Math.abs(i - old_indexes[key]));
}
const will_move = /* @__PURE__ */ new Set();
const did_move = /* @__PURE__ */ new Set();
function insert2(block) {
transition_in(block, 1);
block.m(node, next);
lookup.set(block.key, block);
next = block.first;
n--;
}
while (o && n) {
const new_block = new_blocks[n - 1];
const old_block = old_blocks[o - 1];
const new_key = new_block.key;
const old_key = old_block.key;
if (new_block === old_block) {
next = new_block.first;
o--;
n--;
} else if (!new_lookup.has(old_key)) {
destroy(old_block, lookup);
o--;
} else if (!lookup.has(new_key) || will_move.has(new_key)) {
insert2(new_block);
} else if (did_move.has(old_key)) {
o--;
} else if (deltas.get(new_key) > deltas.get(old_key)) {
did_move.add(new_key);
insert2(new_block);
} else {
will_move.add(old_key);
o--;
}
}
while (o--) {
const old_block = old_blocks[o];
if (!new_lookup.has(old_block.key))
destroy(old_block, lookup);
}
while (n)
insert2(new_blocks[n - 1]);
return new_blocks;
}
function bind(component, name, callback) {
const index = component.$$.props[name];
if (index !== void 0) {
component.$$.bound[index] = callback;
callback(component.$$.ctx[index]);
}
}
function create_component(block) {
block && block.c();
}
function mount_component(component, target, anchor, customElement) {
const { fragment, on_mount, on_destroy, after_update } = component.$$;
fragment && fragment.m(target, anchor);
if (!customElement) {
add_render_callback(() => {
const new_on_destroy = on_mount.map(run).filter(is_function);
if (on_destroy) {
on_destroy.push(...new_on_destroy);
} else {
run_all(new_on_destroy);
}
component.$$.on_mount = [];
});
}
after_update.forEach(add_render_callback);
}
function destroy_component(component, detaching) {
const $$ = component.$$;
if ($$.fragment !== null) {
run_all($$.on_destroy);
$$.fragment && $$.fragment.d(detaching);
$$.on_destroy = $$.fragment = null;
$$.ctx = [];
}
}
function make_dirty(component, i) {
if (component.$$.dirty[0] === -1) {
dirty_components.push(component);
schedule_update();
component.$$.dirty.fill(0);
}
component.$$.dirty[i / 31 | 0] |= 1 << i % 31;
}
function init(component, options, instance23, create_fragment24, not_equal, props, append_styles2, dirty = [-1]) {
const parent_component = current_component;
set_current_component(component);
const $$ = component.$$ = {
fragment: null,
ctx: null,
props,
update: noop,
not_equal,
bound: blank_object(),
on_mount: [],
on_destroy: [],
on_disconnect: [],
before_update: [],
after_update: [],
context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),
callbacks: blank_object(),
dirty,
skip_bound: false,
root: options.target || parent_component.$$.root
};
append_styles2 && append_styles2($$.root);
let ready = false;
$$.ctx = instance23 ? instance23(component, options.props || {}, (i, ret, ...rest) => {
const value = rest.length ? rest[0] : ret;
if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
if (!$$.skip_bound && $$.bound[i])
$$.bound[i](value);
if (ready)
make_dirty(component, i);
}
return ret;
}) : [];
$$.update();
ready = true;
run_all($$.before_update);
$$.fragment = create_fragment24 ? create_fragment24($$.ctx) : false;
if (options.target) {
if (options.hydrate) {
start_hydrating();
const nodes = children(options.target);
$$.fragment && $$.fragment.l(nodes);
nodes.forEach(detach);
} else {
$$.fragment && $$.fragment.c();
}
if (options.intro)
transition_in(component.$$.fragment);
mount_component(component, options.target, options.anchor, options.customElement);
end_hydrating();
flush();
}
set_current_component(parent_component);
}
var SvelteElement;
if (typeof HTMLElement === "function") {
SvelteElement = class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
}
connectedCallback() {
const { on_mount } = this.$$;
this.$$.on_disconnect = on_mount.map(run).filter(is_function);
for (const key in this.$$.slotted) {
this.appendChild(this.$$.slotted[key]);
}
}
attributeChangedCallback(attr2, _oldValue, newValue) {
this[attr2] = newValue;
}
disconnectedCallback() {
run_all(this.$$.on_disconnect);
}
$destroy() {
destroy_component(this, 1);
this.$destroy = noop;
}
$on(type, callback) {
const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []);
callbacks.push(callback);
return () => {
const index = callbacks.indexOf(callback);
if (index !== -1)
callbacks.splice(index, 1);
};
}
$set($$props) {
if (this.$$set && !is_empty($$props)) {
this.$$.skip_bound = true;
this.$$set($$props);
this.$$.skip_bound = false;
}
}
};
}
var SvelteComponent = class {
$destroy() {
destroy_component(this, 1);
this.$destroy = noop;
}
$on(type, callback) {
const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []);
callbacks.push(callback);
return () => {
const index = callbacks.indexOf(callback);
if (index !== -1)
callbacks.splice(index, 1);
};
}
$set($$props) {
if (this.$$set && !is_empty($$props)) {
this.$$.skip_bound = true;
this.$$set($$props);
this.$$.skip_bound = false;
}
}
};
// node_modules/svelte/store/index.mjs
var subscriber_queue = [];
function writable(value, start = noop) {
let stop;
const subscribers = /* @__PURE__ */ new Set();
function set(new_value) {
if (safe_not_equal(value, new_value)) {
value = new_value;
if (stop) {
const run_queue = !subscriber_queue.length;
for (const subscriber of subscribers) {
subscriber[1]();
subscriber_queue.push(subscriber, value);
}
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 update2(fn) {
set(fn(value));
}
function subscribe2(run2, invalidate = noop) {
const subscriber = [run2, invalidate];
subscribers.add(subscriber);
if (subscribers.size === 1) {
stop = start(set) || noop;
}
run2(value);
return () => {
subscribers.delete(subscriber);
if (subscribers.size === 0) {
stop();
stop = null;
}
};
}
return { set, update: update2, subscribe: subscribe2 };
}
// src/store/index.ts
var import_obsidian = require("obsidian");
var plugin = writable();
var currentTime = writable(0);
var duration = writable(0);
var currentEpisode = (() => {
const store = writable();
const { subscribe: subscribe2, update: update2 } = store;
return {
subscribe: subscribe2,
update: update2,
set: (newEpisode, addPrevToQueue = true) => {
update2((previousEpisode) => {
if (previousEpisode) {
if (addPrevToQueue) {
addEpisodeToQueue(previousEpisode);
}
const ct = get_store_value(currentTime);
const dur = get_store_value(duration);
const isFinished = ct === dur;
playedEpisodes.setEpisodeTime(previousEpisode, ct, dur, isFinished);
}
return newEpisode;
});
}
};
})();
var isPaused = writable(true);
var playedEpisodes = (() => {
const store = writable({});
const { subscribe: subscribe2, update: update2, set } = store;
return {
subscribe: subscribe2,
set,
update: update2,
setEpisodeTime: (episode, time, duration2, finished) => {
update2((playedEpisodes2) => {
playedEpisodes2[episode.title] = {
title: episode.title,
podcastName: episode.podcastName,
time,
duration: duration2,
finished
};
return playedEpisodes2;
});
},
markAsPlayed: (episode) => {
update2((playedEpisodes2) => {
const playedEpisode = playedEpisodes2[episode.title] || episode;
if (playedEpisode) {
playedEpisode.time = playedEpisode.duration;
playedEpisode.finished = true;
}
playedEpisodes2[episode.title] = playedEpisode;
return playedEpisodes2;
});
},
markAsUnplayed: (episode) => {
update2((playedEpisodes2) => {
const playedEpisode = playedEpisodes2[episode.title] || episode;
if (playedEpisode) {
playedEpisode.time = 0;
playedEpisode.finished = false;
}
playedEpisodes2[episode.title] = playedEpisode;
return playedEpisodes2;
});
}
};
})();
var podcastsUpdated = writable(0);
var savedFeeds = writable({});
var episodeCache = writable({});
var downloadedEpisodes = (() => {
const store = writable({});
const { subscribe: subscribe2, update: update2, set } = store;
function isEpisodeDownloaded(episode) {
return get_store_value(store)[episode.podcastName]?.some((e) => e.title === episode.title);
}
return {
subscribe: subscribe2,
set,
update: update2,
isEpisodeDownloaded,
addEpisode: (episode, filePath, size) => {
update2((downloadedEpisodes2) => {
const podcastEpisodes = downloadedEpisodes2[episode.podcastName] || [];
const idx = podcastEpisodes.findIndex((ep) => ep.title === episode.title);
if (idx !== -1) {
podcastEpisodes[idx] = { ...episode, filePath, size };
} else {
podcastEpisodes.push({
...episode,
filePath,
size
});
}
downloadedEpisodes2[episode.podcastName] = podcastEpisodes;
return downloadedEpisodes2;
});
},
removeEpisode: (episode, removeFile) => {
update2((downloadedEpisodes2) => {
const podcastEpisodes = downloadedEpisodes2[episode.podcastName] || [];
const index = podcastEpisodes.findIndex((e) => e.title === episode.title);
const filePath = podcastEpisodes[index].filePath;
podcastEpisodes.splice(index, 1);
if (removeFile) {
try {
const file = app.vault.getAbstractFileByPath(filePath);
if (file instanceof import_obsidian.TFile) {
app.vault.delete(file);
}
} catch (error) {
console.error(error);
}
}
downloadedEpisodes2[episode.podcastName] = podcastEpisodes;
return downloadedEpisodes2;
});
},
getEpisode: (episode) => {
return get_store_value(store)[episode.podcastName]?.find((e) => e.title === episode.title);
}
};
})();
var queue = (() => {
const store = writable({
icon: "list-ordered",
name: "Queue",
episodes: [],
shouldEpisodeRemoveAfterPlay: true,
shouldRepeat: false
});
const { subscribe: subscribe2, update: update2, set } = store;
return {
subscribe: subscribe2,
update: update2,
set,
add: (episode) => {
update2((queue2) => {
queue2.episodes.push(episode);
return queue2;
});
},
remove: (episode) => {
update2((queue2) => {
queue2.episodes = queue2.episodes.filter((e) => e.title !== episode.title);
return queue2;
});
},
playNext: () => {
update2((queue2) => {
const nextEp = queue2.episodes.shift();
if (nextEp) {
currentEpisode.set(nextEp, false);
}
return queue2;
});
}
};
})();
var favorites = writable({
icon: "lucide-star",
name: "Favorites",
episodes: [],
shouldEpisodeRemoveAfterPlay: false,
shouldRepeat: false
});
var localFiles = (() => {
const store = writable({
icon: "folder",
name: "Local Files",
episodes: [],
shouldEpisodeRemoveAfterPlay: false,
shouldRepeat: false
});
const { subscribe: subscribe2, update: update2, set } = store;
return {
subscribe: subscribe2,
update: update2,
set,
getLocalEpisode: (title) => {
const ep = get_store_value(store).episodes.find((ep2) => ep2.title === title);
return ep;
},
updateStreamUrl: (title, newUrl) => {
store.update((playlist) => {
const idx = playlist.episodes.findIndex((ep) => ep.title === title);
if (idx !== -1)
playlist.episodes[idx].streamUrl = newUrl;
return playlist;
});
},
addEpisode: (episode) => {
store.update((playlist) => {
const idx = playlist.episodes.findIndex((ep) => ep.title === episode.title);
if (idx !== -1) {
playlist.episodes[idx] = episode;
} else {
playlist.episodes.push(episode);
}
return playlist;
});
}
};
})();
var playlists = writable({});
var podcastView = writable();
var viewState = (() => {
const store = writable(0 /* PodcastGrid */);
const { subscribe: subscribe2, set } = store;
return {
subscribe: subscribe2,
set: (newState) => {
set(newState);
get_store_value(podcastView)?.scrollIntoView();
}
};
})();
function addEpisodeToQueue(episode) {
queue.update((playlist) => {
const newEpisodes = [episode, ...playlist.episodes];
playlist.episodes = newEpisodes;
return playlist;
});
}
// src/main.ts
var import_obsidian24 = require("obsidian");
// src/utility/formatSeconds.ts
function formatSeconds(seconds, format2) {
return window.moment().startOf("day").seconds(seconds).format(format2);
}
// src/utility/encodePodnotesURI.ts
function encodePodnotesURI(title, feedUrl, time) {
const url = new URL(`obsidian://podnotes`);
url.searchParams.set("episodeName", title);
url.searchParams.set("url", feedUrl);
if (time) {
url.searchParams.set("time", time.toString());
}
return url;
}
// src/utility/isLocalFile.ts
function isLocalFile(ep) {
return ep.podcastName === "local file";
}
// src/API/API.ts
var API = class {
get podcast() {
return get_store_value(currentEpisode);
}
get length() {
return get_store_value(duration);
}
get currentTime() {
return get_store_value(currentTime);
}
set currentTime(value) {
currentTime.update((_) => value);
}
get isPlaying() {
return !get_store_value(isPaused);
}
getPodcastTimeFormatted(format2, linkify = false) {
if (!this.podcast) {
throw new Error("No podcast loaded");
}
const time = formatSeconds(this.currentTime, format2);
if (!linkify)
return time;
const epIsLocal = isLocalFile(this.podcast);
const feedUrl = !epIsLocal ? this.podcast.feedUrl : downloadedEpisodes.getEpisode(this.podcast)?.filePath;
if (!feedUrl || feedUrl === "") {
return time;
}
const url = encodePodnotesURI(this.podcast.title, feedUrl, this.currentTime);
return `[${time}](${url.href})`;
}
start() {
isPaused.update((_) => false);
}
stop() {
isPaused.update((_) => true);
}
togglePlayback() {
isPaused.update((isPaused2) => !isPaused2);
}
skipBackward() {
const skipBackLen = get_store_value(plugin).settings.skipBackwardLength;
this.currentTime -= skipBackLen;
}
skipForward() {
const skipForwardLen = get_store_value(plugin).settings.skipForwardLength;
this.currentTime += skipForwardLen;
}
};
// src/constants.ts
var VIEW_TYPE = "podcast_player_view";
var FAVORITES_SETTINGS = {
icon: "lucide-star",
name: "Favorites",
shouldEpisodeRemoveAfterPlay: false,
shouldRepeat: false
};
var QUEUE_SETTINGS = {
icon: "list-ordered",
name: "Queue",
shouldEpisodeRemoveAfterPlay: true,
shouldRepeat: false
};
var LOCAL_FILES_SETTINGS = {
icon: "folder",
name: "Local Files",
shouldEpisodeRemoveAfterPlay: false,
shouldRepeat: false
};
var DEFAULT_SETTINGS = {
savedFeeds: {},
podNotes: {},
defaultPlaybackRate: 1,
playedEpisodes: {},
favorites: {
...FAVORITES_SETTINGS,
episodes: []
},
queue: {
...QUEUE_SETTINGS,
episodes: []
},
playlists: {},
skipBackwardLength: 15,
skipForwardLength: 15,
currentEpisode: void 0,
timestamp: {
template: "- {{time}} "
},
note: {
path: "",
template: ""
},
download: {
path: ""
},
downloadedEpisodes: {},
localFiles: {
...LOCAL_FILES_SETTINGS,
episodes: []
},
openAIApiKey: "",
transcript: {
path: "transcripts/{{podcast}}/{{title}}.md",
template: "# {{title}}\n\nPodcast: {{podcast}}\nDate: {{date}}\n\n{{transcript}}"
}
};
// src/ui/settings/PodNotesSettingsTab.ts
var import_obsidian11 = require("obsidian");
// node_modules/tslib/modules/index.js
var import_tslib = __toESM(require_tslib(), 1);
var {
__extends,
__assign,
__rest,
__decorate,
__param,
__metadata,
__awaiter,
__generator,
__exportStar,
__createBinding,
__values,
__read,
__spread,
__spreadArrays,
__spreadArray,
__await,
__asyncGenerator,
__asyncDelegator,
__asyncValues,
__makeTemplateObject,
__importStar,
__importDefault,
__classPrivateFieldGet,
__classPrivateFieldSet,
__classPrivateFieldIn
} = import_tslib.default;
// src/ui/settings/PodcastQueryGrid.svelte
var import_obsidian6 = require("obsidian");
// src/iTunesAPIConsumer.ts
var import_obsidian2 = require("obsidian");
async function queryiTunesPodcasts(query) {
const url = new URL("https://itunes.apple.com/search?");
url.searchParams.append("term", query);
url.searchParams.append("media", "podcast");
url.searchParams.append("limit", "3");
url.searchParams.append("kind", "podcast");
const res = await (0, import_obsidian2.requestUrl)({ url: url.href });
const data = res.json.results;
return data.map((d) => ({
title: d.collectionName,
url: d.feedUrl,
artworkUrl: d.artworkUrl100,
collectionId: d.collectionId
}));
}
// src/parser/feedParser.ts
var import_obsidian3 = require("obsidian");
var FeedParser = class {
constructor(feed) {
this.feed = feed;
}
async findItemByTitle(title, url) {
const body = await this.parseFeed(url);
const items = body.querySelectorAll("item");
const item = Array.from(items).find((item2) => {
const parsed = this.parseItem(item2);
const isMatch = parsed && parsed.title === title;
return isMatch;
});
if (!item) {
throw new Error("Could not find episode");
}
const episode = this.parseItem(item);
const feed = await this.getFeed(url);
if (!episode) {
throw new Error("Episode is invalid.");
}
if (!episode.artworkUrl) {
episode.artworkUrl = feed.artworkUrl;
}
if (!episode.podcastName) {
episode.podcastName = feed.title;
}
if (!episode.feedUrl) {
episode.feedUrl = feed.url;
}
return episode;
}
async getEpisodes(url) {
const body = await this.parseFeed(url);
return this.parsePage(body);
}
async getFeed(url) {
const body = await this.parseFeed(url);
const titleEl = body.querySelector("title");
const linkEl = body.querySelector("link");
const itunesImageEl = body.querySelector("image");
if (!titleEl || !linkEl) {
throw new Error("Invalid RSS feed");
}
const title = titleEl.textContent || "";
const artworkUrl = itunesImageEl?.getAttribute("href") || itunesImageEl?.querySelector("url")?.textContent || "";
return {
title,
url,
artworkUrl
};
}
parsePage(page) {
const items = page.querySelectorAll("item");
function isEpisode(ep) {
return !!ep;
}
return Array.from(items).map(this.parseItem.bind(this)).filter(isEpisode);
}
parseItem(item) {
const titleEl = item.querySelector("title");
const streamUrlEl = item.querySelector("enclosure");
const linkEl = item.querySelector("link");
const descriptionEl = item.querySelector("description");
const contentEl = item.querySelector("*|encoded");
const pubDateEl = item.querySelector("pubDate");
const itunesImageEl = item.querySelector("image");
const itunesTitleEl = item.getElementsByTagName("itunes:title")[0];
if (!titleEl || !streamUrlEl || !pubDateEl) {
return null;
}
const title = titleEl.textContent || "";
const streamUrl = streamUrlEl.getAttribute("url") || "";
const url = linkEl?.textContent || "";
const description = descriptionEl?.textContent || "";
const content = contentEl?.textContent || "";
const pubDate = new Date(pubDateEl.textContent);
const artworkUrl = itunesImageEl?.getAttribute("href") || this.feed?.artworkUrl;
const itunesTitle = itunesTitleEl?.textContent;
return {
title,
streamUrl,
url: url || this.feed?.url || "",
description,
content,
podcastName: this.feed?.title || "",
artworkUrl,
episodeDate: pubDate,
feedUrl: this.feed?.url || "",
itunesTitle: itunesTitle || ""
};
}
async parseFeed(feedUrl) {
const req = await (0, import_obsidian3.requestUrl)({ url: feedUrl });
const dp = new DOMParser();
const body = dp.parseFromString(req.text, "text/xml");
return body;
}
};
// src/utility/checkStringIsUrl.ts
function checkStringIsUrl(url) {
try {
return new URL(url);
} catch (e) {
return null;
}
}
// src/ui/obsidian/Text.svelte
var import_obsidian4 = require("obsidian");
// src/utility/extractStylesFromObj.ts
function extractStylesFromObj(obj) {
return Object.entries(obj).map(([key, value]) => `${key}: ${value}`).join("; ");
}
// src/ui/obsidian/Text.svelte
function create_fragment(ctx) {
let span;
return {
c() {
span = element("span");
},
m(target, anchor) {
insert(target, span, anchor);
ctx[6](span);
},
p: noop,
i: noop,
o: noop,
d(detaching) {
if (detaching)
detach(span);
ctx[6](null);
}
};
}
function instance($$self, $$props, $$invalidate) {
let { value = "" } = $$props;
let { disabled = false } = $$props;
let { placeholder = "" } = $$props;
let { type = "text" } = $$props;
let textRef;
const dispatch2 = createEventDispatcher();
let text2;
let { style: styles = {} } = $$props;
onMount(() => {
text2 = new import_obsidian4.TextComponent(textRef);
updateTextComponentAttributes(text2);
});
afterUpdate(() => {
updateTextComponentAttributes(text2);
});
function updateTextComponentAttributes(component) {
if (value !== void 0)
component.setValue(value);
if (disabled)
component.setDisabled(disabled);
if (placeholder)
component.setPlaceholder(placeholder);
if (type)
component.inputEl.type = type;
if (styles) {
text2.inputEl.setAttr("style", extractStylesFromObj(styles));
}
component.onChange((newValue) => {
$$invalidate(1, value = newValue);
dispatch2("change", { value: newValue });
});
}
function span_binding($$value) {
binding_callbacks[$$value ? "unshift" : "push"](() => {
textRef = $$value;
$$invalidate(0, textRef);
});
}
$$self.$$set = ($$props2) => {
if ("value" in $$props2)
$$invalidate(1, value = $$props2.value);
if ("disabled" in $$props2)
$$invalidate(2, disabled = $$props2.disabled);
if ("placeholder" in $$props2)
$$invalidate(3, placeholder = $$props2.placeholder);
if ("type" in $$props2)
$$invalidate(4, type = $$props2.type);
if ("style" in $$props2)
$$invalidate(5, styles = $$props2.style);
};
return [textRef, value, disabled, placeholder, type, styles, span_binding];
}
var Text = class extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance, create_fragment, safe_not_equal, {
value: 1,
disabled: 2,
placeholder: 3,
type: 4,
style: 5
});
}
};
var Text_default = Text;
// src/ui/obsidian/Button.svelte
var import_obsidian5 = require("obsidian");
// src/types/IconType.ts
var ICON_LIST_UNIQUE = /* @__PURE__ */ new Set(["activity", "airplay", "alarm-check", "alarm-clock-off", "alarm-clock", "alarm-minus", "alarm-plus", "album", "alert-circle", "alert-octagon", "alert-triangle", "align-center-horizontal", "align-center-vertical", "align-center", "align-end-horizontal", "align-end-vertical", "align-horizontal-distribute-center", "align-horizontal-distribute-end", "align-horizontal-distribute-start", "align-horizontal-justify-center", "align-horizontal-justify-end", "align-horizontal-justify-start", "align-horizontal-space-around", "align-horizontal-space-between", "align-justify", "align-left", "align-right", "align-start-horizontal", "align-start-vertical", "align-vertical-distribute-center", "align-vertical-distribute-end", "align-vertical-distribute-start", "align-vertical-justify-center", "align-vertical-justify-end", "align-vertical-justify-start", "align-vertical-space-around", "align-vertical-space-between", "anchor", "aperture", "archive", "arrow-big-down", "arrow-big-left", "arrow-big-right", "arrow-big-up", "arrow-down-circle", "arrow-down-left", "arrow-down-right", "arrow-down", "arrow-left-circle", "arrow-left-right", "arrow-left", "arrow-right-circle", "arrow-right", "arrow-up-circle", "arrow-up-left", "arrow-up-right", "arrow-up", "asterisk", "at-sign", "award", "axe", "banknote", "bar-chart-2", "bar-chart", "baseline", "battery-charging", "battery-full", "battery-low", "battery-medium", "battery", "beaker", "bell-minus", "bell-off", "bell-plus", "bell-ring", "bell", "bike", "binary", "bitcoin", "bluetooth-connected", "bluetooth-off", "bluetooth-searching", "bluetooth", "bold", "book-open", "book", "bookmark-minus", "bookmark-plus", "bookmark", "bot", "box-select", "box", "briefcase", "brush", "bug", "building-2", "building", "bus", "calculator", "calendar", "camera-off", "camera", "car", "carrot", "cast", "check-circle-2", "check-circle", "check-square", "check", "chevron-down", "chevron-first", "chevron-last", "chevron-left", "chevron-right", "chevron-up", "chevrons-down-up", "chevrons-down", "chevrons-left", "chevrons-right", "chevrons-up-down", "chevrons-up", "chrome", "circle-slashed", "circle", "clipboard-check", "clipboard-copy", "clipboard-list", "clipboard-x", "clipboard", "clock-1", "clock-10", "clock-11", "clock-12", "clock-2", "clock-3", "clock-4", "clock-5", "clock-6", "clock-7", "clock-8", "clock-9", "clock", "cloud-drizzle", "cloud-fog", "cloud-hail", "cloud-lightning", "cloud-moon", "cloud-off", "cloud-rain-wind", "cloud-rain", "cloud-snow", "cloud-sun", "cloud", "cloudy", "clover", "code-2", "code", "codepen", "codesandbox", "coffee", "coins", "columns", "command", "compass", "contact", "contrast", "cookie", "copy", "copyleft", "copyright", "corner-down-left", "corner-down-right", "corner-left-down", "corner-left-up", "corner-right-down", "corner-right-up", "corner-up-left", "corner-up-right", "cpu", "credit-card", "crop", "cross", "crosshair", "crown", "currency", "database", "delete", "dice-1", "dice-2", "dice-3", "dice-4", "dice-5", "dice-6", "disc", "divide-circle", "divide-square", "divide", "dollar-sign", "download-cloud", "download", "dribbble", "droplet", "droplets", "drumstick", "edit-2", "edit-3", "edit", "egg", "equal-not", "equal", "eraser", "euro", "expand", "external-link", "eye-off", "eye", "facebook", "fast-forward", "feather", "figma", "file-check-2", "file-check", "file-code", "file-digit", "file-input", "file-minus-2", "file-minus", "file-output", "file-plus-2", "file-plus", "file-search", "file-text", "file-x-2", "file-x", "file", "files", "film", "filter", "flag-off", "flag-triangle-left", "flag-triangle-right", "flag", "flame", "flashlight-off", "flashlight", "flask-conical", "flask-round", "folder-minus", "folder-open", "folder-plus", "folder", "form-input", "forward", "frame", "framer", "frown", "function-square", "gamepad-2", "gamepad", "gauge", "gavel", "gem", "ghost", "gift", "git-branch-plus", "git-branch", "git-commit", "git-fork", "git-merge", "git-pull-request", "github", "gitlab", "glasses", "globe-2", "globe", "grab", "graduation-cap", "grid", "grip-horizontal", "grip-vertical", "hammer", "hand-metal", "hand", "hard-drive", "hard-hat", "hash", "haze", "headphones", "heart", "help-circle", "hexagon", "highlighter", "history", "home", "image-minus", "image-off", "image-plus", "image", "import", "inbox", "indent", "indian-rupee", "infinity", "info", "inspect", "instagram", "italic", "japanese-yen", "key", "keyboard", "landmark", "languages", "laptop-2", "laptop", "lasso-select", "lasso", "layers", "layout-dashboard", "layout-grid", "layout-list", "layout-template", "layout", "library", "life-buoy", "lightbulb-off", "lightbulb", "link-2-off", "link-2", "link", "linkedin", "list-checks", "list-minus", "list-ordered", "list-plus", "list-x", "list", "loader-2", "loader", "locate-fixed", "locate-off", "locate", "lock", "log-in", "log-out", "mail", "map-pin", "map", "maximize-2", "maximize", "megaphone", "meh", "menu", "message-circle", "message-square", "mic-off", "mic", "minimize-2", "minimize", "minus-circle", "minus-square", "minus", "monitor-off", "monitor-speaker", "monitor", "moon", "more-horizontal", "more-vertical", "mountain-snow", "mountain", "mouse-pointer-2", "mouse-pointer-click", "mouse-pointer", "mouse", "move-diagonal-2", "move-diagonal", "move-horizontal", "move-vertical", "move", "music", "navigation-2", "navigation", "network", "octagon", "option", "outdent", "package-check", "package-minus", "package-plus", "package-search", "package-x", "package", "palette", "palmtree", "paperclip", "pause-circle", "pause-octagon", "pause", "pen-tool", "pencil", "percent", "person-standing", "phone-call", "phone-forwarded", "phone-incoming", "phone-missed", "phone-off", "phone-outgoing", "phone", "pie-chart", "piggy-bank", "pin", "pipette", "plane", "play-circle", "play", "plug-zap", "plus-circle", "plus-square", "plus", "pocket", "podcast", "pointer", "pound-sterling", "power-off", "power", "printer", "qr-code", "quote", "radio-receiver", "radio", "redo", "refresh-ccw", "refresh-cw", "regex", "repeat-1", "repeat", "reply-all", "reply", "rewind", "rocket", "rocking-chair", "rotate-ccw", "rotate-cw", "rss", "ruler", "russian-ruble", "save", "scale", "scan-line", "scan", "scissors", "screen-share-off", "screen-share", "search", "send", "separator-horizontal", "separator-vertical", "server-crash", "server-off", "server", "settings-2", "settings", "share-2", "share", "sheet", "shield-alert", "shield-check", "shield-close", "shield-off", "shield", "shirt", "shopping-bag", "shopping-cart", "shovel", "shrink", "shuffle", "sidebar-close", "sidebar-open", "sidebar", "sigma", "signal-high", "signal-low", "signal-medium", "signal-zero", "signal", "skip-back", "skip-forward", "skull", "slack", "slash", "sliders", "smartphone-charging", "smartphone", "smile", "snowflake", "sort-asc", "sort-desc", "speaker", "sprout", "square", "star-half", "star", "stop-circle", "stretch-horizontal", "stretch-vertical", "strikethrough", "subscript", "sun", "sunrise", "sunset", "superscript", "swiss-franc", "switch-camera", "table", "tablet", "tag", "target", "tent", "terminal-square", "terminal", "text-cursor-input", "text-cursor", "thermometer-snowflake", "thermometer-sun", "thermometer", "thumbs-down", "thumbs-up", "ticket", "timer-off", "timer-reset", "timer", "toggle-left", "toggle-right", "tornado", "trash-2", "trash", "trello", "trending-down", "trending-up", "triangle", "truck", "tv-2", "tv", "twitch", "twitter", "type", "umbrella", "underline", "undo", "unlink-2", "unlink", "unlock", "upload-cloud", "upload", "user-check", "user-minus", "user-plus", "user-x", "user", "users", "verified", "vibrate", "video-off", "video", "view", "voicemail", "volume-1", "volume-2", "volume-x", "volume", "wallet", "wand", "watch", "waves", "webcam", "wifi-off", "wifi", "wind", "wrap-text", "wrench", "x-circle", "x-octagon", "x-square", "x", "youtube", "zap-off", "zap", "zoom-in", "zoom-out", "search-large", "search", "activity", "airplay", "alarm-check", "alarm-clock-off", "alarm-clock", "alarm-minus", "alarm-plus", "album", "alert-circle", "alert-octagon", "alert-triangle", "align-center-horizontal", "align-center-vertical", "align-center", "align-end-horizontal", "align-end-vertical", "align-horizontal-distribute-center", "align-horizontal-distribute-end", "align-horizontal-distribute-start", "align-horizontal-justify-center", "align-horizontal-justify-end", "align-horizontal-justify-start", "align-horizontal-space-around", "align-horizontal-space-between", "align-justify", "align-left", "align-right", "align-start-horizontal", "align-start-vertical", "align-vertical-distribute-center", "align-vertical-distribute-end", "align-vertical-distribute-start", "align-vertical-justify-center", "align-vertical-justify-end", "align-vertical-justify-start", "align-vertical-space-around", "align-vertical-space-between", "anchor", "aperture", "archive", "arrow-big-down", "arrow-big-left", "arrow-big-right", "arrow-big-up", "arrow-down-circle", "arrow-down-left", "arrow-down-right", "arrow-down", "arrow-left-circle", "arrow-left-right", "arrow-left", "arrow-right-circle", "arrow-right", "arrow-up-circle", "arrow-up-left", "arrow-up-right", "arrow-up", "asterisk", "at-sign", "award", "axe", "banknote", "bar-chart-2", "bar-chart", "baseline", "battery-charging", "battery-full", "battery-low", "battery-medium", "battery", "beaker", "bell-minus", "bell-off", "bell-plus", "bell-ring", "bell", "bike", "binary", "bitcoin", "bluetooth-connected", "bluetooth-off", "bluetooth-searching", "bluetooth", "bold", "book-open", "book", "bookmark-minus", "bookmark-plus", "bookmark", "bot", "box-select", "box", "briefcase", "brush", "bug", "building-2", "building", "bus", "calculator", "calendar", "camera-off", "camera", "car", "carrot", "cast", "check-circle-2", "check-circle", "check-square", "check", "chevron-down", "chevron-first", "chevron-last", "chevron-left", "chevron-right", "chevron-up", "chevrons-down-up", "chevrons-down", "chevrons-left", "chevrons-right", "chevrons-up-down", "chevrons-up", "chrome", "circle-slashed", "circle", "clipboard-check", "clipboard-copy", "clipboard-list", "clipboard-x", "clipboard", "clock-1", "clock-10", "clock-11", "clock-12", "clock-2", "clock-3", "clock-4", "clock-5", "clock-6", "clock-7", "clock-8", "clock-9", "lucide-clock", "cloud-drizzle", "cloud-fog", "cloud-hail", "cloud-lightning", "cloud-moon", "cloud-off", "cloud-rain-wind", "cloud-rain", "cloud-snow", "cloud-sun", "lucide-cloud", "cloudy", "clover", "code-2", "code", "codepen", "codesandbox", "coffee", "coins", "columns", "command", "compass", "contact", "contrast", "cookie", "copy", "copyleft", "copyright", "corner-down-left", "corner-down-right", "corner-left-down", "corner-left-up", "corner-right-down", "corner-right-up", "corner-up-left", "corner-up-right", "cpu", "credit-card", "crop", "lucide-cross", "crosshair", "crown", "currency", "database", "delete", "dice-1", "dice-2", "dice-3", "dice-4", "dice-5", "dice-6", "disc", "divide-circle", "divide-square", "divide", "dollar-sign", "download-cloud", "download", "dribbble", "droplet", "droplets", "drumstick", "edit-2", "edit-3", "edit", "egg", "equal-not", "equal", "eraser", "euro", "expand", "external-link", "eye-off", "eye", "facebook", "fast-forward", "feather", "figma", "file-check-2", "file-check", "file-code", "file-digit", "file-input", "file-minus-2", "file-minus", "file-output", "file-plus-2", "file-plus", "file-search", "file-text", "file-x-2", "file-x", "file", "files", "film", "filter", "flag-off", "flag-triangle-left", "flag-triangle-right", "flag", "flame", "flashlight-off", "flashlight", "flask-conical", "flask-round", "folder-minus", "folder-open", "folder-plus", "lucide-folder", "form-input", "forward", "frame", "framer", "frown", "function-square", "gamepad-2", "gamepad", "gauge", "gavel", "gem", "ghost", "gift", "git-branch-plus", "git-branch", "git-commit", "git-fork", "git-merge", "git-pull-request", "github", "gitlab", "glasses", "globe-2", "globe", "grab", "graduation-cap", "grid", "grip-horizontal", "grip-vertical", "hammer", "hand-metal", "hand", "hard-drive", "hard-hat", "hash", "haze", "headphones", "heart", "help-circle", "hexagon", "highlighter", "history", "home", "image-minus", "image-off", "image-plus", "image", "import", "inbox", "indent", "indian-rupee", "infinity", "lucide-info", "inspect", "instagram", "italic", "japanese-yen", "key", "keyboard", "landmark", "lucide-languages", "laptop-2", "laptop", "lasso-select", "lasso", "layers", "layout-dashboard", "layout-grid", "layout-list", "layout-template", "layout", "library", "life-buoy", "lightbulb-off", "lightbulb", "link-2-off", "link-2", "lucide-link", "linkedin", "list-checks", "list-minus", "list-ordered", "list-plus", "list-x", "list", "loader-2", "loader", "locate-fixed", "locate-off", "locate", "lock", "log-in", "log-out", "mail", "map-pin", "map", "maximize-2", "maximize", "megaphone", "meh", "menu", "message-circle", "message-square", "mic-off", "mic", "minimize-2", "minimize", "minus-circle", "minus-square", "minus", "monitor-off", "monitor-speaker", "monitor", "moon", "more-horizontal", "more-vertical", "mountain-snow", "mountain", "mouse-pointer-2", "mouse-pointer-click", "mouse-pointer", "mouse", "move-diagonal-2", "move-diagonal", "move-horizontal", "move-vertical", "move", "music", "navigation-2", "navigation", "network", "octagon", "option", "outdent", "package-check", "package-minus", "package-plus", "package-search", "package-x", "package", "palette", "palmtree", "paperclip", "pause-circle", "pause-octagon", "pause", "pen-tool", "lucide-pencil", "percent", "person-standing", "phone-call", "phone-forwarded", "phone-incoming", "phone-missed", "phone-off", "phone-outgoing", "phone", "pie-chart", "piggy-bank", "lucide-pin", "pipette", "plane", "play-circle", "play", "plug-zap", "plus-circle", "plus-square", "plus", "pocket", "podcast", "pointer", "pound-sterling", "power-off", "power", "printer", "qr-code", "quote", "radio-receiver", "radio", "redo", "refresh-ccw", "refresh-cw", "regex", "repeat-1", "repeat", "reply-all", "reply", "rewind", "rocket", "rocking-chair", "rotate-ccw", "rotate-cw", "rss", "ruler", "russian-ruble", "save", "scale", "scan-line", "scan", "scissors", "screen-share-off", "screen-share", "lucide-search", "send", "separator-horizontal", "separator-vertical", "server-crash", "server-off", "server", "settings-2", "settings", "share-2", "share", "sheet", "shield-alert", "shield-check", "shield-close", "shield-off", "shield", "shirt", "shopping-bag", "shopping-cart", "shovel", "shrink", "shuffle", "sidebar-close", "sidebar-open", "sidebar", "sigma", "signal-high", "signal-low", "signal-medium", "signal-zero", "signal", "skip-back", "skip-forward", "skull", "slack", "slash", "sliders", "smartphone-charging", "smartphone", "smile", "snowflake", "sort-asc", "sort-desc", "speaker", "sprout", "square", "star-half", "lucide-star", "stop-circle", "stretch-horizontal", "stretch-vertical", "strikethrough", "subscript", "sun", "sunrise", "sunset", "superscript", "swiss-franc", "switch-camera", "table", "tablet", "tag", "target", "tent", "terminal-square", "terminal", "text-cursor-input", "text-cursor", "thermometer-snowflake", "thermometer-sun", "thermometer", "thumbs-down", "thumbs-up", "ticket", "timer-off", "timer-reset", "timer", "toggle-left", "toggle-right", "tornado", "trash-2", "lucide-trash", "trello", "trending-down", "trending-up", "triangle", "truck", "tv-2", "tv", "twitch", "twitter", "type", "umbrella", "underline", "undo", "unlink-2", "unlink", "unlock", "upload-cloud", "upload", "user-check", "user-minus", "user-plus", "user-x", "user", "users", "verified", "vibrate", "video-off", "video", "view", "voicemail", "volume-1", "volume-2", "volume-x", "volume", "wallet", "wand", "watch", "waves", "webcam", "wifi-off", "wifi", "wind", "wrap-text", "wrench", "x-circle", "x-octagon", "x-square", "x", "youtube", "zap-off", "zap", "zoom-in", "zoom-out", "search-large", "lucide-search"]);
var ICON_LIST = Array.from(ICON_LIST_UNIQUE);
// src/ui/obsidian/Button.svelte
function create_fragment2(ctx) {
let span;
return {
c() {
span = element("span");
},
m(target, anchor) {
insert(target, span, anchor);
ctx[9](span);
},
p: noop,
i: noop,
o: noop,
d(detaching) {
if (detaching)
detach(span);
ctx[9](null);
}
};
}
function instance2($$self, $$props, $$invalidate) {
let { text: text2 = "" } = $$props;
let { tooltip = "" } = $$props;
let { icon = void 0 } = $$props;
let { disabled = false } = $$props;
let { warning = false } = $$props;
let { cta = false } = $$props;
let buttonRef;
let { class: className } = $$props;
let { style: styles } = $$props;
let button;
const dispatch2 = createEventDispatcher();
onMount(() => createButton(buttonRef));
afterUpdate(() => updateButtonAttributes(button));
function createButton(container) {
button = new import_obsidian5.ButtonComponent(container);
updateButtonAttributes(button);
}
function updateButtonAttributes(btn) {
if (text2)
btn.setButtonText(text2);
if (tooltip)
btn.setTooltip(tooltip);
if (icon)
btn.setIcon(icon);
if (disabled)
btn.setDisabled(disabled);
if (warning)
btn.setWarning();
else
btn.buttonEl.classList.remove("mod-warning");
if (className)
btn.setClass(className);
if (cta)
btn.setCta();
else
btn.removeCta();
btn.onClick((event) => {
dispatch2("click", { event });
});
if (styles) {
btn.buttonEl.setAttr("style", extractStylesFromObj(styles));
}
}
function span_binding($$value) {
binding_callbacks[$$value ? "unshift" : "push"](() => {
buttonRef = $$value;
$$invalidate(0, buttonRef);
});
}
$$self.$$set = ($$props2) => {
if ("text" in $$props2)
$$invalidate(1, text2 = $$props2.text);
if ("tooltip" in $$props2)
$$invalidate(2, tooltip = $$props2.tooltip);
if ("icon" in $$props2)
$$invalidate(3, icon = $$props2.icon);
if ("disabled" in $$props2)
$$invalidate(4, disabled = $$props2.disabled);
if ("warning" in $$props2)
$$invalidate(5, warning = $$props2.warning);
if ("cta" in $$props2)
$$invalidate(6, cta = $$props2.cta);
if ("class" in $$props2)
$$invalidate(7, className = $$props2.class);
if ("style" in $$props2)
$$invalidate(8, styles = $$props2.style);
};
return [
buttonRef,
text2,
tooltip,
icon,
disabled,
warning,
cta,
className,
styles,
span_binding
];
}
var Button = class extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance2, create_fragment2, safe_not_equal, {
text: 1,
tooltip: 2,
icon: 3,
disabled: 4,
warning: 5,
cta: 6,
class: 7,
style: 8
});
}
};
var Button_default = Button;
// node_modules/svelte/transition/index.mjs
function fade(node, { delay = 0, duration: duration2 = 400, easing = identity } = {}) {
const o = +getComputedStyle(node).opacity;
return {
delay,
duration: duration2,
easing,
css: (t) => `opacity: ${t * o}`
};
}
// src/ui/settings/PodcastResultCard.svelte
function add_css(target) {
append_styles(target, "svelte-1yveck6", ".podcast-result-card.svelte-1yveck6{display:flex;align-items:center;padding:16px;border:1px solid var(--background-modifier-border);border-radius:8px;background-color:var(--background-secondary);max-width:100%;transition:all 0.3s ease;position:relative}.podcast-artwork-container.svelte-1yveck6{width:70px;height:70px;flex-shrink:0;margin-right:20px;overflow:hidden;border-radius:4px;position:relative}.podcast-artwork.svelte-1yveck6{width:100%;height:100%;object-fit:cover;position:absolute;top:0;left:0}.podcast-result-card.svelte-1yveck6:hover{box-shadow:0 2px 8px rgba(0, 0, 0, 0.1);transform:translateY(-2px)}.podcast-info.svelte-1yveck6{flex-grow:1;min-width:0;padding-right:12px}.podcast-title.svelte-1yveck6{margin:0 0 6px 0;font-size:16px;font-weight:bold;line-height:1.3;word-break:break-word}.podcast-actions.svelte-1yveck6{display:flex;align-items:center;flex-shrink:0}.podcast-actions button{padding:4px;width:24px;height:24px}.podcast-actions button svg{width:16px;height:16px}");
}
function create_else_block(ctx) {
let button;
let current;
button = new Button_default({
props: {
icon: "plus",
"aria-label": `Add ${ctx[0].title} podcast`
}
});
button.$on("click", ctx[4]);
return {
c() {
create_component(button.$$.fragment);
},
m(target, anchor) {
mount_component(button, target, anchor);
current = true;
},
p(ctx2, dirty) {
const button_changes = {};
if (dirty & 1)
button_changes["aria-label"] = `Add ${ctx2[0].title} podcast`;
button.$set(button_changes);
},
i(local) {
if (current)
return;
transition_in(button.$$.fragment, local);
current = true;
},
o(local) {
transition_out(button.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(button, detaching);
}
};
}
function create_if_block(ctx) {
let button;
let current;
button = new Button_default({
props: {
icon: "trash",
"aria-label": `Remove ${ctx[0].title} podcast`
}
});
button.$on("click", ctx[3]);
return {
c() {
create_component(button.$$.fragment);
},
m(target, anchor) {
mount_component(button, target, anchor);
current = true;
},
p(ctx2, dirty) {
const button_changes = {};
if (dirty & 1)
button_changes["aria-label"] = `Remove ${ctx2[0].title} podcast`;
button.$set(button_changes);
},
i(local) {
if (current)
return;
transition_in(button.$$.fragment, local);
current = true;
},
o(local) {
transition_out(button.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(button, detaching);
}
};
}
function create_fragment3(ctx) {
let div3;
let div0;
let img;
let img_src_value;
let img_alt_value;
let t0;
let div1;
let h3;
let t1_value = ctx[0].title + "";
let t1;
let t2;
let div2;
let current_block_type_index;
let if_block;
let div3_transition;
let current;
const if_block_creators = [create_if_block, create_else_block];
const if_blocks = [];
function select_block_type(ctx2, dirty) {
if (ctx2[1])
return 0;
return 1;
}
current_block_type_index = select_block_type(ctx, -1);
if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
return {
c() {
div3 = element("div");
div0 = element("div");
img = element("img");
t0 = space();
div1 = element("div");
h3 = element("h3");
t1 = text(t1_value);
t2 = space();
div2 = element("div");
if_block.c();
if (!src_url_equal(img.src, img_src_value = ctx[0].artworkUrl))
attr(img, "src", img_src_value);
attr(img, "alt", img_alt_value = `Artwork for ${ctx[0].title}`);
attr(img, "class", "podcast-artwork svelte-1yveck6");
attr(div0, "class", "podcast-artwork-container svelte-1yveck6");
attr(h3, "class", "podcast-title svelte-1yveck6");
attr(div1, "class", "podcast-info svelte-1yveck6");
attr(div2, "class", "podcast-actions svelte-1yveck6");
attr(div3, "class", "podcast-result-card svelte-1yveck6");
},
m(target, anchor) {
insert(target, div3, anchor);
append(div3, div0);
append(div0, img);
append(div3, t0);
append(div3, div1);
append(div1, h3);
append(h3, t1);
append(div3, t2);
append(div3, div2);
if_blocks[current_block_type_index].m(div2, null);
current = true;
},
p(ctx2, [dirty]) {
if (!current || dirty & 1 && !src_url_equal(img.src, img_src_value = ctx2[0].artworkUrl)) {
attr(img, "src", img_src_value);
}
if (!current || dirty & 1 && img_alt_value !== (img_alt_value = `Artwork for ${ctx2[0].title}`)) {
attr(img, "alt", img_alt_value);
}
if ((!current || dirty & 1) && t1_value !== (t1_value = ctx2[0].title + ""))
set_data(t1, t1_value);
let previous_block_index = current_block_type_index;
current_block_type_index = select_block_type(ctx2, dirty);
if (current_block_type_index === previous_block_index) {
if_blocks[current_block_type_index].p(ctx2, dirty);
} else {
group_outros();
transition_out(if_blocks[previous_block_index], 1, 1, () => {
if_blocks[previous_block_index] = null;
});
check_outros();
if_block = if_blocks[current_block_type_index];
if (!if_block) {
if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2);
if_block.c();
} else {
if_block.p(ctx2, dirty);
}
transition_in(if_block, 1);
if_block.m(div2, null);
}
},
i(local) {
if (current)
return;
transition_in(if_block);
add_render_callback(() => {
if (!div3_transition)
div3_transition = create_bidirectional_transition(div3, fade, { duration: 300 }, true);
div3_transition.run(1);
});
current = true;
},
o(local) {
transition_out(if_block);
if (!div3_transition)
div3_transition = create_bidirectional_transition(div3, fade, { duration: 300 }, false);
div3_transition.run(0);
current = false;
},
d(detaching) {
if (detaching)
detach(div3);
if_blocks[current_block_type_index].d();
if (detaching && div3_transition)
div3_transition.end();
}
};
}
function instance3($$self, $$props, $$invalidate) {
let { podcast } = $$props;
let { isSaved = false } = $$props;
const dispatch2 = createEventDispatcher();
const click_handler = () => dispatch2("removePodcast", { podcast });
const click_handler_1 = () => dispatch2("addPodcast", { podcast });
$$self.$$set = ($$props2) => {
if ("podcast" in $$props2)
$$invalidate(0, podcast = $$props2.podcast);
if ("isSaved" in $$props2)
$$invalidate(1, isSaved = $$props2.isSaved);
};
return [podcast, isSaved, dispatch2, click_handler, click_handler_1];
}
var PodcastResultCard = class extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance3, create_fragment3, safe_not_equal, { podcast: 0, isSaved: 1 }, add_css);
}
};
var PodcastResultCard_default = PodcastResultCard;
// src/ui/settings/PodcastQueryGrid.svelte
function add_css2(target) {
append_styles(target, "svelte-nkazu8", ".podcast-query-container.svelte-nkazu8{margin-bottom:2rem}.podcast-query-results.svelte-nkazu8{display:grid;grid-gap:16px;grid-template-columns:repeat(auto-fill, minmax(280px, 1fr))}@media(max-width: 600px){.podcast-query-results.svelte-nkazu8{grid-template-columns:1fr}}");
}
function get_each_context(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[11] = list[i];
return child_ctx;
}
function create_each_block(key_1, ctx) {
let div;
let podcastresultcard;
let t;
let current;
podcastresultcard = new PodcastResultCard_default({
props: {
podcast: ctx[11],
isSaved: typeof ctx[11].url === "string" && ctx[1][ctx[11].title]?.url === ctx[11].url
}
});
podcastresultcard.$on("addPodcast", ctx[4]);
podcastresultcard.$on("removePodcast", ctx[5]);
return {
key: key_1,
first: null,
c() {
div = element("div");
create_component(podcastresultcard.$$.fragment);
t = space();
attr(div, "role", "listitem");
this.first = div;
},
m(target, anchor) {
insert(target, div, anchor);
mount_component(podcastresultcard, div, null);
append(div, t);
current = true;
},
p(new_ctx, dirty) {
ctx = new_ctx;
const podcastresultcard_changes = {};
if (dirty & 1)
podcastresultcard_changes.podcast = ctx[11];
if (dirty & 3)
podcastresultcard_changes.isSaved = typeof ctx[11].url === "string" && ctx[1][ctx[11].title]?.url === ctx[11].url;
podcastresultcard.$set(podcastresultcard_changes);
},
i(local) {
if (current)
return;
transition_in(podcastresultcard.$$.fragment, local);
current = true;
},
o(local) {
transition_out(podcastresultcard.$$.fragment, local);
current = false;
},
d(detaching) {
if (detaching)
detach(div);
destroy_component(podcastresultcard);
}
};
}
function create_fragment4(ctx) {
let div1;
let text_1;
let updating_el;
let t;
let div0;
let each_blocks = [];
let each_1_lookup = /* @__PURE__ */ new Map();
let div1_transition;
let current;
function text_1_el_binding(value) {
ctx[8](value);
}
let text_1_props = {
placeholder: "Search or enter feed URL...",
style: { width: "100%", "margin-bottom": "1rem" }
};
if (ctx[2] !== void 0) {
text_1_props.el = ctx[2];
}
text_1 = new Text_default({ props: text_1_props });
binding_callbacks.push(() => bind(text_1, "el", text_1_el_binding));
text_1.$on("change", ctx[3]);
let each_value = ctx[0];
const get_key = (ctx2) => ctx2[11].url;
for (let i = 0; i < each_value.length; i += 1) {
let child_ctx = get_each_context(ctx, each_value, i);
let key = get_key(child_ctx);
each_1_lookup.set(key, each_blocks[i] = create_each_block(key, child_ctx));
}
return {
c() {
div1 = element("div");
create_component(text_1.$$.fragment);
t = space();
div0 = element("div");
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].c();
}
attr(div0, "class", "podcast-query-results svelte-nkazu8");
attr(div0, "role", "list");
attr(div0, "aria-label", "Podcast search results");
attr(div1, "class", "podcast-query-container svelte-nkazu8");
},
m(target, anchor) {
insert(target, div1, anchor);
mount_component(text_1, div1, null);
append(div1, t);
append(div1, div0);
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].m(div0, null);
}
current = true;
},
p(ctx2, [dirty]) {
const text_1_changes = {};
if (!updating_el && dirty & 4) {
updating_el = true;
text_1_changes.el = ctx2[2];
add_flush_callback(() => updating_el = false);
}
text_1.$set(text_1_changes);
if (dirty & 51) {
each_value = ctx2[0];
group_outros();
each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx2, each_value, each_1_lookup, div0, outro_and_destroy_block, create_each_block, null, get_each_context);
check_outros();
}
},
i(local) {
if (current)
return;
transition_in(text_1.$$.fragment, local);
for (let i = 0; i < each_value.length; i += 1) {
transition_in(each_blocks[i]);
}
add_render_callback(() => {
if (!div1_transition)
div1_transition = create_bidirectional_transition(div1, fade, { duration: 300 }, true);
div1_transition.run(1);
});
current = true;
},
o(local) {
transition_out(text_1.$$.fragment, local);
for (let i = 0; i < each_blocks.length; i += 1) {
transition_out(each_blocks[i]);
}
if (!div1_transition)
div1_transition = create_bidirectional_transition(div1, fade, { duration: 300 }, false);
div1_transition.run(0);
current = false;
},
d(detaching) {
if (detaching)
detach(div1);
destroy_component(text_1);
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].d();
}
if (detaching && div1_transition)
div1_transition.end();
}
};
}
function instance4($$self, $$props, $$invalidate) {
let $savedFeeds;
let $podcastsUpdated;
component_subscribe($$self, savedFeeds, ($$value) => $$invalidate(1, $savedFeeds = $$value));
component_subscribe($$self, podcastsUpdated, ($$value) => $$invalidate(7, $podcastsUpdated = $$value));
let searchResults = [];
let gridSizeClass = "grid-3";
let searchQuery = "";
let searchInput;
onMount(() => {
updateSearchResults();
if (searchInput) {
searchInput.focus();
}
});
function updateSearchResults() {
if (searchQuery.trim() === "") {
$$invalidate(0, searchResults = Object.values($savedFeeds));
}
}
const debouncedUpdate = (0, import_obsidian6.debounce)(({ detail: { value } }) => __awaiter(void 0, void 0, void 0, function* () {
$$invalidate(6, searchQuery = value);
const customFeedUrl = checkStringIsUrl(value);
if (customFeedUrl) {
const feed = yield new FeedParser().getFeed(customFeedUrl.href);
$$invalidate(0, searchResults = [feed]);
} else if (value.trim() === "") {
updateSearchResults();
} else {
$$invalidate(0, searchResults = yield queryiTunesPodcasts(value));
}
}), 300, true);
function addPodcast(event) {
const { podcast } = event.detail;
savedFeeds.update((feeds) => Object.assign(Object.assign({}, feeds), { [podcast.title]: podcast }));
updateSearchResults();
}
function removePodcast(event) {
const { podcast } = event.detail;
savedFeeds.update((feeds) => {
const newFeeds = Object.assign({}, feeds);
delete newFeeds[podcast.title];
return newFeeds;
});
updateSearchResults();
}
function text_1_el_binding(value) {
searchInput = value;
$$invalidate(2, searchInput);
}
$$self.$$.update = () => {
if ($$self.$$.dirty & 194) {
$: {
if (searchQuery.trim() === "") {
$$invalidate(0, searchResults = Object.values($savedFeeds));
}
$podcastsUpdated;
}
}
if ($$self.$$.dirty & 1) {
$: {
if (searchResults.length % 3 === 0 || searchResults.length > 3) {
gridSizeClass = "grid-3";
} else if (searchResults.length % 2 === 0) {
gridSizeClass = "grid-2";
} else if (searchResults.length % 1 === 0) {
gridSizeClass = "grid-1";
}
}
}
};
return [
searchResults,
$savedFeeds,
searchInput,
debouncedUpdate,
addPodcast,
removePodcast,
searchQuery,
$podcastsUpdated,
text_1_el_binding
];
}
var PodcastQueryGrid = class extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance4, create_fragment4, safe_not_equal, {}, add_css2);
}
};
var PodcastQueryGrid_default = PodcastQueryGrid;
// src/ui/obsidian/Icon.svelte
var import_obsidian7 = require("obsidian");
function add_css3(target) {
append_styles(target, "svelte-c77uvx", ".icon-clickable.svelte-c77uvx{cursor:pointer}");
}
function create_fragment5(ctx) {
let div;
let span;
let div_class_value;
let mounted;
let dispose;
return {
c() {
div = element("div");
span = element("span");
attr(div, "class", div_class_value = null_to_empty(ctx[0] ? "icon-clickable" : "") + " svelte-c77uvx");
attr(div, "aria-label", ctx[1]);
},
m(target, anchor) {
insert(target, div, anchor);
append(div, span);
ctx[7](span);
if (!mounted) {
dispose = listen(div, "click", ctx[3]);
mounted = true;
}
},
p(ctx2, [dirty]) {
if (dirty & 1 && div_class_value !== (div_class_value = null_to_empty(ctx2[0] ? "icon-clickable" : "") + " svelte-c77uvx")) {
attr(div, "class", div_class_value);
}
if (dirty & 2) {
attr(div, "aria-label", ctx2[1]);
}
},
i: noop,
o: noop,
d(detaching) {
if (detaching)
detach(div);
ctx[7](null);
mounted = false;
dispose();
}
};
}
function instance5($$self, $$props, $$invalidate) {
let { size = 16 } = $$props;
let { icon } = $$props;
let { clickable = true } = $$props;
let { label = "" } = $$props;
let ref;
let { style: styles = {} } = $$props;
let stylesStr;
const dispatch2 = createEventDispatcher();
onMount(() => {
(0, import_obsidian7.setIcon)(ref, icon, size);
$$invalidate(2, ref.style.cssText = stylesStr, ref);
});
afterUpdate(() => {
(0, import_obsidian7.setIcon)(ref, icon, size);
$$invalidate(2, ref.style.cssText = stylesStr, ref);
});
function forwardClick(event) {
dispatch2("click", { event });
}
function span_binding($$value) {
binding_callbacks[$$value ? "unshift" : "push"](() => {
ref = $$value;
$$invalidate(2, ref);
});
}
$$self.$$set = ($$props2) => {
if ("size" in $$props2)
$$invalidate(4, size = $$props2.size);
if ("icon" in $$props2)
$$invalidate(5, icon = $$props2.icon);
if ("clickable" in $$props2)
$$invalidate(0, clickable = $$props2.clickable);
if ("label" in $$props2)
$$invalidate(1, label = $$props2.label);
if ("style" in $$props2)
$$invalidate(6, styles = $$props2.style);
};
$$self.$$.update = () => {
if ($$self.$$.dirty & 64) {
$:
stylesStr = extractStylesFromObj(styles);
}
};
return [clickable, label, ref, forwardClick, size, icon, styles, span_binding];
}
var Icon = class extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance5, create_fragment5, safe_not_equal, {
size: 4,
icon: 5,
clickable: 0,
label: 1,
style: 6
}, add_css3);
}
};
var Icon_default = Icon;
// src/ui/settings/PlaylistItem.svelte
function add_css4(target) {
append_styles(target, "svelte-nlujum", ".playlist-item.svelte-nlujum{display:flex;align-items:center;justify-content:space-between;padding:0.5rem;border-bottom:1px solid var(--background-modifier-border);width:100%}.playlist-item-left.svelte-nlujum{display:flex;align-items:center}.playlist-item-controls.svelte-nlujum{display:flex;align-items:center;gap:0.25rem}");
}
function create_if_block2(ctx) {
let icon;
let current;
icon = new Icon_default({
props: {
icon: ctx[2] ? "check" : "trash",
label: ctx[2] ? "Confirm deletion" : "Delete playlist",
size: 20,
style: { color: "red" }
}
});
icon.$on("click", ctx[3]);
return {
c() {
create_component(icon.$$.fragment);
},
m(target, anchor) {
mount_component(icon, target, anchor);
current = true;
},
p(ctx2, dirty) {
const icon_changes = {};
if (dirty & 4)
icon_changes.icon = ctx2[2] ? "check" : "trash";
if (dirty & 4)
icon_changes.label = ctx2[2] ? "Confirm deletion" : "Delete playlist";
icon.$set(icon_changes);
},
i(local) {
if (current)
return;
transition_in(icon.$$.fragment, local);
current = true;
},
o(local) {
transition_out(icon.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(icon, detaching);
}
};
}
function create_fragment6(ctx) {
let div2;
let div0;
let icon;
let t0;
let span;
let t1_value = ctx[0].name + "";
let t1;
let t2;
let t3_value = ctx[0].episodes.length + "";
let t3;
let t4;
let t5;
let div1;
let current;
icon = new Icon_default({
props: {
icon: ctx[0].icon,
style: { "margin-right": "0.2rem" },
clickable: false,
size: 20
}
});
let if_block = ctx[1] && create_if_block2(ctx);
return {
c() {
div2 = element("div");
div0 = element("div");
create_component(icon.$$.fragment);
t0 = space();
span = element("span");
t1 = text(t1_value);
t2 = text("\n (");
t3 = text(t3_value);
t4 = text(")");
t5 = space();
div1 = element("div");
if (if_block)
if_block.c();
set_style(span, "font-weight", "500");
set_style(span, "margin-right", "0.2rem");
attr(div0, "class", "playlist-item-left svelte-nlujum");
attr(div1, "class", "playlist-item-controls svelte-nlujum");
attr(div2, "class", "playlist-item svelte-nlujum");
},
m(target, anchor) {
insert(target, div2, anchor);
append(div2, div0);
mount_component(icon, div0, null);
append(div0, t0);
append(div0, span);
append(span, t1);
append(div0, t2);
append(div0, t3);
append(div0, t4);
append(div2, t5);
append(div2, div1);
if (if_block)
if_block.m(div1, null);
current = true;
},
p(ctx2, [dirty]) {
const icon_changes = {};
if (dirty & 1)
icon_changes.icon = ctx2[0].icon;
icon.$set(icon_changes);
if ((!current || dirty & 1) && t1_value !== (t1_value = ctx2[0].name + ""))
set_data(t1, t1_value);
if ((!current || dirty & 1) && t3_value !== (t3_value = ctx2[0].episodes.length + ""))
set_data(t3, t3_value);
if (ctx2[1]) {
if (if_block) {
if_block.p(ctx2, dirty);
if (dirty & 2) {
transition_in(if_block, 1);
}
} else {
if_block = create_if_block2(ctx2);
if_block.c();
transition_in(if_block, 1);
if_block.m(div1, null);
}
} else if (if_block) {
group_outros();
transition_out(if_block, 1, 1, () => {
if_block = null;
});
check_outros();
}
},
i(local) {
if (current)
return;
transition_in(icon.$$.fragment, local);
transition_in(if_block);
current = true;
},
o(local) {
transition_out(icon.$$.fragment, local);
transition_out(if_block);
current = false;
},
d(detaching) {
if (detaching)
detach(div2);
destroy_component(icon);
if (if_block)
if_block.d();
}
};
}
function instance6($$self, $$props, $$invalidate) {
let { playlist } = $$props;
let { showDeleteButton = true } = $$props;
let clickedDelete = false;
const dispatch2 = createEventDispatcher();
function onClickedDelete(event) {
if (clickedDelete) {
dispatch2("delete", { value: playlist });
return;
}
$$invalidate(2, clickedDelete = true);
setTimeout(() => {
$$invalidate(2, clickedDelete = false);
}, 2e3);
}
function onClickedRepeat(event) {
dispatch2("toggleRepeat", { value: playlist });
}
$$self.$$set = ($$props2) => {
if ("playlist" in $$props2)
$$invalidate(0, playlist = $$props2.playlist);
if ("showDeleteButton" in $$props2)
$$invalidate(1, showDeleteButton = $$props2.showDeleteButton);
};
return [playlist, showDeleteButton, clickedDelete, onClickedDelete];
}
var PlaylistItem = class extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance6, create_fragment6, safe_not_equal, { playlist: 0, showDeleteButton: 1 }, add_css4);
}
};
var PlaylistItem_default = PlaylistItem;
// src/ui/obsidian/Dropdown.svelte
var import_obsidian8 = require("obsidian");
function create_fragment7(ctx) {
let span;
return {
c() {
span = element("span");
},
m(target, anchor) {
insert(target, span, anchor);
ctx[5](span);
},
p: noop,
i: noop,
o: noop,
d(detaching) {
if (detaching)
detach(span);
ctx[5](null);
}
};
}
function instance7($$self, $$props, $$invalidate) {
let { value = "" } = $$props;
let { options = {} } = $$props;
let { disabled = false } = $$props;
let dropdownRef;
let dropdown;
let { style: styles } = $$props;
const dispatch2 = createEventDispatcher();
onMount(() => {
dropdown = new import_obsidian8.DropdownComponent(dropdownRef);
updateDropdownAttributes(dropdown);
});
function updateDropdownAttributes(dropdown2) {
if (options)
dropdown2.addOptions(options);
if (value)
dropdown2.setValue(value);
if (disabled)
dropdown2.setDisabled(disabled);
dropdown2.onChange((value2) => {
dispatch2("change", { value: value2 });
});
if (styles) {
dropdown2.selectEl.setAttr("style", extractStylesFromObj(styles));
}
}
function span_binding($$value) {
binding_callbacks[$$value ? "unshift" : "push"](() => {
dropdownRef = $$value;
$$invalidate(0, dropdownRef);
});
}
$$self.$$set = ($$props2) => {
if ("value" in $$props2)
$$invalidate(1, value = $$props2.value);
if ("options" in $$props2)
$$invalidate(2, options = $$props2.options);
if ("disabled" in $$props2)
$$invalidate(3, disabled = $$props2.disabled);
if ("style" in $$props2)
$$invalidate(4, styles = $$props2.style);
};
return [dropdownRef, value, options, disabled, styles, span_binding];
}
var Dropdown = class extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance7, create_fragment7, safe_not_equal, {
value: 1,
options: 2,
disabled: 3,
style: 4
});
}
};
var Dropdown_default = Dropdown;
// src/ui/settings/PlaylistManager.svelte
function add_css5(target) {
append_styles(target, "svelte-46vu4x", ".playlist-manager-container.svelte-46vu4x{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;margin-bottom:2rem}.playlist-list.svelte-46vu4x{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;overflow-y:auto}.add-playlist-container.svelte-46vu4x{margin-top:1rem}");
}
function get_each_context2(ctx, list, i) {
const child_ctx = ctx.slice();
child_ctx[12] = list[i];
return child_ctx;
}
function create_each_block2(ctx) {
let playlistitem;
let current;
playlistitem = new PlaylistItem_default({
props: { playlist: ctx[12] }
});
playlistitem.$on("delete", ctx[8]);
playlistitem.$on("toggleRepeat", ctx[9]);
return {
c() {
create_component(playlistitem.$$.fragment);
},
m(target, anchor) {
mount_component(playlistitem, target, anchor);
current = true;
},
p(ctx2, dirty) {
const playlistitem_changes = {};
if (dirty & 1)
playlistitem_changes.playlist = ctx2[12];
playlistitem.$set(playlistitem_changes);
},
i(local) {
if (current)
return;
transition_in(playlistitem.$$.fragment, local);
current = true;
},
o(local) {
transition_out(playlistitem.$$.fragment, local);
current = false;
},
d(detaching) {
destroy_component(playlistitem, detaching);
}
};
}
function create_fragment8(ctx) {
let div2;
let div0;
let playlistitem0;
let t0;
let playlistitem1;
let t1;
let t2;
let div1;
let dropdown;
let updating_value;
let t3;
let text_1;
let updating_value_1;
let t4;
let button;
let current;
playlistitem0 = new PlaylistItem_default({
props: {
playlist: ctx[3],
showDeleteButton: false
}
});
playlistitem1 = new PlaylistItem_default({
props: {
playlist: ctx[4],
showDeleteButton: false
}
});
let each_value = ctx[0];
let each_blocks = [];
for (let i = 0; i < each_value.length; i += 1) {
each_blocks[i] = create_each_block2(get_each_context2(ctx, each_value, i));
}
const out = (i) => transition_out(each_blocks[i], 1, 1, () => {
each_blocks[i] = null;
});
function dropdown_value_binding(value) {
ctx[10](value);
}
let dropdown_props = { options: ctx[5] };
if (ctx[2] !== void 0) {
dropdown_props.value = ctx[2];
}
dropdown = new Dropdown_default({ props: dropdown_props });
binding_callbacks.push(() => bind(dropdown, "value", dropdown_value_binding));
dropdown.$on("change", ctx[7]);
function text_1_value_binding(value) {
ctx[11](value);
}
let text_1_props = { placeholder: "Playlist name" };
if (ctx[1] !== void 0) {
text_1_props.value = ctx[1];
}
text_1 = new Text_default({ props: text_1_props });
binding_callbacks.push(() => bind(text_1, "value", text_1_value_binding));
button = new Button_default({ props: { icon: "plus", cta: true } });
button.$on("click", ctx[6]);
return {
c() {
div2 = element("div");
div0 = element("div");
create_component(playlistitem0.$$.fragment);
t0 = space();
create_component(playlistitem1.$$.fragment);
t1 = space();
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].c();
}
t2 = space();
div1 = element("div");
create_component(dropdown.$$.fragment);
t3 = space();
create_component(text_1.$$.fragment);
t4 = space();
create_component(button.$$.fragment);
attr(div0, "class", "playlist-list svelte-46vu4x");
attr(div1, "class", "add-playlist-container svelte-46vu4x");
attr(div2, "class", "playlist-manager-container svelte-46vu4x");
},
m(target, anchor) {
insert(target, div2, anchor);
append(div2, div0);
mount_component(playlistitem0, div0, null);
append(div0, t0);
mount_component(playlistitem1, div0, null);
append(div0, t1);
for (let i = 0; i < each_blocks.length; i += 1) {
each_blocks[i].m(div0, null);
}
append(div2, t2);
append(div2, div1);
mount_component(dropdown, div1, null);
append(div1, t3);
mount_component(text_1, div1, null);
append(div1, t4);
mount_component(button, div1, null);
current = true;
},
p(ctx2, [dirty]) {
const playlistitem0_changes = {};
if (dirty & 8)
playlistitem0_changes.playlist = ctx2[3];
playlistitem0.$set(playlistitem0_changes);
const playlistitem1_changes = {};
if (dirty & 16)
playlistitem1_changes.playlist = ctx2[4];
playlistitem1.$set(playlistitem1_changes);
if (dirty & 769) {
each_value = ctx2[0];
let i;
for (i = 0; i < each_value.length; i += 1) {
const child_ctx = get_each_context2(ctx2, each_value, i);
if (each_blocks[i]) {
each_blocks[i].p(child_ctx, dirty);
transition_in(each_blocks[i], 1);
} else {
each_blocks[i] = create_each_block2(child_ctx);
each_blocks[i].c();
transition_in(each_blocks[i], 1);
each_blocks[i].m(div0, null);
}
}
group_outros();
for (i = each_value.length; i < each_blocks.length; i += 1) {
out(i);
}
check_outros();
}
const dropdown_changes = {};
if (!updating_value && dirty & 4) {
updating_value = true;
dropdown_changes.value = ctx2[2];
add_flush_callback(() => updating_value = false);
}
dropdown.$set(dropdown_changes);
const text_1_changes = {};
if (!updating_value_1 && dirty & 2) {
updating_value_1 = true;
text_1_changes.value = ctx2[1];
add_flush_callback(() => updating_value_1 = false);
}
text_1.$set(text_1_changes);
},
i(local) {
if (current)
return;
transition_in(playlistitem0.$$.fragment, local);
transition_in(playlistitem1.$$.fragment, local);
for (let i = 0; i < each_value.length; i += 1) {
transition_in(each_blocks[i]);
}
transition_in(dropdown.$$.fragment, local);
transition_in(text_1.$$.fragment, local);
transition_in(button.$$.fragment, local);
current = true;
},
o(local) {
transition_out(playlistitem0.$$.fragment, local);
transition_out(playlistitem1.$$.fragment, local);
each_blocks = each_blocks.filter(Boolean);
for (let i = 0; i < each_blocks.length; i += 1) {
transition_out(each_blocks[i]);
}
transition_out(dropdown.$$.fragment, local);
transition_out(text_1.$$.fragment, local);
transition_out(button.$$.fragment, local);
current = false;
},
d(detaching) {
if (detaching)
detach(div2);
destroy_component(playlistitem0);
destroy_component(playlistitem1);
destroy_each(each_blocks, detaching);
destroy_component(dropdown);
destroy_component(text_1);
destroy_component(button);
}
};
}
function instance8($$self, $$props, $$invalidate) {
let $queue;
let $favorites;
component_subscribe($$self, queue, ($$value) => $$invalidate(3, $queue = $$value));
component_subscribe($$self, favorites, ($$value) => $$invalidate(4, $favorites = $$value));
let playlistArr = [];
let playlistInput = "";
let options = ICON_LIST.reduce((acc, curr) => {
acc[curr] = curr;
return acc;
}, {});
let icon = ICON_LIST[0];
onMount(() => {
const unsubscribe = playlists.subscribe((playlists2) => {
$$invalidate(0, playlistArr = Object.values(playlists2));
});
return () => {
unsubscribe();
};
});
function onAddPlaylist() {
playlists.update((value) => {
value[playlistInput] = {
name: playlistInput,
icon,
episodes: [],
shouldEpisodeRemoveAfterPlay: false,
shouldRepeat: false
};
return value;
});
$$invalidate(1, playlistInput = "");
$$invalidate(2, icon = ICON_LIST[0]);
}
function onChangeIcon(event) {
$$invalidate(2, icon = event.detail.value);
}
function onDeletePlaylist(event) {
playlists.update((value) => {
delete value[event.detail.value.name];
return value;
});
}
function onToggleRepeat(event) {
playlists.update((value) => {
value[event.detail.value.name].shouldRepeat = !value[event.detail.value.name].shouldRepeat;
return value;
});
}
function dropdown_value_binding(value) {
icon = value;
$$invalidate(2, icon);
}
function text_1_value_binding(value) {
playlistInput = value;
$$invalidate(1, playlistInput);
}
return [
playlistArr,
playlistInput,
icon,
$queue,
$favorites,
options,
onAddPlaylist,
onChangeIcon,
onDeletePlaylist,
onToggleRepeat,
dropdown_value_binding,
text_1_value_binding
];
}
var PlaylistManager = class extends SvelteComponent {
constructor(options) {
super();
init(this, options, instance8, create_fragment8, safe_not_equal, {}, add_css5);
}
};
var PlaylistManager_default = PlaylistManager;
// src/TemplateEngine.ts
var import_obsidian9 = require("obsidian");
// node_modules/fuse.js/dist/fuse.esm.js
function isArray(value) {
return !Array.isArray ? getTag(value) === "[object Array]" : Array.isArray(value);
}
var INFINITY = 1 / 0;
function baseToString(value) {
if (typeof value == "string") {
return value;
}
let result = value + "";
return result == "0" && 1 / value == -INFINITY ? "-0" : result;
}
function toString(value) {
return value == null ? "" : baseToString(value);
}
function isString(value) {
return typeof value === "string";
}
function isNumber(value) {
return typeof value === "number";
}
function isBoolean(value) {
return value === true || value === false || isObjectLike(value) && getTag(value) == "[object Boolean]";
}
function isObject(value) {
return typeof value === "object";
}
function isObjectLike(value) {
return isObject(value) && value !== null;
}
function isDefined(value) {
return value !== void 0 && value !== null;
}
function isBlank(value) {
return !value.trim().length;
}
function getTag(value) {
return value == null ? value === void 0 ? "[object Undefined]" : "[object Null]" : Object.prototype.toString.call(value);
}
var INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
var LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) => `Invalid value for key ${key}`;
var PATTERN_LENGTH_TOO_LARGE = (max) => `Pattern length exceeds max of ${max}.`;
var MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`;
var INVALID_KEY_WEIGHT_VALUE = (key) => `Property 'weight' in key '${key}' must be a positive integer`;
var hasOwn = Object.prototype.hasOwnProperty;
var KeyStore = class {
constructor(keys) {
this._keys = [];
this._keyMap = {};
let totalWeight = 0;
keys.forEach((key) => {
let obj = createKey(key);
totalWeight += obj.weight;
this._keys.push(obj);
this._keyMap[obj.id] = obj;
totalWeight += obj.weight;
});
this._keys.forEach((key) => {
key.weight /= totalWeight;
});
}
get(keyId) {
return this._keyMap[keyId];
}
keys() {
return this._keys;
}
toJSON() {
return JSON.stringify(this._keys);
}
};
function createKey(key) {
let path = null;
let id = null;
let src = null;
let weight = 1;
let getFn = null;
if (isString(key) || isArray(key)) {
src = key;
path = createKeyPath(key);
id = createKeyId(key);
} else {
if (!hasOwn.call(key, "name")) {
throw new Error(MISSING_KEY_PROPERTY("name"));
}
const name = key.name;
src = name;
if (hasOwn.call(key, "weight")) {
weight = key.weight;
if (weight <= 0) {
throw new Error(INVALID_KEY_WEIGHT_VALUE(name));
}
}
path = createKeyPath(name);
id = createKeyId(name);
getFn = key.getFn;
}
return { path, id, weight, src, getFn };
}
function createKeyPath(key) {
return isArray(key) ? key : key.split(".");
}
function createKeyId(key) {
return isArray(key) ? key.join(".") : key;
}
function get(obj, path) {
let list = [];
let arr = false;
const deepGet = (obj2, path2, index) => {
if (!isDefined(obj2)) {
return;
}
if (!path2[index]) {
list.push(obj2);
} else {
let key = path2[index];
const value = obj2[key];
if (!isDefined(value)) {
return;
}
if (index === path2.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) {
list.push(toString(value));
} else if (isArray(value)) {
arr = true;
for (let i = 0, len = value.length; i < len; i += 1) {
deepGet(value[i], path2, index + 1);
}
} else if (path2.length) {
deepGet(value, path2, index + 1);
}
}
};
deepGet(obj, isString(path) ? path.split(".") : path, 0);
return arr ? list : list[0];
}
var MatchOptions = {
includeMatches: false,
findAllMatches: false,
minMatchCharLength: 1
};
var BasicOptions = {
isCaseSensitive: false,
includeScore: false,
keys: [],
shouldSort: true,
sortFn: (a, b) => a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1
};
var FuzzyOptions = {
location: 0,
threshold: 0.6,
distance: 100
};
var AdvancedOptions = {
useExtendedSearch: false,
getFn: get,
ignoreLocation: false,
ignoreFieldNorm: false,
fieldNormWeight: 1
};
var Config = {
...BasicOptions,
...MatchOptions,
...FuzzyOptions,
...AdvancedOptions
};
var SPACE = /[^ ]+/g;
function norm(weight = 1, mantissa = 3) {
const cache = /* @__PURE__ */ new Map();
const m = Math.pow(10, mantissa);
return {
get(value) {
const numTokens = value.match(SPACE).length;
if (cache.has(numTokens)) {
return cache.get(numTokens);
}
const norm2 = 1 / Math.pow(numTokens, 0.5 * weight);
const n = parseFloat(Math.round(norm2 * m) / m);
cache.set(numTokens, n);
return n;
},
clear() {
cache.clear();
}
};
}
var FuseIndex = class {
constructor({
getFn = Config.getFn,
fieldNormWeight = Config.fieldNormWeight
} = {}) {
this.norm = norm(fieldNormWeight, 3);
this.getFn = getFn;
this.isCreated = false;
this.setIndexRecords();
}
setSources(docs = []) {
this.docs = docs;
}
setIndexRecords(records = []) {
this.records = records;
}
setKeys(keys = []) {
this.keys = keys;
this._keysMap = {};
keys.forEach((key, idx) => {
this._keysMap[key.id] = idx;
});
}
create() {
if (this.isCreated || !this.docs.length) {
return;
}
this.isCreated = true;
if (isString(this.docs[0])) {
this.docs.forEach((doc, docIndex) => {
this._addString(doc, docIndex);
});
} else {
this.docs.forEach((doc, docIndex) => {
this._addObject(doc, docIndex);
});
}
this.norm.clear();
}
add(doc) {
const idx = this.size();
if (isString(doc)) {
this._addString(doc, idx);
} else {
this._addObject(doc, idx);
}
}
removeAt(idx) {
this.records.splice(idx, 1);
for (let i = idx, len = this.size(); i < len; i += 1) {
this.records[i].i -= 1;
}
}
getValueForItemAtKeyId(item, keyId) {
return item[this._keysMap[keyId]];
}
size() {
return this.records.length;
}
_addString(doc, docIndex) {
if (!isDefined(doc) || isBlank(doc)) {
return;
}
let record = {
v: doc,
i: docIndex,
n: this.norm.get(doc)
};
this.records.push(record);
}
_addObject(doc, docIndex) {
let record = { i: docIndex, $: {} };
this.keys.forEach((key, keyIndex) => {
let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);
if (!isDefined(value)) {
return;
}
if (isArray(value)) {
let subRecords = [];
const stack = [{ nestedArrIndex: -1, value }];
while (stack.length) {
const { nestedArrIndex, value: value2 } = stack.pop();
if (!isDefined(value2)) {
continue;
}
if (isString(value2) && !isBlank(value2)) {
let subRecord = {
v: value2,
i: nestedArrIndex,
n: this.norm.get(value2)
};
subRecords.push(subRecord);
} else if (isArray(value2)) {
value2.forEach((item, k) => {
stack.push({
nestedArrIndex: k,
value: item
});
});
} else
;
}
record.$[keyIndex] = subRecords;
} else if (isString(value) && !isBlank(value)) {
let subRecord = {
v: value,
n: this.norm.get(value)
};
record.$[keyIndex] = subRecord;
}
});
this.records.push(record);
}
toJSON() {
return {
keys: this.keys,
records: this.records
};
}
};
function createIndex(keys, docs, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
const myIndex = new FuseIndex({ getFn, fieldNormWeight });
myIndex.setKeys(keys.map(createKey));
myIndex.setSources(docs);
myIndex.create();
return myIndex;
}
function parseIndex(data, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
const { keys, records } = data;
const myIndex = new FuseIndex({ getFn, fieldNormWeight });
myIndex.setKeys(keys);
myIndex.setIndexRecords(records);
return myIndex;
}
function computeScore$1(pattern, {
errors = 0,
currentLocation = 0,
expectedLocation = 0,
distance = Config.distance,
ignoreLocation = Config.ignoreLocation
} = {}) {
const accuracy = errors / pattern.length;
if (ignoreLocation) {
return accuracy;
}
const proximity = Math.abs(expectedLocation - currentLocation);
if (!distance) {
return proximity ? 1 : accuracy;
}
return accuracy + proximity / distance;
}
function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) {
let indices = [];
let start = -1;
let end = -1;
let i = 0;
for (let len = matchmask.length; i < len; i += 1) {
let match = matchmask[i];
if (match && start === -1) {
start = i;
} else if (!match && start !== -1) {
end = i - 1;
if (end - start + 1 >= minMatchCharLength) {
indices.push([start, end]);
}
start = -1;
}
}
if (matchmask[i - 1] && i - start >= minMatchCharLength) {
indices.push([start, i - 1]);
}
return indices;
}
var MAX_BITS = 32;
function search(text2, pattern, patternAlphabet, {
location = Config.location,
distance = Config.distance,
threshold = Config.threshold,
findAllMatches = Config.findAllMatches,
minMatchCharLength = Config.minMatchCharLength,
includeMatches = Config.includeMatches,
ignoreLocation = Config.ignoreLocation
} = {}) {
if (pattern.length > MAX_BITS) {
throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS));
}
const patternLen = pattern.length;
const textLen = text2.length;
const expectedLocation = Math.max(0, Math.min(location, textLen));
let currentThreshold = threshold;
let bestLocation = expectedLocation;
const computeMatches = minMatchCharLength > 1 || includeMatches;
const matchMask = computeMatches ? Array(textLen) : [];
let index;
while ((index = text2.indexOf(pattern, bestLocation)) > -1) {
let score = computeScore$1(pattern, {
currentLocation: index,
expectedLocation,
distance,
ignoreLocation
});
currentThreshold = Math.min(score, currentThreshold);
bestLocation = index + patternLen;
if (computeMatches) {
let i = 0;
while (i < patternLen) {
matchMask[index + i] = 1;
i += 1;
}
}
}
bestLocation = -1;
let lastBitArr = [];
let finalScore = 1;
let binMax = patternLen + textLen;
const mask = 1 << patternLen - 1;
for (let i = 0; i < patternLen; i += 1) {
let binMin = 0;
let binMid = binMax;
while (binMin < binMid) {
const score2 = computeScore$1(pattern, {
errors: i,
currentLocation: expectedLocation + binMid,
expectedLocation,
distance,
ignoreLocation
});
if (score2 <= currentThreshold) {
binMin = binMid;
} else {
binMax = binMid;
}
binMid = Math.floor((binMax - binMin) / 2 + binMin);
}
binMax = binMid;
let start = Math.max(1, expectedLocation - binMid + 1);
let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen;
let bitArr = Array(finish + 2);
bitArr[finish + 1] = (1 << i) - 1;
for (let j = finish; j >= start; j -= 1) {
let currentLocation = j - 1;
let charMatch = patternAlphabet[text2.charAt(currentLocation)];
if (computeMatches) {
matchMask[currentLocation] = +!!charMatch;
}
bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch;
if (i) {
bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1];
}
if (bitArr[j] & mask) {
finalScore = computeScore$1(pattern, {
errors: i,
currentLocation,
expectedLocation,
distance,
ignoreLocation
});
if (finalScore <= currentThreshold) {
currentThreshold = finalScore;
bestLocation = currentLocation;
if (bestLocation <= expectedLocation) {
break;
}
start = Math.max(1, 2 * expectedLocation - bestLocation);
}
}
}
const score = computeScore$1(pattern, {
errors: i + 1,
currentLocation: expectedLocation,
expectedLocation,
distance,
ignoreLocation
});
if (score > currentThreshold) {
break;
}
lastBitArr = bitArr;
}
const result = {
isMatch: bestLocation >= 0,
score: Math.max(1e-3, finalScore)
};
if (computeMatches) {
const indices = convertMaskToIndices(matchMask, minMatchCharLength);
if (!indices.length) {
result.isMatch = false;
} else if (includeMatches) {
result.indices = indices;
}
}
return result;
}
function createPatternAlphabet(pattern) {
let mask = {};
for (let i = 0, len = pattern.length; i < len; i += 1) {
const char = pattern.charAt(i);
mask[char] = (mask[char] || 0) | 1 << len - i - 1;
}
return mask;
}
var BitapSearch = class {
constructor(pattern, {
location = Config.location,
threshold = Config.threshold,
distance = Config.distance,
includeMatches = Config.includeMatches,
findAllMatches = Config.findAllMatches,
minMatchCharLength = Config.minMatchCharLength,
isCaseSensitive = Config.isCaseSensitive,
ignoreLocation = Config.ignoreLocation
} = {}) {
this.options = {
location,
threshold,
distance,
includeMatches,
findAllMatches,
minMatchCharLength,
isCaseSensitive,
ignoreLocation
};
this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
this.chunks = [];
if (!this.pattern.length) {
return;
}
const addChunk = (pattern2, startIndex) => {
this.chunks.push({
pattern: pattern2,
alphabet: createPatternAlphabet(pattern2),
startIndex
});
};
const len = this.pattern.length;
if (len > MAX_BITS) {
let i = 0;
const remainder = len % MAX_BITS;
const end = len - remainder;
while (i < end) {
addChunk(this.pattern.substr(i, MAX_BITS), i);
i += MAX_BITS;
}
if (remainder) {
const startIndex = len - MAX_BITS;
addChunk(this.pattern.substr(startIndex), startIndex);
}
} else {
addChunk(this.pattern, 0);
}
}
searchIn(text2) {
const { isCaseSensitive, includeMatches } = this.options;
if (!isCaseSensitive) {
text2 = text2.toLowerCase();
}
if (this.pattern === text2) {
let result2 = {
isMatch: true,
score: 0
};
if (includeMatches) {
result2.indices = [[0, text2.length - 1]];
}
return result2;
}
const {
location,
distance,
threshold,
findAllMatches,
minMatchCharLength,
ignoreLocation
} = this.options;
let allIndices = [];
let totalScore = 0;
let hasMatches = false;
this.chunks.forEach(({ pattern, alphabet, startIndex }) => {
const { isMatch, score, indices } = search(text2, pattern, alphabet, {
location: location + startIndex,
distance,
threshold,
findAllMatches,
minMatchCharLength,
includeMatches,
ignoreLocation
});
if (isMatch) {
hasMatches = true;
}
totalScore += score;
if (isMatch && indices) {
allIndices = [...allIndices, ...indices];
}
});
let result = {
isMatch: hasMatches,
score: hasMatches ? totalScore / this.chunks.length : 1
};
if (hasMatches && includeMatches) {
result.indices = allIndices;
}
return result;
}
};
var BaseMatch = class {
constructor(pattern) {
this.pattern = pattern;
}
static isMultiMatch(pattern) {
return getMatch(pattern, this.multiRegex);
}
static isSingleMatch(pattern) {
return getMatch(pattern, this.singleRegex);
}
search() {
}
};
function getMatch(pattern, exp) {
const matches = pattern.match(exp);
return matches ? matches[1] : null;
}
var ExactMatch = class extends BaseMatch {
constructor(pattern) {
super(pattern);
}
static get type() {
return "exact";
}
static get multiRegex() {
return /^="(.*)"$/;
}
static get singleRegex() {
return /^=(.*)$/;
}
search(text2) {
const isMatch = text2 === this.pattern;
return {
isMatch,
score: isMatch ? 0 : 1,
indices: [0, this.pattern.length - 1]
};
}
};
var InverseExactMatch = class extends BaseMatch {
constructor(pattern) {
super(pattern);
}
static get type() {
return "inverse-exact";
}
static get multiRegex() {
return /^!"(.*)"$/;
}
static get singleRegex() {
return /^!(.*)$/;
}
search(text2) {
const index = text2.indexOf(this.pattern);
const isMatch = index === -1;
return {
isMatch,
score: isMatch ? 0 : 1,
indices: [0, text2.length - 1]
};
}
};
var PrefixExactMatch = class extends BaseMatch {
constructor(pattern) {
super(pattern);
}
static get type() {
return "prefix-exact";
}
static get multiRegex() {
return /^\^"(.*)"$/;
}
static get singleRegex() {
return /^\^(.*)$/;
}
search(text2) {
const isMatch = text2.startsWith(this.pattern);
return {
isMatch,
score: isMatch ? 0 : 1,
indices: [0, this.pattern.length - 1]
};
}
};
var InversePrefixExactMatch = class extends BaseMatch {
constructor(pattern) {
super(pattern);
}
static get type() {
return "inverse-prefix-exact";
}
static get multiRegex() {
return /^!\^"(.*)"$/;
}
static get singleRegex() {
return /^!\^(.*)$/;
}
search(text2) {
const isMatch = !text2.startsWith(this.pattern);
return {
isMatch,
score: isMatch ? 0 : 1,
indices: [0, text2.length - 1]
};
}
};
var SuffixExactMatch = class extends BaseMatch {
constructor(pattern) {
super(pattern);
}
static get type() {
return "suffix-exact";
}
static get multiRegex() {
return /^"(.*)"\$$/;
}
static get singleRegex() {
return /^(.*)\$$/;
}
search(text2) {
const isMatch = text2.endsWith(this.pattern);
return {
isMatch,
score: isMatch ? 0 : 1,
indices: [text2.length - this.pattern.length, text2.length - 1]
};
}
};
var InverseSuffixExactMatch = class extends BaseMatch {
constructor(pattern) {
super(pattern);
}
static get type() {
return "inverse-suffix-exact";
}
static get multiRegex() {
return /^!"(.*)"\$$/;
}
static get singleRegex() {
return /^!(.*)\$$/;
}
search(text2) {
const isMatch = !text2.endsWith(this.pattern);
return {
isMatch,
score: isMatch ? 0 : 1,
indices: [0, text2.length - 1]
};
}
};
var FuzzyMatch = class extends BaseMatch {
constructor(pattern, {
location = Config.location,
threshold = Config.threshold,
distance = Config.distance,
includeMatches = Config.includeMatches,
findAllMatches = Config.findAllMatches,
minMatchCharLength = Config.minMatchCharLength,
isCaseSensitive = Config.isCaseSensitive,
ignoreLocation = Config.ignoreLocation
} = {}) {
super(pattern);
this._bitapSearch = new BitapSearch(pattern, {
location,
threshold,
distance,
includeMatches,
findAllMatches,
minMatchCharLength,
isCaseSensitive,
ignoreLocation
});
}
static get type() {
return "fuzzy";
}
static get multiRegex() {
return /^"(.*)"$/;
}
static get singleRegex() {
return /^(.*)$/;
}
search(text2) {
return this._bitapSearch.searchIn(text2);
}
};
var IncludeMatch = class extends BaseMatch {
constructor(pattern) {
super(pattern);
}
static get type() {
return "include";
}
static get multiRegex() {
return /^'"(.*)"$/;
}
static get singleRegex() {
return /^'(.*)$/;
}
search(text2) {
let location = 0;
let index;
const indices = [];
const patternLen = this.pattern.length;
while ((index = text2.indexOf(this.pattern, location)) > -1) {
location = index + patternLen;
indices.push([index, location - 1]);
}
const isMatch = !!indices.length;
return {
isMatch,
score: isMatch ? 0 : 1,
indices
};
}
};
var searchers = [
ExactMatch,
IncludeMatch,
PrefixExactMatch,
InversePrefixExactMatch,
InverseSuffixExactMatch,
SuffixExactMatch,
InverseExactMatch,
FuzzyMatch
];
var searchersLen = searchers.length;
var SPACE_RE = / +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;
var OR_TOKEN = "|";
function parseQuery(pattern, options = {}) {
return pattern.split(OR_TOKEN).map((item) => {
let query = item.trim().split(SPACE_RE).filter((item2) => item2 && !!item2.trim());
let results = [];
for (let i = 0, len = query.length; i < len; i += 1) {
const queryItem = query[i];
let found = false;
let idx = -1;
while (!found && ++idx < searchersLen) {
const searcher = searchers[idx];
let token = searcher.isMultiMatch(queryItem);
if (token) {
results.push(new searcher(token, options));
found = true;
}
}
if (found) {
continue;
}
idx = -1;
while (++idx < searchersLen) {
const searcher = searchers[idx];
let token = searcher.isSingleMatch(queryItem);
if (token) {
results.push(new searcher(token, options));
break;
}
}
}
return results;
});
}
var MultiMatchSet = /* @__PURE__ */ new Set([FuzzyMatch.type, IncludeMatch.type]);
var ExtendedSearch = class {
constructor(pattern, {
isCaseSensitive = Config.isCaseSensitive,
includeMatches = Config.includeMatches,
minMatchCharLength = Config.minMatchCharLength,
ignoreLocation = Config.ignoreLocation,
findAllMatches = Config.findAllMatches,
location = Config.location,
threshold = Config.threshold,
distance = Config.distance
} = {}) {
this.query = null;
this.options = {
isCaseSensitive,
includeMatches,
minMatchCharLength,
findAllMatches,
ignoreLocation,
location,
threshold,
distance
};
this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
this.query = parseQuery(this.pattern, this.options);
}
static condition(_, options) {
return options.useExtendedSearch;
}
searchIn(text2) {
const query = this.query;
if (!query) {
return {
isMatch: false,
score: 1
};
}
const { includeMatches, isCaseSensitive } = this.options;
text2 = isCaseSensitive ? text2 : text2.toLowerCase();
let numMatches = 0;
let allIndices = [];
let totalScore = 0;
for (let i = 0, qLen = query.length; i < qLen; i += 1) {
const searchers2 = query[i];
allIndices.length = 0;
numMatches = 0;
for (let j = 0, pLen = searchers2.length; j < pLen; j += 1) {
const searcher = searchers2[j];
const { isMatch, indices, score } = searcher.search(text2);
if (isMatch) {
numMatches += 1;
totalScore += score;
if (includeMatches) {
const type = searcher.constructor.type;
if (MultiMatchSet.has(type)) {
allIndices = [...allIndices, ...indices];
} else {
allIndices.push(indices);
}
}
} else {
totalScore = 0;
numMatches = 0;
allIndices.length = 0;
break;
}
}
if (numMatches) {
let result = {
isMatch: true,
score: totalScore / numMatches
};
if (includeMatches) {
result.indices = allIndices;
}
return result;
}
}
return {
isMatch: false,
score: 1
};
}
};
var registeredSearchers = [];
function register(...args) {
registeredSearchers.push(...args);
}
function createSearcher(pattern, options) {
for (let i = 0, len = registeredSearchers.length; i < len; i += 1) {
let searcherClass = registeredSearchers[i];
if (searcherClass.condition(pattern, options)) {
return new searcherClass(pattern, options);
}
}
return new BitapSearch(pattern, options);
}
var LogicalOperator = {
AND: "$and",
OR: "$or"
};
var KeyType = {
PATH: "$path",
PATTERN: "$val"
};
var isExpression = (query) => !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]);
var isPath = (query) => !!query[KeyType.PATH];
var isLeaf = (query) => !isArray(query) && isObject(query) && !isExpression(query);
var convertToExplicit = (query) => ({
[LogicalOperator.AND]: Object.keys(query).map((key) => ({
[key]: query[key]
}))
});
function parse(query, options, { auto: auto2 = true } = {}) {
const next = (query2) => {
let keys = Object.keys(query2);
const isQueryPath = isPath(query2);
if (!isQueryPath && keys.length > 1 && !isExpression(query2)) {
return next(convertToExplicit(query2));
}
if (isLeaf(query2)) {
const key = isQueryPath ? query2[KeyType.PATH] : keys[0];
const pattern = isQueryPath ? query2[KeyType.PATTERN] : query2[key];
if (!isString(pattern)) {
throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key));
}
const obj = {
keyId: createKeyId(key),
pattern
};
if (auto2) {
obj.searcher = createSearcher(pattern, options);
}
return obj;
}
let node = {
children: [],
operator: keys[0]
};
keys.forEach((key) => {
const value = query2[key];
if (isArray(value)) {
value.forEach((item) => {
node.children.push(next(item));
});
}
});
return node;
};
if (!isExpression(query)) {
query = convertToExplicit(query);
}
return next(query);
}
function computeScore(results, { ignoreFieldNorm = Config.ignoreFieldNorm }) {
results.forEach((result) => {
let totalScore = 1;
result.matches.forEach(({ key, norm: norm2, score }) => {
const weight = key ? key.weight : null;
totalScore *= Math.pow(score === 0 && weight ? Number.EPSILON : score, (weight || 1) * (ignoreFieldNorm ? 1 : norm2));
});
result.score = totalScore;
});
}
function transformMatches(result, data) {
const matches = result.matches;
data.matches = [];
if (!isDefined(matches)) {
return;
}
matches.forEach((match) => {
if (!isDefined(match.indices) || !match.indices.length) {
return;
}
const { indices, value } = match;
let obj = {
indices,
value
};
if (match.key) {
obj.key = match.key.src;
}
if (match.idx > -1) {
obj.refIndex = match.idx;
}
data.matches.push(obj);
});
}
function transformScore(result, data) {
data.score = result.score;
}
function format(results, docs, {
includeMatches = Config.includeMatches,
includeScore = Config.includeScore
} = {}) {
const transformers = [];
if (includeMatches)
transformers.push(transformMatches);
if (includeScore)
transformers.push(transformScore);
return results.map((result) => {
const { idx } = result;
const data = {
item: docs[idx],
refIndex: idx
};
if (transformers.length) {
transformers.forEach((transformer) => {
transformer(result, data);
});
}
return data;
});
}
var Fuse = class {
constructor(docs, options = {}, index) {
this.options = { ...Config, ...options };
if (this.options.useExtendedSearch && false) {
throw new Error(EXTENDED_SEARCH_UNAVAILABLE);
}
this._keyStore = new KeyStore(this.options.keys);
this.setCollection(docs, index);
}
setCollection(docs, index) {
this._docs = docs;
if (index && !(index instanceof FuseIndex)) {
throw new Error(INCORRECT_INDEX_TYPE);
}
this._myIndex = index || createIndex(this.options.keys, this._docs, {
getFn: this.options.getFn,
fieldNormWeight: this.options.fieldNormWeight
});
}
add(doc) {
if (!isDefined(doc)) {
return;
}
this._docs.push(doc);
this._myIndex.add(doc);
}
remove(predicate = () => false) {
const results = [];
for (let i = 0, len = this._docs.length; i < len; i += 1) {
const doc = this._docs[i];
if (predicate(doc, i)) {
this.removeAt(i);
i -= 1;
len -= 1;
results.push(doc);
}
}
return results;
}
removeAt(idx) {
this._docs.splice(idx, 1);
this._myIndex.removeAt(idx);
}
getIndex() {
return this._myIndex;
}
search(query, { limit = -1 } = {}) {
const {
includeMatches,
includeScore,
shouldSort,
sortFn,
ignoreFieldNorm
} = this.options;
let results = isString(query) ? isString(this._docs[0]) ? this._searchStringList(query) : this._searchObjectList(query) : this._searchLogical(query);
computeScore(results, { ignoreFieldNorm });
if (shouldSort) {
results.sort(sortFn);
}
if (isNumber(limit) && limit > -1) {
results = results.slice(0, limit);
}
return format(results, this._docs, {
includeMatches,
includeScore
});
}
_searchStringList(query) {
const searcher = createSearcher(query, this.options);
const { records } = this._myIndex;
const results = [];
records.forEach(({ v: text2, i: idx, n: norm2 }) => {
if (!isDefined(text2)) {
return;
}
const { isMatch, score, indices } = searcher.searchIn(text2);
if (isMatch) {
results.push({
item: text2,
idx,
matches: [{ score, value: text2, norm: norm2, indices }]
});
}
});
return results;
}
_searchLogical(query) {
const expression = parse(query, this.options);
const evaluate = (node, item, idx) => {
if (!node.children) {
const { keyId, searcher } = node;
const matches = this._findMatches({
key: this._keyStore.get(keyId),
value: this._myIndex.getValueForItemAtKeyId(item, keyId),
searcher
});
if (matches && matches.length) {
return [
{
idx,
item,
matches
}
];
}
return [];
}
const res = [];
for (let i = 0, len = node.children.length; i < len; i += 1) {
const child = node.children[i];
const result = evaluate(child, item, idx);
if (result.length) {
res.push(...result);
} else if (node.operator === LogicalOperator.AND) {
return [];
}
}
return res;
};
const records = this._myIndex.records;
const resultMap = {};
const results = [];
records.forEach(({ $: item, i: idx }) => {
if (isDefined(item)) {
let expResults = evaluate(expression, item, idx);
if (expResults.length) {
if (!resultMap[idx]) {
resultMap[idx] = { idx, item, matches: [] };
results.push(resultMap[idx]);
}
expResults.forEach(({ matches }) => {
resultMap[idx].matches.push(...matches);
});
}
}
});
return results;
}
_searchObjectList(query) {
const searcher = createSearcher(query, this.options);
const { keys, records } = this._myIndex;
const results = [];
records.forEach(({ $: item, i: idx }) => {
if (!isDefined(item)) {
return;
}
let matches = [];
keys.forEach((key, keyIndex) => {
matches.push(...this._findMatches({
key,
value: item[keyIndex],
searcher
}));
});
if (matches.length) {
results.push({
idx,
item,
matches
});
}
});
return results;
}
_findMatches({ key, value, searcher }) {
if (!isDefined(value)) {
return [];
}
let matches = [];
if (isArray(value)) {
value.forEach(({ v: text2, i: idx, n: norm2 }) => {
if (!isDefined(text2)) {
return;
}
const { isMatch, score, indices } = searcher.searchIn(text2);
if (isMatch) {
matches.push({
score,
key,
value: text2,
idx,
norm: norm2,
indices
});
}
});
} else {
const { v: text2, n: norm2 } = value;
const { isMatch, score, indices } = searcher.searchIn(text2);
if (isMatch) {
matches.push({ score, key, value: text2, norm: norm2, indices });
}
}
return matches;
}
};
Fuse.version = "6.6.2";
Fuse.createIndex = createIndex;
Fuse.parseIndex = parseIndex;
Fuse.config = Config;
{
Fuse.parseQuery = parse;
}
{
register(ExtendedSearch);
}
// src/utility/getUrlExtension.ts
function getUrlExtension(url) {
const regexp = new RegExp(/\.([0-9a-z]+)(?:[?#]|$)/i);
const match = regexp.exec(url);
if (!match) {
return "";
}
const [, extension] = match;
return extension;
}
// src/TemplateEngine.ts
function useTemplateEngine() {
const tags = {};
function addTag(tag, value) {
tags[tag] = value;
}
function replacer(template) {
return template.replace(/\{\{(.*?)(:\s*?.+?)?\}\}/g, (match, tagId, params) => {
const tagValue = tags[tagId.toLowerCase()];
if (tagValue === null || tagValue === void 0) {
const fuse = new Fuse(Object.keys(tags), {
shouldSort: true,
findAllMatches: false,
threshold: 0.4,
isCaseSensitive: false
});
const similarTag = fuse.search(tagId);
new import_obsidian9.Notice(`Tag ${tagId} is invalid.${similarTag.length > 0 ? ` Did you mean ${similarTag[0].item}?` : ""}`);
return match;
}
if (typeof tagValue === "function") {
if (params) {
const splitParams = params.slice(1).split(",");
const args = Array.isArray(splitParams) ? splitParams : [params];
return tagValue(...args);
}
return tagValue();
}
return tagValue;
});
}
return [replacer, addTag];
}
function NoteTemplateEngine(template, episode) {
const [replacer, addTag] = useTemplateEngine();
addTag("title", episode.title);
addTag("description", (prependToLines) => {
const sanitizeDescription = (0, import_obsidian9.htmlToMarkdown)(episode.description).replace(/\n{3,}/g, "\n\n");
if (prependToLines) {
return sanitizeDescription.split("\n").map((str2) => `${prependToLines}${str2}`).join("\n");
}
return sanitizeDescription;
});
addTag("content", (prependToLines) => {
if (prependToLines) {
return (0, import_obsidian9.htmlToMarkdown)(episode.content).split("\n").map((str2) => `${prependToLines}${str2}`).join("\n");
}
return (0, import_obsidian9.htmlToMarkdown)(episode.content);
});
addTag("safetitle", replaceIllegalFileNameCharactersInString(episode.title));
addTag("url", episode.url);
addTag("date", (format2) => episode.episodeDate ? window.moment(episode.episodeDate).format(format2 ?? "YYYY-MM-DD") : "");
addTag("podcast", replaceIllegalFileNameCharactersInString(episode.podcastName));
addTag("artwork", episode.artworkUrl ?? "");
return replacer(template);
}
function TimestampTemplateEngine(template) {
const [replacer, addTag] = useTemplateEngine();
addTag("time", (format2) => get_store_value(plugin).api.getPodcastTimeFormatted(format2 ?? "HH:mm:ss"));
addTag("linktime", (format2) => get_store_value(plugin).api.getPodcastTimeFormatted(format2 ?? "HH:mm:ss", true));
return replacer(template);
}
function FilePathTemplateEngine(template, episode) {
const [replacer, addTag] = useTemplateEngine();
addTag("title", (whitespaceReplacement) => {
const legalTitle = replaceIllegalFileNameCharactersInString(episode.title);
if (whitespaceReplacement) {
return legalTitle.replace(/\s+/g, whitespaceReplacement);
}
return legalTitle;
});
addTag("podcast", (whitespaceReplacement) => {
const legalName = replaceIllegalFileNameCharactersInString(episode.podcastName);
if (whitespaceReplacement) {
return legalName.replace(/\s+/g, whitespaceReplacement);
}
return legalName;
});
addTag("date", (format2) => episode.episodeDate ? window.moment(episode.episodeDate).format(format2 ?? "YYYY-MM-DD") : "");
return replacer(template);
}
function DownloadPathTemplateEngine(template, episode) {
const templateExtension = getUrlExtension(template);
const templateWithoutExtension = templateExtension ? template.replace(templateExtension, "") : template;
const [replacer, addTag] = useTemplateEngine();
addTag("title", (whitespaceReplacement) => {
const legalTitle = replaceIllegalFileNameCharactersInString(episode.title);
if (whitespaceReplacement) {
return legalTitle.replace(/\s+/g, whitespaceReplacement);
}
return legalTitle;
});
addTag("podcast", (whitespaceReplacement) => {
const legalName = replaceIllegalFileNameCharactersInString(episode.podcastName);
if (whitespaceReplacement) {
return legalName.replace(/\s+/g, whitespaceReplacement);
}
return legalName;
});
addTag("date", (format2) => episode.episodeDate ? window.moment(episode.episodeDate).format(format2 ?? "YYYY-MM-DD") : "");
return replacer(templateWithoutExtension);
}
function TranscriptTemplateEngine(template, episode, transcription) {
const [replacer, addTag] = useTemplateEngine();
addTag("title", (whitespaceReplacement) => {
const legalTitle = replaceIllegalFileNameCharactersInString(episode.title);
if (whitespaceReplacement) {
return legalTitle.replace(/\s+/g, whitespaceReplacement);
}
return legalTitle;
});
addTag("podcast", (whitespaceReplacement) => {
const legalName = replaceIllegalFileNameCharactersInString(episode.podcastName);
if (whitespaceReplacement) {
return legalName.replace(/\s+/g, whitespaceReplacement);
}
return legalName;
});
addTag("date", (format2) => episode.episodeDate ? window.moment(episode.episodeDate).format(format2 ?? "YYYY-MM-DD") : "");
addTag("transcript", transcription);
addTag("description", (prependToLines) => {
if (prependToLines) {
return (0, import_obsidian9.htmlToMarkdown)(episode.description).split("\n").map((str2) => `${prependToLines}${str2}`).join("\n");
}
return (0, import_obsidian9.htmlToMarkdown)(episode.description);
});
addTag("url", episode.url);
addTag("artwork", episode.artworkUrl ?? "");
return replacer(template);
}
function replaceIllegalFileNameCharactersInString(string) {
return string.replace(/[\\,#%&{}/*<>$'":@\u2023|\\.]/g, "").replace(/\n/, " ").replace(" ", " ");
}
// src/opml.ts
var import_obsidian10 = require("obsidian");
function TimerNotice(heading, initialMessage) {
let currentMessage = initialMessage;
const startTime = Date.now();
let stopTime;
const notice = new import_obsidian10.Notice(initialMessage, 0);
function formatMsg(message) {
return `${heading} (${getTime()}):
${message}`;
}
function update2(message) {
currentMessage = message;
notice.setMessage(formatMsg(currentMessage));
}
const interval = setInterval(() => {
notice.setMessage(formatMsg(currentMessage));
}, 1e3);
function getTime() {
return formatTime(stopTime ? stopTime - startTime : Date.now() - startTime);
}
return {
update: update2,
hide: () => notice.hide(),
stop: () => {
stopTime = Date.now();
clearInterval(interval);
}
};
}
function formatTime(ms) {
const seconds = Math.floor(ms / 1e3);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
return `${hours.toString().padStart(2, "0")}:${(minutes % 60).toString().padStart(2, "0")}:${(seconds % 60).toString().padStart(2, "0")}`;
}
async function importOPML(opml) {
try {
const dp = new DOMParser();
const dom = dp.parseFromString(opml, "application/xml");
if (dom.documentElement.nodeName === "parsererror") {
throw new Error("Invalid XML format");
}
const podcastEntryNodes = dom.querySelectorAll("outline[text][xmlUrl]");
const incompletePodcastsToAdd = [];
for (let i = 0; i < podcastEntryNodes.length; i++) {
const node = podcastEntryNodes.item(i);
const text2 = node.getAttribute("text");
const xmlUrl = node.getAttribute("xmlUrl");
if (!text2 || !xmlUrl) {
continue;
}
incompletePodcastsToAdd.push({
title: text2,
url: xmlUrl
});
}
if (incompletePodcastsToAdd.length === 0) {
throw new Error("No valid podcast entries found in OPML");
}
const existingSavedFeeds = get_store_value(savedFeeds);
const newPodcastsToAdd = incompletePodcastsToAdd.filter((pod) => !Object.values(existingSavedFeeds).some((savedPod) => savedPod.url === pod.url));
const notice = TimerNotice("Importing podcasts", "Preparing to import...");
let completedImports = 0;
const updateProgress = () => {
const progress = (completedImports / newPodcastsToAdd.length * 100).toFixed(1);
notice.update(`Importing... ${completedImports}/${newPodcastsToAdd.length} podcasts completed (${progress}%)`);
};
updateProgress();
const podcasts = await Promise.all(newPodcastsToAdd.map(async (feed) => {
try {
const result = await new FeedParser().getFeed(feed.url);
completedImports++;
updateProgress();
return result;
} catch (error) {
console.error(`Failed to fetch feed for ${feed.title}: ${error}`);
completedImports++;
updateProgress();
return null;
}
}));
notice.stop();
const validPodcasts = podcasts.filter((pod) => pod !== null);
savedFeeds.update((feeds) => {
for (const pod of validPodcasts) {
if (feeds[pod.title])
continue;
feeds[pod.title] = structuredClone(pod);
}
return feeds;
});
const skippedCount = incompletePodcastsToAdd.length - newPodcastsToAdd.length;
notice.update(`OPML import complete. Saved ${validPodcasts.length} new podcasts. Skipped ${skippedCount} existing podcasts.`);
if (validPodcasts.length !== newPodcastsToAdd.length) {
const failedImports = newPodcastsToAdd.length - validPodcasts.length;
console.error(`Failed to import ${failedImports} podcasts.`);
new import_obsidian10.Notice(`Failed to import ${failedImports} podcasts. Check console for details.`, 1e4);
}
setTimeout(() => notice.hide(), 5e3);
} catch (error) {
console.error("Error importing OPML:", error);
new import_obsidian10.Notice(`Error importing OPML: ${error instanceof Error ? error.message : "Unknown error"}`, 1e4);
}
}
async function exportOPML(app2, feeds, filePath = "PodNotes_Export.opml") {
const header = ``;
const opml = (child) => `
No saved podcasts.
`; }, m(target, anchor) { insert(target, div, anchor); }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) detach(div); } }; } function create_if_block4(ctx) { let each_1_anchor; let current; let each_value = ctx[0]; let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { each_blocks[i] = create_each_block3(get_each_context3(ctx, each_value, i)); } const out = (i) => transition_out(each_blocks[i], 1, 1, () => { each_blocks[i] = null; }); return { c() { for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } each_1_anchor = empty(); }, m(target, anchor) { for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].m(target, anchor); } insert(target, each_1_anchor, anchor); current = true; }, p(ctx2, dirty) { if (dirty & 1) { each_value = ctx2[0]; let i; for (i = 0; i < each_value.length; i += 1) { const child_ctx = get_each_context3(ctx2, each_value, i); if (each_blocks[i]) { each_blocks[i].p(child_ctx, dirty); transition_in(each_blocks[i], 1); } else { each_blocks[i] = create_each_block3(child_ctx); each_blocks[i].c(); transition_in(each_blocks[i], 1); each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor); } } group_outros(); for (i = each_value.length; i < each_blocks.length; i += 1) { out(i); } check_outros(); } }, i(local) { if (current) return; for (let i = 0; i < each_value.length; i += 1) { transition_in(each_blocks[i]); } current = true; }, o(local) { each_blocks = each_blocks.filter(Boolean); for (let i = 0; i < each_blocks.length; i += 1) { transition_out(each_blocks[i]); } current = false; }, d(detaching) { destroy_each(each_blocks, detaching); if (detaching) detach(each_1_anchor); } }; } function create_each_block3(ctx) { let podcastgridcard; let current; podcastgridcard = new PodcastGridCard_default({ props: { feed: ctx[5] } }); podcastgridcard.$on("clickPodcast", ctx[3]); return { c() { create_component(podcastgridcard.$$.fragment); }, m(target, anchor) { mount_component(podcastgridcard, target, anchor); current = true; }, p(ctx2, dirty) { const podcastgridcard_changes = {}; if (dirty & 1) podcastgridcard_changes.feed = ctx2[5]; podcastgridcard.$set(podcastgridcard_changes); }, i(local) { if (current) return; transition_in(podcastgridcard.$$.fragment, local); current = true; }, o(local) { transition_out(podcastgridcard.$$.fragment, local); current = false; }, d(detaching) { destroy_component(podcastgridcard, detaching); } }; } function create_fragment12(ctx) { let div; let t; let current_block_type_index; let if_block1; let current; let if_block0 = ctx[1].length > 0 && create_if_block_12(ctx); const if_block_creators = [create_if_block4, create_else_block2]; const if_blocks = []; function select_block_type(ctx2, dirty) { if (ctx2[0].length > 0) return 0; return 1; } current_block_type_index = select_block_type(ctx, -1); if_block1 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); return { c() { div = element("div"); if (if_block0) if_block0.c(); t = space(); if_block1.c(); attr(div, "class", "podcast-grid svelte-1xbcyvn"); }, m(target, anchor) { insert(target, div, anchor); if (if_block0) if_block0.m(div, null); append(div, t); if_blocks[current_block_type_index].m(div, null); current = true; }, p(ctx2, [dirty]) { if (ctx2[1].length > 0) { if (if_block0) { if_block0.p(ctx2, dirty); if (dirty & 2) { transition_in(if_block0, 1); } } else { if_block0 = create_if_block_12(ctx2); if_block0.c(); transition_in(if_block0, 1); if_block0.m(div, t); } } else if (if_block0) { group_outros(); transition_out(if_block0, 1, 1, () => { if_block0 = null; }); check_outros(); } let previous_block_index = current_block_type_index; current_block_type_index = select_block_type(ctx2, dirty); if (current_block_type_index === previous_block_index) { if_blocks[current_block_type_index].p(ctx2, dirty); } else { group_outros(); transition_out(if_blocks[previous_block_index], 1, 1, () => { if_blocks[previous_block_index] = null; }); check_outros(); if_block1 = if_blocks[current_block_type_index]; if (!if_block1) { if_block1 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); if_block1.c(); } else { if_block1.p(ctx2, dirty); } transition_in(if_block1, 1); if_block1.m(div, null); } }, i(local) { if (current) return; transition_in(if_block0); transition_in(if_block1); current = true; }, o(local) { transition_out(if_block0); transition_out(if_block1); current = false; }, d(detaching) { if (detaching) detach(div); if (if_block0) if_block0.d(); if_blocks[current_block_type_index].d(); } }; } function instance12($$self, $$props, $$invalidate) { let { feeds = [] } = $$props; let { playlists: playlists2 = [] } = $$props; const dispatch2 = createEventDispatcher(); function forwardClickPlaylist({ detail: { playlist, event } }) { dispatch2("clickPlaylist", { playlist, event }); } function clickPodcast_handler(event) { bubble.call(this, $$self, event); } $$self.$$set = ($$props2) => { if ("feeds" in $$props2) $$invalidate(0, feeds = $$props2.feeds); if ("playlists" in $$props2) $$invalidate(1, playlists2 = $$props2.playlists); }; return [feeds, playlists2, forwardClickPlaylist, clickPodcast_handler]; } var PodcastGrid = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance12, create_fragment12, safe_not_equal, { feeds: 0, playlists: 1 }, add_css9); } }; var PodcastGrid_default = PodcastGrid; // src/ui/obsidian/Slider.svelte var import_obsidian13 = require("obsidian"); function create_fragment13(ctx) { let span; return { c() { span = element("span"); }, m(target, anchor) { insert(target, span, anchor); ctx[4](span); }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) detach(span); ctx[4](null); } }; } function instance13($$self, $$props, $$invalidate) { let { value } = $$props; let { limits } = $$props; let sliderRef; const dispatch2 = createEventDispatcher(); let slider; let { style: styles } = $$props; onMount(() => { slider = new import_obsidian13.SliderComponent(sliderRef); updateSliderAttributes(slider); }); afterUpdate(() => { updateSliderAttributes(slider); }); function updateSliderAttributes(sldr) { if (value) sldr.setValue(value); if (limits) sldr.setLimits.apply(sldr, limits); if (styles) { sldr.sliderEl.setAttr("style", extractStylesFromObj(styles)); } sldr.onChange((value2) => { dispatch2("change", { value: value2 }); }); } function span_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { sliderRef = $$value; $$invalidate(0, sliderRef); }); } $$self.$$set = ($$props2) => { if ("value" in $$props2) $$invalidate(1, value = $$props2.value); if ("limits" in $$props2) $$invalidate(2, limits = $$props2.limits); if ("style" in $$props2) $$invalidate(3, styles = $$props2.style); }; return [sliderRef, value, limits, styles, span_binding]; } var Slider = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance13, create_fragment13, safe_not_equal, { value: 1, limits: 2, style: 3 }); } }; var Slider_default = Slider; // src/ui/PodcastView/Loading.svelte function add_css10(target) { append_styles(target, "svelte-11b4xh2", ".la-line-scale.svelte-11b4xh2.svelte-11b4xh2,.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2{position:relative;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.la-line-scale.svelte-11b4xh2.svelte-11b4xh2{display:block;font-size:0;color:#fff}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2{display:inline-block;float:none;background-color:currentColor;border:0 solid currentColor}.la-line-scale.svelte-11b4xh2.svelte-11b4xh2{width:40px;height:32px}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2{width:4px;height:32px;margin:2px;margin-top:0;margin-bottom:0;border-radius:0;-webkit-animation:svelte-11b4xh2-line-scale 1.2s infinite ease;-moz-animation:svelte-11b4xh2-line-scale 1.2s infinite ease;-o-animation:svelte-11b4xh2-line-scale 1.2s infinite ease;animation:svelte-11b4xh2-line-scale 1.2s infinite ease}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2:nth-child(1){-webkit-animation-delay:-1.2s;-moz-animation-delay:-1.2s;-o-animation-delay:-1.2s;animation-delay:-1.2s}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2:nth-child(2){-webkit-animation-delay:-1.1s;-moz-animation-delay:-1.1s;-o-animation-delay:-1.1s;animation-delay:-1.1s}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2:nth-child(3){-webkit-animation-delay:-1s;-moz-animation-delay:-1s;-o-animation-delay:-1s;animation-delay:-1s}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2:nth-child(4){-webkit-animation-delay:-.9s;-moz-animation-delay:-.9s;-o-animation-delay:-.9s;animation-delay:-.9s}.la-line-scale.svelte-11b4xh2>div.svelte-11b4xh2:nth-child(5){-webkit-animation-delay:-.8s;-moz-animation-delay:-.8s;-o-animation-delay:-.8s;animation-delay:-.8s}@-webkit-keyframes svelte-11b4xh2-line-scale{0%,40%,100%{-webkit-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);transform:scaleY(1)}}@-moz-keyframes svelte-11b4xh2-line-scale{0%,40%,100%{-webkit-transform:scaleY(.4);-moz-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);-moz-transform:scaleY(1);transform:scaleY(1)}}@-o-keyframes svelte-11b4xh2-line-scale{0%,40%,100%{-webkit-transform:scaleY(.4);-o-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1)}}@keyframes svelte-11b4xh2-line-scale{0%,40%,100%{-webkit-transform:scaleY(.4);-moz-transform:scaleY(.4);-o-transform:scaleY(.4);transform:scaleY(.4)}20%{-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1)}}"); } function create_fragment14(ctx) { let div5; return { c() { div5 = element("div"); div5.innerHTML = ` `; attr(div5, "class", "la-line-scale svelte-11b4xh2"); }, m(target, anchor) { insert(target, div5, anchor); }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) detach(div5); } }; } var Loading = class extends SvelteComponent { constructor(options) { super(); init(this, options, null, create_fragment14, safe_not_equal, {}, add_css10); } }; var Loading_default = Loading; // src/ui/common/IntersectionObserver.svelte function add_css11(target) { append_styles(target, "svelte-1kuj9kb", "div.svelte-1kuj9kb{width:100%;height:100%}"); } var get_default_slot_changes = (dirty) => ({ intersecting: dirty & 1 }); var get_default_slot_context = (ctx) => ({ intersecting: ctx[0] }); function create_fragment15(ctx) { let div; let current; const default_slot_template = ctx[8].default; const default_slot = create_slot(default_slot_template, ctx, ctx[7], get_default_slot_context); return { c() { div = element("div"); if (default_slot) default_slot.c(); attr(div, "class", "svelte-1kuj9kb"); }, m(target, anchor) { insert(target, div, anchor); if (default_slot) { default_slot.m(div, null); } ctx[9](div); current = true; }, p(ctx2, [dirty]) { if (default_slot) { if (default_slot.p && (!current || dirty & 129)) { update_slot_base(default_slot, default_slot_template, ctx2, ctx2[7], !current ? get_all_dirty_from_scope(ctx2[7]) : get_slot_changes(default_slot_template, ctx2[7], dirty, get_default_slot_changes), get_default_slot_context); } } }, i(local) { if (current) return; transition_in(default_slot, local); current = true; }, o(local) { transition_out(default_slot, local); current = false; }, d(detaching) { if (detaching) detach(div); if (default_slot) default_slot.d(detaching); ctx[9](null); } }; } function instance14($$self, $$props, $$invalidate) { let { $$slots: slots = {}, $$scope } = $$props; let { once = false } = $$props; let { top = 0 } = $$props; let { bottom = 0 } = $$props; let { left = 0 } = $$props; let { right = 0 } = $$props; let intersecting = false; let container; onMount(() => { if (typeof IntersectionObserver !== "undefined") { const rootMargin = `${bottom}px ${left}px ${top}px ${right}px`; const observer = new IntersectionObserver((entries) => { $$invalidate(0, intersecting = entries[0].isIntersecting); if (intersecting && once) { observer.unobserve(container); } }, { rootMargin }); observer.observe(container); return () => observer.unobserve(container); } function handler() { const bcr = container.getBoundingClientRect(); $$invalidate(0, intersecting = bcr.bottom + bottom > 0 && bcr.right + right > 0 && bcr.top - top < window.innerHeight && bcr.left - left < window.innerWidth); if (intersecting && once) { window.removeEventListener("scroll", handler); } } window.addEventListener("scroll", handler); return () => window.removeEventListener("scroll", handler); }); function div_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { container = $$value; $$invalidate(1, container); }); } $$self.$$set = ($$props2) => { if ("once" in $$props2) $$invalidate(2, once = $$props2.once); if ("top" in $$props2) $$invalidate(3, top = $$props2.top); if ("bottom" in $$props2) $$invalidate(4, bottom = $$props2.bottom); if ("left" in $$props2) $$invalidate(5, left = $$props2.left); if ("right" in $$props2) $$invalidate(6, right = $$props2.right); if ("$$scope" in $$props2) $$invalidate(7, $$scope = $$props2.$$scope); }; return [ intersecting, container, once, top, bottom, left, right, $$scope, slots, div_binding ]; } var IntersectionObserver_1 = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance14, create_fragment15, safe_not_equal, { once: 2, top: 3, bottom: 4, left: 5, right: 6 }, add_css11); } }; var IntersectionObserver_default = IntersectionObserver_1; // src/ui/common/ImageLoader.svelte function create_if_block5(ctx) { let image; let current; image = new Image_default({ props: { alt: ctx[1], src: ctx[0], fadeIn: ctx[2], class: ctx[3] } }); image.$on("click", ctx[5]); return { c() { create_component(image.$$.fragment); }, m(target, anchor) { mount_component(image, target, anchor); current = true; }, p(ctx2, dirty) { const image_changes = {}; if (dirty & 2) image_changes.alt = ctx2[1]; if (dirty & 1) image_changes.src = ctx2[0]; if (dirty & 4) image_changes.fadeIn = ctx2[2]; if (dirty & 8) image_changes.class = ctx2[3]; image.$set(image_changes); }, i(local) { if (current) return; transition_in(image.$$.fragment, local); current = true; }, o(local) { transition_out(image.$$.fragment, local); current = false; }, d(detaching) { destroy_component(image, detaching); } }; } function create_default_slot(ctx) { let if_block_anchor; let current; let if_block = ctx[6] && create_if_block5(ctx); return { c() { if (if_block) if_block.c(); if_block_anchor = empty(); }, m(target, anchor) { if (if_block) if_block.m(target, anchor); insert(target, if_block_anchor, anchor); current = true; }, p(ctx2, dirty) { if (ctx2[6]) { if (if_block) { if_block.p(ctx2, dirty); if (dirty & 64) { transition_in(if_block, 1); } } else { if_block = create_if_block5(ctx2); if_block.c(); transition_in(if_block, 1); if_block.m(if_block_anchor.parentNode, if_block_anchor); } } else if (if_block) { group_outros(); transition_out(if_block, 1, 1, () => { if_block = null; }); check_outros(); } }, i(local) { if (current) return; transition_in(if_block); current = true; }, o(local) { transition_out(if_block); current = false; }, d(detaching) { if (if_block) if_block.d(detaching); if (detaching) detach(if_block_anchor); } }; } function create_fragment16(ctx) { let intersectionobserver; let current; intersectionobserver = new IntersectionObserver_default({ props: { once: true, $$slots: { default: [ create_default_slot, ({ intersecting }) => ({ 6: intersecting }), ({ intersecting }) => intersecting ? 64 : 0 ] }, $$scope: { ctx } } }); return { c() { create_component(intersectionobserver.$$.fragment); }, m(target, anchor) { mount_component(intersectionobserver, target, anchor); current = true; }, p(ctx2, [dirty]) { const intersectionobserver_changes = {}; if (dirty & 207) { intersectionobserver_changes.$$scope = { dirty, ctx: ctx2 }; } intersectionobserver.$set(intersectionobserver_changes); }, i(local) { if (current) return; transition_in(intersectionobserver.$$.fragment, local); current = true; }, o(local) { transition_out(intersectionobserver.$$.fragment, local); current = false; }, d(detaching) { destroy_component(intersectionobserver, detaching); } }; } function instance15($$self, $$props, $$invalidate) { let { src } = $$props; let { alt } = $$props; let { fadeIn = false } = $$props; let { class: _class = "" } = $$props; const dispatcher = createEventDispatcher(); const click_handler = (event) => dispatcher("click", { event }); $$self.$$set = ($$props2) => { if ("src" in $$props2) $$invalidate(0, src = $$props2.src); if ("alt" in $$props2) $$invalidate(1, alt = $$props2.alt); if ("fadeIn" in $$props2) $$invalidate(2, fadeIn = $$props2.fadeIn); if ("class" in $$props2) $$invalidate(3, _class = $$props2.class); }; return [src, alt, fadeIn, _class, dispatcher, click_handler]; } var ImageLoader = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance15, create_fragment16, safe_not_equal, { src: 0, alt: 1, fadeIn: 2, class: 3 }); } }; var ImageLoader_default = ImageLoader; // src/ui/PodcastView/EpisodeListItem.svelte function add_css12(target) { append_styles(target, "svelte-1gcgk6w", ".podcast-episode-item.svelte-1gcgk6w{display:flex;flex-direction:row;justify-content:space-between;align-items:center;padding:0.5rem;width:100%;border:solid 1px var(--background-divider);gap:0.25rem}.podcast-episode-item.svelte-1gcgk6w:hover{background-color:var(--background-divider)}.podcast-episode-item.svelte-1gcgk6w:hover{cursor:pointer}.strikeout.svelte-1gcgk6w{text-decoration:line-through}.podcast-episode-information.svelte-1gcgk6w{display:flex;flex-direction:column;justify-content:space-between;align-items:left;width:100%}.episode-item-date.svelte-1gcgk6w{color:gray}.podcast-episode-thumbnail-container.svelte-1gcgk6w{flex-basis:20%;display:flex;align-items:center;justify-content:center}.podcast-episode-thumbnail{border-radius:15%;max-width:5rem;max-height:5rem;cursor:pointer !important}"); } function create_if_block_13(ctx) { let div; return { c() { div = element("div"); attr(div, "class", "podcast-episode-thumbnail-container svelte-1gcgk6w"); }, m(target, anchor) { insert(target, div, anchor); }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) detach(div); } }; } function create_if_block6(ctx) { let div; let imageloader; let current; imageloader = new ImageLoader_default({ props: { src: ctx[0].artworkUrl, alt: ctx[0].title, fadeIn: true, class: "podcast-episode-thumbnail" } }); return { c() { div = element("div"); create_component(imageloader.$$.fragment); attr(div, "class", "podcast-episode-thumbnail-container svelte-1gcgk6w"); }, m(target, anchor) { insert(target, div, anchor); mount_component(imageloader, div, null); current = true; }, p(ctx2, dirty) { const imageloader_changes = {}; if (dirty & 1) imageloader_changes.src = ctx2[0].artworkUrl; if (dirty & 1) imageloader_changes.alt = ctx2[0].title; imageloader.$set(imageloader_changes); }, i(local) { if (current) return; transition_in(imageloader.$$.fragment, local); current = true; }, o(local) { transition_out(imageloader.$$.fragment, local); current = false; }, d(detaching) { if (detaching) detach(div); destroy_component(imageloader); } }; } function create_fragment17(ctx) { let div1; let current_block_type_index; let if_block; let t0; let div0; let span0; let t1_value = ctx[3].toUpperCase() + ""; let t1; let t2; let span1; let t3_value = ctx[0].title + ""; let t3; let span1_class_value; let current; let mounted; let dispose; const if_block_creators = [create_if_block6, create_if_block_13]; const if_blocks = []; function select_block_type(ctx2, dirty) { if (ctx2[2] && ctx2[0]?.artworkUrl) return 0; if (ctx2[2]) return 1; return -1; } if (~(current_block_type_index = select_block_type(ctx, -1))) { if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); } return { c() { div1 = element("div"); if (if_block) if_block.c(); t0 = space(); div0 = element("div"); span0 = element("span"); t1 = text(t1_value); t2 = space(); span1 = element("span"); t3 = text(t3_value); attr(span0, "class", "episode-item-date svelte-1gcgk6w"); attr(span1, "class", span1_class_value = null_to_empty(`episode-item-title ${ctx[1] && "strikeout"}`) + " svelte-1gcgk6w"); attr(div0, "class", "podcast-episode-information svelte-1gcgk6w"); set_style(div0, "flex-basis", "80%", false); attr(div1, "class", "podcast-episode-item svelte-1gcgk6w"); }, m(target, anchor) { insert(target, div1, anchor); if (~current_block_type_index) { if_blocks[current_block_type_index].m(div1, null); } append(div1, t0); append(div1, div0); append(div0, span0); append(span0, t1); append(div0, t2); append(div0, span1); append(span1, t3); current = true; if (!mounted) { dispose = [ listen(div1, "click", ctx[4]), listen(div1, "contextmenu", ctx[5]) ]; mounted = true; } }, p(ctx2, [dirty]) { let previous_block_index = current_block_type_index; current_block_type_index = select_block_type(ctx2, dirty); if (current_block_type_index === previous_block_index) { if (~current_block_type_index) { if_blocks[current_block_type_index].p(ctx2, dirty); } } else { if (if_block) { group_outros(); transition_out(if_blocks[previous_block_index], 1, 1, () => { if_blocks[previous_block_index] = null; }); check_outros(); } if (~current_block_type_index) { if_block = if_blocks[current_block_type_index]; if (!if_block) { if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); if_block.c(); } else { if_block.p(ctx2, dirty); } transition_in(if_block, 1); if_block.m(div1, t0); } else { if_block = null; } } if ((!current || dirty & 8) && t1_value !== (t1_value = ctx2[3].toUpperCase() + "")) set_data(t1, t1_value); if ((!current || dirty & 1) && t3_value !== (t3_value = ctx2[0].title + "")) set_data(t3, t3_value); if (!current || dirty & 2 && span1_class_value !== (span1_class_value = null_to_empty(`episode-item-title ${ctx2[1] && "strikeout"}`) + " svelte-1gcgk6w")) { attr(span1, "class", span1_class_value); } }, i(local) { if (current) return; transition_in(if_block); current = true; }, o(local) { transition_out(if_block); current = false; }, d(detaching) { if (detaching) detach(div1); if (~current_block_type_index) { if_blocks[current_block_type_index].d(); } mounted = false; run_all(dispose); } }; } function instance16($$self, $$props, $$invalidate) { let { episode } = $$props; let { episodeFinished = false } = $$props; let { showEpisodeImage = false } = $$props; const dispatch2 = createEventDispatcher(); function onClickEpisode() { dispatch2("clickEpisode", { episode }); } function onContextMenu(event) { dispatch2("contextMenu", { episode, event }); } let _date; let date; $$self.$$set = ($$props2) => { if ("episode" in $$props2) $$invalidate(0, episode = $$props2.episode); if ("episodeFinished" in $$props2) $$invalidate(1, episodeFinished = $$props2.episodeFinished); if ("showEpisodeImage" in $$props2) $$invalidate(2, showEpisodeImage = $$props2.showEpisodeImage); }; $$self.$$.update = () => { if ($$self.$$.dirty & 65) { $: { $$invalidate(6, _date = new Date(episode.episodeDate || "")); $$invalidate(3, date = window.moment(_date).format("DD MMMM YYYY")); } } }; return [ episode, episodeFinished, showEpisodeImage, date, onClickEpisode, onContextMenu, _date ]; } var EpisodeListItem = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance16, create_fragment17, safe_not_equal, { episode: 0, episodeFinished: 1, showEpisodeImage: 2 }, add_css12); } }; var EpisodeListItem_default = EpisodeListItem; // src/ui/PodcastView/EpisodeList.svelte function add_css13(target) { append_styles(target, "svelte-1ov6u04", ".episode-list-view-container.svelte-1ov6u04{display:flex;flex-direction:column;align-items:center;justify-content:center}.podcast-episode-list.svelte-1ov6u04{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%}.episode-list-menu.svelte-1ov6u04{display:flex;flex-direction:row;justify-content:right;align-items:center;gap:1rem;width:100%;padding-left:0.5rem;padding-right:0.5rem}.episode-list-search.svelte-1ov6u04{width:100%;margin-bottom:0.5rem}"); } function get_each_context4(ctx, list, i) { const child_ctx = ctx.slice(); child_ctx[15] = list[i]; const constants_0 = child_ctx[5][child_ctx[15].title]?.finished; child_ctx[16] = constants_0; return child_ctx; } var get_header_slot_changes = (dirty) => ({}); var get_header_slot_context = (ctx) => ({}); function fallback_block(ctx) { let t; return { c() { t = text("Fallback"); }, m(target, anchor) { insert(target, t, anchor); }, d(detaching) { if (detaching) detach(t); } }; } function create_if_block_2(ctx) { let div1; let div0; let text_1; let updating_value; let t0; let icon0; let t1; let icon1; let current; function text_1_value_binding(value) { ctx[12](value); } let text_1_props = { placeholder: "Search episodes", style: { width: "100%" } }; if (ctx[4] !== void 0) { text_1_props.value = ctx[4]; } text_1 = new Text_default({ props: text_1_props }); binding_callbacks.push(() => bind(text_1, "value", text_1_value_binding)); text_1.$on("change", ctx[9]); icon0 = new Icon_default({ props: { icon: ctx[3] ? "eye-off" : "eye", size: 25 } }); icon0.$on("click", ctx[13]); icon1 = new Icon_default({ props: { icon: "refresh-cw", size: 25 } }); icon1.$on("click", ctx[14]); return { c() { div1 = element("div"); div0 = element("div"); create_component(text_1.$$.fragment); t0 = space(); create_component(icon0.$$.fragment); t1 = space(); create_component(icon1.$$.fragment); attr(div0, "class", "episode-list-search svelte-1ov6u04"); attr(div1, "class", "episode-list-menu svelte-1ov6u04"); }, m(target, anchor) { insert(target, div1, anchor); append(div1, div0); mount_component(text_1, div0, null); append(div1, t0); mount_component(icon0, div1, null); append(div1, t1); mount_component(icon1, div1, null); current = true; }, p(ctx2, dirty) { const text_1_changes = {}; if (!updating_value && dirty & 16) { updating_value = true; text_1_changes.value = ctx2[4]; add_flush_callback(() => updating_value = false); } text_1.$set(text_1_changes); const icon0_changes = {}; if (dirty & 8) icon0_changes.icon = ctx2[3] ? "eye-off" : "eye"; icon0.$set(icon0_changes); }, i(local) { if (current) return; transition_in(text_1.$$.fragment, local); transition_in(icon0.$$.fragment, local); transition_in(icon1.$$.fragment, local); current = true; }, o(local) { transition_out(text_1.$$.fragment, local); transition_out(icon0.$$.fragment, local); transition_out(icon1.$$.fragment, local); current = false; }, d(detaching) { if (detaching) detach(div1); destroy_component(text_1); destroy_component(icon0); destroy_component(icon1); } }; } function create_if_block_14(ctx) { let p; return { c() { p = element("p"); p.textContent = "No episodes found."; }, m(target, anchor) { insert(target, p, anchor); }, d(detaching) { if (detaching) detach(p); } }; } function create_if_block7(ctx) { let episodelistitem; let current; episodelistitem = new EpisodeListItem_default({ props: { episode: ctx[15], episodeFinished: ctx[16], showEpisodeImage: ctx[1] } }); episodelistitem.$on("clickEpisode", ctx[7]); episodelistitem.$on("contextMenu", ctx[8]); return { c() { create_component(episodelistitem.$$.fragment); }, m(target, anchor) { mount_component(episodelistitem, target, anchor); current = true; }, p(ctx2, dirty) { const episodelistitem_changes = {}; if (dirty & 1) episodelistitem_changes.episode = ctx2[15]; if (dirty & 33) episodelistitem_changes.episodeFinished = ctx2[16]; if (dirty & 2) episodelistitem_changes.showEpisodeImage = ctx2[1]; episodelistitem.$set(episodelistitem_changes); }, i(local) { if (current) return; transition_in(episodelistitem.$$.fragment, local); current = true; }, o(local) { transition_out(episodelistitem.$$.fragment, local); current = false; }, d(detaching) { destroy_component(episodelistitem, detaching); } }; } function create_each_block4(ctx) { let if_block_anchor; let current; let if_block = (!ctx[3] || !ctx[16]) && create_if_block7(ctx); return { c() { if (if_block) if_block.c(); if_block_anchor = empty(); }, m(target, anchor) { if (if_block) if_block.m(target, anchor); insert(target, if_block_anchor, anchor); current = true; }, p(ctx2, dirty) { if (!ctx2[3] || !ctx2[16]) { if (if_block) { if_block.p(ctx2, dirty); if (dirty & 41) { transition_in(if_block, 1); } } else { if_block = create_if_block7(ctx2); if_block.c(); transition_in(if_block, 1); if_block.m(if_block_anchor.parentNode, if_block_anchor); } } else if (if_block) { group_outros(); transition_out(if_block, 1, 1, () => { if_block = null; }); check_outros(); } }, i(local) { if (current) return; transition_in(if_block); current = true; }, o(local) { transition_out(if_block); current = false; }, d(detaching) { if (if_block) if_block.d(detaching); if (detaching) detach(if_block_anchor); } }; } function create_fragment18(ctx) { let div1; let t0; let t1; let div0; let t2; let current; const header_slot_template = ctx[11].header; const header_slot = create_slot(header_slot_template, ctx, ctx[10], get_header_slot_context); const header_slot_or_fallback = header_slot || fallback_block(ctx); let if_block0 = ctx[2] && create_if_block_2(ctx); let if_block1 = ctx[0].length === 0 && create_if_block_14(ctx); let each_value = ctx[0]; let each_blocks = []; for (let i = 0; i < each_value.length; i += 1) { each_blocks[i] = create_each_block4(get_each_context4(ctx, each_value, i)); } const out = (i) => transition_out(each_blocks[i], 1, 1, () => { each_blocks[i] = null; }); return { c() { div1 = element("div"); if (header_slot_or_fallback) header_slot_or_fallback.c(); t0 = space(); if (if_block0) if_block0.c(); t1 = space(); div0 = element("div"); if (if_block1) if_block1.c(); t2 = space(); for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].c(); } attr(div0, "class", "podcast-episode-list svelte-1ov6u04"); attr(div1, "class", "episode-list-view-container svelte-1ov6u04"); }, m(target, anchor) { insert(target, div1, anchor); if (header_slot_or_fallback) { header_slot_or_fallback.m(div1, null); } append(div1, t0); if (if_block0) if_block0.m(div1, null); append(div1, t1); append(div1, div0); if (if_block1) if_block1.m(div0, null); append(div0, t2); for (let i = 0; i < each_blocks.length; i += 1) { each_blocks[i].m(div0, null); } current = true; }, p(ctx2, [dirty]) { if (header_slot) { if (header_slot.p && (!current || dirty & 1024)) { update_slot_base(header_slot, header_slot_template, ctx2, ctx2[10], !current ? get_all_dirty_from_scope(ctx2[10]) : get_slot_changes(header_slot_template, ctx2[10], dirty, get_header_slot_changes), get_header_slot_context); } } if (ctx2[2]) { if (if_block0) { if_block0.p(ctx2, dirty); if (dirty & 4) { transition_in(if_block0, 1); } } else { if_block0 = create_if_block_2(ctx2); if_block0.c(); transition_in(if_block0, 1); if_block0.m(div1, t1); } } else if (if_block0) { group_outros(); transition_out(if_block0, 1, 1, () => { if_block0 = null; }); check_outros(); } if (ctx2[0].length === 0) { if (if_block1) { } else { if_block1 = create_if_block_14(ctx2); if_block1.c(); if_block1.m(div0, t2); } } else if (if_block1) { if_block1.d(1); if_block1 = null; } if (dirty & 427) { each_value = ctx2[0]; let i; for (i = 0; i < each_value.length; i += 1) { const child_ctx = get_each_context4(ctx2, each_value, i); if (each_blocks[i]) { each_blocks[i].p(child_ctx, dirty); transition_in(each_blocks[i], 1); } else { each_blocks[i] = create_each_block4(child_ctx); each_blocks[i].c(); transition_in(each_blocks[i], 1); each_blocks[i].m(div0, null); } } group_outros(); for (i = each_value.length; i < each_blocks.length; i += 1) { out(i); } check_outros(); } }, i(local) { if (current) return; transition_in(header_slot_or_fallback, local); transition_in(if_block0); for (let i = 0; i < each_value.length; i += 1) { transition_in(each_blocks[i]); } current = true; }, o(local) { transition_out(header_slot_or_fallback, local); transition_out(if_block0); each_blocks = each_blocks.filter(Boolean); for (let i = 0; i < each_blocks.length; i += 1) { transition_out(each_blocks[i]); } current = false; }, d(detaching) { if (detaching) detach(div1); if (header_slot_or_fallback) header_slot_or_fallback.d(detaching); if (if_block0) if_block0.d(); if (if_block1) if_block1.d(); destroy_each(each_blocks, detaching); } }; } function instance17($$self, $$props, $$invalidate) { let $playedEpisodes; component_subscribe($$self, playedEpisodes, ($$value) => $$invalidate(5, $playedEpisodes = $$value)); let { $$slots: slots = {}, $$scope } = $$props; let { episodes = [] } = $$props; let { showThumbnails = false } = $$props; let { showListMenu = true } = $$props; let hidePlayedEpisodes = false; let searchInputQuery = ""; const dispatch2 = createEventDispatcher(); function forwardClickEpisode(event) { dispatch2("clickEpisode", { episode: event.detail.episode }); } function forwardContextMenuEpisode(event) { dispatch2("contextMenuEpisode", { episode: event.detail.episode, event: event.detail.event }); } function forwardSearchInput(event) { dispatch2("search", { query: event.detail.value }); } function text_1_value_binding(value) { searchInputQuery = value; $$invalidate(4, searchInputQuery); } const click_handler = () => $$invalidate(3, hidePlayedEpisodes = !hidePlayedEpisodes); const click_handler_1 = () => dispatch2("clickRefresh"); $$self.$$set = ($$props2) => { if ("episodes" in $$props2) $$invalidate(0, episodes = $$props2.episodes); if ("showThumbnails" in $$props2) $$invalidate(1, showThumbnails = $$props2.showThumbnails); if ("showListMenu" in $$props2) $$invalidate(2, showListMenu = $$props2.showListMenu); if ("$$scope" in $$props2) $$invalidate(10, $$scope = $$props2.$$scope); }; return [ episodes, showThumbnails, showListMenu, hidePlayedEpisodes, searchInputQuery, $playedEpisodes, dispatch2, forwardClickEpisode, forwardContextMenuEpisode, forwardSearchInput, $$scope, slots, text_1_value_binding, click_handler, click_handler_1 ]; } var EpisodeList = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance17, create_fragment18, safe_not_equal, { episodes: 0, showThumbnails: 1, showListMenu: 2 }, add_css13); } }; var EpisodeList_default = EpisodeList; // src/ui/common/Progressbar.svelte function create_fragment19(ctx) { let progress; let mounted; let dispose; return { c() { progress = element("progress"); attr(progress, "style", ctx[2]); attr(progress, "max", ctx[0]); progress.value = ctx[1]; }, m(target, anchor) { insert(target, progress, anchor); if (!mounted) { dispose = [ listen(progress, "click", ctx[3]), listen(progress, "mousedown", ctx[4]), listen(progress, "mouseup", ctx[5]), listen(progress, "mousemove", ctx[6]) ]; mounted = true; } }, p(ctx2, [dirty]) { if (dirty & 4) { attr(progress, "style", ctx2[2]); } if (dirty & 1) { attr(progress, "max", ctx2[0]); } if (dirty & 2) { progress.value = ctx2[1]; } }, i: noop, o: noop, d(detaching) { if (detaching) detach(progress); mounted = false; run_all(dispose); } }; } function instance18($$self, $$props, $$invalidate) { let { max } = $$props; let { value } = $$props; let isDragging = false; let { style: _styled = {} } = $$props; let styles; const dispatch2 = createEventDispatcher(); function forwardClick(e) { dispatch2("click", { event: e }); } function onDragStart() { isDragging = true; } function onDragEnd() { isDragging = false; } function handleDragging(e) { if (!isDragging) return; forwardClick(e); } $$self.$$set = ($$props2) => { if ("max" in $$props2) $$invalidate(0, max = $$props2.max); if ("value" in $$props2) $$invalidate(1, value = $$props2.value); if ("style" in $$props2) $$invalidate(7, _styled = $$props2.style); }; $$self.$$.update = () => { if ($$self.$$.dirty & 128) { $: { $$invalidate(2, styles = extractStylesFromObj(_styled)); } } }; return [ max, value, styles, forwardClick, onDragStart, onDragEnd, handleDragging, _styled ]; } var Progressbar = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance18, create_fragment19, safe_not_equal, { max: 0, value: 1, style: 7 }); } }; var Progressbar_default = Progressbar; // src/ui/PodcastView/spawnEpisodeContextMenu.ts var import_obsidian16 = require("obsidian"); // src/createPodcastNote.ts var import_obsidian14 = require("obsidian"); // src/utility/addExtension.ts function addExtension(path, extension) { const ext = extension.startsWith(".") ? extension : `.${extension}`; return path.endsWith(ext) ? path : `${path}${ext}`; } // src/createPodcastNote.ts async function createPodcastNote(episode) { const pluginInstance = get_store_value(plugin); const filePath = FilePathTemplateEngine(pluginInstance.settings.note.path, episode); const filePathDotMd = addExtension(filePath, "md"); const content = NoteTemplateEngine(pluginInstance.settings.note.template, episode); try { const file = await createFileIfNotExists(filePathDotMd, content, episode); app.workspace.getLeaf().openFile(file); } catch (error) { console.error(error); new import_obsidian14.Notice(`Failed to create note: "${filePathDotMd}"`); } } function getPodcastNote(episode) { const pluginInstance = get_store_value(plugin); const filePath = FilePathTemplateEngine(pluginInstance.settings.note.path, episode); const filePathDotMd = addExtension(filePath, "md"); const file = app.vault.getAbstractFileByPath(filePathDotMd); if (!file || !(file instanceof import_obsidian14.TFile)) { return null; } return file; } function openPodcastNote(epiosode) { const file = getPodcastNote(epiosode); if (!file) { new import_obsidian14.Notice(`Note for "${epiosode.title}" does not exist`); return; } app.workspace.getLeaf().openFile(file); } async function createFileIfNotExists(path, content, episode, createFolder = true) { const file = getPodcastNote(episode); if (file) { new import_obsidian14.Notice(`Note for "${episode.title}" already exists`); return file; } const foldersInPath = path.split("/").slice(0, -1); for (let i = 0; i < foldersInPath.length; i++) { const folderPath = foldersInPath.slice(0, i + 1).join("/"); const folder = app.vault.getAbstractFileByPath(folderPath); if (!folder && createFolder) { await app.vault.createFolder(folderPath); } } return await app.vault.create(path, content); } // src/downloadEpisode.ts var import_obsidian15 = require("obsidian"); async function downloadFile(url, options) { try { const response = await (0, import_obsidian15.requestUrl)({ url, method: "GET" }); if (response.status !== 200) { throw new Error("Could not download episode."); } const contentLength = response.arrayBuffer.byteLength; options?.onFinished?.(); return { blob: new Blob([response.arrayBuffer], { type: response.headers["content-type"] ?? response.headers["Content-Type"] ?? "" }), contentLength, receivedLength: contentLength, responseUrl: url }; } catch (error) { const err = new Error(`Failed to download ${url}: ${error.message}`); options?.onError?.(err); throw err; } } async function downloadEpisodeWithNotice(episode, downloadPathTemplate) { const { doc, update: update2 } = createNoticeDoc(`Download "${episode.title}"`); const SOME_LARGE_INT_SO_THE_BOX_DOESNT_AUTO_CLOSE = 999999999; const notice = new import_obsidian15.Notice(doc, SOME_LARGE_INT_SO_THE_BOX_DOESNT_AUTO_CLOSE); update2((bodyEl) => bodyEl.createEl("p", { text: "Starting download..." })); update2((bodyEl) => { bodyEl.createEl("p", { text: "Downloading..." }); }); const { blob } = await downloadFile(episode.streamUrl, { onFinished: () => { update2((bodyEl) => bodyEl.createEl("p", { text: "Download complete!" })); }, onError: (error) => { update2((bodyEl) => bodyEl.createEl("p", { text: `Download failed: ${error.message}` })); } }); const fileExtension = await detectAudioFileExtension(blob); if (!fileExtension) { update2((bodyEl) => { bodyEl.createEl("p", { text: `Could not determine file extension for downloaded file. Blob: ${blob.size} bytes.` }); }); throw new Error("Could not determine file extension"); } if (!blob.type.contains("audio") && !fileExtension) { update2((bodyEl) => { bodyEl.createEl("p", { text: `Downloaded file is not an audio file. It is of type "${blob.type}". Blob: ${blob.size} bytes.` }); }); throw new Error("Not an audio file"); } try { update2((bodyEl) => bodyEl.createEl("p", { text: "Creating file..." })); await createEpisodeFile({ episode, downloadPathTemplate, blob, extension: fileExtension }); update2((bodyEl) => bodyEl.createEl("p", { text: `Successfully downloaded "${episode.title}" from ${episode.podcastName}.` })); } catch (error) { update2((bodyEl) => { bodyEl.createEl("p", { text: `Failed to create file for downloaded episode "${episode.title}" from ${episode.podcastName}.` }); const errorMsgEl = bodyEl.createEl("p", { text: error.message }); errorMsgEl.style.fontStyle = "italic"; }); } setTimeout(() => notice.hide(), 1e4); } function createNoticeDoc(title) { const doc = new DocumentFragment(); const container = doc.createDiv(); container.style.width = "100%"; container.style.display = "flex"; const titleEl = container.createEl("span", { text: title }); titleEl.style.textAlign = "center"; titleEl.style.fontWeight = "bold"; titleEl.style.marginBottom = "0.5em"; const bodyEl = doc.createDiv(); bodyEl.style.display = "flex"; bodyEl.style.flexDirection = "column"; bodyEl.style.alignItems = "center"; bodyEl.style.justifyContent = "center"; return { doc, update: (updateFn, empty2 = true) => { if (empty2) bodyEl.empty(); updateFn(bodyEl); } }; } async function createEpisodeFile({ episode, downloadPathTemplate, blob, extension }) { const basename = DownloadPathTemplateEngine(downloadPathTemplate, episode); const filePath = `${basename}.${extension}`; const buffer = await blob.arrayBuffer(); try { await app.vault.createBinary(filePath, buffer); } catch (error) { throw new Error(`Failed to write file "${filePath}": ${error.message}`); } downloadedEpisodes.addEpisode(episode, filePath, blob.size); } async function downloadEpisode(episode, downloadPathTemplate) { const basename = DownloadPathTemplateEngine(downloadPathTemplate, episode); const fileExtension = await getFileExtension(episode.streamUrl); const filePath = `${basename}.${fileExtension}`; const existingFile = app.vault.getAbstractFileByPath(filePath); if (existingFile instanceof import_obsidian15.TFile) { return filePath; } try { const { blob, responseUrl } = await downloadFile(episode.streamUrl); if (!blob.type.includes("audio") && !fileExtension) { throw new Error("Not an audio file."); } await createEpisodeFile({ episode, downloadPathTemplate, blob, extension: fileExtension }); return filePath; } catch (error) { throw new Error(`Failed to download ${episode.title}: ${error.message}`); } } async function getFileExtension(url) { const urlExtension = getUrlExtension(url); if (urlExtension) return urlExtension; const response = await fetch(url, { method: "HEAD" }); const contentType = response.headers.get("content-type"); if (contentType?.includes("audio/mpeg")) return "mp3"; if (contentType?.includes("audio/mp4")) return "m4a"; if (contentType?.includes("audio/ogg")) return "ogg"; if (contentType?.includes("audio/wav")) return "wav"; if (contentType?.includes("audio/x-m4a")) return "m4a"; return "mp3"; } async function detectAudioFileExtension(blob) { const audioSignatures = [ { signature: [255, 224], mask: [255, 224], fileExtension: "mp3" }, { signature: [73, 68, 51], fileExtension: "mp3" }, { signature: [82, 73, 70, 70], fileExtension: "wav" }, { signature: [79, 103, 103, 83], fileExtension: "ogg" }, { signature: [102, 76, 97, 67], fileExtension: "flac" }, { signature: [77, 52, 65, 32], fileExtension: "m4a" }, { signature: [48, 38, 178, 117, 142, 102, 207, 17], fileExtension: "wma" }, { signature: [35, 33, 65, 77, 82, 10], fileExtension: "amr" } ]; return new Promise((resolve, reject) => { const fileReader = new FileReader(); fileReader.onloadend = (e) => { if (!e.target?.result) { reject(new Error("No result from file reader")); return; } const arr = new Uint8Array(e.target.result); for (const { signature, mask, fileExtension } of audioSignatures) { let matches = true; for (let i = 0; i < signature.length; i++) { if (mask) { if ((arr[i] & mask[i]) !== (signature[i] & mask[i])) { matches = false; break; } } else { if (arr[i] !== signature[i]) { matches = false; break; } } } if (matches) { resolve(fileExtension); return; } } resolve(null); }; fileReader.onerror = () => { reject(fileReader.error); }; fileReader.readAsArrayBuffer(blob.slice(0, Math.max(...audioSignatures.map((sig) => sig.signature.length)))); }); } // src/ui/PodcastView/spawnEpisodeContextMenu.ts function spawnEpisodeContextMenu(episode, event, disabledMenuItems) { const menu = new import_obsidian16.Menu(); if (!disabledMenuItems?.play) { menu.addItem((item) => item.setIcon("play").setTitle("Play").onClick(() => { currentEpisode.set(episode); viewState.set(2 /* Player */); })); } if (!disabledMenuItems?.markPlayed) { const episodeIsPlayed = Object.values(get_store_value(playedEpisodes)).find((e) => e.title === episode.title && e.finished); menu.addItem((item) => item.setIcon(episodeIsPlayed ? "cross" : "check").setTitle(`Mark as ${episodeIsPlayed ? "Unplayed" : "Played"}`).onClick(() => { if (episodeIsPlayed) { playedEpisodes.markAsUnplayed(episode); } else { playedEpisodes.markAsPlayed(episode); } })); } if (!disabledMenuItems?.download) { const isDownloaded = downloadedEpisodes.isEpisodeDownloaded(episode); menu.addItem((item) => item.setIcon(isDownloaded ? "cross" : "download").setTitle(isDownloaded ? "Remove file" : "Download").onClick(() => { if (isDownloaded) { downloadedEpisodes.removeEpisode(episode, true); } else { const downloadPath = get_store_value(plugin).settings.download.path; if (!downloadPath) { new import_obsidian16.Notice(`Please set a download path in the settings.`); return; } downloadEpisodeWithNotice(episode, downloadPath); } })); } if (!disabledMenuItems?.createNote) { const episodeNoteExists = Boolean(getPodcastNote(episode)); menu.addItem((item) => item.setIcon("pencil").setTitle(`${episodeNoteExists ? "Open" : "Create"} Note`).onClick(async () => { if (episodeNoteExists) { openPodcastNote(episode); } else { const { path, template } = get_store_value(plugin).settings.note; const canCreateNote = Boolean(path && template); if (!canCreateNote) { new import_obsidian16.Notice(`Please set a note path and template in the settings.`); return; } await createPodcastNote(episode); } })); } if (!disabledMenuItems?.favorite) { const episodeIsFavorite = get_store_value(favorites).episodes.find((e) => e.title === episode.title); menu.addItem((item) => item.setIcon("lucide-star").setTitle(`${episodeIsFavorite ? "Remove from" : "Add to"} Favorites`).onClick(() => { if (episodeIsFavorite) { favorites.update((playlist) => { playlist.episodes = playlist.episodes.filter((e) => e.title !== episode.title); return playlist; }); } else { favorites.update((playlist) => { const newEpisodes = [...playlist.episodes, episode]; playlist.episodes = newEpisodes; return playlist; }); } })); } if (!disabledMenuItems?.queue) { const episodeIsInQueue = get_store_value(queue).episodes.find((e) => e.title === episode.title); menu.addItem((item) => item.setIcon("list-ordered").setTitle(`${episodeIsInQueue ? "Remove from" : "Add to"} Queue`).onClick(() => { if (episodeIsInQueue) { queue.update((playlist) => { playlist.episodes = playlist.episodes.filter((e) => e.title !== episode.title); return playlist; }); } else { queue.update((playlist) => { const newEpisodes = [...playlist.episodes, episode]; playlist.episodes = newEpisodes; return playlist; }); } })); } if (!disabledMenuItems?.playlists) { menu.addSeparator(); const playlistsInStore = get_store_value(playlists); for (const playlist of Object.values(playlistsInStore)) { const episodeIsInPlaylist = playlist.episodes.find((e) => e.title === episode.title); menu.addItem((item) => item.setIcon(playlist.icon).setTitle(`${episodeIsInPlaylist ? "Remove from" : "Add to"} ${playlist.name}`).onClick(() => { if (episodeIsInPlaylist) { playlists.update((playlists2) => { playlists2[playlist.name].episodes = playlists2[playlist.name].episodes.filter((e) => e.title !== episode.title); return playlists2; }); } else { playlists.update((playlists2) => { const newEpisodes = [...playlists2[playlist.name].episodes, episode]; playlists2[playlist.name].episodes = newEpisodes; return playlists2; }); } })); } } menu.showAtMouseEvent(event); } // src/utility/createMediaUrlObjectFromFilePath.ts var import_obsidian17 = require("obsidian"); async function createMediaUrlObjectFromFilePath(filePath) { const file = app.vault.getAbstractFileByPath(filePath); if (!file || !(file instanceof import_obsidian17.TFile)) return ""; const binary = await app.vault.readBinary(file); return URL.createObjectURL(new Blob([binary], { type: "audio/mpeg" })); } // src/ui/PodcastView/EpisodePlayer.svelte function add_css14(target) { append_styles(target, "svelte-1itadba", ".episode-player{display:flex;flex-direction:column;height:100%}.episode-image-container{width:100%;height:auto;padding:5% 0%}.hover-container{min-width:10rem;min-height:10rem;width:100%;height:100%;aspect-ratio:1/1;display:flex;align-items:center;justify-content:center;position:relative;margin-left:auto;margin-right:auto}.podcast-artwork{width:100%;height:100%;background-size:cover;background-position:center;background-repeat:no-repeat;position:absolute}.podcast-artwork-placeholder{width:100%;height:100%;background-size:cover;background-position:center;background-repeat:no-repeat;position:absolute;display:flex;align-items:center;justify-content:center}.podcast-artwork:hover{cursor:pointer !important}.podcast-artwork-overlay{position:absolute}.podcast-artwork-isloading-overlay{position:absolute;display:block}.podcast-artwork-overlay:hover{cursor:pointer !important}.opacity-50{opacity:0.5}.podcast-title{font-size:1.5rem;font-weight:bold;margin:0%;margin-bottom:0.5rem;text-align:center}.status-container{display:flex;align-items:center;justify-content:space-around}.controls-container{display:flex;align-items:center;justify-content:space-between;margin-top:1rem;margin-left:25%;margin-right:25%}.playbackrate-container{display:flex;align-items:center;justify-content:space-around;margin-bottom:2.5rem;flex-direction:column;margin-top:auto}"); } function create_fallback_slot(ctx) { let div; let icon; let div_class_value; let current; icon = new Icon_default({ props: { icon: "image", size: 150 } }); return { c() { div = element("div"); create_component(icon.$$.fragment); attr(div, "class", div_class_value = "podcast-artwork-placeholder" + (ctx[2] || ctx[9] ? " opacity-50" : "")); }, m(target, anchor) { insert(target, div, anchor); mount_component(icon, div, null); current = true; }, p(ctx2, dirty) { if (!current || dirty[0] & 516 && div_class_value !== (div_class_value = "podcast-artwork-placeholder" + (ctx2[2] || ctx2[9] ? " opacity-50" : ""))) { attr(div, "class", div_class_value); } }, i(local) { if (current) return; transition_in(icon.$$.fragment, local); current = true; }, o(local) { transition_out(icon.$$.fragment, local); current = false; }, d(detaching) { if (detaching) detach(div); destroy_component(icon); } }; } function create_else_block3(ctx) { let div; let icon; let div_style_value; let current; icon = new Icon_default({ props: { icon: ctx[9] ? "play" : "pause" } }); return { c() { div = element("div"); create_component(icon.$$.fragment); attr(div, "class", "podcast-artwork-overlay"); attr(div, "style", div_style_value = `display: ${ctx[2] || ctx[9] ? "block" : "none"}`); }, m(target, anchor) { insert(target, div, anchor); mount_component(icon, div, null); current = true; }, p(ctx2, dirty) { const icon_changes = {}; if (dirty[0] & 512) icon_changes.icon = ctx2[9] ? "play" : "pause"; icon.$set(icon_changes); if (!current || dirty[0] & 516 && div_style_value !== (div_style_value = `display: ${ctx2[2] || ctx2[9] ? "block" : "none"}`)) { attr(div, "style", div_style_value); } }, i(local) { if (current) return; transition_in(icon.$$.fragment, local); current = true; }, o(local) { transition_out(icon.$$.fragment, local); current = false; }, d(detaching) { if (detaching) detach(div); destroy_component(icon); } }; } function create_if_block8(ctx) { let div; let loading; let current; loading = new Loading_default({}); return { c() { div = element("div"); create_component(loading.$$.fragment); attr(div, "class", "podcast-artwork-isloading-overlay"); }, m(target, anchor) { insert(target, div, anchor); mount_component(loading, div, null); current = true; }, p: noop, i(local) { if (current) return; transition_in(loading.$$.fragment, local); current = true; }, o(local) { transition_out(loading.$$.fragment, local); current = false; }, d(detaching) { if (detaching) detach(div); destroy_component(loading); } }; } function create_catch_block(ctx) { return { c: noop, m: noop, p: noop, d: noop }; } function create_then_block(ctx) { let audio; let audio_src_value; let audio_autoplay_value; let audio_updating = false; let audio_animationframe; let audio_is_paused = true; let mounted; let dispose; function audio_timeupdate_handler() { cancelAnimationFrame(audio_animationframe); if (!audio.paused) { audio_animationframe = raf(audio_timeupdate_handler); audio_updating = true; } ctx[23].call(audio); } return { c() { audio = element("audio"); if (!src_url_equal(audio.src, audio_src_value = ctx[31])) attr(audio, "src", audio_src_value); audio.autoplay = audio_autoplay_value = true; if (ctx[6] === void 0) add_render_callback(() => ctx[22].call(audio)); }, m(target, anchor) { insert(target, audio, anchor); if (!isNaN(ctx[1]._playbackRate)) { audio.playbackRate = ctx[1]._playbackRate; } if (!mounted) { dispose = [ listen(audio, "durationchange", ctx[22]), listen(audio, "timeupdate", audio_timeupdate_handler), listen(audio, "play", ctx[24]), listen(audio, "pause", ctx[24]), listen(audio, "ratechange", ctx[25]), listen(audio, "ended", ctx[13]), listen(audio, "loadedmetadata", ctx[15]), listen(audio, "play", prevent_default(ctx[19])) ]; mounted = true; } }, p(ctx2, dirty) { if (dirty[0] & 16 && !src_url_equal(audio.src, audio_src_value = ctx2[31])) { attr(audio, "src", audio_src_value); } if (!audio_updating && dirty[0] & 1 && !isNaN(ctx2[0])) { audio.currentTime = ctx2[0]; } audio_updating = false; if (dirty[0] & 512 && audio_is_paused !== (audio_is_paused = ctx2[9])) { audio[audio_is_paused ? "pause" : "play"](); } if (dirty[0] & 2 && !isNaN(ctx2[1]._playbackRate)) { audio.playbackRate = ctx2[1]._playbackRate; } }, d(detaching) { if (detaching) detach(audio); mounted = false; run_all(dispose); } }; } function create_pending_block(ctx) { return { c: noop, m: noop, p: noop, d: noop }; } function create_header_slot(ctx) { let h3; return { c() { h3 = element("h3"); h3.textContent = "Queue"; }, m(target, anchor) { insert(target, h3, anchor); }, p: noop, d(detaching) { if (detaching) detach(h3); } }; } function create_fragment20(ctx) { let div5; let div1; let div0; let image; let t0; let current_block_type_index; let if_block; let t1; let h2; let t2_value = ctx[5].title + ""; let t2; let t3; let promise2; let t4; let div2; let span0; let t5_value = formatSeconds(ctx[7], "HH:mm:ss") + ""; let t5; let t6; let progressbar; let t7; let span1; let t8_value = formatSeconds(ctx[6] - ctx[7], "HH:mm:ss") + ""; let t8; let t9; let div3; let button0; let t10; let button1; let t11; let div4; let span2; let t12_value = ctx[1].playbackRate + ""; let t12; let t13; let t14; let slider; let t15; let episodelist; let current; let mounted; let dispose; image = new Image_default({ props: { class: "podcast-artwork", src: ctx[5].artworkUrl ?? "", alt: ctx[5].title, opacity: ctx[2] || ctx[9] ? 0.5 : 1, $$slots: { fallback: [create_fallback_slot] }, $$scope: { ctx } } }); const if_block_creators = [create_if_block8, create_else_block3]; const if_blocks = []; function select_block_type(ctx2, dirty) { if (ctx2[3]) return 0; return 1; } current_block_type_index = select_block_type(ctx, [-1, -1]); if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); let info = { ctx, current: null, token: null, hasCatch: false, pending: create_pending_block, then: create_then_block, catch: create_catch_block, value: 31 }; handle_promise(promise2 = ctx[4], info); progressbar = new Progressbar_default({ props: { value: ctx[7], max: ctx[6], style: { "height": "2rem" } } }); progressbar.$on("click", ctx[12]); button0 = new Button_default({ props: { icon: "skip-back", tooltip: "Skip backward", style: { margin: "0", cursor: "pointer" } } }); button0.$on("click", function() { if (is_function(ctx[8].api.skipBackward.bind(ctx[8].api))) ctx[8].api.skipBackward.bind(ctx[8].api).apply(this, arguments); }); button1 = new Button_default({ props: { icon: "skip-forward", tooltip: "Skip forward", style: { margin: "0", cursor: "pointer" } } }); button1.$on("click", function() { if (is_function(ctx[8].api.skipForward.bind(ctx[8].api))) ctx[8].api.skipForward.bind(ctx[8].api).apply(this, arguments); }); slider = new Slider_default({ props: { value: ctx[1].playbackRate, limits: [0.5, 3.5, 0.1] } }); slider.$on("change", ctx[14]); episodelist = new EpisodeList_default({ props: { episodes: ctx[10].episodes, showListMenu: false, showThumbnails: true, $$slots: { header: [create_header_slot] }, $$scope: { ctx } } }); episodelist.$on("contextMenuEpisode", ctx[16]); episodelist.$on("clickEpisode", ctx[18]); return { c() { div5 = element("div"); div1 = element("div"); div0 = element("div"); create_component(image.$$.fragment); t0 = space(); if_block.c(); t1 = space(); h2 = element("h2"); t2 = text(t2_value); t3 = space(); info.block.c(); t4 = space(); div2 = element("div"); span0 = element("span"); t5 = text(t5_value); t6 = space(); create_component(progressbar.$$.fragment); t7 = space(); span1 = element("span"); t8 = text(t8_value); t9 = space(); div3 = element("div"); create_component(button0.$$.fragment); t10 = space(); create_component(button1.$$.fragment); t11 = space(); div4 = element("div"); span2 = element("span"); t12 = text(t12_value); t13 = text("x"); t14 = space(); create_component(slider.$$.fragment); t15 = space(); create_component(episodelist.$$.fragment); attr(div0, "class", "hover-container"); attr(div1, "class", "episode-image-container"); attr(h2, "class", "podcast-title"); attr(div2, "class", "status-container"); attr(div3, "class", "controls-container"); attr(div4, "class", "playbackrate-container"); attr(div5, "class", "episode-player"); }, m(target, anchor) { insert(target, div5, anchor); append(div5, div1); append(div1, div0); mount_component(image, div0, null); append(div0, t0); if_blocks[current_block_type_index].m(div0, null); append(div5, t1); append(div5, h2); append(h2, t2); append(div5, t3); info.block.m(div5, info.anchor = null); info.mount = () => div5; info.anchor = t4; append(div5, t4); append(div5, div2); append(div2, span0); append(span0, t5); append(div2, t6); mount_component(progressbar, div2, null); append(div2, t7); append(div2, span1); append(span1, t8); append(div5, t9); append(div5, div3); mount_component(button0, div3, null); append(div3, t10); mount_component(button1, div3, null); append(div5, t11); append(div5, div4); append(div4, span2); append(span2, t12); append(span2, t13); append(div4, t14); mount_component(slider, div4, null); append(div5, t15); mount_component(episodelist, div5, null); current = true; if (!mounted) { dispose = [ listen(div0, "click", ctx[11]), listen(div0, "contextmenu", ctx[17]), listen(div0, "mouseenter", ctx[20]), listen(div0, "mouseleave", ctx[21]) ]; mounted = true; } }, p(new_ctx, dirty) { ctx = new_ctx; const image_changes = {}; if (dirty[0] & 32) image_changes.src = ctx[5].artworkUrl ?? ""; if (dirty[0] & 32) image_changes.alt = ctx[5].title; if (dirty[0] & 516) image_changes.opacity = ctx[2] || ctx[9] ? 0.5 : 1; if (dirty[0] & 516 | dirty[1] & 2) { image_changes.$$scope = { dirty, ctx }; } image.$set(image_changes); let previous_block_index = current_block_type_index; current_block_type_index = select_block_type(ctx, dirty); if (current_block_type_index === previous_block_index) { if_blocks[current_block_type_index].p(ctx, dirty); } else { group_outros(); transition_out(if_blocks[previous_block_index], 1, 1, () => { if_blocks[previous_block_index] = null; }); check_outros(); if_block = if_blocks[current_block_type_index]; if (!if_block) { if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); if_block.c(); } else { if_block.p(ctx, dirty); } transition_in(if_block, 1); if_block.m(div0, null); } if ((!current || dirty[0] & 32) && t2_value !== (t2_value = ctx[5].title + "")) set_data(t2, t2_value); info.ctx = ctx; if (dirty[0] & 16 && promise2 !== (promise2 = ctx[4]) && handle_promise(promise2, info)) { } else { update_await_block_branch(info, ctx, dirty); } if ((!current || dirty[0] & 128) && t5_value !== (t5_value = formatSeconds(ctx[7], "HH:mm:ss") + "")) set_data(t5, t5_value); const progressbar_changes = {}; if (dirty[0] & 128) progressbar_changes.value = ctx[7]; if (dirty[0] & 64) progressbar_changes.max = ctx[6]; progressbar.$set(progressbar_changes); if ((!current || dirty[0] & 192) && t8_value !== (t8_value = formatSeconds(ctx[6] - ctx[7], "HH:mm:ss") + "")) set_data(t8, t8_value); if ((!current || dirty[0] & 2) && t12_value !== (t12_value = ctx[1].playbackRate + "")) set_data(t12, t12_value); const slider_changes = {}; if (dirty[0] & 2) slider_changes.value = ctx[1].playbackRate; slider.$set(slider_changes); const episodelist_changes = {}; if (dirty[0] & 1024) episodelist_changes.episodes = ctx[10].episodes; if (dirty[1] & 2) { episodelist_changes.$$scope = { dirty, ctx }; } episodelist.$set(episodelist_changes); }, i(local) { if (current) return; transition_in(image.$$.fragment, local); transition_in(if_block); transition_in(progressbar.$$.fragment, local); transition_in(button0.$$.fragment, local); transition_in(button1.$$.fragment, local); transition_in(slider.$$.fragment, local); transition_in(episodelist.$$.fragment, local); current = true; }, o(local) { transition_out(image.$$.fragment, local); transition_out(if_block); transition_out(progressbar.$$.fragment, local); transition_out(button0.$$.fragment, local); transition_out(button1.$$.fragment, local); transition_out(slider.$$.fragment, local); transition_out(episodelist.$$.fragment, local); current = false; }, d(detaching) { if (detaching) detach(div5); destroy_component(image); if_blocks[current_block_type_index].d(); info.block.d(); info.token = null; info = null; destroy_component(progressbar); destroy_component(button0); destroy_component(button1); destroy_component(slider); destroy_component(episodelist); mounted = false; run_all(dispose); } }; } function instance19($$self, $$props, $$invalidate) { let $currentEpisode; let $duration; let $currentTime; let $playedEpisodes; let $plugin; let $isPaused; let $queue; component_subscribe($$self, currentEpisode, ($$value) => $$invalidate(5, $currentEpisode = $$value)); component_subscribe($$self, duration, ($$value) => $$invalidate(6, $duration = $$value)); component_subscribe($$self, currentTime, ($$value) => $$invalidate(7, $currentTime = $$value)); component_subscribe($$self, playedEpisodes, ($$value) => $$invalidate(26, $playedEpisodes = $$value)); component_subscribe($$self, plugin, ($$value) => $$invalidate(8, $plugin = $$value)); component_subscribe($$self, isPaused, ($$value) => $$invalidate(9, $isPaused = $$value)); component_subscribe($$self, queue, ($$value) => $$invalidate(10, $queue = $$value)); class CircumentForcedTwoWayBinding { constructor() { this.playbackRate = $plugin.settings.defaultPlaybackRate || 1; } get _playbackRate() { return this.playbackRate; } } const offBinding = new CircumentForcedTwoWayBinding(); let isHoveringArtwork = false; let isLoading = true; function togglePlayback() { isPaused.update((value) => !value); } function onClickProgressbar({ detail: { event } }) { const progressbar = event.target; const percent = event.offsetX / progressbar.offsetWidth; currentTime.set(percent * $duration); } function removeEpisodeFromPlaylists() { playlists.update((lists) => { Object.values(lists).forEach((playlist) => { playlist.episodes = playlist.episodes.filter((ep) => ep.title !== $currentEpisode.title); }); return lists; }); queue.remove($currentEpisode); } function onEpisodeEnded() { playedEpisodes.markAsPlayed($currentEpisode); removeEpisodeFromPlaylists(); queue.playNext(); } function onPlaybackRateChange(event) { $$invalidate(1, offBinding.playbackRate = event.detail.value, offBinding); } function onMetadataLoaded() { $$invalidate(3, isLoading = false); restorePlaybackTime(); } function restorePlaybackTime() { const playedEps = $playedEpisodes; const currentEp = $currentEpisode; if (playedEps[currentEp.title]) { currentTime.set(playedEps[currentEp.title].time); } else { currentTime.set(0); } isPaused.set(false); } let srcPromise = getSrc($currentEpisode); let playerTime = 0; onMount(() => { const unsub = currentTime.subscribe((ct) => { $$invalidate(0, playerTime = ct); }); const unsubDownloadedSource = downloadedEpisodes.subscribe((_) => { $$invalidate(4, srcPromise = getSrc($currentEpisode)); }); const unsubCurrentEpisode = currentEpisode.subscribe((_) => { $$invalidate(4, srcPromise = getSrc($currentEpisode)); }); return () => { unsub(); unsubDownloadedSource(); unsubCurrentEpisode(); }; }); onDestroy(() => { playedEpisodes.setEpisodeTime($currentEpisode, $currentTime, $duration, $currentTime === $duration); isPaused.set(true); }); function handleContextMenuEpisode({ detail: { event, episode } }) { spawnEpisodeContextMenu(episode, event); } function handleContextMenuEpisodeImage(event) { spawnEpisodeContextMenu($currentEpisode, event, { play: true, markPlayed: true }); } function handleClickEpisode(event) { const { episode } = event.detail; currentEpisode.set(episode); viewState.set(2 /* Player */); } function getSrc(episode) { return __awaiter(this, void 0, void 0, function* () { if (downloadedEpisodes.isEpisodeDownloaded(episode)) { const downloadedEpisode = downloadedEpisodes.getEpisode(episode); if (!downloadedEpisode) return ""; return createMediaUrlObjectFromFilePath(downloadedEpisode.filePath); } return episode.streamUrl; }); } function play_handler(event) { bubble.call(this, $$self, event); } const mouseenter_handler = () => $$invalidate(2, isHoveringArtwork = true); const mouseleave_handler = () => $$invalidate(2, isHoveringArtwork = false); function audio_durationchange_handler() { $duration = this.duration; duration.set($duration); } function audio_timeupdate_handler() { playerTime = this.currentTime; $$invalidate(0, playerTime); } function audio_play_pause_handler() { $isPaused = this.paused; isPaused.set($isPaused); } function audio_ratechange_handler() { offBinding._playbackRate = this.playbackRate; $$invalidate(1, offBinding); } $$self.$$.update = () => { if ($$self.$$.dirty[0] & 1) { $: { currentTime.set(playerTime); } } }; return [ playerTime, offBinding, isHoveringArtwork, isLoading, srcPromise, $currentEpisode, $duration, $currentTime, $plugin, $isPaused, $queue, togglePlayback, onClickProgressbar, onEpisodeEnded, onPlaybackRateChange, onMetadataLoaded, handleContextMenuEpisode, handleContextMenuEpisodeImage, handleClickEpisode, play_handler, mouseenter_handler, mouseleave_handler, audio_durationchange_handler, audio_timeupdate_handler, audio_play_pause_handler, audio_ratechange_handler ]; } var EpisodePlayer = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance19, create_fragment20, safe_not_equal, {}, add_css14, [-1, -1]); } }; var EpisodePlayer_default = EpisodePlayer; // src/ui/PodcastView/TopBar.svelte function add_css15(target) { append_styles(target, "svelte-shb2ik", ".topbar-container.svelte-shb2ik{display:flex;flex-direction:row;align-items:center;justify-content:space-between;height:50px;min-height:50px;border-bottom:1px solid var(--background-divider)}.topbar-menu-button.svelte-shb2ik{display:flex;align-items:center;justify-content:center;width:100%;height:100%;opacity:0.1}.topbar-selected.svelte-shb2ik{opacity:1 !important}.topbar-selectable.svelte-shb2ik{cursor:pointer;opacity:0.5}"); } function create_fragment21(ctx) { let div3; let div0; let icon0; let div0_class_value; let t0; let div1; let icon1; let div1_class_value; let t1; let div2; let icon2; let div2_class_value; let current; let mounted; let dispose; icon0 = new Icon_default({ props: { icon: "grid", size: 20 } }); icon1 = new Icon_default({ props: { icon: "list-minus", size: 20 } }); icon2 = new Icon_default({ props: { icon: "play", size: 20 } }); return { c() { div3 = element("div"); div0 = element("div"); create_component(icon0.$$.fragment); t0 = space(); div1 = element("div"); create_component(icon1.$$.fragment); t1 = space(); div2 = element("div"); create_component(icon2.$$.fragment); attr(div0, "class", div0_class_value = null_to_empty(` topbar-menu-button topbar-selectable ${ctx[0] === 0 /* PodcastGrid */ ? "topbar-selected" : ""} `) + " svelte-shb2ik"); attr(div0, "aria-label", "Podcast grid"); attr(div1, "class", div1_class_value = null_to_empty(` topbar-menu-button ${ctx[0] === 1 /* EpisodeList */ ? "topbar-selected" : ""} ${ctx[1] ? "topbar-selectable" : ""} `) + " svelte-shb2ik"); attr(div1, "aria-label", "Episode list"); attr(div2, "class", div2_class_value = null_to_empty(` topbar-menu-button ${ctx[0] === 2 /* Player */ ? "topbar-selected" : ""} ${ctx[2] ? "topbar-selectable" : ""} `) + " svelte-shb2ik"); attr(div2, "aria-label", "Player"); attr(div3, "class", "topbar-container svelte-shb2ik"); }, m(target, anchor) { insert(target, div3, anchor); append(div3, div0); mount_component(icon0, div0, null); append(div3, t0); append(div3, div1); mount_component(icon1, div1, null); append(div3, t1); append(div3, div2); mount_component(icon2, div2, null); current = true; if (!mounted) { dispose = [ listen(div0, "click", ctx[3].bind(null, 0 /* PodcastGrid */)), listen(div1, "click", ctx[3].bind(null, 1 /* EpisodeList */)), listen(div2, "click", ctx[3].bind(null, 2 /* Player */)) ]; mounted = true; } }, p(ctx2, [dirty]) { if (!current || dirty & 1 && div0_class_value !== (div0_class_value = null_to_empty(` topbar-menu-button topbar-selectable ${ctx2[0] === 0 /* PodcastGrid */ ? "topbar-selected" : ""} `) + " svelte-shb2ik")) { attr(div0, "class", div0_class_value); } if (!current || dirty & 3 && div1_class_value !== (div1_class_value = null_to_empty(` topbar-menu-button ${ctx2[0] === 1 /* EpisodeList */ ? "topbar-selected" : ""} ${ctx2[1] ? "topbar-selectable" : ""} `) + " svelte-shb2ik")) { attr(div1, "class", div1_class_value); } if (!current || dirty & 5 && div2_class_value !== (div2_class_value = null_to_empty(` topbar-menu-button ${ctx2[0] === 2 /* Player */ ? "topbar-selected" : ""} ${ctx2[2] ? "topbar-selectable" : ""} `) + " svelte-shb2ik")) { attr(div2, "class", div2_class_value); } }, i(local) { if (current) return; transition_in(icon0.$$.fragment, local); transition_in(icon1.$$.fragment, local); transition_in(icon2.$$.fragment, local); current = true; }, o(local) { transition_out(icon0.$$.fragment, local); transition_out(icon1.$$.fragment, local); transition_out(icon2.$$.fragment, local); current = false; }, d(detaching) { if (detaching) detach(div3); destroy_component(icon0); destroy_component(icon1); destroy_component(icon2); mounted = false; run_all(dispose); } }; } function instance20($$self, $$props, $$invalidate) { let { viewState: viewState2 = 0 /* PodcastGrid */ } = $$props; let { canShowEpisodeList = false } = $$props; let { canShowPlayer = false } = $$props; function handleClickMenuItem(newState) { if (viewState2 === newState) return; if (newState === 1 /* EpisodeList */ && !canShowEpisodeList) return; if (newState === 2 /* Player */ && !canShowPlayer) return; $$invalidate(0, viewState2 = newState); } $$self.$$set = ($$props2) => { if ("viewState" in $$props2) $$invalidate(0, viewState2 = $$props2.viewState); if ("canShowEpisodeList" in $$props2) $$invalidate(1, canShowEpisodeList = $$props2.canShowEpisodeList); if ("canShowPlayer" in $$props2) $$invalidate(2, canShowPlayer = $$props2.canShowPlayer); }; return [viewState2, canShowEpisodeList, canShowPlayer, handleClickMenuItem]; } var TopBar = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance20, create_fragment21, safe_not_equal, { viewState: 0, canShowEpisodeList: 1, canShowPlayer: 2 }, add_css15); } }; var TopBar_default = TopBar; // src/ui/PodcastView/EpisodeListHeader.svelte function add_css16(target) { append_styles(target, "svelte-uuatlf", ".podcast-header.svelte-uuatlf{display:flex;flex-direction:column;justify-content:space-around;align-items:center;padding:0.5rem}.podcast-heading.svelte-uuatlf{text-align:center}"); } function create_if_block9(ctx) { let img; let img_src_value; return { c() { img = element("img"); attr(img, "id", "podcast-artwork"); if (!src_url_equal(img.src, img_src_value = ctx[1])) attr(img, "src", img_src_value); attr(img, "alt", ctx[0]); }, m(target, anchor) { insert(target, img, anchor); }, p(ctx2, dirty) { if (dirty & 2 && !src_url_equal(img.src, img_src_value = ctx2[1])) { attr(img, "src", img_src_value); } if (dirty & 1) { attr(img, "alt", ctx2[0]); } }, d(detaching) { if (detaching) detach(img); } }; } function create_fragment22(ctx) { let div; let t0; let h2; let t1; let if_block = ctx[1] && create_if_block9(ctx); return { c() { div = element("div"); if (if_block) if_block.c(); t0 = space(); h2 = element("h2"); t1 = text(ctx[0]); attr(h2, "class", "podcast-heading svelte-uuatlf"); attr(div, "class", "podcast-header svelte-uuatlf"); }, m(target, anchor) { insert(target, div, anchor); if (if_block) if_block.m(div, null); append(div, t0); append(div, h2); append(h2, t1); }, p(ctx2, [dirty]) { if (ctx2[1]) { if (if_block) { if_block.p(ctx2, dirty); } else { if_block = create_if_block9(ctx2); if_block.c(); if_block.m(div, t0); } } else if (if_block) { if_block.d(1); if_block = null; } if (dirty & 1) set_data(t1, ctx2[0]); }, i: noop, o: noop, d(detaching) { if (detaching) detach(div); if (if_block) if_block.d(); } }; } function instance21($$self, $$props, $$invalidate) { let { text: text2 = "" } = $$props; let { artworkUrl = "" } = $$props; $$self.$$set = ($$props2) => { if ("text" in $$props2) $$invalidate(0, text2 = $$props2.text); if ("artworkUrl" in $$props2) $$invalidate(1, artworkUrl = $$props2.artworkUrl); }; return [text2, artworkUrl]; } var EpisodeListHeader = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance21, create_fragment22, safe_not_equal, { text: 0, artworkUrl: 1 }, add_css16); } }; var EpisodeListHeader_default = EpisodeListHeader; // src/ui/PodcastView/PodcastView.svelte var import_obsidian18 = require("obsidian"); // src/utility/searchEpisodes.ts function searchEpisodes(query, episodes) { if (episodes.length === 0) return []; if (query.length === 0) { return episodes; } const fuse = new Fuse(episodes, { shouldSort: true, findAllMatches: true, threshold: 0.4, isCaseSensitive: false, keys: ["title"] }); const searchResults = fuse.search(query); return searchResults.map((resItem) => resItem.item); } // src/ui/PodcastView/PodcastView.svelte function add_css17(target) { append_styles(target, "svelte-unmvd4", ".podcast-view.svelte-unmvd4{display:flex;flex-direction:column;height:100%}.go-back.svelte-unmvd4{display:flex;align-items:center;justify-content:center;padding:0.5rem;gap:0.5rem;cursor:pointer;margin-right:auto;opacity:0.75}.go-back.svelte-unmvd4:hover{opacity:1}"); } function create_if_block_4(ctx) { let podcastgrid; let current; podcastgrid = new PodcastGrid_default({ props: { feeds: ctx[0], playlists: ctx[4] } }); podcastgrid.$on("clickPodcast", ctx[9]); podcastgrid.$on("clickPlaylist", ctx[14]); return { c() { create_component(podcastgrid.$$.fragment); }, m(target, anchor) { mount_component(podcastgrid, target, anchor); current = true; }, p(ctx2, dirty) { const podcastgrid_changes = {}; if (dirty & 1) podcastgrid_changes.feeds = ctx2[0]; if (dirty & 16) podcastgrid_changes.playlists = ctx2[4]; podcastgrid.$set(podcastgrid_changes); }, i(local) { if (current) return; transition_in(podcastgrid.$$.fragment, local); current = true; }, o(local) { transition_out(podcastgrid.$$.fragment, local); current = false; }, d(detaching) { destroy_component(podcastgrid, detaching); } }; } function create_if_block_15(ctx) { let episodelist; let current; episodelist = new EpisodeList_default({ props: { episodes: ctx[3], showThumbnails: !ctx[1] || !ctx[2], $$slots: { header: [create_header_slot2] }, $$scope: { ctx } } }); episodelist.$on("clickEpisode", ctx[10]); episodelist.$on("contextMenuEpisode", ctx[11]); episodelist.$on("clickRefresh", ctx[12]); episodelist.$on("search", ctx[13]); return { c() { create_component(episodelist.$$.fragment); }, m(target, anchor) { mount_component(episodelist, target, anchor); current = true; }, p(ctx2, dirty) { const episodelist_changes = {}; if (dirty & 8) episodelist_changes.episodes = ctx2[3]; if (dirty & 6) episodelist_changes.showThumbnails = !ctx2[1] || !ctx2[2]; if (dirty & 67108910) { episodelist_changes.$$scope = { dirty, ctx: ctx2 }; } episodelist.$set(episodelist_changes); }, i(local) { if (current) return; transition_in(episodelist.$$.fragment, local); current = true; }, o(local) { transition_out(episodelist.$$.fragment, local); current = false; }, d(detaching) { destroy_component(episodelist, detaching); } }; } function create_if_block10(ctx) { let episodeplayer; let current; episodeplayer = new EpisodePlayer_default({}); return { c() { create_component(episodeplayer.$$.fragment); }, m(target, anchor) { mount_component(episodeplayer, target, anchor); current = true; }, p: noop, i(local) { if (current) return; transition_in(episodeplayer.$$.fragment, local); current = true; }, o(local) { transition_out(episodeplayer.$$.fragment, local); current = false; }, d(detaching) { destroy_component(episodeplayer, detaching); } }; } function create_else_block4(ctx) { let episodelistheader; let current; episodelistheader = new EpisodeListHeader_default({ props: { text: "Latest Episodes" } }); return { c() { create_component(episodelistheader.$$.fragment); }, m(target, anchor) { mount_component(episodelistheader, target, anchor); current = true; }, p: noop, i(local) { if (current) return; transition_in(episodelistheader.$$.fragment, local); current = true; }, o(local) { transition_out(episodelistheader.$$.fragment, local); current = false; }, d(detaching) { destroy_component(episodelistheader, detaching); } }; } function create_if_block_3(ctx) { let span; let icon0; let t0; let t1; let div; let icon1; let t2; let episodelistheader; let current; let mounted; let dispose; icon0 = new Icon_default({ props: { icon: "arrow-left", style: { display: "flex", "align-items": "center" }, size: 20 } }); icon1 = new Icon_default({ props: { icon: ctx[2].icon, size: 40, clickable: false } }); episodelistheader = new EpisodeListHeader_default({ props: { text: ctx[2].name } }); return { c() { span = element("span"); create_component(icon0.$$.fragment); t0 = text(" Latest Episodes"); t1 = space(); div = element("div"); create_component(icon1.$$.fragment); t2 = space(); create_component(episodelistheader.$$.fragment); attr(span, "class", "go-back svelte-unmvd4"); set_style(div, "display", "flex"); set_style(div, "align-items", "center"); set_style(div, "justify-content", "center"); }, m(target, anchor) { insert(target, span, anchor); mount_component(icon0, span, null); append(span, t0); insert(target, t1, anchor); insert(target, div, anchor); mount_component(icon1, div, null); insert(target, t2, anchor); mount_component(episodelistheader, target, anchor); current = true; if (!mounted) { dispose = listen(span, "click", ctx[17]); mounted = true; } }, p(ctx2, dirty) { const icon1_changes = {}; if (dirty & 4) icon1_changes.icon = ctx2[2].icon; icon1.$set(icon1_changes); const episodelistheader_changes = {}; if (dirty & 4) episodelistheader_changes.text = ctx2[2].name; episodelistheader.$set(episodelistheader_changes); }, i(local) { if (current) return; transition_in(icon0.$$.fragment, local); transition_in(icon1.$$.fragment, local); transition_in(episodelistheader.$$.fragment, local); current = true; }, o(local) { transition_out(icon0.$$.fragment, local); transition_out(icon1.$$.fragment, local); transition_out(episodelistheader.$$.fragment, local); current = false; }, d(detaching) { if (detaching) detach(span); destroy_component(icon0); if (detaching) detach(t1); if (detaching) detach(div); destroy_component(icon1); if (detaching) detach(t2); destroy_component(episodelistheader, detaching); mounted = false; dispose(); } }; } function create_if_block_22(ctx) { let span; let icon; let t0; let t1; let episodelistheader; let current; let mounted; let dispose; icon = new Icon_default({ props: { icon: "arrow-left", style: { display: "flex", "align-items": "center" }, size: 20 } }); episodelistheader = new EpisodeListHeader_default({ props: { text: ctx[1].title, artworkUrl: ctx[1].artworkUrl } }); return { c() { span = element("span"); create_component(icon.$$.fragment); t0 = text(" Latest Episodes"); t1 = space(); create_component(episodelistheader.$$.fragment); attr(span, "class", "go-back svelte-unmvd4"); }, m(target, anchor) { insert(target, span, anchor); mount_component(icon, span, null); append(span, t0); insert(target, t1, anchor); mount_component(episodelistheader, target, anchor); current = true; if (!mounted) { dispose = listen(span, "click", ctx[16]); mounted = true; } }, p(ctx2, dirty) { const episodelistheader_changes = {}; if (dirty & 2) episodelistheader_changes.text = ctx2[1].title; if (dirty & 2) episodelistheader_changes.artworkUrl = ctx2[1].artworkUrl; episodelistheader.$set(episodelistheader_changes); }, i(local) { if (current) return; transition_in(icon.$$.fragment, local); transition_in(episodelistheader.$$.fragment, local); current = true; }, o(local) { transition_out(icon.$$.fragment, local); transition_out(episodelistheader.$$.fragment, local); current = false; }, d(detaching) { if (detaching) detach(span); destroy_component(icon); if (detaching) detach(t1); destroy_component(episodelistheader, detaching); mounted = false; dispose(); } }; } function create_header_slot2(ctx) { let current_block_type_index; let if_block; let if_block_anchor; let current; const if_block_creators = [create_if_block_22, create_if_block_3, create_else_block4]; const if_blocks = []; function select_block_type_1(ctx2, dirty) { if (ctx2[1]) return 0; if (ctx2[2]) return 1; return 2; } current_block_type_index = select_block_type_1(ctx, -1); if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); return { c() { if_block.c(); if_block_anchor = empty(); }, m(target, anchor) { if_blocks[current_block_type_index].m(target, anchor); insert(target, if_block_anchor, anchor); current = true; }, p(ctx2, dirty) { let previous_block_index = current_block_type_index; current_block_type_index = select_block_type_1(ctx2, dirty); if (current_block_type_index === previous_block_index) { if_blocks[current_block_type_index].p(ctx2, dirty); } else { group_outros(); transition_out(if_blocks[previous_block_index], 1, 1, () => { if_blocks[previous_block_index] = null; }); check_outros(); if_block = if_blocks[current_block_type_index]; if (!if_block) { if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); if_block.c(); } else { if_block.p(ctx2, dirty); } transition_in(if_block, 1); if_block.m(if_block_anchor.parentNode, if_block_anchor); } }, i(local) { if (current) return; transition_in(if_block); current = true; }, o(local) { transition_out(if_block); current = false; }, d(detaching) { if_blocks[current_block_type_index].d(detaching); if (detaching) detach(if_block_anchor); } }; } function create_fragment23(ctx) { let div; let topbar; let updating_viewState; let t; let current_block_type_index; let if_block; let current; function topbar_viewState_binding(value) { ctx[15](value); } let topbar_props = { canShowEpisodeList: true, canShowPlayer: !!ctx[6] }; if (ctx[8] !== void 0) { topbar_props.viewState = ctx[8]; } topbar = new TopBar_default({ props: topbar_props }); binding_callbacks.push(() => bind(topbar, "viewState", topbar_viewState_binding)); const if_block_creators = [create_if_block10, create_if_block_15, create_if_block_4]; const if_blocks = []; function select_block_type(ctx2, dirty) { if (ctx2[8] === 2 /* Player */) return 0; if (ctx2[8] === 1 /* EpisodeList */) return 1; if (ctx2[8] === 0 /* PodcastGrid */) return 2; return -1; } if (~(current_block_type_index = select_block_type(ctx, -1))) { if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); } return { c() { div = element("div"); create_component(topbar.$$.fragment); t = space(); if (if_block) if_block.c(); attr(div, "class", "podcast-view svelte-unmvd4"); }, m(target, anchor) { insert(target, div, anchor); mount_component(topbar, div, null); append(div, t); if (~current_block_type_index) { if_blocks[current_block_type_index].m(div, null); } ctx[18](div); current = true; }, p(ctx2, [dirty]) { const topbar_changes = {}; if (dirty & 64) topbar_changes.canShowPlayer = !!ctx2[6]; if (!updating_viewState && dirty & 256) { updating_viewState = true; topbar_changes.viewState = ctx2[8]; add_flush_callback(() => updating_viewState = false); } topbar.$set(topbar_changes); let previous_block_index = current_block_type_index; current_block_type_index = select_block_type(ctx2, dirty); if (current_block_type_index === previous_block_index) { if (~current_block_type_index) { if_blocks[current_block_type_index].p(ctx2, dirty); } } else { if (if_block) { group_outros(); transition_out(if_blocks[previous_block_index], 1, 1, () => { if_blocks[previous_block_index] = null; }); check_outros(); } if (~current_block_type_index) { if_block = if_blocks[current_block_type_index]; if (!if_block) { if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx2); if_block.c(); } else { if_block.p(ctx2, dirty); } transition_in(if_block, 1); if_block.m(div, null); } else { if_block = null; } } }, i(local) { if (current) return; transition_in(topbar.$$.fragment, local); transition_in(if_block); current = true; }, o(local) { transition_out(topbar.$$.fragment, local); transition_out(if_block); current = false; }, d(detaching) { if (detaching) detach(div); destroy_component(topbar); if (~current_block_type_index) { if_blocks[current_block_type_index].d(); } ctx[18](null); } }; } function instance22($$self, $$props, $$invalidate) { let $queue; let $currentEpisode; let $episodeCache; let $downloadedEpisodes; let $localFiles; let $favorites; let $podcastView; let $viewState; component_subscribe($$self, queue, ($$value) => $$invalidate(19, $queue = $$value)); component_subscribe($$self, currentEpisode, ($$value) => $$invalidate(6, $currentEpisode = $$value)); component_subscribe($$self, episodeCache, ($$value) => $$invalidate(20, $episodeCache = $$value)); component_subscribe($$self, downloadedEpisodes, ($$value) => $$invalidate(21, $downloadedEpisodes = $$value)); component_subscribe($$self, localFiles, ($$value) => $$invalidate(22, $localFiles = $$value)); component_subscribe($$self, favorites, ($$value) => $$invalidate(23, $favorites = $$value)); component_subscribe($$self, podcastView, ($$value) => $$invalidate(7, $podcastView = $$value)); component_subscribe($$self, viewState, ($$value) => $$invalidate(8, $viewState = $$value)); let feeds = []; let selectedFeed = null; let selectedPlaylist = null; let displayedEpisodes = []; let displayedPlaylists = []; let latestEpisodes = []; onMount(() => __awaiter(void 0, void 0, void 0, function* () { const unsubscribePlaylists = playlists.subscribe((pl) => { $$invalidate(4, displayedPlaylists = [$queue, $favorites, $localFiles, ...Object.values(pl)]); }); const unsubscribeSavedFeeds = savedFeeds.subscribe((storeValue) => { $$invalidate(0, feeds = Object.values(storeValue)); }); yield fetchEpisodesInAllFeeds(feeds); const unsubscribeEpisodeCache = episodeCache.subscribe((cache) => { $$invalidate(5, latestEpisodes = Object.entries(cache).map(([_, episodes]) => episodes.slice(0, 10)).flat().sort((a, b) => { if (a.episodeDate && b.episodeDate) return Number(b.episodeDate) - Number(a.episodeDate); return 0; })); }); if (!selectedFeed) { $$invalidate(3, displayedEpisodes = latestEpisodes); } return () => { unsubscribeEpisodeCache(); unsubscribeSavedFeeds(); unsubscribePlaylists(); }; })); function fetchEpisodes(feed, useCache = true) { return __awaiter(this, void 0, void 0, function* () { const cachedEpisodesInFeed = $episodeCache[feed.title]; if (useCache && cachedEpisodesInFeed && cachedEpisodesInFeed.length > 0) { return cachedEpisodesInFeed; } try { const episodes = yield new FeedParser(feed).getEpisodes(feed.url); episodeCache.update((cache) => Object.assign(Object.assign({}, cache), { [feed.title]: episodes })); return episodes; } catch (error) { return $downloadedEpisodes[feed.title]; } }); } function fetchEpisodesInAllFeeds(feedsToSearch) { return Promise.all(feedsToSearch.map((feed) => fetchEpisodes(feed))).then((episodes) => { return episodes.flat(); }); } function handleClickPodcast(event) { return __awaiter(this, void 0, void 0, function* () { const { feed } = event.detail; $$invalidate(3, displayedEpisodes = []); $$invalidate(1, selectedFeed = feed); $$invalidate(3, displayedEpisodes = yield fetchEpisodes(feed)); viewState.set(1 /* EpisodeList */); }); } function handleClickEpisode(event) { const { episode } = event.detail; currentEpisode.set(episode); viewState.set(2 /* Player */); } function handleContextMenuEpisode({ detail: { event, episode } }) { spawnEpisodeContextMenu(episode, event); } function handleClickRefresh() { return __awaiter(this, void 0, void 0, function* () { if (!selectedFeed) return; $$invalidate(3, displayedEpisodes = yield fetchEpisodes(selectedFeed, false)); }); } const handleSearch = (0, import_obsidian18.debounce)((event) => { const { query } = event.detail; if (selectedFeed) { const episodesInFeed = $episodeCache[selectedFeed.title]; $$invalidate(3, displayedEpisodes = searchEpisodes(query, episodesInFeed)); return; } $$invalidate(3, displayedEpisodes = searchEpisodes(query, latestEpisodes)); }, 250); function handleClickPlaylist(event) { const { event: clickEvent, playlist } = event.detail; if (playlist.name === $queue.name && $queue.episodes.length > 0) { if (!$currentEpisode) { currentEpisode.set($queue.episodes[0]); } viewState.set(2 /* Player */); } else { $$invalidate(2, selectedPlaylist = playlist); $$invalidate(3, displayedEpisodes = playlist.episodes); viewState.set(1 /* EpisodeList */); } } function topbar_viewState_binding(value) { $viewState = value; viewState.set($viewState); } const click_handler = () => { $$invalidate(1, selectedFeed = null); $$invalidate(3, displayedEpisodes = latestEpisodes); viewState.set(1 /* EpisodeList */); }; const click_handler_1 = () => { $$invalidate(2, selectedPlaylist = null); $$invalidate(3, displayedEpisodes = latestEpisodes); viewState.set(1 /* EpisodeList */); }; function div_binding($$value) { binding_callbacks[$$value ? "unshift" : "push"](() => { $podcastView = $$value; podcastView.set($podcastView); }); } return [ feeds, selectedFeed, selectedPlaylist, displayedEpisodes, displayedPlaylists, latestEpisodes, $currentEpisode, $podcastView, $viewState, handleClickPodcast, handleClickEpisode, handleContextMenuEpisode, handleClickRefresh, handleSearch, handleClickPlaylist, topbar_viewState_binding, click_handler, click_handler_1, div_binding ]; } var PodcastView = class extends SvelteComponent { constructor(options) { super(); init(this, options, instance22, create_fragment23, safe_not_equal, {}, add_css17); } }; var PodcastView_default = PodcastView; // src/ui/PodcastView/index.ts var MainView = class extends import_obsidian19.ItemView { constructor(leaf, plugin2) { super(leaf); this.plugin = plugin2; } getViewType() { return VIEW_TYPE; } getDisplayText() { return "Podcast Player"; } getIcon() { return "play-circle"; } async onOpen() { this.PodcastView = new PodcastView_default({ target: this.contentEl }); } async onClose() { this.PodcastView?.$destroy(); this.contentEl.empty(); } }; // src/types/StoreController.ts var StoreController = class { constructor(store) { this.store = store; } on() { this.unsubscribe = this.store.subscribe(this.onChange.bind(this)); return this; } off() { this.unsubscribe(); return this; } }; // src/store_controllers/EpisodeStatusController.ts var EpisodeStatusController = class extends StoreController { constructor(store, plugin2) { super(store); this.plugin = plugin2; } onChange(value) { this.plugin.settings.playedEpisodes = value; this.plugin.saveSettings(); } }; // src/store_controllers/SavedFeedsController.ts var SavedFeedsController = class extends StoreController { constructor(store, plugin2) { super(store); this.plugin = plugin2; } onChange(value) { this.plugin.settings.savedFeeds = value; this.plugin.saveSettings(); } }; // src/store_controllers/PlaylistController.ts var PlaylistController = class extends StoreController { constructor(store, plugin2) { super(store); this.plugin = plugin2; } onChange(value) { this.plugin.settings.playlists = value; this.plugin.saveSettings(); } }; // src/store_controllers/QueueController.ts var QueueController = class extends StoreController { constructor(store, plugin2) { super(store); this.plugin = plugin2; } onChange(value) { this.plugin.settings.queue = { ...value, ...QUEUE_SETTINGS }; this.plugin.saveSettings(); } on() { this.removeCurrentEpisodeFromQueue(); return super.on(); } off() { this.unsubscribeCurrentEpisode(); return super.off(); } removeCurrentEpisodeFromQueue() { this.unsubscribeCurrentEpisode = currentEpisode.subscribe((episode) => { if (!episode) return; const queue2 = get_store_value(this.store); const episodeIsInQueue = queue2.episodes.find((e) => e.title === episode.title); this.store.update((playlist) => { if (!episodeIsInQueue) return playlist; playlist.episodes = playlist.episodes.filter((e) => e.title !== episode.title); return playlist; }); }); } }; // src/store_controllers/FavoritesController.ts var FavoritesController = class extends StoreController { constructor(store, plugin2) { super(store); this.plugin = plugin2; } onChange(value) { this.plugin.settings.favorites = { ...value, ...FAVORITES_SETTINGS }; this.plugin.saveSettings(); } }; // src/store_controllers/CurrentEpisodeController.ts var CurrentEpisodeController = class extends StoreController { constructor(store, plugin2) { super(store); this.plugin = plugin2; } onChange(value) { this.plugin.settings.currentEpisode = value; this.plugin.saveSettings(); } }; // src/store_controllers/DownloadedEpisodesController.ts var DownloadedEpisodesController = class extends StoreController { constructor(store, plugin2) { super(store); this.plugin = plugin2; } onChange(value) { this.plugin.settings.downloadedEpisodes = value; this.plugin.saveSettings(); } }; // src/store_controllers/LocalFilesController.ts var LocalFilesController = class extends StoreController { constructor(store, plugin2) { super(store); this.plugin = plugin2; } onChange(value) { this.plugin.settings.localFiles = { ...value, ...LOCAL_FILES_SETTINGS }; this.plugin.saveSettings(); } }; // src/URIHandler.ts var import_obsidian20 = require("obsidian"); async function podNotesURIHandler({ url, episodeName, time }, api) { if (!url || !episodeName || !time) { new import_obsidian20.Notice("URL, episode name, and timestamp are required to play an episode"); return; } const decodedName = episodeName.replace(/\+/g, " "); const currentEp = get_store_value(currentEpisode); const episodeIsPlaying = currentEp?.title === decodedName; if (episodeIsPlaying) { viewState.set(2 /* Player */); api.currentTime = parseFloat(time); return; } const decodedUrl = url.replace(/\+/g, " "); const localFile = app.vault.getAbstractFileByPath(decodedUrl); let episode; if (localFile) { episode = localFiles.getLocalEpisode(decodedName); } else { const feedparser = new FeedParser(); episode = await feedparser.findItemByTitle(decodedName, url); } if (!episode) { new import_obsidian20.Notice("Episode not found"); return; } currentEpisode.set(episode); viewState.set(2 /* Player */); new import_obsidian20.Notice("Episode found, playing now. Please click timestamp again to play at specific time."); } // src/getContextMenuHandler.ts var import_obsidian21 = require("obsidian"); function getContextMenuHandler() { return this.app.workspace.on("file-menu", (menu, file) => { if (!(file instanceof import_obsidian21.TFile)) return; if (!file.extension.match(/mp3|mp4|wma|aac|wav|webm|aac|flac|m4a|/)) return; menu.addItem((item) => item.setIcon("play").setTitle("Play with PodNotes").onClick(async () => { const localEpisode = { title: file.basename, description: "", content: "", podcastName: "local file", url: app.fileManager.generateMarkdownLink(file, ""), streamUrl: await createMediaUrlObjectFromFilePath(file.path), episodeDate: new Date(file.stat.ctime) }; if (!downloadedEpisodes.isEpisodeDownloaded(localEpisode)) { downloadedEpisodes.addEpisode(localEpisode, file.path, file.stat.size); localFiles.addEpisode(localEpisode); } if (get_store_value(playedEpisodes)[file.basename]?.finished) { playedEpisodes.markAsUnplayed(localEpisode); } currentEpisode.set(localEpisode); viewState.set(2 /* Player */); })); }); } // src/getUniversalPodcastLink.ts var import_obsidian22 = require("obsidian"); async function getUniversalPodcastLink(api) { const { title, itunesTitle, podcastName, feedUrl } = api.podcast; try { const iTunesResponse = await queryiTunesPodcasts(api.podcast.podcastName); const podcast = iTunesResponse.find((pod) => pod.title === podcastName && pod.url === feedUrl); if (!podcast || !podcast.collectionId) { throw new Error("Failed to get podcast from iTunes."); } const podLinkUrl = `https://pod.link/${podcast.collectionId}.json?limit=1000`; const res = await (0, import_obsidian22.requestUrl)({ url: podLinkUrl }); if (res.status !== 200) { throw new Error(`Failed to get response from pod.link: ${podLinkUrl}`); } const targetTitle = itunesTitle ?? title; const ep = res.json.episodes.find((episode) => episode.title === targetTitle); if (!ep) { throw new Error(`Failed to find episode "${targetTitle}" on pod.link. URL: ${podLinkUrl}`); } window.navigator.clipboard.writeText(`https://pod.link/${podcast.collectionId}/episode/${ep.episodeId}`); new import_obsidian22.Notice("Universal episode link copied to clipboard."); } catch (error) { new import_obsidian22.Notice("Could not get podcast link."); console.error(error); return; } } // src/services/TranscriptionService.ts var import_obsidian23 = require("obsidian"); // node_modules/openai/error.mjs var error_exports = {}; __export(error_exports, { APIConnectionError: () => APIConnectionError, APIConnectionTimeoutError: () => APIConnectionTimeoutError, APIError: () => APIError, APIUserAbortError: () => APIUserAbortError, AuthenticationError: () => AuthenticationError, BadRequestError: () => BadRequestError, ConflictError: () => ConflictError, InternalServerError: () => InternalServerError, NotFoundError: () => NotFoundError, OpenAIError: () => OpenAIError, PermissionDeniedError: () => PermissionDeniedError, RateLimitError: () => RateLimitError, UnprocessableEntityError: () => UnprocessableEntityError }); // node_modules/openai/version.mjs var VERSION = "4.52.7"; // node_modules/openai/_shims/registry.mjs var auto = false; var kind = void 0; var fetch2 = void 0; var Request2 = void 0; var Response2 = void 0; var Headers2 = void 0; var FormData2 = void 0; var Blob2 = void 0; var File2 = void 0; var ReadableStream2 = void 0; var getMultipartRequestOptions = void 0; var getDefaultAgent = void 0; var fileFromPath = void 0; var isFsReadStream = void 0; function setShims(shims, options = { auto: false }) { if (auto) { throw new Error(`you must \`import 'openai/shims/${shims.kind}'\` before importing anything else from openai`); } if (kind) { throw new Error(`can't \`import 'openai/shims/${shims.kind}'\` after \`import 'openai/shims/${kind}'\``); } auto = options.auto; kind = shims.kind; fetch2 = shims.fetch; Request2 = shims.Request; Response2 = shims.Response; Headers2 = shims.Headers; FormData2 = shims.FormData; Blob2 = shims.Blob; File2 = shims.File; ReadableStream2 = shims.ReadableStream; getMultipartRequestOptions = shims.getMultipartRequestOptions; getDefaultAgent = shims.getDefaultAgent; fileFromPath = shims.fileFromPath; isFsReadStream = shims.isFsReadStream; } // node_modules/openai/_shims/MultipartBody.mjs var MultipartBody = class { constructor(body) { this.body = body; } get [Symbol.toStringTag]() { return "MultipartBody"; } }; // node_modules/openai/_shims/web-runtime.mjs function getRuntime({ manuallyImported } = {}) { const recommendation = manuallyImported ? `You may need to use polyfills` : `Add one of these imports before your first \`import \u2026 from 'openai'\`: - \`import 'openai/shims/node'\` (if you're running on Node) - \`import 'openai/shims/web'\` (otherwise) `; let _fetch, _Request, _Response, _Headers; try { _fetch = fetch; _Request = Request; _Response = Response; _Headers = Headers; } catch (error) { throw new Error(`this environment is missing the following Web Fetch API type: ${error.message}. ${recommendation}`); } return { kind: "web", fetch: _fetch, Request: _Request, Response: _Response, Headers: _Headers, FormData: typeof FormData !== "undefined" ? FormData : class FormData { constructor() { throw new Error(`file uploads aren't supported in this environment yet as 'FormData' is undefined. ${recommendation}`); } }, Blob: typeof Blob !== "undefined" ? Blob : class Blob { constructor() { throw new Error(`file uploads aren't supported in this environment yet as 'Blob' is undefined. ${recommendation}`); } }, File: typeof File !== "undefined" ? File : class File { constructor() { throw new Error(`file uploads aren't supported in this environment yet as 'File' is undefined. ${recommendation}`); } }, ReadableStream: typeof ReadableStream !== "undefined" ? ReadableStream : class ReadableStream { constructor() { throw new Error(`streaming isn't supported in this environment yet as 'ReadableStream' is undefined. ${recommendation}`); } }, getMultipartRequestOptions: async (form, opts) => ({ ...opts, body: new MultipartBody(form) }), getDefaultAgent: (url) => void 0, fileFromPath: () => { throw new Error("The `fileFromPath` function is only supported in Node. See the README for more details: https://www.github.com/openai/openai-node#file-uploads"); }, isFsReadStream: (value) => false }; } // node_modules/openai/_shims/index.mjs if (!kind) setShims(getRuntime(), { auto: true }); // node_modules/openai/streaming.mjs var Stream = class { constructor(iterator, controller) { this.iterator = iterator; this.controller = controller; } static fromSSEResponse(response, controller) { let consumed = false; async function* iterator() { if (consumed) { throw new Error("Cannot iterate over a consumed stream, use `.tee()` to split the stream."); } consumed = true; let done = false; try { for await (const sse of _iterSSEMessages(response, controller)) { if (done) continue; if (sse.data.startsWith("[DONE]")) { done = true; continue; } if (sse.event === null) { let data; try { data = JSON.parse(sse.data); } catch (e) { console.error(`Could not parse message into JSON:`, sse.data); console.error(`From chunk:`, sse.raw); throw e; } if (data && data.error) { throw new APIError(void 0, data.error, void 0, void 0); } yield data; } else { let data; try { data = JSON.parse(sse.data); } catch (e) { console.error(`Could not parse message into JSON:`, sse.data); console.error(`From chunk:`, sse.raw); throw e; } if (sse.event == "error") { throw new APIError(void 0, data.error, data.message, void 0); } yield { event: sse.event, data }; } } done = true; } catch (e) { if (e instanceof Error && e.name === "AbortError") return; throw e; } finally { if (!done) controller.abort(); } } return new Stream(iterator, controller); } static fromReadableStream(readableStream, controller) { let consumed = false; async function* iterLines() { const lineDecoder = new LineDecoder(); const iter = readableStreamAsyncIterable(readableStream); for await (const chunk of iter) { for (const line of lineDecoder.decode(chunk)) { yield line; } } for (const line of lineDecoder.flush()) { yield line; } } async function* iterator() { if (consumed) { throw new Error("Cannot iterate over a consumed stream, use `.tee()` to split the stream."); } consumed = true; let done = false; try { for await (const line of iterLines()) { if (done) continue; if (line) yield JSON.parse(line); } done = true; } catch (e) { if (e instanceof Error && e.name === "AbortError") return; throw e; } finally { if (!done) controller.abort(); } } return new Stream(iterator, controller); } [Symbol.asyncIterator]() { return this.iterator(); } tee() { const left = []; const right = []; const iterator = this.iterator(); const teeIterator = (queue2) => { return { next: () => { if (queue2.length === 0) { const result = iterator.next(); left.push(result); right.push(result); } return queue2.shift(); } }; }; return [ new Stream(() => teeIterator(left), this.controller), new Stream(() => teeIterator(right), this.controller) ]; } toReadableStream() { const self2 = this; let iter; const encoder = new TextEncoder(); return new ReadableStream2({ async start() { iter = self2[Symbol.asyncIterator](); }, async pull(ctrl) { try { const { value, done } = await iter.next(); if (done) return ctrl.close(); const bytes = encoder.encode(JSON.stringify(value) + "\n"); ctrl.enqueue(bytes); } catch (err) { ctrl.error(err); } }, async cancel() { await iter.return?.(); } }); } }; async function* _iterSSEMessages(response, controller) { if (!response.body) { controller.abort(); throw new OpenAIError(`Attempted to iterate over a response with no body`); } const sseDecoder = new SSEDecoder(); const lineDecoder = new LineDecoder(); const iter = readableStreamAsyncIterable(response.body); for await (const sseChunk of iterSSEChunks(iter)) { for (const line of lineDecoder.decode(sseChunk)) { const sse = sseDecoder.decode(line); if (sse) yield sse; } } for (const line of lineDecoder.flush()) { const sse = sseDecoder.decode(line); if (sse) yield sse; } } async function* iterSSEChunks(iterator) { let data = new Uint8Array(); for await (const chunk of iterator) { if (chunk == null) { continue; } const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) : typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk; let newData = new Uint8Array(data.length + binaryChunk.length); newData.set(data); newData.set(binaryChunk, data.length); data = newData; let patternIndex; while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) { yield data.slice(0, patternIndex); data = data.slice(patternIndex); } } if (data.length > 0) { yield data; } } function findDoubleNewlineIndex(buffer) { const newline = 10; const carriage = 13; for (let i = 0; i < buffer.length - 2; i++) { if (buffer[i] === newline && buffer[i + 1] === newline) { return i + 2; } if (buffer[i] === carriage && buffer[i + 1] === carriage) { return i + 2; } if (buffer[i] === carriage && buffer[i + 1] === newline && i + 3 < buffer.length && buffer[i + 2] === carriage && buffer[i + 3] === newline) { return i + 4; } } return -1; } var SSEDecoder = class { constructor() { this.event = null; this.data = []; this.chunks = []; } decode(line) { if (line.endsWith("\r")) { line = line.substring(0, line.length - 1); } if (!line) { if (!this.event && !this.data.length) return null; const sse = { event: this.event, data: this.data.join("\n"), raw: this.chunks }; this.event = null; this.data = []; this.chunks = []; return sse; } this.chunks.push(line); if (line.startsWith(":")) { return null; } let [fieldname, _, value] = partition(line, ":"); if (value.startsWith(" ")) { value = value.substring(1); } if (fieldname === "event") { this.event = value; } else if (fieldname === "data") { this.data.push(value); } return null; } }; var LineDecoder = class { constructor() { this.buffer = []; this.trailingCR = false; } decode(chunk) { let text2 = this.decodeText(chunk); if (this.trailingCR) { text2 = "\r" + text2; this.trailingCR = false; } if (text2.endsWith("\r")) { this.trailingCR = true; text2 = text2.slice(0, -1); } if (!text2) { return []; } const trailingNewline = LineDecoder.NEWLINE_CHARS.has(text2[text2.length - 1] || ""); let lines = text2.split(LineDecoder.NEWLINE_REGEXP); if (trailingNewline) { lines.pop(); } if (lines.length === 1 && !trailingNewline) { this.buffer.push(lines[0]); return []; } if (this.buffer.length > 0) { lines = [this.buffer.join("") + lines[0], ...lines.slice(1)]; this.buffer = []; } if (!trailingNewline) { this.buffer = [lines.pop() || ""]; } return lines; } decodeText(bytes) { if (bytes == null) return ""; if (typeof bytes === "string") return bytes; if (typeof Buffer !== "undefined") { if (bytes instanceof Buffer) { return bytes.toString(); } if (bytes instanceof Uint8Array) { return Buffer.from(bytes).toString(); } throw new OpenAIError(`Unexpected: received non-Uint8Array (${bytes.constructor.name}) stream chunk in an environment with a global "Buffer" defined, which this library assumes to be Node. Please report this error.`); } if (typeof TextDecoder !== "undefined") { if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) { this.textDecoder ?? (this.textDecoder = new TextDecoder("utf8")); return this.textDecoder.decode(bytes); } throw new OpenAIError(`Unexpected: received non-Uint8Array/ArrayBuffer (${bytes.constructor.name}) in a web platform. Please report this error.`); } throw new OpenAIError(`Unexpected: neither Buffer nor TextDecoder are available as globals. Please report this error.`); } flush() { if (!this.buffer.length && !this.trailingCR) { return []; } const lines = [this.buffer.join("")]; this.buffer = []; this.trailingCR = false; return lines; } }; LineDecoder.NEWLINE_CHARS = /* @__PURE__ */ new Set(["\n", "\r"]); LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g; function partition(str2, delimiter) { const index = str2.indexOf(delimiter); if (index !== -1) { return [str2.substring(0, index), delimiter, str2.substring(index + delimiter.length)]; } return [str2, "", ""]; } function readableStreamAsyncIterable(stream) { if (stream[Symbol.asyncIterator]) return stream; const reader = stream.getReader(); return { async next() { try { const result = await reader.read(); if (result?.done) reader.releaseLock(); return result; } catch (e) { reader.releaseLock(); throw e; } }, async return() { const cancelPromise = reader.cancel(); reader.releaseLock(); await cancelPromise; return { done: true, value: void 0 }; }, [Symbol.asyncIterator]() { return this; } }; } // node_modules/openai/uploads.mjs var isResponseLike = (value) => value != null && typeof value === "object" && typeof value.url === "string" && typeof value.blob === "function"; var isFileLike = (value) => value != null && typeof value === "object" && typeof value.name === "string" && typeof value.lastModified === "number" && isBlobLike(value); var isBlobLike = (value) => value != null && typeof value === "object" && typeof value.size === "number" && typeof value.type === "string" && typeof value.text === "function" && typeof value.slice === "function" && typeof value.arrayBuffer === "function"; var isUploadable = (value) => { return isFileLike(value) || isResponseLike(value) || isFsReadStream(value); }; async function toFile(value, name, options) { value = await value; options ?? (options = isFileLike(value) ? { lastModified: value.lastModified, type: value.type } : {}); if (isResponseLike(value)) { const blob = await value.blob(); name || (name = new URL(value.url).pathname.split(/[\\/]/).pop() ?? "unknown_file"); return new File2([blob], name, options); } const bits = await getBytes(value); name || (name = getName(value) ?? "unknown_file"); if (!options.type) { const type = bits[0]?.type; if (typeof type === "string") { options = { ...options, type }; } } return new File2(bits, name, options); } async function getBytes(value) { let parts = []; if (typeof value === "string" || ArrayBuffer.isView(value) || value instanceof ArrayBuffer) { parts.push(value); } else if (isBlobLike(value)) { parts.push(await value.arrayBuffer()); } else if (isAsyncIterableIterator(value)) { for await (const chunk of value) { parts.push(chunk); } } else { throw new Error(`Unexpected data type: ${typeof value}; constructor: ${value?.constructor?.name}; props: ${propsForError(value)}`); } return parts; } function propsForError(value) { const props = Object.getOwnPropertyNames(value); return `[${props.map((p) => `"${p}"`).join(", ")}]`; } function getName(value) { return getStringFromMaybeBuffer(value.name) || getStringFromMaybeBuffer(value.filename) || getStringFromMaybeBuffer(value.path)?.split(/[\\/]/).pop(); } var getStringFromMaybeBuffer = (x) => { if (typeof x === "string") return x; if (typeof Buffer !== "undefined" && x instanceof Buffer) return String(x); return void 0; }; var isAsyncIterableIterator = (value) => value != null && typeof value === "object" && typeof value[Symbol.asyncIterator] === "function"; var isMultipartBody = (body) => body && typeof body === "object" && body.body && body[Symbol.toStringTag] === "MultipartBody"; var multipartFormRequestOptions = async (opts) => { const form = await createForm(opts.body); return getMultipartRequestOptions(form, opts); }; var createForm = async (body) => { const form = new FormData2(); await Promise.all(Object.entries(body || {}).map(([key, value]) => addFormValue(form, key, value))); return form; }; var addFormValue = async (form, key, value) => { if (value === void 0) return; if (value == null) { throw new TypeError(`Received null for "${key}"; to pass null in FormData, you must use the string 'null'`); } if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { form.append(key, String(value)); } else if (isUploadable(value)) { const file = await toFile(value); form.append(key, file); } else if (Array.isArray(value)) { await Promise.all(value.map((entry) => addFormValue(form, key + "[]", entry))); } else if (typeof value === "object") { await Promise.all(Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop))); } else { throw new TypeError(`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`); } }; // node_modules/openai/core.mjs var __classPrivateFieldSet2 = function(receiver, state, value, kind2, f) { if (kind2 === "m") throw new TypeError("Private method is not writable"); if (kind2 === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; }; var __classPrivateFieldGet2 = function(receiver, state, kind2, f) { if (kind2 === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _AbstractPage_client; async function defaultParseResponse(props) { const { response } = props; if (props.options.stream) { debug("response", response.status, response.url, response.headers, response.body); if (props.options.__streamClass) { return props.options.__streamClass.fromSSEResponse(response, props.controller); } return Stream.fromSSEResponse(response, props.controller); } if (response.status === 204) { return null; } if (props.options.__binaryResponse) { return response; } const contentType = response.headers.get("content-type"); const isJSON = contentType?.includes("application/json") || contentType?.includes("application/vnd.api+json"); if (isJSON) { const json = await response.json(); debug("response", response.status, response.url, response.headers, json); return json; } const text2 = await response.text(); debug("response", response.status, response.url, response.headers, text2); return text2; } var APIPromise = class extends Promise { constructor(responsePromise, parseResponse = defaultParseResponse) { super((resolve) => { resolve(null); }); this.responsePromise = responsePromise; this.parseResponse = parseResponse; } _thenUnwrap(transform) { return new APIPromise(this.responsePromise, async (props) => transform(await this.parseResponse(props))); } asResponse() { return this.responsePromise.then((p) => p.response); } async withResponse() { const [data, response] = await Promise.all([this.parse(), this.asResponse()]); return { data, response }; } parse() { if (!this.parsedPromise) { this.parsedPromise = this.responsePromise.then(this.parseResponse); } return this.parsedPromise; } then(onfulfilled, onrejected) { return this.parse().then(onfulfilled, onrejected); } catch(onrejected) { return this.parse().catch(onrejected); } finally(onfinally) { return this.parse().finally(onfinally); } }; var APIClient = class { constructor({ baseURL, maxRetries = 2, timeout = 6e5, httpAgent, fetch: overridenFetch }) { this.baseURL = baseURL; this.maxRetries = validatePositiveInteger("maxRetries", maxRetries); this.timeout = validatePositiveInteger("timeout", timeout); this.httpAgent = httpAgent; this.fetch = overridenFetch ?? fetch2; } authHeaders(opts) { return {}; } defaultHeaders(opts) { return { Accept: "application/json", "Content-Type": "application/json", "User-Agent": this.getUserAgent(), ...getPlatformHeaders(), ...this.authHeaders(opts) }; } validateHeaders(headers, customHeaders) { } defaultIdempotencyKey() { return `stainless-node-retry-${uuid4()}`; } get(path, opts) { return this.methodRequest("get", path, opts); } post(path, opts) { return this.methodRequest("post", path, opts); } patch(path, opts) { return this.methodRequest("patch", path, opts); } put(path, opts) { return this.methodRequest("put", path, opts); } delete(path, opts) { return this.methodRequest("delete", path, opts); } methodRequest(method, path, opts) { return this.request(Promise.resolve(opts).then(async (opts2) => { const body = opts2 && isBlobLike(opts2?.body) ? new DataView(await opts2.body.arrayBuffer()) : opts2?.body instanceof DataView ? opts2.body : opts2?.body instanceof ArrayBuffer ? new DataView(opts2.body) : opts2 && ArrayBuffer.isView(opts2?.body) ? new DataView(opts2.body.buffer) : opts2?.body; return { method, path, ...opts2, body }; })); } getAPIList(path, Page2, opts) { return this.requestAPIList(Page2, { method: "get", path, ...opts }); } calculateContentLength(body) { if (typeof body === "string") { if (typeof Buffer !== "undefined") { return Buffer.byteLength(body, "utf8").toString(); } if (typeof TextEncoder !== "undefined") { const encoder = new TextEncoder(); const encoded = encoder.encode(body); return encoded.length.toString(); } } else if (ArrayBuffer.isView(body)) { return body.byteLength.toString(); } return null; } buildRequest(options) { const { method, path, query, headers = {} } = options; const body = ArrayBuffer.isView(options.body) || options.__binaryRequest && typeof options.body === "string" ? options.body : isMultipartBody(options.body) ? options.body.body : options.body ? JSON.stringify(options.body, null, 2) : null; const contentLength = this.calculateContentLength(body); const url = this.buildURL(path, query); if ("timeout" in options) validatePositiveInteger("timeout", options.timeout); const timeout = options.timeout ?? this.timeout; const httpAgent = options.httpAgent ?? this.httpAgent ?? getDefaultAgent(url); const minAgentTimeout = timeout + 1e3; if (typeof httpAgent?.options?.timeout === "number" && minAgentTimeout > (httpAgent.options.timeout ?? 0)) { httpAgent.options.timeout = minAgentTimeout; } if (this.idempotencyHeader && method !== "get") { if (!options.idempotencyKey) options.idempotencyKey = this.defaultIdempotencyKey(); headers[this.idempotencyHeader] = options.idempotencyKey; } const reqHeaders = this.buildHeaders({ options, headers, contentLength }); const req = { method, ...body && { body }, headers: reqHeaders, ...httpAgent && { agent: httpAgent }, signal: options.signal ?? null }; return { req, url, timeout }; } buildHeaders({ options, headers, contentLength }) { const reqHeaders = {}; if (contentLength) { reqHeaders["content-length"] = contentLength; } const defaultHeaders = this.defaultHeaders(options); applyHeadersMut(reqHeaders, defaultHeaders); applyHeadersMut(reqHeaders, headers); if (isMultipartBody(options.body) && kind !== "node") { delete reqHeaders["content-type"]; } this.validateHeaders(reqHeaders, headers); return reqHeaders; } async prepareOptions(options) { } async prepareRequest(request, { url, options }) { } parseHeaders(headers) { return !headers ? {} : Symbol.iterator in headers ? Object.fromEntries(Array.from(headers).map((header) => [...header])) : { ...headers }; } makeStatusError(status, error, message, headers) { return APIError.generate(status, error, message, headers); } request(options, remainingRetries = null) { return new APIPromise(this.makeRequest(options, remainingRetries)); } async makeRequest(optionsInput, retriesRemaining) { const options = await optionsInput; if (retriesRemaining == null) { retriesRemaining = options.maxRetries ?? this.maxRetries; } await this.prepareOptions(options); const { req, url, timeout } = this.buildRequest(options); await this.prepareRequest(req, { url, options }); debug("request", url, options, req.headers); if (options.signal?.aborted) { throw new APIUserAbortError(); } const controller = new AbortController(); const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError); if (response instanceof Error) { if (options.signal?.aborted) { throw new APIUserAbortError(); } if (retriesRemaining) { return this.retryRequest(options, retriesRemaining); } if (response.name === "AbortError") { throw new APIConnectionTimeoutError(); } throw new APIConnectionError({ cause: response }); } const responseHeaders = createResponseHeaders(response.headers); if (!response.ok) { if (retriesRemaining && this.shouldRetry(response)) { const retryMessage2 = `retrying, ${retriesRemaining} attempts remaining`; debug(`response (error; ${retryMessage2})`, response.status, url, responseHeaders); return this.retryRequest(options, retriesRemaining, responseHeaders); } const errText = await response.text().catch((e) => castToError(e).message); const errJSON = safeJSON(errText); const errMessage = errJSON ? void 0 : errText; const retryMessage = retriesRemaining ? `(error; no more retries left)` : `(error; not retryable)`; debug(`response (error; ${retryMessage})`, response.status, url, responseHeaders, errMessage); const err = this.makeStatusError(response.status, errJSON, errMessage, responseHeaders); throw err; } return { response, options, controller }; } requestAPIList(Page2, options) { const request = this.makeRequest(options, null); return new PagePromise(this, request, Page2); } buildURL(path, query) { const url = isAbsoluteURL(path) ? new URL(path) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path.startsWith("/") ? path.slice(1) : path)); const defaultQuery = this.defaultQuery(); if (!isEmptyObj(defaultQuery)) { query = { ...defaultQuery, ...query }; } if (typeof query === "object" && query && !Array.isArray(query)) { url.search = this.stringifyQuery(query); } return url.toString(); } stringifyQuery(query) { return Object.entries(query).filter(([_, value]) => typeof value !== "undefined").map(([key, value]) => { if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`; } if (value === null) { return `${encodeURIComponent(key)}=`; } throw new OpenAIError(`Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`); }).join("&"); } async fetchWithTimeout(url, init2, ms, controller) { const { signal, ...options } = init2 || {}; if (signal) signal.addEventListener("abort", () => controller.abort()); const timeout = setTimeout(() => controller.abort(), ms); return this.getRequestClient().fetch.call(void 0, url, { signal: controller.signal, ...options }).finally(() => { clearTimeout(timeout); }); } getRequestClient() { return { fetch: this.fetch }; } shouldRetry(response) { const shouldRetryHeader = response.headers.get("x-should-retry"); if (shouldRetryHeader === "true") return true; if (shouldRetryHeader === "false") return false; if (response.status === 408) return true; if (response.status === 409) return true; if (response.status === 429) return true; if (response.status >= 500) return true; return false; } async retryRequest(options, retriesRemaining, responseHeaders) { let timeoutMillis; const retryAfterMillisHeader = responseHeaders?.["retry-after-ms"]; if (retryAfterMillisHeader) { const timeoutMs = parseFloat(retryAfterMillisHeader); if (!Number.isNaN(timeoutMs)) { timeoutMillis = timeoutMs; } } const retryAfterHeader = responseHeaders?.["retry-after"]; if (retryAfterHeader && !timeoutMillis) { const timeoutSeconds = parseFloat(retryAfterHeader); if (!Number.isNaN(timeoutSeconds)) { timeoutMillis = timeoutSeconds * 1e3; } else { timeoutMillis = Date.parse(retryAfterHeader) - Date.now(); } } if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1e3)) { const maxRetries = options.maxRetries ?? this.maxRetries; timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries); } await sleep(timeoutMillis); return this.makeRequest(options, retriesRemaining - 1); } calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) { const initialRetryDelay = 0.5; const maxRetryDelay = 8; const numRetries = maxRetries - retriesRemaining; const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay); const jitter = 1 - Math.random() * 0.25; return sleepSeconds * jitter * 1e3; } getUserAgent() { return `${this.constructor.name}/JS ${VERSION}`; } }; var AbstractPage = class { constructor(client, response, body, options) { _AbstractPage_client.set(this, void 0); __classPrivateFieldSet2(this, _AbstractPage_client, client, "f"); this.options = options; this.response = response; this.body = body; } hasNextPage() { const items = this.getPaginatedItems(); if (!items.length) return false; return this.nextPageInfo() != null; } async getNextPage() { const nextInfo = this.nextPageInfo(); if (!nextInfo) { throw new OpenAIError("No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`."); } const nextOptions = { ...this.options }; if ("params" in nextInfo && typeof nextOptions.query === "object") { nextOptions.query = { ...nextOptions.query, ...nextInfo.params }; } else if ("url" in nextInfo) { const params = [...Object.entries(nextOptions.query || {}), ...nextInfo.url.searchParams.entries()]; for (const [key, value] of params) { nextInfo.url.searchParams.set(key, value); } nextOptions.query = void 0; nextOptions.path = nextInfo.url.toString(); } return await __classPrivateFieldGet2(this, _AbstractPage_client, "f").requestAPIList(this.constructor, nextOptions); } async *iterPages() { let page = this; yield page; while (page.hasNextPage()) { page = await page.getNextPage(); yield page; } } async *[(_AbstractPage_client = /* @__PURE__ */ new WeakMap(), Symbol.asyncIterator)]() { for await (const page of this.iterPages()) { for (const item of page.getPaginatedItems()) { yield item; } } } }; var PagePromise = class extends APIPromise { constructor(client, request, Page2) { super(request, async (props) => new Page2(client, props.response, await defaultParseResponse(props), props.options)); } async *[Symbol.asyncIterator]() { const page = await this; for await (const item of page) { yield item; } } }; var createResponseHeaders = (headers) => { return new Proxy(Object.fromEntries(headers.entries()), { get(target, name) { const key = name.toString(); return target[key.toLowerCase()] || target[key]; } }); }; var requestOptionsKeys = { method: true, path: true, query: true, body: true, headers: true, maxRetries: true, stream: true, timeout: true, httpAgent: true, signal: true, idempotencyKey: true, __binaryRequest: true, __binaryResponse: true, __streamClass: true }; var isRequestOptions = (obj) => { return typeof obj === "object" && obj !== null && !isEmptyObj(obj) && Object.keys(obj).every((k) => hasOwn2(requestOptionsKeys, k)); }; var getPlatformProperties = () => { if (typeof Deno !== "undefined" && Deno.build != null) { return { "X-Stainless-Lang": "js", "X-Stainless-Package-Version": VERSION, "X-Stainless-OS": normalizePlatform(Deno.build.os), "X-Stainless-Arch": normalizeArch(Deno.build.arch), "X-Stainless-Runtime": "deno", "X-Stainless-Runtime-Version": typeof Deno.version === "string" ? Deno.version : Deno.version?.deno ?? "unknown" }; } if (typeof EdgeRuntime !== "undefined") { return { "X-Stainless-Lang": "js", "X-Stainless-Package-Version": VERSION, "X-Stainless-OS": "Unknown", "X-Stainless-Arch": `other:${EdgeRuntime}`, "X-Stainless-Runtime": "edge", "X-Stainless-Runtime-Version": process.version }; } if (Object.prototype.toString.call(typeof process !== "undefined" ? process : 0) === "[object process]") { return { "X-Stainless-Lang": "js", "X-Stainless-Package-Version": VERSION, "X-Stainless-OS": normalizePlatform(process.platform), "X-Stainless-Arch": normalizeArch(process.arch), "X-Stainless-Runtime": "node", "X-Stainless-Runtime-Version": process.version }; } const browserInfo = getBrowserInfo(); if (browserInfo) { return { "X-Stainless-Lang": "js", "X-Stainless-Package-Version": VERSION, "X-Stainless-OS": "Unknown", "X-Stainless-Arch": "unknown", "X-Stainless-Runtime": `browser:${browserInfo.browser}`, "X-Stainless-Runtime-Version": browserInfo.version }; } return { "X-Stainless-Lang": "js", "X-Stainless-Package-Version": VERSION, "X-Stainless-OS": "Unknown", "X-Stainless-Arch": "unknown", "X-Stainless-Runtime": "unknown", "X-Stainless-Runtime-Version": "unknown" }; }; function getBrowserInfo() { if (typeof navigator === "undefined" || !navigator) { return null; } const browserPatterns = [ { key: "edge", pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, { key: "ie", pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, { key: "ie", pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ }, { key: "chrome", pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, { key: "firefox", pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ }, { key: "safari", pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ } ]; for (const { key, pattern } of browserPatterns) { const match = pattern.exec(navigator.userAgent); if (match) { const major = match[1] || 0; const minor = match[2] || 0; const patch = match[3] || 0; return { browser: key, version: `${major}.${minor}.${patch}` }; } } return null; } var normalizeArch = (arch) => { if (arch === "x32") return "x32"; if (arch === "x86_64" || arch === "x64") return "x64"; if (arch === "arm") return "arm"; if (arch === "aarch64" || arch === "arm64") return "arm64"; if (arch) return `other:${arch}`; return "unknown"; }; var normalizePlatform = (platform) => { platform = platform.toLowerCase(); if (platform.includes("ios")) return "iOS"; if (platform === "android") return "Android"; if (platform === "darwin") return "MacOS"; if (platform === "win32") return "Windows"; if (platform === "freebsd") return "FreeBSD"; if (platform === "openbsd") return "OpenBSD"; if (platform === "linux") return "Linux"; if (platform) return `Other:${platform}`; return "Unknown"; }; var _platformHeaders; var getPlatformHeaders = () => { return _platformHeaders ?? (_platformHeaders = getPlatformProperties()); }; var safeJSON = (text2) => { try { return JSON.parse(text2); } catch (err) { return void 0; } }; var startsWithSchemeRegexp = new RegExp("^(?:[a-z]+:)?//", "i"); var isAbsoluteURL = (url) => { return startsWithSchemeRegexp.test(url); }; var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); var validatePositiveInteger = (name, n) => { if (typeof n !== "number" || !Number.isInteger(n)) { throw new OpenAIError(`${name} must be an integer`); } if (n < 0) { throw new OpenAIError(`${name} must be a positive integer`); } return n; }; var castToError = (err) => { if (err instanceof Error) return err; return new Error(err); }; var readEnv = (env) => { if (typeof process !== "undefined") { return process.env?.[env]?.trim() ?? void 0; } if (typeof Deno !== "undefined") { return Deno.env?.get?.(env)?.trim(); } return void 0; }; function isEmptyObj(obj) { if (!obj) return true; for (const _k in obj) return false; return true; } function hasOwn2(obj, key) { return Object.prototype.hasOwnProperty.call(obj, key); } function applyHeadersMut(targetHeaders, newHeaders) { for (const k in newHeaders) { if (!hasOwn2(newHeaders, k)) continue; const lowerKey = k.toLowerCase(); if (!lowerKey) continue; const val = newHeaders[k]; if (val === null) { delete targetHeaders[lowerKey]; } else if (val !== void 0) { targetHeaders[lowerKey] = val; } } } function debug(action, ...args) { if (typeof process !== "undefined" && process?.env?.["DEBUG"] === "true") { console.log(`OpenAI:DEBUG:${action}`, ...args); } } var uuid4 = () => { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { const r = Math.random() * 16 | 0; const v = c === "x" ? r : r & 3 | 8; return v.toString(16); }); }; var isRunningInBrowser = () => { return typeof window !== "undefined" && typeof window.document !== "undefined" && typeof navigator !== "undefined"; }; function isObj(obj) { return obj != null && typeof obj === "object" && !Array.isArray(obj); } // node_modules/openai/error.mjs var OpenAIError = class extends Error { }; var APIError = class extends OpenAIError { constructor(status, error, message, headers) { super(`${APIError.makeMessage(status, error, message)}`); this.status = status; this.headers = headers; this.request_id = headers?.["x-request-id"]; const data = error; this.error = data; this.code = data?.["code"]; this.param = data?.["param"]; this.type = data?.["type"]; } static makeMessage(status, error, message) { const msg = error?.message ? typeof error.message === "string" ? error.message : JSON.stringify(error.message) : error ? JSON.stringify(error) : message; if (status && msg) { return `${status} ${msg}`; } if (status) { return `${status} status code (no body)`; } if (msg) { return msg; } return "(no status code or body)"; } static generate(status, errorResponse, message, headers) { if (!status) { return new APIConnectionError({ cause: castToError(errorResponse) }); } const error = errorResponse?.["error"]; if (status === 400) { return new BadRequestError(status, error, message, headers); } if (status === 401) { return new AuthenticationError(status, error, message, headers); } if (status === 403) { return new PermissionDeniedError(status, error, message, headers); } if (status === 404) { return new NotFoundError(status, error, message, headers); } if (status === 409) { return new ConflictError(status, error, message, headers); } if (status === 422) { return new UnprocessableEntityError(status, error, message, headers); } if (status === 429) { return new RateLimitError(status, error, message, headers); } if (status >= 500) { return new InternalServerError(status, error, message, headers); } return new APIError(status, error, message, headers); } }; var APIUserAbortError = class extends APIError { constructor({ message } = {}) { super(void 0, void 0, message || "Request was aborted.", void 0); this.status = void 0; } }; var APIConnectionError = class extends APIError { constructor({ message, cause }) { super(void 0, void 0, message || "Connection error.", void 0); this.status = void 0; if (cause) this.cause = cause; } }; var APIConnectionTimeoutError = class extends APIConnectionError { constructor({ message } = {}) { super({ message: message ?? "Request timed out." }); } }; var BadRequestError = class extends APIError { constructor() { super(...arguments); this.status = 400; } }; var AuthenticationError = class extends APIError { constructor() { super(...arguments); this.status = 401; } }; var PermissionDeniedError = class extends APIError { constructor() { super(...arguments); this.status = 403; } }; var NotFoundError = class extends APIError { constructor() { super(...arguments); this.status = 404; } }; var ConflictError = class extends APIError { constructor() { super(...arguments); this.status = 409; } }; var UnprocessableEntityError = class extends APIError { constructor() { super(...arguments); this.status = 422; } }; var RateLimitError = class extends APIError { constructor() { super(...arguments); this.status = 429; } }; var InternalServerError = class extends APIError { }; // node_modules/openai/pagination.mjs var Page = class extends AbstractPage { constructor(client, response, body, options) { super(client, response, body, options); this.data = body.data || []; this.object = body.object; } getPaginatedItems() { return this.data ?? []; } nextPageParams() { return null; } nextPageInfo() { return null; } }; var CursorPage = class extends AbstractPage { constructor(client, response, body, options) { super(client, response, body, options); this.data = body.data || []; } getPaginatedItems() { return this.data ?? []; } nextPageParams() { const info = this.nextPageInfo(); if (!info) return null; if ("params" in info) return info.params; const params = Object.fromEntries(info.url.searchParams); if (!Object.keys(params).length) return null; return params; } nextPageInfo() { const data = this.getPaginatedItems(); if (!data.length) { return null; } const id = data[data.length - 1]?.id; if (!id) { return null; } return { params: { after: id } }; } }; // node_modules/openai/resource.mjs var APIResource = class { constructor(client) { this._client = client; } }; // node_modules/openai/resources/chat/completions.mjs var Completions = class extends APIResource { create(body, options) { return this._client.post("/chat/completions", { body, ...options, stream: body.stream ?? false }); } }; (function(Completions4) { })(Completions || (Completions = {})); // node_modules/openai/resources/chat/chat.mjs var Chat = class extends APIResource { constructor() { super(...arguments); this.completions = new Completions(this._client); } }; (function(Chat3) { Chat3.Completions = Completions; })(Chat || (Chat = {})); // node_modules/openai/resources/audio/speech.mjs var Speech = class extends APIResource { create(body, options) { return this._client.post("/audio/speech", { body, ...options, __binaryResponse: true }); } }; (function(Speech2) { })(Speech || (Speech = {})); // node_modules/openai/resources/audio/transcriptions.mjs var Transcriptions = class extends APIResource { create(body, options) { return this._client.post("/audio/transcriptions", multipartFormRequestOptions({ body, ...options })); } }; (function(Transcriptions2) { })(Transcriptions || (Transcriptions = {})); // node_modules/openai/resources/audio/translations.mjs var Translations = class extends APIResource { create(body, options) { return this._client.post("/audio/translations", multipartFormRequestOptions({ body, ...options })); } }; (function(Translations2) { })(Translations || (Translations = {})); // node_modules/openai/resources/audio/audio.mjs var Audio = class extends APIResource { constructor() { super(...arguments); this.transcriptions = new Transcriptions(this._client); this.translations = new Translations(this._client); this.speech = new Speech(this._client); } }; (function(Audio2) { Audio2.Transcriptions = Transcriptions; Audio2.Translations = Translations; Audio2.Speech = Speech; })(Audio || (Audio = {})); // node_modules/openai/resources/batches.mjs var Batches = class extends APIResource { create(body, options) { return this._client.post("/batches", { body, ...options }); } retrieve(batchId, options) { return this._client.get(`/batches/${batchId}`, options); } list(query = {}, options) { if (isRequestOptions(query)) { return this.list({}, query); } return this._client.getAPIList("/batches", BatchesPage, { query, ...options }); } cancel(batchId, options) { return this._client.post(`/batches/${batchId}/cancel`, options); } }; var BatchesPage = class extends CursorPage { }; (function(Batches2) { Batches2.BatchesPage = BatchesPage; })(Batches || (Batches = {})); // node_modules/openai/resources/beta/assistants.mjs var Assistants = class extends APIResource { create(body, options) { return this._client.post("/assistants", { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } retrieve(assistantId, options) { return this._client.get(`/assistants/${assistantId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } update(assistantId, body, options) { return this._client.post(`/assistants/${assistantId}`, { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } list(query = {}, options) { if (isRequestOptions(query)) { return this.list({}, query); } return this._client.getAPIList("/assistants", AssistantsPage, { query, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } del(assistantId, options) { return this._client.delete(`/assistants/${assistantId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } }; var AssistantsPage = class extends CursorPage { }; (function(Assistants2) { Assistants2.AssistantsPage = AssistantsPage; })(Assistants || (Assistants = {})); // node_modules/openai/lib/RunnableFunction.mjs function isRunnableFunctionWithParse(fn) { return typeof fn.parse === "function"; } // node_modules/openai/lib/chatCompletionUtils.mjs var isAssistantMessage = (message) => { return message?.role === "assistant"; }; var isFunctionMessage = (message) => { return message?.role === "function"; }; var isToolMessage = (message) => { return message?.role === "tool"; }; // node_modules/openai/lib/AbstractChatCompletionRunner.mjs var __classPrivateFieldSet3 = function(receiver, state, value, kind2, f) { if (kind2 === "m") throw new TypeError("Private method is not writable"); if (kind2 === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; }; var __classPrivateFieldGet3 = function(receiver, state, kind2, f) { if (kind2 === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _AbstractChatCompletionRunner_instances; var _AbstractChatCompletionRunner_connectedPromise; var _AbstractChatCompletionRunner_resolveConnectedPromise; var _AbstractChatCompletionRunner_rejectConnectedPromise; var _AbstractChatCompletionRunner_endPromise; var _AbstractChatCompletionRunner_resolveEndPromise; var _AbstractChatCompletionRunner_rejectEndPromise; var _AbstractChatCompletionRunner_listeners; var _AbstractChatCompletionRunner_ended; var _AbstractChatCompletionRunner_errored; var _AbstractChatCompletionRunner_aborted; var _AbstractChatCompletionRunner_catchingPromiseCreated; var _AbstractChatCompletionRunner_getFinalContent; var _AbstractChatCompletionRunner_getFinalMessage; var _AbstractChatCompletionRunner_getFinalFunctionCall; var _AbstractChatCompletionRunner_getFinalFunctionCallResult; var _AbstractChatCompletionRunner_calculateTotalUsage; var _AbstractChatCompletionRunner_handleError; var _AbstractChatCompletionRunner_validateParams; var _AbstractChatCompletionRunner_stringifyFunctionCallResult; var DEFAULT_MAX_CHAT_COMPLETIONS = 10; var AbstractChatCompletionRunner = class { constructor() { _AbstractChatCompletionRunner_instances.add(this); this.controller = new AbortController(); _AbstractChatCompletionRunner_connectedPromise.set(this, void 0); _AbstractChatCompletionRunner_resolveConnectedPromise.set(this, () => { }); _AbstractChatCompletionRunner_rejectConnectedPromise.set(this, () => { }); _AbstractChatCompletionRunner_endPromise.set(this, void 0); _AbstractChatCompletionRunner_resolveEndPromise.set(this, () => { }); _AbstractChatCompletionRunner_rejectEndPromise.set(this, () => { }); _AbstractChatCompletionRunner_listeners.set(this, {}); this._chatCompletions = []; this.messages = []; _AbstractChatCompletionRunner_ended.set(this, false); _AbstractChatCompletionRunner_errored.set(this, false); _AbstractChatCompletionRunner_aborted.set(this, false); _AbstractChatCompletionRunner_catchingPromiseCreated.set(this, false); _AbstractChatCompletionRunner_handleError.set(this, (error) => { __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_errored, true, "f"); if (error instanceof Error && error.name === "AbortError") { error = new APIUserAbortError(); } if (error instanceof APIUserAbortError) { __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_aborted, true, "f"); return this._emit("abort", error); } if (error instanceof OpenAIError) { return this._emit("error", error); } if (error instanceof Error) { const openAIError = new OpenAIError(error.message); openAIError.cause = error; return this._emit("error", openAIError); } return this._emit("error", new OpenAIError(String(error))); }); __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_connectedPromise, new Promise((resolve, reject) => { __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_resolveConnectedPromise, resolve, "f"); __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_rejectConnectedPromise, reject, "f"); }), "f"); __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_endPromise, new Promise((resolve, reject) => { __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_resolveEndPromise, resolve, "f"); __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_rejectEndPromise, reject, "f"); }), "f"); __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_connectedPromise, "f").catch(() => { }); __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_endPromise, "f").catch(() => { }); } _run(executor) { setTimeout(() => { executor().then(() => { this._emitFinal(); this._emit("end"); }, __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_handleError, "f")); }, 0); } _addChatCompletion(chatCompletion) { this._chatCompletions.push(chatCompletion); this._emit("chatCompletion", chatCompletion); const message = chatCompletion.choices[0]?.message; if (message) this._addMessage(message); return chatCompletion; } _addMessage(message, emit = true) { if (!("content" in message)) message.content = null; this.messages.push(message); if (emit) { this._emit("message", message); if ((isFunctionMessage(message) || isToolMessage(message)) && message.content) { this._emit("functionCallResult", message.content); } else if (isAssistantMessage(message) && message.function_call) { this._emit("functionCall", message.function_call); } else if (isAssistantMessage(message) && message.tool_calls) { for (const tool_call of message.tool_calls) { if (tool_call.type === "function") { this._emit("functionCall", tool_call.function); } } } } } _connected() { if (this.ended) return; __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_resolveConnectedPromise, "f").call(this); this._emit("connect"); } get ended() { return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_ended, "f"); } get errored() { return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_errored, "f"); } get aborted() { return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_aborted, "f"); } abort() { this.controller.abort(); } on(event, listener) { const listeners = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event] || (__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event] = []); listeners.push({ listener }); return this; } off(event, listener) { const listeners = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event]; if (!listeners) return this; const index = listeners.findIndex((l) => l.listener === listener); if (index >= 0) listeners.splice(index, 1); return this; } once(event, listener) { const listeners = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event] || (__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event] = []); listeners.push({ listener, once: true }); return this; } emitted(event) { return new Promise((resolve, reject) => { __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_catchingPromiseCreated, true, "f"); if (event !== "error") this.once("error", reject); this.once(event, resolve); }); } async done() { __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_catchingPromiseCreated, true, "f"); await __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_endPromise, "f"); } async finalChatCompletion() { await this.done(); const completion = this._chatCompletions[this._chatCompletions.length - 1]; if (!completion) throw new OpenAIError("stream ended without producing a ChatCompletion"); return completion; } async finalContent() { await this.done(); return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalContent).call(this); } async finalMessage() { await this.done(); return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this); } async finalFunctionCall() { await this.done(); return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCall).call(this); } async finalFunctionCallResult() { await this.done(); return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCallResult).call(this); } async totalUsage() { await this.done(); return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_calculateTotalUsage).call(this); } allChatCompletions() { return [...this._chatCompletions]; } _emit(event, ...args) { if (__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_ended, "f")) { return; } if (event === "end") { __classPrivateFieldSet3(this, _AbstractChatCompletionRunner_ended, true, "f"); __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_resolveEndPromise, "f").call(this); } const listeners = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event]; if (listeners) { __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_listeners, "f")[event] = listeners.filter((l) => !l.once); listeners.forEach(({ listener }) => listener(...args)); } if (event === "abort") { const error = args[0]; if (!__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_catchingPromiseCreated, "f") && !listeners?.length) { Promise.reject(error); } __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_rejectConnectedPromise, "f").call(this, error); __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_rejectEndPromise, "f").call(this, error); this._emit("end"); return; } if (event === "error") { const error = args[0]; if (!__classPrivateFieldGet3(this, _AbstractChatCompletionRunner_catchingPromiseCreated, "f") && !listeners?.length) { Promise.reject(error); } __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_rejectConnectedPromise, "f").call(this, error); __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_rejectEndPromise, "f").call(this, error); this._emit("end"); } } _emitFinal() { const completion = this._chatCompletions[this._chatCompletions.length - 1]; if (completion) this._emit("finalChatCompletion", completion); const finalMessage = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this); if (finalMessage) this._emit("finalMessage", finalMessage); const finalContent = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalContent).call(this); if (finalContent) this._emit("finalContent", finalContent); const finalFunctionCall = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCall).call(this); if (finalFunctionCall) this._emit("finalFunctionCall", finalFunctionCall); const finalFunctionCallResult = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalFunctionCallResult).call(this); if (finalFunctionCallResult != null) this._emit("finalFunctionCallResult", finalFunctionCallResult); if (this._chatCompletions.some((c) => c.usage)) { this._emit("totalUsage", __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_calculateTotalUsage).call(this)); } } async _createChatCompletion(completions, params, options) { const signal = options?.signal; if (signal) { if (signal.aborted) this.controller.abort(); signal.addEventListener("abort", () => this.controller.abort()); } __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_validateParams).call(this, params); const chatCompletion = await completions.create({ ...params, stream: false }, { ...options, signal: this.controller.signal }); this._connected(); return this._addChatCompletion(chatCompletion); } async _runChatCompletion(completions, params, options) { for (const message of params.messages) { this._addMessage(message, false); } return await this._createChatCompletion(completions, params, options); } async _runFunctions(completions, params, options) { const role = "function"; const { function_call = "auto", stream, ...restParams } = params; const singleFunctionToCall = typeof function_call !== "string" && function_call?.name; const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS } = options || {}; const functionsByName = {}; for (const f of params.functions) { functionsByName[f.name || f.function.name] = f; } const functions = params.functions.map((f) => ({ name: f.name || f.function.name, parameters: f.parameters, description: f.description })); for (const message of params.messages) { this._addMessage(message, false); } for (let i = 0; i < maxChatCompletions; ++i) { const chatCompletion = await this._createChatCompletion(completions, { ...restParams, function_call, functions, messages: [...this.messages] }, options); const message = chatCompletion.choices[0]?.message; if (!message) { throw new OpenAIError(`missing message in ChatCompletion response`); } if (!message.function_call) return; const { name, arguments: args } = message.function_call; const fn = functionsByName[name]; if (!fn) { const content2 = `Invalid function_call: ${JSON.stringify(name)}. Available options are: ${functions.map((f) => JSON.stringify(f.name)).join(", ")}. Please try again`; this._addMessage({ role, name, content: content2 }); continue; } else if (singleFunctionToCall && singleFunctionToCall !== name) { const content2 = `Invalid function_call: ${JSON.stringify(name)}. ${JSON.stringify(singleFunctionToCall)} requested. Please try again`; this._addMessage({ role, name, content: content2 }); continue; } let parsed; try { parsed = isRunnableFunctionWithParse(fn) ? await fn.parse(args) : args; } catch (error) { this._addMessage({ role, name, content: error instanceof Error ? error.message : String(error) }); continue; } const rawContent = await fn.function(parsed, this); const content = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_stringifyFunctionCallResult).call(this, rawContent); this._addMessage({ role, name, content }); if (singleFunctionToCall) return; } } async _runTools(completions, params, options) { const role = "tool"; const { tool_choice = "auto", stream, ...restParams } = params; const singleFunctionToCall = typeof tool_choice !== "string" && tool_choice?.function?.name; const { maxChatCompletions = DEFAULT_MAX_CHAT_COMPLETIONS } = options || {}; const functionsByName = {}; for (const f of params.tools) { if (f.type === "function") { functionsByName[f.function.name || f.function.function.name] = f.function; } } const tools = "tools" in params ? params.tools.map((t) => t.type === "function" ? { type: "function", function: { name: t.function.name || t.function.function.name, parameters: t.function.parameters, description: t.function.description } } : t) : void 0; for (const message of params.messages) { this._addMessage(message, false); } for (let i = 0; i < maxChatCompletions; ++i) { const chatCompletion = await this._createChatCompletion(completions, { ...restParams, tool_choice, tools, messages: [...this.messages] }, options); const message = chatCompletion.choices[0]?.message; if (!message) { throw new OpenAIError(`missing message in ChatCompletion response`); } if (!message.tool_calls) { return; } for (const tool_call of message.tool_calls) { if (tool_call.type !== "function") continue; const tool_call_id = tool_call.id; const { name, arguments: args } = tool_call.function; const fn = functionsByName[name]; if (!fn) { const content2 = `Invalid tool_call: ${JSON.stringify(name)}. Available options are: ${tools.map((f) => JSON.stringify(f.function.name)).join(", ")}. Please try again`; this._addMessage({ role, tool_call_id, content: content2 }); continue; } else if (singleFunctionToCall && singleFunctionToCall !== name) { const content2 = `Invalid tool_call: ${JSON.stringify(name)}. ${JSON.stringify(singleFunctionToCall)} requested. Please try again`; this._addMessage({ role, tool_call_id, content: content2 }); continue; } let parsed; try { parsed = isRunnableFunctionWithParse(fn) ? await fn.parse(args) : args; } catch (error) { const content2 = error instanceof Error ? error.message : String(error); this._addMessage({ role, tool_call_id, content: content2 }); continue; } const rawContent = await fn.function(parsed, this); const content = __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_stringifyFunctionCallResult).call(this, rawContent); this._addMessage({ role, tool_call_id, content }); if (singleFunctionToCall) { return; } } } return; } }; _AbstractChatCompletionRunner_connectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_resolveConnectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_rejectConnectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_endPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_resolveEndPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_rejectEndPromise = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_listeners = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_ended = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_errored = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_aborted = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_catchingPromiseCreated = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_handleError = /* @__PURE__ */ new WeakMap(), _AbstractChatCompletionRunner_instances = /* @__PURE__ */ new WeakSet(), _AbstractChatCompletionRunner_getFinalContent = function _AbstractChatCompletionRunner_getFinalContent2() { return __classPrivateFieldGet3(this, _AbstractChatCompletionRunner_instances, "m", _AbstractChatCompletionRunner_getFinalMessage).call(this).content ?? null; }, _AbstractChatCompletionRunner_getFinalMessage = function _AbstractChatCompletionRunner_getFinalMessage2() { let i = this.messages.length; while (i-- > 0) { const message = this.messages[i]; if (isAssistantMessage(message)) { const { function_call, ...rest } = message; const ret = { ...rest, content: message.content ?? null }; if (function_call) { ret.function_call = function_call; } return ret; } } throw new OpenAIError("stream ended without producing a ChatCompletionMessage with role=assistant"); }, _AbstractChatCompletionRunner_getFinalFunctionCall = function _AbstractChatCompletionRunner_getFinalFunctionCall2() { for (let i = this.messages.length - 1; i >= 0; i--) { const message = this.messages[i]; if (isAssistantMessage(message) && message?.function_call) { return message.function_call; } if (isAssistantMessage(message) && message?.tool_calls?.length) { return message.tool_calls.at(-1)?.function; } } return; }, _AbstractChatCompletionRunner_getFinalFunctionCallResult = function _AbstractChatCompletionRunner_getFinalFunctionCallResult2() { for (let i = this.messages.length - 1; i >= 0; i--) { const message = this.messages[i]; if (isFunctionMessage(message) && message.content != null) { return message.content; } if (isToolMessage(message) && message.content != null && this.messages.some((x) => x.role === "assistant" && x.tool_calls?.some((y) => y.type === "function" && y.id === message.tool_call_id))) { return message.content; } } return; }, _AbstractChatCompletionRunner_calculateTotalUsage = function _AbstractChatCompletionRunner_calculateTotalUsage2() { const total = { completion_tokens: 0, prompt_tokens: 0, total_tokens: 0 }; for (const { usage } of this._chatCompletions) { if (usage) { total.completion_tokens += usage.completion_tokens; total.prompt_tokens += usage.prompt_tokens; total.total_tokens += usage.total_tokens; } } return total; }, _AbstractChatCompletionRunner_validateParams = function _AbstractChatCompletionRunner_validateParams2(params) { if (params.n != null && params.n > 1) { throw new OpenAIError("ChatCompletion convenience helpers only support n=1 at this time. To use n>1, please use chat.completions.create() directly."); } }, _AbstractChatCompletionRunner_stringifyFunctionCallResult = function _AbstractChatCompletionRunner_stringifyFunctionCallResult2(rawContent) { return typeof rawContent === "string" ? rawContent : rawContent === void 0 ? "undefined" : JSON.stringify(rawContent); }; // node_modules/openai/lib/ChatCompletionRunner.mjs var ChatCompletionRunner = class extends AbstractChatCompletionRunner { static runFunctions(completions, params, options) { const runner = new ChatCompletionRunner(); const opts = { ...options, headers: { ...options?.headers, "X-Stainless-Helper-Method": "runFunctions" } }; runner._run(() => runner._runFunctions(completions, params, opts)); return runner; } static runTools(completions, params, options) { const runner = new ChatCompletionRunner(); const opts = { ...options, headers: { ...options?.headers, "X-Stainless-Helper-Method": "runTools" } }; runner._run(() => runner._runTools(completions, params, opts)); return runner; } _addMessage(message) { super._addMessage(message); if (isAssistantMessage(message) && message.content) { this._emit("content", message.content); } } }; // node_modules/openai/lib/ChatCompletionStream.mjs var __classPrivateFieldGet4 = function(receiver, state, kind2, f) { if (kind2 === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet4 = function(receiver, state, value, kind2, f) { if (kind2 === "m") throw new TypeError("Private method is not writable"); if (kind2 === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; }; var _ChatCompletionStream_instances; var _ChatCompletionStream_currentChatCompletionSnapshot; var _ChatCompletionStream_beginRequest; var _ChatCompletionStream_addChunk; var _ChatCompletionStream_endRequest; var _ChatCompletionStream_accumulateChatCompletion; var ChatCompletionStream = class extends AbstractChatCompletionRunner { constructor() { super(...arguments); _ChatCompletionStream_instances.add(this); _ChatCompletionStream_currentChatCompletionSnapshot.set(this, void 0); } get currentChatCompletionSnapshot() { return __classPrivateFieldGet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"); } static fromReadableStream(stream) { const runner = new ChatCompletionStream(); runner._run(() => runner._fromReadableStream(stream)); return runner; } static createChatCompletion(completions, params, options) { const runner = new ChatCompletionStream(); runner._run(() => runner._runChatCompletion(completions, { ...params, stream: true }, { ...options, headers: { ...options?.headers, "X-Stainless-Helper-Method": "stream" } })); return runner; } async _createChatCompletion(completions, params, options) { const signal = options?.signal; if (signal) { if (signal.aborted) this.controller.abort(); signal.addEventListener("abort", () => this.controller.abort()); } __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this); const stream = await completions.create({ ...params, stream: true }, { ...options, signal: this.controller.signal }); this._connected(); for await (const chunk of stream) { __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk); } if (stream.controller.signal?.aborted) { throw new APIUserAbortError(); } return this._addChatCompletion(__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this)); } async _fromReadableStream(readableStream, options) { const signal = options?.signal; if (signal) { if (signal.aborted) this.controller.abort(); signal.addEventListener("abort", () => this.controller.abort()); } __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_beginRequest).call(this); this._connected(); const stream = Stream.fromReadableStream(readableStream, this.controller); let chatId; for await (const chunk of stream) { if (chatId && chatId !== chunk.id) { this._addChatCompletion(__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this)); } __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_addChunk).call(this, chunk); chatId = chunk.id; } if (stream.controller.signal?.aborted) { throw new APIUserAbortError(); } return this._addChatCompletion(__classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_endRequest).call(this)); } [(_ChatCompletionStream_currentChatCompletionSnapshot = /* @__PURE__ */ new WeakMap(), _ChatCompletionStream_instances = /* @__PURE__ */ new WeakSet(), _ChatCompletionStream_beginRequest = function _ChatCompletionStream_beginRequest2() { if (this.ended) return; __classPrivateFieldSet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, void 0, "f"); }, _ChatCompletionStream_addChunk = function _ChatCompletionStream_addChunk2(chunk) { if (this.ended) return; const completion = __classPrivateFieldGet4(this, _ChatCompletionStream_instances, "m", _ChatCompletionStream_accumulateChatCompletion).call(this, chunk); this._emit("chunk", chunk, completion); const delta = chunk.choices[0]?.delta?.content; const snapshot = completion.choices[0]?.message; if (delta != null && snapshot?.role === "assistant" && snapshot?.content) { this._emit("content", delta, snapshot.content); } }, _ChatCompletionStream_endRequest = function _ChatCompletionStream_endRequest2() { if (this.ended) { throw new OpenAIError(`stream has ended, this shouldn't happen`); } const snapshot = __classPrivateFieldGet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"); if (!snapshot) { throw new OpenAIError(`request ended without sending any chunks`); } __classPrivateFieldSet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, void 0, "f"); return finalizeChatCompletion(snapshot); }, _ChatCompletionStream_accumulateChatCompletion = function _ChatCompletionStream_accumulateChatCompletion2(chunk) { var _a2, _b, _c; let snapshot = __classPrivateFieldGet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, "f"); const { choices, ...rest } = chunk; if (!snapshot) { snapshot = __classPrivateFieldSet4(this, _ChatCompletionStream_currentChatCompletionSnapshot, { ...rest, choices: [] }, "f"); } else { Object.assign(snapshot, rest); } for (const { delta, finish_reason, index, logprobs = null, ...other } of chunk.choices) { let choice = snapshot.choices[index]; if (!choice) { choice = snapshot.choices[index] = { finish_reason, index, message: {}, logprobs, ...other }; } if (logprobs) { if (!choice.logprobs) { choice.logprobs = Object.assign({}, logprobs); } else { const { content: content2, ...rest3 } = logprobs; Object.assign(choice.logprobs, rest3); if (content2) { (_a2 = choice.logprobs).content ?? (_a2.content = []); choice.logprobs.content.push(...content2); } } } if (finish_reason) choice.finish_reason = finish_reason; Object.assign(choice, other); if (!delta) continue; const { content, function_call, role, tool_calls, ...rest2 } = delta; Object.assign(choice.message, rest2); if (content) choice.message.content = (choice.message.content || "") + content; if (role) choice.message.role = role; if (function_call) { if (!choice.message.function_call) { choice.message.function_call = function_call; } else { if (function_call.name) choice.message.function_call.name = function_call.name; if (function_call.arguments) { (_b = choice.message.function_call).arguments ?? (_b.arguments = ""); choice.message.function_call.arguments += function_call.arguments; } } } if (tool_calls) { if (!choice.message.tool_calls) choice.message.tool_calls = []; for (const { index: index2, id, type, function: fn, ...rest3 } of tool_calls) { const tool_call = (_c = choice.message.tool_calls)[index2] ?? (_c[index2] = {}); Object.assign(tool_call, rest3); if (id) tool_call.id = id; if (type) tool_call.type = type; if (fn) tool_call.function ?? (tool_call.function = { arguments: "" }); if (fn?.name) tool_call.function.name = fn.name; if (fn?.arguments) tool_call.function.arguments += fn.arguments; } } } return snapshot; }, Symbol.asyncIterator)]() { const pushQueue = []; const readQueue = []; let done = false; this.on("chunk", (chunk) => { const reader = readQueue.shift(); if (reader) { reader.resolve(chunk); } else { pushQueue.push(chunk); } }); this.on("end", () => { done = true; for (const reader of readQueue) { reader.resolve(void 0); } readQueue.length = 0; }); this.on("abort", (err) => { done = true; for (const reader of readQueue) { reader.reject(err); } readQueue.length = 0; }); this.on("error", (err) => { done = true; for (const reader of readQueue) { reader.reject(err); } readQueue.length = 0; }); return { next: async () => { if (!pushQueue.length) { if (done) { return { value: void 0, done: true }; } return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true }); } const chunk = pushQueue.shift(); return { value: chunk, done: false }; }, return: async () => { this.abort(); return { value: void 0, done: true }; } }; } toReadableStream() { const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller); return stream.toReadableStream(); } }; function finalizeChatCompletion(snapshot) { const { id, choices, created, model, system_fingerprint, ...rest } = snapshot; return { ...rest, id, choices: choices.map(({ message, finish_reason, index, logprobs, ...choiceRest }) => { if (!finish_reason) throw new OpenAIError(`missing finish_reason for choice ${index}`); const { content = null, function_call, tool_calls, ...messageRest } = message; const role = message.role; if (!role) throw new OpenAIError(`missing role for choice ${index}`); if (function_call) { const { arguments: args, name } = function_call; if (args == null) throw new OpenAIError(`missing function_call.arguments for choice ${index}`); if (!name) throw new OpenAIError(`missing function_call.name for choice ${index}`); return { ...choiceRest, message: { content, function_call: { arguments: args, name }, role }, finish_reason, index, logprobs }; } if (tool_calls) { return { ...choiceRest, index, finish_reason, logprobs, message: { ...messageRest, role, content, tool_calls: tool_calls.map((tool_call, i) => { const { function: fn, type, id: id2, ...toolRest } = tool_call; const { arguments: args, name, ...fnRest } = fn || {}; if (id2 == null) throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].id ${str(snapshot)}`); if (type == null) throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].type ${str(snapshot)}`); if (name == null) throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.name ${str(snapshot)}`); if (args == null) throw new OpenAIError(`missing choices[${index}].tool_calls[${i}].function.arguments ${str(snapshot)}`); return { ...toolRest, id: id2, type, function: { ...fnRest, name, arguments: args } }; }) } }; } return { ...choiceRest, message: { ...messageRest, content, role }, finish_reason, index, logprobs }; }), created, model, object: "chat.completion", ...system_fingerprint ? { system_fingerprint } : {} }; } function str(x) { return JSON.stringify(x); } // node_modules/openai/lib/ChatCompletionStreamingRunner.mjs var ChatCompletionStreamingRunner = class extends ChatCompletionStream { static fromReadableStream(stream) { const runner = new ChatCompletionStreamingRunner(); runner._run(() => runner._fromReadableStream(stream)); return runner; } static runFunctions(completions, params, options) { const runner = new ChatCompletionStreamingRunner(); const opts = { ...options, headers: { ...options?.headers, "X-Stainless-Helper-Method": "runFunctions" } }; runner._run(() => runner._runFunctions(completions, params, opts)); return runner; } static runTools(completions, params, options) { const runner = new ChatCompletionStreamingRunner(); const opts = { ...options, headers: { ...options?.headers, "X-Stainless-Helper-Method": "runTools" } }; runner._run(() => runner._runTools(completions, params, opts)); return runner; } }; // node_modules/openai/resources/beta/chat/completions.mjs var Completions2 = class extends APIResource { runFunctions(body, options) { if (body.stream) { return ChatCompletionStreamingRunner.runFunctions(this._client.chat.completions, body, options); } return ChatCompletionRunner.runFunctions(this._client.chat.completions, body, options); } runTools(body, options) { if (body.stream) { return ChatCompletionStreamingRunner.runTools(this._client.chat.completions, body, options); } return ChatCompletionRunner.runTools(this._client.chat.completions, body, options); } stream(body, options) { return ChatCompletionStream.createChatCompletion(this._client.chat.completions, body, options); } }; // node_modules/openai/resources/beta/chat/chat.mjs var Chat2 = class extends APIResource { constructor() { super(...arguments); this.completions = new Completions2(this._client); } }; (function(Chat3) { Chat3.Completions = Completions2; })(Chat2 || (Chat2 = {})); // node_modules/openai/lib/AbstractAssistantStreamRunner.mjs var __classPrivateFieldSet5 = function(receiver, state, value, kind2, f) { if (kind2 === "m") throw new TypeError("Private method is not writable"); if (kind2 === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; }; var __classPrivateFieldGet5 = function(receiver, state, kind2, f) { if (kind2 === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _AbstractAssistantStreamRunner_connectedPromise; var _AbstractAssistantStreamRunner_resolveConnectedPromise; var _AbstractAssistantStreamRunner_rejectConnectedPromise; var _AbstractAssistantStreamRunner_endPromise; var _AbstractAssistantStreamRunner_resolveEndPromise; var _AbstractAssistantStreamRunner_rejectEndPromise; var _AbstractAssistantStreamRunner_listeners; var _AbstractAssistantStreamRunner_ended; var _AbstractAssistantStreamRunner_errored; var _AbstractAssistantStreamRunner_aborted; var _AbstractAssistantStreamRunner_catchingPromiseCreated; var _AbstractAssistantStreamRunner_handleError; var AbstractAssistantStreamRunner = class { constructor() { this.controller = new AbortController(); _AbstractAssistantStreamRunner_connectedPromise.set(this, void 0); _AbstractAssistantStreamRunner_resolveConnectedPromise.set(this, () => { }); _AbstractAssistantStreamRunner_rejectConnectedPromise.set(this, () => { }); _AbstractAssistantStreamRunner_endPromise.set(this, void 0); _AbstractAssistantStreamRunner_resolveEndPromise.set(this, () => { }); _AbstractAssistantStreamRunner_rejectEndPromise.set(this, () => { }); _AbstractAssistantStreamRunner_listeners.set(this, {}); _AbstractAssistantStreamRunner_ended.set(this, false); _AbstractAssistantStreamRunner_errored.set(this, false); _AbstractAssistantStreamRunner_aborted.set(this, false); _AbstractAssistantStreamRunner_catchingPromiseCreated.set(this, false); _AbstractAssistantStreamRunner_handleError.set(this, (error) => { __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_errored, true, "f"); if (error instanceof Error && error.name === "AbortError") { error = new APIUserAbortError(); } if (error instanceof APIUserAbortError) { __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_aborted, true, "f"); return this._emit("abort", error); } if (error instanceof OpenAIError) { return this._emit("error", error); } if (error instanceof Error) { const openAIError = new OpenAIError(error.message); openAIError.cause = error; return this._emit("error", openAIError); } return this._emit("error", new OpenAIError(String(error))); }); __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_connectedPromise, new Promise((resolve, reject) => { __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_resolveConnectedPromise, resolve, "f"); __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_rejectConnectedPromise, reject, "f"); }), "f"); __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_endPromise, new Promise((resolve, reject) => { __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_resolveEndPromise, resolve, "f"); __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_rejectEndPromise, reject, "f"); }), "f"); __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_connectedPromise, "f").catch(() => { }); __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_endPromise, "f").catch(() => { }); } _run(executor) { setTimeout(() => { executor().then(() => { this._emit("end"); }, __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_handleError, "f")); }, 0); } _addRun(run2) { return run2; } _connected() { if (this.ended) return; __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_resolveConnectedPromise, "f").call(this); this._emit("connect"); } get ended() { return __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_ended, "f"); } get errored() { return __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_errored, "f"); } get aborted() { return __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_aborted, "f"); } abort() { this.controller.abort(); } on(event, listener) { const listeners = __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event] || (__classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event] = []); listeners.push({ listener }); return this; } off(event, listener) { const listeners = __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event]; if (!listeners) return this; const index = listeners.findIndex((l) => l.listener === listener); if (index >= 0) listeners.splice(index, 1); return this; } once(event, listener) { const listeners = __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event] || (__classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event] = []); listeners.push({ listener, once: true }); return this; } emitted(event) { return new Promise((resolve, reject) => { __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_catchingPromiseCreated, true, "f"); if (event !== "error") this.once("error", reject); this.once(event, resolve); }); } async done() { __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_catchingPromiseCreated, true, "f"); await __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_endPromise, "f"); } _emit(event, ...args) { if (__classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_ended, "f")) { return; } if (event === "end") { __classPrivateFieldSet5(this, _AbstractAssistantStreamRunner_ended, true, "f"); __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_resolveEndPromise, "f").call(this); } const listeners = __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event]; if (listeners) { __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_listeners, "f")[event] = listeners.filter((l) => !l.once); listeners.forEach(({ listener }) => listener(...args)); } if (event === "abort") { const error = args[0]; if (!__classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_catchingPromiseCreated, "f") && !listeners?.length) { Promise.reject(error); } __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_rejectConnectedPromise, "f").call(this, error); __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_rejectEndPromise, "f").call(this, error); this._emit("end"); return; } if (event === "error") { const error = args[0]; if (!__classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_catchingPromiseCreated, "f") && !listeners?.length) { Promise.reject(error); } __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_rejectConnectedPromise, "f").call(this, error); __classPrivateFieldGet5(this, _AbstractAssistantStreamRunner_rejectEndPromise, "f").call(this, error); this._emit("end"); } } async _threadAssistantStream(body, thread, options) { return await this._createThreadAssistantStream(thread, body, options); } async _runAssistantStream(threadId, runs, params, options) { return await this._createAssistantStream(runs, threadId, params, options); } async _runToolAssistantStream(threadId, runId, runs, params, options) { return await this._createToolAssistantStream(runs, threadId, runId, params, options); } async _createThreadAssistantStream(thread, body, options) { const signal = options?.signal; if (signal) { if (signal.aborted) this.controller.abort(); signal.addEventListener("abort", () => this.controller.abort()); } const runResult = await thread.createAndRun({ ...body, stream: false }, { ...options, signal: this.controller.signal }); this._connected(); return this._addRun(runResult); } async _createToolAssistantStream(run2, threadId, runId, params, options) { const signal = options?.signal; if (signal) { if (signal.aborted) this.controller.abort(); signal.addEventListener("abort", () => this.controller.abort()); } const runResult = await run2.submitToolOutputs(threadId, runId, { ...params, stream: false }, { ...options, signal: this.controller.signal }); this._connected(); return this._addRun(runResult); } async _createAssistantStream(run2, threadId, params, options) { const signal = options?.signal; if (signal) { if (signal.aborted) this.controller.abort(); signal.addEventListener("abort", () => this.controller.abort()); } const runResult = await run2.create(threadId, { ...params, stream: false }, { ...options, signal: this.controller.signal }); this._connected(); return this._addRun(runResult); } }; _AbstractAssistantStreamRunner_connectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_resolveConnectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_rejectConnectedPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_endPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_resolveEndPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_rejectEndPromise = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_listeners = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_ended = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_errored = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_aborted = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_catchingPromiseCreated = /* @__PURE__ */ new WeakMap(), _AbstractAssistantStreamRunner_handleError = /* @__PURE__ */ new WeakMap(); // node_modules/openai/lib/AssistantStream.mjs var __classPrivateFieldGet6 = function(receiver, state, kind2, f) { if (kind2 === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind2 === "m" ? f : kind2 === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet6 = function(receiver, state, value, kind2, f) { if (kind2 === "m") throw new TypeError("Private method is not writable"); if (kind2 === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return kind2 === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; }; var _AssistantStream_instances; var _AssistantStream_events; var _AssistantStream_runStepSnapshots; var _AssistantStream_messageSnapshots; var _AssistantStream_messageSnapshot; var _AssistantStream_finalRun; var _AssistantStream_currentContentIndex; var _AssistantStream_currentContent; var _AssistantStream_currentToolCallIndex; var _AssistantStream_currentToolCall; var _AssistantStream_currentEvent; var _AssistantStream_currentRunSnapshot; var _AssistantStream_currentRunStepSnapshot; var _AssistantStream_addEvent; var _AssistantStream_endRequest; var _AssistantStream_handleMessage; var _AssistantStream_handleRunStep; var _AssistantStream_handleEvent; var _AssistantStream_accumulateRunStep; var _AssistantStream_accumulateMessage; var _AssistantStream_accumulateContent; var _AssistantStream_handleRun; var AssistantStream = class extends AbstractAssistantStreamRunner { constructor() { super(...arguments); _AssistantStream_instances.add(this); _AssistantStream_events.set(this, []); _AssistantStream_runStepSnapshots.set(this, {}); _AssistantStream_messageSnapshots.set(this, {}); _AssistantStream_messageSnapshot.set(this, void 0); _AssistantStream_finalRun.set(this, void 0); _AssistantStream_currentContentIndex.set(this, void 0); _AssistantStream_currentContent.set(this, void 0); _AssistantStream_currentToolCallIndex.set(this, void 0); _AssistantStream_currentToolCall.set(this, void 0); _AssistantStream_currentEvent.set(this, void 0); _AssistantStream_currentRunSnapshot.set(this, void 0); _AssistantStream_currentRunStepSnapshot.set(this, void 0); } [(_AssistantStream_events = /* @__PURE__ */ new WeakMap(), _AssistantStream_runStepSnapshots = /* @__PURE__ */ new WeakMap(), _AssistantStream_messageSnapshots = /* @__PURE__ */ new WeakMap(), _AssistantStream_messageSnapshot = /* @__PURE__ */ new WeakMap(), _AssistantStream_finalRun = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentContentIndex = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentContent = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentToolCallIndex = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentToolCall = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentEvent = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentRunSnapshot = /* @__PURE__ */ new WeakMap(), _AssistantStream_currentRunStepSnapshot = /* @__PURE__ */ new WeakMap(), _AssistantStream_instances = /* @__PURE__ */ new WeakSet(), Symbol.asyncIterator)]() { const pushQueue = []; const readQueue = []; let done = false; this.on("event", (event) => { const reader = readQueue.shift(); if (reader) { reader.resolve(event); } else { pushQueue.push(event); } }); this.on("end", () => { done = true; for (const reader of readQueue) { reader.resolve(void 0); } readQueue.length = 0; }); this.on("abort", (err) => { done = true; for (const reader of readQueue) { reader.reject(err); } readQueue.length = 0; }); this.on("error", (err) => { done = true; for (const reader of readQueue) { reader.reject(err); } readQueue.length = 0; }); return { next: async () => { if (!pushQueue.length) { if (done) { return { value: void 0, done: true }; } return new Promise((resolve, reject) => readQueue.push({ resolve, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true }); } const chunk = pushQueue.shift(); return { value: chunk, done: false }; }, return: async () => { this.abort(); return { value: void 0, done: true }; } }; } static fromReadableStream(stream) { const runner = new AssistantStream(); runner._run(() => runner._fromReadableStream(stream)); return runner; } async _fromReadableStream(readableStream, options) { const signal = options?.signal; if (signal) { if (signal.aborted) this.controller.abort(); signal.addEventListener("abort", () => this.controller.abort()); } this._connected(); const stream = Stream.fromReadableStream(readableStream, this.controller); for await (const event of stream) { __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); } if (stream.controller.signal?.aborted) { throw new APIUserAbortError(); } return this._addRun(__classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); } toReadableStream() { const stream = new Stream(this[Symbol.asyncIterator].bind(this), this.controller); return stream.toReadableStream(); } static createToolAssistantStream(threadId, runId, runs, body, options) { const runner = new AssistantStream(); runner._run(() => runner._runToolAssistantStream(threadId, runId, runs, body, { ...options, headers: { ...options?.headers, "X-Stainless-Helper-Method": "stream" } })); return runner; } async _createToolAssistantStream(run2, threadId, runId, params, options) { const signal = options?.signal; if (signal) { if (signal.aborted) this.controller.abort(); signal.addEventListener("abort", () => this.controller.abort()); } const body = { ...params, stream: true }; const stream = await run2.submitToolOutputs(threadId, runId, body, { ...options, signal: this.controller.signal }); this._connected(); for await (const event of stream) { __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); } if (stream.controller.signal?.aborted) { throw new APIUserAbortError(); } return this._addRun(__classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); } static createThreadAssistantStream(body, thread, options) { const runner = new AssistantStream(); runner._run(() => runner._threadAssistantStream(body, thread, { ...options, headers: { ...options?.headers, "X-Stainless-Helper-Method": "stream" } })); return runner; } static createAssistantStream(threadId, runs, params, options) { const runner = new AssistantStream(); runner._run(() => runner._runAssistantStream(threadId, runs, params, { ...options, headers: { ...options?.headers, "X-Stainless-Helper-Method": "stream" } })); return runner; } currentEvent() { return __classPrivateFieldGet6(this, _AssistantStream_currentEvent, "f"); } currentRun() { return __classPrivateFieldGet6(this, _AssistantStream_currentRunSnapshot, "f"); } currentMessageSnapshot() { return __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f"); } currentRunStepSnapshot() { return __classPrivateFieldGet6(this, _AssistantStream_currentRunStepSnapshot, "f"); } async finalRunSteps() { await this.done(); return Object.values(__classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")); } async finalMessages() { await this.done(); return Object.values(__classPrivateFieldGet6(this, _AssistantStream_messageSnapshots, "f")); } async finalRun() { await this.done(); if (!__classPrivateFieldGet6(this, _AssistantStream_finalRun, "f")) throw Error("Final run was not received."); return __classPrivateFieldGet6(this, _AssistantStream_finalRun, "f"); } async _createThreadAssistantStream(thread, params, options) { const signal = options?.signal; if (signal) { if (signal.aborted) this.controller.abort(); signal.addEventListener("abort", () => this.controller.abort()); } const body = { ...params, stream: true }; const stream = await thread.createAndRun(body, { ...options, signal: this.controller.signal }); this._connected(); for await (const event of stream) { __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); } if (stream.controller.signal?.aborted) { throw new APIUserAbortError(); } return this._addRun(__classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); } async _createAssistantStream(run2, threadId, params, options) { const signal = options?.signal; if (signal) { if (signal.aborted) this.controller.abort(); signal.addEventListener("abort", () => this.controller.abort()); } const body = { ...params, stream: true }; const stream = await run2.create(threadId, body, { ...options, signal: this.controller.signal }); this._connected(); for await (const event of stream) { __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_addEvent).call(this, event); } if (stream.controller.signal?.aborted) { throw new APIUserAbortError(); } return this._addRun(__classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_endRequest).call(this)); } static accumulateDelta(acc, delta) { for (const [key, deltaValue] of Object.entries(delta)) { if (!acc.hasOwnProperty(key)) { acc[key] = deltaValue; continue; } let accValue = acc[key]; if (accValue === null || accValue === void 0) { acc[key] = deltaValue; continue; } if (key === "index" || key === "type") { acc[key] = deltaValue; continue; } if (typeof accValue === "string" && typeof deltaValue === "string") { accValue += deltaValue; } else if (typeof accValue === "number" && typeof deltaValue === "number") { accValue += deltaValue; } else if (isObj(accValue) && isObj(deltaValue)) { accValue = this.accumulateDelta(accValue, deltaValue); } else if (Array.isArray(accValue) && Array.isArray(deltaValue)) { if (accValue.every((x) => typeof x === "string" || typeof x === "number")) { accValue.push(...deltaValue); continue; } } else { throw Error(`Unhandled record type: ${key}, deltaValue: ${deltaValue}, accValue: ${accValue}`); } acc[key] = accValue; } return acc; } }; _AssistantStream_addEvent = function _AssistantStream_addEvent2(event) { if (this.ended) return; __classPrivateFieldSet6(this, _AssistantStream_currentEvent, event, "f"); __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_handleEvent).call(this, event); switch (event.event) { case "thread.created": break; case "thread.run.created": case "thread.run.queued": case "thread.run.in_progress": case "thread.run.requires_action": case "thread.run.completed": case "thread.run.failed": case "thread.run.cancelling": case "thread.run.cancelled": case "thread.run.expired": __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_handleRun).call(this, event); break; case "thread.run.step.created": case "thread.run.step.in_progress": case "thread.run.step.delta": case "thread.run.step.completed": case "thread.run.step.failed": case "thread.run.step.cancelled": case "thread.run.step.expired": __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_handleRunStep).call(this, event); break; case "thread.message.created": case "thread.message.in_progress": case "thread.message.delta": case "thread.message.completed": case "thread.message.incomplete": __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_handleMessage).call(this, event); break; case "error": throw new Error("Encountered an error event in event processing - errors should be processed earlier"); } }, _AssistantStream_endRequest = function _AssistantStream_endRequest2() { if (this.ended) { throw new OpenAIError(`stream has ended, this shouldn't happen`); } if (!__classPrivateFieldGet6(this, _AssistantStream_finalRun, "f")) throw Error("Final run has not been received"); return __classPrivateFieldGet6(this, _AssistantStream_finalRun, "f"); }, _AssistantStream_handleMessage = function _AssistantStream_handleMessage2(event) { const [accumulatedMessage, newContent] = __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_accumulateMessage).call(this, event, __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f")); __classPrivateFieldSet6(this, _AssistantStream_messageSnapshot, accumulatedMessage, "f"); __classPrivateFieldGet6(this, _AssistantStream_messageSnapshots, "f")[accumulatedMessage.id] = accumulatedMessage; for (const content of newContent) { const snapshotContent = accumulatedMessage.content[content.index]; if (snapshotContent?.type == "text") { this._emit("textCreated", snapshotContent.text); } } switch (event.event) { case "thread.message.created": this._emit("messageCreated", event.data); break; case "thread.message.in_progress": break; case "thread.message.delta": this._emit("messageDelta", event.data.delta, accumulatedMessage); if (event.data.delta.content) { for (const content of event.data.delta.content) { if (content.type == "text" && content.text) { let textDelta = content.text; let snapshot = accumulatedMessage.content[content.index]; if (snapshot && snapshot.type == "text") { this._emit("textDelta", textDelta, snapshot.text); } else { throw Error("The snapshot associated with this text delta is not text or missing"); } } if (content.index != __classPrivateFieldGet6(this, _AssistantStream_currentContentIndex, "f")) { if (__classPrivateFieldGet6(this, _AssistantStream_currentContent, "f")) { switch (__classPrivateFieldGet6(this, _AssistantStream_currentContent, "f").type) { case "text": this._emit("textDone", __classPrivateFieldGet6(this, _AssistantStream_currentContent, "f").text, __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f")); break; case "image_file": this._emit("imageFileDone", __classPrivateFieldGet6(this, _AssistantStream_currentContent, "f").image_file, __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f")); break; } } __classPrivateFieldSet6(this, _AssistantStream_currentContentIndex, content.index, "f"); } __classPrivateFieldSet6(this, _AssistantStream_currentContent, accumulatedMessage.content[content.index], "f"); } } break; case "thread.message.completed": case "thread.message.incomplete": if (__classPrivateFieldGet6(this, _AssistantStream_currentContentIndex, "f") !== void 0) { const currentContent = event.data.content[__classPrivateFieldGet6(this, _AssistantStream_currentContentIndex, "f")]; if (currentContent) { switch (currentContent.type) { case "image_file": this._emit("imageFileDone", currentContent.image_file, __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f")); break; case "text": this._emit("textDone", currentContent.text, __classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f")); break; } } } if (__classPrivateFieldGet6(this, _AssistantStream_messageSnapshot, "f")) { this._emit("messageDone", event.data); } __classPrivateFieldSet6(this, _AssistantStream_messageSnapshot, void 0, "f"); } }, _AssistantStream_handleRunStep = function _AssistantStream_handleRunStep2(event) { const accumulatedRunStep = __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_accumulateRunStep).call(this, event); __classPrivateFieldSet6(this, _AssistantStream_currentRunStepSnapshot, accumulatedRunStep, "f"); switch (event.event) { case "thread.run.step.created": this._emit("runStepCreated", event.data); break; case "thread.run.step.delta": const delta = event.data.delta; if (delta.step_details && delta.step_details.type == "tool_calls" && delta.step_details.tool_calls && accumulatedRunStep.step_details.type == "tool_calls") { for (const toolCall of delta.step_details.tool_calls) { if (toolCall.index == __classPrivateFieldGet6(this, _AssistantStream_currentToolCallIndex, "f")) { this._emit("toolCallDelta", toolCall, accumulatedRunStep.step_details.tool_calls[toolCall.index]); } else { if (__classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")) { this._emit("toolCallDone", __classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")); } __classPrivateFieldSet6(this, _AssistantStream_currentToolCallIndex, toolCall.index, "f"); __classPrivateFieldSet6(this, _AssistantStream_currentToolCall, accumulatedRunStep.step_details.tool_calls[toolCall.index], "f"); if (__classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")) this._emit("toolCallCreated", __classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")); } } } this._emit("runStepDelta", event.data.delta, accumulatedRunStep); break; case "thread.run.step.completed": case "thread.run.step.failed": case "thread.run.step.cancelled": case "thread.run.step.expired": __classPrivateFieldSet6(this, _AssistantStream_currentRunStepSnapshot, void 0, "f"); const details = event.data.step_details; if (details.type == "tool_calls") { if (__classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")) { this._emit("toolCallDone", __classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")); __classPrivateFieldSet6(this, _AssistantStream_currentToolCall, void 0, "f"); } } this._emit("runStepDone", event.data, accumulatedRunStep); break; case "thread.run.step.in_progress": break; } }, _AssistantStream_handleEvent = function _AssistantStream_handleEvent2(event) { __classPrivateFieldGet6(this, _AssistantStream_events, "f").push(event); this._emit("event", event); }, _AssistantStream_accumulateRunStep = function _AssistantStream_accumulateRunStep2(event) { switch (event.event) { case "thread.run.step.created": __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = event.data; return event.data; case "thread.run.step.delta": let snapshot = __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]; if (!snapshot) { throw Error("Received a RunStepDelta before creation of a snapshot"); } let data = event.data; if (data.delta) { const accumulated = AssistantStream.accumulateDelta(snapshot, data.delta); __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = accumulated; } return __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]; case "thread.run.step.completed": case "thread.run.step.failed": case "thread.run.step.cancelled": case "thread.run.step.expired": case "thread.run.step.in_progress": __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id] = event.data; break; } if (__classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]) return __classPrivateFieldGet6(this, _AssistantStream_runStepSnapshots, "f")[event.data.id]; throw new Error("No snapshot available"); }, _AssistantStream_accumulateMessage = function _AssistantStream_accumulateMessage2(event, snapshot) { let newContent = []; switch (event.event) { case "thread.message.created": return [event.data, newContent]; case "thread.message.delta": if (!snapshot) { throw Error("Received a delta with no existing snapshot (there should be one from message creation)"); } let data = event.data; if (data.delta.content) { for (const contentElement of data.delta.content) { if (contentElement.index in snapshot.content) { let currentContent = snapshot.content[contentElement.index]; snapshot.content[contentElement.index] = __classPrivateFieldGet6(this, _AssistantStream_instances, "m", _AssistantStream_accumulateContent).call(this, contentElement, currentContent); } else { snapshot.content[contentElement.index] = contentElement; newContent.push(contentElement); } } } return [snapshot, newContent]; case "thread.message.in_progress": case "thread.message.completed": case "thread.message.incomplete": if (snapshot) { return [snapshot, newContent]; } else { throw Error("Received thread message event with no existing snapshot"); } } throw Error("Tried to accumulate a non-message event"); }, _AssistantStream_accumulateContent = function _AssistantStream_accumulateContent2(contentElement, currentContent) { return AssistantStream.accumulateDelta(currentContent, contentElement); }, _AssistantStream_handleRun = function _AssistantStream_handleRun2(event) { __classPrivateFieldSet6(this, _AssistantStream_currentRunSnapshot, event.data, "f"); switch (event.event) { case "thread.run.created": break; case "thread.run.queued": break; case "thread.run.in_progress": break; case "thread.run.requires_action": case "thread.run.cancelled": case "thread.run.failed": case "thread.run.completed": case "thread.run.expired": __classPrivateFieldSet6(this, _AssistantStream_finalRun, event.data, "f"); if (__classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")) { this._emit("toolCallDone", __classPrivateFieldGet6(this, _AssistantStream_currentToolCall, "f")); __classPrivateFieldSet6(this, _AssistantStream_currentToolCall, void 0, "f"); } break; case "thread.run.cancelling": break; } }; // node_modules/openai/resources/beta/threads/messages.mjs var Messages = class extends APIResource { create(threadId, body, options) { return this._client.post(`/threads/${threadId}/messages`, { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } retrieve(threadId, messageId, options) { return this._client.get(`/threads/${threadId}/messages/${messageId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } update(threadId, messageId, body, options) { return this._client.post(`/threads/${threadId}/messages/${messageId}`, { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } list(threadId, query = {}, options) { if (isRequestOptions(query)) { return this.list(threadId, {}, query); } return this._client.getAPIList(`/threads/${threadId}/messages`, MessagesPage, { query, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } del(threadId, messageId, options) { return this._client.delete(`/threads/${threadId}/messages/${messageId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } }; var MessagesPage = class extends CursorPage { }; (function(Messages2) { Messages2.MessagesPage = MessagesPage; })(Messages || (Messages = {})); // node_modules/openai/resources/beta/threads/runs/steps.mjs var Steps = class extends APIResource { retrieve(threadId, runId, stepId, options) { return this._client.get(`/threads/${threadId}/runs/${runId}/steps/${stepId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } list(threadId, runId, query = {}, options) { if (isRequestOptions(query)) { return this.list(threadId, runId, {}, query); } return this._client.getAPIList(`/threads/${threadId}/runs/${runId}/steps`, RunStepsPage, { query, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } }; var RunStepsPage = class extends CursorPage { }; (function(Steps2) { Steps2.RunStepsPage = RunStepsPage; })(Steps || (Steps = {})); // node_modules/openai/resources/beta/threads/runs/runs.mjs var Runs = class extends APIResource { constructor() { super(...arguments); this.steps = new Steps(this._client); } create(threadId, body, options) { return this._client.post(`/threads/${threadId}/runs`, { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }, stream: body.stream ?? false }); } retrieve(threadId, runId, options) { return this._client.get(`/threads/${threadId}/runs/${runId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } update(threadId, runId, body, options) { return this._client.post(`/threads/${threadId}/runs/${runId}`, { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } list(threadId, query = {}, options) { if (isRequestOptions(query)) { return this.list(threadId, {}, query); } return this._client.getAPIList(`/threads/${threadId}/runs`, RunsPage, { query, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } cancel(threadId, runId, options) { return this._client.post(`/threads/${threadId}/runs/${runId}/cancel`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } async createAndPoll(threadId, body, options) { const run2 = await this.create(threadId, body, options); return await this.poll(threadId, run2.id, options); } createAndStream(threadId, body, options) { return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options); } async poll(threadId, runId, options) { const headers = { ...options?.headers, "X-Stainless-Poll-Helper": "true" }; if (options?.pollIntervalMs) { headers["X-Stainless-Custom-Poll-Interval"] = options.pollIntervalMs.toString(); } while (true) { const { data: run2, response } = await this.retrieve(threadId, runId, { ...options, headers: { ...options?.headers, ...headers } }).withResponse(); switch (run2.status) { case "queued": case "in_progress": case "cancelling": let sleepInterval = 5e3; if (options?.pollIntervalMs) { sleepInterval = options.pollIntervalMs; } else { const headerInterval = response.headers.get("openai-poll-after-ms"); if (headerInterval) { const headerIntervalMs = parseInt(headerInterval); if (!isNaN(headerIntervalMs)) { sleepInterval = headerIntervalMs; } } } await sleep(sleepInterval); break; case "requires_action": case "incomplete": case "cancelled": case "completed": case "failed": case "expired": return run2; } } } stream(threadId, body, options) { return AssistantStream.createAssistantStream(threadId, this._client.beta.threads.runs, body, options); } submitToolOutputs(threadId, runId, body, options) { return this._client.post(`/threads/${threadId}/runs/${runId}/submit_tool_outputs`, { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }, stream: body.stream ?? false }); } async submitToolOutputsAndPoll(threadId, runId, body, options) { const run2 = await this.submitToolOutputs(threadId, runId, body, options); return await this.poll(threadId, run2.id, options); } submitToolOutputsStream(threadId, runId, body, options) { return AssistantStream.createToolAssistantStream(threadId, runId, this._client.beta.threads.runs, body, options); } }; var RunsPage = class extends CursorPage { }; (function(Runs2) { Runs2.RunsPage = RunsPage; Runs2.Steps = Steps; Runs2.RunStepsPage = RunStepsPage; })(Runs || (Runs = {})); // node_modules/openai/resources/beta/threads/threads.mjs var Threads = class extends APIResource { constructor() { super(...arguments); this.runs = new Runs(this._client); this.messages = new Messages(this._client); } create(body = {}, options) { if (isRequestOptions(body)) { return this.create({}, body); } return this._client.post("/threads", { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } retrieve(threadId, options) { return this._client.get(`/threads/${threadId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } update(threadId, body, options) { return this._client.post(`/threads/${threadId}`, { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } del(threadId, options) { return this._client.delete(`/threads/${threadId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } createAndRun(body, options) { return this._client.post("/threads/runs", { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers }, stream: body.stream ?? false }); } async createAndRunPoll(body, options) { const run2 = await this.createAndRun(body, options); return await this.runs.poll(run2.thread_id, run2.id, options); } createAndRunStream(body, options) { return AssistantStream.createThreadAssistantStream(body, this._client.beta.threads, options); } }; (function(Threads2) { Threads2.Runs = Runs; Threads2.RunsPage = RunsPage; Threads2.Messages = Messages; Threads2.MessagesPage = MessagesPage; })(Threads || (Threads = {})); // node_modules/openai/lib/Util.mjs var allSettledWithThrow = async (promises) => { const results = await Promise.allSettled(promises); const rejected = results.filter((result) => result.status === "rejected"); if (rejected.length) { for (const result of rejected) { console.error(result.reason); } throw new Error(`${rejected.length} promise(s) failed - see the above errors`); } const values = []; for (const result of results) { if (result.status === "fulfilled") { values.push(result.value); } } return values; }; // node_modules/openai/resources/beta/vector-stores/files.mjs var Files = class extends APIResource { create(vectorStoreId, body, options) { return this._client.post(`/vector_stores/${vectorStoreId}/files`, { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } retrieve(vectorStoreId, fileId, options) { return this._client.get(`/vector_stores/${vectorStoreId}/files/${fileId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } list(vectorStoreId, query = {}, options) { if (isRequestOptions(query)) { return this.list(vectorStoreId, {}, query); } return this._client.getAPIList(`/vector_stores/${vectorStoreId}/files`, VectorStoreFilesPage, { query, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } del(vectorStoreId, fileId, options) { return this._client.delete(`/vector_stores/${vectorStoreId}/files/${fileId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } async createAndPoll(vectorStoreId, body, options) { const file = await this.create(vectorStoreId, body, options); return await this.poll(vectorStoreId, file.id, options); } async poll(vectorStoreId, fileId, options) { const headers = { ...options?.headers, "X-Stainless-Poll-Helper": "true" }; if (options?.pollIntervalMs) { headers["X-Stainless-Custom-Poll-Interval"] = options.pollIntervalMs.toString(); } while (true) { const fileResponse = await this.retrieve(vectorStoreId, fileId, { ...options, headers }).withResponse(); const file = fileResponse.data; switch (file.status) { case "in_progress": let sleepInterval = 5e3; if (options?.pollIntervalMs) { sleepInterval = options.pollIntervalMs; } else { const headerInterval = fileResponse.response.headers.get("openai-poll-after-ms"); if (headerInterval) { const headerIntervalMs = parseInt(headerInterval); if (!isNaN(headerIntervalMs)) { sleepInterval = headerIntervalMs; } } } await sleep(sleepInterval); break; case "failed": case "completed": return file; } } } async upload(vectorStoreId, file, options) { const fileInfo = await this._client.files.create({ file, purpose: "assistants" }, options); return this.create(vectorStoreId, { file_id: fileInfo.id }, options); } async uploadAndPoll(vectorStoreId, file, options) { const fileInfo = await this.upload(vectorStoreId, file, options); return await this.poll(vectorStoreId, fileInfo.id, options); } }; var VectorStoreFilesPage = class extends CursorPage { }; (function(Files3) { Files3.VectorStoreFilesPage = VectorStoreFilesPage; })(Files || (Files = {})); // node_modules/openai/resources/beta/vector-stores/file-batches.mjs var FileBatches = class extends APIResource { create(vectorStoreId, body, options) { return this._client.post(`/vector_stores/${vectorStoreId}/file_batches`, { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } retrieve(vectorStoreId, batchId, options) { return this._client.get(`/vector_stores/${vectorStoreId}/file_batches/${batchId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } cancel(vectorStoreId, batchId, options) { return this._client.post(`/vector_stores/${vectorStoreId}/file_batches/${batchId}/cancel`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } async createAndPoll(vectorStoreId, body, options) { const batch = await this.create(vectorStoreId, body); return await this.poll(vectorStoreId, batch.id, options); } listFiles(vectorStoreId, batchId, query = {}, options) { if (isRequestOptions(query)) { return this.listFiles(vectorStoreId, batchId, {}, query); } return this._client.getAPIList(`/vector_stores/${vectorStoreId}/file_batches/${batchId}/files`, VectorStoreFilesPage, { query, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } async poll(vectorStoreId, batchId, options) { const headers = { ...options?.headers, "X-Stainless-Poll-Helper": "true" }; if (options?.pollIntervalMs) { headers["X-Stainless-Custom-Poll-Interval"] = options.pollIntervalMs.toString(); } while (true) { const { data: batch, response } = await this.retrieve(vectorStoreId, batchId, { ...options, headers }).withResponse(); switch (batch.status) { case "in_progress": let sleepInterval = 5e3; if (options?.pollIntervalMs) { sleepInterval = options.pollIntervalMs; } else { const headerInterval = response.headers.get("openai-poll-after-ms"); if (headerInterval) { const headerIntervalMs = parseInt(headerInterval); if (!isNaN(headerIntervalMs)) { sleepInterval = headerIntervalMs; } } } await sleep(sleepInterval); break; case "failed": case "cancelled": case "completed": return batch; } } } async uploadAndPoll(vectorStoreId, { files, fileIds = [] }, options) { if (files == null || files.length == 0) { throw new Error(`No \`files\` provided to process. If you've already uploaded files you should use \`.createAndPoll()\` instead`); } const configuredConcurrency = options?.maxConcurrency ?? 5; const concurrencyLimit = Math.min(configuredConcurrency, files.length); const client = this._client; const fileIterator = files.values(); const allFileIds = [...fileIds]; async function processFiles(iterator) { for (let item of iterator) { const fileObj = await client.files.create({ file: item, purpose: "assistants" }, options); allFileIds.push(fileObj.id); } } const workers = Array(concurrencyLimit).fill(fileIterator).map(processFiles); await allSettledWithThrow(workers); return await this.createAndPoll(vectorStoreId, { file_ids: allFileIds }); } }; (function(FileBatches2) { })(FileBatches || (FileBatches = {})); // node_modules/openai/resources/beta/vector-stores/vector-stores.mjs var VectorStores = class extends APIResource { constructor() { super(...arguments); this.files = new Files(this._client); this.fileBatches = new FileBatches(this._client); } create(body, options) { return this._client.post("/vector_stores", { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } retrieve(vectorStoreId, options) { return this._client.get(`/vector_stores/${vectorStoreId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } update(vectorStoreId, body, options) { return this._client.post(`/vector_stores/${vectorStoreId}`, { body, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } list(query = {}, options) { if (isRequestOptions(query)) { return this.list({}, query); } return this._client.getAPIList("/vector_stores", VectorStoresPage, { query, ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } del(vectorStoreId, options) { return this._client.delete(`/vector_stores/${vectorStoreId}`, { ...options, headers: { "OpenAI-Beta": "assistants=v2", ...options?.headers } }); } }; var VectorStoresPage = class extends CursorPage { }; (function(VectorStores2) { VectorStores2.VectorStoresPage = VectorStoresPage; VectorStores2.Files = Files; VectorStores2.VectorStoreFilesPage = VectorStoreFilesPage; VectorStores2.FileBatches = FileBatches; })(VectorStores || (VectorStores = {})); // node_modules/openai/resources/beta/beta.mjs var Beta = class extends APIResource { constructor() { super(...arguments); this.vectorStores = new VectorStores(this._client); this.chat = new Chat2(this._client); this.assistants = new Assistants(this._client); this.threads = new Threads(this._client); } }; (function(Beta2) { Beta2.VectorStores = VectorStores; Beta2.VectorStoresPage = VectorStoresPage; Beta2.Chat = Chat2; Beta2.Assistants = Assistants; Beta2.AssistantsPage = AssistantsPage; Beta2.Threads = Threads; })(Beta || (Beta = {})); // node_modules/openai/resources/completions.mjs var Completions3 = class extends APIResource { create(body, options) { return this._client.post("/completions", { body, ...options, stream: body.stream ?? false }); } }; (function(Completions4) { })(Completions3 || (Completions3 = {})); // node_modules/openai/resources/embeddings.mjs var Embeddings = class extends APIResource { create(body, options) { return this._client.post("/embeddings", { body, ...options }); } }; (function(Embeddings2) { })(Embeddings || (Embeddings = {})); // node_modules/openai/resources/files.mjs var Files2 = class extends APIResource { create(body, options) { return this._client.post("/files", multipartFormRequestOptions({ body, ...options })); } retrieve(fileId, options) { return this._client.get(`/files/${fileId}`, options); } list(query = {}, options) { if (isRequestOptions(query)) { return this.list({}, query); } return this._client.getAPIList("/files", FileObjectsPage, { query, ...options }); } del(fileId, options) { return this._client.delete(`/files/${fileId}`, options); } content(fileId, options) { return this._client.get(`/files/${fileId}/content`, { ...options, __binaryResponse: true }); } retrieveContent(fileId, options) { return this._client.get(`/files/${fileId}/content`, { ...options, headers: { Accept: "application/json", ...options?.headers } }); } async waitForProcessing(id, { pollInterval = 5e3, maxWait = 30 * 60 * 1e3 } = {}) { const TERMINAL_STATES = /* @__PURE__ */ new Set(["processed", "error", "deleted"]); const start = Date.now(); let file = await this.retrieve(id); while (!file.status || !TERMINAL_STATES.has(file.status)) { await sleep(pollInterval); file = await this.retrieve(id); if (Date.now() - start > maxWait) { throw new APIConnectionTimeoutError({ message: `Giving up on waiting for file ${id} to finish processing after ${maxWait} milliseconds.` }); } } return file; } }; var FileObjectsPage = class extends Page { }; (function(Files3) { Files3.FileObjectsPage = FileObjectsPage; })(Files2 || (Files2 = {})); // node_modules/openai/resources/fine-tuning/jobs/checkpoints.mjs var Checkpoints = class extends APIResource { list(fineTuningJobId, query = {}, options) { if (isRequestOptions(query)) { return this.list(fineTuningJobId, {}, query); } return this._client.getAPIList(`/fine_tuning/jobs/${fineTuningJobId}/checkpoints`, FineTuningJobCheckpointsPage, { query, ...options }); } }; var FineTuningJobCheckpointsPage = class extends CursorPage { }; (function(Checkpoints2) { Checkpoints2.FineTuningJobCheckpointsPage = FineTuningJobCheckpointsPage; })(Checkpoints || (Checkpoints = {})); // node_modules/openai/resources/fine-tuning/jobs/jobs.mjs var Jobs = class extends APIResource { constructor() { super(...arguments); this.checkpoints = new Checkpoints(this._client); } create(body, options) { return this._client.post("/fine_tuning/jobs", { body, ...options }); } retrieve(fineTuningJobId, options) { return this._client.get(`/fine_tuning/jobs/${fineTuningJobId}`, options); } list(query = {}, options) { if (isRequestOptions(query)) { return this.list({}, query); } return this._client.getAPIList("/fine_tuning/jobs", FineTuningJobsPage, { query, ...options }); } cancel(fineTuningJobId, options) { return this._client.post(`/fine_tuning/jobs/${fineTuningJobId}/cancel`, options); } listEvents(fineTuningJobId, query = {}, options) { if (isRequestOptions(query)) { return this.listEvents(fineTuningJobId, {}, query); } return this._client.getAPIList(`/fine_tuning/jobs/${fineTuningJobId}/events`, FineTuningJobEventsPage, { query, ...options }); } }; var FineTuningJobsPage = class extends CursorPage { }; var FineTuningJobEventsPage = class extends CursorPage { }; (function(Jobs2) { Jobs2.FineTuningJobsPage = FineTuningJobsPage; Jobs2.FineTuningJobEventsPage = FineTuningJobEventsPage; Jobs2.Checkpoints = Checkpoints; Jobs2.FineTuningJobCheckpointsPage = FineTuningJobCheckpointsPage; })(Jobs || (Jobs = {})); // node_modules/openai/resources/fine-tuning/fine-tuning.mjs var FineTuning = class extends APIResource { constructor() { super(...arguments); this.jobs = new Jobs(this._client); } }; (function(FineTuning2) { FineTuning2.Jobs = Jobs; FineTuning2.FineTuningJobsPage = FineTuningJobsPage; FineTuning2.FineTuningJobEventsPage = FineTuningJobEventsPage; })(FineTuning || (FineTuning = {})); // node_modules/openai/resources/images.mjs var Images = class extends APIResource { createVariation(body, options) { return this._client.post("/images/variations", multipartFormRequestOptions({ body, ...options })); } edit(body, options) { return this._client.post("/images/edits", multipartFormRequestOptions({ body, ...options })); } generate(body, options) { return this._client.post("/images/generations", { body, ...options }); } }; (function(Images2) { })(Images || (Images = {})); // node_modules/openai/resources/models.mjs var Models = class extends APIResource { retrieve(model, options) { return this._client.get(`/models/${model}`, options); } list(options) { return this._client.getAPIList("/models", ModelsPage, options); } del(model, options) { return this._client.delete(`/models/${model}`, options); } }; var ModelsPage = class extends Page { }; (function(Models2) { Models2.ModelsPage = ModelsPage; })(Models || (Models = {})); // node_modules/openai/resources/moderations.mjs var Moderations = class extends APIResource { create(body, options) { return this._client.post("/moderations", { body, ...options }); } }; (function(Moderations2) { })(Moderations || (Moderations = {})); // node_modules/openai/index.mjs var _a; var OpenAI = class extends APIClient { constructor({ baseURL = readEnv("OPENAI_BASE_URL"), apiKey = readEnv("OPENAI_API_KEY"), organization = readEnv("OPENAI_ORG_ID") ?? null, project = readEnv("OPENAI_PROJECT_ID") ?? null, ...opts } = {}) { if (apiKey === void 0) { throw new OpenAIError("The OPENAI_API_KEY environment variable is missing or empty; either provide it, or instantiate the OpenAI client with an apiKey option, like new OpenAI({ apiKey: 'My API Key' })."); } const options = { apiKey, organization, project, ...opts, baseURL: baseURL || `https://api.openai.com/v1` }; if (!options.dangerouslyAllowBrowser && isRunningInBrowser()) { throw new OpenAIError("It looks like you're running in a browser-like environment.\n\nThis is disabled by default, as it risks exposing your secret API credentials to attackers.\nIf you understand the risks and have appropriate mitigations in place,\nyou can set the `dangerouslyAllowBrowser` option to `true`, e.g.,\n\nnew OpenAI({ apiKey, dangerouslyAllowBrowser: true });\n\nhttps://help.openai.com/en/articles/5112595-best-practices-for-api-key-safety\n"); } super({ baseURL: options.baseURL, timeout: options.timeout ?? 6e5, httpAgent: options.httpAgent, maxRetries: options.maxRetries, fetch: options.fetch }); this.completions = new Completions3(this); this.chat = new Chat(this); this.embeddings = new Embeddings(this); this.files = new Files2(this); this.images = new Images(this); this.audio = new Audio(this); this.moderations = new Moderations(this); this.models = new Models(this); this.fineTuning = new FineTuning(this); this.beta = new Beta(this); this.batches = new Batches(this); this._options = options; this.apiKey = apiKey; this.organization = organization; this.project = project; } defaultQuery() { return this._options.defaultQuery; } defaultHeaders(opts) { return { ...super.defaultHeaders(opts), "OpenAI-Organization": this.organization, "OpenAI-Project": this.project, ...this._options.defaultHeaders }; } authHeaders(opts) { return { Authorization: `Bearer ${this.apiKey}` }; } }; _a = OpenAI; OpenAI.OpenAI = _a; OpenAI.OpenAIError = OpenAIError; OpenAI.APIError = APIError; OpenAI.APIConnectionError = APIConnectionError; OpenAI.APIConnectionTimeoutError = APIConnectionTimeoutError; OpenAI.APIUserAbortError = APIUserAbortError; OpenAI.NotFoundError = NotFoundError; OpenAI.ConflictError = ConflictError; OpenAI.RateLimitError = RateLimitError; OpenAI.BadRequestError = BadRequestError; OpenAI.AuthenticationError = AuthenticationError; OpenAI.InternalServerError = InternalServerError; OpenAI.PermissionDeniedError = PermissionDeniedError; OpenAI.UnprocessableEntityError = UnprocessableEntityError; OpenAI.toFile = toFile; OpenAI.fileFromPath = fileFromPath; var { OpenAIError: OpenAIError2, APIError: APIError2, APIConnectionError: APIConnectionError2, APIConnectionTimeoutError: APIConnectionTimeoutError2, APIUserAbortError: APIUserAbortError2, NotFoundError: NotFoundError2, ConflictError: ConflictError2, RateLimitError: RateLimitError2, BadRequestError: BadRequestError2, AuthenticationError: AuthenticationError2, InternalServerError: InternalServerError2, PermissionDeniedError: PermissionDeniedError2, UnprocessableEntityError: UnprocessableEntityError2 } = error_exports; (function(OpenAI2) { OpenAI2.Page = Page; OpenAI2.CursorPage = CursorPage; OpenAI2.Completions = Completions3; OpenAI2.Chat = Chat; OpenAI2.Embeddings = Embeddings; OpenAI2.Files = Files2; OpenAI2.FileObjectsPage = FileObjectsPage; OpenAI2.Images = Images; OpenAI2.Audio = Audio; OpenAI2.Moderations = Moderations; OpenAI2.Models = Models; OpenAI2.ModelsPage = ModelsPage; OpenAI2.FineTuning = FineTuning; OpenAI2.Beta = Beta; OpenAI2.Batches = Batches; OpenAI2.BatchesPage = BatchesPage; })(OpenAI || (OpenAI = {})); // src/services/TranscriptionService.ts function TimerNotice2(heading, initialMessage) { let currentMessage = initialMessage; const startTime = Date.now(); let stopTime; const notice = new import_obsidian23.Notice(initialMessage, 0); function formatMsg(message) { return `${heading} (${getTime()}): ${message}`; } function update2(message) { currentMessage = message; notice.setMessage(formatMsg(currentMessage)); } const interval = setInterval(() => { notice.setMessage(formatMsg(currentMessage)); }, 1e3); function getTime() { return formatTime2(stopTime ? stopTime - startTime : Date.now() - startTime); } return { update: update2, hide: () => notice.hide(), stop: () => { stopTime = Date.now(); clearInterval(interval); } }; } function formatTime2(ms) { const seconds = Math.floor(ms / 1e3); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); return `${hours.toString().padStart(2, "0")}:${(minutes % 60).toString().padStart(2, "0")}:${(seconds % 60).toString().padStart(2, "0")}`; } var TranscriptionService = class { constructor(plugin2) { this.MAX_RETRIES = 3; this.isTranscribing = false; this.plugin = plugin2; this.client = new OpenAI({ apiKey: this.plugin.settings.openAIApiKey, dangerouslyAllowBrowser: true }); } async transcribeCurrentEpisode() { if (this.isTranscribing) { new import_obsidian23.Notice("A transcription is already in progress."); return; } const currentEpisode2 = this.plugin.api.podcast; if (!currentEpisode2) { new import_obsidian23.Notice("No episode is currently playing."); return; } const transcriptPath = FilePathTemplateEngine(this.plugin.settings.transcript.path, currentEpisode2); const existingFile = this.plugin.app.vault.getAbstractFileByPath(transcriptPath); if (existingFile instanceof import_obsidian23.TFile) { new import_obsidian23.Notice(`You've already transcribed this episode - found ${transcriptPath}.`); return; } this.isTranscribing = true; const notice = TimerNotice2("Transcription", "Preparing to transcribe..."); try { notice.update("Downloading episode..."); const downloadPath = await downloadEpisode(currentEpisode2, this.plugin.settings.download.path); const podcastFile = this.plugin.app.vault.getAbstractFileByPath(downloadPath); if (!podcastFile || !(podcastFile instanceof import_obsidian23.TFile)) { throw new Error("Failed to download or locate the episode."); } notice.update("Preparing audio for transcription..."); const fileBuffer = await this.plugin.app.vault.readBinary(podcastFile); const fileExtension = podcastFile.extension; const mimeType = this.getMimeType(fileExtension); const chunks = this.chunkFile(fileBuffer); const files = this.createChunkFiles(chunks, podcastFile.basename, fileExtension, mimeType); notice.update("Starting transcription..."); const transcription = await this.transcribeChunks(files, notice.update); notice.update("Saving transcription..."); await this.saveTranscription(currentEpisode2, transcription); notice.stop(); notice.update("Transcription completed and saved."); } catch (error) { console.error("Transcription error:", error); notice.update(`Transcription failed: ${error.message}`); } finally { this.isTranscribing = false; setTimeout(() => notice.hide(), 5e3); } } chunkFile(fileBuffer) { const CHUNK_SIZE_MB = 20; const chunkSizeBytes = CHUNK_SIZE_MB * 1024 * 1024; const chunks = []; for (let i = 0; i < fileBuffer.byteLength; i += chunkSizeBytes) { chunks.push(fileBuffer.slice(i, i + chunkSizeBytes)); } return chunks; } createChunkFiles(chunks, fileName, fileExtension, mimeType) { return chunks.map((chunk, index) => new File([chunk], `${fileName}.part${index}.${fileExtension}`, { type: mimeType })); } getMimeType(fileExtension) { switch (fileExtension.toLowerCase()) { case "mp3": return "audio/mp3"; case "m4a": return "audio/mp4"; case "ogg": return "audio/ogg"; case "wav": return "audio/wav"; case "flac": return "audio/flac"; default: return "audio/mpeg"; } } async transcribeChunks(files, updateNotice) { const transcriptions = new Array(files.length); let completedChunks = 0; const updateProgress = () => { const progress = (completedChunks / files.length * 100).toFixed(1); updateNotice(`Transcribing... ${completedChunks}/${files.length} chunks completed (${progress}%)`); }; updateProgress(); await Promise.all(files.map(async (file, index) => { let retries = 0; while (retries < this.MAX_RETRIES) { try { const result = await this.client.audio.transcriptions.create({ model: "whisper-1", file }); transcriptions[index] = result.text; completedChunks++; updateProgress(); break; } catch (error) { retries++; if (retries >= this.MAX_RETRIES) { console.error(`Failed to transcribe chunk ${index} after ${this.MAX_RETRIES} attempts:`, error); transcriptions[index] = `[Error transcribing chunk ${index}]`; completedChunks++; updateProgress(); } else { await new Promise((resolve) => setTimeout(resolve, 1e3 * retries)); } } } })); return transcriptions.join(" "); } async saveTranscription(episode, transcription) { const transcriptPath = FilePathTemplateEngine(this.plugin.settings.transcript.path, episode); const formattedTranscription = transcription.replace(/\.\s+/g, ".\n\n"); const transcriptContent = TranscriptTemplateEngine(this.plugin.settings.transcript.template, episode, formattedTranscription); const vault = this.plugin.app.vault; const directory = transcriptPath.substring(0, transcriptPath.lastIndexOf("/")); if (directory && !vault.getAbstractFileByPath(directory)) { await vault.createFolder(directory); } const file = vault.getAbstractFileByPath(transcriptPath); if (!file) { const newFile = await vault.create(transcriptPath, transcriptContent); await this.plugin.app.workspace.getLeaf().openFile(newFile); } else { throw new Error("Expected a file but got a folder"); } } }; // src/main.ts var PodNotes = class extends import_obsidian24.Plugin { constructor() { super(...arguments); this.maxLayoutReadyAttempts = 10; this.layoutReadyAttempts = 0; } async onload() { plugin.set(this); await this.loadSettings(); playedEpisodes.set(this.settings.playedEpisodes); savedFeeds.set(this.settings.savedFeeds); playlists.set(this.settings.playlists); queue.set(this.settings.queue); favorites.set(this.settings.favorites); localFiles.set(this.settings.localFiles); downloadedEpisodes.set(this.settings.downloadedEpisodes); if (this.settings.currentEpisode) { currentEpisode.set(this.settings.currentEpisode); } this.playedEpisodeController = new EpisodeStatusController(playedEpisodes, this).on(); this.savedFeedsController = new SavedFeedsController(savedFeeds, this).on(); this.playlistController = new PlaylistController(playlists, this).on(); this.queueController = new QueueController(queue, this).on(); this.favoritesController = new FavoritesController(favorites, this).on(); this.localFilesController = new LocalFilesController(localFiles, this).on(); this.downloadedEpisodesController = new DownloadedEpisodesController(downloadedEpisodes, this).on(); this.currentEpisodeController = new CurrentEpisodeController(currentEpisode, this).on(); this.transcriptionService = new TranscriptionService(this); this.addCommand({ id: "podnotes-show-leaf", name: "Show PodNotes", icon: "podcast", checkCallback: function(checking) { if (checking) { return !this.app.workspace.getLeavesOfType(VIEW_TYPE).length; } this.app.workspace.getRightLeaf(false).setViewState({ type: VIEW_TYPE }); }.bind(this) }); this.addCommand({ id: "start-playing", name: "Play Podcast", icon: "play-circle", checkCallback: (checking) => { if (checking) { return !this.api.isPlaying && !!this.api.podcast; } this.api.start(); } }); this.addCommand({ id: "stop-playing", name: "Stop Podcast", icon: "stop-circle", checkCallback: (checking) => { if (checking) { return this.api.isPlaying && !!this.api.podcast; } this.api.stop(); } }); this.addCommand({ id: "skip-backward", name: "Skip Backward", icon: "skip-back", checkCallback: (checking) => { if (checking) { return this.api.isPlaying && !!this.api.podcast; } this.api.skipBackward(); } }); this.addCommand({ id: "skip-forward", name: "Skip Forward", icon: "skip-forward", checkCallback: (checking) => { if (checking) { return this.api.isPlaying && !!this.api.podcast; } this.api.skipForward(); } }); this.addCommand({ id: "download-playing-episode", name: "Download Playing Episode", icon: "download", checkCallback: (checking) => { if (checking) { return !!this.api.podcast; } const episode = this.api.podcast; downloadEpisodeWithNotice(episode, this.settings.download.path); } }); this.addCommand({ id: "hrpn", name: "Reload PodNotes", callback: () => { const id = this.manifest.id; this.app.plugins.disablePlugin(id).then(() => this.app.plugins.enablePlugin(id)); } }); this.addCommand({ id: "capture-timestamp", name: "Capture Timestamp", icon: "clock", editorCheckCallback: (checking, editor, view) => { if (checking) { return !!this.api.podcast && !!this.settings.timestamp.template; } const cursorPos = editor.getCursor(); const capture = TimestampTemplateEngine(this.settings.timestamp.template); editor.replaceRange(capture, cursorPos); editor.setCursor(cursorPos.line, cursorPos.ch + capture.length); } }); this.addCommand({ id: "create-podcast-note", name: "Create Podcast Note", icon: "file-plus", checkCallback: (checking) => { if (checking) { return !!this.api.podcast && !!this.settings.note.path && !!this.settings.note.template; } createPodcastNote(this.api.podcast); } }); this.addCommand({ id: "get-share-link-episode", name: "Copy universal episode link to clipboard", icon: "share", checkCallback: (checking) => { if (checking) { return !!this.api.podcast; } getUniversalPodcastLink(this.api); } }); this.addCommand({ id: "podnotes-toggle-playback", name: "Toggle playback", icon: "play", checkCallback: (checking) => { if (checking) { return !!this.api.podcast; } this.api.togglePlayback(); } }); this.addCommand({ id: "podnotes-transcribe", name: "Transcribe current episode", callback: () => this.transcriptionService.transcribeCurrentEpisode() }); this.addSettingTab(new PodNotesSettingsTab(this.app, this)); this.registerView(VIEW_TYPE, (leaf) => { this.view = new MainView(leaf, this); this.api = new API(); return this.view; }); this.app.workspace.onLayoutReady(this.onLayoutReady.bind(this)); this.registerObsidianProtocolHandler("podnotes", (action) => podNotesURIHandler(action, this.api)); this.registerEvent(getContextMenuHandler()); } onLayoutReady() { if (!this.app.workspace || !this.app.workspace.layoutReady) { this.layoutReadyAttempts++; if (this.layoutReadyAttempts < this.maxLayoutReadyAttempts) { setTimeout(() => this.onLayoutReady(), 100); } else { console.error("Failed to initialize PodNotes layout after maximum attempts"); } return; } if (this.app.workspace.getLeavesOfType(VIEW_TYPE).length) { return; } const leaf = this.app.workspace.getRightLeaf(false); if (leaf) { leaf.setViewState({ type: VIEW_TYPE }); } } onunload() { this?.playedEpisodeController.off(); this?.savedFeedsController.off(); this?.playlistController.off(); this?.queueController.off(); this?.favoritesController.off(); this?.localFilesController.off(); this?.downloadedEpisodesController.off(); this?.currentEpisodeController.off(); } async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); } async saveSettings() { await this.saveData(this.settings); } }; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */