Bläddra i källkod

Add Norwegian localization and language picker support.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 1 månad sedan
förälder
incheckning
a15bb123ce

+ 1 - 0
Info.plist

@@ -17,6 +17,7 @@
 		<string>it</string>
 		<string>nl</string>
 		<string>sv</string>
+		<string>nb</string>
 		<string>fi</string>
 		<string>el</string>
 		<string>he</string>

+ 1 - 0
meetings_app.xcodeproj/project.pbxproj

@@ -105,6 +105,7 @@
 				it,
 				nl,
 				sv,
+				nb,
 				fi,
 				el,
 				he,

+ 3 - 1
meetings_app/Localization/AppLanguageManager.swift

@@ -8,7 +8,7 @@ enum AppLanguageManager {
     private static let defaultsKey = "settings.appLanguageCode"
 
     /// UI languages shown in Settings → Language (order preserved).
-    private static let supportedLanguageCodes = ["en", "fr", "fr-CA", "es-ES", "es-MX", "de", "it", "nl", "sv", "fi", "el", "he", "ko", "pt-BR", "ru", "vi", "zh-Hans", "zh-Hant"]
+    private static let supportedLanguageCodes = ["en", "fr", "fr-CA", "es-ES", "es-MX", "de", "it", "nl", "sv", "nb", "fi", "el", "he", "ko", "pt-BR", "ru", "vi", "zh-Hans", "zh-Hant"]
 
     /// `nil` follows the system language; otherwise uses the selected `.lproj` code.
     static var selectedLanguageCode: String? {
@@ -99,6 +99,8 @@ enum AppLanguageManager {
             return "Nederlands"
         case "sv":
             return "Svenska"
+        case "nb":
+            return "Norsk"
         case "fi":
             return "Suomi"
         case "el":

+ 4 - 0
meetings_app/nb.lproj/InfoPlist.strings

@@ -0,0 +1,4 @@
+"CFBundleDisplayName" = "AI-assistent for Googles Meet";
+"CFBundleName" = "AI-assistent for Googles Meet";
+"NSMicrophoneUsageDescription" = "Med ditt samtykke vil appen ta opp møtelyden på denne Mac-en og vise den i AI-assistenten etter møtet.";
+"NSSpeechRecognitionUsageDescription" = "Denne appen konverterer lagret møtelyd til teksttranskripsjoner for AI-assistenten.";

+ 452 - 0
meetings_app/nb.lproj/Localizable.strings

@@ -0,0 +1,452 @@
+/* AppBrand.name ("Meetings") bevisst utelatt — appnavnet forblir uendret i koden. */
+"AI Companion for Meet" = "AI-assistent for Googles Meet";
+
+/* MARK: - Generelt */
+"OK" = "OK";
+"Cancel" = "Avbryt";
+"Continue" = "Fortsett";
+"Apply" = "Bruk";
+"Reset" = "Tilbakestill";
+"Save" = "Lagre";
+"Copy" = "Kopier";
+"Copied" = "Kopiert";
+"Close" = "Lukk";
+"Join" = "Bli med";
+"None" = "Ingen";
+"Link" = "Lenke";
+"Stop" = "Stopp";
+"Address" = "Adresse";
+"Title" = "Tittel";
+"Notes" = "Notater";
+"Start" = "Start";
+"Premium" = "Premium";
+"Popular" = "Populær";
+"Browser" = "Nettleser";
+"Meeting" = "Møte";
+"Error" = "Feil";
+"Success" = "Vellykket";
+
+/* MARK: - Statuslinje */
+"Meetings status menu" = "Statusmeny for møter";
+"Open App" = "Åpne app";
+"Join Meetings" = "Bli med i møter";
+"Schedule" = "Planlegg";
+"Calendar" = "Kalender";
+"Widgets" = "Widgeter";
+"AI Companion" = "AI-assistent";
+"Settings" = "Innstillinger";
+"Top meetings" = "Festede møter";
+"No upcoming meetings" = "Ingen kommende møter";
+"Sign Out" = "Logg ut";
+"Sign In" = "Logg inn";
+"Quit" = "Avslutt";
+
+/* MARK: - Hjemmeskjerm */
+"Preparing your meetings workspace" = "Forbereder møtearbeidsområdet ditt";
+"CONNECTING SERVICES" = "KOBLER TIL TJENESTER";
+"READY" = "KLAR";
+"Plan smart, achieve more" = "Planlegg smart, oppnå mer";
+
+/* MARK: - Widgeter */
+"Add Widget to Desktop" = "Legg til widget på skrivebordet";
+"Choose a size and add your Google Meet widget." = "Velg en størrelse og legg til Googles Meet-widgeten din.";
+"Tip: Right-click a desktop widget to remove it." = "Tips: Høyreklikk på en skrivebordswidget for å fjerne den.";
+"Removed %@ widget from desktop." = "Widget %@ fjernet fra skrivebordet.";
+"Added %@ widget from desktop." = "Widget %@ lagt til fra skrivebordet.";
+"Added %@ widget to desktop." = "Widget %@ lagt til på skrivebordet.";
+"Widgets are Premium only. Upgrade to add widgets." = "Widgeter er kun for Premium. Oppgrader for å legge til widgeter.";
+"Remove Widget" = "Fjern widget";
+"Small" = "Liten";
+"Medium" = "Medium";
+"Quick actions" = "Hurtighandlinger";
+"Open Meet" = "Åpne Googles Meet";
+"Upcoming meetings" = "Kommende møter";
+"Sign in to see upcoming meetings" = "Logg inn for å se kommende møter";
+"Sign in with Google" = "Logg inn med Googles konto";
+"Google Meet" = "Googles Meet";
+"Open and join quickly" = "Åpne og bli med raskt";
+"Refresh" = "Oppdater";
+
+/* MARK: - Sidemeny og navigasjon */
+"Planning" = "Planlegging";
+"Additional" = "Tillegg";
+"Get Premium" = "Få Premium";
+"Manage Subscription" = "Administrer abonnement";
+"App for Google Meet" = "App for Googles Meet";
+
+/* MARK: - Bli med i møte */
+"New Instant Meet" = "Nytt direktemøte";
+"Start instant Meet in more section with\nGoogle Meet meet." = "Start et direktemøte med Googles Meet i Mer-delen\nmed Googles Meet.";
+"Join with Link" = "Bli med med lenke";
+"Code or meet.google.com/…" = "Kode eller meet.google.com/…";
+"Join with ID" = "Bli med med ID";
+"Join with URL" = "Bli med med URL";
+"Meeting URL" = "Møte-URL";
+"Enter meeting URL..." = "Skriv inn møte-URL...";
+"Quick Join Meeting" = "Hurtig bli med i møte";
+"Invalid Meet link" = "Ugyldig Googles Meet-lenke";
+"Enter a valid Google Meet link or meeting code (for example nkd-grps-duv, meet.google.com/nkd-grps-duv, or https://meet.google.com/nkd-grps-duv)." = "Skriv inn en gyldig Googles Meet-lenke eller møtekode (for eksempel nkd-grps-duv, meet.google.com/nkd-grps-duv eller https://meet.google.com/nkd-grps-duv).";
+"Instant Meeting" = "Direktemøte";
+"Connect Google to start Instant Meeting" = "Koble til Googles konto for å starte direktemøte";
+"To auto-stop recording when the meeting ends, connect your Google account first." = "Koble til Googles konto først for å stoppe opptaket automatisk når møtet avsluttes.";
+"Could not create Instant Meeting" = "Kunne ikke opprette direktemøte";
+"Free trial used. Upgrade to continue." = "Gratis prøveperiode brukt. Oppgrader for å fortsette.";
+
+/* MARK: - Surf på nettet */
+"Browse the web" = "Surf på nettet";
+"Enter a web address (for example meet.google.com)." = "Skriv inn en nettadresse (for eksempel meet.google.com).";
+"Invalid address" = "Ugyldig adresse";
+"Enter a valid http or https URL." = "Skriv inn en gyldig http- eller https-URL.";
+"Browse" = "Bla gjennom";
+"Quick links" = "Hurtiglenker";
+"Zoom help" = "Zoom-hjelp";
+"https://example.com or example.com" = "https://example.com eller example.com";
+"Enter a valid web address, for example https://example.com" = "Skriv inn en gyldig nettadresse, for eksempel https://example.com";
+"Address not allowed" = "Adresse ikke tillatt";
+"This URL is not permitted with the current in-app browser policy (whitelist)." = "Denne URL-en er ikke tillatt med gjeldende retningslinjer for app-nettleseren (hviteliste).";
+"Unable to load page" = "Kan ikke laste siden";
+"Could not load this page in the in-app browser.\n\n%@" = "Kunne ikke laste denne siden i app-nettleseren.\n\n%@";
+"Page stopped loading" = "Siden sluttet å laste";
+"Unable to open browser" = "Kan ikke åpne nettleser";
+"Unable to Open Safari" = "Kan ikke åpne Safari";
+
+/* MARK: - Planlegging og kalender */
+"All" = "Alle";
+"Today" = "I dag";
+"This week" = "Denne uken";
+"This month" = "Denne måneden";
+"Previous week" = "Forrige uke";
+"Previous month" = "Forrige måned";
+"Custom range" = "Egendefinert område";
+"No meetings match the selected filters." = "Ingen møter samsvarer med de valgte filtrene.";
+"Adjust the date range and tap Apply." = "Juster datoområdet og trykk på Bruk.";
+"Premium required. Get Premium now to unlock Calendar." = "Premium kreves. Få Premium nå for å låse opp Kalender.";
+"Premium required. Click to open paywall." = "Premium kreves. Klikk for å åpne betalingsmur.";
+"Get Premium to see events" = "Få Premium for å se hendelser";
+"Connect Google" = "Koble til Googles konto";
+"Sign in with Google first to schedule a meeting from Calendar." = "Logg inn med Googles konto først for å planlegge et møte fra Kalender.";
+"Select date" = "Velg dato";
+"Choose a date to schedule your meeting." = "Velg en dato for å planlegge møtet ditt.";
+"Google schedule" = "Googles kalender";
+"To show scheduled meetings, connect your Google account. You’ll need a Google OAuth client ID (Desktop) and a redirect URI matching the app’s callback scheme." = "Koble til Googles konto for å vise planlagte møter. Du trenger en Googles OAuth-klient-ID (Skrivebord) og en omdirigerings-URI som samsvarer med appens callback-skjema.";
+"Actions" = "Handlinger";
+"Schedule meeting" = "Planlegg møte";
+"Team sync" = "Teamsynkronisering";
+"Duration (min)" = "Varighet (min)";
+"Refresh saved meetings" = "Oppdater lagrede møter";
+
+/* MARK: - Innstillinger */
+"Manage appearance, account, and app options." = "Administrer utseende, konto og appalternativer.";
+"Appearance" = "Utseende";
+"Account" = "Konto";
+"App" = "App";
+"Notifications" = "Varsler";
+"Help & Legal" = "Hjelp og juridisk";
+"Dark Mode" = "Mørk modus";
+"Language" = "Språk";
+"System Language" = "Systemspråk";
+"Rate Us" = "Vurder oss";
+"Share App" = "Del app";
+"Upgrade" = "Oppgrader";
+"Privacy Policy" = "Personvernerklæring";
+"Support" = "Støtte";
+"Terms of Services" = "Tjenestevilkår";
+"AI Language 1" = "AI-språk 1";
+"AI Language 2" = "AI-språk 2";
+"Google account connected" = "Googles konto tilkoblet";
+"Google account not connected" = "Googles konto ikke tilkoblet";
+"Signed in" = "Innlogget";
+"Sign in to sync your meetings and calendar." = "Logg inn for å synkronisere møter og kalender.";
+"Log out" = "Logg ut";
+"Check out %@ for managing and joining meetings." = "Sjekk ut %@ for å administrere og bli med i møter.";
+"Meetings App" = "Møte-app";
+
+/* MARK: - Samtykke til opptak */
+"Record this meeting locally?" = "Ta opp dette møtet lokalt?";
+"With your consent, the app will record meeting audio on this Mac and show it in AI Companion after the meeting." = "Med ditt samtykke vil appen ta opp møtelyden på denne Mac-en og vise den i AI-assistenten etter møtet.";
+"Allow and Continue" = "Tillat og fortsett";
+"Continue Without Recording" = "Fortsett uten opptak";
+"Transcription Languages" = "Transkripsjonsspråk";
+"Preferred Language 1" = "Foretrukket språk 1";
+"Preferred Language 2" = "Foretrukket språk 2";
+"Microphone permission denied" = "Mikrofontillatelse avslått";
+"Microphone permission required" = "Mikrofontillatelse kreves";
+"Enable microphone access in System Settings to record meetings locally." = "Aktiver mikrofontilgang i Systeminnstillinger for å ta opp møter lokalt.";
+"Could not start recording" = "Kunne ikke starte opptak";
+"Recording will start when the meeting starts" = "Opptaket starter når møtet begynner";
+"Meeting recording started (meeting + microphone)" = "Møteopptak startet (møte + mikrofon)";
+"System audio unavailable. Recording microphone only." = "Systemlyd utilgjengelig. Tar kun opp mikrofon.";
+"Meeting recording started (microphone only)" = "Møteopptak startet (kun mikrofon)";
+"Meeting recording saved" = "Møteopptak lagret";
+
+/* MARK: - AI-assistent */
+"Get notes from your previous meetings" = "Få notater fra dine tidligere møter";
+"Connect your Google account to see your AI Companion meeting history." = "Koble til Googles konto for å se AI-assistentens møtehistorikk.";
+"No previous meetings yet for %@. End a meeting to save it here and generate notes." = "Ingen tidligere møter ennå for %@. Avslutt et møte for å lagre det her og generere notater.";
+"this account" = "denne kontoen";
+"Previous meetings" = "Tidligere møter";
+"Recording in progress: %@" = "Opptak pågår: %@";
+"Started: %@" = "Startet: %@";
+"Stop Recording" = "Stopp opptak";
+"Date: %@" = "Dato: %@";
+"Saved time: %@" = "Lagret tid: %@";
+"Get Notes" = "Få notater";
+"Premium required. Click to unlock AI Companion notes." = "Premium kreves. Klikk for å låse opp AI-assistentens notater.";
+"Play Audio" = "Spill av lyd";
+"Pause Audio" = "Pause lyd";
+"Stopped" = "Stoppet";
+"Speaking..." = "Snakker...";
+"Paused" = "Pauset";
+"Playing..." = "Spiller av...";
+"Not playing" = "Spiller ikke av";
+"Checking audio..." = "Sjekker lyd...";
+"Audio file missing" = "Lydfil mangler";
+"Could not play recording" = "Kunne ikke spille av opptak";
+"Failed: %@" = "Mislyktes: %@";
+"Failed to play audio" = "Kunne ikke spille av lyd";
+"decode error" = "dekodingsfeil";
+"Loading..." = "Laster...";
+"Buffering..." = "Bufrer...";
+"Finished" = "Fullført";
+"Transcript not requested" = "Transkripsjon ikke forespurt";
+"Transcript processing..." = "Behandler transkripsjon...";
+"Transcript ready" = "Transkripsjon klar";
+"Transcript unavailable (tap to retry)" = "Transkripsjon utilgjengelig (trykk for å prøve igjen)";
+"Notes not requested" = "Notater ikke forespurt";
+"Preparing notes, please wait..." = "Forbereder notater, vennligst vent...";
+"Notes ready" = "Notater klare";
+"Notes unavailable (tap to retry)" = "Notater utilgjengelige (trykk for å prøve igjen)";
+"Transcript unavailable" = "Transkripsjon utilgjengelig";
+"Notes unavailable" = "Notater utilgjengelige";
+"Could not find recording details for this meeting." = "Kunne ikke finne opptaksdetaljer for dette møtet.";
+"Transcript - %@" = "Transkripsjon - %@";
+"Notes - %@" = "Notater - %@";
+"Meeting Notes" = "Møtenotater";
+
+/* MARK: - Betalingsmur og StoreKit */
+"Meetings Pro" = "Møter Pro";
+"PREMIUM EXPERIENCE" = "PREMIUMOPPLEVELSE";
+"Elevate your meetings workflow" = "Hev møtearbeidsflyten din";
+"Unlock automation, premium meeting tools, and priority support for every session." = "Lås opp automatisering, premium møteverktøy og prioritert støtte for hver økt.";
+"Manage meetings" = "Administrer møter";
+"Smart scheduling" = "Smart planlegging";
+"Faster workflow" = "Raskere arbeidsflyt";
+"Reminder notifications" = "Påminnelsesvarsler";
+"Monthly" = "Månedlig";
+"Bi Yearly" = "Halvårlig";
+"Yearly" = "Årlig";
+"Most Popular" = "Mest populær";
+"%@ • Most Popular" = "%@ • Mest populær";
+"3 days free trial" = "3 dagers gratis prøveperiode";
+"Cancel anytime" = "Avbryt når som helst";
+"No lock-in" = "Ingen binding";
+"Instant access" = "Umiddelbar tilgang";
+"Unlock all tools" = "Lås opp alle verktøy";
+"Secure billing" = "Sikker fakturering";
+"Handled by Apple" = "Håndteres av Eple";
+"Secured by Apple. Cancel anytime." = "Sikret av Eple. Avbryt når som helst.";
+"Restore Purchase" = "Gjenopprett kjøp";
+"Continue with free plan" = "Fortsett med gratis plan";
+"Already Premium" = "Allerede Premium";
+"You are already premium. Do you want to continue with this purchase?" = "Du er allerede premium. Vil du fortsette med dette kjøpet?";
+"Current plan: %@. Choose a different package to switch." = "Gjeldende plan: %@. Velg en annen pakke for å bytte.";
+"Premium is active on this Apple ID." = "Premium er aktivt på denne Eple-ID-en.";
+"Free for %@, then %@" = "Gratis i %@, deretter %@";
+"Billed via App Store" = "Fakturert via Eples App Store";
+"%@  •  %@" = "%@  •  %@";
+"Save 0%" = "Spar 0%";
+"Save %@%%" = "Spar %@%%";
+"month" = "måned";
+"year" = "år";
+"%@ free trial" = "%@ gratis prøveperiode";
+"Processing..." = "Behandler...";
+"Premium Active" = "Premium aktivt";
+"Continue with 3 day trail" = "Fortsett med 3 dagers prøveperiode";
+"Please Wait" = "Vennligst vent";
+"A purchase is already being processed." = "Et kjøp blir allerede behandlet.";
+"This Apple ID already has premium access." = "Denne Eple-ID-en har allerede premium-tilgang.";
+"Purchase Complete" = "Kjøp fullført";
+"Premium has been unlocked successfully." = "Premium har blitt låst opp.";
+"Purchase Pending" = "Kjøp venter";
+"Your purchase is pending approval. You can continue once it completes." = "Kjøpet ditt venter på godkjenning. Du kan fortsette når det er fullført.";
+"Product Not Available" = "Produkt ikke tilgjengelig";
+"Unable to load this product. Check your StoreKit configuration and product IDs." = "Kan ikke laste dette produktet. Sjekk StoreKit-konfigurasjonen og produkt-ID-ene dine.";
+"Already Purchased" = "Allerede kjøpt";
+"This plan is already active on your Apple ID." = "Denne planen er allerede aktiv på Eple-ID-en din.";
+"Purchase Failed" = "Kjøp mislyktes";
+"Restore Purchases" = "Gjenopprett kjøp";
+"Purchases restored successfully." = "Kjøp gjenopprettet.";
+"No previous premium purchase was found for this Apple ID." = "Ingen tidligere premium-kjøp ble funnet for denne Eple-ID-en.";
+"Restore failed: %@" = "Gjenoppretting mislyktes: %@";
+"Unable to Open Subscriptions" = "Kan ikke åpne Abonnementer";
+"The subscriptions URL is invalid." = "Abonnements-URL-en er ugyldig.";
+"%@ tapped." = "%@ trykket.";
+
+/* MARK: - Autentisering */
+"Google Sign-In" = "Innlogging med Googles konto";
+
+/* MARK: - Talegjenkjenning/transkripsjonsfeil */
+"Speech recognition permission denied. Enable it in System Settings and try again." = "Tillatelse til talegjenkjenning avslått. Aktiver det i Systeminnstillinger og prøv igjen.";
+"Speech recognition is restricted on this Mac." = "Talegjenkjenning er begrenset på denne Mac-en.";
+"Speech recognition authorization is unavailable." = "Autorisasjon for talegjenkjenning er utilgjengelig.";
+"Speech recognizer is unavailable for the current locale." = "Talegjenkjenneren er utilgjengelig for gjeldende språk.";
+"Speech recognizer is unavailable for %@." = "Talegjenkjenneren er utilgjengelig for %@.";
+"No audio was available to transcribe." = "Ingen lyd var tilgjengelig for transkripsjon.";
+
+/* MARK: - StoreKit-transaksjonsfeil */
+"Unable to load products: %@" = "Kan ikke laste produkter: %@";
+"Product ID not found in StoreKit response. Requested: %@. Loaded IDs: %@" = "Produkt-ID ikke funnet i StoreKit-svar. Forespurt: %@. Lastede ID-er: %@";
+"Purchase verification failed." = "Kjøpsverifisering mislyktes.";
+"Unknown purchase state." = "Ukjent kjøpstilstand.";
+"none" = "ingen";
+
+/* MARK: - Betalingsmur pristekster */
+"%@ one-time purchase" = "%@ engangskjøp";
+"%@/month" = "%@/måned";
+"%@/6 months" = "%@/6 måneder";
+"%@/year (3 days free trial)" = "%@/år (3 dagers gratis prøveperiode)";
+"day" = "dag";
+"week" = "uke";
+"period" = "periode";
+"1 %@" = "1 %@";
+"%d %@s" = "%d %@";
+
+/* MARK: - Toast-varsler og rask tilbakemelding */
+"Meeting added successfully." = "Møte lagt til.";
+"An issue occurred. Please try again." = "Det oppstod et problem. Vennligst prøv igjen.";
+"Failed to load transcript." = "Kunne ikke laste transkripsjon.";
+"Failed to generate notes." = "Kunne ikke generere notater.";
+
+/* MARK: - Nettleservarsler */
+"Try Again" = "Prøv igjen";
+"The in-app browser closed this page unexpectedly. You can try loading it again in this same window." = "App-nettleseren lukket denne siden uventet. Du kan prøve å laste den på nytt i samme vindu.";
+
+/* MARK: - Planleggings- og kalenderfeil */
+"Couldn't load schedule." = "Kunne ikke laste timeplan.";
+"Couldn't refresh schedule." = "Kunne ikke oppdatere timeplan.";
+"Couldn't connect Google account." = "Kunne ikke koble til Googles konto.";
+"Couldn't logout Google account." = "Kunne ikke logge ut av Googles konto.";
+"Couldn't load schedule" = "Kunne ikke laste timeplan";
+"Couldn't determine Meet meeting code from URL." = "Kunne ikke fastslå Googles Meet-møtekode fra URL.";
+"Refreshing…" = "Oppdaterer…";
+"Connect Google to see meetings" = "Koble til Googles konto for å se møter";
+"Connect to load schedule" = "Koble til for å laste timeplan";
+"Loading…" = "Laster…";
+"Loading schedule…" = "Laster timeplan…";
+"Start date must be on or before end date." = "Startdato må være på eller før sluttdato.";
+"Invalid custom date range" = "Ugyldig egendefinert datoområde";
+"No meetings" = "Ingen møter";
+"No meetings for selected filters" = "Ingen møter for valgte filtre";
+"No meetings on %@" = "Ingen møter den %@";
+"1 meeting on %@" = "1 møte den %@";
+"%d meetings on %@" = "%d møter den %@";
+"All day" = "Hele dagen";
+"Duration: all day" = "Varighet: hele dagen";
+"Duration: %dh %dm" = "Varighet: %dt %dm";
+"Duration: %dh" = "Varighet: %dt";
+"Duration: %dm" = "Varighet: %dm";
+"%@ - %@" = "%@ - %@";
+"Scheduled Meeting" = "Planlagt møte";
+
+/* MARK: - Opprett møte popup */
+"Please enter a title." = "Vennligst skriv inn en tittel.";
+"Duration must be a positive number of minutes." = "Varighet må være et positivt antall minutter.";
+"Invalid start time." = "Ugyldig starttidspunkt.";
+
+/* MARK: - Påminnelser og varsler */
+"Reminders" = "Påminnelser";
+"1 Day Before" = "1 dag før";
+"12 Hours Before" = "12 timer før";
+"1 Hour Before" = "1 time før";
+"Starts in 1 day" = "Starter om 1 dag";
+"Starts in 12 hours" = "Starter om 12 timer";
+"Starts in 1 hour" = "Starter om 1 time";
+
+/* MARK: - Google OAuth-feil */
+"Missing Google OAuth Client ID." = "Mangler Googles OAuth-klient-ID.";
+"Missing Google OAuth Client Secret." = "Mangler Googles OAuth-klienthemmelighet.";
+"Invalid OAuth callback URL." = "Ugyldig OAuth callback-URL.";
+"Google did not return an authorization code." = "Googles tjeneste returnerte ikke en autorisasjonskode.";
+"Token exchange failed: %@" = "Token-utveksling mislyktes: %@";
+"Could not open browser for Google sign-in." = "Kunne ikke åpne nettleser for innlogging med Googles konto.";
+"Google sign-in timed out." = "Innlogging med Googles konto tidsavbrudd.";
+"No stored Google tokens found." = "Ingen lagrede Googles konto-tokens funnet.";
+
+/* MARK: - AI-assistent/transkripsjonsfeil */
+"Recording not found." = "Opptak ikke funnet.";
+"Local meeting audio is missing." = "Lokal møtelyd mangler.";
+"Generated transcript was empty." = "Generert transkripsjon var tom.";
+"(No transcript entries found.)" = "(Ingen transkripsjonsoppføringer funnet.)";
+"No conference record found for this meeting." = "Ingen konferanseoppføring funnet for dette møtet.";
+"No transcript found for this meeting." = "Ingen transkripsjon funnet for dette møtet.";
+"Unable to create audio composition tracks." = "Kan ikke opprette lydkomposisjonsspor.";
+"Unable to create audio export session." = "Kan ikke opprette lydeksportøkt.";
+"Audio mix export failed." = "Lydmikseksport mislyktes.";
+"No display available for system audio capture." = "Ingen skjerm tilgjengelig for systemlydopptak.";
+"Cannot add audio writer input." = "Kan ikke legge til lydskriverinndata.";
+
+/* MARK: - Google API-feil */
+"Google Meet returned an invalid response." = "Googles Meet returnerte et ugyldig svar.";
+"Google Meet API error (%d): %@" = "Googles Meet-API-feil (%d): %@";
+"Failed to parse Google Meet response: %@" = "Kunne ikke analysere Googles Meet-svar: %@";
+"Google Calendar returned an invalid response." = "Googles kalender returnerte et ugyldig svar.";
+"Google Calendar API error (%d): %@" = "Googles kalender-API-feil (%d): %@";
+"Failed to parse Google Calendar events: %@" = "Kunne ikke analysere Googles kalender-hendelser: %@";
+
+/* MARK: - OpenAI-feil */
+"OpenAI API key is missing. Set OPENAI_API_KEY in the environment or app key vault." = "OpenAI API-nøkkel mangler. Sett OPENAI_API_KEY i miljøet eller app-nøkkelhvelvet.";
+"Notes generation returned an invalid response." = "Notatgenerering returnerte et ugyldig svar.";
+"Notes generation failed (%d): %@" = "Notatgenerering mislyktes (%d): %@";
+"Notes generation returned empty text." = "Notatgenerering returnerte tom tekst.";
+"OpenAI transcription returned an invalid response." = "OpenAI-transkripsjon returnerte et ugyldig svar.";
+"OpenAI transcription failed (%d): %@" = "OpenAI-transkripsjon mislyktes (%d): %@";
+"OpenAI transcription returned no text." = "OpenAI-transkripsjon returnerte ingen tekst.";
+
+/* MARK: - Navigasjon og app-nettleser */
+"Open sites in the in-app browser (back, forward, reload, address bar). OAuth and “Continue in browser” flows stay inside the app." = "Åpne nettsteder i app-nettleseren (tilbake, frem, last inn på nytt, adresselinje). OAuth- og «Fortsett i nettleser»-flyter forblir i appen.";
+"Open in app browser" = "Åpne i app-nettleser";
+"Meet help" = "Hjelp for Googles Meet";
+"Go" = "Gå";
+"Back" = "Tilbake";
+"Forward" = "Frem";
+"Reload" = "Last inn på nytt";
+
+/* MARK: - Kalender- og planleggingsetiketter */
+"Google Calendar" = "Googles kalender";
+"Untitled meeting" = "Uten tittel møte";
+"Created event missing start/end." = "Opprettet hendelse mangler start/slutt.";
+"Created event missing Meet/HTML link." = "Opprettet hendelse mangler Googles Meet-/HTML-lenke.";
+
+/* MARK: - Google-konto */
+"Google account" = "Googles konto";
+"%@, Google account" = "%@, Googles konto";
+"Google User" = "Googles bruker";
+
+/* MARK: - Bli med i Zoom (ubrukte deler) */
+"Meeting ID" = "Møte-ID";
+"Enter meeting ID..." = "Skriv inn møte-ID...";
+"Meeting Passcode" = "Møtepassord";
+"Enter meeting passcode..." = "Skriv inn møtepassord...";
+
+/* MARK: - Betalingsmur (alternative fordeler) */
+"Virtual backgrounds" = "Virtuelle bakgrunner";
+"Tools for productivity" = "Verktøy for produktivitet";
+"24/7 support" = "24/7 støtte";
+
+/* MARK: - Transkripsjonstalere */
+"You" = "Du";
+
+/* MARK: - Nøkkelringfeil */
+"Failed to read OAuth tokens from Keychain." = "Kunne ikke lese OAuth-tokens fra Nøkkelring.";
+"Keychain returned an invalid token payload." = "Nøkkelring returnerte en ugyldig token-nyttelast.";
+"Failed to update OAuth tokens in Keychain." = "Kunne ikke oppdatere OAuth-tokens i Nøkkelring.";
+"Failed to save OAuth tokens to Keychain." = "Kunne ikke lagre OAuth-tokens til Nøkkelring.";
+"Failed to delete OAuth tokens from Keychain." = "Kunne ikke slette OAuth-tokens fra Nøkkelring.";
+"Unable to allocate audio buffer." = "Kan ikke tildele lydbuffer.";
+"Invalid revoke response." = "Ugyldig tilbakekallingssvar.";
+"Token revoke failed with status %d." = "Token-tilbakekalling mislyktes med status %d.";
+
+/* MARK: - Feildiagnostikk */
+"Keychain: %d (%@)" = "Nøkkelring: %d (%@)";
+"OSStatus: %d" = "OSStatus: %d";
+"Item: service=%@, account=%@" = "Element: tjeneste=%@, konto=%@";

+ 17 - 0
meetings_app/nb.lproj/Main.strings

@@ -0,0 +1,17 @@
+/* Class = "NSMenuItem"; title = "AI Companion for Meet"; ObjectID = "1Xt-HY-uBw"; */
+"1Xt-HY-uBw.title" = "AI-assistent for Googles Meet";
+
+/* Class = "NSMenu"; title = "AI Companion for Meet"; ObjectID = "uQy-DD-JDr"; */
+"uQy-DD-JDr.title" = "AI-assistent for Googles Meet";
+
+/* Class = "NSMenuItem"; title = "About AI Companion for Meet"; ObjectID = "5kV-Vb-QxS"; */
+"5kV-Vb-QxS.title" = "Om AI-assistent for Googles Meet";
+
+/* Class = "NSMenuItem"; title = "Hide AI Companion for Meet"; ObjectID = "Olw-nP-bQN"; */
+"Olw-nP-bQN.title" = "Skjul AI-assistent for Googles Meet";
+
+/* Class = "NSMenuItem"; title = "Quit AI Companion for Meet"; ObjectID = "4sb-4s-VLi"; */
+"4sb-4s-VLi.title" = "Avslutt AI-assistent for Googles Meet";
+
+/* Class = "NSMenuItem"; title = "AI Companion for Meet Help"; ObjectID = "FKE-Sm-Kum"; */
+"FKE-Sm-Kum.title" = "Hjelp for AI-assistent for Googles Meet";