package main import "core:strings" get_ext :: proc(url: string) -> string { clean := url if question := strings.index_byte(clean, '?'); question != -1 { clean = clean[:question] } if hash := strings.index_byte(clean, '#'); hash != -1 { clean = clean[:hash] } if dot := strings.last_index_byte(clean, '.'); dot != -1 { return strings.to_lower(clean[dot:], context.temp_allocator) } return "" } detect_type :: proc(url: string) -> string { ext := get_ext(url) switch ext { case ".jpg", ".jpeg", ".jpe", ".jfif", ".jif", ".pjpeg", ".pjp", ".png", ".apng", ".gif", ".webp", ".avif", ".heic", ".heif", ".hif", ".bmp", ".dib", ".tif", ".tiff", ".ico", ".cur", ".svg", ".svgz", ".raw", ".cr2", ".cr3", ".nef", ".nrw", ".orf", ".sr2", ".arw", ".srf", ".rw2", ".pef", ".raf", ".dng", ".3fr", ".ari", ".bay", ".cap", ".dcr", ".erf", ".fff", ".iiq", ".k25", ".kdc", ".mdc", ".mos", ".mrw", ".obm", ".ptx", ".pxn", ".r3d", ".rwl", ".rwz", ".srw", ".x3f", ".gpr", ".pgm", ".ppm", ".pbm", ".pnm", ".pam", ".pfm", ".tga", ".icb", ".vda", ".vst", ".pcx", ".xbm", ".xpm", ".xwd", ".sgi", ".rgb", ".rgba", ".bw", ".jp2", ".j2k", ".j2c", ".jpf", ".jpx", ".jpm", ".mj2", ".wbmp", ".emf", ".wmf", ".eps", ".epsi", ".epsf", ".psd", ".psb", ".ai", ".cdr", ".xcf", ".gbr", ".gih", ".pat", ".art", ".jxl", ".jxr", ".wdp", ".hdp", ".exr", ".hdr", ".dpx", ".cin", ".fits", ".fit", ".fts", ".icns", ".flif", ".dds", ".ktx", ".ktx2", ".astc", ".kodak", ".fpx", ".pcd", ".cmx", ".drw", ".cgm", ".plt", ".hpgl", ".iff", ".ilbm", ".lbm", ".mac", ".msp", ".pct", ".pic", ".pict", ".pntg", ".qtif", ".qti", ".ras", ".sun", ".tpic", ".wpg", ".g3", ".g4", ".dcm", ".dicom", ".ora", ".kra", ".clip": return "image" case ".mp3", ".mp2", ".mp1", ".mpa", ".mpga", ".ogg", ".oga", ".opus", ".spx", ".wav", ".wave", ".flac", ".aac", ".adts", ".wma", ".m4a", ".m4b", ".m4p", ".m4r", ".aif", ".aiff", ".aifc", ".au", ".snd", ".mid", ".midi", ".rmi", ".kar", ".ra", ".ram", ".mka", ".ape", ".wv", ".ac3", ".ec3", ".eac3", ".dts", ".dtshd", ".amr", ".awb", ".caf", ".gsm", ".mpc", ".shn", ".tta", ".voc", ".vox", ".8svx", ".mod", ".s3m", ".xm", ".it", ".stm", ".med", ".mtm", ".umx", ".669", ".far", ".amf", ".dsm", ".gdm", ".imf", ".okt", ".sfx", ".ult", ".uni", ".psm", ".j2b", ".dbm", ".digi", ".dtm", ".plm", ".nsf", ".nsfe", ".spc", ".gym", ".vgm", ".vgz", ".gbs", ".hes", ".ay", ".sid", ".oma", ".aa3", ".at3", ".at9", ".qcp", ".tak", ".ofr", ".ofs", ".sox", ".weba", ".dss", ".alac", ".vqf", ".vql", ".mxmf", ".ota", ".imy", ".rtttl", ".rtx", ".xmf", ".w64", ".rf64", ".bwf", ".cda", ".aup": return "audio" case ".mp4", ".m4v", ".mp4v", ".webm", ".mov", ".qt", ".avi", ".mkv", ".flv", ".f4v", ".f4p", ".f4a", ".f4b", ".wmv", ".mpg", ".mpeg", ".mpe", ".m1v", ".m2v", ".mpv", ".mp2v", ".mpv2", ".ogv", ".ogx", ".3gp", ".3g2", ".3gpp", ".3gpp2", ".asf", ".asx", ".vob", ".ts", ".mts", ".m2ts", ".tsv", ".tsa", ".divx", ".xvid", ".rm", ".rmvb", ".swf", ".dv", ".dif", ".gifv", ".roq", ".nsv", ".svi", ".annodex", ".axv", ".amv", ".bik", ".bk2", ".smk", ".ivf", ".mxf", ".nut", ".ogm", ".fli", ".flc", ".y4m", ".264", ".h264", ".265", ".h265", ".hevc", ".av1", ".vc1", ".vp8", ".vp9", ".wtv", ".yuv", ".str", ".pva", ".trp", ".rec", ".vid", ".rv", ".cpk", ".film": return "video" case: return "iframe" } } parse_type_hint :: proc(type_hint: string) -> string { switch type_hint { case "i", "image", "img": return "image" case "a", "audio": return "audio" case "v", "video": return "video" case "f", "iframe", "frame": return "iframe" case: return "" } }