diff --git a/frontend/src/styles/media-queries-blue.scss b/frontend/src/styles/media-queries-blue.scss index 435c5352cdbe..529289c2eac6 100644 --- a/frontend/src/styles/media-queries-blue.scss +++ b/frontend/src/styles/media-queries-blue.scss @@ -245,7 +245,8 @@ } .pageFriends { - .content .friends table { + .content .friends table, + .content .pendingRequests table { font-size: 0.75rem; } } diff --git a/frontend/src/styles/media-queries-brown.scss b/frontend/src/styles/media-queries-brown.scss index 9fedfe9aeaca..8fdeb33500ef 100644 --- a/frontend/src/styles/media-queries-brown.scss +++ b/frontend/src/styles/media-queries-brown.scss @@ -107,6 +107,11 @@ display: none; } } + .content .pendingRequests table { + td:nth-child(2) { + display: none; + } + } } .pageAccountSettings [data-tab="blockedUsers"] { diff --git a/frontend/src/styles/media-queries-yellow.scss b/frontend/src/styles/media-queries-yellow.scss index 44d86b8d0d95..e3df58e2a8c4 100644 --- a/frontend/src/styles/media-queries-yellow.scss +++ b/frontend/src/styles/media-queries-yellow.scss @@ -91,7 +91,8 @@ } } .pageFriends { - .content .friends table { + .content .friends table, + .content .pendingRequests table { font-size: 0.9rem; .badge .text { diff --git a/frontend/src/ts/commandline/lists/result-screen.ts b/frontend/src/ts/commandline/lists/result-screen.ts index 7688b2d0a465..60207281b555 100644 --- a/frontend/src/ts/commandline/lists/result-screen.ts +++ b/frontend/src/ts/commandline/lists/result-screen.ts @@ -33,6 +33,16 @@ const practiceSubgroup: CommandsSubgroup = { }); }, }, + { + id: "practiseWordsBoth", + display: "both", + exec: (): void => { + PractiseWords.init("words", true); + TestLogic.restart({ + practiseMissed: true, + }); + }, + }, { id: "practiseWordsCustom", display: "custom...", diff --git a/frontend/src/ts/controllers/profile-search-controller.ts b/frontend/src/ts/controllers/profile-search-controller.ts deleted file mode 100644 index 2294d634eb98..000000000000 --- a/frontend/src/ts/controllers/profile-search-controller.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { InputIndicator } from "../elements/input-indicator"; -import { sleep } from "../utils/misc"; -import Ape from "../ape"; -import { navigate } from "../controllers/route-controller"; -import * as Skeleton from "../utils/skeleton"; - -const searchIndicator = new InputIndicator( - $(".page.pageProfileSearch .search input"), - { - notFound: { - icon: "fa-user-slash", - level: -1, - }, - error: { - icon: "fa-times", - level: -1, - }, - checking: { - icon: "fa-circle-notch", - spinIcon: true, - level: 1, - }, - } -); - -function disableInputs(): void { - $(".page.pageProfileSearch .search button").addClass("disabled"); - $(".page.pageProfileSearch .search input").attr("disabled", "disabled"); -} - -function enableInputs(): void { - $(".page.pageProfileSearch .search button").removeClass("disabled"); - $(".page.pageProfileSearch .search input").removeAttr("disabled"); -} - -function areInputsDisabled(): boolean { - return ( - $(".page.pageProfileSearch .search input").attr("disabled") !== undefined - ); -} - -function focusInput(): void { - $(".page.pageProfileSearch .search input").trigger("focus"); -} - -async function lookupProfile(): Promise { - searchIndicator.hide(); - const name = $(".page.pageProfileSearch .search input").val() as string; - if (name === "") return; - - searchIndicator.show("checking"); - disableInputs(); - - await sleep(500); - - const response = await Ape.users.getProfile({ params: { uidOrName: name } }); - enableInputs(); - if (response.status === 404) { - focusInput(); - searchIndicator.show("notFound", "User not found"); - return; - } else if (response.status !== 200) { - focusInput(); - searchIndicator.show("error", `Error: ${response.body.message}`); - return; - } - searchIndicator.hide(); - await navigate(`/profile/${name}`, { - data: response.body.data, - }); -} - -$(".page.pageProfileSearch form").on("submit", (e) => { - e.preventDefault(); - if (areInputsDisabled()) return; - void lookupProfile(); -}); - -Skeleton.save("pageProfileSearch"); diff --git a/frontend/src/ts/controllers/route-controller.ts b/frontend/src/ts/controllers/route-controller.ts index 2c0eda4b504f..1aa6eab0af00 100644 --- a/frontend/src/ts/controllers/route-controller.ts +++ b/frontend/src/ts/controllers/route-controller.ts @@ -6,6 +6,7 @@ import { isFunboxActive } from "../test/funbox/list"; import * as TestState from "../test/test-state"; import * as Notifications from "../elements/notifications"; import { LoadingOptions } from "../pages/page"; +import * as NavigationEvent from "../observables/navigation-event"; //source: https://www.youtube.com/watch?v=OstALBk-jTc // https://www.youtube.com/watch?v=OstALBk-jTc @@ -249,3 +250,7 @@ document.addEventListener("DOMContentLoaded", () => { } }); }); + +NavigationEvent.subscribe((it) => { + void navigate(it.url, { data: it.data }); +}); diff --git a/frontend/src/ts/elements/input-validation.ts b/frontend/src/ts/elements/input-validation.ts index 5dce09c44705..277bcd8d37f5 100644 --- a/frontend/src/ts/elements/input-validation.ts +++ b/frontend/src/ts/elements/input-validation.ts @@ -142,80 +142,75 @@ export type ValidationOptions = (T extends string callback?: (result: ValidationResult) => void; }; -export type ValidatedHtmlInputElement = HTMLInputElement & { - getValidationResult: () => ValidationResult; - setValue: (val: string | null) => void; - triggerValidation: () => void; -}; -/** - * adds an 'InputIndicator` to the given `inputElement` and updates its status depending on the given validation - * @param inputElement - * @param options - */ -export function validateWithIndicator( - inputElement: HTMLInputElement, - options: ValidationOptions -): ValidatedHtmlInputElement { - //use indicator - const indicator = new InputIndicator(inputElement, { - success: { - icon: "fa-check", - level: 1, - }, - failed: { - icon: "fa-times", - level: -1, - }, - warning: { - icon: "fa-exclamation-triangle", - level: 1, - }, - checking: { - icon: "fa-circle-notch", - spinIcon: true, - level: 0, - }, - }); - - let currentStatus: ValidationResult = { +export class ValidatedHtmlInputElement { + public native: HTMLInputElement; + private indicator: InputIndicator; + private currentStatus: ValidationResult = { status: "checking", }; - const callback = (result: ValidationResult): void => { - currentStatus = result; - if (result.status === "failed" || result.status === "warning") { - indicator.show(result.status, result.errorMessage); - } else { - indicator.show(result.status); - } - options.callback?.(result); - }; - const handler = createInputEventHandler( - callback, - options, - "inputValueConvert" in options ? options.inputValueConvert : undefined - ); + constructor(inputElement: HTMLInputElement, options: ValidationOptions) { + this.native = inputElement; - inputElement.addEventListener("input", handler); + this.indicator = new InputIndicator(inputElement, { + success: { + icon: "fa-check", + level: 1, + }, + failed: { + icon: "fa-times", + level: -1, + }, + warning: { + icon: "fa-exclamation-triangle", + level: 1, + }, + checking: { + icon: "fa-circle-notch", + spinIcon: true, + level: 0, + }, + }); - const result = inputElement as ValidatedHtmlInputElement; - result.getValidationResult = () => { - return currentStatus; - }; - result.setValue = (val: string | null) => { - inputElement.value = val ?? ""; + const callback = (result: ValidationResult): void => { + this.currentStatus = result; + if (result.status === "failed" || result.status === "warning") { + this.indicator.show(result.status, result.errorMessage); + } else { + this.indicator.show(result.status); + } + options.callback?.(result); + }; + + const handler = createInputEventHandler( + callback, + options, + "inputValueConvert" in options ? options.inputValueConvert : undefined + ); + + inputElement.addEventListener("input", handler); + } + + getValidationResult(): ValidationResult { + return this.currentStatus; + } + setValue(val: string | null): this { + this.native.value = val ?? ""; if (val === null) { - indicator.hide(); - currentStatus = { status: "checking" }; + this.indicator.hide(); + this.currentStatus = { status: "checking" }; } else { - inputElement.dispatchEvent(new Event("input")); + this.native.dispatchEvent(new Event("input")); } - }; - result.triggerValidation = () => { - inputElement.dispatchEvent(new Event("input")); - }; - return result; + return this; + } + getValue(): string { + return this.native.value; + } + triggerValidation(): void { + this.native.dispatchEvent(new Event("input")); + } } export type ConfigInputOptions = { @@ -260,7 +255,7 @@ export function handleConfigInput({ if (validation !== undefined) { const schema = ConfigSchema.shape[configName] as ZodType; - validateWithIndicator(input, { + new ValidatedHtmlInputElement(input, { schema: validation.schema ? schema : undefined, //@ts-expect-error this is fine isValid: validation.isValid, diff --git a/frontend/src/ts/elements/keymap.ts b/frontend/src/ts/elements/keymap.ts index 2ba5d4f93d21..2234c66cfd49 100644 --- a/frontend/src/ts/elements/keymap.ts +++ b/frontend/src/ts/elements/keymap.ts @@ -17,7 +17,7 @@ import { areSortedArraysEqual } from "../utils/arrays"; import { LayoutObject } from "@monkeytype/schemas/layouts"; import { animate } from "animejs"; -export const keyDataDelimiter = "~~"; +export const keyDataDelimiter = "\uE000"; const stenoKeys: LayoutObject = { keymapShowTopRow: true, @@ -58,27 +58,30 @@ const stenoKeys: LayoutObject = { }, }; +function findKeyElements(char: string): JQuery { + if (char === " ") { + return $("#keymap .keySpace"); + } + + if (char === '"') { + return $(`#keymap .keymapKey[data-key*='${char}']`); + } + + return $(`#keymap .keymapKey[data-key*="${char}"]`); +} + function highlightKey(currentKey: string): void { if (Config.mode === "zen") return; if (currentKey === "") currentKey = " "; try { $(".activeKey").removeClass("activeKey"); - let highlightKey; if (Config.language.startsWith("korean")) { currentKey = Hangul.disassemble(currentKey)[0] ?? currentKey; } - if (currentKey === " ") { - highlightKey = "#keymap .keySpace"; - } else if (currentKey === '"') { - highlightKey = `#keymap .keymapKey[data-key*='${currentKey}']`; - } else { - highlightKey = `#keymap .keymapKey[data-key*="${currentKey}"]`; - } - - // console.log("highlighting", highlightKey); - $(highlightKey).addClass("activeKey"); + const $target = findKeyElements(currentKey); + $target.addClass("activeKey"); } catch (e) { if (e instanceof Error) { console.log("could not update highlighted keymap key: " + e.message); @@ -88,14 +91,11 @@ function highlightKey(currentKey: string): void { async function flashKey(key: string, correct?: boolean): Promise { if (key === undefined) return; - //console.log("key", key); - if (key === " ") { - key = "#keymap .keySpace"; - } else if (key === '"') { - key = `#keymap .keymapKey[data-key*='${key}']`; - } else { - key = `#keymap .keymapKey[data-key*="${key}"]`; - } + + const $target = findKeyElements(key); + + const elements = $target.toArray(); + if (elements.length === 0) return; const themecolors = await ThemeColors.getAll(); @@ -120,7 +120,7 @@ async function flashKey(key: string, correct?: boolean): Promise { }; } - animate(key, { + animate(elements, { color: [startingStyle.color, themecolors.sub], backgroundColor: [startingStyle.backgroundColor, themecolors.subAlt], borderColor: [startingStyle.borderColor, themecolors.sub], diff --git a/frontend/src/ts/elements/settings/fps-limit-section.ts b/frontend/src/ts/elements/settings/fps-limit-section.ts index fb1b994121b3..1c0e52303fe0 100644 --- a/frontend/src/ts/elements/settings/fps-limit-section.ts +++ b/frontend/src/ts/elements/settings/fps-limit-section.ts @@ -1,5 +1,5 @@ import { getfpsLimit, fpsLimitSchema, setfpsLimit } from "../../anim"; -import { validateWithIndicator } from "../input-validation"; +import { ValidatedHtmlInputElement } from "../input-validation"; import * as Notifications from "../notifications"; const section = document.querySelector( @@ -10,7 +10,7 @@ const button = section.querySelector( "button[data-fpsLimit='native']" ) as HTMLButtonElement; -const input = validateWithIndicator( +const input = new ValidatedHtmlInputElement( section.querySelector('input[type="number"]') as HTMLInputElement, { schema: fpsLimitSchema, @@ -24,7 +24,7 @@ export function update(): void { input.setValue(null); button.classList.add("active"); } else { - input.value = fpsLimit.toString(); + input.setValue(fpsLimit.toString()); button.classList.remove("active"); } } @@ -38,7 +38,7 @@ function save(value: number): void { function saveFromInput(): void { if (input.getValidationResult().status !== "success") return; - const val = parseInt(input.value, 10); + const val = parseInt(input.getValue(), 10); save(val); } @@ -47,10 +47,10 @@ button.addEventListener("click", () => { update(); }); -input.addEventListener("keypress", (e) => { +input.native.addEventListener("keypress", (e) => { if (e.key === "Enter") { saveFromInput(); } }); -input.addEventListener("focusout", (e) => saveFromInput()); +input.native.addEventListener("focusout", (e) => saveFromInput()); diff --git a/frontend/src/ts/index.ts b/frontend/src/ts/index.ts index d2d9f2dc5cc0..17167bb2f56a 100644 --- a/frontend/src/ts/index.ts +++ b/frontend/src/ts/index.ts @@ -37,7 +37,6 @@ import { egVideoListener } from "./popups/video-ad-popup"; import "./states/connection"; import "./test/tts"; import "./elements/fps-counter"; -import "./controllers/profile-search-controller"; import { isDevEnvironment, addToGlobal } from "./utils/misc"; import * as VersionButton from "./elements/version-button"; import * as Focus from "./test/focus"; diff --git a/frontend/src/ts/modals/edit-preset.ts b/frontend/src/ts/modals/edit-preset.ts index 5b235f12de43..3efa27fd463a 100644 --- a/frontend/src/ts/modals/edit-preset.ts +++ b/frontend/src/ts/modals/edit-preset.ts @@ -21,10 +21,7 @@ import { } from "@monkeytype/schemas/configs"; import { getDefaultConfig } from "../constants/default-config"; import { SnapshotPreset } from "../constants/default-snapshot"; -import { - ValidatedHtmlInputElement, - validateWithIndicator, -} from "../elements/input-validation"; +import { ValidatedHtmlInputElement } from "../elements/input-validation"; const state = { presetType: "full" as PresetType, @@ -50,7 +47,7 @@ export function show(action: string, id?: string, name?: string): void { $("#editPresetModal .modal .text").addClass("hidden"); addCheckBoxes(); if (!presetNameEl) { - presetNameEl = validateWithIndicator( + presetNameEl = new ValidatedHtmlInputElement( document.querySelector( "#editPresetModal .modal input" ) as HTMLInputElement, @@ -64,7 +61,7 @@ export function show(action: string, id?: string, name?: string): void { $("#editPresetModal .modal .popupTitle").html("Add new preset"); $("#editPresetModal .modal .submit").html(`add`); presetNameEl?.setValue(null); - presetNameEl?.parentElement?.classList.remove("hidden"); + presetNameEl?.native.parentElement?.classList.remove("hidden"); $("#editPresetModal .modal input").removeClass("hidden"); $( "#editPresetModal .modal label.changePresetToCurrentCheckbox" @@ -79,7 +76,7 @@ export function show(action: string, id?: string, name?: string): void { $("#editPresetModal .modal .popupTitle").html("Edit preset"); $("#editPresetModal .modal .submit").html(`save`); presetNameEl?.setValue(name); - presetNameEl?.parentElement?.classList.remove("hidden"); + presetNameEl?.native.parentElement?.classList.remove("hidden"); $("#editPresetModal .modal input").removeClass("hidden"); $( @@ -108,7 +105,7 @@ export function show(action: string, id?: string, name?: string): void { $("#editPresetModal .modal .inputs").addClass("hidden"); $("#editPresetModal .modal .presetType").addClass("hidden"); $("#editPresetModal .modal .presetNameTitle").addClass("hidden"); - presetNameEl?.parentElement?.classList.add("hidden"); + presetNameEl?.native.parentElement?.classList.add("hidden"); } updateUI(); }, diff --git a/frontend/src/ts/modals/google-sign-up.ts b/frontend/src/ts/modals/google-sign-up.ts index fc452a05eff3..5724456d321a 100644 --- a/frontend/src/ts/modals/google-sign-up.ts +++ b/frontend/src/ts/modals/google-sign-up.ts @@ -14,7 +14,7 @@ import * as Loader from "../elements/loader"; import { subscribe as subscribeToSignUpEvent } from "../observables/google-sign-up-event"; import AnimatedModal from "../utils/animated-modal"; import { resetIgnoreAuthCallback } from "../firebase"; -import { validateWithIndicator } from "../elements/input-validation"; +import { ValidatedHtmlInputElement } from "../elements/input-validation"; import { UserNameSchema } from "@monkeytype/schemas/users"; import { remoteValidation } from "../utils/remote-validation"; @@ -153,7 +153,7 @@ function disableInput(): void { nameInputEl.disabled = true; } -validateWithIndicator(nameInputEl, { +new ValidatedHtmlInputElement(nameInputEl, { schema: UserNameSchema, isValid: remoteValidation( async (name) => Ape.users.getNameAvailability({ params: { name } }), diff --git a/frontend/src/ts/modals/save-custom-text.ts b/frontend/src/ts/modals/save-custom-text.ts index 6bf9cd8d6ed3..cde6e32dce73 100644 --- a/frontend/src/ts/modals/save-custom-text.ts +++ b/frontend/src/ts/modals/save-custom-text.ts @@ -2,7 +2,7 @@ import * as CustomText from "../test/custom-text"; import * as Notifications from "../elements/notifications"; import * as CustomTextState from "../states/custom-text-name"; import AnimatedModal, { ShowOptions } from "../utils/animated-modal"; -import { validateWithIndicator } from "../elements/input-validation"; +import { ValidatedHtmlInputElement } from "../elements/input-validation"; import { z } from "zod"; type IncomingData = { @@ -17,7 +17,7 @@ const state: State = { textToSave: [], }; -const validatedInput = validateWithIndicator( +const validatedInput = new ValidatedHtmlInputElement( $("#saveCustomTextModal .textName")[0] as HTMLInputElement, { debounceDelay: 500, diff --git a/frontend/src/ts/observables/navigation-event.ts b/frontend/src/ts/observables/navigation-event.ts new file mode 100644 index 000000000000..42241636204f --- /dev/null +++ b/frontend/src/ts/observables/navigation-event.ts @@ -0,0 +1,23 @@ +type NavigationEvent = { + url: string; + data?: unknown; +}; + +type SubscribeFunction = (event: NavigationEvent) => void; + +const subscribers: SubscribeFunction[] = []; + +export function subscribe(fn: SubscribeFunction): void { + subscribers.push(fn); +} + +export function dispatch(event: NavigationEvent): void { + subscribers.forEach((fn) => { + try { + fn(event); + } catch (e) { + console.error("Navigation event subscriber threw an error"); + console.error(e); + } + }); +} diff --git a/frontend/src/ts/pages/login.ts b/frontend/src/ts/pages/login.ts index 7111ec3fa6ab..8380fc158acb 100644 --- a/frontend/src/ts/pages/login.ts +++ b/frontend/src/ts/pages/login.ts @@ -7,7 +7,7 @@ import { UserEmailSchema, UserNameSchema, } from "@monkeytype/schemas/users"; -import { validateWithIndicator } from "../elements/input-validation"; +import { ValidatedHtmlInputElement } from "../elements/input-validation"; import { isDevEnvironment } from "../utils/misc"; import { z } from "zod"; import { remoteValidation } from "../utils/remote-validation"; @@ -72,7 +72,7 @@ export function getSignupData(): SignupData | false { const nameInputEl = document.querySelector( ".page.pageLogin .register.side input.usernameInput" ) as HTMLInputElement; -validateWithIndicator(nameInputEl, { +new ValidatedHtmlInputElement(nameInputEl, { schema: UserNameSchema, isValid: remoteValidation( async (name) => Ape.users.getNameAvailability({ params: { name } }), @@ -90,7 +90,7 @@ let disposableEmailModule: typeof import("disposable-email-domains-js") | null = null; let moduleLoadAttempted = false; -const emailInputEl = validateWithIndicator( +const emailInputEl = new ValidatedHtmlInputElement( document.querySelector( ".page.pageLogin .register.side input.emailInput" ) as HTMLInputElement, @@ -143,7 +143,7 @@ const emailInputEl = validateWithIndicator( } ); -emailInputEl.addEventListener("focus", async () => { +emailInputEl.native.addEventListener("focus", async () => { if (!moduleLoadAttempted) { moduleLoadAttempted = true; try { @@ -157,9 +157,9 @@ emailInputEl.addEventListener("focus", async () => { const emailVerifyInputEl = document.querySelector( ".page.pageLogin .register.side input.verifyEmailInput" ) as HTMLInputElement; -validateWithIndicator(emailVerifyInputEl, { +new ValidatedHtmlInputElement(emailVerifyInputEl, { isValid: async (emailVerify: string) => { - return emailInputEl.value === emailVerify + return emailInputEl.getValue() === emailVerify ? true : "verify email not matching email"; }, @@ -168,13 +168,13 @@ validateWithIndicator(emailVerifyInputEl, { registerForm.email = emailInputEl.getValidationResult().status === "success" && result.status === "success" - ? emailInputEl.value + ? emailInputEl.getValue() : undefined; updateSignupButton(); }, }); -const passwordInputEl = validateWithIndicator( +const passwordInputEl = new ValidatedHtmlInputElement( document.querySelector( ".page.pageLogin .register.side .passwordInput" ) as HTMLInputElement, @@ -192,9 +192,9 @@ const passwordInputEl = validateWithIndicator( const passwordVerifyInputEl = document.querySelector( ".page.pageLogin .register.side .verifyPasswordInput" ) as HTMLInputElement; -validateWithIndicator(passwordVerifyInputEl, { +new ValidatedHtmlInputElement(passwordVerifyInputEl, { isValid: async (passwordVerify: string) => { - return passwordInputEl.value === passwordVerify + return passwordInputEl.getValue() === passwordVerify ? true : "verify password not matching password"; }, @@ -203,7 +203,7 @@ validateWithIndicator(passwordVerifyInputEl, { registerForm.password = passwordInputEl.getValidationResult().status === "success" && result.status === "success" - ? passwordInputEl.value + ? passwordInputEl.getValue() : undefined; updateSignupButton(); }, diff --git a/frontend/src/ts/pages/profile-search.ts b/frontend/src/ts/pages/profile-search.ts index dcf52ea05c3a..7fea826ba13d 100644 --- a/frontend/src/ts/pages/profile-search.ts +++ b/frontend/src/ts/pages/profile-search.ts @@ -1,5 +1,24 @@ import Page from "./page"; import * as Skeleton from "../utils/skeleton"; +import Ape from "../ape"; +import { + ValidatedHtmlInputElement, + validateWithIndicator, +} from "../elements/input-validation"; +import { UserNameSchema, UserProfile } from "@monkeytype/schemas/users"; +import { remoteValidation } from "../utils/remote-validation"; +import * as NavigationEvent from "../observables/navigation-event"; + +let nameInputEl: ValidatedHtmlInputElement | null = null; +let lastProfile: UserProfile | null = null; + +function enableButton(): void { + $('.page.pageProfileSearch button[type="submit"]').prop("disabled", false); +} + +function disableButton(): void { + $('.page.pageProfileSearch button[type="submit"]').prop("disabled", true); +} export const page = new Page({ id: "profileSearch", @@ -10,9 +29,54 @@ export const page = new Page({ }, beforeShow: async (): Promise => { Skeleton.append("pageProfileSearch", "main"); - $(".page.pageProfileSearch input").val(""); + + if (nameInputEl === null) { + nameInputEl = validateWithIndicator( + document.querySelector( + ".page.pageProfileSearch input" + ) as HTMLInputElement, + { + schema: UserNameSchema, + isValid: remoteValidation( + async (name) => + Ape.users.getProfile({ params: { uidOrName: name } }), + { + check: (data) => { + lastProfile = data; + return true; + }, + on4xx: () => "Unknown user", + } + ), + callback: (result) => { + if (result.status === "success") { + enableButton(); + } else { + disableButton(); + lastProfile = null; + } + }, + } + ); + } + + nameInputEl.setValue(null); + disableButton(); }, afterShow: async (): Promise => { $(".page.pageProfileSearch input").trigger("focus"); }, }); + +$(".page.pageProfileSearch form").on("submit", (e) => { + e.preventDefault(); + if (lastProfile === null) return; + NavigationEvent.dispatch({ + url: `/profile/${lastProfile.name}`, + data: lastProfile, + }); +}); + +$(() => { + Skeleton.save("pageProfileSearch"); +}); diff --git a/frontend/src/ts/test/funbox/funbox-functions.ts b/frontend/src/ts/test/funbox/funbox-functions.ts index d26512871475..f461fe6b37e1 100644 --- a/frontend/src/ts/test/funbox/funbox-functions.ts +++ b/frontend/src/ts/test/funbox/funbox-functions.ts @@ -332,6 +332,30 @@ const list: Partial> = { return randomcaseword; }, }, + rot13: { + alterText(word: string): string { + let alphabet = "abcdefghijklmnopqrstuvwxyz"; + + let rot13Word = ""; + + for (let ch of word) { + let chIndex = alphabet.indexOf(ch.toLowerCase()); + if (chIndex === -1) { + rot13Word += ch; + continue; + } + + let rot13Ch = (chIndex + 13) % 26; + if (ch.toUpperCase() === ch) { + rot13Word += alphabet[rot13Ch]?.toUpperCase(); + } else { + rot13Word += alphabet[rot13Ch]; + } + } + + return rot13Word; + }, + }, backwards: { alterText(word: string): string { return word.split("").reverse().join(""); diff --git a/frontend/src/ts/test/test-ui.ts b/frontend/src/ts/test/test-ui.ts index e2ee27190b5f..a56078b923a9 100644 --- a/frontend/src/ts/test/test-ui.ts +++ b/frontend/src/ts/test/test-ui.ts @@ -1641,7 +1641,7 @@ function afterAnyTestInput( type: "textInput" | "delete" | "compositionUpdate", correctInput: boolean | null ): void { - if (type === "textInput") { + if (type === "textInput" || type === "compositionUpdate") { if ( correctInput === true || Config.playSoundOnError === "off" || diff --git a/frontend/src/ts/utils/misc.ts b/frontend/src/ts/utils/misc.ts index f4abae6998b5..2fbe06363193 100644 --- a/frontend/src/ts/utils/misc.ts +++ b/frontend/src/ts/utils/misc.ts @@ -112,54 +112,11 @@ export function objectToQueryString( return str.join("&"); } -declare global { - // type gets a "Duplicate identifier" error - // eslint-disable-next-line @typescript-eslint/consistent-type-definitions - interface Document { - mozCancelFullScreen?: () => Promise; - msRequestFullscreen?: () => Promise; - msExitFullscreen?: () => Promise; - webkitExitFullscreen?: () => Promise; - mozFullScreenElement?: Element; - msFullscreenElement?: Element; - webkitFullscreenElement?: Element; - } - // eslint-disable-next-line @typescript-eslint/consistent-type-definitions - interface HTMLElement { - msRequestFullscreen?: () => Promise; - mozRequestFullScreen?: () => Promise; - webkitRequestFullscreen?: () => Promise; - } -} - export function toggleFullscreen(): void { - const elem = document.documentElement; - if ( - !document.fullscreenElement && - !document.mozFullScreenElement && - !document.webkitFullscreenElement && - !document.msFullscreenElement - ) { - if (elem.requestFullscreen !== undefined) { - void elem.requestFullscreen(); - } else if (elem.msRequestFullscreen) { - void elem.msRequestFullscreen(); - } else if (elem.mozRequestFullScreen) { - void elem.mozRequestFullScreen(); - } else if (elem.webkitRequestFullscreen) { - // @ts-expect-error some code i found online - void elem.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); - } + if (!document.fullscreenElement) { + void document.documentElement.requestFullscreen(); } else { - if (document.exitFullscreen !== undefined) { - void document.exitFullscreen(); - } else if (document.msExitFullscreen) { - void document.msExitFullscreen(); - } else if (document.mozCancelFullScreen) { - void document.mozCancelFullScreen(); - } else if (document.webkitExitFullscreen) { - void document.webkitExitFullscreen(); - } + void document.exitFullscreen(); } } diff --git a/frontend/src/ts/utils/simple-modal.ts b/frontend/src/ts/utils/simple-modal.ts index a311fee467e1..599d821b8102 100644 --- a/frontend/src/ts/utils/simple-modal.ts +++ b/frontend/src/ts/utils/simple-modal.ts @@ -6,10 +6,10 @@ import * as Notifications from "../elements/notifications"; import * as ConnectionState from "../states/connection"; import { IsValidResponse, + ValidatedHtmlInputElement, Validation, ValidationOptions, ValidationResult, - validateWithIndicator as withValidation, } from "../elements/input-validation"; type CommonInput = { @@ -351,7 +351,7 @@ export class SimpleModal { debounceDelay: input.validation.debounceDelay, }; - withValidation(element, options); + new ValidatedHtmlInputElement(element, options); } }); diff --git a/frontend/static/languages/french_10k.json b/frontend/static/languages/french_10k.json index 7248077ab148..22dd85f18bce 100644 --- a/frontend/static/languages/french_10k.json +++ b/frontend/static/languages/french_10k.json @@ -230,7 +230,7 @@ "claire", "classe", "clef", - "coeur", + "cœur", "coin", "colère", "colline", @@ -859,8 +859,8 @@ "occasion", "occuper", "odeur", - "oeil", - "oeuvre", + "œil", + "œuvre", "officier", "offrir", "oh", @@ -2498,7 +2498,7 @@ "terroriste", "bercez", "ôter", - "manuvres", + "manœuvres", "domine", "aristocrate", "universités", @@ -4918,7 +4918,7 @@ "termes", "pommes", "semi", - "manuvre", + "manœuvre", "aquilon", "collègue", "matérielles", @@ -6309,7 +6309,7 @@ "soudoyer", "recenser", "recherché", - "rancurs", + "rancœurs", "nombrilisme", "huilerie", "pullulation", @@ -6916,7 +6916,7 @@ "légaux", "voyons", "vaccins", - "chur", + "chœur", "tombait", "tournés", "timoré", @@ -7083,7 +7083,7 @@ "dividendes", "bougies", "dispose", - "nud", + "nœud", "différé", "gaulliste", "sens unique", @@ -7787,7 +7787,7 @@ "unanimement", "nuance", "étudiés", - "crève-cur", + "crève-cœur", "créateurs", "variations", "pébroc", @@ -8523,7 +8523,7 @@ "arrêté", "cornu", "acrobatie", - "coup d'il", + "coup d'œil", "demandent", "sonnerie", "bambins", @@ -9807,7 +9807,7 @@ "pétulant", "nutrition", "marches", - "blanc d'uf", + "blanc d'œuf", "ambiguë", "land", "jarousse", diff --git a/frontend/static/languages/french_1k.json b/frontend/static/languages/french_1k.json index 3a509508dc23..c24c0459a345 100644 --- a/frontend/static/languages/french_1k.json +++ b/frontend/static/languages/french_1k.json @@ -228,7 +228,7 @@ "claire", "classe", "clef", - "coeur", + "cœur", "coin", "colère", "colline", @@ -851,8 +851,8 @@ "occasion", "occuper", "odeur", - "oeil", - "oeuvre", + "œil", + "œuvre", "officier", "offrir", "oh", diff --git a/frontend/static/languages/french_2k.json b/frontend/static/languages/french_2k.json index 333e5142ac05..ad0c86481809 100644 --- a/frontend/static/languages/french_2k.json +++ b/frontend/static/languages/french_2k.json @@ -230,7 +230,7 @@ "claire", "classe", "clef", - "coeur", + "cœur", "coin", "colère", "colline", @@ -859,8 +859,8 @@ "occasion", "occuper", "odeur", - "oeil", - "oeuvre", + "œil", + "œuvre", "officier", "offrir", "oh", diff --git a/frontend/static/languages/french_600k.json b/frontend/static/languages/french_600k.json index 25047c03a9ed..2edaf2675946 100644 --- a/frontend/static/languages/french_600k.json +++ b/frontend/static/languages/french_600k.json @@ -5730,10 +5730,10 @@ "acnés", "acochlidiidé", "acochlidiidés", - "acoele", - "acoeles", - "acoelomate", - "acoelomates", + "acœle", + "acœles", + "acœlomate", + "acœlomates", "acolytat", "acolytats", "acolyte", @@ -16296,8 +16296,8 @@ "allodialité", "allodialités", "allodiaux", - "alloeocoele", - "alloeocoeles", + "alloeocœle", + "alloeocœles", "alloesthésie", "alloesthésies", "allogame", @@ -31192,7 +31192,7 @@ "archontats", "archonte", "archontes", - "archontophoenix", + "archontophœnix", "archosaurien", "archosauriens", "archère", @@ -57551,10 +57551,10 @@ "bioclimats", "bioclinique", "biocliniques", - "biocoenose", - "biocoenoses", - "biocoenotique", - "biocoenotiques", + "biocœnose", + "biocœnoses", + "biocœnotique", + "biocœnotiques", "biocompatibilité", "biocompatibilités", "biocompatible", @@ -60047,12 +60047,12 @@ "blastiques", "blastocladiale", "blastocladiales", - "blastocoele", - "blastocoeles", - "blastocoelien", - "blastocoelienne", - "blastocoeliennes", - "blastocoeliens", + "blastocœle", + "blastocœles", + "blastocœlien", + "blastocœlienne", + "blastocœliennes", + "blastocœliens", "blastocyste", "blastocystes", "blastocyte", @@ -61277,10 +61277,10 @@ "boettée", "boettées", "boettés", - "boeuf", - "boeufs", - "boeutier", - "boeutiers", + "bœuf", + "bœufs", + "bœutier", + "bœutiers", "bof", "boffuma", "boffumer", @@ -94426,8 +94426,8 @@ "choerocampe", "choerocampes", "choesels", - "choeur", - "choeurs", + "chœur", + "chœurs", "chogramme", "chogrammes", "choie", @@ -103757,60 +103757,60 @@ "codétenus", "codéthyline", "codéthylines", - "coeco", - "coecosigmoïdostomie", - "coecosigmoïdostomies", - "coecostomie", - "coecostomies", + "cœco", + "cœcosigmoïdostomie", + "cœcosigmoïdostomies", + "cœcostomie", + "cœcostomies", "coefficient", "coefficients", - "coelacanthe", - "coelacanthes", - "coelentéré", - "coelentérés", - "coeliakie", - "coeliakies", - "coelialgie", - "coelialgies", - "coeliaque", - "coeliaques", - "coelifère", - "coelifères", - "coeliochirurgie", - "coeliochirurgies", - "coeliome", - "coeliomes", - "coelioscope", - "coelioscopes", - "coelioscopie", - "coelioscopies", - "coelioscopique", - "coelioscopiques", - "coeliotomie", - "coeliotomies", - "coelioxys", - "coelodendridé", - "coelodendridés", - "coelomate", - "coelomates", - "coelome", - "coelomes", - "coelomique", - "coelomiques", - "coelonychie", - "coelonychies", - "coelope", - "coelopes", - "coelosomie", - "coelosomien", - "coelosomienne", - "coelosomiennes", - "coelosomiens", - "coelosomies", - "coelothéliome", - "coelothéliomes", - "coelurosaure", - "coelurosaures", + "cœlacanthe", + "cœlacanthes", + "cœlentéré", + "cœlentérés", + "cœliakie", + "cœliakies", + "cœlialgie", + "cœlialgies", + "cœliaque", + "cœliaques", + "cœlifère", + "cœlifères", + "cœliochirurgie", + "cœliochirurgies", + "cœliome", + "cœliomes", + "cœlioscope", + "cœlioscopes", + "cœlioscopie", + "cœlioscopies", + "cœlioscopique", + "cœlioscopiques", + "cœliotomie", + "cœliotomies", + "cœlioxys", + "cœlodendridé", + "cœlodendridés", + "cœlomate", + "cœlomates", + "cœlome", + "cœlomes", + "cœlomique", + "cœlomiques", + "cœlonychie", + "cœlonychies", + "cœlope", + "cœlopes", + "cœlosomie", + "cœlosomien", + "cœlosomienne", + "cœlosomiennes", + "cœlosomiens", + "cœlosomies", + "cœlothéliome", + "cœlothéliomes", + "cœlurosaure", + "cœlurosaures", "coempereur", "coempereurs", "coendou", @@ -103819,12 +103819,12 @@ "coenesthésies", "coengagement", "coengagements", - "coenomyie", - "coenomyies", - "coenonympha", - "coenonymphas", - "coenothécale", - "coenothécales", + "cœnomyie", + "cœnomyies", + "cœnonympha", + "cœnonymphas", + "cœnothécale", + "cœnothécales", "coentraîneur", "coentraîneurs", "coentraînrice", @@ -103856,8 +103856,8 @@ "coerébidés", "coesre", "coesres", - "coeur", - "coeurs", + "cœur", + "cœurs", "coexista", "coexister", "coexistai", @@ -106159,8 +106159,8 @@ "colpidiums", "colpo", "colpocléisis", - "colpocoeliotomie", - "colpocoeliotomies", + "colpocœliotomie", + "colpocœliotomies", "colpocystographie", "colpocystographies", "colpocystopexie", @@ -113597,8 +113597,8 @@ "consistâtes", "consistèrent", "consisté", - "consoeur", - "consoeurs", + "consœur", + "consœurs", "consol", "consola", "consoler", @@ -116142,8 +116142,8 @@ "contrechâssis", "contreclef", "contreclefs", - "contrecoeur", - "contrecoeurs", + "contrecœur", + "contrecœurs", "contrecolla", "contrecoller", "contrecollage", @@ -135394,8 +135394,8 @@ "dendrochronologiques", "dendroclimatologie", "dendroclimatologies", - "dendrocoelum", - "dendrocoelums", + "dendrocœlum", + "dendrocœlums", "dendrocolapte", "dendrocolaptes", "dendroctone", @@ -139157,8 +139157,8 @@ "dicranomyias", "dicranure", "dicranures", - "dicrocoeliose", - "dicrocoelioses", + "dicrocœliose", + "dicrocœlioses", "dicroloma", "dicrolomas", "dicrote", @@ -139324,8 +139324,8 @@ "diencéphalo", "diencéphalopathie", "diencéphalopathies", - "dienoestrol", - "dienoestrols", + "dienœstrol", + "dienœstrols", "dientamoebidé", "dientamoebidés", "dieppois", @@ -140984,7 +140984,7 @@ "dioeciques", "dioecète", "dioecètes", - "dioestrus", + "diœstrus", "diogenes", "diogène", "diogènes", @@ -144890,8 +144890,8 @@ "diéthyliques", "diéthylmalonylurée", "diéthylmalonylurées", - "diéthylstilboestrol", - "diéthylstilboestrols", + "diéthylstilbœstrol", + "diéthylstilbœstrols", "diéthyltoluamide", "diéthyltoluamides", "diéthylèneglycol", @@ -160174,47 +160174,47 @@ "décodée", "décodées", "décodés", - "décoeura", - "décoeurer", - "décoeurage", - "décoeurages", - "décoeurai", - "décoeuraient", - "décoeurais", - "décoeurait", - "décoeurant", - "décoeuras", - "décoeurasse", - "décoeurassent", - "décoeurasses", - "décoeurassiez", - "décoeurassions", - "décoeure", - "décoeurent", - "décoeurera", - "décoeurerai", - "décoeureraient", - "décoeurerais", - "décoeurerait", - "décoeureras", - "décoeurerez", - "décoeureriez", - "décoeurerions", - "décoeurerons", - "décoeureront", - "décoeures", - "décoeurez", - "décoeuriez", - "décoeurions", - "décoeurons", - "décoeurâmes", - "décoeurât", - "décoeurâtes", - "décoeurèrent", - "décoeuré", - "décoeurée", - "décoeurées", - "décoeurés", + "décœura", + "décœurer", + "décœurage", + "décœurages", + "décœurai", + "décœuraient", + "décœurais", + "décœurait", + "décœurant", + "décœuras", + "décœurasse", + "décœurassent", + "décœurasses", + "décœurassiez", + "décœurassions", + "décœure", + "décœurent", + "décœurera", + "décœurerai", + "décœureraient", + "décœurerais", + "décœurerait", + "décœureras", + "décœurerez", + "décœureriez", + "décœurerions", + "décœurerons", + "décœureront", + "décœures", + "décœurez", + "décœuriez", + "décœurions", + "décœurons", + "décœurâmes", + "décœurât", + "décœurâtes", + "décœurèrent", + "décœuré", + "décœurée", + "décœurées", + "décœurés", "décoffra", "décoffrer", "décoffrage", @@ -204065,47 +204065,47 @@ "désodée", "désodées", "désodés", - "désoeuvra", - "désoeuvrer", - "désoeuvrai", - "désoeuvraient", - "désoeuvrais", - "désoeuvrait", - "désoeuvrant", - "désoeuvras", - "désoeuvrasse", - "désoeuvrassent", - "désoeuvrasses", - "désoeuvrassiez", - "désoeuvrassions", - "désoeuvre", - "désoeuvrement", - "désoeuvrements", - "désoeuvrent", - "désoeuvrera", - "désoeuvrerai", - "désoeuvreraient", - "désoeuvrerais", - "désoeuvrerait", - "désoeuvreras", - "désoeuvrerez", - "désoeuvreriez", - "désoeuvrerions", - "désoeuvrerons", - "désoeuvreront", - "désoeuvres", - "désoeuvrez", - "désoeuvriez", - "désoeuvrions", - "désoeuvrons", - "désoeuvrâmes", - "désoeuvrât", - "désoeuvrâtes", - "désoeuvrèrent", - "désoeuvré", - "désoeuvrée", - "désoeuvrées", - "désoeuvrés", + "désœuvra", + "désœuvrer", + "désœuvrai", + "désœuvraient", + "désœuvrais", + "désœuvrait", + "désœuvrant", + "désœuvras", + "désœuvrasse", + "désœuvrassent", + "désœuvrasses", + "désœuvrassiez", + "désœuvrassions", + "désœuvre", + "désœuvrement", + "désœuvrements", + "désœuvrent", + "désœuvrera", + "désœuvrerai", + "désœuvreraient", + "désœuvrerais", + "désœuvrerait", + "désœuvreras", + "désœuvrerez", + "désœuvreriez", + "désœuvrerions", + "désœuvrerons", + "désœuvreront", + "désœuvres", + "désœuvrez", + "désœuvriez", + "désœuvrions", + "désœuvrons", + "désœuvrâmes", + "désœuvrât", + "désœuvrâtes", + "désœuvrèrent", + "désœuvré", + "désœuvrée", + "désœuvrées", + "désœuvrés", "désofficialisa", "désofficialiser", "désofficialisai", @@ -212576,8 +212576,8 @@ "ectoplasmies", "ectoplasmique", "ectoplasmiques", - "ectopoesophage", - "ectopoesophages", + "ectopœsophage", + "ectopœsophages", "ectoprocte", "ectoproctes", "ectosome", @@ -257888,28 +257888,28 @@ "focus", "foehn", "foehns", - "foetal", - "foetale", - "foetales", - "foetalisation", - "foetalisations", - "foetaux", - "foeticide", - "foeticides", - "foeticulture", - "foeticultures", - "foeto", - "foetographie", - "foetographies", - "foetologie", - "foetologies", - "foetopathie", - "foetopathies", - "foetoscope", - "foetoscopes", - "foetoscopie", - "foetoscopies", - "foetus", + "fœtal", + "fœtale", + "fœtales", + "fœtalisation", + "fœtalisations", + "fœtaux", + "fœticide", + "fœticides", + "fœticulture", + "fœticultures", + "fœto", + "fœtographie", + "fœtographies", + "fœtologie", + "fœtologies", + "fœtopathie", + "fœtopathies", + "fœtoscope", + "fœtoscopes", + "fœtoscopie", + "fœtoscopies", + "fœtus", "fofolle", "foufou", "fofollement", @@ -261660,8 +261660,8 @@ "framboesias", "framboeside", "framboesides", - "framboesome", - "framboesomes", + "frambœsome", + "frambœsomes", "framboisa", "framboiser", "framboisai", @@ -294620,16 +294620,16 @@ "hypernéphromes", "hyperoctanoatémie", "hyperoctanoatémies", - "hyperoestrogénie", - "hyperoestrogénies", - "hyperoestrogénisme", - "hyperoestrogénismes", - "hyperoestrogénémie", - "hyperoestrogénémies", - "hyperoestroïdie", - "hyperoestroïdies", - "hyperoestroïdurie", - "hyperoestroïduries", + "hyperœstrogénie", + "hyperœstrogénies", + "hyperœstrogénisme", + "hyperœstrogénismes", + "hyperœstrogénémie", + "hyperœstrogénémies", + "hyperœstroïdie", + "hyperœstroïdies", + "hyperœstroïdurie", + "hyperœstroïduries", "hyperolius", "hyperonyme", "hyperonymes", @@ -312607,7 +312607,7 @@ "interoculaires", "interocéanique", "interocéaniques", - "interoestrus", + "interœstrus", "interolivaire", "interolivaires", "interoperculaire", @@ -334225,8 +334225,8 @@ "lymphodermies", "lymphodialyse", "lymphodialyses", - "lymphoedème", - "lymphoedèmes", + "lymphœdème", + "lymphœdèmes", "lymphogenèse", "lymphogenèses", "lymphogonie", @@ -339671,56 +339671,56 @@ "manodétendeurs", "manodétenteur", "manodétenteurs", - "manoeuvra", - "manoeuvrer", - "manoeuvrabilité", - "manoeuvrabilités", - "manoeuvrable", - "manoeuvrables", - "manoeuvrai", - "manoeuvraient", - "manoeuvrais", - "manoeuvrait", - "manoeuvrant", - "manoeuvrante", - "manoeuvrantes", - "manoeuvrants", - "manoeuvras", - "manoeuvrasse", - "manoeuvrassent", - "manoeuvrasses", - "manoeuvrassiez", - "manoeuvrassions", - "manoeuvre", - "manoeuvrent", - "manoeuvrera", - "manoeuvrerai", - "manoeuvreraient", - "manoeuvrerais", - "manoeuvrerait", - "manoeuvreras", - "manoeuvrerez", - "manoeuvreriez", - "manoeuvrerions", - "manoeuvrerons", - "manoeuvreront", - "manoeuvres", - "manoeuvrez", - "manoeuvrier", - "manoeuvriers", - "manoeuvriez", - "manoeuvrions", - "manoeuvrière", - "manoeuvrières", - "manoeuvrons", - "manoeuvrâmes", - "manoeuvrât", - "manoeuvrâtes", - "manoeuvrèrent", - "manoeuvré", - "manoeuvrée", - "manoeuvrées", - "manoeuvrés", + "manœuvra", + "manœuvrer", + "manœuvrabilité", + "manœuvrabilités", + "manœuvrable", + "manœuvrables", + "manœuvrai", + "manœuvraient", + "manœuvrais", + "manœuvrait", + "manœuvrant", + "manœuvrante", + "manœuvrantes", + "manœuvrants", + "manœuvras", + "manœuvrasse", + "manœuvrassent", + "manœuvrasses", + "manœuvrassiez", + "manœuvrassions", + "manœuvre", + "manœuvrent", + "manœuvrera", + "manœuvrerai", + "manœuvreraient", + "manœuvrerais", + "manœuvrerait", + "manœuvreras", + "manœuvrerez", + "manœuvreriez", + "manœuvrerions", + "manœuvrerons", + "manœuvreront", + "manœuvres", + "manœuvrez", + "manœuvrier", + "manœuvriers", + "manœuvriez", + "manœuvrions", + "manœuvrière", + "manœuvrières", + "manœuvrons", + "manœuvrâmes", + "manœuvrât", + "manœuvrâtes", + "manœuvrèrent", + "manœuvré", + "manœuvrée", + "manœuvrées", + "manœuvrés", "manographe", "manographes", "manographie", @@ -344634,7 +344634,7 @@ "melette", "melettes", "melianthus", - "meliboeus", + "melibœus", "melitta", "melkite", "melkites", @@ -350833,7 +350833,7 @@ "moeres", "moeritherium", "moeritheriums", - "moeurs", + "mœurs", "mofette", "mofettes", "moffla", @@ -359319,8 +359319,8 @@ "myomètres", "myonécrose", "myonécroses", - "myooedème", - "myooedèmes", + "myoœdème", + "myoœdèmes", "myopathe", "myopathes", "myopathia", @@ -359842,11 +359842,11 @@ "myxobactériées", "myxochondrome", "myxochondromes", - "myxoedème", - "myxoedèmes", - "myxoedémateuse", - "myxoedémateux", - "myxoedémateuses", + "myxœdème", + "myxœdèmes", + "myxœdémateuse", + "myxœdémateux", + "myxœdémateuses", "myxomatose", "myxomatoses", "myxome", @@ -369273,8 +369273,8 @@ "nodulose", "noduloses", "nodus", - "noeud", - "noeuds", + "nœud", + "nœuds", "noie", "noyer", "noient", @@ -375274,458 +375274,458 @@ "odyssées", "odéon", "odéons", - "oecanthe", - "oecanthes", - "oecologie", - "oecologies", - "oecologique", - "oecologiques", - "oecophylle", - "oecophylles", - "oecuménicité", - "oecuménicités", - "oecuménique", - "oecuméniquement", - "oecuméniques", - "oecuménisme", - "oecuménismes", - "oecuméniste", - "oecuménistes", - "oeda", - "oedas", - "oedicnème", - "oedicnèmes", - "oedipe", - "oedipianisa", - "oedipianiser", - "oedipianisai", - "oedipianisaient", - "oedipianisais", - "oedipianisait", - "oedipianisant", - "oedipianisas", - "oedipianisasse", - "oedipianisassent", - "oedipianisasses", - "oedipianisassiez", - "oedipianisassions", - "oedipianisation", - "oedipianisations", - "oedipianise", - "oedipianisent", - "oedipianisera", - "oedipianiserai", - "oedipianiseraient", - "oedipianiserais", - "oedipianiserait", - "oedipianiseras", - "oedipianiserez", - "oedipianiseriez", - "oedipianiserions", - "oedipianiserons", - "oedipianiseront", - "oedipianises", - "oedipianisez", - "oedipianisiez", - "oedipianisions", - "oedipianisons", - "oedipianisâmes", - "oedipianisât", - "oedipianisâtes", - "oedipianisèrent", - "oedipianisé", - "oedipianisée", - "oedipianisées", - "oedipianisés", - "oedipien", - "oedipienne", - "oedipiennes", - "oedipiens", - "oedipisme", - "oedipismes", - "oedipode", - "oedipodes", - "oedomètre", - "oedomètres", - "oedométrie", - "oedométries", - "oedométrique", - "oedométriques", - "oedème", - "oedèmes", - "oedémagène", - "oedémagènes", - "oedémateuse", - "oedémateux", - "oedémateuses", - "oedématia", - "oedématier", - "oedématiai", - "oedématiaient", - "oedématiais", - "oedématiait", - "oedématiant", - "oedématias", - "oedématiasse", - "oedématiassent", - "oedématiasses", - "oedématiassiez", - "oedématiassions", - "oedématie", - "oedématient", - "oedématiera", - "oedématierai", - "oedématieraient", - "oedématierais", - "oedématierait", - "oedématieras", - "oedématierez", - "oedématieriez", - "oedématierions", - "oedématierons", - "oedématieront", - "oedématies", - "oedématiez", - "oedématiiez", - "oedématiions", - "oedémations", - "oedématisa", - "oedématiser", - "oedématisai", - "oedématisaient", - "oedématisais", - "oedématisait", - "oedématisant", - "oedématisas", - "oedématisasse", - "oedématisassent", - "oedématisasses", - "oedématisassiez", - "oedématisassions", - "oedématise", - "oedématisent", - "oedématisera", - "oedématiserai", - "oedématiseraient", - "oedématiserais", - "oedématiserait", - "oedématiseras", - "oedématiserez", - "oedématiseriez", - "oedématiserions", - "oedématiserons", - "oedématiseront", - "oedématises", - "oedématisez", - "oedématisiez", - "oedématisions", - "oedématisons", - "oedématisâmes", - "oedématisât", - "oedématisâtes", - "oedématisèrent", - "oedématisé", - "oedématisée", - "oedématisées", - "oedématisés", - "oedématiâmes", - "oedématiât", - "oedématiâtes", - "oedématièrent", - "oedématié", - "oedématiée", - "oedématiées", - "oedématiés", - "oeil", - "oeillada", - "oeillader", - "oeilladai", - "oeilladaient", - "oeilladais", - "oeilladait", - "oeilladant", - "oeilladas", - "oeilladasse", - "oeilladassent", - "oeilladasses", - "oeilladassiez", - "oeilladassions", - "oeillade", - "oeilladent", - "oeilladera", - "oeilladerai", - "oeilladeraient", - "oeilladerais", - "oeilladerait", - "oeilladeras", - "oeilladerez", - "oeilladeriez", - "oeilladerions", - "oeilladerons", - "oeilladeront", - "oeillades", - "oeilladez", - "oeilladiez", - "oeilladions", - "oeilladons", - "oeilladâmes", - "oeilladât", - "oeilladâtes", - "oeilladèrent", - "oeilladé", - "oeilladée", - "oeilladées", - "oeilladés", - "oeillard", - "oeillards", - "oeillet", - "oeilleteuse", - "oeilleteuses", - "oeilleton", - "oeilletonna", - "oeilletonner", - "oeilletonnage", - "oeilletonnages", - "oeilletonnai", - "oeilletonnaient", - "oeilletonnais", - "oeilletonnait", - "oeilletonnant", - "oeilletonnas", - "oeilletonnasse", - "oeilletonnassent", - "oeilletonnasses", - "oeilletonnassiez", - "oeilletonnassions", - "oeilletonne", - "oeilletonnent", - "oeilletonnera", - "oeilletonnerai", - "oeilletonneraient", - "oeilletonnerais", - "oeilletonnerait", - "oeilletonneras", - "oeilletonnerez", - "oeilletonneriez", - "oeilletonnerions", - "oeilletonnerons", - "oeilletonneront", - "oeilletonnes", - "oeilletonnez", - "oeilletonniez", - "oeilletonnions", - "oeilletonnons", - "oeilletonnâmes", - "oeilletonnât", - "oeilletonnâtes", - "oeilletonnèrent", - "oeilletonné", - "oeilletonnée", - "oeilletonnées", - "oeilletonnés", - "oeilletons", - "oeillets", - "oeillette", - "oeillettes", - "oeillère", - "oeillères", - "oeillé", - "oeillée", - "oeillées", - "oeillés", - "oeils", - "oekoumène", - "oekoumènes", - "oenanthal", - "oenanthals", - "oenanthe", - "oenanthes", - "oenanthique", - "oenanthiques", - "oenanthylique", - "oenanthyliques", - "oeneis", - "oenilisme", - "oenilismes", - "oenistéries", - "oenochoé", - "oenochoés", - "oenolature", - "oenolatures", - "oenolique", - "oenoliques", - "oenolisme", - "oenolismes", - "oenologie", - "oenologies", - "oenologique", - "oenologiquement", - "oenologiques", - "oenologue", - "oenologues", - "oenolé", - "oenolés", - "oenomancie", - "oenomancies", - "oenomanie", - "oenomanies", - "oenomètre", - "oenomètres", - "oenométrie", - "oenométries", - "oenométrique", - "oenométriques", - "oenotechnie", - "oenotechnies", - "oenothera", - "oenotheras", - "oenothèque", - "oenothèques", - "oenothère", - "oenothères", - "oenothéracée", - "oenothéracées", - "oersted", - "oersteds", - "oerstite", - "oerstites", - "oesocardiogramme", - "oesocardiogrammes", - "oesoduodénostomie", - "oesoduodénostomies", - "oesofibroscope", - "oesofibroscopes", - "oesofibroscopie", - "oesofibroscopies", - "oesogastroduodénofibroscopie", - "oesogastroduodénofibroscopies", - "oesogastroduodénoscopie", - "oesogastroduodénoscopies", - "oesogastrostomie", - "oesogastrostomies", - "oesojéjunostomie", - "oesojéjunostomies", - "oesophage", - "oesophagectomie", - "oesophagectomies", - "oesophages", - "oesophagien", - "oesophagienne", - "oesophagiennes", - "oesophagiens", - "oesophagique", - "oesophagiques", - "oesophagisme", - "oesophagismes", - "oesophagite", - "oesophagites", - "oesophago", - "oesophagofibroscope", - "oesophagofibroscopes", - "oesophagofibroscopie", - "oesophagofibroscopies", - "oesophagomalacie", - "oesophagomalacies", - "oesophagoplastie", - "oesophagoplasties", - "oesophagorragie", - "oesophagorragies", - "oesophagoscope", - "oesophagoscopes", - "oesophagoscopie", - "oesophagoscopies", - "oesophagostomie", - "oesophagostomies", - "oesophagotomie", - "oesophagotomies", - "oesophagotubage", - "oesophagotubages", - "oestradiol", - "oestradiols", - "oestradiolémie", - "oestradiolémies", - "oestral", - "oestrale", - "oestrales", - "oestrane", - "oestranediol", - "oestranediols", - "oestranes", - "oestraux", - "oestre", - "oestres", - "oestridé", - "oestridés", - "oestrien", - "oestrienne", - "oestriennes", - "oestriens", - "oestriol", - "oestriols", - "oestro", - "oestrogène", - "oestrogènes", - "oestrogénie", - "oestrogénies", - "oestrogénique", - "oestrogéniques", - "oestrogénothérapie", - "oestrogénothérapies", - "oestrone", - "oestrones", - "oestroprogestatif", - "oestroprogestatifs", - "oestroprogestative", - "oestroprogestatives", - "oestroïde", - "oestroïdes", - "oestroïdurie", - "oestroïduries", - "oestrus", - "oeuf", - "oeufrier", - "oeufriers", - "oeufs", - "oeuvra", - "oeuvrer", - "oeuvrai", - "oeuvraient", - "oeuvrais", - "oeuvrait", - "oeuvrant", - "oeuvras", - "oeuvrasse", - "oeuvrassent", - "oeuvrasses", - "oeuvrassiez", - "oeuvrassions", - "oeuvre", - "oeuvrent", - "oeuvrera", - "oeuvrerai", - "oeuvreraient", - "oeuvrerais", - "oeuvrerait", - "oeuvreras", - "oeuvrerez", - "oeuvreriez", - "oeuvrerions", - "oeuvrerons", - "oeuvreront", - "oeuvres", - "oeuvrez", - "oeuvriez", - "oeuvrions", - "oeuvrons", - "oeuvrâmes", - "oeuvrât", - "oeuvrâtes", - "oeuvrèrent", - "oeuvré", - "oeuvé", - "oeuvée", - "oeuvées", - "oeuvés", + "œcanthe", + "œcanthes", + "œcologie", + "œcologies", + "œcologique", + "œcologiques", + "œcophylle", + "œcophylles", + "œcuménicité", + "œcuménicités", + "œcuménique", + "œcuméniquement", + "œcuméniques", + "œcuménisme", + "œcuménismes", + "œcuméniste", + "œcuménistes", + "œda", + "œdas", + "œdicnème", + "œdicnèmes", + "œdipe", + "œdipianisa", + "œdipianiser", + "œdipianisai", + "œdipianisaient", + "œdipianisais", + "œdipianisait", + "œdipianisant", + "œdipianisas", + "œdipianisasse", + "œdipianisassent", + "œdipianisasses", + "œdipianisassiez", + "œdipianisassions", + "œdipianisation", + "œdipianisations", + "œdipianise", + "œdipianisent", + "œdipianisera", + "œdipianiserai", + "œdipianiseraient", + "œdipianiserais", + "œdipianiserait", + "œdipianiseras", + "œdipianiserez", + "œdipianiseriez", + "œdipianiserions", + "œdipianiserons", + "œdipianiseront", + "œdipianises", + "œdipianisez", + "œdipianisiez", + "œdipianisions", + "œdipianisons", + "œdipianisâmes", + "œdipianisât", + "œdipianisâtes", + "œdipianisèrent", + "œdipianisé", + "œdipianisée", + "œdipianisées", + "œdipianisés", + "œdipien", + "œdipienne", + "œdipiennes", + "œdipiens", + "œdipisme", + "œdipismes", + "œdipode", + "œdipodes", + "œdomètre", + "œdomètres", + "œdométrie", + "œdométries", + "œdométrique", + "œdométriques", + "œdème", + "œdèmes", + "œdémagène", + "œdémagènes", + "œdémateuse", + "œdémateux", + "œdémateuses", + "œdématia", + "œdématier", + "œdématiai", + "œdématiaient", + "œdématiais", + "œdématiait", + "œdématiant", + "œdématias", + "œdématiasse", + "œdématiassent", + "œdématiasses", + "œdématiassiez", + "œdématiassions", + "œdématie", + "œdématient", + "œdématiera", + "œdématierai", + "œdématieraient", + "œdématierais", + "œdématierait", + "œdématieras", + "œdématierez", + "œdématieriez", + "œdématierions", + "œdématierons", + "œdématieront", + "œdématies", + "œdématiez", + "œdématiiez", + "œdématiions", + "œdémations", + "œdématisa", + "œdématiser", + "œdématisai", + "œdématisaient", + "œdématisais", + "œdématisait", + "œdématisant", + "œdématisas", + "œdématisasse", + "œdématisassent", + "œdématisasses", + "œdématisassiez", + "œdématisassions", + "œdématise", + "œdématisent", + "œdématisera", + "œdématiserai", + "œdématiseraient", + "œdématiserais", + "œdématiserait", + "œdématiseras", + "œdématiserez", + "œdématiseriez", + "œdématiserions", + "œdématiserons", + "œdématiseront", + "œdématises", + "œdématisez", + "œdématisiez", + "œdématisions", + "œdématisons", + "œdématisâmes", + "œdématisât", + "œdématisâtes", + "œdématisèrent", + "œdématisé", + "œdématisée", + "œdématisées", + "œdématisés", + "œdématiâmes", + "œdématiât", + "œdématiâtes", + "œdématièrent", + "œdématié", + "œdématiée", + "œdématiées", + "œdématiés", + "œil", + "œillada", + "œillader", + "œilladai", + "œilladaient", + "œilladais", + "œilladait", + "œilladant", + "œilladas", + "œilladasse", + "œilladassent", + "œilladasses", + "œilladassiez", + "œilladassions", + "œillade", + "œilladent", + "œilladera", + "œilladerai", + "œilladeraient", + "œilladerais", + "œilladerait", + "œilladeras", + "œilladerez", + "œilladeriez", + "œilladerions", + "œilladerons", + "œilladeront", + "œillades", + "œilladez", + "œilladiez", + "œilladions", + "œilladons", + "œilladâmes", + "œilladât", + "œilladâtes", + "œilladèrent", + "œilladé", + "œilladée", + "œilladées", + "œilladés", + "œillard", + "œillards", + "œillet", + "œilleteuse", + "œilleteuses", + "œilleton", + "œilletonna", + "œilletonner", + "œilletonnage", + "œilletonnages", + "œilletonnai", + "œilletonnaient", + "œilletonnais", + "œilletonnait", + "œilletonnant", + "œilletonnas", + "œilletonnasse", + "œilletonnassent", + "œilletonnasses", + "œilletonnassiez", + "œilletonnassions", + "œilletonne", + "œilletonnent", + "œilletonnera", + "œilletonnerai", + "œilletonneraient", + "œilletonnerais", + "œilletonnerait", + "œilletonneras", + "œilletonnerez", + "œilletonneriez", + "œilletonnerions", + "œilletonnerons", + "œilletonneront", + "œilletonnes", + "œilletonnez", + "œilletonniez", + "œilletonnions", + "œilletonnons", + "œilletonnâmes", + "œilletonnât", + "œilletonnâtes", + "œilletonnèrent", + "œilletonné", + "œilletonnée", + "œilletonnées", + "œilletonnés", + "œilletons", + "œillets", + "œillette", + "œillettes", + "œillère", + "œillères", + "œillé", + "œillée", + "œillées", + "œillés", + "œils", + "œkoumène", + "œkoumènes", + "œnanthal", + "œnanthals", + "œnanthe", + "œnanthes", + "œnanthique", + "œnanthiques", + "œnanthylique", + "œnanthyliques", + "œneis", + "œnilisme", + "œnilismes", + "œnistéries", + "œnochoé", + "œnochoés", + "œnolature", + "œnolatures", + "œnolique", + "œnoliques", + "œnolisme", + "œnolismes", + "œnologie", + "œnologies", + "œnologique", + "œnologiquement", + "œnologiques", + "œnologue", + "œnologues", + "œnolé", + "œnolés", + "œnomancie", + "œnomancies", + "œnomanie", + "œnomanies", + "œnomètre", + "œnomètres", + "œnométrie", + "œnométries", + "œnométrique", + "œnométriques", + "œnotechnie", + "œnotechnies", + "œnothera", + "œnotheras", + "œnothèque", + "œnothèques", + "œnothère", + "œnothères", + "œnothéracée", + "œnothéracées", + "œrsted", + "œrsteds", + "œrstite", + "œrstites", + "œsocardiogramme", + "œsocardiogrammes", + "œsoduodénostomie", + "œsoduodénostomies", + "œsofibroscope", + "œsofibroscopes", + "œsofibroscopie", + "œsofibroscopies", + "œsogastroduodénofibroscopie", + "œsogastroduodénofibroscopies", + "œsogastroduodénoscopie", + "œsogastroduodénoscopies", + "œsogastrostomie", + "œsogastrostomies", + "œsojéjunostomie", + "œsojéjunostomies", + "œsophage", + "œsophagectomie", + "œsophagectomies", + "œsophages", + "œsophagien", + "œsophagienne", + "œsophagiennes", + "œsophagiens", + "œsophagique", + "œsophagiques", + "œsophagisme", + "œsophagismes", + "œsophagite", + "œsophagites", + "œsophago", + "œsophagofibroscope", + "œsophagofibroscopes", + "œsophagofibroscopie", + "œsophagofibroscopies", + "œsophagomalacie", + "œsophagomalacies", + "œsophagoplastie", + "œsophagoplasties", + "œsophagorragie", + "œsophagorragies", + "œsophagoscope", + "œsophagoscopes", + "œsophagoscopie", + "œsophagoscopies", + "œsophagostomie", + "œsophagostomies", + "œsophagotomie", + "œsophagotomies", + "œsophagotubage", + "œsophagotubages", + "œstradiol", + "œstradiols", + "œstradiolémie", + "œstradiolémies", + "œstral", + "œstrale", + "œstrales", + "œstrane", + "œstranediol", + "œstranediols", + "œstranes", + "œstraux", + "œstre", + "œstres", + "œstridé", + "œstridés", + "œstrien", + "œstrienne", + "œstriennes", + "œstriens", + "œstriol", + "œstriols", + "œstro", + "œstrogène", + "œstrogènes", + "œstrogénie", + "œstrogénies", + "œstrogénique", + "œstrogéniques", + "œstrogénothérapie", + "œstrogénothérapies", + "œstrone", + "œstrones", + "œstroprogestatif", + "œstroprogestatifs", + "œstroprogestative", + "œstroprogestatives", + "œstroïde", + "œstroïdes", + "œstroïdurie", + "œstroïduries", + "œstrus", + "œuf", + "œufrier", + "œufriers", + "œufs", + "œuvra", + "œuvrer", + "œuvrai", + "œuvraient", + "œuvrais", + "œuvrait", + "œuvrant", + "œuvras", + "œuvrasse", + "œuvrassent", + "œuvrasses", + "œuvrassiez", + "œuvrassions", + "œuvre", + "œuvrent", + "œuvrera", + "œuvrerai", + "œuvreraient", + "œuvrerais", + "œuvrerait", + "œuvreras", + "œuvrerez", + "œuvreriez", + "œuvrerions", + "œuvrerons", + "œuvreront", + "œuvres", + "œuvrez", + "œuvriez", + "œuvrions", + "œuvrons", + "œuvrâmes", + "œuvrât", + "œuvrâtes", + "œuvrèrent", + "œuvré", + "œuvé", + "œuvée", + "œuvées", + "œuvés", "off", "offensa", "offenser", @@ -398081,8 +398081,8 @@ "phlébocavographies", "phlébodynie", "phlébodynies", - "phléboedème", - "phléboedèmes", + "phlébœdème", + "phlébœdèmes", "phlébogramme", "phlébogrammes", "phlébographie", @@ -398197,15 +398197,15 @@ "phocéenne", "phocéennes", "phocéens", - "phoenicochroïte", - "phoenicochroïtes", - "phoenicoptère", - "phoenicoptères", - "phoenicoptéridé", - "phoenicoptéridés", - "phoenicoptériforme", - "phoenicoptériformes", - "phoenix", + "phœnicochroïte", + "phœnicochroïtes", + "phœnicoptère", + "phœnicoptères", + "phœnicoptéridé", + "phœnicoptéridés", + "phœnicoptériforme", + "phœnicoptériformes", + "phœnix", "pholade", "pholades", "pholadomyie", @@ -425076,11 +425076,11 @@ "préoccupée", "préoccupées", "préoccupés", - "préoedipien", - "préoedipienne", - "préoedipiennes", - "préoedipiens", - "préoestrus", + "préœdipien", + "préœdipienne", + "préœdipiennes", + "préœdipiens", + "préœstrus", "préolympique", "préolympiques", "préoperculaire", @@ -427750,10 +427750,10 @@ "pseudocoarctation", "pseudocoarctations", "pseudococcus", - "pseudocoelomate", - "pseudocoelomates", - "pseudocoelome", - "pseudocoelomes", + "pseudocœlomate", + "pseudocœlomates", + "pseudocœlome", + "pseudocœlomes", "pseudocomitial", "pseudocomitiale", "pseudocomitiales", @@ -432912,8 +432912,8 @@ "périodisés", "périodontite", "périodontites", - "périoesophagite", - "périoesophagites", + "périœsophagite", + "périœsophagites", "périonyxis", "périophtalmite", "périophtalmites", @@ -441941,8 +441941,8 @@ "rancissure", "rancissures", "rancit", - "rancoeur", - "rancoeurs", + "rancœur", + "rancœurs", "rancune", "rancunes", "rancuneuse", @@ -475986,45 +475986,45 @@ "remaniée", "remaniées", "remaniés", - "remanoeuvra", - "remanoeuvrer", - "remanoeuvrai", - "remanoeuvraient", - "remanoeuvrais", - "remanoeuvrait", - "remanoeuvrant", - "remanoeuvras", - "remanoeuvrasse", - "remanoeuvrassent", - "remanoeuvrasses", - "remanoeuvrassiez", - "remanoeuvrassions", - "remanoeuvre", - "remanoeuvrent", - "remanoeuvrera", - "remanoeuvrerai", - "remanoeuvreraient", - "remanoeuvrerais", - "remanoeuvrerait", - "remanoeuvreras", - "remanoeuvrerez", - "remanoeuvreriez", - "remanoeuvrerions", - "remanoeuvrerons", - "remanoeuvreront", - "remanoeuvres", - "remanoeuvrez", - "remanoeuvriez", - "remanoeuvrions", - "remanoeuvrons", - "remanoeuvrâmes", - "remanoeuvrât", - "remanoeuvrâtes", - "remanoeuvrèrent", - "remanoeuvré", - "remanoeuvrée", - "remanoeuvrées", - "remanoeuvrés", + "remanœuvra", + "remanœuvrer", + "remanœuvrai", + "remanœuvraient", + "remanœuvrais", + "remanœuvrait", + "remanœuvrant", + "remanœuvras", + "remanœuvrasse", + "remanœuvrassent", + "remanœuvrasses", + "remanœuvrassiez", + "remanœuvrassions", + "remanœuvre", + "remanœuvrent", + "remanœuvrera", + "remanœuvrerai", + "remanœuvreraient", + "remanœuvrerais", + "remanœuvrerait", + "remanœuvreras", + "remanœuvrerez", + "remanœuvreriez", + "remanœuvrerions", + "remanœuvrerons", + "remanœuvreront", + "remanœuvres", + "remanœuvrez", + "remanœuvriez", + "remanœuvrions", + "remanœuvrons", + "remanœuvrâmes", + "remanœuvrât", + "remanœuvrâtes", + "remanœuvrèrent", + "remanœuvré", + "remanœuvrée", + "remanœuvrées", + "remanœuvrés", "remanqua", "remanquer", "remanquai", @@ -498886,8 +498886,8 @@ "rhabditidé", "rhabditidés", "rhabditis", - "rhabdocoele", - "rhabdocoeles", + "rhabdocœle", + "rhabdocœles", "rhabdologie", "rhabdologies", "rhabdomancie", @@ -499189,10 +499189,10 @@ "rhinocérotidés", "rhinoderme", "rhinodermes", - "rhinoedème", - "rhinoedèmes", - "rhinoestre", - "rhinoestres", + "rhinœdème", + "rhinœdèmes", + "rhinœstre", + "rhinœstres", "rhinoglanis", "rhinogène", "rhinogènes", @@ -499615,8 +499615,8 @@ "rhynchiums", "rhynchobdelle", "rhynchobdelles", - "rhynchocoele", - "rhynchocoeles", + "rhynchocœle", + "rhynchocœles", "rhynchocyon", "rhynchocyons", "rhynchocéphale", @@ -506177,8 +506177,8 @@ "rydbergs", "rynchite", "rynchites", - "rynchocoele", - "rynchocoeles", + "rynchocœle", + "rynchocœles", "rynchote", "rynchotes", "ryssota", @@ -536072,8 +536072,8 @@ "schistoïde", "schistoïdes", "schizo", - "schizocoelie", - "schizocoelies", + "schizocœlie", + "schizocœlies", "schizocyte", "schizocytes", "schizocytose", @@ -537104,8 +537104,8 @@ "sclérodermies", "sclérodermiforme", "sclérodermiformes", - "scléroedème", - "scléroedèmes", + "sclérœdème", + "sclérœdèmes", "sclérogène", "sclérogènes", "sclérokératite", @@ -544674,10 +544674,10 @@ "sodée", "sodées", "sodés", - "soeur", - "soeurette", - "soeurettes", - "soeurs", + "sœur", + "sœurette", + "sœurettes", + "sœurs", "sofa", "sofas", "soffie", @@ -552115,8 +552115,8 @@ "stilb", "stilbite", "stilbites", - "stilboestrol", - "stilboestrols", + "stilbœstrol", + "stilbœstrols", "stilbs", "stilbène", "stilbènes", @@ -584749,10 +584749,10 @@ "transocéaniens", "transocéanique", "transocéaniques", - "transoesophagien", - "transoesophagienne", - "transoesophagiennes", - "transoesophagiens", + "transœsophagien", + "transœsophagienne", + "transœsophagiennes", + "transœsophagiens", "transombilical", "transombilicale", "transombilicales", @@ -589525,8 +589525,8 @@ "trophoblastomes", "trophodermatoneurose", "trophodermatoneuroses", - "trophoedème", - "trophoedèmes", + "trophœdème", + "trophœdèmes", "trophoneurotique", "trophoneurotiques", "trophonose", @@ -593146,8 +593146,8 @@ "typo", "typochromie", "typochromies", - "typocoelographie", - "typocoelographies", + "typocœlographie", + "typocœlographies", "typographe", "typographes", "typographia", @@ -606230,8 +606230,8 @@ "vocodeurs", "vodka", "vodkas", - "voeu", - "voeux", + "vœu", + "vœux", "voglite", "voglites", "vogoul", @@ -609553,8 +609553,8 @@ "xéno", "xénobiotique", "xénobiotiques", - "xénocoeloma", - "xénocoelomas", + "xénocœloma", + "xénocœlomas", "xénocristal", "xénocristaux", "xénoderminé", @@ -616331,50 +616331,50 @@ "écoclimatologies", "écocline", "écoclines", - "écoeura", - "écoeurer", - "écoeurai", - "écoeuraient", - "écoeurais", - "écoeurait", - "écoeurant", - "écoeurante", - "écoeurantes", - "écoeurants", - "écoeuras", - "écoeurasse", - "écoeurassent", - "écoeurasses", - "écoeurassiez", - "écoeurassions", - "écoeure", - "écoeurement", - "écoeurements", - "écoeurent", - "écoeurera", - "écoeurerai", - "écoeureraient", - "écoeurerais", - "écoeurerait", - "écoeureras", - "écoeurerez", - "écoeureriez", - "écoeurerions", - "écoeurerons", - "écoeureront", - "écoeures", - "écoeurez", - "écoeuriez", - "écoeurions", - "écoeurons", - "écoeurâmes", - "écoeurât", - "écoeurâtes", - "écoeurèrent", - "écoeuré", - "écoeurée", - "écoeurées", - "écoeurés", + "écœura", + "écœurer", + "écœurai", + "écœuraient", + "écœurais", + "écœurait", + "écœurant", + "écœurante", + "écœurantes", + "écœurants", + "écœuras", + "écœurasse", + "écœurassent", + "écœurasses", + "écœurassiez", + "écœurassions", + "écœure", + "écœurement", + "écœurements", + "écœurent", + "écœurera", + "écœurerai", + "écœureraient", + "écœurerais", + "écœurerait", + "écœureras", + "écœurerez", + "écœureriez", + "écœurerions", + "écœurerons", + "écœureront", + "écœures", + "écœurez", + "écœuriez", + "écœurions", + "écœurons", + "écœurâmes", + "écœurât", + "écœurâtes", + "écœurèrent", + "écœuré", + "écœurée", + "écœurées", + "écœurés", "écoffret", "écoffrets", "écographie", @@ -629714,8 +629714,8 @@ "érythrodiapédèses", "érythrodontie", "érythrodonties", - "érythroedème", - "érythroedèmes", + "érythrœdème", + "érythrœdèmes", "érythroenzymopathie", "érythroenzymopathies", "érythrogène", diff --git a/frontend/static/languages/hinglish.json b/frontend/static/languages/hinglish.json index 1856f9158153..a7d68fc7d527 100644 --- a/frontend/static/languages/hinglish.json +++ b/frontend/static/languages/hinglish.json @@ -19,6 +19,7 @@ "aur", "baad", "baar", + "barre", "baate", "bach", "bachchha", @@ -59,6 +60,7 @@ "dost", "dunga", "duniya", + "durghatana", "dusht", "dusman", "dusra", @@ -142,6 +144,7 @@ "nahi", "nazar", "neend", + "oopar", "paani", "pada", "padh", @@ -159,6 +162,7 @@ "pyaar", "roshan", "saal", + "sabse", "sach", "sahi", "se", @@ -167,6 +171,7 @@ "sona", "sun", "shuru", + "sveekaar", "tab", "tak", "taraf", diff --git a/frontend/static/layouts/pine_v4.json b/frontend/static/layouts/pine_v4.json index adf150630ade..2578b7ff68e1 100644 --- a/frontend/static/layouts/pine_v4.json +++ b/frontend/static/layouts/pine_v4.json @@ -22,7 +22,7 @@ ["l", "L"], ["c", "C"], ["m", "M"], - ["K", "K"], + ["k", "K"], ["'", "\""], ["f", "F"], ["u", "U"], diff --git a/frontend/static/quotes/code_bash.json b/frontend/static/quotes/code_bash.json index 5a0fefe1cb8b..3e0e21bf6b15 100644 --- a/frontend/static/quotes/code_bash.json +++ b/frontend/static/quotes/code_bash.json @@ -66,6 +66,12 @@ "source": "Monitoring disk usage in Bash", "length": 218, "id": 10 + }, + { + "text": "echo INSTALLING PACKAGES\nsudo apt install python3 --assume-yes\nsudo apt install python3-pip --assume-yes\nsudo apt install python3-flask --assume-yes\nsudo apt install python3-transliterate --assume-yes\nsudo apt install python3-fuzzywuzzy --assume-yes\nsudo apt install vsftpd --assume-yes\nsudo apt install nginx --assume-yes\npip install bext --break-system-packages", + "source": "eChat - Install script line 1-9", + "length": 363, + "id": 11 } ] } diff --git a/frontend/static/quotes/code_css.json b/frontend/static/quotes/code_css.json index 43858902bbf6..b7ed838428cc 100644 --- a/frontend/static/quotes/code_css.json +++ b/frontend/static/quotes/code_css.json @@ -126,6 +126,12 @@ "source": "W3Schools CSS Linear Gradient with Multiple Color Stops", "id": 20, "length": 362 + }, + { + "text": "/* General body styles */\nbody {\n\tfont-family: Arial, sans-serif;\n\tmargin: 0;\n\tpadding: 0;\n\tbackground-color: #f4f4f4;\n\tcolor: #333;\n}", + "source": "eChat - CSS source code line 1-8", + "id": 21, + "length": 134 } ] } diff --git a/frontend/static/quotes/code_python.json b/frontend/static/quotes/code_python.json index a458bc9d3a33..82f7b33f3221 100644 --- a/frontend/static/quotes/code_python.json +++ b/frontend/static/quotes/code_python.json @@ -450,6 +450,18 @@ "source": "https://www.geeksforgeeks.org/python-program-for-dijkstras-shortest-path-algorithm-greedy-algo-7/", "id": 75, "length": 851 + }, + { + "text": "def redirect(link:str, text=\"\"):\n\treturn render_template(\"redirect.html\", link=link, text=text)", + "source": "eChat source code line 35-36", + "id": 76, + "length": 95 + }, + { + "text": "def isEnglish(s):\n\ttry:\n\t\ts.encode(encoding='utf-8').decode('ascii')\n\texcept UnicodeDecodeError:\n\t\treturn False\n\telse:\n\t\treturn True", + "source": "eChat source code line 96-102", + "id": 77, + "length": 132 } ] } diff --git a/frontend/static/quotes/english.json b/frontend/static/quotes/english.json index c73fcd5f26cd..dc1c8a50c0e8 100644 --- a/frontend/static/quotes/english.json +++ b/frontend/static/quotes/english.json @@ -39081,6 +39081,12 @@ "source": "End Credits", "id": 7726, "length": 336 + }, + { + "text": "Haven't I done a great job at protecting you? I mean, look at yourself. You haven't died a single time.", + "source": "Undertale", + "id": 7727, + "length": 103 } ] } diff --git a/frontend/static/quotes/russian.json b/frontend/static/quotes/russian.json index 383fa98a0d26..e867871ab9ed 100644 --- a/frontend/static/quotes/russian.json +++ b/frontend/static/quotes/russian.json @@ -6576,6 +6576,66 @@ "source": "А. С. Пушкин - Полтава", "text": "Тиха украинская ночь. Прозрачно небо. Звезды блещут. Своей дремоты превозмочь не хочет воздух. Чуть трепещут сребристых тополей листы. Но мрачны странные мечты в душе Мазепы: звезды ночи, как обвинительные очи, за ним насмешливо глядят. И тополи, стеснившись в ряд, качая тихо головою, как судьи, шепчут меж собою. И летней, теплой ночи тьма душна как черная тюрьма.", "length": 366 + }, + { + "id": 1151, + "source": "Ф. Скотт Фицджеральд - Великий Гэтсби", + "text": "Почти пять лет! Были, вероятно, сегодня минуты, когда живая Дэйзи в чем-то не дотянула до Дэйзи его мечтаний, - и дело тут было не в ней, а в огромной жизненной силе созданного им образа. Этот образ был лучшее ее, лучше всего на свете. Он творил его с подлинной страстью художника, все время что-то к нему прибавляя, украшая его каждым ярким перышком, попадавшимся под руку. Никакая ощутимая, реальная прелесть не может сравниться с тем, что способен накопить человек в глубинах своей фантазии.", + "length": 494 + }, + { + "id": 1152, + "source": "Ф. Скотт Фицджеральд - Великий Гэтсби", + "text": "Гэтсби верил в зеленый огонек, свет неимоверного будущего счастья, которое отодвигается с каждым годом. Пусть оно ускользнуло сегодня, не беда — завтра мы побежим еще быстрее, еще дальше станем протягивать руки… И в одно прекрасное утро… Так мы и пытаемся плыть вперед, борясь с течением, а оно все сносит и сносит наши суденышки обратно в прошлое.", + "length": 348 + }, + { + "id": 1153, + "source": "Ф. Скотт Фицджеральд - Великий Гэтсби", + "text": "Говорят, душевные раны рубцуются - бездумная аналогия с повреждениями телесными, в жизни так не бывает. Такая рана может уменьшиться, затянуться частично, но это всегда открытая рана, пусть и не больше булавочного укола. След испытанного страдания скорей можно сравнить с потерей пальца или зрения в одном глазу. С увечьем сживаешься, о нём вспоминаешь, быть может, только раз в году, - но когда вдруг вспомнишь, помочь всё равно нельзя.", + "length": 437 + }, + { + "id": 1154, + "source": "Ф. Скотт Фицджеральд - Великий Гэтсби", + "text": "Молодость - как тарелка, горой полная сластей. Люди сентиментальные уверяют, что хотели бы вернуться в то простое чистое состояние, в котором пребывали до того, как съели сласти. Это неверно. Они хотели бы снова испытать приятные вкусовые ощущения.", + "length": 248 + }, + { + "id": 1155, + "source": "Ф. Скотт Фицджеральд - Великий Гэтсби", + "text": "Самопожертвование, как высокая выборная должность, как унаследованная власть, для каких-то людей, в какие-то моменты - роскошь, но влечет оно за собой не гарантию, а ответственность, не спокойствие, а отчаянный риск. Собственной инерцией оно может толкнуть к гибели, - спадет эмоциональная волна, породившая его, и человек навсегда останется один на голой скале безнадежности.", + "length": 376 + }, + { + "id": 1156, + "source": "Джек Лондон - Мартин Иден", + "text": "Во мне столько всего, о чем я хочу сказать. Но все это так огромно. Я не нахожу слов, не могу выразить, что там внутри. Иногда мне кажется, весь мир, вся жизнь, все на свете поселилось во мне и требует: будь нашим голосом. Я чувствую, ох, не знаю, как объяснить… Я чувствую, как это огромно а начинаю говорить, выходит детский лепет. До чего трудная задача – передать чувство, ощущение такими словами, на бумаге или вслух, чтобы тот, кто читает или слушает, почувствовал или ощутил то же, что и ты. Это великая задача.", + "length": 518 + }, + { + "id": 1157, + "source": "Джек Лондон - Мартин Иден", + "text": "Сталкиваясь с жизнью, в самых разных ее обличьях, кружась в изменчивом ее водовороте, Мартин усвоил одно правило: когда играешь в незнакомую игру, первый ход предоставь другому. Правило это выручало его тысячи раз, да в придачу отточило его наблюдательность. Он умел приглядываться к тому, что незнакомо, и дождаться, когда обнаружится, в чем тут слабость, где уязвимое место. Все равно как в кулачном бою пробными ударами пытаться обнаружить слабину противника. И обнаружив ее, – этому его научил долгий опыт – использовать ее, использовать вовсю.", + "length": 548 + }, + { + "id": 1158, + "source": "Джек Лондон - Мартин Иден", + "text": "Он приходился ко двору везде, куда бы ни попал, всегда и везде оказывался общим любимцем, потому что в работе ли, в игре ли он оставался верен себе, всегда был готов и умел воевать за свои права и требовать уважения. Но нигде он не пустил корней. Им всюду были довольны те, кто рядом, но сам он вполне доволен не бывал. Не было в нём покоя, вечно что-то звало и манило его, и он скитался по жизни, сам не зная, чего ищет и откуда зов, пока не обрёл книги, творчество и любовь.", + "length": 476 + }, + { + "id": 1159, + "source": "Джек Лондон - Мартин Иден", + "text": "Мечта о любви была для него важнее мечты о знании. Мир казался удивительным вовсе не потому, что состоял из молекул и атомов, подчинявшихся действию каких-то таинственных законов, – мир казался удивительным потому, что в нем жила Руфь. Она была чудом, какое никогда раньше не являлось ему даже в мечтах.", + "length": 303 + }, + { + "id": 1160, + "source": "Джек Лондон - Мартин Иден", + "text": "В устах этих людей ожили книги, которыми он зачитывался. Они говорили страстно, увлечённо. Мысль горячила, их, как других горячат алкоголь или гнев. Философия перестала быть сухими печатными строчками из книг легендарных полубогов вроде Канта и Спенсера. Философия ожила, воплотилась вот в этих двоих, наполнилась кипучей алой кровью, преобразила их лица.", + "length": 355 } ] } diff --git a/packages/funbox/src/list.ts b/packages/funbox/src/list.ts index 84aab9025a9f..3c18199824ec 100644 --- a/packages/funbox/src/list.ts +++ b/packages/funbox/src/list.ts @@ -460,6 +460,14 @@ const list: Record = { name: "asl", cssModifications: ["words"], }, + rot13: { + description: "Vg znl abg or frpher, ohg vg vf sha gb glcr!", + canGetPb: true, + difficultyLevel: 1, + properties: [], + frontendFunctions: ["alterText"], + name: "rot13", + }, no_quit: { description: "You can't restart the test.", canGetPb: true, diff --git a/packages/schemas/src/configs.ts b/packages/schemas/src/configs.ts index 3007b5435f4c..e7a88b2ccf87 100644 --- a/packages/schemas/src/configs.ts +++ b/packages/schemas/src/configs.ts @@ -304,6 +304,7 @@ export const FunboxNameSchema = z.enum([ "ALL_CAPS", "polyglot", "asl", + "rot13", "no_quit", ]); export type FunboxName = z.infer;