// packages/block-library/build-module/playlist/view.mjs
import { store, getContext, getElement } from "@wordpress/interactivity";

// node_modules/colord/index.mjs
var r = { grad: 0.9, turn: 360, rad: 360 / (2 * Math.PI) };
var t = function(r2) {
  return "string" == typeof r2 ? r2.length > 0 : "number" == typeof r2;
};
var n = function(r2, t3, n2) {
  return void 0 === t3 && (t3 = 0), void 0 === n2 && (n2 = Math.pow(10, t3)), Math.round(n2 * r2) / n2 + 0;
};
var e = function(r2, t3, n2) {
  return void 0 === t3 && (t3 = 0), void 0 === n2 && (n2 = 1), r2 > n2 ? n2 : r2 > t3 ? r2 : t3;
};
var u = function(r2) {
  return (r2 = isFinite(r2) ? r2 % 360 : 0) > 0 ? r2 : r2 + 360;
};
var a = function(r2) {
  return { r: e(r2.r, 0, 255), g: e(r2.g, 0, 255), b: e(r2.b, 0, 255), a: e(r2.a) };
};
var o = function(r2) {
  return { r: n(r2.r), g: n(r2.g), b: n(r2.b), a: n(r2.a, 3) };
};
var i = /^#([0-9a-f]{3,8})$/i;
var s = function(r2) {
  var t3 = r2.toString(16);
  return t3.length < 2 ? "0" + t3 : t3;
};
var h = function(r2) {
  var t3 = r2.r, n2 = r2.g, e2 = r2.b, u2 = r2.a, a2 = Math.max(t3, n2, e2), o2 = a2 - Math.min(t3, n2, e2), i2 = o2 ? a2 === t3 ? (n2 - e2) / o2 : a2 === n2 ? 2 + (e2 - t3) / o2 : 4 + (t3 - n2) / o2 : 0;
  return { h: 60 * (i2 < 0 ? i2 + 6 : i2), s: a2 ? o2 / a2 * 100 : 0, v: a2 / 255 * 100, a: u2 };
};
var b = function(r2) {
  var t3 = r2.h, n2 = r2.s, e2 = r2.v, u2 = r2.a;
  t3 = t3 / 360 * 6, n2 /= 100, e2 /= 100;
  var a2 = Math.floor(t3), o2 = e2 * (1 - n2), i2 = e2 * (1 - (t3 - a2) * n2), s2 = e2 * (1 - (1 - t3 + a2) * n2), h2 = a2 % 6;
  return { r: 255 * [e2, i2, o2, o2, s2, e2][h2], g: 255 * [s2, e2, e2, i2, o2, o2][h2], b: 255 * [o2, o2, s2, e2, e2, i2][h2], a: u2 };
};
var g = function(r2) {
  return { h: u(r2.h), s: e(r2.s, 0, 100), l: e(r2.l, 0, 100), a: e(r2.a) };
};
var d = function(r2) {
  return { h: n(r2.h), s: n(r2.s), l: n(r2.l), a: n(r2.a, 3) };
};
var f = function(r2) {
  return b((n2 = (t3 = r2).s, { h: t3.h, s: (n2 *= ((e2 = t3.l) < 50 ? e2 : 100 - e2) / 100) > 0 ? 2 * n2 / (e2 + n2) * 100 : 0, v: e2 + n2, a: t3.a }));
  var t3, n2, e2;
};
var c = function(r2) {
  return { h: (t3 = h(r2)).h, s: (u2 = (200 - (n2 = t3.s)) * (e2 = t3.v) / 100) > 0 && u2 < 200 ? n2 * e2 / 100 / (u2 <= 100 ? u2 : 200 - u2) * 100 : 0, l: u2 / 2, a: t3.a };
  var t3, n2, e2, u2;
};
var l = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
var p = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
var v = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
var m = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
var y = { string: [[function(r2) {
  var t3 = i.exec(r2);
  return t3 ? (r2 = t3[1]).length <= 4 ? { r: parseInt(r2[0] + r2[0], 16), g: parseInt(r2[1] + r2[1], 16), b: parseInt(r2[2] + r2[2], 16), a: 4 === r2.length ? n(parseInt(r2[3] + r2[3], 16) / 255, 2) : 1 } : 6 === r2.length || 8 === r2.length ? { r: parseInt(r2.substr(0, 2), 16), g: parseInt(r2.substr(2, 2), 16), b: parseInt(r2.substr(4, 2), 16), a: 8 === r2.length ? n(parseInt(r2.substr(6, 2), 16) / 255, 2) : 1 } : null : null;
}, "hex"], [function(r2) {
  var t3 = v.exec(r2) || m.exec(r2);
  return t3 ? t3[2] !== t3[4] || t3[4] !== t3[6] ? null : a({ r: Number(t3[1]) / (t3[2] ? 100 / 255 : 1), g: Number(t3[3]) / (t3[4] ? 100 / 255 : 1), b: Number(t3[5]) / (t3[6] ? 100 / 255 : 1), a: void 0 === t3[7] ? 1 : Number(t3[7]) / (t3[8] ? 100 : 1) }) : null;
}, "rgb"], [function(t3) {
  var n2 = l.exec(t3) || p.exec(t3);
  if (!n2) return null;
  var e2, u2, a2 = g({ h: (e2 = n2[1], u2 = n2[2], void 0 === u2 && (u2 = "deg"), Number(e2) * (r[u2] || 1)), s: Number(n2[3]), l: Number(n2[4]), a: void 0 === n2[5] ? 1 : Number(n2[5]) / (n2[6] ? 100 : 1) });
  return f(a2);
}, "hsl"]], object: [[function(r2) {
  var n2 = r2.r, e2 = r2.g, u2 = r2.b, o2 = r2.a, i2 = void 0 === o2 ? 1 : o2;
  return t(n2) && t(e2) && t(u2) ? a({ r: Number(n2), g: Number(e2), b: Number(u2), a: Number(i2) }) : null;
}, "rgb"], [function(r2) {
  var n2 = r2.h, e2 = r2.s, u2 = r2.l, a2 = r2.a, o2 = void 0 === a2 ? 1 : a2;
  if (!t(n2) || !t(e2) || !t(u2)) return null;
  var i2 = g({ h: Number(n2), s: Number(e2), l: Number(u2), a: Number(o2) });
  return f(i2);
}, "hsl"], [function(r2) {
  var n2 = r2.h, a2 = r2.s, o2 = r2.v, i2 = r2.a, s2 = void 0 === i2 ? 1 : i2;
  if (!t(n2) || !t(a2) || !t(o2)) return null;
  var h2 = (function(r3) {
    return { h: u(r3.h), s: e(r3.s, 0, 100), v: e(r3.v, 0, 100), a: e(r3.a) };
  })({ h: Number(n2), s: Number(a2), v: Number(o2), a: Number(s2) });
  return b(h2);
}, "hsv"]] };
var N = function(r2, t3) {
  for (var n2 = 0; n2 < t3.length; n2++) {
    var e2 = t3[n2][0](r2);
    if (e2) return [e2, t3[n2][1]];
  }
  return [null, void 0];
};
var x = function(r2) {
  return "string" == typeof r2 ? N(r2.trim(), y.string) : "object" == typeof r2 && null !== r2 ? N(r2, y.object) : [null, void 0];
};
var M = function(r2, t3) {
  var n2 = c(r2);
  return { h: n2.h, s: e(n2.s + 100 * t3, 0, 100), l: n2.l, a: n2.a };
};
var H = function(r2) {
  return (299 * r2.r + 587 * r2.g + 114 * r2.b) / 1e3 / 255;
};
var $ = function(r2, t3) {
  var n2 = c(r2);
  return { h: n2.h, s: n2.s, l: e(n2.l + 100 * t3, 0, 100), a: n2.a };
};
var j = (function() {
  function r2(r3) {
    this.parsed = x(r3)[0], this.rgba = this.parsed || { r: 0, g: 0, b: 0, a: 1 };
  }
  return r2.prototype.isValid = function() {
    return null !== this.parsed;
  }, r2.prototype.brightness = function() {
    return n(H(this.rgba), 2);
  }, r2.prototype.isDark = function() {
    return H(this.rgba) < 0.5;
  }, r2.prototype.isLight = function() {
    return H(this.rgba) >= 0.5;
  }, r2.prototype.toHex = function() {
    return r3 = o(this.rgba), t3 = r3.r, e2 = r3.g, u2 = r3.b, i2 = (a2 = r3.a) < 1 ? s(n(255 * a2)) : "", "#" + s(t3) + s(e2) + s(u2) + i2;
    var r3, t3, e2, u2, a2, i2;
  }, r2.prototype.toRgb = function() {
    return o(this.rgba);
  }, r2.prototype.toRgbString = function() {
    return r3 = o(this.rgba), t3 = r3.r, n2 = r3.g, e2 = r3.b, (u2 = r3.a) < 1 ? "rgba(" + t3 + ", " + n2 + ", " + e2 + ", " + u2 + ")" : "rgb(" + t3 + ", " + n2 + ", " + e2 + ")";
    var r3, t3, n2, e2, u2;
  }, r2.prototype.toHsl = function() {
    return d(c(this.rgba));
  }, r2.prototype.toHslString = function() {
    return r3 = d(c(this.rgba)), t3 = r3.h, n2 = r3.s, e2 = r3.l, (u2 = r3.a) < 1 ? "hsla(" + t3 + ", " + n2 + "%, " + e2 + "%, " + u2 + ")" : "hsl(" + t3 + ", " + n2 + "%, " + e2 + "%)";
    var r3, t3, n2, e2, u2;
  }, r2.prototype.toHsv = function() {
    return r3 = h(this.rgba), { h: n(r3.h), s: n(r3.s), v: n(r3.v), a: n(r3.a, 3) };
    var r3;
  }, r2.prototype.invert = function() {
    return w({ r: 255 - (r3 = this.rgba).r, g: 255 - r3.g, b: 255 - r3.b, a: r3.a });
    var r3;
  }, r2.prototype.saturate = function(r3) {
    return void 0 === r3 && (r3 = 0.1), w(M(this.rgba, r3));
  }, r2.prototype.desaturate = function(r3) {
    return void 0 === r3 && (r3 = 0.1), w(M(this.rgba, -r3));
  }, r2.prototype.grayscale = function() {
    return w(M(this.rgba, -1));
  }, r2.prototype.lighten = function(r3) {
    return void 0 === r3 && (r3 = 0.1), w($(this.rgba, r3));
  }, r2.prototype.darken = function(r3) {
    return void 0 === r3 && (r3 = 0.1), w($(this.rgba, -r3));
  }, r2.prototype.rotate = function(r3) {
    return void 0 === r3 && (r3 = 15), this.hue(this.hue() + r3);
  }, r2.prototype.alpha = function(r3) {
    return "number" == typeof r3 ? w({ r: (t3 = this.rgba).r, g: t3.g, b: t3.b, a: r3 }) : n(this.rgba.a, 3);
    var t3;
  }, r2.prototype.hue = function(r3) {
    var t3 = c(this.rgba);
    return "number" == typeof r3 ? w({ h: r3, s: t3.s, l: t3.l, a: t3.a }) : n(t3.h);
  }, r2.prototype.isEqual = function(r3) {
    return this.toHex() === w(r3).toHex();
  }, r2;
})();
var w = function(r2) {
  return r2 instanceof j ? r2 : new j(r2);
};

// packages/block-library/node_modules/@arraypress/waveform-player/dist/waveform-player.esm.js
function L(t3) {
  let e2 = {};
  if (t3.dataset.url && (e2.url = t3.dataset.url), t3.dataset.height && (e2.height = parseInt(t3.dataset.height)), t3.dataset.samples && (e2.samples = parseInt(t3.dataset.samples)), t3.dataset.preload && (e2.preload = t3.dataset.preload), t3.dataset.waveformStyle && (e2.waveformStyle = t3.dataset.waveformStyle), t3.dataset.barWidth && (e2.barWidth = parseInt(t3.dataset.barWidth)), t3.dataset.barSpacing && (e2.barSpacing = parseInt(t3.dataset.barSpacing)), t3.dataset.buttonAlign && (e2.buttonAlign = t3.dataset.buttonAlign), t3.dataset.colorPreset && (e2.colorPreset = t3.dataset.colorPreset), t3.dataset.waveformColor && (e2.waveformColor = t3.dataset.waveformColor), t3.dataset.progressColor && (e2.progressColor = t3.dataset.progressColor), t3.dataset.buttonColor && (e2.buttonColor = t3.dataset.buttonColor), t3.dataset.buttonHoverColor && (e2.buttonHoverColor = t3.dataset.buttonHoverColor), t3.dataset.textColor && (e2.textColor = t3.dataset.textColor), t3.dataset.textSecondaryColor && (e2.textSecondaryColor = t3.dataset.textSecondaryColor), t3.dataset.backgroundColor && (e2.backgroundColor = t3.dataset.backgroundColor), t3.dataset.borderColor && (e2.borderColor = t3.dataset.borderColor), t3.dataset.color && (e2.waveformColor = t3.dataset.color), t3.dataset.theme && (e2.colorPreset = t3.dataset.theme), t3.dataset.autoplay && (e2.autoplay = t3.dataset.autoplay === "true"), t3.dataset.showTime && (e2.showTime = t3.dataset.showTime === "true"), t3.dataset.showHoverTime && (e2.showHoverTime = t3.dataset.showHoverTime === "true"), t3.dataset.showBpm && (e2.showBPM = t3.dataset.showBpm === "true"), t3.dataset.singlePlay && (e2.singlePlay = t3.dataset.singlePlay === "true"), t3.dataset.playOnSeek && (e2.playOnSeek = t3.dataset.playOnSeek === "true"), t3.dataset.title && (e2.title = t3.dataset.title), t3.dataset.subtitle && (e2.subtitle = t3.dataset.subtitle), t3.dataset.album && (e2.album = t3.dataset.album), t3.dataset.artwork && (e2.artwork = t3.dataset.artwork), t3.dataset.waveform && (e2.waveform = t3.dataset.waveform), t3.dataset.markers) try {
    e2.markers = JSON.parse(t3.dataset.markers);
  } catch (i2) {
    console.warn("Invalid markers JSON:", i2);
  }
  if (t3.dataset.playbackRate && (e2.playbackRate = parseFloat(t3.dataset.playbackRate)), t3.dataset.showPlaybackSpeed !== void 0 && (e2.showPlaybackSpeed = t3.dataset.showPlaybackSpeed === "true"), t3.dataset.playbackRates) try {
    e2.playbackRates = JSON.parse(t3.dataset.playbackRates);
  } catch (i2) {
    console.warn("Invalid playbackRates JSON:", i2);
  }
  return t3.dataset.enableMediaSession !== void 0 && (e2.enableMediaSession = t3.dataset.enableMediaSession === "true"), e2;
}
function P(t3) {
  if (!t3 || isNaN(t3)) return "0:00";
  let e2 = Math.floor(t3 / 60), i2 = Math.floor(t3 % 60);
  return `${e2}:${i2.toString().padStart(2, "0")}`;
}
function A(t3) {
  let e2 = t3 || Math.random().toString();
  return btoa(e2.substring(0, 10)).replace(/[^a-zA-Z0-9]/g, "");
}
function R(t3) {
  if (!t3) return "Audio";
  let e2 = t3.split("/");
  return e2[e2.length - 1].split(".")[0].replace(/[-_]/g, " ").replace(/\b\w/g, (s2) => s2.toUpperCase());
}
function C(...t3) {
  let e2 = {};
  for (let i2 of t3) for (let a2 in i2) i2[a2] !== null && i2[a2] !== void 0 && (e2[a2] = i2[a2]);
  return e2;
}
function B(t3, e2) {
  let i2;
  return function(...s2) {
    let n2 = () => {
      clearTimeout(i2), t3(...s2);
    };
    clearTimeout(i2), i2 = setTimeout(n2, e2);
  };
}
function S(t3, e2) {
  if (t3.length === e2) return t3;
  if (t3.length === 0 || e2 === 0) return [];
  let i2 = [];
  if (e2 > t3.length) {
    let a2 = (t3.length - 1) / (e2 - 1);
    for (let s2 = 0; s2 < e2; s2++) {
      let n2 = s2 * a2, r2 = Math.floor(n2), o2 = Math.ceil(n2), h2 = n2 - r2;
      if (o2 >= t3.length) i2.push(t3[t3.length - 1]);
      else if (r2 === o2) i2.push(t3[r2]);
      else {
        let l2 = t3[r2] * (1 - h2) + t3[o2] * h2;
        i2.push(l2);
      }
    }
  } else {
    let a2 = t3.length / e2;
    for (let s2 = 0; s2 < e2; s2++) {
      let n2 = Math.floor(s2 * a2), r2 = Math.floor((s2 + 1) * a2), o2 = 0, h2 = 0;
      for (let l2 = n2; l2 <= r2 && l2 < t3.length; l2++) t3[l2] > o2 && (o2 = t3[l2]), h2++;
      if (h2 === 0) {
        let l2 = Math.min(Math.round(s2 * a2), t3.length - 1);
        o2 = t3[l2];
      }
      i2.push(o2);
    }
  }
  return i2;
}
function x2(t3, e2, i2, a2, s2) {
  let n2 = window.devicePixelRatio || 1, r2 = s2.barWidth * n2, o2 = s2.barSpacing * n2, h2 = Math.floor(e2.width / (r2 + o2)), l2 = S(i2, h2), d2 = e2.height, p2 = a2 * e2.width;
  t3.clearRect(0, 0, e2.width, e2.height);
  for (let y2 = 0; y2 < l2.length; y2++) {
    let f2 = y2 * (r2 + o2);
    if (f2 + r2 > e2.width) break;
    let c2 = l2[y2] * d2 * 0.9, m2 = d2 - c2;
    t3.fillStyle = s2.color, t3.fillRect(f2, m2, r2, c2);
  }
  t3.save(), t3.beginPath(), t3.rect(0, 0, p2, d2), t3.clip();
  for (let y2 = 0; y2 < l2.length; y2++) {
    let f2 = y2 * (r2 + o2);
    if (f2 > p2) break;
    let c2 = l2[y2] * d2 * 0.9, m2 = d2 - c2;
    t3.fillStyle = s2.progressColor, t3.fillRect(f2, m2, r2, c2);
  }
  t3.restore();
}
function q(t3, e2, i2, a2, s2) {
  let n2 = window.devicePixelRatio || 1, r2 = s2.barWidth * n2, o2 = s2.barSpacing * n2, h2 = Math.floor(e2.width / (r2 + o2)), l2 = S(i2, h2), d2 = e2.height, p2 = d2 / 2, y2 = a2 * e2.width;
  t3.clearRect(0, 0, e2.width, e2.height);
  for (let f2 = 0; f2 < l2.length; f2++) {
    let c2 = f2 * (r2 + o2);
    if (c2 + r2 > e2.width) break;
    let m2 = l2[f2] * d2 * 0.45;
    t3.fillStyle = s2.color, t3.fillRect(c2, p2 - m2, r2, m2), t3.fillRect(c2, p2, r2, m2);
  }
  t3.save(), t3.beginPath(), t3.rect(0, 0, y2, d2), t3.clip();
  for (let f2 = 0; f2 < l2.length; f2++) {
    let c2 = f2 * (r2 + o2);
    if (c2 > y2) break;
    let m2 = l2[f2] * d2 * 0.45;
    t3.fillStyle = s2.progressColor, t3.fillRect(c2, p2 - m2, r2, m2), t3.fillRect(c2, p2, r2, m2);
  }
  t3.restore();
}
function $2(t3, e2, i2, a2, s2) {
  let n2 = e2.width, r2 = e2.height, o2 = r2 / 2, h2 = r2 * 0.35;
  t3.clearRect(0, 0, n2, r2);
  let l2 = (d2, p2, y2 = 1, f2 = false) => {
    f2 && (t3.shadowBlur = 12, t3.shadowColor = d2), t3.strokeStyle = d2, t3.lineWidth = p2, t3.lineCap = "round", t3.lineJoin = "round", t3.beginPath(), t3.moveTo(0, o2);
    let c2 = [], m2 = Math.floor(i2.length * y2);
    for (let u2 = 0; u2 < m2; u2++) {
      let v2 = u2 / (i2.length - 1) * n2, k = i2[u2], b2 = Math.sin(u2 * 0.1) * k, w2 = o2 + b2 * h2;
      c2.push({ x: v2, y: w2 });
    }
    for (let u2 = 0; u2 < c2.length - 1; u2++) {
      let v2 = c2[u2].x + (c2[u2 + 1].x - c2[u2].x) * 0.5, k = c2[u2].y, b2 = c2[u2 + 1].x - (c2[u2 + 1].x - c2[u2].x) * 0.5, w2 = c2[u2 + 1].y;
      t3.bezierCurveTo(v2, k, b2, w2, c2[u2 + 1].x, c2[u2 + 1].y);
    }
    t3.stroke(), f2 && (t3.shadowBlur = 0);
  };
  t3.strokeStyle = "rgba(255, 255, 255, 0.03)", t3.lineWidth = 0.5, t3.beginPath(), t3.moveTo(0, o2), t3.lineTo(n2, o2), t3.stroke();
  for (let d2 = 0; d2 <= 10; d2++) {
    let p2 = n2 / 10 * d2;
    t3.beginPath(), t3.moveTo(p2, 0), t3.lineTo(p2, r2), t3.stroke();
  }
  l2(s2.color, 2, 1, false), a2 > 0 && l2(s2.progressColor, 3, a2, true);
}
function U(t3, e2, i2, a2, s2) {
  let n2 = window.devicePixelRatio || 1, r2 = (s2.barWidth || 3) * n2, o2 = (s2.barSpacing || 1) * n2, h2 = Math.floor(e2.width / (r2 + o2)), l2 = S(i2, h2), d2 = e2.height, p2 = 4 * n2, y2 = 2 * n2, f2 = a2 * e2.width, c2 = d2 / 2;
  t3.clearRect(0, 0, e2.width, e2.height);
  for (let m2 = 0; m2 < l2.length; m2++) {
    let u2 = m2 * (r2 + o2);
    if (u2 + r2 > e2.width) break;
    let v2 = l2[m2] * d2 * 0.9, k = Math.floor(v2 / (p2 + y2));
    t3.fillStyle = u2 < f2 ? s2.progressColor : s2.color;
    for (let b2 = 0; b2 < k; b2++) {
      let w2 = b2 * (p2 + y2);
      t3.fillRect(u2, c2 - w2 - p2, r2, p2), b2 > 0 && t3.fillRect(u2, c2 + w2, r2, p2);
    }
  }
}
function F(t3, e2, i2, a2, s2) {
  let n2 = window.devicePixelRatio || 1, r2 = (s2.barWidth || 2) * n2, o2 = (s2.barSpacing || 3) * n2, h2 = Math.floor(e2.width / (r2 + o2)), l2 = S(i2, h2), d2 = e2.height, p2 = Math.max(1.5 * n2, r2 / 2), y2 = a2 * e2.width, f2 = d2 / 2;
  t3.clearRect(0, 0, e2.width, e2.height);
  for (let c2 = 0; c2 < l2.length; c2++) {
    let m2 = c2 * (r2 + o2) + r2 / 2;
    if (m2 > e2.width) break;
    let u2 = l2[c2] * d2 * 0.9;
    t3.fillStyle = m2 < y2 ? s2.progressColor : s2.color, t3.beginPath(), t3.arc(m2, f2 - u2 / 2, p2, 0, Math.PI * 2), t3.fill(), t3.beginPath(), t3.arc(m2, f2 + u2 / 2, p2, 0, Math.PI * 2), t3.fill();
  }
}
function N2(t3, e2, i2, a2, s2) {
  let n2 = e2.width, r2 = e2.height, o2 = r2 / 2, h2 = 4, l2 = h2 / 2;
  if (t3.clearRect(0, 0, n2, r2), t3.fillStyle = s2.color || "rgba(255, 255, 255, 0.2)", t3.beginPath(), t3.moveTo(l2, o2 - h2 / 2), t3.lineTo(n2 - l2, o2 - h2 / 2), t3.arc(n2 - l2, o2, h2 / 2, -Math.PI / 2, Math.PI / 2), t3.lineTo(l2, o2 + h2 / 2), t3.arc(l2, o2, h2 / 2, Math.PI / 2, -Math.PI / 2), t3.closePath(), t3.fill(), a2 > 0) {
    let d2 = Math.max(l2 * 2, a2 * n2);
    t3.shadowBlur = 8, t3.shadowColor = s2.progressColor, t3.fillStyle = s2.progressColor || "rgba(255, 255, 255, 0.9)", t3.beginPath(), t3.moveTo(l2, o2 - h2 / 2), t3.lineTo(d2 - l2, o2 - h2 / 2), t3.arc(d2 - l2, o2, h2 / 2, -Math.PI / 2, Math.PI / 2), t3.lineTo(l2, o2 + h2 / 2), t3.arc(l2, o2, h2 / 2, Math.PI / 2, -Math.PI / 2), t3.closePath(), t3.fill(), t3.shadowBlur = 0;
    let p2 = 8, y2 = d2;
    t3.shadowBlur = 4, t3.shadowColor = "rgba(0, 0, 0, 0.3)", t3.shadowOffsetY = 2, t3.fillStyle = "#ffffff", t3.beginPath(), t3.arc(y2, o2, p2, 0, Math.PI * 2), t3.fill(), t3.shadowBlur = 0, t3.shadowOffsetY = 0, t3.fillStyle = s2.progressColor || "rgba(255, 255, 255, 0.9)", t3.beginPath(), t3.arc(y2, o2, p2 * 0.4, 0, Math.PI * 2), t3.fill();
  }
}
var Y = { bars: x2, mirror: q, line: $2, blocks: U, dots: F, seekbar: N2 };
function W(t3, e2, i2, a2, s2) {
  (Y[s2.waveformStyle] || x2)(t3, e2, i2, a2, s2);
}
function I(t3) {
  try {
    let e2 = t3.getChannelData(0), i2 = t3.sampleRate, a2 = j2(e2, i2);
    if (a2.length < 2) return 120;
    let s2 = [];
    for (let h2 = 1; h2 < a2.length; h2++) s2.push((a2[h2] - a2[h2 - 1]) / i2);
    let n2 = {};
    s2.forEach((h2) => {
      let l2 = 60 / h2, d2 = Math.round(l2 / 3) * 3;
      d2 > 60 && d2 < 200 && (n2[d2] = (n2[d2] || 0) + 1);
    });
    let r2 = 0, o2 = 120;
    for (let [h2, l2] of Object.entries(n2)) l2 > r2 && (r2 = l2, o2 = parseInt(h2));
    return o2 < 70 && n2[o2 * 2] ? o2 *= 2 : o2 > 160 && n2[Math.round(o2 / 2)] && (o2 = Math.round(o2 / 2)), o2 - 1;
  } catch (e2) {
    return console.warn("BPM detection failed:", e2), null;
  }
}
function j2(t3, e2) {
  let s2 = [], n2 = 0;
  for (let r2 = 0; r2 < t3.length - 2048; r2 += 1024) {
    let o2 = 0;
    for (let d2 = r2; d2 < r2 + 2048; d2++) o2 += t3[d2] * t3[d2];
    o2 = o2 / 2048;
    let h2 = o2 - n2, l2 = n2 * 1.8 + 0.01;
    if (h2 > l2 && o2 > 0.01) {
      let d2 = s2[s2.length - 1] || 0, p2 = e2 * 0.15;
      r2 - d2 > p2 && s2.push(r2);
    }
    n2 = o2 * 0.8 + n2 * 0.2;
  }
  return s2;
}
function V(t3, e2 = 200) {
  let i2 = t3.length / e2, a2 = ~~(i2 / 10) || 1, s2 = t3.numberOfChannels, n2 = [];
  for (let o2 = 0; o2 < s2; o2++) {
    let h2 = t3.getChannelData(o2);
    for (let l2 = 0; l2 < e2; l2++) {
      let d2 = ~~(l2 * i2), p2 = ~~(d2 + i2), y2 = 0, f2 = 0;
      for (let m2 = d2; m2 < p2; m2 += a2) {
        let u2 = h2[m2];
        u2 > f2 && (f2 = u2), u2 < y2 && (y2 = u2);
      }
      let c2 = Math.max(Math.abs(f2), Math.abs(y2));
      (o2 === 0 || c2 > n2[l2]) && (n2[l2] = c2);
    }
  }
  let r2 = Math.max(...n2);
  return r2 > 0 ? n2.map((o2) => o2 / r2) : n2;
}
async function M2(t3, e2 = 200, i2 = false) {
  try {
    let a2 = new (window.AudioContext || window.webkitAudioContext)(), n2 = await (await fetch(t3)).arrayBuffer(), r2 = await a2.decodeAudioData(n2), o2 = V(r2, e2);
    o2 = J(o2);
    let h2 = null;
    return i2 && (h2 = await I(r2)), a2.close(), { peaks: o2, bpm: h2 };
  } catch (a2) {
    throw console.error("Failed to generate waveform:", a2), a2;
  }
}
function D(t3 = 200) {
  let e2 = [];
  for (let i2 = 0; i2 < t3; i2++) {
    let a2 = Math.random() * 0.5 + 0.3, s2 = Math.sin(i2 / t3 * Math.PI * 4) * 0.2;
    e2.push(Math.max(0.1, Math.min(1, a2 + s2)));
  }
  return e2;
}
function J(t3, e2 = 0.95) {
  let i2 = Math.max(...t3);
  if (i2 === 0 || i2 > e2) return t3;
  let a2 = e2 / i2;
  return t3.map((s2) => s2 * a2);
}
function G() {
  let t3 = document.documentElement, e2 = document.body;
  if (t3.classList.contains("dark") || t3.classList.contains("dark-mode") || t3.classList.contains("theme-dark") || t3.getAttribute("data-theme") === "dark" || t3.getAttribute("data-color-scheme") === "dark" || e2.classList.contains("dark") || e2.classList.contains("dark-mode") || e2.getAttribute("data-theme") === "dark") return "dark";
  if (t3.classList.contains("light") || t3.classList.contains("light-mode") || t3.classList.contains("theme-light") || t3.getAttribute("data-theme") === "light" || t3.getAttribute("data-color-scheme") === "light" || e2.classList.contains("light") || e2.classList.contains("light-mode") || e2.getAttribute("data-theme") === "light") return "light";
  try {
    let a2 = getComputedStyle(document.body).backgroundColor.match(/\d+/g);
    if (a2 && a2.length >= 3) {
      let [s2, n2, r2] = a2.map(Number), o2 = (s2 * 299 + n2 * 587 + r2 * 114) / 1e3;
      if (o2 > 128) return "light";
      if (o2 < 128) return "dark";
    }
  } catch {
  }
  if (window.matchMedia) {
    if (window.matchMedia("(prefers-color-scheme: dark)").matches) return "dark";
    if (window.matchMedia("(prefers-color-scheme: light)").matches) return "light";
  }
  return "dark";
}
var E = { dark: { waveformColor: "rgba(255, 255, 255, 0.3)", progressColor: "rgba(255, 255, 255, 0.9)", buttonColor: "rgba(255, 255, 255, 0.9)", buttonHoverColor: "rgba(255, 255, 255, 1)", textColor: "#ffffff", textSecondaryColor: "rgba(255, 255, 255, 0.6)", backgroundColor: "rgba(255, 255, 255, 0.03)", borderColor: "rgba(255, 255, 255, 0.1)" }, light: { waveformColor: "rgba(0, 0, 0, 0.2)", progressColor: "rgba(0, 0, 0, 0.8)", buttonColor: "rgba(0, 0, 0, 0.8)", buttonHoverColor: "rgba(0, 0, 0, 0.9)", textColor: "#333333", textSecondaryColor: "rgba(0, 0, 0, 0.6)", backgroundColor: "rgba(0, 0, 0, 0.02)", borderColor: "rgba(0, 0, 0, 0.1)" } };
function z(t3) {
  if (t3 && E[t3]) return E[t3];
  let e2 = G();
  return E[e2];
}
var O = { url: "", height: 60, samples: 200, preload: "metadata", playbackRate: 1, showPlaybackSpeed: false, playbackRates: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], buttonAlign: "auto", waveformStyle: "mirror", barWidth: 2, barSpacing: 0, colorPreset: null, waveformColor: null, progressColor: null, buttonColor: null, buttonHoverColor: null, textColor: null, textSecondaryColor: null, backgroundColor: null, borderColor: null, autoplay: false, showTime: true, showHoverTime: false, showBPM: false, singlePlay: true, playOnSeek: true, enableMediaSession: true, markers: [], showMarkers: true, title: null, subtitle: null, artwork: null, album: "", playIcon: '<svg viewBox="0 0 24 24" width="16" height="16"><path d="M8 5v14l11-7z"/></svg>', pauseIcon: '<svg viewBox="0 0 24 24" width="16" height="16"><path d="M6 4h4v16H6zM14 4h4v16h-4z"/></svg>', onLoad: null, onPlay: null, onPause: null, onEnd: null, onError: null, onTimeUpdate: null };
var H2 = { bars: { barWidth: 3, barSpacing: 1 }, mirror: { barWidth: 2, barSpacing: 0 }, line: { barWidth: 2, barSpacing: 0 }, blocks: { barWidth: 4, barSpacing: 2 }, dots: { barWidth: 3, barSpacing: 3 }, seekbar: { barWidth: 1, barSpacing: 0 } };
var g2 = class t2 {
  static instances = /* @__PURE__ */ new Map();
  static currentlyPlaying = null;
  constructor(e2, i2 = {}) {
    if (this.container = typeof e2 == "string" ? document.querySelector(e2) : e2, !this.container) throw new Error("WaveformPlayer: Container element not found");
    let a2 = L(this.container);
    this.options = C(O, a2, i2);
    let s2 = z(this.options.colorPreset);
    for (let [r2, o2] of Object.entries(s2)) (this.options[r2] === null || this.options[r2] === void 0) && (this.options[r2] = o2);
    let n2 = H2[this.options.waveformStyle];
    n2 && (a2.barWidth === void 0 && i2.barWidth === void 0 && (this.options.barWidth = n2.barWidth), a2.barSpacing === void 0 && i2.barSpacing === void 0 && (this.options.barSpacing = n2.barSpacing)), this.audio = null, this.canvas = null, this.ctx = null, this.waveformData = [], this.progress = 0, this.isPlaying = false, this.isLoading = false, this.hasError = false, this.updateTimer = null, this.resizeObserver = null, this.id = this.container.id || A(this.options.url), t2.instances.set(this.id, this), this.init(), setTimeout(() => {
      this.container.dispatchEvent(new CustomEvent("waveformplayer:ready", { bubbles: true, detail: { player: this, url: this.options.url } }));
    }, 100);
  }
  init() {
    this.createDOM(), this.createAudio(), this.initPlaybackSpeed(), this.initKeyboardControls(), this.bindEvents(), this.setupResizeObserver(), requestAnimationFrame(() => {
      this.resizeCanvas(), this.options.url && this.load(this.options.url).then(() => {
        this.options.autoplay && this.play();
      }).catch((e2) => {
        console.error("Failed to load audio:", e2);
      });
    });
  }
  createDOM() {
    this.container.innerHTML = "", this.container.className = "waveform-player";
    let e2 = this.options.buttonAlign;
    e2 === "auto" && (this.options.waveformStyle === "bars" ? e2 = "bottom" : e2 = "center"), this.container.innerHTML = `
  <div class="waveform-player-inner">
    <div class="waveform-body">
      <div class="waveform-track waveform-align-${e2}">
        <button class="waveform-btn" aria-label="Play/Pause" style="
            border-color: ${this.options.buttonColor};
            color: ${this.options.buttonColor};
        ">
          <span class="waveform-icon-play">${this.options.playIcon}</span>
          <span class="waveform-icon-pause" style="display:none;">${this.options.pauseIcon}</span>
        </button>
        
        <div class="waveform-container">
          <canvas></canvas>
          <div class="waveform-markers"></div>
          <div class="waveform-loading" style="display:none;"></div>
          <div class="waveform-error" style="display:none;">
            <span class="waveform-error-text">Unable to load audio</span>
          </div>
        </div>
      </div>
      
      <div class="waveform-info">
        ${this.options.artwork ? `
          <img class="waveform-artwork" src="${this.options.artwork}" alt="Album artwork" style="
            width: 40px;
            height: 40px;
            border-radius: 4px;
            object-fit: cover;
            flex-shrink: 0;
          ">
        ` : ""}
        <div class="waveform-text">
          <span class="waveform-title" style="color: ${this.options.textColor};"></span>
          ${this.options.subtitle ? `<span class="waveform-subtitle" style="color: ${this.options.textSecondaryColor};">${this.options.subtitle}</span>` : ""}
        </div>
        <div style="display: flex; align-items: center; gap: 1rem;">
          ${this.options.showBPM ? `
            <span class="waveform-bpm" style="color: ${this.options.textSecondaryColor}; display: none;">
              <span class="bpm-value">--</span> BPM
            </span>
          ` : ""}
          ${this.options.showPlaybackSpeed ? `
            <div class="waveform-speed">
              <button class="speed-btn" aria-label="Playback speed">
                <span class="speed-value">1x</span>
              </button>
              <div class="speed-menu" style="display: none;">
                ${this.options.playbackRates.map((i2) => `<button class="speed-option" data-rate="${i2}">${i2}x</button>`).join("")}
              </div>
            </div>
          ` : ""}
          ${this.options.showTime ? `
            <span class="waveform-time" style="color: ${this.options.textSecondaryColor};">
              <span class="time-current">0:00</span> / <span class="time-total">0:00</span>
            </span>
          ` : ""}
        </div>
      </div>
    </div>
  </div>
`, this.playBtn = this.container.querySelector(".waveform-btn"), this.canvas = this.container.querySelector("canvas"), this.ctx = this.canvas.getContext("2d"), this.titleEl = this.container.querySelector(".waveform-title"), this.subtitleEl = this.container.querySelector(".waveform-subtitle"), this.artworkEl = this.container.querySelector(".waveform-artwork"), this.currentTimeEl = this.container.querySelector(".time-current"), this.totalTimeEl = this.container.querySelector(".time-total"), this.bpmEl = this.container.querySelector(".waveform-bpm"), this.bpmValueEl = this.container.querySelector(".bpm-value"), this.loadingEl = this.container.querySelector(".waveform-loading"), this.errorEl = this.container.querySelector(".waveform-error"), this.markersContainer = this.container.querySelector(".waveform-markers"), this.speedBtn = this.container.querySelector(".speed-btn"), this.speedMenu = this.container.querySelector(".speed-menu"), this.resizeCanvas();
  }
  createAudio() {
    this.audio = new Audio(), this.audio.preload = this.options.preload || "metadata", this.audio.crossOrigin = "anonymous";
  }
  initPlaybackSpeed() {
    this.options.playbackRate && this.options.playbackRate !== 1 && (this.audio.playbackRate = this.options.playbackRate), this.options.showPlaybackSpeed && this.initSpeedControls();
  }
  initSpeedControls() {
    let e2 = this.container.querySelector(".speed-btn"), i2 = this.container.querySelector(".speed-menu");
    !e2 || !i2 || (e2.addEventListener("click", (a2) => {
      a2.stopPropagation(), i2.style.display = i2.style.display === "none" ? "block" : "none";
    }), document.addEventListener("click", () => {
      i2.style.display = "none";
    }), i2.addEventListener("click", (a2) => {
      if (a2.stopPropagation(), a2.target.classList.contains("speed-option")) {
        let s2 = parseFloat(a2.target.dataset.rate);
        this.setPlaybackRate(s2), i2.style.display = "none";
      }
    }), this.updateSpeedUI());
  }
  initKeyboardControls() {
    this.container.setAttribute("tabindex", "-1"), this.container.addEventListener("click", () => {
      t2.getAllInstances().forEach((e2) => {
        e2 !== this && e2.container.setAttribute("tabindex", "-1");
      }), this.container.setAttribute("tabindex", "0"), this.container.focus();
    }), this.container.addEventListener("keydown", (e2) => {
      if (document.activeElement !== this.container) return;
      let i2 = e2.key, a2 = this.audio.currentTime;
      if (i2 >= "0" && i2 <= "9") {
        e2.preventDefault(), this.seekToPercent(parseInt(i2) / 10);
        return;
      }
      let s2 = { " ": () => this.togglePlay(), ArrowLeft: () => this.seekTo(Math.max(0, a2 - 5)), ArrowRight: () => this.seekTo(Math.min(this.audio.duration, a2 + 5)), ArrowUp: () => this.setVolume(Math.min(1, this.audio.volume + 0.1)), ArrowDown: () => this.setVolume(Math.max(0, this.audio.volume - 0.1)), m: () => this.audio.muted = !this.audio.muted, M: () => this.audio.muted = !this.audio.muted };
      s2[i2] && (e2.preventDefault(), s2[i2]());
    });
  }
  initMediaSession() {
    !("mediaSession" in navigator) || !this.options.enableMediaSession || (navigator.mediaSession.metadata = new MediaMetadata({ title: this.options.title || "Unknown Track", artist: this.options.subtitle || "", album: this.options.album || "", artwork: this.options.artwork ? [{ src: this.options.artwork, sizes: "512x512", type: "image/jpeg" }] : [] }), navigator.mediaSession.setActionHandler("play", () => this.play()), navigator.mediaSession.setActionHandler("pause", () => this.pause()), navigator.mediaSession.setActionHandler("seekbackward", () => {
      this.seekTo(Math.max(0, this.audio.currentTime - 10));
    }), navigator.mediaSession.setActionHandler("seekforward", () => {
      this.seekTo(Math.min(this.audio.duration, this.audio.currentTime + 10));
    }), navigator.mediaSession.setActionHandler("seekto", (e2) => {
      e2.seekTime !== null && this.seekTo(e2.seekTime);
    }));
  }
  bindEvents() {
    this.playBtn.addEventListener("click", () => this.togglePlay()), this.audio.addEventListener("loadstart", () => this.setLoading(true)), this.audio.addEventListener("loadedmetadata", () => this.onMetadataLoaded()), this.audio.addEventListener("canplay", () => this.setLoading(false)), this.audio.addEventListener("play", () => this.onPlay()), this.audio.addEventListener("pause", () => this.onPause()), this.audio.addEventListener("ended", () => this.onEnded()), this.audio.addEventListener("error", (e2) => this.onError(e2)), this.canvas.addEventListener("click", (e2) => this.handleCanvasClick(e2)), this.resizeHandler = B(() => this.resizeCanvas(), 100), window.addEventListener("resize", this.resizeHandler);
  }
  setupResizeObserver() {
    "ResizeObserver" in window && (this.resizeObserver = new ResizeObserver(() => {
      this.resizeCanvas();
    }), this.canvas?.parentElement && this.resizeObserver.observe(this.canvas.parentElement));
  }
  async load(e2) {
    try {
      this.setLoading(true), this.progress = 0, this.hasError = false, this.audio.src = e2, await new Promise((a2, s2) => {
        let n2 = () => {
          this.audio.removeEventListener("loadedmetadata", n2), this.audio.removeEventListener("error", r2), a2();
        }, r2 = (o2) => {
          this.audio.removeEventListener("loadedmetadata", n2), this.audio.removeEventListener("error", r2), s2(o2);
        };
        this.audio.addEventListener("loadedmetadata", n2), this.audio.addEventListener("error", r2);
      });
      let i2 = this.options.title || R(e2);
      if (this.titleEl && (this.titleEl.textContent = i2), this.options.waveform) this.setWaveformData(this.options.waveform);
      else try {
        let a2 = await M2(e2, this.options.samples, this.options.showBPM);
        this.waveformData = a2.peaks, a2.bpm && (this.detectedBPM = a2.bpm, this.updateBPMDisplay());
      } catch (a2) {
        console.warn("Using placeholder waveform:", a2), this.waveformData = D(this.options.samples);
      }
      this.drawWaveform(), this.renderMarkers(), this.initMediaSession(), this.options.onLoad && this.options.onLoad(this);
    } catch (i2) {
      console.error("Failed to load audio:", i2), this.onError(i2);
    } finally {
      this.setLoading(false);
    }
  }
  async loadTrack(e2, i2 = null, a2 = null, s2 = {}) {
    this.isPlaying && this.pause(), this.audio.src = "", this.audio.load(), this.hasError = false, this.errorEl && (this.errorEl.style.display = "none"), this.canvas && (this.canvas.style.opacity = "1"), this.playBtn && (this.playBtn.disabled = false), this.progress = 0, this.waveformData = [], this.options = C(this.options, { url: e2, title: i2 || this.options.title, subtitle: a2 || this.options.subtitle, ...s2 }), s2.preload && (this.audio.preload = s2.preload), this.subtitleEl && (a2 ? (this.subtitleEl.textContent = a2, this.subtitleEl.style.display = "") : a2 === "" && (this.subtitleEl.style.display = "none")), s2.artwork && this.artworkEl && (this.artworkEl.src = s2.artwork), s2.markers && (this.options.markers = s2.markers), await this.load(e2), this.play();
  }
  setWaveformData(e2) {
    if (typeof e2 == "string") try {
      let i2 = JSON.parse(e2);
      this.waveformData = Array.isArray(i2) ? i2 : [];
    } catch {
      this.waveformData = e2.split(",").map(Number);
    }
    else this.waveformData = Array.isArray(e2) ? e2 : [];
    this.drawWaveform();
  }
  drawWaveform() {
    !this.ctx || this.waveformData.length === 0 || W(this.ctx, this.canvas, this.waveformData, this.progress, { ...this.options, waveformStyle: this.options.waveformStyle || "bars", color: this.options.waveformColor, progressColor: this.options.progressColor });
  }
  resizeCanvas() {
    if (!this.canvas || this.isDestroying) return;
    let e2 = window.devicePixelRatio || 1, i2 = this.canvas.getBoundingClientRect();
    this.canvas.width = i2.width * e2, this.canvas.height = this.options.height * e2, this.canvas.style.height = this.options.height + "px", this.canvas.parentElement.style.height = this.options.height + "px", this.drawWaveform();
  }
  renderMarkers() {
    !this.options.showMarkers || !this.options.markers?.length || !this.markersContainer || (this.markersContainer.innerHTML = "", !(!this.audio || !this.audio.duration || this.audio.duration === 0) && this.options.markers.forEach((e2, i2) => {
      if (e2.time > this.audio.duration) {
        console.warn(`Marker "${e2.label}" at ${e2.time}s exceeds audio duration of ${this.audio.duration}s`);
        return;
      }
      let a2 = e2.time / this.audio.duration * 100, s2 = document.createElement("button");
      s2.className = "waveform-marker", s2.style.left = `${a2}%`, s2.style.backgroundColor = e2.color || "rgba(255, 255, 255, 0.5)", s2.setAttribute("aria-label", e2.label), s2.setAttribute("data-time", e2.time);
      let n2 = document.createElement("span");
      n2.className = "waveform-marker-tooltip", n2.textContent = e2.label, s2.appendChild(n2), s2.addEventListener("click", (r2) => {
        r2.stopPropagation(), this.seekTo(e2.time), this.options.playOnSeek && !this.isPlaying && this.play();
      }), this.markersContainer.appendChild(s2);
    }));
  }
  handleCanvasClick(e2) {
    if (!this.audio.duration) return;
    let i2 = this.canvas.getBoundingClientRect(), a2 = e2.clientX - i2.left, s2 = Math.max(0, Math.min(1, a2 / i2.width));
    this.seekToPercent(s2);
  }
  setLoading(e2) {
    this.isLoading = e2, this.loadingEl && (this.loadingEl.style.display = e2 ? "block" : "none");
  }
  onMetadataLoaded() {
    this.isDestroying || (this.totalTimeEl && (this.totalTimeEl.textContent = P(this.audio.duration)), this.renderMarkers());
  }
  onPlay() {
    if (this.isDestroying) return;
    this.isPlaying = true, this.playBtn.classList.add("playing");
    let e2 = this.playBtn.querySelector(".waveform-icon-play"), i2 = this.playBtn.querySelector(".waveform-icon-pause");
    e2 && (e2.style.display = "none"), i2 && (i2.style.display = "flex"), this.startSmoothUpdate(), this.container.dispatchEvent(new CustomEvent("waveformplayer:play", { bubbles: true, detail: { player: this, url: this.options.url } })), this.options.onPlay && this.options.onPlay(this);
  }
  onPause() {
    if (this.isDestroying) return;
    this.isPlaying = false, this.playBtn.classList.remove("playing");
    let e2 = this.playBtn.querySelector(".waveform-icon-play"), i2 = this.playBtn.querySelector(".waveform-icon-pause");
    e2 && (e2.style.display = "flex"), i2 && (i2.style.display = "none"), this.stopSmoothUpdate(), this.container.dispatchEvent(new CustomEvent("waveformplayer:pause", { bubbles: true, detail: { player: this, url: this.options.url } })), this.options.onPause && this.options.onPause(this);
  }
  onEnded() {
    this.isDestroying || (this.progress = 0, this.audio.currentTime = 0, this.drawWaveform(), this.currentTimeEl && (this.currentTimeEl.textContent = "0:00"), this.container.dispatchEvent(new CustomEvent("waveformplayer:ended", { bubbles: true, detail: { player: this, url: this.options.url } })), this.onPause(), this.options.onEnd && this.options.onEnd(this));
  }
  onError(e2) {
    this.isDestroying || (console.error("Audio error:", e2), this.hasError = true, this.setLoading(false), this.errorEl && (this.errorEl.style.display = "flex"), this.canvas && (this.canvas.style.opacity = "0.2"), this.playBtn && (this.playBtn.disabled = true), this.options.onError && this.options.onError(e2, this));
  }
  startSmoothUpdate() {
    this.stopSmoothUpdate();
    let e2 = () => {
      this.isPlaying && this.audio.duration && (this.updateProgress(), this.updateTimer = requestAnimationFrame(e2));
    };
    this.updateTimer = requestAnimationFrame(e2);
  }
  stopSmoothUpdate() {
    this.updateTimer && (cancelAnimationFrame(this.updateTimer), this.updateTimer = null);
  }
  updateProgress() {
    if (!this.audio.duration) return;
    let e2 = this.audio.currentTime / this.audio.duration;
    Math.abs(e2 - this.progress) > 1e-3 && (this.progress = e2, this.drawWaveform()), this.currentTimeEl && (this.currentTimeEl.textContent = P(this.audio.currentTime)), this.container.dispatchEvent(new CustomEvent("waveformplayer:timeupdate", { bubbles: true, detail: { player: this, currentTime: this.audio.currentTime, duration: this.audio.duration, url: this.options.url } })), this.options.onTimeUpdate && this.options.onTimeUpdate(this.audio.currentTime, this.audio.duration, this);
  }
  updateBPMDisplay() {
    this.bpmEl && this.bpmValueEl && this.detectedBPM && (this.bpmValueEl.textContent = Math.round(this.detectedBPM), this.bpmEl.style.display = "inline-flex");
  }
  updateSpeedUI() {
    let e2 = this.container.querySelector(".speed-value");
    if (e2) {
      let i2 = this.audio.playbackRate;
      e2.textContent = i2 === 1 ? "1x" : `${i2}x`;
    }
    this.container.querySelectorAll(".speed-option").forEach((i2) => {
      i2.classList.toggle("active", parseFloat(i2.dataset.rate) === this.audio.playbackRate);
    });
  }
  play() {
    this.options.singlePlay && t2.currentlyPlaying && t2.currentlyPlaying !== this && t2.currentlyPlaying.pause(), t2.currentlyPlaying = this, this.audio.play();
  }
  pause() {
    t2.currentlyPlaying === this && (t2.currentlyPlaying = null), this.audio.pause();
  }
  togglePlay() {
    this.isPlaying ? this.pause() : this.play();
  }
  seekTo(e2) {
    this.audio && this.audio.duration && (this.audio.currentTime = Math.max(0, Math.min(e2, this.audio.duration)), this.updateProgress());
  }
  seekToPercent(e2) {
    this.audio && this.audio.duration && (this.audio.currentTime = this.audio.duration * Math.max(0, Math.min(1, e2)), this.updateProgress());
  }
  setVolume(e2) {
    this.audio && (this.audio.volume = Math.max(0, Math.min(1, e2)));
  }
  setPlaybackRate(e2) {
    if (!this.audio) return;
    let i2 = Math.max(0.5, Math.min(2, e2));
    this.audio.playbackRate = i2, this.options.playbackRate = i2, this.updateSpeedUI();
  }
  destroy() {
    this.isDestroying = true, this.pause(), this.stopSmoothUpdate(), this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = null), this.resizeHandler && (window.removeEventListener("resize", this.resizeHandler), this.resizeHandler = null), t2.instances.delete(this.id), t2.currentlyPlaying === this && (t2.currentlyPlaying = null), this.audio && (this.audio.pause(), this.audio.src = "", this.audio.load(), this.audio = null), this.container.innerHTML = "", this.canvas = null, this.ctx = null, this.playBtn = null, this.waveformData = [];
  }
  static getInstance(e2) {
    if (typeof e2 == "string") {
      let i2 = this.instances.get(e2);
      if (i2) return i2;
      let a2 = document.getElementById(e2);
      if (a2) return Array.from(this.instances.values()).find((s2) => s2.container === a2);
    }
    if (e2 instanceof HTMLElement) return Array.from(this.instances.values()).find((i2) => i2.container === e2);
  }
  static getAllInstances() {
    return Array.from(this.instances.values());
  }
  static destroyAll() {
    this.instances.forEach((e2) => e2.destroy()), this.instances.clear();
  }
  static async generateWaveformData(e2, i2 = 200) {
    try {
      return (await M2(e2, i2)).peaks;
    } catch (a2) {
      throw console.error("Failed to generate waveform:", a2), a2;
    }
  }
};
function T() {
  if (typeof document > "u") return;
  document.querySelectorAll("[data-waveform-player]").forEach((e2) => {
    if (e2.dataset.waveformInitialized !== "true") try {
      new g2(e2), e2.dataset.waveformInitialized = "true";
    } catch (i2) {
      console.error("Failed to initialize WaveformPlayer:", i2, e2);
    }
  });
}
typeof document < "u" && (document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", T) : T());
g2.init = T;
typeof window < "u" && (window.WaveformPlayer = g2);
var lt = g2;

// packages/block-library/build-module/utils/waveform-utils.mjs
var DEFAULT_WAVEFORM_HEIGHT = 100;
function getComputedStyle2(element) {
  return element.ownerDocument.defaultView.getComputedStyle(element);
}
function getWaveformColors(element) {
  const textColor = getComputedStyle2(element).color;
  const waveformColor = w(textColor).alpha(0.3).toRgbString();
  const progressColor = w(textColor).alpha(0.6).toRgbString();
  return { textColor, waveformColor, progressColor };
}
function createWaveformContainer({
  url,
  title,
  artist,
  artwork,
  waveformColor,
  progressColor,
  buttonColor,
  height = DEFAULT_WAVEFORM_HEIGHT
}) {
  const container = document.createElement("div");
  container.setAttribute("data-waveform-player", "");
  container.setAttribute("data-url", url);
  container.setAttribute("data-height", String(height));
  container.setAttribute("data-waveform-style", "bars");
  container.setAttribute("data-waveform-color", waveformColor);
  container.setAttribute("data-progress-color", progressColor);
  container.setAttribute("data-button-color", buttonColor);
  container.setAttribute("data-text-color", buttonColor);
  container.setAttribute("data-text-secondary-color", buttonColor);
  if (title) {
    container.setAttribute("data-title", title);
  }
  if (artist) {
    container.setAttribute("data-subtitle", artist);
  }
  if (artwork) {
    container.setAttribute("data-artwork", artwork);
  }
  return container;
}
function styleSvgIcons(container, buttonColor) {
  const isButtonDark = w(buttonColor).isDark();
  const iconColor = isButtonDark ? "#ffffff" : "#000000";
  const svgPaths = container.querySelectorAll("svg path");
  svgPaths.forEach((path) => {
    path.style.fill = iconColor;
  });
}
function setupPlayButtonAccessibility(container, { play: playLabel = "Play", pause: pauseLabel = "Pause" } = {}) {
  const playBtn = container.querySelector(".waveform-btn");
  if (!playBtn) {
    return;
  }
  playBtn.setAttribute("aria-label", playLabel);
  const onPlay = () => playBtn.setAttribute("aria-label", pauseLabel);
  const onPause = () => playBtn.setAttribute("aria-label", playLabel);
  container.addEventListener("waveformplayer:play", onPlay);
  container.addEventListener("waveformplayer:pause", onPause);
  container.addEventListener("waveformplayer:ended", onPause);
  return () => {
    container.removeEventListener("waveformplayer:play", onPlay);
    container.removeEventListener("waveformplayer:pause", onPause);
    container.removeEventListener("waveformplayer:ended", onPause);
  };
}
function logPlayError(error) {
  if (error.name === "AbortError") {
    return;
  }
  console.error("Playlist play error:", error);
}
function initWaveformPlayer(element, { src, title, artist, image, autoPlay, onEnded, labels }) {
  const { textColor, waveformColor, progressColor } = getWaveformColors(element);
  const container = createWaveformContainer({
    url: src,
    title,
    artist,
    artwork: image,
    waveformColor,
    progressColor,
    buttonColor: textColor
  });
  element.appendChild(container);
  const instance = new lt(container);
  let cleanupAccessibility;
  const handlers = {
    ready: () => {
      styleSvgIcons(container, textColor);
      cleanupAccessibility = setupPlayButtonAccessibility(
        container,
        labels
      );
      if (autoPlay) {
        instance.play()?.catch(logPlayError);
      }
    },
    ended: () => onEnded?.()
  };
  container.addEventListener("waveformplayer:ready", handlers.ready);
  container.addEventListener("waveformplayer:ended", handlers.ended);
  return {
    instance,
    container,
    destroy: () => {
      cleanupAccessibility?.();
      container.removeEventListener(
        "waveformplayer:ready",
        handlers.ready
      );
      container.removeEventListener(
        "waveformplayer:ended",
        handlers.ended
      );
      instance.destroy();
      container.remove();
    }
  };
}

// packages/block-library/build-module/playlist/view.mjs
var playerState = /* @__PURE__ */ new WeakMap();
var { state } = store(
  "core/playlist",
  {
    state: {
      playlists: {},
      get isCurrentTrack() {
        const { currentId, uniqueId } = getContext();
        return currentId === uniqueId;
      }
    },
    actions: {
      changeTrack() {
        const context = getContext();
        context.currentId = context.uniqueId;
      }
    },
    callbacks: {
      initWaveformPlayer() {
        const context = getContext();
        const { ref } = getElement();
        if (!context.currentId || !ref) {
          return;
        }
        const track = state.playlists[context.playlistId]?.tracks[context.currentId];
        if (!track?.url) {
          return;
        }
        const existing = playerState.get(ref);
        if (existing?.url === track.url) {
          return;
        }
        const shouldAutoPlay = !!existing?.url;
        initPlayer(ref, track, shouldAutoPlay, context);
      }
    }
  },
  { lock: true }
);
function initPlayer(ref, track, shouldAutoPlay, context) {
  const existing = playerState.get(ref);
  if (existing?.instance) {
    existing.instance.loadTrack(track.url, track.title, track.artist, {
      artwork: track.image
    }).then(() => {
      existing.url = track.url;
      if (shouldAutoPlay) {
        existing.instance.play()?.catch(logPlayError);
      }
    }).catch(logPlayError);
    return;
  }
  const labels = {
    play: ref.dataset.labelPlay,
    pause: ref.dataset.labelPause
  };
  const player = initWaveformPlayer(ref, {
    src: track.url,
    title: track.title,
    artist: track.artist,
    image: track.image,
    autoPlay: shouldAutoPlay,
    labels,
    onEnded: () => {
      const currentIndex = context.tracks.findIndex(
        (uniqueId) => uniqueId === context.currentId
      );
      const nextTrack = context.tracks[currentIndex + 1];
      if (nextTrack) {
        context.currentId = nextTrack;
      }
    }
  });
  playerState.set(ref, {
    url: track.url,
    instance: player.instance,
    destroy: player.destroy
  });
}
//# sourceMappingURL=view.js.map