notations 0.0.67 → 0.0.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/NotationView.css +100 -0
  2. package/dist/NotationView.css.map +1 -0
  3. package/dist/NotationView.min.css +1 -0
  4. package/dist/NotationView.min.css.map +1 -0
  5. package/dist/notations.umd.js +35875 -0
  6. package/dist/notations.umd.min.js +112 -0
  7. package/dist/notations.umd.min.js.LICENSE.txt +24 -0
  8. package/dist/notations.umd.min.js.map +1 -0
  9. package/lib/cjs/beats.js.map +1 -1
  10. package/lib/cjs/beatutils.js.map +1 -1
  11. package/lib/cjs/beatview.js.map +1 -1
  12. package/lib/cjs/carnatic/LineView.js.map +1 -1
  13. package/lib/cjs/carnatic/NotationView.js.map +1 -1
  14. package/lib/cjs/carnatic/embelishments.js +3 -8
  15. package/lib/cjs/carnatic/embelishments.js.map +1 -1
  16. package/lib/cjs/carnatic/gamakas.js.map +1 -1
  17. package/lib/cjs/commands.js.map +1 -1
  18. package/lib/cjs/core.js.map +1 -1
  19. package/lib/cjs/cycle.js.map +1 -1
  20. package/lib/cjs/entity.js.map +1 -1
  21. package/lib/cjs/grids.js.map +1 -1
  22. package/lib/cjs/iterators.js.map +1 -1
  23. package/lib/cjs/layouts.js.map +1 -1
  24. package/lib/cjs/loader.js.map +1 -1
  25. package/lib/cjs/notation.js.map +1 -1
  26. package/lib/cjs/parser.js.map +1 -1
  27. package/lib/cjs/shapes.js +1 -1
  28. package/lib/cjs/shapes.js.map +1 -1
  29. package/lib/cjs/utils.js.map +1 -1
  30. package/lib/esm/beats.js.map +1 -1
  31. package/lib/esm/beatutils.js.map +1 -1
  32. package/lib/esm/beatview.js.map +1 -1
  33. package/lib/esm/carnatic/LineView.js.map +1 -1
  34. package/lib/esm/carnatic/NotationView.js.map +1 -1
  35. package/lib/esm/carnatic/embelishments.js +3 -8
  36. package/lib/esm/carnatic/embelishments.js.map +1 -1
  37. package/lib/esm/carnatic/gamakas.js.map +1 -1
  38. package/lib/esm/commands.js.map +1 -1
  39. package/lib/esm/core.js.map +1 -1
  40. package/lib/esm/cycle.js.map +1 -1
  41. package/lib/esm/entity.js.map +1 -1
  42. package/lib/esm/grids.js.map +1 -1
  43. package/lib/esm/iterators.js.map +1 -1
  44. package/lib/esm/layouts.js.map +1 -1
  45. package/lib/esm/loader.js.map +1 -1
  46. package/lib/esm/notation.js.map +1 -1
  47. package/lib/esm/parser.js.map +1 -1
  48. package/lib/esm/shapes.js +1 -1
  49. package/lib/esm/shapes.js.map +1 -1
  50. package/lib/esm/utils.js.map +1 -1
  51. package/package.json +22 -15
  52. package/styles/NotationView.scss +74 -1
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity, TimedEntity } from \"./entity\";\nimport { LayoutParams } from \"./layouts\";\n\n/**\n * Alias to TSU.Num.Fraction in tsutils.\n */\ntype Fraction = TSU.Num.Fraction;\nexport const ZERO = TSU.Num.Fraction.ZERO;\nexport const ONE = TSU.Num.Fraction.ONE;\n\n/**\n * AtomType enums are used to denote specific Atoms\n * Each type represents a specific musical or notational element.\n * @enum\n */\nexport enum AtomType {\n NOTE = \"Note\",\n LITERAL = \"Literal\",\n SYLLABLE = \"Syllable\",\n SPACE = \"Space\",\n GROUP = \"Group\",\n LABEL = \"Label\",\n REST = \"Rest\",\n MARKER = \"Marker\",\n}\n\n/**\n * Atoms are the base class for all timed entities that can appear in a Notation.\n * An Atom represents the fundamental building block of the notation system.\n */\nexport abstract class Atom extends TimedEntity {\n readonly TYPE: string = \"Atom\";\n\n protected _duration: Fraction;\n /** Markers to be displayed before this atom */\n markersBefore: Marker[];\n /** Markers to be displayed after this atom */\n markersAfter: Marker[];\n /** Next atom in the sequence */\n nextSibling: TSU.Nullable<Atom> = null;\n /** Previous atom in the sequence */\n prevSibling: TSU.Nullable<Atom> = null;\n /** The Group this Atom belongs to, if any */\n parentGroup: TSU.Nullable<Group> = null;\n\n /** Indicates if this Atom is a continuation from a previous atom */\n isContinuation = false;\n\n /**\n * Creates a new Atom with the specified duration.\n * @param duration The duration of the atom, defaults to ONE (1/1)\n */\n constructor(duration = ONE) {\n super();\n this._duration = duration || ONE;\n }\n\n /**\n * Splits this atom at the specified duration.\n * @param requiredDuration The duration at which to split the atom\n * @returns A new atom representing the portion beyond the split point, or null if no split is needed\n */\n abstract splitAt(requiredDuration: Fraction): TSU.Nullable<Atom>;\n\n /**\n * Returns a debug-friendly representation of this Atom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = super.debugValue();\n if (!this.duration.isOne) {\n out.duration = this.duration.factorized.toString();\n }\n if (this.isContinuation) {\n out.isContinuation = true;\n }\n if ((this.markersBefore || []).length > 0) {\n out.mbef = this.markersBefore.map((m) => m.debugValue());\n }\n if ((this.markersAfter || []).length > 0) {\n out.maft = this.markersAfter.map((m) => m.debugValue());\n }\n return out;\n }\n\n /**\n * Copies the properties of this atom to another atom.\n * @param another The target atom to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another._duration = new TSU.Num.Fraction(this.duration.num, this.duration.den);\n }\n\n /**\n * Gets the duration of this atom.\n */\n get duration(): Fraction {\n return this._duration;\n }\n\n /**\n * Sets the duration of this atom.\n */\n set duration(d: Fraction) {\n this._duration = d;\n }\n}\n\n/**\n * Base class for atoms that cannot contain other atoms.\n * LeafAtom represents atomic elements that can't be further subdivided.\n */\nexport abstract class LeafAtom extends Atom {\n readonly TYPE: string = \"LeafAtom\";\n\n /** Indicates if this atom is followed by a rest */\n beforeRest = false;\n\n /**\n * Splits this atom at a certain duration.\n * If this atom's duration is longer than the given duration, it's truncated\n * to the given duration and a continuation space is returned.\n * \n * @param duration The duration at which to split the atom\n * @returns A new Space atom representing the spillover if needed, otherwise null\n */\n splitAt(duration: Fraction): TSU.Nullable<Atom> {\n if (this.duration.cmp(duration) > 0) {\n const spillOver = this.createSpilloverSpace(this.duration.minus(duration));\n spillOver.isContinuation = true;\n this.duration = duration;\n // TODO - Here we need to move the markersAfter to the spill-over as it doesnt belong to this any more\n return spillOver;\n }\n return null;\n }\n\n /**\n * Creates a Space atom to represent spillover duration when splitting.\n * @param duration The duration of the spillover\n * @returns A new Space atom\n */\n protected createSpilloverSpace(duration: Fraction): Space {\n return new Space(duration);\n }\n\n /**\n * Returns a debug-friendly representation of this LeafAtom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return this.beforeRest ? { ...super.debugValue(), beforeRest: true } : super.debugValue();\n }\n}\n\n/**\n * Represents a marker or annotation in the notation.\n * Markers can be placed before or after atoms to provide additional context.\n */\nexport class Marker extends Entity {\n readonly TYPE = \"Marker\";\n\n /**\n * Creates a new Marker with the specified text.\n * @param text The text content of the marker\n * @param isBefore Whether the marker should appear before (true) or after (false) its associated atom\n */\n constructor(public text: string, public isBefore = true) {\n super();\n }\n\n /**\n * Returns a debug-friendly representation of this Marker.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), text: this.text, before: this.isBefore };\n }\n\n /**\n * Returns a string representation of this Marker.\n * @returns A string representation\n */\n toString(): string {\n return `Marker(${this.text}-${this.isBefore})`;\n }\n}\n\n/**\n * Represents a rest (silence) in the notation.\n * Rests are zero-length atoms that indicate a pause.\n */\nexport class Rest extends LeafAtom {\n readonly TYPE = \"Rest\";\n\n /**\n * Creates a new Rest.\n * Rests are zero length by default.\n */\n constructor() {\n super(ZERO);\n }\n}\n\n/**\n * Represents a space or silence in the notation.\n * Spaces can be used to denote either silence or continuations of previous notes.\n */\nexport class Space extends LeafAtom {\n readonly TYPE = \"Space\";\n \n /**\n * Indicates whether this is a silent space or a continuation of the previous note.\n */\n isSilent = false;\n\n /**\n * Creates a new Space with the specified duration and silence property.\n * @param duration The duration of the space, defaults to ONE (1/1)\n * @param isSilent Whether the space represents silence (true) or a continuation (false)\n */\n constructor(duration = ONE, isSilent = false) {\n super(duration);\n this.isSilent = isSilent;\n }\n\n /**\n * Returns a debug-friendly representation of this Space.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), isSilent: this.isSilent };\n }\n\n /**\n * Returns a string representation of this Space.\n * @returns A string representation\n */\n toString(): string {\n return `Space(${this.duration}-${this.isSilent})`;\n }\n\n /**\n * Copies the properties of this Space to another Space.\n * @param another The target Space to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.isSilent = this.isSilent;\n }\n\n /**\n * Checks if this Space is equal to another Space.\n * @param another The Space to compare with\n * @returns True if the Spaces are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.isSilent == another.isSilent;\n }\n\n /**\n * Creates a Space atom to represent spillover duration when splitting.\n * @param duration The duration of the spillover\n * @returns A new Space atom with the same silence property as this Space\n */\n protected createSpilloverSpace(duration: Fraction): Space {\n const out = super.createSpilloverSpace(duration);\n out.isSilent = this.isSilent;\n return out;\n }\n}\n\n/**\n * Represents a literal value in the notation.\n * Literals are the basic building blocks for notes and syllables.\n */\nexport class Literal extends LeafAtom {\n readonly TYPE: string = \"Literal\";\n \n /**\n * The embellishments applied to this Literal.\n */\n embelishments: any[] = [];\n\n /**\n * Creates a new Literal with the specified value and duration.\n * @param value The string value of the literal\n * @param duration The duration of the literal, defaults to ONE (1/1)\n */\n constructor(public value: string, duration = ONE) {\n super(duration);\n }\n\n /**\n * Returns a debug-friendly representation of this Literal.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue(), value: this.value };\n if (this.embelishments.length > 0) {\n out.embs = this.embelishments.map((e) => (\"debugValue\" in e ? e.debugValue() : e));\n }\n return out;\n }\n\n /**\n * Returns a string representation of this Literal.\n * @returns A string representation\n */\n toString(): string {\n return `Lit(${this.duration}-${this.value})`;\n }\n\n /**\n * Checks if this Literal is equal to another Literal.\n * @param another The Literal to compare with\n * @returns True if the Literals are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.value == another.value;\n }\n\n /**\n * Copies the properties of this Literal to another Literal.\n * @param another The target Literal to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.value = this.value;\n }\n}\n\n/**\n * Represents a syllable in lyrics or text to be sung.\n * Extends Literal to provide specialized handling for sung text.\n */\nexport class Syllable extends Literal {\n readonly TYPE = \"Syllable\";\n\n /**\n * Creates a Syllable from a Literal.\n * @param lit The Literal to convert to a Syllable\n * @returns A new Syllable with the properties of the Literal\n */\n static fromLit(lit: Literal): Syllable {\n if (lit.TYPE == AtomType.SYLLABLE) return lit as Syllable;\n const out = new Syllable(lit.value, lit.duration);\n out.embelishments = lit.embelishments;\n out.beforeRest = lit.beforeRest;\n return out;\n }\n\n /**\n * Returns a string representation of this Syllable.\n * @returns A string representation\n */\n toString(): string {\n return `Syll(${this.duration}-${this.value})`;\n }\n}\n\n/**\n * Represents a musical note in the notation.\n * Extends Literal to add properties specific to musical notes.\n */\nexport class Note extends Literal {\n readonly TYPE = \"Note\";\n\n /**\n * Which octave the note is in. Can be positive or negative to indicate higher or lower octaves.\n */\n octave = 0;\n\n /**\n * How the note is shifted - i.e., shifted towards major or minor by # of semi-tones.\n */\n shift: number | boolean = 0;\n\n /**\n * Creates a new Note with the specified properties.\n * @param value The string value of the note\n * @param duration The duration of the note, defaults to ONE (1/1)\n * @param octave The octave of the note, defaults to 0\n * @param shift The shift of the note, defaults to 0\n */\n constructor(value: string, duration = ONE, octave = 0, shift = 0) {\n super(value, duration);\n this.octave = octave;\n this.shift = shift;\n }\n\n /**\n * Creates a Note from a Literal.\n * @param lit The Literal to convert to a Note\n * @returns A new Note with the properties of the Literal\n */\n static fromLit(lit: Literal): Note {\n if (lit.TYPE == AtomType.NOTE) return lit as Note;\n const out = new Note(lit.value, lit.duration);\n out.embelishments = lit.embelishments;\n out.beforeRest = lit.beforeRest;\n return out;\n }\n\n /**\n * Returns a debug-friendly representation of this Note.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue() };\n if (this.octave != 0) out.octave = this.octave;\n if (this.shift != 0) out.shift = this.shift;\n return out;\n }\n\n /**\n * Returns a string representation of this Note.\n * @returns A string representation\n */\n toString(): string {\n return `Note(${this.duration}-${this.value}-${this.octave})`;\n }\n\n /**\n * Checks if this Note is equal to another Note.\n * @param another The Note to compare with\n * @returns True if the Notes are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.octave == another.octave && this.shift == another.shift;\n }\n\n /**\n * Copies the properties of this Note to another Note.\n * @param another The target Note to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.octave = this.octave;\n another.shift = this.shift;\n }\n}\n\n/**\n * Represents a group of atoms that are treated as a single unit.\n * Groups can contain any number of atoms, including other groups.\n */\nexport class Group extends Atom {\n readonly TYPE = \"Group\";\n\n /**\n * Indicates whether the duration is static or linear to the number of atoms in this group.\n * When true, the duration is used as a multiplier for the total child duration.\n * When false, the duration is absolute.\n */\n durationIsMultiplier = false;\n \n /**\n * The list of atoms in this group.\n */\n readonly atoms = new TSU.Lists.ValueList<Atom>();\n\n /**\n * Creates a new Group containing the specified atoms.\n * @param atoms The atoms to include in this group\n */\n constructor(...atoms: Atom[]) {\n super(atoms.length == 0 ? ZERO : ONE);\n this.addAtoms(false, ...atoms);\n }\n\n /**\n * Checks if this Group is equal to another Group.\n * @param another The Group to compare with\n * @param expect Optional parameter\n * @returns True if the Groups are equal, false otherwise\n */\n equals(another: this, expect = false): boolean {\n if (!super.equals(another)) return false;\n return this.atoms.equals(another.atoms, (a1, a2) => a1.equals(a2));\n }\n\n /**\n * Copies the properties of this Group to another Group.\n * @param another The target Group to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.durationIsMultiplier = this.durationIsMultiplier;\n this.atoms.forEach((atom) => another.atoms.add(atom.clone()));\n }\n\n /**\n * Gets the duration of this group.\n * If durationIsMultiplier is true, returns the total child duration divided by the multiplier.\n * Otherwise, returns the absolute duration.\n */\n get duration(): Fraction {\n if (this.durationIsMultiplier) {\n return this.totalChildDuration.divby(this._duration);\n } else {\n return this._duration;\n }\n }\n\n /**\n * Sets this group to use a multiplier for duration calculations.\n * @param asMultiplier Whether to use the duration as a multiplier\n * @returns This Group instance for method chaining\n */\n setDurationAsMultiplier(asMultiplier = true): this {\n this.durationIsMultiplier = asMultiplier;\n return this;\n }\n\n /**\n * Sets the duration of this group.\n * @param d The new duration\n * @param asMultiplier Whether to use the duration as a multiplier\n * @returns This Group instance for method chaining\n */\n setDuration(d: Fraction, asMultiplier = false): this {\n this._duration = d;\n this.durationIsMultiplier = asMultiplier;\n return this;\n }\n\n /**\n * Returns a debug-friendly representation of this Group.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue(), atoms: Array.from(this.atoms.values(), (a) => a.debugValue()) };\n if (this.durationIsMultiplier) out.durationIsMultiplier = true;\n return out;\n }\n\n /**\n * Splits this group into two parts.\n * The first part (this group) fits within the given duration and everything else\n * longer than the given duration is returned as a new Group.\n * \n * @param requiredDuration The duration at which to split the group\n * @returns A new Group containing the atoms beyond the split point, or null if no split is needed\n */\n splitAt(requiredDuration: Fraction): TSU.Nullable<Group> {\n if (this.duration.isLTE(requiredDuration) || requiredDuration.isLTE(ZERO)) {\n return null;\n }\n const targetGroup = new Group();\n if (this.durationIsMultiplier) {\n targetGroup.durationIsMultiplier = true;\n targetGroup._duration = this._duration;\n }\n\n let remainingDur = this.duration;\n const totalChildDuration = this.totalChildDuration;\n const durationFactor = this.durationIsMultiplier\n ? ONE.divby(this._duration)\n : this._duration.divby(totalChildDuration, true);\n while (remainingDur.isGT(requiredDuration) && this.atoms.last) {\n const lastChild = this.atoms.last;\n // Child's duration is absolute in its own \"system\"\n // Its duration within the parent (this) group's frame of reference depends\n // on whether the parent's duration is absolute or as a multiplier\n //\n // realChildDuration = case (group.durationIsMultiper) {\n // | true => child.duration / this._duration\n // | false => child.duration * this._duration / total child duration\n // }\n const childDuration = lastChild.duration.times(durationFactor);\n const newDuration = remainingDur.minus(childDuration);\n if (newDuration.isGTE(requiredDuration)) {\n // remove ourselves and add to target\n // in both cases duration will be adjusted if need be\n this.removeAtoms(true, lastChild);\n targetGroup.insertAtomsAt(targetGroup.atoms.first, true, lastChild);\n if (newDuration.equals(requiredDuration)) {\n // we have reached the end so return\n return targetGroup;\n }\n } else {\n // our scenario is now this:\n //\n // totalParentDuration = 10\n // required = 8\n // lastChildDuration (relative to parent) is 5\n //\n // durWithoutLast = 10 - 5\n // newRequired = requiredDur - durWithoutLast = 3\n //\n // However 3 is a duration in the parent's frame of reference\n // this has to be converted back to the child's FoR\n const newRequiredDur = requiredDuration.minus(newDuration, true).divby(durationFactor, true);\n // console.log( \"newRequiredDur: \", newRequiredDur, \"requiedDur: \", requiredDuration, \"remainingDur: \", remainingDur,);\n // then the last item needs to be split, and by how much?\n const spillOver = lastChild.splitAt(newRequiredDur);\n if (spillOver == null) {\n throw new Error(\"Spill over cannot be null here\");\n }\n if (!this.durationIsMultiplier) {\n // Our own duration has also now changed\n this._duration = requiredDuration;\n } else {\n if (this._duration.isZero) throw new Error(\"How can this be?\");\n }\n spillOver.isContinuation = true;\n // Add spill over to the target\n targetGroup.insertAtomsAt(targetGroup.atoms.first, true, spillOver);\n return targetGroup;\n }\n remainingDur = newDuration;\n }\n return targetGroup;\n }\n\n /**\n * Gets the total duration of all child atoms.\n * @returns The sum of durations of all atoms in this group\n */\n get totalChildDuration(): Fraction {\n let out = ZERO;\n this.atoms.forEach((atom) => (out = out.plus(atom.duration)));\n return out;\n }\n\n /**\n * Inserts atoms before a given cursor atom.\n * If the cursor atom is null, the atoms are appended at the end.\n * \n * @param beforeAtom The atom before which to insert the new atoms, or null to append\n * @param adjustDuration Whether to adjust this group's duration based on the new atoms\n * @param atoms The atoms to insert\n * @returns This Group instance for method chaining\n */\n insertAtomsAt(beforeAtom: TSU.Nullable<Atom>, adjustDuration = false, ...atoms: Atom[]): this {\n adjustDuration = adjustDuration && !this.durationIsMultiplier;\n const oldChildDuration = adjustDuration ? this.totalChildDuration : ONE;\n // First form a chain of the given atoms\n for (const atom of atoms) {\n if (atom.parentGroup != null) {\n if (atom.parentGroup != this) {\n throw new Error(\"Atom belongs to another parent. Remove it first\");\n }\n atom.parentGroup.removeAtoms(false, atom);\n }\n if (atom.TYPE == AtomType.REST) {\n const last = this.atoms.last;\n if (last && last.TYPE != AtomType.GROUP && last.TYPE != AtomType.LABEL) {\n (last as LeafAtom).beforeRest = true;\n }\n } else {\n atom.parentGroup = this;\n this.atoms.add(atom, beforeAtom);\n }\n }\n if (adjustDuration) {\n if (this._duration.isZero) {\n if (this.durationIsMultiplier) throw new Error(\"How can this be?\");\n this._duration = this.totalChildDuration;\n } else {\n const scaleFactor = this.totalChildDuration.divby(oldChildDuration);\n this._duration = this._duration.times(scaleFactor, true);\n }\n }\n return this;\n }\n\n /**\n * Adds atoms to the end of this group's atom list.\n * \n * @param adjustDuration Whether to adjust this group's duration based on the new atoms\n * @param atoms The atoms to add\n * @returns This Group instance for method chaining\n */\n addAtoms(adjustDuration = false, ...atoms: Atom[]): this {\n return this.insertAtomsAt(null, adjustDuration, ...atoms);\n }\n\n /**\n * Removes atoms from this group's child list.\n * \n * @param adjustDuration Whether to adjust this group's duration after removing atoms\n * @param atoms The atoms to remove\n * @returns This Group instance for method chaining\n */\n removeAtoms(adjustDuration = false, ...atoms: Atom[]): this {\n adjustDuration = adjustDuration && !this.durationIsMultiplier;\n const oldChildDuration = adjustDuration ? this.totalChildDuration : ONE;\n for (const atom of atoms) {\n if (atom.parentGroup == this) {\n this.atoms.remove(atom);\n atom.parentGroup = null;\n } else if (atom.parentGroup != null) {\n throw new Error(\"Atom cannot be removed as it does not belong to this group\");\n }\n }\n if (adjustDuration) {\n if (this._duration.isZero) {\n if (this.durationIsMultiplier) throw new Error(\"How can this be?\");\n this._duration = this.totalChildDuration;\n } else {\n const scaleFactor = this.totalChildDuration.divby(oldChildDuration);\n this._duration = this._duration.times(scaleFactor, true);\n }\n }\n return this;\n }\n}\n\n/**\n * Represents a line of notation containing multiple roles.\n * A line can have atoms starting before or after the cycle.\n */\nexport class Line extends Entity {\n readonly TYPE: string = \"Line\";\n\n /**\n * Offset tells how many notes before or after the cycle this line's atoms start at.\n */\n offset: Fraction = ZERO;\n \n /**\n * The roles contained in this line.\n */\n roles: Role[] = [];\n\n /**\n * Text to be displayed in the margin of the line.\n * This is a hacky solution to doing left side pre-margin text typically\n * found in notations - e.g., line X of a pallavi has this. This makes vertical\n * space less wasteful.\n *\n * A better solution is inter-beat annotation but it is very complex for now.\n */\n marginText = \"\";\n\n /**\n * The LayoutParams associated with this line.\n */\n layoutParams: LayoutParams;\n\n /**\n * Finds the index of a role with the given name.\n * @param name The name of the role to find\n * @returns The index of the role, or -1 if not found\n */\n indexOfRole(name: string): number {\n for (let i = 0; i < this.roles.length; i++) {\n if (this.roles[i].name == name) return i;\n }\n return -1;\n }\n\n /**\n * Checks if this line is empty (has no content in any role).\n */\n get isEmpty(): boolean {\n for (const r of this.roles) if (!r.isEmpty) return false;\n return true;\n }\n\n /**\n * Returns a debug-friendly representation of this Line.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = {\n ...super.debugValue(),\n roles: this.roles.map((r) => r.debugValue()),\n };\n if (!this.offset.isZero) {\n out.offset = this.offset.toString();\n }\n return out;\n }\n\n /**\n * Copies the properties of this Line to another Line.\n * @param another The target Line to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.roles = this.roles.map((r) => r.clone());\n }\n\n /**\n * Adds atoms to a role in this line.\n * @param roleName The name of the role to add atoms to\n * @param defaultToNotes Whether to default to notes for this role\n * @param atoms The atoms to add\n * @returns This Line instance for method chaining\n */\n addAtoms(roleName: string, defaultToNotes: boolean, ...atoms: Atom[]): this {\n const role = this.ensureRole(roleName, defaultToNotes);\n role.addAtoms(...atoms);\n return this;\n }\n\n /**\n * Ensures a role with the given name exists in this line, creating it if needed.\n * @param roleName The name of the role to ensure\n * @param defaultToNotes Whether to default to notes for this role\n * @returns The role with the specified name\n */\n ensureRole(roleName: string, defaultToNotes: boolean): Role {\n // Ensure we have this many roles\n let ri = this.roles.findIndex((r) => r.name == roleName);\n if (ri < 0) {\n ri = this.roles.length;\n const role = new Role(this, roleName);\n role.defaultToNotes = defaultToNotes;\n this.roles.push(role);\n }\n return this.roles[ri];\n }\n\n /**\n * Gets the maximum duration across all roles in this line.\n */\n get duration(): Fraction {\n let max = ZERO;\n for (const role of this.roles) {\n max = TSU.Num.Fraction.max(role.duration, max);\n }\n return max;\n }\n}\n\n/**\n * Represents a specific role or voice in a line of notation.\n * Each role contains a sequence of atoms.\n */\nexport class Role extends Entity {\n readonly TYPE = \"Role\";\n\n /**\n * Whether this role represents notes by default.\n */\n defaultToNotes = true;\n \n /**\n * The atoms in this role.\n */\n atoms: Atom[] = [];\n\n /**\n * Creates a new Role with the specified line and name.\n * @param line The line this role belongs to\n * @param name The name of the role\n */\n constructor(public readonly line: Line, public readonly name: string) {\n super();\n }\n\n /**\n * Checks if this role is empty (has no atoms).\n */\n get isEmpty(): boolean {\n return this.atoms.length == 0;\n }\n\n /**\n * Returns a debug-friendly representation of this Role.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { name: this.name, atoms: this.atoms.map((a) => a.debugValue()) };\n }\n\n /**\n * Adds atoms to this role.\n * @param atoms The atoms to add\n */\n addAtoms(...atoms: Atom[]): void {\n let last: null | Atom = null;\n for (const atom of atoms) {\n if (atom.TYPE == AtomType.REST) {\n if (last && last.TYPE != AtomType.GROUP && last.TYPE != AtomType.LABEL) {\n (last as LeafAtom).beforeRest = true;\n }\n } else {\n this.atoms.push(atom);\n }\n last = atom;\n }\n }\n\n /**\n * Copies the properties of this Role to another Role.\n * @param another The target Role to copy properties to\n */\n copyTo(another: Role): void {\n another.addAtoms(...this.atoms);\n }\n\n /**\n * Gets the total duration of all atoms in this role.\n */\n get duration(): Fraction {\n return this.atoms.reduce((a, b) => a.plus(b.duration), ZERO);\n }\n}\n"]}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity, TimedEntity } from \"./entity\";\nimport { LayoutParams } from \"./layouts\";\n\n/**\n * Alias to TSU.Num.Fraction in tsutils.\n */\ntype Fraction = TSU.Num.Fraction;\nexport const ZERO = TSU.Num.Fraction.ZERO;\nexport const ONE = TSU.Num.Fraction.ONE;\n\n/**\n * AtomType enums are used to denote specific Atoms\n * Each type represents a specific musical or notational element.\n * @enum\n */\nexport enum AtomType {\n NOTE = \"Note\",\n LITERAL = \"Literal\",\n SYLLABLE = \"Syllable\",\n SPACE = \"Space\",\n GROUP = \"Group\",\n LABEL = \"Label\",\n REST = \"Rest\",\n MARKER = \"Marker\",\n}\n\n/**\n * Atoms are the base class for all timed entities that can appear in a Notation.\n * An Atom represents the fundamental building block of the notation system.\n */\nexport abstract class Atom extends TimedEntity {\n readonly TYPE: string = \"Atom\";\n\n protected _duration: Fraction;\n /** Markers to be displayed before this atom */\n markersBefore: Marker[];\n /** Markers to be displayed after this atom */\n markersAfter: Marker[];\n /** Next atom in the sequence */\n nextSibling: TSU.Nullable<Atom> = null;\n /** Previous atom in the sequence */\n prevSibling: TSU.Nullable<Atom> = null;\n /** The Group this Atom belongs to, if any */\n parentGroup: TSU.Nullable<Group> = null;\n\n /** Indicates if this Atom is a continuation from a previous atom */\n isContinuation = false;\n\n /**\n * Creates a new Atom with the specified duration.\n * @param duration The duration of the atom, defaults to ONE (1/1)\n */\n constructor(duration = ONE) {\n super();\n this._duration = duration || ONE;\n }\n\n /**\n * Splits this atom at the specified duration.\n * @param requiredDuration The duration at which to split the atom\n * @returns A new atom representing the portion beyond the split point, or null if no split is needed\n */\n abstract splitAt(requiredDuration: Fraction): TSU.Nullable<Atom>;\n\n /**\n * Returns a debug-friendly representation of this Atom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = super.debugValue();\n if (!this.duration.isOne) {\n out.duration = this.duration.factorized.toString();\n }\n if (this.isContinuation) {\n out.isContinuation = true;\n }\n if ((this.markersBefore || []).length > 0) {\n out.mbef = this.markersBefore.map((m) => m.debugValue());\n }\n if ((this.markersAfter || []).length > 0) {\n out.maft = this.markersAfter.map((m) => m.debugValue());\n }\n return out;\n }\n\n /**\n * Copies the properties of this atom to another atom.\n * @param another The target atom to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another._duration = new TSU.Num.Fraction(this.duration.num, this.duration.den);\n }\n\n /**\n * Gets the duration of this atom.\n */\n get duration(): Fraction {\n return this._duration;\n }\n\n /**\n * Sets the duration of this atom.\n */\n set duration(d: Fraction) {\n this._duration = d;\n }\n}\n\n/**\n * Base class for atoms that cannot contain other atoms.\n * LeafAtom represents atomic elements that can't be further subdivided.\n */\nexport abstract class LeafAtom extends Atom {\n readonly TYPE: string = \"LeafAtom\";\n\n /** Indicates if this atom is followed by a rest */\n beforeRest = false;\n\n /**\n * Splits this atom at a certain duration.\n * If this atom's duration is longer than the given duration, it's truncated\n * to the given duration and a continuation space is returned.\n *\n * @param duration The duration at which to split the atom\n * @returns A new Space atom representing the spillover if needed, otherwise null\n */\n splitAt(duration: Fraction): TSU.Nullable<Atom> {\n if (this.duration.cmp(duration) > 0) {\n const spillOver = this.createSpilloverSpace(this.duration.minus(duration));\n spillOver.isContinuation = true;\n this.duration = duration;\n // TODO - Here we need to move the markersAfter to the spill-over as it doesnt belong to this any more\n return spillOver;\n }\n return null;\n }\n\n /**\n * Creates a Space atom to represent spillover duration when splitting.\n * @param duration The duration of the spillover\n * @returns A new Space atom\n */\n protected createSpilloverSpace(duration: Fraction): Space {\n return new Space(duration);\n }\n\n /**\n * Returns a debug-friendly representation of this LeafAtom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return this.beforeRest ? { ...super.debugValue(), beforeRest: true } : super.debugValue();\n }\n}\n\n/**\n * Represents a marker or annotation in the notation.\n * Markers can be placed before or after atoms to provide additional context.\n */\nexport class Marker extends Entity {\n readonly TYPE = \"Marker\";\n\n /**\n * Creates a new Marker with the specified text.\n * @param text The text content of the marker\n * @param isBefore Whether the marker should appear before (true) or after (false) its associated atom\n */\n constructor(\n public text: string,\n public isBefore = true,\n ) {\n super();\n }\n\n /**\n * Returns a debug-friendly representation of this Marker.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), text: this.text, before: this.isBefore };\n }\n\n /**\n * Returns a string representation of this Marker.\n * @returns A string representation\n */\n toString(): string {\n return `Marker(${this.text}-${this.isBefore})`;\n }\n}\n\n/**\n * Represents a rest (silence) in the notation.\n * Rests are zero-length atoms that indicate a pause.\n */\nexport class Rest extends LeafAtom {\n readonly TYPE = \"Rest\";\n\n /**\n * Creates a new Rest.\n * Rests are zero length by default.\n */\n constructor() {\n super(ZERO);\n }\n}\n\n/**\n * Represents a space or silence in the notation.\n * Spaces can be used to denote either silence or continuations of previous notes.\n */\nexport class Space extends LeafAtom {\n readonly TYPE = \"Space\";\n\n /**\n * Indicates whether this is a silent space or a continuation of the previous note.\n */\n isSilent = false;\n\n /**\n * Creates a new Space with the specified duration and silence property.\n * @param duration The duration of the space, defaults to ONE (1/1)\n * @param isSilent Whether the space represents silence (true) or a continuation (false)\n */\n constructor(duration = ONE, isSilent = false) {\n super(duration);\n this.isSilent = isSilent;\n }\n\n /**\n * Returns a debug-friendly representation of this Space.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), isSilent: this.isSilent };\n }\n\n /**\n * Returns a string representation of this Space.\n * @returns A string representation\n */\n toString(): string {\n return `Space(${this.duration}-${this.isSilent})`;\n }\n\n /**\n * Copies the properties of this Space to another Space.\n * @param another The target Space to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.isSilent = this.isSilent;\n }\n\n /**\n * Checks if this Space is equal to another Space.\n * @param another The Space to compare with\n * @returns True if the Spaces are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.isSilent == another.isSilent;\n }\n\n /**\n * Creates a Space atom to represent spillover duration when splitting.\n * @param duration The duration of the spillover\n * @returns A new Space atom with the same silence property as this Space\n */\n protected createSpilloverSpace(duration: Fraction): Space {\n const out = super.createSpilloverSpace(duration);\n out.isSilent = this.isSilent;\n return out;\n }\n}\n\n/**\n * Represents a literal value in the notation.\n * Literals are the basic building blocks for notes and syllables.\n */\nexport class Literal extends LeafAtom {\n readonly TYPE: string = \"Literal\";\n\n /**\n * The embellishments applied to this Literal.\n */\n embelishments: any[] = [];\n\n /**\n * Creates a new Literal with the specified value and duration.\n * @param value The string value of the literal\n * @param duration The duration of the literal, defaults to ONE (1/1)\n */\n constructor(\n public value: string,\n duration = ONE,\n ) {\n super(duration);\n }\n\n /**\n * Returns a debug-friendly representation of this Literal.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue(), value: this.value };\n if (this.embelishments.length > 0) {\n out.embs = this.embelishments.map((e) => (\"debugValue\" in e ? e.debugValue() : e));\n }\n return out;\n }\n\n /**\n * Returns a string representation of this Literal.\n * @returns A string representation\n */\n toString(): string {\n return `Lit(${this.duration}-${this.value})`;\n }\n\n /**\n * Checks if this Literal is equal to another Literal.\n * @param another The Literal to compare with\n * @returns True if the Literals are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.value == another.value;\n }\n\n /**\n * Copies the properties of this Literal to another Literal.\n * @param another The target Literal to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.value = this.value;\n }\n}\n\n/**\n * Represents a syllable in lyrics or text to be sung.\n * Extends Literal to provide specialized handling for sung text.\n */\nexport class Syllable extends Literal {\n readonly TYPE = \"Syllable\";\n\n /**\n * Creates a Syllable from a Literal.\n * @param lit The Literal to convert to a Syllable\n * @returns A new Syllable with the properties of the Literal\n */\n static fromLit(lit: Literal): Syllable {\n if (lit.TYPE == AtomType.SYLLABLE) return lit as Syllable;\n const out = new Syllable(lit.value, lit.duration);\n out.embelishments = lit.embelishments;\n out.beforeRest = lit.beforeRest;\n return out;\n }\n\n /**\n * Returns a string representation of this Syllable.\n * @returns A string representation\n */\n toString(): string {\n return `Syll(${this.duration}-${this.value})`;\n }\n}\n\n/**\n * Represents a musical note in the notation.\n * Extends Literal to add properties specific to musical notes.\n */\nexport class Note extends Literal {\n readonly TYPE = \"Note\";\n\n /**\n * Which octave the note is in. Can be positive or negative to indicate higher or lower octaves.\n */\n octave = 0;\n\n /**\n * How the note is shifted - i.e., shifted towards major or minor by # of semi-tones.\n */\n shift: number | boolean = 0;\n\n /**\n * Creates a new Note with the specified properties.\n * @param value The string value of the note\n * @param duration The duration of the note, defaults to ONE (1/1)\n * @param octave The octave of the note, defaults to 0\n * @param shift The shift of the note, defaults to 0\n */\n constructor(value: string, duration = ONE, octave = 0, shift = 0) {\n super(value, duration);\n this.octave = octave;\n this.shift = shift;\n }\n\n /**\n * Creates a Note from a Literal.\n * @param lit The Literal to convert to a Note\n * @returns A new Note with the properties of the Literal\n */\n static fromLit(lit: Literal): Note {\n if (lit.TYPE == AtomType.NOTE) return lit as Note;\n const out = new Note(lit.value, lit.duration);\n out.embelishments = lit.embelishments;\n out.beforeRest = lit.beforeRest;\n return out;\n }\n\n /**\n * Returns a debug-friendly representation of this Note.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue() };\n if (this.octave != 0) out.octave = this.octave;\n if (this.shift != 0) out.shift = this.shift;\n return out;\n }\n\n /**\n * Returns a string representation of this Note.\n * @returns A string representation\n */\n toString(): string {\n return `Note(${this.duration}-${this.value}-${this.octave})`;\n }\n\n /**\n * Checks if this Note is equal to another Note.\n * @param another The Note to compare with\n * @returns True if the Notes are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.octave == another.octave && this.shift == another.shift;\n }\n\n /**\n * Copies the properties of this Note to another Note.\n * @param another The target Note to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.octave = this.octave;\n another.shift = this.shift;\n }\n}\n\n/**\n * Represents a group of atoms that are treated as a single unit.\n * Groups can contain any number of atoms, including other groups.\n */\nexport class Group extends Atom {\n readonly TYPE = \"Group\";\n\n /**\n * Indicates whether the duration is static or linear to the number of atoms in this group.\n * When true, the duration is used as a multiplier for the total child duration.\n * When false, the duration is absolute.\n */\n durationIsMultiplier = false;\n\n /**\n * The list of atoms in this group.\n */\n readonly atoms = new TSU.Lists.ValueList<Atom>();\n\n /**\n * Creates a new Group containing the specified atoms.\n * @param atoms The atoms to include in this group\n */\n constructor(...atoms: Atom[]) {\n super(atoms.length == 0 ? ZERO : ONE);\n this.addAtoms(false, ...atoms);\n }\n\n /**\n * Checks if this Group is equal to another Group.\n * @param another The Group to compare with\n * @param expect Optional parameter\n * @returns True if the Groups are equal, false otherwise\n */\n equals(another: this, expect = false): boolean {\n if (!super.equals(another)) return false;\n return this.atoms.equals(another.atoms, (a1, a2) => a1.equals(a2));\n }\n\n /**\n * Copies the properties of this Group to another Group.\n * @param another The target Group to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.durationIsMultiplier = this.durationIsMultiplier;\n this.atoms.forEach((atom) => another.atoms.add(atom.clone()));\n }\n\n /**\n * Gets the duration of this group.\n * If durationIsMultiplier is true, returns the total child duration divided by the multiplier.\n * Otherwise, returns the absolute duration.\n */\n get duration(): Fraction {\n if (this.durationIsMultiplier) {\n return this.totalChildDuration.divby(this._duration);\n } else {\n return this._duration;\n }\n }\n\n /**\n * Sets this group to use a multiplier for duration calculations.\n * @param asMultiplier Whether to use the duration as a multiplier\n * @returns This Group instance for method chaining\n */\n setDurationAsMultiplier(asMultiplier = true): this {\n this.durationIsMultiplier = asMultiplier;\n return this;\n }\n\n /**\n * Sets the duration of this group.\n * @param d The new duration\n * @param asMultiplier Whether to use the duration as a multiplier\n * @returns This Group instance for method chaining\n */\n setDuration(d: Fraction, asMultiplier = false): this {\n this._duration = d;\n this.durationIsMultiplier = asMultiplier;\n return this;\n }\n\n /**\n * Returns a debug-friendly representation of this Group.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue(), atoms: Array.from(this.atoms.values(), (a) => a.debugValue()) };\n if (this.durationIsMultiplier) out.durationIsMultiplier = true;\n return out;\n }\n\n /**\n * Splits this group into two parts.\n * The first part (this group) fits within the given duration and everything else\n * longer than the given duration is returned as a new Group.\n *\n * @param requiredDuration The duration at which to split the group\n * @returns A new Group containing the atoms beyond the split point, or null if no split is needed\n */\n splitAt(requiredDuration: Fraction): TSU.Nullable<Group> {\n if (this.duration.isLTE(requiredDuration) || requiredDuration.isLTE(ZERO)) {\n return null;\n }\n const targetGroup = new Group();\n if (this.durationIsMultiplier) {\n targetGroup.durationIsMultiplier = true;\n targetGroup._duration = this._duration;\n }\n\n let remainingDur = this.duration;\n const totalChildDuration = this.totalChildDuration;\n const durationFactor = this.durationIsMultiplier\n ? ONE.divby(this._duration)\n : this._duration.divby(totalChildDuration, true);\n while (remainingDur.isGT(requiredDuration) && this.atoms.last) {\n const lastChild = this.atoms.last;\n // Child's duration is absolute in its own \"system\"\n // Its duration within the parent (this) group's frame of reference depends\n // on whether the parent's duration is absolute or as a multiplier\n //\n // realChildDuration = case (group.durationIsMultiper) {\n // | true => child.duration / this._duration\n // | false => child.duration * this._duration / total child duration\n // }\n const childDuration = lastChild.duration.times(durationFactor);\n const newDuration = remainingDur.minus(childDuration);\n if (newDuration.isGTE(requiredDuration)) {\n // remove ourselves and add to target\n // in both cases duration will be adjusted if need be\n this.removeAtoms(true, lastChild);\n targetGroup.insertAtomsAt(targetGroup.atoms.first, true, lastChild);\n if (newDuration.equals(requiredDuration)) {\n // we have reached the end so return\n return targetGroup;\n }\n } else {\n // our scenario is now this:\n //\n // totalParentDuration = 10\n // required = 8\n // lastChildDuration (relative to parent) is 5\n //\n // durWithoutLast = 10 - 5\n // newRequired = requiredDur - durWithoutLast = 3\n //\n // However 3 is a duration in the parent's frame of reference\n // this has to be converted back to the child's FoR\n const newRequiredDur = requiredDuration.minus(newDuration, true).divby(durationFactor, true);\n // console.log( \"newRequiredDur: \", newRequiredDur, \"requiedDur: \", requiredDuration, \"remainingDur: \", remainingDur,);\n // then the last item needs to be split, and by how much?\n const spillOver = lastChild.splitAt(newRequiredDur);\n if (spillOver == null) {\n throw new Error(\"Spill over cannot be null here\");\n }\n if (!this.durationIsMultiplier) {\n // Our own duration has also now changed\n this._duration = requiredDuration;\n } else {\n if (this._duration.isZero) throw new Error(\"How can this be?\");\n }\n spillOver.isContinuation = true;\n // Add spill over to the target\n targetGroup.insertAtomsAt(targetGroup.atoms.first, true, spillOver);\n return targetGroup;\n }\n remainingDur = newDuration;\n }\n return targetGroup;\n }\n\n /**\n * Gets the total duration of all child atoms.\n * @returns The sum of durations of all atoms in this group\n */\n get totalChildDuration(): Fraction {\n let out = ZERO;\n this.atoms.forEach((atom) => (out = out.plus(atom.duration)));\n return out;\n }\n\n /**\n * Inserts atoms before a given cursor atom.\n * If the cursor atom is null, the atoms are appended at the end.\n *\n * @param beforeAtom The atom before which to insert the new atoms, or null to append\n * @param adjustDuration Whether to adjust this group's duration based on the new atoms\n * @param atoms The atoms to insert\n * @returns This Group instance for method chaining\n */\n insertAtomsAt(beforeAtom: TSU.Nullable<Atom>, adjustDuration = false, ...atoms: Atom[]): this {\n adjustDuration = adjustDuration && !this.durationIsMultiplier;\n const oldChildDuration = adjustDuration ? this.totalChildDuration : ONE;\n // First form a chain of the given atoms\n for (const atom of atoms) {\n if (atom.parentGroup != null) {\n if (atom.parentGroup != this) {\n throw new Error(\"Atom belongs to another parent. Remove it first\");\n }\n atom.parentGroup.removeAtoms(false, atom);\n }\n if (atom.TYPE == AtomType.REST) {\n const last = this.atoms.last;\n if (last && last.TYPE != AtomType.GROUP && last.TYPE != AtomType.LABEL) {\n (last as LeafAtom).beforeRest = true;\n }\n } else {\n atom.parentGroup = this;\n this.atoms.add(atom, beforeAtom);\n }\n }\n if (adjustDuration) {\n if (this._duration.isZero) {\n if (this.durationIsMultiplier) throw new Error(\"How can this be?\");\n this._duration = this.totalChildDuration;\n } else {\n const scaleFactor = this.totalChildDuration.divby(oldChildDuration);\n this._duration = this._duration.times(scaleFactor, true);\n }\n }\n return this;\n }\n\n /**\n * Adds atoms to the end of this group's atom list.\n *\n * @param adjustDuration Whether to adjust this group's duration based on the new atoms\n * @param atoms The atoms to add\n * @returns This Group instance for method chaining\n */\n addAtoms(adjustDuration = false, ...atoms: Atom[]): this {\n return this.insertAtomsAt(null, adjustDuration, ...atoms);\n }\n\n /**\n * Removes atoms from this group's child list.\n *\n * @param adjustDuration Whether to adjust this group's duration after removing atoms\n * @param atoms The atoms to remove\n * @returns This Group instance for method chaining\n */\n removeAtoms(adjustDuration = false, ...atoms: Atom[]): this {\n adjustDuration = adjustDuration && !this.durationIsMultiplier;\n const oldChildDuration = adjustDuration ? this.totalChildDuration : ONE;\n for (const atom of atoms) {\n if (atom.parentGroup == this) {\n this.atoms.remove(atom);\n atom.parentGroup = null;\n } else if (atom.parentGroup != null) {\n throw new Error(\"Atom cannot be removed as it does not belong to this group\");\n }\n }\n if (adjustDuration) {\n if (this._duration.isZero) {\n if (this.durationIsMultiplier) throw new Error(\"How can this be?\");\n this._duration = this.totalChildDuration;\n } else {\n const scaleFactor = this.totalChildDuration.divby(oldChildDuration);\n this._duration = this._duration.times(scaleFactor, true);\n }\n }\n return this;\n }\n}\n\n/**\n * Represents a line of notation containing multiple roles.\n * A line can have atoms starting before or after the cycle.\n */\nexport class Line extends Entity {\n readonly TYPE: string = \"Line\";\n\n /**\n * Offset tells how many notes before or after the cycle this line's atoms start at.\n */\n offset: Fraction = ZERO;\n\n /**\n * The roles contained in this line.\n */\n roles: Role[] = [];\n\n /**\n * Text to be displayed in the margin of the line.\n * This is a hacky solution to doing left side pre-margin text typically\n * found in notations - e.g., line X of a pallavi has this. This makes vertical\n * space less wasteful.\n *\n * A better solution is inter-beat annotation but it is very complex for now.\n */\n marginText = \"\";\n\n /**\n * The LayoutParams associated with this line.\n */\n layoutParams: LayoutParams;\n\n /**\n * Finds the index of a role with the given name.\n * @param name The name of the role to find\n * @returns The index of the role, or -1 if not found\n */\n indexOfRole(name: string): number {\n for (let i = 0; i < this.roles.length; i++) {\n if (this.roles[i].name == name) return i;\n }\n return -1;\n }\n\n /**\n * Checks if this line is empty (has no content in any role).\n */\n get isEmpty(): boolean {\n for (const r of this.roles) if (!r.isEmpty) return false;\n return true;\n }\n\n /**\n * Returns a debug-friendly representation of this Line.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = {\n ...super.debugValue(),\n roles: this.roles.map((r) => r.debugValue()),\n };\n if (!this.offset.isZero) {\n out.offset = this.offset.toString();\n }\n return out;\n }\n\n /**\n * Copies the properties of this Line to another Line.\n * @param another The target Line to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.roles = this.roles.map((r) => r.clone());\n }\n\n /**\n * Adds atoms to a role in this line.\n * @param roleName The name of the role to add atoms to\n * @param defaultToNotes Whether to default to notes for this role\n * @param atoms The atoms to add\n * @returns This Line instance for method chaining\n */\n addAtoms(roleName: string, defaultToNotes: boolean, ...atoms: Atom[]): this {\n const role = this.ensureRole(roleName, defaultToNotes);\n role.addAtoms(...atoms);\n return this;\n }\n\n /**\n * Ensures a role with the given name exists in this line, creating it if needed.\n * @param roleName The name of the role to ensure\n * @param defaultToNotes Whether to default to notes for this role\n * @returns The role with the specified name\n */\n ensureRole(roleName: string, defaultToNotes: boolean): Role {\n // Ensure we have this many roles\n let ri = this.roles.findIndex((r) => r.name == roleName);\n if (ri < 0) {\n ri = this.roles.length;\n const role = new Role(this, roleName);\n role.defaultToNotes = defaultToNotes;\n this.roles.push(role);\n }\n return this.roles[ri];\n }\n\n /**\n * Gets the maximum duration across all roles in this line.\n */\n get duration(): Fraction {\n let max = ZERO;\n for (const role of this.roles) {\n max = TSU.Num.Fraction.max(role.duration, max);\n }\n return max;\n }\n}\n\n/**\n * Represents a specific role or voice in a line of notation.\n * Each role contains a sequence of atoms.\n */\nexport class Role extends Entity {\n readonly TYPE = \"Role\";\n\n /**\n * Whether this role represents notes by default.\n */\n defaultToNotes = true;\n\n /**\n * The atoms in this role.\n */\n atoms: Atom[] = [];\n\n /**\n * Creates a new Role with the specified line and name.\n * @param line The line this role belongs to\n * @param name The name of the role\n */\n constructor(\n public readonly line: Line,\n public readonly name: string,\n ) {\n super();\n }\n\n /**\n * Checks if this role is empty (has no atoms).\n */\n get isEmpty(): boolean {\n return this.atoms.length == 0;\n }\n\n /**\n * Returns a debug-friendly representation of this Role.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { name: this.name, atoms: this.atoms.map((a) => a.debugValue()) };\n }\n\n /**\n * Adds atoms to this role.\n * @param atoms The atoms to add\n */\n addAtoms(...atoms: Atom[]): void {\n let last: null | Atom = null;\n for (const atom of atoms) {\n if (atom.TYPE == AtomType.REST) {\n if (last && last.TYPE != AtomType.GROUP && last.TYPE != AtomType.LABEL) {\n (last as LeafAtom).beforeRest = true;\n }\n } else {\n this.atoms.push(atom);\n }\n last = atom;\n }\n }\n\n /**\n * Copies the properties of this Role to another Role.\n * @param another The target Role to copy properties to\n */\n copyTo(another: Role): void {\n another.addAtoms(...this.atoms);\n }\n\n /**\n * Gets the total duration of all atoms in this role.\n */\n get duration(): Fraction {\n return this.atoms.reduce((a, b) => a.plus(b.duration), ZERO);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cycle.js","sourceRoot":"","sources":["../../src/cycle.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity, TimedEntity } from \"./entity\";\n\n/**\n * Alias to TSU.Num.Fraction in tsutils.\n */\ntype Fraction = TSU.Num.Fraction;\nexport type CyclePosition = [number, number, number];\nexport type CycleIterator = Generator<[CyclePosition, Fraction]>;\n\nconst ZERO = TSU.Num.Fraction.ZERO;\nconst ONE = TSU.Num.Fraction.ONE;\n\n/**\n * A cursor that traverses through a Cycle's beats in a controlled manner.\n * Allows forward and backward navigation through the cycle.\n */\nexport class CycleCursor {\n /**\n * Creates a new CycleCursor.\n * @param cycle The Cycle to traverse\n * @param barIndex The starting bar index, defaults to 0\n * @param beatIndex The starting beat index within the bar, defaults to 0\n * @param instance The starting instance index within the beat, defaults to 0\n */\n constructor(public readonly cycle: Cycle, public barIndex = 0, public beatIndex = 0, public instance = 0) {}\n\n /**\n * Advances the cursor to the next beat and returns the current position and beat length.\n * @returns A tuple containing the current position and beat length\n */\n get next(): [CyclePosition, Fraction] {\n const currBar = this.cycle.bars[this.barIndex];\n const result: [CyclePosition, Fraction] = [\n [this.barIndex, this.beatIndex, this.instance],\n currBar.beatLengths[this.beatIndex],\n ];\n this.instance++;\n if (!currBar.beatCounts[this.beatIndex] || this.instance >= currBar.beatCounts[this.beatIndex]) {\n this.instance = 0;\n this.beatIndex++;\n if (this.beatIndex >= currBar.beatLengths.length) {\n this.beatIndex = 0;\n this.barIndex++;\n if (this.barIndex >= this.cycle.bars.length) {\n this.barIndex = 0;\n }\n }\n }\n return result;\n }\n\n /**\n * Moves the cursor to the previous beat and returns the current position and beat length.\n * @returns A tuple containing the current position and beat length\n */\n get prev(): [CyclePosition, Fraction] {\n const currBar = this.cycle.bars[this.barIndex];\n const result: [CyclePosition, Fraction] = [\n [this.barIndex, this.beatIndex, this.instance],\n currBar.beatLengths[this.beatIndex],\n ];\n // TODO - result should be set *after* decrementing if we had already\n // done a \"next\" before this otherwise user may have to do a prev twice\n this.instance--;\n if (this.instance < 0) {\n this.beatIndex--;\n if (this.beatIndex < 0) {\n this.barIndex--;\n if (this.barIndex < 0) {\n this.barIndex = this.cycle.bars.length - 1;\n }\n this.beatIndex = this.cycle.bars[this.barIndex].beatCount - 1;\n }\n this.instance = (this.cycle.bars[this.barIndex].beatCounts[this.beatIndex] || 1) - 1;\n }\n return result;\n }\n}\n\n/**\n * Represents a bar in a musical cycle.\n * A bar consists of beats with specific lengths and counts.\n */\nexport class Bar extends TimedEntity {\n readonly TYPE: string = \"Bar\";\n\n /** Name of the bar (e.g., \"Laghu\", \"Dhrutam\") */\n name: string;\n \n /** Length/Duration of each beat in the bar */\n beatLengths: Fraction[] = [];\n\n /** How many times each beat should be repeated (the Kalai) */\n beatCounts: number[] = [];\n\n /**\n * Creates a new Bar.\n * @param config Configuration object containing name, beatLengths, and beatCounts\n */\n constructor(config: any = null) {\n super((config = config || {}));\n this.name = config.name || \"\";\n for (const bl of config.beatLengths || []) {\n if (typeof bl === \"number\") {\n this.beatLengths.push(TSU.Num.Frac(bl));\n } else {\n this.beatLengths.push(bl);\n }\n }\n for (const bc of config.beatCounts || []) {\n this.beatCounts.push(bc);\n }\n while (this.beatCounts.length < this.beatLengths.length) {\n this.beatCounts.push(1);\n }\n }\n\n /**\n * Returns a debug-friendly representation of this Bar.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), name: name, beatLengths: this.beatLengths };\n }\n\n /**\n * Checks if this Bar is equal to another Bar.\n * @param another The Bar to compare with\n * @returns True if the Bars are equal, false otherwise\n */\n equals(another: this): boolean {\n if (!super.equals(another)) return false;\n if (this.beatLengths.length != another.beatLengths.length) return false;\n if (this.beatCounts.length != another.beatCounts.length) return false;\n for (let i = 0; i < this.beatLengths.length; i++) {\n if (!this.beatLengths[i].equals(another.beatLengths[i])) return false;\n }\n for (let i = 0; i < this.beatCounts.length; i++) {\n if (this.beatCounts[i] != another.beatCounts[i]) return false;\n }\n return true;\n }\n\n /**\n * Copies the properties of this Bar to another Bar.\n * @param another The target Bar to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.name = this.name;\n another.beatLengths = [...this.beatLengths];\n another.beatCounts = [...this.beatCounts];\n }\n\n /**\n * Gets the instance count for a specific beat in the bar.\n * @param beatIndex The index of the beat\n * @returns The number of instances for the specified beat\n */\n instanceCount(beatIndex: number): number {\n if (beatIndex > this.beatCounts.length) {\n // by default each beat has 1 instance?\n return 1;\n } else {\n return this.beatCounts[beatIndex];\n }\n }\n\n /**\n * Gets the number of unique beats in this bar (irrespective of instances).\n */\n get beatCount(): number {\n return this.beatLengths.length;\n }\n\n /**\n * Gets the total number of beat instances in this bar.\n */\n get totalBeatCount(): number {\n let out = 0;\n for (let i = 0; i < this.beatLengths.length; i++) {\n out += this.beatCounts[i] || 1;\n }\n return out;\n }\n\n /**\n * Gets the total duration of time across all beats in this bar.\n */\n get duration(): Fraction {\n let total = ZERO;\n for (let i = 0; i < this.beatLengths.length; i++) {\n total = total.plus(this.beatLengths[i].timesNum(this.beatCounts[i] || 1));\n }\n return total;\n }\n}\n\n/**\n * Represents a complete rhythmic cycle pattern composed of bars.\n * In carnatic music, this typically represents a tala.\n */\nexport class Cycle extends TimedEntity {\n readonly TYPE: string = \"Cycle\";\n\n /** Name of the cycle (e.g., \"Adi Thalam\") */\n name: string;\n \n /** The bars that make up this cycle */\n bars: Bar[];\n\n /**\n * Default cycle representing Adi Thalam (4+2+2 structure).\n */\n static readonly DEFAULT = new Cycle({\n name: \"Adi Thalam\",\n bars: [\n new Bar({ name: \"Laghu\", beatLengths: [1, 1, 1, 1] }),\n new Bar({ name: \"Dhrutam\", beatLengths: [1, 1] }),\n new Bar({ name: \"Dhrutam\", beatLengths: [1, 1] }),\n ],\n });\n\n /**\n * Creates a new Cycle.\n * @param config Configuration object containing name and bars\n */\n constructor(config: null | { name?: string; bars?: Bar[] } = null) {\n super((config = config || {}));\n this.name = config.name || \"\";\n this.bars = config.bars || [];\n }\n\n /**\n * Returns a debug-friendly representation of this Cycle.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), name: name, bars: this.bars.map((p) => p.debugValue()) };\n }\n\n /**\n * Gets all child entities of this Cycle.\n * @returns An array of child entities (bars)\n */\n children(): Entity[] {\n return this.bars;\n }\n\n /**\n * Checks if this Cycle is equal to another Cycle.\n * @param another The Cycle to compare with\n * @returns True if the Cycles are equal, false otherwise\n */\n equals(another: this): boolean {\n if (!super.equals(another)) {\n return false;\n }\n if (this.bars.length != another.bars.length) return false;\n for (let i = 0; i < this.bars.length; i++) {\n if (!this.bars[i].equals(another.bars[i])) return false;\n }\n return true;\n }\n\n /**\n * Given a global beat index, returns the position within the cycle.\n * \n * @param globalIndex The global beat index\n * @returns A tuple containing [cycle number, position, start offset]\n * - cycle: The nth cycle in which the beat lies\n * - position: [barIndex, beatIndex, instance] within the cycle\n * - startOffset: Offset of the beat at this global index\n */\n getAtIndex(globalIndex: number): [number, CyclePosition, Fraction] {\n let cycle = 0;\n while (globalIndex < 0) {\n globalIndex += this.totalBeatCount;\n cycle--;\n }\n if (globalIndex >= this.totalBeatCount) {\n cycle = Math.floor(globalIndex / this.totalBeatCount);\n }\n globalIndex = globalIndex % this.totalBeatCount;\n let offset = ZERO;\n for (let barIndex = 0; barIndex < this.bars.length; barIndex++) {\n const bar = this.bars[barIndex];\n if (globalIndex >= bar.totalBeatCount) {\n globalIndex -= bar.totalBeatCount;\n offset = offset.plus(bar.duration);\n } else {\n // this is the bar!\n for (let beatIndex = 0; beatIndex < bar.beatCount; beatIndex++) {\n const beatLength = bar.beatLengths[beatIndex];\n const beatCount = bar.beatCounts[beatIndex] || 1;\n if (globalIndex >= beatCount) {\n globalIndex -= beatCount;\n offset = offset.plus(beatLength.timesNum(beatCount));\n } else {\n // this is it\n const instance = globalIndex;\n return [cycle, [barIndex, beatIndex, instance], offset.plus(beatLength.timesNum(instance))];\n }\n }\n }\n }\n throw new Error(\"Should not be here!\");\n }\n\n /**\n * Given a global offset, returns the position within the cycle.\n * \n * @param globalOffset The global time offset\n * @returns A tuple containing [cycle number, position, note offset, global index]\n * - cycle: The nth cycle in which the offset lies\n * - position: [barIndex, beatIndex, instance] within the cycle\n * - startOffset: The note offset within the beat\n * - globalIndex: The beat index within the entire cycle\n */\n getPosition(globalOffset: Fraction): [number, CyclePosition, Fraction, number] {\n const duration = this.duration;\n let cycleNum = 0;\n if (globalOffset.isLT(ZERO)) {\n while (globalOffset.isLT(ZERO)) {\n cycleNum--;\n globalOffset = globalOffset.plus(duration);\n }\n } else if (globalOffset.isGTE(duration)) {\n const realOffset = globalOffset.mod(duration);\n globalOffset = globalOffset.minus(realOffset).divby(duration);\n TSU.assert(globalOffset.isWhole);\n cycleNum = globalOffset.floor;\n globalOffset = realOffset;\n }\n\n // here globalOffset is positive and >= 0 and < this.duration\n let globalIndex = 0;\n for (let barIndex = 0; barIndex < this.bars.length; barIndex++) {\n const bar = this.bars[barIndex];\n const barDuration = bar.duration;\n if (globalOffset.isGTE(barDuration)) {\n globalOffset = globalOffset.minus(barDuration);\n } else {\n // this is the bar!\n for (let beatIndex = 0; beatIndex < bar.beatCount; beatIndex++) {\n const beatLength = bar.beatLengths[beatIndex];\n const beatCount = bar.beatCounts[beatIndex] || 1;\n for (let instance = 0; instance < beatCount; instance++, globalIndex++) {\n if (globalOffset.isGTE(beatLength)) {\n globalOffset = globalOffset.minus(beatLength);\n } else {\n // this is it\n return [cycleNum, [barIndex, beatIndex, instance], globalOffset, globalIndex];\n }\n }\n }\n }\n globalIndex += bar.totalBeatCount;\n }\n\n throw new Error(\"Should not be here!\");\n }\n\n /**\n * Creates an iterator that yields beats in sequence from a starting position.\n * \n * @param startBar The starting bar index, defaults to 0\n * @param startBeat The starting beat index, defaults to 0\n * @param startInstance The starting instance index, defaults to 0\n * @returns A generator that yields [position, beat length] pairs\n */\n *iterateBeats(startBar = 0, startBeat = 0, startInstance = 0): CycleIterator {\n let barIndex = startBar;\n let beatIndex = startBeat;\n let instanceIndex = startInstance;\n while (true) {\n const currBar = this.bars[barIndex];\n yield [[barIndex, beatIndex, instanceIndex], currBar.beatLengths[beatIndex]];\n instanceIndex++;\n if (!currBar.beatCounts[beatIndex] || instanceIndex >= currBar.beatCounts[beatIndex]) {\n instanceIndex = 0;\n beatIndex++;\n if (beatIndex >= currBar.beatLengths.length) {\n beatIndex = 0;\n barIndex++;\n if (barIndex >= this.bars.length) {\n barIndex = 0;\n }\n }\n }\n }\n }\n\n /**\n * Copies the properties of this Cycle to another Cycle.\n * @param another The target Cycle to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.name = this.name;\n another.bars = this.bars.map((x) => x.clone());\n }\n\n /**\n * Gets the number of unique beats in this cycle (irrespective of instances).\n */\n get beatCount(): number {\n let out = 0;\n for (const bar of this.bars) out += bar.beatCount;\n return out;\n }\n\n /**\n * Gets the total number of beat instances in this cycle.\n */\n get totalBeatCount(): number {\n let out = 0;\n for (const bar of this.bars) out += bar.totalBeatCount;\n return out;\n }\n\n /**\n * Gets the total duration of time across all bars in this cycle.\n */\n get duration(): Fraction {\n return this.bars.reduce((x, y) => x.plus(y.duration), ZERO);\n }\n}\n"]}
1
+ {"version":3,"file":"cycle.js","sourceRoot":"","sources":["../../src/cycle.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity, TimedEntity } from \"./entity\";\n\n/**\n * Alias to TSU.Num.Fraction in tsutils.\n */\ntype Fraction = TSU.Num.Fraction;\nexport type CyclePosition = [number, number, number];\nexport type CycleIterator = Generator<[CyclePosition, Fraction]>;\n\nconst ZERO = TSU.Num.Fraction.ZERO;\nconst ONE = TSU.Num.Fraction.ONE;\n\n/**\n * A cursor that traverses through a Cycle's beats in a controlled manner.\n * Allows forward and backward navigation through the cycle.\n */\nexport class CycleCursor {\n /**\n * Creates a new CycleCursor.\n * @param cycle The Cycle to traverse\n * @param barIndex The starting bar index, defaults to 0\n * @param beatIndex The starting beat index within the bar, defaults to 0\n * @param instance The starting instance index within the beat, defaults to 0\n */\n constructor(\n public readonly cycle: Cycle,\n public barIndex = 0,\n public beatIndex = 0,\n public instance = 0,\n ) {}\n\n /**\n * Advances the cursor to the next beat and returns the current position and beat length.\n * @returns A tuple containing the current position and beat length\n */\n get next(): [CyclePosition, Fraction] {\n const currBar = this.cycle.bars[this.barIndex];\n const result: [CyclePosition, Fraction] = [\n [this.barIndex, this.beatIndex, this.instance],\n currBar.beatLengths[this.beatIndex],\n ];\n this.instance++;\n if (!currBar.beatCounts[this.beatIndex] || this.instance >= currBar.beatCounts[this.beatIndex]) {\n this.instance = 0;\n this.beatIndex++;\n if (this.beatIndex >= currBar.beatLengths.length) {\n this.beatIndex = 0;\n this.barIndex++;\n if (this.barIndex >= this.cycle.bars.length) {\n this.barIndex = 0;\n }\n }\n }\n return result;\n }\n\n /**\n * Moves the cursor to the previous beat and returns the current position and beat length.\n * @returns A tuple containing the current position and beat length\n */\n get prev(): [CyclePosition, Fraction] {\n const currBar = this.cycle.bars[this.barIndex];\n const result: [CyclePosition, Fraction] = [\n [this.barIndex, this.beatIndex, this.instance],\n currBar.beatLengths[this.beatIndex],\n ];\n // TODO - result should be set *after* decrementing if we had already\n // done a \"next\" before this otherwise user may have to do a prev twice\n this.instance--;\n if (this.instance < 0) {\n this.beatIndex--;\n if (this.beatIndex < 0) {\n this.barIndex--;\n if (this.barIndex < 0) {\n this.barIndex = this.cycle.bars.length - 1;\n }\n this.beatIndex = this.cycle.bars[this.barIndex].beatCount - 1;\n }\n this.instance = (this.cycle.bars[this.barIndex].beatCounts[this.beatIndex] || 1) - 1;\n }\n return result;\n }\n}\n\n/**\n * Represents a bar in a musical cycle.\n * A bar consists of beats with specific lengths and counts.\n */\nexport class Bar extends TimedEntity {\n readonly TYPE: string = \"Bar\";\n\n /** Name of the bar (e.g., \"Laghu\", \"Dhrutam\") */\n name: string;\n\n /** Length/Duration of each beat in the bar */\n beatLengths: Fraction[] = [];\n\n /** How many times each beat should be repeated (the Kalai) */\n beatCounts: number[] = [];\n\n /**\n * Creates a new Bar.\n * @param config Configuration object containing name, beatLengths, and beatCounts\n */\n constructor(config: any = null) {\n super((config = config || {}));\n this.name = config.name || \"\";\n for (const bl of config.beatLengths || []) {\n if (typeof bl === \"number\") {\n this.beatLengths.push(TSU.Num.Frac(bl));\n } else {\n this.beatLengths.push(bl);\n }\n }\n for (const bc of config.beatCounts || []) {\n this.beatCounts.push(bc);\n }\n while (this.beatCounts.length < this.beatLengths.length) {\n this.beatCounts.push(1);\n }\n }\n\n /**\n * Returns a debug-friendly representation of this Bar.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), name: name, beatLengths: this.beatLengths };\n }\n\n /**\n * Checks if this Bar is equal to another Bar.\n * @param another The Bar to compare with\n * @returns True if the Bars are equal, false otherwise\n */\n equals(another: this): boolean {\n if (!super.equals(another)) return false;\n if (this.beatLengths.length != another.beatLengths.length) return false;\n if (this.beatCounts.length != another.beatCounts.length) return false;\n for (let i = 0; i < this.beatLengths.length; i++) {\n if (!this.beatLengths[i].equals(another.beatLengths[i])) return false;\n }\n for (let i = 0; i < this.beatCounts.length; i++) {\n if (this.beatCounts[i] != another.beatCounts[i]) return false;\n }\n return true;\n }\n\n /**\n * Copies the properties of this Bar to another Bar.\n * @param another The target Bar to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.name = this.name;\n another.beatLengths = [...this.beatLengths];\n another.beatCounts = [...this.beatCounts];\n }\n\n /**\n * Gets the instance count for a specific beat in the bar.\n * @param beatIndex The index of the beat\n * @returns The number of instances for the specified beat\n */\n instanceCount(beatIndex: number): number {\n if (beatIndex > this.beatCounts.length) {\n // by default each beat has 1 instance?\n return 1;\n } else {\n return this.beatCounts[beatIndex];\n }\n }\n\n /**\n * Gets the number of unique beats in this bar (irrespective of instances).\n */\n get beatCount(): number {\n return this.beatLengths.length;\n }\n\n /**\n * Gets the total number of beat instances in this bar.\n */\n get totalBeatCount(): number {\n let out = 0;\n for (let i = 0; i < this.beatLengths.length; i++) {\n out += this.beatCounts[i] || 1;\n }\n return out;\n }\n\n /**\n * Gets the total duration of time across all beats in this bar.\n */\n get duration(): Fraction {\n let total = ZERO;\n for (let i = 0; i < this.beatLengths.length; i++) {\n total = total.plus(this.beatLengths[i].timesNum(this.beatCounts[i] || 1));\n }\n return total;\n }\n}\n\n/**\n * Represents a complete rhythmic cycle pattern composed of bars.\n * In carnatic music, this typically represents a tala.\n */\nexport class Cycle extends TimedEntity {\n readonly TYPE: string = \"Cycle\";\n\n /** Name of the cycle (e.g., \"Adi Thalam\") */\n name: string;\n\n /** The bars that make up this cycle */\n bars: Bar[];\n\n /**\n * Default cycle representing Adi Thalam (4+2+2 structure).\n */\n static readonly DEFAULT = new Cycle({\n name: \"Adi Thalam\",\n bars: [\n new Bar({ name: \"Laghu\", beatLengths: [1, 1, 1, 1] }),\n new Bar({ name: \"Dhrutam\", beatLengths: [1, 1] }),\n new Bar({ name: \"Dhrutam\", beatLengths: [1, 1] }),\n ],\n });\n\n /**\n * Creates a new Cycle.\n * @param config Configuration object containing name and bars\n */\n constructor(config: null | { name?: string; bars?: Bar[] } = null) {\n super((config = config || {}));\n this.name = config.name || \"\";\n this.bars = config.bars || [];\n }\n\n /**\n * Returns a debug-friendly representation of this Cycle.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), name: name, bars: this.bars.map((p) => p.debugValue()) };\n }\n\n /**\n * Gets all child entities of this Cycle.\n * @returns An array of child entities (bars)\n */\n children(): Entity[] {\n return this.bars;\n }\n\n /**\n * Checks if this Cycle is equal to another Cycle.\n * @param another The Cycle to compare with\n * @returns True if the Cycles are equal, false otherwise\n */\n equals(another: this): boolean {\n if (!super.equals(another)) {\n return false;\n }\n if (this.bars.length != another.bars.length) return false;\n for (let i = 0; i < this.bars.length; i++) {\n if (!this.bars[i].equals(another.bars[i])) return false;\n }\n return true;\n }\n\n /**\n * Given a global beat index, returns the position within the cycle.\n *\n * @param globalIndex The global beat index\n * @returns A tuple containing [cycle number, position, start offset]\n * - cycle: The nth cycle in which the beat lies\n * - position: [barIndex, beatIndex, instance] within the cycle\n * - startOffset: Offset of the beat at this global index\n */\n getAtIndex(globalIndex: number): [number, CyclePosition, Fraction] {\n let cycle = 0;\n while (globalIndex < 0) {\n globalIndex += this.totalBeatCount;\n cycle--;\n }\n if (globalIndex >= this.totalBeatCount) {\n cycle = Math.floor(globalIndex / this.totalBeatCount);\n }\n globalIndex = globalIndex % this.totalBeatCount;\n let offset = ZERO;\n for (let barIndex = 0; barIndex < this.bars.length; barIndex++) {\n const bar = this.bars[barIndex];\n if (globalIndex >= bar.totalBeatCount) {\n globalIndex -= bar.totalBeatCount;\n offset = offset.plus(bar.duration);\n } else {\n // this is the bar!\n for (let beatIndex = 0; beatIndex < bar.beatCount; beatIndex++) {\n const beatLength = bar.beatLengths[beatIndex];\n const beatCount = bar.beatCounts[beatIndex] || 1;\n if (globalIndex >= beatCount) {\n globalIndex -= beatCount;\n offset = offset.plus(beatLength.timesNum(beatCount));\n } else {\n // this is it\n const instance = globalIndex;\n return [cycle, [barIndex, beatIndex, instance], offset.plus(beatLength.timesNum(instance))];\n }\n }\n }\n }\n throw new Error(\"Should not be here!\");\n }\n\n /**\n * Given a global offset, returns the position within the cycle.\n *\n * @param globalOffset The global time offset\n * @returns A tuple containing [cycle number, position, note offset, global index]\n * - cycle: The nth cycle in which the offset lies\n * - position: [barIndex, beatIndex, instance] within the cycle\n * - startOffset: The note offset within the beat\n * - globalIndex: The beat index within the entire cycle\n */\n getPosition(globalOffset: Fraction): [number, CyclePosition, Fraction, number] {\n const duration = this.duration;\n let cycleNum = 0;\n if (globalOffset.isLT(ZERO)) {\n while (globalOffset.isLT(ZERO)) {\n cycleNum--;\n globalOffset = globalOffset.plus(duration);\n }\n } else if (globalOffset.isGTE(duration)) {\n const realOffset = globalOffset.mod(duration);\n globalOffset = globalOffset.minus(realOffset).divby(duration);\n TSU.assert(globalOffset.isWhole);\n cycleNum = globalOffset.floor;\n globalOffset = realOffset;\n }\n\n // here globalOffset is positive and >= 0 and < this.duration\n let globalIndex = 0;\n for (let barIndex = 0; barIndex < this.bars.length; barIndex++) {\n const bar = this.bars[barIndex];\n const barDuration = bar.duration;\n if (globalOffset.isGTE(barDuration)) {\n globalOffset = globalOffset.minus(barDuration);\n } else {\n // this is the bar!\n for (let beatIndex = 0; beatIndex < bar.beatCount; beatIndex++) {\n const beatLength = bar.beatLengths[beatIndex];\n const beatCount = bar.beatCounts[beatIndex] || 1;\n for (let instance = 0; instance < beatCount; instance++, globalIndex++) {\n if (globalOffset.isGTE(beatLength)) {\n globalOffset = globalOffset.minus(beatLength);\n } else {\n // this is it\n return [cycleNum, [barIndex, beatIndex, instance], globalOffset, globalIndex];\n }\n }\n }\n }\n globalIndex += bar.totalBeatCount;\n }\n\n throw new Error(\"Should not be here!\");\n }\n\n /**\n * Creates an iterator that yields beats in sequence from a starting position.\n *\n * @param startBar The starting bar index, defaults to 0\n * @param startBeat The starting beat index, defaults to 0\n * @param startInstance The starting instance index, defaults to 0\n * @returns A generator that yields [position, beat length] pairs\n */\n *iterateBeats(startBar = 0, startBeat = 0, startInstance = 0): CycleIterator {\n let barIndex = startBar;\n let beatIndex = startBeat;\n let instanceIndex = startInstance;\n while (true) {\n const currBar = this.bars[barIndex];\n yield [[barIndex, beatIndex, instanceIndex], currBar.beatLengths[beatIndex]];\n instanceIndex++;\n if (!currBar.beatCounts[beatIndex] || instanceIndex >= currBar.beatCounts[beatIndex]) {\n instanceIndex = 0;\n beatIndex++;\n if (beatIndex >= currBar.beatLengths.length) {\n beatIndex = 0;\n barIndex++;\n if (barIndex >= this.bars.length) {\n barIndex = 0;\n }\n }\n }\n }\n }\n\n /**\n * Copies the properties of this Cycle to another Cycle.\n * @param another The target Cycle to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.name = this.name;\n another.bars = this.bars.map((x) => x.clone());\n }\n\n /**\n * Gets the number of unique beats in this cycle (irrespective of instances).\n */\n get beatCount(): number {\n let out = 0;\n for (const bar of this.bars) out += bar.beatCount;\n return out;\n }\n\n /**\n * Gets the total number of beat instances in this cycle.\n */\n get totalBeatCount(): number {\n let out = 0;\n for (const bar of this.bars) out += bar.totalBeatCount;\n return out;\n }\n\n /**\n * Gets the total duration of time across all bars in this cycle.\n */\n get duration(): Fraction {\n return this.bars.reduce((x, y) => x.plus(y.duration), ZERO);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity.ts"],"names":[],"mappings":";;;AAMA,MAAa,MAAM;IAcjB,YAAY,SAAc,IAAI;QAbrB,SAAI,GAAW,QAAQ,CAAC;QAKxB,SAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAS/B,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QACtB,IAAI,MAAM,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAE7E,CAAC;IAOD,UAAU;QAER,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAMD,QAAQ;QACN,OAAO,EAAE,CAAC;IACZ,CAAC;IAKD,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC;IAChC,CAAC;IAQD,QAAQ,CAAC,KAAa,EAAE,KAAK,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAOD,OAAO,CAAC,KAAa;QACnB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAOD,YAAY,CAAC,MAAc;QACzB,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpC,IAAI,KAAK,IAAI,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC9B,CAAC,EAAE,CAAC;QACN,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IAOD,aAAa,CAAC,KAAa;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5B,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC1B,OAAO,GAAG,CAAC;IACb,CAAC;IAQD,UAAU,CAAC,KAAa,EAAE,MAAc;QACtC,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAuBD,QAAQ;QACN,OAAO,eAAe,IAAI,CAAC,IAAI,GAAG,CAAC;IACrC,CAAC;IAQD,MAAM,CAAC,OAAa,EAAE,MAAM,GAAG,KAAK;QAClC,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAE5C,OAAO,IAAI,CAAC;IACd,CAAC;IAUD,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,GAAG,CAAC;IACb,CAAC;IAMD,MAAM,CAAC,OAAa;IAEpB,CAAC;IAMS,WAAW;QACnB,OAAO,IAAK,IAAI,CAAC,WAAmB,EAAE,CAAC;IACzC,CAAC;;AA3KH,wBA4KC;AAxKgB,cAAO,GAAG,CAAC,AAAJ,CAAK;AA8K7B,MAAsB,WAAY,SAAQ,MAAM;IAAhD;;QACW,SAAI,GAAW,aAAa,CAAC;IAgBxC,CAAC;IAHC,MAAM,CAAC,OAAa;QAClB,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC;CACF;AAjBD,kCAiBC","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\n\n/**\n * A common Entity base class with support for unique IDs, copying, children and\n * debug info. This serves as the foundation for all entities in the notation system.\n */\nexport class Entity {\n readonly TYPE: string = \"Entity\";\n\n // readonly TYPE:string = \"Entity\";\n private static counter = 0;\n /** Unique identifier for this entity */\n readonly uuid = Entity.counter++;\n // private metadata: TSU.StringMap<any>;\n // parent: TSU.Nullable<Entity> = null;\n\n /**\n * Creates a new Entity.\n * @param config Optional configuration object\n */\n constructor(config: any = null) {\n config = config || {};\n if (config.metadata) throw new Error(\"See where metadata is being passed\");\n // this.metadata = config.metadata || {};\n }\n\n /**\n * Returns a debug-friendly representation of this entity.\n * Usually overridden by children to add more debug info.\n * @returns An object containing debug information\n */\n debugValue(): any {\n // if (Object.keys(this.metadata).length > 0) return { metadata: this.metadata, type: this.type };\n return { type: this.TYPE };\n }\n\n /**\n * Gets all child entities of this entity.\n * @returns An array of child entities\n */\n children(): Entity[] {\n return [];\n }\n\n /**\n * Gets the count of child entities.\n */\n get childCount(): number {\n return this.children().length;\n }\n\n /**\n * Adds a child entity at a given index.\n * @param child Child entity to be added\n * @param index Index where the child is to be inserted, -1 to append at the end\n * @returns This entity instance for method chaining\n */\n addChild(child: Entity, index = -1): this {\n if (index < 0) {\n this.children().push(child);\n } else {\n this.children().splice(index, 0, child);\n }\n return this;\n }\n\n /**\n * Returns the child at a given index.\n * @param index The index of the child to retrieve\n * @returns The child entity at the specified index\n */\n childAt(index: number): Entity {\n return this.children()[index];\n }\n\n /**\n * Returns the index of a given child entity.\n * @param entity The child entity to find\n * @returns The index where the child exists, or -1 if not found\n */\n indexOfChild(entity: Entity): number {\n let i = 0;\n for (const child of this.children()) {\n if (child == entity) return i;\n i++;\n }\n return -1;\n }\n\n /**\n * Removes and returns the child entity at the specified index.\n * @param index The index of the child to remove\n * @returns The removed child entity\n */\n removeChildAt(index: number): Entity {\n const children = this.children();\n const out = children[index];\n children.splice(index, 1);\n return out;\n }\n\n /**\n * Sets a child entity at the specified index.\n * @param index The index where to set the child\n * @param entity The entity to set at the index\n * @returns This entity instance for method chaining\n */\n setChildAt(index: number, entity: Entity): this {\n this.children()[index] = entity;\n return this;\n }\n\n /*\n setMetadata(key: string, value: any): this {\n this.metadata[key] = value;\n return this;\n }\n\n getMetadata(key: string, recurse = true): any {\n if (key in this.metadata) {\n return this.metadata[key];\n }\n if (recurse && this.parent) {\n return this.parent.getMetadata(key);\n }\n return null;\n }\n */\n\n /**\n * Returns a simple string representation of this Entity.\n * @returns A string representation\n */\n toString(): string {\n return `Entity(id = ${this.uuid})`;\n }\n\n /**\n * Checks if this Entity is equal to another Entity.\n * @param another The Entity to compare with\n * @param expect Optional parameter\n * @returns True if the Entities are equal, false otherwise\n */\n equals(another: this, expect = false): boolean {\n if (this.TYPE != another.TYPE) return false;\n // check metadata too\n return true;\n }\n\n /**\n * Creates a clone of this entity.\n * Cloning is a two-part process:\n * 1. Creation of a new instance via this.newInstance()\n * 2. Copying of data into the new instance via this.copyTo()\n * \n * @returns A new instance of the same type with the same properties\n */\n clone(): this {\n const out = this.newInstance();\n this.copyTo(out);\n return out;\n }\n\n /**\n * Copies information about this instance into another instance of the same type.\n * @param another The target instance to copy properties to\n */\n copyTo(another: this): void {\n // another.metadata = { ...this.metadata };\n }\n\n /**\n * First part of the cloning process where the instance is created.\n * @returns A new instance of the same type\n */\n protected newInstance(): this {\n return new (this.constructor as any)();\n }\n}\n\n/**\n * Music is all about timing! TimedEntities are base of all entities that\n * have a duration. This is an abstract class that all timed entities inherit from.\n */\nexport abstract class TimedEntity extends Entity {\n readonly TYPE: string = \"TimedEntity\";\n\n /**\n * Gets the duration of this entity in terms of beats.\n * By default, entity durations are readonly.\n */\n abstract get duration(): TSU.Num.Fraction;\n\n /**\n * Checks if this TimedEntity is equal to another TimedEntity.\n * @param another The TimedEntity to compare with\n * @returns True if the TimedEntities are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.duration.equals(another.duration);\n }\n}\n"]}
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity.ts"],"names":[],"mappings":";;;AAMA,MAAa,MAAM;IAcjB,YAAY,SAAc,IAAI;QAbrB,SAAI,GAAW,QAAQ,CAAC;QAKxB,SAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAS/B,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QACtB,IAAI,MAAM,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAE7E,CAAC;IAOD,UAAU;QAER,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAMD,QAAQ;QACN,OAAO,EAAE,CAAC;IACZ,CAAC;IAKD,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC;IAChC,CAAC;IAQD,QAAQ,CAAC,KAAa,EAAE,KAAK,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAOD,OAAO,CAAC,KAAa;QACnB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAOD,YAAY,CAAC,MAAc;QACzB,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpC,IAAI,KAAK,IAAI,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC9B,CAAC,EAAE,CAAC;QACN,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IAOD,aAAa,CAAC,KAAa;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5B,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC1B,OAAO,GAAG,CAAC;IACb,CAAC;IAQD,UAAU,CAAC,KAAa,EAAE,MAAc;QACtC,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAuBD,QAAQ;QACN,OAAO,eAAe,IAAI,CAAC,IAAI,GAAG,CAAC;IACrC,CAAC;IAQD,MAAM,CAAC,OAAa,EAAE,MAAM,GAAG,KAAK;QAClC,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAE5C,OAAO,IAAI,CAAC;IACd,CAAC;IAUD,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,GAAG,CAAC;IACb,CAAC;IAMD,MAAM,CAAC,OAAa;IAEpB,CAAC;IAMS,WAAW;QACnB,OAAO,IAAK,IAAI,CAAC,WAAmB,EAAE,CAAC;IACzC,CAAC;;AA3KH,wBA4KC;AAxKgB,cAAO,GAAG,CAAC,AAAJ,CAAK;AA8K7B,MAAsB,WAAY,SAAQ,MAAM;IAAhD;;QACW,SAAI,GAAW,aAAa,CAAC;IAgBxC,CAAC;IAHC,MAAM,CAAC,OAAa;QAClB,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC;CACF;AAjBD,kCAiBC","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\n\n/**\n * A common Entity base class with support for unique IDs, copying, children and\n * debug info. This serves as the foundation for all entities in the notation system.\n */\nexport class Entity {\n readonly TYPE: string = \"Entity\";\n\n // readonly TYPE:string = \"Entity\";\n private static counter = 0;\n /** Unique identifier for this entity */\n readonly uuid = Entity.counter++;\n // private metadata: TSU.StringMap<any>;\n // parent: TSU.Nullable<Entity> = null;\n\n /**\n * Creates a new Entity.\n * @param config Optional configuration object\n */\n constructor(config: any = null) {\n config = config || {};\n if (config.metadata) throw new Error(\"See where metadata is being passed\");\n // this.metadata = config.metadata || {};\n }\n\n /**\n * Returns a debug-friendly representation of this entity.\n * Usually overridden by children to add more debug info.\n * @returns An object containing debug information\n */\n debugValue(): any {\n // if (Object.keys(this.metadata).length > 0) return { metadata: this.metadata, type: this.type };\n return { type: this.TYPE };\n }\n\n /**\n * Gets all child entities of this entity.\n * @returns An array of child entities\n */\n children(): Entity[] {\n return [];\n }\n\n /**\n * Gets the count of child entities.\n */\n get childCount(): number {\n return this.children().length;\n }\n\n /**\n * Adds a child entity at a given index.\n * @param child Child entity to be added\n * @param index Index where the child is to be inserted, -1 to append at the end\n * @returns This entity instance for method chaining\n */\n addChild(child: Entity, index = -1): this {\n if (index < 0) {\n this.children().push(child);\n } else {\n this.children().splice(index, 0, child);\n }\n return this;\n }\n\n /**\n * Returns the child at a given index.\n * @param index The index of the child to retrieve\n * @returns The child entity at the specified index\n */\n childAt(index: number): Entity {\n return this.children()[index];\n }\n\n /**\n * Returns the index of a given child entity.\n * @param entity The child entity to find\n * @returns The index where the child exists, or -1 if not found\n */\n indexOfChild(entity: Entity): number {\n let i = 0;\n for (const child of this.children()) {\n if (child == entity) return i;\n i++;\n }\n return -1;\n }\n\n /**\n * Removes and returns the child entity at the specified index.\n * @param index The index of the child to remove\n * @returns The removed child entity\n */\n removeChildAt(index: number): Entity {\n const children = this.children();\n const out = children[index];\n children.splice(index, 1);\n return out;\n }\n\n /**\n * Sets a child entity at the specified index.\n * @param index The index where to set the child\n * @param entity The entity to set at the index\n * @returns This entity instance for method chaining\n */\n setChildAt(index: number, entity: Entity): this {\n this.children()[index] = entity;\n return this;\n }\n\n /*\n setMetadata(key: string, value: any): this {\n this.metadata[key] = value;\n return this;\n }\n\n getMetadata(key: string, recurse = true): any {\n if (key in this.metadata) {\n return this.metadata[key];\n }\n if (recurse && this.parent) {\n return this.parent.getMetadata(key);\n }\n return null;\n }\n */\n\n /**\n * Returns a simple string representation of this Entity.\n * @returns A string representation\n */\n toString(): string {\n return `Entity(id = ${this.uuid})`;\n }\n\n /**\n * Checks if this Entity is equal to another Entity.\n * @param another The Entity to compare with\n * @param expect Optional parameter\n * @returns True if the Entities are equal, false otherwise\n */\n equals(another: this, expect = false): boolean {\n if (this.TYPE != another.TYPE) return false;\n // check metadata too\n return true;\n }\n\n /**\n * Creates a clone of this entity.\n * Cloning is a two-part process:\n * 1. Creation of a new instance via this.newInstance()\n * 2. Copying of data into the new instance via this.copyTo()\n *\n * @returns A new instance of the same type with the same properties\n */\n clone(): this {\n const out = this.newInstance();\n this.copyTo(out);\n return out;\n }\n\n /**\n * Copies information about this instance into another instance of the same type.\n * @param another The target instance to copy properties to\n */\n copyTo(another: this): void {\n // another.metadata = { ...this.metadata };\n }\n\n /**\n * First part of the cloning process where the instance is created.\n * @returns A new instance of the same type\n */\n protected newInstance(): this {\n return new (this.constructor as any)();\n }\n}\n\n/**\n * Music is all about timing! TimedEntities are base of all entities that\n * have a duration. This is an abstract class that all timed entities inherit from.\n */\nexport abstract class TimedEntity extends Entity {\n readonly TYPE: string = \"TimedEntity\";\n\n /**\n * Gets the duration of this entity in terms of beats.\n * By default, entity durations are readonly.\n */\n abstract get duration(): TSU.Num.Fraction;\n\n /**\n * Checks if this TimedEntity is equal to another TimedEntity.\n * @param another The TimedEntity to compare with\n * @returns True if the TimedEntities are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.duration.equals(another.duration);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"grids.js","sourceRoot":"","sources":["../../src/grids.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\n// import * as kiwi from \"@lume/kiwi\";\n\n/**\n * A generic grid layout system for hosting child views (similar to GridBagLayout).\n * This provides a framework for hosting BeatViews in a structured grid arrangement,\n * with support for rows, columns, and alignment.\n * \n * Grid \"cells\" can be referred to by cell indexes. Additionally, grid rows and\n * columns can have names (like in spreadsheets) so that even when rows and columns\n * are inserted, though indexes may change, the \"addresses\" remain fixed and immovable.\n */\nexport class GridModel extends TSU.Events.EventEmitter {\n private static idCounter = 0;\n readonly uuid = GridModel.idCounter++;\n /** Timestamp of the last update to this grid */\n lastUpdatedAt = 0;\n // cells = new SparseArray<SparseArray<GridCell>>();\n /** The rows in this grid */\n rows: GridRow[] = [];\n /** Mapping of row indices to row alignment objects */\n rowAligns = new Map<number, RowAlign>();\n /** Mapping of column indices to column alignment objects */\n colAligns = new Map<number, ColAlign>();\n\n /**\n * Returns a debug-friendly representation of this GridModel.\n * @returns An object containing debug information\n */\n debugValue() {\n const out = {\n rows: this.rows.map((r) => r.debugValue()),\n lastUpdatedAt: this.lastUpdatedAt,\n } as any;\n return out;\n }\n\n /**\n * Gets the index of the first non-empty row.\n * @returns The index of the first row containing cells, or -1 if none\n */\n get firstRow(): number {\n for (const gr of this.rows) {\n if (gr.numCells > 0) return gr.rowIndex;\n }\n return -1;\n }\n\n /**\n * Gets the index of the leftmost column containing cells.\n * @returns The index of the first column containing cells, or -1 if none\n */\n get firstCol(): number {\n let minCol = -1;\n for (const gr of this.rows) {\n const fc = gr.firstCol;\n if (fc >= 0) {\n if (minCol < 0 || fc < minCol) {\n minCol = fc;\n }\n }\n }\n return minCol;\n }\n\n /**\n * Gets all non-empty cells in a specific row.\n * @param row The index of the row\n * @returns An array of cells in the row\n */\n cellsInRow(row: number): GridCell[] {\n const out = [] as GridCell[];\n const gr = this.rows[row];\n if (gr) {\n for (const cell of gr.cells) {\n if (cell?.value) out.push(cell);\n }\n }\n return out;\n }\n\n /**\n * Gets all non-empty cells in a specific column.\n * @param col The index of the column\n * @returns An array of cells in the column\n */\n cellsInCol(col: number): GridCell[] {\n const out = [] as GridCell[];\n for (const gr of this.rows) {\n const cell = gr.cellAt(col);\n if (cell?.value) out.push(cell);\n }\n return out;\n }\n\n /**\n * Adds a row alignment object to the grid.\n * @param align The row alignment to add\n */\n addRowAlign(align: RowAlign): void {\n this.rowAligns.set(align.uuid, align);\n }\n\n /**\n * Adds a column alignment object to the grid.\n * @param align The column alignment to add\n */\n addColAlign(align: ColAlign): void {\n this.colAligns.set(align.uuid, align);\n }\n\n /**\n * Adds rows to the grid.\n * @param insertBefore The index before which to insert the rows, or -1 to append\n * @param numRows The number of rows to add\n * @returns This grid instance for method chaining\n */\n addRows(insertBefore = -1, numRows = 1): this {\n if (insertBefore < 0) {\n insertBefore = this.rows.length;\n }\n let next = this.rows[insertBefore] || null;\n const prev = this.rows[insertBefore - 1] || null;\n for (let i = numRows - 1; i >= 0; i--) {\n const newRow = new GridRow(this, insertBefore + i);\n this.rows.splice(insertBefore, 0, newRow);\n if (next != null) {\n newRow.defaultRowAlign.addSuccessor(next.defaultRowAlign);\n }\n if (i == 0 && insertBefore > 0) {\n prev.defaultRowAlign.addSuccessor(newRow.defaultRowAlign);\n }\n next = newRow;\n }\n for (let i = insertBefore + numRows; i < this.rows.length; i++) {\n this.rows[i].rowIndex += numRows;\n }\n return this;\n }\n\n /**\n * Gets a row at the specified index, creating it if necessary.\n * @param row The index of the row to get\n * @returns The row at the specified index\n */\n getRow(row: number): GridRow {\n if (row >= this.rows.length) {\n this.addRows(-1, 1 + row - this.rows.length);\n }\n return this.rows[row];\n }\n\n /**\n * Sets a value in a cell at the specified row and column.\n * @param row The row index\n * @param col The column index\n * @param value The value to set\n * @param cellCreator Optional function to create a custom cell\n * @returns The previous value of the cell\n */\n setValue(row: number, col: number, value: any, cellCreator?: (row: GridRow, col: number) => GridCell): any {\n const grow = this.getRow(row);\n if (!cellCreator) {\n cellCreator = (row: GridRow, col: number) => {\n return new GridCell(row, col);\n };\n }\n if (value == null) {\n const out = grow.clearCellAt(col);\n if (out != null) {\n this.eventHub?.emit(GridCellEvent.CLEARED, this, {\n loc: out.location,\n });\n }\n return out;\n } else {\n const cell = grow.cellAt(col, cellCreator) as GridCell;\n const oldValue = cell.value;\n this.eventHub?.emit(GridCellEvent.UPDATED, this, {\n loc: cell.location,\n cell: cell,\n oldValue: cell.value,\n });\n cell.value = value;\n return oldValue;\n }\n }\n\n /**\n * Handles changes to the event hub.\n */\n protected eventHubChanged(): void {\n console.log(\"Event Hub Changed for GridModel\");\n }\n}\n\n/**\n * Interface for a view associated with a grid cell.\n * GridCellView defines the contract for views that can be placed in grid cells.\n */\nexport interface GridCellView {\n /** The grid cell this view is associated with */\n readonly cell: GridCell;\n /** X-coordinate of the view */\n x: number;\n /** Y-coordinate of the view */\n y: number;\n /** Width of the view */\n width: number;\n /** Height of the view */\n height: number;\n \n /**\n * Sets the bounds of the view.\n * @param x New x-coordinate, or null to keep current value\n * @param y New y-coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @param applyLayout Whether to apply layout immediately\n * @returns The new bounds values\n */\n setBounds(\n x: number | null,\n y: number | null,\n w: number | null,\n h: number | null,\n applyLayout: boolean,\n ): [number | null, number | null, number | null, number | null];\n \n /** Whether this view needs layout */\n readonly needsLayout: boolean;\n \n /** The minimum size this view requires */\n readonly minSize: TSU.Geom.Size;\n \n /** The bounding box of this view */\n readonly bbox: TSU.Geom.Rect;\n}\n\n/**\n * Enum defining the events that can occur on grid cells.\n */\nexport enum GridCellEvent {\n ADDED = \"CellAdded\",\n CLEARED = \"CellCleared\",\n REMOVED = \"CellRemoved\",\n UPDATED = \"CellUpdated\",\n MOVED = \"CellMoved\",\n}\n\n/**\n * Represents a cell in the grid.\n * GridCell holds a value and manages alignment with rows and columns.\n */\nexport class GridCell {\n private static idCounter = 0;\n readonly uuid = GridCell.idCounter++;\n /** The view associated with this cell */\n cellView: GridCellView | null;\n private _rowAlign: RowAlign;\n private _colAlign: ColAlign;\n\n /**\n * Creates a new GridCell.\n * @param gridRow The row this cell belongs to\n * @param colIndex The column index of this cell\n * @param value Optional initial value for the cell\n */\n constructor(public gridRow: GridRow, public colIndex: number, public value: any = null) {\n this.rowAlign = gridRow.defaultRowAlign;\n }\n\n /**\n * Gets the row alignment for this cell.\n */\n get rowAlign(): RowAlign {\n return this._rowAlign;\n }\n\n /**\n * Sets the row alignment for this cell.\n */\n set rowAlign(val: RowAlign) {\n val.addCell(this);\n this._rowAlign = val;\n }\n\n /**\n * Gets the column alignment for this cell.\n */\n get colAlign(): ColAlign {\n return this._colAlign;\n }\n\n /**\n * Sets the column alignment for this cell.\n */\n set colAlign(val: ColAlign) {\n val.addCell(this);\n this._colAlign = val;\n }\n\n /**\n * Gets the location string for this cell (rowIndex:colIndex).\n */\n get location(): string {\n return this.gridRow.rowIndex + \":\" + this.colIndex;\n }\n\n /**\n * Gets the grid this cell belongs to.\n */\n get grid(): GridModel {\n return this.gridRow.grid;\n }\n\n /**\n * Gets the row index of this cell.\n */\n get rowIndex(): number {\n return this.gridRow.rowIndex;\n }\n\n /**\n * Returns a debug-friendly representation of this GridCell.\n * @returns An object containing debug information\n */\n debugValue() {\n const out = {\n r: this.gridRow.rowIndex,\n c: this.colIndex,\n value: this.value,\n y: this.rowAlign.coordOffset,\n h: this.rowAlign.maxLength,\n } as any;\n if (this.colAlign) {\n out.x = this.colAlign.coordOffset;\n out.w = this.colAlign.maxLength;\n }\n return out;\n }\n}\n\n/**\n * Represents a row of grid cells in a GridModel.\n */\nexport class GridRow {\n /** The cells in this row */\n cells: (null | GridCell)[] = [];\n /** The default vertical alignment for all cells in this row */\n defaultRowAlign: RowAlign;\n\n /**\n * Creates a new GridRow.\n * @param grid The grid this row belongs to\n * @param rowIndex The index of this row\n */\n constructor(public grid: GridModel, public rowIndex: number) {\n this.defaultRowAlign = new RowAlign();\n this.grid.addRowAlign(this.defaultRowAlign);\n }\n\n /**\n * Gets the index of the first non-empty column in this row.\n */\n get firstCol() {\n for (let i = 0; i < this.cells.length; i++) {\n if (this.cells[i]?.value) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Gets the number of columns in this row.\n */\n get numCols() {\n return this.cells.length;\n }\n\n /**\n * Gets the number of cells that contain values.\n */\n get numCells() {\n let i = 0;\n for (const cell of this.cells) {\n if (cell != null && cell.value != null) i++;\n }\n return i;\n }\n\n /**\n * Gets the cell at the specified column index, optionally creating it if it doesn't exist.\n * @param col The column index\n * @param creator Optional function to create the cell if it doesn't exist\n * @returns The cell at the specified index, or null if it doesn't exist and no creator was provided\n */\n cellAt(col: number, creator?: (row: GridRow, col: number) => GridCell): GridCell | null {\n let out = this.cells[col] || null;\n if (!out && creator) {\n this.cells[col] = out = creator(this, col);\n out.gridRow = this;\n out.colIndex = col;\n if (out.rowAlign) {\n this.grid.addRowAlign(out.rowAlign);\n }\n if (out.colAlign) {\n this.grid.addColAlign(out.colAlign);\n }\n }\n return out;\n }\n\n /**\n * Clears the cell at the given column.\n * Note this is not the same as \"removing\" a cell.\n * Removing a cell would require all cells to the \"right\" to be shifted left.\n * @param col The column index\n * @returns The cell that was cleared, or null if none existed\n */\n clearCellAt(col: number): GridCell | null {\n const out = this.cells[col] || null;\n if (out) {\n this.cells[col] = null;\n }\n return out;\n }\n\n /**\n * Returns a debug-friendly representation of this GridRow.\n * @returns An object containing debug information\n */\n debugValue() {\n return {\n r: this.rowIndex,\n cells: this.cells.filter((c) => c).map((c) => c?.debugValue()),\n };\n }\n}\n\n/**\n * Base class for row and column alignment objects.\n * AlignedLine manages the alignment of cells along a line (row or column).\n */\nexport abstract class AlignedLine {\n private static idCounter = 0;\n readonly uuid = AlignedLine.idCounter++;\n /** Whether this line needs layout */\n needsLayout = false;\n /** The coordinate offset of this line */\n protected _coordOffset = 0;\n /** The maximum length of this line */\n protected _maxLength = 0;\n /** Padding before this line */\n paddingBefore = 5;\n /** Padding after this line */\n paddingAfter = 5;\n /** The cells that belong to this line */\n cells: GridCell[] = [];\n /** Function to get a view for a cell value */\n getCellView: (value: any) => GridCellView;\n\n /**\n * Sets the offset of this line.\n * @param val The new offset value\n */\n abstract setOffset(val: number): void;\n \n /**\n * Evaluates the maximum length required for this line.\n * @param changedCells Cells that have changed and need re-evaluation\n * @returns The maximum length\n */\n abstract evalMaxLength(changedCells: GridCell[]): number;\n\n /**\n * Gets the coordinate offset of this line.\n */\n get coordOffset(): number {\n return this._coordOffset;\n }\n\n /**\n * Gets the maximum length of this line, including padding.\n */\n get maxLength(): number {\n return this._maxLength + this.paddingBefore + this.paddingAfter;\n }\n\n /**\n * Sets the maximum length of this line.\n * @param length The new maximum length\n */\n setMaxLength(length: number) {\n this._maxLength = length;\n }\n\n /**\n * Sets the padding before and after this line.\n * @param before Padding before the line\n * @param after Padding after the line\n */\n setPadding(before: number, after: number): void {\n if (before >= 0) {\n this.paddingBefore = before;\n }\n if (after >= 0) {\n this.paddingAfter = after;\n }\n }\n\n /**\n * Adds a cell to this line.\n * @param cell The cell to add\n * @returns This line instance for method chaining\n */\n addCell(cell: GridCell): this {\n if (this.beforeAddingCell(cell)) {\n this.cells.push(cell);\n }\n return this;\n }\n\n /**\n * Called before adding a cell to perform validation or preparation.\n * @param cell The cell to be added\n * @returns Whether the cell should be added\n */\n protected abstract beforeAddingCell(cell: GridCell): boolean;\n\n /**\n * Removes a cell from this line.\n * @param cell The cell to remove\n * @returns This line instance for method chaining\n */\n removeCell(cell: GridCell): this {\n if (this.beforeRemovingCell(cell)) {\n for (let i = 0; i < this.cells.length; i++) {\n if (this.cells[i].uuid == cell.uuid) {\n this.cells.splice(i, 1);\n break;\n }\n }\n }\n return this;\n }\n\n /**\n * Called before removing a cell to perform validation.\n * @param cell The cell to be removed\n * @returns Whether the cell should be removed\n */\n protected abstract beforeRemovingCell(cell: GridCell): boolean;\n\n // The \"neighboring\" lines that depend on this line to be placed\n // before they are placed\n /** Lines that must be positioned before this line */\n prevLines = [] as this[];\n /** Lines that must be positioned after this line */\n nextLines = [] as this[];\n \n /**\n * Adds a successor line to this line.\n * @param next The line to add as a successor\n */\n addSuccessor(next: this): void {\n // Set nextCol as a successor of this col\n // TODO - Ensure no cycles\n for (const c of this.nextLines) {\n if (c == next) return;\n }\n this.nextLines.push(next);\n next.prevLines.push(this);\n }\n\n /* TODO: Disabling only to improve test coverage as this method is\n * not used.\n * When we have mutable grids where we can insert/remove neighbors\n * we can enable this again.\n */\n /*\n removeSuccessor(next: this): void {\n // Set nextCol as a successor of this col\n // TODO - Ensure no cycles\n for (let i = 0; i < this.nextLines.length; i++) {\n if (this.nextLines[i] == next) {\n this.nextLines.splice(i, 1);\n break;\n }\n }\n for (let i = 0; i < next.prevLines.length; i++) {\n if (next.prevLines[i] == this) {\n next.prevLines.splice(i, 1);\n break;\n }\n }\n }\n */\n}\n\n/**\n * Manages the alignment of cells in a column.\n */\nexport class ColAlign extends AlignedLine {\n paddingBefore = 10;\n /** Padding after this line */\n paddingAfter = 10;\n\n /**\n * Sets the offset of this column and updates all associated cells.\n * @param val The new offset value\n */\n setOffset(val: number): void {\n this._coordOffset = val;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n if (this._maxLength <= 0) {\n // this hasnt been evaluated yet so do it!\n this.evalMaxLength();\n }\n cellView.setBounds(val, null, this.maxLength, null, true);\n }\n }\n }\n\n /**\n * Evaluates the maximum width required for this column.\n * @param changedCells Cells that have changed and need re-evaluation\n * @returns The maximum width\n */\n evalMaxLength(changedCells: GridCell[] = []): number {\n this._maxLength = 0;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n this._maxLength = Math.max(cellView.minSize.width, this._maxLength);\n }\n }\n return this._maxLength;\n }\n\n /**\n * Called before adding a cell to perform validation or preparation.\n * @param cell The cell to be added\n * @returns Whether the cell should be added\n */\n protected beforeAddingCell(cell: GridCell): boolean {\n if (cell.colAlign && cell.colAlign != this) {\n cell.colAlign.removeCell(cell);\n }\n return cell.colAlign != this;\n }\n\n /**\n * Called before removing a cell to perform validation.\n * @param cell The cell to be removed\n * @returns Whether the cell should be removed\n */\n beforeRemovingCell(cell: GridCell): boolean {\n return cell.colAlign == this;\n }\n}\n\n/**\n * Manages the alignment of cells in a row.\n */\nexport class RowAlign extends AlignedLine {\n /**\n * Sets the Y coordinate of all cells in this row.\n * @param val The new Y coordinate\n */\n setOffset(val: number): void {\n this._coordOffset = val;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n if (this._maxLength <= 0) {\n // this hasnt been evaluated yet so do it!\n this.evalMaxLength();\n }\n cellView.setBounds(null, val, null, this.maxLength, true);\n }\n }\n }\n\n /**\n * Evaluates the maximum height required for this row.\n * @param changedCells Cells that have changed and need re-evaluation\n * @returns The maximum height\n */\n evalMaxLength(changedCells: GridCell[] = []): number {\n this._maxLength = 0;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n this._maxLength = Math.max(cellView.minSize.height, this._maxLength);\n }\n }\n return this._maxLength;\n }\n\n /**\n * Called before adding a cell to perform validation or preparation.\n * @param cell The cell to be added\n * @returns Whether the cell should be added\n */\n protected beforeAddingCell(cell: GridCell): boolean {\n if (cell.rowAlign && cell.rowAlign != this) {\n cell.rowAlign.removeCell(cell);\n }\n return cell.rowAlign != this;\n }\n\n /**\n * Called before removing a cell to perform validation.\n * @param cell The cell to be removed\n * @returns Whether the cell should be removed\n */\n beforeRemovingCell(cell: GridCell): boolean {\n return cell.rowAlign == this;\n }\n}\n\n/**\n * The layout manager for a collection of GridViews bound by common alignment objects.\n * Manages the layout of multiple grid models, ensuring proper alignment between them.\n */\nexport class GridLayoutGroup {\n // rowAligns = new Map<number, RowAlign>();\n // colAligns = new Map<number, ColAlign>();\n /** The grid models managed by this layout group */\n gridModels = [] as GridModel[];\n\n /**\n * Event handler for processing events from grid models.\n */\n private eventHandler = (event: TSU.Events.TEvent) => {\n this.applyModelEvents(event.payload);\n };\n\n /**\n * Adds a grid model to this layout group.\n * @param gridModel The grid model to add\n * @returns True if the model was added successfully\n */\n addGridModel(gridModel: GridModel): boolean {\n gridModel.eventHub?.on(TSU.Events.EventHub.BATCH_EVENTS, this.eventHandler);\n this.gridModels.push(gridModel);\n return true;\n }\n\n /**\n * Gets all row alignment objects that have no predecessors.\n * @returns An array of starting row alignments\n */\n startingRowAligns(): RowAlign[] {\n const out = [] as RowAlign[];\n const visited = {} as any;\n for (const gm of this.gridModels) {\n for (const cell of gm.cellsInRow(gm.firstRow)) {\n if (cell.rowAlign && !visited[cell.rowAlign.uuid]) {\n visited[cell.rowAlign.uuid] = true;\n out.push(cell.rowAlign);\n }\n }\n }\n return out;\n }\n\n /**\n * Gets all column alignment objects that have no predecessors.\n * @returns An array of starting column alignments\n */\n startingColAligns(): ColAlign[] {\n const out = [] as ColAlign[];\n const visited = {} as any;\n for (const gm of this.gridModels) {\n for (const cell of gm.cellsInCol(gm.firstCol)) {\n if (cell.colAlign && !visited[cell.colAlign.uuid]) {\n visited[cell.colAlign.uuid] = true;\n out.push(cell.colAlign);\n }\n }\n }\n return out;\n }\n\n /**\n * Removes a grid model from this layout group.\n * @param gridModel The grid model to remove\n */\n removeGridModel(gridModel: GridModel): void {\n gridModel.eventHub?.removeOn(TSU.Events.EventHub.BATCH_EVENTS, this.eventHandler);\n }\n\n /**\n * Function to get a view for a cell value.\n */\n getCellView: (cell: GridCell) => GridCellView;\n\n /**\n * Gets the starting row alignments.\n */\n get startingRows(): RowAlign[] {\n return this.startingRowAligns();\n }\n\n /**\n * Gets the starting column alignments.\n */\n get startingCols(): ColAlign[] {\n return this.startingColAligns();\n }\n\n /**\n * Forces a full refresh of the layout.\n * This recalculates all row and column sizes and positions.\n */\n refreshLayout() {\n const changedRowAligns = {} as any;\n const changedColAligns = {} as any;\n\n for (const rowAlign of this.startingRowAligns()) {\n if (!(rowAlign.uuid in changedRowAligns)) {\n changedRowAligns[rowAlign.uuid] = {\n align: rowAlign,\n cells: [],\n };\n }\n }\n\n for (const colAlign of this.startingColAligns()) {\n if (!(colAlign.uuid in changedColAligns)) {\n changedColAligns[colAlign.uuid] = {\n align: colAlign,\n cells: [],\n };\n }\n }\n\n this.doBfsLayout(this.startingRows, changedRowAligns);\n this.doBfsLayout(this.startingCols, changedColAligns);\n }\n\n /**\n * Applies model events to update the layout.\n * @param events The events to process\n */\n protected applyModelEvents(events: TSU.Events.TEvent[]) {\n // As the grid model changes (cell content changed, cleared etc) we need\n // to refresh our layout based on this.\n // As a first step the new height and width of all changed cells is\n // evaluted to see which rows and/or columns are affected (and need to be\n // resized/repositioned).\n const [changedRowAligns, changedColAligns] = this.changesForEvents(events);\n this.doBfsLayout(this.startingRows, changedRowAligns);\n this.doBfsLayout(this.startingCols, changedColAligns);\n }\n\n /**\n * Determines which rows and columns need to be updated based on events.\n * @param events The events to process\n * @returns A tuple containing the changed row and column alignments\n */\n protected changesForEvents(events: TSU.Events.TEvent[]): [any, any] {\n // Step 1 - topologically sort RowAligns of changed cells\n // Step 2 - topologically sort ColAligns of changed cells\n // Step 3 -\n const cellVisited = {} as any;\n const changedRowAligns = {} as any;\n const changedColAligns = {} as any;\n // Going in reverse means we only get the latest event affecting a cell\n // instead of going through every change.\n // Later on we can revisit this if the events are edge triggered instead\n // of level triggered\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n const loc = event.payload.loc;\n if (cellVisited[loc]) continue;\n cellVisited[loc] = true;\n const [row, col] = loc.split(\":\").map((x: string) => parseInt(x));\n const gridModel = event.source;\n const cell = gridModel.getRow(row).cellAt(col);\n if (cell) {\n // TODO - For now we are marking both row and col as having\n // changed for a cell. We can optimize this to only row or\n // col based on whether height or width has changed.\n if (!(cell.rowAlign.uuid in changedRowAligns)) {\n changedRowAligns[cell.rowAlign.uuid] = {\n align: cell.rowAlign,\n cells: [],\n };\n }\n changedRowAligns[cell.rowAlign.uuid][\"cells\"].push(cell);\n\n if (!(cell.colAlign.uuid in changedColAligns)) {\n changedColAligns[cell.colAlign.uuid] = {\n align: cell.colAlign,\n cells: [],\n };\n }\n changedColAligns[cell.colAlign.uuid][\"cells\"].push(cell);\n }\n }\n return [changedRowAligns, changedColAligns];\n }\n\n /**\n * Ensures that a cell view getter function is available for an alignment.\n * @param align The alignment to check\n * @returns The cell view getter function\n */\n protected ensureGetCellView(align: AlignedLine) {\n if (!align.getCellView) {\n if (!this.getCellView) {\n return null;\n }\n align.getCellView = this.getCellView;\n }\n return align.getCellView;\n }\n\n /**\n * Performs a breadth-first layout of aligned lines.\n * @param startingLines The lines to start from\n * @param changedAligns Map of alignment IDs to changed alignments\n */\n protected doBfsLayout<T extends AlignedLine>(startingLines: T[], changedAligns: any) {\n // 1. start from the starting lines and do a BF traversal\n // 2. If a line not visited (ie laid out):\n // if it is in the changedAlign list then reval its length (w/h)\n // set its offset and length if either width or offset has changed\n // offset can be thought of changed if the preceding line's offset has changed\n // first do above for rows\n if (!this.getCellView) return;\n for (const alignId in changedAligns) {\n const val = changedAligns[alignId];\n this.ensureGetCellView(val.align);\n val.align.evalMaxLength(val.cells);\n }\n let lineQueue = [] as [null | T, T][];\n const visitedLines = {} as any;\n for (const line of startingLines) lineQueue.push([null, line]);\n const lineOffsetChanged = {} as any;\n while (lineQueue.length > 0) {\n const nextQueue = [] as [null | T, T][];\n for (let i = 0; i < lineQueue.length; i++) {\n const [prevLineAlign, lineAlign] = lineQueue[i];\n visitedLines[lineAlign.uuid] = true;\n let newOffset = lineAlign.coordOffset;\n let lineChanged = lineAlign.uuid in changedAligns;\n if (prevLineAlign) {\n if (lineOffsetChanged[prevLineAlign.uuid]) {\n newOffset = prevLineAlign.coordOffset + prevLineAlign.maxLength;\n lineChanged = true;\n }\n }\n if (lineChanged) {\n this.ensureGetCellView(lineAlign);\n lineAlign.setOffset(newOffset);\n lineOffsetChanged[lineAlign.uuid] = true;\n }\n\n // Add next neighbors now\n for (const next of lineAlign.nextLines) {\n if (!visitedLines[next.uuid]) {\n nextQueue.push([lineAlign, next]);\n }\n }\n }\n lineQueue = nextQueue;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"grids.js","sourceRoot":"","sources":["../../src/grids.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\n// import * as kiwi from \"@lume/kiwi\";\n\n/**\n * A generic grid layout system for hosting child views (similar to GridBagLayout).\n * This provides a framework for hosting BeatViews in a structured grid arrangement,\n * with support for rows, columns, and alignment.\n *\n * Grid \"cells\" can be referred to by cell indexes. Additionally, grid rows and\n * columns can have names (like in spreadsheets) so that even when rows and columns\n * are inserted, though indexes may change, the \"addresses\" remain fixed and immovable.\n */\nexport class GridModel extends TSU.Events.EventEmitter {\n private static idCounter = 0;\n readonly uuid = GridModel.idCounter++;\n /** Timestamp of the last update to this grid */\n lastUpdatedAt = 0;\n // cells = new SparseArray<SparseArray<GridCell>>();\n /** The rows in this grid */\n rows: GridRow[] = [];\n /** Mapping of row indices to row alignment objects */\n rowAligns = new Map<number, RowAlign>();\n /** Mapping of column indices to column alignment objects */\n colAligns = new Map<number, ColAlign>();\n\n /**\n * Returns a debug-friendly representation of this GridModel.\n * @returns An object containing debug information\n */\n debugValue() {\n const out = {\n rows: this.rows.map((r) => r.debugValue()),\n lastUpdatedAt: this.lastUpdatedAt,\n } as any;\n return out;\n }\n\n /**\n * Gets the index of the first non-empty row.\n * @returns The index of the first row containing cells, or -1 if none\n */\n get firstRow(): number {\n for (const gr of this.rows) {\n if (gr.numCells > 0) return gr.rowIndex;\n }\n return -1;\n }\n\n /**\n * Gets the index of the leftmost column containing cells.\n * @returns The index of the first column containing cells, or -1 if none\n */\n get firstCol(): number {\n let minCol = -1;\n for (const gr of this.rows) {\n const fc = gr.firstCol;\n if (fc >= 0) {\n if (minCol < 0 || fc < minCol) {\n minCol = fc;\n }\n }\n }\n return minCol;\n }\n\n /**\n * Gets all non-empty cells in a specific row.\n * @param row The index of the row\n * @returns An array of cells in the row\n */\n cellsInRow(row: number): GridCell[] {\n const out = [] as GridCell[];\n const gr = this.rows[row];\n if (gr) {\n for (const cell of gr.cells) {\n if (cell?.value) out.push(cell);\n }\n }\n return out;\n }\n\n /**\n * Gets all non-empty cells in a specific column.\n * @param col The index of the column\n * @returns An array of cells in the column\n */\n cellsInCol(col: number): GridCell[] {\n const out = [] as GridCell[];\n for (const gr of this.rows) {\n const cell = gr.cellAt(col);\n if (cell?.value) out.push(cell);\n }\n return out;\n }\n\n /**\n * Adds a row alignment object to the grid.\n * @param align The row alignment to add\n */\n addRowAlign(align: RowAlign): void {\n this.rowAligns.set(align.uuid, align);\n }\n\n /**\n * Adds a column alignment object to the grid.\n * @param align The column alignment to add\n */\n addColAlign(align: ColAlign): void {\n this.colAligns.set(align.uuid, align);\n }\n\n /**\n * Adds rows to the grid.\n * @param insertBefore The index before which to insert the rows, or -1 to append\n * @param numRows The number of rows to add\n * @returns This grid instance for method chaining\n */\n addRows(insertBefore = -1, numRows = 1): this {\n if (insertBefore < 0) {\n insertBefore = this.rows.length;\n }\n let next = this.rows[insertBefore] || null;\n const prev = this.rows[insertBefore - 1] || null;\n for (let i = numRows - 1; i >= 0; i--) {\n const newRow = new GridRow(this, insertBefore + i);\n this.rows.splice(insertBefore, 0, newRow);\n if (next != null) {\n newRow.defaultRowAlign.addSuccessor(next.defaultRowAlign);\n }\n if (i == 0 && insertBefore > 0) {\n prev.defaultRowAlign.addSuccessor(newRow.defaultRowAlign);\n }\n next = newRow;\n }\n for (let i = insertBefore + numRows; i < this.rows.length; i++) {\n this.rows[i].rowIndex += numRows;\n }\n return this;\n }\n\n /**\n * Gets a row at the specified index, creating it if necessary.\n * @param row The index of the row to get\n * @returns The row at the specified index\n */\n getRow(row: number): GridRow {\n if (row >= this.rows.length) {\n this.addRows(-1, 1 + row - this.rows.length);\n }\n return this.rows[row];\n }\n\n /**\n * Sets a value in a cell at the specified row and column.\n * @param row The row index\n * @param col The column index\n * @param value The value to set\n * @param cellCreator Optional function to create a custom cell\n * @returns The previous value of the cell\n */\n setValue(row: number, col: number, value: any, cellCreator?: (row: GridRow, col: number) => GridCell): any {\n const grow = this.getRow(row);\n if (!cellCreator) {\n cellCreator = (row: GridRow, col: number) => {\n return new GridCell(row, col);\n };\n }\n if (value == null) {\n const out = grow.clearCellAt(col);\n if (out != null) {\n this.eventHub?.emit(GridCellEvent.CLEARED, this, {\n loc: out.location,\n });\n }\n return out;\n } else {\n const cell = grow.cellAt(col, cellCreator) as GridCell;\n const oldValue = cell.value;\n this.eventHub?.emit(GridCellEvent.UPDATED, this, {\n loc: cell.location,\n cell: cell,\n oldValue: cell.value,\n });\n cell.value = value;\n return oldValue;\n }\n }\n\n /**\n * Handles changes to the event hub.\n */\n protected eventHubChanged(): void {\n console.log(\"Event Hub Changed for GridModel\");\n }\n}\n\n/**\n * Interface for a view associated with a grid cell.\n * GridCellView defines the contract for views that can be placed in grid cells.\n */\nexport interface GridCellView {\n /** The grid cell this view is associated with */\n readonly cell: GridCell;\n /** X-coordinate of the view */\n x: number;\n /** Y-coordinate of the view */\n y: number;\n /** Width of the view */\n width: number;\n /** Height of the view */\n height: number;\n\n /**\n * Sets the bounds of the view.\n * @param x New x-coordinate, or null to keep current value\n * @param y New y-coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @param applyLayout Whether to apply layout immediately\n * @returns The new bounds values\n */\n setBounds(\n x: number | null,\n y: number | null,\n w: number | null,\n h: number | null,\n applyLayout: boolean,\n ): [number | null, number | null, number | null, number | null];\n\n /** Whether this view needs layout */\n readonly needsLayout: boolean;\n\n /** The minimum size this view requires */\n readonly minSize: TSU.Geom.Size;\n\n /** The bounding box of this view */\n readonly bbox: TSU.Geom.Rect;\n}\n\n/**\n * Enum defining the events that can occur on grid cells.\n */\nexport enum GridCellEvent {\n ADDED = \"CellAdded\",\n CLEARED = \"CellCleared\",\n REMOVED = \"CellRemoved\",\n UPDATED = \"CellUpdated\",\n MOVED = \"CellMoved\",\n}\n\n/**\n * Represents a cell in the grid.\n * GridCell holds a value and manages alignment with rows and columns.\n */\nexport class GridCell {\n private static idCounter = 0;\n readonly uuid = GridCell.idCounter++;\n /** The view associated with this cell */\n cellView: GridCellView | null;\n private _rowAlign: RowAlign;\n private _colAlign: ColAlign;\n\n /**\n * Creates a new GridCell.\n * @param gridRow The row this cell belongs to\n * @param colIndex The column index of this cell\n * @param value Optional initial value for the cell\n */\n constructor(\n public gridRow: GridRow,\n public colIndex: number,\n public value: any = null,\n ) {\n this.rowAlign = gridRow.defaultRowAlign;\n }\n\n /**\n * Gets the row alignment for this cell.\n */\n get rowAlign(): RowAlign {\n return this._rowAlign;\n }\n\n /**\n * Sets the row alignment for this cell.\n */\n set rowAlign(val: RowAlign) {\n val.addCell(this);\n this._rowAlign = val;\n }\n\n /**\n * Gets the column alignment for this cell.\n */\n get colAlign(): ColAlign {\n return this._colAlign;\n }\n\n /**\n * Sets the column alignment for this cell.\n */\n set colAlign(val: ColAlign) {\n val.addCell(this);\n this._colAlign = val;\n }\n\n /**\n * Gets the location string for this cell (rowIndex:colIndex).\n */\n get location(): string {\n return this.gridRow.rowIndex + \":\" + this.colIndex;\n }\n\n /**\n * Gets the grid this cell belongs to.\n */\n get grid(): GridModel {\n return this.gridRow.grid;\n }\n\n /**\n * Gets the row index of this cell.\n */\n get rowIndex(): number {\n return this.gridRow.rowIndex;\n }\n\n /**\n * Returns a debug-friendly representation of this GridCell.\n * @returns An object containing debug information\n */\n debugValue() {\n const out = {\n r: this.gridRow.rowIndex,\n c: this.colIndex,\n value: this.value,\n y: this.rowAlign.coordOffset,\n h: this.rowAlign.maxLength,\n } as any;\n if (this.colAlign) {\n out.x = this.colAlign.coordOffset;\n out.w = this.colAlign.maxLength;\n }\n return out;\n }\n}\n\n/**\n * Represents a row of grid cells in a GridModel.\n */\nexport class GridRow {\n /** The cells in this row */\n cells: (null | GridCell)[] = [];\n /** The default vertical alignment for all cells in this row */\n defaultRowAlign: RowAlign;\n\n /**\n * Creates a new GridRow.\n * @param grid The grid this row belongs to\n * @param rowIndex The index of this row\n */\n constructor(\n public grid: GridModel,\n public rowIndex: number,\n ) {\n this.defaultRowAlign = new RowAlign();\n this.grid.addRowAlign(this.defaultRowAlign);\n }\n\n /**\n * Gets the index of the first non-empty column in this row.\n */\n get firstCol() {\n for (let i = 0; i < this.cells.length; i++) {\n if (this.cells[i]?.value) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Gets the number of columns in this row.\n */\n get numCols() {\n return this.cells.length;\n }\n\n /**\n * Gets the number of cells that contain values.\n */\n get numCells() {\n let i = 0;\n for (const cell of this.cells) {\n if (cell != null && cell.value != null) i++;\n }\n return i;\n }\n\n /**\n * Gets the cell at the specified column index, optionally creating it if it doesn't exist.\n * @param col The column index\n * @param creator Optional function to create the cell if it doesn't exist\n * @returns The cell at the specified index, or null if it doesn't exist and no creator was provided\n */\n cellAt(col: number, creator?: (row: GridRow, col: number) => GridCell): GridCell | null {\n let out = this.cells[col] || null;\n if (!out && creator) {\n this.cells[col] = out = creator(this, col);\n out.gridRow = this;\n out.colIndex = col;\n if (out.rowAlign) {\n this.grid.addRowAlign(out.rowAlign);\n }\n if (out.colAlign) {\n this.grid.addColAlign(out.colAlign);\n }\n }\n return out;\n }\n\n /**\n * Clears the cell at the given column.\n * Note this is not the same as \"removing\" a cell.\n * Removing a cell would require all cells to the \"right\" to be shifted left.\n * @param col The column index\n * @returns The cell that was cleared, or null if none existed\n */\n clearCellAt(col: number): GridCell | null {\n const out = this.cells[col] || null;\n if (out) {\n this.cells[col] = null;\n }\n return out;\n }\n\n /**\n * Returns a debug-friendly representation of this GridRow.\n * @returns An object containing debug information\n */\n debugValue() {\n return {\n r: this.rowIndex,\n cells: this.cells.filter((c) => c).map((c) => c?.debugValue()),\n };\n }\n}\n\n/**\n * Base class for row and column alignment objects.\n * AlignedLine manages the alignment of cells along a line (row or column).\n */\nexport abstract class AlignedLine {\n private static idCounter = 0;\n readonly uuid = AlignedLine.idCounter++;\n /** Whether this line needs layout */\n needsLayout = false;\n /** The coordinate offset of this line */\n protected _coordOffset = 0;\n /** The maximum length of this line */\n protected _maxLength = 0;\n /** Padding before this line */\n paddingBefore = 5;\n /** Padding after this line */\n paddingAfter = 5;\n /** The cells that belong to this line */\n cells: GridCell[] = [];\n /** Function to get a view for a cell value */\n getCellView: (value: any) => GridCellView;\n\n /**\n * Sets the offset of this line.\n * @param val The new offset value\n */\n abstract setOffset(val: number): void;\n\n /**\n * Evaluates the maximum length required for this line.\n * @param changedCells Cells that have changed and need re-evaluation\n * @returns The maximum length\n */\n abstract evalMaxLength(changedCells: GridCell[]): number;\n\n /**\n * Gets the coordinate offset of this line.\n */\n get coordOffset(): number {\n return this._coordOffset;\n }\n\n /**\n * Gets the maximum length of this line, including padding.\n */\n get maxLength(): number {\n return this._maxLength + this.paddingBefore + this.paddingAfter;\n }\n\n /**\n * Sets the maximum length of this line.\n * @param length The new maximum length\n */\n setMaxLength(length: number) {\n this._maxLength = length;\n }\n\n /**\n * Sets the padding before and after this line.\n * @param before Padding before the line\n * @param after Padding after the line\n */\n setPadding(before: number, after: number): void {\n if (before >= 0) {\n this.paddingBefore = before;\n }\n if (after >= 0) {\n this.paddingAfter = after;\n }\n }\n\n /**\n * Adds a cell to this line.\n * @param cell The cell to add\n * @returns This line instance for method chaining\n */\n addCell(cell: GridCell): this {\n if (this.beforeAddingCell(cell)) {\n this.cells.push(cell);\n }\n return this;\n }\n\n /**\n * Called before adding a cell to perform validation or preparation.\n * @param cell The cell to be added\n * @returns Whether the cell should be added\n */\n protected abstract beforeAddingCell(cell: GridCell): boolean;\n\n /**\n * Removes a cell from this line.\n * @param cell The cell to remove\n * @returns This line instance for method chaining\n */\n removeCell(cell: GridCell): this {\n if (this.beforeRemovingCell(cell)) {\n for (let i = 0; i < this.cells.length; i++) {\n if (this.cells[i].uuid == cell.uuid) {\n this.cells.splice(i, 1);\n break;\n }\n }\n }\n return this;\n }\n\n /**\n * Called before removing a cell to perform validation.\n * @param cell The cell to be removed\n * @returns Whether the cell should be removed\n */\n protected abstract beforeRemovingCell(cell: GridCell): boolean;\n\n // The \"neighboring\" lines that depend on this line to be placed\n // before they are placed\n /** Lines that must be positioned before this line */\n prevLines = [] as this[];\n /** Lines that must be positioned after this line */\n nextLines = [] as this[];\n\n /**\n * Adds a successor line to this line.\n * @param next The line to add as a successor\n */\n addSuccessor(next: this): void {\n // Set nextCol as a successor of this col\n // TODO - Ensure no cycles\n for (const c of this.nextLines) {\n if (c == next) return;\n }\n this.nextLines.push(next);\n next.prevLines.push(this);\n }\n\n /* TODO: Disabling only to improve test coverage as this method is\n * not used.\n * When we have mutable grids where we can insert/remove neighbors\n * we can enable this again.\n */\n /*\n removeSuccessor(next: this): void {\n // Set nextCol as a successor of this col\n // TODO - Ensure no cycles\n for (let i = 0; i < this.nextLines.length; i++) {\n if (this.nextLines[i] == next) {\n this.nextLines.splice(i, 1);\n break;\n }\n }\n for (let i = 0; i < next.prevLines.length; i++) {\n if (next.prevLines[i] == this) {\n next.prevLines.splice(i, 1);\n break;\n }\n }\n }\n */\n}\n\n/**\n * Manages the alignment of cells in a column.\n */\nexport class ColAlign extends AlignedLine {\n paddingBefore = 10;\n /** Padding after this line */\n paddingAfter = 10;\n\n /**\n * Sets the offset of this column and updates all associated cells.\n * @param val The new offset value\n */\n setOffset(val: number): void {\n this._coordOffset = val;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n if (this._maxLength <= 0) {\n // this hasnt been evaluated yet so do it!\n this.evalMaxLength();\n }\n cellView.setBounds(val, null, this.maxLength, null, true);\n }\n }\n }\n\n /**\n * Evaluates the maximum width required for this column.\n * @param changedCells Cells that have changed and need re-evaluation\n * @returns The maximum width\n */\n evalMaxLength(changedCells: GridCell[] = []): number {\n this._maxLength = 0;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n this._maxLength = Math.max(cellView.minSize.width, this._maxLength);\n }\n }\n return this._maxLength;\n }\n\n /**\n * Called before adding a cell to perform validation or preparation.\n * @param cell The cell to be added\n * @returns Whether the cell should be added\n */\n protected beforeAddingCell(cell: GridCell): boolean {\n if (cell.colAlign && cell.colAlign != this) {\n cell.colAlign.removeCell(cell);\n }\n return cell.colAlign != this;\n }\n\n /**\n * Called before removing a cell to perform validation.\n * @param cell The cell to be removed\n * @returns Whether the cell should be removed\n */\n beforeRemovingCell(cell: GridCell): boolean {\n return cell.colAlign == this;\n }\n}\n\n/**\n * Manages the alignment of cells in a row.\n */\nexport class RowAlign extends AlignedLine {\n /**\n * Sets the Y coordinate of all cells in this row.\n * @param val The new Y coordinate\n */\n setOffset(val: number): void {\n this._coordOffset = val;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n if (this._maxLength <= 0) {\n // this hasnt been evaluated yet so do it!\n this.evalMaxLength();\n }\n cellView.setBounds(null, val, null, this.maxLength, true);\n }\n }\n }\n\n /**\n * Evaluates the maximum height required for this row.\n * @param changedCells Cells that have changed and need re-evaluation\n * @returns The maximum height\n */\n evalMaxLength(changedCells: GridCell[] = []): number {\n this._maxLength = 0;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n this._maxLength = Math.max(cellView.minSize.height, this._maxLength);\n }\n }\n return this._maxLength;\n }\n\n /**\n * Called before adding a cell to perform validation or preparation.\n * @param cell The cell to be added\n * @returns Whether the cell should be added\n */\n protected beforeAddingCell(cell: GridCell): boolean {\n if (cell.rowAlign && cell.rowAlign != this) {\n cell.rowAlign.removeCell(cell);\n }\n return cell.rowAlign != this;\n }\n\n /**\n * Called before removing a cell to perform validation.\n * @param cell The cell to be removed\n * @returns Whether the cell should be removed\n */\n beforeRemovingCell(cell: GridCell): boolean {\n return cell.rowAlign == this;\n }\n}\n\n/**\n * The layout manager for a collection of GridViews bound by common alignment objects.\n * Manages the layout of multiple grid models, ensuring proper alignment between them.\n */\nexport class GridLayoutGroup {\n // rowAligns = new Map<number, RowAlign>();\n // colAligns = new Map<number, ColAlign>();\n /** The grid models managed by this layout group */\n gridModels = [] as GridModel[];\n\n /**\n * Event handler for processing events from grid models.\n */\n private eventHandler = (event: TSU.Events.TEvent) => {\n this.applyModelEvents(event.payload);\n };\n\n /**\n * Adds a grid model to this layout group.\n * @param gridModel The grid model to add\n * @returns True if the model was added successfully\n */\n addGridModel(gridModel: GridModel): boolean {\n gridModel.eventHub?.on(TSU.Events.EventHub.BATCH_EVENTS, this.eventHandler);\n this.gridModels.push(gridModel);\n return true;\n }\n\n /**\n * Gets all row alignment objects that have no predecessors.\n * @returns An array of starting row alignments\n */\n startingRowAligns(): RowAlign[] {\n const out = [] as RowAlign[];\n const visited = {} as any;\n for (const gm of this.gridModels) {\n for (const cell of gm.cellsInRow(gm.firstRow)) {\n if (cell.rowAlign && !visited[cell.rowAlign.uuid]) {\n visited[cell.rowAlign.uuid] = true;\n out.push(cell.rowAlign);\n }\n }\n }\n return out;\n }\n\n /**\n * Gets all column alignment objects that have no predecessors.\n * @returns An array of starting column alignments\n */\n startingColAligns(): ColAlign[] {\n const out = [] as ColAlign[];\n const visited = {} as any;\n for (const gm of this.gridModels) {\n for (const cell of gm.cellsInCol(gm.firstCol)) {\n if (cell.colAlign && !visited[cell.colAlign.uuid]) {\n visited[cell.colAlign.uuid] = true;\n out.push(cell.colAlign);\n }\n }\n }\n return out;\n }\n\n /**\n * Removes a grid model from this layout group.\n * @param gridModel The grid model to remove\n */\n removeGridModel(gridModel: GridModel): void {\n gridModel.eventHub?.removeOn(TSU.Events.EventHub.BATCH_EVENTS, this.eventHandler);\n }\n\n /**\n * Function to get a view for a cell value.\n */\n getCellView: (cell: GridCell) => GridCellView;\n\n /**\n * Gets the starting row alignments.\n */\n get startingRows(): RowAlign[] {\n return this.startingRowAligns();\n }\n\n /**\n * Gets the starting column alignments.\n */\n get startingCols(): ColAlign[] {\n return this.startingColAligns();\n }\n\n /**\n * Forces a full refresh of the layout.\n * This recalculates all row and column sizes and positions.\n */\n refreshLayout() {\n const changedRowAligns = {} as any;\n const changedColAligns = {} as any;\n\n for (const rowAlign of this.startingRowAligns()) {\n if (!(rowAlign.uuid in changedRowAligns)) {\n changedRowAligns[rowAlign.uuid] = {\n align: rowAlign,\n cells: [],\n };\n }\n }\n\n for (const colAlign of this.startingColAligns()) {\n if (!(colAlign.uuid in changedColAligns)) {\n changedColAligns[colAlign.uuid] = {\n align: colAlign,\n cells: [],\n };\n }\n }\n\n this.doBfsLayout(this.startingRows, changedRowAligns);\n this.doBfsLayout(this.startingCols, changedColAligns);\n }\n\n /**\n * Applies model events to update the layout.\n * @param events The events to process\n */\n protected applyModelEvents(events: TSU.Events.TEvent[]) {\n // As the grid model changes (cell content changed, cleared etc) we need\n // to refresh our layout based on this.\n // As a first step the new height and width of all changed cells is\n // evaluted to see which rows and/or columns are affected (and need to be\n // resized/repositioned).\n const [changedRowAligns, changedColAligns] = this.changesForEvents(events);\n this.doBfsLayout(this.startingRows, changedRowAligns);\n this.doBfsLayout(this.startingCols, changedColAligns);\n }\n\n /**\n * Determines which rows and columns need to be updated based on events.\n * @param events The events to process\n * @returns A tuple containing the changed row and column alignments\n */\n protected changesForEvents(events: TSU.Events.TEvent[]): [any, any] {\n // Step 1 - topologically sort RowAligns of changed cells\n // Step 2 - topologically sort ColAligns of changed cells\n // Step 3 -\n const cellVisited = {} as any;\n const changedRowAligns = {} as any;\n const changedColAligns = {} as any;\n // Going in reverse means we only get the latest event affecting a cell\n // instead of going through every change.\n // Later on we can revisit this if the events are edge triggered instead\n // of level triggered\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n const loc = event.payload.loc;\n if (cellVisited[loc]) continue;\n cellVisited[loc] = true;\n const [row, col] = loc.split(\":\").map((x: string) => parseInt(x));\n const gridModel = event.source;\n const cell = gridModel.getRow(row).cellAt(col);\n if (cell) {\n // TODO - For now we are marking both row and col as having\n // changed for a cell. We can optimize this to only row or\n // col based on whether height or width has changed.\n if (!(cell.rowAlign.uuid in changedRowAligns)) {\n changedRowAligns[cell.rowAlign.uuid] = {\n align: cell.rowAlign,\n cells: [],\n };\n }\n changedRowAligns[cell.rowAlign.uuid][\"cells\"].push(cell);\n\n if (!(cell.colAlign.uuid in changedColAligns)) {\n changedColAligns[cell.colAlign.uuid] = {\n align: cell.colAlign,\n cells: [],\n };\n }\n changedColAligns[cell.colAlign.uuid][\"cells\"].push(cell);\n }\n }\n return [changedRowAligns, changedColAligns];\n }\n\n /**\n * Ensures that a cell view getter function is available for an alignment.\n * @param align The alignment to check\n * @returns The cell view getter function\n */\n protected ensureGetCellView(align: AlignedLine) {\n if (!align.getCellView) {\n if (!this.getCellView) {\n return null;\n }\n align.getCellView = this.getCellView;\n }\n return align.getCellView;\n }\n\n /**\n * Performs a breadth-first layout of aligned lines.\n * @param startingLines The lines to start from\n * @param changedAligns Map of alignment IDs to changed alignments\n */\n protected doBfsLayout<T extends AlignedLine>(startingLines: T[], changedAligns: any) {\n // 1. start from the starting lines and do a BF traversal\n // 2. If a line not visited (ie laid out):\n // if it is in the changedAlign list then reval its length (w/h)\n // set its offset and length if either width or offset has changed\n // offset can be thought of changed if the preceding line's offset has changed\n // first do above for rows\n if (!this.getCellView) return;\n for (const alignId in changedAligns) {\n const val = changedAligns[alignId];\n this.ensureGetCellView(val.align);\n val.align.evalMaxLength(val.cells);\n }\n let lineQueue = [] as [null | T, T][];\n const visitedLines = {} as any;\n for (const line of startingLines) lineQueue.push([null, line]);\n const lineOffsetChanged = {} as any;\n while (lineQueue.length > 0) {\n const nextQueue = [] as [null | T, T][];\n for (let i = 0; i < lineQueue.length; i++) {\n const [prevLineAlign, lineAlign] = lineQueue[i];\n visitedLines[lineAlign.uuid] = true;\n let newOffset = lineAlign.coordOffset;\n let lineChanged = lineAlign.uuid in changedAligns;\n if (prevLineAlign) {\n if (lineOffsetChanged[prevLineAlign.uuid]) {\n newOffset = prevLineAlign.coordOffset + prevLineAlign.maxLength;\n lineChanged = true;\n }\n }\n if (lineChanged) {\n this.ensureGetCellView(lineAlign);\n lineAlign.setOffset(newOffset);\n lineOffsetChanged[lineAlign.uuid] = true;\n }\n\n // Add next neighbors now\n for (const next of lineAlign.nextLines) {\n if (!visitedLines[next.uuid]) {\n nextQueue.push([lineAlign, next]);\n }\n }\n }\n lineQueue = nextQueue;\n }\n }\n}\n"]}