[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/js/dist/script-modules/block-library/playlist/ -> view.js (source)

   1  // packages/block-library/build-module/playlist/view.mjs
   2  import { store, getContext, getElement } from "@wordpress/interactivity";
   3  
   4  // node_modules/colord/index.mjs
   5  var r = { grad: 0.9, turn: 360, rad: 360 / (2 * Math.PI) };
   6  var t = function(r2) {
   7    return "string" == typeof r2 ? r2.length > 0 : "number" == typeof r2;
   8  };
   9  var n = function(r2, t3, n2) {
  10    return void 0 === t3 && (t3 = 0), void 0 === n2 && (n2 = Math.pow(10, t3)), Math.round(n2 * r2) / n2 + 0;
  11  };
  12  var e = function(r2, t3, n2) {
  13    return void 0 === t3 && (t3 = 0), void 0 === n2 && (n2 = 1), r2 > n2 ? n2 : r2 > t3 ? r2 : t3;
  14  };
  15  var u = function(r2) {
  16    return (r2 = isFinite(r2) ? r2 % 360 : 0) > 0 ? r2 : r2 + 360;
  17  };
  18  var a = function(r2) {
  19    return { r: e(r2.r, 0, 255), g: e(r2.g, 0, 255), b: e(r2.b, 0, 255), a: e(r2.a) };
  20  };
  21  var o = function(r2) {
  22    return { r: n(r2.r), g: n(r2.g), b: n(r2.b), a: n(r2.a, 3) };
  23  };
  24  var i = /^#([0-9a-f]{3,8})$/i;
  25  var s = function(r2) {
  26    var t3 = r2.toString(16);
  27    return t3.length < 2 ? "0" + t3 : t3;
  28  };
  29  var h = function(r2) {
  30    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;
  31    return { h: 60 * (i2 < 0 ? i2 + 6 : i2), s: a2 ? o2 / a2 * 100 : 0, v: a2 / 255 * 100, a: u2 };
  32  };
  33  var b = function(r2) {
  34    var t3 = r2.h, n2 = r2.s, e2 = r2.v, u2 = r2.a;
  35    t3 = t3 / 360 * 6, n2 /= 100, e2 /= 100;
  36    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;
  37    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 };
  38  };
  39  var g = function(r2) {
  40    return { h: u(r2.h), s: e(r2.s, 0, 100), l: e(r2.l, 0, 100), a: e(r2.a) };
  41  };
  42  var d = function(r2) {
  43    return { h: n(r2.h), s: n(r2.s), l: n(r2.l), a: n(r2.a, 3) };
  44  };
  45  var f = function(r2) {
  46    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 }));
  47    var t3, n2, e2;
  48  };
  49  var c = function(r2) {
  50    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 };
  51    var t3, n2, e2, u2;
  52  };
  53  var l = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
  54  var p = /^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
  55  var v = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
  56  var m = /^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i;
  57  var y = { string: [[function(r2) {
  58    var t3 = i.exec(r2);
  59    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;
  60  }, "hex"], [function(r2) {
  61    var t3 = v.exec(r2) || m.exec(r2);
  62    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;
  63  }, "rgb"], [function(t3) {
  64    var n2 = l.exec(t3) || p.exec(t3);
  65    if (!n2) return null;
  66    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) });
  67    return f(a2);
  68  }, "hsl"]], object: [[function(r2) {
  69    var n2 = r2.r, e2 = r2.g, u2 = r2.b, o2 = r2.a, i2 = void 0 === o2 ? 1 : o2;
  70    return t(n2) && t(e2) && t(u2) ? a({ r: Number(n2), g: Number(e2), b: Number(u2), a: Number(i2) }) : null;
  71  }, "rgb"], [function(r2) {
  72    var n2 = r2.h, e2 = r2.s, u2 = r2.l, a2 = r2.a, o2 = void 0 === a2 ? 1 : a2;
  73    if (!t(n2) || !t(e2) || !t(u2)) return null;
  74    var i2 = g({ h: Number(n2), s: Number(e2), l: Number(u2), a: Number(o2) });
  75    return f(i2);
  76  }, "hsl"], [function(r2) {
  77    var n2 = r2.h, a2 = r2.s, o2 = r2.v, i2 = r2.a, s2 = void 0 === i2 ? 1 : i2;
  78    if (!t(n2) || !t(a2) || !t(o2)) return null;
  79    var h2 = (function(r3) {
  80      return { h: u(r3.h), s: e(r3.s, 0, 100), v: e(r3.v, 0, 100), a: e(r3.a) };
  81    })({ h: Number(n2), s: Number(a2), v: Number(o2), a: Number(s2) });
  82    return b(h2);
  83  }, "hsv"]] };
  84  var N = function(r2, t3) {
  85    for (var n2 = 0; n2 < t3.length; n2++) {
  86      var e2 = t3[n2][0](r2);
  87      if (e2) return [e2, t3[n2][1]];
  88    }
  89    return [null, void 0];
  90  };
  91  var x = function(r2) {
  92    return "string" == typeof r2 ? N(r2.trim(), y.string) : "object" == typeof r2 && null !== r2 ? N(r2, y.object) : [null, void 0];
  93  };
  94  var M = function(r2, t3) {
  95    var n2 = c(r2);
  96    return { h: n2.h, s: e(n2.s + 100 * t3, 0, 100), l: n2.l, a: n2.a };
  97  };
  98  var H = function(r2) {
  99    return (299 * r2.r + 587 * r2.g + 114 * r2.b) / 1e3 / 255;
 100  };
 101  var $ = function(r2, t3) {
 102    var n2 = c(r2);
 103    return { h: n2.h, s: n2.s, l: e(n2.l + 100 * t3, 0, 100), a: n2.a };
 104  };
 105  var j = (function() {
 106    function r2(r3) {
 107      this.parsed = x(r3)[0], this.rgba = this.parsed || { r: 0, g: 0, b: 0, a: 1 };
 108    }
 109    return r2.prototype.isValid = function() {
 110      return null !== this.parsed;
 111    }, r2.prototype.brightness = function() {
 112      return n(H(this.rgba), 2);
 113    }, r2.prototype.isDark = function() {
 114      return H(this.rgba) < 0.5;
 115    }, r2.prototype.isLight = function() {
 116      return H(this.rgba) >= 0.5;
 117    }, r2.prototype.toHex = function() {
 118      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;
 119      var r3, t3, e2, u2, a2, i2;
 120    }, r2.prototype.toRgb = function() {
 121      return o(this.rgba);
 122    }, r2.prototype.toRgbString = function() {
 123      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 + ")";
 124      var r3, t3, n2, e2, u2;
 125    }, r2.prototype.toHsl = function() {
 126      return d(c(this.rgba));
 127    }, r2.prototype.toHslString = function() {
 128      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 + "%)";
 129      var r3, t3, n2, e2, u2;
 130    }, r2.prototype.toHsv = function() {
 131      return r3 = h(this.rgba), { h: n(r3.h), s: n(r3.s), v: n(r3.v), a: n(r3.a, 3) };
 132      var r3;
 133    }, r2.prototype.invert = function() {
 134      return w({ r: 255 - (r3 = this.rgba).r, g: 255 - r3.g, b: 255 - r3.b, a: r3.a });
 135      var r3;
 136    }, r2.prototype.saturate = function(r3) {
 137      return void 0 === r3 && (r3 = 0.1), w(M(this.rgba, r3));
 138    }, r2.prototype.desaturate = function(r3) {
 139      return void 0 === r3 && (r3 = 0.1), w(M(this.rgba, -r3));
 140    }, r2.prototype.grayscale = function() {
 141      return w(M(this.rgba, -1));
 142    }, r2.prototype.lighten = function(r3) {
 143      return void 0 === r3 && (r3 = 0.1), w($(this.rgba, r3));
 144    }, r2.prototype.darken = function(r3) {
 145      return void 0 === r3 && (r3 = 0.1), w($(this.rgba, -r3));
 146    }, r2.prototype.rotate = function(r3) {
 147      return void 0 === r3 && (r3 = 15), this.hue(this.hue() + r3);
 148    }, r2.prototype.alpha = function(r3) {
 149      return "number" == typeof r3 ? w({ r: (t3 = this.rgba).r, g: t3.g, b: t3.b, a: r3 }) : n(this.rgba.a, 3);
 150      var t3;
 151    }, r2.prototype.hue = function(r3) {
 152      var t3 = c(this.rgba);
 153      return "number" == typeof r3 ? w({ h: r3, s: t3.s, l: t3.l, a: t3.a }) : n(t3.h);
 154    }, r2.prototype.isEqual = function(r3) {
 155      return this.toHex() === w(r3).toHex();
 156    }, r2;
 157  })();
 158  var w = function(r2) {
 159    return r2 instanceof j ? r2 : new j(r2);
 160  };
 161  
 162  // packages/block-library/node_modules/@arraypress/waveform-player/dist/waveform-player.esm.js
 163  function L(t3) {
 164    let e2 = {};
 165    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 {
 166      e2.markers = JSON.parse(t3.dataset.markers);
 167    } catch (i2) {
 168      console.warn("Invalid markers JSON:", i2);
 169    }
 170    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 {
 171      e2.playbackRates = JSON.parse(t3.dataset.playbackRates);
 172    } catch (i2) {
 173      console.warn("Invalid playbackRates JSON:", i2);
 174    }
 175    return t3.dataset.enableMediaSession !== void 0 && (e2.enableMediaSession = t3.dataset.enableMediaSession === "true"), e2;
 176  }
 177  function P(t3) {
 178    if (!t3 || isNaN(t3)) return "0:00";
 179    let e2 = Math.floor(t3 / 60), i2 = Math.floor(t3 % 60);
 180    return `$e2}:$i2.toString().padStart(2, "0")}`;
 181  }
 182  function A(t3) {
 183    let e2 = t3 || Math.random().toString();
 184    return btoa(e2.substring(0, 10)).replace(/[^a-zA-Z0-9]/g, "");
 185  }
 186  function R(t3) {
 187    if (!t3) return "Audio";
 188    let e2 = t3.split("/");
 189    return e2[e2.length - 1].split(".")[0].replace(/[-_]/g, " ").replace(/\b\w/g, (s2) => s2.toUpperCase());
 190  }
 191  function C(...t3) {
 192    let e2 = {};
 193    for (let i2 of t3) for (let a2 in i2) i2[a2] !== null && i2[a2] !== void 0 && (e2[a2] = i2[a2]);
 194    return e2;
 195  }
 196  function B(t3, e2) {
 197    let i2;
 198    return function(...s2) {
 199      let n2 = () => {
 200        clearTimeout(i2), t3(...s2);
 201      };
 202      clearTimeout(i2), i2 = setTimeout(n2, e2);
 203    };
 204  }
 205  function S(t3, e2) {
 206    if (t3.length === e2) return t3;
 207    if (t3.length === 0 || e2 === 0) return [];
 208    let i2 = [];
 209    if (e2 > t3.length) {
 210      let a2 = (t3.length - 1) / (e2 - 1);
 211      for (let s2 = 0; s2 < e2; s2++) {
 212        let n2 = s2 * a2, r2 = Math.floor(n2), o2 = Math.ceil(n2), h2 = n2 - r2;
 213        if (o2 >= t3.length) i2.push(t3[t3.length - 1]);
 214        else if (r2 === o2) i2.push(t3[r2]);
 215        else {
 216          let l2 = t3[r2] * (1 - h2) + t3[o2] * h2;
 217          i2.push(l2);
 218        }
 219      }
 220    } else {
 221      let a2 = t3.length / e2;
 222      for (let s2 = 0; s2 < e2; s2++) {
 223        let n2 = Math.floor(s2 * a2), r2 = Math.floor((s2 + 1) * a2), o2 = 0, h2 = 0;
 224        for (let l2 = n2; l2 <= r2 && l2 < t3.length; l2++) t3[l2] > o2 && (o2 = t3[l2]), h2++;
 225        if (h2 === 0) {
 226          let l2 = Math.min(Math.round(s2 * a2), t3.length - 1);
 227          o2 = t3[l2];
 228        }
 229        i2.push(o2);
 230      }
 231    }
 232    return i2;
 233  }
 234  function x2(t3, e2, i2, a2, s2) {
 235    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;
 236    t3.clearRect(0, 0, e2.width, e2.height);
 237    for (let y2 = 0; y2 < l2.length; y2++) {
 238      let f2 = y2 * (r2 + o2);
 239      if (f2 + r2 > e2.width) break;
 240      let c2 = l2[y2] * d2 * 0.9, m2 = d2 - c2;
 241      t3.fillStyle = s2.color, t3.fillRect(f2, m2, r2, c2);
 242    }
 243    t3.save(), t3.beginPath(), t3.rect(0, 0, p2, d2), t3.clip();
 244    for (let y2 = 0; y2 < l2.length; y2++) {
 245      let f2 = y2 * (r2 + o2);
 246      if (f2 > p2) break;
 247      let c2 = l2[y2] * d2 * 0.9, m2 = d2 - c2;
 248      t3.fillStyle = s2.progressColor, t3.fillRect(f2, m2, r2, c2);
 249    }
 250    t3.restore();
 251  }
 252  function q(t3, e2, i2, a2, s2) {
 253    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;
 254    t3.clearRect(0, 0, e2.width, e2.height);
 255    for (let f2 = 0; f2 < l2.length; f2++) {
 256      let c2 = f2 * (r2 + o2);
 257      if (c2 + r2 > e2.width) break;
 258      let m2 = l2[f2] * d2 * 0.45;
 259      t3.fillStyle = s2.color, t3.fillRect(c2, p2 - m2, r2, m2), t3.fillRect(c2, p2, r2, m2);
 260    }
 261    t3.save(), t3.beginPath(), t3.rect(0, 0, y2, d2), t3.clip();
 262    for (let f2 = 0; f2 < l2.length; f2++) {
 263      let c2 = f2 * (r2 + o2);
 264      if (c2 > y2) break;
 265      let m2 = l2[f2] * d2 * 0.45;
 266      t3.fillStyle = s2.progressColor, t3.fillRect(c2, p2 - m2, r2, m2), t3.fillRect(c2, p2, r2, m2);
 267    }
 268    t3.restore();
 269  }
 270  function $2(t3, e2, i2, a2, s2) {
 271    let n2 = e2.width, r2 = e2.height, o2 = r2 / 2, h2 = r2 * 0.35;
 272    t3.clearRect(0, 0, n2, r2);
 273    let l2 = (d2, p2, y2 = 1, f2 = false) => {
 274      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);
 275      let c2 = [], m2 = Math.floor(i2.length * y2);
 276      for (let u2 = 0; u2 < m2; u2++) {
 277        let v2 = u2 / (i2.length - 1) * n2, k = i2[u2], b2 = Math.sin(u2 * 0.1) * k, w2 = o2 + b2 * h2;
 278        c2.push({ x: v2, y: w2 });
 279      }
 280      for (let u2 = 0; u2 < c2.length - 1; u2++) {
 281        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;
 282        t3.bezierCurveTo(v2, k, b2, w2, c2[u2 + 1].x, c2[u2 + 1].y);
 283      }
 284      t3.stroke(), f2 && (t3.shadowBlur = 0);
 285    };
 286    t3.strokeStyle = "rgba(255, 255, 255, 0.03)", t3.lineWidth = 0.5, t3.beginPath(), t3.moveTo(0, o2), t3.lineTo(n2, o2), t3.stroke();
 287    for (let d2 = 0; d2 <= 10; d2++) {
 288      let p2 = n2 / 10 * d2;
 289      t3.beginPath(), t3.moveTo(p2, 0), t3.lineTo(p2, r2), t3.stroke();
 290    }
 291    l2(s2.color, 2, 1, false), a2 > 0 && l2(s2.progressColor, 3, a2, true);
 292  }
 293  function U(t3, e2, i2, a2, s2) {
 294    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;
 295    t3.clearRect(0, 0, e2.width, e2.height);
 296    for (let m2 = 0; m2 < l2.length; m2++) {
 297      let u2 = m2 * (r2 + o2);
 298      if (u2 + r2 > e2.width) break;
 299      let v2 = l2[m2] * d2 * 0.9, k = Math.floor(v2 / (p2 + y2));
 300      t3.fillStyle = u2 < f2 ? s2.progressColor : s2.color;
 301      for (let b2 = 0; b2 < k; b2++) {
 302        let w2 = b2 * (p2 + y2);
 303        t3.fillRect(u2, c2 - w2 - p2, r2, p2), b2 > 0 && t3.fillRect(u2, c2 + w2, r2, p2);
 304      }
 305    }
 306  }
 307  function F(t3, e2, i2, a2, s2) {
 308    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;
 309    t3.clearRect(0, 0, e2.width, e2.height);
 310    for (let c2 = 0; c2 < l2.length; c2++) {
 311      let m2 = c2 * (r2 + o2) + r2 / 2;
 312      if (m2 > e2.width) break;
 313      let u2 = l2[c2] * d2 * 0.9;
 314      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();
 315    }
 316  }
 317  function N2(t3, e2, i2, a2, s2) {
 318    let n2 = e2.width, r2 = e2.height, o2 = r2 / 2, h2 = 4, l2 = h2 / 2;
 319    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) {
 320      let d2 = Math.max(l2 * 2, a2 * n2);
 321      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;
 322      let p2 = 8, y2 = d2;
 323      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();
 324    }
 325  }
 326  var Y = { bars: x2, mirror: q, line: $2, blocks: U, dots: F, seekbar: N2 };
 327  function W(t3, e2, i2, a2, s2) {
 328    (Y[s2.waveformStyle] || x2)(t3, e2, i2, a2, s2);
 329  }
 330  function I(t3) {
 331    try {
 332      let e2 = t3.getChannelData(0), i2 = t3.sampleRate, a2 = j2(e2, i2);
 333      if (a2.length < 2) return 120;
 334      let s2 = [];
 335      for (let h2 = 1; h2 < a2.length; h2++) s2.push((a2[h2] - a2[h2 - 1]) / i2);
 336      let n2 = {};
 337      s2.forEach((h2) => {
 338        let l2 = 60 / h2, d2 = Math.round(l2 / 3) * 3;
 339        d2 > 60 && d2 < 200 && (n2[d2] = (n2[d2] || 0) + 1);
 340      });
 341      let r2 = 0, o2 = 120;
 342      for (let [h2, l2] of Object.entries(n2)) l2 > r2 && (r2 = l2, o2 = parseInt(h2));
 343      return o2 < 70 && n2[o2 * 2] ? o2 *= 2 : o2 > 160 && n2[Math.round(o2 / 2)] && (o2 = Math.round(o2 / 2)), o2 - 1;
 344    } catch (e2) {
 345      return console.warn("BPM detection failed:", e2), null;
 346    }
 347  }
 348  function j2(t3, e2) {
 349    let s2 = [], n2 = 0;
 350    for (let r2 = 0; r2 < t3.length - 2048; r2 += 1024) {
 351      let o2 = 0;
 352      for (let d2 = r2; d2 < r2 + 2048; d2++) o2 += t3[d2] * t3[d2];
 353      o2 = o2 / 2048;
 354      let h2 = o2 - n2, l2 = n2 * 1.8 + 0.01;
 355      if (h2 > l2 && o2 > 0.01) {
 356        let d2 = s2[s2.length - 1] || 0, p2 = e2 * 0.15;
 357        r2 - d2 > p2 && s2.push(r2);
 358      }
 359      n2 = o2 * 0.8 + n2 * 0.2;
 360    }
 361    return s2;
 362  }
 363  function V(t3, e2 = 200) {
 364    let i2 = t3.length / e2, a2 = ~~(i2 / 10) || 1, s2 = t3.numberOfChannels, n2 = [];
 365    for (let o2 = 0; o2 < s2; o2++) {
 366      let h2 = t3.getChannelData(o2);
 367      for (let l2 = 0; l2 < e2; l2++) {
 368        let d2 = ~~(l2 * i2), p2 = ~~(d2 + i2), y2 = 0, f2 = 0;
 369        for (let m2 = d2; m2 < p2; m2 += a2) {
 370          let u2 = h2[m2];
 371          u2 > f2 && (f2 = u2), u2 < y2 && (y2 = u2);
 372        }
 373        let c2 = Math.max(Math.abs(f2), Math.abs(y2));
 374        (o2 === 0 || c2 > n2[l2]) && (n2[l2] = c2);
 375      }
 376    }
 377    let r2 = Math.max(...n2);
 378    return r2 > 0 ? n2.map((o2) => o2 / r2) : n2;
 379  }
 380  async function M2(t3, e2 = 200, i2 = false) {
 381    try {
 382      let a2 = new (window.AudioContext || window.webkitAudioContext)(), n2 = await (await fetch(t3)).arrayBuffer(), r2 = await a2.decodeAudioData(n2), o2 = V(r2, e2);
 383      o2 = J(o2);
 384      let h2 = null;
 385      return i2 && (h2 = await I(r2)), a2.close(), { peaks: o2, bpm: h2 };
 386    } catch (a2) {
 387      throw console.error("Failed to generate waveform:", a2), a2;
 388    }
 389  }
 390  function D(t3 = 200) {
 391    let e2 = [];
 392    for (let i2 = 0; i2 < t3; i2++) {
 393      let a2 = Math.random() * 0.5 + 0.3, s2 = Math.sin(i2 / t3 * Math.PI * 4) * 0.2;
 394      e2.push(Math.max(0.1, Math.min(1, a2 + s2)));
 395    }
 396    return e2;
 397  }
 398  function J(t3, e2 = 0.95) {
 399    let i2 = Math.max(...t3);
 400    if (i2 === 0 || i2 > e2) return t3;
 401    let a2 = e2 / i2;
 402    return t3.map((s2) => s2 * a2);
 403  }
 404  function G() {
 405    let t3 = document.documentElement, e2 = document.body;
 406    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";
 407    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";
 408    try {
 409      let a2 = getComputedStyle(document.body).backgroundColor.match(/\d+/g);
 410      if (a2 && a2.length >= 3) {
 411        let [s2, n2, r2] = a2.map(Number), o2 = (s2 * 299 + n2 * 587 + r2 * 114) / 1e3;
 412        if (o2 > 128) return "light";
 413        if (o2 < 128) return "dark";
 414      }
 415    } catch {
 416    }
 417    if (window.matchMedia) {
 418      if (window.matchMedia("(prefers-color-scheme: dark)").matches) return "dark";
 419      if (window.matchMedia("(prefers-color-scheme: light)").matches) return "light";
 420    }
 421    return "dark";
 422  }
 423  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)" } };
 424  function z(t3) {
 425    if (t3 && E[t3]) return E[t3];
 426    let e2 = G();
 427    return E[e2];
 428  }
 429  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 };
 430  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 } };
 431  var g2 = class t2 {
 432    static instances = /* @__PURE__ */ new Map();
 433    static currentlyPlaying = null;
 434    constructor(e2, i2 = {}) {
 435      if (this.container = typeof e2 == "string" ? document.querySelector(e2) : e2, !this.container) throw new Error("WaveformPlayer: Container element not found");
 436      let a2 = L(this.container);
 437      this.options = C(O, a2, i2);
 438      let s2 = z(this.options.colorPreset);
 439      for (let [r2, o2] of Object.entries(s2)) (this.options[r2] === null || this.options[r2] === void 0) && (this.options[r2] = o2);
 440      let n2 = H2[this.options.waveformStyle];
 441      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(() => {
 442        this.container.dispatchEvent(new CustomEvent("waveformplayer:ready", { bubbles: true, detail: { player: this, url: this.options.url } }));
 443      }, 100);
 444    }
 445    init() {
 446      this.createDOM(), this.createAudio(), this.initPlaybackSpeed(), this.initKeyboardControls(), this.bindEvents(), this.setupResizeObserver(), requestAnimationFrame(() => {
 447        this.resizeCanvas(), this.options.url && this.load(this.options.url).then(() => {
 448          this.options.autoplay && this.play();
 449        }).catch((e2) => {
 450          console.error("Failed to load audio:", e2);
 451        });
 452      });
 453    }
 454    createDOM() {
 455      this.container.innerHTML = "", this.container.className = "waveform-player";
 456      let e2 = this.options.buttonAlign;
 457      e2 === "auto" && (this.options.waveformStyle === "bars" ? e2 = "bottom" : e2 = "center"), this.container.innerHTML = `
 458    <div class="waveform-player-inner">
 459      <div class="waveform-body">
 460        <div class="waveform-track waveform-align-$e2}">
 461          <button class="waveform-btn" aria-label="Play/Pause" style="
 462              border-color: $this.options.buttonColor};
 463              color: $this.options.buttonColor};
 464          ">
 465            <span class="waveform-icon-play">$this.options.playIcon}</span>
 466            <span class="waveform-icon-pause" style="display:none;">$this.options.pauseIcon}</span>
 467          </button>
 468          
 469          <div class="waveform-container">
 470            <canvas></canvas>
 471            <div class="waveform-markers"></div>
 472            <div class="waveform-loading" style="display:none;"></div>
 473            <div class="waveform-error" style="display:none;">
 474              <span class="waveform-error-text">Unable to load audio</span>
 475            </div>
 476          </div>
 477        </div>
 478        
 479        <div class="waveform-info">
 480          $this.options.artwork ? `
 481            <img class="waveform-artwork" src="$this.options.artwork}" alt="Album artwork" style="
 482              width: 40px;
 483              height: 40px;
 484              border-radius: 4px;
 485              object-fit: cover;
 486              flex-shrink: 0;
 487            ">
 488          ` : ""}
 489          <div class="waveform-text">
 490            <span class="waveform-title" style="color: $this.options.textColor};"></span>
 491            $this.options.subtitle ? `<span class="waveform-subtitle" style="color: $this.options.textSecondaryColor};">$this.options.subtitle}</span>` : ""}
 492          </div>
 493          <div style="display: flex; align-items: center; gap: 1rem;">
 494            $this.options.showBPM ? `
 495              <span class="waveform-bpm" style="color: $this.options.textSecondaryColor}; display: none;">
 496                <span class="bpm-value">--</span> BPM
 497              </span>
 498            ` : ""}
 499            $this.options.showPlaybackSpeed ? `
 500              <div class="waveform-speed">
 501                <button class="speed-btn" aria-label="Playback speed">
 502                  <span class="speed-value">1x</span>
 503                </button>
 504                <div class="speed-menu" style="display: none;">
 505                  $this.options.playbackRates.map((i2) => `<button class="speed-option" data-rate="$i2}">$i2}x</button>`).join("")}
 506                </div>
 507              </div>
 508            ` : ""}
 509            $this.options.showTime ? `
 510              <span class="waveform-time" style="color: $this.options.textSecondaryColor};">
 511                <span class="time-current">0:00</span> / <span class="time-total">0:00</span>
 512              </span>
 513            ` : ""}
 514          </div>
 515        </div>
 516      </div>
 517    </div>
 518  `, 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();
 519    }
 520    createAudio() {
 521      this.audio = new Audio(), this.audio.preload = this.options.preload || "metadata", this.audio.crossOrigin = "anonymous";
 522    }
 523    initPlaybackSpeed() {
 524      this.options.playbackRate && this.options.playbackRate !== 1 && (this.audio.playbackRate = this.options.playbackRate), this.options.showPlaybackSpeed && this.initSpeedControls();
 525    }
 526    initSpeedControls() {
 527      let e2 = this.container.querySelector(".speed-btn"), i2 = this.container.querySelector(".speed-menu");
 528      !e2 || !i2 || (e2.addEventListener("click", (a2) => {
 529        a2.stopPropagation(), i2.style.display = i2.style.display === "none" ? "block" : "none";
 530      }), document.addEventListener("click", () => {
 531        i2.style.display = "none";
 532      }), i2.addEventListener("click", (a2) => {
 533        if (a2.stopPropagation(), a2.target.classList.contains("speed-option")) {
 534          let s2 = parseFloat(a2.target.dataset.rate);
 535          this.setPlaybackRate(s2), i2.style.display = "none";
 536        }
 537      }), this.updateSpeedUI());
 538    }
 539    initKeyboardControls() {
 540      this.container.setAttribute("tabindex", "-1"), this.container.addEventListener("click", () => {
 541        t2.getAllInstances().forEach((e2) => {
 542          e2 !== this && e2.container.setAttribute("tabindex", "-1");
 543        }), this.container.setAttribute("tabindex", "0"), this.container.focus();
 544      }), this.container.addEventListener("keydown", (e2) => {
 545        if (document.activeElement !== this.container) return;
 546        let i2 = e2.key, a2 = this.audio.currentTime;
 547        if (i2 >= "0" && i2 <= "9") {
 548          e2.preventDefault(), this.seekToPercent(parseInt(i2) / 10);
 549          return;
 550        }
 551        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 };
 552        s2[i2] && (e2.preventDefault(), s2[i2]());
 553      });
 554    }
 555    initMediaSession() {
 556      !("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", () => {
 557        this.seekTo(Math.max(0, this.audio.currentTime - 10));
 558      }), navigator.mediaSession.setActionHandler("seekforward", () => {
 559        this.seekTo(Math.min(this.audio.duration, this.audio.currentTime + 10));
 560      }), navigator.mediaSession.setActionHandler("seekto", (e2) => {
 561        e2.seekTime !== null && this.seekTo(e2.seekTime);
 562      }));
 563    }
 564    bindEvents() {
 565      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);
 566    }
 567    setupResizeObserver() {
 568      "ResizeObserver" in window && (this.resizeObserver = new ResizeObserver(() => {
 569        this.resizeCanvas();
 570      }), this.canvas?.parentElement && this.resizeObserver.observe(this.canvas.parentElement));
 571    }
 572    async load(e2) {
 573      try {
 574        this.setLoading(true), this.progress = 0, this.hasError = false, this.audio.src = e2, await new Promise((a2, s2) => {
 575          let n2 = () => {
 576            this.audio.removeEventListener("loadedmetadata", n2), this.audio.removeEventListener("error", r2), a2();
 577          }, r2 = (o2) => {
 578            this.audio.removeEventListener("loadedmetadata", n2), this.audio.removeEventListener("error", r2), s2(o2);
 579          };
 580          this.audio.addEventListener("loadedmetadata", n2), this.audio.addEventListener("error", r2);
 581        });
 582        let i2 = this.options.title || R(e2);
 583        if (this.titleEl && (this.titleEl.textContent = i2), this.options.waveform) this.setWaveformData(this.options.waveform);
 584        else try {
 585          let a2 = await M2(e2, this.options.samples, this.options.showBPM);
 586          this.waveformData = a2.peaks, a2.bpm && (this.detectedBPM = a2.bpm, this.updateBPMDisplay());
 587        } catch (a2) {
 588          console.warn("Using placeholder waveform:", a2), this.waveformData = D(this.options.samples);
 589        }
 590        this.drawWaveform(), this.renderMarkers(), this.initMediaSession(), this.options.onLoad && this.options.onLoad(this);
 591      } catch (i2) {
 592        console.error("Failed to load audio:", i2), this.onError(i2);
 593      } finally {
 594        this.setLoading(false);
 595      }
 596    }
 597    async loadTrack(e2, i2 = null, a2 = null, s2 = {}) {
 598      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();
 599    }
 600    setWaveformData(e2) {
 601      if (typeof e2 == "string") try {
 602        let i2 = JSON.parse(e2);
 603        this.waveformData = Array.isArray(i2) ? i2 : [];
 604      } catch {
 605        this.waveformData = e2.split(",").map(Number);
 606      }
 607      else this.waveformData = Array.isArray(e2) ? e2 : [];
 608      this.drawWaveform();
 609    }
 610    drawWaveform() {
 611      !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 });
 612    }
 613    resizeCanvas() {
 614      if (!this.canvas || this.isDestroying) return;
 615      let e2 = window.devicePixelRatio || 1, i2 = this.canvas.getBoundingClientRect();
 616      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();
 617    }
 618    renderMarkers() {
 619      !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) => {
 620        if (e2.time > this.audio.duration) {
 621          console.warn(`Marker "$e2.label}" at $e2.time}s exceeds audio duration of $this.audio.duration}s`);
 622          return;
 623        }
 624        let a2 = e2.time / this.audio.duration * 100, s2 = document.createElement("button");
 625        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);
 626        let n2 = document.createElement("span");
 627        n2.className = "waveform-marker-tooltip", n2.textContent = e2.label, s2.appendChild(n2), s2.addEventListener("click", (r2) => {
 628          r2.stopPropagation(), this.seekTo(e2.time), this.options.playOnSeek && !this.isPlaying && this.play();
 629        }), this.markersContainer.appendChild(s2);
 630      }));
 631    }
 632    handleCanvasClick(e2) {
 633      if (!this.audio.duration) return;
 634      let i2 = this.canvas.getBoundingClientRect(), a2 = e2.clientX - i2.left, s2 = Math.max(0, Math.min(1, a2 / i2.width));
 635      this.seekToPercent(s2);
 636    }
 637    setLoading(e2) {
 638      this.isLoading = e2, this.loadingEl && (this.loadingEl.style.display = e2 ? "block" : "none");
 639    }
 640    onMetadataLoaded() {
 641      this.isDestroying || (this.totalTimeEl && (this.totalTimeEl.textContent = P(this.audio.duration)), this.renderMarkers());
 642    }
 643    onPlay() {
 644      if (this.isDestroying) return;
 645      this.isPlaying = true, this.playBtn.classList.add("playing");
 646      let e2 = this.playBtn.querySelector(".waveform-icon-play"), i2 = this.playBtn.querySelector(".waveform-icon-pause");
 647      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);
 648    }
 649    onPause() {
 650      if (this.isDestroying) return;
 651      this.isPlaying = false, this.playBtn.classList.remove("playing");
 652      let e2 = this.playBtn.querySelector(".waveform-icon-play"), i2 = this.playBtn.querySelector(".waveform-icon-pause");
 653      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);
 654    }
 655    onEnded() {
 656      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));
 657    }
 658    onError(e2) {
 659      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));
 660    }
 661    startSmoothUpdate() {
 662      this.stopSmoothUpdate();
 663      let e2 = () => {
 664        this.isPlaying && this.audio.duration && (this.updateProgress(), this.updateTimer = requestAnimationFrame(e2));
 665      };
 666      this.updateTimer = requestAnimationFrame(e2);
 667    }
 668    stopSmoothUpdate() {
 669      this.updateTimer && (cancelAnimationFrame(this.updateTimer), this.updateTimer = null);
 670    }
 671    updateProgress() {
 672      if (!this.audio.duration) return;
 673      let e2 = this.audio.currentTime / this.audio.duration;
 674      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);
 675    }
 676    updateBPMDisplay() {
 677      this.bpmEl && this.bpmValueEl && this.detectedBPM && (this.bpmValueEl.textContent = Math.round(this.detectedBPM), this.bpmEl.style.display = "inline-flex");
 678    }
 679    updateSpeedUI() {
 680      let e2 = this.container.querySelector(".speed-value");
 681      if (e2) {
 682        let i2 = this.audio.playbackRate;
 683        e2.textContent = i2 === 1 ? "1x" : `$i2}x`;
 684      }
 685      this.container.querySelectorAll(".speed-option").forEach((i2) => {
 686        i2.classList.toggle("active", parseFloat(i2.dataset.rate) === this.audio.playbackRate);
 687      });
 688    }
 689    play() {
 690      this.options.singlePlay && t2.currentlyPlaying && t2.currentlyPlaying !== this && t2.currentlyPlaying.pause(), t2.currentlyPlaying = this, this.audio.play();
 691    }
 692    pause() {
 693      t2.currentlyPlaying === this && (t2.currentlyPlaying = null), this.audio.pause();
 694    }
 695    togglePlay() {
 696      this.isPlaying ? this.pause() : this.play();
 697    }
 698    seekTo(e2) {
 699      this.audio && this.audio.duration && (this.audio.currentTime = Math.max(0, Math.min(e2, this.audio.duration)), this.updateProgress());
 700    }
 701    seekToPercent(e2) {
 702      this.audio && this.audio.duration && (this.audio.currentTime = this.audio.duration * Math.max(0, Math.min(1, e2)), this.updateProgress());
 703    }
 704    setVolume(e2) {
 705      this.audio && (this.audio.volume = Math.max(0, Math.min(1, e2)));
 706    }
 707    setPlaybackRate(e2) {
 708      if (!this.audio) return;
 709      let i2 = Math.max(0.5, Math.min(2, e2));
 710      this.audio.playbackRate = i2, this.options.playbackRate = i2, this.updateSpeedUI();
 711    }
 712    destroy() {
 713      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 = [];
 714    }
 715    static getInstance(e2) {
 716      if (typeof e2 == "string") {
 717        let i2 = this.instances.get(e2);
 718        if (i2) return i2;
 719        let a2 = document.getElementById(e2);
 720        if (a2) return Array.from(this.instances.values()).find((s2) => s2.container === a2);
 721      }
 722      if (e2 instanceof HTMLElement) return Array.from(this.instances.values()).find((i2) => i2.container === e2);
 723    }
 724    static getAllInstances() {
 725      return Array.from(this.instances.values());
 726    }
 727    static destroyAll() {
 728      this.instances.forEach((e2) => e2.destroy()), this.instances.clear();
 729    }
 730    static async generateWaveformData(e2, i2 = 200) {
 731      try {
 732        return (await M2(e2, i2)).peaks;
 733      } catch (a2) {
 734        throw console.error("Failed to generate waveform:", a2), a2;
 735      }
 736    }
 737  };
 738  function T() {
 739    if (typeof document > "u") return;
 740    document.querySelectorAll("[data-waveform-player]").forEach((e2) => {
 741      if (e2.dataset.waveformInitialized !== "true") try {
 742        new g2(e2), e2.dataset.waveformInitialized = "true";
 743      } catch (i2) {
 744        console.error("Failed to initialize WaveformPlayer:", i2, e2);
 745      }
 746    });
 747  }
 748  typeof document < "u" && (document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", T) : T());
 749  g2.init = T;
 750  typeof window < "u" && (window.WaveformPlayer = g2);
 751  var lt = g2;
 752  
 753  // packages/block-library/build-module/utils/waveform-utils.mjs
 754  var DEFAULT_WAVEFORM_HEIGHT = 100;
 755  function getComputedStyle2(element) {
 756    return element.ownerDocument.defaultView.getComputedStyle(element);
 757  }
 758  function getWaveformColors(element) {
 759    const textColor = getComputedStyle2(element).color;
 760    const waveformColor = w(textColor).alpha(0.3).toRgbString();
 761    const progressColor = w(textColor).alpha(0.6).toRgbString();
 762    return { textColor, waveformColor, progressColor };
 763  }
 764  function createWaveformContainer({
 765    url,
 766    title,
 767    artist,
 768    artwork,
 769    waveformColor,
 770    progressColor,
 771    buttonColor,
 772    height = DEFAULT_WAVEFORM_HEIGHT,
 773    waveformStyle = "bars"
 774  }) {
 775    const container = document.createElement("div");
 776    container.setAttribute("data-waveform-player", "");
 777    container.setAttribute("data-url", url);
 778    container.setAttribute("data-height", String(height));
 779    container.setAttribute("data-waveform-style", waveformStyle);
 780    container.setAttribute("data-waveform-color", waveformColor);
 781    container.setAttribute("data-progress-color", progressColor);
 782    container.setAttribute("data-button-color", buttonColor);
 783    container.setAttribute("data-text-color", buttonColor);
 784    container.setAttribute("data-text-secondary-color", buttonColor);
 785    if (title) {
 786      container.setAttribute("data-title", title);
 787    }
 788    if (artist) {
 789      container.setAttribute("data-subtitle", artist);
 790    }
 791    if (artwork) {
 792      container.setAttribute("data-artwork", artwork);
 793    }
 794    return container;
 795  }
 796  function styleSvgIcons(container, buttonColor) {
 797    const isButtonDark = w(buttonColor).isDark();
 798    const iconColor = isButtonDark ? "#ffffff" : "#000000";
 799    const svgPaths = container.querySelectorAll("svg path");
 800    svgPaths.forEach((path) => {
 801      path.style.fill = iconColor;
 802    });
 803  }
 804  function setupPlayButtonAccessibility(container, { play: playLabel = "Play", pause: pauseLabel = "Pause" } = {}) {
 805    const playBtn = container.querySelector(".waveform-btn");
 806    if (!playBtn) {
 807      return;
 808    }
 809    playBtn.setAttribute("aria-label", playLabel);
 810    const onPlay = () => playBtn.setAttribute("aria-label", pauseLabel);
 811    const onPause = () => playBtn.setAttribute("aria-label", playLabel);
 812    container.addEventListener("waveformplayer:play", onPlay);
 813    container.addEventListener("waveformplayer:pause", onPause);
 814    container.addEventListener("waveformplayer:ended", onPause);
 815    return () => {
 816      container.removeEventListener("waveformplayer:play", onPlay);
 817      container.removeEventListener("waveformplayer:pause", onPause);
 818      container.removeEventListener("waveformplayer:ended", onPause);
 819    };
 820  }
 821  function logPlayError(error) {
 822    if (error.name === "AbortError") {
 823      return;
 824    }
 825    console.error("Playlist play error:", error);
 826  }
 827  function initWaveformPlayer(element, { src, title, artist, image, autoPlay, onEnded, labels, waveformStyle }) {
 828    const { textColor, waveformColor, progressColor } = getWaveformColors(element);
 829    const container = createWaveformContainer({
 830      url: src,
 831      title,
 832      artist,
 833      artwork: image,
 834      waveformColor,
 835      progressColor,
 836      buttonColor: textColor,
 837      waveformStyle
 838    });
 839    element.appendChild(container);
 840    const instance = new lt(container);
 841    let cleanupAccessibility;
 842    const handlers = {
 843      ready: () => {
 844        styleSvgIcons(container, textColor);
 845        cleanupAccessibility = setupPlayButtonAccessibility(
 846          container,
 847          labels
 848        );
 849        if (autoPlay) {
 850          instance.play()?.catch(logPlayError);
 851        }
 852      },
 853      ended: () => onEnded?.()
 854    };
 855    container.addEventListener("waveformplayer:ready", handlers.ready);
 856    container.addEventListener("waveformplayer:ended", handlers.ended);
 857    return {
 858      instance,
 859      container,
 860      destroy: () => {
 861        cleanupAccessibility?.();
 862        container.removeEventListener(
 863          "waveformplayer:ready",
 864          handlers.ready
 865        );
 866        container.removeEventListener(
 867          "waveformplayer:ended",
 868          handlers.ended
 869        );
 870        instance.destroy();
 871        container.remove();
 872      }
 873    };
 874  }
 875  
 876  // packages/block-library/build-module/playlist/view.mjs
 877  var playerState = /* @__PURE__ */ new WeakMap();
 878  var { state } = store(
 879    "core/playlist",
 880    {
 881      state: {
 882        playlists: {},
 883        get isCurrentTrack() {
 884          const { currentId, uniqueId } = getContext();
 885          return currentId === uniqueId;
 886        }
 887      },
 888      actions: {
 889        changeTrack() {
 890          const context = getContext();
 891          context.currentId = context.uniqueId;
 892        }
 893      },
 894      callbacks: {
 895        initWaveformPlayer() {
 896          const context = getContext();
 897          const { ref } = getElement();
 898          if (!context.currentId || !ref) {
 899            return;
 900          }
 901          const track = state.playlists[context.playlistId]?.tracks[context.currentId];
 902          if (!track?.url) {
 903            return;
 904          }
 905          const existing = playerState.get(ref);
 906          if (existing?.url === track.url) {
 907            return;
 908          }
 909          const shouldAutoPlay = !!existing?.url;
 910          initPlayer(ref, track, shouldAutoPlay, context);
 911        }
 912      }
 913    },
 914    { lock: true }
 915  );
 916  function initPlayer(ref, track, shouldAutoPlay, context) {
 917    const existing = playerState.get(ref);
 918    if (existing?.instance) {
 919      existing.instance.loadTrack(track.url, track.title, track.artist, {
 920        artwork: track.image
 921      }).then(() => {
 922        existing.url = track.url;
 923        if (shouldAutoPlay) {
 924          existing.instance.play()?.catch(logPlayError);
 925        }
 926      }).catch(logPlayError);
 927      return;
 928    }
 929    const labels = {
 930      play: ref.dataset.labelPlay,
 931      pause: ref.dataset.labelPause
 932    };
 933    const player = initWaveformPlayer(ref, {
 934      src: track.url,
 935      title: track.title,
 936      artist: track.artist,
 937      image: track.image,
 938      autoPlay: shouldAutoPlay,
 939      labels,
 940      waveformStyle: context.waveformStyle,
 941      onEnded: () => {
 942        const currentIndex = context.tracks.findIndex(
 943          (uniqueId) => uniqueId === context.currentId
 944        );
 945        const nextTrack = context.tracks[currentIndex + 1];
 946        if (nextTrack) {
 947          context.currentId = nextTrack;
 948        }
 949      }
 950    });
 951    playerState.set(ref, {
 952      url: track.url,
 953      instance: player.instance,
 954      destroy: player.destroy
 955    });
 956  }


Generated : Fri Jul 3 08:20:12 2026 Cross-referenced by PHPXref