Add data templates for QR codes (#109)

This commit is contained in:
Estee Tey 2025-04-25 20:53:15 +08:00 committed by GitHub
parent d0e09d963f
commit df3c568ce7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 4900 additions and 58 deletions

View File

@ -32,6 +32,7 @@ An app to create beautiful QR codes and scan various QR code types.
- 📱 QR Code Scanner: Scan QR codes using your camera or by uploading images, with intelligent detection for URLs, emails, phone numbers, WiFi credentials, and more
- 📦 Batch data export: Import a CSV file with multiple data strings and export QR codes for them all at once.
- 📲 PWA Support: Install MiniQR as a desktop or mobile app
- 📝 Data templates: Support for various data types including text, URLs, emails, phone numbers, SMS, WiFi credentials, vCards, locations, and calendar events
### Installation as PWA
@ -87,6 +88,13 @@ https://github.com/user-attachments/assets/e160d60d-3c7f-4bbb-908c-efd11fec20e8
</details>
<details>
<summary>Data templates (added in v0.16.0)</summary>
https://github.com/user-attachments/assets/863f9330-2645-4d23-88aa-04f5f5beaa67
</details>
## Self-hosting with Docker 🐋
Mini-QR can easily be self-hosted. We provide a [docker-compose.yml](docker-compose.yml) file as well as our own images. We are using GitHub's `ghrc.io` Container Registry.
@ -99,4 +107,5 @@ docker compose up -d
## Contributing
Translations and bug fixes are welcome!
See [CONTRIBUTING.md](CONTRIBUTING.md) for more details.

View File

@ -141,5 +141,89 @@
"right": "right",
"Close scanner": "Close scanner",
"Switch camera": "Switch camera",
"Ignore header row": "Ignore header row"
"Ignore header row": "Ignore header row",
"Data Type": "Data Type",
"Text": "Text",
"URL": "URL",
"Email": "Email",
"Phone": "Phone",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Event",
"Invalid URL format": "Invalid URL format",
"Invalid email format": "Invalid email format",
"Invalid phone number format": "Invalid phone number format",
"Invalid WiFi format": "Invalid WiFi format",
"Invalid vCard format": "Invalid vCard format",
"Invalid location format": "Invalid location format",
"Invalid event format": "Invalid event format",
"Network Name (SSID)": "Network Name (SSID)",
"Password": "Password",
"Network Type": "Network Type",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "None",
"First Name": "First Name",
"Last Name": "Last Name",
"Organization": "Organization",
"Title": "Title",
"Phone Number": "Phone Number",
"Email Address": "Email Address",
"Website": "Website",
"Address": "Address",
"City": "City",
"State": "State",
"Zip Code": "Zip Code",
"Country": "Country",
"Notes": "Notes",
"Latitude": "Latitude",
"Longitude": "Longitude",
"Event Title": "Event Title",
"Start Date": "Start Date",
"End Date": "End Date",
"Location": "Location",
"Description": "Description",
"Save": "Save",
"Have a beautiful day!": "Have a beautiful day!",
"Data templates": "Data templates",
"Hidden SSID": "Hidden SSID",
"Close dialog": "Close dialog",
"Use example": "Use example",
"Required fields are marked with an asterisk (*)": "Required fields are marked with an asterisk (*)",
"Text is required": "Text is required",
"URL is required": "URL is required",
"Email address is required": "Email address is required",
"Optional subject line": "Optional subject line",
"Optional email body": "Optional email body",
"Phone number is required": "Phone number is required",
"Optional SMS message": "Optional SMS message",
"Encryption": "Encryption",
"No encryption": "No encryption",
"Wireless SSID": "Wireless SSID",
"Your network name": "Your network name",
"Wireless SSID is required": "Wireless SSID is required",
"Network password (case-sensitive)": "Network password (case-sensitive)",
"Password is required when encryption is enabled": "Password is required when encryption is enabled",
"vCard Version": "vCard Version",
"e.g., John": "e.g., John",
"e.g., Doe": "e.g., Doe",
"e.g., Acme Corp": "e.g., Acme Corp",
"e.g., Software Engineer": "e.g., Software Engineer",
"Phone (Work)": "Phone (Work)",
"Phone (Private)": "Phone (Private)",
"Phone (Mobile)": "Phone (Mobile)",
"Street": "Street",
"Zipcode": "Zipcode",
"Latitude is required": "Latitude is required",
"Longitude is required": "Longitude is required",
"e.g., Team Meeting": "e.g., Team Meeting",
"e.g., Conference Room A": "e.g., Conference Room A",
"Event Location": "Event Location",
"Start Time": "Start Time",
"End Time": "End Time",
"Start time is required": "Start time is required",
"End time is required": "End time is required",
"Subject": "Subject",
"Message": "Message"
}

View File

@ -79,13 +79,13 @@
"square": "مربع",
"extra-rounded": "خارج التقريب",
"dot": "نقطة",
"Drag and drop a CSV file here or click to select": "قم بسحب وإسقاط ملف CSV هنا أو انقر لتحديد",
"Click to select and upload a CSV file": "انقر لتحديد وتحميل ملف CSV",
"Drag and drop a CSV file here or click to select": "قم بسحب ملف CSV وإفلاته هنا أو انقر لتحديد",
"Click to select and upload a CSV file": "انقر لتحديد ملف CSV وتحميله",
"{count} piece(s) of data detected": "{count} جزء (أجزاء) البيانات المكتشفة",
"Invalid CSV": "CSV غير صالح",
"Single export": "تصدير واحد",
"Batch export": "تصدير دفعة",
"Creating QR codes... This may take a while.": "إنشاء رموز QR... قد يستغرق هذا بعض الوقت.",
"Invalid CSV": "ملف CSV غير صالح",
"Single export": "التصدير الفردي",
"Batch export": "تصدير الدُفعات",
"Creating QR codes... This may take a while.": "إنشاء رموز QR... قد يستغرق ذلك بعض الوقت.",
"{index} / {count} QR codes have been created.": "تم إنشاء رموز QR {index} / {count}",
"QR codes have been successfully exported.": "تم تصدير رموز QR بنجاح.",
"Start new batch export": "بدء تصدير دفعة جديدة",
@ -141,5 +141,89 @@
"right": "يمين",
"Close scanner": "إغلاق الماسح الضوئي",
"Switch camera": "تبديل الكاميرا",
"Ignore header row": "تجاهل صف الرأس"
"Ignore header row": "تجاهل صف الرأس",
"Data Type": "نوع البيانات",
"Text": "النص",
"URL": "عنوان URL",
"Email": "البريد الإلكتروني",
"Phone": "الهاتف",
"SMS": "الرسائل النصية القصيرة",
"WiFi": "الواي فاي",
"vCard": "بطاقة vCard",
"Event": "الحدث",
"Invalid URL format": "تنسيق عنوان URL غير صالح",
"Invalid email format": "تنسيق البريد الإلكتروني غير صالح",
"Invalid phone number format": "تنسيق رقم الهاتف غير صالح",
"Invalid WiFi format": "تنسيق WiFi غير صالح",
"Invalid vCard format": "تنسيق بطاقة vCard غير صالح",
"Invalid location format": "تنسيق الموقع غير صالح",
"Invalid event format": "تنسيق حدث غير صالح",
"Network Name (SSID)": "اسم الشبكة (SSID)",
"Password": "كلمة المرور",
"Network Type": "نوع الشبكة",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "لا يوجد",
"First Name": "الاسم الأول",
"Last Name": "الاسم العائلي",
"Organization": "التنظيم",
"Title": "العنوان",
"Phone Number": "رقم الهاتف",
"Email Address": "عنوان البريد الإلكتروني",
"Website": "الموقع الإلكتروني",
"Address": "العنوان",
"City": "المدينة",
"State": "الولاية",
"Zip Code": "الرمز البريدي",
"Country": "البلد",
"Notes": "الملاحظات",
"Latitude": "خط العرض",
"Longitude": "خط الطول",
"Event Title": "عنوان الحدث",
"Start Date": "تاريخ البدء",
"End Date": "تاريخ الانتهاء",
"Location": "الموقع",
"Description": "الوصف",
"Save": "الحفظ",
"Have a beautiful day!": "أتمنى لك يوماً جميلاً!",
"Data templates": "قوالب البيانات",
"Hidden SSID": "معرّف SSID مخفي",
"Close dialog": "إغلاق مربع الحوار",
"Use example": "استخدم مثالاً",
"Required fields are marked with an asterisk (*)": "الحقول المطلوبة مميزة بعلامة النجمة (*)",
"Text is required": "النص مطلوب",
"URL is required": "عنوان URL مطلوب",
"Email address is required": "عنوان البريد الإلكتروني مطلوب",
"Optional subject line": "سطر الموضوع الاختياري",
"Optional email body": "نص البريد الإلكتروني الاختياري",
"Phone number is required": "رقم الهاتف مطلوب",
"Optional SMS message": "رسالة نصية قصيرة اختيارية",
"Encryption": "التشفير",
"No encryption": "لا يوجد تشفير",
"Wireless SSID": "معرّف SSID اللاسلكي",
"Your network name": "اسم الشبكة الخاص بك",
"Wireless SSID is required": "مطلوب SSID لاسلكي SSID",
"Network password (case-sensitive)": "كلمة مرور الشبكة (حساسة لحالة الأحرف)",
"Password is required when encryption is enabled": "كلمة المرور مطلوبة عند تمكين التشفير",
"vCard Version": "إصدار بطاقة vCard",
"e.g., John": "على سبيل المثال، جون",
"e.g., Doe": "على سبيل المثال، ظبية",
"e.g., Acme Corp": "على سبيل المثال، شركة أكمي كورب",
"e.g., Software Engineer": "على سبيل المثال، مهندس برمجيات",
"Phone (Work)": "الهاتف (العمل)",
"Phone (Private)": "الهاتف (خاص)",
"Phone (Mobile)": "الهاتف (الجوال)",
"Street": "الشارع",
"Zipcode": "الرمز البريدي",
"Latitude is required": "خط العرض مطلوب",
"Longitude is required": "خط الطول مطلوب",
"e.g., Team Meeting": "على سبيل المثال، اجتماع الفريق",
"e.g., Conference Room A": "على سبيل المثال، غرفة الاجتماعات A",
"Event Location": "موقع الحدث",
"Start Time": "وقت البدء",
"End Time": "وقت الانتهاء",
"Start time is required": "وقت البدء مطلوب",
"End time is required": "وقت الانتهاء مطلوب",
"Subject": "الموضوع",
"Message": "الرسالة"
}

View File

@ -141,5 +141,89 @@
"right": "right",
"Close scanner": "Close scanner",
"Switch camera": "Switch camera",
"Ignore header row": "Ignore header row"
"Ignore header row": "Ignore header row",
"Data Type": "Data Type",
"Text": "Text",
"URL": "URL",
"Email": "Email",
"Phone": "Phone",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Event",
"Invalid URL format": "Invalid URL format",
"Invalid email format": "Invalid email format",
"Invalid phone number format": "Invalid phone number format",
"Invalid WiFi format": "Invalid WiFi format",
"Invalid vCard format": "Invalid vCard format",
"Invalid location format": "Invalid location format",
"Invalid event format": "Invalid event format",
"Network Name (SSID)": "Network Name (SSID)",
"Password": "Password",
"Network Type": "Network Type",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "None",
"First Name": "First Name",
"Last Name": "Last Name",
"Organization": "Organization",
"Title": "Title",
"Phone Number": "Phone Number",
"Email Address": "Email Address",
"Website": "Website",
"Address": "Address",
"City": "City",
"State": "State",
"Zip Code": "Zip Code",
"Country": "Country",
"Notes": "Notes",
"Latitude": "Latitude",
"Longitude": "Longitude",
"Event Title": "Event Title",
"Start Date": "Start Date",
"End Date": "End Date",
"Location": "Location",
"Description": "Description",
"Save": "Save",
"Have a beautiful day!": "Have a beautiful day!",
"Data templates": "Data templates",
"Hidden SSID": "Hidden SSID",
"Close dialog": "Close dialog",
"Use example": "Use example",
"Required fields are marked with an asterisk (*)": "Required fields are marked with an asterisk (*)",
"Text is required": "Text is required",
"URL is required": "URL is required",
"Email address is required": "Email address is required",
"Optional subject line": "Optional subject line",
"Optional email body": "Optional email body",
"Phone number is required": "Phone number is required",
"Optional SMS message": "Optional SMS message",
"Encryption": "Encryption",
"No encryption": "No encryption",
"Wireless SSID": "Wireless SSID",
"Your network name": "Your network name",
"Wireless SSID is required": "Wireless SSID is required",
"Network password (case-sensitive)": "Network password (case-sensitive)",
"Password is required when encryption is enabled": "Password is required when encryption is enabled",
"vCard Version": "vCard Version",
"e.g., John": "e.g., John",
"e.g., Doe": "e.g., Doe",
"e.g., Acme Corp": "e.g., Acme Corp",
"e.g., Software Engineer": "e.g., Software Engineer",
"Phone (Work)": "Phone (Work)",
"Phone (Private)": "Phone (Private)",
"Phone (Mobile)": "Phone (Mobile)",
"Street": "Street",
"Zipcode": "Zipcode",
"Latitude is required": "Latitude is required",
"Longitude is required": "Longitude is required",
"e.g., Team Meeting": "e.g., Team Meeting",
"e.g., Conference Room A": "e.g., Conference Room A",
"Event Location": "Event Location",
"Start Time": "Start Time",
"End Time": "End Time",
"Start time is required": "Start time is required",
"End time is required": "End time is required",
"Subject": "Subject",
"Message": "Message"
}

View File

@ -141,5 +141,89 @@
"right": "vpravo",
"Close scanner": "Zavřít skener",
"Switch camera": "Přepnout fotoaparát",
"Ignore header row": "Ignorování řádku záhlaví"
"Ignore header row": "Ignorování řádku záhlaví",
"Data Type": "Typ dat",
"Text": "Text",
"URL": "ADRESA URL",
"Email": "E-mail",
"Phone": "Telefon",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Událost",
"Invalid URL format": "Nesprávný formát adresy URL",
"Invalid email format": "Nesprávný formát e-mailu",
"Invalid phone number format": "Nesprávný formát telefonního čísla",
"Invalid WiFi format": "Neplatný formát WiFi",
"Invalid vCard format": "Nesprávný formát karty vCard",
"Invalid location format": "Nesprávný formát umístění",
"Invalid event format": "Nesprávný formát události",
"Network Name (SSID)": "Název sítě (SSID)",
"Password": "Heslo",
"Network Type": "Typ sítě",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Žádné",
"First Name": "Jméno",
"Last Name": "Příjmení",
"Organization": "Organizace",
"Title": "Název",
"Phone Number": "Telefonní číslo",
"Email Address": "E-mailová adresa",
"Website": "Webové stránky",
"Address": "Adresa",
"City": "Město",
"State": "Stát",
"Zip Code": "Poštovní směrovací číslo",
"Country": "Země",
"Notes": "Poznámky",
"Latitude": "Zeměpisná šířka",
"Longitude": "Zeměpisná délka",
"Event Title": "Název události",
"Start Date": "Datum zahájení",
"End Date": "Datum ukončení",
"Location": "Umístění",
"Description": "Popis",
"Save": "Uložit",
"Have a beautiful day!": "Přeji krásný den!",
"Data templates": "Šablony dat",
"Hidden SSID": "Skrytý identifikátor SSID",
"Close dialog": "Zavřít dialogové okno",
"Use example": "Použijte příklad",
"Required fields are marked with an asterisk (*)": "Povinná pole jsou označena hvězdičkou (*).",
"Text is required": "Text je vyžadován",
"URL is required": "Je vyžadována adresa URL",
"Email address is required": "Je vyžadována e-mailová adresa",
"Optional subject line": "Nepovinný předmět",
"Optional email body": "Nepovinné tělo e-mailu",
"Phone number is required": "Vyžaduje se telefonní číslo",
"Optional SMS message": "Volitelná zpráva SMS",
"Encryption": "Šifrování",
"No encryption": "Žádné šifrování",
"Wireless SSID": "Bezdrátový identifikátor SSID",
"Your network name": "Název vaší sítě",
"Wireless SSID is required": "Je vyžadován bezdrátový identifikátor SSID",
"Network password (case-sensitive)": "Síťové heslo (rozlišuje velká a malá písmena)",
"Password is required when encryption is enabled": "Při zapnutém šifrování je vyžadováno heslo",
"vCard Version": "Verze vCard",
"e.g., John": "např. John",
"e.g., Doe": "např. Doe",
"e.g., Acme Corp": "např. Acme Corp.",
"e.g., Software Engineer": "např. softwarový inženýr",
"Phone (Work)": "Telefon (pracovní)",
"Phone (Private)": "Telefon (soukromý)",
"Phone (Mobile)": "Telefon (mobilní)",
"Street": "Ulice",
"Zipcode": "PSČ",
"Latitude is required": "Je vyžadována zeměpisná šířka",
"Longitude is required": "Je vyžadována zeměpisná délka",
"e.g., Team Meeting": "např. týmová schůzka",
"e.g., Conference Room A": "např. konferenční místnost A",
"Event Location": "Umístění události",
"Start Time": "Čas zahájení",
"End Time": "Čas konce",
"Start time is required": "Je vyžadován čas zahájení",
"End time is required": "Je vyžadován čas ukončení",
"Subject": "Předmět",
"Message": "Zpráva"
}

View File

@ -141,5 +141,89 @@
"right": "højre",
"Close scanner": "Luk scanner",
"Switch camera": "Skift kamera",
"Ignore header row": "Ignorer overskriftsrække"
"Ignore header row": "Ignorer overskriftsrække",
"Data Type": "Datatype",
"Text": "Tekst",
"URL": "URL",
"Email": "E-mail",
"Phone": "Telefon",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Begivenhed",
"Invalid URL format": "Ugyldigt URL-format",
"Invalid email format": "Ugyldigt e-mail-format",
"Invalid phone number format": "Ugyldigt telefonnummerformat",
"Invalid WiFi format": "Ugyldigt WiFi-format",
"Invalid vCard format": "Ugyldigt vCard-format",
"Invalid location format": "Ugyldigt placeringsformat",
"Invalid event format": "Ugyldigt hændelsesformat",
"Network Name (SSID)": "Netværksnavn (SSID)",
"Password": "Adgangskode",
"Network Type": "Netværkstype",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Ingen",
"First Name": "Fornavn",
"Last Name": "Efternavn",
"Organization": "Organisation",
"Title": "Titel",
"Phone Number": "Telefonnummer",
"Email Address": "E-mail-adresse",
"Website": "Hjemmeside",
"Address": "Adresse",
"City": "By",
"State": "Stat",
"Zip Code": "Postnummer",
"Country": "Land",
"Notes": "Noter",
"Latitude": "Breddegrad",
"Longitude": "Længdegrad",
"Event Title": "Titel på begivenhed",
"Start Date": "Startdato",
"End Date": "Slutdato",
"Location": "Beliggenhed",
"Description": "Beskrivelse",
"Save": "Gemme",
"Have a beautiful day!": "Hav en dejlig dag!",
"Data templates": "Skabeloner til data",
"Hidden SSID": "Skjult SSID",
"Close dialog": "Luk dialogboksen",
"Use example": "Brug et eksempel",
"Required fields are marked with an asterisk (*)": "Obligatoriske felter er markeret med en stjerne (*)",
"Text is required": "Tekst er påkrævet",
"URL is required": "URL er påkrævet",
"Email address is required": "E-mail-adresse er påkrævet",
"Optional subject line": "Valgfri emnelinje",
"Optional email body": "Valgfri e-mailtekst",
"Phone number is required": "Telefonnummer er påkrævet",
"Optional SMS message": "Valgfri SMS-besked",
"Encryption": "Kryptering",
"No encryption": "Ingen kryptering",
"Wireless SSID": "Trådløs SSID",
"Your network name": "Dit netværksnavn",
"Wireless SSID is required": "Trådløs SSID er påkrævet",
"Network password (case-sensitive)": "Netværksadgangskode (skelner mellem store og små bogstaver)",
"Password is required when encryption is enabled": "Adgangskode er påkrævet, når kryptering er aktiveret",
"vCard Version": "vCard-version",
"e.g., John": "f.eks. John",
"e.g., Doe": "f.eks.",
"e.g., Acme Corp": "f.eks. Acme Corp.",
"e.g., Software Engineer": "f.eks. softwareingeniør",
"Phone (Work)": "Telefon (arbejde)",
"Phone (Private)": "Telefon (privat)",
"Phone (Mobile)": "Telefon (mobil)",
"Street": "Gade",
"Zipcode": "Postnummer",
"Latitude is required": "Breddegrad er påkrævet",
"Longitude is required": "Længdegrad er påkrævet",
"e.g., Team Meeting": "f.eks. teammøde",
"e.g., Conference Room A": "f.eks. konferencelokale A",
"Event Location": "Sted for begivenhed",
"Start Time": "Starttidspunkt",
"End Time": "Sluttidspunkt",
"Start time is required": "Starttidspunkt er påkrævet",
"End time is required": "Sluttidspunkt er påkrævet",
"Subject": "Emne",
"Message": "Besked"
}

View File

@ -141,5 +141,89 @@
"right": "right",
"Close scanner": "Close scanner",
"Switch camera": "Switch camera",
"Ignore header row": "Ignore header row"
"Ignore header row": "Ignore header row",
"Data Type": "Data Type",
"Text": "Text",
"URL": "URL",
"Email": "Email",
"Phone": "Phone",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Event",
"Invalid URL format": "Invalid URL format",
"Invalid email format": "Invalid email format",
"Invalid phone number format": "Invalid phone number format",
"Invalid WiFi format": "Invalid WiFi format",
"Invalid vCard format": "Invalid vCard format",
"Invalid location format": "Invalid location format",
"Invalid event format": "Invalid event format",
"Network Name (SSID)": "Network Name (SSID)",
"Password": "Password",
"Network Type": "Network Type",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "None",
"First Name": "First Name",
"Last Name": "Last Name",
"Organization": "Organization",
"Title": "Title",
"Phone Number": "Phone Number",
"Email Address": "Email Address",
"Website": "Website",
"Address": "Address",
"City": "City",
"State": "State",
"Zip Code": "Zip Code",
"Country": "Country",
"Notes": "Notes",
"Latitude": "Latitude",
"Longitude": "Longitude",
"Event Title": "Event Title",
"Start Date": "Start Date",
"End Date": "End Date",
"Location": "Location",
"Description": "Description",
"Save": "Save",
"Have a beautiful day!": "Have a beautiful day!",
"Data templates": "Data templates",
"Hidden SSID": "Hidden SSID",
"Close dialog": "Close dialog",
"Use example": "Use example",
"Required fields are marked with an asterisk (*)": "Required fields are marked with an asterisk (*)",
"Text is required": "Text is required",
"URL is required": "URL is required",
"Email address is required": "Email address is required",
"Optional subject line": "Optional subject line",
"Optional email body": "Optional email body",
"Phone number is required": "Phone number is required",
"Optional SMS message": "Optional SMS message",
"Encryption": "Encryption",
"No encryption": "No encryption",
"Wireless SSID": "Wireless SSID",
"Your network name": "Your network name",
"Wireless SSID is required": "Wireless SSID is required",
"Network password (case-sensitive)": "Network password (case-sensitive)",
"Password is required when encryption is enabled": "Password is required when encryption is enabled",
"vCard Version": "vCard Version",
"e.g., John": "e.g., John",
"e.g., Doe": "e.g., Doe",
"e.g., Acme Corp": "e.g., Acme Corp",
"e.g., Software Engineer": "e.g., Software Engineer",
"Phone (Work)": "Phone (Work)",
"Phone (Private)": "Phone (Private)",
"Phone (Mobile)": "Phone (Mobile)",
"Street": "Street",
"Zipcode": "Zipcode",
"Latitude is required": "Latitude is required",
"Longitude is required": "Longitude is required",
"e.g., Team Meeting": "e.g., Team Meeting",
"e.g., Conference Room A": "e.g., Conference Room A",
"Event Location": "Event Location",
"Start Time": "Start Time",
"End Time": "End Time",
"Start time is required": "Start time is required",
"End time is required": "End time is required",
"Subject": "Subject",
"Message": "Message"
}

View File

@ -141,5 +141,89 @@
"right": "δεξιά",
"Close scanner": "Κλείσιμο σαρωτή",
"Switch camera": "Εναλλαγή κάμερας",
"Ignore header row": "Αγνοήστε τη γραμμή κεφαλίδας"
"Ignore header row": "Αγνοήστε τη γραμμή κεφαλίδας",
"Data Type": "Τύπος δεδομένων",
"Text": "Κείμενο",
"URL": "URL",
"Email": "Ηλεκτρονικό ταχυδρομείο",
"Phone": "Τηλέφωνο",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Εκδήλωση",
"Invalid URL format": "Μη έγκυρη μορφή URL",
"Invalid email format": "Μη έγκυρη μορφή email",
"Invalid phone number format": "Μη έγκυρη μορφή αριθμού τηλεφώνου",
"Invalid WiFi format": "Μη έγκυρη μορφή WiFi",
"Invalid vCard format": "Μη έγκυρη μορφή vCard",
"Invalid location format": "Μη έγκυρη μορφή τοποθεσίας",
"Invalid event format": "Μη έγκυρη μορφή συμβάντος",
"Network Name (SSID)": "Όνομα δικτύου (SSID)",
"Password": "Κωδικός πρόσβασης",
"Network Type": "Τύπος δικτύου",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Κανένα",
"First Name": "Όνομα",
"Last Name": "Επώνυμο",
"Organization": "Οργανισμός",
"Title": "Τίτλος",
"Phone Number": "Αριθμός τηλεφώνου",
"Email Address": "Διεύθυνση ηλεκτρονικού ταχυδρομείου",
"Website": "Ιστοσελίδα",
"Address": "Διεύθυνση",
"City": "Πόλη",
"State": "Κράτος",
"Zip Code": "Ταχυδρομικός κώδικας",
"Country": "Χώρα",
"Notes": "Σημειώσεις",
"Latitude": "Γεωγραφικό πλάτος",
"Longitude": "Γεωγραφικό μήκος",
"Event Title": "Τίτλος εκδήλωσης",
"Start Date": "Ημερομηνία έναρξης",
"End Date": "Ημερομηνία λήξης",
"Location": "Τοποθεσία",
"Description": "Περιγραφή",
"Save": "Αποθήκευση",
"Have a beautiful day!": "Να έχετε μια όμορφη μέρα!",
"Data templates": "Πρότυπα δεδομένων",
"Hidden SSID": "Κρυφό SSID",
"Close dialog": "Κλείσιμο διαλόγου",
"Use example": "Χρήση παραδείγματος",
"Required fields are marked with an asterisk (*)": "Τα υποχρεωτικά πεδία επισημαίνονται με αστερίσκο (*)",
"Text is required": "Απαιτείται κείμενο",
"URL is required": "Απαιτείται URL",
"Email address is required": "Απαιτείται διεύθυνση ηλεκτρονικού ταχυδρομείου",
"Optional subject line": "Προαιρετική γραμμή θέματος",
"Optional email body": "Προαιρετικό σώμα email",
"Phone number is required": "Απαιτείται αριθμός τηλεφώνου",
"Optional SMS message": "Προαιρετικό μήνυμα SMS",
"Encryption": "Κρυπτογράφηση",
"No encryption": "Δεν υπάρχει κρυπτογράφηση",
"Wireless SSID": "Ασύρματο SSID",
"Your network name": "Το όνομα του δικτύου σας",
"Wireless SSID is required": "Απαιτείται ασύρματο SSID",
"Network password (case-sensitive)": "Κωδικός πρόσβασης δικτύου (ευαίσθητη στην πεζότητα)",
"Password is required when encryption is enabled": "Απαιτείται κωδικός πρόσβασης όταν είναι ενεργοποιημένη η κρυπτογράφηση",
"vCard Version": "Έκδοση vCard",
"e.g., John": "π.χ., John",
"e.g., Doe": "π.χ., Doe",
"e.g., Acme Corp": "π.χ., Acme Corp",
"e.g., Software Engineer": "π.χ., Μηχανικός λογισμικού",
"Phone (Work)": "Τηλέφωνο (εργασίας)",
"Phone (Private)": "Τηλέφωνο (ιδιωτικό)",
"Phone (Mobile)": "Τηλέφωνο (κινητό)",
"Street": "Οδός",
"Zipcode": "Ταχυδρομικός κώδικας",
"Latitude is required": "Απαιτείται γεωγραφικό πλάτος",
"Longitude is required": "Απαιτείται γεωγραφικό μήκος",
"e.g., Team Meeting": "π.χ., συνάντηση ομάδας",
"e.g., Conference Room A": "π.χ., αίθουσα συνεδριάσεων Α",
"Event Location": "Τοποθεσία εκδήλωσης",
"Start Time": "Ώρα έναρξης",
"End Time": "Χρόνος τέλους",
"Start time is required": "Απαιτείται ώρα έναρξης",
"End time is required": "Απαιτείται χρόνος λήξης",
"Subject": "Θέμα",
"Message": "Μήνυμα"
}

View File

@ -141,5 +141,89 @@
"right": "right",
"Close scanner": "Close scanner",
"Switch camera": "Switch camera",
"Ignore header row": "Ignore header row"
"Ignore header row": "Ignore header row",
"Data Type": "Data Type",
"Text": "Text",
"URL": "URL",
"Email": "Email",
"Phone": "Phone",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Event",
"Invalid URL format": "Invalid URL format",
"Invalid email format": "Invalid email format",
"Invalid phone number format": "Invalid phone number format",
"Invalid WiFi format": "Invalid WiFi format",
"Invalid vCard format": "Invalid vCard format",
"Invalid location format": "Invalid location format",
"Invalid event format": "Invalid event format",
"Network Name (SSID)": "Network Name (SSID)",
"Password": "Password",
"Network Type": "Network Type",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "None",
"First Name": "First Name",
"Last Name": "Last Name",
"Organization": "Organization",
"Title": "Title",
"Phone Number": "Phone Number",
"Email Address": "Email Address",
"Website": "Website",
"Address": "Address",
"City": "City",
"State": "State",
"Zip Code": "Zip Code",
"Country": "Country",
"Notes": "Notes",
"Latitude": "Latitude",
"Longitude": "Longitude",
"Event Title": "Event Title",
"Start Date": "Start Date",
"End Date": "End Date",
"Location": "Location",
"Description": "Description",
"Save": "Save",
"Have a beautiful day!": "Have a beautiful day!",
"Data templates": "Data templates",
"Hidden SSID": "Hidden SSID",
"Close dialog": "Close dialog",
"Use example": "Use example",
"Required fields are marked with an asterisk (*)": "Required fields are marked with an asterisk (*)",
"Text is required": "Text is required",
"URL is required": "URL is required",
"Email address is required": "Email address is required",
"Optional subject line": "Optional subject line",
"Optional email body": "Optional email body",
"Phone number is required": "Phone number is required",
"Optional SMS message": "Optional SMS message",
"Encryption": "Encryption",
"No encryption": "No encryption",
"Wireless SSID": "Wireless SSID",
"Your network name": "Your network name",
"Wireless SSID is required": "Wireless SSID is required",
"Network password (case-sensitive)": "Network password (case-sensitive)",
"Password is required when encryption is enabled": "Password is required when encryption is enabled",
"vCard Version": "vCard Version",
"e.g., John": "e.g., John",
"e.g., Doe": "e.g., Doe",
"e.g., Acme Corp": "e.g., Acme Corp",
"e.g., Software Engineer": "e.g., Software Engineer",
"Phone (Work)": "Phone (Work)",
"Phone (Private)": "Phone (Private)",
"Phone (Mobile)": "Phone (Mobile)",
"Street": "Street",
"Zipcode": "Zipcode",
"Latitude is required": "Latitude is required",
"Longitude is required": "Longitude is required",
"e.g., Team Meeting": "e.g., Team Meeting",
"e.g., Conference Room A": "e.g., Conference Room A",
"Event Location": "Event Location",
"Start Time": "Start Time",
"End Time": "End Time",
"Start time is required": "Start time is required",
"End time is required": "End time is required",
"Subject": "Subject",
"Message": "Message"
}

View File

@ -141,5 +141,89 @@
"right": "derecha",
"Close scanner": "Cerrar escáner",
"Switch camera": "Cambiar cámara",
"Ignore header row": "Ignorar fila de cabecera"
"Ignore header row": "Ignorar fila de cabecera",
"Data Type": "Tipo de datos",
"Text": "Texto",
"URL": "URL",
"Email": "Correo electrónico",
"Phone": "Teléfono",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Evento",
"Invalid URL format": "Formato de URL no válido",
"Invalid email format": "Formato de correo electrónico no válido",
"Invalid phone number format": "Formato de número de teléfono no válido",
"Invalid WiFi format": "Formato WiFi no válido",
"Invalid vCard format": "Formato vCard no válido",
"Invalid location format": "Formato de ubicación no válido",
"Invalid event format": "Formato de evento no válido",
"Network Name (SSID)": "Nombre de la red (SSID)",
"Password": "Contraseña",
"Network Type": "Tipo de red",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Ninguno",
"First Name": "Nombre",
"Last Name": "Apellido",
"Organization": "Organización",
"Title": "Título",
"Phone Number": "Número de teléfono",
"Email Address": "Dirección de correo electrónico",
"Website": "Página web",
"Address": "Dirección",
"City": "Ciudad",
"State": "Estado",
"Zip Code": "Código postal",
"Country": "País",
"Notes": "Notas",
"Latitude": "Latitud",
"Longitude": "Longitud",
"Event Title": "Título del evento",
"Start Date": "Fecha de inicio",
"End Date": "Fecha final",
"Location": "Ubicación",
"Description": "Descripción",
"Save": "Guardar",
"Have a beautiful day!": "Que tenga un buen día.",
"Data templates": "Plantillas de datos",
"Hidden SSID": "SSID oculto",
"Close dialog": "Cerrar diálogo",
"Use example": "Utilice el ejemplo",
"Required fields are marked with an asterisk (*)": "Los campos obligatorios están marcados con un asterisco (*)",
"Text is required": "Texto obligatorio",
"URL is required": "URL obligatoria",
"Email address is required": "Dirección de correo electrónico obligatoria",
"Optional subject line": "Asunto opcional",
"Optional email body": "Cuerpo opcional del correo electrónico",
"Phone number is required": "Número de teléfono obligatorio",
"Optional SMS message": "Mensaje SMS opcional",
"Encryption": "Cifrado",
"No encryption": "Sin encriptación",
"Wireless SSID": "SSID inalámbrico",
"Your network name": "Su nombre de red",
"Wireless SSID is required": "Se requiere SSID inalámbrico",
"Network password (case-sensitive)": "Contraseña de red (distingue mayúsculas de minúsculas)",
"Password is required when encryption is enabled": "La contraseña es necesaria cuando la encriptación está activada",
"vCard Version": "Versión vCard",
"e.g., John": "por ejemplo, John",
"e.g., Doe": "por ejemplo, Doe",
"e.g., Acme Corp": "por ejemplo, Acme Corp",
"e.g., Software Engineer": "por ejemplo, Ingeniero de Software",
"Phone (Work)": "Teléfono (trabajo)",
"Phone (Private)": "Teléfono (privado)",
"Phone (Mobile)": "Teléfono (móvil)",
"Street": "Calle",
"Zipcode": "Código postal",
"Latitude is required": "Se requiere latitud",
"Longitude is required": "Se requiere longitud",
"e.g., Team Meeting": "p. ej., Reunión de equipo",
"e.g., Conference Room A": "por ejemplo, Sala de Conferencias A",
"Event Location": "Lugar del evento",
"Start Time": "Hora de inicio",
"End Time": "Fin de los tiempos",
"Start time is required": "Se requiere hora de inicio",
"End time is required": "Se requiere hora de finalización",
"Subject": "Asunto",
"Message": "Mensaje"
}

View File

@ -141,5 +141,89 @@
"right": "oikea",
"Close scanner": "Sulje skanneri",
"Switch camera": "Vaihda kameraa",
"Ignore header row": "Jätä otsikkorivi huomiotta"
"Ignore header row": "Jätä otsikkorivi huomiotta",
"Data Type": "Tietotyyppi",
"Text": "Teksti",
"URL": "URL",
"Email": "Sähköposti",
"Phone": "Puhelin",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Tapahtuma",
"Invalid URL format": "Virheellinen URL-muoto",
"Invalid email format": "Virheellinen sähköpostimuoto",
"Invalid phone number format": "Väärä puhelinnumeron muoto",
"Invalid WiFi format": "Virheellinen WiFi-muoto",
"Invalid vCard format": "Virheellinen vCard-muoto",
"Invalid location format": "Virheellinen sijaintiformaatti",
"Invalid event format": "Virheellinen tapahtumaformaatti",
"Network Name (SSID)": "Verkon nimi (SSID)",
"Password": "Salasana",
"Network Type": "Verkkotyyppi",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Ei ole",
"First Name": "Etunimi",
"Last Name": "Sukunimi",
"Organization": "Organisaatio",
"Title": "Otsikko",
"Phone Number": "Puhelinnumero",
"Email Address": "Sähköpostiosoite",
"Website": "Verkkosivusto",
"Address": "Osoite",
"City": "Kaupunki",
"State": "Valtio",
"Zip Code": "Postinumero",
"Country": "Maa",
"Notes": "Huomautukset",
"Latitude": "Leveysaste",
"Longitude": "Pituusaste",
"Event Title": "Tapahtuman nimi",
"Start Date": "Aloituspäivä",
"End Date": "Loppupäivä",
"Location": "Sijainti",
"Description": "Kuvaus",
"Save": "Tallenna",
"Have a beautiful day!": "Kaunista päivää!",
"Data templates": "Tietomallit",
"Hidden SSID": "Piilotettu SSID",
"Close dialog": "Sulje valintaikkuna",
"Use example": "Käytä esimerkkiä",
"Required fields are marked with an asterisk (*)": "Pakolliset kentät on merkitty tähdellä (*).",
"Text is required": "Teksti vaaditaan",
"URL is required": "URL-osoite vaaditaan",
"Email address is required": "Sähköpostiosoite vaaditaan",
"Optional subject line": "Vapaaehtoinen otsikkorivi",
"Optional email body": "Valinnainen sähköpostin runko",
"Phone number is required": "Puhelinnumero vaaditaan",
"Optional SMS message": "Valinnainen tekstiviesti",
"Encryption": "Salaus",
"No encryption": "Ei salausta",
"Wireless SSID": "Langaton SSID",
"Your network name": "Verkon nimi",
"Wireless SSID is required": "Langaton SSID vaaditaan",
"Network password (case-sensitive)": "Verkon salasana (isojen ja pienten kirjainten erittely)",
"Password is required when encryption is enabled": "Salasana vaaditaan, kun salaus on käytössä",
"vCard Version": "vCard-versio",
"e.g., John": "esimerkiksi John",
"e.g., Doe": "esimerkiksi Doe",
"e.g., Acme Corp": "esim. Acme Corp.",
"e.g., Software Engineer": "esim. ohjelmistoinsinööri",
"Phone (Work)": "Puhelin (työ)",
"Phone (Private)": "Puhelin (yksityinen)",
"Phone (Mobile)": "Puhelin (matkapuhelin)",
"Street": "Street",
"Zipcode": "Postinumero",
"Latitude is required": "Vaaditaan leveysaste",
"Longitude is required": "Pituusaste vaaditaan",
"e.g., Team Meeting": "esim. tiimikokous",
"e.g., Conference Room A": "esim. kokoushuone A",
"Event Location": "Tapahtuman sijainti",
"Start Time": "Aloitusaika",
"End Time": "Loppuaika",
"Start time is required": "Aloitusaika vaaditaan",
"End time is required": "Loppuaika vaaditaan",
"Subject": "Aihe",
"Message": "Viesti"
}

View File

@ -141,5 +141,89 @@
"right": "à droite",
"Close scanner": "Fermer le scanner",
"Switch camera": "Changer de caméra",
"Ignore header row": "Ignorer la ligne d'en-tête"
"Ignore header row": "Ignorer la ligne d'en-tête",
"Data Type": "Type de données",
"Text": "Texte",
"URL": "URL",
"Email": "Courriel",
"Phone": "Téléphone",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Événement",
"Invalid URL format": "Format d'URL non valide",
"Invalid email format": "Format d'email non valide",
"Invalid phone number format": "Format de numéro de téléphone non valide",
"Invalid WiFi format": "Format WiFi non valide",
"Invalid vCard format": "Format vCard non valide",
"Invalid location format": "Format d'emplacement non valide",
"Invalid event format": "Format d'événement non valide",
"Network Name (SSID)": "Nom du réseau (SSID)",
"Password": "Mot de passe",
"Network Type": "Type de réseau",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Aucun",
"First Name": "Prénom",
"Last Name": "Nom de famille",
"Organization": "Organisation",
"Title": "Titre",
"Phone Number": "Numéro de téléphone",
"Email Address": "Adresse électronique",
"Website": "Site web",
"Address": "Adresse",
"City": "Ville",
"State": "État",
"Zip Code": "Code postal",
"Country": "Pays",
"Notes": "Notes",
"Latitude": "Latitude",
"Longitude": "Longitude",
"Event Title": "Titre de l'événement",
"Start Date": "Date de début",
"End Date": "Date de fin",
"Location": "Localisation",
"Description": "Description",
"Save": "Économiser",
"Have a beautiful day!": "Bonne journée !",
"Data templates": "Modèles de données",
"Hidden SSID": "SSID caché",
"Close dialog": "Fermer le dialogue",
"Use example": "Exemple d'utilisation",
"Required fields are marked with an asterisk (*)": "Les champs obligatoires sont marqués d'un astérisque (*)",
"Text is required": "Le texte est obligatoire",
"URL is required": "L'URL est obligatoire",
"Email address is required": "L'adresse électronique est requise",
"Optional subject line": "Objet facultatif",
"Optional email body": "Corps du message facultatif",
"Phone number is required": "Le numéro de téléphone est requis",
"Optional SMS message": "Message SMS facultatif",
"Encryption": "Cryptage",
"No encryption": "Pas de cryptage",
"Wireless SSID": "SSID sans fil",
"Your network name": "Votre nom de réseau",
"Wireless SSID is required": "Le SSID sans fil est requis",
"Network password (case-sensitive)": "Mot de passe du réseau (sensible à la casse)",
"Password is required when encryption is enabled": "Le mot de passe est requis lorsque le cryptage est activé",
"vCard Version": "Version vCard",
"e.g., John": "par exemple, John",
"e.g., Doe": "par exemple, Doe",
"e.g., Acme Corp": "par exemple, Acme Corp",
"e.g., Software Engineer": "par exemple, Ingénieur logiciel",
"Phone (Work)": "Téléphone (travail)",
"Phone (Private)": "Téléphone (privé)",
"Phone (Mobile)": "Téléphone (mobile)",
"Street": "Rue",
"Zipcode": "Code postal",
"Latitude is required": "La latitude est requise",
"Longitude is required": "La longitude est requise",
"e.g., Team Meeting": "par exemple, réunion d'équipe",
"e.g., Conference Room A": "par exemple, la salle de conférence A",
"Event Location": "Lieu de l'événement",
"Start Time": "Heure de début",
"End Time": "L'heure de la fin",
"Start time is required": "L'heure de début est requise",
"End time is required": "L'heure de fin est requise",
"Subject": "Sujet",
"Message": "Message"
}

View File

@ -141,5 +141,89 @@
"right": "right",
"Close scanner": "Close scanner",
"Switch camera": "Switch camera",
"Ignore header row": "Ignore header row"
"Ignore header row": "Ignore header row",
"Data Type": "Data Type",
"Text": "Text",
"URL": "URL",
"Email": "Email",
"Phone": "Phone",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Event",
"Invalid URL format": "Invalid URL format",
"Invalid email format": "Invalid email format",
"Invalid phone number format": "Invalid phone number format",
"Invalid WiFi format": "Invalid WiFi format",
"Invalid vCard format": "Invalid vCard format",
"Invalid location format": "Invalid location format",
"Invalid event format": "Invalid event format",
"Network Name (SSID)": "Network Name (SSID)",
"Password": "Password",
"Network Type": "Network Type",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "None",
"First Name": "First Name",
"Last Name": "Last Name",
"Organization": "Organization",
"Title": "Title",
"Phone Number": "Phone Number",
"Email Address": "Email Address",
"Website": "Website",
"Address": "Address",
"City": "City",
"State": "State",
"Zip Code": "Zip Code",
"Country": "Country",
"Notes": "Notes",
"Latitude": "Latitude",
"Longitude": "Longitude",
"Event Title": "Event Title",
"Start Date": "Start Date",
"End Date": "End Date",
"Location": "Location",
"Description": "Description",
"Save": "Save",
"Have a beautiful day!": "Have a beautiful day!",
"Data templates": "Data templates",
"Hidden SSID": "Hidden SSID",
"Close dialog": "Close dialog",
"Use example": "Use example",
"Required fields are marked with an asterisk (*)": "Required fields are marked with an asterisk (*)",
"Text is required": "Text is required",
"URL is required": "URL is required",
"Email address is required": "Email address is required",
"Optional subject line": "Optional subject line",
"Optional email body": "Optional email body",
"Phone number is required": "Phone number is required",
"Optional SMS message": "Optional SMS message",
"Encryption": "Encryption",
"No encryption": "No encryption",
"Wireless SSID": "Wireless SSID",
"Your network name": "Your network name",
"Wireless SSID is required": "Wireless SSID is required",
"Network password (case-sensitive)": "Network password (case-sensitive)",
"Password is required when encryption is enabled": "Password is required when encryption is enabled",
"vCard Version": "vCard Version",
"e.g., John": "e.g., John",
"e.g., Doe": "e.g., Doe",
"e.g., Acme Corp": "e.g., Acme Corp",
"e.g., Software Engineer": "e.g., Software Engineer",
"Phone (Work)": "Phone (Work)",
"Phone (Private)": "Phone (Private)",
"Phone (Mobile)": "Phone (Mobile)",
"Street": "Street",
"Zipcode": "Zipcode",
"Latitude is required": "Latitude is required",
"Longitude is required": "Longitude is required",
"e.g., Team Meeting": "e.g., Team Meeting",
"e.g., Conference Room A": "e.g., Conference Room A",
"Event Location": "Event Location",
"Start Time": "Start Time",
"End Time": "End Time",
"Start time is required": "Start time is required",
"End time is required": "End time is required",
"Subject": "Subject",
"Message": "Message"
}

View File

@ -141,5 +141,89 @@
"right": "jobbra",
"Close scanner": "Szkenner bezárása",
"Switch camera": "Kamera váltás",
"Ignore header row": "Fejléc sor figyelmen kívül hagyása"
"Ignore header row": "Fejléc sor figyelmen kívül hagyása",
"Data Type": "Adattípus",
"Text": "Szöveg",
"URL": "URL",
"Email": "E-mail",
"Phone": "Telefon",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Esemény",
"Invalid URL format": "Érvénytelen URL formátum",
"Invalid email format": "Érvénytelen e-mail formátum",
"Invalid phone number format": "Érvénytelen telefonszám formátum",
"Invalid WiFi format": "Érvénytelen WiFi formátum",
"Invalid vCard format": "Érvénytelen vCard formátum",
"Invalid location format": "Érvénytelen hely formátum",
"Invalid event format": "Érvénytelen esemény formátum",
"Network Name (SSID)": "Hálózati név (SSID)",
"Password": "Jelszó",
"Network Type": "Hálózat típusa",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Nincs",
"First Name": "Keresztnév",
"Last Name": "Vezetéknév",
"Organization": "Szervezet",
"Title": "Cím",
"Phone Number": "Telefonszám",
"Email Address": "E-mail cím",
"Website": "Honlap",
"Address": "Cím:",
"City": "Város",
"State": "Állam",
"Zip Code": "Irányítószám",
"Country": "Ország",
"Notes": "Megjegyzések",
"Latitude": "Szélesség",
"Longitude": "Hosszúság",
"Event Title": "Esemény címe",
"Start Date": "Kezdeti dátum",
"End Date": "Végdátum",
"Location": "Helyszín",
"Description": "Leírás",
"Save": "Mentés",
"Have a beautiful day!": "Legyen szép napod!",
"Data templates": "Adatsablonok",
"Hidden SSID": "Rejtett SSID",
"Close dialog": "Bezár párbeszédpanel",
"Use example": "Használjon példát",
"Required fields are marked with an asterisk (*)": "A kötelezően kitöltendő mezőket csillaggal (*) jelöljük.",
"Text is required": "Szöveg szükséges",
"URL is required": "URL szükséges",
"Email address is required": "Email cím szükséges",
"Optional subject line": "Választható tárgysor",
"Optional email body": "Választható e-mail szöveg",
"Phone number is required": "Telefonszám szükséges",
"Optional SMS message": "Választható SMS üzenet",
"Encryption": "Titkosítás",
"No encryption": "Nincs titkosítás",
"Wireless SSID": "Vezeték nélküli SSID",
"Your network name": "A hálózat neve",
"Wireless SSID is required": "Vezeték nélküli SSID szükséges",
"Network password (case-sensitive)": "Hálózati jelszó (nagy- és kisbetű-érzékeny)",
"Password is required when encryption is enabled": "Jelszó szükséges, ha a titkosítás engedélyezve van",
"vCard Version": "vCard verzió",
"e.g., John": "pl. John",
"e.g., Doe": "pl. Doe",
"e.g., Acme Corp": "pl. Acme Corp.",
"e.g., Software Engineer": "pl. szoftvermérnök",
"Phone (Work)": "Telefon (munka)",
"Phone (Private)": "Telefon (magán)",
"Phone (Mobile)": "Telefon (mobil)",
"Street": "Street",
"Zipcode": "Irányítószám",
"Latitude is required": "Szükséges a földrajzi szélesség",
"Longitude is required": "Hosszúságra van szükség",
"e.g., Team Meeting": "pl. Csapatértekezlet",
"e.g., Conference Room A": "pl. A konferenciaterem",
"Event Location": "Esemény helye",
"Start Time": "Kezdési idő",
"End Time": "Végidő",
"Start time is required": "A kezdési időre van szükség",
"End time is required": "Végidőre van szükség",
"Subject": "Tárgy:",
"Message": "Üzenet"
}

View File

@ -141,5 +141,89 @@
"right": "destra",
"Close scanner": "Chiudi scanner",
"Switch camera": "Cambia fotocamera",
"Ignore header row": "Ignora riga di intestazione"
"Ignore header row": "Ignora riga di intestazione",
"Data Type": "Tipo di dati",
"Text": "Testo",
"URL": "URL",
"Email": "Email",
"Phone": "Telefono",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Evento",
"Invalid URL format": "Formato URL non valido",
"Invalid email format": "Formato e-mail non valido",
"Invalid phone number format": "Formato del numero di telefono non valido",
"Invalid WiFi format": "Formato WiFi non valido",
"Invalid vCard format": "Formato vCard non valido",
"Invalid location format": "Formato della posizione non valido",
"Invalid event format": "Formato evento non valido",
"Network Name (SSID)": "Nome della rete (SSID)",
"Password": "Password",
"Network Type": "Tipo di rete",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Nessuno",
"First Name": "Nome",
"Last Name": "Cognome",
"Organization": "Organizzazione",
"Title": "Titolo",
"Phone Number": "Numero di telefono",
"Email Address": "Indirizzo e-mail",
"Website": "Sito web",
"Address": "Indirizzo",
"City": "Città",
"State": "Stato",
"Zip Code": "Codice postale",
"Country": "Paese",
"Notes": "Note",
"Latitude": "Latitudine",
"Longitude": "Longitudine",
"Event Title": "Titolo dell'evento",
"Start Date": "Data di inizio",
"End Date": "Data di fine",
"Location": "Posizione",
"Description": "Descrizione",
"Save": "Risparmiare",
"Have a beautiful day!": "Buona giornata!",
"Data templates": "Modelli di dati",
"Hidden SSID": "SSID nascosto",
"Close dialog": "Chiudere la finestra di dialogo",
"Use example": "Esempio di utilizzo",
"Required fields are marked with an asterisk (*)": "I campi obbligatori sono contrassegnati da un asterisco (*).",
"Text is required": "Il testo è richiesto",
"URL is required": "L'URL è richiesto",
"Email address is required": "L'indirizzo e-mail è richiesto",
"Optional subject line": "Oggetto facoltativo",
"Optional email body": "Corpo dell'e-mail opzionale",
"Phone number is required": "Il numero di telefono è richiesto",
"Optional SMS message": "Messaggio SMS opzionale",
"Encryption": "Crittografia",
"No encryption": "Nessuna crittografia",
"Wireless SSID": "SSID wireless",
"Your network name": "Il nome della rete",
"Wireless SSID is required": "È necessario un SSID wireless",
"Network password (case-sensitive)": "Password di rete (sensibile alle maiuscole)",
"Password is required when encryption is enabled": "La password è richiesta quando la crittografia è abilitata",
"vCard Version": "Versione vCard",
"e.g., John": "ad esempio, Giovanni",
"e.g., Doe": "ad esempio, Doe",
"e.g., Acme Corp": "ad esempio, Acme Corp",
"e.g., Software Engineer": "ad esempio, Ingegnere del software",
"Phone (Work)": "Telefono (lavoro)",
"Phone (Private)": "Telefono (privato)",
"Phone (Mobile)": "Telefono (cellulare)",
"Street": "Via",
"Zipcode": "Codice postale",
"Latitude is required": "È richiesta la latitudine",
"Longitude is required": "È richiesta la longitudine",
"e.g., Team Meeting": "Ad esempio, riunione di squadra",
"e.g., Conference Room A": "ad esempio, Sala conferenze A",
"Event Location": "Luogo dell'evento",
"Start Time": "Ora di inizio",
"End Time": "Tempo di fine",
"Start time is required": "È richiesta l'ora di inizio",
"End time is required": "L'ora di fine è richiesta",
"Subject": "Oggetto",
"Message": "Messaggio"
}

View File

@ -141,5 +141,89 @@
"right": "右|右",
"Close scanner": "スキャナーを閉じる",
"Switch camera": "カメラを切り替える",
"Ignore header row": "ヘッダー行を無視する"
"Ignore header row": "ヘッダー行を無視する",
"Data Type": "データタイプ",
"Text": "テキスト",
"URL": "URL",
"Email": "電子メール",
"Phone": "電話",
"SMS": "ショートメール",
"WiFi": "WiFi",
"vCard": "vカード",
"Event": "イベント",
"Invalid URL format": "無効なURL形式",
"Invalid email format": "無効な電子メール形式",
"Invalid phone number format": "無効な電話番号形式",
"Invalid WiFi format": "無効なWiFiフォーマット",
"Invalid vCard format": "無効なvCardフォーマット",
"Invalid location format": "無効なロケーション形式",
"Invalid event format": "無効なイベント形式",
"Network Name (SSID)": "ネットワーク名SSID",
"Password": "パスワード",
"Network Type": "ネットワークタイプ",
"WPA/WPA2": "WPA/WPA2",
"WEP": "ウェップ",
"None": "なし",
"First Name": "名前",
"Last Name": "ラストネーム",
"Organization": "組織",
"Title": "タイトル",
"Phone Number": "電話番号",
"Email Address": "メールアドレス",
"Website": "ウェブサイト",
"Address": "住所",
"City": "都市",
"State": "州",
"Zip Code": "郵便番号",
"Country": "国名",
"Notes": "備考",
"Latitude": "緯度",
"Longitude": "経度",
"Event Title": "イベント名",
"Start Date": "開始日",
"End Date": "終了日",
"Location": "所在地",
"Description": "説明",
"Save": "セーブ",
"Have a beautiful day!": "良い一日を!",
"Data templates": "データテンプレート",
"Hidden SSID": "隠しSSID",
"Close dialog": "ダイアログを閉じる",
"Use example": "使用例",
"Required fields are marked with an asterisk (*)": "は必須項目です。",
"Text is required": "テキストが必要",
"URL is required": "URLは必須",
"Email address is required": "メールアドレスは必須",
"Optional subject line": "任意の件名",
"Optional email body": "メール本文",
"Phone number is required": "電話番号は必須",
"Optional SMS message": "オプションのSMSメッセージ",
"Encryption": "暗号化",
"No encryption": "暗号化なし",
"Wireless SSID": "ワイヤレスSSID",
"Your network name": "ネットワーク名",
"Wireless SSID is required": "ワイヤレスSSIDが必要",
"Network password (case-sensitive)": "ネットワークパスワード(大文字と小文字を区別)",
"Password is required when encryption is enabled": "暗号化が有効な場合はパスワードが必要",
"vCard Version": "vCardバージョン",
"e.g., John": "例:ジョン",
"e.g., Doe": "例:ドウ",
"e.g., Acme Corp": "例:アクメ社",
"e.g., Software Engineer": "例:ソフトウェア・エンジニア",
"Phone (Work)": "電話番号(勤務先)",
"Phone (Private)": "電話 (プライベート)",
"Phone (Mobile)": "電話番号(携帯)",
"Street": "ストリート",
"Zipcode": "ジップコード",
"Latitude is required": "緯度が必要",
"Longitude is required": "経度が必要",
"e.g., Team Meeting": "例:チームミーティング",
"e.g., Conference Room A": "例会議室A",
"Event Location": "イベント会場",
"Start Time": "開始時間",
"End Time": "終了時間",
"Start time is required": "開始時間が必要",
"End time is required": "終了時間が必要",
"Subject": "テーマ",
"Message": "メッセージ"
}

View File

@ -141,5 +141,89 @@
"right": "오른쪽",
"Close scanner": "스캐너 닫기",
"Switch camera": "카메라 전환",
"Ignore header row": "헤더 행 무시"
"Ignore header row": "헤더 행 무시",
"Data Type": "데이터 유형",
"Text": "텍스트",
"URL": "URL",
"Email": "이메일",
"Phone": "전화",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "이벤트",
"Invalid URL format": "잘못된 URL 형식",
"Invalid email format": "잘못된 이메일 형식",
"Invalid phone number format": "잘못된 전화 번호 형식",
"Invalid WiFi format": "잘못된 WiFi 형식",
"Invalid vCard format": "잘못된 vCard 형식",
"Invalid location format": "잘못된 위치 형식",
"Invalid event format": "잘못된 이벤트 형식",
"Network Name (SSID)": "네트워크 이름(SSID)",
"Password": "비밀번호",
"Network Type": "네트워크 유형",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "없음",
"First Name": "이름",
"Last Name": "성",
"Organization": "조직",
"Title": "제목",
"Phone Number": "전화 번호",
"Email Address": "이메일 주소",
"Website": "웹사이트",
"Address": "주소",
"City": "도시",
"State": "상태",
"Zip Code": "우편 번호",
"Country": "국가",
"Notes": "참고",
"Latitude": "위도",
"Longitude": "경도",
"Event Title": "이벤트 제목",
"Start Date": "시작 날짜",
"End Date": "종료 날짜",
"Location": "위치",
"Description": "설명",
"Save": "저장",
"Have a beautiful day!": "아름다운 하루 되세요!",
"Data templates": "데이터 템플릿",
"Hidden SSID": "숨겨진 SSID",
"Close dialog": "대화 상자 닫기",
"Use example": "사용 예",
"Required fields are marked with an asterisk (*)": "필수 필드는 별표(*)로 표시되어 있습니다.",
"Text is required": "텍스트 입력 필수",
"URL is required": "URL은 필수입니다.",
"Email address is required": "이메일 주소는 필수 입력 사항입니다.",
"Optional subject line": "선택적 제목",
"Optional email body": "이메일 본문(선택 사항)",
"Phone number is required": "전화번호 필수 입력",
"Optional SMS message": "선택적 SMS 메시지",
"Encryption": "암호화",
"No encryption": "암호화 없음",
"Wireless SSID": "무선 SSID",
"Your network name": "네트워크 이름",
"Wireless SSID is required": "무선 SSID가 필요합니다.",
"Network password (case-sensitive)": "네트워크 비밀번호(대소문자 구분)",
"Password is required when encryption is enabled": "암호화를 사용하도록 설정한 경우 비밀번호가 필요합니다.",
"vCard Version": "vCard 버전",
"e.g., John": "예: John",
"e.g., Doe": "예: 신원 미상",
"e.g., Acme Corp": "예: Acme Corp",
"e.g., Software Engineer": "예: 소프트웨어 엔지니어",
"Phone (Work)": "전화(업무용)",
"Phone (Private)": "전화(비공개)",
"Phone (Mobile)": "전화(모바일)",
"Street": "거리",
"Zipcode": "우편번호",
"Latitude is required": "위도 필수",
"Longitude is required": "경도가 필요합니다.",
"e.g., Team Meeting": "예: 팀 회의",
"e.g., Conference Room A": "예: 회의실 A",
"Event Location": "이벤트 위치",
"Start Time": "시작 시간",
"End Time": "종료 시간",
"Start time is required": "시작 시간이 필요합니다.",
"End time is required": "종료 시간이 필요합니다.",
"Subject": "제목",
"Message": "메시지"
}

View File

@ -141,5 +141,89 @@
"right": "rechts",
"Close scanner": "Sluit scanner",
"Switch camera": "Wijzig camera",
"Ignore header row": "Kopregel negeren"
"Ignore header row": "Kopregel negeren",
"Data Type": "Gegevenstype",
"Text": "Tekst",
"URL": "URL",
"Email": "E-mail",
"Phone": "Telefoon",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Evenement",
"Invalid URL format": "Ongeldig URL-formaat",
"Invalid email format": "Ongeldig e-mailformaat",
"Invalid phone number format": "Ongeldig formaat telefoonnummer",
"Invalid WiFi format": "Ongeldig WiFi-formaat",
"Invalid vCard format": "Ongeldig vCard-formaat",
"Invalid location format": "Ongeldige locatie-indeling",
"Invalid event format": "Ongeldig gebeurtenisformaat",
"Network Name (SSID)": "Netwerknaam (SSID)",
"Password": "Wachtwoord",
"Network Type": "Type netwerk",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Geen",
"First Name": "Voornaam",
"Last Name": "Achternaam",
"Organization": "Organisatie",
"Title": "Titel",
"Phone Number": "Telefoonnummer",
"Email Address": "E-mailadres",
"Website": "Website",
"Address": "Adres",
"City": "Stad",
"State": "Staat",
"Zip Code": "Postcode",
"Country": "Land",
"Notes": "Opmerkingen",
"Latitude": "Breedte",
"Longitude": "Lengte",
"Event Title": "Titel evenement",
"Start Date": "Startdatum",
"End Date": "Einddatum",
"Location": "Locatie",
"Description": "Beschrijving",
"Save": "Sla",
"Have a beautiful day!": "Heb een mooie dag!",
"Data templates": "Gegevenssjablonen",
"Hidden SSID": "Verborgen SSID",
"Close dialog": "Dialoog sluiten",
"Use example": "Voorbeeld gebruiken",
"Required fields are marked with an asterisk (*)": "Verplichte velden zijn gemarkeerd met een sterretje (*)",
"Text is required": "Tekst is vereist",
"URL is required": "URL is vereist",
"Email address is required": "E-mailadres is vereist",
"Optional subject line": "Optionele onderwerpregel",
"Optional email body": "Optionele e-mailtekst",
"Phone number is required": "Telefoonnummer is vereist",
"Optional SMS message": "Optioneel SMS-bericht",
"Encryption": "Encryptie",
"No encryption": "Geen versleuteling",
"Wireless SSID": "Draadloze SSID",
"Your network name": "Je netwerknaam",
"Wireless SSID is required": "Draadloze SSID is vereist",
"Network password (case-sensitive)": "Netwerkwachtwoord (hoofdlettergevoelig)",
"Password is required when encryption is enabled": "Wachtwoord is vereist als versleuteling is ingeschakeld",
"vCard Version": "vCard-versie",
"e.g., John": "bijv.",
"e.g., Doe": "bijv. Doe",
"e.g., Acme Corp": "bijv. Acme Corp",
"e.g., Software Engineer": "bijv. software-ingenieur",
"Phone (Work)": "Telefoon (werk)",
"Phone (Private)": "Telefoon (privé)",
"Phone (Mobile)": "Telefoon (mobiel)",
"Street": "Straat",
"Zipcode": "Postcode",
"Latitude is required": "Breedtegraad is vereist",
"Longitude is required": "Lengtegraad is vereist",
"e.g., Team Meeting": "bijv. teamvergadering",
"e.g., Conference Room A": "bijv. conferentieruimte A",
"Event Location": "Locatie evenement",
"Start Time": "Starttijd",
"End Time": "Eindtijd",
"Start time is required": "Starttijd is vereist",
"End time is required": "Eindtijd is vereist",
"Subject": "Onderwerp",
"Message": "Bericht"
}

View File

@ -141,5 +141,89 @@
"right": "høyre",
"Close scanner": "Lukk skanner",
"Switch camera": "Bytt kamera",
"Ignore header row": "Ignore header row"
"Ignore header row": "Ignore header row",
"Data Type": "Data Type",
"Text": "Text",
"URL": "URL",
"Email": "Email",
"Phone": "Phone",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Event",
"Invalid URL format": "Invalid URL format",
"Invalid email format": "Invalid email format",
"Invalid phone number format": "Invalid phone number format",
"Invalid WiFi format": "Invalid WiFi format",
"Invalid vCard format": "Invalid vCard format",
"Invalid location format": "Invalid location format",
"Invalid event format": "Invalid event format",
"Network Name (SSID)": "Network Name (SSID)",
"Password": "Password",
"Network Type": "Network Type",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "None",
"First Name": "First Name",
"Last Name": "Last Name",
"Organization": "Organization",
"Title": "Title",
"Phone Number": "Phone Number",
"Email Address": "Email Address",
"Website": "Website",
"Address": "Address",
"City": "City",
"State": "State",
"Zip Code": "Zip Code",
"Country": "Country",
"Notes": "Notes",
"Latitude": "Latitude",
"Longitude": "Longitude",
"Event Title": "Event Title",
"Start Date": "Start Date",
"End Date": "End Date",
"Location": "Location",
"Description": "Description",
"Save": "Save",
"Have a beautiful day!": "Have a beautiful day!",
"Data templates": "Data templates",
"Hidden SSID": "Hidden SSID",
"Close dialog": "Close dialog",
"Use example": "Use example",
"Required fields are marked with an asterisk (*)": "Required fields are marked with an asterisk (*)",
"Text is required": "Text is required",
"URL is required": "URL is required",
"Email address is required": "Email address is required",
"Optional subject line": "Optional subject line",
"Optional email body": "Optional email body",
"Phone number is required": "Phone number is required",
"Optional SMS message": "Optional SMS message",
"Encryption": "Encryption",
"No encryption": "No encryption",
"Wireless SSID": "Wireless SSID",
"Your network name": "Your network name",
"Wireless SSID is required": "Wireless SSID is required",
"Network password (case-sensitive)": "Network password (case-sensitive)",
"Password is required when encryption is enabled": "Password is required when encryption is enabled",
"vCard Version": "vCard Version",
"e.g., John": "e.g., John",
"e.g., Doe": "e.g., Doe",
"e.g., Acme Corp": "e.g., Acme Corp",
"e.g., Software Engineer": "e.g., Software Engineer",
"Phone (Work)": "Phone (Work)",
"Phone (Private)": "Phone (Private)",
"Phone (Mobile)": "Phone (Mobile)",
"Street": "Street",
"Zipcode": "Zipcode",
"Latitude is required": "Latitude is required",
"Longitude is required": "Longitude is required",
"e.g., Team Meeting": "e.g., Team Meeting",
"e.g., Conference Room A": "e.g., Conference Room A",
"Event Location": "Event Location",
"Start Time": "Start Time",
"End Time": "End Time",
"Start time is required": "Start time is required",
"End time is required": "End time is required",
"Subject": "Subject",
"Message": "Message"
}

View File

@ -141,5 +141,89 @@
"right": "po prawej",
"Close scanner": "Zamknij skaner",
"Switch camera": "Przełącz aparat",
"Ignore header row": "Ignorowanie wiersza nagłówka"
"Ignore header row": "Ignorowanie wiersza nagłówka",
"Data Type": "Typ danych",
"Text": "Tekst",
"URL": "URL",
"Email": "E-mail",
"Phone": "Telefon",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Wydarzenie",
"Invalid URL format": "Nieprawidłowy format adresu URL",
"Invalid email format": "Nieprawidłowy format wiadomości e-mail",
"Invalid phone number format": "Nieprawidłowy format numeru telefonu",
"Invalid WiFi format": "Nieprawidłowy format WiFi",
"Invalid vCard format": "Nieprawidłowy format vCard",
"Invalid location format": "Nieprawidłowy format lokalizacji",
"Invalid event format": "Nieprawidłowy format zdarzenia",
"Network Name (SSID)": "Nazwa sieci (SSID)",
"Password": "Hasło",
"Network Type": "Typ sieci",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Brak",
"First Name": "Imię",
"Last Name": "Nazwisko",
"Organization": "Organizacja",
"Title": "Tytuł",
"Phone Number": "Numer telefonu",
"Email Address": "Adres e-mail",
"Website": "Strona internetowa",
"Address": "Adres",
"City": "Miasto",
"State": "Stan",
"Zip Code": "Kod pocztowy",
"Country": "Kraj",
"Notes": "Uwagi",
"Latitude": "Szerokość geograficzna",
"Longitude": "Długość geograficzna",
"Event Title": "Tytuł wydarzenia",
"Start Date": "Data rozpoczęcia",
"End Date": "Data zakończenia",
"Location": "Lokalizacja",
"Description": "Opis",
"Save": "Zapisz",
"Have a beautiful day!": "Miłego dnia!",
"Data templates": "Szablony danych",
"Hidden SSID": "Ukryty identyfikator SSID",
"Close dialog": "Zamknij okno dialogowe",
"Use example": "Użyj przykładu",
"Required fields are marked with an asterisk (*)": "Wymagane pola są oznaczone gwiazdką (*).",
"Text is required": "Wymagany jest tekst",
"URL is required": "Wymagany jest adres URL",
"Email address is required": "Adres e-mail jest wymagany",
"Optional subject line": "Opcjonalny temat wiadomości",
"Optional email body": "Opcjonalna treść wiadomości e-mail",
"Phone number is required": "Numer telefonu jest wymagany",
"Optional SMS message": "Opcjonalna wiadomość SMS",
"Encryption": "Szyfrowanie",
"No encryption": "Brak szyfrowania",
"Wireless SSID": "Identyfikator SSID sieci bezprzewodowej",
"Your network name": "Nazwa sieci użytkownika",
"Wireless SSID is required": "Wymagany jest bezprzewodowy identyfikator SSID",
"Network password (case-sensitive)": "Hasło sieciowe (wielkość liter ma znaczenie)",
"Password is required when encryption is enabled": "Hasło jest wymagane, gdy włączone jest szyfrowanie",
"vCard Version": "Wersja vCard",
"e.g., John": "np. John",
"e.g., Doe": "np. Doe",
"e.g., Acme Corp": "np. Acme Corp",
"e.g., Software Engineer": "np. inżynier oprogramowania",
"Phone (Work)": "Telefon (służbowy)",
"Phone (Private)": "Telefon (prywatny)",
"Phone (Mobile)": "Telefon (komórkowy)",
"Street": "ul.",
"Zipcode": "Kod pocztowy",
"Latitude is required": "Wymagana jest szerokość geograficzna",
"Longitude is required": "Wymagana jest długość geograficzna",
"e.g., Team Meeting": "np. spotkanie zespołu",
"e.g., Conference Room A": "np. sala konferencyjna A",
"Event Location": "Lokalizacja wydarzenia",
"Start Time": "Godzina rozpoczęcia",
"End Time": "Czas zakończenia",
"Start time is required": "Wymagany jest czas rozpoczęcia",
"End time is required": "Wymagany jest czas zakończenia",
"Subject": "Przedmiot",
"Message": "Wiadomość"
}

View File

@ -141,5 +141,89 @@
"right": "Direita",
"Close scanner": "Fechar scanner",
"Switch camera": "Trocar câmera",
"Ignore header row": "Ignorar linha de cabeçalho"
"Ignore header row": "Ignorar linha de cabeçalho",
"Data Type": "Tipo de dados",
"Text": "Texto",
"URL": "URL",
"Email": "E-mail",
"Phone": "Telefone",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Evento",
"Invalid URL format": "Formato de URL inválido",
"Invalid email format": "Formato de e-mail inválido",
"Invalid phone number format": "Formato de número telefônico inválido",
"Invalid WiFi format": "Formato de WiFi inválido",
"Invalid vCard format": "Formato de vCard inválido",
"Invalid location format": "Formato de local inválido",
"Invalid event format": "Formato de evento inválido",
"Network Name (SSID)": "Nome da rede (SSID)",
"Password": "Senha",
"Network Type": "Tipo de rede",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Nenhum",
"First Name": "Primeiro nome",
"Last Name": "Sobrenome",
"Organization": "Organização",
"Title": "Título",
"Phone Number": "Número de telefone",
"Email Address": "Endereço de e-mail",
"Website": "Site",
"Address": "Endereço",
"City": "Cidade",
"State": "Estado",
"Zip Code": "Código Postal",
"Country": "País",
"Notes": "Notas",
"Latitude": "Latitude",
"Longitude": "Longitude",
"Event Title": "Título do evento",
"Start Date": "Data de início",
"End Date": "Data final",
"Location": "Localização",
"Description": "Descrição",
"Save": "Salvar",
"Have a beautiful day!": "Tenha um lindo dia!",
"Data templates": "Modelos de dados",
"Hidden SSID": "SSID oculto",
"Close dialog": "Fechar diálogo",
"Use example": "Exemplo de uso",
"Required fields are marked with an asterisk (*)": "Os campos obrigatórios estão marcados com um asterisco (*)",
"Text is required": "O texto é obrigatório",
"URL is required": "O URL é obrigatório",
"Email address is required": "O endereço de e-mail é obrigatório",
"Optional subject line": "Linha de assunto opcional",
"Optional email body": "Corpo do e-mail opcional",
"Phone number is required": "O número de telefone é obrigatório",
"Optional SMS message": "Mensagem SMS opcional",
"Encryption": "Criptografia",
"No encryption": "Sem criptografia",
"Wireless SSID": "SSID sem fio",
"Your network name": "Seu nome de rede",
"Wireless SSID is required": "O SSID sem fio é necessário",
"Network password (case-sensitive)": "Senha da rede (diferencia maiúsculas de minúsculas)",
"Password is required when encryption is enabled": "A senha é necessária quando a criptografia está ativada",
"vCard Version": "Versão do vCard",
"e.g., John": "Por exemplo, John",
"e.g., Doe": "Por exemplo, Doe",
"e.g., Acme Corp": "Por exemplo, Acme Corp",
"e.g., Software Engineer": "Por exemplo, Engenheiro de Software",
"Phone (Work)": "Telefone (trabalho)",
"Phone (Private)": "Telefone (particular)",
"Phone (Mobile)": "Telefone (celular)",
"Street": "Rua",
"Zipcode": "Código postal",
"Latitude is required": "A latitude é necessária",
"Longitude is required": "A longitude é necessária",
"e.g., Team Meeting": "Por exemplo, reunião de equipe",
"e.g., Conference Room A": "Por exemplo, Sala de Conferência A",
"Event Location": "Local do evento",
"Start Time": "Hora de início",
"End Time": "Tempo final",
"Start time is required": "O horário de início é obrigatório",
"End time is required": "O horário de término é obrigatório",
"Subject": "Assunto",
"Message": "Mensagem"
}

View File

@ -141,5 +141,89 @@
"right": "dreapta",
"Close scanner": "Închide scanerul",
"Switch camera": "Comutați camera foto",
"Ignore header row": "Ignorați rândul de antet"
"Ignore header row": "Ignorați rândul de antet",
"Data Type": "Tip de date",
"Text": "Text",
"URL": "URL",
"Email": "E-mail",
"Phone": "Telefon",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Eveniment",
"Invalid URL format": "Format URL invalid",
"Invalid email format": "Format e-mail invalid",
"Invalid phone number format": "Format invalid al numărului de telefon",
"Invalid WiFi format": "Format WiFi invalid",
"Invalid vCard format": "Format vCard invalid",
"Invalid location format": "Format de locație invalid",
"Invalid event format": "Format de eveniment invalid",
"Network Name (SSID)": "Numele rețelei (SSID)",
"Password": "Parolă",
"Network Type": "Tip rețea",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Niciuna",
"First Name": "Numele și prenumele",
"Last Name": "Numele de familie",
"Organization": "Organizație",
"Title": "Titlu",
"Phone Number": "Număr de telefon",
"Email Address": "Adresa de e-mail",
"Website": "Site web",
"Address": "Adresă",
"City": "Oraș",
"State": "Stat",
"Zip Code": "Cod poștal",
"Country": "Țara",
"Notes": "Note",
"Latitude": "Latitudine",
"Longitude": "Longitudine",
"Event Title": "Titlul evenimentului",
"Start Date": "Data de începere",
"End Date": "Data de încheiere",
"Location": "Locație",
"Description": "Descriere",
"Save": "Salvați",
"Have a beautiful day!": "Să aveți o zi frumoasă!",
"Data templates": "Modele de date",
"Hidden SSID": "SSID ascuns",
"Close dialog": "Închideți dialogul",
"Use example": "Exemplu de utilizare",
"Required fields are marked with an asterisk (*)": "Câmpurile obligatorii sunt marcate cu un asterisc (*)",
"Text is required": "Textul este necesar",
"URL is required": "URL-ul este necesar",
"Email address is required": "Adresa de e-mail este obligatorie",
"Optional subject line": "Subiect opțional",
"Optional email body": "Corp e-mail opțional",
"Phone number is required": "Numărul de telefon este necesar",
"Optional SMS message": "Mesaj SMS opțional",
"Encryption": "Criptare",
"No encryption": "Nu există criptare",
"Wireless SSID": "SSID fără fir",
"Your network name": "Numele rețelei dvs.",
"Wireless SSID is required": "SSID fără fir este necesar",
"Network password (case-sensitive)": "Parola rețelei (sensibilă la majuscule)",
"Password is required when encryption is enabled": "Parola este necesară atunci când criptarea este activată",
"vCard Version": "Versiunea vCard",
"e.g., John": "de exemplu, John",
"e.g., Doe": "de exemplu, Doe",
"e.g., Acme Corp": "de exemplu, Acme Corp",
"e.g., Software Engineer": "de exemplu, inginer software",
"Phone (Work)": "Telefon (serviciu)",
"Phone (Private)": "Telefon (privat)",
"Phone (Mobile)": "Telefon (mobil)",
"Street": "Strada",
"Zipcode": "Cod poștal",
"Latitude is required": "Latitudinea este necesară",
"Longitude is required": "Longitudinea este necesară",
"e.g., Team Meeting": "de exemplu, Reuniunea echipei",
"e.g., Conference Room A": "de exemplu, Sala de conferințe A",
"Event Location": "Locația evenimentului",
"Start Time": "Ora de începere",
"End Time": "Timpul final",
"Start time is required": "Este necesară ora de începere",
"End time is required": "Este necesară ora finală",
"Subject": "Subiect",
"Message": "Mesaj"
}

View File

@ -141,5 +141,89 @@
"right": "справа",
"Close scanner": "Закрыть сканер",
"Switch camera": "Переключить камеру",
"Ignore header row": "Игнорировать строку заголовка"
"Ignore header row": "Игнорировать строку заголовка",
"Data Type": "Тип данных",
"Text": "Текст",
"URL": "URL",
"Email": "Электронная почта",
"Phone": "Телефон",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Событие",
"Invalid URL format": "Недопустимый формат URL",
"Invalid email format": "Неверный формат электронной почты",
"Invalid phone number format": "Неверный формат телефонного номера",
"Invalid WiFi format": "Недопустимый формат WiFi",
"Invalid vCard format": "Недопустимый формат vCard",
"Invalid location format": "Недопустимый формат местоположения",
"Invalid event format": "Недопустимый формат события",
"Network Name (SSID)": "Имя сети (SSID)",
"Password": "Пароль",
"Network Type": "Тип сети",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Нет",
"First Name": "Имя",
"Last Name": "Фамилия",
"Organization": "Организация",
"Title": "Название",
"Phone Number": "Номер телефона",
"Email Address": "Адрес электронной почты",
"Website": "Сайт",
"Address": "Адрес",
"City": "Город",
"State": "Государство",
"Zip Code": "Почтовый индекс",
"Country": "Страна",
"Notes": "Примечания",
"Latitude": "Широта",
"Longitude": "Долгота",
"Event Title": "Название мероприятия",
"Start Date": "Дата начала",
"End Date": "Дата окончания",
"Location": "Расположение",
"Description": "Описание",
"Save": "Сохранить",
"Have a beautiful day!": "Хорошего дня!",
"Data templates": "Шаблоны данных",
"Hidden SSID": "Скрытый SSID",
"Close dialog": "Закрыть диалог",
"Use example": "Используйте пример",
"Required fields are marked with an asterisk (*)": "Обязательные поля отмечены звездочкой (*)",
"Text is required": "Текст обязателен",
"URL is required": "URL-адрес обязателен",
"Email address is required": "Адрес электронной почты обязателен",
"Optional subject line": "Необязательная строка темы",
"Optional email body": "Необязательное тело письма",
"Phone number is required": "Номер телефона обязателен",
"Optional SMS message": "Дополнительное SMS-сообщение",
"Encryption": "Шифрование",
"No encryption": "Нет шифрования",
"Wireless SSID": "SSID беспроводной сети",
"Your network name": "Имя вашей сети",
"Wireless SSID is required": "Требуется идентификатор беспроводной сети SSID",
"Network password (case-sensitive)": "Сетевой пароль (с учетом регистра)",
"Password is required when encryption is enabled": "Пароль требуется, если включено шифрование",
"vCard Version": "Версия vCard",
"e.g., John": "Например, Джон",
"e.g., Doe": "например, Доу",
"e.g., Acme Corp": "например, Acme Corp",
"e.g., Software Engineer": "Например, инженер-программист",
"Phone (Work)": "Телефон (рабочий)",
"Phone (Private)": "Телефон (частный)",
"Phone (Mobile)": "Телефон (мобильный)",
"Street": "Улица",
"Zipcode": "Zipcode",
"Latitude is required": "Требуется широта",
"Longitude is required": "Требуется долгота",
"e.g., Team Meeting": "Например, собрание команды",
"e.g., Conference Room A": "например, конференц-зал A",
"Event Location": "Место проведения мероприятия",
"Start Time": "Время начала",
"End Time": "Конец времени",
"Start time is required": "Необходимо время начала",
"End time is required": "Требуется время окончания",
"Subject": "Тема",
"Message": "Сообщение"
}

View File

@ -141,5 +141,89 @@
"right": "right",
"Close scanner": "Close scanner",
"Switch camera": "Switch camera",
"Ignore header row": "Ignore header row"
"Ignore header row": "Ignore header row",
"Data Type": "Data Type",
"Text": "Text",
"URL": "URL",
"Email": "Email",
"Phone": "Phone",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Event",
"Invalid URL format": "Invalid URL format",
"Invalid email format": "Invalid email format",
"Invalid phone number format": "Invalid phone number format",
"Invalid WiFi format": "Invalid WiFi format",
"Invalid vCard format": "Invalid vCard format",
"Invalid location format": "Invalid location format",
"Invalid event format": "Invalid event format",
"Network Name (SSID)": "Network Name (SSID)",
"Password": "Password",
"Network Type": "Network Type",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "None",
"First Name": "First Name",
"Last Name": "Last Name",
"Organization": "Organization",
"Title": "Title",
"Phone Number": "Phone Number",
"Email Address": "Email Address",
"Website": "Website",
"Address": "Address",
"City": "City",
"State": "State",
"Zip Code": "Zip Code",
"Country": "Country",
"Notes": "Notes",
"Latitude": "Latitude",
"Longitude": "Longitude",
"Event Title": "Event Title",
"Start Date": "Start Date",
"End Date": "End Date",
"Location": "Location",
"Description": "Description",
"Save": "Save",
"Have a beautiful day!": "Have a beautiful day!",
"Data templates": "Data templates",
"Hidden SSID": "Hidden SSID",
"Close dialog": "Close dialog",
"Use example": "Use example",
"Required fields are marked with an asterisk (*)": "Required fields are marked with an asterisk (*)",
"Text is required": "Text is required",
"URL is required": "URL is required",
"Email address is required": "Email address is required",
"Optional subject line": "Optional subject line",
"Optional email body": "Optional email body",
"Phone number is required": "Phone number is required",
"Optional SMS message": "Optional SMS message",
"Encryption": "Encryption",
"No encryption": "No encryption",
"Wireless SSID": "Wireless SSID",
"Your network name": "Your network name",
"Wireless SSID is required": "Wireless SSID is required",
"Network password (case-sensitive)": "Network password (case-sensitive)",
"Password is required when encryption is enabled": "Password is required when encryption is enabled",
"vCard Version": "vCard Version",
"e.g., John": "e.g., John",
"e.g., Doe": "e.g., Doe",
"e.g., Acme Corp": "e.g., Acme Corp",
"e.g., Software Engineer": "e.g., Software Engineer",
"Phone (Work)": "Phone (Work)",
"Phone (Private)": "Phone (Private)",
"Phone (Mobile)": "Phone (Mobile)",
"Street": "Street",
"Zipcode": "Zipcode",
"Latitude is required": "Latitude is required",
"Longitude is required": "Longitude is required",
"e.g., Team Meeting": "e.g., Team Meeting",
"e.g., Conference Room A": "e.g., Conference Room A",
"Event Location": "Event Location",
"Start Time": "Start Time",
"End Time": "End Time",
"Start time is required": "Start time is required",
"End time is required": "End time is required",
"Subject": "Subject",
"Message": "Message"
}

View File

@ -141,5 +141,89 @@
"right": "höger",
"Close scanner": "Stäng scanner",
"Switch camera": "Växla kamera",
"Ignore header row": "Ignorera rubrikraden"
"Ignore header row": "Ignorera rubrikraden",
"Data Type": "Typ av data",
"Text": "Text",
"URL": "URL",
"Email": "E-post",
"Phone": "Telefon",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Händelse",
"Invalid URL format": "Ogiltigt URL-format",
"Invalid email format": "Ogiltigt e-postformat",
"Invalid phone number format": "Ogiltigt format på telefonnumret",
"Invalid WiFi format": "Ogiltigt WiFi-format",
"Invalid vCard format": "Ogiltigt vCard-format",
"Invalid location format": "Ogiltigt platsformat",
"Invalid event format": "Ogiltigt händelseformat",
"Network Name (SSID)": "Nätverksnamn (SSID)",
"Password": "Lösenord",
"Network Type": "Typ av nätverk",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Ingen",
"First Name": "Förnamn",
"Last Name": "Efternamn",
"Organization": "Organisation",
"Title": "Titel",
"Phone Number": "Telefonnummer",
"Email Address": "E-postadress",
"Website": "Webbplats",
"Address": "Adress",
"City": "Stad",
"State": "Stat",
"Zip Code": "Postnummer",
"Country": "Land",
"Notes": "Anteckningar",
"Latitude": "Latitud",
"Longitude": "Longitud",
"Event Title": "Händelsens titel",
"Start Date": "Startdatum",
"End Date": "Slutdatum",
"Location": "Plats",
"Description": "Beskrivning",
"Save": "Spara",
"Have a beautiful day!": "Ha en vacker dag!",
"Data templates": "Mallar för data",
"Hidden SSID": "Dold SSID",
"Close dialog": "Stäng dialogrutan",
"Use example": "Använd exempel",
"Required fields are marked with an asterisk (*)": "Obligatoriska fält är markerade med en asterisk (*)",
"Text is required": "Text krävs",
"URL is required": "URL krävs",
"Email address is required": "E-postadress krävs",
"Optional subject line": "Valfri ämnesrad",
"Optional email body": "Valfri e-posttext",
"Phone number is required": "Telefonnummer är obligatoriskt",
"Optional SMS message": "Valfritt SMS-meddelande",
"Encryption": "Kryptering",
"No encryption": "Ingen kryptering",
"Wireless SSID": "Trådlös SSID",
"Your network name": "Ditt nätverksnamn",
"Wireless SSID is required": "Trådlöst SSID krävs",
"Network password (case-sensitive)": "Nätverkslösenord (skiftlägeskänsligt)",
"Password is required when encryption is enabled": "Lösenord krävs när kryptering är aktiverad",
"vCard Version": "vCard-version",
"e.g., John": "t.ex. John",
"e.g., Doe": "t.ex. Doe",
"e.g., Acme Corp": "t.ex. Acme Corp",
"e.g., Software Engineer": "t.ex. programvaruingenjör",
"Phone (Work)": "Telefon (arbete)",
"Phone (Private)": "Telefon (privat)",
"Phone (Mobile)": "Telefon (mobil)",
"Street": "Gata",
"Zipcode": "Postnummer",
"Latitude is required": "Latitud krävs",
"Longitude is required": "Longitud krävs",
"e.g., Team Meeting": "t.ex. team-möte",
"e.g., Conference Room A": "t.ex. konferensrum A",
"Event Location": "Plats för evenemang",
"Start Time": "Starttid",
"End Time": "Sluttid",
"Start time is required": "Starttid krävs",
"End time is required": "Sluttid krävs",
"Subject": "Ämne",
"Message": "Meddelande"
}

View File

@ -141,5 +141,89 @@
"right": "doğru",
"Close scanner": "Tarayıcıyı kapat",
"Switch camera": "Kamera değiştir",
"Ignore header row": "Başlık satırını yoksay"
"Ignore header row": "Başlık satırını yoksay",
"Data Type": "Veri Tipi",
"Text": "Metin",
"URL": "URL",
"Email": "E-posta",
"Phone": "Telefon",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Etkinlik",
"Invalid URL format": "Geçersiz URL biçimi",
"Invalid email format": "Geçersiz e-posta biçimi",
"Invalid phone number format": "Geçersiz telefon numarası biçimi",
"Invalid WiFi format": "Geçersiz WiFi biçimi",
"Invalid vCard format": "Geçersiz vCard biçimi",
"Invalid location format": "Geçersiz konum biçimi",
"Invalid event format": "Geçersiz olay biçimi",
"Network Name (SSID)": "Ağ Adı (SSID)",
"Password": "Şifre",
"Network Type": "Ağ Tipi",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Hiçbiri",
"First Name": "İlk İsim",
"Last Name": "Soyadı",
"Organization": "Organizasyon",
"Title": "Başlık",
"Phone Number": "Telefon Numarası",
"Email Address": "E-posta Adresi",
"Website": "Web sitesi",
"Address": "Adres",
"City": "Şehir",
"State": "Eyalet",
"Zip Code": "Posta Kodu",
"Country": "Ülke",
"Notes": "Notlar",
"Latitude": "Enlem",
"Longitude": "Boylam",
"Event Title": "Etkinlik Başlığı",
"Start Date": "Başlangıç Tarihi",
"End Date": "Bitiş Tarihi",
"Location": "Konum",
"Description": "Açıklama",
"Save": "Kaydet",
"Have a beautiful day!": "Güzel bir gün geçirin!",
"Data templates": "Veri şablonları",
"Hidden SSID": "Gizli SSID",
"Close dialog": "İletişim kutusunu kapat",
"Use example": "Örnek kullanın",
"Required fields are marked with an asterisk (*)": "Zorunlu alanlar yıldız işareti (*) ile işaretlenmiştir",
"Text is required": "Metin gereklidir",
"URL is required": "URL gereklidir",
"Email address is required": "E-posta adresi gereklidir",
"Optional subject line": "İsteğe bağlı konu satırı",
"Optional email body": "İsteğe bağlı e-posta gövdesi",
"Phone number is required": "Telefon numarası gereklidir",
"Optional SMS message": "İsteğe bağlı SMS mesajı",
"Encryption": "Şifreleme",
"No encryption": "Şifreleme yok",
"Wireless SSID": "Kablosuz SSID",
"Your network name": "Ağ adınız",
"Wireless SSID is required": "Kablosuz SSID gereklidir",
"Network password (case-sensitive)": "Ağ parolası (büyük/küçük harfe duyarlı)",
"Password is required when encryption is enabled": "Şifreleme etkinleştirildiğinde parola gereklidir",
"vCard Version": "vCard Sürümü",
"e.g., John": "Örneğin, John",
"e.g., Doe": "Örneğin, Doe",
"e.g., Acme Corp": "Örneğin, Acme Corp",
"e.g., Software Engineer": "Örneğin, Yazılım Mühendisi",
"Phone (Work)": "Telefon (İş)",
"Phone (Private)": "Telefon (Özel)",
"Phone (Mobile)": "Telefon (Mobil)",
"Street": "Sokak",
"Zipcode": "Posta kodu",
"Latitude is required": "Enlem gereklidir",
"Longitude is required": "Boylam gereklidir",
"e.g., Team Meeting": "Örneğin, Ekip Toplantısı",
"e.g., Conference Room A": "Örneğin, Konferans Odası A",
"Event Location": "Etkinlik Konumu",
"Start Time": "Başlangıç Zamanı",
"End Time": "Bitiş Zamanı",
"Start time is required": "Başlangıç zamanı gereklidir",
"End time is required": "Bitiş zamanı gereklidir",
"Subject": "Konu",
"Message": "Mesaj"
}

View File

@ -141,5 +141,89 @@
"right": "правий",
"Close scanner": "Закрити сканер",
"Switch camera": "Змінити камеру",
"Ignore header row": "Ігнорувати рядок заголовка"
"Ignore header row": "Ігнорувати рядок заголовка",
"Data Type": "Тип даних",
"Text": "Текст",
"URL": "URL",
"Email": "Електронна пошта",
"Phone": "Телефон",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Подія",
"Invalid URL format": "Неправильний формат URL-адреси",
"Invalid email format": "Неправильний формат електронної пошти",
"Invalid phone number format": "Неправильний формат номера телефону",
"Invalid WiFi format": "Неправильний формат WiFi",
"Invalid vCard format": "Неправильний формат vCard",
"Invalid location format": "Неправильний формат місцезнаходження",
"Invalid event format": "Неправильний формат події",
"Network Name (SSID)": "Ім'я мережі (SSID)",
"Password": "Пароль",
"Network Type": "Тип мережі",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "Ні.",
"First Name": "Ім'я та прізвище",
"Last Name": "Прізвище",
"Organization": "Організація",
"Title": "Назва",
"Phone Number": "Номер телефону",
"Email Address": "Адреса електронної пошти",
"Website": "Веб-сайт",
"Address": "Адреса",
"City": "Місто",
"State": "Держава",
"Zip Code": "Поштовий індекс",
"Country": "Країна",
"Notes": "Примітки",
"Latitude": "Широта",
"Longitude": "Довгота",
"Event Title": "Назва події",
"Start Date": "Дата початку",
"End Date": "Дата закінчення",
"Location": "Місцезнаходження",
"Description": "Опис",
"Save": "Зберегти",
"Have a beautiful day!": "Гарного вам дня!",
"Data templates": "Шаблони даних",
"Hidden SSID": "Прихований SSID",
"Close dialog": "Закрити діалогове вікно",
"Use example": "Приклад використання",
"Required fields are marked with an asterisk (*)": "Обов'язкові поля позначені зірочкою (*)",
"Text is required": "Текст обов'язковий",
"URL is required": "URL-адреса обов'язкова",
"Email address is required": "Адреса електронної пошти обов'язкова",
"Optional subject line": "Необов'язкова тема листа",
"Optional email body": "Необов'язкове тіло листа",
"Phone number is required": "Номер телефону обов'язковий",
"Optional SMS message": "Додаткове SMS-повідомлення",
"Encryption": "Шифрування",
"No encryption": "Без шифрування",
"Wireless SSID": "Бездротовий SSID",
"Your network name": "Ваше мережеве ім'я",
"Wireless SSID is required": "Потрібен бездротовий SSID",
"Network password (case-sensitive)": "Мережевий пароль (з урахуванням регістру)",
"Password is required when encryption is enabled": "Пароль потрібен, якщо увімкнено шифрування",
"vCard Version": "Версія vCard",
"e.g., John": "наприклад, Джон",
"e.g., Doe": "наприклад, Доу",
"e.g., Acme Corp": "наприклад, Acme Corp",
"e.g., Software Engineer": "наприклад, інженер-програміст",
"Phone (Work)": "Телефон (робочий)",
"Phone (Private)": "Телефон (приватний)",
"Phone (Mobile)": "Телефон (мобільний)",
"Street": "Вулиця",
"Zipcode": "Поштовий індекс",
"Latitude is required": "Потрібна широта",
"Longitude is required": "Потрібна довгота",
"e.g., Team Meeting": "наприклад, командні збори",
"e.g., Conference Room A": "наприклад, конференц-зал А",
"Event Location": "Місце проведення заходу",
"Start Time": "Час початку",
"End Time": "Кінцевий час",
"Start time is required": "Необхідно вказати час початку",
"End time is required": "Необхідно вказати час закінчення",
"Subject": "Тема",
"Message": "Повідомлення"
}

View File

@ -141,5 +141,89 @@
"right": "right",
"Close scanner": "Close scanner",
"Switch camera": "Switch camera",
"Ignore header row": "Ignore header row"
"Ignore header row": "Ignore header row",
"Data Type": "Data Type",
"Text": "Text",
"URL": "URL",
"Email": "Email",
"Phone": "Phone",
"SMS": "SMS",
"WiFi": "WiFi",
"vCard": "vCard",
"Event": "Event",
"Invalid URL format": "Invalid URL format",
"Invalid email format": "Invalid email format",
"Invalid phone number format": "Invalid phone number format",
"Invalid WiFi format": "Invalid WiFi format",
"Invalid vCard format": "Invalid vCard format",
"Invalid location format": "Invalid location format",
"Invalid event format": "Invalid event format",
"Network Name (SSID)": "Network Name (SSID)",
"Password": "Password",
"Network Type": "Network Type",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "None",
"First Name": "First Name",
"Last Name": "Last Name",
"Organization": "Organization",
"Title": "Title",
"Phone Number": "Phone Number",
"Email Address": "Email Address",
"Website": "Website",
"Address": "Address",
"City": "City",
"State": "State",
"Zip Code": "Zip Code",
"Country": "Country",
"Notes": "Notes",
"Latitude": "Latitude",
"Longitude": "Longitude",
"Event Title": "Event Title",
"Start Date": "Start Date",
"End Date": "End Date",
"Location": "Location",
"Description": "Description",
"Save": "Save",
"Have a beautiful day!": "Have a beautiful day!",
"Data templates": "Data templates",
"Hidden SSID": "Hidden SSID",
"Close dialog": "Close dialog",
"Use example": "Use example",
"Required fields are marked with an asterisk (*)": "Required fields are marked with an asterisk (*)",
"Text is required": "Text is required",
"URL is required": "URL is required",
"Email address is required": "Email address is required",
"Optional subject line": "Optional subject line",
"Optional email body": "Optional email body",
"Phone number is required": "Phone number is required",
"Optional SMS message": "Optional SMS message",
"Encryption": "Encryption",
"No encryption": "No encryption",
"Wireless SSID": "Wireless SSID",
"Your network name": "Your network name",
"Wireless SSID is required": "Wireless SSID is required",
"Network password (case-sensitive)": "Network password (case-sensitive)",
"Password is required when encryption is enabled": "Password is required when encryption is enabled",
"vCard Version": "vCard Version",
"e.g., John": "e.g., John",
"e.g., Doe": "e.g., Doe",
"e.g., Acme Corp": "e.g., Acme Corp",
"e.g., Software Engineer": "e.g., Software Engineer",
"Phone (Work)": "Phone (Work)",
"Phone (Private)": "Phone (Private)",
"Phone (Mobile)": "Phone (Mobile)",
"Street": "Street",
"Zipcode": "Zipcode",
"Latitude is required": "Latitude is required",
"Longitude is required": "Longitude is required",
"e.g., Team Meeting": "e.g., Team Meeting",
"e.g., Conference Room A": "e.g., Conference Room A",
"Event Location": "Event Location",
"Start Time": "Start Time",
"End Time": "End Time",
"Start time is required": "Start time is required",
"End time is required": "End time is required",
"Subject": "Subject",
"Message": "Message"
}

View File

@ -141,5 +141,89 @@
"right": "對",
"Close scanner": "關閉掃描器",
"Switch camera": "切換攝影機",
"Ignore header row": "忽略標頭行"
"Ignore header row": "忽略標頭行",
"Data Type": "資料類型",
"Text": "正文",
"URL": "網址",
"Email": "電子郵件",
"Phone": "電話",
"SMS": "簡訊",
"WiFi": "無線網路",
"vCard": "vCard",
"Event": "活動",
"Invalid URL format": "無效的 URL 格式",
"Invalid email format": "無效的電子郵件格式",
"Invalid phone number format": "電話號碼格式無效",
"Invalid WiFi format": "無效的 WiFi 格式",
"Invalid vCard format": "無效的 vCard 格式",
"Invalid location format": "位置格式無效",
"Invalid event format": "無效事件格式",
"Network Name (SSID)": "網路名稱 (SSID)",
"Password": "密碼",
"Network Type": "網路類型",
"WPA/WPA2": "WPA/WPA2",
"WEP": "WEP",
"None": "無",
"First Name": "姓名",
"Last Name": "姓氏",
"Organization": "組織架構",
"Title": "標題",
"Phone Number": "電話號碼",
"Email Address": "電子郵件地址",
"Website": "網站",
"Address": "地址",
"City": "城市",
"State": "國家",
"Zip Code": "郵遞區號",
"Country": "國家",
"Notes": "注意事項",
"Latitude": "緯度",
"Longitude": "經度",
"Event Title": "活動標題",
"Start Date": "開始日期",
"End Date": "結束日期",
"Location": "地點",
"Description": "說明",
"Save": "節省",
"Have a beautiful day!": "祝您有美好的一天",
"Data templates": "資料範本",
"Hidden SSID": "隱藏 SSID",
"Close dialog": "關閉對話框",
"Use example": "使用範例",
"Required fields are marked with an asterisk (*)": "必填欄位以星號 (*) 標示",
"Text is required": "必須使用文字",
"URL is required": "URL 為必填項目",
"Email address is required": "必須填寫電子郵件地址",
"Optional subject line": "可選擇的主題行",
"Optional email body": "可選的電子郵件正文",
"Phone number is required": "需要電話號碼",
"Optional SMS message": "可選的 SMS 訊息",
"Encryption": "加密",
"No encryption": "無加密",
"Wireless SSID": "無線 SSID",
"Your network name": "您的網路名稱",
"Wireless SSID is required": "需要無線 SSID",
"Network password (case-sensitive)": "網路密碼 (區分大小寫)",
"Password is required when encryption is enabled": "啟用加密時需要輸入密碼",
"vCard Version": "vCard 版本",
"e.g., John": "例如:約翰",
"e.g., Doe": "例如Doe",
"e.g., Acme Corp": "例如Acme Corp",
"e.g., Software Engineer": "例如:軟體工程師",
"Phone (Work)": "電話(工作)",
"Phone (Private)": "電話(私人)",
"Phone (Mobile)": "電話(手機)",
"Street": "街道",
"Zipcode": "郵編",
"Latitude is required": "需要緯度",
"Longitude is required": "需要經度",
"e.g., Team Meeting": "例如:團隊會議",
"e.g., Conference Room A": "例如:會議室 A",
"Event Location": "活動地點",
"Start Time": "開始時間",
"End Time": "結束時間",
"Start time is required": "需要開始時間",
"End time is required": "需要結束時間",
"Subject": "主題",
"Message": "訊息"
}

View File

@ -8,6 +8,7 @@
"build": "vite build",
"preview": "vite preview",
"test:e2e": "playwright test",
"vitest": "vitest",
"type-check": "vue-tsc --noEmit",
"lint": "eslint --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore --ignore-pattern \"*.json\"",
"format": "prettier --write",
@ -63,6 +64,7 @@
"sharp": "^0.33.5",
"typescript": "^5.8.2",
"vite-plugin-pwa": "^0.21.1",
"vitest": "^3.1.1",
"vue-eslint-parser": "^9.4.3"
}
}

252
pnpm-lock.yaml generated
View File

@ -127,6 +127,9 @@ devDependencies:
vite-plugin-pwa:
specifier: ^0.21.1
version: 0.21.2(vite@5.4.18)(workbox-build@7.3.0)(workbox-window@7.3.0)
vitest:
specifier: ^3.1.1
version: 3.1.2(@types/node@20.17.30)
vue-eslint-parser:
specifier: ^9.4.3
version: 9.4.3(eslint@8.57.1)
@ -2241,6 +2244,67 @@ packages:
vue: 3.5.13(typescript@5.8.3)
dev: false
/@vitest/expect@3.1.2:
resolution: {integrity: sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA==}
dependencies:
'@vitest/spy': 3.1.2
'@vitest/utils': 3.1.2
chai: 5.2.0
tinyrainbow: 2.0.0
dev: true
/@vitest/mocker@3.1.2(vite@5.4.18):
resolution: {integrity: sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==}
peerDependencies:
msw: ^2.4.9
vite: ^5.0.0 || ^6.0.0
peerDependenciesMeta:
msw:
optional: true
vite:
optional: true
dependencies:
'@vitest/spy': 3.1.2
estree-walker: 3.0.3
magic-string: 0.30.17
vite: 5.4.18(@types/node@20.17.30)
dev: true
/@vitest/pretty-format@3.1.2:
resolution: {integrity: sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==}
dependencies:
tinyrainbow: 2.0.0
dev: true
/@vitest/runner@3.1.2:
resolution: {integrity: sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g==}
dependencies:
'@vitest/utils': 3.1.2
pathe: 2.0.3
dev: true
/@vitest/snapshot@3.1.2:
resolution: {integrity: sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q==}
dependencies:
'@vitest/pretty-format': 3.1.2
magic-string: 0.30.17
pathe: 2.0.3
dev: true
/@vitest/spy@3.1.2:
resolution: {integrity: sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==}
dependencies:
tinyspy: 3.0.2
dev: true
/@vitest/utils@3.1.2:
resolution: {integrity: sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg==}
dependencies:
'@vitest/pretty-format': 3.1.2
loupe: 3.1.3
tinyrainbow: 2.0.0
dev: true
/@vue/babel-helper-vue-transform-on@1.4.0:
resolution: {integrity: sha512-mCokbouEQ/ocRce/FpKCRItGo+013tHg7tixg3DUNS+6bmIchPt66012kBMm476vyEIJPafrvOf4E5OYj3shSw==}
dev: false
@ -2577,6 +2641,11 @@ packages:
is-array-buffer: 3.0.5
dev: true
/assertion-error@2.0.1:
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
engines: {node: '>=12'}
dev: true
/async-function@1.0.0:
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
engines: {node: '>= 0.4'}
@ -2693,6 +2762,11 @@ packages:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
/cac@6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
dev: true
/call-bind-apply-helpers@1.0.2:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
@ -2731,6 +2805,17 @@ packages:
/caniuse-lite@1.0.30001715:
resolution: {integrity: sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==}
/chai@5.2.0:
resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
engines: {node: '>=12'}
dependencies:
assertion-error: 2.0.1
check-error: 2.1.1
deep-eql: 5.0.2
loupe: 3.1.3
pathval: 2.0.0
dev: true
/chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
@ -2744,6 +2829,11 @@ packages:
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
dev: true
/check-error@2.1.1:
resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
engines: {node: '>= 16'}
dev: true
/chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
@ -2907,6 +2997,11 @@ packages:
dependencies:
ms: 2.1.3
/deep-eql@5.0.2:
resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
engines: {node: '>=6'}
dev: true
/deep-is@0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
@ -3085,6 +3180,10 @@ packages:
engines: {node: '>= 0.4'}
dev: true
/es-module-lexer@1.7.0:
resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
dev: true
/es-object-atoms@1.1.1:
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
engines: {node: '>= 0.4'}
@ -3306,6 +3405,12 @@ packages:
/estree-walker@2.0.2:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
/estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
dependencies:
'@types/estree': 1.0.7
dev: true
/esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
@ -3330,6 +3435,11 @@ packages:
strip-final-newline: 3.0.0
dev: true
/expect-type@1.2.1:
resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==}
engines: {node: '>=12.0.0'}
dev: true
/fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@ -4148,6 +4258,10 @@ packages:
wrap-ansi: 9.0.0
dev: true
/loupe@3.1.3:
resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==}
dev: true
/lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
@ -4174,7 +4288,6 @@ packages:
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
dev: false
/math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
@ -4423,6 +4536,15 @@ packages:
engines: {node: '>=8'}
dev: true
/pathe@2.0.3:
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
dev: true
/pathval@2.0.0:
resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
engines: {node: '>= 14.16'}
dev: true
/picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@ -4977,6 +5099,10 @@ packages:
side-channel-weakmap: 1.0.2
dev: true
/siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
dev: true
/signal-exit@4.1.0:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
@ -5040,6 +5166,14 @@ packages:
deprecated: Please use @jridgewell/sourcemap-codec instead
dev: true
/stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
dev: true
/std-env@3.9.0:
resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==}
dev: true
/string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
engines: {node: '>=0.6.19'}
@ -5278,6 +5412,14 @@ packages:
dependencies:
any-promise: 1.3.0
/tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
dev: true
/tinyexec@0.3.2:
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
dev: true
/tinyglobby@0.2.13:
resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==}
engines: {node: '>=12.0.0'}
@ -5286,6 +5428,21 @@ packages:
picomatch: 4.0.2
dev: true
/tinypool@1.0.2:
resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==}
engines: {node: ^18.0.0 || >=20.0.0}
dev: true
/tinyrainbow@2.0.0:
resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
engines: {node: '>=14.0.0'}
dev: true
/tinyspy@3.0.2:
resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==}
engines: {node: '>=14.0.0'}
dev: true
/to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@ -5465,6 +5622,28 @@ packages:
- '@vue/composition-api'
dev: false
/vite-node@3.1.2(@types/node@20.17.30):
resolution: {integrity: sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
dependencies:
cac: 6.7.14
debug: 4.4.0
es-module-lexer: 1.7.0
pathe: 2.0.3
vite: 5.4.18(@types/node@20.17.30)
transitivePeerDependencies:
- '@types/node'
- less
- lightningcss
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
dev: true
/vite-plugin-pwa@0.21.2(vite@5.4.18)(workbox-build@7.3.0)(workbox-window@7.3.0):
resolution: {integrity: sha512-vFhH6Waw8itNu37hWUJxL50q+CBbNcMVzsKaYHQVrfxTt3ihk3PeLO22SbiP1UNWzcEPaTQv+YVxe4G0KOjAkg==}
engines: {node: '>=16.0.0'}
@ -5525,6 +5704,68 @@ packages:
optionalDependencies:
fsevents: 2.3.3
/vitest@3.1.2(@types/node@20.17.30):
resolution: {integrity: sha512-WaxpJe092ID1C0mr+LH9MmNrhfzi8I65EX/NRU/Ld016KqQNRgxSOlGNP1hHN+a/F8L15Mh8klwaF77zR3GeDQ==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
hasBin: true
peerDependencies:
'@edge-runtime/vm': '*'
'@types/debug': ^4.1.12
'@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
'@vitest/browser': 3.1.2
'@vitest/ui': 3.1.2
happy-dom: '*'
jsdom: '*'
peerDependenciesMeta:
'@edge-runtime/vm':
optional: true
'@types/debug':
optional: true
'@types/node':
optional: true
'@vitest/browser':
optional: true
'@vitest/ui':
optional: true
happy-dom:
optional: true
jsdom:
optional: true
dependencies:
'@types/node': 20.17.30
'@vitest/expect': 3.1.2
'@vitest/mocker': 3.1.2(vite@5.4.18)
'@vitest/pretty-format': 3.1.2
'@vitest/runner': 3.1.2
'@vitest/snapshot': 3.1.2
'@vitest/spy': 3.1.2
'@vitest/utils': 3.1.2
chai: 5.2.0
debug: 4.4.0
expect-type: 1.2.1
magic-string: 0.30.17
pathe: 2.0.3
std-env: 3.9.0
tinybench: 2.9.0
tinyexec: 0.3.2
tinyglobby: 0.2.13
tinypool: 1.0.2
tinyrainbow: 2.0.0
vite: 5.4.18(@types/node@20.17.30)
vite-node: 3.1.2(@types/node@20.17.30)
why-is-node-running: 2.3.0
transitivePeerDependencies:
- less
- lightningcss
- msw
- sass
- sass-embedded
- stylus
- sugarss
- supports-color
- terser
dev: true
/vue-demi@0.14.10(vue@3.5.13):
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'}
@ -5658,6 +5899,15 @@ packages:
dependencies:
isexe: 2.0.0
/why-is-node-running@2.3.0:
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
engines: {node: '>=8'}
hasBin: true
dependencies:
siginfo: 2.0.0
stackback: 0.0.2
dev: true
/word-wrap@1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import DataTemplatesModal from '@/components/DataTemplatesModal.vue'
import QRCodeFrame from '@/components/QRCodeFrame.vue'
import StyledQRCode from '@/components/StyledQRCode.vue'
import {
@ -646,6 +647,21 @@ async function generateBatchQRCodes(format: 'png' | 'svg' | 'jpg') {
}
}
//#endregion
const isDataModalVisible = ref(false)
const openDataModal = () => {
isDataModalVisible.value = true
}
const closeDataModal = () => {
isDataModalVisible.value = false
}
const updateDataFromModal = (newData: string) => {
data.value = newData
// Optionally trigger QR code regeneration here if needed
}
</script>
<template>
@ -998,7 +1014,7 @@ async function generateBatchQRCodes(format: 'png' | 'svg' | 'jpg') {
<div class="space-y-4">
<div class="flex flex-row items-center gap-2">
<label for="show-frame">{{ t('Add frame') }}</label>
<input id="show-frame" type="checkbox" class="checkbox" v-model="showFrame" />
<input id="show-frame" type="checkbox" v-model="showFrame" />
</div>
<div v-if="showFrame">
@ -1148,15 +1164,15 @@ async function generateBatchQRCodes(format: 'png' | 'svg' | 'jpg') {
<div class="w-full">
<div class="flex w-full flex-col gap-4 sm:flex-row sm:gap-8">
<div class="w-full sm:w-2/3">
<!-- Header row: Label + Mode Toggles + Batch Options -->
<div class="mb-2 flex items-center gap-4">
<label for="data">
{{ t('Data to encode') }}
</label>
<label for="data">{{ t('Data to encode') }}</label>
<!-- Mode Toggle Buttons -->
<div class="flex grow items-center gap-2">
<button
:class="[
'secondary-button',
{ 'opacity-50': exportMode !== ExportMode.Single }
{ 'opacity-50': exportMode === ExportMode.Single } // Dim if active
]"
@click="exportMode = ExportMode.Single"
>
@ -1165,12 +1181,13 @@ async function generateBatchQRCodes(format: 'png' | 'svg' | 'jpg') {
<button
:class="[
'secondary-button',
{ 'opacity-50': exportMode !== ExportMode.Batch }
{ 'opacity-50': exportMode === ExportMode.Batch } // Dim if active
]"
@click="exportMode = ExportMode.Batch"
>
{{ $t('Batch export') }}
</button>
<!-- Batch specific options -->
<div
v-if="exportMode === ExportMode.Batch"
:class="[
@ -1181,7 +1198,7 @@ async function generateBatchQRCodes(format: 'png' | 'svg' | 'jpg') {
<input
id="ignore-header"
type="checkbox"
class="checkbox mr-2"
class="checkbox me-2"
v-model="ignoreHeaderRow"
@change="onBatchInputFileUpload($event)"
/>
@ -1191,15 +1208,41 @@ async function generateBatchQRCodes(format: 'png' | 'svg' | 'jpg') {
</div>
</div>
</div>
<!-- Single Mode Input -->
<div v-if="exportMode === ExportMode.Single" class="flex flex-col items-start">
<textarea
v-if="exportMode === ExportMode.Single"
name="data"
class="text-input"
id="data"
:placeholder="t('data to encode e.g. a URL or a string')"
v-model="data"
class="mr-2 grow text-input"
:placeholder="t('data to encode e.g. a URL or a string')"
></textarea>
<button
@click="openDataModal"
aria-haspopup="dialog"
:aria-expanded="isDataModalVisible"
class="secondary-button mt-2 flex items-center gap-1 self-end"
:aria-label="t('Open data type generator')"
>
<span>{{ t('Data templates') }}</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
>
<!-- Icon from Tabler Icons by Paweł Kuna - https://github.com/tabler/tabler-icons/blob/master/LICENSE -->
<path
fill="none"
stroke="#888888"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="m7 7l5 5l-5 5m6-10l5 5l-5 5"
/>
<template v-else>
</svg>
</button>
</div>
<template v-if="exportMode === ExportMode.Batch">
<template v-if="!inputFileForBatchEncoding">
<button
class="flex items-center justify-center rounded-lg border-2 border-dashed border-gray-300 p-1 py-4 text-center text-input"
@ -1383,12 +1426,7 @@ async function generateBatchQRCodes(format: 'png' | 'svg' | 'jpg') {
<label for="with-background">
{{ t('With background') }}
</label>
<input
id="with-background"
type="checkbox"
class="checkbox"
v-model="includeBackground"
/>
<input id="with-background" type="checkbox" v-model="includeBackground" />
</div>
<div id="color-settings" :class="'flex w-full flex-row flex-wrap gap-4'">
<div
@ -1557,4 +1595,11 @@ async function generateBatchQRCodes(format: 'png' | 'svg' | 'jpg') {
</Accordion>
</div>
</div>
<DataTemplatesModal
:show="isDataModalVisible"
:initial-data="data"
@close="closeDataModal"
@update:data="updateDataFromModal"
/>
</template>

View File

@ -9,12 +9,43 @@
-webkit-text-size-adjust: 100%;
transition-duration: 300ms;
transition-property: background-color, color;
--scrollbar-width: 8px;
@media screen and (prefers-reduced-motion: reduce), (update: slow) {
transition-duration: 0s;
}
}
/* Scrollbar Styling */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
@apply bg-zinc-100 dark:bg-zinc-800;
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
@apply bg-zinc-300 dark:bg-zinc-600;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
@apply bg-zinc-400 dark:bg-zinc-500;
}
/* Hide scrollbar class */
.no-scrollbar::-webkit-scrollbar {
display: none;
}
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
a {
color: #0000EE;
text-decoration: underline;
@ -50,7 +81,7 @@ body {
}
label {
@apply text-balance;
@apply text-balance self-start;
}
svg {
@ -84,6 +115,7 @@ input[type='radio'] {
@apply m-3;
}
.button {
@apply bg-zinc-100 dark:bg-zinc-700 text-zinc-900 dark:text-zinc-200;
@apply shadow-sm hover:shadow p-2 focus-visible:shadow-md rounded-lg;
@ -116,3 +148,51 @@ input[type='radio'] {
.radiogroup > label {
@apply font-normal;
}
input[type='number'] {
-moz-appearance: textfield;
}
input[type='number']::-webkit-outer-spin-button,
input[type='number']::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="checkbox"] {
-webkit-appearance: none;
appearance: none;
margin: 0;
font: inherit;
width: 1.15em;
height: 1.15em;
@apply bg-white dark:bg-zinc-800;
@apply border-2 border-zinc-300 dark:border-zinc-600;
border-radius: 0.15em;
display: grid;
place-content: center;
transform: translateY(-0.075em);
}
input[type="checkbox"]::before {
content: "";
width: 0.65em;
height: 0.65em;
transform: scale(0);
transition: 120ms transform ease-in-out;
transform-origin: bottom left;
@apply bg-zinc-800 dark:bg-zinc-200;
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
}
input[type="checkbox"]:checked::before {
transform: scale(1);
}
input[type="checkbox"]:focus {
@apply outline-none ring-2 ring-zinc-500 dark:ring-zinc-400;
outline-offset: max(2px, 0.15em);
}
input[type="checkbox"]:hover {
@apply border-zinc-400 dark:border-zinc-500;
}

View File

@ -0,0 +1,362 @@
import { describe, it, expect } from 'vitest'
import {
generateTextData,
generateUrlData,
generateEmailData,
generatePhoneData,
generateSmsData,
generateWifiData,
generateVCardData,
generateLocationData,
generateEventData,
detectDataType,
escapeVCard,
escapeWiFi,
escapeICal
} from './dataEncoding'
describe('Data Encoding Functions', () => {
it('generateTextData returns correct string', () => {
expect(generateTextData({ text: 'Hello World' })).toBe('Hello World')
expect(generateTextData({ text: '' })).toBe('')
})
it('generateUrlData formats URL correctly', () => {
expect(generateUrlData({ url: 'example.com' })).toBe('https://example.com')
expect(generateUrlData({ url: 'http://example.com' })).toBe('http://example.com')
expect(generateUrlData({ url: 'https://example.com' })).toBe('https://example.com')
expect(generateUrlData({ url: '' })).toBe('')
})
it('generateEmailData formats mailto string correctly', () => {
expect(generateEmailData({ address: 'test@example.com' })).toBe('mailto:test@example.com')
expect(generateEmailData({ address: 'test@example.com', subject: 'Hi' })).toBe(
'mailto:test@example.com?subject=Hi'
)
expect(generateEmailData({ address: 'test@example.com', body: 'Hello there' })).toBe(
'mailto:test@example.com?body=Hello%20there'
)
expect(
generateEmailData({
address: 'test@example.com',
subject: 'Hi & Bye',
body: 'Line 1\nLine 2'
})
).toBe('mailto:test@example.com?subject=Hi%20%26%20Bye&body=Line%201%0ALine%202')
expect(generateEmailData({ address: '' })).toBe('')
})
it('generatePhoneData formats tel string correctly', () => {
expect(generatePhoneData({ phone: '+123456789' })).toBe('tel:+123456789')
expect(generatePhoneData({ phone: '' })).toBe('')
})
it('generateSmsData formats SMSTO string correctly', () => {
expect(generateSmsData({ phone: '+12345' })).toBe('SMSTO:+12345:')
expect(generateSmsData({ phone: '+12345', message: 'Hello' })).toBe('SMSTO:+12345:Hello')
expect(generateSmsData({ phone: '' })).toBe('')
})
it('generateWifiData formats WIFI string correctly', () => {
expect(generateWifiData({ ssid: 'MyNet', encryption: 'WPA', password: 'pass123' })).toBe(
'WIFI:T:WPA;S:MyNet;P:pass123;;'
)
expect(generateWifiData({ ssid: 'MyNet', encryption: 'WPA', password: 'pass;123"' })).toBe(
'WIFI:T:WPA;S:MyNet;P:pass\\;123\\";;'
) // Escaping
expect(generateWifiData({ ssid: 'MyNet', encryption: 'nopass' })).toBe(
'WIFI:T:nopass;S:MyNet;;;'
)
expect(
generateWifiData({ ssid: 'HiddenNet', encryption: 'WPA', password: 'abc', hidden: true })
).toBe('WIFI:T:WPA;S:HiddenNet;P:abc;H:true;;')
expect(generateWifiData({ ssid: '', encryption: 'WPA' })).toBe('')
})
it('generateVCardData formats vCard string correctly', () => {
expect(generateVCardData({ firstName: 'John', lastName: 'Doe' })).toBe(
'BEGIN:VCARD\nVERSION:3.0\nN:Doe;John;;;\nFN:John Doe\nEND:VCARD'
)
expect(generateVCardData({ email: 'j.doe@example.com' })).toBe(
'BEGIN:VCARD\nVERSION:3.0\nEMAIL:j.doe@example.com\nEND:VCARD'
)
// Test vCard 2.1 format
expect(
generateVCardData({
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
phoneWork: '+1234567890',
version: '2'
})
).toBe(
'BEGIN:VCARD\nVERSION:2.1\nN:Doe;John;;;\nFN:John Doe\nTEL;WORK;VOICE:+1234567890\nEMAIL;INTERNET:john.doe@example.com\nEND:VCARD'
)
// Test vCard 3.0 format
expect(
generateVCardData({
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
phoneWork: '+1234567890',
version: '3'
})
).toBe(
'BEGIN:VCARD\nVERSION:3.0\nN:Doe;John;;;\nFN:John Doe\nTEL;TYPE=WORK,VOICE:+1234567890\nEMAIL:john.doe@example.com\nEND:VCARD'
)
// Test vCard 4.0 format
expect(
generateVCardData({
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
phoneWork: '+1234567890',
version: '4'
})
).toBe(
'BEGIN:VCARD\nVERSION:4.0\nN:Doe;John;;;\nFN:John Doe\nTEL;TYPE=work,voice;VALUE=uri:tel:+1234567890\nEMAIL;TYPE=work:john.doe@example.com\nEND:VCARD'
)
})
it('generateLocationData formats geo string correctly', () => {
expect(generateLocationData({ latitude: 40.7128, longitude: -74.006 })).toBe(
'geo:40.7128,-74.006'
)
expect(generateLocationData({ latitude: '40.7128', longitude: '-74.0060' })).toBe(
'geo:40.7128,-74.0060'
)
expect(generateLocationData({ latitude: 'invalid', longitude: -74 })).toBe('')
})
it('generateEventData formats VCALENDAR string correctly', () => {
const startTime = new Date(Date.UTC(2025, 0, 15, 10, 0, 0)) // Jan 15, 2025 10:00:00 UTC
const endTime = new Date(Date.UTC(2025, 0, 15, 11, 0, 0)) // Jan 15, 2025 11:00:00 UTC
const expectedStart = '20250115T100000Z'
const expectedEnd = '20250115T110000Z'
const result = generateEventData({ title: 'Meeting', startTime, endTime })
expect(result).toContain('BEGIN:VCALENDAR')
expect(result).toContain('VERSION:2.0')
expect(result).toContain('BEGIN:VEVENT')
expect(result).toContain('SUMMARY:Meeting')
expect(result).toContain(`DTSTART:${expectedStart}`)
expect(result).toContain(`DTEND:${expectedEnd}`)
expect(result).toContain('DTSTAMP:') // Check if timestamp exists
expect(result).toContain('END:VEVENT')
expect(result).toContain('END:VCALENDAR')
const resultStringDates = generateEventData({
title: 'Party',
startTime: '2024-12-25T18:00:00Z',
endTime: '2024-12-25T22:00:00Z'
})
expect(resultStringDates).toContain('SUMMARY:Party')
expect(resultStringDates).toContain('DTSTART:20241225T180000Z')
expect(resultStringDates).toContain('DTEND:20241225T220000Z')
expect(generateEventData({})).toContain('BEGIN:VCALENDAR')
})
})
describe('Data Type Detection Functions', () => {
it('detectDataType identifies plain text', () => {
const result = detectDataType('Hello World')
expect(result.type).toBe('text')
expect(result.parsedData.text).toBe('Hello World')
})
it('detectDataType identifies URLs', () => {
const result = detectDataType('https://example.com')
expect(result.type).toBe('url')
expect(result.parsedData.url).toBe('https://example.com')
})
it('detectDataType identifies email links', () => {
const result = detectDataType('mailto:test@example.com?subject=Hello&body=Hi%20there')
expect(result.type).toBe('email')
expect(result.parsedData.address).toBe('test@example.com')
expect(result.parsedData.subject).toBe('Hello')
expect(result.parsedData.body).toBe('Hi there')
})
it('detectDataType identifies phone numbers', () => {
const result = detectDataType('tel:+123456789')
expect(result.type).toBe('phone')
expect(result.parsedData.phone).toBe('+123456789')
})
it('detectDataType identifies SMS messages', () => {
const result1 = detectDataType('SMSTO:+12345:Hello there')
expect(result1.type).toBe('sms')
expect(result1.parsedData.phone).toBe('+12345')
expect(result1.parsedData.message).toBe('Hello there')
const result2 = detectDataType('sms:+12345?body=Hello%20there')
expect(result2.type).toBe('sms')
expect(result2.parsedData.phone).toBe('+12345')
expect(result2.parsedData.message).toBe('Hello there')
})
it('detectDataType identifies WiFi credentials', () => {
const result = detectDataType('WIFI:T:WPA;S:MyNetwork;P:password123;H:true;;')
expect(result.type).toBe('wifi')
expect(result.parsedData.ssid).toBe('MyNetwork')
expect(result.parsedData.encryption).toBe('wpa')
expect(result.parsedData.password).toBe('password123')
expect(result.parsedData.hidden).toBe(true)
})
it('detectDataType identifies vCard data', () => {
const vcard = `BEGIN:VCARD
VERSION:3.0
N:Doe;John;Q.,Public
FN:John Doe
TEL;TYPE=WORK,VOICE:(111) 555-1212
TEL;TYPE=HOME,VOICE:(404) 555-1212
TEL;TYPE=CELL,VOICE:(404) 555-1213
EMAIL:johndoe@example.com
URL:https://www.example.com
ADR;TYPE=HOME:;;42 Plantation St.;Baytown;LA;30314;USA
END:VCARD`
const result = detectDataType(vcard)
expect(result.type).toBe('vcard')
expect(result.parsedData.firstName).toBe('John')
expect(result.parsedData.lastName).toBe('Doe')
expect(result.parsedData.phoneWork).toBe('(111) 555-1212')
expect(result.parsedData.phonePrivate).toBe('(404) 555-1212')
expect(result.parsedData.phoneMobile).toBe('(404) 555-1213')
expect(result.parsedData.email).toBe('johndoe@example.com')
expect(result.parsedData.website).toBe('https://www.example.com')
expect(result.parsedData.street).toBe('42 Plantation St.')
expect(result.parsedData.city).toBe('Baytown')
expect(result.parsedData.state).toBe('LA')
expect(result.parsedData.zipcode).toBe('30314')
expect(result.parsedData.country).toBe('USA')
expect(result.parsedData.version).toBe('3')
// Test vCard 2.1 detection
const vcard21 = `BEGIN:VCARD
VERSION:2.1
N:Doe;John;;;
FN:John Doe
TEL;WORK;VOICE:+1234567890
EMAIL;INTERNET:john.doe@example.com
END:VCARD`
const result21 = detectDataType(vcard21)
expect(result21.type).toBe('vcard')
expect(result21.parsedData.firstName).toBe('John')
expect(result21.parsedData.lastName).toBe('Doe')
expect(result21.parsedData.phoneWork).toBe('+1234567890')
expect(result21.parsedData.email).toBe('john.doe@example.com')
expect(result21.parsedData.version).toBe('2')
// Test vCard 4.0 detection
const vcard40 = `BEGIN:VCARD
VERSION:4.0
N:Doe;John;;;
FN:John Doe
TEL;TYPE=work,voice;VALUE=uri:tel:+1234567890
EMAIL;TYPE=work:john.doe@example.com
END:VCARD`
const result40 = detectDataType(vcard40)
expect(result40.type).toBe('vcard')
expect(result40.parsedData.firstName).toBe('John')
expect(result40.parsedData.lastName).toBe('Doe')
expect(result40.parsedData.phoneWork).toBe('+1234567890')
expect(result40.parsedData.email).toBe('john.doe@example.com')
expect(result40.parsedData.version).toBe('4')
})
it('detectDataType identifies geo location data', () => {
const result = detectDataType('geo:40.7128,-74.0060')
expect(result.type).toBe('location')
expect(result.parsedData.latitude).toBe('40.7128')
expect(result.parsedData.longitude).toBe('-74.0060')
})
it('detectDataType identifies calendar events', () => {
const event = `BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
SUMMARY:Team Meeting
LOCATION:Conference Room A
DTSTART:20240115T100000Z
DTEND:20240115T110000Z
END:VEVENT
END:VCALENDAR`
const result = detectDataType(event)
expect(result.type).toBe('event')
expect(result.parsedData.title).toBe('Team Meeting')
expect(result.parsedData.location).toBe('Conference Room A')
expect(result.parsedData.startTime).toContain('2024-01-15T10:00:00')
expect(result.parsedData.endTime).toContain('2024-01-15T11:00:00')
})
})
describe('Escape Functions', () => {
describe('escapeVCard', () => {
it('escapes special characters for vCard format', () => {
expect(escapeVCard('Hello, World')).toBe('Hello\\, World')
expect(escapeVCard('Name;Surname')).toBe('Name\\;Surname')
expect(escapeVCard('Back\\slash')).toBe('Back\\\\slash')
expect(escapeVCard('')).toBe('')
})
it('handles multiple special characters', () => {
expect(escapeVCard('Test,;\\')).toBe('Test\\,\\;\\\\')
})
it('preserves non-special characters', () => {
expect(escapeVCard('Hello World')).toBe('Hello World')
expect(escapeVCard('12345')).toBe('12345')
expect(escapeVCard('test@example.com')).toBe('test@example.com')
})
})
describe('escapeWiFi', () => {
it('escapes special characters for WiFi format', () => {
expect(escapeWiFi('Network;Name')).toBe('Network\\;Name')
expect(escapeWiFi('Password:123')).toBe('Password\\:123')
expect(escapeWiFi('Test,Comma')).toBe('Test\\,Comma')
expect(escapeWiFi('"Quoted"')).toBe('\\"Quoted\\"')
expect(escapeWiFi("Single'Quote")).toBe("Single\\'Quote")
expect(escapeWiFi('Back\\slash')).toBe('Back\\\\slash')
expect(escapeWiFi('')).toBe('')
})
it('handles multiple special characters', () => {
expect(escapeWiFi('Test;,:"\'\\')).toBe('Test\\;\\,\\:\\"\\\'\\\\')
})
it('preserves non-special characters', () => {
expect(escapeWiFi('MyNetwork')).toBe('MyNetwork')
expect(escapeWiFi('12345')).toBe('12345')
expect(escapeWiFi('test@example.com')).toBe('test@example.com')
})
})
describe('escapeICal', () => {
it('escapes special characters for iCalendar format', () => {
expect(escapeICal('Event,Name')).toBe('Event\\,Name')
expect(escapeICal('Location;Room')).toBe('Location\\;Room')
expect(escapeICal('Back\\slash')).toBe('Back\\\\slash')
expect(escapeICal('')).toBe('')
})
it('handles multiple special characters', () => {
expect(escapeICal('Test,;\\')).toBe('Test\\,\\;\\\\')
})
it('preserves non-special characters', () => {
expect(escapeICal('Meeting')).toBe('Meeting')
expect(escapeICal('12345')).toBe('12345')
expect(escapeICal('test@example.com')).toBe('test@example.com')
})
})
})

674
src/utils/dataEncoding.ts Normal file
View File

@ -0,0 +1,674 @@
/** Generic function to escape special characters in a string */
const escapeSpecialChars = (val: string, charsToEscape: string): string => {
if (!val) return ''
const regex = new RegExp(`([${charsToEscape.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}])`, 'g')
return val.replace(regex, '\\$1')
}
/**
* Escapes special characters for vCard format: \ , ;
* Based on RFC 6350 (vCard 4.0) and RFC 2426 (vCard 3.0)
* @see https://datatracker.ietf.org/doc/html/rfc6350
* @see https://datatracker.ietf.org/doc/html/rfc2426
*/
export const escapeVCard = (val: string): string => escapeSpecialChars(val, '\\,;')
/**
* Escapes special characters for WiFi format: \ ; , : " '
* Based on WPA/WPA2 Enterprise Configuration Specification
* @see https://github.com/zxing/zxing/wiki/Barcode-Contents#wi-fi-network-config-android-ios-11
*/
export const escapeWiFi = (val: string): string => escapeSpecialChars(val, '\\;,:"\'')
/**
* Escapes special characters for iCalendar format: \ , ;
* Based on RFC 5545 (iCalendar)
* @see https://datatracker.ietf.org/doc/html/rfc5545
*/
export const escapeICal = (val: string): string => escapeSpecialChars(val, '\\,;')
/** Formats a Date object or date string into YYYYMMDDTHHMMSSZ format for iCalendar */
const formatICalDateTime = (dateTime: string | Date): string => {
try {
const date = typeof dateTime === 'string' ? new Date(dateTime) : dateTime
if (isNaN(date.getTime())) return '' // Invalid date
return (
date.getUTCFullYear() +
('0' + (date.getUTCMonth() + 1)).slice(-2) +
('0' + date.getUTCDate()).slice(-2) +
'T' +
('0' + date.getUTCHours()).slice(-2) +
('0' + date.getUTCMinutes()).slice(-2) +
('0' + date.getUTCSeconds()).slice(-2) +
'Z'
)
} catch (e) {
console.error('Error formatting iCal date:', e)
return ''
}
}
// --- Data Type Generators ---
/**
* Generates plain text data for QR code
* @param {object} data - Text data to encode
* @param {string} data.text - The text content to encode
* @returns {string} - Formatted text string
*/
export const generateTextData = (data: { text: string }): string => {
return data.text || ''
}
/**
* Generates a URL string for QR code, ensuring proper http/https prefix
* @param {object} data - URL data to encode
* @param {string} data.url - The URL to encode, with or without protocol
* @returns {string} - Formatted URL string with protocol
*/
export const generateUrlData = (data: { url: string }): string => {
if (!data.url) return ''
return data.url.startsWith('http://') || data.url.startsWith('https://')
? data.url
: `https://${data.url}`
}
/**
* Generates a mailto URI string for email QR codes
* @param {object} data - Email data to encode
* @param {string} data.address - Email address of the recipient
* @param {string} [data.subject] - Optional email subject
* @param {string} [data.body] - Optional email body text
* @returns {string} - Formatted mailto URI string
*/
export const generateEmailData = (data: {
address: string
subject?: string
body?: string
}): string => {
if (!data.address) return ''
const parts: string[] = []
if (data.subject) parts.push(`subject=${encodeURIComponent(data.subject)}`)
if (data.body) parts.push(`body=${encodeURIComponent(data.body)}`)
return `mailto:${data.address}${parts.length > 0 ? '?' + parts.join('&') : ''}`
}
/**
* Generates a tel URI string for phone number QR codes
* @param {object} data - Phone data to encode
* @param {string} data.phone - Phone number to call
* @returns {string} - Formatted tel URI string
*/
export const generatePhoneData = (data: { phone: string }): string => {
return data.phone ? `tel:${data.phone}` : ''
}
/**
* Generates an SMS string for SMS QR codes
* @param {object} data - SMS data to encode
* @param {string} data.phone - Phone number to text
* @param {string} [data.message] - Optional message content
* @returns {string} - Formatted SMS URI string
*/
export const generateSmsData = (data: { phone: string; message?: string }): string => {
return data.phone ? `SMSTO:${data.phone}:${data.message || ''}` : ''
}
/**
* Generates a WiFi network string for WiFi QR codes
* @param {object} data - WiFi data to encode
* @param {string} data.ssid - Network name (SSID)
* @param {string} [data.password] - Network password
* @param {'nopass' | 'WEP' | 'WPA'} data.encryption - Security type (nopass, WEP, or WPA/WPA2)
* @param {boolean} [data.hidden] - Whether the network is hidden (not broadcasting SSID)
* @returns {string} - Formatted WiFi string
*/
export const generateWifiData = (data: {
ssid: string
encryption: 'nopass' | 'WEP' | 'WPA'
password?: string
hidden?: boolean
}): string => {
if (!data.ssid) return ''
const ssid = escapeWiFi(data.ssid)
const encryption = data.encryption
const hidden = data.hidden ? 'H:true;' : ''
if (encryption === 'nopass') {
return `WIFI:T:nopass;S:${ssid};;${hidden};`
} else {
const password = escapeWiFi(data.password || '')
return `WIFI:T:${encryption};S:${ssid};P:${password};${hidden};`
}
}
/**
* Generates a vCard format string from contact information
* @param {object} data - Contact information to encode in vCard format
* @param {string} [data.firstName] - First name of the contact
* @param {string} [data.lastName] - Last name of the contact
* @param {string} [data.org] - Organization name
* @param {string} [data.position] - Job title or position
* @param {string} [data.phoneWork] - Work phone number
* @param {string} [data.phonePrivate] - Home/private phone number
* @param {string} [data.phoneMobile] - Mobile phone number
* @param {string} [data.email] - Email address
* @param {string} [data.website] - Website URL
* @param {string} [data.street] - Street address
* @param {string} [data.zipcode] - Postal/ZIP code
* @param {string} [data.city] - City
* @param {string} [data.state] - State/province
* @param {string} [data.country] - Country
* @param {string} [data.version] - vCard version to generate:
* - '2': Generates vCard 2.1 format (older, simplest format)
* - '3': Generates vCard 3.0 format (default, widely compatible)
* - '4': Generates vCard 4.0 format (newest standard with additional features)
* @returns {string} - Formatted vCard string
*/
export const generateVCardData = (data: {
firstName?: string
lastName?: string
org?: string
position?: string
phoneWork?: string
phonePrivate?: string
phoneMobile?: string
email?: string
website?: string
street?: string
zipcode?: string
city?: string
state?: string
country?: string
version?: string
}): string => {
const lines: string[] = []
lines.push('BEGIN:VCARD')
const version = data.version || '3'
lines.push(`VERSION:${version === '2' ? '2.1' : version === '4' ? '4.0' : '3.0'}`)
const firstName = escapeVCard(data.firstName || '')
const lastName = escapeVCard(data.lastName || '')
if (firstName || lastName) {
lines.push(`N:${lastName};${firstName};;;`)
lines.push(`FN:${firstName} ${lastName}`.trim())
}
if (data.org) lines.push(`ORG:${escapeVCard(data.org)}`)
if (data.position) lines.push(`TITLE:${escapeVCard(data.position)}`)
// Format telephone entries based on vCard version
if (data.phoneWork) {
if (version === '2') {
lines.push(`TEL;WORK;VOICE:${escapeVCard(data.phoneWork)}`)
} else if (version === '4') {
lines.push(`TEL;TYPE=work,voice;VALUE=uri:tel:${escapeVCard(data.phoneWork)}`)
} else {
lines.push(`TEL;TYPE=WORK,VOICE:${escapeVCard(data.phoneWork)}`)
}
}
if (data.phonePrivate) {
if (version === '2') {
lines.push(`TEL;HOME;VOICE:${escapeVCard(data.phonePrivate)}`)
} else if (version === '4') {
lines.push(`TEL;TYPE=home,voice;VALUE=uri:tel:${escapeVCard(data.phonePrivate)}`)
} else {
lines.push(`TEL;TYPE=HOME,VOICE:${escapeVCard(data.phonePrivate)}`)
}
}
if (data.phoneMobile) {
if (version === '2') {
lines.push(`TEL;CELL;VOICE:${escapeVCard(data.phoneMobile)}`)
} else if (version === '4') {
lines.push(`TEL;TYPE=cell,voice;VALUE=uri:tel:${escapeVCard(data.phoneMobile)}`)
} else {
lines.push(`TEL;TYPE=CELL,VOICE:${escapeVCard(data.phoneMobile)}`)
}
}
// Email format differs by version
if (data.email) {
if (version === '2') {
lines.push(`EMAIL;INTERNET:${escapeVCard(data.email)}`)
} else if (version === '4') {
lines.push(`EMAIL;TYPE=work:${escapeVCard(data.email)}`)
} else {
lines.push(`EMAIL:${escapeVCard(data.email)}`)
}
}
// URL format
if (data.website) {
if (version === '4') {
lines.push(`URL;TYPE=work:${escapeVCard(data.website)}`)
} else {
lines.push(`URL:${escapeVCard(data.website)}`)
}
}
const adrParts = [
'',
'', // PO Box, Extended Addr
escapeVCard(data.street || ''),
escapeVCard(data.city || ''),
escapeVCard(data.state || ''),
escapeVCard(data.zipcode || ''),
escapeVCard(data.country || '')
]
if (adrParts.some((part) => part !== '')) {
if (version === '2') {
lines.push(`ADR;WORK:;;${adrParts.join(';')}`)
} else if (version === '4') {
lines.push(`ADR;TYPE=work:;;${adrParts.join(';')}`)
} else {
lines.push(`ADR;TYPE=WORK:;;${adrParts.join(';')}`)
}
}
lines.push('END:VCARD')
return lines.join('\n')
}
/**
* Generates a geographic location URI string for location QR codes
* @param {object} data - Location data to encode
* @param {number|string} data.latitude - Latitude coordinate
* @param {number|string} data.longitude - Longitude coordinate
* @returns {string} - Formatted geo URI string
*/
export const generateLocationData = (data: {
latitude: number | string
longitude: number | string
}): string => {
// Convert to string to preserve formatting, then validate if needed
const latStr = String(data.latitude)
const lonStr = String(data.longitude)
// Basic validation (optional, could be more robust)
if (isNaN(parseFloat(latStr)) || isNaN(parseFloat(lonStr))) {
return ''
}
return `geo:${latStr},${lonStr}`
}
/**
* Generates a calendar event string in iCalendar format for event QR codes
* @param {object} data - Calendar event data to encode
* @param {string} [data.title] - Event title/summary
* @param {string} [data.location] - Event location
* @param {string|Date} [data.startTime] - Event start time
* @param {string|Date} [data.endTime] - Event end time
* @returns {string} - Formatted iCalendar string
*/
export const generateEventData = (data: {
title?: string
location?: string
startTime?: string | Date
endTime?: string | Date
}): string => {
const lines: string[] = []
lines.push('BEGIN:VEVENT')
if (data.title) lines.push(`SUMMARY:${escapeICal(data.title)}`)
if (data.location) lines.push(`LOCATION:${escapeICal(data.location)}`)
const dtStart = data.startTime ? formatICalDateTime(data.startTime) : ''
const dtEnd = data.endTime ? formatICalDateTime(data.endTime) : ''
if (dtStart) lines.push(`DTSTART:${dtStart}`)
if (dtEnd) lines.push(`DTEND:${dtEnd}`)
// Optionally add DTSTAMP (creation timestamp)
lines.push(`DTSTAMP:${formatICalDateTime(new Date())}`)
lines.push('END:VEVENT')
// Wrap in VCALENDAR
return `BEGIN:VCALENDAR\nVERSION:2.0\n${lines.join('\n')}\nEND:VCALENDAR`
}
// --- Data Detection ---
/**
* Detect data type from a string and parse it into structured data
* @param {string} data - The input string to detect and parse
* @returns {object} Object containing detected type and parsed data fields
* with the following properties:
* - type: One of 'text', 'url', 'email', 'phone', 'sms', 'wifi', 'vcard', 'location', 'event'
* - parsedData: An object with fields appropriate for the detected type
*
* For vCard detection, the function detects the vCard version (2.1, 3.0, or 4.0)
* and extracts personal information fields into parsedData, including:
* - firstName, lastName: Name components
* - org: Organization name
* - position: Job title or position
* - phoneWork, phonePrivate, phoneMobile: Contact numbers
* - email: Email address
* - website: URL
* - street, city, state, zipcode, country: Address components
* - version: Detected vCard version mapped to '2', '3', or '4'
*/
export const detectDataType = (
data: string
): {
type: 'text' | 'url' | 'email' | 'phone' | 'sms' | 'wifi' | 'vcard' | 'location' | 'event'
parsedData: Record<string, string | boolean>
} => {
// Default result
const result: {
type: 'text' | 'url' | 'email' | 'phone' | 'sms' | 'wifi' | 'vcard' | 'location' | 'event'
parsedData: Record<string, string | boolean>
} = {
type: 'text',
parsedData: { text: data }
}
if (!data) return result
// vCard detection
if (data.match(/^BEGIN:VCARD/i)) {
result.type = 'vcard'
result.parsedData = {}
// Extract name with a more precise pattern
const fullContent = data.replace(/\r/g, '').split('\n')
// Detect vCard version
const versionLine = fullContent.find((line) => line.match(/^VERSION:/i))
if (versionLine) {
const versionValue = versionLine.substring(8).trim()
// Map version string to our selection values
if (versionValue === '2.1') {
result.parsedData.version = '2'
} else if (versionValue === '3.0') {
result.parsedData.version = '3'
} else if (versionValue === '4.0') {
result.parsedData.version = '4'
}
} else {
// If no version found, default to v3
result.parsedData.version = '3'
}
// Find the N: field
const nField = fullContent.find((line) => line.match(/^N:/i))
if (nField) {
const nameParts = nField.substring(2).split(';')
if (nameParts.length >= 2) {
result.parsedData.lastName = nameParts[0].trim()
result.parsedData.firstName = nameParts[1].trim()
}
}
// Extract formatted name (if no name found)
if (!result.parsedData.firstName && !result.parsedData.lastName) {
const fnField = fullContent.find((line) => line.match(/^FN:/i))
if (fnField) {
const fnValue = fnField.substring(3).trim()
const parts = fnValue.split(' ')
if (parts.length > 1) {
result.parsedData.firstName = parts[0]
result.parsedData.lastName = parts.slice(1).join(' ')
} else {
result.parsedData.firstName = fnValue
}
}
}
// Extract organization
const orgField = fullContent.find((line) => line.match(/^ORG:/i))
if (orgField) {
result.parsedData.org = orgField.substring(4).trim()
}
// Extract position/title
const titleField = fullContent.find((line) => line.match(/^TITLE:/i))
if (titleField) {
result.parsedData.position = titleField.substring(6).trim()
}
// Extract phone numbers
for (const line of fullContent) {
if (line.match(/^TEL[^:]*(?:TYPE=WORK|WORK)[^:]*:/i)) {
let phoneValue = line.substring(line.indexOf(':') + 1).trim()
// For vCard 4.0, remove the "tel:" prefix
if (phoneValue.startsWith('tel:')) {
phoneValue = phoneValue.substring(4)
}
result.parsedData.phoneWork = phoneValue
} else if (line.match(/^TEL[^:]*(?:TYPE=HOME|HOME)[^:]*:/i)) {
let phoneValue = line.substring(line.indexOf(':') + 1).trim()
// For vCard 4.0, remove the "tel:" prefix
if (phoneValue.startsWith('tel:')) {
phoneValue = phoneValue.substring(4)
}
result.parsedData.phonePrivate = phoneValue
} else if (line.match(/^TEL[^:]*(?:TYPE=CELL|CELL|TYPE=MOBILE|MOBILE)[^:]*:/i)) {
let phoneValue = line.substring(line.indexOf(':') + 1).trim()
// For vCard 4.0, remove the "tel:" prefix
if (phoneValue.startsWith('tel:')) {
phoneValue = phoneValue.substring(4)
}
result.parsedData.phoneMobile = phoneValue
} else if (
line.match(/^TEL[^:]*/i) &&
!result.parsedData.phoneWork &&
!result.parsedData.phonePrivate &&
!result.parsedData.phoneMobile
) {
let phoneValue = line.substring(line.indexOf(':') + 1).trim()
// For vCard 4.0, remove the "tel:" prefix
if (phoneValue.startsWith('tel:')) {
phoneValue = phoneValue.substring(4)
}
result.parsedData.phoneMobile = phoneValue
}
}
// Extract email
const emailField = fullContent.find((line) => line.match(/^EMAIL[^:]*:/i))
if (emailField) {
result.parsedData.email = emailField.substring(emailField.indexOf(':') + 1).trim()
}
// Extract website
const urlField = fullContent.find((line) => line.match(/^URL[^:]*:/i))
if (urlField) {
result.parsedData.website = urlField.substring(urlField.indexOf(':') + 1).trim()
}
// Extract address
const addrField = fullContent.find((line) => line.match(/^ADR[^:]*:/i))
if (addrField) {
const addressParts = addrField.substring(addrField.indexOf(':') + 1).split(';')
if (addressParts.length >= 7) {
result.parsedData.street = addressParts[2].trim()
result.parsedData.city = addressParts[3].trim()
result.parsedData.state = addressParts[4].trim()
result.parsedData.zipcode = addressParts[5].trim()
result.parsedData.country = addressParts[6].trim()
}
}
return result
}
// URL detection
if (data.match(/^https?:\/\//i)) {
result.type = 'url'
result.parsedData = { url: data }
return result
}
// Email detection
if (data.match(/^mailto:/i)) {
result.type = 'email'
result.parsedData = {}
const emailParts = data.replace(/^mailto:/i, '').split('?')
result.parsedData.address = emailParts[0] || ''
if (emailParts[1]) {
const params = new URLSearchParams(emailParts[1])
result.parsedData.subject = params.get('subject') || ''
result.parsedData.body = params.get('body') || ''
}
return result
}
// Phone detection
if (data.match(/^tel:/i)) {
result.type = 'phone'
result.parsedData = { phone: data.replace(/^tel:/i, '') }
return result
}
// SMS detection
if (data.match(/^SMSTO:/i) || data.match(/^sms:/i)) {
result.type = 'sms'
result.parsedData = {}
// Handle both SMSTO: and sms: formats
if (data.startsWith('SMSTO:')) {
const smsParts = data.replace(/^SMSTO:/i, '').split(':')
if (smsParts.length >= 1) {
result.parsedData.phone = smsParts[0].trim() || ''
}
if (smsParts.length >= 2) {
result.parsedData.message = smsParts[1].trim() || ''
}
} else if (data.startsWith('sms:')) {
// Handle sms:phone?body=message format
const phone = data.replace(/^sms:/i, '')
if (phone.includes('?')) {
const queryIndex = phone.indexOf('?')
const phoneNumber = phone.substring(0, queryIndex)
const queryString = phone.substring(queryIndex + 1)
result.parsedData.phone = phoneNumber.trim()
const params = new URLSearchParams(queryString)
result.parsedData.message = params.get('body') || ''
} else {
result.parsedData.phone = phone.trim()
}
}
return result
}
// WiFi detection
if (data.match(/^WIFI:/i)) {
result.type = 'wifi'
result.parsedData = {}
// Extract SSID
const ssidMatch = data.match(/S:([^;]*);/i)
if (ssidMatch) {
result.parsedData.ssid = ssidMatch[1] || ''
}
// Extract encryption type
const encMatch = data.match(/T:([^;]*);/i)
if (encMatch) {
const encType = encMatch[1].toUpperCase()
result.parsedData.encryption =
encType === 'NOPASS' || encType === 'WEP' || encType === 'WPA'
? encType.toLowerCase()
: 'nopass'
} else {
result.parsedData.encryption = 'nopass'
}
// Extract password
const passMatch = data.match(/P:([^;]*);/i)
if (passMatch) {
result.parsedData.password = passMatch[1] || ''
}
// Extract hidden flag
const hiddenMatch = data.match(/H:(true|false);/i)
if (hiddenMatch) {
result.parsedData.hidden = hiddenMatch[1].toLowerCase() === 'true'
} else {
result.parsedData.hidden = false
}
return result
}
// Location detection
if (data.match(/^geo:/i)) {
result.type = 'location'
result.parsedData = {}
const coords = data.replace(/^geo:/i, '').split(',')
if (coords.length >= 2) {
result.parsedData.latitude = coords[0] || ''
result.parsedData.longitude = coords[1] || ''
}
return result
}
// Calendar/Event detection (simplified)
if (data.match(/BEGIN:VCALENDAR/i) || data.match(/BEGIN:VEVENT/i)) {
result.type = 'event'
result.parsedData = {}
const summaryMatch = data.match(/SUMMARY:([^\n\r]*)/i)
if (summaryMatch) {
result.parsedData.title = summaryMatch[1] || ''
}
const locationMatch = data.match(/LOCATION:([^\n\r]*)/i)
if (locationMatch) {
result.parsedData.location = locationMatch[1] || ''
}
const startMatch = data.match(/DTSTART(?:[^:]*):([^\n\r]*)/i)
if (startMatch && startMatch[1]) {
result.parsedData.startTime = formatDateFromICal(startMatch[1])
}
const endMatch = data.match(/DTEND(?:[^:]*):([^\n\r]*)/i)
if (endMatch && endMatch[1]) {
result.parsedData.endTime = formatDateFromICal(endMatch[1])
}
return result
}
// Default to text
return result
}
/**
* Converts an iCalendar format date to an ISO string
* @param {string} iCalDate - Date in iCalendar format (e.g., "20230101T120000Z")
* @returns {string} ISO date string, or empty string if invalid
*/
function formatDateFromICal(iCalDate: string): string {
// Handle basic format: YYYYMMDDTHHMMSSZ
const datePattern = /^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})Z?$/
const match = iCalDate.match(datePattern)
if (match) {
try {
const [, year, month, day, hour, minute, second] = match
return `${year}-${month}-${day}T${hour}:${minute}:${second}${iCalDate.endsWith('Z') ? 'Z' : ''}`
} catch (e) {
console.error('Error parsing iCal date:', e)
}
}
return iCalDate // Return as is if not parseable
}

31
vitest.config.ts Normal file
View File

@ -0,0 +1,31 @@
// vitest.config.ts
import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()], // Include Vue plugin if testing Vue components
test: {
globals: true, // Use global APIs like describe, it, expect
// Exclude E2E tests
exclude: [
'**/node_modules/**',
'**/dist/**',
'**/cypress/**',
'**/.{idea,git,cache,output,temp}/**',
'**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',
'./tests/e2e/**'
],
// Add any other Vitest config options here
coverage: {
provider: 'v8', // or 'istanbul'
reporter: ['text', 'json', 'html']
}
},
resolve: {
alias: {
// Setup aliases to match your Vite/Vue config if necessary
'@': path.resolve(__dirname, './src')
}
}
})