{"version":3,"sources":["../src/PitchInterval.ts","../src/internal/utils.ts","../src/internal/refined/Literal.ts","../src/internal/refined/Int.ts","../src/internal/refined/NonNegative.ts","../src/internal/PitchInterval.ts","../src/internal/PitchIntervalClass.ts","../src/internal/Semitones.ts","../src/internal/conversion.ts"],"sourcesContent":["export {\n  piBetweenMnn as between,\n  picFromPi as pic,\n  stFromPi as semitones,\n} from \"./internal/conversion.js\";\nexport * from \"./internal/PitchInterval.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","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","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 { 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 PitchIntervalClassBrand {\n  readonly PitchIntervalClass: unique symbol;\n}\n\n/**\n * Ordered pitch-class interval\n *\n * Number of ascending semitones from one pitch-class to the next, ordered from lowest to highest\n * @see {@link https://en.wikipedia.org/wiki/Pitch_interval#Ordered_pitch-class_intervals_('pitch_interval_class;_PIC')}\n */\nexport type PitchIntervalClass = Shape & PitchIntervalClassBrand;\n\nexport const mark = (_v: Shape): _v is PitchIntervalClass => true;\nexport const markNum = (v: number): v is PitchIntervalClass => hasShape(v);\nexport const markUnknown = (v: unknown): v is PitchIntervalClass => hasShape(v);\n\nexport const from = (v: Shape) => v as PitchIntervalClass;\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) => (markUnknown(v) ? v : undefined);\n\nconst const_ = <T extends Shape>(value: T) => value as T & PitchIntervalClass;\nexport const MIN = const_(min);\nexport const MAX = const_(max);\nexport const ALL: readonly PitchIntervalClass[] = all(min, max).map(const_);\n\nexport const invert = (v: PitchIntervalClass, index: Shape = 0) =>\n  fromIntMod(I.sub(asInt(index), asInt(v)));\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":"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","names":["PitchInterval_exports","add","addChecked","divChecked","divRound","divTrunc","fromUnknown","mul","mulChecked","mulRound","mulTrunc","sub","subChecked","fromUnknown","add","addChecked","sub","subChecked","mul","mulChecked","mulRound","mulTrunc","divChecked","divRound","divTrunc","hasShape","from","from","from","from","const_","MIN","from"]}