Function bodies 245 total
PopoverTitle function · typescript · L58-L66 (9 LOC)src/components/ui/popover.tsx
function PopoverTitle({ className, ...props }: React.ComponentProps<"h2">) {
return (
<div
data-slot="popover-title"
className={cn("font-medium", className)}
{...props}
/>
)
}PopoverDescription function · typescript · L68-L79 (12 LOC)src/components/ui/popover.tsx
function PopoverDescription({
className,
...props
}: React.ComponentProps<"p">) {
return (
<p
data-slot="popover-description"
className={cn("text-muted-foreground", className)}
{...props}
/>
)
}ScrollArea function · typescript · L8-L29 (22 LOC)src/components/ui/scroll-area.tsx
function ScrollArea({
className,
children,
...props
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
return (
<ScrollAreaPrimitive.Root
data-slot="scroll-area"
className={cn("relative", className)}
{...props}
>
<ScrollAreaPrimitive.Viewport
data-slot="scroll-area-viewport"
className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
>
{children}
</ScrollAreaPrimitive.Viewport>
<ScrollBar />
<ScrollAreaPrimitive.Corner />
</ScrollAreaPrimitive.Root>
)
}ScrollBar function · typescript · L31-L56 (26 LOC)src/components/ui/scroll-area.tsx
function ScrollBar({
className,
orientation = "vertical",
...props
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
return (
<ScrollAreaPrimitive.ScrollAreaScrollbar
data-slot="scroll-area-scrollbar"
orientation={orientation}
className={cn(
"flex touch-none p-px transition-colors select-none",
orientation === "vertical" &&
"h-full w-2.5 border-l border-l-transparent",
orientation === "horizontal" &&
"h-2.5 flex-col border-t border-t-transparent",
className
)}
{...props}
>
<ScrollAreaPrimitive.ScrollAreaThumb
data-slot="scroll-area-thumb"
className="bg-border relative flex-1 rounded-full"
/>
</ScrollAreaPrimitive.ScrollAreaScrollbar>
)
}Separator function · typescript · L8-L26 (19 LOC)src/components/ui/separator.tsx
function Separator({
className,
orientation = "horizontal",
decorative = true,
...props
}: React.ComponentProps<typeof SeparatorPrimitive.Root>) {
return (
<SeparatorPrimitive.Root
data-slot="separator"
decorative={decorative}
orientation={orientation}
className={cn(
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
className
)}
{...props}
/>
)
}Slider function · typescript · L8-L61 (54 LOC)src/components/ui/slider.tsx
function Slider({
className,
defaultValue,
value,
min = 0,
max = 100,
...props
}: React.ComponentProps<typeof SliderPrimitive.Root>) {
const _values = React.useMemo(
() =>
Array.isArray(value)
? value
: Array.isArray(defaultValue)
? defaultValue
: [min, max],
[value, defaultValue, min, max]
)
return (
<SliderPrimitive.Root
data-slot="slider"
defaultValue={defaultValue}
value={value}
min={min}
max={max}
className={cn(
"relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
className
)}
{...props}
>
<SliderPrimitive.Track
data-slot="slider-track"
className={cn(
"bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1Tabs function · typescript · L9-L26 (18 LOC)src/components/ui/tabs.tsx
function Tabs({
className,
orientation = "horizontal",
...props
}: React.ComponentProps<typeof TabsPrimitive.Root>) {
return (
<TabsPrimitive.Root
data-slot="tabs"
data-orientation={orientation}
orientation={orientation}
className={cn(
"group/tabs flex gap-2 data-[orientation=horizontal]:flex-col",
className
)}
{...props}
/>
)
}Repobility · code-quality intelligence · https://repobility.com
TabsList function · typescript · L43-L57 (15 LOC)src/components/ui/tabs.tsx
function TabsList({
className,
variant = "default",
...props
}: React.ComponentProps<typeof TabsPrimitive.List> &
VariantProps<typeof tabsListVariants>) {
return (
<TabsPrimitive.List
data-slot="tabs-list"
data-variant={variant}
className={cn(tabsListVariants({ variant }), className)}
{...props}
/>
)
}TabsTrigger function · typescript · L59-L76 (18 LOC)src/components/ui/tabs.tsx
function TabsTrigger({
className,
...props
}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
return (
<TabsPrimitive.Trigger
data-slot="tabs-trigger"
className={cn(
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring text-foreground/60 hover:text-foreground dark:text-muted-foreground dark:hover:text-foreground relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm group-data-[variant=line]/tabs-list:data-[state=active]:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
"group-data-[TabsContent function · typescript · L78-L89 (12 LOC)src/components/ui/tabs.tsx
function TabsContent({
className,
...props
}: React.ComponentProps<typeof TabsPrimitive.Content>) {
return (
<TabsPrimitive.Content
data-slot="tabs-content"
className={cn("flex-1 outline-none", className)}
{...props}
/>
)
}midiToNote function · typescript · L16-L18 (3 LOC)src/lib/ai/build-system-prompt.ts
function midiToNote(midi: number): string {
return `${NOTE_NAMES[midi % 12]}${Math.floor(midi / 12) - 1}`;
}buildRecordingSystemPrompt function · typescript · L20-L106 (87 LOC)src/lib/ai/build-system-prompt.ts
export function buildRecordingSystemPrompt(analysis: Analysis): string {
if (!analysis) {
return "You are a music theory expert. The recording has not been analyzed yet. Let the user know they need to run the analysis first.";
}
// Top chords by frequency
const chordCounts = new Map<string, number>();
for (const c of analysis.chords) {
chordCounts.set(c.chord, (chordCounts.get(c.chord) || 0) + 1);
}
const sortedChords = [...chordCounts.entries()]
.sort((a, b) => b[1] - a[1])
.slice(0, 15);
// Chord progression (limited to first 30 to avoid token waste)
const chordProgression = analysis.chords
.slice(0, 30)
.map((c) => c.chord)
.join(" | ");
const progressionSuffix = analysis.chords.length > 30
? ` ... (${analysis.chords.length - 30} more chord changes)`
: "";
// Note range
const midiValues = analysis.notes.map((n) => n.midi);
const minNote = midiValues.length > 0 ? midiToNote(Math.min(...midiValues)) : "N/A";
const maxNbuildCompareSystemPrompt function · typescript · L108-L177 (70 LOC)src/lib/ai/build-system-prompt.ts
export function buildCompareSystemPrompt(
titleA: string,
analysisA: Analysis,
titleB: string,
analysisB: Analysis
): string {
function summarizeAnalysis(title: string, a: Analysis): string {
const chordCounts = new Map<string, number>();
for (const c of a.chords) {
chordCounts.set(c.chord, (chordCounts.get(c.chord) || 0) + 1);
}
const topChords = [...chordCounts.entries()]
.sort((a, b) => b[1] - a[1])
.slice(0, 12);
const progression = a.chords
.slice(0, 25)
.map((c) => c.chord)
.join(" | ");
const midiValues = a.notes.map((n) => n.midi);
const minNote = midiValues.length > 0 ? midiToNote(Math.min(...midiValues)) : "N/A";
const maxNote = midiValues.length > 0 ? midiToNote(Math.max(...midiValues)) : "N/A";
const melodySummary = a.melody && a.melody.length > 0
? a.melody.slice(0, 15).map((n) => midiToNote(n.midi)).join(" ")
: "Not extracted";
const bassSummary = a.bass_line && a.bass_lisummarizeAnalysis function · typescript · L114-L155 (42 LOC)src/lib/ai/build-system-prompt.ts
function summarizeAnalysis(title: string, a: Analysis): string {
const chordCounts = new Map<string, number>();
for (const c of a.chords) {
chordCounts.set(c.chord, (chordCounts.get(c.chord) || 0) + 1);
}
const topChords = [...chordCounts.entries()]
.sort((a, b) => b[1] - a[1])
.slice(0, 12);
const progression = a.chords
.slice(0, 25)
.map((c) => c.chord)
.join(" | ");
const midiValues = a.notes.map((n) => n.midi);
const minNote = midiValues.length > 0 ? midiToNote(Math.min(...midiValues)) : "N/A";
const maxNote = midiValues.length > 0 ? midiToNote(Math.max(...midiValues)) : "N/A";
const melodySummary = a.melody && a.melody.length > 0
? a.melody.slice(0, 15).map((n) => midiToNote(n.midi)).join(" ")
: "Not extracted";
const bassSummary = a.bass_line && a.bass_line.length > 0
? a.bass_line.slice(0, 10).map((n) => NOTE_NAMES[n.midi % 12]).join(" ")
: "Not extracted";
const progrebuildInsightsSystemPrompt function · typescript · L179-L209 (31 LOC)src/lib/ai/build-system-prompt.ts
export function buildInsightsSystemPrompt(
analyses: { recording_title: string; key_signature: string | null; tempo: number | null; chords: { chord: string }[] }[]
): string {
const keyDistribution = new Map<string, number>();
const allChords = new Map<string, number>();
for (const a of analyses) {
if (a.key_signature) {
keyDistribution.set(a.key_signature, (keyDistribution.get(a.key_signature) || 0) + 1);
}
for (const c of a.chords) {
allChords.set(c.chord, (allChords.get(c.chord) || 0) + 1);
}
}
const topKeys = [...keyDistribution.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10);
const topChords = [...allChords.entries()].sort((a, b) => b[1] - a[1]).slice(0, 20);
return `You are a music theory expert and composition coach analyzing a library of ${analyses.length} piano voice memos recorded over several years.
**Key Distribution:**
${topKeys.map(([key, count]) => `- ${key}: ${count} recordings`).join("\n")}
**Most Used Chords:**
${toHi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
findCommonProgressions function · typescript · L9-L12 (4 LOC)src/lib/analysis/cross-recording.ts
export function findCommonProgressions(
analyses: RecordingAnalysis[],
minLength: number = 3
): { progression: string[]; count: number; recordings: string[] }[] {findSimilarRecordings function · typescript · L42-L44 (3 LOC)src/lib/analysis/cross-recording.ts
export function findSimilarRecordings(
analyses: RecordingAnalysis[]
): { pair: [string, string]; similarity: number; reasons: string[] }[] {getKeyDistribution function · typescript · L94-L96 (3 LOC)src/lib/analysis/cross-recording.ts
export function getKeyDistribution(
analyses: RecordingAnalysis[]
): { key: string; count: number }[] {getHarmonicTendencies function · typescript · L108-L110 (3 LOC)src/lib/analysis/cross-recording.ts
export function getHarmonicTendencies(
analyses: RecordingAnalysis[]
): { tendencies: string[]; dominantStyle: string } {getChordFrequency function · typescript · L156-L158 (3 LOC)src/lib/analysis/cross-recording.ts
export function getChordFrequency(
analyses: RecordingAnalysis[]
): { chord: string; count: number }[] {autoAnalyzeRecording function · typescript · L5-L33 (29 LOC)src/lib/audio/analysis-queue.ts
export async function autoAnalyzeRecording(recordingId: string, audioUrl: string) {
try {
const { transcribeAudio } = await import("./transcribe");
const { analyzeNotes } = await import("./analyze");
const notes = await transcribeAudio(audioUrl);
const result = analyzeNotes(notes);
const supabase = createClient();
await supabase.from("analyses").upsert(
{
recording_id: recordingId,
status: result.status,
key_signature: result.key_signature,
tempo: result.tempo,
time_signature: result.time_signature,
chords: result.chords,
notes: result.notes,
midi_data: result.midi_data,
},
{ onConflict: "recording_id" }
);
return result;
} catch (error) {
console.error(`Auto-analysis failed for ${recordingId}:`, error);
return null;
}
}midiToNoteName function · typescript · L6-L8 (3 LOC)src/lib/audio/analyze.ts
function midiToNoteName(midi: number): string {
return PITCH_CLASSES[midi % 12];
}midiToFullName function · typescript · L10-L13 (4 LOC)src/lib/audio/analyze.ts
function midiToFullName(midi: number): string {
const octave = Math.floor(midi / 12) - 1;
return `${PITCH_CLASSES[midi % 12]}${octave}`;
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
detectChords function · typescript · L19-L79 (61 LOC)src/lib/audio/analyze.ts
function detectChords(notes: NoteEvent[], baseTempo: number | null): ChordEvent[] {
if (notes.length === 0) return [];
// Adaptive window: use beat duration if tempo known, else 0.5s
const windowSize = baseTempo ? 60 / baseTempo : 0.5;
const maxTime = Math.max(...notes.map((n) => n.time + n.duration));
const chords: ChordEvent[] = [];
for (let t = 0; t < maxTime; t += windowSize) {
const windowEnd = t + windowSize;
const activeNotes = notes.filter(
(n) => n.time < windowEnd && n.time + n.duration > t
);
if (activeNotes.length === 0) continue;
// Sort by pitch — bass note matters for inversions
const notesByPitch = [...activeNotes].sort((a, b) => a.midi - b.midi);
const pitchClasses = [...new Set(notesByPitch.map((n) => midiToNoteName(n.midi)))];
const bassNote = midiToNoteName(notesByPitch[0].midi);
if (pitchClasses.length < 2) continue;
let chordName: string | null = null;
// Try with bass note first for better invecorrelate function · typescript · L103-L115 (13 LOC)src/lib/audio/analyze.ts
function correlate(profile: number[]): number {
const meanP = profile.reduce((a, b) => a + b) / 12;
const meanH = normalized.reduce((a: number, b: number) => a + b) / 12;
let num = 0, denP = 0, denH = 0;
for (let i = 0; i < 12; i++) {
const dp = profile[i] - meanP;
const dh = normalized[i] - meanH;
num += dp * dh;
denP += dp * dp;
denH += dh * dh;
}
return denP * denH > 0 ? num / Math.sqrt(denP * denH) : 0;
}estimateTempo function · typescript · L143-L189 (47 LOC)src/lib/audio/analyze.ts
function estimateTempo(notes: NoteEvent[]): number | null {
if (notes.length < 4) return null;
const onsets = notes.map((n) => n.time).sort((a, b) => a - b);
const intervals: number[] = [];
for (let i = 1; i < onsets.length; i++) {
const interval = onsets[i] - onsets[i - 1];
if (interval > 0.05 && interval < 2.0) {
intervals.push(interval);
}
}
if (intervals.length === 0) return null;
const minBeatDuration = 60 / 240;
const maxBeatDuration = 60 / 40;
const step = 0.005;
let bestBeat = 0;
let bestScore = -Infinity;
for (let beat = minBeatDuration; beat <= maxBeatDuration; beat += step) {
let score = 0;
for (const interval of intervals) {
for (let mult = 0.5; mult <= 4; mult *= 2) {
const ratio = interval / (beat * mult);
const nearestInt = Math.round(ratio);
if (nearestInt > 0 && nearestInt <= 8) {
const deviation = Math.abs(ratio - nearestInt);
score += Math.exp(-deviation * deviatidetectTimeSignature function · typescript · L194-L218 (25 LOC)src/lib/audio/analyze.ts
function detectTimeSignature(notes: NoteEvent[], tempo: number | null): string {
if (!tempo || notes.length < 8) return "4/4";
const beatDuration = 60 / tempo;
const onsets = notes.map((n) => n.time).sort((a, b) => a - b);
const totalDuration = Math.max(...onsets) - Math.min(...onsets);
let score3 = 0;
let score4 = 0;
for (const note of notes) {
const beatPos3 = (note.time / beatDuration) % 3;
const beatPos4 = (note.time / beatDuration) % 4;
const dist3 = Math.min(beatPos3, 3 - beatPos3);
const dist4 = Math.min(beatPos4, 4 - beatPos4);
score3 += note.velocity * Math.exp(-dist3 * dist3 * 10);
score4 += note.velocity * Math.exp(-dist4 * dist4 * 10);
}
score3 /= Math.max(1, totalDuration / (beatDuration * 3));
score4 /= Math.max(1, totalDuration / (beatDuration * 4));
if (score3 > score4 * 1.15) return "3/4";
return "4/4";
}extractMelody function · typescript · L223-L248 (26 LOC)src/lib/audio/analyze.ts
function extractMelody(notes: NoteEvent[]): NoteEvent[] {
if (notes.length === 0) return [];
const sorted = [...notes].sort((a, b) => a.time - b.time);
const melody: NoteEvent[] = [];
const windowSize = 0.1;
const maxTime = Math.max(...notes.map((n) => n.time + n.duration));
for (let t = 0; t < maxTime; t += windowSize) {
const active = sorted.filter(
(n) => n.time <= t + windowSize && n.time + n.duration > t
);
if (active.length === 0) continue;
const highest = active.reduce((a, b) => (a.midi > b.midi ? a : b));
const last = melody[melody.length - 1];
if (last && last.midi === highest.midi && Math.abs(last.time + last.duration - t) < 0.01) {
last.duration += windowSize;
} else {
melody.push({ ...highest, time: t, duration: windowSize });
}
}
return melody;
}extractBassLine function · typescript · L253-L278 (26 LOC)src/lib/audio/analyze.ts
function extractBassLine(notes: NoteEvent[]): NoteEvent[] {
if (notes.length === 0) return [];
const sorted = [...notes].sort((a, b) => a.time - b.time);
const bass: NoteEvent[] = [];
const windowSize = 0.25;
const maxTime = Math.max(...notes.map((n) => n.time + n.duration));
for (let t = 0; t < maxTime; t += windowSize) {
const active = sorted.filter(
(n) => n.time <= t + windowSize && n.time + n.duration > t
);
if (active.length === 0) continue;
const lowest = active.reduce((a, b) => (a.midi < b.midi ? a : b));
const last = bass[bass.length - 1];
if (last && last.midi === lowest.midi && Math.abs(last.time + last.duration - t) < 0.01) {
last.duration += windowSize;
} else {
bass.push({ ...lowest, time: t, duration: windowSize });
}
}
return bass;
}analyzeHarmonicRhythm function · typescript · L283-L293 (11 LOC)src/lib/audio/analyze.ts
function analyzeHarmonicRhythm(chords: ChordEvent[]): string {
if (chords.length < 2) return "static";
const durations = chords.map((c) => c.duration);
const avgDuration = durations.reduce((a, b) => a + b, 0) / durations.length;
if (avgDuration < 0.75) return "fast (chord per beat or faster)";
if (avgDuration < 1.5) return "moderate (1-2 beats per chord)";
if (avgDuration < 3) return "slow (1-2 bars per chord)";
return "very slow (multi-bar)";
}detectProgressions function · typescript · L298-L321 (24 LOC)src/lib/audio/analyze.ts
function detectProgressions(chords: ChordEvent[]): string[] {
if (chords.length < 3) return [];
const patterns: string[] = [];
for (let i = 0; i < chords.length - 2; i++) {
const seq3 = [chords[i].chord, chords[i + 1].chord, chords[i + 2].chord].join(" → ");
patterns.push(seq3);
if (i < chords.length - 3) {
const seq4 = [chords[i].chord, chords[i + 1].chord, chords[i + 2].chord, chords[i + 3].chord].join(" → ");
patterns.push(seq4);
}
}
const counts = new Map<string, number>();
for (const p of patterns) {
counts.set(p, (counts.get(p) || 0) + 1);
}
return [...counts.entries()]
.filter(([, count]) => count > 1)
.sort((a, b) => b[1] - a[1])
.slice(0, 5)
.map(([pattern, count]) => `${pattern} (×${count})`);
}Repobility · code-quality intelligence platform · https://repobility.com
analyzeNotes function · typescript · L323-L348 (26 LOC)src/lib/audio/analyze.ts
export function analyzeNotes(notes: NoteEvent[]): AnalysisResult {
const tempo = estimateTempo(notes);
const keyResult = detectKey(notes);
const key_signature = keyResult?.key ?? null;
const chords = detectChords(notes, tempo);
const time_signature = detectTimeSignature(notes, tempo);
const melody = extractMelody(notes);
const bassLine = extractBassLine(notes);
const harmonicRhythm = analyzeHarmonicRhythm(chords);
const progressions = detectProgressions(chords);
return {
status: "completed",
key_signature,
key_confidence: keyResult?.confidence ?? 0,
tempo,
time_signature,
chords,
notes,
melody,
bass_line: bassLine,
harmonic_rhythm: harmonicRhythm,
progressions,
midi_data: null,
};
}detectAudioCodec function · typescript · L6-L39 (34 LOC)src/lib/audio/detect-codec.ts
export async function detectAudioCodec(file: File): Promise<string | null> {
try {
const readSize = Math.min(file.size, 500000);
const buffer = await file.slice(0, readSize).arrayBuffer();
const bytes = new Uint8Array(buffer);
// Scan for known codec FourCC codes in the MP4 container
// "alac" = 0x616c6163, "mp4a" (AAC) = 0x6d703461
for (let i = 0; i < bytes.length - 3; i++) {
if (
bytes[i] === 0x61 && bytes[i + 1] === 0x6c &&
bytes[i + 2] === 0x61 && bytes[i + 3] === 0x63
) {
return "alac";
}
}
// If it's an M4A/MP4 but not ALAC, it's likely AAC
const ext = file.name.toLowerCase();
if (ext.endsWith(".m4a") || ext.endsWith(".mp4") || ext.endsWith(".aac")) {
return "aac";
}
if (ext.endsWith(".mp3")) {
return "mp3";
}
if (ext.endsWith(".wav")) {
return "wav";
}
return null;
} catch {
return null;
}
}midiToNoteName function · typescript · L6-L9 (4 LOC)src/lib/audio/midi-utils.ts
export function midiToNoteName(midi: number): string {
const octave = Math.floor(midi / 12) - 1;
return `${NOTE_NAMES[midi % 12]}${octave}`;
}noteNameToMidi function · typescript · L11-L17 (7 LOC)src/lib/audio/midi-utils.ts
export function noteNameToMidi(name: string): number {
const match = name.match(/^([A-G]#?)(-?\d+)$/);
if (!match) return 60;
const [, note, octave] = match;
const noteIndex = NOTE_NAMES.indexOf(note);
return (parseInt(octave) + 1) * 12 + noteIndex;
}createMidiFile function · typescript · L19-L34 (16 LOC)src/lib/audio/midi-utils.ts
export function createMidiFile(notes: NoteEvent[], name: string = "Transcription"): Uint8Array {
const midi = new Midi();
const track = midi.addTrack();
track.name = name;
for (const note of notes) {
track.addNote({
midi: note.midi,
time: note.time,
duration: note.duration,
velocity: note.velocity / 127,
});
}
return midi.toArray();
}downloadMidi function · typescript · L36-L45 (10 LOC)src/lib/audio/midi-utils.ts
export function downloadMidi(notes: NoteEvent[], filename: string = "transcription.mid") {
const midiData = createMidiFile(notes, filename.replace(".mid", ""));
const blob = new Blob([midiData.buffer as ArrayBuffer], { type: "audio/midi" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}getMp4CreationDate function · typescript · L8-L88 (81 LOC)src/lib/audio/mp4-creation-date.ts
export async function getMp4CreationDate(file: File): Promise<Date | null> {
try {
// Step 1: Scan top-level atoms to find where `moov` lives.
let offset = 0;
let moovOffset = -1;
let moovSize = 0;
let moovHeaderSize = 8;
while (offset + 8 <= file.size) {
const headerBuf = await file.slice(offset, offset + 16).arrayBuffer();
const hv = new DataView(headerBuf);
let size = hv.getUint32(0);
const type = String.fromCharCode(
hv.getUint8(4), hv.getUint8(5), hv.getUint8(6), hv.getUint8(7)
);
let hdrSize = 8;
// 64-bit extended size: size field = 1 means real size is in next 8 bytes
if (size === 1 && headerBuf.byteLength >= 16) {
const hi = hv.getUint32(8);
const lo = hv.getUint32(12);
size = hi * 4294967296 + lo;
hdrSize = 16;
}
if (size < 8) break;
if (type === "moov") {
moovOffset = offset;
moovSize = size;
moovHeaderSize = hdrSizetranscribeAudio function · typescript · L3-L91 (89 LOC)src/lib/audio/transcribe.ts
export async function transcribeAudio(
audioUrl: string,
onProgress?: (stage: string, progress: number) => void
): Promise<NoteEvent[]> {
onProgress?.("Loading audio...", 10);
// Resolve signed URL if needed (the audio API now returns JSON with a URL)
let finalUrl = audioUrl;
if (audioUrl.startsWith("/api/")) {
const res = await fetch(audioUrl);
const data = await res.json();
if (data.url) {
finalUrl = data.url;
}
}
const audioContext = new AudioContext({ sampleRate: 22050 });
let audioBuffer: AudioBuffer;
// Try decoding the signed URL first; if it fails (ALAC on Chrome), use server transcoding
try {
const response = await fetch(finalUrl);
const arrayBuffer = await response.arrayBuffer();
onProgress?.("Decoding audio...", 20);
audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
} catch {
// ALAC decode failed — fall back to server-side transcoding
onProgress?.("Transcoding audio (this may take a minuteRepobility · code-quality intelligence · https://repobility.com
createClient function · typescript · L3-L8 (6 LOC)src/lib/supabase/client.ts
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
}createClient function · typescript · L4-L28 (25 LOC)src/lib/supabase/server.ts
export async function createClient() {
const cookieStore = await cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll();
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
);
} catch {
// The `setAll` method was called from a Server Component.
// This can be ignored if you have middleware refreshing sessions.
}
},
},
}
);
}resolveColor function · typescript · L5-L15 (11 LOC)src/lib/use-theme-colors.ts
function resolveColor(varName: string): string {
const value = getComputedStyle(document.documentElement)
.getPropertyValue(varName)
.trim();
const el = document.createElement("div");
el.style.color = value;
document.body.appendChild(el);
const resolved = getComputedStyle(el).color;
el.remove();
return resolved;
}resolveAll function · typescript · L17-L23 (7 LOC)src/lib/use-theme-colors.ts
function resolveAll() {
return {
primary: resolveColor("--primary"),
mutedForeground: resolveColor("--muted-foreground"),
chart1: resolveColor("--chart-1"),
};
}useThemeColors function · typescript · L25-L52 (28 LOC)src/lib/use-theme-colors.ts
export function useThemeColors() {
const [colors, setColors] = useState({
primary: "rgb(80, 60, 200)",
mutedForeground: "rgb(150, 150, 150)",
chart1: "rgb(80, 60, 200)",
});
useEffect(() => {
// Resolve on mount
const id = requestAnimationFrame(() => setColors(resolveAll()));
// Re-resolve when theme class changes on <html>
const observer = new MutationObserver(() => {
requestAnimationFrame(() => setColors(resolveAll()));
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["class"],
});
return () => {
cancelAnimationFrame(id);
observer.disconnect();
};
}, []);
return colors;
}cn function · typescript · L4-L6 (3 LOC)src/lib/utils.ts
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}‹ prevpage 5 / 5