{"version":3,"sources":["../src/MidiNoteNumber.ts","../src/internal/utils.ts","../src/internal/refined/Literal.ts","../src/internal/MidiNoteNumber.ts","../src/internal/refined/Int.ts","../src/internal/PitchClass.ts","../src/internal/refined/NonNegative.ts","../src/internal/PitchInterval.ts","../src/internal/Semitones.ts","../src/internal/conversion.ts"],"sourcesContent":["export {\n  pcFromMnn as pc,\n  piBetweenMnn as pi,\n  stBetweenMnn as semitones,\n  mnnTransposeChecked as transposeChecked,\n  mnnTransposeClamped as transposeClamped,\n  mnnTransposeModded as transposeModded,\n} from \"./internal/conversion.js\";\nexport * from \"./internal/MidiNoteNumber.js\";\n","// mod(-3, 5) = 2\nexport const mod = (a: number, n: number) => ((a % n) + n) % n;\n","import { mod } from \"../utils.js\";\nimport { Int } from \"./Int.js\";\n\nexport type Negate<N extends number> = N extends 0\n  ? 0\n  : `${N}` extends `-${infer X extends number}`\n    ? X\n    : `-${N}` extends `${infer X extends number}`\n      ? X\n      : number;\n\nexport type RangedNat<\n  START extends number,\n  END extends number,\n  ARR extends unknown[] = [],\n  ACC extends number = never,\n> = ARR[\"length\"] extends END\n  ? ACC | START | END\n  : RangedNat<\n      START,\n      END,\n      [...ARR, 1],\n      ARR[START] extends undefined ? ACC : ACC | ARR[\"length\"]\n    >;\n\nexport const is =\n  <S extends number, E extends number>(start: S, end: E) =>\n  <T>(v: T): v is T & RangedNat<S, E> =>\n    Number.isSafeInteger(v) &&\n    start <= (v as unknown as number) &&\n    (v as unknown as number) <= end;\n\nexport const clamp =\n  <S extends number, E extends number>(start: S, end: E) =>\n  (v: Int): RangedNat<S, E> =>\n    v < start ? start : v > end ? end : (v as RangedNat<S, E>);\n\n// range:           [s,             e]\n// input:  -5 -4 -3 -2 -1  0  1  2  3  4  5\n// output:  1  2  3 -2 -1  0  1  2  3 -2 -1\nexport const modded =\n  <S extends number, E extends number>(start: S, end: E) =>\n  (v: Int): RangedNat<S, E> => {\n    const size = end - start + 1;\n    const zero = v - start;\n\n    const m = mod(zero, size);\n    return (m + start) as RangedNat<S, E>;\n  };\n\nexport const all = <S extends number, E extends number>(\n  start: S,\n  end: E,\n): readonly RangedNat<S, E>[] =>\n  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n  [...Array(end - start + 1)].map((_, i) => (start + i) as RangedNat<S, E>);\n\nexport const asInt = (v: RangedNat<number, number>) => v as Int;\n","import { Int } from \"./refined/Int.js\";\nimport { all, clamp, is, modded, RangedNat } from \"./refined/Literal.js\";\n\nconst min = 0;\nconst max = 127;\n\nexport type Shape = RangedNat<typeof min, typeof max>;\nexport const hasShape = is(min, max);\n\nexport interface MidiNoteNumberBrand {\n  readonly MidiNoteNumber: unique symbol;\n}\nexport type MidiNoteNumber = Shape & MidiNoteNumberBrand;\n\nexport const mark = (_v: Shape): _v is MidiNoteNumber => true;\nexport const markNum = (v: number): v is MidiNoteNumber => hasShape(v);\nexport const markUnknown = (v: unknown): v is MidiNoteNumber => hasShape(v);\n\nexport const from = (v: Shape) => v as MidiNoteNumber;\nexport const fromNum = (v: number) => (markNum(v) ? v : undefined);\nexport const fromIntClamp = (v: Int) => from(clamp(min, max)(v));\nexport const fromIntMod = (v: Int) => from(modded(min, max)(v));\nexport const fromUnknown = (v: unknown) => (markUnknown(v) ? v : undefined);\n\nconst const_ = <T extends Shape>(v: T) => v as T & MidiNoteNumber;\nexport const MIN = const_(min);\nexport const MAX = const_(max);\nexport const ALL: readonly MidiNoteNumber[] = all(min, max).map(const_);\n\n// TODO: other constants\nexport const C_1 = const_(0);\nexport const C4 = const_(60);\nexport const G9 = const_(127);\n","export interface IntBrand {\n  readonly Int: unique symbol;\n}\n\nexport type Int = number & IntBrand;\n\nexport const isInt = <T>(v: T): v is T & Int => Number.isInteger(v);\nexport const fromUnknown = <T>(v: T) => (isInt(v) ? v : undefined);\nexport const makeChecked = <T extends number>(v: T) => fromUnknown(v);\nexport const makeRound = <T extends number>(v: T) => Math.round(v) as T & Int;\nexport const makeTrunc = <T extends number>(v: T) => Math.trunc(v) as T & Int;\n\nexport const add = (a: Int, b: Int) => (a + b) as Int;\nexport const addChecked = (a: number, b: number) => makeChecked(a + b);\n\nexport const sub = (a: Int, b: Int) => (a - b) as Int;\nexport const subChecked = (a: number, b: number) => makeChecked(a - b);\n\nexport const mul = (a: Int, b: Int) => (a * b) as Int;\nexport const mulChecked = (a: number, b: number) => makeChecked(a * b);\nexport const mulRound = (a: number, b: number) => makeRound(a * b);\nexport const mulTrunc = (a: number, b: number) => makeTrunc(a * b);\n\nexport const divChecked = (a: number, b: number) => makeChecked(a * b);\nexport const divRound = (a: number, b: number) => makeRound(a * b);\nexport const divTrunc = (a: number, b: number) => makeTrunc(a * b);\n","import * as I from \"./refined/Int.js\";\nimport { all, asInt, clamp, is, modded, RangedNat } from \"./refined/Literal.js\";\n\nconst min = 0;\nconst max = 11;\nexport type Shape = RangedNat<typeof min, typeof max>;\nexport const hasShape = is(min, max);\n\nexport interface PitchClassBrand {\n  readonly PitchClass: unique symbol;\n}\n\n/**\n * Integer notation of pitch class\n *\n * @see {@link https://en.wikipedia.org/wiki/Pitch_class}\n */\nexport type PitchClass = Shape & PitchClassBrand;\n\nexport const mark = (_v: Shape): _v is PitchClass => true;\nexport const markNum = (v: number): v is PitchClass => hasShape(v);\nexport const markUnknown = (v: unknown): v is PitchClass => hasShape(v);\n\nexport const from = (v: Shape) => v as PitchClass;\nexport const fromNum = (v: number) => (markNum(v) ? v : undefined);\nexport const fromIntClamp = (v: I.Int) => from(clamp(min, max)(v));\nexport const fromIntMod = (v: I.Int) => from(modded(min, max)(v));\nexport const fromUnknown = (v: unknown) =>\n  is(min, max)(v) ? from(v) : undefined;\n\nconst const_ = <T extends Shape>(value: T) => value as T & PitchClass;\nexport const MIN = const_(min);\nexport const MAX = const_(max);\nexport const ALL: readonly PitchClass[] = all(min, max).map(const_);\n\nexport const invert = (v: PitchClass, index: Shape = 0) =>\n  fromIntMod(I.sub(asInt(index), asInt(v)));\n","export interface NonNegativeBrand {\n  readonly NonNegative: unique symbol;\n}\n\nexport type NonNegative = number & NonNegativeBrand;\n\nexport const isNonNegative = <T>(v: T): v is T & NonNegative =>\n  typeof v === \"number\" && v >= 0;\n\nexport function makeAbs<T extends number, N extends NonNegative>(\n  v: T,\n  edgeCases: { NaN: N },\n): (T & NonNegative) | N;\nexport function makeAbs<T extends number>(\n  v: T,\n  edgeCases?: { NaN?: never },\n): (T & NonNegative) | (0 & NonNegative);\nexport function makeAbs(v: number, edgeCases?: { NaN?: NonNegative }) {\n  const caseNaN = edgeCases?.NaN ?? (0 as 0 & NonNegative);\n\n  if (Number.isNaN(v)) {\n    return caseNaN;\n  } else {\n    return Math.abs(v);\n  }\n}\n","import type { Int } from \"./refined/Int.js\";\nimport * as I from \"./refined/Int.js\";\nimport { Negate, RangedNat } from \"./refined/Literal.js\";\nimport { makeAbs } from \"./refined/NonNegative.js\";\nimport { NonNegativeInt } from \"./refined/NonNegativeInt.js\";\n\ntype Shape = Int;\nexport const hasShape = I.isInt;\n\nexport interface PitchIntervalBrand {\n  readonly PitchInterval: unique symbol;\n}\n\n/**\n * Ordered pitch interval\n *\n * Number of semitones that separates one pitch from another, upward or downward.\n * @see {@link https://en.wikipedia.org/wiki/Pitch_interval#Ordered_Pitch_Interval}\n */\nexport type PitchInterval = Shape & PitchIntervalBrand;\n\nexport const mark = (_v: Int): _v is PitchInterval => true;\nexport const markNum = (v: number): v is PitchInterval => hasShape(v);\nexport const markUnknown = (v: unknown): v is PitchInterval => hasShape(v);\n\ntype PartialPositivePitchInterval = RangedNat<1, 999>;\ntype PartialPitchInterval =\n  | PartialPositivePitchInterval\n  | 0\n  | Negate<PartialPositivePitchInterval>;\n\nexport const from = (v: Shape | PartialPitchInterval) => v as PitchInterval;\nexport const fromNum = (v: number) => (markNum(v) ? v : undefined);\nexport const fromNumRound = (v: number) => from(I.makeRound(v));\nexport const fromNumTrunc = (v: number) => from(I.makeTrunc(v));\nexport const fromUnknown = (v: unknown) => (markUnknown(v) ? v : undefined);\n\nconst fromUndefinedable = (v?: Int | undefined) => (v != null ? from(v) : v);\n\n// operators\nexport const add = (a: PitchInterval, b: PitchInterval) => from(I.add(a, b));\nexport const addChecked = (a: PitchInterval, b: PitchInterval) =>\n  fromUndefinedable(I.addChecked(a, b));\n\nexport const sub = (a: PitchInterval, b: PitchInterval) => from(I.sub(a, b));\nexport const subChecked = (a: PitchInterval, b: PitchInterval) =>\n  fromUndefinedable(I.subChecked(a, b));\n\nexport const mul = (a: PitchInterval, b: Int) => from(I.mul(a, b));\nexport const mulChecked = (a: PitchInterval, b: PitchInterval) =>\n  fromUndefinedable(I.mulChecked(a, b));\nexport const mulRound = (a: PitchInterval, b: number) => from(I.mulRound(a, b));\nexport const mulTrunc = (a: PitchInterval, b: number) => from(I.mulTrunc(a, b));\n\nexport const divChecked = (a: PitchInterval, b: PitchInterval) =>\n  fromUndefinedable(I.divChecked(a, b));\nexport const divRound = (a: PitchInterval, b: number) => from(I.divRound(a, b));\nexport const divTrunc = (a: PitchInterval, b: number) => from(I.divTrunc(a, b));\n\nexport const octaves = (pi: PitchInterval): NonNegativeInt =>\n  pi === 0\n    ? (0 as NonNegativeInt)\n    : (makeAbs(I.makeTrunc(pi / 12)) as NonNegativeInt);\nexport const direction = (pi: PitchInterval) => (pi < 0 ? -1 : pi > 0 ? 1 : 0);\n","import * as I from \"./refined/Int.js\";\nimport { RangedNat } from \"./refined/Literal.js\";\nimport { makeAbs } from \"./refined/NonNegative.js\";\nimport { isNonNegativeInt, NonNegativeInt } from \"./refined/NonNegativeInt.js\";\n\ntype Shape = NonNegativeInt;\nexport const hasShape = isNonNegativeInt;\n\nexport interface SemitonesBrand {\n  readonly Semitones: unique symbol;\n}\n\n/**\n * Unordered pitch interval\n *\n * Number of semitones that separates one pitch from another.\n * @see {@link https://en.wikipedia.org/wiki/Pitch_interval#Unordered_Pitch_Interval}\n */\nexport type Semitones = NonNegativeInt & SemitonesBrand;\n\nexport const mark = (_v: Shape): _v is Semitones => true;\nexport const markNum = (v: number): v is Semitones => hasShape(v);\nexport const markUnknown = (v: unknown): v is Semitones => hasShape(v);\n\nexport const from = (v: Shape | RangedNat<0, 999>) => v as Semitones;\nexport const fromNum = (v: number) => (markNum(v) ? v : undefined);\nexport const fromIntAbs = (v: I.Int) => from(makeAbs(v) as NonNegativeInt);\nexport const fromUnknown = (v: unknown) => (markUnknown(v) ? v : undefined);\n\nconst const_ = <T>(v: T) => v as T & Semitones;\nexport const MIN = const_(0);\n\nexport const octaves = (st: Semitones) =>\n  st === 0 ? (0 as NonNegativeInt) : (I.makeTrunc(st / 12) as NonNegativeInt);\n","import * as IC from \"./IntervalClass.js\";\nimport * as MNN from \"./MidiNoteNumber.js\";\nimport * as PC from \"./PitchClass.js\";\nimport * as PI from \"./PitchInterval.js\";\nimport * as PIC from \"./PitchIntervalClass.js\";\nimport * as I from \"./refined/Int.js\";\nimport { asInt } from \"./refined/Literal.js\";\nimport * as ST from \"./Semitones.js\";\n\nexport const icFromPic = (pic: PIC.PitchIntervalClass) =>\n  Math.min(pic, PIC.invert(pic)) as IC.IntervalClass;\nexport const icBetweenPc = (a: PC.PitchClass, b: PC.PitchClass) =>\n  icFromPic(picBetweenPc(a, b));\n\nconst mnnAdd = (value: MNN.MidiNoteNumber, interval: PI.PitchInterval) =>\n  I.add(asInt(value), asInt(interval));\nexport const mnnTransposeChecked = (\n  value: MNN.MidiNoteNumber,\n  interval: PI.PitchInterval,\n) => MNN.fromNum(mnnAdd(value, interval));\nexport const mnnTransposeClamped = (\n  value: MNN.MidiNoteNumber,\n  interval: PI.PitchInterval,\n) => MNN.fromIntClamp(mnnAdd(value, interval));\nexport const mnnTransposeModded = (\n  value: MNN.MidiNoteNumber,\n  interval: PI.PitchInterval,\n) => MNN.fromIntMod(mnnAdd(value, interval));\n\nexport const pcTranspose = (\n  value: PC.PitchClass,\n  interval: PIC.PitchIntervalClass,\n) => PC.fromIntMod(I.add(asInt(value), asInt(interval)));\nexport const pcFromMnn = (mnn: MNN.MidiNoteNumber) => PC.fromIntMod(asInt(mnn));\n\nexport const piBetweenMnn = (\n  from: MNN.MidiNoteNumber,\n  to: MNN.MidiNoteNumber,\n) => PI.from(I.sub(asInt(to), asInt(from)));\n\nexport const picBetweenPc = (from: PC.PitchClass, to: PC.PitchClass) =>\n  PIC.fromIntMod(I.sub(asInt(to), asInt(from)));\n\n/**\n * Gets the pitch interval class of the pitch interval.\n *\n * @example\n * ```ts\n * import * as PI from \"brand-music/PitchInterval\";\n * import * as PIC from \"brand-music/PitchIntervalClass\";\n *\n * const picOfPi = PIC.fromPi(PI.from(-2)); // 10\n * const picOfSemitones = PIC.fromSemitones(PI.semitones(PI.from(-2))); // 2\n * ```\n */\nexport const picFromPi = (pi: PI.PitchInterval) => PIC.fromIntMod(pi);\nexport const picFromSemitones = (semitones: ST.Semitones) =>\n  PIC.fromIntMod(semitones);\n\nexport const stFromPi = (pi: PI.PitchInterval) => ST.fromIntAbs(pi);\nexport const stBetweenMnn = (a: MNN.MidiNoteNumber, b: MNN.MidiNoteNumber) =>\n  ST.fromIntAbs(I.sub(asInt(a), asInt(b)));\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,0BAAA;AAAA,SAAAA,yBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAAAA;;;ACCO,IAAM,MAAM,CAAC,GAAW,OAAgB,IAAI,IAAK,KAAK;;;ACwBtD,IAAM,KACX,CAAqC,OAAU,QAC/C,CAAI,MACF,OAAO,cAAc,CAAC,KACtB,SAAU,KACT,KAA2B;AAEzB,IAAM,QACX,CAAqC,OAAU,QAC/C,CAAC,MACC,IAAI,QAAQ,QAAQ,IAAI,MAAM,MAAO;AAKlC,IAAM,SACX,CAAqC,OAAU,QAC/C,CAAC,MAA4B;AAC3B,QAAM,OAAO,MAAM,QAAQ;AAC3B,QAAM,OAAO,IAAI;AAEjB,QAAM,IAAI,IAAI,MAAM,IAAI;AACxB,SAAQ,IAAI;AACd;AAEK,IAAM,MAAM,CACjB,OACA;AAAA;AAAA,EAGA,CAAC,GAAG,MAAM,MAAM,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,MAAO,QAAQ,CAAqB;AAAA;AAEnE,IAAM,QAAQ,CAAC,MAAiC;;;ACtDvD,IAAM,MAAM;AACZ,IAAM,MAAM;AAGL,IAAM,WAAW,GAAG,KAAK,GAAG;AAO5B,IAAM,OAAO,CAAC,OAAoC;AAClD,IAAM,UAAU,CAAC,MAAmC,SAAS,CAAC;AAC9D,IAAM,cAAc,CAAC,MAAoC,SAAS,CAAC;AAEnE,IAAM,OAAO,CAAC,MAAa;AAC3B,IAAM,UAAU,CAAC,MAAe,QAAQ,CAAC,IAAI,IAAI;AACjD,IAAM,eAAe,CAAC,MAAW,KAAK,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC;AACxD,IAAM,aAAa,CAAC,MAAW,KAAK,OAAO,KAAK,GAAG,EAAE,CAAC,CAAC;AACvD,IAAM,cAAc,CAAC,MAAgB,YAAY,CAAC,IAAI,IAAI;AAEjE,IAAM,SAAS,CAAkB,MAAS;AACnC,IAAM,MAAM,OAAO,GAAG;AACtB,IAAM,MAAM,OAAO,GAAG;AACtB,IAAM,MAAiC,IAAI,KAAK,GAAG,EAAE,IAAI,MAAM;AAG/D,IAAM,MAAM,OAAO,CAAC;AACpB,IAAM,KAAK,OAAO,EAAE;AACpB,IAAM,KAAK,OAAO,GAAG;;;ACpBrB,IAAM,MAAM,CAAC,GAAQ,MAAY,IAAI;AAGrC,IAAM,MAAM,CAAC,GAAQ,MAAY,IAAI;;;ACZ5C,IAAMC,OAAM;AACZ,IAAMC,OAAM;AAEL,IAAMC,YAAW,GAAGF,MAAKC,IAAG;AAiB5B,IAAME,QAAO,CAAC,MAAa;AAG3B,IAAMC,cAAa,CAAC,MAAaC,MAAK,OAAOC,MAAKC,IAAG,EAAE,CAAC,CAAC;AAIhE,IAAMC,UAAS,CAAkB,UAAa;AACvC,IAAMC,OAAMD,QAAOE,IAAG;AACtB,IAAMC,OAAMH,QAAOI,IAAG;AACtB,IAAMC,OAA6B,IAAIH,MAAKE,IAAG,EAAE,IAAIJ,OAAM;;;AChB3D,SAAS,QAAQ,GAAW,WAAmC;AACpE,QAAM,UAAU,WAAW,OAAQ;AAEnC,MAAI,OAAO,MAAM,CAAC,GAAG;AACnB,WAAO;AAAA,EACT,OAAO;AACL,WAAO,KAAK,IAAI,CAAC;AAAA,EACnB;AACF;;;ACMO,IAAMM,QAAO,CAAC,MAAoC;;;ACPlD,IAAMC,QAAO,CAAC,MAAiC;AAE/C,IAAM,aAAa,CAAC,MAAaC,MAAK,QAAQ,CAAC,CAAmB;AAGzE,IAAMC,UAAS,CAAI,MAAS;AACrB,IAAMC,OAAMD,QAAO,CAAC;;;AChB3B,IAAM,SAAS,CAAC,OAA2B,aACvC,IAAI,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC;AAC9B,IAAM,sBAAsB,CACjC,OACA,aACO,QAAQ,OAAO,OAAO,QAAQ,CAAC;AACjC,IAAM,sBAAsB,CACjC,OACA,aACO,aAAa,OAAO,OAAO,QAAQ,CAAC;AACtC,IAAM,qBAAqB,CAChC,OACA,aACO,WAAW,OAAO,OAAO,QAAQ,CAAC;AAMpC,IAAM,YAAY,CAAC,QAA+BE,YAAW,MAAM,GAAG,CAAC;AAEvE,IAAM,eAAe,CAC1BC,OACA,OACMA,MAAO,IAAI,MAAM,EAAE,GAAG,MAAMA,KAAI,CAAC,CAAC;AAsBnC,IAAM,eAAe,CAAC,GAAuB,MAC/C,WAAa,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;","names":["MidiNoteNumber_exports","min","max","hasShape","from","fromIntMod","from","min","max","const_","MIN","min","MAX","max","ALL","from","from","from","const_","MIN","fromIntMod","from"]}