{"version":3,"file":"flat-embed.mjs","sources":["../src/lib/compatibility.ts","../src/lib/callback.ts","../src/lib/communication.ts","../src/lib/dom.ts","../src/lib/embed.ts","../src/embed.ts"],"sourcesContent":["if (typeof window.postMessage === 'undefined') {\n  throw new Error('The Flat Embed JS API is not supported in this browser');\n}\n","import type Embed from '../embed';\nimport type {\n  EmbedMessageReceived,\n  EmbedMessageReceivedEvent,\n  EmbedMessageReceivedMethod,\n} from '../types';\nimport type { EmbedEventName } from '../types/events';\n\nclass EmbedCallback {\n  embed: Embed;\n  promises: Partial<\n    Record<string, { resolve: (value: unknown) => void; reject: (reason?: unknown) => void }[]>\n  >;\n  eventCallbacks: Partial<Record<EmbedEventName, ((parameters: unknown) => void)[]>>;\n\n  constructor(embed: Embed) {\n    this.embed = embed;\n    this.promises = {};\n    this.eventCallbacks = {};\n  }\n\n  pushCall(\n    // NOTE: We could type this with list of public methods\n    name: string,\n    resolve: (value: unknown) => void,\n    reject: (reason?: unknown) => void,\n  ) {\n    this.promises[name] = this.promises[name] || [];\n    this.promises[name]!.push({ resolve, reject });\n  }\n\n  /**\n   * Register a callback for a specified event\n   *\n   * @param event The name of the event.\n   * @param callback The function to call when receiving an event\n   * @return `true` if it is the first subscriber, `false otherwise`\n   */\n  subscribeEvent(event: EmbedEventName, callback: (parameters: unknown) => void): boolean {\n    this.eventCallbacks[event] = this.eventCallbacks[event] || [];\n    this.eventCallbacks[event]!.push(callback);\n    return this.eventCallbacks[event]!.length === 1;\n  }\n\n  /**\n   * Unregister a callback for a specified event\n   *\n   * @param event The name of the event.\n   * @param callback The function to call when receiving an event\n   * @return `true` if it is the last subscriber, `false otherwise`\n   */\n  unsubscribeEvent(event: EmbedEventName, callback?: (parameters: unknown) => void): boolean {\n    // Was not subscribed\n    if (!this.eventCallbacks[event]) {\n      return false;\n    }\n\n    // If a callback is specified, unsub this one\n    if (callback) {\n      const idx = this.eventCallbacks[event]!.indexOf(callback);\n      if (idx >= 0) {\n        this.eventCallbacks[event]!.splice(idx, 1);\n      }\n    }\n    // Unsub all\n    else {\n      this.eventCallbacks[event] = [];\n    }\n\n    return !callback || this.eventCallbacks[event]!.length === 0;\n  }\n\n  /**\n   * Process a message received from postMessage\n   *\n   * @param {object} data The data received from postMessage\n   */\n  process(data: EmbedMessageReceived) {\n    if ('method' in data && data.method) {\n      this.processMethodResponse(data);\n    } else if ('event' in data && data.event) {\n      this.processEvent(data);\n    }\n  }\n\n  /**\n   * Process a method response\n   *\n   * @param {object} data The data received from postMessage\n   */\n  processMethodResponse(data: EmbedMessageReceivedMethod) {\n    if (!this.promises[data.method]) {\n      return;\n    }\n    const promise = this.promises[data.method]!.shift();\n    if (!promise) {\n      return;\n    }\n    if (data.error) {\n      promise.reject(data.error);\n    } else {\n      promise.resolve(data.response);\n    }\n  }\n\n  /**\n   * Process a receieved event\n   *\n   * @param {object} data The data received from postMessage\n   */\n  processEvent(data: EmbedMessageReceivedEvent) {\n    if (!this.eventCallbacks[data.event] || this.eventCallbacks[data.event]!.length === 0) {\n      return;\n    }\n    this.eventCallbacks[data.event]!.forEach(callback => {\n      callback.call(this.embed, data.parameters);\n    });\n  }\n}\n\nexport default EmbedCallback;\n","import type Embed from '../embed';\nimport type { EmbedMessageReceived } from '../types';\n\n/**\n * Send a message to the embed via postMessage\n *\n * @param embed The instance of the embed where to send the message\n * @param method The name of the method to call\n * @param parameters The parameters to pass to the method\n */\nexport function postMessage(embed: Embed, method: string, parameters?: unknown): void {\n  if (!embed.element.contentWindow || !embed.element.contentWindow.postMessage) {\n    throw new Error('No `contentWindow` or `contentWindow.postMessage` available on the element');\n  }\n\n  const message = {\n    method,\n    parameters,\n  };\n\n  embed.element.contentWindow.postMessage(message, embed.origin);\n}\n\n/**\n * Parse a message received from postMessage\n *\n * @param data The data received from postMessage\n * @return Received message from the embed\n */\nexport function parseMessage(data: string | Record<string, unknown>): EmbedMessageReceived {\n  if (typeof data === 'string') {\n    data = JSON.parse(data);\n  }\n  return data as unknown as EmbedMessageReceived;\n}\n","/**\n * Select and normalize the DOM element input\n */\nexport function normalizeElement(\n  element: HTMLIFrameElement | HTMLElement | string,\n): HTMLIFrameElement | HTMLElement {\n  // Find an element by identifier\n  if (typeof element === 'string') {\n    const container = document.getElementById(element);\n    if (!container) {\n      throw new TypeError(`The DOM element with the identifier \"${element}\" was not found.`);\n    }\n    element = container;\n  }\n\n  // Check if a DOM element\n  if (!(element instanceof window.HTMLElement)) {\n    throw new TypeError('The first parameter must be an existing DOM element or an identifier.');\n  }\n\n  // The element is not an embed iframe?\n  if (element.nodeName !== 'IFRAME') {\n    // check if already present in the element\n    const iframe = element.querySelector('iframe');\n    if (iframe) {\n      element = iframe;\n    }\n  }\n\n  return element;\n}\n","import type { EmbedParameters } from '../types';\n\n/**\n * Build url for the new iframe\n *\n * @param {object} parameters\n */\nexport function buildIframeUrl(parameters: EmbedParameters) {\n  let url = parameters.baseUrl || 'https://flat-embed.com';\n\n  // Score id or blank embed\n  if (!parameters.isCustomUrl) {\n    url += `/${parameters.score || 'blank'}`;\n  }\n\n  // Build qs parameters\n  const urlParameters: Record<string, string | number | boolean> = Object.assign(\n    {\n      jsapi: true,\n    },\n    parameters.embedParams as Record<string, string | number | boolean>,\n  );\n\n  const qs = Object.keys(urlParameters)\n    .map(k => `${encodeURIComponent(k)}=${encodeURIComponent(urlParameters[k])}`)\n    .join('&');\n\n  return `${url}?${qs}`;\n}\n\n/**\n * Create an iframe inside a specified element\n *\n * @param {HTMLElement} element\n * @param {object} parameters\n */\nexport function createEmbedIframe(\n  element: HTMLElement,\n  parameters: EmbedParameters,\n): HTMLIFrameElement {\n  const url = buildIframeUrl(parameters);\n\n  const iframe = document.createElement('iframe');\n  iframe.setAttribute('src', url);\n  iframe.setAttribute('width', parameters.width || '100%');\n  iframe.setAttribute('height', parameters.height || '100%');\n  iframe.setAttribute('allowfullscreen', 'true');\n  iframe.setAttribute('allow', 'autoplay; midi');\n  iframe.setAttribute('frameborder', '0');\n\n  if (parameters.lazy) {\n    iframe.setAttribute('loading', 'lazy');\n  }\n\n  element.appendChild(iframe);\n\n  return iframe;\n}\n","import './lib/compatibility';\n\nimport EmbedCallback from './lib/callback';\nimport { parseMessage, postMessage } from './lib/communication';\nimport { normalizeElement } from './lib/dom';\nimport { createEmbedIframe } from './lib/embed';\nimport type {\n  EmbedEventName,\n  EmbedMessageReceived,\n  EmbedMessageReceivedEvent,\n  EmbedMessageReceivedMethod,\n  EmbedParameters,\n  MeasureDetails,\n  MetronomeMode,\n  NoteCursorPosition,\n  NoteCursorPositionOptional,\n  NoteDetails,\n  PartConfiguration,\n  PlaybackPosition,\n  ScoreTrackConfiguration,\n} from './types';\nimport type { ScoreDetails } from './types/scoreDetails';\n\nconst embeds = new WeakMap<HTMLIFrameElement, Embed>();\nconst embedsReady = new WeakMap<HTMLIFrameElement, Promise<void>>();\n\nclass Embed {\n  origin: string = '*';\n  element!: HTMLIFrameElement;\n  embedCallback!: EmbedCallback;\n\n  /**\n   * Create a new Flat Embed\n   *\n   * @param element A reference to a Flat Embed iframe or a container for the new iframe\n   * @param parameters Parameters for the new iframe\n   */\n  constructor(element: HTMLIFrameElement | HTMLElement | string, parameters: EmbedParameters = {}) {\n    const normalizedElement = normalizeElement(element);\n\n    // Keep a single object instance per iframe\n    if (normalizedElement instanceof HTMLIFrameElement && embeds.has(normalizedElement)) {\n      return embeds.get(normalizedElement) as Embed;\n    }\n\n    // Create new element iframe if needed\n    let iframeElement: HTMLIFrameElement;\n    if (normalizedElement.nodeName !== 'IFRAME') {\n      iframeElement = createEmbedIframe(normalizedElement, parameters);\n    } else {\n      iframeElement = normalizedElement as HTMLIFrameElement;\n    }\n\n    this.element = iframeElement;\n    this.embedCallback = new EmbedCallback(this);\n\n    const onReady = new Promise<void>(resolve => {\n      // Handle incoming messages from embed\n      const onMessage = (event: MessageEvent) => {\n        if (this.element.contentWindow !== event.source) {\n          return;\n        }\n\n        if (this.origin === '*') {\n          this.origin = event.origin;\n        }\n\n        // Parse inbound message\n        const data: EmbedMessageReceived = parseMessage(event.data);\n\n        // Mark the embed as ready\n        if (\n          (data as EmbedMessageReceivedEvent).event === 'ready' ||\n          (data as EmbedMessageReceivedMethod).method === 'ping'\n        ) {\n          resolve();\n          return;\n        }\n\n        // Process regular messages from the embed\n        this.embedCallback.process(data);\n      };\n\n      window.addEventListener('message', onMessage, false);\n      postMessage(this, 'ping');\n    });\n\n    embeds.set(this.element, this);\n    embedsReady.set(this.element, onReady);\n\n    return this;\n  }\n\n  /**\n   * Wait for the embed to be ready\n   *\n   * Returns a promise that resolves when the embed iframe has fully loaded and\n   * communication with the Flat embed has been established. This method is automatically\n   * called by all other embed methods, so you typically don't need to call it directly.\n   * However, it can be useful when you want to know exactly when the embed is ready\n   * without performing any other action.\n   *\n   * @returns A promise that resolves when the embed is ready\n   *\n   * @example\n   * // Explicitly wait for embed to be ready\n   * const embed = new Embed('container', {\n   *   score: '56ae21579a127715a02901a6'\n   * });\n   * await embed.ready();\n   * console.log('Embed is now ready!');\n   *\n   * @example\n   * // Note: Other methods automatically wait for ready state\n   * const embed = new Embed('container');\n   * // No need to call ready() - play() will wait automatically\n   * await embed.play();\n   *\n   * @note All embed methods automatically call ready() internally, so explicit calls are optional\n   */\n  ready() {\n    return embedsReady.get(this.element) || Promise.resolve();\n  }\n\n  /**\n   * Call a method on the embed\n   *\n   * @param method Name of the method to call\n   * @param parameters Method parameters\n   * @returns Call result from Embed (if any)\n   */\n  call(\n    method: string,\n    parameters: Record<string, unknown> | string | string[] | number | boolean | Uint8Array = {},\n  ) {\n    return new Promise((resolve, reject) => {\n      return this.ready().then(() => {\n        this.embedCallback.pushCall(method, resolve, reject);\n        postMessage(this, method, parameters);\n      });\n    });\n  }\n\n  /**\n   * Subscribe to a specific event\n   *\n   * @param event The name of the event.\n   * @param callback The function to call when receiving an event\n   */\n  on(event: EmbedEventName, callback: () => void) {\n    if (typeof event !== 'string') {\n      throw new TypeError('An event name (string) is required');\n    }\n    if (typeof callback !== 'function') {\n      throw new TypeError('An callback (function) is required');\n    }\n    if (this.embedCallback.subscribeEvent(event, callback)) {\n      this.call('addEventListener', event).catch(() => {});\n    }\n  }\n\n  /**\n   * Unsubscribe to a specific event\n   *\n   * @param event The name of the event.\n   * @param callback The function to unsubscribe\n   */\n  off(event: EmbedEventName, callback?: () => void) {\n    if (typeof event !== 'string') {\n      throw new TypeError('An event name (string) is required');\n    }\n    if (this.embedCallback.unsubscribeEvent(event, callback)) {\n      this.call('removeEventListener', event).catch(() => {});\n    }\n  }\n\n  /**\n   * Load a score hosted on Flat\n   *\n   * Loads a Flat score by its unique identifier. For private scores, you must provide\n   * the sharing key obtained from a private link.\n   *\n   * @param score - The score identifier as a string, or an object containing:\n   *   - `score`: The unique identifier of the score (required)\n   *   - `sharingKey`: The sharing key for private scores (optional)\n   * @returns A promise that resolves when the score is successfully loaded\n   * @throws {TypeError} If the score parameter is invalid\n   * @throws {Error} If the score cannot be loaded (e.g., not found, access denied)\n   *\n   * @example\n   * // Load a public score\n   * await embed.loadFlatScore('56ae21579a127715a02901a6');\n   *\n   * @example\n   * // Load a private score with sharing key\n   * await embed.loadFlatScore({\n   *   score: '56ae21579a127715a02901a6',\n   *   sharingKey: 'f79c3c0dd1fc76ed8b30d6f2c845c8c30f11fe88d9fc39ab96e8e407629d4885'\n   * });\n   */\n  loadFlatScore(score: string | { score: string; sharingKey?: string }): Promise<void> {\n    if (typeof score === 'string') {\n      score = { score };\n    }\n    return this.call('loadFlatScore', score) as Promise<void>;\n  }\n\n  /**\n   * Load a MusicXML score\n   *\n   * Loads a MusicXML score from a string or binary data. The score will be converted\n   * to Flat's internal format and displayed in the embed.\n   *\n   * @param score - The MusicXML content as a string (XML) or Uint8Array (compressed MXL)\n   * @returns A promise that resolves when the score is successfully loaded\n   * @throws {TypeError} If the score format is invalid\n   * @throws {Error} If the MusicXML cannot be parsed or loaded\n   *\n   * @example\n   * // Load from XML string\n   * const xmlString = '<?xml version=\"1.0\"?>...';\n   * await embed.loadMusicXML(xmlString);\n   *\n   * @example\n   * // Load from compressed MXL file\n   * const response = await fetch('score.mxl');\n   * const buffer = await response.arrayBuffer();\n   * await embed.loadMusicXML(new Uint8Array(buffer));\n   */\n  loadMusicXML(score: string | Uint8Array) {\n    return this.call('loadMusicXML', score) as Promise<void>;\n  }\n\n  /**\n   * Load a MIDI score\n   *\n   * Loads a MIDI file and converts it to sheet music notation. Note that MIDI files\n   * contain performance data rather than notation, so the conversion may not perfectly\n   * represent the original musical intent.\n   *\n   * @param score - The MIDI file as a Uint8Array\n   * @returns A promise that resolves when the score is successfully loaded\n   * @throws {TypeError} If the score format is invalid\n   * @throws {Error} If the MIDI file cannot be parsed or loaded\n   *\n   * @example\n   * // Load MIDI file from URL\n   * const response = await fetch('song.mid');\n   * const buffer = await response.arrayBuffer();\n   * await embed.loadMIDI(new Uint8Array(buffer));\n   *\n   * @example\n   * // Load MIDI file from file input\n   * const file = document.getElementById('fileInput').files[0];\n   * const buffer = await file.arrayBuffer();\n   * await embed.loadMIDI(new Uint8Array(buffer));\n   */\n  loadMIDI(score: Uint8Array): Promise<void> {\n    return this.call('loadMIDI', score) as Promise<void>;\n  }\n\n  /**\n   * Load a Flat JSON score\n   *\n   * Loads a score from Flat's native JSON format. This format preserves all score\n   * data and is the most reliable way to transfer scores between Flat applications.\n   *\n   * @param score - The score data as a JSON string or JavaScript object\n   * @returns A promise that resolves when the score is successfully loaded\n   * @throws {TypeError} If the JSON is invalid or cannot be parsed\n   * @throws {Error} If the score data is malformed or cannot be loaded\n   *\n   * @example\n   * // Load from JSON object\n   * const scoreData = await fetch('score.json').then(r => r.json());\n   * await embed.loadJSON(scoreData);\n   *\n   * @example\n   * // Load from JSON string\n   * const jsonString = '{\"score-partwise\": {...}}';\n   * await embed.loadJSON(jsonString);\n   */\n  loadJSON(score: string | Record<string, unknown>) {\n    return this.call('loadJSON', score) as Promise<void>;\n  }\n\n  /**\n   * Get the score in Flat JSON format\n   *\n   * Exports the currently loaded score as Flat's native JSON format. This format\n   * preserves all score data including notation, layout, and metadata.\n   *\n   * @returns A promise that resolves with the score data as a JavaScript object\n   * @throws {Error} If no score is currently loaded\n   *\n   * @example\n   * // Export and save score data\n   * const scoreData = await embed.getJSON();\n   * const jsonString = JSON.stringify(scoreData);\n   *\n   * // Save to file\n   * const blob = new Blob([jsonString], { type: 'application/json' });\n   * const url = URL.createObjectURL(blob);\n   * const a = document.createElement('a');\n   * a.href = url;\n   * a.download = 'score.json';\n   * a.click();\n   */\n  getJSON() {\n    return this.call('getJSON') as Promise<Record<string, unknown>>;\n  }\n\n  /**\n   * Convert the displayed score to MusicXML\n   *\n   * Exports the currently loaded score as MusicXML, the standard format for sheet music\n   * notation exchange. Supports both uncompressed XML and compressed MXL formats.\n   *\n   * @param options - Export options:\n   *   - `compressed`: If true, returns compressed MusicXML (.mxl) as Uint8Array.\n   *                   If false (default), returns uncompressed XML as string.\n   * @returns A promise that resolves with the MusicXML data\n   * @throws {TypeError} If options parameter is invalid\n   * @throws {Error} If no score is loaded or conversion fails\n   *\n   * @example\n   * // Get uncompressed MusicXML\n   * const xml = await embed.getMusicXML();\n   * console.log(xml); // <?xml version=\"1.0\"...\n   *\n   * @example\n   * // Get compressed MusicXML (.mxl)\n   * const mxl = await embed.getMusicXML({ compressed: true });\n   * const blob = new Blob([mxl], { type: 'application/vnd.recordare.musicxml' });\n   * const url = URL.createObjectURL(blob);\n   */\n  getMusicXML(options?: { compressed?: boolean }): Promise<string | Uint8Array> {\n    return new Promise((resolve, reject) => {\n      options = options || {};\n      if (typeof options !== 'object') {\n        return reject(new TypeError('Options must be an object'));\n      }\n      this.call('getMusicXML', options)\n        .then(data => {\n          // Plain XML\n          if (typeof data === 'string') {\n            return resolve(data);\n          }\n          // Compressed, re-create Uint8Array\n          return resolve(new Uint8Array(data as [number]));\n        })\n        .catch(reject);\n    });\n  }\n\n  /**\n   * Convert the displayed score to PNG image\n   *\n   * Exports the currently loaded score as a PNG image. Supports various export options\n   * including resolution, layout mode, and output format.\n   *\n   * @param options - Export options:\n   *   - `result`: Output format - 'Uint8Array' (default) or 'dataURL'\n   *   - `dpi`: Resolution in dots per inch (50-300, default: 150)\n   *   - `layout`: Layout mode - 'track' (default, horizontal single system) or 'page'\n   * @returns A promise that resolves with the PNG data\n   * @throws {TypeError} If options parameter is invalid\n   * @throws {Error} If no score is loaded or conversion fails\n   *\n   * @example\n   * // Get PNG as Uint8Array\n   * const pngData = await embed.getPNG();\n   * const blob = new Blob([pngData], { type: 'image/png' });\n   *\n   * @example\n   * // Get PNG as data URL for direct display\n   * const dataUrl = await embed.getPNG({ result: 'dataURL' });\n   * document.getElementById('preview').src = dataUrl;\n   *\n   * @example\n   * // High resolution export with page layout\n   * const hqPng = await embed.getPNG({ dpi: 300, layout: 'page' });\n   */\n  getPNG(options?: {\n    /** Export result (either a PNG returned as Uint8Array or in dataURL) */\n    result?: 'Uint8Array' | 'dataURL';\n    /** DPI of exported image (min: 50, max: 300, default: 150) */\n    dpi?: number;\n    /** Layout of exported image */\n    layout?: 'track' | 'page';\n  }): Promise<Uint8Array | string> {\n    return new Promise((resolve, reject) => {\n      options = options || {};\n      if (typeof options !== 'object') {\n        return reject(new TypeError('Options must be an object'));\n      }\n      this.call('getPNG', options)\n        .then(data => {\n          if (typeof data === 'string') {\n            return resolve(data);\n          }\n          resolve(new Uint8Array(data as [number]));\n        })\n        .catch(reject);\n    });\n  }\n\n  /**\n   * Convert the displayed score to MIDI\n   *\n   * Exports the currently loaded score as a MIDI file. The MIDI file will contain\n   * performance data including notes, tempo, dynamics, and instrument information.\n   * Note that some notation elements may not be represented in MIDI format.\n   *\n   * @returns A promise that resolves with a Uint8Array containing the MIDI file data\n   * @throws {Error} If no score is loaded or conversion fails\n   *\n   * @example\n   * // Export score as MIDI\n   * const midiData = await embed.getMIDI();\n   *\n   * // Save as file\n   * const blob = new Blob([midiData], { type: 'audio/midi' });\n   * const url = URL.createObjectURL(blob);\n   * const a = document.createElement('a');\n   * a.href = url;\n   * a.download = 'score.mid';\n   * a.click();\n   *\n   * @example\n   * // Play MIDI in browser (requires Web MIDI API)\n   * const midiData = await embed.getMIDI();\n   * // ... use with Web MIDI API or MIDI player library\n   */\n  getMIDI(): Promise<Uint8Array> {\n    return this.call('getMIDI').then(data => new Uint8Array(data as [number]));\n  }\n\n  /**\n   * Get the metadata of the score (for scores hosted on Flat)\n   *\n   * Retrieves metadata for scores that are hosted on Flat, including title, composer,\n   * collaborators, creation date, and other information available through Flat's API.\n   * This method only works for scores loaded via `loadFlatScore()`.\n   *\n   * @returns A promise that resolves with the score metadata object\n   * @throws {Error} If no Flat score is loaded or metadata is unavailable\n   *\n   * @example\n   * // Get metadata after loading a Flat score\n   * await embed.loadFlatScore('56ae21579a127715a02901a6');\n   * const metadata = await embed.getFlatScoreMetadata();\n   * console.log(`Title: ${metadata.title}`);\n   * console.log(`Created by: ${metadata.user.username}`);\n   *\n   * @see {@link https://flat.io/developers/api/reference/#operation/getScore}\n   */\n  getFlatScoreMetadata(): Promise<ScoreDetails> {\n    return this.call('getFlatScoreMetadata') as Promise<ScoreDetails>;\n  }\n\n  /**\n   * Get the embed configuration\n   *\n   * Retrieves the complete configuration object for the embed, including display\n   * settings, permissions, editor configuration, and enabled features.\n   *\n   * @returns A promise that resolves with the embed configuration object\n   * @throws {Error} If the configuration cannot be retrieved\n   *\n   * @example\n   * // Get current embed configuration\n   * const config = await embed.getEmbedConfig();\n   * console.log(`Mode: ${config.mode}`);\n   * console.log(`Controls enabled: ${config.controlsPlay}`);\n   */\n  getEmbedConfig(): Promise<Record<string, unknown>> {\n    return this.call('getEmbedConfig') as Promise<Record<string, unknown>>;\n  }\n\n  /**\n   * Set the editor configuration\n   *\n   * Updates the editor configuration for the embed. These settings control various\n   * aspects of the editor interface and behavior. The configuration is applied\n   * when the next score is loaded.\n   *\n   * @param editor - Editor configuration object that may include:\n   *   - displayMode: Score display mode\n   *   - toolsetId: Active toolset identifier\n   *   - hiddenTools: Array of tool identifiers to hide\n   *   - Additional editor-specific settings\n   * @returns A promise that resolves when the configuration is updated\n   * @throws {Error} If the configuration is invalid\n   *\n   * @example\n   * // Configure editor before loading a score\n   * await embed.setEditorConfig({\n   *   displayMode: 'responsive',\n   *   hiddenTools: ['note-duration', 'note-pitch']\n   * });\n   * await embed.loadFlatScore('56ae21579a127715a02901a6');\n   *\n   * @note This configuration persists across score loads until changed\n   */\n  setEditorConfig(editor: Record<string, unknown>): Promise<void> {\n    return this.call('setEditorConfig', editor) as Promise<void>;\n  }\n\n  /**\n   * Toggle fullscreen mode\n   *\n   * Switches the embed in or out of fullscreen mode. When in fullscreen, the embed\n   * expands to fill the entire screen, providing an immersive view of the score.\n   *\n   * @param active - true to enter fullscreen, false to exit fullscreen\n   * @returns A promise that resolves when the fullscreen state has changed\n   * @throws {Error} If fullscreen mode cannot be toggled (e.g., browser restrictions)\n   *\n   * @example\n   * // Enter fullscreen mode\n   * await embed.fullscreen(true);\n   *\n   * @example\n   * // Exit fullscreen mode\n   * await embed.fullscreen(false);\n   *\n   * @example\n   * // Toggle fullscreen with user interaction\n   * button.addEventListener('click', () => {\n   *   embed.fullscreen(true);\n   * });\n   *\n   * @note Fullscreen requests may require user interaction due to browser policies\n   */\n  fullscreen(active: boolean): Promise<void> {\n    return this.call('fullscreen', active) as Promise<void>;\n  }\n\n  /**\n   * Start playback\n   *\n   * Begins playing the score from the current cursor position. If playback was\n   * previously paused, it resumes from the pause position. If stopped, it starts\n   * from the beginning or the current cursor position.\n   *\n   * @returns A promise that resolves when playback has started\n   * @throws {Error} If no score is loaded or playback cannot start\n   *\n   * @example\n   * // Start playback\n   * await embed.play();\n   *\n   * @example\n   * // Play with event handling\n   * embed.on('play', () => console.log('Playback started'));\n   * await embed.play();\n   *\n   * @see {@link pause} - Pause playback\n   * @see {@link stop} - Stop playback\n   */\n  play(): Promise<void> {\n    return this.call('play') as Promise<void>;\n  }\n\n  /**\n   * Pause playback\n   *\n   * Pauses the score playback at the current position. The playback position\n   * is maintained, allowing you to resume from the same point using `play()`.\n   *\n   * @returns A promise that resolves when playback has been paused\n   * @throws {Error} If no score is loaded or playback cannot be paused\n   *\n   * @example\n   * // Pause playback\n   * await embed.pause();\n   *\n   * @example\n   * // Toggle play/pause\n   * if (isPlaying) {\n   *   await embed.pause();\n   * } else {\n   *   await embed.play();\n   * }\n   *\n   * @see {@link play} - Start or resume playback\n   * @see {@link stop} - Stop and reset playback\n   */\n  pause(): Promise<void> {\n    return this.call('pause') as Promise<void>;\n  }\n\n  /**\n   * Stop playback\n   *\n   * Stops the score playback and resets the playback position to the beginning\n   * of the score. Unlike `pause()`, the playback position is not maintained.\n   *\n   * @returns A promise that resolves when playback has been stopped\n   * @throws {Error} If no score is loaded or playback cannot be stopped\n   *\n   * @example\n   * // Stop playback\n   * await embed.stop();\n   *\n   * @example\n   * // Stop and restart from beginning\n   * await embed.stop();\n   * await embed.play(); // Starts from beginning\n   *\n   * @see {@link play} - Start playback\n   * @see {@link pause} - Pause playback\n   */\n  stop(): Promise<void> {\n    return this.call('stop') as Promise<void>;\n  }\n\n  /**\n   * Mute playback\n   *\n   * Mutes all audio output from the score playback. The playback continues\n   * but without sound. This is equivalent to setting the master volume to 0\n   * but preserves the previous volume setting.\n   *\n   * @returns A promise that resolves when audio has been muted\n   * @throws {Error} If muting fails\n   *\n   * @example\n   * // Mute audio\n   * await embed.mute();\n   *\n   * @example\n   * // Mute during playback\n   * await embed.play();\n   * await embed.mute();\n   *\n   * @see {@link setMasterVolume} - Set master volume level\n   * @note There is no unmute method; use setMasterVolume to restore audio\n   */\n  mute(): Promise<void> {\n    return this.call('mute') as Promise<void>;\n  }\n\n  /**\n   * Get the current master volume\n   *\n   * Retrieves the current master volume level for score playback.\n   *\n   * @returns A promise that resolves with the volume level (0-100)\n   * @throws {Error} If the volume cannot be retrieved\n   *\n   * @example\n   * // Get current volume\n   * const volume = await embed.getMasterVolume();\n   * console.log(`Current volume: ${volume}%`);\n   *\n   * @see {@link setMasterVolume} - Set the master volume\n   */\n  getMasterVolume(): Promise<number> {\n    return this.call('getMasterVolume') as Promise<number>;\n  }\n\n  /**\n   * Set the master volume\n   *\n   * Sets the master volume level for score playback. This affects all parts\n   * proportionally based on their individual volume settings.\n   *\n   * @param parameters - Volume settings\n   * @returns A promise that resolves when the volume has been set\n   * @throws {Error} If the volume value is invalid or cannot be set\n   *\n   * @example\n   * // Set volume to 50%\n   * await embed.setMasterVolume({ volume: 50 });\n   *\n   * @example\n   * // Mute audio\n   * await embed.setMasterVolume({ volume: 0 });\n   *\n   * @example\n   * // Maximum volume\n   * await embed.setMasterVolume({ volume: 100 });\n   *\n   * @see {@link getMasterVolume} - Get the current master volume\n   */\n  setMasterVolume(parameters: { volume: number }): Promise<void> {\n    return this.call('setMasterVolume', parameters) as Promise<void>;\n  }\n\n  /**\n   * Get the volume of a specific part\n   *\n   * Retrieves the current volume level for a specific instrument part in the score.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: The unique identifier of the part\n   * @returns A promise that resolves with the part's volume level (0-100)\n   * @throws {Error} If the part UUID is invalid or volume cannot be retrieved\n   *\n   * @example\n   * // Get volume for a specific part\n   * const parts = await embed.getParts();\n   * const violinVolume = await embed.getPartVolume({\n   *   partUuid: parts[0].uuid\n   * });\n   *\n   * @see {@link setPartVolume} - Set the volume for a part\n   * @see {@link getParts} - Get all parts information\n   */\n  getPartVolume(parameters: { partUuid: string }): Promise<number> {\n    return this.call('getPartVolume', parameters) as Promise<number>;\n  }\n\n  /**\n   * Set the volume of a specific part\n   *\n   * Sets the volume level for a specific instrument part in the score. Part volumes\n   * are independent but affected by the master volume.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: The unique identifier of the part\n   *   - `volume`: Volume level (0-100, where 0 is muted and 100 is maximum)\n   * @returns A promise that resolves when the volume has been set\n   * @throws {Error} If the part UUID or volume value is invalid\n   *\n   * @example\n   * // Set violin part to 75% volume\n   * const parts = await embed.getParts();\n   * await embed.setPartVolume({\n   *   partUuid: parts[0].uuid,\n   *   volume: 75\n   * });\n   *\n   * @example\n   * // Mute the bass part\n   * await embed.setPartVolume({\n   *   partUuid: bassPartUuid,\n   *   volume: 0\n   * });\n   *\n   * @see {@link getPartVolume} - Get the volume for a part\n   * @see {@link mutePart} - Mute a part\n   */\n  setPartVolume(parameters: { partUuid: string; volume: number }): Promise<void> {\n    return this.call('setPartVolume', parameters) as Promise<void>;\n  }\n\n  /**\n   * Mute a specific part\n   *\n   * Mutes the audio output for a specific instrument part. The part's volume\n   * setting is preserved and can be restored using `unmutePart()`.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: The unique identifier of the part to mute\n   * @returns A promise that resolves when the part has been muted\n   * @throws {Error} If the part UUID is invalid or muting fails\n   *\n   * @example\n   * // Mute the drums part\n   * const parts = await embed.getParts();\n   * const drumsPart = parts.find(p => p.instrument === 'drums');\n   * await embed.mutePart({ partUuid: drumsPart.uuid });\n   *\n   * @see {@link unmutePart} - Unmute a part\n   * @see {@link setPartVolume} - Set part volume to 0 (alternative)\n   */\n  mutePart(parameters: { partUuid: string }): Promise<void> {\n    return this.call('mutePart', parameters) as Promise<void>;\n  }\n\n  /**\n   * Unmute a specific part\n   *\n   * Restores the audio output for a previously muted part. The part returns\n   * to its previous volume level before it was muted.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: The unique identifier of the part to unmute\n   * @returns A promise that resolves when the part has been unmuted\n   * @throws {Error} If the part UUID is invalid or unmuting fails\n   *\n   * @example\n   * // Unmute a previously muted part\n   * await embed.unmutePart({ partUuid: drumsPart.uuid });\n   *\n   * @see {@link mutePart} - Mute a part\n   */\n  unmutePart(parameters: { partUuid: string }): Promise<void> {\n    return this.call('unmutePart', parameters) as Promise<void>;\n  }\n\n  /**\n   * Enable solo mode for a part\n   *\n   * Enables solo mode for a specific part, which mutes all other parts while\n   * keeping the selected part audible. Multiple parts can be in solo mode\n   * simultaneously.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: The unique identifier of the part to solo\n   * @returns A promise that resolves when solo mode has been enabled\n   * @throws {Error} If the part UUID is invalid or solo mode cannot be set\n   *\n   * @example\n   * // Solo the violin part\n   * const parts = await embed.getParts();\n   * const violinPart = parts.find(p => p.instrument === 'violin');\n   * await embed.setPartSoloMode({ partUuid: violinPart.uuid });\n   *\n   * @example\n   * // Solo multiple parts\n   * await embed.setPartSoloMode({ partUuid: violinUuid });\n   * await embed.setPartSoloMode({ partUuid: celloUuid });\n   *\n   * @see {@link unsetPartSoloMode} - Disable solo mode\n   * @see {@link getPartSoloMode} - Check solo mode status\n   */\n  setPartSoloMode(parameters: { partUuid: string }): Promise<void> {\n    return this.call('setPartSoloMode', parameters) as Promise<void>;\n  }\n\n  /**\n   * Disable solo mode for a part\n   *\n   * Disables solo mode for a specific part. If this was the only part in solo\n   * mode, all parts return to their normal volume/mute states. If other parts\n   * remain in solo mode, this part will be muted.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: The unique identifier of the part\n   * @returns A promise that resolves when solo mode has been disabled\n   * @throws {Error} If the part UUID is invalid or solo mode cannot be unset\n   *\n   * @example\n   * // Remove solo from a part\n   * await embed.unsetPartSoloMode({ partUuid: violinPart.uuid });\n   *\n   * @see {@link setPartSoloMode} - Enable solo mode\n   * @see {@link getPartSoloMode} - Check solo mode status\n   */\n  unsetPartSoloMode(parameters: { partUuid: string }): Promise<void> {\n    return this.call('unsetPartSoloMode', parameters) as Promise<void>;\n  }\n\n  /**\n   * Get the solo mode status of a part\n   *\n   * Checks whether a specific part is currently in solo mode.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: The unique identifier of the part\n   * @returns A promise that resolves with true if solo mode is enabled, false otherwise\n   * @throws {Error} If the part UUID is invalid\n   *\n   * @example\n   * // Check if violin is in solo mode\n   * const isSolo = await embed.getPartSoloMode({\n   *   partUuid: violinPart.uuid\n   * });\n   * if (isSolo) {\n   *   console.log('Violin is in solo mode');\n   * }\n   *\n   * @see {@link setPartSoloMode} - Enable solo mode\n   * @see {@link unsetPartSoloMode} - Disable solo mode\n   */\n  getPartSoloMode(parameters: { partUuid: string }): Promise<boolean> {\n    return this.call('getPartSoloMode', parameters) as Promise<boolean>;\n  }\n\n  /**\n   * Get the reverb level of a part\n   *\n   * Retrieves the current reverb (reverberation) effect level for a specific\n   * instrument part. Reverb adds spatial depth and ambience to the sound.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: The unique identifier of the part\n   * @returns A promise that resolves with the reverb level (0-100)\n   * @throws {Error} If the part UUID is invalid or reverb cannot be retrieved\n   *\n   * @example\n   * // Get reverb level for piano part\n   * const parts = await embed.getParts();\n   * const pianoPart = parts.find(p => p.instrument === 'piano');\n   * const reverb = await embed.getPartReverb({\n   *   partUuid: pianoPart.uuid\n   * });\n   * console.log(`Piano reverb: ${reverb}%`);\n   *\n   * @see {@link setPartReverb} - Set the reverb level\n   */\n  getPartReverb(parameters: { partUuid: string }): Promise<number> {\n    return this.call('getPartReverb', parameters) as Promise<number>;\n  }\n\n  /**\n   * Set the reverb level of a part\n   *\n   * Sets the reverb (reverberation) effect level for a specific instrument part.\n   * Higher values create more spacious, ambient sound.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: The unique identifier of the part\n   *   - `reverberation`: Reverb level (0-100, where 0 is dry and 100 is maximum reverb)\n   * @returns A promise that resolves when the reverb has been set\n   * @throws {Error} If the part UUID or reverb value is invalid\n   *\n   * @example\n   * // Add subtle reverb to piano\n   * await embed.setPartReverb({\n   *   partUuid: pianoPart.uuid,\n   *   reverberation: 30\n   * });\n   *\n   * @example\n   * // Remove reverb (dry sound)\n   * await embed.setPartReverb({\n   *   partUuid: pianoPart.uuid,\n   *   reverberation: 0\n   * });\n   *\n   * @see {@link getPartReverb} - Get the current reverb level\n   */\n  setPartReverb(parameters: { partUuid: string; reverberation: number }): Promise<void> {\n    return this.call('setPartReverb', parameters) as Promise<void>;\n  }\n\n  /**\n   * Configure an audio or video track\n   *\n   * Sets up a new audio or video track to synchronize with the score playback.\n   * This allows you to play backing tracks, reference recordings, or video\n   * alongside the score.\n   *\n   * @param parameters - Track configuration object (see ScoreTrackConfiguration type)\n   * @returns A promise that resolves when the track has been configured\n   * @throws {Error} If the track configuration is invalid\n   *\n   * @example\n   * // Configure an audio backing track\n   * await embed.setTrack({\n   *   id: 'backing-track-1',\n   *   type: 'audio',\n   *   url: 'https://example.com/backing-track.mp3',\n   *   synchronizationPoints: [\n   *     { type: 'measure', measure: 0, time: 0 },\n   *     { type: 'measure', measure: 16, time: 32.5 }\n   *   ]\n   * });\n   *\n   * @see {@link useTrack} - Enable a configured track\n   * @see {@link seekTrackTo} - Seek to a position in the track\n   */\n  setTrack(parameters: ScoreTrackConfiguration): Promise<void> {\n    return this.call('setTrack', parameters as unknown as Record<string, unknown>) as Promise<void>;\n  }\n\n  /**\n   * Enable a previously configured track\n   *\n   * Activates a track that was previously configured with `setTrack()`. Only one\n   * track can be active at a time.\n   *\n   * @param parameters - Object containing:\n   *   - `id`: The identifier of the track to enable\n   * @returns A promise that resolves when the track has been enabled\n   * @throws {Error} If the track ID is invalid or track cannot be enabled\n   *\n   * @example\n   * // Enable a configured backing track\n   * await embed.useTrack({ id: 'backing-track-1' });\n   *\n   * @example\n   * // Switch between multiple tracks\n   * await embed.useTrack({ id: 'practice-tempo' });\n   * // Later...\n   * await embed.useTrack({ id: 'full-tempo' });\n   *\n   * @see {@link setTrack} - Configure a new track\n   */\n  useTrack(parameters: { id: string }): Promise<void> {\n    return this.call('useTrack', parameters) as Promise<void>;\n  }\n\n  /**\n   * Seek to a position in the audio track\n   *\n   * Moves the playback position of the currently active audio/video track to\n   * a specific time. This is useful for synchronizing with score playback or\n   * jumping to specific sections.\n   *\n   * @param parameters - Object containing:\n   *   - `time`: Time position in seconds\n   * @returns A promise that resolves when seeking is complete\n   * @throws {Error} If no track is active or seeking fails\n   *\n   * @example\n   * // Seek to 30 seconds\n   * await embed.seekTrackTo({ time: 30 });\n   *\n   * @example\n   * // Seek to beginning\n   * await embed.seekTrackTo({ time: 0 });\n   *\n   * @see {@link setTrack} - Configure a track\n   * @see {@link useTrack} - Enable a track\n   */\n  seekTrackTo(parameters: { time: number }): Promise<void> {\n    return this.call('seekTrackTo', parameters) as Promise<void>;\n  }\n\n  /**\n   * Print the score\n   *\n   * Opens the browser's print dialog to print the currently loaded score. The score\n   * is formatted for optimal printing with proper page breaks and sizing.\n   *\n   * @returns A promise that resolves when the print dialog has been opened\n   * @throws {Error} If no score is loaded or printing cannot be initiated\n   *\n   * @example\n   * // Print the current score\n   * await embed.print();\n   *\n   * @example\n   * // Add print button\n   * document.getElementById('printBtn').addEventListener('click', () => {\n   *   embed.print();\n   * });\n   *\n   * @note The actual printing is controlled by the browser's print dialog\n   */\n  print(): Promise<void> {\n    return this.call('print') as Promise<void>;\n  }\n\n  /**\n   * Get the current zoom ratio\n   *\n   * Retrieves the current zoom level of the score display. The zoom level affects\n   * how large the notation appears on screen.\n   *\n   * @returns A promise that resolves with the zoom ratio (0.5 to 3)\n   * @throws {Error} If the zoom level cannot be retrieved\n   *\n   * @example\n   * // Get current zoom level\n   * const zoom = await embed.getZoom();\n   * console.log(`Current zoom: ${zoom * 100}%`);\n   *\n   * @see {@link setZoom} - Set the zoom level\n   * @see {@link getAutoZoom} - Check if auto-zoom is enabled\n   */\n  getZoom(): Promise<number> {\n    return this.call('getZoom') as Promise<number>;\n  }\n\n  /**\n   * Set the zoom ratio\n   *\n   * Sets a specific zoom level for the score display. Setting a manual zoom level\n   * automatically disables auto-zoom mode.\n   *\n   * @param zoom - The zoom ratio (0.5 to 3)\n   *   - 0.5 = 50% (minimum zoom)\n   *   - 1 = 100% (normal size)\n   *   - 3 = 300% (maximum zoom)\n   * @returns A promise that resolves with the actual zoom ratio applied\n   * @throws {Error} If the zoom value is outside the valid range\n   *\n   * @example\n   * // Set zoom to 150%\n   * await embed.setZoom(1.5);\n   *\n   * @example\n   * // Zoom in/out buttons\n   * const zoomIn = async () => {\n   *   const current = await embed.getZoom();\n   *   await embed.setZoom(Math.min(current + 0.1, 3));\n   * };\n   *\n   * @see {@link getZoom} - Get current zoom level\n   * @see {@link setAutoZoom} - Enable automatic zoom\n   */\n  setZoom(zoom: number): Promise<number> {\n    return this.call('setZoom', zoom) as Promise<number>;\n  }\n\n  /**\n   * Get the auto-zoom status\n   *\n   * Checks whether auto-zoom mode is currently enabled. When auto-zoom is active,\n   * the score automatically adjusts its zoom level to fit the available space.\n   *\n   * @returns A promise that resolves with true if auto-zoom is enabled, false otherwise\n   * @throws {Error} If the status cannot be retrieved\n   *\n   * @example\n   * // Check auto-zoom status\n   * const isAutoZoom = await embed.getAutoZoom();\n   * if (isAutoZoom) {\n   *   console.log('Score will auto-fit to container');\n   * }\n   *\n   * @see {@link setAutoZoom} - Enable or disable auto-zoom\n   */\n  getAutoZoom(): Promise<boolean> {\n    return this.call('getAutoZoom') as Promise<boolean>;\n  }\n\n  /**\n   * Enable or disable auto-zoom\n   *\n   * Controls the auto-zoom feature. When enabled, the score automatically adjusts\n   * its zoom level to fit the available container width. When disabled, the zoom\n   * level remains fixed at the last set value.\n   *\n   * @param state - true to enable auto-zoom, false to disable\n   * @returns A promise that resolves with the new auto-zoom state\n   * @throws {Error} If auto-zoom cannot be toggled\n   *\n   * @example\n   * // Enable auto-zoom\n   * await embed.setAutoZoom(true);\n   *\n   * @example\n   * // Disable auto-zoom and set fixed zoom\n   * await embed.setAutoZoom(false);\n   * await embed.setZoom(1.2);\n   *\n   * @see {@link getAutoZoom} - Check current auto-zoom status\n   * @see {@link setZoom} - Set a specific zoom level\n   */\n  setAutoZoom(state: boolean): Promise<boolean> {\n    return this.call('setAutoZoom', state) as Promise<boolean>;\n  }\n\n  /**\n   * Set focus to the score\n   *\n   * Gives keyboard focus to the score iframe, allowing keyboard shortcuts and\n   * navigation to work. This is useful when embedding multiple interactive elements\n   * on a page.\n   *\n   * @returns A promise that resolves when focus has been set\n   *\n   * @example\n   * // Focus score for keyboard interaction\n   * await embed.focusScore();\n   *\n   * @example\n   * // Focus score when user clicks a button\n   * document.getElementById('editBtn').addEventListener('click', () => {\n   *   embed.focusScore();\n   * });\n   */\n  focusScore(): Promise<void> {\n    return this.call('focusScore') as Promise<void>;\n  }\n\n  /**\n   * Get the cursor position\n   *\n   * Retrieves the current position of the cursor in the score, including the part,\n   * measure, voice, and note location.\n   *\n   * @returns A promise that resolves with the cursor position object\n   * @throws {Error} If cursor position cannot be retrieved\n   *\n   * @example\n   * // Get current cursor position\n   * const pos = await embed.getCursorPosition();\n   * console.log(`Cursor at measure ${pos.measureIdx + 1}`);\n   *\n   * @see {@link setCursorPosition} - Set cursor position\n   * @see {@link goLeft} - Move cursor left\n   * @see {@link goRight} - Move cursor right\n   */\n  getCursorPosition(): Promise<NoteCursorPosition> {\n    return this.call('getCursorPosition') as unknown as Promise<NoteCursorPosition>;\n  }\n\n  /**\n   * Set the cursor position\n   *\n   * Moves the cursor to a specific position in the score. You can specify any\n   * combination of part, measure, voice, staff, and note indices. Unspecified\n   * values remain at their current position.\n   *\n   * @param position - New cursor position with optional fields:\n   *   - `partIdx`: Target part index (optional)\n   *   - `measureIdx`: Target measure index (optional)\n   *   - `voiceIdx`: Target voice index (optional)\n   *   - `noteIdx`: Target note index (optional)\n   *   - `staffIdx`: Target staff index (optional)\n   * @returns A promise that resolves when the cursor has been moved\n   * @throws {Error} If the position is invalid or cursor cannot be moved\n   *\n   * @example\n   * // Move to beginning of measure 5\n   * await embed.setCursorPosition({\n   *   measureIdx: 4,  // 0-based index\n   *   noteIdx: 0\n   * });\n   *\n   * @example\n   * // Move to second voice of current measure\n   * await embed.setCursorPosition({ voiceIdx: 1 });\n   *\n   * @see {@link getCursorPosition} - Get current position\n   */\n  setCursorPosition(position: NoteCursorPositionOptional): Promise<void> {\n    return this.call('setCursorPosition', position as Record<string, unknown>) as Promise<void>;\n  }\n\n  /**\n   * Get information about all parts\n   *\n   * Retrieves detailed information about all instrument parts in the score,\n   * including their names, instruments, and unique identifiers.\n   *\n   * @returns A promise that resolves with an array of part configurations\n   * @throws {Error} If no score is loaded or parts cannot be retrieved\n   *\n   * @example\n   * // Get all parts\n   * const parts = await embed.getParts();\n   * parts.forEach(part => {\n   *   console.log(`${part.name}: ${part.uuid}`);\n   * });\n   *\n   * @example\n   * // Find specific instrument\n   * const parts = await embed.getParts();\n   * const violin = parts.find(p => p.instrument === 'violin');\n   *\n   * @see {@link getDisplayedParts} - Get currently visible parts\n   * @see {@link setDisplayedParts} - Choose which parts to display\n   */\n  getParts(): Promise<PartConfiguration[]> {\n    return this.call('getParts') as Promise<PartConfiguration[]>;\n  }\n\n  /**\n   * Get the currently displayed parts\n   *\n   * Retrieves information about which parts are currently visible in the score.\n   * Some parts may be hidden for focused practice or simplified viewing.\n   *\n   * @returns A promise that resolves with an array of currently displayed part configurations\n   * @throws {Error} If displayed parts cannot be retrieved\n   *\n   * @example\n   * // Check which parts are visible\n   * const displayedParts = await embed.getDisplayedParts();\n   * console.log(`Showing ${displayedParts.length} parts`);\n   *\n   * @see {@link getParts} - Get all parts in the score\n   * @see {@link setDisplayedParts} - Change which parts are visible\n   */\n  getDisplayedParts(): Promise<PartConfiguration[]> {\n    return this.call('getDisplayedParts') as Promise<PartConfiguration[]>;\n  }\n\n  /**\n   * Set which parts to display\n   *\n   * Controls which instrument parts are visible in the score. Parts can be\n   * identified by their UUID, index, name, or abbreviation. Hidden parts\n   * are not displayed but still play during playback unless muted.\n   *\n   * @param parts - Array of part identifiers. Each can be:\n   *   - UUID (recommended): The unique identifier\n   *   - Index: Numeric position (0-based)\n   *   - Name: Full part name (e.g., \"Violin\")\n   *   - Abbreviation: Short name (e.g., \"Vln\")\n   * @returns A promise that resolves when parts visibility has been updated\n   * @throws {Error} If part identifiers are invalid\n   *\n   * @example\n   * // Show only violin and piano parts by UUID\n   * const parts = await embed.getParts();\n   * const violin = parts.find(p => p.instrument === 'violin');\n   * const piano = parts.find(p => p.instrument === 'piano');\n   * await embed.setDisplayedParts([violin.uuid, piano.uuid]);\n   *\n   * @example\n   * // Show parts by index\n   * await embed.setDisplayedParts(['0', '2', '3']);\n   *\n   * @example\n   * // Show all parts\n   * const allParts = await embed.getParts();\n   * await embed.setDisplayedParts(allParts.map(p => p.uuid));\n   *\n   * @see {@link getParts} - Get all available parts\n   * @see {@link getDisplayedParts} - Check which parts are visible\n   */\n  setDisplayedParts(parts: string[]): Promise<void> {\n    return this.call('setDisplayedParts', parts) as Promise<void>;\n  }\n\n  /**\n   * Get the number of measures in the score\n   *\n   * Retrieves the total count of measures (bars) in the currently loaded score.\n   *\n   * @returns A promise that resolves with the number of measures\n   * @throws {Error} If no score is loaded\n   *\n   * @example\n   * // Get measure count\n   * const measureCount = await embed.getNbMeasures();\n   * console.log(`This score has ${measureCount} measures`);\n   *\n   * @see {@link getMeasuresUuids} - Get measure identifiers\n   * @see {@link getMeasureDetails} - Get detailed measure information\n   */\n  getNbMeasures(): Promise<number> {\n    return this.call('getNbMeasures') as Promise<number>;\n  }\n\n  /**\n   * Get the measure UUIDs of the score\n   *\n   * Retrieves the unique identifiers for all measures in the score. These UUIDs\n   * can be used to reference specific measures in other API calls.\n   *\n   * @returns A promise that resolves with an array of measure UUIDs in order\n   * @throws {Error} If no score is loaded\n   *\n   * @example\n   * // Get all measure UUIDs\n   * const measureUuids = await embed.getMeasuresUuids();\n   * console.log(`First measure UUID: ${measureUuids[0]}`);\n   *\n   * @see {@link getNbMeasures} - Get the total number of measures\n   * @see {@link getMeasureDetails} - Get details for a specific measure\n   */\n  getMeasuresUuids(): Promise<string[]> {\n    return this.call('getMeasuresUuids') as Promise<string[]>;\n  }\n\n  /**\n   * Get detailed measure information\n   *\n   * Retrieves comprehensive information about the current measure at the cursor\n   * position, including time signature, key signature, tempo, and other properties.\n   *\n   * @returns A promise that resolves with the measure details\n   * @throws {Error} If no score is loaded or details cannot be retrieved\n   *\n   * @example\n   * // Get current measure details\n   * const details = await embed.getMeasureDetails();\n   * console.log(`Time signature: ${details.time.beats}/${details.time['beat-type']}`);\n   * console.log(`Key signature: ${details.key.fifths} sharps/flats`);\n   * console.log(`Tempo: ${details.tempo.bpm} BPM`);\n   *\n   * @see {@link getNbMeasures} - Get measure count\n   * @see {@link getMeasuresUuids} - Get measure identifiers\n   */\n  getMeasureDetails(): Promise<MeasureDetails> {\n    return this.call('getMeasureDetails') as Promise<MeasureDetails>;\n  }\n\n  /**\n   * Get the number of parts in the score\n   *\n   * Retrieves the total count of instrument parts in the currently loaded score.\n   *\n   * @returns A promise that resolves with the number of parts\n   * @throws {Error} If no score is loaded\n   *\n   * @example\n   * // Get part count\n   * const partCount = await embed.getNbParts();\n   * console.log(`Score has ${partCount} instruments`);\n   *\n   * @see {@link getParts} - Get detailed part information\n   * @see {@link getPartsUuids} - Get part identifiers\n   */\n  getNbParts(): Promise<number> {\n    return this.call('getNbParts') as Promise<number>;\n  }\n\n  /**\n   * Get the part UUIDs of the score\n   *\n   * Retrieves the unique identifiers for all parts in the score. These UUIDs\n   * are used to reference specific parts in volume, mute, and other part-specific\n   * operations.\n   *\n   * @returns A promise that resolves with an array of part UUIDs in order\n   * @throws {Error} If no score is loaded\n   *\n   * @example\n   * // Get all part UUIDs\n   * const partUuids = await embed.getPartsUuids();\n   * // Mute the first part\n   * await embed.mutePart({ partUuid: partUuids[0] });\n   *\n   * @see {@link getNbParts} - Get the total number of parts\n   * @see {@link getParts} - Get detailed part information\n   */\n  getPartsUuids(): Promise<string[]> {\n    return this.call('getPartsUuids') as Promise<string[]>;\n  }\n\n  /**\n   * Get voice UUIDs for a specific measure\n   *\n   * Retrieves the unique identifiers of all voices present in a specific measure\n   * of a part. Voices represent independent melodic lines within a part.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: UUID of the part\n   *   - `measureUuid`: UUID of the measure\n   * @returns A promise that resolves with an array of voice UUIDs\n   * @throws {Error} If the part or measure UUID is invalid\n   *\n   * @example\n   * // Get voices in first measure of piano part\n   * const parts = await embed.getParts();\n   * const measures = await embed.getMeasuresUuids();\n   * const voices = await embed.getMeasureVoicesUuids({\n   *   partUuid: parts[0].uuid,\n   *   measureUuid: measures[0]\n   * });\n   * console.log(`Found ${voices.length} voices`);\n   *\n   * @see {@link getMeasureNbNotes} - Count notes in a voice\n   */\n  getMeasureVoicesUuids(parameters: { partUuid: string; measureUuid: string }): Promise<string[]> {\n    return this.call('getMeasureVoicesUuids', parameters) as Promise<string[]>;\n  }\n\n  /**\n   * Get the number of notes in a voice\n   *\n   * Counts the total number of notes (including rests) in a specific voice\n   * within a measure. This is useful for iterating through notes or determining\n   * voice complexity.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: UUID of the part\n   *   - `measureUuid`: UUID of the measure\n   *   - `voiceUuid`: UUID of the voice\n   * @returns A promise that resolves with the number of notes\n   * @throws {Error} If any UUID is invalid\n   *\n   * @example\n   * // Count notes in first voice\n   * const noteCount = await embed.getMeasureNbNotes({\n   *   partUuid: partUuid,\n   *   measureUuid: measureUuid,\n   *   voiceUuid: voiceUuids[0]\n   * });\n   *\n   * @see {@link getNoteData} - Get details about specific notes\n   * @see {@link getMeasureVoicesUuids} - Get voice UUIDs\n   */\n  getMeasureNbNotes(parameters: {\n    partUuid: string;\n    measureUuid: string;\n    voiceUuid: string;\n  }): Promise<number> {\n    return this.call('getMeasureNbNotes', parameters) as Promise<number>;\n  }\n\n  /**\n   * Get information about a specific note\n   *\n   * Retrieves detailed information about a note at a specific position, including\n   * pitch, duration, articulations, and other musical properties.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: UUID of the part\n   *   - `measureUuid`: UUID of the measure\n   *   - `voiceUuid`: UUID of the voice\n   *   - `noteIdx`: Index of the note (0-based)\n   * @returns A promise that resolves with the note details\n   * @throws {Error} If the position is invalid or note not found\n   *\n   * @example\n   * // Get first note details\n   * const noteData = await embed.getNoteData({\n   *   partUuid: partUuid,\n   *   measureUuid: measureUuid,\n   *   voiceUuid: voiceUuid,\n   *   noteIdx: 0\n   * });\n   * console.log(`Note: ${noteData.pitch}`);\n   *\n   * @see {@link getMeasureNbNotes} - Get total notes in voice\n   */\n  getNoteData(parameters: {\n    partUuid: string;\n    measureUuid: string;\n    voiceUuid: string;\n    noteIdx: number;\n  }): Promise<NoteDetails> {\n    return this.call('getNoteData', parameters) as Promise<NoteDetails>;\n  }\n\n  /**\n   * Convert playback position to note index\n   *\n   * Finds the note index that corresponds to a specific playback position.\n   * This is useful for synchronizing visual elements with audio playback.\n   *\n   * @param parameters - Object containing:\n   *   - `partUuid`: UUID of the part\n   *   - `voiceUuid`: UUID of the voice\n   *   - `playbackPosition`: Position object with measure and beat information\n   * @returns A promise that resolves with the note index (0-based)\n   * @throws {Error} If the position cannot be mapped to a note\n   *\n   * @example\n   * // Find note at current playback position\n   * const noteIdx = await embed.playbackPositionToNoteIdx({\n   *   partUuid: partUuid,\n   *   voiceUuid: voiceUuid,\n   *   playbackPosition: currentPosition\n   * });\n   *\n   * @see {@link getNoteData} - Get note details at index\n   */\n  playbackPositionToNoteIdx(parameters: {\n    partUuid: string;\n    voiceUuid: string;\n    playbackPosition: PlaybackPosition;\n  }): Promise<number> {\n    return this.call('playbackPositionToNoteIdx', parameters) as Promise<number>;\n  }\n\n  /**\n   * Get note details at cursor position\n   *\n   * Retrieves detailed information about the note at the current cursor position,\n   * including pitch, duration, and musical attributes.\n   *\n   * @returns A promise that resolves with the note details at cursor\n   * @throws {Error} If no note is at the cursor position\n   *\n   * @example\n   * // Get details of note at cursor\n   * const noteDetails = await embed.getNoteDetails();\n   * console.log(`Current note: ${noteDetails.pitch}`);\n   *\n   * @see {@link getCursorPosition} - Get cursor position\n   * @see {@link getNoteData} - Get note at specific position\n   */\n  getNoteDetails(): Promise<NoteDetails> {\n    return this.call('getNoteDetails') as Promise<NoteDetails>;\n  }\n\n  /**\n   * Move cursor left\n   *\n   * Moves the cursor to the previous item in the score (note, rest, or grace note).\n   * Navigation follows the reading order of the score.\n   *\n   * @param mute - If false, plays the note at the new cursor position (default: false)\n   * @returns A promise that resolves when the cursor has moved\n   * @throws {Error} If cursor cannot move (e.g., at beginning of score)\n   *\n   * @example\n   * // Move left silently\n   * await embed.goLeft(true);\n   *\n   * @example\n   * // Move left and play the note\n   * await embed.goLeft(false);\n   *\n   * @see {@link goRight} - Move cursor right\n   * @see {@link setCursorPosition} - Set specific position\n   */\n  goLeft(mute: boolean = false): Promise<void> {\n    return this.call('goLeft', { mute }) as Promise<void>;\n  }\n\n  /**\n   * Move cursor right\n   *\n   * Moves the cursor to the next item in the score (note, rest, or grace note).\n   * Navigation follows the reading order of the score.\n   *\n   * @param mute - If false, plays the note at the new cursor position (default: false)\n   * @returns A promise that resolves when the cursor has moved\n   * @throws {Error} If cursor cannot move (e.g., at end of score)\n   *\n   * @example\n   * // Move right and play the note\n   * await embed.goRight();\n   *\n   * @example\n   * // Navigate through score silently\n   * for (let i = 0; i < 4; i++) {\n   *   await embed.goRight(true);\n   * }\n   *\n   * @see {@link goLeft} - Move cursor left\n   * @see {@link setCursorPosition} - Set specific position\n   */\n  goRight(mute: boolean = false): Promise<void> {\n    return this.call('goRight', { mute }) as Promise<void>;\n  }\n\n  /**\n   * Get the metronome mode\n   *\n   * Retrieves the current metronome setting, which controls when the metronome\n   * clicks are played during playback.\n   *\n   * @returns A promise that resolves with the metronome mode\n   * @throws {Error} If metronome mode cannot be retrieved\n   *\n   * @example\n   * // Check current metronome setting\n   * const mode = await embed.getMetronomeMode();\n   * switch(mode) {\n   *   case 0: console.log('Count-in only'); break;\n   *   case 1: console.log('Continuous'); break;\n   *   case 2: console.log('Disabled'); break;\n   * }\n   *\n   * @see {@link setMetronomeMode} - Change metronome mode\n   */\n  getMetronomeMode(): Promise<MetronomeMode> {\n    return this.call('getMetronomeMode') as Promise<MetronomeMode>;\n  }\n\n  /**\n   * Set the metronome mode\n   *\n   * Controls when metronome clicks are played during score playback.\n   *\n   * @param mode - The metronome mode:\n   *   - 0: COUNT_IN - Metronome plays only during count-in before playback\n   *   - 1: CONTINUOUS - Metronome plays throughout the entire playback\n   *   - 2: DISABLED - Metronome is completely disabled\n   * @returns A promise that resolves when the mode has been set\n   * @throws {Error} If the mode value is invalid\n   *\n   * @example\n   * // Enable continuous metronome\n   * await embed.setMetronomeMode(1);\n   *\n   * @example\n   * // Use count-in only\n   * await embed.setMetronomeMode(0);\n   *\n   * @example\n   * // Disable metronome\n   * await embed.setMetronomeMode(2);\n   *\n   * @see {@link getMetronomeMode} - Get current mode\n   */\n  setMetronomeMode(mode: MetronomeMode): Promise<void> {\n    return this.call('setMetronomeMode', { mode }) as Promise<void>;\n  }\n\n  /**\n   * Get the playback speed\n   *\n   * Retrieves the current playback speed multiplier. Normal speed is 1.0.\n   *\n   * @returns A promise that resolves with the speed multiplier (0.2 to 2.0)\n   * @throws {Error} If speed cannot be retrieved\n   *\n   * @example\n   * // Get current playback speed\n   * const speed = await embed.getPlaybackSpeed();\n   * console.log(`Playing at ${speed * 100}% speed`);\n   *\n   * @see {@link setPlaybackSpeed} - Change playback speed\n   */\n  getPlaybackSpeed(): Promise<number> {\n    return this.call('getPlaybackSpeed') as Promise<number>;\n  }\n\n  /**\n   * Set the playback speed\n   *\n   * Adjusts the playback speed without affecting pitch. Useful for practice\n   * at slower or faster tempos.\n   *\n   * @param speed - Speed multiplier (0.2 to 2.0):\n   *   - 0.2: 20% speed (very slow)\n   *   - 1.0: Normal speed (100%)\n   *   - 2.0: Double speed (200%)\n   * @returns A promise that resolves when speed has been set\n   * @throws {Error} If speed is outside valid range\n   *\n   * @example\n   * // Slow down for practice\n   * await embed.setPlaybackSpeed(0.5);\n   *\n   * @example\n   * // Return to normal speed\n   * await embed.setPlaybackSpeed(1.0);\n   *\n   * @example\n   * // Speed up playback\n   * await embed.setPlaybackSpeed(1.5);\n   *\n   * @see {@link getPlaybackSpeed} - Get current speed\n   */\n  setPlaybackSpeed(speed: number): Promise<void> {\n    return this.call('setPlaybackSpeed', { speed }) as Promise<void>;\n  }\n\n  /**\n   * Scroll to cursor position\n   *\n   * Scrolls the score view to ensure the cursor is visible on screen. This is\n   * useful after programmatically moving the cursor or when the cursor moves\n   * out of view during navigation.\n   *\n   * @returns A promise that resolves when scrolling has been initiated\n   * @throws {Error} If scrolling fails\n   *\n   * @example\n   * // Move cursor and scroll to it\n   * await embed.setCursorPosition({ measureIdx: 20 });\n   * await embed.scrollToCursor();\n   *\n   * @example\n   * // Ensure cursor visible after navigation\n   * for (let i = 0; i < 10; i++) {\n   *   await embed.goRight();\n   * }\n   * await embed.scrollToCursor();\n   *\n   * @note Scrolling is performed asynchronously and may not complete before the promise resolves\n   * @see {@link setCursorPosition} - Set cursor position\n   */\n  scrollToCursor(): Promise<void> {\n    return this.call('scrollToCursor') as Promise<void>;\n  }\n}\n\nexport default Embed;\n"],"names":["EmbedCallback","embed","__publicField","name","resolve","reject","event","callback","idx","data","promise","postMessage","method","parameters","message","parseMessage","normalizeElement","element","container","iframe","buildIframeUrl","url","urlParameters","qs","k","createEmbedIframe","embeds","embedsReady","Embed","normalizedElement","iframeElement","onReady","onMessage","score","options","editor","active","zoom","state","position","parts","mute","mode","speed"],"mappings":"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"}