{"version":3,"sources":["../src/index.ts","../src/pitch.ts","../src/dom.ts","../src/gpx-parser.ts","../src/gp5-parser.ts","../src/gp3-parser.ts","../src/tab-parser.ts"],"sourcesContent":["/**\n * Copyright 2026 Emilien Bevierre\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * guitarpro-parser — Pure JavaScript parser for Guitar Pro files.\n *\n * Supports .gpx (GP6), .gp (GP7+), .gp5 (GP5), and .gp3 (GP3) formats.\n * Works in both browser and Node.js environments.\n *\n * @example\n * ```ts\n * import { parseTabFile } from 'guitarpro-parser';\n * import { readFileSync } from 'fs';\n *\n * const data = new Uint8Array(readFileSync('song.gp'));\n * const song = parseTabFile(data);\n * console.log(song.title, song.artist, song.tracks.length);\n * ```\n */\n\n// Primary API\nexport { parseTabFile, detectFormat } from './tab-parser.js';\n\n// Format-specific parsers\nexport { parseGpxFile, gpifToTabSong, durationToBeats, beatDurationMs, musicalBeatPosition, barMusicalBeatCount } from './gpx-parser.js';\nexport { parseGp5File } from './gp5-parser.js';\nexport { parseGp3File } from './gp3-parser.js';\n\n// Types\nexport type {\n\tDuration,\n\tTabNote,\n\tTabBeat,\n\tTabBar,\n\tTabTrack,\n\tTabSong\n} from './types.js';\n\n// Pitch utilities\nexport type { PitchClass, Accidental, Note } from './pitch.js';\nexport { noteFromPitchClass, midiToPitchClass } from './pitch.js';\n","/**\n * Copyright 2026 Emilien Bevierre\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Minimal pitch utilities — inlined from GuitarWeaver's pitch.ts to make\n * this package fully self-contained with zero external dependencies.\n */\n\n/** Chromatic pitch class: 0 = C, 1 = C#/Db, ..., 11 = B */\nexport type PitchClass = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;\n\nexport type Accidental = 'sharp' | 'flat' | 'natural';\n\nexport interface Note {\n\tpitchClass: PitchClass;\n\tname: string;\n\taccidental: Accidental;\n\toctave?: number;\n}\n\nconst SHARP_NAMES: Record<PitchClass, string> = {\n\t0: 'C',\n\t1: 'C#',\n\t2: 'D',\n\t3: 'D#',\n\t4: 'E',\n\t5: 'F',\n\t6: 'F#',\n\t7: 'G',\n\t8: 'G#',\n\t9: 'A',\n\t10: 'A#',\n\t11: 'B'\n};\n\nconst FLAT_NAMES: Record<PitchClass, string> = {\n\t0: 'C',\n\t1: 'Db',\n\t2: 'D',\n\t3: 'Eb',\n\t4: 'E',\n\t5: 'F',\n\t6: 'Gb',\n\t7: 'G',\n\t8: 'Ab',\n\t9: 'A',\n\t10: 'Bb',\n\t11: 'B'\n};\n\nconst NATURAL_PITCH_CLASSES = new Set<PitchClass>([0, 2, 4, 5, 7, 9, 11]);\n\nfunction resolveAccidental(pc: PitchClass, preferFlats: boolean): Accidental {\n\tif (NATURAL_PITCH_CLASSES.has(pc)) return 'natural';\n\treturn preferFlats ? 'flat' : 'sharp';\n}\n\n/** Builds a Note from a pitch class, with optional octave and flat preference. */\nexport function noteFromPitchClass(\n\tpc: PitchClass,\n\tpreferFlats = false,\n\toctave?: number\n): Note {\n\tconst name = preferFlats ? FLAT_NAMES[pc] : SHARP_NAMES[pc];\n\treturn {\n\t\tpitchClass: pc,\n\t\tname,\n\t\taccidental: resolveAccidental(pc, preferFlats),\n\t\toctave\n\t};\n}\n\n/** Converts MIDI note number to PitchClass. */\nexport function midiToPitchClass(midi: number): PitchClass {\n\treturn (((midi % 12) + 12) % 12) as PitchClass;\n}\n","/**\n * Copyright 2026 Emilien Bevierre\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * DOMParser abstraction — uses browser-native DOMParser when available,\n * falls back to linkedom for Node.js environments.\n */\n\ntype DOMParserConstructor = new () => DOMParser;\n\n/** Returns a DOMParser constructor that works in both browser and Node.js. */\nexport function getDOMParser(): DOMParserConstructor {\n\tif (typeof globalThis.DOMParser !== 'undefined') {\n\t\treturn globalThis.DOMParser;\n\t}\n\n\t// Node.js: use linkedom (provides full DOM with querySelector support)\n\ttry {\n\t\t// eslint-disable-next-line @typescript-eslint/no-require-imports\n\t\tconst linkedom = require('linkedom');\n\t\treturn linkedom.DOMParser as DOMParserConstructor;\n\t} catch {\n\t\tthrow new Error(\n\t\t\t'DOMParser is not available. In Node.js, install linkedom: npm install linkedom'\n\t\t);\n\t}\n}\n","/**\n * Copyright 2026 Emilien Bevierre\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * GPX parser : decodes Guitar Pro (.gpx) binary files and transforms them\n * directly into TabSong structures. Pure, zero native dependencies.\n *\n * Pipeline: Uint8Array → BCFZ/BCFS decode → extract score.gpif XML → DOMParser → TabSong\n */\n\nimport type { PitchClass, Note } from './pitch.js';\nimport { noteFromPitchClass, midiToPitchClass } from './pitch.js';\nimport type {\n\tDuration,\n\tTabNote,\n\tTabBeat,\n\tTabBar,\n\tTabTrack,\n\tTabSong\n} from './types.js';\nimport { getDOMParser } from './dom.js';\n\n// ---------------------------------------------------------------------------\n// Duration helpers (public — used by playback engine)\n// ---------------------------------------------------------------------------\n\n/** Maps Duration enum to beat fraction (quarter note = 1.0). */\nconst DURATION_BEATS: Record<string, number> = {\n\twhole: 4,\n\thalf: 2,\n\tquarter: 1,\n\teighth: 0.5,\n\t'16th': 0.25,\n\t'32nd': 0.125,\n\t'64th': 0.0625,\n\t'128th': 0.03125\n};\n\n/** Converts a rhythm value to a beat fraction accounting for dots and tuplets. */\nexport function durationToBeats(\n\tduration: Duration,\n\tdotCount: number,\n\ttuplet: { num: number; den: number } | null\n): number {\n\tlet beats = DURATION_BEATS[duration] ?? 1;\n\n\t// Augmentation dots: each dot adds half of the previous value\n\tlet dotValue = beats;\n\tfor (let i = 0; i < dotCount; i++) {\n\t\tdotValue /= 2;\n\t\tbeats += dotValue;\n\t}\n\n\t// Tuplet: e.g. triplet = 3 notes in the space of 2 → multiply by den/num\n\tif (tuplet && tuplet.num > 0) {\n\t\tbeats *= tuplet.den / tuplet.num;\n\t}\n\n\treturn beats;\n}\n\n/** Computes the duration in milliseconds for a beat at its tempo. */\nexport function beatDurationMs(beat: TabBeat): number {\n\tconst beatFraction = durationToBeats(beat.duration, beat.dotted, beat.tuplet);\n\tconst quarterNoteMs = 60000 / beat.tempo;\n\treturn beatFraction * quarterNoteMs;\n}\n\n/**\n * Computes which musical beat (1-based) a tab-beat falls on within its bar.\n * Musical beats are defined by the time signature: in 4/4 there are 4 beats,\n * in 6/8 there are 6 beats, etc. A \"beat\" in the time signature has a duration\n * of (4 / denominator) quarter notes (e.g. 1.0 for /4, 0.5 for /8).\n *\n * @param bar       The bar containing the beat\n * @param beatIdx   Index of the tab-beat within bar.beats\n * @returns 1-based musical beat number (clamped to numerator)\n */\nexport function musicalBeatPosition(bar: TabBar, beatIdx: number): number {\n\tconst { numerator, denominator } = bar.timeSignature;\n\tconst musicalBeatDuration = 4 / denominator; // in quarter notes\n\tlet cumulative = 0;\n\tfor (let i = 0; i < beatIdx && i < bar.beats.length; i++) {\n\t\tconst b = bar.beats[i];\n\t\tcumulative += durationToBeats(b.duration, b.dotted, b.tuplet);\n\t}\n\tconst musicalBeat = Math.floor(cumulative / musicalBeatDuration) + 1;\n\treturn Math.min(musicalBeat, numerator);\n}\n\n/** Returns the number of musical beats in a bar (the time signature numerator). */\nexport function barMusicalBeatCount(bar: TabBar): number {\n\treturn bar.timeSignature.numerator;\n}\n\n// ---------------------------------------------------------------------------\n// BCFZ / BCFS binary decoder — pure DataView, no jDataView / Node deps\n// ---------------------------------------------------------------------------\n\n/**\n * Wraps a DataView with a position cursor and jDataView-compatible bit-level reading.\n * Bit reads are MSB-first with a persistent bit offset that carries across calls,\n * matching jDataView.getUnsigned() semantics exactly.\n */\nclass BinaryReader {\n\tprivate view: DataView;\n\tprivate bytes: Uint8Array;\n\tprivate pos: number;\n\tprivate bitOffset: number;\n\treadonly byteLength: number;\n\n\tconstructor(buffer: ArrayBuffer) {\n\t\tthis.view = new DataView(buffer);\n\t\tthis.bytes = new Uint8Array(buffer);\n\t\tthis.pos = 0;\n\t\tthis.bitOffset = 0;\n\t\tthis.byteLength = buffer.byteLength;\n\t}\n\n\tseek(offset: number): void {\n\t\tthis.pos = offset;\n\t\tthis.bitOffset = 0;\n\t}\n\n\tgetPosition(): number {\n\t\treturn this.pos;\n\t}\n\n\tgetUint8(): number {\n\t\tthis.bitOffset = 0;\n\t\tconst v = this.view.getUint8(this.pos);\n\t\tthis.pos += 1;\n\t\treturn v;\n\t}\n\n\tgetUint32LE(offset?: number): number {\n\t\tthis.bitOffset = 0;\n\t\tif (offset !== undefined) {\n\t\t\treturn this.view.getUint32(offset, true);\n\t\t}\n\t\tconst v = this.view.getUint32(this.pos, true);\n\t\tthis.pos += 4;\n\t\treturn v;\n\t}\n\n\tgetString(length: number): string {\n\t\tthis.bitOffset = 0;\n\t\tconst chars: number[] = [];\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tchars.push(this.view.getUint8(this.pos + i));\n\t\t}\n\t\tthis.pos += length;\n\t\treturn String.fromCharCode(...chars);\n\t}\n\n\tgetZeroTerminatedString(offset: number, maxLength: number): string {\n\t\tconst chars: number[] = [];\n\t\tfor (let i = 0; i < maxLength; i++) {\n\t\t\tconst code = this.view.getUint8(offset + i) & 0xff;\n\t\t\tif (code === 0) break;\n\t\t\tchars.push(code);\n\t\t}\n\t\treturn String.fromCharCode(...chars);\n\t}\n\n\tgetBytes(length: number, offset?: number): Uint8Array {\n\t\tthis.bitOffset = 0;\n\t\tconst start = offset !== undefined ? offset : this.pos;\n\t\tif (offset === undefined) this.pos += length;\n\t\treturn new Uint8Array(this.view.buffer, start, length);\n\t}\n\n\t/**\n\t * Reads `bitLength` bits as an unsigned integer (MSB-first), matching\n\t * jDataView.getUnsigned() semantics: a persistent bitOffset carries across\n\t * calls, and bits are read big-endian from the byte stream.\n\t */\n\tgetUnsigned(bitLength: number): number {\n\t\tconst startBit = (this.pos << 3) + this.bitOffset;\n\t\tconst endBit = startBit + bitLength;\n\n\t\t// Byte range we need to read\n\t\tconst startByte = startBit >>> 3;\n\t\tconst endByte = (endBit + 7) >>> 3;\n\n\t\t// Update position: advance to the byte containing the last bit\n\t\tthis.bitOffset = endBit & 7;\n\t\tif (this.bitOffset !== 0) {\n\t\t\tthis.pos = (endBit >>> 3);\n\t\t} else {\n\t\t\tthis.pos = endBit >>> 3;\n\t\t}\n\n\t\t// Build wide value from the spanning bytes (MSB-first)\n\t\tlet wideValue = 0;\n\t\tfor (let i = startByte; i < endByte; i++) {\n\t\t\twideValue = (wideValue << 8) | (this.bytes[i] ?? 0);\n\t\t}\n\n\t\t// Right-shift to discard trailing bits we don't need\n\t\tconst trailingBits = (endByte << 3) - endBit;\n\t\twideValue = wideValue >>> trailingBits;\n\n\t\t// Mask to the requested bit length\n\t\tif (bitLength < 32) {\n\t\t\twideValue = wideValue & ((1 << bitLength) - 1);\n\t\t}\n\n\t\treturn wideValue;\n\t}\n}\n\n/** Reads `count` bits in reversed order (LSB first). */\nfunction readBitsReversed(reader: BinaryReader, count: number): number {\n\tlet bits = 0;\n\tfor (let i = 0; i < count; i++) {\n\t\tbits |= reader.getUnsigned(1) << i;\n\t}\n\treturn bits;\n}\n\ninterface InternalFile {\n\tname: string;\n\tsize: number;\n\tdata: Uint8Array | null;\n}\n\n/** Determines if a file from the BCFS container should be extracted. */\nfunction isFileToStore(name: string): boolean {\n\treturn name === 'score.gpif' || name === 'misc.xml';\n}\n\n/** Decompresses BCFZ block data using the custom LZ-style algorithm. */\nfunction decompressBlock(reader: BinaryReader, skipHeader: boolean): ArrayBuffer {\n\tconst expectedLength = reader.getUint32LE();\n\tconst temp = new Uint8Array(expectedLength);\n\tlet pos = 0;\n\n\ttry {\n\t\twhile (pos < expectedLength) {\n\t\t\tconst flag = reader.getUnsigned(1);\n\n\t\t\tif (flag === 1) {\n\t\t\t\tconst wordSize = reader.getUnsigned(4);\n\t\t\t\tconst offset = readBitsReversed(reader, wordSize);\n\t\t\t\tconst size = readBitsReversed(reader, wordSize);\n\n\t\t\t\tconst sourcePosition = pos - offset;\n\t\t\t\tconst readSize = Math.min(offset, size);\n\n\t\t\t\tfor (let i = 0; i < readSize; i++) {\n\t\t\t\t\ttemp[pos + i] = temp[sourcePosition + i];\n\t\t\t\t}\n\t\t\t\tpos += readSize;\n\t\t\t} else {\n\t\t\t\tconst size = readBitsReversed(reader, 2);\n\n\t\t\t\tfor (let i = 0; i < size; i++) {\n\t\t\t\t\ttemp[pos++] = reader.getUnsigned(8);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// End-of-block reached — partial decompression is acceptable\n\t}\n\n\tif (skipHeader) {\n\t\treturn temp.buffer.slice(4, temp.byteLength);\n\t}\n\treturn temp.buffer;\n}\n\n/** Parses the sector-based block filesystem from a BCFS/BCFZ container. */\nfunction parseBlockFilesystem(buffer: ArrayBuffer): InternalFile[] {\n\tconst SECTOR_SIZE = 0x1000;\n\tconst reader = new BinaryReader(buffer);\n\tlet offset = SECTOR_SIZE;\n\tconst files: InternalFile[] = [];\n\n\twhile (offset + SECTOR_SIZE + 3 < reader.byteLength) {\n\t\tconst entryType = reader.getUint32LE(offset);\n\n\t\tif (entryType === 2) {\n\t\t\tconst name = reader.getZeroTerminatedString(offset + 0x04, 127);\n\t\t\tconst size = reader.getUint32LE(offset + 0x8c);\n\n\t\t\tconst file: InternalFile = { name, size, data: null };\n\t\t\tfiles.push(file);\n\n\t\t\tconst store = isFileToStore(name);\n\t\t\tconst blocksOffset = offset + 0x94;\n\n\t\t\tconst dataChunks: Uint8Array[] = [];\n\t\t\tlet blockCount = 0;\n\t\t\tlet blockId: number;\n\n\t\t\twhile ((blockId = reader.getUint32LE(blocksOffset + 4 * blockCount)) !== 0) {\n\t\t\t\tconst blockOffset = blockId * SECTOR_SIZE;\n\n\t\t\t\tif (store) {\n\t\t\t\t\tconst max = blockOffset + SECTOR_SIZE;\n\t\t\t\t\tconst blockSize =\n\t\t\t\t\t\tmax > reader.byteLength\n\t\t\t\t\t\t\t? SECTOR_SIZE - (max - reader.byteLength)\n\t\t\t\t\t\t\t: SECTOR_SIZE;\n\t\t\t\t\tdataChunks.push(reader.getBytes(blockSize, blockOffset));\n\t\t\t\t}\n\n\t\t\t\tblockCount++;\n\t\t\t}\n\n\t\t\tif (store && dataChunks.length > 0) {\n\t\t\t\tconst totalSize = dataChunks.reduce((s, c) => s + c.length, 0);\n\t\t\t\tconst combined = new Uint8Array(Math.max(size, totalSize));\n\t\t\t\tlet writePos = 0;\n\t\t\t\tfor (const chunk of dataChunks) {\n\t\t\t\t\tcombined.set(chunk, writePos);\n\t\t\t\t\twritePos += chunk.length;\n\t\t\t\t}\n\t\t\t\tfile.data = combined.subarray(0, Math.min(size, totalSize));\n\t\t\t}\n\t\t}\n\n\t\toffset += SECTOR_SIZE;\n\t}\n\n\treturn files;\n}\n\n/** Top-level decoder: reads header, decompresses if needed, extracts files. */\nfunction decodeGpxBinary(data: Uint8Array): Map<string, string> {\n\t// Copy into a fresh ArrayBuffer to avoid SharedArrayBuffer issues\n\tconst buf = new ArrayBuffer(data.byteLength);\n\tnew Uint8Array(buf).set(data);\n\tconst reader = new BinaryReader(buf);\n\tconst header = reader.getString(4);\n\n\tlet filesystemBuffer: ArrayBuffer;\n\n\tswitch (header) {\n\t\tcase 'BCFZ':\n\t\t\tfilesystemBuffer = decompressBlock(reader, true);\n\t\t\tbreak;\n\t\tcase 'BCFS': {\n\t\t\tconst raw = reader.getBytes(reader.byteLength - 4);\n\t\t\tconst copy = new ArrayBuffer(raw.byteLength);\n\t\t\tnew Uint8Array(copy).set(raw);\n\t\t\tfilesystemBuffer = copy;\n\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow new Error(`Bad GPX header: \"${header}\" (unsupported format)`);\n\t}\n\n\tconst files = parseBlockFilesystem(filesystemBuffer);\n\tconst result = new Map<string, string>();\n\n\tfor (const file of files) {\n\t\tif (file.data && isFileToStore(file.name)) {\n\t\t\tconst decoder = new TextDecoder('utf-8');\n\t\t\tresult.set(file.name, decoder.decode(file.data));\n\t\t}\n\t}\n\n\treturn result;\n}\n\n// ---------------------------------------------------------------------------\n// XML → TabSong transformer (replaces both gpifReducer + gpx-adapter)\n// ---------------------------------------------------------------------------\n\n/** Safely reads text content of a child element by tag name. */\nfunction childText(el: Element, tag: string): string | null {\n\tconst child = el.querySelector(`:scope > ${tag}`);\n\treturn child?.textContent?.trim() ?? null;\n}\n\n/** Parses a time signature string like \"4/4\" into { numerator, denominator }. */\nfunction parseTimeSignature(time: string | null): { numerator: number; denominator: number } {\n\tif (!time) return { numerator: 4, denominator: 4 };\n\tconst parts = time.split('/');\n\treturn {\n\t\tnumerator: parseInt(parts[0], 10) || 4,\n\t\tdenominator: parseInt(parts[1], 10) || 4\n\t};\n}\n\n/** Computes pitch class from string tuning + capo + fret. Frets are capo-relative. */\nfunction pitchClassFromStringFret(tuningPitches: number[], stringIndex: number, fret: number, capoFret: number = 0): PitchClass {\n\tconst openPitch = tuningPitches[stringIndex] ?? 0;\n\treturn (((openPitch + capoFret + fret) % 12 + 12) % 12) as PitchClass;\n}\n\n/** Parses tuning pitches string (e.g. \"40 45 50 55 59 64\") into MIDI note numbers. */\nfunction parseTuningPitches(pitchesStr: string): number[] {\n\treturn pitchesStr\n\t\t.split(/\\s+/)\n\t\t.filter((s) => s.length > 0)\n\t\t.map(Number);\n}\n\n// ---------------------------------------------------------------------------\n// Note property extraction from XML\n// ---------------------------------------------------------------------------\n\n/** Finds a <Property name=\"X\"> child element and returns its first child element. */\nfunction findProperty(propertiesEl: Element | null, name: string): Element | null {\n\tif (!propertiesEl) return null;\n\tconst props = propertiesEl.querySelectorAll(':scope > Property');\n\tfor (const prop of props) {\n\t\tif (prop.getAttribute('name') === name) return prop;\n\t}\n\treturn null;\n}\n\n/** Reads the text of the first child element of a property element. */\nfunction propValue(propertiesEl: Element | null, name: string): string | null {\n\tconst prop = findProperty(propertiesEl, name);\n\tif (!prop) return null;\n\tconst firstChild = prop.firstElementChild;\n\treturn firstChild?.textContent?.trim() ?? null;\n}\n\n/** Reads a boolean-enable property (e.g. <Enable /> present means true). */\nfunction propEnabled(propertiesEl: Element | null, name: string): boolean {\n\tconst prop = findProperty(propertiesEl, name);\n\tif (!prop) return null as unknown as boolean;\n\treturn prop.querySelector('Enable') !== null;\n}\n\n/** Reads numeric flags from a property (e.g. Slide flags). */\nfunction propFlags(propertiesEl: Element | null, name: string): number | null {\n\tconst prop = findProperty(propertiesEl, name);\n\tif (!prop) return null;\n\tconst flagsEl = prop.querySelector('Flags');\n\tif (!flagsEl) return null;\n\tconst val = parseInt(flagsEl.textContent?.trim() ?? '', 10);\n\treturn isNaN(val) ? null : val;\n}\n\n/** Reads a float value from a property child element. */\nfunction propFloat(propertiesEl: Element | null, name: string): number | null {\n\tconst prop = findProperty(propertiesEl, name);\n\tif (!prop) return null;\n\tconst floatEl = prop.querySelector('Float');\n\tif (!floatEl) return null;\n\tconst val = parseFloat(floatEl.textContent?.trim() ?? '');\n\treturn isNaN(val) ? null : val;\n}\n\n/** Reads the HType value from a HarmonicType property. */\nfunction propHType(propertiesEl: Element | null, name: string): string | null {\n\tconst prop = findProperty(propertiesEl, name);\n\tif (!prop) return null;\n\tconst htypeEl = prop.querySelector('HType');\n\treturn htypeEl?.textContent?.trim() ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// Note transformation from XML element\n// ---------------------------------------------------------------------------\n\n/** Transforms a <Note> XML element into a TabNote. */\nfunction transformNoteElement(noteEl: Element, tuningPitches: number[], capoFret: number = 0): TabNote {\n\tconst propsEl = noteEl.querySelector(':scope > Properties');\n\n\tconst stringIndex = parseInt(propValue(propsEl, 'String') ?? '0', 10);\n\tconst fret = parseInt(propValue(propsEl, 'Fret') ?? '0', 10);\n\n\tconst pc = pitchClassFromStringFret(tuningPitches, stringIndex, fret, capoFret);\n\tconst note = noteFromPitchClass(pc, false);\n\n\tconst isBended = propEnabled(propsEl, 'Bended');\n\tconst bend = isBended\n\t\t? {\n\t\t\t\torigin: propFloat(propsEl, 'BendOriginValue') ?? 0,\n\t\t\t\tdestination: propFloat(propsEl, 'BendDestinationValue') ?? 0,\n\t\t\t\tmiddle: propFloat(propsEl, 'BendMiddleValue') ?? 0\n\t\t\t}\n\t\t: null;\n\n\tconst tieEl = noteEl.querySelector(':scope > Tie');\n\tconst letRingEl = noteEl.querySelector(':scope > LetRing');\n\tconst vibratoEl = noteEl.querySelector(':scope > Vibrato');\n\tconst accentEl = noteEl.querySelector(':scope > Accent');\n\n\treturn {\n\t\tstring: stringIndex,\n\t\tfret,\n\t\tpitchClass: pc,\n\t\tnoteName: note.name,\n\t\tslide: propFlags(propsEl, 'Slide'),\n\t\tharmonic: propHType(propsEl, 'HarmonicType'),\n\t\tpalmMute: propEnabled(propsEl, 'PalmMuted') ?? false,\n\t\tmuted: propEnabled(propsEl, 'Muted') ?? false,\n\t\tletRing: letRingEl !== null,\n\t\tbend,\n\t\ttie: {\n\t\t\torigin: tieEl ? tieEl.getAttribute('origin') === 'true' : false,\n\t\t\tdestination: tieEl ? tieEl.getAttribute('destination') === 'true' : false\n\t\t},\n\t\tvibrato: vibratoEl?.textContent?.trim() ?? null,\n\t\thammerOn: propEnabled(propsEl, 'HopoOrigin') ?? false,\n\t\tpullOff: propEnabled(propsEl, 'HopoDestination') ?? false,\n\t\ttapped: propEnabled(propsEl, 'Tapped') ?? false,\n\t\taccent: accentEl ? parseInt(accentEl.textContent?.trim() ?? '', 10) || null : null\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Main parser : XML DOM → TabSong\n// ---------------------------------------------------------------------------\n\n/** Builds a Map from id attribute to Element for all children of a container. */\nfunction indexElements(container: Element | null, childTag: string): Map<string, Element> {\n\tconst map = new Map<string, Element>();\n\tif (!container) return map;\n\tconst children = container.querySelectorAll(`:scope > ${childTag}`);\n\tfor (const child of children) {\n\t\tconst id = child.getAttribute('id');\n\t\tif (id) map.set(id, child);\n\t}\n\treturn map;\n}\n\n/** Splits a space-separated ID string into an array of trimmed strings. */\nfunction splitIds(text: string | null): string[] {\n\tif (!text) return [];\n\treturn text.split(/\\s+/).filter((s) => s.length > 0);\n}\n\n/** Builds a bar-index → tempo map from MasterTrack Automations. */\nfunction buildTempoMap(masterTrackEl: Element | null): Map<number, number> {\n\tconst tempoMap = new Map<number, number>();\n\tif (!masterTrackEl) return tempoMap;\n\n\tconst automationsEl = masterTrackEl.querySelector(':scope > Automations');\n\tif (!automationsEl) return tempoMap;\n\n\tconst autos = automationsEl.querySelectorAll(':scope > Automation');\n\tfor (const auto of autos) {\n\t\tconst type = childText(auto, 'Type');\n\t\tif (type?.toLowerCase() !== 'tempo') continue;\n\n\t\tconst barText = childText(auto, 'Bar');\n\t\tconst valueText = childText(auto, 'Value');\n\t\tif (barText === null || valueText === null) continue;\n\n\t\tconst barIndex = parseInt(barText, 10);\n\t\tconst value = parseFloat(valueText);\n\t\tif (!isNaN(barIndex) && !isNaN(value)) {\n\t\t\ttempoMap.set(barIndex, value);\n\t\t}\n\t}\n\treturn tempoMap;\n}\n\n/** Resolves the tempo at a given bar index by walking backwards through the tempo map. */\nfunction tempoAtBar(barIndex: number, tempoMap: Map<number, number>, defaultTempo: number): number {\n\tfor (let i = barIndex; i >= 0; i--) {\n\t\tconst t = tempoMap.get(i);\n\t\tif (t !== undefined) return t;\n\t}\n\treturn defaultTempo;\n}\n\n/** Transforms GPIF XML DOM into a TabSong. Exported for reuse by GP7+ ZIP parser. */\nexport function gpifToTabSong(doc: Document): TabSong {\n\tconst gpif = doc.querySelector('GPIF');\n\tif (!gpif) throw new Error('Invalid GPIF XML: no <GPIF> root element');\n\n\t// Score metadata\n\tconst scoreEl = gpif.querySelector(':scope > Score');\n\tconst title = scoreEl ? childText(scoreEl, 'Title') ?? '' : '';\n\tconst artist = scoreEl ? childText(scoreEl, 'Artist') ?? '' : '';\n\tconst album = scoreEl ? childText(scoreEl, 'Album') ?? '' : '';\n\n\t// Build lookup maps for all ID-referenced entities\n\tconst noteMap = indexElements(gpif.querySelector(':scope > Notes'), 'Note');\n\tconst beatMap = indexElements(gpif.querySelector(':scope > Beats'), 'Beat');\n\tconst voiceMap = indexElements(gpif.querySelector(':scope > Voices'), 'Voice');\n\tconst barMap = indexElements(gpif.querySelector(':scope > Bars'), 'Bar');\n\tconst rhythmMap = indexElements(gpif.querySelector(':scope > Rhythms'), 'Rhythm');\n\n\t// MasterBars\n\tconst masterBarsEl = gpif.querySelector(':scope > MasterBars');\n\tconst masterBarEls = masterBarsEl\n\t\t? Array.from(masterBarsEl.querySelectorAll(':scope > MasterBar'))\n\t\t: [];\n\n\t// Tempo map from MasterTrack automations\n\tconst masterTrackEl = gpif.querySelector(':scope > MasterTrack');\n\tconst tempoMap = buildTempoMap(masterTrackEl);\n\n\tlet initialTempo = 120;\n\tif (tempoMap.size > 0) {\n\t\tinitialTempo = tempoMap.get(0) ?? 120;\n\t}\n\n\t// Tracks\n\tconst tracksEl = gpif.querySelector(':scope > Tracks');\n\tconst trackEls = tracksEl ? Array.from(tracksEl.querySelectorAll(':scope > Track')) : [];\n\n\tconst tracks: TabTrack[] = trackEls.map((trackEl) =>\n\t\ttransformTrackElement(\n\t\t\ttrackEl,\n\t\t\tmasterBarEls,\n\t\t\tbarMap,\n\t\t\tvoiceMap,\n\t\t\tbeatMap,\n\t\t\tnoteMap,\n\t\t\trhythmMap,\n\t\t\ttempoMap,\n\t\t\tinitialTempo\n\t\t)\n\t);\n\n\treturn { title, artist, album, tempo: initialTempo, tracks };\n}\n\n/** Transforms a single <Track> element into a TabTrack. */\nfunction transformTrackElement(\n\ttrackEl: Element,\n\tmasterBarEls: Element[],\n\tbarMap: Map<string, Element>,\n\tvoiceMap: Map<string, Element>,\n\tbeatMap: Map<string, Element>,\n\tnoteMap: Map<string, Element>,\n\trhythmMap: Map<string, Element>,\n\ttempoMap: Map<number, number>,\n\tdefaultTempo: number\n): TabTrack {\n\tconst trackId = trackEl.getAttribute('id') ?? '0';\n\n\t// Extract tuning from track Properties\n\tconst propsEl = trackEl.querySelector(':scope > Properties');\n\tlet tuningPitches = [40, 45, 50, 55, 59, 64]; // Standard guitar tuning MIDI values\n\tlet capoFret = 0;\n\n\tif (propsEl) {\n\t\tconst tuningProp = findProperty(propsEl, 'Tuning');\n\t\tif (tuningProp) {\n\t\t\tconst pitchesEl = tuningProp.querySelector('Pitches');\n\t\t\tif (pitchesEl?.textContent) {\n\t\t\t\ttuningPitches = parseTuningPitches(pitchesEl.textContent.trim());\n\t\t\t}\n\t\t}\n\n\t\tconst capoProp = findProperty(propsEl, 'CapoFret');\n\t\tif (capoProp) {\n\t\t\tconst fretEl = capoProp.querySelector('Fret');\n\t\t\tif (fretEl?.textContent) {\n\t\t\t\tconst parsed = parseInt(fretEl.textContent.trim(), 10);\n\t\t\t\tif (!isNaN(parsed)) capoFret = parsed;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Fallback: check Staves > Staff > Properties for CapoFret (GP7+ layout)\n\tif (capoFret === 0) {\n\t\tconst staffProps = trackEl.querySelector(':scope > Staves > Staff > Properties');\n\t\tif (staffProps) {\n\t\t\tconst capoProp = findProperty(staffProps, 'CapoFret');\n\t\t\tif (capoProp) {\n\t\t\t\tconst fretEl = capoProp.querySelector('Fret');\n\t\t\t\tif (fretEl?.textContent) {\n\t\t\t\t\tconst parsed = parseInt(fretEl.textContent.trim(), 10);\n\t\t\t\t\tif (!isNaN(parsed)) capoFret = parsed;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Also use Staff Properties for tuning if direct Properties had none\n\t\t\tif (!propsEl) {\n\t\t\t\tconst tuningProp = findProperty(staffProps, 'Tuning');\n\t\t\t\tif (tuningProp) {\n\t\t\t\t\tconst pitchesEl = tuningProp.querySelector('Pitches');\n\t\t\t\t\tif (pitchesEl?.textContent) {\n\t\t\t\t\t\ttuningPitches = parseTuningPitches(pitchesEl.textContent.trim());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Convert MIDI pitches to Note[] — kept in GPX native low→high order during parsing;\n\t// reversed to high→low (index 0 = highest pitch) before returning, to match GP3/GP5 convention.\n\tconst tuning: Note[] = tuningPitches\n\t\t.map((midi) => noteFromPitchClass(midiToPitchClass(midi)));\n\n\t// Determine track index for bar resolution\n\tconst trackIndex = parseInt(trackId, 10);\n\tlet globalBeatIndex = 0;\n\tconst bars: TabBar[] = [];\n\tconst trackBeatIds: string[] = [];\n\n\tfor (let mbIdx = 0; mbIdx < masterBarEls.length; mbIdx++) {\n\t\tconst masterBarEl = masterBarEls[mbIdx];\n\n\t\t// Bars element contains space-separated bar IDs\n\t\tconst barsText = childText(masterBarEl, 'Bars');\n\t\tconst barIds = splitIds(barsText);\n\n\t\tconst barId = barIds[trackIndex] ?? barIds[0];\n\t\tconst barEl = barId ? barMap.get(barId) : undefined;\n\n\t\tif (!barEl) {\n\t\t\tbars.push(makeEmptyBar(mbIdx, masterBarEl));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Parse time signature\n\t\tconst timeText = childText(masterBarEl, 'Time');\n\t\tconst timeSig = parseTimeSignature(timeText);\n\n\t\t// Parse key signature\n\t\tconst keyEl = masterBarEl.querySelector(':scope > Key');\n\t\tconst keySig = keyEl\n\t\t\t? {\n\t\t\t\t\taccidentalCount: parseInt(childText(keyEl, 'AccidentalCount') ?? '0', 10),\n\t\t\t\t\tmode: (childText(keyEl, 'Mode')?.toLowerCase() ?? 'major') as 'major' | 'minor'\n\t\t\t\t}\n\t\t\t: null;\n\n\t\t// Parse section\n\t\tconst sectionEl = masterBarEl.querySelector(':scope > Section');\n\t\tconst section = sectionEl\n\t\t\t? {\n\t\t\t\t\tletter: sectionEl.getAttribute('letter') ?? undefined,\n\t\t\t\t\ttext: sectionEl.getAttribute('text') ?? undefined\n\t\t\t\t}\n\t\t\t: null;\n\n\t\t// Parse repeat\n\t\tconst repeatEl = masterBarEl.querySelector(':scope > Repeat');\n\t\tconst repeatStart = repeatEl ? repeatEl.getAttribute('start') === 'true' : false;\n\t\tconst repeatEnd = repeatEl ? repeatEl.getAttribute('end') === 'true' : false;\n\t\tconst repeatCount = repeatEl ? parseInt(repeatEl.getAttribute('count') ?? '0', 10) || 0 : 0;\n\n\t\t// Resolve beats from the bar's voices\n\t\tconst voicesText = childText(barEl, 'Voices');\n\t\tconst voiceIds = splitIds(voicesText);\n\t\tconst tabBeats: TabBeat[] = [];\n\t\tconst currentTempo = tempoAtBar(mbIdx, tempoMap, defaultTempo);\n\n\t\t// Use first voice (primary voice)\n\t\tif (voiceIds.length > 0) {\n\t\t\tconst voiceEl = voiceMap.get(voiceIds[0]);\n\t\t\tif (voiceEl) {\n\t\t\t\tconst voiceBeatsText = childText(voiceEl, 'Beats');\n\t\t\t\tconst voiceBeatIds = splitIds(voiceBeatsText);\n\n\t\t\t\tfor (const beatId of voiceBeatIds) {\n\t\t\t\t\tconst beatEl = beatMap.get(beatId);\n\t\t\t\t\tif (!beatEl) continue;\n\t\t\t\t\ttrackBeatIds.push(beatId);\n\n\t\t\t\t\t// Resolve rhythm\n\t\t\t\t\tconst rhythmRef = beatEl.querySelector(':scope > Rhythm')?.getAttribute('ref');\n\t\t\t\t\tconst rhythmEl = rhythmRef ? rhythmMap.get(rhythmRef) : undefined;\n\n\t\t\t\t\t// Resolve notes\n\t\t\t\t\tconst notesText = childText(beatEl, 'Notes');\n\t\t\t\t\tconst noteIds = splitIds(notesText);\n\t\t\t\t\tconst tabNotes: TabNote[] = noteIds\n\t\t\t\t\t\t.map((nid) => noteMap.get(nid))\n\t\t\t\t\t\t.filter((n): n is Element => n !== undefined)\n\t\t\t\t\t\t.map((n) => transformNoteElement(n, tuningPitches, capoFret));\n\n\t\t\t\t\t// Extract duration from rhythm\n\t\t\t\t\tconst noteValueText = rhythmEl\n\t\t\t\t\t\t? childText(rhythmEl, 'NoteValue')\n\t\t\t\t\t\t: null;\n\t\t\t\t\tconst duration = (noteValueText?.toLowerCase() ?? 'quarter') as Duration;\n\n\t\t\t\t\t// Extract tuplet\n\t\t\t\t\tconst tupletEl = rhythmEl?.querySelector(':scope > PrimaryTuplet');\n\t\t\t\t\tconst tuplet = tupletEl\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tnum: parseInt(tupletEl.getAttribute('num') ?? '1', 10) || 1,\n\t\t\t\t\t\t\t\tden: parseInt(tupletEl.getAttribute('den') ?? '1', 10) || 1\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: null;\n\n\t\t\t\t\t// Extract dot count\n\t\t\t\t\tconst dotEl = rhythmEl?.querySelector(':scope > AugmentationDot');\n\t\t\t\t\tconst dotCount = dotEl\n\t\t\t\t\t\t? parseInt(dotEl.getAttribute('count') ?? '0', 10) || 0\n\t\t\t\t\t\t: 0;\n\n\t\t\t\t\tconst isRest = tabNotes.length === 0;\n\n\t\t\t\t\t// Extract dynamic\n\t\t\t\t\tconst dynamicText = childText(beatEl, 'Dynamic');\n\n\t\t\t\t\ttabBeats.push({\n\t\t\t\t\t\tindex: globalBeatIndex++,\n\t\t\t\t\t\tbarIndex: mbIdx,\n\t\t\t\t\t\tnotes: tabNotes,\n\t\t\t\t\t\tduration,\n\t\t\t\t\t\ttuplet: tuplet && (tuplet.num !== 1 || tuplet.den !== 1) ? tuplet : null,\n\t\t\t\t\t\tdotted: dotCount,\n\t\t\t\t\t\tisRest,\n\t\t\t\t\t\tdynamic: dynamicText,\n\t\t\t\t\t\ttempo: currentTempo\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tbars.push({\n\t\t\tindex: mbIdx,\n\t\t\ttimeSignature: timeSig,\n\t\t\tkeySignature: keySig,\n\t\t\tsection,\n\t\t\tbeats: tabBeats,\n\t\t\trepeatStart,\n\t\t\trepeatEnd,\n\t\t\trepeatCount\n\t\t});\n\t}\n\n\t// Fallback: scan this track's beat FreeText for capo annotations (e.g. \"capo 4th fret\")\n\tif (capoFret === 0) {\n\t\tconst capoPattern = /capo\\s+(\\d+)/i;\n\t\tfor (const beatId of trackBeatIds) {\n\t\t\tconst beatEl = beatMap.get(beatId);\n\t\t\tif (!beatEl) continue;\n\t\t\tconst freeText = childText(beatEl, 'FreeText');\n\t\t\tif (freeText) {\n\t\t\t\tconst match = capoPattern.exec(freeText);\n\t\t\t\tif (match) {\n\t\t\t\t\tconst parsed = parseInt(match[1], 10);\n\t\t\t\t\tif (!isNaN(parsed) && parsed > 0 && parsed <= 24) {\n\t\t\t\t\t\tcapoFret = parsed;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize to high→low convention (index 0 = highest pitch string) matching GP3/GP5 and types.ts.\n\t// GPX XML stores tuning low→high and note.string 0 = lowest pitch; flip both.\n\tconst stringCount = tuningPitches.length;\n\tconst reversedTuning = [...tuning].reverse();\n\tconst reversedTuningMidi = [...tuningPitches].reverse();\n\tfor (const bar of bars) {\n\t\tfor (const beat of bar.beats) {\n\t\t\tfor (const note of beat.notes) {\n\t\t\t\tnote.string = stringCount - 1 - note.string;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tid: trackId,\n\t\tname: childText(trackEl, 'Name') ?? 'Track',\n\t\tshortName: childText(trackEl, 'ShortName') ?? '',\n\t\tinstrument: trackEl.querySelector(':scope > Instrument')?.getAttribute('ref') ?? null,\n\t\ttuning: reversedTuning,\n\t\ttuningMidi: reversedTuningMidi,\n\t\tcapoFret,\n\t\tbars\n\t};\n}\n\n/** Creates an empty bar placeholder when a bar can't be resolved. */\nfunction makeEmptyBar(index: number, masterBarEl: Element): TabBar {\n\tconst timeText = childText(masterBarEl, 'Time');\n\treturn {\n\t\tindex,\n\t\ttimeSignature: parseTimeSignature(timeText),\n\t\tkeySignature: null,\n\t\tsection: null,\n\t\tbeats: [],\n\t\trepeatStart: false,\n\t\trepeatEnd: false,\n\t\trepeatCount: 0\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Parses a Guitar Pro .gpx file from raw bytes into a TabSong.\n *  Pipeline: Uint8Array → BCFZ/BCFS decode → extract score.gpif → DOMParser → TabSong\n */\nexport function parseGpxFile(data: Uint8Array): TabSong {\n\t// Step 1: Decode the binary container\n\tconst files = decodeGpxBinary(data);\n\tconst gpifXml = files.get('score.gpif');\n\tif (!gpifXml) {\n\t\tthrow new Error('No score.gpif found in GPX archive');\n\t}\n\n\t// Step 2: Parse XML using DOMParser (browser-native or @xmldom/xmldom)\n\tconst DOMParserImpl = getDOMParser();\n\tconst parser = new DOMParserImpl();\n\tconst doc = parser.parseFromString(gpifXml, 'text/xml');\n\n\tconst parseError = doc.querySelector('parsererror');\n\tif (parseError) {\n\t\tthrow new Error(`Failed to parse GPIF XML: ${parseError.textContent}`);\n\t}\n\n\t// Step 3: Transform DOM into TabSong\n\treturn gpifToTabSong(doc);\n}\n","/**\n * Copyright 2026 Emilien Bevierre\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * GP5 parser : decodes Guitar Pro 5 (.gp5) binary files and transforms them\n * into TabSong structures. Pure, zero native dependencies.\n *\n * Pipeline: Uint8Array → sequential binary read → TabSong\n *\n * Based on the PyGuitarPro format specification (GP3→GP4→GP5 inheritance chain).\n */\n\nimport type { PitchClass, Note } from './pitch.js';\nimport { noteFromPitchClass, midiToPitchClass } from './pitch.js';\nimport type {\n\tDuration,\n\tTabNote,\n\tTabBeat,\n\tTabBar,\n\tTabTrack,\n\tTabSong\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Binary reader — sequential LE reader with position tracking\n// ---------------------------------------------------------------------------\n\nclass GP5Reader {\n\tprivate view: DataView;\n\tprivate buf: Uint8Array;\n\tprivate pos: number;\n\treadonly byteLength: number;\n\n\tconstructor(buffer: ArrayBuffer) {\n\t\tthis.view = new DataView(buffer);\n\t\tthis.buf = new Uint8Array(buffer);\n\t\tthis.pos = 0;\n\t\tthis.byteLength = buffer.byteLength;\n\t}\n\n\tgetPosition(): number {\n\t\treturn this.pos;\n\t}\n\n\tskip(n: number): void {\n\t\tthis.pos += n;\n\t}\n\n\treadByte(): number {\n\t\tconst v = this.buf[this.pos];\n\t\tthis.pos += 1;\n\t\treturn v;\n\t}\n\n\treadSignedByte(): number {\n\t\tconst v = this.view.getInt8(this.pos);\n\t\tthis.pos += 1;\n\t\treturn v;\n\t}\n\n\treadBool(): boolean {\n\t\treturn this.readByte() !== 0;\n\t}\n\n\treadShort(): number {\n\t\tconst v = this.view.getInt16(this.pos, true);\n\t\tthis.pos += 2;\n\t\treturn v;\n\t}\n\n\treadInt(): number {\n\t\tconst v = this.view.getInt32(this.pos, true);\n\t\tthis.pos += 4;\n\t\treturn v;\n\t}\n\n\treadDouble(): number {\n\t\tconst v = this.view.getFloat64(this.pos, true);\n\t\tthis.pos += 8;\n\t\treturn v;\n\t}\n\n\t/** Reads IntByteSizeString: int(strLen+1) + byte(strLen) + chars. */\n\treadIntByteSizeString(): string {\n\t\tconst totalSize = this.readInt();\n\t\tconst strLen = this.readByte();\n\t\tconst str = this.readChars(strLen);\n\t\tconst padding = Math.max(0, totalSize - 1 - strLen);\n\t\tthis.skip(padding);\n\t\treturn str;\n\t}\n\n\t/** Reads IntSizeString: int(len) + chars. */\n\treadIntString(): string {\n\t\tconst len = this.readInt();\n\t\tif (len <= 0) return '';\n\t\treturn this.readChars(len);\n\t}\n\n\t/** Reads ByteSizeString with fixed buffer length. */\n\treadByteSizeString(fixedLen: number): string {\n\t\tconst strLen = this.readByte();\n\t\tconst str = this.readChars(Math.min(strLen, fixedLen));\n\t\tconst remaining = fixedLen - Math.min(strLen, fixedLen);\n\t\tthis.skip(remaining);\n\t\treturn str;\n\t}\n\n\tprivate readChars(length: number): string {\n\t\tconst chars: number[] = [];\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tchars.push(this.buf[this.pos + i]);\n\t\t}\n\t\tthis.pos += length;\n\t\treturn String.fromCharCode(...chars);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// GP version detection\n// ---------------------------------------------------------------------------\n\ninterface GP5Version {\n\tmajor: number;\n\tminor: number;\n\tpatch: number;\n}\n\nfunction parseVersionString(versionStr: string): GP5Version {\n\tconst match = versionStr.match(/v(\\d+)\\.(\\d+)/);\n\tif (!match) return { major: 5, minor: 10, patch: 0 };\n\treturn {\n\t\tmajor: parseInt(match[1], 10),\n\t\tminor: parseInt(match[2], 10),\n\t\tpatch: 0\n\t};\n}\n\nfunction versionGreaterThan(v: GP5Version, major: number, minor: number, patch: number): boolean {\n\tif (v.major !== major) return v.major > major;\n\tif (v.minor !== minor) return v.minor > minor;\n\treturn v.patch > patch;\n}\n\n// ---------------------------------------------------------------------------\n// Duration mapping\n// ---------------------------------------------------------------------------\n\nconst GP_DURATION_MAP: Record<number, Duration> = {\n\t[-2]: 'whole',\n\t[-1]: 'half',\n\t[0]: 'quarter',\n\t[1]: 'eighth',\n\t[2]: '16th',\n\t[3]: '32nd',\n\t[4]: '64th',\n\t[5]: '128th'\n};\n\nfunction gpDurationToDuration(value: number): Duration {\n\treturn GP_DURATION_MAP[value] ?? 'quarter';\n}\n\n// ---------------------------------------------------------------------------\n// Tuplet mapping\n// ---------------------------------------------------------------------------\n\nconst TUPLET_MAP: Record<number, { num: number; den: number }> = {\n\t3: { num: 3, den: 2 },\n\t5: { num: 5, den: 4 },\n\t6: { num: 6, den: 4 },\n\t7: { num: 7, den: 4 },\n\t9: { num: 9, den: 8 },\n\t10: { num: 10, den: 8 },\n\t11: { num: 11, den: 8 },\n\t12: { num: 12, den: 8 },\n\t13: { num: 13, den: 8 }\n};\n\n// ---------------------------------------------------------------------------\n// Harmonic type mapping\n// ---------------------------------------------------------------------------\n\nconst HARMONIC_TYPE_MAP: Record<number, string> = {\n\t1: 'Natural',\n\t2: 'Artificial',\n\t3: 'Tapped',\n\t4: 'Pinch',\n\t5: 'Semi'\n};\n\n// ---------------------------------------------------------------------------\n// MIDI channel info\n// ---------------------------------------------------------------------------\n\ninterface MidiChannel {\n\tinstrument: number;\n\tvolume: number;\n\tbalance: number;\n\tchorus: number;\n\treverb: number;\n\tphaser: number;\n\ttremolo: number;\n}\n\n// ---------------------------------------------------------------------------\n// Measure header (parsed from the measure header block)\n// ---------------------------------------------------------------------------\n\ninterface MeasureHeader {\n\tnumerator: number;\n\tdenominator: number;\n\trepeatOpen: boolean;\n\trepeatClose: number;\n\trepeatAlternative: number;\n\tmarker: { name: string; color: [number, number, number] } | null;\n\tkeySignature: number;\n\tkeyMode: number;\n\thasDoubleBar: boolean;\n\ttripletFeel: number;\n}\n\n// ---------------------------------------------------------------------------\n// Track header\n// ---------------------------------------------------------------------------\n\ninterface TrackHeader {\n\tname: string;\n\tisPercussion: boolean;\n\tnumStrings: number;\n\ttuning: number[];\n\tport: number;\n\tchannelIndex: number;\n\teffectChannel: number;\n\tfretCount: number;\n\tcapoFret: number;\n}\n\n// ---------------------------------------------------------------------------\n// Internal beat/note structures used during parsing\n// ---------------------------------------------------------------------------\n\ninterface GP5ParsedNote {\n\tstring: number;\n\tfret: number;\n\tisTied: boolean;\n\tisDead: boolean;\n\tvelocity: number;\n\thammerOn: boolean;\n\tletRing: boolean;\n\tslide: number | null;\n\tharmonic: string | null;\n\tpalmMute: boolean;\n\tvibrato: boolean;\n\tbend: { type: number; value: number; points: { position: number; value: number; vibrato: boolean }[] } | null;\n\tstaccato: boolean;\n\theavyAccent: boolean;\n\taccent: boolean;\n\ttrill: { fret: number; period: number } | null;\n\ttremoloPicking: number | null;\n}\n\ninterface GP5ParsedBeat {\n\tduration: Duration;\n\tdotted: boolean;\n\ttuplet: { num: number; den: number } | null;\n\tisRest: boolean;\n\tisEmpty: boolean;\n\tnotes: GP5ParsedNote[];\n}\n\n// ---------------------------------------------------------------------------\n// Read helpers — individual GP binary sections\n// ---------------------------------------------------------------------------\n\nfunction readInfo(r: GP5Reader): { title: string; subtitle: string; artist: string; album: string } {\n\tconst title = r.readIntByteSizeString();\n\tconst subtitle = r.readIntByteSizeString();\n\tconst artist = r.readIntByteSizeString();\n\tconst album = r.readIntByteSizeString();\n\tr.readIntByteSizeString(); // words\n\tr.readIntByteSizeString(); // music\n\tr.readIntByteSizeString(); // copyright\n\tr.readIntByteSizeString(); // tab\n\tr.readIntByteSizeString(); // instructions\n\n\tconst noticeCount = r.readInt();\n\tfor (let i = 0; i < noticeCount; i++) {\n\t\tr.readIntByteSizeString();\n\t}\n\n\treturn { title, subtitle, artist, album };\n}\n\nfunction readLyrics(r: GP5Reader): void {\n\tr.readInt(); // lyric track\n\tfor (let i = 0; i < 5; i++) {\n\t\tr.readInt(); // start bar\n\t\tr.readIntString(); // text\n\t}\n}\n\nfunction readRSEMasterEffect(r: GP5Reader, version: GP5Version): void {\n\tif (versionGreaterThan(version, 5, 0, 0)) {\n\t\tr.readInt(); // master volume\n\t\tr.readInt(); // unknown\n\t\treadEqualizer(r, 11);\n\t}\n}\n\nfunction readEqualizer(r: GP5Reader, bands: number): void {\n\tfor (let i = 0; i < bands; i++) {\n\t\tr.readSignedByte();\n\t}\n}\n\nfunction readPageSetup(r: GP5Reader): void {\n\tr.readInt(); // width\n\tr.readInt(); // height\n\tr.readInt(); // margin left\n\tr.readInt(); // margin right\n\tr.readInt(); // margin top\n\tr.readInt(); // margin bottom\n\tr.readInt(); // score size proportion\n\tr.readShort(); // header/footer flags\n\tfor (let i = 0; i < 10; i++) {\n\t\tr.readIntByteSizeString(); // template strings\n\t}\n}\n\nfunction readDirections(r: GP5Reader): void {\n\tfor (let i = 0; i < 19; i++) {\n\t\tr.readShort();\n\t}\n}\n\nfunction readMidiChannels(r: GP5Reader): MidiChannel[] {\n\tconst channels: MidiChannel[] = [];\n\tfor (let i = 0; i < 64; i++) {\n\t\tconst instrument = r.readInt();\n\t\tconst volume = r.readByte();\n\t\tconst balance = r.readByte();\n\t\tconst chorus = r.readByte();\n\t\tconst reverb = r.readByte();\n\t\tconst phaser = r.readByte();\n\t\tconst tremolo = r.readByte();\n\t\tr.skip(2); // padding\n\t\tchannels.push({ instrument, volume, balance, chorus, reverb, phaser, tremolo });\n\t}\n\treturn channels;\n}\n\nfunction readMeasureHeaders(r: GP5Reader, count: number, _version: GP5Version): MeasureHeader[] {\n\tconst headers: MeasureHeader[] = [];\n\tlet prevNumerator = 4;\n\tlet prevDenominator = 4;\n\n\tfor (let i = 0; i < count; i++) {\n\t\tif (i > 0) {\n\t\t\tr.skip(1); // blank byte before each header except first\n\t\t}\n\n\t\tconst flags = r.readByte();\n\n\t\tlet numerator = prevNumerator;\n\t\tlet denominator = prevDenominator;\n\n\t\tif (flags & 0x01) {\n\t\t\tnumerator = r.readSignedByte();\n\t\t}\n\t\tif (flags & 0x02) {\n\t\t\tdenominator = r.readSignedByte();\n\t\t}\n\n\t\tconst repeatOpen = (flags & 0x04) !== 0;\n\n\t\tlet repeatClose = -1;\n\t\tif (flags & 0x08) {\n\t\t\trepeatClose = r.readSignedByte();\n\t\t\tif (repeatClose > 0) repeatClose -= 1;\n\t\t}\n\n\t\tlet marker: MeasureHeader['marker'] = null;\n\t\tif (flags & 0x20) {\n\t\t\tconst name = r.readIntByteSizeString();\n\t\t\tconst colorR = r.readByte();\n\t\t\tconst colorG = r.readByte();\n\t\t\tconst colorB = r.readByte();\n\t\t\tr.skip(1); // padding\n\t\t\tmarker = { name, color: [colorR, colorG, colorB] };\n\t\t}\n\n\t\tlet keySignature = 0;\n\t\tlet keyMode = 0;\n\t\tif (flags & 0x40) {\n\t\t\tkeySignature = r.readSignedByte();\n\t\t\tkeyMode = r.readSignedByte();\n\t\t}\n\n\t\tconst hasDoubleBar = (flags & 0x80) !== 0;\n\n\t\tlet repeatAlternative = 0;\n\t\tif (flags & 0x10) {\n\t\t\trepeatAlternative = r.readByte();\n\t\t}\n\n\t\t// GP5: beam groups if time sig was set (both bits 0x01 and 0x02)\n\t\tif (flags & 0x03) {\n\t\t\tr.skip(4); // beam groups\n\t\t}\n\n\t\t// Blank byte if not alternate ending\n\t\tif (!(flags & 0x10)) {\n\t\t\tr.skip(1);\n\t\t}\n\n\t\tconst tripletFeel = r.readByte();\n\n\t\theaders.push({\n\t\t\tnumerator,\n\t\t\tdenominator,\n\t\t\trepeatOpen,\n\t\t\trepeatClose,\n\t\t\trepeatAlternative,\n\t\t\tmarker,\n\t\t\tkeySignature,\n\t\t\tkeyMode,\n\t\t\thasDoubleBar,\n\t\t\ttripletFeel\n\t\t});\n\n\t\tprevNumerator = numerator;\n\t\tprevDenominator = denominator;\n\t}\n\n\treturn headers;\n}\n\nfunction readTrackHeaders(r: GP5Reader, count: number, version: GP5Version): TrackHeader[] {\n\tconst tracks: TrackHeader[] = [];\n\n\tfor (let i = 0; i < count; i++) {\n\t\t// GP5.10: blank byte before first track; GP5.0: blank byte before every track\n\t\tif (i === 0 || versionGreaterThan(version, 5, 0, 0) === false) {\n\t\t\tr.skip(1);\n\t\t}\n\n\t\tconst flags1 = r.readByte();\n\t\tconst isPercussion = (flags1 & 0x01) !== 0;\n\n\t\tconst name = r.readByteSizeString(40);\n\t\tconst numStrings = r.readInt();\n\n\t\tconst tuning: number[] = [];\n\t\tfor (let s = 0; s < 7; s++) {\n\t\t\tconst val = r.readInt();\n\t\t\tif (s < numStrings) tuning.push(val);\n\t\t}\n\n\t\tconst port = r.readInt();\n\t\tconst channelIndex = r.readInt() - 1; // 1-based → 0-based\n\t\tconst effectChannel = r.readInt() - 1;\n\t\tconst fretCount = r.readInt();\n\t\tconst capoFret = r.readInt();\n\t\tr.skip(4); // color (3 bytes + padding)\n\n\t\ttracks.push({ name, isPercussion, numStrings, tuning, port, channelIndex, effectChannel, fretCount, capoFret });\n\n\t\t// GP5 track flags2 (display settings)\n\t\tr.readShort();\n\n\t\t// Auto accentuation + MIDI bank\n\t\tr.readByte(); // auto accentuation\n\t\tr.readByte(); // MIDI bank\n\n\t\t// Track RSE\n\t\treadTrackRSE(r, version);\n\t}\n\n\t// Trailing bytes after all tracks\n\tif (versionGreaterThan(version, 5, 0, 0)) {\n\t\tr.skip(1);\n\t} else {\n\t\tr.skip(2);\n\t}\n\n\treturn tracks;\n}\n\nfunction readTrackRSE(r: GP5Reader, version: GP5Version): void {\n\tr.readByte(); // humanize\n\tr.skip(12); // 3 ints unknown\n\tr.skip(12); // additional unknown\n\treadRSEInstrument(r, version);\n\tif (versionGreaterThan(version, 5, 0, 0)) {\n\t\treadEqualizer(r, 4); // 3-band + gain\n\t\treadRSEInstrumentEffect(r, version);\n\t}\n}\n\nfunction readRSEInstrument(r: GP5Reader, version: GP5Version): void {\n\tr.readInt(); // MIDI instrument number\n\tr.readInt(); // unknown\n\tr.readInt(); // sound bank\n\tif (versionGreaterThan(version, 5, 0, 0)) {\n\t\tr.readInt(); // effect number\n\t} else {\n\t\tr.readShort(); // effect number (GP5.0)\n\t\tr.skip(1);\n\t}\n}\n\nfunction readRSEInstrumentEffect(r: GP5Reader, version: GP5Version): void {\n\tif (versionGreaterThan(version, 5, 0, 0)) {\n\t\tr.readIntByteSizeString(); // effect name\n\t\tr.readIntByteSizeString(); // effect category\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Measure / Beat / Note reading — the per-measure data block\n// ---------------------------------------------------------------------------\n\nfunction readMeasures(\n\tr: GP5Reader,\n\tmeasureCount: number,\n\ttrackHeaders: TrackHeader[],\n\tversion: GP5Version\n): GP5ParsedBeat[][][] {\n\t// Result: measures[trackIdx][measureIdx] = beats[]\n\tconst trackCount = trackHeaders.length;\n\tconst allMeasures: GP5ParsedBeat[][][] = [];\n\tfor (let t = 0; t < trackCount; t++) {\n\t\tallMeasures.push([]);\n\t}\n\n\t// GP5 stores measures in order: measure1/track1, measure1/track2, ..., measure2/track1, ...\n\t// GP5 has 2 voices per measure\n\tfor (let m = 0; m < measureCount; m++) {\n\t\tfor (let t = 0; t < trackCount; t++) {\n\t\t\tconst numStrings = trackHeaders[t].numStrings;\n\t\t\tconst voice1Beats = readVoice(r, version, numStrings);\n\t\t\tconst voice2Beats = readVoice(r, version, numStrings);\n\t\t\tr.readByte(); // line break\n\n\t\t\t// Use voice 1 as primary; include voice 2 beats if voice 1 is empty\n\t\t\tconst beats = voice1Beats.length > 0 ? voice1Beats : voice2Beats;\n\t\t\tallMeasures[t].push(beats);\n\t\t}\n\t}\n\n\treturn allMeasures;\n}\n\nfunction readVoice(r: GP5Reader, version: GP5Version, numStrings: number): GP5ParsedBeat[] {\n\tconst beatCount = r.readInt();\n\tconst beats: GP5ParsedBeat[] = [];\n\n\tfor (let b = 0; b < beatCount; b++) {\n\t\tbeats.push(readBeat(r, version, numStrings));\n\t}\n\n\treturn beats;\n}\n\nfunction readBeat(r: GP5Reader, version: GP5Version, numStrings: number): GP5ParsedBeat {\n\tconst flags = r.readByte();\n\n\tlet isRest = false;\n\tlet isEmpty = false;\n\tif (flags & 0x40) {\n\t\tconst status = r.readByte();\n\t\tisEmpty = status === 0x00;\n\t\tisRest = status === 0x02;\n\t}\n\n\t// Duration\n\tconst durationValue = r.readSignedByte();\n\tconst duration = gpDurationToDuration(durationValue);\n\tconst dotted = (flags & 0x01) !== 0;\n\n\tlet tuplet: { num: number; den: number } | null = null;\n\tif (flags & 0x20) {\n\t\tconst tupletValue = r.readInt();\n\t\ttuplet = TUPLET_MAP[tupletValue] ?? null;\n\t}\n\n\t// Chord diagram\n\tif (flags & 0x02) {\n\t\treadChord(r, version);\n\t}\n\n\t// Text\n\tif (flags & 0x04) {\n\t\tr.readIntByteSizeString();\n\t}\n\n\t// Beat effects\n\tif (flags & 0x08) {\n\t\treadBeatEffects(r, version);\n\t}\n\n\t// Mix table change\n\tif (flags & 0x10) {\n\t\treadMixTableChange(r, version);\n\t}\n\n\t// Notes — bit 6 = GP string 1 (highest pitch), bit 0 = GP string 7\n\tconst stringFlags = r.readByte();\n\tconst notes: GP5ParsedNote[] = [];\n\n\tfor (let i = 6; i >= 0; i--) {\n\t\tif (stringFlags & (1 << i)) {\n\t\t\tconst gpString = 7 - i; // 1-based, 1 = highest pitch string\n\t\t\tconst tuningIndex = gpString - 1; // 0-based into tuning array (0 = highest pitch string)\n\t\t\tconst note = readNote(r, version);\n\t\t\tnote.string = tuningIndex;\n\t\t\tnotes.push(note);\n\t\t}\n\t}\n\n\t// GP5 beat flags2\n\tconst flags2 = r.readShort();\n\tif (flags2 & 0x0800) {\n\t\tr.readByte(); // break secondary beams\n\t}\n\n\treturn { duration, dotted, tuplet, isRest: isRest || isEmpty, isEmpty, notes };\n}\n\nfunction readChord(r: GP5Reader, _version: GP5Version): void {\n\tconst header = r.readByte();\n\tif (header === 0) {\n\t\t// Old GP3 chord format: name + firstFret + (6 ints if firstFret != 0)\n\t\tr.readIntByteSizeString();\n\t\tconst firstFret = r.readInt();\n\t\tif (firstFret !== 0) {\n\t\t\tfor (let i = 0; i < 6; i++) r.readInt();\n\t\t}\n\t} else {\n\t\t// GP4+ format chord — large fixed structure\n\t\tr.skip(16); // sharp(1) + blank(3) + root(1) + type(1) + extension(1) + bassNote(4) + tonality(4) + add(1)\n\t\tr.readByteSizeString(22);\n\t\tr.readByte(); // fifth\n\t\tr.readByte(); // ninth\n\t\tr.readByte(); // eleventh\n\t\tfor (let i = 0; i < 6; i++) r.readInt(); // frets\n\t\tr.readByte(); // barreCount\n\t\tr.skip(5); // barre frets\n\t\tr.skip(5); // barre start strings\n\t\tr.skip(5); // barre end strings\n\t\tr.skip(7); // omissions\n\t\tr.skip(1); // blank\n\t\tr.skip(7); // fingering\n\t\tr.readBool(); // show diagrams fingering\n\t}\n}\n\nfunction readBeatEffects(r: GP5Reader, _version: GP5Version): void {\n\t// GP4+ uses 2 bytes of flags\n\tconst flags1 = r.readByte();\n\tconst flags2 = r.readByte();\n\n\tif (flags1 & 0x20) {\n\t\tconst slapEffect = r.readSignedByte();\n\t\tif (slapEffect === 0) {\n\t\t\t// Tremolo bar\n\t\t\treadBend(r);\n\t\t}\n\t}\n\n\tif (flags2 & 0x04) {\n\t\t// Tremolo bar\n\t\treadBend(r);\n\t}\n\n\tif (flags1 & 0x40) {\n\t\t// Beat stroke\n\t\tr.readByte(); // stroke down\n\t\tr.readByte(); // stroke up\n\t}\n\n\tif (flags2 & 0x02) {\n\t\t// Pick stroke\n\t\tr.readSignedByte();\n\t}\n}\n\nfunction readBend(r: GP5Reader): { type: number; value: number; points: { position: number; value: number; vibrato: boolean }[] } {\n\tconst type = r.readSignedByte();\n\tconst value = r.readInt();\n\tconst pointCount = r.readInt();\n\tconst points: { position: number; value: number; vibrato: boolean }[] = [];\n\tfor (let i = 0; i < pointCount; i++) {\n\t\tconst position = r.readInt();\n\t\tconst pointValue = r.readInt();\n\t\tconst vibrato = r.readBool();\n\t\tpoints.push({ position, value: pointValue, vibrato });\n\t}\n\treturn { type, value, points };\n}\n\nfunction readMixTableChange(r: GP5Reader, version: GP5Version): void {\n\tr.readSignedByte(); // instrument\n\n\t// RSE instrument (GP5)\n\treadRSEInstrument(r, version);\n\tif (!versionGreaterThan(version, 5, 0, 0)) {\n\t\tr.skip(1); // GP5.0 extra byte\n\t}\n\n\tconst volume = r.readSignedByte();\n\tconst balance = r.readSignedByte();\n\tconst chorus = r.readSignedByte();\n\tconst reverb = r.readSignedByte();\n\tconst phaser = r.readSignedByte();\n\tconst tremolo = r.readSignedByte();\n\n\tr.readIntByteSizeString(); // tempo name\n\tconst tempo = r.readInt();\n\n\t// Durations for changed values\n\tif (volume >= 0) r.readSignedByte();\n\tif (balance >= 0) r.readSignedByte();\n\tif (chorus >= 0) r.readSignedByte();\n\tif (reverb >= 0) r.readSignedByte();\n\tif (phaser >= 0) r.readSignedByte();\n\tif (tremolo >= 0) r.readSignedByte();\n\tif (tempo >= 0) {\n\t\tr.readSignedByte(); // duration\n\t\tif (versionGreaterThan(version, 5, 0, 0)) {\n\t\t\tr.readBool(); // hide tempo\n\t\t}\n\t}\n\n\t// Mix table change flags (GP4+)\n\tr.readByte();\n\n\t// Wah effect (GP5)\n\tr.readSignedByte();\n\n\t// RSE instrument effect (GP5.1+)\n\treadRSEInstrumentEffect(r, version);\n}\n\nfunction readNote(r: GP5Reader, version: GP5Version): GP5ParsedNote {\n\tconst flags = r.readByte();\n\n\tconst heavyAccent = (flags & 0x02) !== 0;\n\tconst accent = (flags & 0x40) !== 0;\n\n\tlet isTied = false;\n\tlet isDead = false;\n\tif (flags & 0x20) {\n\t\tconst noteType = r.readByte();\n\t\tisTied = noteType === 2;\n\t\tisDead = noteType === 3;\n\t}\n\n\tlet velocity = 8; // default mf\n\tif (flags & 0x10) {\n\t\tvelocity = r.readSignedByte();\n\t}\n\n\tlet fret = 0;\n\tif (flags & 0x20) {\n\t\tfret = r.readSignedByte();\n\t\tif (fret < 0 || fret > 99) fret = 0;\n\t}\n\n\tif (flags & 0x80) {\n\t\tr.readSignedByte(); // left hand finger\n\t\tr.readSignedByte(); // right hand finger\n\t}\n\n\tif (flags & 0x01) {\n\t\tr.readDouble(); // duration percent\n\t}\n\n\t// GP5: second flags byte\n\tr.readByte();\n\n\t// Note effects\n\tlet hammerOn = false;\n\tlet letRing = false;\n\tlet slide: number | null = null;\n\tlet harmonic: string | null = null;\n\tlet palmMute = false;\n\tlet vibrato = false;\n\tlet bend: GP5ParsedNote['bend'] = null;\n\tlet staccato = false;\n\tlet trill: GP5ParsedNote['trill'] = null;\n\tlet tremoloPicking: number | null = null;\n\n\tif (flags & 0x08) {\n\t\tconst result = readNoteEffects(r, version);\n\t\thammerOn = result.hammerOn;\n\t\tletRing = result.letRing;\n\t\tslide = result.slide;\n\t\tharmonic = result.harmonic;\n\t\tpalmMute = result.palmMute;\n\t\tvibrato = result.vibrato;\n\t\tbend = result.bend;\n\t\tstaccato = result.staccato;\n\t\ttrill = result.trill;\n\t\ttremoloPicking = result.tremoloPicking;\n\t}\n\n\treturn {\n\t\tstring: 0, // Will be set by caller based on string index\n\t\tfret,\n\t\tisTied,\n\t\tisDead,\n\t\tvelocity,\n\t\thammerOn,\n\t\tletRing,\n\t\tslide,\n\t\tharmonic,\n\t\tpalmMute,\n\t\tvibrato,\n\t\tbend,\n\t\tstaccato,\n\t\theavyAccent,\n\t\taccent,\n\t\ttrill,\n\t\ttremoloPicking\n\t};\n}\n\ninterface NoteEffectsResult {\n\thammerOn: boolean;\n\tletRing: boolean;\n\tslide: number | null;\n\tharmonic: string | null;\n\tpalmMute: boolean;\n\tvibrato: boolean;\n\tbend: GP5ParsedNote['bend'];\n\tstaccato: boolean;\n\ttrill: GP5ParsedNote['trill'];\n\ttremoloPicking: number | null;\n}\n\nfunction readNoteEffects(r: GP5Reader, version: GP5Version): NoteEffectsResult {\n\t// GP4+ uses 2 bytes of flags\n\tconst flags1 = r.readByte();\n\tconst flags2 = r.readByte();\n\n\tlet bend: GP5ParsedNote['bend'] = null;\n\tlet hammerOn = false;\n\tlet letRing = false;\n\tlet slide: number | null = null;\n\tlet harmonic: string | null = null;\n\tlet palmMute = false;\n\tlet vibrato = false;\n\tlet staccato = false;\n\tlet trill: GP5ParsedNote['trill'] = null;\n\tlet tremoloPicking: number | null = null;\n\n\tif (flags1 & 0x01) {\n\t\tbend = readBend(r);\n\t}\n\thammerOn = (flags1 & 0x02) !== 0;\n\tletRing = (flags1 & 0x08) !== 0;\n\n\tif (flags1 & 0x10) {\n\t\treadGraceNote(r, version);\n\t}\n\n\tstaccato = (flags2 & 0x01) !== 0;\n\tpalmMute = (flags2 & 0x02) !== 0;\n\n\tif (flags2 & 0x04) {\n\t\ttremoloPicking = r.readSignedByte();\n\t}\n\n\tif (flags2 & 0x08) {\n\t\t// GP5 slides: byte with flags\n\t\tslide = r.readByte();\n\t}\n\n\tif (flags2 & 0x10) {\n\t\tconst harmonicType = r.readSignedByte();\n\t\tharmonic = HARMONIC_TYPE_MAP[harmonicType] ?? null;\n\t\tif (harmonicType === 2) {\n\t\t\t// Artificial harmonic extra data\n\t\t\tr.readByte(); // note\n\t\t\tr.readSignedByte(); // accidental\n\t\t\tr.readByte(); // octave\n\t\t} else if (harmonicType === 3) {\n\t\t\tr.readByte(); // fret\n\t\t}\n\t}\n\n\tif (flags2 & 0x20) {\n\t\tconst trillFret = r.readSignedByte();\n\t\tconst trillPeriod = r.readSignedByte();\n\t\ttrill = { fret: trillFret, period: trillPeriod };\n\t}\n\n\tvibrato = (flags2 & 0x40) !== 0;\n\n\treturn { hammerOn, letRing, slide, harmonic, palmMute, vibrato, bend, staccato, trill, tremoloPicking };\n}\n\nfunction readGraceNote(r: GP5Reader, version: GP5Version): void {\n\tr.readByte(); // fret\n\tr.readByte(); // velocity\n\tr.readByte(); // transition\n\tr.readByte(); // duration\n\tif (versionGreaterThan(version, 5, 0, 0)) {\n\t\tr.readByte(); // flags (dead, on beat)\n\t} else {\n\t\tr.readByte();\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Transform parsed GP5 data → TabSong\n// ---------------------------------------------------------------------------\n\nfunction transformToTabSong(\n\tinfo: { title: string; subtitle: string; artist: string; album: string },\n\ttempo: number,\n\tmeasureHeaders: MeasureHeader[],\n\ttrackHeaders: TrackHeader[],\n\tparsedMeasures: GP5ParsedBeat[][][],\n\tchannels: MidiChannel[]\n): TabSong {\n\tconst tracks: TabTrack[] = trackHeaders.map((th, trackIdx) => {\n\t\tconst tuningPitches = th.tuning;\n\t\tconst tuning: Note[] = tuningPitches\n\t\t\t.map((midi) => noteFromPitchClass(midiToPitchClass(midi)));\n\n\t\tlet globalBeatIndex = 0;\n\t\tconst bars: TabBar[] = [];\n\n\t\tfor (let mIdx = 0; mIdx < measureHeaders.length; mIdx++) {\n\t\t\tconst mh = measureHeaders[mIdx];\n\t\t\tconst beatsData = parsedMeasures[trackIdx]?.[mIdx] ?? [];\n\n\t\t\tconst tabBeats: TabBeat[] = [];\n\n\t\t\tfor (const beatData of beatsData) {\n\t\t\t\tif (beatData.isEmpty) continue;\n\n\t\t\t\tconst stringCount = th.numStrings;\n\t\t\t\tconst tabNotes: TabNote[] = [];\n\n\t\t\t\tfor (const noteData of beatData.notes) {\n\t\t\t\t\tconst tuningIndex = noteData.string; // 0-based, 0 = highest pitch string (matches GP tuning array order)\n\t\t\t\t\tconst stringIdx = tuningIndex; // display order: 0 = highest pitch string\n\t\t\t\t\tconst fret = noteData.fret;\n\t\t\t\t\tconst openPitch = tuningPitches[tuningIndex] ?? 0;\n\t\t\t\t\tconst pc = (((openPitch + th.capoFret + fret) % 12 + 12) % 12) as PitchClass;\n\t\t\t\t\tconst note = noteFromPitchClass(pc, false);\n\n\t\t\t\t\tlet bendResult: TabNote['bend'] = null;\n\t\t\t\t\tif (noteData.bend) {\n\t\t\t\t\t\tconst points = noteData.bend.points;\n\t\t\t\t\t\tconst origin = points.length > 0 ? points[0].value / 100 : 0;\n\t\t\t\t\t\tconst destination = points.length > 1 ? points[points.length - 1].value / 100 : 0;\n\t\t\t\t\t\tconst middle = points.length > 2 ? points[Math.floor(points.length / 2)].value / 100 : 0;\n\t\t\t\t\t\tbendResult = { origin, destination, middle };\n\t\t\t\t\t}\n\n\t\t\t\t\ttabNotes.push({\n\t\t\t\t\t\tstring: stringIdx,\n\t\t\t\t\t\tfret,\n\t\t\t\t\t\tpitchClass: pc,\n\t\t\t\t\t\tnoteName: note.name,\n\t\t\t\t\t\tslide: noteData.slide,\n\t\t\t\t\t\tharmonic: noteData.harmonic,\n\t\t\t\t\t\tpalmMute: noteData.palmMute,\n\t\t\t\t\t\tmuted: noteData.isDead,\n\t\t\t\t\t\tletRing: noteData.letRing,\n\t\t\t\t\t\tbend: bendResult,\n\t\t\t\t\t\ttie: {\n\t\t\t\t\t\t\torigin: false,\n\t\t\t\t\t\t\tdestination: noteData.isTied\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvibrato: noteData.vibrato ? 'slight' : null,\n\t\t\t\t\t\thammerOn: noteData.hammerOn,\n\t\t\t\t\t\tpullOff: false, // GP5 uses hammerOn for both — context determines direction\n\t\t\t\t\t\ttapped: false,\n\t\t\t\t\t\taccent: noteData.accent ? 1 : noteData.heavyAccent ? 2 : null\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\ttabBeats.push({\n\t\t\t\t\tindex: globalBeatIndex++,\n\t\t\t\t\tbarIndex: mIdx,\n\t\t\t\t\tnotes: tabNotes,\n\t\t\t\t\tduration: beatData.duration,\n\t\t\t\t\ttuplet: beatData.tuplet,\n\t\t\t\t\tdotted: beatData.dotted ? 1 : 0,\n\t\t\t\t\tisRest: beatData.isRest && tabNotes.length === 0,\n\t\t\t\t\tdynamic: null,\n\t\t\t\t\ttempo\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst section = mh.marker\n\t\t\t\t? { text: mh.marker.name }\n\t\t\t\t: null;\n\n\t\t\tbars.push({\n\t\t\t\tindex: mIdx,\n\t\t\t\ttimeSignature: { numerator: mh.numerator, denominator: mh.denominator },\n\t\t\t\tkeySignature: mh.keySignature !== 0\n\t\t\t\t\t? { accidentalCount: mh.keySignature, mode: mh.keyMode === 1 ? 'minor' : 'major' }\n\t\t\t\t\t: null,\n\t\t\t\tsection,\n\t\t\t\tbeats: tabBeats,\n\t\t\t\trepeatStart: mh.repeatOpen,\n\t\t\t\trepeatEnd: mh.repeatClose >= 0,\n\t\t\t\trepeatCount: mh.repeatClose >= 0 ? mh.repeatClose : 0\n\t\t\t});\n\t\t}\n\n\t\tconst ch = channels[th.channelIndex];\n\t\tconst instrumentName = ch ? `MIDI ${ch.instrument}` : null;\n\n\t\treturn {\n\t\t\tid: String(trackIdx),\n\t\t\tname: th.name,\n\t\t\tshortName: th.name.substring(0, 4),\n\t\t\tinstrument: instrumentName,\n\t\t\ttuning,\n\t\t\ttuningMidi: [...tuningPitches],\n\t\t\tcapoFret: th.capoFret,\n\t\t\tbars\n\t\t};\n\t});\n\n\treturn {\n\t\ttitle: info.title || info.subtitle || '',\n\t\tartist: info.artist,\n\t\talbum: info.album,\n\t\ttempo,\n\t\ttracks\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Parses a Guitar Pro 5 (.gp5) file from raw bytes into a TabSong. */\nexport function parseGp5File(data: Uint8Array): TabSong {\n\tconst buf = new ArrayBuffer(data.byteLength);\n\tnew Uint8Array(buf).set(data);\n\tconst r = new GP5Reader(buf);\n\n\t// Version string: ByteSizeString of size 30 (1 byte len + 30 chars)\n\tconst versionStr = r.readByteSizeString(30);\n\tconst version = parseVersionString(versionStr);\n\n\t// Validate it's a GP5 file\n\tif (version.major !== 5) {\n\t\tthrow new Error(`Unsupported Guitar Pro version: ${versionStr} (expected GP5)`);\n\t}\n\n\t// Score information\n\tconst info = readInfo(r);\n\n\t// Lyrics\n\treadLyrics(r);\n\n\t// RSE master effect\n\treadRSEMasterEffect(r, version);\n\n\t// Page setup\n\treadPageSetup(r);\n\n\t// Tempo\n\tr.readIntByteSizeString(); // tempo name\n\tconst tempo = r.readInt();\n\n\t// Hide tempo (GP5.1+)\n\tif (versionGreaterThan(version, 5, 0, 0)) {\n\t\tr.readBool();\n\t}\n\n\t// Key signature + octave\n\tr.readSignedByte(); // key\n\tr.readInt(); // octave\n\n\t// MIDI channels\n\tconst channels = readMidiChannels(r);\n\n\t// Directions (GP5)\n\treadDirections(r);\n\n\t// Master reverb\n\tr.readInt();\n\n\t// Measure count + track count\n\tconst measureCount = r.readInt();\n\tconst trackCount = r.readInt();\n\n\t// Measure headers\n\tconst measureHeaders = readMeasureHeaders(r, measureCount, version);\n\n\t// Tracks\n\tconst trackHeaders = readTrackHeaders(r, trackCount, version);\n\n\t// Measures (the actual beat/note data)\n\tconst parsedMeasures = readMeasures(r, measureCount, trackHeaders, version);\n\n\treturn transformToTabSong(info, tempo, measureHeaders, trackHeaders, parsedMeasures, channels);\n}\n","/**\n * Copyright 2026 Emilien Bevierre\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * GP3 parser : decodes Guitar Pro 3 (.gp3) binary files and transforms them\n * into TabSong structures. Pure, zero native dependencies.\n *\n * Pipeline: Uint8Array → sequential binary read → TabSong\n *\n * Based on the PyGuitarPro GP3 format specification.\n * GP3 is the simplest of the Guitar Pro legacy binary formats:\n * - 1 voice per measure (vs 2 in GP5)\n * - No lyrics, RSE, page setup, or directions blocks\n * - Simpler beat/note effects (single flag byte each)\n * - No second note flags byte\n * - Tremolo bar is a simple Int value (dip only)\n */\n\nimport type { PitchClass, Note } from './pitch.js';\nimport { noteFromPitchClass, midiToPitchClass } from './pitch.js';\nimport type {\n\tDuration,\n\tTabNote,\n\tTabBeat,\n\tTabBar,\n\tTabTrack,\n\tTabSong\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Binary reader — sequential LE reader with position tracking\n// ---------------------------------------------------------------------------\n\nclass GP3Reader {\n\tprivate view: DataView;\n\tprivate buf: Uint8Array;\n\tprivate pos: number;\n\treadonly byteLength: number;\n\n\tconstructor(buffer: ArrayBuffer) {\n\t\tthis.view = new DataView(buffer);\n\t\tthis.buf = new Uint8Array(buffer);\n\t\tthis.pos = 0;\n\t\tthis.byteLength = buffer.byteLength;\n\t}\n\n\tgetPosition(): number {\n\t\treturn this.pos;\n\t}\n\n\tskip(n: number): void {\n\t\tthis.pos += n;\n\t}\n\n\treadByte(): number {\n\t\tconst v = this.buf[this.pos];\n\t\tthis.pos += 1;\n\t\treturn v;\n\t}\n\n\treadSignedByte(): number {\n\t\tconst v = this.view.getInt8(this.pos);\n\t\tthis.pos += 1;\n\t\treturn v;\n\t}\n\n\treadBool(): boolean {\n\t\treturn this.readByte() !== 0;\n\t}\n\n\treadShort(): number {\n\t\tconst v = this.view.getInt16(this.pos, true);\n\t\tthis.pos += 2;\n\t\treturn v;\n\t}\n\n\treadInt(): number {\n\t\tconst v = this.view.getInt32(this.pos, true);\n\t\tthis.pos += 4;\n\t\treturn v;\n\t}\n\n\t/** Reads IntByteSizeString: int(strLen+1) + byte(strLen) + chars. */\n\treadIntByteSizeString(): string {\n\t\tconst totalSize = this.readInt();\n\t\tconst strLen = this.readByte();\n\t\tconst str = this.readChars(strLen);\n\t\tconst padding = Math.max(0, totalSize - 1 - strLen);\n\t\tthis.skip(padding);\n\t\treturn str;\n\t}\n\n\t/** Reads ByteSizeString with fixed buffer length. */\n\treadByteSizeString(fixedLen: number): string {\n\t\tconst strLen = this.readByte();\n\t\tconst str = this.readChars(Math.min(strLen, fixedLen));\n\t\tconst remaining = fixedLen - Math.min(strLen, fixedLen);\n\t\tthis.skip(remaining);\n\t\treturn str;\n\t}\n\n\tprivate readChars(length: number): string {\n\t\tconst chars: number[] = [];\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tchars.push(this.buf[this.pos + i]);\n\t\t}\n\t\tthis.pos += length;\n\t\treturn String.fromCharCode(...chars);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Duration mapping\n// ---------------------------------------------------------------------------\n\nconst GP_DURATION_MAP: Record<number, Duration> = {\n\t[-2]: 'whole',\n\t[-1]: 'half',\n\t[0]: 'quarter',\n\t[1]: 'eighth',\n\t[2]: '16th',\n\t[3]: '32nd',\n\t[4]: '64th',\n\t[5]: '128th'\n};\n\nfunction gpDurationToDuration(value: number): Duration {\n\treturn GP_DURATION_MAP[value] ?? 'quarter';\n}\n\n// ---------------------------------------------------------------------------\n// Tuplet mapping\n// ---------------------------------------------------------------------------\n\nconst TUPLET_MAP: Record<number, { num: number; den: number }> = {\n\t3: { num: 3, den: 2 },\n\t5: { num: 5, den: 4 },\n\t6: { num: 6, den: 4 },\n\t7: { num: 7, den: 4 },\n\t9: { num: 9, den: 8 },\n\t10: { num: 10, den: 8 },\n\t11: { num: 11, den: 8 },\n\t12: { num: 12, den: 8 },\n\t13: { num: 13, den: 8 }\n};\n\n// ---------------------------------------------------------------------------\n// MIDI channel info\n// ---------------------------------------------------------------------------\n\ninterface MidiChannel {\n\tinstrument: number;\n\tvolume: number;\n\tbalance: number;\n\tchorus: number;\n\treverb: number;\n\tphaser: number;\n\ttremolo: number;\n}\n\n// ---------------------------------------------------------------------------\n// Measure header\n// ---------------------------------------------------------------------------\n\ninterface MeasureHeader {\n\tnumerator: number;\n\tdenominator: number;\n\trepeatOpen: boolean;\n\trepeatClose: number;\n\trepeatAlternative: number;\n\tmarker: { name: string; color: [number, number, number] } | null;\n\tkeySignature: number;\n\tkeyMode: number;\n\thasDoubleBar: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Track header\n// ---------------------------------------------------------------------------\n\ninterface TrackHeader {\n\tname: string;\n\tisPercussion: boolean;\n\tnumStrings: number;\n\ttuning: number[];\n\tport: number;\n\tchannelIndex: number;\n\teffectChannel: number;\n\tfretCount: number;\n\tcapoFret: number;\n}\n\n// ---------------------------------------------------------------------------\n// Internal beat/note structures used during parsing\n// ---------------------------------------------------------------------------\n\ninterface GP3ParsedNote {\n\tstring: number;\n\tfret: number;\n\tisTied: boolean;\n\tisDead: boolean;\n\tvelocity: number;\n\thammerOn: boolean;\n\tletRing: boolean;\n\tslide: boolean;\n\tbend: { type: number; value: number; points: { position: number; value: number; vibrato: boolean }[] } | null;\n}\n\ninterface GP3ParsedBeat {\n\tduration: Duration;\n\tdotted: boolean;\n\ttuplet: { num: number; den: number } | null;\n\tisRest: boolean;\n\tisEmpty: boolean;\n\tnotes: GP3ParsedNote[];\n}\n\n// ---------------------------------------------------------------------------\n// Read helpers — individual GP3 binary sections\n// ---------------------------------------------------------------------------\n\n/** GP3 readInfo: 8 fields (no separate \"music\" field). */\nfunction readInfo(r: GP3Reader): { title: string; subtitle: string; artist: string; album: string } {\n\tconst title = r.readIntByteSizeString();\n\tconst subtitle = r.readIntByteSizeString();\n\tconst artist = r.readIntByteSizeString();\n\tconst album = r.readIntByteSizeString();\n\tr.readIntByteSizeString(); // words (= music in GP3)\n\tr.readIntByteSizeString(); // copyright\n\tr.readIntByteSizeString(); // tab\n\tr.readIntByteSizeString(); // instructions\n\n\t// Notice lines\n\tconst noticeCount = r.readInt();\n\tfor (let i = 0; i < noticeCount; i++) {\n\t\tr.readIntByteSizeString();\n\t}\n\n\treturn { title, subtitle, artist, album };\n}\n\nfunction readMidiChannels(r: GP3Reader): MidiChannel[] {\n\tconst channels: MidiChannel[] = [];\n\tfor (let i = 0; i < 64; i++) {\n\t\tconst instrument = r.readInt();\n\t\tconst volume = r.readByte();\n\t\tconst balance = r.readByte();\n\t\tconst chorus = r.readByte();\n\t\tconst reverb = r.readByte();\n\t\tconst phaser = r.readByte();\n\t\tconst tremolo = r.readByte();\n\t\tr.skip(2); // padding\n\t\tchannels.push({ instrument, volume, balance, chorus, reverb, phaser, tremolo });\n\t}\n\treturn channels;\n}\n\nfunction readMeasureHeaders(r: GP3Reader, count: number): MeasureHeader[] {\n\tconst headers: MeasureHeader[] = [];\n\tlet prevNumerator = 4;\n\tlet prevDenominator = 4;\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst flags = r.readByte();\n\n\t\tlet numerator = prevNumerator;\n\t\tlet denominator = prevDenominator;\n\n\t\tif (flags & 0x01) {\n\t\t\tnumerator = r.readSignedByte();\n\t\t}\n\t\tif (flags & 0x02) {\n\t\t\tdenominator = r.readSignedByte();\n\t\t}\n\n\t\tconst repeatOpen = (flags & 0x04) !== 0;\n\n\t\tlet repeatClose = -1;\n\t\tif (flags & 0x08) {\n\t\t\trepeatClose = r.readSignedByte();\n\t\t}\n\n\t\tlet repeatAlternative = 0;\n\t\tif (flags & 0x10) {\n\t\t\trepeatAlternative = r.readByte();\n\t\t}\n\n\t\tlet marker: MeasureHeader['marker'] = null;\n\t\tif (flags & 0x20) {\n\t\t\tconst name = r.readIntByteSizeString();\n\t\t\tconst colorR = r.readByte();\n\t\t\tconst colorG = r.readByte();\n\t\t\tconst colorB = r.readByte();\n\t\t\tr.skip(1); // padding\n\t\t\tmarker = { name, color: [colorR, colorG, colorB] };\n\t\t}\n\n\t\tlet keySignature = 0;\n\t\tlet keyMode = 0;\n\t\tif (flags & 0x40) {\n\t\t\tkeySignature = r.readSignedByte();\n\t\t\tkeyMode = r.readSignedByte();\n\t\t}\n\n\t\tconst hasDoubleBar = (flags & 0x80) !== 0;\n\n\t\theaders.push({\n\t\t\tnumerator,\n\t\t\tdenominator,\n\t\t\trepeatOpen,\n\t\t\trepeatClose,\n\t\t\trepeatAlternative,\n\t\t\tmarker,\n\t\t\tkeySignature,\n\t\t\tkeyMode,\n\t\t\thasDoubleBar\n\t\t});\n\n\t\tprevNumerator = numerator;\n\t\tprevDenominator = denominator;\n\t}\n\n\treturn headers;\n}\n\nfunction readTrackHeaders(r: GP3Reader, count: number): TrackHeader[] {\n\tconst tracks: TrackHeader[] = [];\n\n\tfor (let i = 0; i < count; i++) {\n\t\tconst flags1 = r.readByte();\n\t\tconst isPercussion = (flags1 & 0x01) !== 0;\n\n\t\tconst name = r.readByteSizeString(40);\n\t\tconst numStrings = r.readInt();\n\n\t\tconst tuning: number[] = [];\n\t\tfor (let s = 0; s < 7; s++) {\n\t\t\tconst val = r.readInt();\n\t\t\tif (s < numStrings) tuning.push(val);\n\t\t}\n\n\t\tconst port = r.readInt();\n\t\tconst channelIndex = r.readInt() - 1; // 1-based → 0-based\n\t\tconst effectChannel = r.readInt() - 1;\n\t\tconst fretCount = r.readInt();\n\t\tconst capoFret = r.readInt();\n\t\tr.skip(4); // color (3 bytes + padding)\n\n\t\ttracks.push({ name, isPercussion, numStrings, tuning, port, channelIndex, effectChannel, fretCount, capoFret });\n\t}\n\n\treturn tracks;\n}\n\n// ---------------------------------------------------------------------------\n// Measure / Beat / Note reading — the per-measure data block\n// ---------------------------------------------------------------------------\n\n/** GP3: single voice per measure, no voice2, no linebreak byte. */\nfunction readMeasures(\n\tr: GP3Reader,\n\tmeasureCount: number,\n\ttrackHeaders: TrackHeader[]\n): GP3ParsedBeat[][][] {\n\tconst trackCount = trackHeaders.length;\n\tconst allMeasures: GP3ParsedBeat[][][] = [];\n\tfor (let t = 0; t < trackCount; t++) {\n\t\tallMeasures.push([]);\n\t}\n\n\tfor (let m = 0; m < measureCount; m++) {\n\t\tfor (let t = 0; t < trackCount; t++) {\n\t\t\tconst beats = readVoice(r, trackHeaders[t].numStrings);\n\t\t\tallMeasures[t].push(beats);\n\t\t}\n\t}\n\n\treturn allMeasures;\n}\n\nfunction readVoice(r: GP3Reader, numStrings: number): GP3ParsedBeat[] {\n\tconst beatCount = r.readInt();\n\tconst beats: GP3ParsedBeat[] = [];\n\n\tfor (let b = 0; b < beatCount; b++) {\n\t\tbeats.push(readBeat(r, numStrings));\n\t}\n\n\treturn beats;\n}\n\nfunction readBeat(r: GP3Reader, numStrings: number): GP3ParsedBeat {\n\tconst flags = r.readByte();\n\n\tlet isRest = false;\n\tlet isEmpty = false;\n\tif (flags & 0x40) {\n\t\tconst status = r.readByte();\n\t\tisEmpty = status === 0x00;\n\t\tisRest = status === 0x02;\n\t}\n\n\t// Duration\n\tconst durationValue = r.readSignedByte();\n\tconst duration = gpDurationToDuration(durationValue);\n\tconst dotted = (flags & 0x01) !== 0;\n\n\tlet tuplet: { num: number; den: number } | null = null;\n\tif (flags & 0x20) {\n\t\tconst tupletValue = r.readInt();\n\t\ttuplet = TUPLET_MAP[tupletValue] ?? null;\n\t}\n\n\t// Chord diagram\n\tif (flags & 0x02) {\n\t\treadChord(r);\n\t}\n\n\t// Text\n\tif (flags & 0x04) {\n\t\tr.readIntByteSizeString();\n\t}\n\n\t// Beat effects (GP3: single flag byte)\n\tif (flags & 0x08) {\n\t\treadBeatEffects(r);\n\t}\n\n\t// Mix table change\n\tif (flags & 0x10) {\n\t\treadMixTableChange(r);\n\t}\n\n\t// Notes — bit 6 = GP string 1 (highest pitch), bit 0 = GP string 7\n\tconst stringFlags = r.readByte();\n\tconst notes: GP3ParsedNote[] = [];\n\n\tfor (let i = 6; i >= 0; i--) {\n\t\tif (stringFlags & (1 << i)) {\n\t\t\tconst gpString = 7 - i; // 1-based, 1 = highest pitch string\n\t\t\tconst tuningIndex = gpString - 1; // 0-based into tuning array (0 = highest pitch string)\n\t\t\tconst note = readNote(r);\n\t\t\tnote.string = tuningIndex;\n\t\t\tnotes.push(note);\n\t\t}\n\t}\n\n\treturn { duration, dotted, tuplet, isRest: isRest || isEmpty, isEmpty, notes };\n}\n\nfunction readChord(r: GP3Reader): void {\n\tconst newFormat = r.readBool();\n\tif (!newFormat) {\n\t\t// GP3 old chord format\n\t\tr.readIntByteSizeString(); // name\n\t\tconst firstFret = r.readInt();\n\t\tif (firstFret !== 0) {\n\t\t\tfor (let i = 0; i < 6; i++) r.readInt();\n\t\t}\n\t} else {\n\t\t// GP4+ new format chord (can appear in GP3 files saved by later editors)\n\t\tr.readBool(); // sharp\n\t\tr.skip(3); // blank\n\t\tr.readInt(); // root\n\t\tr.readInt(); // type\n\t\tr.readInt(); // extension\n\t\tr.readInt(); // bass note\n\t\tr.readInt(); // tonality\n\t\tr.readBool(); // add\n\t\tr.readByteSizeString(22); // name\n\t\tr.readInt(); // fifth\n\t\tr.readInt(); // ninth\n\t\tr.readInt(); // eleventh\n\t\tr.readInt(); // first fret\n\t\tfor (let i = 0; i < 6; i++) r.readInt(); // frets\n\t\tr.readInt(); // barres count\n\t\tr.readInt(); r.readInt(); // barre frets\n\t\tr.readInt(); r.readInt(); // barre starts\n\t\tr.readInt(); r.readInt(); // barre ends\n\t\tfor (let i = 0; i < 7; i++) r.readBool(); // omissions\n\t\tr.skip(1); // blank\n\t}\n}\n\n/** GP3 beat effects: single flag byte. */\nfunction readBeatEffects(r: GP3Reader): void {\n\tconst flags1 = r.readByte();\n\n\tif (flags1 & 0x20) {\n\t\tconst slapEffect = r.readByte();\n\t\tif (slapEffect === 0) {\n\t\t\t// Tremolo bar — GP3 stores only the dip value as Int\n\t\t\tr.readInt();\n\t\t} else {\n\t\t\t// Slap/tap/pop — read accompanying Int\n\t\t\tr.readInt();\n\t\t}\n\t}\n\n\tif (flags1 & 0x40) {\n\t\t// Beat stroke: down + up\n\t\tr.readByte();\n\t\tr.readByte();\n\t}\n}\n\n/** GP3 mix table change: simpler than GP5 (no RSE, no tempo name, no wah). */\nfunction readMixTableChange(r: GP3Reader): void {\n\tr.readSignedByte(); // instrument\n\tconst volume = r.readSignedByte();\n\tconst balance = r.readSignedByte();\n\tconst chorus = r.readSignedByte();\n\tconst reverb = r.readSignedByte();\n\tconst phaser = r.readSignedByte();\n\tconst tremolo = r.readSignedByte();\n\tconst tempo = r.readInt();\n\n\t// Durations for changed values\n\tif (volume >= 0) r.readSignedByte();\n\tif (balance >= 0) r.readSignedByte();\n\tif (chorus >= 0) r.readSignedByte();\n\tif (reverb >= 0) r.readSignedByte();\n\tif (phaser >= 0) r.readSignedByte();\n\tif (tremolo >= 0) r.readSignedByte();\n\tif (tempo >= 0) r.readSignedByte();\n}\n\nfunction readNote(r: GP3Reader): GP3ParsedNote {\n\tconst flags = r.readByte();\n\n\tlet isTied = false;\n\tlet isDead = false;\n\tif (flags & 0x20) {\n\t\tconst noteType = r.readByte();\n\t\tisTied = noteType === 2;\n\t\tisDead = noteType === 3;\n\t}\n\n\t// Time-independent duration (GP3: 2 signed bytes)\n\tif (flags & 0x01) {\n\t\tr.readSignedByte(); // duration\n\t\tr.readSignedByte(); // tuplet\n\t}\n\n\tlet velocity = 8; // default mf\n\tif (flags & 0x10) {\n\t\tvelocity = r.readSignedByte();\n\t}\n\n\tlet fret = 0;\n\tif (flags & 0x20) {\n\t\tfret = r.readSignedByte();\n\t\tif (fret < 0 || fret > 99) fret = 0;\n\t}\n\n\tif (flags & 0x80) {\n\t\tr.readSignedByte(); // left hand finger\n\t\tr.readSignedByte(); // right hand finger\n\t}\n\n\t// GP3: NO second flags byte\n\n\t// Note effects\n\tlet hammerOn = false;\n\tlet letRing = false;\n\tlet slide = false;\n\tlet bend: GP3ParsedNote['bend'] = null;\n\n\tif (flags & 0x08) {\n\t\tconst result = readNoteEffects(r);\n\t\thammerOn = result.hammerOn;\n\t\tletRing = result.letRing;\n\t\tslide = result.slide;\n\t\tbend = result.bend;\n\t}\n\n\treturn {\n\t\tstring: 0, // Will be set by caller based on string index\n\t\tfret,\n\t\tisTied,\n\t\tisDead,\n\t\tvelocity,\n\t\thammerOn,\n\t\tletRing,\n\t\tslide,\n\t\tbend\n\t};\n}\n\ninterface NoteEffectsResult {\n\thammerOn: boolean;\n\tletRing: boolean;\n\tslide: boolean;\n\tbend: GP3ParsedNote['bend'];\n}\n\n/** GP3 note effects: single flag byte. */\nfunction readNoteEffects(r: GP3Reader): NoteEffectsResult {\n\tconst flags = r.readByte();\n\n\tlet bend: GP3ParsedNote['bend'] = null;\n\tconst hammerOn = (flags & 0x02) !== 0;\n\tconst slide = (flags & 0x04) !== 0;\n\tconst letRing = (flags & 0x08) !== 0;\n\n\tif (flags & 0x01) {\n\t\tbend = readBend(r);\n\t}\n\n\tif (flags & 0x10) {\n\t\treadGraceNote(r);\n\t}\n\n\treturn { hammerOn, letRing, slide, bend };\n}\n\nfunction readBend(r: GP3Reader): { type: number; value: number; points: { position: number; value: number; vibrato: boolean }[] } {\n\tconst type = r.readSignedByte();\n\tconst value = r.readInt();\n\tconst pointCount = r.readInt();\n\tconst points: { position: number; value: number; vibrato: boolean }[] = [];\n\tfor (let i = 0; i < pointCount; i++) {\n\t\tconst position = r.readInt();\n\t\tconst pointValue = r.readInt();\n\t\tconst vibrato = r.readBool();\n\t\tpoints.push({ position, value: pointValue, vibrato });\n\t}\n\treturn { type, value, points };\n}\n\nfunction readGraceNote(r: GP3Reader): void {\n\tr.readByte(); // fret\n\tr.readByte(); // velocity\n\tr.readByte(); // transition\n\tr.readByte(); // duration\n}\n\n// ---------------------------------------------------------------------------\n// Transform parsed GP3 data → TabSong\n// ---------------------------------------------------------------------------\n\nfunction transformToTabSong(\n\tinfo: { title: string; subtitle: string; artist: string; album: string },\n\ttempo: number,\n\tmeasureHeaders: MeasureHeader[],\n\ttrackHeaders: TrackHeader[],\n\tparsedMeasures: GP3ParsedBeat[][][],\n\tchannels: MidiChannel[]\n): TabSong {\n\tconst tracks: TabTrack[] = trackHeaders.map((th, trackIdx) => {\n\t\tconst tuningPitches = th.tuning;\n\t\tconst tuning: Note[] = tuningPitches\n\t\t\t.map((midi) => noteFromPitchClass(midiToPitchClass(midi)));\n\n\t\tlet globalBeatIndex = 0;\n\t\tconst bars: TabBar[] = [];\n\n\t\tfor (let mIdx = 0; mIdx < measureHeaders.length; mIdx++) {\n\t\t\tconst mh = measureHeaders[mIdx];\n\t\t\tconst beatsData = parsedMeasures[trackIdx]?.[mIdx] ?? [];\n\n\t\t\tconst tabBeats: TabBeat[] = [];\n\n\t\t\tfor (const beatData of beatsData) {\n\t\t\t\tif (beatData.isEmpty) continue;\n\n\t\t\t\tconst stringCount = th.numStrings;\n\t\t\t\tconst tabNotes: TabNote[] = [];\n\n\t\t\t\tfor (const noteData of beatData.notes) {\n\t\t\t\t\tconst tuningIndex = noteData.string; // 0-based, 0 = highest pitch string (matches GP tuning array order)\n\t\t\t\t\tconst stringIdx = tuningIndex; // display order: 0 = highest pitch string\n\t\t\t\t\tconst fret = noteData.fret;\n\t\t\t\t\tconst openPitch = tuningPitches[tuningIndex] ?? 0;\n\t\t\t\t\tconst pc = (((openPitch + th.capoFret + fret) % 12 + 12) % 12) as PitchClass;\n\t\t\t\t\tconst note = noteFromPitchClass(pc, false);\n\n\t\t\t\t\tlet bendResult: TabNote['bend'] = null;\n\t\t\t\t\tif (noteData.bend) {\n\t\t\t\t\t\tconst points = noteData.bend.points;\n\t\t\t\t\t\tconst origin = points.length > 0 ? points[0].value / 100 : 0;\n\t\t\t\t\t\tconst destination = points.length > 1 ? points[points.length - 1].value / 100 : 0;\n\t\t\t\t\t\tconst middle = points.length > 2 ? points[Math.floor(points.length / 2)].value / 100 : 0;\n\t\t\t\t\t\tbendResult = { origin, destination, middle };\n\t\t\t\t\t}\n\n\t\t\t\t\ttabNotes.push({\n\t\t\t\t\t\tstring: stringIdx,\n\t\t\t\t\t\tfret,\n\t\t\t\t\t\tpitchClass: pc,\n\t\t\t\t\t\tnoteName: note.name,\n\t\t\t\t\t\tslide: noteData.slide ? 1 : null,\n\t\t\t\t\t\tharmonic: null,\n\t\t\t\t\t\tpalmMute: false,\n\t\t\t\t\t\tmuted: noteData.isDead,\n\t\t\t\t\t\tletRing: noteData.letRing,\n\t\t\t\t\t\tbend: bendResult,\n\t\t\t\t\t\ttie: {\n\t\t\t\t\t\t\torigin: false,\n\t\t\t\t\t\t\tdestination: noteData.isTied\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvibrato: null,\n\t\t\t\t\t\thammerOn: noteData.hammerOn,\n\t\t\t\t\t\tpullOff: false,\n\t\t\t\t\t\ttapped: false,\n\t\t\t\t\t\taccent: null\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\ttabBeats.push({\n\t\t\t\t\tindex: globalBeatIndex++,\n\t\t\t\t\tbarIndex: mIdx,\n\t\t\t\t\tnotes: tabNotes,\n\t\t\t\t\tduration: beatData.duration,\n\t\t\t\t\ttuplet: beatData.tuplet,\n\t\t\t\t\tdotted: beatData.dotted ? 1 : 0,\n\t\t\t\t\tisRest: beatData.isRest && tabNotes.length === 0,\n\t\t\t\t\tdynamic: null,\n\t\t\t\t\ttempo\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst section = mh.marker\n\t\t\t\t? { text: mh.marker.name }\n\t\t\t\t: null;\n\n\t\t\tbars.push({\n\t\t\t\tindex: mIdx,\n\t\t\t\ttimeSignature: { numerator: mh.numerator, denominator: mh.denominator },\n\t\t\t\tkeySignature: mh.keySignature !== 0\n\t\t\t\t\t? { accidentalCount: mh.keySignature, mode: mh.keyMode === 1 ? 'minor' : 'major' }\n\t\t\t\t\t: null,\n\t\t\t\tsection,\n\t\t\t\tbeats: tabBeats,\n\t\t\t\trepeatStart: mh.repeatOpen,\n\t\t\t\trepeatEnd: mh.repeatClose >= 0,\n\t\t\t\trepeatCount: mh.repeatClose >= 0 ? mh.repeatClose : 0\n\t\t\t});\n\t\t}\n\n\t\tconst ch = channels[th.channelIndex];\n\t\tconst instrumentName = ch ? `MIDI ${ch.instrument}` : null;\n\n\t\treturn {\n\t\t\tid: String(trackIdx),\n\t\t\tname: th.name,\n\t\t\tshortName: th.name.substring(0, 4),\n\t\t\tinstrument: instrumentName,\n\t\t\ttuning,\n\t\t\ttuningMidi: [...tuningPitches],\n\t\t\tcapoFret: th.capoFret,\n\t\t\tbars\n\t\t};\n\t});\n\n\treturn {\n\t\ttitle: info.title || info.subtitle || '',\n\t\tartist: info.artist,\n\t\talbum: info.album,\n\t\ttempo,\n\t\ttracks\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/** Parses a Guitar Pro 3 (.gp3) file from raw bytes into a TabSong. */\nexport function parseGp3File(data: Uint8Array): TabSong {\n\tconst buf = new ArrayBuffer(data.byteLength);\n\tnew Uint8Array(buf).set(data);\n\tconst r = new GP3Reader(buf);\n\n\t// Version string: ByteSizeString of size 30\n\tconst versionStr = r.readByteSizeString(30);\n\n\t// Validate it's a GP3 file\n\tif (!versionStr.includes('GUITAR PRO') || !versionStr.includes('v3')) {\n\t\tthrow new Error(`Unsupported Guitar Pro version: ${versionStr} (expected GP3)`);\n\t}\n\n\t// Score information (GP3: 8 fields, no separate \"music\")\n\tconst info = readInfo(r);\n\n\t// Triplet feel (GP3: global bool, not per-measure)\n\tr.readBool();\n\n\t// Tempo\n\tconst tempo = r.readInt();\n\n\t// Key signature\n\tr.readInt();\n\n\t// MIDI channels\n\tconst channels = readMidiChannels(r);\n\n\t// Measure count + track count\n\tconst measureCount = r.readInt();\n\tconst trackCount = r.readInt();\n\n\t// Measure headers\n\tconst measureHeaders = readMeasureHeaders(r, measureCount);\n\n\t// Tracks\n\tconst trackHeaders = readTrackHeaders(r, trackCount);\n\n\t// Measures (the actual beat/note data)\n\tconst parsedMeasures = readMeasures(r, measureCount, trackHeaders);\n\n\treturn transformToTabSong(info, tempo, measureHeaders, trackHeaders, parsedMeasures, channels);\n}\n","/**\n * Copyright 2026 Emilien Bevierre\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Unified Guitar Pro file parser — dispatches to format-specific parsers\n * based on file header detection.\n *\n * Supported formats:\n * - .gpx  → BCFZ/BCFS container (Guitar Pro 6)\n * - .gp   → ZIP container with Content/score.gpif (Guitar Pro 7+)\n * - .gp5  → Legacy sequential binary (Guitar Pro 5)\n * - .gp3  → Legacy sequential binary (Guitar Pro 3)\n *\n * Pure, zero native dependencies.\n */\n\nimport type { TabSong } from './types.js';\nimport { parseGpxFile, gpifToTabSong } from './gpx-parser.js';\nimport { parseGp5File } from './gp5-parser.js';\nimport { parseGp3File } from './gp3-parser.js';\nimport { getDOMParser } from './dom.js';\n\n// ---------------------------------------------------------------------------\n// Minimal ZIP extractor — handles STORE and DEFLATE methods\n// ---------------------------------------------------------------------------\n\n/** Central Directory entry with resolved sizes for files using data descriptors. */\ninterface ZipCentralEntry {\n\tfileName: string;\n\tcompressionMethod: number;\n\tcompressedSize: number;\n\tuncompressedSize: number;\n\tlocalHeaderOffset: number;\n}\n\n/** Finds the End of Central Directory record and reads all central entries. */\nfunction readCentralDirectory(data: Uint8Array, view: DataView): ZipCentralEntry[] {\n\t// Scan backwards for End of Central Directory signature (0x06054b50)\n\tlet eocdOffset = -1;\n\tfor (let i = data.byteLength - 22; i >= 0; i--) {\n\t\tif (view.getUint32(i, true) === 0x06054b50) {\n\t\t\teocdOffset = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (eocdOffset === -1) return [];\n\n\tconst cdOffset = view.getUint32(eocdOffset + 16, true);\n\tconst cdEntryCount = view.getUint16(eocdOffset + 10, true);\n\n\tconst entries: ZipCentralEntry[] = [];\n\tlet pos = cdOffset;\n\n\tfor (let i = 0; i < cdEntryCount; i++) {\n\t\tif (pos + 46 > data.byteLength) break;\n\t\tif (view.getUint32(pos, true) !== 0x02014b50) break;\n\n\t\tconst compressionMethod = view.getUint16(pos + 10, true);\n\t\tconst compressedSize = view.getUint32(pos + 20, true);\n\t\tconst uncompressedSize = view.getUint32(pos + 24, true);\n\t\tconst nameLength = view.getUint16(pos + 28, true);\n\t\tconst extraLength = view.getUint16(pos + 30, true);\n\t\tconst commentLength = view.getUint16(pos + 32, true);\n\t\tconst localHeaderOffset = view.getUint32(pos + 42, true);\n\n\t\tconst nameBytes = data.subarray(pos + 46, pos + 46 + nameLength);\n\t\tconst fileName = String.fromCharCode(...nameBytes);\n\n\t\tentries.push({ fileName, compressionMethod, compressedSize, uncompressedSize, localHeaderOffset });\n\t\tpos += 46 + nameLength + extraLength + commentLength;\n\t}\n\n\treturn entries;\n}\n\n/**\n * Extracts a single file from a ZIP archive by name.\n * Uses the Central Directory for reliable size info (handles data descriptors).\n * Supports compression methods 0 (STORE) and 8 (DEFLATE).\n */\nfunction extractFileFromZip(data: Uint8Array, targetName: string): Uint8Array | null {\n\tconst view = new DataView(data.buffer, data.byteOffset, data.byteLength);\n\tconst entries = readCentralDirectory(data, view);\n\n\tconst entry = entries.find((e) => e.fileName === targetName);\n\tif (!entry) return null;\n\n\t// Read past the local file header to find the data\n\tconst localOffset = entry.localHeaderOffset;\n\tif (view.getUint32(localOffset, true) !== 0x04034b50) return null;\n\n\tconst localNameLength = view.getUint16(localOffset + 26, true);\n\tconst localExtraLength = view.getUint16(localOffset + 28, true);\n\tconst dataOffset = localOffset + 30 + localNameLength + localExtraLength;\n\n\tconst compressedData = data.subarray(dataOffset, dataOffset + entry.compressedSize);\n\n\tif (entry.compressionMethod === 0) {\n\t\treturn compressedData;\n\t} else if (entry.compressionMethod === 8) {\n\t\treturn decompressDeflateSync(compressedData, entry.uncompressedSize);\n\t} else {\n\t\tthrow new Error(`Unsupported ZIP compression method: ${entry.compressionMethod}`);\n\t}\n}\n\n/** Decompresses raw DEFLATE data using a synchronous inflate implementation. */\nfunction decompressDeflateSync(compressed: Uint8Array, expectedSize: number): Uint8Array {\n\treturn inflate(compressed, expectedSize);\n}\n\n// ---------------------------------------------------------------------------\n// Minimal INFLATE implementation — pure JS, handles raw DEFLATE (no zlib header)\n// ---------------------------------------------------------------------------\n\n/** Fixed Huffman code length tables per RFC 1951 */\nfunction buildFixedLitLenTree(): { codes: Uint16Array; lengths: Uint8Array } {\n\tconst lengths = new Uint8Array(288);\n\tfor (let i = 0; i <= 143; i++) lengths[i] = 8;\n\tfor (let i = 144; i <= 255; i++) lengths[i] = 9;\n\tfor (let i = 256; i <= 279; i++) lengths[i] = 7;\n\tfor (let i = 280; i <= 287; i++) lengths[i] = 8;\n\treturn buildHuffmanTable(lengths);\n}\n\nfunction buildFixedDistTree(): { codes: Uint16Array; lengths: Uint8Array } {\n\tconst lengths = new Uint8Array(32);\n\tlengths.fill(5);\n\treturn buildHuffmanTable(lengths);\n}\n\n/** Builds a Huffman decoding table from code lengths. */\nfunction buildHuffmanTable(codeLengths: Uint8Array): { codes: Uint16Array; lengths: Uint8Array } {\n\tconst maxBits = Math.max(...codeLengths);\n\tconst count = new Uint16Array(maxBits + 1);\n\tfor (const len of codeLengths) {\n\t\tif (len > 0) count[len]++;\n\t}\n\n\tconst nextCode = new Uint16Array(maxBits + 1);\n\tlet code = 0;\n\tfor (let bits = 1; bits <= maxBits; bits++) {\n\t\tcode = (code + count[bits - 1]) << 1;\n\t\tnextCode[bits] = code;\n\t}\n\n\tconst codes = new Uint16Array(codeLengths.length);\n\tconst lengths = new Uint8Array(codeLengths.length);\n\tfor (let i = 0; i < codeLengths.length; i++) {\n\t\tconst len = codeLengths[i];\n\t\tif (len > 0) {\n\t\t\tcodes[i] = nextCode[len]++;\n\t\t\tlengths[i] = len;\n\t\t}\n\t}\n\n\treturn { codes, lengths };\n}\n\n/** Bit reader for DEFLATE streams. */\nclass BitReader {\n\tprivate data: Uint8Array;\n\tprivate bytePos: number;\n\tprivate bitPos: number;\n\n\tconstructor(data: Uint8Array) {\n\t\tthis.data = data;\n\t\tthis.bytePos = 0;\n\t\tthis.bitPos = 0;\n\t}\n\n\treadBits(n: number): number {\n\t\tlet result = 0;\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tif (this.bytePos >= this.data.length) return result;\n\t\t\tresult |= ((this.data[this.bytePos] >> this.bitPos) & 1) << i;\n\t\t\tthis.bitPos++;\n\t\t\tif (this.bitPos === 8) {\n\t\t\t\tthis.bitPos = 0;\n\t\t\t\tthis.bytePos++;\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\talignToByte(): void {\n\t\tif (this.bitPos > 0) {\n\t\t\tthis.bitPos = 0;\n\t\t\tthis.bytePos++;\n\t\t}\n\t}\n\n\treadByte(): number {\n\t\treturn this.data[this.bytePos++];\n\t}\n\n\treadBytes(n: number): Uint8Array {\n\t\tconst result = this.data.subarray(this.bytePos, this.bytePos + n);\n\t\tthis.bytePos += n;\n\t\treturn result;\n\t}\n}\n\n/** Decodes a Huffman symbol from the bit stream. */\nfunction decodeSymbol(bits: BitReader, table: { codes: Uint16Array; lengths: Uint8Array }): number {\n\tlet code = 0;\n\n\tfor (let len = 1; len <= 15; len++) {\n\t\tcode = (code << 1) | bits.readBits(1);\n\t\tfor (let i = 0; i < table.codes.length; i++) {\n\t\t\tif (table.lengths[i] === len && table.codes[i] === code) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow new Error('Invalid Huffman code');\n}\n\nconst LENGTH_BASE = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258];\nconst LENGTH_EXTRA = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0];\nconst DIST_BASE = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577];\nconst DIST_EXTRA = [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13];\nconst CL_ORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];\n\n/** Inflates a raw DEFLATE stream (no zlib/gzip header). */\nfunction inflate(compressed: Uint8Array, expectedSize: number): Uint8Array {\n\tconst bits = new BitReader(compressed);\n\tconst output = new Uint8Array(expectedSize);\n\tlet outPos = 0;\n\n\tlet bfinal = 0;\n\twhile (bfinal === 0) {\n\t\tbfinal = bits.readBits(1);\n\t\tconst btype = bits.readBits(2);\n\n\t\tif (btype === 0) {\n\t\t\t// No compression\n\t\t\tbits.alignToByte();\n\t\t\tconst len = bits.readByte() | (bits.readByte() << 8);\n\t\t\tbits.readByte(); bits.readByte(); // nlen\n\t\t\tconst block = bits.readBytes(len);\n\t\t\toutput.set(block, outPos);\n\t\t\toutPos += len;\n\t\t} else {\n\t\t\tlet litLenTree: { codes: Uint16Array; lengths: Uint8Array };\n\t\t\tlet distTree: { codes: Uint16Array; lengths: Uint8Array };\n\n\t\t\tif (btype === 1) {\n\t\t\t\tlitLenTree = buildFixedLitLenTree();\n\t\t\t\tdistTree = buildFixedDistTree();\n\t\t\t} else if (btype === 2) {\n\t\t\t\tconst hlit = bits.readBits(5) + 257;\n\t\t\t\tconst hdist = bits.readBits(5) + 1;\n\t\t\t\tconst hclen = bits.readBits(4) + 4;\n\n\t\t\t\tconst clLengths = new Uint8Array(19);\n\t\t\t\tfor (let i = 0; i < hclen; i++) {\n\t\t\t\t\tclLengths[CL_ORDER[i]] = bits.readBits(3);\n\t\t\t\t}\n\t\t\t\tconst clTree = buildHuffmanTable(clLengths);\n\n\t\t\t\tconst allLengths = new Uint8Array(hlit + hdist);\n\t\t\t\tlet idx = 0;\n\t\t\t\twhile (idx < hlit + hdist) {\n\t\t\t\t\tconst sym = decodeSymbol(bits, clTree);\n\t\t\t\t\tif (sym < 16) {\n\t\t\t\t\t\tallLengths[idx++] = sym;\n\t\t\t\t\t} else if (sym === 16) {\n\t\t\t\t\t\tconst repeat = bits.readBits(2) + 3;\n\t\t\t\t\t\tconst prev = allLengths[idx - 1];\n\t\t\t\t\t\tfor (let i = 0; i < repeat; i++) allLengths[idx++] = prev;\n\t\t\t\t\t} else if (sym === 17) {\n\t\t\t\t\t\tconst repeat = bits.readBits(3) + 3;\n\t\t\t\t\t\tfor (let i = 0; i < repeat; i++) allLengths[idx++] = 0;\n\t\t\t\t\t} else if (sym === 18) {\n\t\t\t\t\t\tconst repeat = bits.readBits(7) + 11;\n\t\t\t\t\t\tfor (let i = 0; i < repeat; i++) allLengths[idx++] = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlitLenTree = buildHuffmanTable(allLengths.subarray(0, hlit));\n\t\t\t\tdistTree = buildHuffmanTable(allLengths.subarray(hlit));\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Invalid DEFLATE block type: ${btype}`);\n\t\t\t}\n\n\t\t\t// Decode compressed data\n\t\t\twhile (true) {\n\t\t\t\tconst sym = decodeSymbol(bits, litLenTree);\n\n\t\t\t\tif (sym < 256) {\n\t\t\t\t\toutput[outPos++] = sym;\n\t\t\t\t} else if (sym === 256) {\n\t\t\t\t\tbreak; // End of block\n\t\t\t\t} else {\n\t\t\t\t\tconst lengthIdx = sym - 257;\n\t\t\t\t\tconst length = LENGTH_BASE[lengthIdx] + bits.readBits(LENGTH_EXTRA[lengthIdx]);\n\n\t\t\t\t\tconst distSym = decodeSymbol(bits, distTree);\n\t\t\t\t\tconst distance = DIST_BASE[distSym] + bits.readBits(DIST_EXTRA[distSym]);\n\n\t\t\t\t\tfor (let i = 0; i < length; i++) {\n\t\t\t\t\t\toutput[outPos] = output[outPos - distance];\n\t\t\t\t\t\toutPos++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn output.subarray(0, outPos);\n}\n\n// ---------------------------------------------------------------------------\n// GP7+ ZIP parser — extracts score.gpif and delegates to GPIF transformer\n// ---------------------------------------------------------------------------\n\n/** Parses a Guitar Pro 7+ (.gp) ZIP file into a TabSong. */\nfunction parseGp7File(data: Uint8Array): TabSong {\n\tconst gpifData = extractFileFromZip(data, 'Content/score.gpif');\n\tif (!gpifData) {\n\t\tthrow new Error('No Content/score.gpif found in GP7+ archive');\n\t}\n\n\tconst decoder = new TextDecoder('utf-8');\n\tconst gpifXml = decoder.decode(gpifData);\n\n\tconst DOMParserImpl = getDOMParser();\n\tconst parser = new DOMParserImpl();\n\tconst doc = parser.parseFromString(gpifXml, 'text/xml');\n\n\tconst parseError = doc.querySelector('parsererror');\n\tif (parseError) {\n\t\tthrow new Error(`Failed to parse GPIF XML: ${parseError.textContent}`);\n\t}\n\n\treturn gpifToTabSong(doc);\n}\n\n// ---------------------------------------------------------------------------\n// Format detection\n// ---------------------------------------------------------------------------\n\n/** Detects file format from header bytes and filename. */\nfunction detectFormat(data: Uint8Array, fileName?: string): 'gpx' | 'gp7' | 'gp5' | 'gp3' {\n\tif (data.length < 4) {\n\t\tthrow new Error('File too small to be a valid Guitar Pro file');\n\t}\n\n\tconst header = String.fromCharCode(data[0], data[1], data[2], data[3]);\n\n\t// BCFZ or BCFS → GPX format (Guitar Pro 6)\n\tif (header === 'BCFZ' || header === 'BCFS') {\n\t\treturn 'gpx';\n\t}\n\n\t// PK (ZIP signature) → GP7+ format\n\tif (data[0] === 0x50 && data[1] === 0x4B) {\n\t\treturn 'gp7';\n\t}\n\n\t// Check for GP3/GP4/GP5 version string: first byte is string length, followed by \"FICHIER GUITAR PRO\"\n\tconst strLen = data[0];\n\tif (strLen > 10 && strLen < 50 && data.byteLength > strLen + 1) {\n\t\tconst versionStr = String.fromCharCode(...Array.from(data.subarray(1, 1 + Math.min(strLen, 40))));\n\t\tif (versionStr.includes('GUITAR PRO')) {\n\t\t\tif (versionStr.includes('v3.')) return 'gp3';\n\t\t\treturn 'gp5';\n\t\t}\n\t}\n\n\t// Fall back to file extension\n\tif (fileName) {\n\t\tconst ext = fileName.toLowerCase();\n\t\tif (ext.endsWith('.gpx')) return 'gpx';\n\t\tif (ext.endsWith('.gp3')) return 'gp3';\n\t\tif (ext.endsWith('.gp5') || ext.endsWith('.gp4')) return 'gp5';\n\t\tif (ext.endsWith('.gp')) return 'gp7';\n\t}\n\n\tthrow new Error('Unrecognized Guitar Pro file format');\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Parses any supported Guitar Pro file format into a TabSong.\n * Detects format automatically from file header bytes.\n *\n * Supported: .gpx (GP6), .gp (GP7+), .gp5 (GP5), .gp3 (GP3)\n */\nexport function parseTabFile(data: Uint8Array, fileName?: string): TabSong {\n\tconst format = detectFormat(data, fileName);\n\n\tswitch (format) {\n\t\tcase 'gpx':\n\t\t\treturn parseGpxFile(data);\n\t\tcase 'gp7':\n\t\t\treturn parseGp7File(data);\n\t\tcase 'gp5':\n\t\t\treturn parseGp5File(data);\n\t\tcase 'gp3':\n\t\t\treturn parseGp3File(data);\n\t}\n}\n\nexport { detectFormat };\n"],"mappings":"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","names":["GP_DURATION_MAP","gpDurationToDuration","TUPLET_MAP","readInfo","readMidiChannels","readMeasureHeaders","readTrackHeaders","readMeasures","readVoice","readBeat","readChord","readBeatEffects","readMixTableChange","readNote","readNoteEffects","readBend","readGraceNote","transformToTabSong"]}