diff --git a/README.md b/README.md index f107363..97900b0 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ The original introduces improvements to the Canvas user interface: ## Newly added features -Canvas Refined adds more with more to come! +Canvas Refined adds more with more to come! (This list will no longer be updated due to too many features) - GPA presets - backend stuff: @@ -75,31 +75,6 @@ Canvas Refined adds more with more to come! - Center cards - Hide new dashboard button -## Planned Features -- mail assistant + ui revamp -- better calender (+ calender sync) -- better what if grade -- fix darkmode fixer (and automatic) -- grade history with graph - -## Extra features that might be added: -- card grade position, card outline -- streaks -- maybe find a way for faster loading -- rotating background, time/weather background overlay -- custom side logo -- goals -- Scheduled Reminder Popups -- preview font -- button to remove all card images and undo -- auto dark mode based on background - -## Community suggestions (maybe will be done at some point) -- when opening assignments it will show you "if you get a 0 on this your grade will be _" -- module sorting (newest, oldest) (maybe grid view) -- grade leaderboard per class (opt in) -- sticky notes - ## Dev Installation To install, run, and build with this repository locally, diff --git a/_locales/de/messages.json b/_locales/de/messages.json index d3413c0..7fd8678 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -21,10 +21,26 @@ "message": "Likes-Anzahl immer anzeigen" }, "assignment_avg": { - "message": "— Durchschn. $AVG$% über $COUNT$ Aufgabe(n):" + "message": "— Durchschn. $AVG$% über $COUNT$ Aufgabe(n):", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "Aufgabe fällig in $TIME$" + "message": "Aufgabe fällig in $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "automatisch" @@ -243,7 +259,17 @@ "message": "erledigt" }, "completed_total": { - "message": "$DONE$/$TOTAL$ erledigt" + "message": "$DONE$/$TOTAL$ erledigt", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "Verdichtete Karten" @@ -429,7 +455,13 @@ "message": "Fällig" }, "due_days": { - "message": "Fällig in $COUNT$ Tagen" + "message": "Fällig in $COUNT$ Tagen", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "Fällig später" @@ -447,7 +479,13 @@ "message": "Fällig morgen" }, "due_weeks": { - "message": "Fällig in $COUNT$ Wochen" + "message": "Fällig in $COUNT$ Wochen", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "Diese eigene Aufgabe bearbeiten" @@ -555,7 +593,13 @@ "message": "Aufgaben" }, "final_avg": { - "message": "— Durchschn. $AVG$% ..." + "message": "— Durchschn. $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "Warte auf Notendaten…" @@ -573,7 +617,17 @@ "message": "Der Fixer wird automatisch auf diesen Seiten ausgeführt:" }, "fix_took": { - "message": "Korrektur dauerte $TIME$ms (Bewertung: $RATING$)" + "message": "Korrektur dauerte $TIME$ms (Bewertung: $RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "Flexibles Raster" @@ -606,13 +660,25 @@ "message": "Y-Achse anpassen" }, "ga_heatmap_assignments": { - "message": "$COUNT$ Aufgabe(n):" + "message": "$COUNT$ Aufgabe(n):", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "Ø" }, "ga_heatmap_undated": { - "message": "$COUNT$ benotete Aufgabe(n) ohne Fälligkeitsdatum werden nicht angezeigt." + "message": "$COUNT$ benotete Aufgabe(n) ohne Fälligkeitsdatum werden nicht angezeigt.", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "Gesamtnote im Zeitverlauf" @@ -666,10 +732,30 @@ "message": "Unbenotet" }, "ga_sub_secured": { - "message": "Selbst eine 0 in der Prüfung lässt dich bei $ZERO$%, was über deinem Ziel von $TARGET$% liegt." + "message": "Selbst eine 0 in der Prüfung lässt dich bei $ZERO$%, was über deinem Ziel von $TARGET$% liegt.", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "Selbst eine perfekte Prüfung bringt dich nur auf $PERFECT$%, was unter deinem Ziel von $TARGET$% liegt." + "message": "Selbst eine perfekte Prüfung bringt dich nur auf $PERFECT$%, was unter deinem Ziel von $TARGET$% liegt.", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "Endnoten-Rechner" @@ -702,13 +788,25 @@ "message": "Imagine-If Punktzahl (Zähler); leer = zählt nicht" }, "ga_tooltip_assignments": { - "message": "$COUNT$ Aufgabe(n)" + "message": "$COUNT$ Aufgabe(n)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "Das schaffst du!" }, "ga_you_need": { - "message": "Du brauchst ≥ $PCT$% in der Prüfung" + "message": "Du brauchst ≥ $PCT$% in der Prüfung", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "Aktive Karten vom Dashboard holen" @@ -834,7 +932,13 @@ "message": "Fügt Werkzeuge hinzu, mit denen du deine Noten analysieren kannst." }, "grade_analytics_failed": { - "message": "Notenanalyse konnte nicht geladen werden: $ERROR$" + "message": "Notenanalyse konnte nicht geladen werden: $ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "Info zur Notenanalyse" @@ -864,7 +968,29 @@ "message": " (einschließlich des GPA-Rechners)" }, "grid_warning": { - "message": "Dein Raster bietet Platz für $TOTAL$ Karte$TOTAL_S$, aber du hast $ACTIVE$ Karte$ACTIVE_S$$GPA_NOTE$ – einige Karten werden möglicherweise abgeschnitten." + "message": "Dein Raster bietet Platz für $TOTAL$ Karte$TOTAL_S$, aber du hast $ACTIVE$ Karte$ACTIVE_S$$GPA_NOTE$ – einige Karten werden möglicherweise abgeschnitten.", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "Benotet" @@ -1023,16 +1149,34 @@ "message": "NASA-Astronomiebild des Tages" }, "nasa_credit": { - "message": "Quelle: $CREDIT$" + "message": "Quelle: $CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "Datum: $DATE$" + "message": "Datum: $DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "Möglicherweise musst du die Seite aktualisieren, um einige Änderungen zu sehen." }, "new_canvas_desc": { - "message": "Canvas Refined hat eine Canvas-Seite unter $HOST$ erkannt. Zur Canvas-Liste hinzufügen?" + "message": "Canvas Refined hat eine Canvas-Seite unter $HOST$ erkannt. Zur Canvas-Liste hinzufügen?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "Neue Canvas-Seite erkannt" @@ -1143,7 +1287,13 @@ "message": "Klicke oben rechts auf dieses Puzzle-Symbol" }, "options_contact": { - "message": "Meine E-Mail ist $EMAIL$, falls du Probleme oder Vorschläge hast – Feedback ist willkommen!" + "message": "Meine E-Mail ist $EMAIL$, falls du Probleme oder Vorschläge hast – Feedback ist willkommen!", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "So erreichst du dieses Menü später:" @@ -1233,7 +1383,13 @@ "message": "Wassermelone" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "Persönliche Aufgabe" @@ -1290,13 +1446,51 @@ "message": "Datenschutz" }, "progress_done": { - "message": "$DONE$/$TOTAL$ erledigt" + "message": "$DONE$/$TOTAL$ erledigt", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "Nicht mehr anzeigen" @@ -1344,13 +1538,25 @@ "message": "Notendaten werden gelesen…" }, "relative_ago": { - "message": "vor $TIME$" + "message": "vor $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "Relative Fälligkeitsdaten" }, "relative_in": { - "message": "in $TIME$" + "message": "in $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "Sidebar-Logo entfernen" @@ -1425,16 +1631,34 @@ "message": "neuer Tab" }, "search_no_course": { - "message": "Kein Kurs entspricht \"$QUERY$\"." + "message": "Kein Kurs entspricht \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "Keine Kurse gefunden, für die Noten geöffnet werden können." }, "search_no_match": { - "message": "Keine Ergebnisse für \"$QUERY$\"." + "message": "Keine Ergebnisse für \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "Keine Ergebnisse für \"$QUERY$\". Versuche andere Suchbegriffe." + "message": "Keine Ergebnisse für \"$QUERY$\". Versuche andere Suchbegriffe.", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "Keine Module oder Aufgaben gefunden..." @@ -1443,7 +1667,13 @@ "message": "Keine Module oder Aufgaben gefunden. Öffne die Suche später erneut, falls deine Kurse noch geladen werden." }, "search_no_results": { - "message": "Keine Ergebnisse für \"$QUERY$\"." + "message": "Keine Ergebnisse für \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "öffnen" @@ -1488,7 +1718,13 @@ "message": "Abschnitt" }, "selected_count": { - "message": "$COUNT$ ausgewählt" + "message": "$COUNT$ ausgewählt", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "Anzeigen" @@ -1533,7 +1769,13 @@ "message": "leer" }, "storage_items": { - "message": " ($COUNT$ Elemente)" + "message": " ($COUNT$ Elemente)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "Die eingegebenen Daten überschreiten das Speicherlimit und werden nicht gespeichert. Verwende kürzere Links und stelle sicher, dass du \"Bildadresse kopieren\" und nicht \"Bild kopieren\" verwendest." @@ -1620,7 +1862,13 @@ "message": "Stelle sicher, dass dein Theme diese Richtlinien befolgt:" }, "theme_number": { - "message": "Theme $NUM$" + "message": "Theme $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "Theme-Browser-Opt-in zurückgesetzt" @@ -1725,7 +1973,21 @@ "message": "Abhaken" }, "todo_date_format": { - "message": "$DATE$ um $TIME$ ($RELATIVE$)" + "message": "$DATE$ um $TIME$ ($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "Löschen" @@ -1863,7 +2125,13 @@ "message": "Mehr anzeigen" }, "view_more_count": { - "message": "Mehr anzeigen ($COUNT$)" + "message": "Mehr anzeigen ($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "Auf GitHub ansehen" @@ -1891,5 +2159,8 @@ }, "widgets": { "message": "Widgets" + }, + "gpa_show_on_hover": { + "message": "Show on hover" } } diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 46bd2dc..313211e 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -21,10 +21,26 @@ "message": "Always show like count" }, "assignment_avg": { - "message": "— avg $AVG$% over $COUNT$ assignment(s):" + "message": "— avg $AVG$% over $COUNT$ assignment(s):", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "Assignment due in $TIME$" + "message": "Assignment due in $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "auto" @@ -243,7 +259,17 @@ "message": "complete" }, "completed_total": { - "message": "$DONE$/$TOTAL$ done" + "message": "$DONE$/$TOTAL$ done", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "Condensed Cards" @@ -429,7 +455,13 @@ "message": "Due" }, "due_days": { - "message": "Due $COUNT$ days" + "message": "Due $COUNT$ days", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "Due Later" @@ -447,7 +479,13 @@ "message": "Due Tomorrow" }, "due_weeks": { - "message": "Due $COUNT$ weeks" + "message": "Due $COUNT$ weeks", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "Edit this custom task" @@ -555,7 +593,13 @@ "message": "assignments" }, "final_avg": { - "message": "— avg $AVG$% ..." + "message": "— avg $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "Waiting for grade data…" @@ -573,7 +617,17 @@ "message": "The Fixer Is Automatically Running On These Pages:" }, "fix_took": { - "message": "Fix took $TIME$ms (rating: $RATING$)" + "message": "Fix took $TIME$ms (rating: $RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "Flexible grid" @@ -606,13 +660,25 @@ "message": "Fit Y axis" }, "ga_heatmap_assignments": { - "message": "$COUNT$ assignment(s):" + "message": "$COUNT$ assignment(s):", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "avg" }, "ga_heatmap_undated": { - "message": "$COUNT$ graded assignment(s) without a due date not shown." + "message": "$COUNT$ graded assignment(s) without a due date not shown.", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "Overall grade over time" @@ -666,10 +732,30 @@ "message": "Ungraded" }, "ga_sub_secured": { - "message": "Even a 0 on the final leaves you at $ZERO$%, which is above your $TARGET$% goal." + "message": "Even a 0 on the final leaves you at $ZERO$%, which is above your $TARGET$% goal.", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "Even a perfect final only gets you to $PERFECT$%, which is below your $TARGET$% goal." + "message": "Even a perfect final only gets you to $PERFECT$%, which is below your $TARGET$% goal.", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "Final Calculator" @@ -702,13 +788,25 @@ "message": "Imagine-If score (numerator); blank = not counted" }, "ga_tooltip_assignments": { - "message": "$COUNT$ assignment(s)" + "message": "$COUNT$ assignment(s)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "You got this!" }, "ga_you_need": { - "message": "You need ≥ $PCT$% on the final" + "message": "You need ≥ $PCT$% on the final", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "Get Active Cards From Dashboard" @@ -731,6 +829,9 @@ "gpa_calc_weighted": { "message": "Show Weighted GPA" }, + "gpa_show_on_hover": { + "message": "Show on hover" + }, "gpa_calculator": { "message": "GPA Calculator" }, @@ -834,7 +935,13 @@ "message": "Adds tools to help you analyze your grades." }, "grade_analytics_failed": { - "message": "Grade Analytics failed to load: $ERROR$" + "message": "Grade Analytics failed to load: $ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "Grade Analytics info" @@ -864,7 +971,29 @@ "message": " (including the GPA calculator)" }, "grid_warning": { - "message": "Your grid holds $TOTAL$ card$TOTAL_S$ but you have $ACTIVE$ card$ACTIVE_S$$GPA_NOTE$ - some cards may be cut off." + "message": "Your grid holds $TOTAL$ card$TOTAL_S$ but you have $ACTIVE$ card$ACTIVE_S$$GPA_NOTE$ - some cards may be cut off.", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "Graded" @@ -1029,16 +1158,34 @@ "message": "NASA Astronomy Picture of the Day" }, "nasa_credit": { - "message": "Credit: $CREDIT$" + "message": "Credit: $CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "Date: $DATE$" + "message": "Date: $DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "You may need to refresh the page to see some changes." }, "new_canvas_desc": { - "message": "Canvas Refined detected a Canvas page at $HOST$. Add it to your canvas list?" + "message": "Canvas Refined detected a Canvas page at $HOST$. Add it to your canvas list?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "New Canvas detected" @@ -1149,7 +1296,13 @@ "message": "Click on this puzzle icon at the top right" }, "options_contact": { - "message": "My email is $EMAIL$ if you have any issues/suggestions - any feedback is appreciated!" + "message": "My email is $EMAIL$ if you have any issues/suggestions - any feedback is appreciated!", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "How to access this menu later:" @@ -1239,7 +1392,13 @@ "message": "Watermelon" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "Personal task" @@ -1296,13 +1455,51 @@ "message": "Privacy" }, "progress_done": { - "message": "$DONE$/$TOTAL$ done" + "message": "$DONE$/$TOTAL$ done", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "Don't show again" @@ -1350,13 +1547,25 @@ "message": "Reading grade data…" }, "relative_ago": { - "message": "$TIME$ ago" + "message": "$TIME$ ago", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "Relative Due Dates" }, "relative_in": { - "message": "in $TIME$" + "message": "in $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "Remove Sidebar Logo" @@ -1431,16 +1640,34 @@ "message": "new tab" }, "search_no_course": { - "message": "No course matches \"$QUERY$\"." + "message": "No course matches \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "No courses found to open grades for." }, "search_no_match": { - "message": "No results for \"$QUERY$\"." + "message": "No results for \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "No results for \"$QUERY$\". Try different keywords." + "message": "No results for \"$QUERY$\". Try different keywords.", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "No modules or assignments found..." @@ -1449,7 +1676,13 @@ "message": "No modules or assignments found. Open the search again later if your courses are still loading." }, "search_no_results": { - "message": "No results for \"$QUERY$\"." + "message": "No results for \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "open" @@ -1494,7 +1727,13 @@ "message": "Section" }, "selected_count": { - "message": "$COUNT$ selected" + "message": "$COUNT$ selected", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "Show" @@ -1539,7 +1778,13 @@ "message": "empty" }, "storage_items": { - "message": " ($COUNT$ items)" + "message": " ($COUNT$ items)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "The data you're entering is exceeding the storage limit, so it won't save. Try using shorter links, and make sure to press \"copy image address\" and not \"copy image\" for links." @@ -1626,7 +1871,13 @@ "message": "Make sure your theme follows these guidelines:" }, "theme_number": { - "message": "Theme $NUM$" + "message": "Theme $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "Theme browser opt-in reset" @@ -1731,7 +1982,21 @@ "message": "Cross off" }, "todo_date_format": { - "message": "$DATE$ at $TIME$ ($RELATIVE$)" + "message": "$DATE$ at $TIME$ ($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "Delete" @@ -1869,7 +2134,13 @@ "message": "View More" }, "view_more_count": { - "message": "View More ($COUNT$)" + "message": "View More ($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "View on GitHub" @@ -1895,7 +2166,79 @@ "widget_short_quotes": { "message": "Quotes" }, + "widget_short_links": { + "message": "Links" + }, "widgets": { "message": "Widgets" + }, + "quick_links": { + "message": "Quick Links" + }, + "quick_links_hint_edit": { + "message": "Click a link to edit it." + }, + "quick_links_edit": { + "message": "Edit links" + }, + "quick_links_done": { + "message": "Done" + }, + "quick_links_edit_link": { + "message": "Edit link" + }, + "quick_links_edit_title": { + "message": "Edit link" + }, + "quick_links_add_title": { + "message": "New link" + }, + "quick_links_add": { + "message": "Add link" + }, + "quick_links_delete": { + "message": "Delete" + }, + "quick_links_delete_confirm": { + "message": "Delete this link?" + }, + "quick_links_label": { + "message": "Label" + }, + "quick_links_label_ph": { + "message": "e.g. Canvas" + }, + "quick_links_url": { + "message": "URL" + }, + "quick_links_url_ph": { + "message": "https://..." + }, + "quick_links_icon": { + "message": "Icon" + }, + "quick_links_custom_image": { + "message": "Custom image URL" + }, + "quick_links_custom_image_ph": { + "message": "https://example.com/icon.png" + }, + "quick_links_save": { + "message": "Save" + }, + "quick_links_cancel": { + "message": "Cancel" + }, + "quick_links_empty": { + "message": "No links yet." + }, + "quick_links_url_error": { + "message": "Enter a valid URL." + }, + "quick_links_image_error": { + "message": "Enter a valid image URL." + }, + "quick_links_store_error": { + "message": "Couldn't save your links. Try shorter URLs." } } diff --git a/_locales/es/messages.json b/_locales/es/messages.json index a29f5be..ee34e67 100644 --- a/_locales/es/messages.json +++ b/_locales/es/messages.json @@ -21,10 +21,26 @@ "message": "Mostrar siempre el número de me gusta" }, "assignment_avg": { - "message": "— prom. $AVG$% en $COUNT$ tarea(s):" + "message": "— prom. $AVG$% en $COUNT$ tarea(s):", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "Tarea que vence en $TIME$" + "message": "Tarea que vence en $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "automático" @@ -243,7 +259,17 @@ "message": "completado" }, "completed_total": { - "message": "$DONE$/$TOTAL$ hechas" + "message": "$DONE$/$TOTAL$ hechas", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "Tarjetas condensadas" @@ -429,7 +455,13 @@ "message": "Pendiente" }, "due_days": { - "message": "Vence en $COUNT$ días" + "message": "Vence en $COUNT$ días", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "Vence más tarde" @@ -447,13 +479,19 @@ "message": "Vence mañana" }, "due_weeks": { - "message": "Vence en $COUNT$ semanas" + "message": "Vence en $COUNT$ semanas", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "Editar esta tarea personalizada" }, "edit_dark_mode": { - "message": "Editar modo oscuro" + "message": "Modo oscuro" }, "enter_multiple": { "message": "(Ingrese varios con una coma)" @@ -555,7 +593,13 @@ "message": "tareas" }, "final_avg": { - "message": "— prom. $AVG$% ..." + "message": "— prom. $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "Esperando datos de calificaciones…" @@ -573,7 +617,17 @@ "message": "El reparador se ejecuta automáticamente en estas páginas:" }, "fix_took": { - "message": "La corrección tardó $TIME$ ms (valoración: $RATING$)" + "message": "La corrección tardó $TIME$ ms (valoración: $RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "Cuadrícula flexible" @@ -606,13 +660,25 @@ "message": "Ajustar eje Y" }, "ga_heatmap_assignments": { - "message": "$COUNT$ tarea(s):" + "message": "$COUNT$ tarea(s):", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "prom." }, "ga_heatmap_undated": { - "message": "$COUNT$ tarea(s) calificada(s) sin fecha de entrega no mostrada(s)." + "message": "$COUNT$ tarea(s) calificada(s) sin fecha de entrega no mostrada(s).", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "Nota general a lo largo del tiempo" @@ -666,10 +732,30 @@ "message": "Sin calificar" }, "ga_sub_secured": { - "message": "Incluso un 0 en el final te deja en $ZERO$%, que está por encima de tu objetivo de $TARGET$%." + "message": "Incluso un 0 en el final te deja en $ZERO$%, que está por encima de tu objetivo de $TARGET$%.", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "Incluso un final perfecto solo te llevaría a $PERFECT$%, que está por debajo de tu objetivo de $TARGET$%." + "message": "Incluso un final perfecto solo te llevaría a $PERFECT$%, que está por debajo de tu objetivo de $TARGET$%.", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "Calculadora del final" @@ -702,13 +788,25 @@ "message": "Puntuación Imagine-If (numerador); vacío = no cuenta" }, "ga_tooltip_assignments": { - "message": "$COUNT$ tarea(s)" + "message": "$COUNT$ tarea(s)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "¡Tú puedes!" }, "ga_you_need": { - "message": "Necesitas ≥ $PCT$% en el final" + "message": "Necesitas ≥ $PCT$% en el final", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "Obtener tarjetas activas del panel" @@ -834,7 +932,13 @@ "message": "Añade herramientas para ayudarte a analizar tus calificaciones." }, "grade_analytics_failed": { - "message": "No se pudo cargar el análisis de calificaciones: $ERROR$" + "message": "No se pudo cargar el análisis de calificaciones: $ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "Información del análisis de calificaciones" @@ -864,7 +968,29 @@ "message": " (incluida la calculadora de GPA)" }, "grid_warning": { - "message": "Tu cuadrícula admite $TOTAL$ tarjeta$TOTAL_S$ pero tienes $ACTIVE$ tarjeta$ACTIVE_S$$GPA_NOTE$ - algunas tarjetas pueden quedar cortadas." + "message": "Tu cuadrícula admite $TOTAL$ tarjeta$TOTAL_S$ pero tienes $ACTIVE$ tarjeta$ACTIVE_S$$GPA_NOTE$ - algunas tarjetas pueden quedar cortadas.", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "Calificadas" @@ -1023,16 +1149,34 @@ "message": "Imagen astronómica del día de la NASA" }, "nasa_credit": { - "message": "Crédito: $CREDIT$" + "message": "Crédito: $CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "Fecha: $DATE$" + "message": "Fecha: $DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "Puede que debas actualizar la página para ver algunos cambios." }, "new_canvas_desc": { - "message": "Canvas Refined detectó una página de Canvas en $HOST$. ¿Añadirla a tu lista de Canvas?" + "message": "Canvas Refined detectó una página de Canvas en $HOST$. ¿Añadirla a tu lista de Canvas?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "Nuevo Canvas detectado" @@ -1143,7 +1287,13 @@ "message": "Haz clic en este icono de rompecabezas en la esquina superior derecha" }, "options_contact": { - "message": "Mi correo es $EMAIL$ si tienes problemas o sugerencias: ¡cualquier comentario es bienvenido!" + "message": "Mi correo es $EMAIL$ si tienes problemas o sugerencias: ¡cualquier comentario es bienvenido!", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "Cómo acceder a este menú más tarde:" @@ -1233,7 +1383,13 @@ "message": "Sandía" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "Tarea personal" @@ -1290,13 +1446,51 @@ "message": "Privacidad" }, "progress_done": { - "message": "$DONE$/$TOTAL$ hechas" + "message": "$DONE$/$TOTAL$ hechas", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "No volver a mostrar" @@ -1344,13 +1538,25 @@ "message": "Leyendo datos de calificaciones…" }, "relative_ago": { - "message": "hace $TIME$" + "message": "hace $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "Fechas pendientes relativas" }, "relative_in": { - "message": "dentro de $TIME$" + "message": "dentro de $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "Quitar el logo de la barra lateral" @@ -1425,16 +1631,34 @@ "message": "nueva pestaña" }, "search_no_course": { - "message": "Ningún curso coincide con \"$QUERY$\"." + "message": "Ningún curso coincide con \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "No se encontraron cursos para abrir sus notas." }, "search_no_match": { - "message": "No hay resultados para \"$QUERY$\"." + "message": "No hay resultados para \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "No hay resultados para \"$QUERY$\". Prueba con otras palabras clave." + "message": "No hay resultados para \"$QUERY$\". Prueba con otras palabras clave.", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "No se encontraron módulos ni tareas..." @@ -1443,7 +1667,13 @@ "message": "No se encontraron módulos ni tareas. Vuelve a abrir la búsqueda más tarde si tus cursos aún están cargando." }, "search_no_results": { - "message": "No hay resultados para \"$QUERY$\"." + "message": "No hay resultados para \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "abrir" @@ -1488,7 +1718,13 @@ "message": "Sección" }, "selected_count": { - "message": "$COUNT$ seleccionados" + "message": "$COUNT$ seleccionados", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "Mostrar" @@ -1533,7 +1769,13 @@ "message": "vacío" }, "storage_items": { - "message": " ($COUNT$ elementos)" + "message": " ($COUNT$ elementos)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "Los datos que introduces superan el límite de almacenamiento, así que no se guardarán. Prueba con enlaces más cortos y asegúrate de pulsar \"copiar dirección de imagen\" y no \"copiar imagen\" para los enlaces." @@ -1620,7 +1862,13 @@ "message": "Asegúrate de que tu tema cumpla estas normas:" }, "theme_number": { - "message": "Tema $NUM$" + "message": "Tema $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "Suscripción al navegador de temas restablecida" @@ -1725,7 +1973,21 @@ "message": "Tachar" }, "todo_date_format": { - "message": "$DATE$ a las $TIME$ ($RELATIVE$)" + "message": "$DATE$ a las $TIME$ ($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "Eliminar" @@ -1863,7 +2125,13 @@ "message": "Ver más" }, "view_more_count": { - "message": "Ver más ($COUNT$)" + "message": "Ver más ($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "Ver en GitHub" @@ -1891,5 +2159,8 @@ }, "widgets": { "message": "Widgets" + }, + "gpa_show_on_hover": { + "message": "Show on hover" } } diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index dfe27cf..6a4bd13 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -21,10 +21,26 @@ "message": "Toujours afficher le nombre de mentions J'aime" }, "assignment_avg": { - "message": "— moy. $AVG$% sur $COUNT$ devoir(s) :" + "message": "— moy. $AVG$% sur $COUNT$ devoir(s) :", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "Devoir à rendre dans $TIME$" + "message": "Devoir à rendre dans $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "auto" @@ -243,7 +259,17 @@ "message": "terminé" }, "completed_total": { - "message": "$DONE$/$TOTAL$ terminés" + "message": "$DONE$/$TOTAL$ terminés", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "Cartes condensées" @@ -429,7 +455,13 @@ "message": "Exigible" }, "due_days": { - "message": "Dû dans $COUNT$ jours" + "message": "Dû dans $COUNT$ jours", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "Dû plus tard" @@ -447,7 +479,13 @@ "message": "Dû demain" }, "due_weeks": { - "message": "Dû dans $COUNT$ semaines" + "message": "Dû dans $COUNT$ semaines", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "Modifier cette tâche personnalisée" @@ -555,7 +593,13 @@ "message": "devoirs" }, "final_avg": { - "message": "— moy. $AVG$% ..." + "message": "— moy. $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "En attente des données de notes…" @@ -573,7 +617,17 @@ "message": "Le fixateur s'exécute automatiquement sur ces pages :" }, "fix_took": { - "message": "Correction en $TIME$ ms (évaluation : $RATING$)" + "message": "Correction en $TIME$ ms (évaluation : $RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "Grille flexible" @@ -606,13 +660,25 @@ "message": "Ajuster l'axe Y" }, "ga_heatmap_assignments": { - "message": "$COUNT$ devoir(s) :" + "message": "$COUNT$ devoir(s) :", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "moy." }, "ga_heatmap_undated": { - "message": "$COUNT$ devoir(s) noté(s) sans date d'échéance non affiché(s)." + "message": "$COUNT$ devoir(s) noté(s) sans date d'échéance non affiché(s).", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "Note globale au fil du temps" @@ -666,10 +732,30 @@ "message": "Non noté" }, "ga_sub_secured": { - "message": "Même avec 0 à l'examen final, vous restez à $ZERO$%, au-dessus de votre objectif de $TARGET$%." + "message": "Même avec 0 à l'examen final, vous restez à $ZERO$%, au-dessus de votre objectif de $TARGET$%.", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "Même un examen parfait ne vous mène qu'à $PERFECT$%, en dessous de votre objectif de $TARGET$%." + "message": "Même un examen parfait ne vous mène qu'à $PERFECT$%, en dessous de votre objectif de $TARGET$%.", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "Calculateur final" @@ -702,13 +788,25 @@ "message": "Score Imagine-If (numérateur) ; vide = non pris en compte" }, "ga_tooltip_assignments": { - "message": "$COUNT$ devoir(s)" + "message": "$COUNT$ devoir(s)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "Vous pouvez le faire !" }, "ga_you_need": { - "message": "Il vous faut ≥ $PCT$% à l'examen final" + "message": "Il vous faut ≥ $PCT$% à l'examen final", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "Récupérer les cartes actives du tableau de bord" @@ -834,7 +932,13 @@ "message": "Ajoute des outils pour vous aider à analyser vos notes." }, "grade_analytics_failed": { - "message": "L'analyse des notes n'a pas pu se charger : $ERROR$" + "message": "L'analyse des notes n'a pas pu se charger : $ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "Infos sur l'analyse des notes" @@ -864,7 +968,29 @@ "message": " (y compris le calculateur GPA)" }, "grid_warning": { - "message": "Votre grille contient $TOTAL$ carte$TOTAL_S$ mais vous avez $ACTIVE$ carte$ACTIVE_S$$GPA_NOTE$ — certaines cartes peuvent être coupées." + "message": "Votre grille contient $TOTAL$ carte$TOTAL_S$ mais vous avez $ACTIVE$ carte$ACTIVE_S$$GPA_NOTE$ — certaines cartes peuvent être coupées.", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "Noté" @@ -1023,16 +1149,34 @@ "message": "Image astronomique du jour de la NASA" }, "nasa_credit": { - "message": "Crédit : $CREDIT$" + "message": "Crédit : $CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "Date : $DATE$" + "message": "Date : $DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "Vous devrez peut-être actualiser la page pour voir certains changements." }, "new_canvas_desc": { - "message": "Canvas Refined a détecté une page Canvas sur $HOST$. L'ajouter à votre liste de Canvas ?" + "message": "Canvas Refined a détecté une page Canvas sur $HOST$. L'ajouter à votre liste de Canvas ?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "Nouveau Canvas détecté" @@ -1143,7 +1287,13 @@ "message": "Cliquez sur cette icône de puzzle en haut à droite" }, "options_contact": { - "message": "Mon e-mail est $EMAIL$ si vous avez des problèmes ou des suggestions — vos retours sont les bienvenus !" + "message": "Mon e-mail est $EMAIL$ si vous avez des problèmes ou des suggestions — vos retours sont les bienvenus !", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "Comment accéder à ce menu plus tard :" @@ -1233,7 +1383,13 @@ "message": "Pastèque" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "Tâche personnelle" @@ -1290,13 +1446,51 @@ "message": "Confidentialité" }, "progress_done": { - "message": "$DONE$/$TOTAL$ terminés" + "message": "$DONE$/$TOTAL$ terminés", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "Ne plus afficher" @@ -1344,13 +1538,25 @@ "message": "Lecture des données de notes…" }, "relative_ago": { - "message": "il y a $TIME$" + "message": "il y a $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "Dates d'échéance relatives" }, "relative_in": { - "message": "dans $TIME$" + "message": "dans $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "Supprimer le logo de la barre latérale" @@ -1425,16 +1631,34 @@ "message": "nouvel onglet" }, "search_no_course": { - "message": "Aucun cours ne correspond à « $QUERY$ »." + "message": "Aucun cours ne correspond à « $QUERY$ ».", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "Aucun cours trouvé pour ouvrir les notes." }, "search_no_match": { - "message": "Aucun résultat pour « $QUERY$ »." + "message": "Aucun résultat pour « $QUERY$ ».", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "Aucun résultat pour « $QUERY$ ». Essayez d'autres mots-clés." + "message": "Aucun résultat pour « $QUERY$ ». Essayez d'autres mots-clés.", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "Aucun module ou devoir trouvé..." @@ -1443,7 +1667,13 @@ "message": "Aucun module ni devoir trouvé. Rouvrez la recherche plus tard si vos cours sont encore en chargement." }, "search_no_results": { - "message": "Aucun résultat pour « $QUERY$ »." + "message": "Aucun résultat pour « $QUERY$ ».", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "ouvrir" @@ -1488,7 +1718,13 @@ "message": "Section" }, "selected_count": { - "message": "$COUNT$ sélectionné(s)" + "message": "$COUNT$ sélectionné(s)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "Afficher" @@ -1533,7 +1769,13 @@ "message": "vide" }, "storage_items": { - "message": " ($COUNT$ éléments)" + "message": " ($COUNT$ éléments)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "Les données saisies dépassent la limite de stockage et ne seront pas enregistrées. Essayez des liens plus courts et assurez-vous de cliquer sur « copier l'adresse de l'image » et non « copier l'image »." @@ -1620,7 +1862,13 @@ "message": "Assurez-vous que votre thème respecte ces règles :" }, "theme_number": { - "message": "Thème $NUM$" + "message": "Thème $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "Adhésion au navigateur de thèmes réinitialisée" @@ -1725,7 +1973,21 @@ "message": "Barrer" }, "todo_date_format": { - "message": "$DATE$ à $TIME$ ($RELATIVE$)" + "message": "$DATE$ à $TIME$ ($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "Supprimer" @@ -1863,7 +2125,13 @@ "message": "Voir plus" }, "view_more_count": { - "message": "Voir plus ($COUNT$)" + "message": "Voir plus ($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "Voir sur GitHub" @@ -1891,5 +2159,8 @@ }, "widgets": { "message": "Widgets" + }, + "gpa_show_on_hover": { + "message": "Show on hover" } } diff --git a/_locales/it/messages.json b/_locales/it/messages.json index 657ee32..8c65fe8 100644 --- a/_locales/it/messages.json +++ b/_locales/it/messages.json @@ -21,10 +21,26 @@ "message": "Mostra sempre il numero di Mi piace" }, "assignment_avg": { - "message": "— media $AVG$% su $COUNT$ compito/i:" + "message": "— media $AVG$% su $COUNT$ compito/i:", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "Compito in scadenza tra $TIME$" + "message": "Compito in scadenza tra $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "auto" @@ -243,7 +259,17 @@ "message": "completato" }, "completed_total": { - "message": "$DONE$/$TOTAL$ completati" + "message": "$DONE$/$TOTAL$ completati", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "Carte condensate" @@ -429,7 +455,13 @@ "message": "Dovuto" }, "due_days": { - "message": "Scade tra $COUNT$ giorni" + "message": "Scade tra $COUNT$ giorni", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "Scade più tardi" @@ -447,7 +479,13 @@ "message": "Scade domani" }, "due_weeks": { - "message": "Scade tra $COUNT$ settimane" + "message": "Scade tra $COUNT$ settimane", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "Modifica questa attività personalizzata" @@ -555,7 +593,13 @@ "message": "compiti" }, "final_avg": { - "message": "— media $AVG$% ..." + "message": "— media $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "In attesa dei dati sui voti…" @@ -573,7 +617,17 @@ "message": "Il fissatore viene eseguito automaticamente su queste pagine:" }, "fix_took": { - "message": "Correzione completata in $TIME$ms (valutazione: $RATING$)" + "message": "Correzione completata in $TIME$ms (valutazione: $RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "Griglia flessibile" @@ -606,13 +660,25 @@ "message": "Adatta asse Y" }, "ga_heatmap_assignments": { - "message": "$COUNT$ consegna/e:" + "message": "$COUNT$ consegna/e:", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "media" }, "ga_heatmap_undated": { - "message": "$COUNT$ consegna/e valutata/e senza data di scadenza non mostrata/e." + "message": "$COUNT$ consegna/e valutata/e senza data di scadenza non mostrata/e.", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "Voto complessivo nel tempo" @@ -666,10 +732,30 @@ "message": "Non valutate" }, "ga_sub_secured": { - "message": "Anche con 0 all'esame finale resteresti a $ZERO$%, sopra il tuo obiettivo del $TARGET$%." + "message": "Anche con 0 all'esame finale resteresti a $ZERO$%, sopra il tuo obiettivo del $TARGET$%.", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "Anche un esame finale perfetto ti porterebbe solo a $PERFECT$%, sotto il tuo obiettivo del $TARGET$%." + "message": "Anche un esame finale perfetto ti porterebbe solo a $PERFECT$%, sotto il tuo obiettivo del $TARGET$%.", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "Calcolatore finale" @@ -702,13 +788,25 @@ "message": "Punteggio Imagine-If (numeratore); vuoto = non conteggiata" }, "ga_tooltip_assignments": { - "message": "$COUNT$ consegna/e" + "message": "$COUNT$ consegna/e", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "Puoi farcela!" }, "ga_you_need": { - "message": "Ti serve ≥ $PCT$% all'esame finale" + "message": "Ti serve ≥ $PCT$% all'esame finale", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "Ottieni card attive dalla dashboard" @@ -834,7 +932,13 @@ "message": "Aggiunge strumenti per aiutarti ad analizzare i tuoi voti." }, "grade_analytics_failed": { - "message": "Impossibile caricare l'analisi dei voti: $ERROR$" + "message": "Impossibile caricare l'analisi dei voti: $ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "Informazioni sull'analisi dei voti" @@ -864,7 +968,29 @@ "message": " (incluso il calcolatore GPA)" }, "grid_warning": { - "message": "La tua griglia contiene $TOTAL$ card$TOTAL_S$ ma ne hai $ACTIVE$ card$ACTIVE_S$$GPA_NOTE$ - alcune card potrebbero essere tagliate." + "message": "La tua griglia contiene $TOTAL$ card$TOTAL_S$ ma ne hai $ACTIVE$ card$ACTIVE_S$$GPA_NOTE$ - alcune card potrebbero essere tagliate.", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "Valutate" @@ -1023,16 +1149,34 @@ "message": "Immagine astronomica del giorno NASA" }, "nasa_credit": { - "message": "Crediti: $CREDIT$" + "message": "Crediti: $CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "Data: $DATE$" + "message": "Data: $DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "Potrebbe essere necessario aggiornare la pagina per vedere alcune modifiche." }, "new_canvas_desc": { - "message": "Canvas Refined ha rilevato una pagina Canvas su $HOST$. Aggiungerla al tuo elenco Canvas?" + "message": "Canvas Refined ha rilevato una pagina Canvas su $HOST$. Aggiungerla al tuo elenco Canvas?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "Nuovo Canvas rilevato" @@ -1143,7 +1287,13 @@ "message": "Fai clic su questa icona del puzzle in alto a destra" }, "options_contact": { - "message": "La mia email è $EMAIL$ se hai problemi o suggerimenti: qualsiasi feedback è apprezzato!" + "message": "La mia email è $EMAIL$ se hai problemi o suggerimenti: qualsiasi feedback è apprezzato!", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "Come accedere a questo menu in seguito:" @@ -1233,7 +1383,13 @@ "message": "Anguria" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "Attività personale" @@ -1290,13 +1446,51 @@ "message": "Privacy" }, "progress_done": { - "message": "$DONE$/$TOTAL$ completati" + "message": "$DONE$/$TOTAL$ completati", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "Non mostrare più" @@ -1344,13 +1538,25 @@ "message": "Lettura dei dati sui voti…" }, "relative_ago": { - "message": "$TIME$ fa" + "message": "$TIME$ fa", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "Date di scadenza relative" }, "relative_in": { - "message": "tra $TIME$" + "message": "tra $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "Rimuovi il logo della barra laterale" @@ -1425,16 +1631,34 @@ "message": "nuova scheda" }, "search_no_course": { - "message": "Nessun corso corrisponde a \"$QUERY$\"." + "message": "Nessun corso corrisponde a \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "Nessun corso disponibile per aprire i voti." }, "search_no_match": { - "message": "Nessun risultato per \"$QUERY$\"." + "message": "Nessun risultato per \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "Nessun risultato per \"$QUERY$\". Prova con parole chiave diverse." + "message": "Nessun risultato per \"$QUERY$\". Prova con parole chiave diverse.", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "Nessun modulo o compito trovato..." @@ -1443,7 +1667,13 @@ "message": "Nessun modulo o consegna trovato. Riapri la ricerca più tardi se i tuoi corsi sono ancora in caricamento." }, "search_no_results": { - "message": "Nessun risultato per \"$QUERY$\"." + "message": "Nessun risultato per \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "apri" @@ -1488,7 +1718,13 @@ "message": "Sezione" }, "selected_count": { - "message": "$COUNT$ selezionati" + "message": "$COUNT$ selezionati", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "Mostra" @@ -1533,7 +1769,13 @@ "message": "vuota" }, "storage_items": { - "message": " ($COUNT$ elementi)" + "message": " ($COUNT$ elementi)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "I dati che stai inserendo superano il limite di archiviazione, quindi non verranno salvati. Prova a usare link più brevi e assicurati di premere \"Copia indirizzo immagine\" e non \"Copia immagine\" per i link." @@ -1620,7 +1862,13 @@ "message": "Assicurati che il tuo tema rispetti queste linee guida:" }, "theme_number": { - "message": "Tema $NUM$" + "message": "Tema $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "Adesione al browser dei temi ripristinata" @@ -1725,7 +1973,21 @@ "message": "Barra" }, "todo_date_format": { - "message": "$DATE$ alle $TIME$ ($RELATIVE$)" + "message": "$DATE$ alle $TIME$ ($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "Elimina" @@ -1863,7 +2125,13 @@ "message": "Mostra di più" }, "view_more_count": { - "message": "Mostra di più ($COUNT$)" + "message": "Mostra di più ($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "Visualizza su GitHub" @@ -1891,5 +2159,8 @@ }, "widgets": { "message": "Widget" + }, + "gpa_show_on_hover": { + "message": "Show on hover" } } diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json index b7e1f92..3408531 100644 --- a/_locales/ja/messages.json +++ b/_locales/ja/messages.json @@ -21,10 +21,26 @@ "message": "いいね数を常に表示" }, "assignment_avg": { - "message": "— $COUNT$ 件の課題の平均 $AVG$%:" + "message": "— $COUNT$ 件の課題の平均 $AVG$%:", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "課題の期限まで $TIME$" + "message": "課題の期限まで $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "自動" @@ -243,7 +259,17 @@ "message": "完了" }, "completed_total": { - "message": "$DONE$/$TOTAL$ 完了" + "message": "$DONE$/$TOTAL$ 完了", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "凝縮カード" @@ -429,7 +455,13 @@ "message": "期限" }, "due_days": { - "message": "期限 $COUNT$日" + "message": "期限 $COUNT$日", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "期限 後日" @@ -447,7 +479,13 @@ "message": "期限 明日" }, "due_weeks": { - "message": "期限 $COUNT$週間" + "message": "期限 $COUNT$週間", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "このカスタムタスクを編集" @@ -555,7 +593,13 @@ "message": "課題" }, "final_avg": { - "message": "— 平均 $AVG$% ..." + "message": "— 平均 $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "成績データを待っています…" @@ -573,7 +617,17 @@ "message": "Fixer はこれらのページで自動的に実行されます:" }, "fix_took": { - "message": "修正に $TIME$ms かかりました (評価: $RATING$)" + "message": "修正に $TIME$ms かかりました (評価: $RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "フレキシブルグリッド" @@ -606,13 +660,25 @@ "message": "Y軸に合わせる" }, "ga_heatmap_assignments": { - "message": "$COUNT$件の課題:" + "message": "$COUNT$件の課題:", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "平均" }, "ga_heatmap_undated": { - "message": "期限のない評価済み課題$COUNT$件は表示されていません。" + "message": "期限のない評価済み課題$COUNT$件は表示されていません。", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "総合評価の推移" @@ -666,10 +732,30 @@ "message": "未評価" }, "ga_sub_secured": { - "message": "期末試験で0点でも$ZERO$%となり、目標の$TARGET$%を上回ります。" + "message": "期末試験で0点でも$ZERO$%となり、目標の$TARGET$%を上回ります。", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "期末試験で満点でも$PERFECT$%にしかならず、目標の$TARGET$%を下回ります。" + "message": "期末試験で満点でも$PERFECT$%にしかならず、目標の$TARGET$%を下回ります。", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "期末計算" @@ -702,13 +788,25 @@ "message": "Imagine-Ifの得点(分子)。空欄 = 集計しない" }, "ga_tooltip_assignments": { - "message": "$COUNT$件の課題" + "message": "$COUNT$件の課題", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "いけますよ!" }, "ga_you_need": { - "message": "期末試験で$PCT$%以上必要です" + "message": "期末試験で$PCT$%以上必要です", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "ダッシュボードからアクティブなカードを取得" @@ -834,7 +932,13 @@ "message": "成績を分析するためのツールを追加します。" }, "grade_analytics_failed": { - "message": "成績分析の読み込みに失敗しました: $ERROR$" + "message": "成績分析の読み込みに失敗しました: $ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "成績分析の情報" @@ -864,7 +968,29 @@ "message": " (GPA計算を含む)" }, "grid_warning": { - "message": "グリッドには$TOTAL$枚のカード$TOTAL_S$が入りますが、$ACTIVE$枚のカード$ACTIVE_S$$GPA_NOTE$があります - 一部のカードが切れる可能性があります。" + "message": "グリッドには$TOTAL$枚のカード$TOTAL_S$が入りますが、$ACTIVE$枚のカード$ACTIVE_S$$GPA_NOTE$があります - 一部のカードが切れる可能性があります。", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "評価済み" @@ -1023,16 +1149,34 @@ "message": "NASAの天文写真" }, "nasa_credit": { - "message": "クレジット: $CREDIT$" + "message": "クレジット: $CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "日付: $DATE$" + "message": "日付: $DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "変更を反映するにはページを更新する必要がある場合があります。" }, "new_canvas_desc": { - "message": "Canvas Refinedが$HOST$でCanvasページを検出しました。canvasリストに追加しますか?" + "message": "Canvas Refinedが$HOST$でCanvasページを検出しました。canvasリストに追加しますか?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "新しいCanvasを検出" @@ -1143,7 +1287,13 @@ "message": "右上のパズルアイコンをクリックします" }, "options_contact": { - "message": "問題や提案があれば $EMAIL$ までご連絡ください。フィードバックをお待ちしています!" + "message": "問題や提案があれば $EMAIL$ までご連絡ください。フィードバックをお待ちしています!", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "後でこのメニューを開く方法:" @@ -1233,7 +1383,13 @@ "message": "スイカ" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "個人タスク" @@ -1290,13 +1446,51 @@ "message": "プライバシー" }, "progress_done": { - "message": "$DONE$/$TOTAL$ 完了" + "message": "$DONE$/$TOTAL$ 完了", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "今後表示しない" @@ -1344,13 +1538,25 @@ "message": "成績データを読み込み中…" }, "relative_ago": { - "message": "$TIME$前" + "message": "$TIME$前", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "相対的な期日" }, "relative_in": { - "message": "$TIME$後" + "message": "$TIME$後", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "サイドバーのロゴを削除" @@ -1425,16 +1631,34 @@ "message": "新しいタブ" }, "search_no_course": { - "message": "「$QUERY$」に一致するコースはありません。" + "message": "「$QUERY$」に一致するコースはありません。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "成績を開けるコースが見つかりません。" }, "search_no_match": { - "message": "「$QUERY$」の結果はありません。" + "message": "「$QUERY$」の結果はありません。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "「$QUERY$」の結果はありません。別のキーワードを試してください。" + "message": "「$QUERY$」の結果はありません。別のキーワードを試してください。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "モジュールや課題が見つかりません..." @@ -1443,7 +1667,13 @@ "message": "モジュールや課題が見つかりません。コースの読み込み中であれば、後で検索を開き直してください。" }, "search_no_results": { - "message": "「$QUERY$」の結果はありません。" + "message": "「$QUERY$」の結果はありません。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "開く" @@ -1488,7 +1718,13 @@ "message": "セクション" }, "selected_count": { - "message": "$COUNT$ 件選択中" + "message": "$COUNT$ 件選択中", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "表示" @@ -1533,7 +1769,13 @@ "message": "空" }, "storage_items": { - "message": " ($COUNT$件)" + "message": " ($COUNT$件)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "入力したデータがストレージの上限を超えているため保存できません。リンクを短くし、リンクには「画像をコピー」ではなく「画像アドレスをコピー」を使用してください。" @@ -1620,7 +1862,13 @@ "message": "テーマが次のガイドラインに従っていることを確認してください:" }, "theme_number": { - "message": "テーマ $NUM$" + "message": "テーマ $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "テーマブラウザのオプトインをリセット" @@ -1725,7 +1973,21 @@ "message": "打ち消し線" }, "todo_date_format": { - "message": "$DATE$ $TIME$($RELATIVE$)" + "message": "$DATE$ $TIME$($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "削除" @@ -1863,7 +2125,13 @@ "message": "もっと見る" }, "view_more_count": { - "message": "もっと見る ($COUNT$)" + "message": "もっと見る ($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "GitHubで見る" @@ -1891,5 +2159,8 @@ }, "widgets": { "message": "ウィジェット" + }, + "gpa_show_on_hover": { + "message": "Show on hover" } } diff --git a/_locales/pt_PT/messages.json b/_locales/pt_PT/messages.json index 1526006..f2c30fc 100644 --- a/_locales/pt_PT/messages.json +++ b/_locales/pt_PT/messages.json @@ -21,10 +21,26 @@ "message": "Mostrar sempre o número de gostos" }, "assignment_avg": { - "message": "— média $AVG$% em $COUNT$ trabalho(s):" + "message": "— média $AVG$% em $COUNT$ trabalho(s):", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "Trabalho é entregue daqui a $TIME$" + "message": "Trabalho é entregue daqui a $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "auto" @@ -243,7 +259,17 @@ "message": "concluído" }, "completed_total": { - "message": "$DONE$/$TOTAL$ concluídos" + "message": "$DONE$/$TOTAL$ concluídos", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "Cartões condensados" @@ -429,7 +455,13 @@ "message": "Devido" }, "due_days": { - "message": "Entrega em $COUNT$ dias" + "message": "Entrega em $COUNT$ dias", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "Entrega mais tarde" @@ -447,7 +479,13 @@ "message": "Entrega amanhã" }, "due_weeks": { - "message": "Entrega em $COUNT$ semanas" + "message": "Entrega em $COUNT$ semanas", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "Editar esta tarefa personalizada" @@ -555,7 +593,13 @@ "message": "trabalhos" }, "final_avg": { - "message": "— média $AVG$% ..." + "message": "— média $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "A aguardar dados das notas…" @@ -573,7 +617,17 @@ "message": "O Fixer está sendo executado automaticamente nestas páginas:" }, "fix_took": { - "message": "A correção demorou $TIME$ms (avaliação: $RATING$)" + "message": "A correção demorou $TIME$ms (avaliação: $RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "Grelha flexível" @@ -606,13 +660,25 @@ "message": "Ajustar eixo Y" }, "ga_heatmap_assignments": { - "message": "$COUNT$ trabalho(s):" + "message": "$COUNT$ trabalho(s):", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "média" }, "ga_heatmap_undated": { - "message": "$COUNT$ trabalho(s) avaliado(s) sem data de entrega não apresentado(s)." + "message": "$COUNT$ trabalho(s) avaliado(s) sem data de entrega não apresentado(s).", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "Nota global ao longo do tempo" @@ -666,10 +732,30 @@ "message": "Não avaliados" }, "ga_sub_secured": { - "message": "Mesmo um 0 no exame final deixa-te com $ZERO$%, acima do teu objetivo de $TARGET$%." + "message": "Mesmo um 0 no exame final deixa-te com $ZERO$%, acima do teu objetivo de $TARGET$%.", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "Mesmo um exame final perfeito só te leva a $PERFECT$%, abaixo do teu objetivo de $TARGET$%." + "message": "Mesmo um exame final perfeito só te leva a $PERFECT$%, abaixo do teu objetivo de $TARGET$%.", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "Calculadora do exame final" @@ -702,13 +788,25 @@ "message": "Nota no Imagine-If (numerador); vazio = não contabilizado" }, "ga_tooltip_assignments": { - "message": "$COUNT$ trabalho(s)" + "message": "$COUNT$ trabalho(s)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "Consegues!" }, "ga_you_need": { - "message": "Precisas de ≥ $PCT$% no exame final" + "message": "Precisas de ≥ $PCT$% no exame final", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "Obter cartões ativos do painel" @@ -834,7 +932,13 @@ "message": "Adiciona ferramentas para te ajudar a analisar as tuas notas." }, "grade_analytics_failed": { - "message": "Falha ao carregar a análise de notas: $ERROR$" + "message": "Falha ao carregar a análise de notas: $ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "Informação da análise de notas" @@ -864,7 +968,29 @@ "message": " (incluindo a calculadora de GPA)" }, "grid_warning": { - "message": "A tua grelha comporta $TOTAL$ vaga$TOTAL_S$, mas tens $ACTIVE$ vaga$ACTIVE_S$$GPA_NOTE$ - alguns cartões podem ficar cortados." + "message": "A tua grelha comporta $TOTAL$ vaga$TOTAL_S$, mas tens $ACTIVE$ vaga$ACTIVE_S$$GPA_NOTE$ - alguns cartões podem ficar cortados.", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "Avaliados" @@ -1023,16 +1149,34 @@ "message": "Imagem Astronómica do Dia da NASA" }, "nasa_credit": { - "message": "Crédito: $CREDIT$" + "message": "Crédito: $CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "Data: $DATE$" + "message": "Data: $DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "Pode ser necessário atualizar a página para veres algumas alterações." }, "new_canvas_desc": { - "message": "O Canvas Refined detetou uma página do Canvas em $HOST$. Adicioná-la à tua lista de Canvas?" + "message": "O Canvas Refined detetou uma página do Canvas em $HOST$. Adicioná-la à tua lista de Canvas?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "Novo Canvas detetado" @@ -1143,7 +1287,13 @@ "message": "Clica neste ícone de puzzle no canto superior direito" }, "options_contact": { - "message": "O meu email é $EMAIL$ se tiveres problemas ou sugestões — todo o feedback é bem-vindo!" + "message": "O meu email é $EMAIL$ se tiveres problemas ou sugestões — todo o feedback é bem-vindo!", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "Como aceder a este menu mais tarde:" @@ -1233,7 +1383,13 @@ "message": "Melancia" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "Tarefa pessoal" @@ -1290,13 +1446,51 @@ "message": "Privacidade" }, "progress_done": { - "message": "$DONE$/$TOTAL$ concluídos" + "message": "$DONE$/$TOTAL$ concluídos", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "Não mostrar novamente" @@ -1344,13 +1538,25 @@ "message": "A ler os dados das notas…" }, "relative_ago": { - "message": "há $TIME$" + "message": "há $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "Datas de vencimento relativas" }, "relative_in": { - "message": "dentro de $TIME$" + "message": "dentro de $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "Remover logotipo da barra lateral" @@ -1425,16 +1631,34 @@ "message": "novo separador" }, "search_no_course": { - "message": "Nenhuma disciplina corresponde a \"$QUERY$\"." + "message": "Nenhuma disciplina corresponde a \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "Não foram encontrados cursos para abrir as notas." }, "search_no_match": { - "message": "Sem resultados para \"$QUERY$\"." + "message": "Sem resultados para \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "Sem resultados para \"$QUERY$\". Tenta outras palavras-chave." + "message": "Sem resultados para \"$QUERY$\". Tenta outras palavras-chave.", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "Não foram encontrados módulos ou trabalhos..." @@ -1443,7 +1667,13 @@ "message": "Não foram encontrados módulos ou trabalhos. Volta a abrir a pesquisa mais tarde se os teus cursos ainda estiverem a carregar." }, "search_no_results": { - "message": "Sem resultados para \"$QUERY$\"." + "message": "Sem resultados para \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "abrir" @@ -1488,7 +1718,13 @@ "message": "Secção" }, "selected_count": { - "message": "$COUNT$ selecionados" + "message": "$COUNT$ selecionados", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "Mostrar" @@ -1533,7 +1769,13 @@ "message": "vazio" }, "storage_items": { - "message": " ($COUNT$ itens)" + "message": " ($COUNT$ itens)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "Os dados que estás a introduzir excedem o limite de armazenamento, por isso não serão guardados. Tenta usar ligações mais curtas e certifica-te de que pressionas \"copiar endereço da imagem\" e não \"copiar imagem\"." @@ -1620,7 +1862,13 @@ "message": "Certifica-te de que o teu tema segue estas diretrizes:" }, "theme_number": { - "message": "Tema $NUM$" + "message": "Tema $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "Adesão ao navegador de temas reposta" @@ -1725,7 +1973,21 @@ "message": "Riscar" }, "todo_date_format": { - "message": "$DATE$ às $TIME$ ($RELATIVE$)" + "message": "$DATE$ às $TIME$ ($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "Eliminar" @@ -1863,7 +2125,13 @@ "message": "Ver mais" }, "view_more_count": { - "message": "Ver mais ($COUNT$)" + "message": "Ver mais ($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "Ver no GitHub" @@ -1891,5 +2159,8 @@ }, "widgets": { "message": "Widgets" + }, + "gpa_show_on_hover": { + "message": "Show on hover" } } diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json index 2ed5c07..d4d57b8 100644 --- a/_locales/ru/messages.json +++ b/_locales/ru/messages.json @@ -21,10 +21,26 @@ "message": "Всегда показывать число лайков" }, "assignment_avg": { - "message": "— в среднем $AVG$% по $COUNT$ заданиям:" + "message": "— в среднем $AVG$% по $COUNT$ заданиям:", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "Задание нужно сдать через $TIME$" + "message": "Задание нужно сдать через $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "авто" @@ -243,7 +259,17 @@ "message": "готово" }, "completed_total": { - "message": "$DONE$/$TOTAL$ выполнено" + "message": "$DONE$/$TOTAL$ выполнено", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "Сжатые карты" @@ -429,7 +455,13 @@ "message": "Должный" }, "due_days": { - "message": "Срок через $COUNT$ дн." + "message": "Срок через $COUNT$ дн.", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "Срок позже" @@ -447,7 +479,13 @@ "message": "Срок завтра" }, "due_weeks": { - "message": "Срок через $COUNT$ нед." + "message": "Срок через $COUNT$ нед.", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "Изменить эту задачу" @@ -555,7 +593,13 @@ "message": "заданий" }, "final_avg": { - "message": "— в среднем $AVG$% ..." + "message": "— в среднем $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "Ожидание данных об оценках…" @@ -573,7 +617,17 @@ "message": "Fixer автоматически запускается на этих страницах:" }, "fix_took": { - "message": "Исправление заняло $TIME$ мс (оценка: $RATING$)" + "message": "Исправление заняло $TIME$ мс (оценка: $RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "Гибкая сетка" @@ -606,13 +660,25 @@ "message": "По размеру оси Y" }, "ga_heatmap_assignments": { - "message": "$COUNT$ заданий:" + "message": "$COUNT$ заданий:", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "сред." }, "ga_heatmap_undated": { - "message": "$COUNT$ оценённых заданий без срока не показано." + "message": "$COUNT$ оценённых заданий без срока не показано.", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "Итоговая оценка во времени" @@ -666,10 +732,30 @@ "message": "Не оценено" }, "ga_sub_secured": { - "message": "Даже 0 за экзамен оставит вас на $ZERO$%, что выше вашей цели $TARGET$%." + "message": "Даже 0 за экзамен оставит вас на $ZERO$%, что выше вашей цели $TARGET$%.", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "Даже идеальный экзамен даст только $PERFECT$%, что ниже вашей цели $TARGET$%." + "message": "Даже идеальный экзамен даст только $PERFECT$%, что ниже вашей цели $TARGET$%.", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "Калькулятор экзамена" @@ -702,13 +788,25 @@ "message": "Баллы Imagine-If (числитель); пусто = не учитывается" }, "ga_tooltip_assignments": { - "message": "$COUNT$ заданий" + "message": "$COUNT$ заданий", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "У вас всё получится!" }, "ga_you_need": { - "message": "Вам нужно ≥ $PCT$% за экзамен" + "message": "Вам нужно ≥ $PCT$% за экзамен", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "Получить активные карточки с панели" @@ -834,7 +932,13 @@ "message": "Добавляет инструменты для анализа ваших оценок." }, "grade_analytics_failed": { - "message": "Не удалось загрузить анализ оценок: $ERROR$" + "message": "Не удалось загрузить анализ оценок: $ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "Сведения об анализе оценок" @@ -864,7 +968,29 @@ "message": " (включая калькулятор GPA)" }, "grid_warning": { - "message": "В вашей сетке помещается $TOTAL$ карточек$TOTAL_S$, но у вас $ACTIVE$ карточка$ACTIVE_S$$GPA_NOTE$ — некоторые карточки могут обрезаться." + "message": "В вашей сетке помещается $TOTAL$ карточек$TOTAL_S$, но у вас $ACTIVE$ карточка$ACTIVE_S$$GPA_NOTE$ — некоторые карточки могут обрезаться.", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "С оценкой" @@ -1023,16 +1149,34 @@ "message": "Астрономическое изображение дня NASA" }, "nasa_credit": { - "message": "Автор: $CREDIT$" + "message": "Автор: $CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "Дата: $DATE$" + "message": "Дата: $DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "Возможно, потребуется обновить страницу, чтобы увидеть некоторые изменения." }, "new_canvas_desc": { - "message": "Canvas Refined обнаружил страницу Canvas по адресу $HOST$. Добавить её в ваш список Canvas?" + "message": "Canvas Refined обнаружил страницу Canvas по адресу $HOST$. Добавить её в ваш список Canvas?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "Обнаружен новый Canvas" @@ -1143,7 +1287,13 @@ "message": "Нажмите на значок пазла в правом верхнем углу" }, "options_contact": { - "message": "Моя почта — $EMAIL$. Если у вас есть проблемы или предложения, буду рад обратной связи!" + "message": "Моя почта — $EMAIL$. Если у вас есть проблемы или предложения, буду рад обратной связи!", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "Как открыть это меню позже:" @@ -1233,7 +1383,13 @@ "message": "Арбуз" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "Личная задача" @@ -1290,13 +1446,51 @@ "message": "Конфиденциальность" }, "progress_done": { - "message": "$DONE$/$TOTAL$ выполнено" + "message": "$DONE$/$TOTAL$ выполнено", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "Больше не показывать" @@ -1344,13 +1538,25 @@ "message": "Чтение данных об оценках…" }, "relative_ago": { - "message": "$TIME$ назад" + "message": "$TIME$ назад", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "Относительные сроки выполнения" }, "relative_in": { - "message": "через $TIME$" + "message": "через $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "Удалить логотип боковой панели" @@ -1425,16 +1631,34 @@ "message": "новая вкладка" }, "search_no_course": { - "message": "Нет курса, соответствующего \"$QUERY$\"." + "message": "Нет курса, соответствующего \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "Курсы для открытия оценок не найдены." }, "search_no_match": { - "message": "Нет результатов по \"$QUERY$\"." + "message": "Нет результатов по \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "Нет результатов по \"$QUERY$\". Попробуйте другие ключевые слова." + "message": "Нет результатов по \"$QUERY$\". Попробуйте другие ключевые слова.", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "Модули или задания не найдены..." @@ -1443,7 +1667,13 @@ "message": "Модули или задания не найдены. Откройте поиск позже, если ваши курсы ещё загружаются." }, "search_no_results": { - "message": "Нет результатов по \"$QUERY$\"." + "message": "Нет результатов по \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "открыть" @@ -1488,7 +1718,13 @@ "message": "Раздел" }, "selected_count": { - "message": "Выбрано: $COUNT$" + "message": "Выбрано: $COUNT$", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "Показать" @@ -1533,7 +1769,13 @@ "message": "пусто" }, "storage_items": { - "message": " ($COUNT$ элем.)" + "message": " ($COUNT$ элем.)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "Вводимые данные превышают лимит хранилища, поэтому они не сохранятся. Используйте более короткие ссылки и обязательно нажимайте «копировать адрес изображения», а не «копировать изображение»." @@ -1620,7 +1862,13 @@ "message": "Убедитесь, что ваша тема соответствует этим правилам:" }, "theme_number": { - "message": "Тема $NUM$" + "message": "Тема $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "Сброс согласия браузера тем" @@ -1725,7 +1973,21 @@ "message": "Вычеркнуть" }, "todo_date_format": { - "message": "$DATE$ в $TIME$ ($RELATIVE$)" + "message": "$DATE$ в $TIME$ ($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "Удалить" @@ -1863,7 +2125,13 @@ "message": "Показать больше" }, "view_more_count": { - "message": "Показать больше ($COUNT$)" + "message": "Показать больше ($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "Посмотреть на GitHub" @@ -1891,5 +2159,8 @@ }, "widgets": { "message": "Виджеты" + }, + "gpa_show_on_hover": { + "message": "Show on hover" } } diff --git a/_locales/sv/messages.json b/_locales/sv/messages.json index 9a1f1e1..6b13720 100644 --- a/_locales/sv/messages.json +++ b/_locales/sv/messages.json @@ -21,10 +21,26 @@ "message": "Visa alltid antal gillningar" }, "assignment_avg": { - "message": "— snitt $AVG$% över $COUNT$ uppgift(er):" + "message": "— snitt $AVG$% över $COUNT$ uppgift(er):", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "Uppgift förfaller om $TIME$" + "message": "Uppgift förfaller om $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "auto" @@ -243,7 +259,17 @@ "message": "klar" }, "completed_total": { - "message": "$DONE$/$TOTAL$ klara" + "message": "$DONE$/$TOTAL$ klara", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "Kondenserade kort" @@ -429,7 +455,13 @@ "message": "Förfaller" }, "due_days": { - "message": "Förfaller om $COUNT$ dagar" + "message": "Förfaller om $COUNT$ dagar", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "Förfaller senare" @@ -447,7 +479,13 @@ "message": "Förfaller imorgon" }, "due_weeks": { - "message": "Förfaller om $COUNT$ veckor" + "message": "Förfaller om $COUNT$ veckor", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "Redigera denna anpassade uppgift" @@ -555,7 +593,13 @@ "message": "uppgifter" }, "final_avg": { - "message": "— snitt $AVG$% ..." + "message": "— snitt $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "Väntar på betygsdata…" @@ -573,7 +617,17 @@ "message": "Fixern körs automatiskt på dessa sidor:" }, "fix_took": { - "message": "Åtgärden tog $TIME$ ms (betyg: $RATING$)" + "message": "Åtgärden tog $TIME$ ms (betyg: $RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "Flexibelt rutnät" @@ -606,13 +660,25 @@ "message": "Anpassa Y-axeln" }, "ga_heatmap_assignments": { - "message": "$COUNT$ uppgift(er):" + "message": "$COUNT$ uppgift(er):", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "snitt" }, "ga_heatmap_undated": { - "message": "$COUNT$ betygsatt(a) uppgift(er) utan förfallodatum visas inte." + "message": "$COUNT$ betygsatt(a) uppgift(er) utan förfallodatum visas inte.", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "Totalt betyg över tid" @@ -666,10 +732,30 @@ "message": "Ej betygsatta" }, "ga_sub_secured": { - "message": "Även en 0 på tentan ger dig $ZERO$%, vilket är över ditt mål på $TARGET$%." + "message": "Även en 0 på tentan ger dig $ZERO$%, vilket är över ditt mål på $TARGET$%.", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "Även en perfekt tenta ger dig bara $PERFECT$%, vilket är under ditt mål på $TARGET$%." + "message": "Även en perfekt tenta ger dig bara $PERFECT$%, vilket är under ditt mål på $TARGET$%.", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "Tentakalkylator" @@ -702,13 +788,25 @@ "message": "Imagine-If-poäng (täljare); tomt = räknas inte" }, "ga_tooltip_assignments": { - "message": "$COUNT$ uppgift(er)" + "message": "$COUNT$ uppgift(er)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "Det här klarar du!" }, "ga_you_need": { - "message": "Du behöver ≥ $PCT$% på tentan" + "message": "Du behöver ≥ $PCT$% på tentan", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "Hämta aktiva kort från översikten" @@ -834,7 +932,13 @@ "message": "Lägger till verktyg som hjälper dig analysera dina betyg." }, "grade_analytics_failed": { - "message": "Betygsanalysen kunde inte laddas: $ERROR$" + "message": "Betygsanalysen kunde inte laddas: $ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "Information om betygsanalys" @@ -864,7 +968,29 @@ "message": " (inklusive GPA-kalkylatorn)" }, "grid_warning": { - "message": "Ditt rutnät har plats för $TOTAL$ kort$TOTAL_S$ men du har $ACTIVE$ kort$ACTIVE_S$$GPA_NOTE$ – vissa kort kan klippas av." + "message": "Ditt rutnät har plats för $TOTAL$ kort$TOTAL_S$ men du har $ACTIVE$ kort$ACTIVE_S$$GPA_NOTE$ – vissa kort kan klippas av.", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "Betygsatta" @@ -1023,16 +1149,34 @@ "message": "NASA:s astronomiska bild för dagen" }, "nasa_credit": { - "message": "Kredit: $CREDIT$" + "message": "Kredit: $CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "Datum: $DATE$" + "message": "Datum: $DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "Du kan behöva uppdatera sidan för att se vissa ändringar." }, "new_canvas_desc": { - "message": "Canvas Refined hittade en Canvas-sida på $HOST$. Lägg till den i din Canvas-lista?" + "message": "Canvas Refined hittade en Canvas-sida på $HOST$. Lägg till den i din Canvas-lista?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "Ny Canvas hittad" @@ -1143,7 +1287,13 @@ "message": "Klicka på pusselikonen uppe till höger" }, "options_contact": { - "message": "Min e-post är $EMAIL$ om du har problem eller förslag – all feedback uppskattas!" + "message": "Min e-post är $EMAIL$ om du har problem eller förslag – all feedback uppskattas!", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "Så här öppnar du menyn senare:" @@ -1233,7 +1383,13 @@ "message": "Vattenmelon" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "Personlig uppgift" @@ -1290,13 +1446,51 @@ "message": "Integritet" }, "progress_done": { - "message": "$DONE$/$TOTAL$ klara" + "message": "$DONE$/$TOTAL$ klara", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$% ($DONE$/$TOTAL$)" + "message": "$PCT$% ($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "Visa inte igen" @@ -1344,13 +1538,25 @@ "message": "Läser betygsdata…" }, "relative_ago": { - "message": "$TIME$ sedan" + "message": "$TIME$ sedan", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "Relativa förfallodatum" }, "relative_in": { - "message": "om $TIME$" + "message": "om $TIME$", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "Ta bort Sidebar-logotypen" @@ -1425,16 +1631,34 @@ "message": "ny flik" }, "search_no_course": { - "message": "Ingen kurs matchar \"$QUERY$\"." + "message": "Ingen kurs matchar \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "Inga kurser hittades att öppna betyg för." }, "search_no_match": { - "message": "Inga resultat för \"$QUERY$\"." + "message": "Inga resultat för \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "Inga resultat för \"$QUERY$\". Prova andra sökord." + "message": "Inga resultat för \"$QUERY$\". Prova andra sökord.", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "Inga moduler eller uppgifter hittades..." @@ -1443,7 +1667,13 @@ "message": "Inga moduler eller uppgifter hittades. Öppna sökningen igen senare om kurserna fortfarande laddas." }, "search_no_results": { - "message": "Inga resultat för \"$QUERY$\"." + "message": "Inga resultat för \"$QUERY$\".", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "öppna" @@ -1488,7 +1718,13 @@ "message": "Avsnitt" }, "selected_count": { - "message": "$COUNT$ valda" + "message": "$COUNT$ valda", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "Visa" @@ -1533,7 +1769,13 @@ "message": "tom" }, "storage_items": { - "message": " ($COUNT$ objekt)" + "message": " ($COUNT$ objekt)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "Uppgifterna du anger överskrider lagringsgränsen och sparas inte. Prova kortare länkar och se till att trycka på \"kopiera bildadress\" och inte \"kopiera bild\" för länkar." @@ -1620,7 +1862,13 @@ "message": "Se till att ditt tema följer dessa riktlinjer:" }, "theme_number": { - "message": "Tema $NUM$" + "message": "Tema $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "Opt-in för temabläddrare återställd" @@ -1725,7 +1973,21 @@ "message": "Stryk över" }, "todo_date_format": { - "message": "$DATE$ kl. $TIME$ ($RELATIVE$)" + "message": "$DATE$ kl. $TIME$ ($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "Ta bort" @@ -1863,7 +2125,13 @@ "message": "Visa mer" }, "view_more_count": { - "message": "Visa mer ($COUNT$)" + "message": "Visa mer ($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "Visa på GitHub" @@ -1891,5 +2159,8 @@ }, "widgets": { "message": "Widgetar" + }, + "gpa_show_on_hover": { + "message": "Show on hover" } } diff --git a/_locales/zh_CN/messages.json b/_locales/zh_CN/messages.json index 81f08e2..663f49b 100644 --- a/_locales/zh_CN/messages.json +++ b/_locales/zh_CN/messages.json @@ -21,10 +21,26 @@ "message": "始终显示点赞数" }, "assignment_avg": { - "message": "— 平均 $AVG$%,共 $COUNT$ 项作业:" + "message": "— 平均 $AVG$%,共 $COUNT$ 项作业:", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "作业将在 $TIME$ 后到期" + "message": "作业将在 $TIME$ 后到期", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "自动" @@ -243,7 +259,17 @@ "message": "完成" }, "completed_total": { - "message": "$DONE$/$TOTAL$ 已完成" + "message": "$DONE$/$TOTAL$ 已完成", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "浓缩卡" @@ -429,7 +455,13 @@ "message": "到期的" }, "due_days": { - "message": "$COUNT$ 天后到期" + "message": "$COUNT$ 天后到期", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "稍后到期" @@ -447,7 +479,13 @@ "message": "明天到期" }, "due_weeks": { - "message": "$COUNT$ 周后到期" + "message": "$COUNT$ 周后到期", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "编辑此自定义任务" @@ -555,7 +593,13 @@ "message": "项作业" }, "final_avg": { - "message": "— 平均 $AVG$% ..." + "message": "— 平均 $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "正在等待成绩数据…" @@ -573,7 +617,17 @@ "message": "修复程序会自动在这些页面上运行:" }, "fix_took": { - "message": "修复耗时 $TIME$ms(评分:$RATING$)" + "message": "修复耗时 $TIME$ms(评分:$RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "弹性网格" @@ -606,13 +660,25 @@ "message": "自适应 Y 轴" }, "ga_heatmap_assignments": { - "message": "$COUNT$ 项作业:" + "message": "$COUNT$ 项作业:", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "平均" }, "ga_heatmap_undated": { - "message": "$COUNT$ 项有评分但无截止日期的作业未显示。" + "message": "$COUNT$ 项有评分但无截止日期的作业未显示。", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "总评成绩变化" @@ -666,10 +732,30 @@ "message": "未评分" }, "ga_sub_secured": { - "message": "即使期末考 0 分,你的成绩仍有 $ZERO$%,高于 $TARGET$% 的目标。" + "message": "即使期末考 0 分,你的成绩仍有 $ZERO$%,高于 $TARGET$% 的目标。", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "即使期末考满分,你的成绩也只能达到 $PERFECT$%,低于 $TARGET$% 的目标。" + "message": "即使期末考满分,你的成绩也只能达到 $PERFECT$%,低于 $TARGET$% 的目标。", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "期末计算器" @@ -702,13 +788,25 @@ "message": "Imagine-If 得分(分子);留空 = 不计入" }, "ga_tooltip_assignments": { - "message": "$COUNT$ 项作业" + "message": "$COUNT$ 项作业", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "你能行!" }, "ga_you_need": { - "message": "期末需要 ≥ $PCT$%" + "message": "期末需要 ≥ $PCT$%", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "从仪表板获取活动卡片" @@ -834,7 +932,13 @@ "message": "添加帮助你分析成绩的工具。" }, "grade_analytics_failed": { - "message": "成绩分析加载失败:$ERROR$" + "message": "成绩分析加载失败:$ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "成绩分析信息" @@ -864,7 +968,29 @@ "message": " (包括 GPA 计算器)" }, "grid_warning": { - "message": "你的网格可容纳 $TOTAL$ 张卡片$TOTAL_S$,但你有 $ACTIVE$ 张卡片$ACTIVE_S$$GPA_NOTE$ - 部分卡片可能会被裁切。" + "message": "你的网格可容纳 $TOTAL$ 张卡片$TOTAL_S$,但你有 $ACTIVE$ 张卡片$ACTIVE_S$$GPA_NOTE$ - 部分卡片可能会被裁切。", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "已评分" @@ -1023,16 +1149,34 @@ "message": "NASA 每日天文图片" }, "nasa_credit": { - "message": "图片来源:$CREDIT$" + "message": "图片来源:$CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "日期:$DATE$" + "message": "日期:$DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "你可能需要刷新页面才能看到某些更改。" }, "new_canvas_desc": { - "message": "Canvas Refined 在 $HOST$ 检测到 Canvas 页面。要将它添加到你的 Canvas 列表吗?" + "message": "Canvas Refined 在 $HOST$ 检测到 Canvas 页面。要将它添加到你的 Canvas 列表吗?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "检测到新的 Canvas" @@ -1143,7 +1287,13 @@ "message": "点击右上角的拼图图标" }, "options_contact": { - "message": "如果你有任何问题或建议,我的邮箱是 $EMAIL$,欢迎反馈!" + "message": "如果你有任何问题或建议,我的邮箱是 $EMAIL$,欢迎反馈!", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "以后如何打开此菜单:" @@ -1233,7 +1383,13 @@ "message": "西瓜" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "个人任务" @@ -1290,13 +1446,51 @@ "message": "隐私" }, "progress_done": { - "message": "$DONE$/$TOTAL$ 已完成" + "message": "$DONE$/$TOTAL$ 已完成", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$%($DONE$/$TOTAL$)" + "message": "$PCT$%($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$%($DONE$/$TOTAL$)" + "message": "$PCT$%($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "不再显示" @@ -1344,13 +1538,25 @@ "message": "正在读取成绩数据…" }, "relative_ago": { - "message": "$TIME$前" + "message": "$TIME$前", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "相对到期日" }, "relative_in": { - "message": "$TIME$后" + "message": "$TIME$后", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "删除侧边栏徽标" @@ -1425,16 +1631,34 @@ "message": "新标签页" }, "search_no_course": { - "message": "没有匹配 \"$QUERY$\" 的课程。" + "message": "没有匹配 \"$QUERY$\" 的课程。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "未找到可打开成绩的课程。" }, "search_no_match": { - "message": "未找到 \"$QUERY$\" 的结果。" + "message": "未找到 \"$QUERY$\" 的结果。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "未找到 \"$QUERY$\" 的结果。请尝试其他关键词。" + "message": "未找到 \"$QUERY$\" 的结果。请尝试其他关键词。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "未找到模块或作业..." @@ -1443,7 +1667,13 @@ "message": "未找到模块或作业。如果你的课程仍在加载,请稍后重新打开搜索。" }, "search_no_results": { - "message": "未找到 \"$QUERY$\" 的结果。" + "message": "未找到 \"$QUERY$\" 的结果。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "打开" @@ -1488,7 +1718,13 @@ "message": "章节" }, "selected_count": { - "message": "已选择 $COUNT$ 项" + "message": "已选择 $COUNT$ 项", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "显示" @@ -1533,7 +1769,13 @@ "message": "空" }, "storage_items": { - "message": " ($COUNT$ 项)" + "message": " ($COUNT$ 项)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "输入的数据超出存储限制,因此无法保存。请尝试使用更短的链接,并确保按“复制图片地址”而不是“复制图片”来获取链接。" @@ -1620,7 +1862,13 @@ "message": "确保你的主题遵循以下准则:" }, "theme_number": { - "message": "主题 $NUM$" + "message": "主题 $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "主题浏览器选择已重置" @@ -1725,7 +1973,21 @@ "message": "划掉" }, "todo_date_format": { - "message": "$DATE$ $TIME$($RELATIVE$)" + "message": "$DATE$ $TIME$($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "删除" @@ -1863,7 +2125,13 @@ "message": "查看更多" }, "view_more_count": { - "message": "查看更多($COUNT$)" + "message": "查看更多($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "在 GitHub 上查看" @@ -1891,5 +2159,8 @@ }, "widgets": { "message": "小组件" + }, + "gpa_show_on_hover": { + "message": "Show on hover" } } diff --git a/_locales/zh_TW/messages.json b/_locales/zh_TW/messages.json index 1093752..a75c366 100644 --- a/_locales/zh_TW/messages.json +++ b/_locales/zh_TW/messages.json @@ -21,10 +21,26 @@ "message": "永遠顯示按讚數" }, "assignment_avg": { - "message": "— 平均 $AVG$%,共 $COUNT$ 份作業:" + "message": "— 平均 $AVG$%,共 $COUNT$ 份作業:", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + }, + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "assignment_due_in": { - "message": "作業將於 $TIME$ 後到期" + "message": "作業將於 $TIME$ 後到期", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "auto": { "message": "自動" @@ -243,7 +259,17 @@ "message": "完成" }, "completed_total": { - "message": "已完成 $DONE$/$TOTAL$" + "message": "已完成 $DONE$/$TOTAL$", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "condensed_cards": { "message": "浓缩卡" @@ -429,7 +455,13 @@ "message": "到期的" }, "due_days": { - "message": "到期 $COUNT$ 天" + "message": "到期 $COUNT$ 天", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "due_later": { "message": "到期 稍後" @@ -447,7 +479,13 @@ "message": "到期 明天" }, "due_weeks": { - "message": "到期 $COUNT$ 週" + "message": "到期 $COUNT$ 週", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "edit_custom_task": { "message": "編輯此自訂待辦事項" @@ -555,7 +593,13 @@ "message": "份作業" }, "final_avg": { - "message": "— 平均 $AVG$% ..." + "message": "— 平均 $AVG$% ...", + "placeholders": { + "avg": { + "content": "$AVG$", + "example": "AVG" + } + } }, "final_waiting": { "message": "正在等待成績資料…" @@ -573,7 +617,17 @@ "message": "修复程序会自动在这些页面上运行:" }, "fix_took": { - "message": "修正耗時 $TIME$ 毫秒(評分:$RATING$)" + "message": "修正耗時 $TIME$ 毫秒(評分:$RATING$)", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "rating": { + "content": "$RATING$", + "example": "RATING" + } + } }, "flexible_grid": { "message": "彈性格線" @@ -606,13 +660,25 @@ "message": "調整 Y 軸範圍" }, "ga_heatmap_assignments": { - "message": "$COUNT$ 項作業:" + "message": "$COUNT$ 項作業:", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_heatmap_avg": { "message": "平均" }, "ga_heatmap_undated": { - "message": "有 $COUNT$ 項已評分作業沒有到期日,因此未顯示。" + "message": "有 $COUNT$ 項已評分作業沒有到期日,因此未顯示。", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_line_title": { "message": "總成績變化" @@ -666,10 +732,30 @@ "message": "未評分" }, "ga_sub_secured": { - "message": "即使期末考拿 0 分,你仍有 $ZERO$%,高於你的目標 $TARGET$%。" + "message": "即使期末考拿 0 分,你仍有 $ZERO$%,高於你的目標 $TARGET$%。", + "placeholders": { + "target": { + "content": "$TARGET$", + "example": "TARGET" + }, + "zero": { + "content": "$ZERO$", + "example": "ZERO" + } + } }, "ga_sub_unreachable": { - "message": "即使期末考滿分,你也只能達到 $PERFECT$%,低於你的目標 $TARGET$%。" + "message": "即使期末考滿分,你也只能達到 $PERFECT$%,低於你的目標 $TARGET$%。", + "placeholders": { + "perfect": { + "content": "$PERFECT$", + "example": "PERFECT" + }, + "target": { + "content": "$TARGET$", + "example": "TARGET" + } + } }, "ga_tab_calc": { "message": "期末考計算器" @@ -702,13 +788,25 @@ "message": "Imagine-If 分數(分子);留空 = 不計入" }, "ga_tooltip_assignments": { - "message": "$COUNT$ 項作業" + "message": "$COUNT$ 項作業", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "ga_you_got_this": { "message": "你可以的!" }, "ga_you_need": { - "message": "你的期末考需要 ≥ $PCT$%" + "message": "你的期末考需要 ≥ $PCT$%", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + } + } }, "get_active_cards": { "message": "從儀表板取得使用中的卡片" @@ -834,7 +932,13 @@ "message": "新增工具,協助你分析成績。" }, "grade_analytics_failed": { - "message": "成績分析載入失敗:$ERROR$" + "message": "成績分析載入失敗:$ERROR$", + "placeholders": { + "error": { + "content": "$ERROR$", + "example": "ERROR" + } + } }, "grade_analytics_info_label": { "message": "成績分析資訊" @@ -864,7 +968,29 @@ "message": " (包含 GPA 計算器)" }, "grid_warning": { - "message": "你的格線可容納 $TOTAL$ 張卡片$TOTAL_S$,但你目前有 $ACTIVE$ 張卡片$ACTIVE_S$$GPA_NOTE$——部分卡片可能會被裁切。" + "message": "你的格線可容納 $TOTAL$ 張卡片$TOTAL_S$,但你目前有 $ACTIVE$ 張卡片$ACTIVE_S$$GPA_NOTE$——部分卡片可能會被裁切。", + "placeholders": { + "gpa_note": { + "content": "$GPA_NOTE$", + "example": "GPA_NOTE" + }, + "active_s": { + "content": "$ACTIVE_S$", + "example": "ACTIVE_S" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "active": { + "content": "$ACTIVE$", + "example": "ACTIVE" + }, + "total_s": { + "content": "$TOTAL_S$", + "example": "TOTAL_S" + } + } }, "group_graded": { "message": "已評分" @@ -1023,16 +1149,34 @@ "message": "NASA 每日天文圖片" }, "nasa_credit": { - "message": "版權:$CREDIT$" + "message": "版權:$CREDIT$", + "placeholders": { + "credit": { + "content": "$CREDIT$", + "example": "CREDIT" + } + } }, "nasa_date": { - "message": "日期:$DATE$" + "message": "日期:$DATE$", + "placeholders": { + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "need_refresh": { "message": "你可能需要重新整理頁面才能看到某些變更。" }, "new_canvas_desc": { - "message": "Canvas Refined 在 $HOST$ 偵測到 Canvas 頁面。要將它加入你的 Canvas 清單嗎?" + "message": "Canvas Refined 在 $HOST$ 偵測到 Canvas 頁面。要將它加入你的 Canvas 清單嗎?", + "placeholders": { + "host": { + "content": "$HOST$", + "example": "HOST" + } + } }, "new_canvas_detected": { "message": "偵測到新的 Canvas" @@ -1143,7 +1287,13 @@ "message": "點擊右上角的拼圖圖示" }, "options_contact": { - "message": "如果你有任何問題或建議,我的電子郵件是 $EMAIL$,歡迎回饋!" + "message": "如果你有任何問題或建議,我的電子郵件是 $EMAIL$,歡迎回饋!", + "placeholders": { + "email": { + "content": "$EMAIL$", + "example": "EMAIL" + } + } }, "options_how_to_access": { "message": "之後如何開啟此選單:" @@ -1233,7 +1383,13 @@ "message": "西瓜" }, "percent_done": { - "message": "$PERCENT$%" + "message": "$PERCENT$%", + "placeholders": { + "percent": { + "content": "$PERCENT$", + "example": "PERCENT" + } + } }, "personal_task": { "message": "個人任務" @@ -1290,13 +1446,51 @@ "message": "隱私" }, "progress_done": { - "message": "已完成 $DONE$/$TOTAL$" + "message": "已完成 $DONE$/$TOTAL$", + "placeholders": { + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_overall": { - "message": "$PCT$%($DONE$/$TOTAL$)" + "message": "$PCT$%($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "progress_pct": { - "message": "$PCT$%($DONE$/$TOTAL$)" + "message": "$PCT$%($DONE$/$TOTAL$)", + "placeholders": { + "pct": { + "content": "$PCT$", + "example": "PCT" + }, + "total": { + "content": "$TOTAL$", + "example": "TOTAL" + }, + "done": { + "content": "$DONE$", + "example": "DONE" + } + } }, "quiz_dont_show": { "message": "不再顯示" @@ -1344,13 +1538,25 @@ "message": "正在讀取成績資料…" }, "relative_ago": { - "message": "$TIME$前" + "message": "$TIME$前", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "relative_due_dates": { "message": "相对到期日" }, "relative_in": { - "message": "$TIME$後" + "message": "$TIME$後", + "placeholders": { + "time": { + "content": "$TIME$", + "example": "TIME" + } + } }, "remlogo": { "message": "删除侧边栏徽标" @@ -1425,16 +1631,34 @@ "message": "新分頁" }, "search_no_course": { - "message": "沒有符合「$QUERY$」的課程。" + "message": "沒有符合「$QUERY$」的課程。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_courses_grades": { "message": "找不到可開啟成績的課程。" }, "search_no_match": { - "message": "找不到「$QUERY$」的結果。" + "message": "找不到「$QUERY$」的結果。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_match_hint": { - "message": "找不到「$QUERY$」的結果。請嘗試其他關鍵字。" + "message": "找不到「$QUERY$」的結果。請嘗試其他關鍵字。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_no_modules": { "message": "找不到模組或作業..." @@ -1443,7 +1667,13 @@ "message": "找不到課程模組或作業。如果你的課程仍在載入,請稍後再開啟搜尋。" }, "search_no_results": { - "message": "找不到「$QUERY$」的結果。" + "message": "找不到「$QUERY$」的結果。", + "placeholders": { + "query": { + "content": "$QUERY$", + "example": "QUERY" + } + } }, "search_open": { "message": "開啟" @@ -1488,7 +1718,13 @@ "message": "章節" }, "selected_count": { - "message": "已選取 $COUNT$ 項" + "message": "已選取 $COUNT$ 項", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "show": { "message": "顯示" @@ -1533,7 +1769,13 @@ "message": "空白" }, "storage_items": { - "message": " ($COUNT$ 項)" + "message": " ($COUNT$ 項)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "storage_limit_error": { "message": "你輸入的資料超過儲存上限,因此無法儲存。請嘗試使用較短的連結,並確認按下「複製圖片網址」而不是「複製圖片」來取得連結。" @@ -1620,7 +1862,13 @@ "message": "請確認你的主題符合以下規範:" }, "theme_number": { - "message": "主題 $NUM$" + "message": "主題 $NUM$", + "placeholders": { + "num": { + "content": "$NUM$", + "example": "NUM" + } + } }, "theme_optin_reset": { "message": "已重設主題瀏覽器加入狀態" @@ -1725,7 +1973,21 @@ "message": "劃掉" }, "todo_date_format": { - "message": "$DATE$ $TIME$($RELATIVE$)" + "message": "$DATE$ $TIME$($RELATIVE$)", + "placeholders": { + "relative": { + "content": "$RELATIVE$", + "example": "RELATIVE" + }, + "time": { + "content": "$TIME$", + "example": "TIME" + }, + "date": { + "content": "$DATE$", + "example": "DATE" + } + } }, "todo_delete": { "message": "刪除" @@ -1863,7 +2125,13 @@ "message": "顯示更多" }, "view_more_count": { - "message": "顯示更多($COUNT$)" + "message": "顯示更多($COUNT$)", + "placeholders": { + "count": { + "content": "$COUNT$", + "example": "COUNT" + } + } }, "view_on_github": { "message": "在 GitHub 上檢視" @@ -1891,5 +2159,8 @@ }, "widgets": { "message": "小工具" + }, + "gpa_show_on_hover": { + "message": "Show on hover" } } diff --git a/css/content.css b/css/content.css index b18e5be..da7e982 100644 --- a/css/content.css +++ b/css/content.css @@ -132,6 +132,21 @@ .canvasrefined-gpa-card p {margin: 0;} #cumulative-gpa .canvasrefined-gpa-name {font-weight:bold;} #canvasrefined-gpa-unweighted, #canvasrefined-gpa-weighted, #canvasrefined-gpa-cumulative {font-size: 24px; font-weight: bold;margin-top: 10px} +.canvasrefined-gpa-card.gpa-show-on-hover #canvasrefined-gpa-unweighted, +.canvasrefined-gpa-card.gpa-show-on-hover #canvasrefined-gpa-weighted, +.canvasrefined-gpa-card.gpa-show-on-hover #canvasrefined-gpa-cumulative { + filter: blur(8px); + transition: filter 0.2s ease; + user-select: none; +} +.canvasrefined-gpa-card.gpa-show-on-hover:hover #canvasrefined-gpa-unweighted, +.canvasrefined-gpa-card.gpa-show-on-hover:hover #canvasrefined-gpa-weighted, +.canvasrefined-gpa-card.gpa-show-on-hover:hover #canvasrefined-gpa-cumulative, +.canvasrefined-gpa-card.gpa-show-on-hover:focus-within #canvasrefined-gpa-unweighted, +.canvasrefined-gpa-card.gpa-show-on-hover:focus-within #canvasrefined-gpa-weighted, +.canvasrefined-gpa-card.gpa-show-on-hover:focus-within #canvasrefined-gpa-cumulative { + filter: blur(0); +} .canvasrefined-gpa-edit-btn {background: #f5f5f5; border: 1px solid #c7cdd1; border-radius:6px; width: 100%; padding: 5px 0px; color: #000;margin-top: 10px} .canvasrefined-due-soon {background: #db3754; padding: 1px 4px; color: #fff; border-radius: 4px;display:inline-block} .canvasrefined-assignment-overdue { background: #db3754!important;color:#fff!important;} @@ -619,6 +634,59 @@ .cr-quote-text {margin:0;font-size:clamp(14px,7.5cqw,26px);line-height:1.45;font-style:italic;color:var(--bctext-0,#2d3b45);} .cr-quote-author {font-size:clamp(11px,3.6cqw,17px);font-weight:600;color:var(--bctext-2,#9aa3ab);align-self:flex-end;} +/* Quick Links: editable link grid with theme-tinted preset icons */ +.canvasrefined-quick-links .cr-widget-head {gap:8px;} +.cr-ql-edit-toggle {display:flex;align-items:center;justify-content:center;width:28px;height:28px;flex:none;padding:0;border:none;border-radius:7px;background:transparent;color:var(--bctext-2,#9aa3ab);cursor:pointer;} +.cr-ql-edit-toggle:hover {background:color-mix(in srgb, var(--bctext-0,#2d3b45) 10%, transparent);color:var(--bctext-0,#2d3b45) !important;} +.cr-ql-edit-toggle.is-editing {background:color-mix(in srgb, var(--bclinks,#0374b5) 14%, transparent);color:var(--bclinks,#0374b5) !important;} +.cr-ql-edit-toggle svg {width:16px;height:16px;display:block;} +.cr-ql-body {display:flex;flex-direction:column;flex:1;min-height:0;padding:12px;overflow-y:auto;} +.cr-ql-body.is-editing {padding-top:10px;} +.cr-ql-grid {display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:8px;align-content:start;} +.canvasrefined-quick-links.container-mode .cr-ql-grid {grid-template-columns:repeat(auto-fill,minmax(112px,1fr));} +.cr-ql-tile {position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;min-height:84px;padding:11px 8px;box-sizing:border-box;border:1px solid var(--bcborders,#c7cdd1);border-radius:10px;background:transparent;color:var(--bctext-0,#2d3b45);text-decoration:none;font:inherit;cursor:pointer;transition:border-color .15s, background .15s, transform .1s;} +.cr-ql-tile:hover {border-color:var(--bclinks,#0374b5);background:color-mix(in srgb, var(--bclinks,#0374b5) 8%, transparent);} +.cr-ql-tile:active {transform:scale(.97);} +.cr-ql-tile:focus-visible {outline:2px solid var(--bclinks,#0374b5);outline-offset:2px;} +.cr-ql-tile.is-editing {cursor:pointer;} +.cr-ql-icon {display:flex;align-items:center;justify-content:center;width:36px;height:36px;flex:none;border-radius:10px;overflow:hidden;background:color-mix(in srgb, var(--bclinks,#0374b5) 12%, transparent);color:var(--bclinks,#0374b5);} +.cr-ql-icon svg {width:21px;height:21px;display:block;} +.cr-ql-icon img {width:100%;height:100%;object-fit:contain;display:block;} +.cr-ql-icon-letter {display:none;font-size:16px;font-weight:800;line-height:1;color:var(--bclinks,#0374b5);} +.cr-ql-tile.cr-ql-img-broken .cr-ql-icon img, +.cr-ql-tile.cr-ql-img-broken .cr-ql-icon svg {display:none;} +.cr-ql-tile.cr-ql-img-broken .cr-ql-icon-letter {display:block;} +.cr-ql-label {display:-webkit-box;max-width:100%;overflow:hidden;font-size:12px;font-weight:600;line-height:1.25;text-align:center;word-break:break-word;-webkit-line-clamp:2;-webkit-box-orient:vertical;} +.cr-ql-tile-delete {position:absolute;top:4px;right:4px;width:20px;height:20px;display:flex;align-items:center;justify-content:center;padding:0;border:none;border-radius:6px;background:transparent;color:var(--bctext-2,#9aa3ab);font-size:14px;line-height:1;cursor:pointer;} +.cr-ql-tile-delete:hover {background:color-mix(in srgb, #e5484d 18%, transparent);color:#e5484d !important;} +.cr-ql-add {border-style:dashed;color:var(--bctext-2,#9aa3ab);} +.cr-ql-add:hover {color:var(--bclinks,#0374b5) !important;} +.cr-ql-add-plus {display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:10px;background:color-mix(in srgb, var(--bctext-0,#2d3b45) 7%, transparent);font-size:22px;font-weight:400;line-height:1;} +.cr-ql-empty {display:flex;flex:1;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:14px 6px;text-align:center;color:var(--bctext-2,#9aa3ab);font-size:12px;} +.cr-ql-empty .cr-widget-btn {flex:none;} +.cr-ql-hint {margin:0 0 8px;color:var(--bctext-2,#9aa3ab);font-size:11px;} +.cr-ql-editor {display:flex;flex-direction:column;gap:9px;} +.cr-ql-editor-title {color:var(--bctext-0,#2d3b45);font-size:12px;font-weight:700;} +.cr-ql-field {display:flex;flex-direction:column;gap:4px;color:var(--bctext-2,#9aa3ab);font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;} +.cr-ql-input {box-sizing:border-box;width:100%;height:32px;padding:0 9px;border:1px solid var(--bcborders,#c7cdd1);border-radius:8px;background:color-mix(in srgb, var(--bctext-0,#2d3b45) 4%, transparent);color:var(--bctext-0,#2d3b45);font:inherit;font-size:12.5px;font-weight:500;letter-spacing:normal;text-transform:none;} +.cr-ql-input:focus {outline:none;border-color:var(--bclinks,#0374b5) !important;box-shadow:0 0 0 2px color-mix(in srgb, var(--bclinks,#0374b5) 22%, transparent);} +.cr-ql-input::placeholder {color:var(--bctext-2,#9aa3ab);opacity:.75;} +.cr-ql-icon-picker {display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px;} +.cr-ql-icon-choice {display:flex;align-items:center;justify-content:center;height:36px;padding:0;border:1px solid var(--bcborders,#c7cdd1);border-radius:8px;background:transparent;color:var(--bctext-2,#9aa3ab);cursor:pointer;} +.cr-ql-icon-choice:hover {border-color:var(--bctext-2,#9aa3ab);color:var(--bctext-0,#2d3b45) !important;} +.cr-ql-icon-choice.is-active {border-color:var(--bclinks,#0374b5);background:color-mix(in srgb, var(--bclinks,#0374b5) 14%, transparent);color:var(--bclinks,#0374b5) !important;} +.cr-ql-icon-choice svg {width:18px;height:18px;display:block;} +.cr-ql-custom-row {display:flex;align-items:center;gap:7px;} +.cr-ql-custom-preview {display:flex;align-items:center;justify-content:center;width:32px;height:32px;flex:none;overflow:hidden;border:1px dashed var(--bcborders,#c7cdd1);border-radius:8px;color:var(--bctext-2,#9aa3ab);} +.cr-ql-custom-preview svg {width:16px;height:16px;} +.cr-ql-custom-preview img {width:100%;height:100%;object-fit:contain;} +.cr-ql-error {margin:0;color:#e5484d;font-size:11px;line-height:1.35;} +.cr-ql-error[hidden] {display:none;} +.cr-ql-editor-actions {display:flex;gap:8px;margin-top:2px;} +.cr-ql-editor-actions .cr-widget-btn {padding:7px 10px;font-size:12.5px;} +.cr-ql-delete-link {align-self:flex-start;padding:4px 0;border:none;background:transparent;color:#e5484d !important;font:inherit;font-size:11.5px;font-weight:600;cursor:pointer;} +.cr-ql-delete-link:hover {text-decoration:underline;} + /* Canvas' SpeedGrader/document preview container: give the preview 80% of its parent instead of Canvas' default height. */ #doc_preview { diff --git a/html/popup.html b/html/popup.html index f66712b..3baf2f7 100644 --- a/html/popup.html +++ b/html/popup.html @@ -34,7 +34,7 @@
@@ -1214,6 +1214,10 @@
+
+ + +
@@ -1348,6 +1352,32 @@
+
+ +
+
+ + +
+
+ + + px +
+
+
diff --git a/js/background.js b/js/background.js index 91a2cea..a719eb1 100644 --- a/js/background.js +++ b/js/background.js @@ -54,12 +54,15 @@ chrome.runtime.onInstalled.addListener(function () { "breathing_preset_3": { "h": 0, "m": 10, "s": 0 }, "daily_quotes": false, "daily_quotes_position": "top", + "quick_links": false, + "quick_links_position": "cards_end", "widget_row_height": 0, "dashboard_notes_height": 0, "gpa_calc_height": 0, "focus_timer_height": 0, "breathing_height": 0, "daily_quotes_height": 0, + "quick_links_height": 0, "better_todo": true, "todo_hr24": false, "todo_separate_scrollbar": false, @@ -127,6 +130,7 @@ chrome.runtime.onInstalled.addListener(function () { "new_browser": null, "gpa_calc_cumulative": false, "gpa_calc_weighted": true, + "gpa_calc_show_on_hover": false, "browser_show_likes": false, "custom_styles": "", "imageSize": 100, diff --git a/js/content.js b/js/content.js index 8c7b53f..abd0b85 100644 --- a/js/content.js +++ b/js/content.js @@ -1087,6 +1087,14 @@ function applyOptionsChanges(changes) { case "daily_quotes_height": loadDailyQuotesWidget(); break; + case "quick_links": + case "quick_links_position": + case "quick_links_height": + loadQuickLinksWidget(); + break; + case "quick_links_items": + updateQuickLinksWidget(); + break; case "daily_quote": document.querySelectorAll(".canvasrefined-quotes").forEach(el => { renderDailyQuote(el, changes["daily_quote"].newValue); @@ -1218,8 +1226,10 @@ function applyOptionsChanges(changes) { case "gpa_calc_height": case "gpa_calc_weighted": case "gpa_calc_cumulative": + case "gpa_calc_show_on_hover": if (!grades) getGrades(); setupGPACalc(); + updateGpaHoverBlur(); // GPA elements take part in the grid layout, so regenerate the grid CSS. if (options.card_grid === true) debouncedApplyAestheticChanges(); break; @@ -5996,6 +6006,36 @@ const BC_LIGHT_DEFAULTS = { "text-2": "#4f4f4f" }; +const BC_DARK_DEFAULTS = { + "background-0": "#161616", + "background-1": "#1e1e1e", + "background-2": "#262626", + "borders": "#3c3c3c", + "text-0": "#f5f5f5", + "text-1": "#e2e2e2", + "text-2": "#ababab", + "links": "#56Caf0", + "sidebar": "#1e1e1e", + "sidebar-text": "#f5f5f5" +}; + +function generateWidgetDarkCSS() { + const preset = options.dark_preset || BC_DARK_DEFAULTS; + let css = "/* CanvasRefined widgets always use dark mode colors */\n"; + css += ".canvasrefined-widget-card,\n"; + css += ".canvasrefined-dashboard-notes,\n"; + css += ".canvasrefined-gpa-card,\n"; + css += ".canvasrefined-gpa,\n"; + css += "#canvasrefined-gpa-modal,\n"; + css += ".cr-gpa-modal,\n"; + css += ".canvasrefined-widget-slot {\n"; + Object.keys(preset).forEach((key) => { + css += " --bc" + key + ": " + preset[key] + ";\n"; + }); + css += "}\n"; + return css; +} + function generateDarkModeCSS() { let css = ":root{\n"; Object.keys(BC_LIGHT_DEFAULTS).forEach((key) => { @@ -6003,6 +6043,8 @@ function generateDarkModeCSS() { }); css += "}\n\n"; + css += generateWidgetDarkCSS() + "\n"; + const darkOn = options.dark_mode === true || options.device_dark === true; if (!darkOn) return css; @@ -7181,9 +7223,9 @@ function placeGPAElements(dashboardContainer, container, container2) { } } -const CR_WIDGET_IDS = ["dashboard_notes", "gpa_calc", "focus_timer", "breathing", "daily_quotes"]; +const CR_WIDGET_IDS = ["dashboard_notes", "gpa_calc", "focus_timer", "breathing", "daily_quotes", "quick_links"]; // Widgets rendered by the generic loader: one root element, no GPA-style pair. -const CR_SIMPLE_WIDGET_IDS = ["focus_timer", "breathing", "daily_quotes"]; +const CR_SIMPLE_WIDGET_IDS = ["focus_timer", "breathing", "daily_quotes", "quick_links"]; function isCRWidget(id) { return CR_WIDGET_IDS.indexOf(id) !== -1; } // Shared full-width row (top/below): slot width is the % from the Widgets tab. @@ -7507,6 +7549,12 @@ function openGpaModal(dashboardContainer, container, container2) { modal.addEventListener("mousedown", (e) => { if (e.target === modal) close(); }); } +function updateGpaHoverBlur() { + const card = document.querySelector(".canvasrefined-gpa-card"); + if (!card) return; + card.classList.toggle("gpa-show-on-hover", options.gpa_calc_show_on_hover === true); +} + // Bounded retry while Canvas renders the container, instead of waiting for the observer. let gpaSetupRetryTimer = null; let gpaSetupAttempts = 0; @@ -7563,6 +7611,7 @@ function setupGPACalc() { } placeGPAElements(dashboardContainer, container, container2); + updateGpaHoverBlur(); try { if (sortableContainer && window.jQuery && window.jQuery.fn && window.jQuery.fn.sortable) { @@ -7940,6 +7989,7 @@ const CR_WIDGET_DEFAULT_POSITION = { focus_timer: "cards_end", breathing: "cards_end", daily_quotes: "top", + quick_links: "cards_end", }; function crWidgetPosition(id) { @@ -8406,6 +8456,405 @@ function loadAllSimpleWidgets() { loadFocusTimer(); loadBreathingWidget(); loadDailyQuotesWidget(); + loadQuickLinksWidget(); +} + +/* ---- Quick Links (editable links with theme-aware preset icons) ---- */ + +const QUICK_LINK_ICONS = { + link: ``, + home: ``, + book: ``, + calendar: ``, + mail: ``, + video: ``, + code: ``, + chart: ``, + chat: ``, + star: ``, +}; +const QUICK_LINK_ICON_KEYS = Object.keys(QUICK_LINK_ICONS); +const QUICK_LINK_ICON_LABELS = { + link: "Link", home: "Home", book: "Book", calendar: "Calendar", mail: "Mail", + video: "Video", code: "Code", chart: "Chart", chat: "Chat", star: "Star", +}; + +const quickLinksUI = { editing: false, mode: null, id: null, error: "" }; + +function crEscapeHtml(value) { + return String(value == null ? "" : value) + .replace(/&/g, "&").replace(//g, ">") + .replace(/"/g, """).replace(/'/g, "'"); +} + +// Blocks script-ish schemes; plain "example.com" becomes https, bare paths stay Canvas-relative. +function quickLinksSafeUrl(value, isImage) { + const raw = String(value == null ? "" : value).trim(); + if (!raw) return ""; + if (isImage) { + if (/^data:image\/(?:png|jpe?g|gif|webp|svg\+xml);/i.test(raw)) return raw.length <= 4000 ? raw : ""; + if (/^https?:\/\//i.test(raw)) return raw; + if (/^\/\//.test(raw)) return "https:" + raw; + if (/^[a-z][a-z0-9+.-]*:/i.test(raw)) return ""; + if (/^[\w-]+(?:\.[\w-]+)+(?::\d+)?(?=[/?#]|$)/.test(raw)) return "https://" + raw; + return ""; + } + if (/^\/\//.test(raw)) return "https:" + raw; + if (/^(?:\/|#|\?)/.test(raw)) return raw; + if (/^(?:https?:|mailto:|tel:)/i.test(raw)) return raw; + if (/^(?:javascript:|vbscript:|file:|data:|blob:)/i.test(raw)) return ""; + if (/^[a-z][a-z0-9+.-]*:/i.test(raw)) return ""; + if (/^[\w-]+(?:\.[\w-]+)+(?::\d+)?(?=[/?#]|$)/.test(raw)) return "https://" + raw; + return "/" + raw.replace(/^\.?\/+/, ""); +} + +function quickLinksLabelFromUrl(url) { + try { + const parsed = new URL(url, window.location.origin); + if (parsed.hostname && parsed.hostname !== window.location.hostname) { + return parsed.hostname.replace(/^www\./i, ""); + } + const part = parsed.pathname.split("/").filter(Boolean).pop(); + if (part) return decodeURIComponent(part).replace(/[-_]+/g, " "); + return parsed.hostname || url; + } catch (e) { + return url; + } +} + +function quickLinksSanitizeItem(raw, index) { + if (!raw || typeof raw !== "object") return null; + const url = quickLinksSafeUrl(raw.url, false); + if (!url) return null; + let image = raw.icon === "image" ? quickLinksSafeUrl(raw.image, true) : ""; + const icon = image ? "image" : (QUICK_LINK_ICONS[raw.icon] ? raw.icon : "link"); + let label = typeof raw.label === "string" ? raw.label.trim().slice(0, 60) : ""; + if (!label) label = quickLinksLabelFromUrl(url).slice(0, 60); + return { + id: typeof raw.id === "string" && raw.id ? raw.id : "ql_legacy_" + index, + label: label, + url: url, + icon: icon, + image: icon === "image" ? image : "", + }; +} + +function quickLinksItems() { + const raw = options.quick_links_items; + if (!Array.isArray(raw)) return []; + return raw.map(quickLinksSanitizeItem).filter(Boolean); +} + +function quickLinksIconMarkup(item) { + const image = item.icon === "image" ? quickLinksSafeUrl(item.image, true) : ""; + if (image) return ``; + return QUICK_LINK_ICONS[item.icon] || QUICK_LINK_ICONS.link; +} + +function quickLinksTileHtml(item, editing) { + const label = crEscapeHtml(item.label || quickLinksLabelFromUrl(item.url)); + const letter = crEscapeHtml((item.label || quickLinksLabelFromUrl(item.url) || "?").trim().charAt(0).toUpperCase() || "?"); + const icon = `${quickLinksIconMarkup(item)}`; + if (editing) { + return `
+ ${icon}${label} + +
`; + } + return ` + ${icon}${label} + `; +} + +function quickLinksGridHtml(items, editing) { + const tiles = items.map(item => quickLinksTileHtml(item, editing)).join(""); + const error = quickLinksUI.error + ? `

${crEscapeHtml(quickLinksUI.error)}

` + : ""; + if (editing) { + return `
${getMsg("quick_links_hint_edit", "Click a link to edit it.")}
+ ${error}
${tiles} + +
`; + } + if (!items.length) { + return `
+ ${getMsg("quick_links_empty", "No links yet.")} + +
`; + } + return `
${tiles}
`; +} + +function quickLinksEditorHtml(item) { + const isEdit = quickLinksUI.mode === "edit"; + const icon = item && item.icon !== "image" ? item.icon : "link"; + const image = item && item.icon === "image" ? item.image : ""; + const picks = QUICK_LINK_ICON_KEYS.map(key => ` + `).join(""); + const preview = image + ? `` + : QUICK_LINK_ICONS[icon] || QUICK_LINK_ICONS.link; + return `
+
${isEdit ? getMsg("quick_links_edit_title", "Edit link") : getMsg("quick_links_add_title", "New link")}
+ + +
${getMsg("quick_links_icon", "Icon")} +
${picks}
+
+ +

${crEscapeHtml(quickLinksUI.error)}

+
+ + +
+ ${isEdit ? `` : ""} +
`; +} + +function renderQuickLinks(el) { + if (!el) return; + const body = el.querySelector(".cr-ql-body"); + const toggle = el.querySelector(".cr-ql-edit-toggle"); + if (!body) return; + body.classList.toggle("is-editing", quickLinksUI.editing); + if (quickLinksUI.mode) { + const items = quickLinksItems(); + const item = quickLinksUI.mode === "edit" ? items.find(i => i.id === quickLinksUI.id) : null; + body.innerHTML = quickLinksEditorHtml(item); + } else { + body.innerHTML = quickLinksGridHtml(quickLinksItems(), quickLinksUI.editing); + } + if (toggle) { + const done = quickLinksUI.editing; + toggle.classList.toggle("is-editing", done); + toggle.title = done ? getMsg("quick_links_done", "Done") : getMsg("quick_links_edit", "Edit links"); + toggle.setAttribute("aria-label", toggle.title); + toggle.innerHTML = done + ? `` + : ``; + } +} + +function quickLinksCloseEditor(keepEditing) { + quickLinksUI.editing = keepEditing === true; + quickLinksUI.mode = null; + quickLinksUI.id = null; + quickLinksUI.error = ""; +} + +function quickLinksPersist(items, el) { + // Drop our bookkeeping fields and keep only serializable link data. + const payload = items.map(item => ({ + id: item.id, + label: item.label, + url: item.url, + icon: item.icon, + image: item.icon === "image" ? item.image : "", + })); + const previous = options.quick_links_items; + options = { ...options, quick_links_items: payload }; + renderQuickLinks(el); + chrome.storage.sync.set({ quick_links_items: payload }, () => { + if (chrome.runtime.lastError) { + options = { ...options, quick_links_items: previous }; + quickLinksUI.editing = true; + quickLinksUI.error = getMsg("quick_links_store_error", "Couldn't save your links. Try shorter URLs."); + renderQuickLinks(el); + } + }); +} + +function quickLinksShowError(el, message, focusSelector) { + quickLinksUI.error = message; + const errorEl = el.querySelector(".cr-ql-error"); + if (errorEl) { + errorEl.hidden = false; + errorEl.textContent = message; + } + if (focusSelector) { + const field = el.querySelector(focusSelector); + if (field) field.focus(); + } +} + +function quickLinksSaveEditor(el) { + const labelEl = el.querySelector(".cr-ql-label-input"); + const urlEl = el.querySelector(".cr-ql-url-input"); + const imageEl = el.querySelector(".cr-ql-image-input"); + const active = el.querySelector(".cr-ql-icon-choice.is-active"); + const rawUrl = urlEl ? urlEl.value.trim() : ""; + const rawImage = imageEl ? imageEl.value.trim() : ""; + const url = quickLinksSafeUrl(rawUrl, false); + const image = rawImage ? quickLinksSafeUrl(rawImage, true) : ""; + if (!url) { + quickLinksShowError(el, getMsg("quick_links_url_error", "Enter a valid URL."), ".cr-ql-url-input"); + return; + } + if (rawImage && !image) { + quickLinksShowError(el, getMsg("quick_links_image_error", "Enter a valid image URL."), ".cr-ql-image-input"); + return; + } + const items = quickLinksItems(); + let label = labelEl ? labelEl.value.trim().slice(0, 60) : ""; + if (!label) label = quickLinksLabelFromUrl(url).slice(0, 60); + const icon = image ? "image" : ((active && active.dataset.icon) || "link"); + if (quickLinksUI.mode === "edit") { + const index = items.findIndex(item => item.id === quickLinksUI.id); + if (index !== -1) items[index] = { ...items[index], label, url, icon, image }; + else items.push({ id: "ql_" + Date.now().toString(36), label, url, icon, image }); + } else { + items.push({ id: "ql_" + Date.now().toString(36) + Math.random().toString(36).slice(2, 6), label, url, icon, image }); + } + quickLinksCloseEditor(true); + quickLinksPersist(items, el); +} + +function quickLinksOpenEditor(el, mode, id) { + quickLinksUI.editing = true; + quickLinksUI.mode = mode; + quickLinksUI.id = id || null; + quickLinksUI.error = ""; + renderQuickLinks(el); + const label = el.querySelector(".cr-ql-label-input"); + if (label) label.focus(); +} + +function quickLinksDelete(el, id) { + if (!id) return; + if (!window.confirm(getMsg("quick_links_delete_confirm", "Delete this link?"))) return; + const items = quickLinksItems().filter(item => item.id !== id); + quickLinksCloseEditor(true); + quickLinksPersist(items, el); +} + +function wireQuickLinks(el) { + el.addEventListener("click", e => { + const toggle = e.target.closest(".cr-ql-edit-toggle"); + if (toggle) { + if (quickLinksUI.editing) quickLinksCloseEditor(false); + else quickLinksUI.editing = true; + renderQuickLinks(el); + return; + } + const actionEl = e.target.closest("[data-ql-action]"); + if (!actionEl) return; + const action = actionEl.dataset.qlAction; + if (action === "add") { + e.preventDefault(); + quickLinksOpenEditor(el, "add", null); + } else if (action === "edit") { + e.preventDefault(); + quickLinksOpenEditor(el, "edit", actionEl.dataset.qlId); + } else if (action === "delete") { + e.preventDefault(); + quickLinksDelete(el, actionEl.dataset.qlId); + } else if (action === "save") { + e.preventDefault(); + quickLinksSaveEditor(el); + } else if (action === "cancel") { + e.preventDefault(); + quickLinksCloseEditor(true); + renderQuickLinks(el); + } else if (action === "icon") { + e.preventDefault(); + el.querySelectorAll(".cr-ql-icon-choice.is-active").forEach(btn => btn.classList.remove("is-active")); + actionEl.classList.add("is-active"); + const imageEl = el.querySelector(".cr-ql-image-input"); + if (imageEl) imageEl.value = ""; + const preview = el.querySelector(".cr-ql-custom-preview"); + if (preview) preview.innerHTML = QUICK_LINK_ICONS[actionEl.dataset.icon] || QUICK_LINK_ICONS.link; + } + }); + + el.addEventListener("input", e => { + const target = e.target; + if (target.classList.contains("cr-ql-image-input")) { + el.querySelectorAll(".cr-ql-icon-choice.is-active").forEach(btn => btn.classList.remove("is-active")); + const preview = el.querySelector(".cr-ql-custom-preview"); + const image = quickLinksSafeUrl(target.value.trim(), true); + if (preview) preview.innerHTML = image + ? `` + : QUICK_LINK_ICONS.link; + } + if (quickLinksUI.error) { + quickLinksUI.error = ""; + const errorEl = el.querySelector(".cr-ql-error"); + if (errorEl) { errorEl.hidden = true; errorEl.textContent = ""; } + } + }); + + el.addEventListener("keydown", e => { + if (!el.querySelector(".cr-ql-editor")) { + if ((e.key === "Enter" || e.key === " ") && e.target.matches && e.target.matches("[data-ql-action='edit']")) { + e.preventDefault(); + e.target.click(); + } + return; + } + if (e.key === "Escape") { + e.preventDefault(); + quickLinksCloseEditor(true); + renderQuickLinks(el); + } else if (e.key === "Enter" && e.target.matches && e.target.matches(".cr-ql-input")) { + e.preventDefault(); + quickLinksSaveEditor(el); + } + }); + + // Custom image URLs can 404; reveal the label initial instead of a broken icon. + el.addEventListener("error", e => { + const img = e.target; + if (!img || img.tagName !== "IMG") return; + if (img.closest(".cr-ql-icon")) { + const tile = img.closest(".cr-ql-tile"); + if (tile) tile.classList.add("cr-ql-img-broken"); + } else if (img.closest(".cr-ql-custom-preview")) { + img.parentNode.innerHTML = QUICK_LINK_ICONS.link; + } + }, true); + + renderQuickLinks(el); +} + +function quickLinksHtml() { return ` +
+ ${getMsg("quick_links", "Quick Links")} + +
+
+`; } + +function updateQuickLinksWidget() { + const el = document.querySelector(".canvasrefined-quick-links"); + if (!el) return; + // Don't rebuild while the user is typing in the editor (e.g. our own storage echo). + if (quickLinksUI.mode && el.querySelector(".cr-ql-editor")) return; + renderQuickLinks(el); +} + +function loadQuickLinksWidget() { + if (options.quick_links !== true) quickLinksCloseEditor(false); + crLoadWidget("quick_links", { + className: "canvasrefined-quick-links", + html: quickLinksHtml(), + wire: wireQuickLinks, + update: updateQuickLinksWidget, + }); } diff --git a/js/popup.js b/js/popup.js index 24d70c2..62fbe01 100644 --- a/js/popup.js +++ b/js/popup.js @@ -1,4 +1,4 @@ -const syncedSwitches = ['remind', 'tab_icons', 'dark_mode', 'remlogo', 'full_width', 'auto_dark', 'assignments_due', 'gpa_calc', 'gradient_cards', 'disable_color_overlay', 'dashboard_grades', 'dashboard_notes', 'focus_timer', 'breathing', 'daily_quotes', 'better_todo', 'todo_celebrations_enabled', 'better_sidebar', 'condensed_cards', 'hide_new_canvas', 'hide_sequence_footer', 'center_cards', 'quiz_safe_mode', 'global_search', 'grade_analytics', 'hide_personal_details']; +const syncedSwitches = ['remind', 'tab_icons', 'dark_mode', 'remlogo', 'full_width', 'auto_dark', 'assignments_due', 'gpa_calc', 'gradient_cards', 'disable_color_overlay', 'dashboard_grades', 'dashboard_notes', 'focus_timer', 'breathing', 'daily_quotes', 'quick_links', 'better_todo', 'todo_celebrations_enabled', 'better_sidebar', 'condensed_cards', 'hide_new_canvas', 'hide_sequence_footer', 'center_cards', 'quiz_safe_mode', 'global_search', 'grade_analytics', 'hide_personal_details']; const syncedSubOptions = [ "grade_analytics_zones", "hide_course_images", @@ -19,6 +19,7 @@ const syncedSubOptions = [ "gpa_calc_prepend", "gpa_calc_cumulative", "gpa_calc_weighted", + "gpa_calc_show_on_hover", "focus_timer_position", "focus_timer_preset_1", "focus_timer_preset_2", @@ -28,12 +29,14 @@ const syncedSubOptions = [ "breathing_preset_2", "breathing_preset_3", "daily_quotes_position", + "quick_links_position", "widget_row_height", "dashboard_notes_height", "gpa_calc_height", "focus_timer_height", "breathing_height", "daily_quotes_height", + "quick_links_height", "auto_dark", "auto_dark_start", "auto_dark_end", @@ -189,7 +192,7 @@ const exportCardStyles = ["customCardStyles", "imageSize", "cardRoundness", "ima const exportLayout = ["full_width", "center_cards", "condensed_cards", "equal_height_cards", "remlogo", "hide_new_canvas", "hide_navbar", "tab_icons"]; const exportSidebar = ["better_sidebar", "sidebar_scale"]; const exportTodo = ["better_todo", "todo_hide_feedback", "todo_hide_read", "todo_full_height", "todo_celebrations_enabled", "todo_celebrations", "todo_celebration_amount", "todo_progress_rings", "todo_timeframe", "todo_timeframe_custom_past", "todo_timeframe_custom_future", "todo_hr24", "todo_separate_scrollbar", "todo_alternate_colors", "todo_ignore_card_colors", "todo_remove_icons", "todo_show_scores", "hover_preview"]; -const exportGpa = ["gpa_calc", "gpa_calc_prepend", "gpa_calc_cumulative", "gpa_calc_weighted"]; +const exportGpa = ["gpa_calc", "gpa_calc_prepend", "gpa_calc_cumulative", "gpa_calc_weighted", "gpa_calc_show_on_hover"]; const exportBackground = ["customBackgroundLink", "customBackgroundScale", "customBackgroundDaily", "customBackgroundNasaDaily", "fitImageToScreen", "card_transparency", "bg_opacity", "sidebar_opacity", "bg_blur", "sidebar_blur", "card_opacity", "card_blur"]; // Master "On/off toggles": every visual toggle, minus GPA/schedule/productivity. const exportToggles = ["dark_mode", "quiz_safe_mode", "grade_analytics", "grade_analytics_zones"].concat(exportCardColorToggles, exportLayout, exportSidebar, exportTodo); @@ -239,6 +242,7 @@ const defaultOptions = { "dashboard_notes_mode": "edit", "dashboard_notes_position": "top", "gpa_calc_position": "cards_end", + "gpa_calc_show_on_hover": false, "focus_timer": false, "focus_timer_position": "cards_end", "focus_timer_preset_1": { "h": 0, "m": 15, "s": 0 }, @@ -251,6 +255,8 @@ const defaultOptions = { "breathing_preset_3": { "h": 0, "m": 10, "s": 0 }, "daily_quotes": false, "daily_quotes_position": "top", + "quick_links": false, + "quick_links_position": "cards_end", // Height in px (0 = auto); widget_row_height is the shared Top/Bottom row. "widget_row_height": 0, "dashboard_notes_height": 0, @@ -258,6 +264,7 @@ const defaultOptions = { "focus_timer_height": 0, "breathing_height": 0, "daily_quotes_height": 0, + "quick_links_height": 0, "better_todo": true, "better_sidebar": false, "sidebar_scale": 100, @@ -1070,6 +1077,7 @@ const WIDGET_LIST = [ { id: "focus_timer", nameKey: "focus_timer", shortKey: "widget_short_focus" }, { id: "breathing", nameKey: "breathing_breaks", shortKey: "widget_short_breathing" }, { id: "daily_quotes", nameKey: "daily_quotes", shortKey: "widget_short_quotes" }, + { id: "quick_links", nameKey: "quick_links", shortKey: "widget_short_links" }, ]; function widgetPosFromSync(id, sync) { @@ -1283,6 +1291,7 @@ function setupWidgetPosition() { { select: "focus_timer_position", key: "focus_timer_position" }, { select: "breathing_position", key: "breathing_position" }, { select: "daily_quotes_position", key: "daily_quotes_position" }, + { select: "quick_links_position", key: "quick_links_position" }, ].forEach(({ select, key }) => { const el = document.getElementById(select); if (!el) return; @@ -1365,7 +1374,7 @@ function setupWidgetTimeInput(prefix, initial) { } function toggleSubOptionsVisibility(option, isOn) { - const togglesWithSubOptions = ["dashboard_notes", "gpa_calc", "focus_timer", "breathing", "daily_quotes", "assignments_due", "better_todo", "auto_dark", "grade_analytics", "hide_personal_details"]; + const togglesWithSubOptions = ["dashboard_notes", "gpa_calc", "focus_timer", "breathing", "daily_quotes", "quick_links", "assignments_due", "better_todo", "auto_dark", "grade_analytics", "hide_personal_details"]; if (!togglesWithSubOptions.includes(option)) return; const optionEl = document.getElementById(option); if (!optionEl) return; @@ -1717,6 +1726,7 @@ async function setup() { "browser_show_likes", "gpa_calc_weighted", "gpa_calc_cumulative", + "gpa_calc_show_on_hover", "todo_hide_feedback", "todo_hide_read", "todo_full_height", @@ -1963,6 +1973,10 @@ async function setup() { identifier: "daily_quotes_height", setup: (initial) => setupWidgetHeightInput("daily_quotes_height", initial), }, + { + identifier: "quick_links_height", + setup: (initial) => setupWidgetHeightInput("quick_links_height", initial), + }, { identifier: "focus_timer_preset_1", setup: (initial) => setupWidgetTimeInput("focus_timer_preset_1", initial), @@ -2029,7 +2043,7 @@ async function setup() { chrome.storage.sync.set({ "hide_course_images": false }); } toggleSubOptionsVisibility(option, status); - if (option === "dashboard_notes" || option === "gpa_calc" || option === "focus_timer" || option === "breathing" || option === "daily_quotes") { + if (option === "dashboard_notes" || option === "gpa_calc" || option === "focus_timer" || option === "breathing" || option === "daily_quotes" || option === "quick_links") { if (refreshWidgetOrder) refreshWidgetOrder(); } }); @@ -2039,7 +2053,7 @@ async function setup() { chrome.storage.sync.get("todo_celebrations_enabled", v => { toggleCelebrationOptionsVisibility(v["todo_celebrations_enabled"] !== false); }); - ["dashboard_notes", "gpa_calc", "focus_timer", "breathing", "daily_quotes", "assignments_due", "better_todo", "auto_dark", "grade_analytics", "hide_personal_details"].forEach(opt => { + ["dashboard_notes", "gpa_calc", "focus_timer", "breathing", "daily_quotes", "quick_links", "assignments_due", "better_todo", "auto_dark", "grade_analytics", "hide_personal_details"].forEach(opt => { toggleSubOptionsVisibility(opt, sync[opt] === true); }); toggleAlternateColorsVisibility(sync["dark_mode"] === true);