char/sorcery
static-files based git repo viewer
git clone https://git.t4t.associates/char/sorcery
838fb02
main
1export const utf8 = new TextDecoder (); 2export const looksBinary = ( data :Uint8Array ) => data . subarray ( 0 , 8192 ). includes ( 0 ); 3 4// mirrors excluded_directory / excluded_file in src/languages.rs; keep them in sync 5const GENERATED_DIRECTORIES = new Set ([ 6"node_modules" , "vendor" , "third_party" , "third-party" , "target" , "dist" , "build" , 7"coverage" , ".next" , ".nuxt" , ".output" , ".yarn" , ".gradle" , ".terraform" , ".dart_tool" , 8".direnv" , ".venv" , "venv" , "__pycache__" , "pods" , "carthage" , "generated" , 9]); 10const GENERATED_FILES = new Set ([ 11"cargo.lock" , "package-lock.json" , "npm-shrinkwrap.json" , "yarn.lock" , "pnpm-lock.yaml" , 12"bun.lock" , "bun.lockb" , "deno.lock" , "composer.lock" , "gemfile.lock" , "go.sum" , "poetry.lock" , 13"uv.lock" , "pipfile.lock" , "pdm.lock" , "flake.lock" , "mix.lock" , "pubspec.lock" , 14"package.resolved" , "packages.lock.json" , "gradle.lockfile" , "podfile.lock" , "cartfile.resolved" , 15]); 16const GENERATED_SUFFIXES = [ 17".lock" , ".min.js" , ".min.css" , ".g.dart" , ".pb.go" , ".pb.rs" , ".pb.cc" , ".pb.h" , "_pb2.py" , 18".designer.cs" , 19]; 20 21export function looksGenerated ( path :string ) :boolean { 22const segments = path . toLowerCase (). split ( "/" ); 23const name = segments . pop () ! ; 24return segments . some ( dir => GENERATED_DIRECTORIES . has ( dir )) 25|| GENERATED_FILES . has ( name ) 26|| GENERATED_SUFFIXES . some ( suffix => name . endsWith ( suffix )) 27|| name . includes ( ".generated." ) 28|| name . includes ( "_generated." ); 29} 30 31/** mirrors human_size in src/render.rs */ 32export function humanSize ( bytes :number ) :string { 33if ( bytes < 1024 ) return ` ${ bytes } B` ; 34if ( bytes < 1 << 20 ) return ` ${( bytes / 1024 ). toFixed ( 1 )} KiB` ; 35return ` ${( bytes / ( 1 << 20 )). toFixed ( 1 )} MiB` ; 36} 37 38export const plural = ( n :number , noun :string ) => ` ${ n } ${ noun } ${ n === 1 ? "" : "s" } ` ; 39 40/** the identity's own timezone, like git log */ 41export function identityDate ( id :{ time :number ; tz :string }) :string { 42const offset = ( Number ( id . tz . slice ( 0 , 3 )) * 60 + Number ( id . tz [ 0 ] + id . tz . slice ( 3 ))) * 60000 ; 43const local = new Date ( id . time * 1000 + offset ). toISOString (); 44return ` ${ local . slice ( 0 , 10 )} ${ local . slice ( 11 , 16 )} ${ id . tz } ` ; 45}