{"version":3,"sources":["constants.ts","utils/error.ts","data/manifest.ts","utils/parsers/parse.ts","utils/normalize.ts","data/task.ts","utils/parsers/task.ts","data/taskList.ts","Manifest.tsx","utils/parsers/manifest.ts","utils/usePersistentState.ts","utils/Debug.tsx","components/Task/SubmitCode.tsx","components/keyboard/useKeyboard.ts","components/keyboard/IPAInput.tsx","components/keyboard/common.ts","utils/ipa.ts","components/keyboard/Pulmonics.tsx","components/keyboard/NonPulmonics.tsx","components/keyboard/trapezium.svg","components/keyboard/Vowels.tsx","components/keyboard/GridDisplay.tsx","components/keyboard/Diacritics.tsx","components/keyboard/Other.tsx","components/keyboard/Suprasegmentals.tsx","components/keyboard/Keyboard.tsx","components/keyboard/StickyIPA.tsx","components/Task/WordInput.tsx","components/ConfirmDialog.tsx","components/Task/PlayButton.tsx","components/CodeBlock.tsx","components/Markdown.tsx","components/Task/Task.tsx","components/ErrorMessage.tsx","components/Task/LoadTask.tsx","config.ts","components/Task/RouteTask.tsx","components/Task/TaskList.tsx","components/ClassPage.tsx","utils/parsers/taskList.ts","components/Homepage.tsx","components/TypeIPA.tsx","components/Tools/ToolLoader.tsx","Router.tsx","utils/styles.ts","components/Header.tsx","components/Footer.tsx","utils/AudioContext.ts","App.tsx","index.tsx","utils/validation.ts","components/Link.tsx","components/NotFound.tsx"],"names":["BASE_URL","fileUrl","folder","path","IPAError","Error","getLines","lines","lineIdx","context","lineArr","split","line","start","Math","max","errorLine","slice","map","contents","i","num","error","indexToLines","str","idx","findIndex","ln","this","pos","length","ParseError","constructor","data","err","super","message","dat","headline","n","linePos","ValidateError","document","doc","node","getIn","range","ResourceError","msg","orig","originalMessage","ManifestFile","object","homepage","title","string","body","classes","array","name","hidden","optional","boolean","parse","struct","YAML","parseDocument","prettyErrors","warnings","forEach","warning","console","warn","errors","fileContents","toJSON","valid","validate","CANONICAL_FORMS","Map","MATCHER","RegExp","Array","from","keys","join","normalize","replace","match","get","Macros","record","Segment","union","ValidateSegment","refine","segment","index","parent","branch","list","isArray","includes","isParentSegmentList","key","Object","values","reduce","run","curr","Word","display","audio","instructions","segments","TaskFile","author","salt","macros","words","DEFAULT_MESSAGE","END_MESSAGE","KLEENE_REPLACE","escapeStringRegexp","ANY_REPLACE","matchSegment","rawInput","correct","input","explanations","wildcards","find","matcher","wildcard","kleene","wildcardToRegex","test","expandMacro","encountered","hasOwnProperty","newEncountered","results","value","expanded","concat","push","pickValues","ops","result","parseTask","metadata","getMacros","word","validSegments","hint","sym","expand","set","lastElement","final","getSegments","TaskInfo","description","file","TaskListFile","tasks","ManifestContext","createContext","fetchManifest","async","req","fetch","text","useManifest","asyncManifest","useContext","errorShown","Manifest","children","manifest","useAsync","YAMLError","alert","Provider","usePersistentState","defaultValue","persistOnLoad","mount","useRef","setValue","useState","stored","localStorage","getItem","JSON","useDebugValue","setter","useCallback","prevState","useEffect","current","setItem","stringify","DebugContext","useDebugContext","Debug","props","debug","setDebug","addEventListener","e","metaKey","shiftKey","d","process","DEFAULTS","prompt","SubmitCode","Op","existingName","onSubmit","controls","setName","setRun","open","setOpen","inputRef","timer","computeHash","displayValue","copyText","select","setSelectionRange","execCommand","window","clearTimeout","setTimeout","button","Button","variant","color","onClick","startIcon","type","preventDefault","trim","Grid","container","spacing","alignItems","justify","item","xs","sm","md","lg","Typography","component","gutterBottom","Tooltip","PopperProps","disablePortal","disableFocusListener","disableHoverListener","disableTouchListener","TextField","label","InputProps","readOnly","fullWidth","onChange","target","reducer","state","action","cursor","ref","selectionStart","cursorAfter","selectionEnd","Delete","Append","Set","Type","useKeyboard","dispatch","useReducer","handleKeyboard","char","handleType","handleDelete","val","useLayoutEffect","oldFocus","activeElement","focus","blur","useStyles","makeStyles","theme","breakpoints","up","fontSize","noRightMargin","marginRight","helpTextSize","IPAInput","placeholder","onType","onDelete","header","onCheck","checkDescription","helpText","headerTooltip","handleSubmit","handleEnter","check","enterDelay","IconButton","aria-label","onMouseDown","helperText","className","headerContent","InputAdornment","disablePointerEvents","disableTypography","position","positionStart","placement","TransitionComponent","Fade","TransitionProps","timeout","FormControl","InputLabel","htmlFor","OutlinedInput","id","onKeyPress","inputProps","spellCheck","autoCorrect","autoComplete","style","lineHeight","endAdornment","startAdornment","Collapse","in","FormHelperText","borderColor","palette","lighten","fade","divider","darken","PLACES","MANNERS","IMPOSSIBLE","NUL","PULMONICS","CLICKS","IMPLOSIVES","EJECTIVES","VOWEL_HEIGHTS","VOWEL_FRONTEDNESS","VOWELS","DIACRITICS","ipa","examples","MISC","SUPRASEGMENTALS","voiceless","backgroundColor","hover","voiced","impossible","disabledBackground","symbol","padding","userSelect","leftSideBorder","borderLeft","rightSideBorder","borderRight","caps","minWidth","Pulmonics","clickCallback","undefined","Cell","x","y","hasBorders","TableCell","align","clsx","TableContainer","Table","size","TableHead","TableRow","place","colSpan","TableBody","manner","memo","textAlign","descr","verticalAlign","NonPulmonics","sounds","useMemo","click","span","row","j","_extends","assign","arguments","source","prototype","call","apply","_ref","strokeWidth","fill","strokeLinecap","strokeLinejoin","SvgTrapezium","titleId","svgRef","xmlns","viewBox","preserveAspectRatio","fillRule","clipRule","ForwardRef","root","width","height","outerQuad","minHeight","fullRel","trapezium","stroke","primary","quad","left","top","element","transform","overflow","rounded","unrounded","right","mid","borderRadius","paperBack","zIndex","content","background","paper","fullHeight","vowelPos","vowelHeight","vowelCoords","offset","Vowels","VowelElement","vowels","coords","Box","noCenter","center","vowelChart","wrap","direction","descriptionParent","justifyContent","flexDirection","bordered","boxShadow","GridDisplay","genSym","combine","combined","Diacritics","Other","Suprasegmentals","childOrder","orderChildren","styles","order","child","Keyboard","Paper","sticky","pointerEvents","marginBottom","default","StickyIPA","useTheme","elevation","paddingY","success","main","dark","reset","attempt","SoftReset","is","Reset","SetHeader","NextSegment","ClearError","ErrorMessage","errorMessage","WordInput","handleCheck","currentValue","headerValue","ConfirmDialog","onClose","Dialog","disableBackdropClick","disableEscapeKeyDown","maxWidth","aria-labelledby","DialogTitle","DialogContent","DialogContentText","DialogActions","autoFocus","PlayButton","baseUrl","audioFile","audioUrl","URL","toString","Audio","disable","currentTime","play","catch","src","disabled","codeBlock","inline","CodeBlock","block","comp","klass","URL_PATTERN","typeTag","v","RelativeImg","imgProps","imgSrc","SmartLink","href","rest","Link","to","CustomInput","Checkbox","checked","Markdown","allowTags","paragraph","options","disableParsingRawHTML","forceBlock","overrides","img","h1","h2","h3","h4","h5","h6","p","a","pre","code","currWord","DismissModal","showModal","Submit","modalWord","ModalExit","ShowReset","resetModal","CloseReset","inputKey","random","useDispatch","op","Task","task","noPersist","persistKey","persist","setPersist","anchorEl","setAnchorEl","showWord","dismissModal","handleModalExit","handleShowReset","handleReset","scroll","behavior","s","aria-controls","aria-haspopup","event","currentTarget","Menu","keepMounted","Boolean","MenuListProps","subheader","ListSubheader","MenuItem","wordInstructions","mb","min","mountOnEnter","unmountOnExit","aria-describedby","disableRestoreFocus","onExited","disableFocusRipple","fileDump","typography","defaultHeader","o","issue","data-line","padStart","fetchTask","taskFileUrl","log","TypeError","status","statusText","Status","LoadTask","location","loading","transitionDelay","CircularProgress","hostedSite","REACT_APP_ORIGINAL_HOSTED_SITE","VERSION","REACT_APP_SHORT_DOMAIN","RouteTask","assignment","useParams","taskLink","TaskList","alignContent","flexWrap","fetchClassTasks","classId","url","ClassPage","params","classTasks","pathname","Homepage","TypeIPA","ToolList","lazy","ToolLoader","fallback","Router","exact","NotFound","notchGutters","paddingLeft","paddingRight","itemGutters","gutters","Loading","ListItem","ListItemText","LinearProgress","ListLink","useLocation","icon","selected","matchPath","ListItemIcon","DarkSwitch","withStyles","switchBase","grey","track","Switch","Header","drawer","setDrawer","changeDarkMode","openDrawer","closeDrawer","toggleDarkMode","List","Divider","Drawer","anchor","role","darkMode","AppBar","Toolbar","edge","marginTop","disclaimer","Footer","Container","AudioContext","webkitAudioContext","lightTheme","blue","secondary","indigo","darkTheme","containerRoot","boxSizing","debugRoot","siteRoot","siteContent","flex","App","prefersDarkMode","useMediaQuery","setDark","create","removeEventListener","latencyHint","createMuiTheme","ThemeProvider","CssBaseline","Snackbar","anchorOrigin","vertical","horizontal","ContentProps","ReactDOM","render","getElementById","smoothscroll","polyfill","INVALID","EPOCH","Date","DEFAULT_SALT","time","effectiveSalt","outName","normName","hashName","toLowerCase","outTime","now","floor","getTime","minuteOfYear","longer","shorter","interleaved","charAt","interleave","bytes","buf","crypto","subtle","digest","fromUint8Array","Uint8Array","sha1sum","TextEncoder","encode","checkHash","hash","sha","encoded","parseInt","deinterleave","date","timestamp","millis","timestampToDate","lowerHash","RouterLink"],"mappings":"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","file":"static/js/main.33f4d0ea.chunk.js","sourcesContent":["// A list of constants for the project\n\n// PUBLIC_URL access\nexport const BASE_URL = `${process.env.PUBLIC_URL}/config`;\n\n// URL of teh manifest file\nexport const MANIFEST_FILE = `${BASE_URL}/manifest.yaml`;\n\n// Name of the task file\nexport const TASK_FILE = \"tasks.yaml\";\n\n// Generate a full file URL given the folder and the pathname\nexport const fileUrl = (folder: string, path: string) => `${BASE_URL}/${folder}/${path}`;\n\nexport const fullBaseUrl = () => new URL(BASE_URL, window.location.href);\n","import { Document } from \"yaml\";\nimport { StructError } from \"superstruct\";\nimport { YAMLError } from \"yaml/util\";\n\nexport class IPAError extends Error {}\n\ninterface Line {\n num: number;\n contents: string;\n error: boolean;\n}\n\n// Note: line is assumed one indexed\nconst getLines = (lines: string | string[], lineIdx: number, context: number): Line[] => {\n const lineArr = typeof lines === \"string\" ? lines.split(\"\\n\") : lines;\n const line = lineIdx - 1;\n\n const start = Math.max(line - context, 0);\n const errorLine = Math.max(line, line - context) - start;\n\n if (line < 0) {\n return [];\n } else {\n return lineArr.slice(line - context, line + context + 1).map((contents, i) => ({\n num: start + i + 1,\n contents,\n error: i === errorLine,\n }));\n }\n};\n\nconst indexToLines = (str: string, idx: number, context: number): Line[] => {\n const lines = str.split(\"\\n\");\n\n // Yes, we need this here from function\n const line = lines.findIndex(\n function (this: { pos: number }, ln) {\n this.pos += ln.length + 1;\n return idx < this.pos;\n },\n { pos: 0 }\n );\n\n return getLines(lines, line + 1, context);\n};\n\ninterface ContextError {\n headline: string;\n context(n?: number): Line[];\n}\n\nexport const isContextError = (o: any): o is ContextError => {\n return o instanceof IPAError && \"context\" in o;\n};\n\nexport class ParseError extends IPAError implements ContextError {\n dat: string;\n err: YAMLError;\n headline = \"File parsing error\";\n\n constructor(data: string, err: YAMLError) {\n super(err.message);\n this.dat = data;\n this.err = err;\n }\n\n context(n = 1) {\n const linePos = this.err.linePos?.start;\n if (linePos) {\n return getLines(this.dat, linePos.line, n);\n } else {\n return [];\n }\n }\n}\n\nexport class ValidateError extends IPAError implements ContextError {\n dat: string;\n doc: Document;\n err: StructError;\n headline = \"File validation error\";\n\n constructor(data: string, document: Document, err: StructError) {\n super(err.message);\n this.dat = data;\n this.doc = document;\n this.err = err;\n }\n\n context(n = 1) {\n // issues importing type Node and function Document#getIn\n const node = (this.doc as any).getIn(this.err.path, true) as { range: [number, number] };\n return indexToLines(this.dat, node.range[0], n);\n }\n}\n\nexport class ResourceError extends IPAError {\n originalMessage?: string;\n\n constructor(msg: string, orig?: string) {\n super(msg);\n this.originalMessage = orig;\n }\n}\n","import { Infer, array, boolean, object, optional, string } from \"superstruct\";\n\nexport type ManifestDef = Infer;\n\nexport const ManifestFile = object({\n homepage: object({ title: string(), body: string() }),\n classes: array(\n object({\n name: string(),\n folder: string(),\n hidden: optional(boolean()),\n })\n ),\n});\n","import YAML from \"yaml\";\nimport { Struct, validate } from \"superstruct\";\nimport { IPAError, ParseError, ValidateError } from \"../error\";\n\nexport const parse = (contents: string, struct: Struct): T => {\n const doc = YAML.parseDocument(contents, { prettyErrors: true });\n\n doc.warnings.forEach((warning) => console.warn(warning));\n\n if (doc.errors.length > 0) {\n // Log all of the errors, but only throw the first one.\n doc.errors.forEach((err) => console.error(err));\n throw new ParseError(contents, doc.errors[0]);\n }\n const fileContents = doc.toJSON();\n\n const [err, valid] = validate(fileContents, struct);\n if (!valid) {\n if (!err) {\n throw new IPAError(\"Bad state. Both No valid and no error!\");\n }\n throw new ValidateError(contents, doc, err);\n }\n\n return valid;\n};\n","// import { STRESS } from \"./ipa\";\n\n// We will always prefer the multi char version of a symbol, so always expand it\nconst CANONICAL_FORMS = new Map([\n [\"ʧ\", \"t͡ʃ\"],\n [\"ʤ\", \"d͡ʒ\"],\n [\"ɚ\", \"ə˞\"],\n [\"ɝ\", \"ɜ˞\"],\n // coerce an exclamation point to postalveolar click\n // [\"!\", \"ǃ\"],\n // coerce an apostrophe to the ejective\n // [\"'\", STRESS],\n]);\n\nconst NORM = \"NFKD\";\n\nconst MATCHER = new RegExp(Array.from(CANONICAL_FORMS.keys()).join(\"|\"), \"gu\");\n\nconst normalize = (str: string) => {\n const normalized = str.normalize(NORM);\n return normalized.replace(MATCHER, (match) => CANONICAL_FORMS.get(match) || \"⍰\");\n};\n\nexport default normalize;\n","import {\n Infer,\n array,\n boolean,\n object,\n optional,\n record,\n refine,\n string,\n union,\n} from \"superstruct\";\n\nexport type TaskFileDef = Infer;\nexport type TaskFileWord = Infer;\nexport type TaskFileMacros = Infer;\nexport type TaskFileSegment = Infer;\n\nconst Macros = record(string(), array(string()));\n\nconst Segment = record(string(), union([boolean(), string()]));\n\n// ensure the segment is a member of the parent (guard against version changes)\n// and get typescript guarantees later on.\nconst isParentSegmentList = (list: any, segment: TaskFileSegment): list is TaskFileSegment[] =>\n Array.isArray(list) && list.includes(segment);\n\nconst ValidateSegment = refine(Segment, \"Segment\", (segment, context) => {\n const index = context.path[context.path.length - 1];\n // Grab the parent object so we can check against it for certain rules\n const parent = context.branch[context.branch.length - 2];\n\n // Slightly hacky way of checking for current segment number and if last segment\n if (typeof index === \"string\" || !isParentSegmentList(parent, segment)) {\n return \"Segments may only occur in arrays\";\n }\n\n for (const key in segment) {\n if ((key.includes(\"...\") || key.includes(\"%\")) && segment[key] === true) {\n return \"Correct options are not allowed to use wildcards\";\n }\n }\n\n if (index < parent.length - 1) {\n if (segment[\"\"] === true) {\n return `You may only terminate with \"\" on the last segment`;\n }\n\n if (Object.values(segment).reduce((run: boolean, curr) => run && curr !== true, true)) {\n return `There must be at least one valid value in segment`;\n }\n } else {\n // Last segment\n if (segment[\"\"] === true) {\n for (const key in segment) {\n if (key !== \"\" && segment[key] === true) {\n return \"You cannot have both a termination and another valid option in the last segment\";\n }\n }\n }\n }\n // Validation successful\n return true;\n});\n\nconst Word = object({\n display: string(),\n audio: optional(string()),\n instructions: optional(string()),\n segments: array(ValidateSegment),\n});\n\nexport const TaskFile = object({\n author: string(),\n title: string(),\n salt: optional(string()),\n instructions: optional(string()),\n macros: optional(Macros),\n words: array(Word),\n});\n","import escapeStringRegexp from \"escape-string-regexp\";\nimport normalize from \"../normalize\";\nimport { TaskFile, TaskFileMacros, TaskFileSegment } from \"../../data/task\";\nimport { parse } from \"./parse\";\n\nexport interface TaskDef {\n author: string;\n title: string;\n instructions?: string;\n salt?: string;\n macros: Macros;\n words: Word[];\n}\n\ntype Explanations = Map;\ninterface Wildcard {\n matcher: string;\n message: string;\n}\n\nexport interface WordSegment {\n final?: boolean;\n correct: string[];\n explanations: Explanations;\n wildcards?: Wildcard[];\n hint?: string;\n}\n\nexport interface Word {\n display: string;\n audio?: string;\n instructions?: string;\n segments: WordSegment[];\n}\n\ninterface SegmentMatch {\n correct: boolean;\n message?: string;\n}\n\nexport const DEFAULT_MESSAGE = \"Whoops, that's not right. Try again!\";\nexport const END_MESSAGE = \"Hmmm... Are you sure there's more sounds here?\";\n// replaceAll is not supported in Github actions because we need node 15.x for that :'(\nconst KLEENE_REPLACE = new RegExp(escapeStringRegexp(escapeStringRegexp(\"...\")), \"g\");\nconst ANY_REPLACE = new RegExp(escapeStringRegexp(escapeStringRegexp(\"%\")), \"g\");\n\nexport const wildcardToRegex = (wildcard: string) => {\n const str = escapeStringRegexp(wildcard);\n const kleene = str.replace(KLEENE_REPLACE, \".*\").replace(ANY_REPLACE, \".\");\n return new RegExp(`^${kleene}$`, \"u\");\n};\n\n/**\n * Attempt to match a word segment\n * @param input The user inputted value to check\n * @param segment The word segment we are matching\n */\nexport const matchSegment = (rawInput: string, segment?: WordSegment): SegmentMatch => {\n if (!segment) {\n return { correct: false, message: END_MESSAGE };\n }\n\n const input = normalize(rawInput);\n\n let message: string | undefined;\n if (segment.correct.includes(input)) {\n return { correct: true };\n } else if ((message = segment.explanations.get(input))) {\n return { correct: false, message: message };\n } else if (segment.wildcards) {\n // Do the wildcard lookup :(\n const match = segment.wildcards.find(({ matcher }) => {\n return wildcardToRegex(matcher).test(input);\n });\n if (match) {\n return { correct: false, message: match.message };\n }\n }\n\n // Return a the end message if there are no correct options\n return { correct: false, message: segment.correct.length === 0 ? END_MESSAGE : DEFAULT_MESSAGE };\n};\n\ntype Macro = string;\n\ninterface Macros {\n [k: string]: string[];\n}\n\nexport const expandMacro = (str: Macro, macros: Macros, encountered: string[] = []): string[] => {\n if (macros.hasOwnProperty(str)) {\n // Key exists\n const newEncountered = [...encountered, str];\n let results: string[] = [];\n\n macros[str].forEach((value) => {\n if (macros.hasOwnProperty(value) && !newEncountered.includes(value)) {\n // If we find another macro we haven't encountered, append it's expansion\n const expanded = expandMacro(value, macros, newEncountered);\n results = results.concat(expanded);\n } else {\n results.push(value);\n }\n });\n return results;\n } else {\n // Resolve the base case of no macros\n return [str];\n }\n};\n\nconst pickValues = (values: T, ops: K[]): Pick => {\n let result = {} as Pick;\n ops.forEach((key) => {\n result[key] = values[key];\n });\n return result;\n};\n\nconst getMacros = (macros: TaskFileMacros | undefined): Macros => {\n if (macros) {\n let result: Macros = {};\n // iterate over record\n for (const key in macros) {\n // Todo: raise an error if a key is defined twice\n result[normalize(key)] = macros[key].map(normalize);\n }\n return result;\n } else {\n return {};\n }\n};\n\nconst getSegments = (segments: TaskFileSegment[], macros: Macros): WordSegment[] => {\n const validSegments = segments.map((segment, i): WordSegment => {\n let correct: string[] = [];\n let wildcards: Wildcard[] = [];\n const explanations = new Map();\n let hint: string | undefined;\n\n // Record iteration\n for (const key in segment) {\n const sym = normalize(key);\n const value = segment[key];\n if (value === true) {\n // Correct value(s)\n correct = correct.concat(expandMacro(sym, macros));\n } else if (sym.includes(\"...\") || sym.includes(\"%\")) {\n // Wildcard matcher\n wildcards.push({ matcher: sym, message: value || DEFAULT_MESSAGE });\n } else if (sym === \"HINT\" && typeof value === \"string\") {\n // Require the optional hint to be all caps\n hint = value;\n } else {\n // We just have a normal explanation\n expandMacro(sym, macros).forEach((expand) => {\n explanations.set(expand, value || DEFAULT_MESSAGE);\n });\n }\n }\n return { correct, explanations, wildcards, hint };\n });\n\n // Ensure we have a final element listed\n const lastElement = validSegments[validSegments.length - 1];\n if (lastElement.correct.length === 0) {\n // Final element exists, but we don't have a termination identifier\n lastElement.correct.push(\"\");\n lastElement.final = true;\n } else if (lastElement.correct.includes(\"\")) {\n // All data is good. Mark as final\n lastElement.final = true;\n } else {\n // No final element existed, so we create one\n validSegments.push({ correct: [\"\"], explanations: new Map(), final: true });\n }\n\n return validSegments;\n};\n\n// TODO: Actually do validations and make this type safe\nexport const parseTask = (contents: string): TaskDef => {\n const valid = parse(contents, TaskFile);\n\n const metadata = pickValues(valid, [\"author\", \"title\", \"salt\", \"instructions\"]);\n const macros = getMacros(valid.macros);\n const words = valid.words.map((word): Word => {\n const meta = pickValues(word, [\"display\", \"audio\", \"instructions\"]);\n const segments = getSegments(word.segments, macros);\n return { ...meta, segments };\n });\n\n return { ...metadata, macros, words };\n};\n","import { Infer, array, boolean, object, optional, string } from \"superstruct\";\n\nexport type TaskListDef = Infer;\nexport type TaskInfoDef = Infer;\n\nconst TaskInfo = object({\n name: string(),\n description: string(),\n file: string(),\n hidden: optional(boolean()),\n});\n\nexport const TaskListFile = object({\n title: string(),\n description: string(),\n tasks: array(TaskInfo),\n});\n","import { createContext, useContext } from \"react\";\nimport { UseAsyncReturn, useAsync } from \"react-async-hook\";\nimport { YAMLError } from \"yaml/util\";\nimport { MANIFEST_FILE } from \"./constants\";\nimport { ValidateError } from \"./utils/error\";\n\nimport { ManifestDef, parseManifest } from \"./utils/parsers\";\n\nconst ManifestContext = createContext | null>(null);\n\nconst fetchManifest = async (): Promise => {\n // TODO: Change to force fetch even when cached\n const req = await fetch(MANIFEST_FILE);\n const body = await req.text();\n // console.log(YAML.parseDocument(body, { prettyErrors: true }));\n return parseManifest(body);\n};\n\nexport const useManifest = () => {\n const asyncManifest = useContext(ManifestContext);\n if (!asyncManifest) {\n // Absurd\n throw new Error(\"Error: you must wrapped in a context\");\n }\n return asyncManifest;\n};\n\ntype Props = {\n children: React.ReactNode;\n};\n\n// Only show the error once\nlet errorShown = false;\n\nconst Manifest = ({ children }: Props) => {\n const manifest = useAsync(fetchManifest, []);\n if (manifest.error && !errorShown) {\n errorShown = true;\n console.error(manifest.error);\n if (manifest.error instanceof YAMLError) {\n // This is a YAML error\n alert(\n `Error: Your manifest.yaml contains invalid syntax. Please check the console for more info.`\n );\n } else if (manifest.error instanceof ValidateError) {\n alert(`Issue parsing manifest.yaml: ${manifest.error.message}`);\n } else {\n alert(\"There was an error loading your manifest.yaml\");\n }\n }\n return {children};\n};\n\nexport default Manifest;\n","import { ManifestDef, ManifestFile } from \"../../data/manifest\";\nimport { parse } from \"./parse\";\n\nexport type { ManifestDef } from \"../../data/manifest\";\n\nexport const parseManifest = (contents: string): ManifestDef => parse(contents, ManifestFile);\n","import { useCallback, useDebugValue, useEffect, useRef, useState } from \"react\";\n\ntype JSONSafe = string | number | boolean | null | Array | { [l: string]: JSONSafe };\n\nexport const usePersistentState = (\n key: string | null,\n defaultValue: T,\n persistOnLoad = false\n): [T, React.Dispatch>] => {\n const mount = useRef(false);\n const [value, setValue] = useState(() => {\n const stored = key && localStorage.getItem(key);\n if (stored === null) {\n return defaultValue;\n } else {\n return JSON.parse(stored) as T;\n }\n });\n\n useDebugValue({ [key || \"\"]: value });\n\n const setter = useCallback((prevState: React.SetStateAction) => {\n setValue(prevState);\n }, []);\n\n useEffect(() => {\n if (key && (mount.current || persistOnLoad)) {\n localStorage.setItem(key, JSON.stringify(value));\n } else {\n mount.current = true;\n }\n }, [key, value, persistOnLoad]);\n\n return [value, setter];\n};\n","import { createContext, useContext, useEffect } from \"react\";\nimport { usePersistentState } from \"./usePersistentState\";\n\nconst DebugContext = createContext(false);\n\nexport const useDebugContext = () => useContext(DebugContext);\n\nconst Debug = (props: { children: React.ReactNode }) => {\n const [debug, setDebug] = usePersistentState(\"debug_mode\", false);\n\n useEffect(() => {\n document.addEventListener(\"keydown\", (e) => {\n if (e.key === \".\" && e.metaKey && e.shiftKey) {\n setDebug((d) => !d);\n }\n });\n }, [setDebug]);\n\n // Register a way to toggle debugging for iOS, etc. disable in production\n useEffect(() => {\n if (process.env.NODE_ENV !== \"production\") {\n window.toggleDebug = () => setDebug((d) => !d);\n }\n }, [setDebug]);\n\n return {props.children};\n};\n\nexport default Debug;\n","import { useCallback, useRef, useState } from \"react\";\nimport { useAsync } from \"react-async-hook\";\nimport { Button, Grid, TextField, Tooltip, Typography } from \"@material-ui/core\";\nimport { computeHash } from \"../../utils/validation\";\n\nimport AssignmentIcon from \"@material-ui/icons/Assignment\";\n\ninterface Props {\n prompt?: string;\n salt?: string;\n debug?: boolean;\n name?: string | null;\n onSubmit?: (name: string) => void;\n controls?: React.ReactNode;\n}\n\nconst DEFAULTS = {\n prompt: \"Name\",\n debug: false,\n} as const;\n\nconst SubmitCode = (props: Props) => {\n const { salt, debug, prompt, name: existingName, onSubmit, controls } = { ...DEFAULTS, ...props };\n const [name, setName] = useState(existingName || \"\");\n const [run, setRun] = useState(!!existingName);\n const [open, setOpen] = useState(false);\n const inputRef = useRef();\n const timer = useRef();\n\n const { result } = useAsync(computeHash, [name, salt, run]);\n\n const displayValue = result ? result : name;\n\n const copyText = useCallback(() => {\n if (inputRef.current) {\n const e = inputRef.current;\n e.select();\n e.setSelectionRange(0, e.value.length);\n document.execCommand(\"copy\");\n setOpen(true);\n window.clearTimeout(timer.current);\n timer.current = window.setTimeout(() => setOpen(false), 2000);\n }\n }, []);\n\n const button = run ? (\n \n ) : (\n \n );\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (name.trim()) {\n setRun(true);\n if (onSubmit) {\n onSubmit(name);\n }\n }\n };\n\n return (\n
\n \n \n \n Congratulations on finishing this assignment! Type your {prompt} below and hit submit to\n receive a unique code for completion.\n \n Copied code!}\n >\n setName(e.target.value)}\n value={displayValue}\n />\n \n \n \n \n {button}\n {debug && (\n \n \n \n )}\n {controls && {controls}}\n \n \n \n
\n );\n};\n\nexport default SubmitCode;\n","import { RefObject, useCallback, useDebugValue, useLayoutEffect, useReducer, useRef } from \"react\";\n\ninterface Action {\n type: T;\n}\n\ninterface ValueAction extends Action {\n value: string;\n}\n\nenum Op {\n Delete,\n Append,\n Set,\n Type,\n}\n\ntype Actions =\n | Action\n | ValueAction\n | ValueAction\n | ValueAction;\n\ninterface State {\n cursor: number;\n value: string;\n ref: RefObject;\n}\n\nfunction reducer(state: State, action: Actions): State {\n const { value } = state;\n // make broad assumptions about never having a large cursor selection\n const cursor = state.ref?.current?.selectionStart || 0;\n // console.log({ src: \"ref\", cursor: state.ref?.current?.selectionStart });\n // console.log({ src: \"reducer\", cursor: cursor });\n const cursorAfter = state.ref?.current?.selectionEnd || cursor;\n switch (action.type) {\n case Op.Delete:\n if (cursor !== cursorAfter) {\n return {\n ...state,\n cursor: cursor,\n value: value.slice(0, cursor) + value.slice(cursorAfter, value.length),\n };\n } else if (cursor === 0) {\n return state;\n } else {\n return {\n ...state,\n cursor: cursor - 1,\n value: value.slice(0, cursor - 1) + value.slice(cursor, value.length),\n };\n }\n case Op.Append:\n return {\n ...state,\n cursor: cursor + action.value.length,\n value: value.slice(0, cursor) + action.value + value.slice(cursorAfter, value.length),\n };\n case Op.Set:\n return { ...state, value: action.value, cursor: action.value.length };\n case Op.Type:\n return { ...state, value: action.value };\n }\n}\n\nconst useKeyboard = () => {\n const inputRef = useRef(null);\n const [{ cursor, value }, dispatch] = useReducer(reducer, {\n cursor: 0,\n value: \"\",\n ref: inputRef,\n });\n\n const handleKeyboard = useCallback(\n (char: string) => dispatch({ type: Op.Append, value: char }),\n []\n );\n const handleType = useCallback(\n (e: React.ChangeEvent) => dispatch({ type: Op.Type, value: e.target.value }),\n []\n );\n const handleDelete = useCallback(() => dispatch({ type: Op.Delete }), []);\n const setValue = useCallback((val: string) => dispatch({ type: Op.Set, value: val }), []);\n\n useLayoutEffect(() => {\n // console.log(inputRef?.current?.selectionStart);\n // console.log(cursor);\n // Current hypothesis is that the value can end up getting updated after the element\n // changes. If this happens, then chrome ends up with the cursor stuck at 0 ~half the time\n // Edit: Still broken.\n // setTimeout(() => {\n // I tried both ways (leaving the text focused or not) and blur was a better experience\n // console.log(inputRef?.current?.value);\n const oldFocus = document.activeElement as HTMLInputElement;\n inputRef.current?.focus();\n inputRef.current?.setSelectionRange(cursor, cursor);\n inputRef.current?.blur();\n oldFocus?.focus();\n // console.log(inputRef?.current?.selectionStart);\n // console.log(cursor);\n // }, 0);\n }, [cursor]);\n\n useDebugValue({ cursor: cursor, value: value });\n\n return { handleKeyboard, handleDelete, handleType, setValue, value, ref: inputRef };\n};\n\nexport default useKeyboard;\n","import { KeyboardEvent, RefObject, useCallback, useEffect, useState } from \"react\";\n\nimport {\n Collapse,\n Fade,\n FormControl,\n FormHelperText,\n IconButton,\n InputAdornment,\n InputLabel,\n OutlinedInput,\n Tooltip,\n Typography,\n makeStyles,\n} from \"@material-ui/core\";\nimport BackspaceOutlinedIcon from \"@material-ui/icons/BackspaceOutlined\";\nimport CheckIcon from \"@material-ui/icons/Check\";\n\nconst useStyles = makeStyles((theme) => ({\n label: {\n \"&:not(.MuiInputLabel-shrink)\": {\n [theme.breakpoints.up(\"lg\")]: {\n fontSize: \"2rem\",\n },\n fontSize: \"1.5rem\",\n },\n },\n input: {\n [theme.breakpoints.up(\"lg\")]: {\n fontSize: \"2rem\",\n },\n fontSize: \"1.5rem\",\n \"&> fieldset > legend > span\": {\n fontSize: \"0.75rem\",\n },\n },\n noRightMargin: {\n marginRight: 0,\n },\n helpTextSize: {\n fontSize: \"1rem\",\n [theme.breakpoints.up(\"lg\")]: {\n fontSize: \"1.5rem\",\n },\n },\n}));\n\nexport interface Props {\n inputRef: RefObject;\n value: string;\n onType: (e: React.ChangeEvent) => void;\n onDelete: () => void;\n // optional header stuff\n header?: React.ReactNode;\n onCheck?: (val: string) => void;\n checkDescription?: string;\n\n error?: boolean;\n helpText?: string;\n placeholder?: string;\n headerTooltip?: string;\n}\n\nconst IPAInput = (props: Props) => {\n const classes = useStyles();\n const {\n placeholder = \"Type IPA\",\n value,\n onType,\n onDelete,\n inputRef,\n header,\n onCheck,\n checkDescription,\n error,\n helpText,\n headerTooltip,\n } = props;\n\n const [open, setOpen] = useState(false);\n\n // This should be fine (famous last words...)\n const handleSubmit = useCallback(() => {\n onCheck && onCheck(inputRef.current?.value || \"\");\n }, [onCheck, inputRef]);\n\n const handleEnter = useCallback(\n (e: KeyboardEvent) => {\n if (e.key === \"Enter\") {\n handleSubmit();\n }\n },\n [handleSubmit]\n );\n\n const preventDefault = useCallback((e) => e.preventDefault(), []);\n\n const check = onCheck && (\n \n \n \n \n \n );\n\n const helperText = helpText && (\n \n {helpText}\n \n );\n\n useEffect(() => {\n if (header && headerTooltip) {\n setOpen(true);\n window.setTimeout(() => setOpen(false), 1500);\n }\n }, [header, headerTooltip]);\n\n const headerContent = header && (\n \n {headerTooltip ? (\n {headerTooltip}}\n >\n {header}\n \n ) : (\n header\n )}\n \n );\n\n return (\n \n \n {placeholder}\n \n \n \n \n \n \n \n {check}\n \n }\n startAdornment={headerContent}\n />\n {/* Look into changing this to be a tool tip possibly */}\n \n \n {helperText}\n \n \n \n );\n};\n\nexport default IPAInput;\n","import { Theme, darken, fade, lighten } from \"@material-ui/core/styles\";\n\nexport interface Clickable {\n onClick?: (char: string) => void;\n}\n\nexport const borderColor = (theme: Theme) =>\n theme.palette.type === \"light\"\n ? lighten(fade(theme.palette.divider, 1), 0.88)\n : darken(fade(theme.palette.divider, 1), 0.68);\n\nexport const shadowBorder = (size: string, color: string) => {\n return `${size} 0 0 0 ${color}, 0 ${size} 0 0 ${color}, ${size} ${size} 0 0 ${color}, ${size} 0 0 0 ${color} inset, 0 ${size} 0 0 ${color} inset`;\n};\n","/**\n * Places of articulation\n */\nexport const PLACES = [\n \"Bilabial\",\n \"Labiodental\",\n \"Dental\",\n \"Alveolar\",\n \"Postalveolar\",\n \"Retroflex\",\n \"Palatal\",\n \"Velar\",\n \"Uvular\",\n \"Pharyngeal\",\n \"Glottal\",\n] as const;\n\n/**\n * Manners of articulation\n */\nexport const MANNERS = [\n \"Plosive\",\n \"Nasal\",\n \"Trill\",\n \"Tap\",\n \"Fricative\",\n \"Lateral fricative\",\n \"Approximant\",\n \"Lateral approximant\",\n] as const;\n\nexport type PlaceOfArt = typeof PLACES[number];\nexport type MannerOfArt = typeof MANNERS[number];\n\n// The sounds that are either impossible or not used\nexport const IMPOSSIBLE = \"_\";\nconst IMP = IMPOSSIBLE;\nexport const NOT_USED = \"\";\nconst NUL = NOT_USED;\n\n// prettier-ignore\nexport const PULMONICS = [\n [\"p\", \"b\", NUL, NUL, NUL, NUL, \"t\", \"d\", NUL, NUL, \"ʈ\", \"ɖ\", \"c\", \"ɟ\", \"k\", \"g\", \"q\", \"ɢ\", NUL, IMP, \"ʔ\", IMP],\n [NUL, \"m\", NUL, \"ɱ\", NUL, NUL, NUL, \"n\", NUL, NUL, NUL, \"ɳ\", NUL, \"ɲ\", NUL, \"ŋ\", NUL, \"ɴ\", IMP, IMP, IMP, IMP],\n [NUL, \"ʙ\", NUL, NUL, NUL, NUL, NUL, \"r\", NUL, NUL, NUL, NUL, NUL, NUL, IMP, IMP, NUL, \"ʀ\", NUL, NUL, IMP, IMP],\n [NUL, NUL, NUL, \"ⱱ\", NUL, NUL, NUL, \"ɾ\", NUL, NUL, NUL, \"ɽ\", NUL, NUL, IMP, IMP, NUL, NUL, NUL, NUL, IMP, IMP],\n [\"ɸ\", \"β\", \"f\", \"v\", \"θ\", \"ð\", \"s\", \"z\", \"ʃ\", \"ʒ\", \"ʂ\", \"ʐ\", \"ç\", \"ʝ\", \"x\", \"ɣ\", \"χ\", \"ʁ\", \"ħ\", \"ʕ\", \"h\", \"ɦ\"],\n [IMP, IMP, IMP, IMP, NUL, NUL, \"ɬ\", \"ɮ\", NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, NUL, IMP, IMP, IMP, IMP],\n [NUL, NUL, NUL, \"ʋ\", NUL, NUL, NUL, \"ɹ\", NUL, NUL, NUL, \"ɻ\", NUL, \"j\", NUL, \"ɰ\", NUL, NUL, NUL, NUL, IMP, IMP],\n [IMP, IMP, IMP, IMP, NUL, NUL, NUL, \"l\", NUL, NUL, NUL, \"ɭ\", NUL, \"ʎ\", NUL, \"ʟ\", NUL, NUL, IMP, IMP, IMP, IMP]\n] as const;\n\nexport const CLICKS = [\n [\"ʘ\", \"Bilabial\"],\n [\"ǀ\", \"Dental\"],\n [\"ǃ\", \"(Post)alveolar\"],\n [\"ǂ\", \"Palatoalveolar\"],\n [\"ǁ\", \"Alveolar lateral\"],\n] as const;\n\nexport const IMPLOSIVES = [\n [\"ɓ\", \"Bilabial\"],\n [\"ɗ\", \"Dental/alveolar\"],\n [\"ʄ\", \"Palatal\"],\n [\"ɠ\", \"Velar\"],\n [\"ʛ\", \"Uvular\"],\n] as const;\n\n// U+02BC\nexport const EJECTIVE = \"ʼ\";\n\nexport const EJECTIVES = [\n [\"ʼ\", \"Examples:\"],\n [\"pʼ\", \"Bilabial\"],\n [\"tʼ\", \"Dental/alveolar\"],\n [\"kʼ\", \"Velar\"],\n [\"sʼ\", \"Alveolar fricative\"],\n] as const;\n\nexport const FILLER = \"◌\";\n\nexport const VOWEL_HEIGHTS = [\"Close\", \"Close-mid\", \"Open-mid\", \"Open\"] as const;\nexport const VOWEL_FRONTEDNESS = [\"Front\", \"Central\", \"Back\"] as const;\n\nexport type VowelLiteral = readonly [string, string] | string;\nexport type Coords = readonly [number, number];\n\ntype VowelCoords = readonly (readonly [VowelLiteral, Coords])[];\n\n/**\n * Associative array of Vowel pairs and ~coordinates\n *\n * Coords are specified on the range [0, 1]\n * x = frontedness\n * y = height\n *\n * Upper left (close front) is origin. Everything is translated afterwards to be\n * in the trapezium shape\n */\n// prettier-ignore\nexport const VOWELS: VowelCoords = [\n // Close vowels\n [[\"i\", \"y\"], [0, 0]],\n [[\"ɨ\", \"ʉ\"], [0.5, 0]],\n [[\"ɯ\", \"u\"], [1, 0]],\n\n // Near close vowels\n [[\"ɪ\", \"ʏ\"], [0.2, 1/6]],\n [[\"\", \"ʊ\"], [0.75, 1/6]],\n\n // Close-mid\n [[\"e\", \"ø\"], [0, 1/3]],\n [[\"ɘ\", \"ɵ\"], [0.5, 1/3]],\n [[\"ɤ\", \"o\"], [1, 1/3]],\n\n // Mid\n [\"ə\", [0.5, 0.5]],\n\n // Open-mid\n [[\"ɛ\", \"œ\"], [0, 2/3]],\n [[\"ɜ\", \"ɞ\"], [0.5, 2/3]],\n [[\"ʌ\", \"ɔ\"], [1, 2/3]],\n\n // Near-open\n [[\"æ\", \"\"], [0, 5/6]],\n [\"ɐ\", [0.5, 5/6]],\n\n // Open\n [[\"a\", \"ɶ\"], [0, 1]],\n [[\"ɑ\", \"ɒ\"], [1, 1]],\n];\n\nexport const STRESS = \"ˈ\";\nexport const SECONDARY_STRESS = \"ˌ\";\n\ninterface MiscChar {\n ipa: string;\n sym?: string;\n description: string;\n examples?: readonly string[];\n}\n\nexport type MiscList = readonly Readonly[];\n\nexport const DIACRITICS: MiscList = [\n { ipa: \"\\u0325\", description: \"Voiceless\", examples: [\"n\", \"d\"] },\n { ipa: \"\\u032C\", description: \"Voiced\", examples: [\"s\", \"t\"] },\n { ipa: \"\\u02B0\", description: \"Aspirated\", examples: [\"t\", \"d\"] },\n { ipa: \"\\u0339\", description: \"More rounded\", examples: [\"ɔ\"] },\n { ipa: \"\\u031C\", description: \"Less rounded\", examples: [\"ɔ\"] },\n { ipa: \"\\u031F\", description: \"Advanced\", examples: [\"u\"] },\n { ipa: \"\\u0320\", description: \"Retracted\", examples: [\"e\"] },\n { ipa: \"\\u0308\", description: \"Centralized\", examples: [\"e\"] },\n { ipa: \"\\u033D\", description: \"Mid-centralized\", examples: [\"e\"] },\n { ipa: \"\\u0329\", description: \"Syllabic\", examples: [\"n\"] },\n { ipa: \"\\u032F\", description: \"Non-syllabic\", examples: [\"n\"] },\n { ipa: \"\\u02DE\", description: \"Rhoticity\", examples: [\"ə\", \"a\"] },\n { ipa: \"\\u0324\", description: \"Breathy voiced\", examples: [\"b\", \"a\"] },\n { ipa: \"\\u0330\", description: \"Creaky voiced\", examples: [\"b\", \"a\"] },\n { ipa: \"\\u033C\", description: \"Linguolabial\", examples: [\"t\", \"d\"] },\n { ipa: \"\\u02B7\", description: \"Labialized\", examples: [\"t\", \"d\"] },\n { ipa: \"\\u02B2\", description: \"Palatalized\", examples: [\"t\", \"d\"] },\n { ipa: \"\\u02E0\", description: \"Velarized\", examples: [\"t\", \"d\"] },\n { ipa: \"\\u02E4\", description: \"Pharyngealized\", examples: [\"t\", \"d\"] },\n\n { ipa: \"\\u032A\", description: \"Dental\", examples: [\"t\", \"d\"] },\n { ipa: \"\\u033A\", description: \"Apical\", examples: [\"t\", \"d\"] },\n { ipa: \"\\u033B\", description: \"Laminal\", examples: [\"t\", \"d\"] },\n { ipa: \"\\u0303\", description: \"Nasalized\", examples: [\"e\"] },\n { ipa: \"\\u207F\", description: \"Nasal release\", examples: [\"d\"] },\n { ipa: \"\\u02E1\", description: \"Lateral release\", examples: [\"d\"] },\n { ipa: \"\\u031A\", description: \"No audible release\", examples: [\"d\"] },\n\n { ipa: \"\\u0334\", description: \"Velarized or pharyngealized\", examples: [\"l\"] },\n\n { ipa: \"\\u031D\", description: \"Raised\", examples: [\"e\"] },\n { ipa: \"\\u031E\", description: \"Lowered\", examples: [\"e\"] },\n { ipa: \"\\u0318\", description: \"Advanced tongue root\", examples: [\"e\"] },\n { ipa: \"\\u0319\", description: \"Retracted tongue root\", examples: [\"e\"] },\n];\n\nexport const MISC: MiscList = [\n {\n ipa: \"\\u0361\",\n sym: `${FILLER}\\u0361${FILLER}`,\n description: \"Tie bar\",\n examples: [\"t͡ʃ\", \"d͡ʒ\"],\n },\n { ipa: \"w\", sym: \"w\", description: \"Voiced labial-velar approximant\" },\n { ipa: \"ʍ\", sym: \"ʍ\", description: \"Voiceless labial-velar fricative\" },\n { ipa: \"ɥ\", sym: \"ɥ\", description: \"Voiced labial-palatal approximant\" },\n { ipa: \"ʜ\", sym: \"ʜ\", description: \"Voiceless epiglottal fricative\" },\n { ipa: \"ʢ\", sym: \"ʢ\", description: \"Voiced epiglottal fricative\" },\n { ipa: \"ʡ\", sym: \"ʡ\", description: \"Epiglottal plosive\" },\n { ipa: \"ɺ\", sym: \"ɺ\", description: \"Voiced alveolar lateral flap\" },\n { ipa: \"ɕ\", sym: \"ɕ\", description: \"Voiceless alveolo-palatal fricative\" },\n { ipa: \"ʑ\", sym: \"ʑ\", description: \"Voiced alveolo-palatal fricative\" },\n { ipa: \"ɧ\", sym: \"ɧ\", description: \"Simultaneous ʃ and x\" },\n] as const;\n\nexport const SUPRASEGMENTALS: MiscList = [\n { ipa: STRESS, sym: STRESS, description: \"Primary stress\" },\n { ipa: SECONDARY_STRESS, sym: SECONDARY_STRESS, description: \"Secondary stress\" },\n { ipa: \"ː\", sym: \"ː\", description: \"Long\", examples: [\"eː\"] },\n { ipa: \"ˑ\", sym: \"ˑ\", description: \"Half-long\", examples: [\"eˑ\"] },\n { ipa: \"\\u0306\", sym: `${FILLER}\\u0306`, description: \"Extra-short\", examples: [\"e\\u0306\"] },\n { ipa: \"|\", sym: \"|\", description: \"Minor (foot) group\" },\n { ipa: \"‖\", sym: \"‖\", description: \"Major (intonation) group\" },\n { ipa: \".\", sym: \".\", description: \"Syllable break\" },\n { ipa: \"‿\", sym: \"‿\", description: \"Linking (absence of break)\" },\n] as const;\n","import { memo, useCallback } from \"react\";\n\nimport clsx from \"clsx\";\nimport { Clickable, borderColor } from \"./common\";\n\nimport {\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n} from \"@material-ui/core\";\nimport { makeStyles } from \"@material-ui/core/styles\";\n\nimport { IMPOSSIBLE, MANNERS, NOT_USED, PLACES, PULMONICS } from \"../../utils/ipa\";\n\nconst useStyles = makeStyles((theme) => ({\n voiceless: {\n cursor: \"pointer\",\n \"&:hover\": {\n backgroundColor: theme.palette.action.hover,\n },\n },\n voiced: {\n cursor: \"pointer\",\n \"&:hover\": {\n backgroundColor: theme.palette.action.hover,\n },\n },\n impossible: {\n backgroundColor: theme.palette.action.disabledBackground,\n color: \"transparent\",\n cursor: \"default\",\n \"&:hover\": {\n backgroundColor: theme.palette.action.disabledBackground,\n },\n },\n symbol: {\n padding: theme.spacing(0, 0.5),\n userSelect: \"none\",\n fontSize: \"1.5rem\",\n },\n leftSideBorder: {\n borderLeft: `1px solid ${borderColor(theme)}`,\n },\n rightSideBorder: {\n borderRight: `1px solid ${borderColor(theme)}`,\n },\n caps: {\n padding: \"6px 5.5px\",\n },\n header: {\n minWidth: \"56px\",\n borderLeft: `1px solid ${borderColor(theme)}`,\n borderRight: `1px solid ${borderColor(theme)}`,\n },\n}));\n\ninterface Props extends Clickable {}\n\nconst Pulmonics = (props: Props) => {\n const classes = useStyles();\n const { onClick } = props;\n const clickCallback = useCallback(\n (char) =>\n (char !== IMPOSSIBLE && char !== NOT_USED && onClick && (() => onClick(char))) || undefined,\n [onClick]\n );\n\n const preventDefault = useCallback((e) => e.preventDefault(), []);\n\n // TODO: Fix this at some point\n const Cell = useCallback(\n ({ x, y }: { x: number; y: number }) => {\n const voiceless = PULMONICS[y]?.[x * 2];\n const voiced = PULMONICS[y]?.[x * 2 + 1];\n\n const hasBorders = x < 2 || x > 4 || y === 4;\n\n return (\n <>\n \n {voiceless}\n \n \n {voiced}\n \n \n );\n },\n [classes, clickCallback, preventDefault]\n );\n\n return (\n \n \n \n \n {/* Filler for articulation row */}\n {PLACES.map((place) => (\n \n {place}\n \n ))}\n \n \n \n {MANNERS.map((manner, y) => (\n \n {manner}\n {PLACES.map((place, x) => (\n \n ))}\n \n ))}\n \n
\n
\n );\n};\n\nexport default memo(Pulmonics);\n","import { memo, useCallback, useMemo } from \"react\";\n\nimport { Clickable, borderColor } from \"./common\";\n\nimport {\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n} from \"@material-ui/core\";\nimport { makeStyles } from \"@material-ui/core/styles\";\nimport { CLICKS, EJECTIVES, IMPLOSIVES } from \"../../utils/ipa\";\n\nconst useStyles = makeStyles((theme) => ({\n symbol: {\n padding: theme.spacing(0.75, 1),\n textAlign: \"center\",\n userSelect: \"none\",\n fontSize: \"1.5rem\",\n cursor: \"pointer\",\n \"&:hover\": {\n backgroundColor: theme.palette.action.hover,\n },\n borderLeft: `1px solid ${borderColor(theme)}`,\n },\n descr: {\n fontSize: \"0.8rem\",\n verticalAlign: \"middle\",\n padding: theme.spacing(0, 0.5),\n borderRight: `1px solid ${borderColor(theme)}`,\n },\n header: {\n padding: theme.spacing(0.75, 1.5),\n borderLeft: `1px solid ${borderColor(theme)}`,\n borderRight: `1px solid ${borderColor(theme)}`,\n },\n}));\n\ninterface Props extends Clickable {}\n\nconst NonPulmonics = (props: Props) => {\n const classes = useStyles();\n const { onClick = () => {} } = props;\n\n const sounds = useMemo(() => {\n return CLICKS.map((click, i) => [click, IMPLOSIVES[i], EJECTIVES[i]]);\n }, []);\n\n const preventDefault = useCallback((e) => e.preventDefault(), []);\n\n const Cell = useCallback(\n ({ symbol, name }: { symbol: string; name: string }) => {\n return (\n <>\n onClick(symbol)}\n onMouseDown={preventDefault}\n >\n {symbol}\n \n {name}\n \n );\n },\n [classes, onClick, preventDefault]\n );\n\n return (\n \n \n \n \n \n \n \n \n Clicks\n \n \n Voiced implosives\n \n \n Ejectives\n \n \n \n \n {sounds.map((row, i) => (\n \n {row.map(([symbol, name], j) => (\n \n ))}\n \n ))}\n \n
\n
\n );\n};\n\nexport default memo(NonPulmonics);\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nimport * as React from \"react\";\n\nvar _ref = /*#__PURE__*/React.createElement(\"g\", {\n strokeWidth: 4,\n fill: \"none\",\n strokeLinecap: \"butt\",\n strokeLinejoin: \"miter\"\n}, /*#__PURE__*/React.createElement(\"path\", {\n d: \"M24 17.74l950.68-.94L976 683.2l-477.16-1.23L24 17.74zM499.85 17.74l235.9 664.23M183.29 239.78l791.4-.94\"\n}), /*#__PURE__*/React.createElement(\"path\", {\n d: \"M343.58 461.81l629.09-1.88h1V459\"\n}));\n\nfunction SvgTrapezium({\n title,\n titleId,\n ...props\n}, svgRef) {\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n xmlns: \"http://www.w3.org/2000/svg\",\n viewBox: \"0 0 1000 700\",\n preserveAspectRatio: \"none\",\n fillRule: \"evenodd\",\n clipRule: \"evenodd\",\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _ref);\n}\n\nconst ForwardRef = /*#__PURE__*/React.forwardRef(SvgTrapezium);\nexport default __webpack_public_path__ + \"static/media/trapezium.dacff88a.svg\";\nexport { ForwardRef as ReactComponent };","import { memo, useCallback, useMemo } from \"react\";\nimport clsx from \"clsx\";\nimport { Clickable } from \"./common\";\n\nimport { Box, Grid, Typography } from \"@material-ui/core\";\nimport { makeStyles } from \"@material-ui/core/styles\";\nimport { Coords, VOWELS, VOWEL_FRONTEDNESS, VOWEL_HEIGHTS, VowelLiteral } from \"../../utils/ipa\";\n\nimport { ReactComponent as Trapezium } from \"./trapezium.svg\";\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n width: \"100%\",\n height: \"100%\",\n },\n outerQuad: {\n padding: theme.spacing(1, 3),\n fontSize: \"1.5rem\",\n position: \"relative\",\n height: \"100%\",\n minHeight: \"275px\",\n minWidth: \"270px\",\n },\n fullRel: {\n height: \"100%\",\n width: \"100%\",\n position: \"relative\",\n },\n trapezium: {\n position: \"absolute\",\n height: \"100%\",\n width: \"100%\",\n stroke: theme.palette.text.primary,\n },\n quad: {\n position: \"absolute\",\n height: \"95%\",\n width: \"95%\",\n left: \"2.5%\",\n top: \"2.75%\",\n },\n element: {\n userSelect: \"none\",\n cursor: \"default\",\n position: \"absolute\",\n transform: \"translate(-50%, -50%)\",\n overflow: \"visible\",\n width: \"1.2em\",\n textAlign: \"center\",\n },\n rounded: {\n position: \"absolute\",\n width: \"1.2em\",\n left: \"0.75em\",\n },\n unrounded: {\n position: \"absolute\",\n width: \"1.2em\",\n right: \"0.75em\",\n },\n mid: {\n width: \"100%\",\n },\n symbol: {\n display: \"inline-block\",\n cursor: \"pointer\",\n \"&:hover\": {\n borderRadius: \"3px\",\n backgroundColor: theme.palette.action.hover,\n },\n },\n paperBack: {\n \"&::before\": {\n zIndex: \"-1\",\n left: \"0\",\n content: \"''\",\n borderRadius: \"3px\",\n position: \"absolute\",\n display: \"inline-block\",\n width: \"1.2em\",\n height: \"100%\",\n backgroundColor: theme.palette.background.paper,\n },\n },\n fullHeight: {\n height: \"100%\",\n },\n vowelPos: {\n padding: theme.spacing(0, 2),\n },\n vowelHeight: {\n padding: theme.spacing(0.5, 0),\n },\n}));\n\ninterface Props extends Clickable {}\n\nconst vowelCoords = ([x, y]: Coords): { left: string; top: string } => {\n const offset = y * 0.5;\n const val = offset + (1 - offset) * x;\n return { left: `${val * 100}%`, top: `${y * 100}%` };\n};\n\n/**\n * Vowel chart\n */\nconst Vowels = (props: Props) => {\n const classes = useStyles();\n const { onClick = () => {} } = props;\n\n const preventDefault = useCallback((e) => e.preventDefault(), []);\n\n const VowelElement = useCallback(\n ({ vowels, coords }: { vowels: VowelLiteral; coords: Coords }) => {\n if (typeof vowels === \"string\") {\n return (\n \n onClick(vowels)}\n onMouseDown={preventDefault}\n >\n {vowels}\n \n \n );\n } else {\n const noCenter = vowels.join(\"\").length < 2;\n // Zero width space or dot\n const center = noCenter ? \"\\u00A0\" : \"•\";\n return (\n \n {center}\n onClick(vowels[0])}\n onMouseDown={preventDefault}\n >\n {vowels[0]}\n \n onClick(vowels[1])}\n onMouseDown={preventDefault}\n >\n {vowels[1]}\n \n \n );\n }\n },\n [classes, onClick, preventDefault]\n );\n\n const vowelChart = useMemo(\n () => (\n \n
\n \n
\n {VOWELS.map(([vowels, coords]) => (\n \n ))}\n
\n
\n
\n ),\n [classes, VowelElement]\n );\n\n return (\n \n \n \n \n \n ​\n \n \n \n {VOWEL_HEIGHTS.map((height) => (\n \n {height}\n \n ))}\n \n \n \n \n \n \n \n \n {VOWEL_FRONTEDNESS.map((pos) => (\n \n {pos}\n \n ))}\n \n \n \n {vowelChart}\n \n \n \n \n \n );\n};\n\nexport default memo(Vowels);\n","import { memo, useCallback } from \"react\";\nimport { Clickable, borderColor, shadowBorder } from \"./common\";\n\nimport { Grid, GridProps } from \"@material-ui/core\";\nimport { makeStyles } from \"@material-ui/core/styles\";\nimport { MiscList } from \"../../utils/ipa\";\n\nconst useStyles = makeStyles((theme) => ({\n root: {\n width: \"100%\",\n height: \"100%\",\n },\n symbol: {\n userSelect: \"none\",\n textAlign: \"center\",\n cursor: \"pointer\",\n fontSize: \"1.5rem\",\n \"&:hover\": {\n backgroundColor: theme.palette.action.hover,\n },\n },\n description: {\n padding: \"2px\",\n fontSize: \"0.8rem\",\n },\n descriptionParent: {\n display: \"flex\",\n justifyContent: \"center\",\n flexDirection: \"column\",\n height: \"100%\",\n },\n bordered: {\n boxShadow: shadowBorder(\"1px\", borderColor(theme)),\n },\n}));\n\ntype Breakpoints = Pick;\n\ninterface Props extends Clickable {\n content: MiscList;\n genSym?: (ipa: string) => string;\n breakpoints?: Breakpoints;\n combine?: boolean;\n}\n\nconst GridDisplay = (props: Props) => {\n const classes = useStyles();\n const { onClick = () => {}, content, breakpoints = {}, genSym = (ipa) => ipa, combine } = props;\n const preventDefault = useCallback((e) => e.preventDefault(), []);\n\n return (\n \n {content.map(({ ipa, sym, description, examples }) => (\n \n \n onClick(ipa)}\n onMouseDown={preventDefault}\n >\n {sym || genSym(ipa)}\n \n \n
\n
{description}
\n
\n
\n {/* Forgive me father, for I have sinned. I never should have used this much indentation */}\n {examples?.map((char) => {\n const combined = combine ? `${char}${ipa}` : char;\n return (\n onClick(combined)}\n onMouseDown={preventDefault}\n >\n {combined}\n
\n );\n })}\n
\n \n ))}\n \n );\n};\n\nexport default memo(GridDisplay);\n","import { memo } from \"react\";\nimport { Clickable } from \"./common\";\nimport { DIACRITICS, FILLER } from \"../../utils/ipa\";\nimport GridDisplay from \"./GridDisplay\";\n\nconst Diacritics = (props: Clickable) => {\n return (\n `${FILLER}${ipa}`}\n combine\n />\n );\n};\n\nexport default memo(Diacritics);\n","import { memo } from \"react\";\nimport { Clickable } from \"./common\";\nimport { MISC } from \"../../utils/ipa\";\nimport GridDisplay from \"./GridDisplay\";\n\nconst Other = (props: Clickable) => {\n return ;\n};\n\nexport default memo(Other);\n","import { memo } from \"react\";\nimport { Clickable } from \"./common\";\nimport { SUPRASEGMENTALS } from \"../../utils/ipa\";\nimport GridDisplay from \"./GridDisplay\";\n\nconst Suprasegmentals = (props: Clickable) => {\n return (\n \n );\n};\n\nexport default memo(Suprasegmentals);\n","import { memo } from \"react\";\nimport { Grid, Paper, Typography, makeStyles } from \"@material-ui/core\";\n\nimport Pulmonics from \"./Pulmonics\";\nimport { Clickable } from \"./common\";\nimport NonPulmonics from \"./NonPulmonics\";\nimport Vowels from \"./Vowels\";\nimport Diacritics from \"./Diacritics\";\nimport { CSSProperties } from \"@material-ui/core/styles/withStyles\";\nimport Other from \"./Other\";\nimport Suprasegmentals from \"./Suprasegmentals\";\n\n// import BackspaceOutlinedIcon from \"@material-ui/icons/BackspaceOutlined\";\n\nconst useStyles = makeStyles((theme) => ({\n paper: {\n padding: theme.spacing(1),\n height: \"100%\",\n },\n childOrder: {\n // Allow reordering the children of this element.\n // This has the additional benefit of allowing an \"IPA\" setting\n // On larger screens, show \"other\" left of \"vowels\"\n [theme.breakpoints.up(\"md\")]: orderChildren(1, 3, 2),\n },\n}));\n\nconst orderChildren = (...children: number[]) => {\n let styles: CSSProperties = { \"& > *\": { order: 100 } };\n children.forEach((child, i) => {\n styles[`& > :nth-child(${i + 1})`] = { order: child };\n });\n return styles;\n};\n\ninterface Props extends Clickable {}\n\n/**\n * Accepts an onClick option. This is assumed to be memoized.\n */\nconst Keyboard = (props: Props) => {\n const classes = useStyles();\n const { onClick } = props;\n\n return (\n // 1\n \n \n \n \n Consonants (Pulmonics)\n \n \n \n Symbols to the right in a cell are voiced, to the left are voiceless. Shaded areas\n denote articulations judged impossible.\n \n \n \n {/* 2 */}\n \n \n \n \n \n {/* 3 */}\n \n \n \n Other\n \n \n \n \n\n \n \n \n Diacritics\n \n \n \n \n\n \n \n \n Suprasegmentals\n \n \n \n \n\n {/* Ugh... non-pulmonics are the worst... */}\n \n \n \n Consonants (Non-pulmonics)\n \n \n \n \n\n {/* Placeholder for adding phonology symbols? */}\n \n \n );\n};\n\nexport default memo(Keyboard);\n","import { Box, Grid, Paper, makeStyles, useTheme } from \"@material-ui/core\";\n\nimport IPAInput, { Props as InputProps } from \"./IPAInput\";\nimport useKeyboard from \"./useKeyboard\";\n\n// const Keyboard = React.lazy(() => import(\"./Keyboard\"));\nimport Keyboard from \"./Keyboard\";\n\nconst useStyles = makeStyles((theme) => ({\n sticky: {\n pointerEvents: \"none\", // Prevent background centering overlapping content\n zIndex: 10,\n position: \"sticky\",\n top: `${theme.spacing(-1)}px`,\n marginBottom: `${theme.spacing(theme.palette.type === \"dark\" ? 0 : 1)}px`,\n },\n input: {\n pointerEvents: \"auto\", // Restore pointer events\n backgroundColor:\n theme.palette.type === \"dark\"\n ? theme.palette.background.default\n : theme.palette.background.paper,\n borderRadius: \"8px\",\n },\n}));\n\ninterface Props extends InputProps {\n handleKeyboard: ReturnType[\"handleKeyboard\"];\n}\n\nconst StickyIPA = (props: Props) => {\n const theme = useTheme();\n const classes = useStyles();\n\n const { handleKeyboard, ...inputProps } = props;\n\n // Testing revealed an elevated paper was preferred in light mode and contrastive flat in dark mode\n const elevation = theme.palette.type === \"dark\" ? 0 : 3;\n\n return (\n
\n \n \n \n \n \n \n \n\n \n
\n );\n};\n\nexport default StickyIPA;\n","import { useCallback, useEffect, useMemo, useReducer } from \"react\";\n\nimport { makeStyles } from \"@material-ui/core\";\n\nimport useKeyboard from \"../keyboard/useKeyboard\";\nimport StickyIPA from \"../keyboard/StickyIPA\";\n\nimport { Word, matchSegment } from \"../../utils/parsers/task\";\nimport { useDebugContext } from \"../../utils/Debug\";\n\nconst ATTEMPTS_BEFORE_HINT = 5;\n\nconst useStyles = makeStyles((theme) => ({\n correct: {\n color: theme.palette.type === \"dark\" ? theme.palette.success.main : theme.palette.success.dark,\n },\n}));\n\ninterface Props {\n word: Word;\n onSubmit: () => void;\n}\n\nenum Op {\n Reset,\n SoftReset,\n SetHeader,\n NextSegment,\n ErrorMessage,\n ClearError,\n}\n\ninterface State {\n word: Word;\n segment: number;\n header: string;\n errorMessage?: string;\n error: boolean;\n attempt: number;\n}\n\ninterface Action {\n type: T;\n}\n\ninterface SetAction extends Action {\n value: V;\n}\n\ntype Act =\n | SetAction\n | SetAction\n | SetAction\n | SetAction\n | SetAction\n | Action;\n\nconst reset = (word: Word) => {\n return {\n word,\n segment: 0,\n header: \"\",\n error: false,\n attempt: 0,\n };\n};\n\nconst reducer = (state: State, action: Act): State => {\n switch (action.type) {\n case Op.SoftReset:\n return Object.is(action.value, state.word) ? state : reset(action.value);\n case Op.Reset:\n return reset(action.value);\n case Op.SetHeader:\n return { ...state, header: action.value };\n case Op.NextSegment: // Inc segment and add value to header\n return {\n ...state,\n segment: state.segment + 1,\n header: state.header + action.value,\n attempt: 0,\n };\n case Op.ClearError:\n return state.error ? { ...state, error: false } : state;\n case Op.ErrorMessage:\n const { attempt } = state;\n const { hint } = state.word.segments[state.segment];\n // if the user has failed too many times, display the hint instead of error message if it exists\n const errorMessage = attempt >= ATTEMPTS_BEFORE_HINT && hint ? hint : action.value;\n return { ...state, error: true, errorMessage, attempt: attempt + 1 };\n }\n};\n\nconst WordInput = (props: Props) => {\n const classes = useStyles();\n const debug = useDebugContext();\n\n const { word, onSubmit: handleSubmit } = props;\n const { handleKeyboard, handleDelete, handleType, setValue, value, ref } = useKeyboard();\n const [state, dispatch] = useReducer(reducer, word, reset);\n\n useEffect(() => dispatch({ type: Op.SoftReset, value: word }), [word]);\n useEffect(() => dispatch({ type: Op.ClearError }), [value]);\n\n // Run validation logic. If the\n const handleCheck = useCallback(\n (currentValue: string) => {\n // Make life easier with debug mode\n if (debug && currentValue === \"winston\") {\n setValue(\"\");\n dispatch({ type: Op.SetHeader, value: currentValue });\n handleSubmit();\n return;\n }\n\n // IDEA: add an optional \"accept_multiple\" that will allow submission\n // of multiple segments at once.\n const segment = word.segments[state.segment];\n const match = matchSegment(currentValue, segment);\n if (match.correct) {\n dispatch({ type: Op.NextSegment, value: currentValue });\n setValue(\"\"); // Clear the text box\n if (segment.final) {\n handleSubmit();\n }\n } else {\n // If not a match, set the error text\n dispatch({ type: Op.ErrorMessage, value: match.message });\n }\n },\n [word, state.segment, setValue, handleSubmit, debug]\n );\n\n const { header, error, errorMessage } = state;\n\n const headerValue = useMemo(\n () => header && {header},\n [header, classes.correct]\n );\n\n return (\n \n );\n};\n\nexport default WordInput;\n","import {\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogContentText,\n DialogTitle,\n} from \"@material-ui/core\";\n\nexport interface Props {\n open: boolean;\n onClose: (confirm: boolean) => void;\n title: string;\n body: string;\n}\n\nconst ConfirmDialog = (props: Props) => {\n const { onClose, open, title, body } = props;\n\n const handleCancel = () => {\n onClose(false);\n };\n\n const handleOk = () => {\n onClose(true);\n };\n\n return (\n \n {title}\n \n {body}\n \n \n \n \n \n \n );\n};\n\nexport default ConfirmDialog;\n","import { memo } from \"react\";\nimport { Button, Tooltip } from \"@material-ui/core\";\nimport PlayCircleFilledIcon from \"@material-ui/icons/PlayCircleFilled\";\n\ninterface Props {\n baseUrl: string;\n file?: string;\n}\n\nconst PlayButton = (props: Props) => {\n const { file, baseUrl } = props;\n\n // hey, it's easier just to use the function than figure it out...\n const audioFile = (() => {\n if (file) {\n const audioUrl = new URL(file, baseUrl).toString();\n const element = new Audio(audioUrl);\n return element;\n }\n })();\n\n const playAudio = () => {\n if (audioFile) {\n try {\n audioFile.currentTime = 0;\n audioFile.play().catch((e) => {\n console.error({ message: \"unable to play url\", src: audioFile.src, err: e });\n });\n } catch (e) {\n console.error({ message: \"unable to play url\", src: audioFile.src, err: e });\n }\n }\n };\n\n // A more robust method would be checking if the audio file loads, but there's no easy way\n // to check this until after the play button is pressed.\n const disable = !audioFile;\n\n return (\n \n
\n }\n onClick={playAudio}\n disabled={disable}\n >\n Play\n \n
\n
\n );\n};\n\nexport default memo(PlayButton);\n","import { memo } from \"react\";\n\nimport { Paper, makeStyles } from \"@material-ui/core\";\n\nconst useStyles = makeStyles((theme) => ({\n codeBlock: {\n fontSize: \"1rem\",\n padding: `${theme.spacing(1)}px`,\n },\n inline: {\n padding: theme.spacing(0.25, 0.5),\n \"pre &\": {\n padding: 0,\n boxShadow: \"none\",\n borderRadius: 0,\n },\n },\n}));\n\ninterface Props {\n block?: boolean;\n children: React.ReactNode;\n}\n\nconst CodeBlock = (props: Props) => {\n const classes = useStyles();\n const { block, children } = props;\n\n const comp = block ? \"pre\" : \"code\";\n const klass = block ? classes.codeBlock : classes.inline;\n\n return (\n \n {children}\n \n );\n};\n\nexport default memo(CodeBlock);\n","import { memo } from \"react\";\nimport Md from \"markdown-to-jsx\";\nimport { Checkbox, Link, LinkProps, Typography, TypographyProps } from \"@material-ui/core\";\nimport AppLink from \"./Link\";\nimport CodeBlock from \"./CodeBlock\";\n\ntype AnyURL = string | URL;\n\nconst URL_PATTERN = /^(https?:)?\\/\\//i;\n\ninterface Props {\n baseUrl?: AnyURL;\n paragraph?: Var;\n children: string;\n allowTags?: boolean;\n}\n\ntype Var = TypographyProps[\"variant\"];\n\nconst typeTag = (v: Var) =>\n ({\n component: Typography,\n props: { variant: v, component: \"p\", gutterBottom: true },\n } as const);\n\ninterface ImgProps extends React.ImgHTMLAttributes {\n baseUrl?: AnyURL;\n}\n\nconst RelativeImg = (props: ImgProps) => {\n const { baseUrl, src, ...imgProps } = props;\n const imgSrc = baseUrl && src ? new URL(src, baseUrl).toString() : src;\n // eslint-disable-next-line\n return ;\n};\n\nconst SmartLink = (props: LinkProps) => {\n const { href, ...rest } = props;\n if (href?.match(URL_PATTERN)) {\n return ;\n } else {\n return ;\n }\n};\n\nconst CustomInput = (props: React.ComponentProps<\"input\">) => {\n if (props.type === \"checkbox\") {\n return ;\n } else {\n return ;\n }\n};\n\nconst Markdown = (props: Props) => {\n const { children, baseUrl, allowTags, paragraph = \"body1\" } = props;\n const options = {\n disableParsingRawHTML: !allowTags,\n forceBlock: true,\n overrides: {\n img: { component: RelativeImg, props: { baseUrl } },\n h1: typeTag(\"h1\"),\n h2: typeTag(\"h2\"),\n h3: typeTag(\"h3\"),\n h4: typeTag(\"h4\"),\n h5: typeTag(\"h5\"),\n h6: typeTag(\"h6\"),\n p: typeTag(paragraph),\n a: { component: SmartLink },\n pre: { component: CodeBlock, props: { block: true } },\n code: { component: CodeBlock },\n input: { component: CustomInput },\n },\n };\n\n return ;\n};\n\nexport default memo(Markdown);\n","import { memo, useCallback, useEffect, useReducer, useState } from \"react\";\nimport {\n Box,\n Button,\n Collapse,\n Dialog,\n DialogActions,\n DialogContent,\n DialogContentText,\n DialogTitle,\n Grid,\n IconButton,\n ListSubheader,\n Menu,\n MenuItem,\n Typography,\n} from \"@material-ui/core\";\nimport MoreVertIcon from \"@material-ui/icons/MoreVert\";\n\nimport { useDebugContext } from \"../../utils/Debug\";\nimport { TaskDef } from \"../../utils/parsers/task\";\n\nimport SubmitCode from \"./SubmitCode\";\nimport WordInput from \"./WordInput\";\nimport ConfirmDialog from \"../ConfirmDialog\";\nimport { usePersistentState } from \"../../utils/usePersistentState\";\nimport PlayButton from \"./PlayButton\";\n\nimport Markdown from \"../Markdown\";\n\ninterface TaskProps {\n baseUrl: string;\n task: TaskDef;\n noPersist?: boolean;\n}\n\nenum Op {\n Reset,\n ShowReset,\n CloseReset,\n DismissModal,\n Submit,\n ModalExit,\n}\n\ninterface State {\n modalWord: number;\n currWord: number;\n showModal: boolean;\n resetModal: boolean;\n inputKey: string;\n}\n\nconst reducer = (state: State, action: Op): State => {\n const { currWord } = state;\n switch (action) {\n case Op.DismissModal:\n return { ...state, showModal: false, currWord: currWord + 1 };\n case Op.Submit:\n return { ...state, showModal: true, modalWord: currWord + 1 };\n case Op.ModalExit:\n // Callback unused, but still here.\n return state;\n case Op.ShowReset:\n return { ...state, resetModal: true };\n case Op.CloseReset:\n return { ...state, resetModal: false };\n case Op.Reset:\n // Reset back to start\n return {\n modalWord: 0,\n currWord: 0,\n showModal: false,\n resetModal: false,\n inputKey: Math.random().toString(36), // Force the keyboard input to reload. avoids page refresh\n };\n }\n};\n\nconst useDispatch = (dispatch: React.Dispatch, op: T) =>\n useCallback(() => dispatch(op), [op, dispatch]);\n\nconst Task = (props: TaskProps) => {\n const { task, baseUrl, noPersist } = props;\n const { title, words, instructions } = task;\n\n const persistKey = noPersist ? null : `persist-${baseUrl}`;\n\n const [persist, setPersist] = usePersistentState(persistKey, { word: 0, name: \"\" });\n\n const [{ currWord, modalWord, showModal, resetModal, ...rest }, dispatch] = useReducer(reducer, {\n modalWord: persist.word, // Modal needs to lag behind a word because of exit button\n currWord: persist.word,\n showModal: false,\n resetModal: false,\n inputKey: \"original\", // This is a hacky way to force the inputWord to refresh on reset\n });\n\n const [anchorEl, setAnchorEl] = useState(null);\n\n const debug = useDebugContext();\n const showWord = currWord < words.length;\n\n const word = showWord ? words[currWord] : words[words.length - 1];\n\n const handleSubmit = useDispatch(dispatch, Op.Submit);\n const dismissModal = useDispatch(dispatch, Op.DismissModal);\n const handleModalExit = useDispatch(dispatch, Op.ModalExit);\n const handleShowReset = useCallback(() => {\n setAnchorEl(null);\n dispatch(Op.ShowReset);\n }, []);\n const handleReset = useCallback((reset: boolean) => {\n dispatch(reset ? Op.Reset : Op.CloseReset);\n }, []);\n\n const handleClickMore = (event: React.MouseEvent) => {\n setAnchorEl(event.currentTarget);\n };\n\n const handleCloseMore = () => {\n setAnchorEl(null);\n };\n\n // Scroll back to top at start of each word\n useEffect(() => {\n window.scroll({ top: 0, behavior: \"smooth\" });\n setPersist((s) => {\n // Make sure name is cleared when we reset\n const name = modalWord === 0 ? \"\" : s.name;\n return { name, word: modalWord };\n });\n }, [modalWord, setPersist]);\n\n const controls = (\n <>\n \n \n \n Options }}\n >\n Reset assignment\n \n \n );\n\n const wordInstructions = word.instructions && (\n \n \n \n \n \n );\n\n return (\n
\n \n {title}\n \n\n \n \n \n \n \n \n \n {Math.min(currWord + 1, words.length)}/{words.length}: Transcribe \"{word.display}\"\n \n \n \n \n \n {controls}\n \n\n {wordInstructions}\n\n {/* Setting key here lets us force clear the nested state when we need to */}\n \n \n\n {/* Finish splash screen. The mount/unmount are required for persist to work correctly */}\n \n setPersist((s) => ({ ...s, name: name }))}\n name={persist.name}\n controls={controls}\n />\n \n\n \n Congrats! You got it correct\n \n \n You did a good job of getting the word correct!\n \n \n \n \n {modalWord < words.length ? \"Next word\" : \"Finish\"}\n \n \n \n \n
\n );\n};\n\nexport default memo(Task);\n","import clsx from \"clsx\";\n\nimport CodeBlock from \"./CodeBlock\";\nimport { IPAError, isContextError } from \"../utils/error\";\nimport { Typography, makeStyles } from \"@material-ui/core\";\n\nconst useStyles = makeStyles((theme) => ({\n fileDump: {\n fontSize: theme.typography.h6.fontSize,\n lineHeight: 1.3,\n },\n line: {\n \"&::before\": {\n content: 'attr(data-line) \"| \"',\n },\n },\n errorLine: {\n color: theme.palette.error.main,\n },\n}));\n\ninterface Props {\n error: IPAError | Error;\n context?: number;\n defaultHeader?: string;\n}\n\nconst ErrorMessage = (props: Props) => {\n const classes = useStyles();\n\n const { defaultHeader, error, context = 2 } = props;\n\n console.error(error);\n\n if (isContextError(error)) {\n const issue = error.context(context);\n return (\n
\n \n {error.headline}\n \n \n {error.message}\n \n \n \n \n {issue.map(({ num, contents, error }) => (\n \n {contents}\n {\"\\n\"}\n \n ))}\n \n \n
\n );\n } else {\n return (\n <>\n \n {defaultHeader}\n \n \n {error.message}\n \n \n );\n }\n};\n\nexport default ErrorMessage;\n","import { CircularProgress, Fade, Typography } from \"@material-ui/core\";\nimport { useAsync } from \"react-async-hook\";\nimport { parseTask } from \"../../utils/parsers/task\";\nimport Task from \"./Task\";\nimport { fullBaseUrl } from \"../../constants\";\n\nimport ErrorMessage from \"../ErrorMessage\";\nimport { ResourceError } from \"../../utils/error\";\n\nconst fetchTask = async (taskFileUrl: string) => {\n if (!taskFileUrl) {\n // Absurd. klass will actually always be defined\n console.log(\"empty task\");\n return;\n }\n\n const req = await fetch(taskFileUrl).catch((error) => {\n if (error instanceof TypeError) {\n console.error(error);\n throw new ResourceError(\n `Cannot fetch resource. Permissions may not be correctly configured.`,\n error.message\n );\n } else {\n throw error;\n }\n });\n\n if (req.status !== 200) {\n throw new ResourceError(`${req.statusText}: Resource cannot be retrieved`);\n }\n\n const body = await req.text();\n\n return parseTask(body);\n};\n\ninterface StatusProps {\n children: React.ReactNode;\n error?: boolean;\n}\n\nconst Status = ({ children, error }: StatusProps) => (\n \n {error && \"Error: \"}\n {children}\n \n);\n\ninterface LoadProps {\n taskFileUrl: string;\n}\n\n/**\n * Wrapper around the Task with loading state\n */\nconst LoadTask = (props: LoadProps) => {\n const { taskFileUrl } = props;\n const task = useAsync(fetchTask, [taskFileUrl]);\n const baseUrl = new URL(taskFileUrl, fullBaseUrl()).toString();\n\n if (task.result) {\n return ;\n } else if (task.loading) {\n return (\n \n \n \n \n \n );\n } else if (task.error) {\n return ;\n } else {\n return ;\n }\n};\n\nexport default LoadTask;\n","// Central place for getting env based config\nexport const allowRemote = process.env.REACT_APP_ALLOW_REMOTE === \"true\";\nexport const browserRouter = process.env.REACT_APP_ROUTER === \"browser\";\nexport const hostedSite = process.env.REACT_APP_ORIGINAL_HOSTED_SITE === \"true\";\n\nexport const VERSION = process.env.REACT_APP_VERSION;\nexport const REPO = process.env.REACT_APP_REPO;\nexport const REPO_URL =\n REPO && VERSION ? `${REPO.replace(\".git\", \"\")}/tree/${VERSION}` : REPO || \"#\";\n\nexport const SHORT_DOMAIN = process.env.REACT_APP_SHORT_DOMAIN;\n","import { useState } from \"react\";\nimport { useLocation, useParams } from \"react-router-dom\";\nimport { fileUrl } from \"../../constants\";\nimport LoadTask from \"./LoadTask\";\n\nimport { decode, encode } from \"js-base64\";\n\nimport { Link } from \"react-router-dom\";\nimport { Button, Grid, InputAdornment, TextField, Typography } from \"@material-ui/core\";\nimport { SHORT_DOMAIN } from \"../../config\";\n\nconst RouteTask = () => {\n const { klass, assignment } = useParams<{ klass: string; assignment: string }>();\n return ;\n};\n\nexport const RouteRemoteTask = () => {\n const location = useLocation();\n const params = new URLSearchParams(location.search);\n const config = params.get(\"config\");\n\n if (config) {\n const url = decode(config);\n const target = url.includes(\"://\") ? url : `https://${url}`;\n\n return ;\n } else {\n return ;\n }\n};\n\nconst BuildTaskLink = () => {\n const [url, setUrl] = useState(\"\");\n const params = new URLSearchParams({ config: encode(url, true) }).toString();\n\n const base = new URL(window.location.href);\n if (SHORT_DOMAIN) {\n base.hostname = SHORT_DOMAIN;\n }\n const resultUrl = `${base}?${params}`;\n\n return (\n \n \n \n Enter the URL of a task file below.\n \n setUrl(e.target.value)}\n value={url}\n InputProps={{\n endAdornment: (\n \n \n Go!\n \n \n ),\n }}\n />\n \n \n \n {resultUrl}\n \n \n \n );\n};\n\nexport default RouteTask;\n","import { Box, Button, Grid, Paper, Typography } from \"@material-ui/core\";\nimport { Link } from \"react-router-dom\";\n\ninterface TaskInfo {\n name: string;\n description: string;\n file: string;\n hidden?: boolean;\n}\n\ninterface Props {\n tasks: TaskInfo[];\n path: string;\n}\n\nconst taskLink = (path: string, file: string) => `${path}/${file.replace(\".yaml\", \"\")}`;\n\nconst TaskList = (props: Props) => {\n const { tasks, path } = props;\n\n if (tasks.length === 0) {\n return No tasks to do;\n } else {\n return (\n \n {tasks.map(\n (task: TaskInfo, i: number) =>\n !task.hidden && (\n \n \n \n \n {task.name}\n \n \n {task.description}\n \n \n \n \n Work on task\n \n \n \n \n )\n )}\n \n );\n }\n};\n\nexport default TaskList;\n","import { RouteComponentProps } from \"react-router\";\nimport { useManifest } from \"../Manifest\";\n\nimport { useAsync } from \"react-async-hook\";\nimport { TASK_FILE, fileUrl } from \"../constants\";\nimport { Typography } from \"@material-ui/core\";\nimport { TaskList } from \"./Task\";\n\nimport { parseTaskList } from \"../utils/parsers\";\nimport { ResourceError } from \"../utils/error\";\nimport ErrorMessage from \"./ErrorMessage\";\n\ninterface MatchParams {\n klass: string;\n}\n\ninterface Props extends RouteComponentProps {}\n\nconst fetchClassTasks = async (classId: string) => {\n if (!classId) {\n // Absurd. klass will actually always be defined. but just in case\n console.log(\"empty class\");\n return;\n }\n const url = fileUrl(classId, TASK_FILE);\n\n const req = await fetch(url).catch((error) => {\n if (error instanceof TypeError) {\n console.error(error);\n throw new ResourceError(\n `Cannot fetch resource. Permissions may not be correctly configured.`,\n error.message\n );\n } else {\n throw error;\n }\n });\n\n if (req.status !== 200) {\n throw new ResourceError(`${req.statusText}: Resource cannot be retrieved`);\n }\n\n const body = await req.text();\n\n return parseTaskList(body);\n};\n\ninterface StatusProps {\n msg: string;\n error?: boolean;\n}\n\nconst Status = ({ msg, error }: StatusProps) => (\n \n {error && \"Error: \"}\n {msg}\n \n);\nconst ClassPage = (props: Props) => {\n const classId = props.match.params.klass;\n\n const manifest = useManifest();\n const klass = manifest?.result?.classes?.find(({ folder }) => classId === folder);\n // classTasks can begin loading before we confirm classId\n const classTasks = useAsync(fetchClassTasks, [classId]);\n\n /**\n * Cases:\n * if classTasks.result : Good\n * while loading class && manifest: Class name\n * while loading manifest: Loading...\n * if (classTasks.error) : \"cannot load class X\"\n *\n */\n\n if (classTasks.result) {\n const { title, description, tasks } = classTasks.result;\n return (\n
\n
\n \n {title}\n \n \n {description}\n \n
\n \n Assignments:\n \n \n
\n );\n } else if (classTasks.loading && klass) {\n return (\n
\n \n Loading {klass.name}...\n \n
\n );\n } else if (manifest.loading || classTasks.loading) {\n return (\n \n Loading...\n \n );\n } else if (classTasks.error) {\n return (\n \n );\n } else {\n return ;\n }\n};\n\nexport default ClassPage;\n","import { TaskListDef, TaskListFile } from \"../../data/taskList\";\nimport { parse } from \"./parse\";\n\nexport type { TaskListDef } from \"../../data/taskList\";\n\nexport const parseTaskList = (contents: string): TaskListDef => parse(contents, TaskListFile);\n","import { Box, Grid, Typography } from \"@material-ui/core\";\nimport Markdown from \"./Markdown\";\nimport { useManifest } from \"../Manifest\";\n\nconst Homepage = () => {\n const { result, loading } = useManifest();\n\n if (result) {\n const { title, body } = result.homepage;\n return (\n \n \n {title}\n \n \n \n \n \n \n \n );\n } else {\n return (\n \n {loading ? \"Loading\" : \"Error\"}\n \n );\n }\n};\n\nexport default Homepage;\n","import useKeyboard from \"./keyboard/useKeyboard\";\n\nimport StickyIPA from \"./keyboard/StickyIPA\";\n\nconst TypeIPA = () => {\n const { handleKeyboard, handleDelete, handleType, value, ref } = useKeyboard();\n\n return (\n \n );\n};\n\nexport default TypeIPA;\n","import { Suspense, lazy } from \"react\";\nimport { RouteComponentProps } from \"react-router-dom\";\n\nconst ToolList = lazy(() => import(\"./ToolList\"));\n\ninterface Props extends RouteComponentProps {}\n\nconst ToolLoader = (props: Props) => (\n \n \n \n);\n\nexport default ToolLoader;\n","import { Redirect, Route, Switch } from \"react-router-dom\";\n\nimport ClassPage from \"./components/ClassPage\";\nimport Homepage from \"./components/Homepage\";\nimport NotFound from \"./components/NotFound\";\nimport { RouteRemoteTask, RouteTask } from \"./components/Task\";\nimport TypeIPA from \"./components/TypeIPA\";\nimport ToolLoader from \"./components/Tools/ToolLoader\";\n\nimport { allowRemote } from \"./config\";\n\nconst Router = () => {\n return (\n \n \n \n \n {/* Allow slashes for nested assignments */}\n \n {allowRemote && }\n\n {/* Old routes which have been moved */}\n \n\n \n\n {/* Catchall */}\n \n \n );\n};\n\nexport default Router;\n","import { Theme } from \"@material-ui/core\";\n\nexport const notchGutters = (theme: Theme) => ({\n paddingLeft: `max(env(safe-area-inset-left, 0px), ${theme.spacing(2)}px)`,\n paddingRight: `max(env(safe-area-inset-right, 0px), ${theme.spacing(2)}px)`,\n [theme.breakpoints.up(\"sm\")]: {\n paddingLeft: `max(env(safe-area-inset-left, 0px), ${theme.spacing(3)}px)`,\n paddingRight: `max(env(safe-area-inset-right, 0px), ${theme.spacing(3)}px)`,\n },\n});\n","import { useCallback, useState } from \"react\";\nimport { makeStyles } from \"@material-ui/core/styles\";\nimport {\n AppBar,\n Box,\n Divider,\n Drawer,\n Grid,\n IconButton,\n LinearProgress,\n List,\n ListItem,\n ListItemIcon,\n ListItemText,\n ListSubheader,\n Link as MatLink,\n Switch,\n Theme,\n Toolbar,\n Typography,\n withStyles,\n} from \"@material-ui/core\";\n\nimport MenuIcon from \"@material-ui/icons/Menu\";\nimport HomeIcon from \"@material-ui/icons/Home\";\nimport KeyboardIcon from \"@material-ui/icons/Keyboard\";\nimport CastIcon from \"@material-ui/icons/Cast\";\n\nimport { Link, matchPath, useLocation } from \"react-router-dom\";\n\nimport { useManifest } from \"../Manifest\";\nimport { grey } from \"@material-ui/core/colors\";\nimport { notchGutters } from \"../utils/styles\";\nimport { REPO_URL, VERSION, allowRemote } from \"../config\";\n\nconst DRAWER_WIDTH = 275;\n\nconst useStyles = makeStyles((theme: Theme) => ({\n itemGutters: {\n paddingLeft: `max(env(safe-area-inset-left, 0px), ${theme.spacing(2)}px)`,\n },\n gutters: notchGutters(theme),\n}));\n\nconst Loading = ({ error }: { error?: boolean }) => (\n <>\n \n \n \n \n \n);\n\ninterface ListLinkProps {\n gutters: string;\n to: string;\n text: string;\n exact?: boolean;\n icon?: JSX.Element;\n}\n\nconst ListLink = (props: ListLinkProps) => {\n const { pathname } = useLocation();\n const { to, text, icon, exact, gutters } = props;\n\n const selected = !!matchPath(pathname, { path: to, exact: exact });\n\n return (\n \n {icon && {icon}}\n \n \n );\n};\n\nconst DarkSwitch = withStyles({\n switchBase: {\n color: grey[100],\n \"&$checked\": {\n color: \"black\",\n },\n \"&$checked + $track\": {\n backgroundColor: grey[500],\n },\n },\n checked: {},\n track: {},\n})(Switch);\n\ninterface Props {\n darkMode: boolean;\n changeDarkMode: (mode: boolean) => void;\n}\n\nconst Header = (props: Props) => {\n const [drawer, setDrawer] = useState(false);\n const classes = useStyles();\n\n const { changeDarkMode } = props;\n\n const { result, loading, error } = useManifest();\n\n const openDrawer = useCallback(() => {\n setDrawer(true);\n }, []);\n const closeDrawer = useCallback(() => {\n setDrawer(false);\n }, []);\n\n const toggleDarkMode = useCallback(\n (event) => {\n changeDarkMode(event.target.checked);\n },\n [changeDarkMode]\n );\n\n const list = (\n
\n \n } exact gutters={classes.itemGutters} />\n \n \n \n Classes\n {error && }\n {loading && }\n {result &&\n result.classes.map(\n ({ name, folder, hidden }, i) =>\n !hidden && (\n \n )\n )}\n \n \n \n Tools\n {allowRemote && (\n }\n exact\n gutters={classes.itemGutters}\n />\n )}\n }\n exact\n gutters={classes.itemGutters}\n />\n \n
\n );\n\n return (\n
\n \n \n {list}\n \n \n \n Light\n \n \n \n Dark\n \n \n \n Int IPA –{\" \"}\n \n {VERSION}\n \n \n \n \n \n\n \n \n \n \n \n Int IPA\n \n \n
\n );\n};\n\nexport default Header;\n","import { Container, Link, Typography, makeStyles } from \"@material-ui/core\";\nimport { hostedSite } from \"../config\";\n\n// import GitHubIcon from \"@material-ui/icons/GitHub\";\n\nconst useStyles = makeStyles(() => ({\n root: {\n marginTop: \"1rem\",\n marginBottom: \"1rem\",\n },\n}));\n\n// Only state \"maintained\" for the hosted variant\nconst disclaimer = hostedSite ? \"Created and maintained by \" : \"Originally created by \";\n\nconst Footer = () => {\n const classes = useStyles();\n\n return (\n \n \n {disclaimer}\n \n Winston Durand\n \n . Source code and examples released under the{\" \"}\n \n MIT\n {\" \"}\n license. Website and documentation licensed under{\" \"}\n \n CC BY 4.0\n \n .\n \n \n );\n};\n\nexport default Footer;\n","export default window.AudioContext || window.webkitAudioContext;\n","import { useEffect, useMemo } from \"react\";\n\nimport { Container, CssBaseline, Snackbar } from \"@material-ui/core\";\nimport { ThemeProvider } from \"@material-ui/styles\";\nimport { ThemeOptions, createMuiTheme } from \"@material-ui/core/styles\";\nimport { blue, indigo } from \"@material-ui/core/colors\";\nimport { Theme, makeStyles, useMediaQuery } from \"@material-ui/core\";\n\nimport Router from \"./Router\";\nimport Header from \"./components/Header\";\nimport Footer from \"./components/Footer\";\n\nimport { notchGutters } from \"./utils/styles\";\nimport { useDebugContext } from \"./utils/Debug\";\nimport { usePersistentState } from \"./utils/usePersistentState\";\n\nimport AudioContext from \"./utils/AudioContext\";\n\nimport MetaTags from \"react-meta-tags\";\n\nconst lightTheme: ThemeOptions = {\n palette: {\n type: \"light\",\n primary: {\n main: blue[900],\n },\n secondary: {\n main: indigo[700],\n },\n },\n};\n\nconst darkTheme: ThemeOptions = {\n palette: {\n type: \"dark\",\n primary: {\n main: blue[500],\n },\n secondary: {\n main: indigo[700],\n },\n },\n};\n\nconst useStyles = makeStyles((theme: Theme) => ({\n // Modified from source\n // https://github.com/mui-org/material-ui/blob/v4.11.0/packages/material-ui/src/Container/Container.js\n containerRoot: {\n marginTop: `${theme.spacing(1)}px`,\n width: \"100%\",\n boxSizing: \"border-box\",\n display: \"block\", // Fix IE 11 layout when used with main.\n ...notchGutters(theme),\n },\n debug: {\n pointerEvents: \"none\",\n zIndex: 1150,\n },\n debugRoot: {\n minWidth: 0,\n background: \"rgba(240, 240, 240, 0.25)\",\n color: theme.palette.text.disabled,\n },\n siteRoot: {\n marginBottom: \"env(safe-area-inset-bottom, 0px)\",\n display: \"flex\",\n minHeight: \"100vh\",\n flexDirection: \"column\",\n },\n siteContent: {\n flex: 1,\n },\n}));\n\nconst DARK_KEY = \"useDarkMode\";\n\nexport default function App() {\n const classes = useStyles();\n const debug = useDebugContext();\n\n const prefersDarkMode = useMediaQuery(\"(prefers-color-scheme: dark)\");\n const [dark, setDark] = usePersistentState(DARK_KEY, null);\n\n useEffect(() => {\n if (process.env.NODE_ENV !== \"production\") {\n document.title = `${process.env.NODE_ENV.slice(0, 3)} - ${document.title}`;\n }\n }, []);\n\n // Create an audio context on first user interaction. Reduces audio playing delay\n useEffect(() => {\n const create = () => {\n document.removeEventListener(\"click\", create);\n new AudioContext({\n latencyHint: \"interactive\",\n });\n };\n document.addEventListener(\"click\", create);\n }, []);\n\n const darkMode = dark === null ? prefersDarkMode : dark;\n\n const theme = useMemo(() => createMuiTheme(darkMode ? darkTheme : lightTheme), [darkMode]);\n\n return (\n
\n \n \n \n \n\n \n
\n \n \n \n
\n \n \n
\n );\n}\n","import { StrictMode } from \"react\";\nimport ReactDOM from \"react-dom\";\n// import \"./index.css\";\nimport App from \"./App\";\n// import reportWebVitals from \"./reportWebVitals\";\nimport Manifest from \"./Manifest\";\nimport Debug from \"./utils/Debug\";\nimport smoothscroll from \"smoothscroll-polyfill\";\n\nimport { BrowserRouter, HashRouter } from \"react-router-dom\";\n\nimport \"./index.css\";\nimport { browserRouter } from \"./config\";\n\nconst Router = ({ children }: { children: React.ReactNode }) => {\n if (browserRouter) {\n return ;\n } else {\n return ;\n }\n};\n\nReactDOM.render(\n \n \n \n \n \n \n \n \n ,\n document.getElementById(\"root\")\n);\n\nsmoothscroll.polyfill();\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\n// reportWebVitals();\n","import { fromUint8Array } from \"js-base64\";\n\nconst INVALID = /[^a-zA-Z0-9-]/g;\n\nconst normName = (name: string) => {\n return name.replace(/[\\s-]+/g, \"-\").replace(INVALID, \"\");\n};\n\nasync function sha1sum(bytes: ArrayBuffer) {\n const buf = await crypto.subtle.digest(\"SHA-256\", bytes);\n return fromUint8Array(new Uint8Array(buf));\n}\n\nconst EPOCH = new Date(\"2020-02-02\");\n\nconst SHA_LENGTH = 16;\n\nconst minuteOfYear = () => {\n const now = new Date();\n return Math.floor((now.getTime() - EPOCH.getTime()) / 1000 / 60).toString(36);\n};\n\nconst timestampToDate = (timestamp: string) => {\n const minutes = parseInt(timestamp, 36);\n const millis = minutes * 60 * 1000 + EPOCH.getTime();\n return new Date(millis);\n};\n\n// Assume the second string is shorter\nexport const interleave = (longer: string, shorter: string): string => {\n const interleaved: string[] = [shorter.length.toString(36)];\n for (let i = 0; i < shorter.length; i++) {\n interleaved.push(longer.charAt(i));\n interleaved.push(shorter.charAt(i));\n }\n interleaved.push(longer.slice(shorter.length, longer.length));\n return interleaved.join(\"\");\n};\n\n// Assume the second string is shorter\nexport const deinterleave = (encoded: string): [string, string] => {\n const length = parseInt(encoded.charAt(0), 36);\n const interleaved = encoded.slice(1, encoded.length);\n const longer: string[] = [];\n const shorter: string[] = [];\n for (let i = 0; i < length * 2; i += 2) {\n longer.push(interleaved.charAt(i));\n shorter.push(interleaved.charAt(i + 1));\n }\n longer.push(interleaved.slice(length * 2, interleaved.length));\n return [longer.join(\"\"), shorter.join(\"\")];\n};\n\nconst DEFAULT_SALT = \"vowelsAreCool!!!\";\n\nexport const computeHash = async (\n name: string | undefined,\n salt: string | undefined,\n run: boolean = true,\n time?: string\n) => {\n if (typeof name === \"undefined\" || !run) {\n return;\n }\n\n const effectiveSalt = salt || DEFAULT_SALT;\n\n const outName = normName(name);\n const hashName = outName.toLowerCase();\n const outTime = (time || minuteOfYear()).toLowerCase();\n const nameTime = `${hashName}_${outTime}`;\n const input = [nameTime, effectiveSalt].join(\"_\");\n\n const sha1 = await sha1sum(new TextEncoder().encode(input));\n\n // Remove special characters and limit to the first 16 chars\n const cleanupSha1 = sha1\n .toLowerCase()\n .replace(/[^a-z0-9]/g, \"\")\n .slice(0, SHA_LENGTH);\n const interleaved = interleave(cleanupSha1, outTime);\n return [outName, interleaved].join(\"_\");\n};\n\ninterface HashResult {\n correct: boolean;\n name: string;\n date?: Date;\n message: string;\n}\n\nexport const checkHash = async (hash: string, salt?: string): Promise => {\n const effectiveSalt = salt || DEFAULT_SALT;\n\n const segments = hash.split(\"_\");\n const [name, interleaved] = segments;\n if (segments.length !== 2 || interleaved.match(INVALID)) {\n const message =\n segments.length < 2 ? \"Missing validation hash\" : \"Invalid characters in string\";\n return { name: hash, correct: false, message };\n }\n const [sha, time] = deinterleave(interleaved.toLowerCase());\n const date = timestampToDate(time);\n\n if (sha?.length !== SHA_LENGTH) {\n console.warn(\"sha segment differs from expected length.\");\n }\n const lowerHash = hash.toLowerCase();\n const expected = (await computeHash(name, effectiveSalt, true, time))?.toLowerCase();\n return { name, date, correct: expected === lowerHash, message: hash };\n};\n","import { LinkProps, Link as MatLink } from \"@material-ui/core\";\nimport { Link as RouterLink } from \"react-router-dom\";\n\ntype Props = LinkProps;\n\nconst Link = (props: Props) => ;\n\nexport default Link;\n","import { Typography } from \"@material-ui/core\";\n\nconst NotFound = () => (\n \n The page you are looking for cannot be found 😫\n \n);\n\nexport default NotFound;\n"],"sourceRoot":""}