diff --git a/next.config.js b/next.config.js
index 4a46dcfac..601f9534d 100644
--- a/next.config.js
+++ b/next.config.js
@@ -28,12 +28,6 @@ module.exports = (phase) =>
'@mui/system',
'@mui/icons-material',
],
- compiler: {
- styledComponents: {
- ssr: true,
- displayName: true,
- },
- },
env: {
SENTRY_RELEASE: GIT_SHA,
NEXT_PUBLIC_IS_TEST_APP: process.env.IS_TEST_RELEASE,
diff --git a/package.json b/package.json
index c8384085e..9e4486014 100644
--- a/package.json
+++ b/package.json
@@ -14,10 +14,12 @@
},
"dependencies": {
"@date-io/date-fns": "^2.14.0",
+ "@emotion/cache": "^11.10.5",
+ "@emotion/react": "^11.10.6",
+ "@emotion/server": "^11.10.0",
+ "@emotion/styled": "^11.10.6",
"@mui/icons-material": "^5.6.2",
"@mui/material": "^5.6.2",
- "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest",
- "@mui/styled-engine-sc": "^5.6.1",
"@mui/x-date-pickers": "^5.0.0-alpha.6",
"@sentry/nextjs": "^6.7.1",
"@stripe/stripe-js": "^1.13.2",
@@ -99,7 +101,6 @@
"@types/react-select": "^4.0.15",
"@types/react-window": "^1.8.2",
"@types/react-window-infinite-loader": "^1.0.3",
- "@types/styled-components": "^5.1.25",
"@types/wicg-file-system-access": "^2020.9.5",
"@types/yup": "^0.29.7",
"@types/zxcvbn": "^4.4.1",
@@ -114,8 +115,5 @@
},
"standard": {
"parser": "babel-eslint"
- },
- "resolutions": {
- "@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
}
-}
+}
\ No newline at end of file
diff --git a/public/locales/de/translation.json b/public/locales/de/translation.json
new file mode 100644
index 000000000..280e51edf
--- /dev/null
+++ b/public/locales/de/translation.json
@@ -0,0 +1,592 @@
+{
+ "HERO_SLIDE_1_TITLE": "",
+ "HERO_SLIDE_1": "",
+ "HERO_SLIDE_2_TITLE": "",
+ "HERO_SLIDE_2": "",
+ "HERO_SLIDE_3_TITLE": "",
+ "HERO_SLIDE_3": "",
+ "LOGIN": "",
+ "SIGN_UP": "",
+ "NEW_USER": "",
+ "EXISTING_USER": "",
+ "NAME": "",
+ "ENTER_NAME": "",
+ "PUBLIC_UPLOADER_NAME_MESSAGE": "",
+ "EMAIL": "",
+ "ENTER_EMAIL": "",
+ "DATA_DISCLAIMER": "",
+ "SUBMIT": "",
+ "EMAIL_ERROR": "",
+ "REQUIRED": "",
+ "VERIFY_EMAIL": "",
+ "EMAIL_SENT": "",
+ "CHECK_INBOX": "",
+ "ENTER_OTT": "",
+ "RESEND_MAIL": "",
+ "VERIFY": "",
+ "UNKNOWN_ERROR": "",
+ "INVALID_CODE": "",
+ "EXPIRED_CODE": "",
+ "SENDING": "",
+ "SENT": "",
+ "PASSWORD": "",
+ "LINK_PASSWORD": "",
+ "ENTER_PASSPHRASE": "",
+ "RETURN_PASSPHRASE_HINT": "",
+ "SET_PASSPHRASE": "",
+ "VERIFY_PASSPHRASE": "",
+ "INCORRECT_PASSPHRASE": "",
+ "ENTER_ENC_PASSPHRASE": "",
+ "PASSPHRASE_DISCLAIMER": "",
+ "WELCOME_TO_ENTE_HEADING": "",
+ "WELCOME_TO_ENTE_SUBHEADING": "",
+ "WHERE_YOUR_BEST_PHOTOS_LIVE": "",
+ "KEY_GENERATION_IN_PROGRESS_MESSAGE": "",
+ "PASSPHRASE_HINT": "",
+ "CONFIRM_PASSPHRASE": "",
+ "PASSPHRASE_MATCH_ERROR": "",
+ "CONSOLE_WARNING_STOP": "",
+ "CONSOLE_WARNING_DESC": "",
+ "SELECT_COLLECTION": "",
+ "CREATE_COLLECTION": "",
+ "ENTER_ALBUM_NAME": "",
+ "CLOSE_OPTION": "",
+ "ENTER_FILE_NAME": "",
+ "CLOSE": "",
+ "NO": "",
+ "NOTHING_HERE": "",
+ "UPLOAD": "",
+ "IMPORT": "",
+ "ADD_PHOTOS": "",
+ "ADD_MORE_PHOTOS": "",
+ "add_photos_one": "",
+ "add_photos_other": "",
+ "SELECT_PHOTOS": "",
+ "FILE_UPLOAD": "",
+ "UPLOAD_STAGE_MESSAGE": {
+ "0": "",
+ "1": "",
+ "2": "",
+ "3": "",
+ "4": "",
+ "5": ""
+ },
+ "UPLOADING_FILES": "",
+ "FILE_NOT_UPLOADED_LIST": "",
+ "SUBSCRIPTION_EXPIRED": "",
+ "SUBSCRIPTION_EXPIRED_MESSAGE": "",
+ "STORAGE_QUOTA_EXCEEDED": "",
+ "INITIAL_LOAD_DELAY_WARNING": "",
+ "USER_DOES_NOT_EXIST": "",
+ "UPLOAD_BUTTON_TEXT": "",
+ "NO_ACCOUNT": "",
+ "ACCOUNT_EXISTS": "",
+ "ALBUM_NAME": "",
+ "CREATE": "",
+ "DOWNLOAD": "",
+ "DOWNLOAD_OPTION": "",
+ "DOWNLOAD_FAVORITES": "",
+ "DOWNLOAD_UNCATEGORIZED": "",
+ "COPY_OPTION": "",
+ "TOGGLE_FULLSCREEN": "",
+ "ZOOM_IN_OUT": "",
+ "PREVIOUS": "",
+ "NEXT": "",
+ "NO_INTERNET_CONNECTION": "",
+ "TITLE": "",
+ "UPLOAD_FIRST_PHOTO": "",
+ "IMPORT_YOUR_FOLDERS": "",
+ "UPLOAD_DROPZONE_MESSAGE": "",
+ "WATCH_FOLDER_DROPZONE_MESSAGE": "",
+ "TRASH_FILES_TITLE": "",
+ "TRASH_FILE_TITLE": "",
+ "DELETE_FILES_TITLE": "",
+ "DELETE_FILES_MESSAGE": "",
+ "DELETE_FILE": "",
+ "DELETE": "",
+ "DELETE_OPTION": "",
+ "FAVORITE": "",
+ "FAVORITE_OPTION": "",
+ "UNFAVORITE_OPTION": "",
+ "UNFAVORITE": "",
+ "MULTI_FOLDER_UPLOAD": "",
+ "UPLOAD_STRATEGY_CHOICE": "",
+ "UPLOAD_STRATEGY_SINGLE_COLLECTION": "",
+ "OR": "",
+ "UPLOAD_STRATEGY_COLLECTION_PER_FOLDER": "",
+ "SESSION_EXPIRED_MESSAGE": "",
+ "SESSION_EXPIRED": "",
+ "SYNC_FAILED": "",
+ "PASSWORD_GENERATION_FAILED": "",
+ "CHANGE_PASSWORD": "",
+ "GO_BACK": "",
+ "RECOVERY_KEY": "",
+ "SAVE_LATER": "",
+ "SAVE": "",
+ "RECOVERY_KEY_DESCRIPTION": "",
+ "RECOVER_KEY_GENERATION_FAILED": "",
+ "KEY_NOT_STORED_DISCLAIMER": "",
+ "FORGOT_PASSWORD": "",
+ "RECOVER_ACCOUNT": "",
+ "RECOVERY_KEY_HINT": "",
+ "RECOVER": "",
+ "NO_RECOVERY_KEY": "",
+ "INCORRECT_RECOVERY_KEY": "",
+ "SORRY": "",
+ "NO_RECOVERY_KEY_MESSAGE": "",
+ "NO_TWO_FACTOR_RECOVERY_KEY_MESSAGE": "",
+ "CONTACT_SUPPORT": "",
+ "REQUEST_FEATURE": "",
+ "SUPPORT": "",
+ "CONFIRM": "",
+ "SKIP_SUBSCRIPTION_PURCHASE": "",
+ "CANCEL": "",
+ "LOGOUT": "",
+ "DELETE_ACCOUNT": "",
+ "DELETE_ACCOUNT_MESSAGE": "",
+ "LOGOUT_MESSAGE": "",
+ "CHANGE": "",
+ "CHANGE_EMAIL": "",
+ "OK": "",
+ "SUCCESS": "",
+ "ERROR": "",
+ "MESSAGE": "",
+ "INSTALL_MOBILE_APP": "",
+ "DOWNLOAD_APP_MESSAGE": "",
+ "DOWNLOAD_APP": "",
+ "EXPORT": "",
+ "SUBSCRIPTION": "",
+ "SUBSCRIBE": "",
+ "SUBSCRIPTION_PLAN": "",
+ "USAGE_DETAILS": "",
+ "MANAGE": "",
+ "MANAGEMENT_PORTAL": "",
+ "MANAGE_FAMILY_PORTAL": "",
+ "LEAVE_FAMILY_PLAN": "",
+ "LEAVE": "",
+ "LEAVE_FAMILY_CONFIRM": "",
+ "CHOOSE_PLAN": "",
+ "MANAGE_PLAN": "",
+ "ACTIVE": "",
+ "OFFLINE_MSG": "",
+ "FREE_SUBSCRIPTION_INFO": "",
+ "FAMILY_SUBSCRIPTION_INFO": "",
+ "RENEWAL_ACTIVE_SUBSCRIPTION_STATUS": "",
+ "RENEWAL_CANCELLED_SUBSCRIPTION_STATUS": "",
+ "RENEWAL_CANCELLED_SUBSCRIPTION_INFO": "",
+ "STORAGE_QUOTA_EXCEEDED_SUBSCRIPTION_INFO": "",
+ "SUBSCRIPTION_PURCHASE_SUCCESS": "",
+ "SUBSCRIPTION_PURCHASE_CANCELLED": "",
+ "SUBSCRIPTION_VERIFICATION_FAILED": "",
+ "SUBSCRIPTION_PURCHASE_FAILED": "",
+ "SUBSCRIPTION_UPDATE_FAILED": "",
+ "UPDATE_PAYMENT_METHOD_MESSAGE": "",
+ "STRIPE_AUTHENTICATION_FAILED": "",
+ "UPDATE_PAYMENT_METHOD": "",
+ "MONTHLY": "",
+ "YEARLY": "",
+ "UPDATE_SUBSCRIPTION_MESSAGE": "",
+ "UPDATE_SUBSCRIPTION": "",
+ "CANCEL_SUBSCRIPTION": "",
+ "CANCEL_SUBSCRIPTION_MESSAGE": "",
+ "SUBSCRIPTION_CANCEL_FAILED": "",
+ "SUBSCRIPTION_CANCEL_SUCCESS": "",
+ "REACTIVATE_SUBSCRIPTION": "",
+ "REACTIVATE_SUBSCRIPTION_MESSAGE": "",
+ "SUBSCRIPTION_ACTIVATE_SUCCESS": "",
+ "SUBSCRIPTION_ACTIVATE_FAILED": "",
+ "SUBSCRIPTION_PURCHASE_SUCCESS_TITLE": "",
+ "CANCEL_SUBSCRIPTION_ON_MOBILE": "",
+ "CANCEL_SUBSCRIPTION_ON_MOBILE_MESSAGE": "",
+ "MAIL_TO_MANAGE_SUBSCRIPTION": "",
+ "RENAME": "",
+ "RENAME_FILE": "",
+ "RENAME_COLLECTION": "",
+ "DELETE_COLLECTION_TITLE": "",
+ "DELETE_COLLECTION": "",
+ "DELETE_COLLECTION_FAILED": "",
+ "DELETE_COLLECTION_MESSAGE": "",
+ "DELETE_PHOTOS": "",
+ "KEEP_PHOTOS": "",
+ "SHARE": "",
+ "SHARE_COLLECTION": "",
+ "SHARE_WITH_PEOPLE": "",
+ "SHAREES": "",
+ "PUBLIC_URL": "",
+ "SHARE_WITH_SELF": "",
+ "ALREADY_SHARED": "",
+ "SHARING_BAD_REQUEST_ERROR": "",
+ "SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
+ "DOWNLOAD_COLLECTION": "",
+ "DOWNLOAD_COLLECTION_MESSAGE": "",
+ "DOWNLOAD_COLLECTION_FAILED": "",
+ "CREATE_ALBUM_FAILED": "",
+ "SEARCH_RESULTS": "",
+ "SEARCH_HINT": "",
+ "SEARCH_TYPE": {
+ "COLLECTION": "",
+ "LOCATION": "",
+ "DATE": "",
+ "FILE_NAME": "",
+ "THING": "",
+ "FILE_CAPTION": ""
+ },
+ "photos_count_zero": "",
+ "photos_count_one": "",
+ "photos_count_other": "",
+ "TERMS_AND_CONDITIONS": "",
+ "CONFIRM_PASSWORD_NOT_SAVED": "",
+ "ADD_TO_COLLECTION": "",
+ "SELECTED": "",
+ "VIDEO_PLAYBACK_FAILED": "",
+ "VIDEO_PLAYBACK_FAILED_DOWNLOAD_INSTEAD": "",
+ "PEOPLE": "",
+ "INDEXING_SCHEDULED": "",
+ "ANALYZING_PHOTOS": "",
+ "INDEXING_PEOPLE": "",
+ "INDEXING_DONE": "",
+ "UNIDENTIFIED_FACES": "",
+ "OBJECTS": "",
+ "TEXT": "",
+ "METADATA": "",
+ "INFO": "",
+ "INFO_OPTION": "",
+ "FILE_ID": "",
+ "FILE_NAME": "",
+ "CAPTION": "",
+ "CAPTION_PLACEHOLDER": "",
+ "CREATION_TIME": "",
+ "UPDATED_ON": "",
+ "LOCATION": "",
+ "SHOW_ON_MAP": "",
+ "DETAILS": "",
+ "VIEW_EXIF": "",
+ "NO_EXIF": "",
+ "EXIF": "",
+ "DEVICE": "",
+ "IMAGE_SIZE": "",
+ "FLASH": "",
+ "FOCAL_LENGTH": "",
+ "APERTURE": "",
+ "ISO": "",
+ "SHOW_ALL": "",
+ "TWO_FACTOR": "",
+ "TWO_FACTOR_AUTHENTICATION": "",
+ "TWO_FACTOR_QR_INSTRUCTION": "",
+ "ENTER_CODE_MANUALLY": "",
+ "TWO_FACTOR_MANUAL_CODE_INSTRUCTION": "",
+ "SCAN_QR_CODE": "",
+ "CONTINUE": "",
+ "BACK": "",
+ "ENABLE_TWO_FACTOR": "",
+ "ENABLE": "",
+ "LOST_DEVICE": "",
+ "INCORRECT_CODE": "",
+ "RECOVER_TWO_FACTOR": "",
+ "TWO_FACTOR_INFO": "",
+ "DISABLE_TWO_FACTOR_LABEL": "",
+ "UPDATE_TWO_FACTOR_LABEL": "",
+ "DISABLE": "",
+ "RECONFIGURE": "",
+ "UPDATE_TWO_FACTOR": "",
+ "UPDATE_TWO_FACTOR_MESSAGE": "",
+ "UPDATE": "",
+ "DISABLE_TWO_FACTOR": "",
+ "DISABLE_TWO_FACTOR_MESSAGE": "",
+ "TWO_FACTOR_SETUP_FAILED": "",
+ "TWO_FACTOR_SETUP_SUCCESS": "",
+ "TWO_FACTOR_DISABLE_SUCCESS": "",
+ "TWO_FACTOR_DISABLE_FAILED": "",
+ "EXPORT_DATA": "",
+ "SELECT_FOLDER": "",
+ "DESTINATION": "",
+ "START": "",
+ "EXPORT_IN_PROGRESS": "",
+ "PAUSE": "",
+ "RESUME": "",
+ "MINIMIZE": "",
+ "LAST_EXPORT_TIME": "",
+ "SUCCESSFULLY_EXPORTED_FILES": "",
+ "FAILED_EXPORTED_FILES": "",
+ "EXPORT_AGAIN": "",
+ "RETRY_EXPORT": "",
+ "LOCAL_STORAGE_NOT_ACCESSIBLE": "",
+ "LOCAL_STORAGE_NOT_ACCESSIBLE_MESSAGE": "",
+ "RETRY": "",
+ "SEND_OTT": "",
+ "EMAIl_ALREADY_OWNED": "",
+ "EMAIL_UDPATE_SUCCESSFUL": "",
+ "UPLOAD_FAILED": "",
+ "ETAGS_BLOCKED": "",
+ "SKIPPED_VIDEOS_INFO": "",
+ "LIVE_PHOTOS_DETECTED": "",
+ "RETRY_FAILED": "",
+ "FAILED_UPLOADS": "",
+ "SKIPPED_FILES": "",
+ "THUMBNAIL_GENERATION_FAILED_UPLOADS": "",
+ "UNSUPPORTED_FILES": "",
+ "SUCCESSFUL_UPLOADS": "",
+ "SKIPPED_INFO": "",
+ "UNSUPPORTED_INFO": "",
+ "BLOCKED_UPLOADS": "",
+ "SKIPPED_VIDEOS": "",
+ "INPROGRESS_METADATA_EXTRACTION": "",
+ "INPROGRESS_UPLOADS": "",
+ "TOO_LARGE_UPLOADS": "",
+ "LARGER_THAN_AVAILABLE_STORAGE_UPLOADS": "",
+ "LARGER_THAN_AVAILABLE_STORAGE_INFO": "",
+ "TOO_LARGE_INFO": "",
+ "THUMBNAIL_GENERATION_FAILED_INFO": "",
+ "UPLOAD_TO_COLLECTION": "",
+ "UNCATEGORIZED": "",
+ "MOVE_TO_UNCATEGORIZED": "",
+ "ARCHIVE": "",
+ "ARCHIVE_COLLECTION": "",
+ "ARCHIVE_SECTION_NAME": "",
+ "ALL_SECTION_NAME": "",
+ "MOVE_TO_COLLECTION": "",
+ "UNARCHIVE": "",
+ "UNARCHIVE_COLLECTION": "",
+ "MOVE": "",
+ "ADD": "",
+ "SORT": "",
+ "REMOVE": "",
+ "YES_REMOVE": "",
+ "CONFIRM_REMOVE": "",
+ "REMOVE_FROM_COLLECTION": "",
+ "TRASH": "",
+ "MOVE_TO_TRASH": "",
+ "TRASH_FILES_MESSAGE": "",
+ "TRASH_FILE_MESSAGE": "",
+ "DELETE_PERMANENTLY": "",
+ "RESTORE": "",
+ "CONFIRM_RESTORE": "",
+ "RESTORE_MESSAGE": "",
+ "RESTORE_TO_COLLECTION": "",
+ "EMPTY_TRASH": "",
+ "EMPTY_TRASH_TITLE": "",
+ "EMPTY_TRASH_MESSAGE": "",
+ "LEAVE_SHARED_ALBUM": "",
+ "LEAVE_ALBUM": "",
+ "LEAVE_SHARED_ALBUM_TITLE": "",
+ "LEAVE_SHARED_ALBUM_MESSAGE": "",
+ "NOT_FILE_OWNER": "",
+ "CONFIRM_SELF_REMOVE_MESSAGE": "",
+ "CONFIRM_SELF_AND_OTHER_REMOVE_MESSAGE": "",
+ "SORT_BY_CREATION_TIME_ASCENDING": "",
+ "SORT_BY_CREATION_TIME_DESCENDING": "",
+ "SORT_BY_UPDATION_TIME_DESCENDING": "",
+ "SORT_BY_NAME": "",
+ "COMPRESS_THUMBNAILS": "",
+ "THUMBNAIL_REPLACED": "",
+ "FIX_THUMBNAIL": "",
+ "FIX_THUMBNAIL_LATER": "",
+ "REPLACE_THUMBNAIL_NOT_STARTED": "",
+ "REPLACE_THUMBNAIL_COMPLETED": "",
+ "REPLACE_THUMBNAIL_NOOP": "",
+ "REPLACE_THUMBNAIL_COMPLETED_WITH_ERROR": "",
+ "FIX_CREATION_TIME": "",
+ "FIX_CREATION_TIME_IN_PROGRESS": "",
+ "CREATION_TIME_UPDATED": "",
+ "UPDATE_CREATION_TIME_NOT_STARTED": "",
+ "UPDATE_CREATION_TIME_COMPLETED": "",
+ "UPDATE_CREATION_TIME_COMPLETED_WITH_ERROR": "",
+ "FILE_NAME_CHARACTER_LIMIT": "",
+ "CAPTION_CHARACTER_LIMIT": "",
+ "DATE_TIME_ORIGINAL": "",
+ "DATE_TIME_DIGITIZED": "",
+ "CUSTOM_TIME": "",
+ "REOPEN_PLAN_SELECTOR_MODAL": "",
+ "OPEN_PLAN_SELECTOR_MODAL_FAILED": "",
+ "COMMENT": "",
+ "ABUSE_REPORT_DESCRIPTION": "",
+ "OTHER_REASON_REQUIRES_COMMENTS": "",
+ "REPORT_SUBMIT_SUCCESS_CONTENT": "",
+ "REPORT_SUBMIT_SUCCESS_TITLE": "",
+ "REPORT_SUBMIT_FAILED": "",
+ "INSTALL": "",
+ "ALBUM_URL": "",
+ "SHARING_DETAILS": "",
+ "MODIFY_SHARING": "",
+ "NOT_FOUND": "",
+ "LINK_EXPIRED": "",
+ "LINK_EXPIRED_MESSAGE": "",
+ "MANAGE_LINK": "",
+ "LINK_TOO_MANY_REQUESTS": "",
+ "DISABLE_PUBLIC_SHARING": "",
+ "DISABLE_PUBLIC_SHARING_MESSAGE": "",
+ "FILE_DOWNLOAD": "",
+ "LINK_PASSWORD_LOCK": "",
+ "PUBLIC_COLLECT": "",
+ "LINK_DEVICE_LIMIT": "",
+ "LINK_EXPIRY": "",
+ "LINK_EXPIRY_NEVER": "",
+ "DISABLE_FILE_DOWNLOAD": "",
+ "DISABLE_FILE_DOWNLOAD_MESSAGE": "",
+ "ABUSE_REPORT": "",
+ "ABUSE_REPORT_BUTTON_TEXT": "",
+ "MALICIOUS_CONTENT": "",
+ "COPYRIGHT": "",
+ "ENTER_EMAIL_ADDRESS": "",
+ "SELECT_REASON": "",
+ "ENTER_FULL_NAME": "",
+ "ENTER_DIGITAL_SIGNATURE": "",
+ "ENTER_ON_BEHALF_OF": "",
+ "ENTER_ADDRESS": "",
+ "ENTER_JOB_TITLE": "",
+ "ENTER_CITY": "",
+ "ENTER_PHONE": "",
+ "ENTER_STATE": "",
+ "ENTER_POSTAL_CODE": "",
+ "ENTER_COUNTRY": "",
+ "JUDICIAL_DESCRIPTION": "",
+ "TERM_1": "",
+ "TERM_2": "",
+ "TERM_3": "",
+ "SHARED_USING": "",
+ "ENTE_IO": "",
+ "LIVE": "",
+ "DISABLE_PASSWORD": "",
+ "DISABLE_PASSWORD_MESSAGE": "",
+ "PASSWORD_LOCK": "",
+ "LOCK": "",
+ "DOWNLOAD_UPLOAD_LOGS": "",
+ "CHOOSE_UPLOAD_TYPE": "",
+ "UPLOAD_FILES": "",
+ "UPLOAD_DIRS": "",
+ "UPLOAD_GOOGLE_TAKEOUT": "",
+ "CANCEL_UPLOADS": "",
+ "DEDUPLICATE_FILES": "",
+ "NO_DUPLICATES_FOUND": "",
+ "CLUB_BY_CAPTURE_TIME": "",
+ "FILES": "",
+ "EACH": "",
+ "DEDUPLICATE_BASED_ON_SIZE": "",
+ "DEDUPLICATE_BASED_ON_SIZE_AND_CAPTURE_TIME": "",
+ "STOP_ALL_UPLOADS_MESSAGE": "",
+ "STOP_UPLOADS_HEADER": "",
+ "YES_STOP_UPLOADS": "",
+ "albums_one": "",
+ "albums_other": "",
+ "NEW": "",
+ "VIEW_ALL_ALBUMS": "",
+ "ALL_ALBUMS": "",
+ "ALBUMS": "",
+ "ENDS": "",
+ "ENTER_TWO_FACTOR_OTP": "",
+ "CREATE_ACCOUNT": "",
+ "COPIED": "",
+ "CANVAS_BLOCKED_TITLE": "",
+ "CANVAS_BLOCKED_MESSAGE": "",
+ "WATCH_FOLDERS": "",
+ "UPGRADE_NOW": "",
+ "RENEW_NOW": "",
+ "STORAGE": "",
+ "USED": "",
+ "YOU": "",
+ "FAMILY": "",
+ "FREE": "",
+ "OF": "",
+ "WATCHED_FOLDERS": "",
+ "NO_FOLDERS_ADDED": "",
+ "FOLDERS_AUTOMATICALLY_MONITORED": "",
+ "UPLOAD_NEW_FILES_TO_ENTE": "",
+ "REMOVE_DELETED_FILES_FROM_ENTE": "",
+ "ADD_FOLDER": "",
+ "STOP_WATCHING": "",
+ "STOP_WATCHING_FOLDER": "",
+ "STOP_WATCHING_DIALOG_MESSAGE": "",
+ "YES_STOP": "",
+ "MONTH_SHORT": "",
+ "YEAR": "",
+ "FAMILY_PLAN": "",
+ "DOWNLOAD_LOGS": "",
+ "DOWNLOAD_LOGS_MESSAGE": "",
+ "CHANGE_FOLDER": "",
+ "TWO_MONTHS_FREE": "",
+ "GB": "",
+ "POPULAR": "",
+ "FREE_PLAN_OPTION_LABEL": "",
+ "FREE_PLAN_DESCRIPTION": "",
+ "CURRENT_USAGE": "",
+ "WEAK_DEVICE": "",
+ "DRAG_AND_DROP_HINT": "",
+ "ASK_FOR_FEEDBACK": "",
+ "SEND_FEEDBACK": "",
+ "CONFIRM_ACCOUNT_DELETION_TITLE": "",
+ "CONFIRM_ACCOUNT_DELETION_MESSAGE": "",
+ "AUTHENTICATE": "",
+ "UPLOADED_TO_SINGLE_COLLECTION": "",
+ "UPLOADED_TO_SEPARATE_COLLECTIONS": "",
+ "NEVERMIND": "",
+ "UPDATE_AVAILABLE": "",
+ "UPDATE_INSTALLABLE_MESSAGE": "",
+ "INSTALL_NOW": "",
+ "INSTALL_ON_NEXT_LAUNCH": "",
+ "UPDATE_AVAILABLE_MESSAGE": "",
+ "DOWNLOAD_AND_INSTALL": "",
+ "IGNORE_THIS_VERSION": "",
+ "TODAY": "",
+ "YESTERDAY": "",
+ "AT": "",
+ "NAME_PLACEHOLDER": "",
+ "ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED": "",
+ "ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED_MESSAGE": "",
+ "CHOSE_THEME": "",
+ "ML_SEARCH": "",
+ "ENABLE_ML_SEARCH_DESCRIPTION": "",
+ "ML_MORE_DETAILS": "",
+ "ENABLE_FACE_SEARCH": "",
+ "ENABLE_FACE_SEARCH_TITLE": "",
+ "ENABLE_FACE_SEARCH_DESCRIPTION": "",
+ "DISABLE_BETA": "",
+ "DISABLE_FACE_SEARCH": "",
+ "DISABLE_FACE_SEARCH_TITLE": "",
+ "DISABLE_FACE_SEARCH_DESCRIPTION": "",
+ "ADVANCED": "",
+ "FACE_SEARCH_CONFIRMATION": "",
+ "LABS": "",
+ "YOURS": "",
+ "PASSPHRASE_STRENGTH": "",
+ "PREFERENCES": "",
+ "LANGUAGE": "",
+ "EXPORT_DIRECTORY_DOES_NOT_EXIST": "",
+ "EXPORT_DIRECTORY_DOES_NOT_EXIST_MESSAGE": "",
+ "SUBSCRIPTION_VERIFICATION_ERROR": "",
+ "STORAGE_UNITS": {
+ "B": "",
+ "KB": "",
+ "MB": "",
+ "GB": "",
+ "TB": ""
+ },
+ "AFTER_TIME": {
+ "HOUR": "",
+ "DAY": "",
+ "WEEK": "",
+ "MONTH": "",
+ "YEAR": ""
+ },
+ "COPY_LINK": "",
+ "DONE": "",
+ "ADD_EMAIL_TITLE": "",
+ "LINK_SHARE_TITLE": "",
+ "REMOVE_LINK": "",
+ "CREATE_PUBLIC_SHARING": "",
+ "PUBLIC_LINK_CREATED": "",
+ "PUBLIC_LINK_ENABLED": "",
+ "COLLECT_PHOTOS": "",
+ "PUBLIC_COLLECT_SUBTEXT": "",
+ "STOP_EXPORT": "",
+ "EXPORT_PROGRESS": "",
+ "EXPORT_NOTIFICATION": {
+ "START": "",
+ "IN_PROGRESS": "",
+ "FINISH": "",
+ "UP_TO_DATE": ""
+ },
+ "CONTINUOUS_EXPORT": "",
+ "TOTAL_ITEMS": "",
+ "PENDING_ITEMS": "",
+ "EXPORT_STARTING": ""
+}
\ No newline at end of file
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index 879208e1c..a1e27bcfe 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -9,16 +9,11 @@
"SIGN_UP": "Signup",
"NEW_USER": "New to ente",
"EXISTING_USER": "Existing user",
- "NAME": "Name",
"ENTER_NAME": "Enter name",
"PUBLIC_UPLOADER_NAME_MESSAGE": "Add a name so that your friends know who to thank for these great photos!",
- "EMAIL": "Email",
"ENTER_EMAIL": "Enter email address",
- "DATA_DISCLAIMER": "We'll never share your data with anyone else.",
- "SUBMIT": "Submit",
"EMAIL_ERROR": "Enter a valid email",
"REQUIRED": "Required",
- "VERIFY_EMAIL": "Verify email",
"EMAIL_SENT": "Verification code sent to {{email}} ",
"CHECK_INBOX": "Please check your inbox (and spam) to complete verification",
"ENTER_OTT": "Verification code",
@@ -31,7 +26,6 @@
"SENT": "Sent!",
"PASSWORD": "Password",
"LINK_PASSWORD": "Enter password to unlock the album",
- "ENTER_PASSPHRASE": "Enter your password",
"RETURN_PASSPHRASE_HINT": "Password",
"SET_PASSPHRASE": "Set password",
"VERIFY_PASSPHRASE": "Sign in",
@@ -47,7 +41,6 @@
"PASSPHRASE_MATCH_ERROR": "Passwords don't match",
"CONSOLE_WARNING_STOP": "STOP!",
"CONSOLE_WARNING_DESC": "This is a browser feature intended for developers. Please don't copy-paste unverified code here.",
- "SELECT_COLLECTION": "Select an album to upload to",
"CREATE_COLLECTION": "New album",
"ENTER_ALBUM_NAME": "Album name",
"CLOSE_OPTION": "Close (Esc)",
@@ -71,17 +64,14 @@
"4": "Cancelling remaining uploads",
"5": "Backup complete"
},
- "UPLOADING_FILES": "File upload",
"FILE_NOT_UPLOADED_LIST": "The following files were not uploaded",
"SUBSCRIPTION_EXPIRED": "Subscription expired",
"SUBSCRIPTION_EXPIRED_MESSAGE": "Your subscription has expired, please renew ",
"STORAGE_QUOTA_EXCEEDED": "Storage limit exceeded",
"INITIAL_LOAD_DELAY_WARNING": "First load may take some time",
"USER_DOES_NOT_EXIST": "Sorry, could not find a user with that email",
- "UPLOAD_BUTTON_TEXT": "Upload",
"NO_ACCOUNT": "Don't have an account",
"ACCOUNT_EXISTS": "Already have an account",
- "ALBUM_NAME": "Album name",
"CREATE": "Create",
"DOWNLOAD": "Download",
"DOWNLOAD_OPTION": "Download (D)",
@@ -102,13 +92,10 @@
"TRASH_FILE_TITLE": "Delete file?",
"DELETE_FILES_TITLE": "Delete immediately?",
"DELETE_FILES_MESSAGE": "Selected files will be permanently deleted from your ente account.",
- "DELETE_FILE": "Delete files",
"DELETE": "Delete",
"DELETE_OPTION": "Delete (DEL)",
- "FAVORITE": "Favorite",
"FAVORITE_OPTION": "Favorite (L)",
"UNFAVORITE_OPTION": "Unfavorite (L)",
- "UNFAVORITE": "Unfavorite",
"MULTI_FOLDER_UPLOAD": "Multiple folders detected",
"UPLOAD_STRATEGY_CHOICE": "Would you like to upload them into",
"UPLOAD_STRATEGY_SINGLE_COLLECTION": "A single album",
@@ -116,7 +103,6 @@
"UPLOAD_STRATEGY_COLLECTION_PER_FOLDER": "Separate albums",
"SESSION_EXPIRED_MESSAGE": "Your session has expired, please login again to continue",
"SESSION_EXPIRED": "Session expired",
- "SYNC_FAILED": "Failed to sync with server, please refresh this page",
"PASSWORD_GENERATION_FAILED": "Your browser was unable to generate a strong key that meets ente's encryption standards, please try using the mobile app or another browser",
"CHANGE_PASSWORD": "Change password",
"GO_BACK": "Go back",
@@ -139,13 +125,11 @@
"REQUEST_FEATURE": "Request Feature",
"SUPPORT": "Support",
"CONFIRM": "Confirm",
- "SKIP_SUBSCRIPTION_PURCHASE": "Continue with free plan",
"CANCEL": "Cancel",
"LOGOUT": "Logout",
"DELETE_ACCOUNT": "Delete account",
"DELETE_ACCOUNT_MESSAGE": "
Please send an email to {{emailID}} from your registered email address.
Your request will be processed within 72 hours.
",
"LOGOUT_MESSAGE": "Are you sure you want to logout?",
- "CHANGE": "Change",
"CHANGE_EMAIL": "Change email",
"OK": "OK",
"SUCCESS": "Success",
@@ -157,9 +141,6 @@
"EXPORT": "Export Data",
"SUBSCRIPTION": "Subscription",
"SUBSCRIBE": "Subscribe",
- "SUBSCRIPTION_PLAN": "Subscription plan",
- "USAGE_DETAILS": "Usage",
- "MANAGE": "Manage",
"MANAGEMENT_PORTAL": "Manage payment method",
"MANAGE_FAMILY_PORTAL": "Manage family",
"LEAVE_FAMILY_PLAN": "Leave family plan",
@@ -177,7 +158,6 @@
"STORAGE_QUOTA_EXCEEDED_SUBSCRIPTION_INFO": "You have exceeded your storage quota, please upgrade ",
"SUBSCRIPTION_PURCHASE_SUCCESS": "We've received your payment
Your subscription is valid till {{date, dateTime}}
",
"SUBSCRIPTION_PURCHASE_CANCELLED": "Your purchase was canceled, please try again if you want to subscribe",
- "SUBSCRIPTION_VERIFICATION_FAILED": "We were not able to verify your purchase, verification can take few hours",
"SUBSCRIPTION_PURCHASE_FAILED": "Subscription purchase failed , please try again",
"SUBSCRIPTION_UPDATE_FAILED": "Subscription updated failed , please try again",
"UPDATE_PAYMENT_METHOD_MESSAGE": "We are sorry, payment failed when we tried to charge your card, please update your payment method and try again",
@@ -204,22 +184,18 @@
"RENAME_COLLECTION": "Rename album",
"DELETE_COLLECTION_TITLE": "Delete album?",
"DELETE_COLLECTION": "Delete album",
- "DELETE_COLLECTION_FAILED": "Album deletion failed, please try again",
"DELETE_COLLECTION_MESSAGE": "Also delete the photos (and videos) present in this album from all other albums they are part of?",
"DELETE_PHOTOS": "Delete photos",
"KEEP_PHOTOS": "Keep photos",
"SHARE": "Share",
"SHARE_COLLECTION": "Share album",
- "SHARE_WITH_PEOPLE": "Share with your loved ones",
"SHAREES": "Shared with",
- "PUBLIC_URL": "Public link",
"SHARE_WITH_SELF": "Oops, you cannot share with yourself",
"ALREADY_SHARED": "Oops, you're already sharing this with {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Sharing album not allowed",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Sharing is disabled for free accounts",
"DOWNLOAD_COLLECTION": "Download album",
"DOWNLOAD_COLLECTION_MESSAGE": "Are you sure you want to download the complete album?
All files will be queued for download sequentially
",
- "DOWNLOAD_COLLECTION_FAILED": "Album downloading failed, please try again",
"CREATE_ALBUM_FAILED": "Failed to create album , please try again",
"SEARCH_RESULTS": "Search results",
"SEARCH_HINT": "Search for albums, dates ...",
@@ -235,10 +211,8 @@
"photos_count_one": "1 memory",
"photos_count_other": "{{count}} memories",
"TERMS_AND_CONDITIONS": "I agree to the terms and privacy policy ",
- "CONFIRM_PASSWORD_NOT_SAVED": "I understand that if I lose my password , I may lose my data since my data is <1>end-to-end encrypted1> with ente
",
"ADD_TO_COLLECTION": "Add to album",
"SELECTED": "selected",
- "VIDEO_PLAYBACK_FAILED": "Video format not supported",
"VIDEO_PLAYBACK_FAILED_DOWNLOAD_INSTEAD": "This video cannot be played on your browser",
"PEOPLE": "People",
"INDEXING_SCHEDULED": "indexing is scheduled...",
@@ -248,41 +222,27 @@
"UNIDENTIFIED_FACES": "unidentified faces",
"OBJECTS": "objects",
"TEXT": "text",
- "METADATA": "Metadata",
"INFO": "Info ",
"INFO_OPTION": "Info (I)",
- "FILE_ID": "File ID",
"FILE_NAME": "File name",
- "CAPTION": "Description",
"CAPTION_PLACEHOLDER": "Add a description",
- "CREATION_TIME": "Creation time",
- "UPDATED_ON": "Updated on",
"LOCATION": "Location",
"SHOW_ON_MAP": "View on OpenStreetMap",
"DETAILS": "Details",
"VIEW_EXIF": "View all EXIF data",
"NO_EXIF": "No EXIF data",
"EXIF": "EXIF",
- "DEVICE": "Device",
- "IMAGE_SIZE": "Image size",
- "FLASH": "Flash",
- "FOCAL_LENGTH": "Focal length",
- "APERTURE": "Aperture",
"ISO": "ISO",
- "SHOW_ALL": "show all",
"TWO_FACTOR": "Two-factor",
"TWO_FACTOR_AUTHENTICATION": "Two-factor authentication",
"TWO_FACTOR_QR_INSTRUCTION": "Scan the QR code below with your favorite authenticator app",
"ENTER_CODE_MANUALLY": "Enter the code manually",
"TWO_FACTOR_MANUAL_CODE_INSTRUCTION": "Please enter this code in your favorite authenticator app",
"SCAN_QR_CODE": "Scan QR code instead",
- "CONTINUE": "Continue",
- "BACK": "Back",
"ENABLE_TWO_FACTOR": "Enable two-factor",
"ENABLE": "Enable",
"LOST_DEVICE": "Lost two-factor device",
"INCORRECT_CODE": "Incorrect code",
- "RECOVER_TWO_FACTOR": "Recover two-factor",
"TWO_FACTOR_INFO": "Add an additional layer of security by requiring more than your email and password to log in to your account",
"DISABLE_TWO_FACTOR_LABEL": "Disable two-factor authentication",
"UPDATE_TWO_FACTOR_LABEL": "Update your authenticator device",
@@ -293,31 +253,17 @@
"UPDATE": "Update",
"DISABLE_TWO_FACTOR": "Disable two-factor",
"DISABLE_TWO_FACTOR_MESSAGE": "Are you sure you want to disable your two-factor authentication",
- "TWO_FACTOR_SETUP_FAILED": "Failed to setup two factor, please try again",
- "TWO_FACTOR_SETUP_SUCCESS": "Two factor authentication successfully configured",
- "TWO_FACTOR_DISABLE_SUCCESS": "Two factor authentication disabled",
"TWO_FACTOR_DISABLE_FAILED": "Failed to disable two factor, please try again",
"EXPORT_DATA": "Export data",
"SELECT_FOLDER": "Select folder",
"DESTINATION": "Destination",
- "EXPORT_SIZE": "Export size",
"START": "Start",
- "EXPORT_IN_PROGRESS": "Export in progress...",
- "PAUSE": "Pause",
- "RESUME": "Resume",
- "MINIMIZE": "Minimize",
"LAST_EXPORT_TIME": "Last export time",
- "SUCCESSFULLY_EXPORTED_FILES": "Successful exports",
- "FAILED_EXPORTED_FILES": "Failed exports",
"EXPORT_AGAIN": "Resync",
- "RETRY_EXPORT": "Retry failed exports",
"LOCAL_STORAGE_NOT_ACCESSIBLE": "Local storage not accessible",
"LOCAL_STORAGE_NOT_ACCESSIBLE_MESSAGE": "Your browser or an addon is blocking ente from saving data into local storage. please try loading this page after switching your browsing mode.",
- "RETRY": "Retry",
"SEND_OTT": "Send OTP",
"EMAIl_ALREADY_OWNED": "Email already taken",
- "EMAIL_UDPATE_SUCCESSFUL": "Your email has been updated successfully",
- "UPLOAD_FAILED": "Upload failed",
"ETAGS_BLOCKED": "We were unable to upload the following files because of your browser configuration.
Please disable any addons that might be preventing ente from using eTags
to upload large files, or use our desktop app for a more reliable import experience.
",
"SKIPPED_VIDEOS_INFO": "Presently we do not support adding videos via public links.
To share videos, please signup for ente and share with the intended recipients using their email.
",
"LIVE_PHOTOS_DETECTED": "The photo and video files from your Live Photos have been merged into a single file",
@@ -340,7 +286,6 @@
"THUMBNAIL_GENERATION_FAILED_INFO": "These files were uploaded, but unfortunately we could not generate the thumbnails for them.",
"UPLOAD_TO_COLLECTION": "Upload to album",
"UNCATEGORIZED": "Uncategorized",
- "MOVE_TO_UNCATEGORIZED": "Move to uncategorized",
"ARCHIVE": "Archive",
"ARCHIVE_COLLECTION": "Archive album",
"ARCHIVE_SECTION_NAME": "Archive",
@@ -350,10 +295,8 @@
"UNARCHIVE_COLLECTION": "Unarchive album",
"MOVE": "Move",
"ADD": "Add",
- "SORT": "Sort",
"REMOVE": "Remove",
"YES_REMOVE": "Yes, remove",
- "CONFIRM_REMOVE": "Confirm removal",
"REMOVE_FROM_COLLECTION": "Remove from album",
"TRASH": "Trash",
"MOVE_TO_TRASH": "Move to trash",
@@ -361,8 +304,6 @@
"TRASH_FILE_MESSAGE": "The file will be removed from all albums and moved to trash.",
"DELETE_PERMANENTLY": "Delete permanently",
"RESTORE": "Restore",
- "CONFIRM_RESTORE": "Confirm restoration",
- "RESTORE_MESSAGE": "Restore selected files ?",
"RESTORE_TO_COLLECTION": "Restore to album",
"EMPTY_TRASH": "Empty trash",
"EMPTY_TRASH_TITLE": "Empty trash?",
@@ -375,7 +316,6 @@
"CONFIRM_SELF_REMOVE_MESSAGE": "Selected items will be removed from this album. Items which are only in this album will be moved to Uncategorized.",
"CONFIRM_SELF_AND_OTHER_REMOVE_MESSAGE": "Some of the items you are removing were added by other people, and you will lose access to them.",
"SORT_BY_CREATION_TIME_ASCENDING": "Oldest",
- "SORT_BY_CREATION_TIME_DESCENDING": "Newest",
"SORT_BY_UPDATION_TIME_DESCENDING": "Last updated",
"SORT_BY_NAME": "Name",
"COMPRESS_THUMBNAILS": "Compress thumbnails",
@@ -392,22 +332,13 @@
"UPDATE_CREATION_TIME_NOT_STARTED": "Select the option you want to use",
"UPDATE_CREATION_TIME_COMPLETED": "Successfully updated all files",
"UPDATE_CREATION_TIME_COMPLETED_WITH_ERROR": "File time updation failed for some files, please retry",
- "FILE_NAME_CHARACTER_LIMIT": "100 characters max",
"CAPTION_CHARACTER_LIMIT": "5000 characters max",
"DATE_TIME_ORIGINAL": "EXIF:DateTimeOriginal",
"DATE_TIME_DIGITIZED": "EXIF:DateTimeDigitized",
"CUSTOM_TIME": "Custom time",
"REOPEN_PLAN_SELECTOR_MODAL": "Re-open plans",
"OPEN_PLAN_SELECTOR_MODAL_FAILED": "Failed to open plans",
- "COMMENT": "Comment",
- "ABUSE_REPORT_DESCRIPTION": "Submitting this report will notify the album owner.",
- "OTHER_REASON_REQUIRES_COMMENTS": "Reason = other, require a mandatory comment ",
- "REPORT_SUBMIT_SUCCESS_CONTENT": "Your report has been submitted",
- "REPORT_SUBMIT_SUCCESS_TITLE": "Report sent",
- "REPORT_SUBMIT_FAILED": "Failed to sent report, try again",
"INSTALL": "Install",
- "ALBUM_URL": "Album url",
- "PUBLIC_SHARING": "Public link",
"SHARING_DETAILS": "Sharing details",
"MODIFY_SHARING": "Modify sharing",
"NOT_FOUND": "404 - not found",
@@ -415,8 +346,6 @@
"LINK_EXPIRED_MESSAGE": "This link has either expired or been disabled!",
"MANAGE_LINK": "Manage link",
"LINK_TOO_MANY_REQUESTS": "This album is too popular for us to handle!",
- "DISABLE_PUBLIC_SHARING": "Disable public sharing",
- "DISABLE_PUBLIC_SHARING_MESSAGE": "Are you sure you want to disable public sharing?",
"FILE_DOWNLOAD": "Allow downloads",
"LINK_PASSWORD_LOCK": "Password lock",
"PUBLIC_COLLECT": "Allow adding photos",
@@ -425,26 +354,8 @@
"LINK_EXPIRY_NEVER": "Never",
"DISABLE_FILE_DOWNLOAD": "Disable download",
"DISABLE_FILE_DOWNLOAD_MESSAGE": "Are you sure that you want to disable the download button for files?
Viewers can still take screenshots or save a copy of your photos using external tools.
",
- "ABUSE_REPORT": "Abuse report",
- "ABUSE_REPORT_BUTTON_TEXT": "Report abuse?",
"MALICIOUS_CONTENT": "Contains malicious content",
"COPYRIGHT": "Infringes on the copyright of someone I am authorized to represent",
- "ENTER_EMAIL_ADDRESS": "Email*",
- "SELECT_REASON": "Select a reason*",
- "ENTER_FULL_NAME": "Full name*",
- "ENTER_DIGITAL_SIGNATURE": "Typing your full name in this box will act as your digital signature*",
- "ENTER_ON_BEHALF_OF": "I am reporting on behalf of*",
- "ENTER_ADDRESS": "Address*",
- "ENTER_JOB_TITLE": "Job title*",
- "ENTER_CITY": "City*",
- "ENTER_PHONE": "Phone number*",
- "ENTER_STATE": "State*",
- "ENTER_POSTAL_CODE": "Zip/postal code*",
- "ENTER_COUNTRY": "Country*",
- "JUDICIAL_DESCRIPTION": "By checking the following boxes, I state UNDER PENALTY OF PERJURY of law that:",
- "TERM_1": "I hereby state that I have a good faith belief that the sharing of copyrighted material at the location above is not authorized by the copyright owner, its agent, or the law (e.g., as a fair use). ",
- "TERM_2": "I hereby state that the information in this Notice is accurate and, under penalty of perjury, that I am the owner, or authorized to act on behalf of, the owner, of the copyright or of an exclusive right under the copyright that is allegedly infringed. ",
- "TERM_3": "I acknowledge that any person who knowingly materially misrepresents that material or activity is infringing may be subject to liability for damages. ",
"SHARED_USING": "Shared using ",
"ENTE_IO": "ente.io",
"LIVE": "LIVE",
@@ -453,11 +364,9 @@
"PASSWORD_LOCK": "Password lock",
"LOCK": "Lock",
"DOWNLOAD_UPLOAD_LOGS": "Debug logs",
- "CHOOSE_UPLOAD_TYPE": "Upload",
"UPLOAD_FILES": "File",
"UPLOAD_DIRS": "Folder",
"UPLOAD_GOOGLE_TAKEOUT": "Google takeout",
- "CANCEL_UPLOADS": "Cancel uploads",
"DEDUPLICATE_FILES": "Deduplicate files",
"AUTHENTICATOR_SECTION": "Authenticator",
"NO_DUPLICATES_FOUND": "You've no duplicate files that can be cleared",
@@ -471,11 +380,8 @@
"YES_STOP_UPLOADS": "Yes, stop uploads",
"albums_one": "1 Album",
"albums_other": "{{count}} Albums",
- "NEW": "New",
- "VIEW_ALL_ALBUMS": "View all Albums",
"ALL_ALBUMS": "All Albums",
"ALBUMS": "Albums",
- "ENDS": "Ends",
"ENTER_TWO_FACTOR_OTP": "Enter the 6-digit code from your authenticator app.",
"CREATE_ACCOUNT": "Create account",
"COPIED": "Copied",
@@ -531,7 +437,6 @@
"IGNORE_THIS_VERSION": "Ignore this version",
"TODAY": "Today",
"YESTERDAY": "Yesterday",
- "AT": "at",
"NAME_PLACEHOLDER": "Name...",
"ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED": "Cannot create albums from file/folder mix",
"ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED_MESSAGE": "You have dragged and dropped a mixture of files and folders.
Please provide either only files, or only folders when selecting option to create separate albums
",
@@ -550,7 +455,9 @@
"FACE_SEARCH_CONFIRMATION": "I understand, and wish to allow ente to process face geometry",
"LABS": "Labs",
"YOURS": "yours",
- "PASSPHRASE_STRENGTH": "Password strength: {{passwordStrength}}",
+ "PASSPHRASE_STRENGTH_WEAK": "Password strength: Weak",
+ "PASSPHRASE_STRENGTH_MODERATE": "Password strength: Moderate",
+ "PASSPHRASE_STRENGTH_STRONG": "Password strength: Strong",
"PREFERENCES": "Preferences",
"LANGUAGE": "Language",
"EXPORT_DIRECTORY_DOES_NOT_EXIST": "Invalid export directory",
@@ -569,5 +476,27 @@
"WEEK": "after a week",
"MONTH": "after a month",
"YEAR": "after a year"
- }
-}
\ No newline at end of file
+ },
+ "COPY_LINK": "Copy link",
+ "DONE": "Done",
+ "ADD_EMAIL_TITLE": "Share with specific people",
+ "LINK_SHARE_TITLE": "Or share a link",
+ "REMOVE_LINK": "Remove link",
+ "CREATE_PUBLIC_SHARING": "Create public link",
+ "PUBLIC_LINK_CREATED": "Public link created",
+ "PUBLIC_LINK_ENABLED": "Public link enabled",
+ "COLLECT_PHOTOS": "Collect photos",
+ "PUBLIC_COLLECT_SUBTEXT": "Allow people with the link to also add photos to the shared album.",
+ "STOP_EXPORT": "Stop",
+ "EXPORT_PROGRESS": "{{progress.current}} / {{progress.total}} files exported",
+ "EXPORT_NOTIFICATION": {
+ "START": "Export started",
+ "IN_PROGRESS": "Export already in progress",
+ "FINISH": "Export finished",
+ "UP_TO_DATE": "No new files to export"
+ },
+ "CONTINUOUS_EXPORT": "Sync continuously",
+ "TOTAL_ITEMS": "Total items",
+ "PENDING_ITEMS": "Pending items",
+ "EXPORT_STARTING": "Export starting..."
+}
diff --git a/public/locales/es/translation.json b/public/locales/es/translation.json
new file mode 100644
index 000000000..280e51edf
--- /dev/null
+++ b/public/locales/es/translation.json
@@ -0,0 +1,592 @@
+{
+ "HERO_SLIDE_1_TITLE": "",
+ "HERO_SLIDE_1": "",
+ "HERO_SLIDE_2_TITLE": "",
+ "HERO_SLIDE_2": "",
+ "HERO_SLIDE_3_TITLE": "",
+ "HERO_SLIDE_3": "",
+ "LOGIN": "",
+ "SIGN_UP": "",
+ "NEW_USER": "",
+ "EXISTING_USER": "",
+ "NAME": "",
+ "ENTER_NAME": "",
+ "PUBLIC_UPLOADER_NAME_MESSAGE": "",
+ "EMAIL": "",
+ "ENTER_EMAIL": "",
+ "DATA_DISCLAIMER": "",
+ "SUBMIT": "",
+ "EMAIL_ERROR": "",
+ "REQUIRED": "",
+ "VERIFY_EMAIL": "",
+ "EMAIL_SENT": "",
+ "CHECK_INBOX": "",
+ "ENTER_OTT": "",
+ "RESEND_MAIL": "",
+ "VERIFY": "",
+ "UNKNOWN_ERROR": "",
+ "INVALID_CODE": "",
+ "EXPIRED_CODE": "",
+ "SENDING": "",
+ "SENT": "",
+ "PASSWORD": "",
+ "LINK_PASSWORD": "",
+ "ENTER_PASSPHRASE": "",
+ "RETURN_PASSPHRASE_HINT": "",
+ "SET_PASSPHRASE": "",
+ "VERIFY_PASSPHRASE": "",
+ "INCORRECT_PASSPHRASE": "",
+ "ENTER_ENC_PASSPHRASE": "",
+ "PASSPHRASE_DISCLAIMER": "",
+ "WELCOME_TO_ENTE_HEADING": "",
+ "WELCOME_TO_ENTE_SUBHEADING": "",
+ "WHERE_YOUR_BEST_PHOTOS_LIVE": "",
+ "KEY_GENERATION_IN_PROGRESS_MESSAGE": "",
+ "PASSPHRASE_HINT": "",
+ "CONFIRM_PASSPHRASE": "",
+ "PASSPHRASE_MATCH_ERROR": "",
+ "CONSOLE_WARNING_STOP": "",
+ "CONSOLE_WARNING_DESC": "",
+ "SELECT_COLLECTION": "",
+ "CREATE_COLLECTION": "",
+ "ENTER_ALBUM_NAME": "",
+ "CLOSE_OPTION": "",
+ "ENTER_FILE_NAME": "",
+ "CLOSE": "",
+ "NO": "",
+ "NOTHING_HERE": "",
+ "UPLOAD": "",
+ "IMPORT": "",
+ "ADD_PHOTOS": "",
+ "ADD_MORE_PHOTOS": "",
+ "add_photos_one": "",
+ "add_photos_other": "",
+ "SELECT_PHOTOS": "",
+ "FILE_UPLOAD": "",
+ "UPLOAD_STAGE_MESSAGE": {
+ "0": "",
+ "1": "",
+ "2": "",
+ "3": "",
+ "4": "",
+ "5": ""
+ },
+ "UPLOADING_FILES": "",
+ "FILE_NOT_UPLOADED_LIST": "",
+ "SUBSCRIPTION_EXPIRED": "",
+ "SUBSCRIPTION_EXPIRED_MESSAGE": "",
+ "STORAGE_QUOTA_EXCEEDED": "",
+ "INITIAL_LOAD_DELAY_WARNING": "",
+ "USER_DOES_NOT_EXIST": "",
+ "UPLOAD_BUTTON_TEXT": "",
+ "NO_ACCOUNT": "",
+ "ACCOUNT_EXISTS": "",
+ "ALBUM_NAME": "",
+ "CREATE": "",
+ "DOWNLOAD": "",
+ "DOWNLOAD_OPTION": "",
+ "DOWNLOAD_FAVORITES": "",
+ "DOWNLOAD_UNCATEGORIZED": "",
+ "COPY_OPTION": "",
+ "TOGGLE_FULLSCREEN": "",
+ "ZOOM_IN_OUT": "",
+ "PREVIOUS": "",
+ "NEXT": "",
+ "NO_INTERNET_CONNECTION": "",
+ "TITLE": "",
+ "UPLOAD_FIRST_PHOTO": "",
+ "IMPORT_YOUR_FOLDERS": "",
+ "UPLOAD_DROPZONE_MESSAGE": "",
+ "WATCH_FOLDER_DROPZONE_MESSAGE": "",
+ "TRASH_FILES_TITLE": "",
+ "TRASH_FILE_TITLE": "",
+ "DELETE_FILES_TITLE": "",
+ "DELETE_FILES_MESSAGE": "",
+ "DELETE_FILE": "",
+ "DELETE": "",
+ "DELETE_OPTION": "",
+ "FAVORITE": "",
+ "FAVORITE_OPTION": "",
+ "UNFAVORITE_OPTION": "",
+ "UNFAVORITE": "",
+ "MULTI_FOLDER_UPLOAD": "",
+ "UPLOAD_STRATEGY_CHOICE": "",
+ "UPLOAD_STRATEGY_SINGLE_COLLECTION": "",
+ "OR": "",
+ "UPLOAD_STRATEGY_COLLECTION_PER_FOLDER": "",
+ "SESSION_EXPIRED_MESSAGE": "",
+ "SESSION_EXPIRED": "",
+ "SYNC_FAILED": "",
+ "PASSWORD_GENERATION_FAILED": "",
+ "CHANGE_PASSWORD": "",
+ "GO_BACK": "",
+ "RECOVERY_KEY": "",
+ "SAVE_LATER": "",
+ "SAVE": "",
+ "RECOVERY_KEY_DESCRIPTION": "",
+ "RECOVER_KEY_GENERATION_FAILED": "",
+ "KEY_NOT_STORED_DISCLAIMER": "",
+ "FORGOT_PASSWORD": "",
+ "RECOVER_ACCOUNT": "",
+ "RECOVERY_KEY_HINT": "",
+ "RECOVER": "",
+ "NO_RECOVERY_KEY": "",
+ "INCORRECT_RECOVERY_KEY": "",
+ "SORRY": "",
+ "NO_RECOVERY_KEY_MESSAGE": "",
+ "NO_TWO_FACTOR_RECOVERY_KEY_MESSAGE": "",
+ "CONTACT_SUPPORT": "",
+ "REQUEST_FEATURE": "",
+ "SUPPORT": "",
+ "CONFIRM": "",
+ "SKIP_SUBSCRIPTION_PURCHASE": "",
+ "CANCEL": "",
+ "LOGOUT": "",
+ "DELETE_ACCOUNT": "",
+ "DELETE_ACCOUNT_MESSAGE": "",
+ "LOGOUT_MESSAGE": "",
+ "CHANGE": "",
+ "CHANGE_EMAIL": "",
+ "OK": "",
+ "SUCCESS": "",
+ "ERROR": "",
+ "MESSAGE": "",
+ "INSTALL_MOBILE_APP": "",
+ "DOWNLOAD_APP_MESSAGE": "",
+ "DOWNLOAD_APP": "",
+ "EXPORT": "",
+ "SUBSCRIPTION": "",
+ "SUBSCRIBE": "",
+ "SUBSCRIPTION_PLAN": "",
+ "USAGE_DETAILS": "",
+ "MANAGE": "",
+ "MANAGEMENT_PORTAL": "",
+ "MANAGE_FAMILY_PORTAL": "",
+ "LEAVE_FAMILY_PLAN": "",
+ "LEAVE": "",
+ "LEAVE_FAMILY_CONFIRM": "",
+ "CHOOSE_PLAN": "",
+ "MANAGE_PLAN": "",
+ "ACTIVE": "",
+ "OFFLINE_MSG": "",
+ "FREE_SUBSCRIPTION_INFO": "",
+ "FAMILY_SUBSCRIPTION_INFO": "",
+ "RENEWAL_ACTIVE_SUBSCRIPTION_STATUS": "",
+ "RENEWAL_CANCELLED_SUBSCRIPTION_STATUS": "",
+ "RENEWAL_CANCELLED_SUBSCRIPTION_INFO": "",
+ "STORAGE_QUOTA_EXCEEDED_SUBSCRIPTION_INFO": "",
+ "SUBSCRIPTION_PURCHASE_SUCCESS": "",
+ "SUBSCRIPTION_PURCHASE_CANCELLED": "",
+ "SUBSCRIPTION_VERIFICATION_FAILED": "",
+ "SUBSCRIPTION_PURCHASE_FAILED": "",
+ "SUBSCRIPTION_UPDATE_FAILED": "",
+ "UPDATE_PAYMENT_METHOD_MESSAGE": "",
+ "STRIPE_AUTHENTICATION_FAILED": "",
+ "UPDATE_PAYMENT_METHOD": "",
+ "MONTHLY": "",
+ "YEARLY": "",
+ "UPDATE_SUBSCRIPTION_MESSAGE": "",
+ "UPDATE_SUBSCRIPTION": "",
+ "CANCEL_SUBSCRIPTION": "",
+ "CANCEL_SUBSCRIPTION_MESSAGE": "",
+ "SUBSCRIPTION_CANCEL_FAILED": "",
+ "SUBSCRIPTION_CANCEL_SUCCESS": "",
+ "REACTIVATE_SUBSCRIPTION": "",
+ "REACTIVATE_SUBSCRIPTION_MESSAGE": "",
+ "SUBSCRIPTION_ACTIVATE_SUCCESS": "",
+ "SUBSCRIPTION_ACTIVATE_FAILED": "",
+ "SUBSCRIPTION_PURCHASE_SUCCESS_TITLE": "",
+ "CANCEL_SUBSCRIPTION_ON_MOBILE": "",
+ "CANCEL_SUBSCRIPTION_ON_MOBILE_MESSAGE": "",
+ "MAIL_TO_MANAGE_SUBSCRIPTION": "",
+ "RENAME": "",
+ "RENAME_FILE": "",
+ "RENAME_COLLECTION": "",
+ "DELETE_COLLECTION_TITLE": "",
+ "DELETE_COLLECTION": "",
+ "DELETE_COLLECTION_FAILED": "",
+ "DELETE_COLLECTION_MESSAGE": "",
+ "DELETE_PHOTOS": "",
+ "KEEP_PHOTOS": "",
+ "SHARE": "",
+ "SHARE_COLLECTION": "",
+ "SHARE_WITH_PEOPLE": "",
+ "SHAREES": "",
+ "PUBLIC_URL": "",
+ "SHARE_WITH_SELF": "",
+ "ALREADY_SHARED": "",
+ "SHARING_BAD_REQUEST_ERROR": "",
+ "SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
+ "DOWNLOAD_COLLECTION": "",
+ "DOWNLOAD_COLLECTION_MESSAGE": "",
+ "DOWNLOAD_COLLECTION_FAILED": "",
+ "CREATE_ALBUM_FAILED": "",
+ "SEARCH_RESULTS": "",
+ "SEARCH_HINT": "",
+ "SEARCH_TYPE": {
+ "COLLECTION": "",
+ "LOCATION": "",
+ "DATE": "",
+ "FILE_NAME": "",
+ "THING": "",
+ "FILE_CAPTION": ""
+ },
+ "photos_count_zero": "",
+ "photos_count_one": "",
+ "photos_count_other": "",
+ "TERMS_AND_CONDITIONS": "",
+ "CONFIRM_PASSWORD_NOT_SAVED": "",
+ "ADD_TO_COLLECTION": "",
+ "SELECTED": "",
+ "VIDEO_PLAYBACK_FAILED": "",
+ "VIDEO_PLAYBACK_FAILED_DOWNLOAD_INSTEAD": "",
+ "PEOPLE": "",
+ "INDEXING_SCHEDULED": "",
+ "ANALYZING_PHOTOS": "",
+ "INDEXING_PEOPLE": "",
+ "INDEXING_DONE": "",
+ "UNIDENTIFIED_FACES": "",
+ "OBJECTS": "",
+ "TEXT": "",
+ "METADATA": "",
+ "INFO": "",
+ "INFO_OPTION": "",
+ "FILE_ID": "",
+ "FILE_NAME": "",
+ "CAPTION": "",
+ "CAPTION_PLACEHOLDER": "",
+ "CREATION_TIME": "",
+ "UPDATED_ON": "",
+ "LOCATION": "",
+ "SHOW_ON_MAP": "",
+ "DETAILS": "",
+ "VIEW_EXIF": "",
+ "NO_EXIF": "",
+ "EXIF": "",
+ "DEVICE": "",
+ "IMAGE_SIZE": "",
+ "FLASH": "",
+ "FOCAL_LENGTH": "",
+ "APERTURE": "",
+ "ISO": "",
+ "SHOW_ALL": "",
+ "TWO_FACTOR": "",
+ "TWO_FACTOR_AUTHENTICATION": "",
+ "TWO_FACTOR_QR_INSTRUCTION": "",
+ "ENTER_CODE_MANUALLY": "",
+ "TWO_FACTOR_MANUAL_CODE_INSTRUCTION": "",
+ "SCAN_QR_CODE": "",
+ "CONTINUE": "",
+ "BACK": "",
+ "ENABLE_TWO_FACTOR": "",
+ "ENABLE": "",
+ "LOST_DEVICE": "",
+ "INCORRECT_CODE": "",
+ "RECOVER_TWO_FACTOR": "",
+ "TWO_FACTOR_INFO": "",
+ "DISABLE_TWO_FACTOR_LABEL": "",
+ "UPDATE_TWO_FACTOR_LABEL": "",
+ "DISABLE": "",
+ "RECONFIGURE": "",
+ "UPDATE_TWO_FACTOR": "",
+ "UPDATE_TWO_FACTOR_MESSAGE": "",
+ "UPDATE": "",
+ "DISABLE_TWO_FACTOR": "",
+ "DISABLE_TWO_FACTOR_MESSAGE": "",
+ "TWO_FACTOR_SETUP_FAILED": "",
+ "TWO_FACTOR_SETUP_SUCCESS": "",
+ "TWO_FACTOR_DISABLE_SUCCESS": "",
+ "TWO_FACTOR_DISABLE_FAILED": "",
+ "EXPORT_DATA": "",
+ "SELECT_FOLDER": "",
+ "DESTINATION": "",
+ "START": "",
+ "EXPORT_IN_PROGRESS": "",
+ "PAUSE": "",
+ "RESUME": "",
+ "MINIMIZE": "",
+ "LAST_EXPORT_TIME": "",
+ "SUCCESSFULLY_EXPORTED_FILES": "",
+ "FAILED_EXPORTED_FILES": "",
+ "EXPORT_AGAIN": "",
+ "RETRY_EXPORT": "",
+ "LOCAL_STORAGE_NOT_ACCESSIBLE": "",
+ "LOCAL_STORAGE_NOT_ACCESSIBLE_MESSAGE": "",
+ "RETRY": "",
+ "SEND_OTT": "",
+ "EMAIl_ALREADY_OWNED": "",
+ "EMAIL_UDPATE_SUCCESSFUL": "",
+ "UPLOAD_FAILED": "",
+ "ETAGS_BLOCKED": "",
+ "SKIPPED_VIDEOS_INFO": "",
+ "LIVE_PHOTOS_DETECTED": "",
+ "RETRY_FAILED": "",
+ "FAILED_UPLOADS": "",
+ "SKIPPED_FILES": "",
+ "THUMBNAIL_GENERATION_FAILED_UPLOADS": "",
+ "UNSUPPORTED_FILES": "",
+ "SUCCESSFUL_UPLOADS": "",
+ "SKIPPED_INFO": "",
+ "UNSUPPORTED_INFO": "",
+ "BLOCKED_UPLOADS": "",
+ "SKIPPED_VIDEOS": "",
+ "INPROGRESS_METADATA_EXTRACTION": "",
+ "INPROGRESS_UPLOADS": "",
+ "TOO_LARGE_UPLOADS": "",
+ "LARGER_THAN_AVAILABLE_STORAGE_UPLOADS": "",
+ "LARGER_THAN_AVAILABLE_STORAGE_INFO": "",
+ "TOO_LARGE_INFO": "",
+ "THUMBNAIL_GENERATION_FAILED_INFO": "",
+ "UPLOAD_TO_COLLECTION": "",
+ "UNCATEGORIZED": "",
+ "MOVE_TO_UNCATEGORIZED": "",
+ "ARCHIVE": "",
+ "ARCHIVE_COLLECTION": "",
+ "ARCHIVE_SECTION_NAME": "",
+ "ALL_SECTION_NAME": "",
+ "MOVE_TO_COLLECTION": "",
+ "UNARCHIVE": "",
+ "UNARCHIVE_COLLECTION": "",
+ "MOVE": "",
+ "ADD": "",
+ "SORT": "",
+ "REMOVE": "",
+ "YES_REMOVE": "",
+ "CONFIRM_REMOVE": "",
+ "REMOVE_FROM_COLLECTION": "",
+ "TRASH": "",
+ "MOVE_TO_TRASH": "",
+ "TRASH_FILES_MESSAGE": "",
+ "TRASH_FILE_MESSAGE": "",
+ "DELETE_PERMANENTLY": "",
+ "RESTORE": "",
+ "CONFIRM_RESTORE": "",
+ "RESTORE_MESSAGE": "",
+ "RESTORE_TO_COLLECTION": "",
+ "EMPTY_TRASH": "",
+ "EMPTY_TRASH_TITLE": "",
+ "EMPTY_TRASH_MESSAGE": "",
+ "LEAVE_SHARED_ALBUM": "",
+ "LEAVE_ALBUM": "",
+ "LEAVE_SHARED_ALBUM_TITLE": "",
+ "LEAVE_SHARED_ALBUM_MESSAGE": "",
+ "NOT_FILE_OWNER": "",
+ "CONFIRM_SELF_REMOVE_MESSAGE": "",
+ "CONFIRM_SELF_AND_OTHER_REMOVE_MESSAGE": "",
+ "SORT_BY_CREATION_TIME_ASCENDING": "",
+ "SORT_BY_CREATION_TIME_DESCENDING": "",
+ "SORT_BY_UPDATION_TIME_DESCENDING": "",
+ "SORT_BY_NAME": "",
+ "COMPRESS_THUMBNAILS": "",
+ "THUMBNAIL_REPLACED": "",
+ "FIX_THUMBNAIL": "",
+ "FIX_THUMBNAIL_LATER": "",
+ "REPLACE_THUMBNAIL_NOT_STARTED": "",
+ "REPLACE_THUMBNAIL_COMPLETED": "",
+ "REPLACE_THUMBNAIL_NOOP": "",
+ "REPLACE_THUMBNAIL_COMPLETED_WITH_ERROR": "",
+ "FIX_CREATION_TIME": "",
+ "FIX_CREATION_TIME_IN_PROGRESS": "",
+ "CREATION_TIME_UPDATED": "",
+ "UPDATE_CREATION_TIME_NOT_STARTED": "",
+ "UPDATE_CREATION_TIME_COMPLETED": "",
+ "UPDATE_CREATION_TIME_COMPLETED_WITH_ERROR": "",
+ "FILE_NAME_CHARACTER_LIMIT": "",
+ "CAPTION_CHARACTER_LIMIT": "",
+ "DATE_TIME_ORIGINAL": "",
+ "DATE_TIME_DIGITIZED": "",
+ "CUSTOM_TIME": "",
+ "REOPEN_PLAN_SELECTOR_MODAL": "",
+ "OPEN_PLAN_SELECTOR_MODAL_FAILED": "",
+ "COMMENT": "",
+ "ABUSE_REPORT_DESCRIPTION": "",
+ "OTHER_REASON_REQUIRES_COMMENTS": "",
+ "REPORT_SUBMIT_SUCCESS_CONTENT": "",
+ "REPORT_SUBMIT_SUCCESS_TITLE": "",
+ "REPORT_SUBMIT_FAILED": "",
+ "INSTALL": "",
+ "ALBUM_URL": "",
+ "SHARING_DETAILS": "",
+ "MODIFY_SHARING": "",
+ "NOT_FOUND": "",
+ "LINK_EXPIRED": "",
+ "LINK_EXPIRED_MESSAGE": "",
+ "MANAGE_LINK": "",
+ "LINK_TOO_MANY_REQUESTS": "",
+ "DISABLE_PUBLIC_SHARING": "",
+ "DISABLE_PUBLIC_SHARING_MESSAGE": "",
+ "FILE_DOWNLOAD": "",
+ "LINK_PASSWORD_LOCK": "",
+ "PUBLIC_COLLECT": "",
+ "LINK_DEVICE_LIMIT": "",
+ "LINK_EXPIRY": "",
+ "LINK_EXPIRY_NEVER": "",
+ "DISABLE_FILE_DOWNLOAD": "",
+ "DISABLE_FILE_DOWNLOAD_MESSAGE": "",
+ "ABUSE_REPORT": "",
+ "ABUSE_REPORT_BUTTON_TEXT": "",
+ "MALICIOUS_CONTENT": "",
+ "COPYRIGHT": "",
+ "ENTER_EMAIL_ADDRESS": "",
+ "SELECT_REASON": "",
+ "ENTER_FULL_NAME": "",
+ "ENTER_DIGITAL_SIGNATURE": "",
+ "ENTER_ON_BEHALF_OF": "",
+ "ENTER_ADDRESS": "",
+ "ENTER_JOB_TITLE": "",
+ "ENTER_CITY": "",
+ "ENTER_PHONE": "",
+ "ENTER_STATE": "",
+ "ENTER_POSTAL_CODE": "",
+ "ENTER_COUNTRY": "",
+ "JUDICIAL_DESCRIPTION": "",
+ "TERM_1": "",
+ "TERM_2": "",
+ "TERM_3": "",
+ "SHARED_USING": "",
+ "ENTE_IO": "",
+ "LIVE": "",
+ "DISABLE_PASSWORD": "",
+ "DISABLE_PASSWORD_MESSAGE": "",
+ "PASSWORD_LOCK": "",
+ "LOCK": "",
+ "DOWNLOAD_UPLOAD_LOGS": "",
+ "CHOOSE_UPLOAD_TYPE": "",
+ "UPLOAD_FILES": "",
+ "UPLOAD_DIRS": "",
+ "UPLOAD_GOOGLE_TAKEOUT": "",
+ "CANCEL_UPLOADS": "",
+ "DEDUPLICATE_FILES": "",
+ "NO_DUPLICATES_FOUND": "",
+ "CLUB_BY_CAPTURE_TIME": "",
+ "FILES": "",
+ "EACH": "",
+ "DEDUPLICATE_BASED_ON_SIZE": "",
+ "DEDUPLICATE_BASED_ON_SIZE_AND_CAPTURE_TIME": "",
+ "STOP_ALL_UPLOADS_MESSAGE": "",
+ "STOP_UPLOADS_HEADER": "",
+ "YES_STOP_UPLOADS": "",
+ "albums_one": "",
+ "albums_other": "",
+ "NEW": "",
+ "VIEW_ALL_ALBUMS": "",
+ "ALL_ALBUMS": "",
+ "ALBUMS": "",
+ "ENDS": "",
+ "ENTER_TWO_FACTOR_OTP": "",
+ "CREATE_ACCOUNT": "",
+ "COPIED": "",
+ "CANVAS_BLOCKED_TITLE": "",
+ "CANVAS_BLOCKED_MESSAGE": "",
+ "WATCH_FOLDERS": "",
+ "UPGRADE_NOW": "",
+ "RENEW_NOW": "",
+ "STORAGE": "",
+ "USED": "",
+ "YOU": "",
+ "FAMILY": "",
+ "FREE": "",
+ "OF": "",
+ "WATCHED_FOLDERS": "",
+ "NO_FOLDERS_ADDED": "",
+ "FOLDERS_AUTOMATICALLY_MONITORED": "",
+ "UPLOAD_NEW_FILES_TO_ENTE": "",
+ "REMOVE_DELETED_FILES_FROM_ENTE": "",
+ "ADD_FOLDER": "",
+ "STOP_WATCHING": "",
+ "STOP_WATCHING_FOLDER": "",
+ "STOP_WATCHING_DIALOG_MESSAGE": "",
+ "YES_STOP": "",
+ "MONTH_SHORT": "",
+ "YEAR": "",
+ "FAMILY_PLAN": "",
+ "DOWNLOAD_LOGS": "",
+ "DOWNLOAD_LOGS_MESSAGE": "",
+ "CHANGE_FOLDER": "",
+ "TWO_MONTHS_FREE": "",
+ "GB": "",
+ "POPULAR": "",
+ "FREE_PLAN_OPTION_LABEL": "",
+ "FREE_PLAN_DESCRIPTION": "",
+ "CURRENT_USAGE": "",
+ "WEAK_DEVICE": "",
+ "DRAG_AND_DROP_HINT": "",
+ "ASK_FOR_FEEDBACK": "",
+ "SEND_FEEDBACK": "",
+ "CONFIRM_ACCOUNT_DELETION_TITLE": "",
+ "CONFIRM_ACCOUNT_DELETION_MESSAGE": "",
+ "AUTHENTICATE": "",
+ "UPLOADED_TO_SINGLE_COLLECTION": "",
+ "UPLOADED_TO_SEPARATE_COLLECTIONS": "",
+ "NEVERMIND": "",
+ "UPDATE_AVAILABLE": "",
+ "UPDATE_INSTALLABLE_MESSAGE": "",
+ "INSTALL_NOW": "",
+ "INSTALL_ON_NEXT_LAUNCH": "",
+ "UPDATE_AVAILABLE_MESSAGE": "",
+ "DOWNLOAD_AND_INSTALL": "",
+ "IGNORE_THIS_VERSION": "",
+ "TODAY": "",
+ "YESTERDAY": "",
+ "AT": "",
+ "NAME_PLACEHOLDER": "",
+ "ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED": "",
+ "ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED_MESSAGE": "",
+ "CHOSE_THEME": "",
+ "ML_SEARCH": "",
+ "ENABLE_ML_SEARCH_DESCRIPTION": "",
+ "ML_MORE_DETAILS": "",
+ "ENABLE_FACE_SEARCH": "",
+ "ENABLE_FACE_SEARCH_TITLE": "",
+ "ENABLE_FACE_SEARCH_DESCRIPTION": "",
+ "DISABLE_BETA": "",
+ "DISABLE_FACE_SEARCH": "",
+ "DISABLE_FACE_SEARCH_TITLE": "",
+ "DISABLE_FACE_SEARCH_DESCRIPTION": "",
+ "ADVANCED": "",
+ "FACE_SEARCH_CONFIRMATION": "",
+ "LABS": "",
+ "YOURS": "",
+ "PASSPHRASE_STRENGTH": "",
+ "PREFERENCES": "",
+ "LANGUAGE": "",
+ "EXPORT_DIRECTORY_DOES_NOT_EXIST": "",
+ "EXPORT_DIRECTORY_DOES_NOT_EXIST_MESSAGE": "",
+ "SUBSCRIPTION_VERIFICATION_ERROR": "",
+ "STORAGE_UNITS": {
+ "B": "",
+ "KB": "",
+ "MB": "",
+ "GB": "",
+ "TB": ""
+ },
+ "AFTER_TIME": {
+ "HOUR": "",
+ "DAY": "",
+ "WEEK": "",
+ "MONTH": "",
+ "YEAR": ""
+ },
+ "COPY_LINK": "",
+ "DONE": "",
+ "ADD_EMAIL_TITLE": "",
+ "LINK_SHARE_TITLE": "",
+ "REMOVE_LINK": "",
+ "CREATE_PUBLIC_SHARING": "",
+ "PUBLIC_LINK_CREATED": "",
+ "PUBLIC_LINK_ENABLED": "",
+ "COLLECT_PHOTOS": "",
+ "PUBLIC_COLLECT_SUBTEXT": "",
+ "STOP_EXPORT": "",
+ "EXPORT_PROGRESS": "",
+ "EXPORT_NOTIFICATION": {
+ "START": "",
+ "IN_PROGRESS": "",
+ "FINISH": "",
+ "UP_TO_DATE": ""
+ },
+ "CONTINUOUS_EXPORT": "",
+ "TOTAL_ITEMS": "",
+ "PENDING_ITEMS": "",
+ "EXPORT_STARTING": ""
+}
\ No newline at end of file
diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json
index 90d6f81da..5c50ddb60 100644
--- a/public/locales/fr/translation.json
+++ b/public/locales/fr/translation.json
@@ -1,7 +1,7 @@
{
- "HERO_SLIDE_1_TITLE": "Sauvegardes personnelles
de vos souvenirs
",
+ "HERO_SLIDE_1_TITLE": "Sauvegardes personnelles
de vos souvenirs
",
"HERO_SLIDE_1": "Chiffrement de bout en bout par défaut",
- "HERO_SLIDE_2_TITLE": "Sécurisé
dans un abri antiatomique
",
+ "HERO_SLIDE_2_TITLE": "Sécurisé
dans un abri antiatomique
",
"HERO_SLIDE_2": "Conçu pour survivre",
"HERO_SLIDE_3_TITLE": "Disponible
partout
",
"HERO_SLIDE_3": "Android, iOS, Web, Ordinateur",
@@ -19,10 +19,10 @@
"EMAIL_ERROR": "Saisir un e-mail valide",
"REQUIRED": "Nécessaire",
"VERIFY_EMAIL": "Vérifier l'e-mail",
- "EMAIL_SENT": "Verification code sent to {{emailID}} ",
+ "EMAIL_SENT": "Verification code sent to {{email}} ",
"CHECK_INBOX": "Veuillez consulter votre boite de réception (et indésirables) pour poursuivre la vérification",
"ENTER_OTT": "Code de vérification",
- "RESEND_MAIL": "envoyer le code",
+ "RESEND_MAIL": "Envoyer le code",
"VERIFY": "Vérifier",
"UNKNOWN_ERROR": "Quelque chose s'est mal passé, veuillez recommencer",
"INVALID_CODE": "Code de vérification non valide",
@@ -37,7 +37,7 @@
"VERIFY_PASSPHRASE": "Connexion",
"INCORRECT_PASSPHRASE": "Mot de passe non valide",
"ENTER_ENC_PASSPHRASE": "Veuillez saisir un mot de passe que nous pourrons utiliser pour chiffrer vos données",
- "PASSPHRASE_DISCLAIMER": "Nous ne stockons pas votre mot de passe, donc si vous le perdez, nous ne pourrons pas vous aider à récupérer vosdonnées sans une clé de récupération.",
+ "PASSPHRASE_DISCLAIMER": "Nous ne stockons pas votre mot de passe, donc si vous le perdez, nous ne pourrons pas vous aider à récupérer vos données sans une clé de récupération.",
"WELCOME_TO_ENTE_HEADING": "Bienvenue sur ",
"WELCOME_TO_ENTE_SUBHEADING": "Stockage et partage photo avec cryptage de bout en bout",
"WHERE_YOUR_BEST_PHOTOS_LIVE": "Là où vivent vos meilleures photos",
@@ -56,23 +56,25 @@
"NO": "Non",
"NOTHING_HERE": "Il n'y a encore rien à voir ici 👀",
"UPLOAD": "Charger",
- "IMPORT": "Import",
+ "IMPORT": "Importer",
"ADD_PHOTOS": "Ajouter des photos",
"ADD_MORE_PHOTOS": "Ajouter plus de photos",
+ "add_photos_one": "Ajouter une photo",
+ "add_photos_other": "Ajouter {{count}} photos",
"SELECT_PHOTOS": "Sélectionner des photos",
"FILE_UPLOAD": "Fichier chargé",
"UPLOAD_STAGE_MESSAGE": {
"0": "Préparation du chargement",
"1": "Lire les fichiers métadonnées de Google",
- "2": "{{uploadCounter.finished}} / {{uploadCounter.total}} files metadata extracted",
- "3": "{{uploadCounter.finished}} / {{uploadCounter.total}} files backed up",
+ "2": "Métadonnées des fichiers {{uploadCounter.finished}} / {{uploadCounter.total}} extraites",
+ "3": "{{uploadCounter.finished}} / {{uploadCounter.total}} fichiers sauvegardés",
"4": "Annulation des chargements restants",
"5": "Sauvegarde terminée"
},
"UPLOADING_FILES": "Chargement de fichiers",
"FILE_NOT_UPLOADED_LIST": "Les fichiers suivants n'ont pas été chargés",
"SUBSCRIPTION_EXPIRED": "Abonnement expiré",
- "SUBSCRIPTION_EXPIRED_MESSAGE": "Votre abonnement a expiré, veuillezle renouvelleer ",
+ "SUBSCRIPTION_EXPIRED_MESSAGE": "Votre abonnement a expiré, veuillez le renouveler ",
"STORAGE_QUOTA_EXCEEDED": "Limite de stockage atteinte",
"INITIAL_LOAD_DELAY_WARNING": "La première consultation peut prendre du temps",
"USER_DOES_NOT_EXIST": "Désolé, impossible de trouver un utilisateur avec cet e-mail",
@@ -93,7 +95,7 @@
"NO_INTERNET_CONNECTION": "Veuillez vérifier votre connexion internet puis réessayer",
"TITLE": "ente Photos",
"UPLOAD_FIRST_PHOTO": "Chargez votre 1ere photo",
- "IMPORT_YOUR_FOLDERS": "Import your folders",
+ "IMPORT_YOUR_FOLDERS": "Importez vos dossiers",
"UPLOAD_DROPZONE_MESSAGE": "Déposez pour sauvegarder vos fichiers",
"WATCH_FOLDER_DROPZONE_MESSAGE": "Déposez pour ajouter un dossier surveillé",
"TRASH_FILES_TITLE": "Supprimer les fichiers?",
@@ -128,11 +130,11 @@
"RECOVER_ACCOUNT": "Récupérer le compte",
"RECOVERY_KEY_HINT": "Clé de récupération",
"RECOVER": "Récupérer",
- "NO_RECOVERY_KEY": "Pas de clé de récuparation?",
+ "NO_RECOVERY_KEY": "Pas de clé de récupération?",
"INCORRECT_RECOVERY_KEY": "Clé de récupération non valide",
"SORRY": "Désolé",
"NO_RECOVERY_KEY_MESSAGE": "En raison de notre protocole de chiffrement de bout en bout, vos données ne peuvent être décryptées sans votre mot de passe ou clé de récupération",
- "NO_TWO_FACTOR_RECOVERY_KEY_MESSAGE": "Veuillez envoyer un e-mail à{{emailID} depuis votre adresse enregistrée",
+ "NO_TWO_FACTOR_RECOVERY_KEY_MESSAGE": "Veuillez envoyer un e-mail à {{emailID}} depuis votre adresse enregistrée",
"CONTACT_SUPPORT": "Contacter le support",
"REQUEST_FEATURE": "Soumettre une idée",
"SUPPORT": "Support",
@@ -141,11 +143,11 @@
"CANCEL": "Annuler",
"LOGOUT": "Déconnexion",
"DELETE_ACCOUNT": "Supprimer le compte",
- "DELETE_ACCOUNT_MESSAGE": "Veuillez envoyer un e-mail à <1>account-deletion@ente.io1> depuis votre adresse enregistrée.
Votre demande sera traitée dans les 72 heures.
",
+ "DELETE_ACCOUNT_MESSAGE": "Veuillez envoyer un e-mail à {{emailID}} depuis Votre adresse enregistrée.
Votre demande sera traitée dans les 72 heures.
",
"LOGOUT_MESSAGE": "Voulez-vous vraiment vous déconnecter?",
"CHANGE": "Modifier",
"CHANGE_EMAIL": "Modifier l'e-mail",
- "OK": "OK",
+ "OK": "Ok",
"SUCCESS": "Parfait",
"ERROR": "Erreur",
"MESSAGE": "Message",
@@ -169,11 +171,11 @@
"OFFLINE_MSG": "Vous êtes hors-ligne, les mémoires cache sont affichées",
"FREE_SUBSCRIPTION_INFO": "Vous êtes sur le plan gratuit qui expire le {{date, dateTime}}",
"FAMILY_SUBSCRIPTION_INFO": "Vous êtes sur le plan famille géré par",
- "RENEWAL_ACTIVE_SUBSCRIPTION_STATUS": "Renouveller le {{date, dateTime}}",
+ "RENEWAL_ACTIVE_SUBSCRIPTION_STATUS": "Renouveler le {{date, dateTime}}",
"RENEWAL_CANCELLED_SUBSCRIPTION_STATUS": "Pris fin le {{date, dateTime}}",
"RENEWAL_CANCELLED_SUBSCRIPTION_INFO": "Votre abonnement sera annulé le {{date, dateTime}}",
- "STORAGE_QUOTA_EXCEEDED_SUBSCRIPTION_INFO": "Vous avez dépassé votre quota de stockage,, veuillez mettre à niveau ",
- "SUBSCRIPTION_PURCHASE_SUCCESS": "Nous avons reçu votre paiement
Votre abonnement est valide jusqu'au {{date, dateTime}}
",
+ "STORAGE_QUOTA_EXCEEDED_SUBSCRIPTION_INFO": "Vous avez dépassé votre quota de stockage, veuillez mettre à niveau ",
+ "SUBSCRIPTION_PURCHASE_SUCCESS": "Nous avons reçu votre paiement
Votre abonnement est valide jusqu'au {{date, dateTime}}
",
"SUBSCRIPTION_PURCHASE_CANCELLED": "Votre achat est annulé, veuillez réessayer si vous souhaitez vous abonner",
"SUBSCRIPTION_VERIFICATION_FAILED": "Nous ne sommes pas encore en mesure de vérifier votre achat, cela peut prendre quelques heures",
"SUBSCRIPTION_PURCHASE_FAILED": "Échec lors de l'achat de l'abonnement, veuillez réessayer",
@@ -211,7 +213,7 @@
"SHARE_WITH_PEOPLE": "Partager avec vos proches",
"SHAREES": "Partager avec",
"PUBLIC_URL": "Lien public",
- "SHARE_WITH_SELF": "Oups, vous ne pouvez pas partager avec vous même",
+ "SHARE_WITH_SELF": "Oups, vous ne pouvez pas partager avec vous-même",
"ALREADY_SHARED": "Oups, vous partager déjà cela avec {{email}}",
"SHARING_BAD_REQUEST_ERROR": "Partage d'album non autorisé",
"SHARING_DISABLED_FOR_FREE_ACCOUNTS": "Le partage est désactivé pour les comptes gratuits",
@@ -230,22 +232,22 @@
"FILE_CAPTION": "Description"
},
"photos_count_zero": "Pas de souvenirs",
- "photos_count_one": "1 mémoire",
+ "photos_count_one": "1 souvenir",
"photos_count_other": "{{count}} souvenirs",
- "TERMS_AND_CONDITIONS": "I agree to the terms and privacy policy ",
+ "TERMS_AND_CONDITIONS": "J'accepte les conditions et la politique de confidentialité ",
"CONFIRM_PASSWORD_NOT_SAVED": "Je comprend que si je perd le mot de passe,je peux perdre mes données puisque mes données sont{' '}<1>chiffrées de bout en bout1>avec ente
",
"ADD_TO_COLLECTION": "Ajouter à l'album",
- "SELECTED": "sélectionné",
+ "SELECTED": "Sélectionné",
"VIDEO_PLAYBACK_FAILED": "Le format vidéo n'est pas supporté",
"VIDEO_PLAYBACK_FAILED_DOWNLOAD_INSTEAD": "Cette vidéo ne peut pas être lue sur votre navigateur",
- "PEOPLE": "People",
- "INDEXING_SCHEDULED": "indexing is scheduled...",
- "ANALYZING_PHOTOS": "analyzing new photos {{indexStatus.nSyncedFiles}} of {{indexStatus.nTotalFiles}} done)...",
- "INDEXING_PEOPLE": "indexing people in {{indexStatus.nSyncedFiles}} photos...",
- "INDEXING_DONE": "indexed {{indexStatus.nSyncedFiles}} photos",
- "UNIDENTIFIED_FACES": "unidentified faces",
- "OBJECTS": "objects",
- "TEXT": "text",
+ "PEOPLE": "Visages",
+ "INDEXING_SCHEDULED": "L'indexation est planifiée...",
+ "ANALYZING_PHOTOS": "analyse des nouvelles photos {{indexStatus.nSyncedFiles}} sur {{indexStatus.nTotalFiles}} effectué)...",
+ "INDEXING_PEOPLE": "indexation des visages dans {{indexStatus.nSyncedFiles}} photos...",
+ "INDEXING_DONE": "{{indexStatus.nSyncedFiles}} photos indexées",
+ "UNIDENTIFIED_FACES": "visages non-identifiés",
+ "OBJECTS": "objets",
+ "TEXT": "texte",
"METADATA": "Metadonnées",
"INFO": "Info ",
"INFO_OPTION": "Info (I)",
@@ -298,7 +300,6 @@
"EXPORT_DATA": "Exporter les données",
"SELECT_FOLDER": "Sélectionner un dossier",
"DESTINATION": "Destination",
- "EXPORT_SIZE": "Taille d'export",
"START": "Démarrer",
"EXPORT_IN_PROGRESS": "Export en cours...",
"PAUSE": "Pause",
@@ -405,7 +406,6 @@
"REPORT_SUBMIT_FAILED": "Échec lors de l'envoi du commentaire, veuillez réessayer",
"INSTALL": "Installer",
"ALBUM_URL": "Lien de l'album",
- "PUBLIC_SHARING": "Lien public",
"SHARING_DETAILS": "Détails du partage",
"MODIFY_SHARING": "Modifier le partage",
"NOT_FOUND": "404 - non trouvé",
@@ -454,11 +454,11 @@
"CHOOSE_UPLOAD_TYPE": "Charger",
"UPLOAD_FILES": "Fichier",
"UPLOAD_DIRS": "Dossier",
- "UPLOAD_GOOGLE_TAKEOUT": "Google takeout",
+ "UPLOAD_GOOGLE_TAKEOUT": "Google Takeout",
"CANCEL_UPLOADS": "Annuler les chargements",
"DEDUPLICATE_FILES": "Déduplication de fichiers",
"NO_DUPLICATES_FOUND": "Vous n'avez aucun fichier dédupliqué pouvant être nettoyé",
- "CLUB_BY_CAPTURE_TIME": "Club by capture time",
+ "CLUB_BY_CAPTURE_TIME": "Durée de la capture par club",
"FILES": "Fichiers",
"EACH": "Chacun",
"DEDUPLICATE_BASED_ON_SIZE": "Les fichiers suivants ont été clubbed, basé sur leurs tailles, veuillez corriger et supprimer les objets que vous pensez être dupliqués",
@@ -466,13 +466,13 @@
"STOP_ALL_UPLOADS_MESSAGE": "Êtes-vous certains de vouloir arrêter tous les chargements en cours?",
"STOP_UPLOADS_HEADER": "Arrêter les chargements?",
"YES_STOP_UPLOADS": "Oui, arrêter tout",
- "albums_one": "1 Album",
- "albums_other": "{{count}} Albums",
+ "albums_one": "1 album",
+ "albums_other": "{{count}} albums",
"NEW": "Nouveau",
"VIEW_ALL_ALBUMS": "Voir tous les albums",
"ALL_ALBUMS": "Tous les albums",
"ALBUMS": "Albums",
- "ENDS": "Ends",
+ "ENDS": "Fin",
"ENTER_TWO_FACTOR_OTP": "Saisir le code à 6 caractères de votre appli d'authentification.",
"CREATE_ACCOUNT": "Créer un compte",
"COPIED": "Copieé",
@@ -534,25 +534,25 @@
"ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED_MESSAGE": "Vous avez glissé déposé un mélange de fichiers et dossiers.
Veuillez sélectionner soit uniquement des fichiers, ou des dossiers lors du choix d'options pour créer des albums séparés
",
"CHOSE_THEME": "Choisir un thème",
"ML_SEARCH": "ML search (beta)",
- "ENABLE_ML_SEARCH_DESCRIPTION": "This will enable on-device machine learning and face search which will start analyzing your uploaded photos locally.
For the first run after login or enabling this feature, it will download all images on local device to analyze them. So please only enable this if you are ok with bandwidth and local processing of all images in your photo library.
If this is the first time you're enabling this, we'll also ask your permission to process face data.
",
- "ML_MORE_DETAILS": "More details",
- "ENABLE_FACE_SEARCH": "Enable face search",
- "ENABLE_FACE_SEARCH_TITLE": "Enable face search?",
+ "ENABLE_ML_SEARCH_DESCRIPTION": "Ceci activera l'apprentissage automatique sur l'appareil et la recherche faciale qui commencera à analyser vos photos chargées.
Pour la première exécution après la connexion ou l'activation de cette fonctionnalité, cela téléchargera toutes les images sur l'appareil local pour les analyser. Veuillez donc activer ceci uniquement si vous avez de la bande passante et le traitement local de toutes les images dans votre photothèque.
Si c'est la première fois que vous activez ceci, nous vous demanderons également la permission de traiter les données faciales.
",
+ "ML_MORE_DETAILS": "Plus de détails",
+ "ENABLE_FACE_SEARCH": "Activer la recherche faciale",
+ "ENABLE_FACE_SEARCH_TITLE": "Activer la recherche faciale ?",
"ENABLE_FACE_SEARCH_DESCRIPTION": "If you enable face search, ente will extract face geometry from your photos. This will happen on your device, and any generated biometric data will be end-to-encrypted.
Please click here for more details about this feature in our privacy policy
",
- "DISABLE_BETA": "Disable beta",
- "DISABLE_FACE_SEARCH": "Disable face search",
- "DISABLE_FACE_SEARCH_TITLE": "Disable face search?",
+ "DISABLE_BETA": "Désactiver la bêta",
+ "DISABLE_FACE_SEARCH": "Désactiver la recherche faciale",
+ "DISABLE_FACE_SEARCH_TITLE": "Désactiver la recherche faciale ?",
"DISABLE_FACE_SEARCH_DESCRIPTION": "ente will stop processing face geometry, and will also disable ML search (beta)
You can reenable face search again if you wish, so this operation is safe
",
- "ADVANCED": "Advanced",
- "FACE_SEARCH_CONFIRMATION": "I understand, and wish to allow ente to process face geometry",
+ "ADVANCED": "Avancé",
+ "FACE_SEARCH_CONFIRMATION": "Je comprends, et je souhaite permettre à ente de traiter la géométrie faciale",
"LABS": "Labs",
"YOURS": "Le vôtre",
- "PASSPHRASE_STRENGTH": "Password strength: {{passwordStrength}}",
+ "PASSPHRASE_STRENGTH": "Force du mot de passe : {{passwordStrength}}",
"PREFERENCES": "Préférences",
"LANGUAGE": "Langue",
"EXPORT_DIRECTORY_DOES_NOT_EXIST": "Dossier d'export invalide",
"EXPORT_DIRECTORY_DOES_NOT_EXIST_MESSAGE": " Le dossier d'export que vous avez sélectionné n'existe pas
Veuillez sélectionner un dossier valide
",
- "SUBSCRIPTION_VERIFICATION_ERROR": "Subscription verification failed",
+ "SUBSCRIPTION_VERIFICATION_ERROR": "Échec de la vérification de l'abonnement",
"STORAGE_UNITS": {
"B": "o",
"KB": "Ko",
@@ -566,5 +566,27 @@
"WEEK": "dans une semaine",
"MONTH": "dans un mois",
"YEAR": "dans un an"
- }
+ },
+ "COPY_LINK": "Copier le lien",
+ "DONE": "Terminé",
+ "ADD_EMAIL_TITLE": "Partager avec des personnes spécifiques",
+ "LINK_SHARE_TITLE": "Ou partager un lien",
+ "REMOVE_LINK": "Supprimer le lien",
+ "CREATE_PUBLIC_SHARING": "Créer un lien public",
+ "PUBLIC_LINK_CREATED": "Lien public créé",
+ "PUBLIC_LINK_ENABLED": "Lien public activé",
+ "COLLECT_PHOTOS": "Récupérer les photos",
+ "PUBLIC_COLLECT_SUBTEXT": "Autoriser les personnes ayant le lien d'ajouter des photos à l'album partagé.",
+ "STOP_EXPORT": "Stop",
+ "EXPORT_PROGRESS": "{{progress.current}} / {{progress.total}} fichiers exportés",
+ "EXPORT_NOTIFICATION": {
+ "START": "L'export a démarré",
+ "IN_PROGRESS": "Un export est déjà en cours",
+ "FINISH": "Export terminé",
+ "UP_TO_DATE": "Aucun nouveau fichier à exporter"
+ },
+ "CONTINUOUS_EXPORT": "Synchronisation en continu",
+ "TOTAL_ITEMS": "Total d'objets",
+ "PENDING_ITEMS": "Objets en attente",
+ "EXPORT_STARTING": "Démarrage de l'export..."
}
\ No newline at end of file
diff --git a/public/locales/it/translation.json b/public/locales/it/translation.json
new file mode 100644
index 000000000..280e51edf
--- /dev/null
+++ b/public/locales/it/translation.json
@@ -0,0 +1,592 @@
+{
+ "HERO_SLIDE_1_TITLE": "",
+ "HERO_SLIDE_1": "",
+ "HERO_SLIDE_2_TITLE": "",
+ "HERO_SLIDE_2": "",
+ "HERO_SLIDE_3_TITLE": "",
+ "HERO_SLIDE_3": "",
+ "LOGIN": "",
+ "SIGN_UP": "",
+ "NEW_USER": "",
+ "EXISTING_USER": "",
+ "NAME": "",
+ "ENTER_NAME": "",
+ "PUBLIC_UPLOADER_NAME_MESSAGE": "",
+ "EMAIL": "",
+ "ENTER_EMAIL": "",
+ "DATA_DISCLAIMER": "",
+ "SUBMIT": "",
+ "EMAIL_ERROR": "",
+ "REQUIRED": "",
+ "VERIFY_EMAIL": "",
+ "EMAIL_SENT": "",
+ "CHECK_INBOX": "",
+ "ENTER_OTT": "",
+ "RESEND_MAIL": "",
+ "VERIFY": "",
+ "UNKNOWN_ERROR": "",
+ "INVALID_CODE": "",
+ "EXPIRED_CODE": "",
+ "SENDING": "",
+ "SENT": "",
+ "PASSWORD": "",
+ "LINK_PASSWORD": "",
+ "ENTER_PASSPHRASE": "",
+ "RETURN_PASSPHRASE_HINT": "",
+ "SET_PASSPHRASE": "",
+ "VERIFY_PASSPHRASE": "",
+ "INCORRECT_PASSPHRASE": "",
+ "ENTER_ENC_PASSPHRASE": "",
+ "PASSPHRASE_DISCLAIMER": "",
+ "WELCOME_TO_ENTE_HEADING": "",
+ "WELCOME_TO_ENTE_SUBHEADING": "",
+ "WHERE_YOUR_BEST_PHOTOS_LIVE": "",
+ "KEY_GENERATION_IN_PROGRESS_MESSAGE": "",
+ "PASSPHRASE_HINT": "",
+ "CONFIRM_PASSPHRASE": "",
+ "PASSPHRASE_MATCH_ERROR": "",
+ "CONSOLE_WARNING_STOP": "",
+ "CONSOLE_WARNING_DESC": "",
+ "SELECT_COLLECTION": "",
+ "CREATE_COLLECTION": "",
+ "ENTER_ALBUM_NAME": "",
+ "CLOSE_OPTION": "",
+ "ENTER_FILE_NAME": "",
+ "CLOSE": "",
+ "NO": "",
+ "NOTHING_HERE": "",
+ "UPLOAD": "",
+ "IMPORT": "",
+ "ADD_PHOTOS": "",
+ "ADD_MORE_PHOTOS": "",
+ "add_photos_one": "",
+ "add_photos_other": "",
+ "SELECT_PHOTOS": "",
+ "FILE_UPLOAD": "",
+ "UPLOAD_STAGE_MESSAGE": {
+ "0": "",
+ "1": "",
+ "2": "",
+ "3": "",
+ "4": "",
+ "5": ""
+ },
+ "UPLOADING_FILES": "",
+ "FILE_NOT_UPLOADED_LIST": "",
+ "SUBSCRIPTION_EXPIRED": "",
+ "SUBSCRIPTION_EXPIRED_MESSAGE": "",
+ "STORAGE_QUOTA_EXCEEDED": "",
+ "INITIAL_LOAD_DELAY_WARNING": "",
+ "USER_DOES_NOT_EXIST": "",
+ "UPLOAD_BUTTON_TEXT": "",
+ "NO_ACCOUNT": "",
+ "ACCOUNT_EXISTS": "",
+ "ALBUM_NAME": "",
+ "CREATE": "",
+ "DOWNLOAD": "",
+ "DOWNLOAD_OPTION": "",
+ "DOWNLOAD_FAVORITES": "",
+ "DOWNLOAD_UNCATEGORIZED": "",
+ "COPY_OPTION": "",
+ "TOGGLE_FULLSCREEN": "",
+ "ZOOM_IN_OUT": "",
+ "PREVIOUS": "",
+ "NEXT": "",
+ "NO_INTERNET_CONNECTION": "",
+ "TITLE": "",
+ "UPLOAD_FIRST_PHOTO": "",
+ "IMPORT_YOUR_FOLDERS": "",
+ "UPLOAD_DROPZONE_MESSAGE": "",
+ "WATCH_FOLDER_DROPZONE_MESSAGE": "",
+ "TRASH_FILES_TITLE": "",
+ "TRASH_FILE_TITLE": "",
+ "DELETE_FILES_TITLE": "",
+ "DELETE_FILES_MESSAGE": "",
+ "DELETE_FILE": "",
+ "DELETE": "",
+ "DELETE_OPTION": "",
+ "FAVORITE": "",
+ "FAVORITE_OPTION": "",
+ "UNFAVORITE_OPTION": "",
+ "UNFAVORITE": "",
+ "MULTI_FOLDER_UPLOAD": "",
+ "UPLOAD_STRATEGY_CHOICE": "",
+ "UPLOAD_STRATEGY_SINGLE_COLLECTION": "",
+ "OR": "",
+ "UPLOAD_STRATEGY_COLLECTION_PER_FOLDER": "",
+ "SESSION_EXPIRED_MESSAGE": "",
+ "SESSION_EXPIRED": "",
+ "SYNC_FAILED": "",
+ "PASSWORD_GENERATION_FAILED": "",
+ "CHANGE_PASSWORD": "",
+ "GO_BACK": "",
+ "RECOVERY_KEY": "",
+ "SAVE_LATER": "",
+ "SAVE": "",
+ "RECOVERY_KEY_DESCRIPTION": "",
+ "RECOVER_KEY_GENERATION_FAILED": "",
+ "KEY_NOT_STORED_DISCLAIMER": "",
+ "FORGOT_PASSWORD": "",
+ "RECOVER_ACCOUNT": "",
+ "RECOVERY_KEY_HINT": "",
+ "RECOVER": "",
+ "NO_RECOVERY_KEY": "",
+ "INCORRECT_RECOVERY_KEY": "",
+ "SORRY": "",
+ "NO_RECOVERY_KEY_MESSAGE": "",
+ "NO_TWO_FACTOR_RECOVERY_KEY_MESSAGE": "",
+ "CONTACT_SUPPORT": "",
+ "REQUEST_FEATURE": "",
+ "SUPPORT": "",
+ "CONFIRM": "",
+ "SKIP_SUBSCRIPTION_PURCHASE": "",
+ "CANCEL": "",
+ "LOGOUT": "",
+ "DELETE_ACCOUNT": "",
+ "DELETE_ACCOUNT_MESSAGE": "",
+ "LOGOUT_MESSAGE": "",
+ "CHANGE": "",
+ "CHANGE_EMAIL": "",
+ "OK": "",
+ "SUCCESS": "",
+ "ERROR": "",
+ "MESSAGE": "",
+ "INSTALL_MOBILE_APP": "",
+ "DOWNLOAD_APP_MESSAGE": "",
+ "DOWNLOAD_APP": "",
+ "EXPORT": "",
+ "SUBSCRIPTION": "",
+ "SUBSCRIBE": "",
+ "SUBSCRIPTION_PLAN": "",
+ "USAGE_DETAILS": "",
+ "MANAGE": "",
+ "MANAGEMENT_PORTAL": "",
+ "MANAGE_FAMILY_PORTAL": "",
+ "LEAVE_FAMILY_PLAN": "",
+ "LEAVE": "",
+ "LEAVE_FAMILY_CONFIRM": "",
+ "CHOOSE_PLAN": "",
+ "MANAGE_PLAN": "",
+ "ACTIVE": "",
+ "OFFLINE_MSG": "",
+ "FREE_SUBSCRIPTION_INFO": "",
+ "FAMILY_SUBSCRIPTION_INFO": "",
+ "RENEWAL_ACTIVE_SUBSCRIPTION_STATUS": "",
+ "RENEWAL_CANCELLED_SUBSCRIPTION_STATUS": "",
+ "RENEWAL_CANCELLED_SUBSCRIPTION_INFO": "",
+ "STORAGE_QUOTA_EXCEEDED_SUBSCRIPTION_INFO": "",
+ "SUBSCRIPTION_PURCHASE_SUCCESS": "",
+ "SUBSCRIPTION_PURCHASE_CANCELLED": "",
+ "SUBSCRIPTION_VERIFICATION_FAILED": "",
+ "SUBSCRIPTION_PURCHASE_FAILED": "",
+ "SUBSCRIPTION_UPDATE_FAILED": "",
+ "UPDATE_PAYMENT_METHOD_MESSAGE": "",
+ "STRIPE_AUTHENTICATION_FAILED": "",
+ "UPDATE_PAYMENT_METHOD": "",
+ "MONTHLY": "",
+ "YEARLY": "",
+ "UPDATE_SUBSCRIPTION_MESSAGE": "",
+ "UPDATE_SUBSCRIPTION": "",
+ "CANCEL_SUBSCRIPTION": "",
+ "CANCEL_SUBSCRIPTION_MESSAGE": "",
+ "SUBSCRIPTION_CANCEL_FAILED": "",
+ "SUBSCRIPTION_CANCEL_SUCCESS": "",
+ "REACTIVATE_SUBSCRIPTION": "",
+ "REACTIVATE_SUBSCRIPTION_MESSAGE": "",
+ "SUBSCRIPTION_ACTIVATE_SUCCESS": "",
+ "SUBSCRIPTION_ACTIVATE_FAILED": "",
+ "SUBSCRIPTION_PURCHASE_SUCCESS_TITLE": "",
+ "CANCEL_SUBSCRIPTION_ON_MOBILE": "",
+ "CANCEL_SUBSCRIPTION_ON_MOBILE_MESSAGE": "",
+ "MAIL_TO_MANAGE_SUBSCRIPTION": "",
+ "RENAME": "",
+ "RENAME_FILE": "",
+ "RENAME_COLLECTION": "",
+ "DELETE_COLLECTION_TITLE": "",
+ "DELETE_COLLECTION": "",
+ "DELETE_COLLECTION_FAILED": "",
+ "DELETE_COLLECTION_MESSAGE": "",
+ "DELETE_PHOTOS": "",
+ "KEEP_PHOTOS": "",
+ "SHARE": "",
+ "SHARE_COLLECTION": "",
+ "SHARE_WITH_PEOPLE": "",
+ "SHAREES": "",
+ "PUBLIC_URL": "",
+ "SHARE_WITH_SELF": "",
+ "ALREADY_SHARED": "",
+ "SHARING_BAD_REQUEST_ERROR": "",
+ "SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
+ "DOWNLOAD_COLLECTION": "",
+ "DOWNLOAD_COLLECTION_MESSAGE": "",
+ "DOWNLOAD_COLLECTION_FAILED": "",
+ "CREATE_ALBUM_FAILED": "",
+ "SEARCH_RESULTS": "",
+ "SEARCH_HINT": "",
+ "SEARCH_TYPE": {
+ "COLLECTION": "",
+ "LOCATION": "",
+ "DATE": "",
+ "FILE_NAME": "",
+ "THING": "",
+ "FILE_CAPTION": ""
+ },
+ "photos_count_zero": "",
+ "photos_count_one": "",
+ "photos_count_other": "",
+ "TERMS_AND_CONDITIONS": "",
+ "CONFIRM_PASSWORD_NOT_SAVED": "",
+ "ADD_TO_COLLECTION": "",
+ "SELECTED": "",
+ "VIDEO_PLAYBACK_FAILED": "",
+ "VIDEO_PLAYBACK_FAILED_DOWNLOAD_INSTEAD": "",
+ "PEOPLE": "",
+ "INDEXING_SCHEDULED": "",
+ "ANALYZING_PHOTOS": "",
+ "INDEXING_PEOPLE": "",
+ "INDEXING_DONE": "",
+ "UNIDENTIFIED_FACES": "",
+ "OBJECTS": "",
+ "TEXT": "",
+ "METADATA": "",
+ "INFO": "",
+ "INFO_OPTION": "",
+ "FILE_ID": "",
+ "FILE_NAME": "",
+ "CAPTION": "",
+ "CAPTION_PLACEHOLDER": "",
+ "CREATION_TIME": "",
+ "UPDATED_ON": "",
+ "LOCATION": "",
+ "SHOW_ON_MAP": "",
+ "DETAILS": "",
+ "VIEW_EXIF": "",
+ "NO_EXIF": "",
+ "EXIF": "",
+ "DEVICE": "",
+ "IMAGE_SIZE": "",
+ "FLASH": "",
+ "FOCAL_LENGTH": "",
+ "APERTURE": "",
+ "ISO": "",
+ "SHOW_ALL": "",
+ "TWO_FACTOR": "",
+ "TWO_FACTOR_AUTHENTICATION": "",
+ "TWO_FACTOR_QR_INSTRUCTION": "",
+ "ENTER_CODE_MANUALLY": "",
+ "TWO_FACTOR_MANUAL_CODE_INSTRUCTION": "",
+ "SCAN_QR_CODE": "",
+ "CONTINUE": "",
+ "BACK": "",
+ "ENABLE_TWO_FACTOR": "",
+ "ENABLE": "",
+ "LOST_DEVICE": "",
+ "INCORRECT_CODE": "",
+ "RECOVER_TWO_FACTOR": "",
+ "TWO_FACTOR_INFO": "",
+ "DISABLE_TWO_FACTOR_LABEL": "",
+ "UPDATE_TWO_FACTOR_LABEL": "",
+ "DISABLE": "",
+ "RECONFIGURE": "",
+ "UPDATE_TWO_FACTOR": "",
+ "UPDATE_TWO_FACTOR_MESSAGE": "",
+ "UPDATE": "",
+ "DISABLE_TWO_FACTOR": "",
+ "DISABLE_TWO_FACTOR_MESSAGE": "",
+ "TWO_FACTOR_SETUP_FAILED": "",
+ "TWO_FACTOR_SETUP_SUCCESS": "",
+ "TWO_FACTOR_DISABLE_SUCCESS": "",
+ "TWO_FACTOR_DISABLE_FAILED": "",
+ "EXPORT_DATA": "",
+ "SELECT_FOLDER": "",
+ "DESTINATION": "",
+ "START": "",
+ "EXPORT_IN_PROGRESS": "",
+ "PAUSE": "",
+ "RESUME": "",
+ "MINIMIZE": "",
+ "LAST_EXPORT_TIME": "",
+ "SUCCESSFULLY_EXPORTED_FILES": "",
+ "FAILED_EXPORTED_FILES": "",
+ "EXPORT_AGAIN": "",
+ "RETRY_EXPORT": "",
+ "LOCAL_STORAGE_NOT_ACCESSIBLE": "",
+ "LOCAL_STORAGE_NOT_ACCESSIBLE_MESSAGE": "",
+ "RETRY": "",
+ "SEND_OTT": "",
+ "EMAIl_ALREADY_OWNED": "",
+ "EMAIL_UDPATE_SUCCESSFUL": "",
+ "UPLOAD_FAILED": "",
+ "ETAGS_BLOCKED": "",
+ "SKIPPED_VIDEOS_INFO": "",
+ "LIVE_PHOTOS_DETECTED": "",
+ "RETRY_FAILED": "",
+ "FAILED_UPLOADS": "",
+ "SKIPPED_FILES": "",
+ "THUMBNAIL_GENERATION_FAILED_UPLOADS": "",
+ "UNSUPPORTED_FILES": "",
+ "SUCCESSFUL_UPLOADS": "",
+ "SKIPPED_INFO": "",
+ "UNSUPPORTED_INFO": "",
+ "BLOCKED_UPLOADS": "",
+ "SKIPPED_VIDEOS": "",
+ "INPROGRESS_METADATA_EXTRACTION": "",
+ "INPROGRESS_UPLOADS": "",
+ "TOO_LARGE_UPLOADS": "",
+ "LARGER_THAN_AVAILABLE_STORAGE_UPLOADS": "",
+ "LARGER_THAN_AVAILABLE_STORAGE_INFO": "",
+ "TOO_LARGE_INFO": "",
+ "THUMBNAIL_GENERATION_FAILED_INFO": "",
+ "UPLOAD_TO_COLLECTION": "",
+ "UNCATEGORIZED": "",
+ "MOVE_TO_UNCATEGORIZED": "",
+ "ARCHIVE": "",
+ "ARCHIVE_COLLECTION": "",
+ "ARCHIVE_SECTION_NAME": "",
+ "ALL_SECTION_NAME": "",
+ "MOVE_TO_COLLECTION": "",
+ "UNARCHIVE": "",
+ "UNARCHIVE_COLLECTION": "",
+ "MOVE": "",
+ "ADD": "",
+ "SORT": "",
+ "REMOVE": "",
+ "YES_REMOVE": "",
+ "CONFIRM_REMOVE": "",
+ "REMOVE_FROM_COLLECTION": "",
+ "TRASH": "",
+ "MOVE_TO_TRASH": "",
+ "TRASH_FILES_MESSAGE": "",
+ "TRASH_FILE_MESSAGE": "",
+ "DELETE_PERMANENTLY": "",
+ "RESTORE": "",
+ "CONFIRM_RESTORE": "",
+ "RESTORE_MESSAGE": "",
+ "RESTORE_TO_COLLECTION": "",
+ "EMPTY_TRASH": "",
+ "EMPTY_TRASH_TITLE": "",
+ "EMPTY_TRASH_MESSAGE": "",
+ "LEAVE_SHARED_ALBUM": "",
+ "LEAVE_ALBUM": "",
+ "LEAVE_SHARED_ALBUM_TITLE": "",
+ "LEAVE_SHARED_ALBUM_MESSAGE": "",
+ "NOT_FILE_OWNER": "",
+ "CONFIRM_SELF_REMOVE_MESSAGE": "",
+ "CONFIRM_SELF_AND_OTHER_REMOVE_MESSAGE": "",
+ "SORT_BY_CREATION_TIME_ASCENDING": "",
+ "SORT_BY_CREATION_TIME_DESCENDING": "",
+ "SORT_BY_UPDATION_TIME_DESCENDING": "",
+ "SORT_BY_NAME": "",
+ "COMPRESS_THUMBNAILS": "",
+ "THUMBNAIL_REPLACED": "",
+ "FIX_THUMBNAIL": "",
+ "FIX_THUMBNAIL_LATER": "",
+ "REPLACE_THUMBNAIL_NOT_STARTED": "",
+ "REPLACE_THUMBNAIL_COMPLETED": "",
+ "REPLACE_THUMBNAIL_NOOP": "",
+ "REPLACE_THUMBNAIL_COMPLETED_WITH_ERROR": "",
+ "FIX_CREATION_TIME": "",
+ "FIX_CREATION_TIME_IN_PROGRESS": "",
+ "CREATION_TIME_UPDATED": "",
+ "UPDATE_CREATION_TIME_NOT_STARTED": "",
+ "UPDATE_CREATION_TIME_COMPLETED": "",
+ "UPDATE_CREATION_TIME_COMPLETED_WITH_ERROR": "",
+ "FILE_NAME_CHARACTER_LIMIT": "",
+ "CAPTION_CHARACTER_LIMIT": "",
+ "DATE_TIME_ORIGINAL": "",
+ "DATE_TIME_DIGITIZED": "",
+ "CUSTOM_TIME": "",
+ "REOPEN_PLAN_SELECTOR_MODAL": "",
+ "OPEN_PLAN_SELECTOR_MODAL_FAILED": "",
+ "COMMENT": "",
+ "ABUSE_REPORT_DESCRIPTION": "",
+ "OTHER_REASON_REQUIRES_COMMENTS": "",
+ "REPORT_SUBMIT_SUCCESS_CONTENT": "",
+ "REPORT_SUBMIT_SUCCESS_TITLE": "",
+ "REPORT_SUBMIT_FAILED": "",
+ "INSTALL": "",
+ "ALBUM_URL": "",
+ "SHARING_DETAILS": "",
+ "MODIFY_SHARING": "",
+ "NOT_FOUND": "",
+ "LINK_EXPIRED": "",
+ "LINK_EXPIRED_MESSAGE": "",
+ "MANAGE_LINK": "",
+ "LINK_TOO_MANY_REQUESTS": "",
+ "DISABLE_PUBLIC_SHARING": "",
+ "DISABLE_PUBLIC_SHARING_MESSAGE": "",
+ "FILE_DOWNLOAD": "",
+ "LINK_PASSWORD_LOCK": "",
+ "PUBLIC_COLLECT": "",
+ "LINK_DEVICE_LIMIT": "",
+ "LINK_EXPIRY": "",
+ "LINK_EXPIRY_NEVER": "",
+ "DISABLE_FILE_DOWNLOAD": "",
+ "DISABLE_FILE_DOWNLOAD_MESSAGE": "",
+ "ABUSE_REPORT": "",
+ "ABUSE_REPORT_BUTTON_TEXT": "",
+ "MALICIOUS_CONTENT": "",
+ "COPYRIGHT": "",
+ "ENTER_EMAIL_ADDRESS": "",
+ "SELECT_REASON": "",
+ "ENTER_FULL_NAME": "",
+ "ENTER_DIGITAL_SIGNATURE": "",
+ "ENTER_ON_BEHALF_OF": "",
+ "ENTER_ADDRESS": "",
+ "ENTER_JOB_TITLE": "",
+ "ENTER_CITY": "",
+ "ENTER_PHONE": "",
+ "ENTER_STATE": "",
+ "ENTER_POSTAL_CODE": "",
+ "ENTER_COUNTRY": "",
+ "JUDICIAL_DESCRIPTION": "",
+ "TERM_1": "",
+ "TERM_2": "",
+ "TERM_3": "",
+ "SHARED_USING": "",
+ "ENTE_IO": "",
+ "LIVE": "",
+ "DISABLE_PASSWORD": "",
+ "DISABLE_PASSWORD_MESSAGE": "",
+ "PASSWORD_LOCK": "",
+ "LOCK": "",
+ "DOWNLOAD_UPLOAD_LOGS": "",
+ "CHOOSE_UPLOAD_TYPE": "",
+ "UPLOAD_FILES": "",
+ "UPLOAD_DIRS": "",
+ "UPLOAD_GOOGLE_TAKEOUT": "",
+ "CANCEL_UPLOADS": "",
+ "DEDUPLICATE_FILES": "",
+ "NO_DUPLICATES_FOUND": "",
+ "CLUB_BY_CAPTURE_TIME": "",
+ "FILES": "",
+ "EACH": "",
+ "DEDUPLICATE_BASED_ON_SIZE": "",
+ "DEDUPLICATE_BASED_ON_SIZE_AND_CAPTURE_TIME": "",
+ "STOP_ALL_UPLOADS_MESSAGE": "",
+ "STOP_UPLOADS_HEADER": "",
+ "YES_STOP_UPLOADS": "",
+ "albums_one": "",
+ "albums_other": "",
+ "NEW": "",
+ "VIEW_ALL_ALBUMS": "",
+ "ALL_ALBUMS": "",
+ "ALBUMS": "",
+ "ENDS": "",
+ "ENTER_TWO_FACTOR_OTP": "",
+ "CREATE_ACCOUNT": "",
+ "COPIED": "",
+ "CANVAS_BLOCKED_TITLE": "",
+ "CANVAS_BLOCKED_MESSAGE": "",
+ "WATCH_FOLDERS": "",
+ "UPGRADE_NOW": "",
+ "RENEW_NOW": "",
+ "STORAGE": "",
+ "USED": "",
+ "YOU": "",
+ "FAMILY": "",
+ "FREE": "",
+ "OF": "",
+ "WATCHED_FOLDERS": "",
+ "NO_FOLDERS_ADDED": "",
+ "FOLDERS_AUTOMATICALLY_MONITORED": "",
+ "UPLOAD_NEW_FILES_TO_ENTE": "",
+ "REMOVE_DELETED_FILES_FROM_ENTE": "",
+ "ADD_FOLDER": "",
+ "STOP_WATCHING": "",
+ "STOP_WATCHING_FOLDER": "",
+ "STOP_WATCHING_DIALOG_MESSAGE": "",
+ "YES_STOP": "",
+ "MONTH_SHORT": "",
+ "YEAR": "",
+ "FAMILY_PLAN": "",
+ "DOWNLOAD_LOGS": "",
+ "DOWNLOAD_LOGS_MESSAGE": "",
+ "CHANGE_FOLDER": "",
+ "TWO_MONTHS_FREE": "",
+ "GB": "",
+ "POPULAR": "",
+ "FREE_PLAN_OPTION_LABEL": "",
+ "FREE_PLAN_DESCRIPTION": "",
+ "CURRENT_USAGE": "",
+ "WEAK_DEVICE": "",
+ "DRAG_AND_DROP_HINT": "",
+ "ASK_FOR_FEEDBACK": "",
+ "SEND_FEEDBACK": "",
+ "CONFIRM_ACCOUNT_DELETION_TITLE": "",
+ "CONFIRM_ACCOUNT_DELETION_MESSAGE": "",
+ "AUTHENTICATE": "",
+ "UPLOADED_TO_SINGLE_COLLECTION": "",
+ "UPLOADED_TO_SEPARATE_COLLECTIONS": "",
+ "NEVERMIND": "",
+ "UPDATE_AVAILABLE": "",
+ "UPDATE_INSTALLABLE_MESSAGE": "",
+ "INSTALL_NOW": "",
+ "INSTALL_ON_NEXT_LAUNCH": "",
+ "UPDATE_AVAILABLE_MESSAGE": "",
+ "DOWNLOAD_AND_INSTALL": "",
+ "IGNORE_THIS_VERSION": "",
+ "TODAY": "",
+ "YESTERDAY": "",
+ "AT": "",
+ "NAME_PLACEHOLDER": "",
+ "ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED": "",
+ "ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED_MESSAGE": "",
+ "CHOSE_THEME": "",
+ "ML_SEARCH": "",
+ "ENABLE_ML_SEARCH_DESCRIPTION": "",
+ "ML_MORE_DETAILS": "",
+ "ENABLE_FACE_SEARCH": "",
+ "ENABLE_FACE_SEARCH_TITLE": "",
+ "ENABLE_FACE_SEARCH_DESCRIPTION": "",
+ "DISABLE_BETA": "",
+ "DISABLE_FACE_SEARCH": "",
+ "DISABLE_FACE_SEARCH_TITLE": "",
+ "DISABLE_FACE_SEARCH_DESCRIPTION": "",
+ "ADVANCED": "",
+ "FACE_SEARCH_CONFIRMATION": "",
+ "LABS": "",
+ "YOURS": "",
+ "PASSPHRASE_STRENGTH": "",
+ "PREFERENCES": "",
+ "LANGUAGE": "",
+ "EXPORT_DIRECTORY_DOES_NOT_EXIST": "",
+ "EXPORT_DIRECTORY_DOES_NOT_EXIST_MESSAGE": "",
+ "SUBSCRIPTION_VERIFICATION_ERROR": "",
+ "STORAGE_UNITS": {
+ "B": "",
+ "KB": "",
+ "MB": "",
+ "GB": "",
+ "TB": ""
+ },
+ "AFTER_TIME": {
+ "HOUR": "",
+ "DAY": "",
+ "WEEK": "",
+ "MONTH": "",
+ "YEAR": ""
+ },
+ "COPY_LINK": "",
+ "DONE": "",
+ "ADD_EMAIL_TITLE": "",
+ "LINK_SHARE_TITLE": "",
+ "REMOVE_LINK": "",
+ "CREATE_PUBLIC_SHARING": "",
+ "PUBLIC_LINK_CREATED": "",
+ "PUBLIC_LINK_ENABLED": "",
+ "COLLECT_PHOTOS": "",
+ "PUBLIC_COLLECT_SUBTEXT": "",
+ "STOP_EXPORT": "",
+ "EXPORT_PROGRESS": "",
+ "EXPORT_NOTIFICATION": {
+ "START": "",
+ "IN_PROGRESS": "",
+ "FINISH": "",
+ "UP_TO_DATE": ""
+ },
+ "CONTINUOUS_EXPORT": "",
+ "TOTAL_ITEMS": "",
+ "PENDING_ITEMS": "",
+ "EXPORT_STARTING": ""
+}
\ No newline at end of file
diff --git a/public/locales/nl/translation.json b/public/locales/nl/translation.json
new file mode 100644
index 000000000..582e88020
--- /dev/null
+++ b/public/locales/nl/translation.json
@@ -0,0 +1,592 @@
+{
+ "HERO_SLIDE_1_TITLE": "Privé back-ups
voor uw herinneringen
",
+ "HERO_SLIDE_1": "Standaard end-to-end versleuteld",
+ "HERO_SLIDE_2_TITLE": "Veilig opgeslagen
in een kernbunker
",
+ "HERO_SLIDE_2": "Ontworpen om levenslang mee te gaan",
+ "HERO_SLIDE_3_TITLE": "Overal
beschikbaar
",
+ "HERO_SLIDE_3": "Android, iOS, Web, Desktop",
+ "LOGIN": "Inloggen",
+ "SIGN_UP": "Registreren",
+ "NEW_USER": "Nieuw bij ente",
+ "EXISTING_USER": "Bestaande gebruiker",
+ "NAME": "Naam",
+ "ENTER_NAME": "Naam invoeren",
+ "PUBLIC_UPLOADER_NAME_MESSAGE": "Voeg een naam toe zodat je vrienden weten wie ze moeten bedanken voor deze geweldige foto's!",
+ "EMAIL": "E-mail",
+ "ENTER_EMAIL": "Vul e-mailadres in",
+ "DATA_DISCLAIMER": "We geven jouw data nooit door aan derden.",
+ "SUBMIT": "Verzenden",
+ "EMAIL_ERROR": "Vul een geldig e-mailadres in",
+ "REQUIRED": "Vereist",
+ "VERIFY_EMAIL": "Bevestig e-mail",
+ "EMAIL_SENT": "Verificatiecode verzonden naar {{email}} ",
+ "CHECK_INBOX": "Controleer je inbox (en spam) om verificatie te voltooien",
+ "ENTER_OTT": "Verificatiecode",
+ "RESEND_MAIL": "Code opnieuw versturen",
+ "VERIFY": "Verifiëren",
+ "UNKNOWN_ERROR": "Er is iets fout gegaan, probeer het opnieuw",
+ "INVALID_CODE": "Ongeldige verificatiecode",
+ "EXPIRED_CODE": "Uw verificatiecode is verlopen",
+ "SENDING": "Verzenden...",
+ "SENT": "Verzonden!",
+ "PASSWORD": "Wachtwoord",
+ "LINK_PASSWORD": "Voer wachtwoord in om het album te ontgrendelen",
+ "ENTER_PASSPHRASE": "Voer je wachtwoord in",
+ "RETURN_PASSPHRASE_HINT": "Wachtwoord",
+ "SET_PASSPHRASE": "Wachtwoord instellen",
+ "VERIFY_PASSPHRASE": "Aanmelden",
+ "INCORRECT_PASSPHRASE": "Onjuist wachtwoord",
+ "ENTER_ENC_PASSPHRASE": "Voer een wachtwoord in dat we kunnen gebruiken om je gegevens te versleutelen",
+ "PASSPHRASE_DISCLAIMER": "We slaan je wachtwoord niet op, dus als je het vergeet, zullen we u niet kunnen helpen uw data te herstellen zonder een herstelcode.",
+ "WELCOME_TO_ENTE_HEADING": "Welkom bij ",
+ "WELCOME_TO_ENTE_SUBHEADING": "Foto opslag en delen met end to end encryptie",
+ "WHERE_YOUR_BEST_PHOTOS_LIVE": "Waar je beste foto's leven",
+ "KEY_GENERATION_IN_PROGRESS_MESSAGE": "Encryptiecodes worden gegenereerd...",
+ "PASSPHRASE_HINT": "Wachtwoord",
+ "CONFIRM_PASSPHRASE": "Wachtwoord bevestigen",
+ "PASSPHRASE_MATCH_ERROR": "Wachtwoorden komen niet overeen",
+ "CONSOLE_WARNING_STOP": "STOP!",
+ "CONSOLE_WARNING_DESC": "Dit is een browserfunctie bedoeld voor ontwikkelaars. Gelieve hier geen niet-geverifieerde code te kopiëren/plakken.",
+ "SELECT_COLLECTION": "Selecteer een album om de foto's naar te uploaden",
+ "CREATE_COLLECTION": "Nieuw album",
+ "ENTER_ALBUM_NAME": "Album naam",
+ "CLOSE_OPTION": "Sluiten (Esc)",
+ "ENTER_FILE_NAME": "",
+ "CLOSE": "",
+ "NO": "",
+ "NOTHING_HERE": "",
+ "UPLOAD": "",
+ "IMPORT": "",
+ "ADD_PHOTOS": "",
+ "ADD_MORE_PHOTOS": "",
+ "add_photos_one": "",
+ "add_photos_other": "",
+ "SELECT_PHOTOS": "",
+ "FILE_UPLOAD": "",
+ "UPLOAD_STAGE_MESSAGE": {
+ "0": "",
+ "1": "",
+ "2": "",
+ "3": "",
+ "4": "",
+ "5": ""
+ },
+ "UPLOADING_FILES": "",
+ "FILE_NOT_UPLOADED_LIST": "",
+ "SUBSCRIPTION_EXPIRED": "",
+ "SUBSCRIPTION_EXPIRED_MESSAGE": "",
+ "STORAGE_QUOTA_EXCEEDED": "",
+ "INITIAL_LOAD_DELAY_WARNING": "",
+ "USER_DOES_NOT_EXIST": "",
+ "UPLOAD_BUTTON_TEXT": "",
+ "NO_ACCOUNT": "",
+ "ACCOUNT_EXISTS": "",
+ "ALBUM_NAME": "",
+ "CREATE": "",
+ "DOWNLOAD": "",
+ "DOWNLOAD_OPTION": "",
+ "DOWNLOAD_FAVORITES": "",
+ "DOWNLOAD_UNCATEGORIZED": "",
+ "COPY_OPTION": "",
+ "TOGGLE_FULLSCREEN": "",
+ "ZOOM_IN_OUT": "",
+ "PREVIOUS": "",
+ "NEXT": "",
+ "NO_INTERNET_CONNECTION": "",
+ "TITLE": "",
+ "UPLOAD_FIRST_PHOTO": "",
+ "IMPORT_YOUR_FOLDERS": "",
+ "UPLOAD_DROPZONE_MESSAGE": "",
+ "WATCH_FOLDER_DROPZONE_MESSAGE": "",
+ "TRASH_FILES_TITLE": "",
+ "TRASH_FILE_TITLE": "",
+ "DELETE_FILES_TITLE": "",
+ "DELETE_FILES_MESSAGE": "",
+ "DELETE_FILE": "",
+ "DELETE": "",
+ "DELETE_OPTION": "",
+ "FAVORITE": "",
+ "FAVORITE_OPTION": "",
+ "UNFAVORITE_OPTION": "",
+ "UNFAVORITE": "",
+ "MULTI_FOLDER_UPLOAD": "",
+ "UPLOAD_STRATEGY_CHOICE": "",
+ "UPLOAD_STRATEGY_SINGLE_COLLECTION": "",
+ "OR": "",
+ "UPLOAD_STRATEGY_COLLECTION_PER_FOLDER": "",
+ "SESSION_EXPIRED_MESSAGE": "",
+ "SESSION_EXPIRED": "",
+ "SYNC_FAILED": "",
+ "PASSWORD_GENERATION_FAILED": "",
+ "CHANGE_PASSWORD": "",
+ "GO_BACK": "",
+ "RECOVERY_KEY": "",
+ "SAVE_LATER": "",
+ "SAVE": "",
+ "RECOVERY_KEY_DESCRIPTION": "",
+ "RECOVER_KEY_GENERATION_FAILED": "",
+ "KEY_NOT_STORED_DISCLAIMER": "",
+ "FORGOT_PASSWORD": "",
+ "RECOVER_ACCOUNT": "",
+ "RECOVERY_KEY_HINT": "",
+ "RECOVER": "",
+ "NO_RECOVERY_KEY": "",
+ "INCORRECT_RECOVERY_KEY": "",
+ "SORRY": "",
+ "NO_RECOVERY_KEY_MESSAGE": "",
+ "NO_TWO_FACTOR_RECOVERY_KEY_MESSAGE": "",
+ "CONTACT_SUPPORT": "",
+ "REQUEST_FEATURE": "",
+ "SUPPORT": "",
+ "CONFIRM": "",
+ "SKIP_SUBSCRIPTION_PURCHASE": "",
+ "CANCEL": "",
+ "LOGOUT": "",
+ "DELETE_ACCOUNT": "",
+ "DELETE_ACCOUNT_MESSAGE": "",
+ "LOGOUT_MESSAGE": "",
+ "CHANGE": "",
+ "CHANGE_EMAIL": "",
+ "OK": "",
+ "SUCCESS": "",
+ "ERROR": "",
+ "MESSAGE": "",
+ "INSTALL_MOBILE_APP": "",
+ "DOWNLOAD_APP_MESSAGE": "",
+ "DOWNLOAD_APP": "",
+ "EXPORT": "",
+ "SUBSCRIPTION": "",
+ "SUBSCRIBE": "",
+ "SUBSCRIPTION_PLAN": "",
+ "USAGE_DETAILS": "",
+ "MANAGE": "",
+ "MANAGEMENT_PORTAL": "",
+ "MANAGE_FAMILY_PORTAL": "",
+ "LEAVE_FAMILY_PLAN": "",
+ "LEAVE": "",
+ "LEAVE_FAMILY_CONFIRM": "",
+ "CHOOSE_PLAN": "",
+ "MANAGE_PLAN": "",
+ "ACTIVE": "",
+ "OFFLINE_MSG": "",
+ "FREE_SUBSCRIPTION_INFO": "",
+ "FAMILY_SUBSCRIPTION_INFO": "",
+ "RENEWAL_ACTIVE_SUBSCRIPTION_STATUS": "",
+ "RENEWAL_CANCELLED_SUBSCRIPTION_STATUS": "",
+ "RENEWAL_CANCELLED_SUBSCRIPTION_INFO": "",
+ "STORAGE_QUOTA_EXCEEDED_SUBSCRIPTION_INFO": "",
+ "SUBSCRIPTION_PURCHASE_SUCCESS": "",
+ "SUBSCRIPTION_PURCHASE_CANCELLED": "",
+ "SUBSCRIPTION_VERIFICATION_FAILED": "",
+ "SUBSCRIPTION_PURCHASE_FAILED": "",
+ "SUBSCRIPTION_UPDATE_FAILED": "",
+ "UPDATE_PAYMENT_METHOD_MESSAGE": "",
+ "STRIPE_AUTHENTICATION_FAILED": "",
+ "UPDATE_PAYMENT_METHOD": "",
+ "MONTHLY": "",
+ "YEARLY": "",
+ "UPDATE_SUBSCRIPTION_MESSAGE": "",
+ "UPDATE_SUBSCRIPTION": "",
+ "CANCEL_SUBSCRIPTION": "",
+ "CANCEL_SUBSCRIPTION_MESSAGE": "",
+ "SUBSCRIPTION_CANCEL_FAILED": "",
+ "SUBSCRIPTION_CANCEL_SUCCESS": "",
+ "REACTIVATE_SUBSCRIPTION": "",
+ "REACTIVATE_SUBSCRIPTION_MESSAGE": "",
+ "SUBSCRIPTION_ACTIVATE_SUCCESS": "",
+ "SUBSCRIPTION_ACTIVATE_FAILED": "",
+ "SUBSCRIPTION_PURCHASE_SUCCESS_TITLE": "",
+ "CANCEL_SUBSCRIPTION_ON_MOBILE": "",
+ "CANCEL_SUBSCRIPTION_ON_MOBILE_MESSAGE": "",
+ "MAIL_TO_MANAGE_SUBSCRIPTION": "",
+ "RENAME": "",
+ "RENAME_FILE": "",
+ "RENAME_COLLECTION": "",
+ "DELETE_COLLECTION_TITLE": "",
+ "DELETE_COLLECTION": "",
+ "DELETE_COLLECTION_FAILED": "",
+ "DELETE_COLLECTION_MESSAGE": "",
+ "DELETE_PHOTOS": "",
+ "KEEP_PHOTOS": "",
+ "SHARE": "",
+ "SHARE_COLLECTION": "",
+ "SHARE_WITH_PEOPLE": "",
+ "SHAREES": "",
+ "PUBLIC_URL": "",
+ "SHARE_WITH_SELF": "",
+ "ALREADY_SHARED": "",
+ "SHARING_BAD_REQUEST_ERROR": "",
+ "SHARING_DISABLED_FOR_FREE_ACCOUNTS": "",
+ "DOWNLOAD_COLLECTION": "",
+ "DOWNLOAD_COLLECTION_MESSAGE": "",
+ "DOWNLOAD_COLLECTION_FAILED": "",
+ "CREATE_ALBUM_FAILED": "",
+ "SEARCH_RESULTS": "",
+ "SEARCH_HINT": "",
+ "SEARCH_TYPE": {
+ "COLLECTION": "",
+ "LOCATION": "",
+ "DATE": "",
+ "FILE_NAME": "",
+ "THING": "",
+ "FILE_CAPTION": ""
+ },
+ "photos_count_zero": "",
+ "photos_count_one": "",
+ "photos_count_other": "",
+ "TERMS_AND_CONDITIONS": "",
+ "CONFIRM_PASSWORD_NOT_SAVED": "",
+ "ADD_TO_COLLECTION": "",
+ "SELECTED": "",
+ "VIDEO_PLAYBACK_FAILED": "",
+ "VIDEO_PLAYBACK_FAILED_DOWNLOAD_INSTEAD": "",
+ "PEOPLE": "",
+ "INDEXING_SCHEDULED": "",
+ "ANALYZING_PHOTOS": "",
+ "INDEXING_PEOPLE": "",
+ "INDEXING_DONE": "",
+ "UNIDENTIFIED_FACES": "",
+ "OBJECTS": "",
+ "TEXT": "",
+ "METADATA": "",
+ "INFO": "",
+ "INFO_OPTION": "",
+ "FILE_ID": "",
+ "FILE_NAME": "",
+ "CAPTION": "",
+ "CAPTION_PLACEHOLDER": "",
+ "CREATION_TIME": "",
+ "UPDATED_ON": "",
+ "LOCATION": "",
+ "SHOW_ON_MAP": "",
+ "DETAILS": "",
+ "VIEW_EXIF": "",
+ "NO_EXIF": "",
+ "EXIF": "",
+ "DEVICE": "",
+ "IMAGE_SIZE": "",
+ "FLASH": "",
+ "FOCAL_LENGTH": "",
+ "APERTURE": "",
+ "ISO": "",
+ "SHOW_ALL": "",
+ "TWO_FACTOR": "",
+ "TWO_FACTOR_AUTHENTICATION": "",
+ "TWO_FACTOR_QR_INSTRUCTION": "",
+ "ENTER_CODE_MANUALLY": "",
+ "TWO_FACTOR_MANUAL_CODE_INSTRUCTION": "",
+ "SCAN_QR_CODE": "",
+ "CONTINUE": "",
+ "BACK": "",
+ "ENABLE_TWO_FACTOR": "",
+ "ENABLE": "",
+ "LOST_DEVICE": "",
+ "INCORRECT_CODE": "",
+ "RECOVER_TWO_FACTOR": "",
+ "TWO_FACTOR_INFO": "",
+ "DISABLE_TWO_FACTOR_LABEL": "",
+ "UPDATE_TWO_FACTOR_LABEL": "",
+ "DISABLE": "",
+ "RECONFIGURE": "",
+ "UPDATE_TWO_FACTOR": "",
+ "UPDATE_TWO_FACTOR_MESSAGE": "",
+ "UPDATE": "",
+ "DISABLE_TWO_FACTOR": "",
+ "DISABLE_TWO_FACTOR_MESSAGE": "",
+ "TWO_FACTOR_SETUP_FAILED": "",
+ "TWO_FACTOR_SETUP_SUCCESS": "",
+ "TWO_FACTOR_DISABLE_SUCCESS": "",
+ "TWO_FACTOR_DISABLE_FAILED": "",
+ "EXPORT_DATA": "",
+ "SELECT_FOLDER": "",
+ "DESTINATION": "",
+ "START": "",
+ "EXPORT_IN_PROGRESS": "",
+ "PAUSE": "",
+ "RESUME": "",
+ "MINIMIZE": "",
+ "LAST_EXPORT_TIME": "",
+ "SUCCESSFULLY_EXPORTED_FILES": "",
+ "FAILED_EXPORTED_FILES": "",
+ "EXPORT_AGAIN": "",
+ "RETRY_EXPORT": "",
+ "LOCAL_STORAGE_NOT_ACCESSIBLE": "",
+ "LOCAL_STORAGE_NOT_ACCESSIBLE_MESSAGE": "",
+ "RETRY": "",
+ "SEND_OTT": "",
+ "EMAIl_ALREADY_OWNED": "",
+ "EMAIL_UDPATE_SUCCESSFUL": "",
+ "UPLOAD_FAILED": "",
+ "ETAGS_BLOCKED": "",
+ "SKIPPED_VIDEOS_INFO": "",
+ "LIVE_PHOTOS_DETECTED": "",
+ "RETRY_FAILED": "",
+ "FAILED_UPLOADS": "",
+ "SKIPPED_FILES": "",
+ "THUMBNAIL_GENERATION_FAILED_UPLOADS": "",
+ "UNSUPPORTED_FILES": "",
+ "SUCCESSFUL_UPLOADS": "",
+ "SKIPPED_INFO": "",
+ "UNSUPPORTED_INFO": "",
+ "BLOCKED_UPLOADS": "",
+ "SKIPPED_VIDEOS": "",
+ "INPROGRESS_METADATA_EXTRACTION": "",
+ "INPROGRESS_UPLOADS": "",
+ "TOO_LARGE_UPLOADS": "",
+ "LARGER_THAN_AVAILABLE_STORAGE_UPLOADS": "",
+ "LARGER_THAN_AVAILABLE_STORAGE_INFO": "",
+ "TOO_LARGE_INFO": "",
+ "THUMBNAIL_GENERATION_FAILED_INFO": "",
+ "UPLOAD_TO_COLLECTION": "",
+ "UNCATEGORIZED": "",
+ "MOVE_TO_UNCATEGORIZED": "",
+ "ARCHIVE": "",
+ "ARCHIVE_COLLECTION": "",
+ "ARCHIVE_SECTION_NAME": "",
+ "ALL_SECTION_NAME": "",
+ "MOVE_TO_COLLECTION": "",
+ "UNARCHIVE": "",
+ "UNARCHIVE_COLLECTION": "",
+ "MOVE": "",
+ "ADD": "",
+ "SORT": "",
+ "REMOVE": "",
+ "YES_REMOVE": "",
+ "CONFIRM_REMOVE": "",
+ "REMOVE_FROM_COLLECTION": "",
+ "TRASH": "",
+ "MOVE_TO_TRASH": "",
+ "TRASH_FILES_MESSAGE": "",
+ "TRASH_FILE_MESSAGE": "",
+ "DELETE_PERMANENTLY": "",
+ "RESTORE": "",
+ "CONFIRM_RESTORE": "",
+ "RESTORE_MESSAGE": "",
+ "RESTORE_TO_COLLECTION": "",
+ "EMPTY_TRASH": "",
+ "EMPTY_TRASH_TITLE": "",
+ "EMPTY_TRASH_MESSAGE": "",
+ "LEAVE_SHARED_ALBUM": "",
+ "LEAVE_ALBUM": "",
+ "LEAVE_SHARED_ALBUM_TITLE": "",
+ "LEAVE_SHARED_ALBUM_MESSAGE": "",
+ "NOT_FILE_OWNER": "",
+ "CONFIRM_SELF_REMOVE_MESSAGE": "",
+ "CONFIRM_SELF_AND_OTHER_REMOVE_MESSAGE": "",
+ "SORT_BY_CREATION_TIME_ASCENDING": "",
+ "SORT_BY_CREATION_TIME_DESCENDING": "",
+ "SORT_BY_UPDATION_TIME_DESCENDING": "",
+ "SORT_BY_NAME": "",
+ "COMPRESS_THUMBNAILS": "",
+ "THUMBNAIL_REPLACED": "",
+ "FIX_THUMBNAIL": "",
+ "FIX_THUMBNAIL_LATER": "",
+ "REPLACE_THUMBNAIL_NOT_STARTED": "",
+ "REPLACE_THUMBNAIL_COMPLETED": "",
+ "REPLACE_THUMBNAIL_NOOP": "",
+ "REPLACE_THUMBNAIL_COMPLETED_WITH_ERROR": "",
+ "FIX_CREATION_TIME": "",
+ "FIX_CREATION_TIME_IN_PROGRESS": "",
+ "CREATION_TIME_UPDATED": "",
+ "UPDATE_CREATION_TIME_NOT_STARTED": "",
+ "UPDATE_CREATION_TIME_COMPLETED": "",
+ "UPDATE_CREATION_TIME_COMPLETED_WITH_ERROR": "",
+ "FILE_NAME_CHARACTER_LIMIT": "",
+ "CAPTION_CHARACTER_LIMIT": "",
+ "DATE_TIME_ORIGINAL": "",
+ "DATE_TIME_DIGITIZED": "",
+ "CUSTOM_TIME": "",
+ "REOPEN_PLAN_SELECTOR_MODAL": "",
+ "OPEN_PLAN_SELECTOR_MODAL_FAILED": "",
+ "COMMENT": "",
+ "ABUSE_REPORT_DESCRIPTION": "",
+ "OTHER_REASON_REQUIRES_COMMENTS": "",
+ "REPORT_SUBMIT_SUCCESS_CONTENT": "",
+ "REPORT_SUBMIT_SUCCESS_TITLE": "",
+ "REPORT_SUBMIT_FAILED": "",
+ "INSTALL": "",
+ "ALBUM_URL": "",
+ "SHARING_DETAILS": "",
+ "MODIFY_SHARING": "",
+ "NOT_FOUND": "",
+ "LINK_EXPIRED": "",
+ "LINK_EXPIRED_MESSAGE": "",
+ "MANAGE_LINK": "",
+ "LINK_TOO_MANY_REQUESTS": "",
+ "DISABLE_PUBLIC_SHARING": "",
+ "DISABLE_PUBLIC_SHARING_MESSAGE": "",
+ "FILE_DOWNLOAD": "",
+ "LINK_PASSWORD_LOCK": "",
+ "PUBLIC_COLLECT": "",
+ "LINK_DEVICE_LIMIT": "",
+ "LINK_EXPIRY": "",
+ "LINK_EXPIRY_NEVER": "",
+ "DISABLE_FILE_DOWNLOAD": "",
+ "DISABLE_FILE_DOWNLOAD_MESSAGE": "",
+ "ABUSE_REPORT": "",
+ "ABUSE_REPORT_BUTTON_TEXT": "",
+ "MALICIOUS_CONTENT": "",
+ "COPYRIGHT": "",
+ "ENTER_EMAIL_ADDRESS": "",
+ "SELECT_REASON": "",
+ "ENTER_FULL_NAME": "",
+ "ENTER_DIGITAL_SIGNATURE": "",
+ "ENTER_ON_BEHALF_OF": "",
+ "ENTER_ADDRESS": "",
+ "ENTER_JOB_TITLE": "",
+ "ENTER_CITY": "",
+ "ENTER_PHONE": "",
+ "ENTER_STATE": "",
+ "ENTER_POSTAL_CODE": "",
+ "ENTER_COUNTRY": "",
+ "JUDICIAL_DESCRIPTION": "",
+ "TERM_1": "",
+ "TERM_2": "",
+ "TERM_3": "",
+ "SHARED_USING": "",
+ "ENTE_IO": "",
+ "LIVE": "",
+ "DISABLE_PASSWORD": "",
+ "DISABLE_PASSWORD_MESSAGE": "",
+ "PASSWORD_LOCK": "",
+ "LOCK": "",
+ "DOWNLOAD_UPLOAD_LOGS": "",
+ "CHOOSE_UPLOAD_TYPE": "",
+ "UPLOAD_FILES": "",
+ "UPLOAD_DIRS": "",
+ "UPLOAD_GOOGLE_TAKEOUT": "",
+ "CANCEL_UPLOADS": "",
+ "DEDUPLICATE_FILES": "",
+ "NO_DUPLICATES_FOUND": "",
+ "CLUB_BY_CAPTURE_TIME": "",
+ "FILES": "",
+ "EACH": "",
+ "DEDUPLICATE_BASED_ON_SIZE": "",
+ "DEDUPLICATE_BASED_ON_SIZE_AND_CAPTURE_TIME": "",
+ "STOP_ALL_UPLOADS_MESSAGE": "",
+ "STOP_UPLOADS_HEADER": "",
+ "YES_STOP_UPLOADS": "",
+ "albums_one": "",
+ "albums_other": "",
+ "NEW": "",
+ "VIEW_ALL_ALBUMS": "",
+ "ALL_ALBUMS": "",
+ "ALBUMS": "",
+ "ENDS": "",
+ "ENTER_TWO_FACTOR_OTP": "",
+ "CREATE_ACCOUNT": "",
+ "COPIED": "",
+ "CANVAS_BLOCKED_TITLE": "",
+ "CANVAS_BLOCKED_MESSAGE": "",
+ "WATCH_FOLDERS": "",
+ "UPGRADE_NOW": "",
+ "RENEW_NOW": "",
+ "STORAGE": "",
+ "USED": "",
+ "YOU": "",
+ "FAMILY": "",
+ "FREE": "",
+ "OF": "",
+ "WATCHED_FOLDERS": "",
+ "NO_FOLDERS_ADDED": "",
+ "FOLDERS_AUTOMATICALLY_MONITORED": "",
+ "UPLOAD_NEW_FILES_TO_ENTE": "",
+ "REMOVE_DELETED_FILES_FROM_ENTE": "",
+ "ADD_FOLDER": "",
+ "STOP_WATCHING": "",
+ "STOP_WATCHING_FOLDER": "",
+ "STOP_WATCHING_DIALOG_MESSAGE": "",
+ "YES_STOP": "",
+ "MONTH_SHORT": "",
+ "YEAR": "",
+ "FAMILY_PLAN": "",
+ "DOWNLOAD_LOGS": "",
+ "DOWNLOAD_LOGS_MESSAGE": "",
+ "CHANGE_FOLDER": "",
+ "TWO_MONTHS_FREE": "",
+ "GB": "",
+ "POPULAR": "",
+ "FREE_PLAN_OPTION_LABEL": "",
+ "FREE_PLAN_DESCRIPTION": "",
+ "CURRENT_USAGE": "",
+ "WEAK_DEVICE": "",
+ "DRAG_AND_DROP_HINT": "",
+ "ASK_FOR_FEEDBACK": "",
+ "SEND_FEEDBACK": "",
+ "CONFIRM_ACCOUNT_DELETION_TITLE": "",
+ "CONFIRM_ACCOUNT_DELETION_MESSAGE": "",
+ "AUTHENTICATE": "",
+ "UPLOADED_TO_SINGLE_COLLECTION": "",
+ "UPLOADED_TO_SEPARATE_COLLECTIONS": "",
+ "NEVERMIND": "",
+ "UPDATE_AVAILABLE": "",
+ "UPDATE_INSTALLABLE_MESSAGE": "",
+ "INSTALL_NOW": "",
+ "INSTALL_ON_NEXT_LAUNCH": "",
+ "UPDATE_AVAILABLE_MESSAGE": "",
+ "DOWNLOAD_AND_INSTALL": "",
+ "IGNORE_THIS_VERSION": "",
+ "TODAY": "",
+ "YESTERDAY": "",
+ "AT": "",
+ "NAME_PLACEHOLDER": "",
+ "ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED": "",
+ "ROOT_LEVEL_FILE_WITH_FOLDER_NOT_ALLOWED_MESSAGE": "",
+ "CHOSE_THEME": "",
+ "ML_SEARCH": "",
+ "ENABLE_ML_SEARCH_DESCRIPTION": "",
+ "ML_MORE_DETAILS": "",
+ "ENABLE_FACE_SEARCH": "",
+ "ENABLE_FACE_SEARCH_TITLE": "",
+ "ENABLE_FACE_SEARCH_DESCRIPTION": "",
+ "DISABLE_BETA": "",
+ "DISABLE_FACE_SEARCH": "",
+ "DISABLE_FACE_SEARCH_TITLE": "",
+ "DISABLE_FACE_SEARCH_DESCRIPTION": "",
+ "ADVANCED": "",
+ "FACE_SEARCH_CONFIRMATION": "",
+ "LABS": "",
+ "YOURS": "",
+ "PASSPHRASE_STRENGTH": "",
+ "PREFERENCES": "",
+ "LANGUAGE": "",
+ "EXPORT_DIRECTORY_DOES_NOT_EXIST": "",
+ "EXPORT_DIRECTORY_DOES_NOT_EXIST_MESSAGE": "",
+ "SUBSCRIPTION_VERIFICATION_ERROR": "",
+ "STORAGE_UNITS": {
+ "B": "",
+ "KB": "",
+ "MB": "",
+ "GB": "",
+ "TB": ""
+ },
+ "AFTER_TIME": {
+ "HOUR": "",
+ "DAY": "",
+ "WEEK": "",
+ "MONTH": "",
+ "YEAR": ""
+ },
+ "COPY_LINK": "",
+ "DONE": "",
+ "ADD_EMAIL_TITLE": "",
+ "LINK_SHARE_TITLE": "",
+ "REMOVE_LINK": "",
+ "CREATE_PUBLIC_SHARING": "",
+ "PUBLIC_LINK_CREATED": "",
+ "PUBLIC_LINK_ENABLED": "",
+ "COLLECT_PHOTOS": "",
+ "PUBLIC_COLLECT_SUBTEXT": "",
+ "STOP_EXPORT": "",
+ "EXPORT_PROGRESS": "",
+ "EXPORT_NOTIFICATION": {
+ "START": "",
+ "IN_PROGRESS": "",
+ "FINISH": "",
+ "UP_TO_DATE": ""
+ },
+ "CONTINUOUS_EXPORT": "",
+ "TOTAL_ITEMS": "",
+ "PENDING_ITEMS": "",
+ "EXPORT_STARTING": ""
+}
\ No newline at end of file
diff --git a/scripts/purge_unused_strings.sh b/scripts/purge_unused_strings.sh
new file mode 100755
index 000000000..246cefbbd
--- /dev/null
+++ b/scripts/purge_unused_strings.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+# Set the path to the JSON file and folder
+json_file_path="./public/locales/en/translation.json"
+folder_path="./src"
+tab_width=4
+
+# Check if jq and grep are installed
+if ! command -v jq &> /dev/null || ! command -v grep &> /dev/null
+then
+ echo "jq or grep command not found. Please install jq and grep."
+ exit
+fi
+
+# Recursive function to check for keys in nested JSON objects
+check_keys() {
+ local keys="$1"
+ local parent_key="$2"
+ for key in $keys
+ do
+ local full_key=""
+ if [[ -z $parent_key ]]; then
+ full_key="$key"
+ else
+ full_key="$parent_key.$key"
+ fi
+ local children_keys=$(jq -r --arg key "$key" 'select(.[$key] | type == "object") | .[$key] | keys[]' "$json_file_path")
+ if [ -n "$children_keys" ]; then
+ # check first if the key is not in the ignore list
+ check_keys "$children_keys" "$full_key"
+ else
+ if ! grep -rqE "'$full_key'|\"$full_key\"" "$folder_path"; then
+ # Remove the key from the JSON file
+ # echo the command to remove the key from the JSON file
+ jq "del(.$(echo $full_key | sed 's/\./"."/g' | sed 's/^/"/' | sed 's/$/"/'))" "$json_file_path" > "$json_file_path.tmp" && mv "$json_file_path.tmp" "$json_file_path"
+ echo "Removing key \"$full_key\" from the JSON file"
+ else
+ echo "Key \"$full_key\" is being used."
+ fi
+ fi
+ done
+}
+
+# Get the top-level keys from the JSON file
+keys=$(jq -r 'keys[]' "$json_file_path")
+
+# Loop through the keys and recursively check for nested keys
+check_keys "$keys" ""
+
+# Format the updated JSON using the specified tab width
+jq --indent "$tab_width" '.' "$json_file_path" > "$json_file_path.tmp" && mv "$json_file_path.tmp" "$json_file_path"
+
+
+
+
+echo "Done checking for missing keys."
diff --git a/src/components/ChangeEmail.tsx b/src/components/ChangeEmail.tsx
index f127059f9..b753393ca 100644
--- a/src/components/ChangeEmail.tsx
+++ b/src/components/ChangeEmail.tsx
@@ -41,7 +41,7 @@ function ChangeEmailForm() {
ottInputRef.current?.focus();
}, 250);
} catch (e) {
- setFieldError('email', t('EMAIl_ALREADY_OWNED}'));
+ setFieldError('email', t('EMAIl_ALREADY_OWNED'));
}
setLoading(false);
};
diff --git a/src/components/Collections/CollectionShare/index.tsx b/src/components/Collections/CollectionShare/index.tsx
index 3bdae9bed..4b1ecaf5b 100644
--- a/src/components/Collections/CollectionShare/index.tsx
+++ b/src/components/Collections/CollectionShare/index.tsx
@@ -1,16 +1,13 @@
import EmailShare from './emailShare';
-import React, { useContext } from 'react';
+import React from 'react';
import { Collection } from 'types/collection';
-import DialogTitleWithCloseButton, {
- dialogCloseHandler,
-} from 'components/DialogBox/TitleWithCloseButton';
-import DialogContent from '@mui/material/DialogContent';
-import { Divider } from '@mui/material';
-
-import { CollectionShareContainer } from './container';
+import { EnteDrawer } from 'components/EnteDrawer';
import PublicShare from './publicShare';
-import { AppContext } from 'pages/_app';
+import WorkspacesIcon from '@mui/icons-material/Workspaces';
import { t } from 'i18next';
+import MenuSectionTitle from 'components/Menu/MenuSectionTitle';
+import { DialogProps, Stack } from '@mui/material';
+import Titlebar from 'components/Titlebar';
interface Props {
open: boolean;
@@ -19,30 +16,48 @@ interface Props {
}
function CollectionShare(props: Props) {
- const { isMobile } = useContext(AppContext);
- const handleClose = dialogCloseHandler({
- onClose: props.onClose,
- });
-
+ const handleRootClose = () => {
+ props.onClose();
+ };
+ const handleDrawerClose: DialogProps['onClose'] = (_, reason) => {
+ if (reason === 'backdropClick') {
+ handleRootClose();
+ } else {
+ props.onClose();
+ }
+ };
if (!props.collection) {
return <>>;
}
return (
<>
-
-
- {t('SHARE_COLLECTION')}
-
-
-
-
-
-
-
+ onClose={handleDrawerClose}
+ BackdropProps={{
+ sx: { '&&&': { backgroundColor: 'transparent' } },
+ }}>
+
+
+
+ }
+ />
+
+
+
+
+
>
);
}
diff --git a/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx b/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx
new file mode 100644
index 000000000..fc5a25fe8
--- /dev/null
+++ b/src/components/Collections/CollectionShare/publicShare/EnablePublicShareOptions.tsx
@@ -0,0 +1,101 @@
+import { Stack, Typography } from '@mui/material';
+import { GalleryContext } from 'pages/gallery';
+import React, { useContext, useState } from 'react';
+import { t } from 'i18next';
+import {
+ createShareableURL,
+ updateShareableURL,
+} from 'services/collectionService';
+import { Collection, PublicURL } from 'types/collection';
+import { handleSharingErrors } from 'utils/error/ui';
+import { EnteMenuItem } from 'components/Menu/menuItem';
+import PublicIcon from '@mui/icons-material/Public';
+interface Iprops {
+ collection: Collection;
+ setPublicShareProp: (value: PublicURL) => void;
+ setCopyLinkModalView: (value: boolean) => void;
+}
+import LinkIcon from '@mui/icons-material/Link';
+import { EnteMenuItemGroup } from 'components/Menu/menuItemGroup';
+import MenuSectionTitle from 'components/Menu/MenuSectionTitle';
+import EnteMenuItemDivider from 'components/Menu/menuItemDivider';
+
+export default function EnablePublicShareOptions({
+ collection,
+ setPublicShareProp,
+ setCopyLinkModalView,
+}: Iprops) {
+ const galleryContext = useContext(GalleryContext);
+ const [sharableLinkError, setSharableLinkError] = useState(null);
+
+ const createSharableURLHelper = async () => {
+ try {
+ setSharableLinkError(null);
+ galleryContext.setBlockingLoad(true);
+ const publicURL = await createShareableURL(collection);
+ setPublicShareProp(publicURL);
+ setCopyLinkModalView(true);
+ galleryContext.syncWithRemote(false, true);
+ } catch (e) {
+ const errorMessage = handleSharingErrors(e);
+ setSharableLinkError(errorMessage);
+ } finally {
+ galleryContext.setBlockingLoad(false);
+ }
+ };
+
+ const createCollectPhotoShareableURLHelper = async () => {
+ try {
+ setSharableLinkError(null);
+ galleryContext.setBlockingLoad(true);
+ const publicURL = await createShareableURL(collection);
+ await updateShareableURL({
+ collectionID: collection.id,
+ enableCollect: true,
+ });
+ setPublicShareProp(publicURL);
+ setCopyLinkModalView(true);
+ galleryContext.syncWithRemote(false, true);
+ } catch (e) {
+ const errorMessage = handleSharingErrors(e);
+ setSharableLinkError(errorMessage);
+ } finally {
+ galleryContext.setBlockingLoad(false);
+ }
+ };
+
+ return (
+
+ }
+ />
+
+ }
+ color="primary"
+ onClick={createSharableURLHelper}>
+ {t('CREATE_PUBLIC_SHARING')}
+
+
+ }
+ color="primary"
+ onClick={createCollectPhotoShareableURLHelper}>
+ {t('COLLECT_PHOTOS')}
+
+
+ {sharableLinkError && (
+ theme.palette.danger.main,
+ mt: 0.5,
+ }}>
+ {sharableLinkError}
+
+ )}
+
+ );
+}
diff --git a/src/components/Collections/CollectionShare/publicShare/control.tsx b/src/components/Collections/CollectionShare/publicShare/control.tsx
deleted file mode 100644
index 943b0a086..000000000
--- a/src/components/Collections/CollectionShare/publicShare/control.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import { Box, Typography } from '@mui/material';
-import { FlexWrapper } from 'components/Container';
-import { GalleryContext } from 'pages/gallery';
-import { AppContext } from 'pages/_app';
-import React, { useContext, useState } from 'react';
-import { t } from 'i18next';
-import {
- createShareableURL,
- deleteShareableURL,
-} from 'services/collectionService';
-import { Collection, PublicURL } from 'types/collection';
-import { handleSharingErrors } from 'utils/error/ui';
-import PublicShareSwitch from './switch';
-interface Iprops {
- collection: Collection;
- publicShareActive: boolean;
- setPublicShareProp: (value: PublicURL) => void;
-}
-
-export default function PublicShareControl({
- collection,
- publicShareActive,
- setPublicShareProp,
-}: Iprops) {
- const appContext = useContext(AppContext);
- const galleryContext = useContext(GalleryContext);
- const [sharableLinkError, setSharableLinkError] = useState(null);
-
- const createSharableURLHelper = async () => {
- try {
- appContext.startLoading();
- const publicURL = await createShareableURL(collection);
- setPublicShareProp(publicURL);
- await galleryContext.syncWithRemote(false, true);
- } catch (e) {
- const errorMessage = handleSharingErrors(e);
- setSharableLinkError(errorMessage);
- } finally {
- appContext.finishLoading();
- }
- };
-
- const disablePublicSharing = async () => {
- try {
- appContext.startLoading();
- await deleteShareableURL(collection);
- setPublicShareProp(null);
- await galleryContext.syncWithRemote(false, true);
- } catch (e) {
- const errorMessage = handleSharingErrors(e);
- setSharableLinkError(errorMessage);
- } finally {
- appContext.finishLoading();
- }
- };
-
- const confirmDisablePublicSharing = () => {
- appContext.setDialogMessage({
- title: t('DISABLE_PUBLIC_SHARING'),
- content: t('DISABLE_PUBLIC_SHARING_MESSAGE'),
- close: { text: t('CANCEL') },
- proceed: {
- text: t('DISABLE'),
- action: disablePublicSharing,
- variant: 'danger',
- },
- });
- };
-
- const handleCollectionPublicSharing = () => {
- setSharableLinkError(null);
- if (publicShareActive) {
- confirmDisablePublicSharing();
- } else {
- createSharableURLHelper();
- }
- };
- return (
-
-
- {t('PUBLIC_SHARING')}
-
-
-
- {sharableLinkError && (
- theme.palette.danger.main,
- mt: 0.5,
- }}>
- {sharableLinkError}
-
- )}
-
- );
-}
diff --git a/src/components/Collections/CollectionShare/publicShare/copyLinkModal.tsx b/src/components/Collections/CollectionShare/publicShare/copyLinkModal.tsx
new file mode 100644
index 000000000..aeaa1131c
--- /dev/null
+++ b/src/components/Collections/CollectionShare/publicShare/copyLinkModal.tsx
@@ -0,0 +1,58 @@
+import DialogBoxBase from 'components/DialogBox/base';
+import {
+ DialogActions,
+ Button,
+ Typography,
+ DialogContent,
+ Box,
+} from '@mui/material';
+import VerticallyCentered from 'components/Container';
+import Check from '@mui/icons-material/Check';
+import { t } from 'i18next';
+interface Iprops {
+ open: boolean;
+ onClose: () => void;
+ handleCancel: () => void;
+ copyToClipboardHelper: () => void;
+}
+export default function CopyLinkModal({
+ open,
+ onClose,
+ handleCancel,
+ copyToClipboardHelper,
+}: Iprops) {
+ return (
+
+
+
+
+ {t('PUBLIC_LINK_CREATED')}
+
+
+
+
+
+
+
+
+ {t('DONE')}
+
+
+ {t('COPY_LINK')}
+
+
+
+ );
+}
diff --git a/src/components/Collections/CollectionShare/publicShare/index.tsx b/src/components/Collections/CollectionShare/publicShare/index.tsx
index db103fb2c..d8bad6939 100644
--- a/src/components/Collections/CollectionShare/publicShare/index.tsx
+++ b/src/components/Collections/CollectionShare/publicShare/index.tsx
@@ -1,17 +1,20 @@
import React, { useEffect, useState } from 'react';
import { Collection, PublicURL } from 'types/collection';
import { appendCollectionKeyToShareURL } from 'utils/collection';
-import PublicShareControl from './control';
-import PublicShareLink from './link';
-import PublicShareManage from './manage';
+import EnablePublicShareOptions from './EnablePublicShareOptions';
+import CopyLinkModal from './copyLinkModal';
+import ManagePublicShare from './managePublicShare';
export default function PublicShare({
collection,
+ onRootClose,
}: {
collection: Collection;
+ onRootClose: () => void;
}) {
const [publicShareUrl, setPublicShareUrl] = useState(null);
const [publicShareProp, setPublicShareProp] = useState(null);
+ const [copyLinkModalView, setCopyLinkModalView] = useState(false);
useEffect(() => {
if (collection.publicURLs?.length) {
@@ -31,24 +34,38 @@ export default function PublicShare({
}
}, [publicShareProp]);
+ const copyToClipboardHelper = () => {
+ navigator.clipboard.writeText(publicShareUrl);
+ handleCancel();
+ };
+ const handleCancel = () => {
+ setCopyLinkModalView(false);
+ };
+
return (
<>
-
- {publicShareProp && (
- <>
-
-
-
- >
+ {publicShareProp ? (
+
+ ) : (
+
)}
+
>
);
}
diff --git a/src/components/Collections/CollectionShare/publicShare/link.tsx b/src/components/Collections/CollectionShare/publicShare/link.tsx
deleted file mode 100644
index c5cadf36b..000000000
--- a/src/components/Collections/CollectionShare/publicShare/link.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import { Box } from '@mui/material';
-import CodeBlock from 'components/CodeBlock';
-import React from 'react';
-
-export default function PublicShareLink({ publicShareUrl }) {
- return (
-
-
-
- );
-}
diff --git a/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx b/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx
index fe5b3d92f..4f817af30 100644
--- a/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx
+++ b/src/components/Collections/CollectionShare/publicShare/manage/deviceLimit.tsx
@@ -1,22 +1,27 @@
-import { Box, Typography } from '@mui/material';
-import React from 'react';
+import ChevronRight from '@mui/icons-material/ChevronRight';
+import { DialogProps, Stack } from '@mui/material';
+import { EnteDrawer } from 'components/EnteDrawer';
+import { EnteMenuItem } from 'components/Menu/menuItem';
+import { EnteMenuItemGroup } from 'components/Menu/menuItemGroup';
+import Titlebar from 'components/Titlebar';
import { t } from 'i18next';
-import Select from 'react-select';
-import { DropdownStyle } from 'styles/dropdown';
+import React, { useMemo, useState } from 'react';
import { Collection, PublicURL, UpdatePublicURL } from 'types/collection';
import { getDeviceLimitOptions } from 'utils/collection';
-import { OptionWithDivider } from './selectComponents/OptionWithDivider';
+import EnteMenuItemDivider from 'components/Menu/menuItemDivider';
interface Iprops {
publicShareProp: PublicURL;
collection: Collection;
updatePublicShareURLHelper: (req: UpdatePublicURL) => Promise;
+ onRootClose: () => void;
}
export function ManageDeviceLimit({
- publicShareProp,
collection,
+ publicShareProp,
updatePublicShareURLHelper,
+ onRootClose,
}: Iprops) {
const updateDeviceLimit = async (newLimit: number) => {
return updatePublicShareURLHelper({
@@ -24,24 +29,68 @@ export function ManageDeviceLimit({
deviceLimit: newLimit,
});
};
+ const [isChangeDeviceLimitVisible, setIsChangeDeviceLimitVisible] =
+ useState(false);
+ const deviceLimitOptions = useMemo(() => getDeviceLimitOptions(), []);
+
+ const closeDeviceLimitChangeModal = () =>
+ setIsChangeDeviceLimitVisible(false);
+ const openDeviceLimitChangeModalView = () =>
+ setIsChangeDeviceLimitVisible(true);
+
+ const changeDeviceLimitValue = (value: number) => async () => {
+ await updateDeviceLimit(value);
+ setIsChangeDeviceLimitVisible(false);
+ };
+
+ const handleDrawerClose: DialogProps['onClose'] = (_, reason) => {
+ if (reason === 'backdropClick') {
+ onRootClose();
+ } else {
+ closeDeviceLimitChangeModal();
+ }
+ };
return (
-
- {t('LINK_DEVICE_LIMIT')}
- updateDeviceLimit(e.value)}
- styles={DropdownStyle}
- />
-
+ <>
+ }
+ subText={String(publicShareProp.deviceLimit)}>
+ {t('LINK_DEVICE_LIMIT')}
+
+
+
+
+
+
+
+ {deviceLimitOptions.map((item, index) => (
+ <>
+
+ {item.label}
+
+ {index !==
+ deviceLimitOptions.length - 1 && (
+
+ )}
+ >
+ ))}
+
+
+
+
+ >
);
}
diff --git a/src/components/Collections/CollectionShare/publicShare/manage/downloadAccess.tsx b/src/components/Collections/CollectionShare/publicShare/manage/downloadAccess.tsx
index a0a61d404..bc05cb7a9 100644
--- a/src/components/Collections/CollectionShare/publicShare/manage/downloadAccess.tsx
+++ b/src/components/Collections/CollectionShare/publicShare/manage/downloadAccess.tsx
@@ -1,11 +1,9 @@
-import { Box, Typography } from '@mui/material';
+import { EnteMenuItem } from 'components/Menu/menuItem';
import { AppContext } from 'pages/_app';
import React, { useContext } from 'react';
import { Trans } from 'react-i18next';
import { t } from 'i18next';
import { PublicURL, Collection, UpdatePublicURL } from 'types/collection';
-import PublicShareSwitch from '../switch';
-
interface Iprops {
publicShareProp: PublicURL;
collection: Collection;
@@ -47,12 +45,11 @@ export function ManageDownloadAccess({
});
};
return (
-
- {t('FILE_DOWNLOAD')}
-
-
+
+ {t('FILE_DOWNLOAD')}
+
);
}
diff --git a/src/components/Collections/CollectionShare/publicShare/manage/index.tsx b/src/components/Collections/CollectionShare/publicShare/manage/index.tsx
index 32adec5b4..687deefd9 100644
--- a/src/components/Collections/CollectionShare/publicShare/manage/index.tsx
+++ b/src/components/Collections/CollectionShare/publicShare/manage/index.tsx
@@ -4,30 +4,51 @@ import { ManageLinkExpiry } from './linkExpiry';
import { Stack, Typography } from '@mui/material';
import { GalleryContext } from 'pages/gallery';
import React, { useContext, useState } from 'react';
-import { updateShareableURL } from 'services/collectionService';
-import { Collection, PublicURL, UpdatePublicURL } from 'types/collection';
-import { sleep } from 'utils/common';
import {
- ManageSectionLabel,
- ManageSectionOptions,
-} from '../../styledComponents';
+ deleteShareableURL,
+ updateShareableURL,
+} from 'services/collectionService';
+import { Collection, PublicURL, UpdatePublicURL } from 'types/collection';
import { ManageDownloadAccess } from './downloadAccess';
import { handleSharingErrors } from 'utils/error/ui';
import { SetPublicShareProp } from 'types/publicCollection';
import { ManagePublicCollect } from './publicCollect';
+import { EnteDrawer } from 'components/EnteDrawer';
+import RemoveCircleOutline from '@mui/icons-material/RemoveCircleOutline';
+import ContentCopyIcon from '@mui/icons-material/ContentCopy';
+import { EnteMenuItem } from 'components/Menu/menuItem';
import { t } from 'i18next';
+import { EnteMenuItemGroup } from 'components/Menu/menuItemGroup';
+import { DialogProps } from '@mui/material';
+import Titlebar from 'components/Titlebar';
+import EnteMenuItemDivider from 'components/Menu/menuItemDivider';
interface Iprops {
publicShareProp: PublicURL;
collection: Collection;
setPublicShareProp: SetPublicShareProp;
+ open: boolean;
+ onClose: () => void;
+ onRootClose: () => void;
+ publicShareUrl: string;
}
-export default function PublicShareManage({
+export default function ManagePublicShareOptions({
publicShareProp,
collection,
setPublicShareProp,
+ open,
+ onClose,
+ onRootClose,
+ publicShareUrl,
}: Iprops) {
+ const handleDrawerClose: DialogProps['onClose'] = (_, reason) => {
+ if (reason === 'backdropClick') {
+ onRootClose();
+ } else {
+ onClose();
+ }
+ };
const galleryContext = useContext(GalleryContext);
const [sharableLinkError, setSharableLinkError] = useState(null);
@@ -44,74 +65,100 @@ export default function PublicShareManage({
galleryContext.setBlockingLoad(false);
}
};
-
- const scrollToEnd = (e) => {
- const lastOptionRow: Element =
- e.currentTarget.nextElementSibling.lastElementChild;
- const main = async (lastOptionRow: Element) => {
- await sleep(0);
- lastOptionRow.scrollIntoView(true);
- };
- main(lastOptionRow);
+ const disablePublicSharing = async () => {
+ try {
+ galleryContext.setBlockingLoad(true);
+ await deleteShareableURL(collection);
+ setPublicShareProp(null);
+ onClose();
+ } catch (e) {
+ const errorMessage = handleSharingErrors(e);
+ setSharableLinkError(errorMessage);
+ } finally {
+ galleryContext.setBlockingLoad(false);
+ }
+ };
+ const copyToClipboardHelper = (text: string) => () => {
+ navigator.clipboard.writeText(text);
};
-
return (
<>
-
-
- {t('MANAGE_LINK')}
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ onClick={copyToClipboardHelper(publicShareUrl)}>
+ {t('COPY_LINK')}
+
+ }
+ onClick={disablePublicSharing}>
+ {t('REMOVE_LINK')}
+
+
+ {sharableLinkError && (
+ theme.palette.danger.main,
+ mt: 0.5,
+ }}>
+ {sharableLinkError}
+
+ )}
- {sharableLinkError && (
- theme.palette.danger.main,
- mt: 0.5,
- }}>
- {sharableLinkError}
-
- )}
-
-
+
+
>
);
}
diff --git a/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx b/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx
index 6af104d9e..2945a3939 100644
--- a/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx
+++ b/src/components/Collections/CollectionShare/publicShare/manage/linkExpiry.tsx
@@ -1,52 +1,103 @@
-import { Box, Typography } from '@mui/material';
-import React from 'react';
-import Select from 'react-select';
-import { linkExpiryStyle } from 'styles/linkExpiry';
+import ChevronRight from '@mui/icons-material/ChevronRight';
+import { DialogProps, Stack } from '@mui/material';
+import { EnteDrawer } from 'components/EnteDrawer';
+import { EnteMenuItem } from 'components/Menu/menuItem';
+import React, { useMemo, useState } from 'react';
import { PublicURL, Collection, UpdatePublicURL } from 'types/collection';
import { shareExpiryOptions } from 'utils/collection';
import { t } from 'i18next';
-
+import { EnteMenuItemGroup } from 'components/Menu/menuItemGroup';
import { formatDateTime } from 'utils/time/format';
-import { OptionWithDivider } from './selectComponents/OptionWithDivider';
+import Titlebar from 'components/Titlebar';
+import EnteMenuItemDivider from 'components/Menu/menuItemDivider';
interface Iprops {
publicShareProp: PublicURL;
collection: Collection;
updatePublicShareURLHelper: (req: UpdatePublicURL) => Promise;
+ onRootClose: () => void;
}
export function ManageLinkExpiry({
publicShareProp,
collection,
updatePublicShareURLHelper,
+ onRootClose,
}: Iprops) {
const updateDeviceExpiry = async (optionFn) => {
return updatePublicShareURLHelper({
collectionID: collection.id,
- validTill: optionFn(),
+ validTill: optionFn,
});
};
+
+ const [shareExpiryOptionsModalView, setShareExpiryOptionsModalView] =
+ useState(false);
+
+ const shareExpireOption = useMemo(() => shareExpiryOptions(), []);
+
+ const closeShareExpiryOptionsModalView = () =>
+ setShareExpiryOptionsModalView(false);
+
+ const openShareExpiryOptionsModalView = () =>
+ setShareExpiryOptionsModalView(true);
+
+ const changeShareExpiryValue = (value: number) => async () => {
+ await updateDeviceExpiry(value);
+ publicShareProp.validTill = value;
+ setShareExpiryOptionsModalView(false);
+ };
+
+ const handleDrawerClose: DialogProps['onClose'] = (_, reason) => {
+ if (reason === 'backdropClick') {
+ onRootClose();
+ } else {
+ closeShareExpiryOptionsModalView();
+ }
+ };
+
return (
-
- {t('LINK_EXPIRY')}
-
+ }
+ subText={
publicShareProp?.validTill
? formatDateTime(publicShareProp?.validTill / 1000)
: t('LINK_EXPIRY_NEVER')
- }
- onChange={(e) => {
- updateDeviceExpiry(e.value);
- }}
- styles={linkExpiryStyle}
- />
-
+ }>
+ {t('LINK_EXPIRY')}
+
+
+
+
+
+
+ {shareExpireOption.map((item, index) => (
+ <>
+
+ {item.label}
+
+ {index !== shareExpireOption.length - 1 && (
+
+ )}
+ >
+ ))}
+
+
+
+
+ >
);
}
diff --git a/src/components/Collections/CollectionShare/publicShare/manage/linkPassword/index.tsx b/src/components/Collections/CollectionShare/publicShare/manage/linkPassword/index.tsx
index 2f8d3bdba..abb15055b 100644
--- a/src/components/Collections/CollectionShare/publicShare/manage/linkPassword/index.tsx
+++ b/src/components/Collections/CollectionShare/publicShare/manage/linkPassword/index.tsx
@@ -1,9 +1,8 @@
-import { Box, Typography } from '@mui/material';
import { AppContext } from 'pages/_app';
import React, { useContext, useState } from 'react';
import { PublicURL, Collection, UpdatePublicURL } from 'types/collection';
import { PublicLinkSetPassword } from './setPassword';
-import PublicShareSwitch from '../../switch';
+import { EnteMenuItem } from 'components/Menu/menuItem';
import { t } from 'i18next';
interface Iprops {
@@ -49,13 +48,12 @@ export function ManageLinkPassword({
return (
<>
-
- {t('LINK_PASSWORD_LOCK')}
-
-
+
+ {t('LINK_PASSWORD_LOCK')}
+
- {t('PUBLIC_COLLECT')}
-
-
+
+
+ {t('PUBLIC_COLLECT')}
+
+
+
);
}
diff --git a/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx b/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx
new file mode 100644
index 000000000..ede962c20
--- /dev/null
+++ b/src/components/Collections/CollectionShare/publicShare/managePublicShare.tsx
@@ -0,0 +1,67 @@
+import { Stack, Typography } from '@mui/material';
+import { EnteMenuItem } from 'components/Menu/menuItem';
+import EnteMenuItemDivider from 'components/Menu/menuItemDivider';
+import { EnteMenuItemGroup } from 'components/Menu/menuItemGroup';
+import { Collection, PublicURL } from 'types/collection';
+import ManagePublicShareOptions from './manage';
+import PublicIcon from '@mui/icons-material/Public';
+import ContentCopyIcon from '@mui/icons-material/ContentCopyOutlined';
+import ChevronRightIcon from '@mui/icons-material/ChevronRight';
+import { SetPublicShareProp } from 'types/publicCollection';
+import LinkIcon from '@mui/icons-material/Link';
+import { useState } from 'react';
+import { t } from 'i18next';
+
+interface Iprops {
+ publicShareProp: PublicURL;
+ collection: Collection;
+ setPublicShareProp: SetPublicShareProp;
+ onRootClose: () => void;
+ publicShareUrl: string;
+ copyToClipboardHelper: () => void;
+}
+export default function ManagePublicShare({
+ publicShareProp,
+ setPublicShareProp,
+ collection,
+ onRootClose,
+ publicShareUrl,
+ copyToClipboardHelper,
+}: Iprops) {
+ const [manageShareView, setManageShareView] = useState(false);
+ const closeManageShare = () => setManageShareView(false);
+ const openManageShare = () => setManageShareView(true);
+ return (
+ <>
+
+
+
+ {t('PUBLIC_LINK_ENABLED')}
+
+
+ }
+ onClick={copyToClipboardHelper}>
+ {t('COPY_LINK')}
+
+
+ }
+ endIcon={ }
+ onClick={openManageShare}>
+ {t('MANAGE_LINK')}
+
+
+
+
+ >
+ );
+}
diff --git a/src/components/Collections/styledComponents.ts b/src/components/Collections/styledComponents.ts
index 3a45be248..d80425615 100644
--- a/src/components/Collections/styledComponents.ts
+++ b/src/components/Collections/styledComponents.ts
@@ -1,7 +1,7 @@
import { Box } from '@mui/material';
import { styled } from '@mui/material';
import { Overlay } from 'components/Container';
-import { SpecialPadding } from 'styles/SpecialPadding';
+import { IMAGE_CONTAINER_MAX_WIDTH, MIN_COLUMNS } from 'constants/gallery';
export const CollectionListWrapper = styled(Box)`
position: relative;
overflow: hidden;
@@ -10,7 +10,10 @@ export const CollectionListWrapper = styled(Box)`
`;
export const CollectionListBarWrapper = styled(Box)`
- ${SpecialPadding}
+ padding: 0 24px;
+ @media (max-width: ${IMAGE_CONTAINER_MAX_WIDTH * MIN_COLUMNS}px) {
+ padding: 0 4px;
+ }
margin-bottom: 16px;
border-bottom: 1px solid ${({ theme }) => theme.palette.divider};
`;
diff --git a/src/components/Container.ts b/src/components/Container.ts
index bcb7464ca..317728e52 100644
--- a/src/components/Container.ts
+++ b/src/components/Container.ts
@@ -27,10 +27,6 @@ export const Row = styled('div')`
flex: 1;
`;
-export const Label = styled('div')<{ width?: string }>`
- width: ${(props) => props.width ?? '70%'};
- color: ${(props) => props.theme.palette.text.secondary};
-`;
export const Value = styled('div')<{ width?: string }>`
display: flex;
justify-content: flex-start;
@@ -77,3 +73,11 @@ export const IconButtonWithBG = styled(IconButton)(({ theme }) => ({
export const HorizontalFlex = styled(Box)({
display: 'flex',
});
+
+export const VerticalFlex = styled(HorizontalFlex)({
+ flexDirection: 'column',
+});
+
+export const VerticallyCenteredFlex = styled(HorizontalFlex)({
+ alignItems: 'center',
+});
diff --git a/src/components/DialogBoxV2/index.tsx b/src/components/DialogBoxV2/index.tsx
new file mode 100644
index 000000000..be9d76ef9
--- /dev/null
+++ b/src/components/DialogBoxV2/index.tsx
@@ -0,0 +1,126 @@
+import React from 'react';
+import {
+ Box,
+ Breakpoint,
+ Button,
+ Dialog,
+ DialogProps,
+ Stack,
+ Typography,
+} from '@mui/material';
+import { t } from 'i18next';
+import { dialogCloseHandler } from 'components/DialogBox/TitleWithCloseButton';
+import { DialogBoxAttributesV2 } from 'types/dialogBox';
+
+type IProps = React.PropsWithChildren<
+ Omit & {
+ onClose: () => void;
+ attributes: DialogBoxAttributesV2;
+ size?: Breakpoint;
+ titleCloseButton?: boolean;
+ }
+>;
+
+export default function DialogBoxV2({
+ attributes,
+ children,
+ open,
+ onClose,
+ ...props
+}: IProps) {
+ if (!attributes) {
+ return <>>;
+ }
+
+ const handleClose = dialogCloseHandler({
+ staticBackdrop: attributes.staticBackdrop,
+ nonClosable: attributes.nonClosable,
+ onClose: onClose,
+ });
+
+ return (
+
+
+
+ {attributes.icon && (
+ svg': {
+ fontSize: '32px',
+ },
+ }}>
+ {attributes.icon}
+
+ )}
+ {attributes.title && (
+
+ {attributes.title}
+
+ )}
+ {children ||
+ (attributes?.content && (
+
+ {attributes.content}
+
+ ))}
+
+
+ {attributes.proceed && (
+ {
+ attributes.proceed.action();
+ onClose();
+ }}
+ disabled={attributes.proceed.disabled}>
+ {attributes.proceed.text}
+
+ )}
+ {attributes.close && (
+ {
+ attributes.close.action &&
+ attributes.close?.action();
+ onClose();
+ }}>
+ {attributes.close?.text ?? t('OK')}
+
+ )}
+ {attributes.buttons &&
+ attributes.buttons.map((b) => (
+ {
+ b.action();
+ onClose();
+ }}
+ disabled={b.disabled}>
+ {b.text}
+
+ ))}
+
+
+
+ );
+}
diff --git a/src/components/DropdownInput.tsx b/src/components/DropdownInput.tsx
new file mode 100644
index 000000000..cd53ae1a0
--- /dev/null
+++ b/src/components/DropdownInput.tsx
@@ -0,0 +1,105 @@
+import ExpandMore from '@mui/icons-material/ExpandMore';
+import {
+ Box,
+ MenuItem,
+ Select,
+ SelectChangeEvent,
+ Stack,
+ Typography,
+ TypographyTypeMap,
+} from '@mui/material';
+
+export interface DropdownOption {
+ label: string;
+ value: T;
+}
+
+interface Iprops {
+ label: string;
+ labelProps: TypographyTypeMap['props'];
+ options: DropdownOption[];
+ message?: string;
+ selectedValue: string;
+ setSelectedValue: (selectedValue: T) => void;
+ placeholder?: string;
+}
+
+export default function DropdownInput({
+ label,
+ labelProps,
+ options,
+ message,
+ selectedValue,
+ placeholder,
+ setSelectedValue,
+}: Iprops) {
+ return (
+
+ {label}
+ ({
+ backgroundColor: theme.palette.background.overPaper,
+ '.MuiMenuItem-root ': {
+ color: theme.palette.text.secondary,
+ },
+ '&& > .Mui-selected': {
+ background: theme.palette.background.overPaper,
+ color: theme.palette.text.primary,
+ },
+ }),
+ },
+ }}
+ sx={(theme) => ({
+ '::before , ::after': {
+ borderBottom: 'none !important',
+ },
+ '.MuiSelect-select': {
+ background: theme.palette.fill.dark,
+ borderRadius: '8px',
+ },
+ '&&& .MuiSelect-select': {
+ p: '12px 36px 12px 16px',
+ },
+ '.MuiSelect-icon': {
+ mr: '12px',
+ color: theme.palette.stroke.muted,
+ },
+ })}
+ renderValue={(selected) => {
+ return !selected?.length ? (
+ {placeholder ?? ''}
+ ) : (
+ options.find((o) => o.value === selected).label
+ );
+ }}
+ value={selectedValue}
+ onChange={(event: SelectChangeEvent) => {
+ setSelectedValue(event.target.value as T);
+ }}>
+ {options.map((option, index) => (
+ theme.palette.primary.main,
+ }}>
+ {option.label}
+
+ ))}
+
+ {message && (
+
+ {message}
+
+ )}
+
+ );
+}
diff --git a/src/components/EnteDrawer.tsx b/src/components/EnteDrawer.tsx
index 5c860e9d6..beacae98a 100644
--- a/src/components/EnteDrawer.tsx
+++ b/src/components/EnteDrawer.tsx
@@ -1,5 +1,4 @@
-import { Drawer } from '@mui/material';
-import styled from 'styled-components';
+import { Drawer, styled } from '@mui/material';
export const EnteDrawer = styled(Drawer)(({ theme }) => ({
'& .MuiPaper-root': {
diff --git a/src/components/ExportFinished.tsx b/src/components/ExportFinished.tsx
index 4535b0ca9..c458e2b60 100644
--- a/src/components/ExportFinished.tsx
+++ b/src/components/ExportFinished.tsx
@@ -1,74 +1,53 @@
-import { Button, DialogActions, DialogContent, Stack } from '@mui/material';
+import {
+ Button,
+ DialogActions,
+ DialogContent,
+ Stack,
+ Typography,
+} from '@mui/material';
import React from 'react';
import { t } from 'i18next';
-import { ExportStats } from 'types/export';
import { formatDateTime } from 'utils/time/format';
-import { FlexWrapper, Label, Value } from './Container';
-import { ComfySpan } from './ExportInProgress';
+import { SpaceBetweenFlex } from './Container';
interface Props {
+ pendingFileCount: number;
onHide: () => void;
lastExportTime: number;
- exportStats: ExportStats;
- exportFiles: () => void;
- retryFailed: () => void;
+ startExport: () => void;
}
export default function ExportFinished(props: Props) {
- const totalFiles = props.exportStats.failed + props.exportStats.success;
return (
<>
-
-
- {t('LAST_EXPORT_TIME')}
-
+
+
+
+ {t('PENDING_ITEMS')}
+
+ {props.pendingFileCount}
+
+
+
+ {t('LAST_EXPORT_TIME')}
+
+
{formatDateTime(props.lastExportTime)}
-
-
-
-
- {t('SUCCESSFULLY_EXPORTED_FILES')}
-
-
-
- {props.exportStats.success} / {totalFiles}
-
-
-
- {props.exportStats.failed > 0 && (
-
-
- {t('FAILED_EXPORTED_FILES')}
-
-
-
- {props.exportStats.failed} / {totalFiles}
-
-
-
- )}
+
+
- {props.exportStats.failed !== 0 ? (
-
- {t('RETRY_EXPORT')}
-
- ) : (
-
- {t('EXPORT_AGAIN')}
-
- )}
{t('CLOSE')}
+
+ {t('EXPORT_AGAIN')}
+
>
);
diff --git a/src/components/ExportInProgress.tsx b/src/components/ExportInProgress.tsx
index 9f28eb401..e71504bbb 100644
--- a/src/components/ExportInProgress.tsx
+++ b/src/components/ExportInProgress.tsx
@@ -11,8 +11,10 @@ import { ExportStage } from 'constants/export';
import VerticallyCentered, { FlexWrapper } from './Container';
import { ProgressBar } from 'react-bootstrap';
import { t } from 'i18next';
+import { Trans } from 'react-i18next';
export const ComfySpan = styled('span')`
+ padding: 0 0.5rem;
word-spacing: 1rem;
color: #ddd;
`;
@@ -20,65 +22,57 @@ export const ComfySpan = styled('span')`
interface Props {
exportStage: ExportStage;
exportProgress: ExportProgress;
- resumeExport: () => void;
- cancelExport: () => void;
- pauseExport: () => void;
+ stopExport: () => void;
+ closeExportDialog: () => void;
}
export default function ExportInProgress(props: Props) {
+ const isLoading = props.exportProgress.total === 0;
return (
<>
-
- {' '}
- {props.exportProgress.current} /{' '}
- {props.exportProgress.total}{' '}
- {' '}
-
- {' '}
- files exported{' '}
- {props.exportStage === ExportStage.PAUSED &&
- `(paused)`}
-
+ {isLoading ? (
+ t('EXPORT_STARTING')
+ ) : (
+ ,
+ }}
+ values={{
+ progress: props.exportProgress,
+ }}
+ />
+ )}
- {props.exportStage === ExportStage.PAUSED ? (
-
- {t('RESUME')}
-
- ) : (
-
- {t('PAUSE')}
-
- )}
- {t('CANCEL')}
+ onClick={props.closeExportDialog}>
+ {t('CLOSE')}
+
+
+ {t('STOP_EXPORT')}
>
diff --git a/src/components/ExportModal.tsx b/src/components/ExportModal.tsx
index 584920dbb..0de1db764 100644
--- a/src/components/ExportModal.tsx
+++ b/src/components/ExportModal.tsx
@@ -1,47 +1,41 @@
import isElectron from 'is-electron';
-import React, { useEffect, useMemo, useState, useContext } from 'react';
+import React, { useEffect, useState, useContext } from 'react';
import exportService from 'services/exportService';
-import { ExportProgress, ExportStats } from 'types/export';
-import { getLocalFiles } from 'services/fileService';
-import { User } from 'types/user';
+import { ExportProgress, ExportSettings, FileExportStats } from 'types/export';
import {
+ Box,
Button,
Dialog,
DialogContent,
Divider,
- Stack,
styled,
+ Switch,
Tooltip,
+ Typography,
} from '@mui/material';
-import { sleep } from 'utils/common';
-import { getExportRecordFileUID } from 'utils/export';
import { logError } from 'utils/sentry';
import { getData, LS_KEYS, setData } from 'utils/storage/localStorage';
-import { FlexWrapper, Label, Value } from './Container';
+import { SpaceBetweenFlex, VerticallyCenteredFlex } from './Container';
import ExportFinished from './ExportFinished';
import ExportInit from './ExportInit';
import ExportInProgress from './ExportInProgress';
import FolderIcon from '@mui/icons-material/Folder';
-import { ExportStage, ExportType } from 'constants/export';
-import EnteSpinner from './EnteSpinner';
+import { ExportStage } from 'constants/export';
import DialogTitleWithCloseButton from './DialogBox/TitleWithCloseButton';
import MoreHoriz from '@mui/icons-material/MoreHoriz';
import OverflowMenu from './OverflowMenu/menu';
import { OverflowMenuOption } from './OverflowMenu/option';
-import { convertBytesToHumanReadable } from 'utils/file/size';
-import { CustomError } from 'utils/error';
-import { getLocalUserDetails } from 'utils/user';
import { AppContext } from 'pages/_app';
import { getExportDirectoryDoesNotExistMessage } from 'utils/ui';
-import { addLogLine } from 'utils/logging';
import { t } from 'i18next';
+import LinkButton from './pages/gallery/LinkButton';
+import { CustomError } from 'utils/error';
-const ExportFolderPathContainer = styled('span')`
+const ExportFolderPathContainer = styled(LinkButton)`
+ width: 262px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
- width: 100%;
-
/* Beginning of string */
direction: rtl;
text-align: left;
@@ -53,17 +47,16 @@ interface Props {
}
export default function ExportModal(props: Props) {
const appContext = useContext(AppContext);
- const userDetails = useMemo(() => getLocalUserDetails(), []);
const [exportStage, setExportStage] = useState(ExportStage.INIT);
const [exportFolder, setExportFolder] = useState('');
- const [exportSize, setExportSize] = useState('');
+ const [continuousExport, setContinuousExport] = useState(false);
const [exportProgress, setExportProgress] = useState({
current: 0,
total: 0,
});
- const [exportStats, setExportStats] = useState({
- failed: 0,
- success: 0,
+ const [fileExportStats, setFileExportStats] = useState({
+ totalCount: 0,
+ pendingCount: 0,
});
const [lastExportTime, setLastExportTime] = useState(0);
@@ -75,43 +68,53 @@ export default function ExportModal(props: Props) {
return;
}
try {
- setExportFolder(getData(LS_KEYS.EXPORT)?.folder);
-
- exportService.electronAPIs.registerStopExportListener(
- stopExportHandler
- );
- exportService.electronAPIs.registerPauseExportListener(
- pauseExportHandler
- );
- exportService.electronAPIs.registerResumeExportListener(
- resumeExportHandler
- );
- exportService.electronAPIs.registerRetryFailedExportListener(
- retryFailedExportHandler
- );
+ const exportSettings: ExportSettings = getData(LS_KEYS.EXPORT);
+ setExportFolder(exportSettings?.folder);
+ setContinuousExport(exportSettings?.continuousExport);
+ syncFileCounts();
} catch (e) {
logError(e, 'error in exportModal');
}
}, []);
+ useEffect(() => {
+ if (!props.show) {
+ return;
+ }
+ if (exportService.isExportInProgress()) {
+ setExportStage(ExportStage.INPROGRESS);
+ }
+ syncFileCounts();
+ }, [props.show]);
+
+ useEffect(() => {
+ try {
+ if (continuousExport) {
+ exportService.enableContinuousExport(startExport);
+ } else {
+ exportService.disableContinuousExport();
+ }
+ } catch (e) {
+ logError(e, 'error handling continuousExport change');
+ }
+ }, [continuousExport]);
+
useEffect(() => {
if (!exportFolder) {
return;
}
const main = async () => {
try {
- const exportInfo = await exportService.getExportRecord();
- setExportStage(exportInfo?.stage ?? ExportStage.INIT);
- setLastExportTime(exportInfo?.lastAttemptTimestamp);
- setExportProgress(
- exportInfo?.progress ?? { current: 0, total: 0 }
- );
- setExportStats({
- success: exportInfo?.exportedFiles?.length ?? 0,
- failed: exportInfo?.failedFiles?.length ?? 0,
- });
- if (exportInfo?.stage === ExportStage.INPROGRESS) {
- await resumeExport();
+ const exportRecord = await exportService.getExportRecord();
+ if (!exportRecord) {
+ setExportStage(ExportStage.INIT);
+ return;
+ }
+ setExportStage(exportRecord.stage);
+ setLastExportTime(exportRecord.lastAttemptTimestamp);
+ await syncFileCounts();
+ if (exportRecord.stage === ExportStage.INPROGRESS) {
+ await startExport();
}
} catch (e) {
logError(e, 'error handling exportFolder change');
@@ -120,62 +123,27 @@ export default function ExportModal(props: Props) {
void main();
}, [exportFolder]);
- useEffect(() => {
- if (!props.show) {
- return;
- }
- const main = async () => {
- const user: User = getData(LS_KEYS.USER);
- if (exportStage === ExportStage.FINISHED) {
- try {
- const localFiles = await getLocalFiles();
- const userPersonalFiles = localFiles.filter(
- (file) => file.ownerID === user?.id
- );
- const exportRecord = await exportService.getExportRecord();
- const exportedFileCnt = exportRecord.exportedFiles?.length;
- const failedFilesCnt = exportRecord.failedFiles?.length;
- const syncedFilesCnt = userPersonalFiles.length;
- if (syncedFilesCnt > exportedFileCnt + failedFilesCnt) {
- await updateExportProgress({
- current: exportedFileCnt + failedFilesCnt,
- total: syncedFilesCnt,
- });
- const exportFileUIDs = new Set([
- ...exportRecord.exportedFiles,
- ...exportRecord.failedFiles,
- ]);
- const unExportedFiles = userPersonalFiles.filter(
- (file) =>
- !exportFileUIDs.has(
- getExportRecordFileUID(file)
- )
- );
- await exportService.addFilesQueuedRecord(
- exportFolder,
- unExportedFiles
- );
- await updateExportStage(ExportStage.PAUSED);
- }
- } catch (e) {
- setExportStage(ExportStage.INIT);
- logError(e, 'error while updating exportModal on reopen');
- }
- }
- };
- void main();
- }, [props.show]);
-
- useEffect(() => {
- setExportSize(convertBytesToHumanReadable(userDetails?.usage));
- }, [userDetails]);
-
// =============
// STATE UPDATERS
// ==============
const updateExportFolder = (newFolder: string) => {
+ const exportSettings: ExportSettings = getData(LS_KEYS.EXPORT);
+ const updatedExportSettings: ExportSettings = {
+ ...exportSettings,
+ folder: newFolder,
+ };
+ setData(LS_KEYS.EXPORT, updatedExportSettings);
setExportFolder(newFolder);
- setData(LS_KEYS.EXPORT, { folder: newFolder });
+ };
+
+ const updateContinuousExport = (updatedContinuousExport: boolean) => {
+ const exportSettings: ExportSettings = getData(LS_KEYS.EXPORT);
+ const updatedExportSettings: ExportSettings = {
+ ...exportSettings,
+ continuousExport: updatedContinuousExport,
+ };
+ setData(LS_KEYS.EXPORT, updatedExportSettings);
+ setContinuousExport(updatedContinuousExport);
};
const updateExportStage = async (newStage: ExportStage) => {
@@ -190,70 +158,65 @@ export default function ExportModal(props: Props) {
});
};
- const updateExportProgress = async (newProgress: ExportProgress) => {
- setExportProgress(newProgress);
- await exportService.updateExportRecord({ progress: newProgress });
- };
-
// ======================
// HELPER FUNCTIONS
- // =========================
+ // =======================
const preExportRun = async () => {
const exportFolder = getData(LS_KEYS.EXPORT)?.folder;
- if (!exportFolder) {
- await selectExportDirectory();
- }
const exportFolderExists = exportService.exists(exportFolder);
if (!exportFolderExists) {
appContext.setDialogMessage(
getExportDirectoryDoesNotExistMessage()
);
- return;
+ throw Error(CustomError.EXPORT_FOLDER_DOES_NOT_EXIST);
}
await updateExportStage(ExportStage.INPROGRESS);
- await sleep(100);
- };
- const postExportRun = async (exportResult?: { paused?: boolean }) => {
- if (!exportResult?.paused) {
- await updateExportStage(ExportStage.FINISHED);
- await sleep(100);
- await updateExportTime(Date.now());
- await syncExportStatsWithRecord();
- }
};
- const selectExportDirectory = async () => {
- const newFolder = await exportService.selectExportDirectory();
- if (newFolder) {
- updateExportFolder(newFolder);
- } else {
- throw Error(CustomError.REQUEST_CANCELLED);
- }
+ const postExportRun = async () => {
+ await updateExportStage(ExportStage.FINISHED);
+ await updateExportTime(Date.now());
+ await syncFileCounts();
};
- const syncExportStatsWithRecord = async () => {
- const exportRecord = await exportService.getExportRecord();
- const failed = exportRecord?.failedFiles?.length ?? 0;
- const success = exportRecord?.exportedFiles?.length ?? 0;
- setExportStats({ failed, success });
+ const syncFileCounts = async () => {
+ try {
+ const fileExportStats = await exportService.getFileExportStats();
+ setFileExportStats(fileExportStats);
+ } catch (e) {
+ logError(e, 'error updating file counts');
+ }
};
// =============
// UI functions
// =============
+ const handleChangeExportDirectoryClick = () => {
+ void exportService.changeExportDirectory(updateExportFolder);
+ };
+
+ const handleOpenExportDirectoryClick = () => {
+ void exportService.openExportDirectory(exportFolder);
+ };
+
+ const toggleContinuousExport = () => {
+ try {
+ updateContinuousExport(!continuousExport);
+ } catch (e) {
+ logError(e, 'toggleContinuousExport failed');
+ }
+ };
+
const startExport = async () => {
try {
await preExportRun();
- await updateExportProgress({ current: 0, total: 0 });
- const exportResult = await exportService.exportFiles(
- updateExportProgress,
- ExportType.NEW
- );
- await postExportRun(exportResult);
+ setExportProgress({ current: 0, total: 0 });
+ await exportService.exportFiles(setExportProgress);
+ await postExportRun();
} catch (e) {
- if (e.message !== CustomError.REQUEST_CANCELLED) {
+ if (e.message !== CustomError.EXPORT_FOLDER_DOES_NOT_EXIST) {
logError(e, 'startExport failed');
}
}
@@ -264,120 +227,7 @@ export default function ExportModal(props: Props) {
exportService.stopRunningExport();
await postExportRun();
} catch (e) {
- if (e.message !== CustomError.REQUEST_CANCELLED) {
- logError(e, 'stopExport failed');
- }
- }
- };
-
- const pauseExport = async () => {
- try {
- await updateExportStage(ExportStage.PAUSED);
- exportService.pauseRunningExport();
- await postExportRun({ paused: true });
- } catch (e) {
- if (e.message !== CustomError.REQUEST_CANCELLED) {
- logError(e, 'pauseExport failed');
- }
- }
- };
-
- const resumeExport = async () => {
- try {
- const exportRecord = await exportService.getExportRecord();
- await preExportRun();
-
- const pausedStageProgress = exportRecord.progress;
- setExportProgress(pausedStageProgress);
-
- addLogLine(
- `resuming export, pausedStageProgress: ${JSON.stringify(
- pausedStageProgress
- )}`
- );
- const updateExportStatsWithOffset = (progress: ExportProgress) =>
- updateExportProgress({
- current: pausedStageProgress.current + progress.current,
- total: pausedStageProgress.current + progress.total,
- });
- const exportResult = await exportService.exportFiles(
- updateExportStatsWithOffset,
- ExportType.PENDING
- );
-
- await postExportRun(exportResult);
- } catch (e) {
- if (e.message !== CustomError.REQUEST_CANCELLED) {
- logError(e, 'resumeExport failed');
- }
- }
- };
-
- const retryFailedExport = async () => {
- try {
- await preExportRun();
- await updateExportProgress({
- current: 0,
- total: exportStats.failed,
- });
-
- const exportResult = await exportService.exportFiles(
- updateExportProgress,
- ExportType.RETRY_FAILED
- );
- await postExportRun(exportResult);
- } catch (e) {
- if (e.message !== CustomError.REQUEST_CANCELLED) {
- logError(e, 'retryFailedExport failed');
- }
- }
- };
-
- const startExportHandler = () => {
- void startExport();
- };
- const stopExportHandler = () => {
- void stopExport();
- };
- const pauseExportHandler = () => {
- void pauseExport();
- };
- const resumeExportHandler = () => {
- void resumeExport();
- };
- const retryFailedExportHandler = () => {
- void retryFailedExport();
- };
-
- const ExportDynamicContent = () => {
- switch (exportStage) {
- case ExportStage.INIT:
- return ;
-
- case ExportStage.INPROGRESS:
- case ExportStage.PAUSED:
- return (
-
- );
- case ExportStage.FINISHED:
- return (
-
- );
-
- default:
- return <>>;
+ logError(e, 'stopExport failed');
}
};
@@ -387,71 +237,80 @@ export default function ExportModal(props: Props) {
{t('EXPORT_DATA')}
-
-
-
-
+
+
+
+
+ {t('TOTAL_ITEMS')}
+
+
+ {fileExportStats.totalCount}
+
+
-
+
);
}
-function ExportDirectory({ exportFolder, selectExportDirectory, exportStage }) {
+function ExportDirectory({
+ exportFolder,
+ changeExportDirectory,
+ exportStage,
+ openExportDirectory,
+}) {
return (
-
- {t('DESTINATION')}
-
+
+
+ {t('DESTINATION')}
+
+ <>
{!exportFolder ? (
-
+
{t('SELECT_FOLDER')}
) : (
- <>
-
-
- {exportFolder}
-
-
- {(exportStage === ExportStage.FINISHED ||
- exportStage === ExportStage.INIT) && (
+
+
+
+ {exportFolder}
+
+
+
+ {exportStage === ExportStage.FINISHED ||
+ exportStage === ExportStage.INIT ? (
+ ) : (
+
)}
- >
+
)}
-
-
+ >
+
);
}
-function ExportSize({ exportSize }) {
- return (
-
- {t('EXPORT_SIZE')}
-
- {exportSize ? `${exportSize}` : }
-
-
- );
-}
-
-function ExportDirectoryOption({ selectExportDirectory }) {
- const handleClick = () => {
- try {
- selectExportDirectory();
- } catch (e) {
- if (e.message !== CustomError.REQUEST_CANCELLED) {
- logError(e, 'startExport failed');
- }
- }
- };
+function ExportDirectoryOption({ changeExportDirectory }) {
return (
}>
}>
{t('CHANGE_FOLDER')}
);
}
+
+function ContinuousExport({ continuousExport, toggleContinuousExport }) {
+ return (
+
+
+ {t('CONTINUOUS_EXPORT')}
+
+
+
+
+
+ );
+}
+
+const ExportDynamicContent = ({
+ exportStage,
+ startExport,
+ stopExport,
+ onHide,
+ lastExportTime,
+ pendingFileCount,
+ exportProgress,
+}: {
+ exportStage: ExportStage;
+ startExport: () => void;
+ stopExport: () => void;
+ onHide: () => void;
+ lastExportTime: number;
+ pendingFileCount: number;
+ exportProgress: ExportProgress;
+}) => {
+ switch (exportStage) {
+ case ExportStage.INIT:
+ return ;
+
+ case ExportStage.INPROGRESS:
+ return (
+
+ );
+ case ExportStage.FINISHED:
+ return (
+
+ );
+
+ default:
+ return <>>;
+ }
+};
diff --git a/src/components/MachineLearning/ImageViews.tsx b/src/components/MachineLearning/ImageViews.tsx
index f8c7bdf99..1b059359d 100644
--- a/src/components/MachineLearning/ImageViews.tsx
+++ b/src/components/MachineLearning/ImageViews.tsx
@@ -1,19 +1,18 @@
import React, { useState, useEffect } from 'react';
-import styled from 'styled-components';
+import { styled } from '@mui/material';
+
import { imageBitmapToBlob } from 'utils/image';
import { logError } from 'utils/sentry';
import { getBlobFromCache } from 'utils/storage/cache';
-export const Image = styled.img``;
-
-export const FaceCropsRow = styled.div`
+export const FaceCropsRow = styled('div')`
& > img {
width: 256px;
height: 256px;
}
`;
-export const FaceImagesRow = styled.div`
+export const FaceImagesRow = styled('div')`
& > img {
width: 112px;
height: 112px;
@@ -92,9 +91,5 @@ export function ImageBlobView(props: { blob: Blob }) {
}
}, [props.blob]);
- return (
- <>
-
- >
- );
+ return ;
}
diff --git a/src/components/MachineLearning/MlDebug-disabled.tsx b/src/components/MachineLearning/MlDebug-disabled.tsx
index cba276875..86405b3d2 100644
--- a/src/components/MachineLearning/MlDebug-disabled.tsx
+++ b/src/components/MachineLearning/MlDebug-disabled.tsx
@@ -24,7 +24,8 @@ export {};
// import mlIDbStorage from 'utils/storage/mlIDbStorage';
// import { getFaceCropBlobFromStorage } from 'utils/machineLearning/faceCrop';
// import { PeopleList } from './PeopleList';
-// import styled from 'styled-components';
+// import { styled } from '@mui/material';
+
// import { RawNodeDatum } from 'react-d3-tree/lib/types/common';
// import { DebugInfo, mstToBinaryTree } from 'hdbscan';
// import { toD3Tree } from 'utils/machineLearning/clustering';
@@ -70,7 +71,7 @@ export {};
// );
// }
-// const D3ImageContainer = styled.div`
+// const D3ImageContainer = styled('div')`
// & > img {
// width: 100%;
// height: 100%;
diff --git a/src/components/MachineLearning/PeopleList.tsx b/src/components/MachineLearning/PeopleList.tsx
index fec3c365d..d28a75b62 100644
--- a/src/components/MachineLearning/PeopleList.tsx
+++ b/src/components/MachineLearning/PeopleList.tsx
@@ -5,7 +5,7 @@ import {
getPeopleList,
getUnidentifiedFaces,
} from 'utils/machineLearning';
-import styled from 'styled-components';
+import { styled } from '@mui/material';
import { EnteFile } from 'types/file';
import { ImageCacheView } from './ImageViews';
import { CACHES } from 'constants/cache';
@@ -14,7 +14,7 @@ import { addLogLine } from 'utils/logging';
import { logError } from 'utils/sentry';
import { t } from 'i18next';
-const FaceChipContainer = styled.div`
+const FaceChipContainer = styled('div')`
display: flex;
flex-wrap: wrap;
justify-content: center;
@@ -24,7 +24,7 @@ const FaceChipContainer = styled.div`
overflow: auto;
`;
-const FaceChip = styled.div<{ clickable?: boolean }>`
+const FaceChip = styled('div')<{ clickable?: boolean }>`
width: 112px;
height: 112px;
margin: 5px;
diff --git a/src/components/Menu/menuItem.tsx b/src/components/Menu/menuItem.tsx
new file mode 100644
index 000000000..c380961d0
--- /dev/null
+++ b/src/components/Menu/menuItem.tsx
@@ -0,0 +1,91 @@
+import { MenuItem, ButtonProps, Typography, Box } from '@mui/material';
+import PublicShareSwitch from 'components/Collections/CollectionShare/publicShare/switch';
+import {
+ FluidContainer,
+ HorizontalFlex,
+ SpaceBetweenFlex,
+} from 'components/Container';
+import { DotSeparator } from 'components/Sidebar/styledComponents';
+import React from 'react';
+
+interface Iprops {
+ onClick: () => void;
+ color?: ButtonProps['color'];
+ startIcon?: React.ReactNode;
+ endIcon?: React.ReactNode;
+ subText?: string;
+ children?: any;
+ hasSwitch?: boolean;
+ checked?: boolean;
+}
+export function EnteMenuItem({
+ onClick,
+ color = 'primary',
+ startIcon,
+ endIcon,
+ subText,
+ children,
+ hasSwitch = false,
+ checked,
+}: Iprops) {
+ const handleClick = () => {
+ onClick();
+ };
+ return (
+ theme.palette[color].main,
+ backgroundColor: (theme) => theme.palette.background.overPaper,
+ padding: 2,
+ '& .MuiSvgIcon-root': {
+ fontSize: '20px',
+ },
+ borderRadius: '8px',
+ }}>
+
+
+ {startIcon && (
+
+ {startIcon}
+
+ )}
+ {children}
+
+ {subText && (
+
+
+
+ {subText}
+
+ )}
+
+
+ {endIcon && (
+
+ {endIcon}
+
+ )}
+ {hasSwitch && (
+
+ )}
+
+
+
+ );
+}
diff --git a/src/components/Menu/menuItemDivider.tsx b/src/components/Menu/menuItemDivider.tsx
new file mode 100644
index 000000000..3c8626751
--- /dev/null
+++ b/src/components/Menu/menuItemDivider.tsx
@@ -0,0 +1,16 @@
+import { Divider } from '@mui/material';
+interface Iprops {
+ hasIcon?: boolean;
+}
+export default function EnteMenuItemDivider({ hasIcon = false }: Iprops) {
+ return (
+
+ );
+}
diff --git a/src/components/Menu/menuItemGroup.tsx b/src/components/Menu/menuItemGroup.tsx
new file mode 100644
index 000000000..fb3f77b94
--- /dev/null
+++ b/src/components/Menu/menuItemGroup.tsx
@@ -0,0 +1,16 @@
+import { styled } from '@mui/material';
+
+export const EnteMenuItemGroup = styled('div')(
+ ({ theme }) => `
+ & > .MuiMenuItem-root:not(:last-of-type) {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+ & > .MuiMenuItem-root:not(:first-of-type) {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+ background-color: ${theme.palette.background.overPaper};
+ border-radius: 4px;
+`
+);
diff --git a/src/components/Navbar/base.tsx b/src/components/Navbar/base.tsx
index 1c67b12fe..d4df73a5b 100644
--- a/src/components/Navbar/base.tsx
+++ b/src/components/Navbar/base.tsx
@@ -1,6 +1,6 @@
import { FlexWrapper } from 'components/Container';
import { styled } from '@mui/material';
-import { SpecialPadding } from 'styles/SpecialPadding';
+import { IMAGE_CONTAINER_MAX_WIDTH, MIN_COLUMNS } from 'constants/gallery';
const NavbarBase = styled(FlexWrapper)`
min-height: 64px;
position: sticky;
@@ -10,7 +10,10 @@ const NavbarBase = styled(FlexWrapper)`
border-bottom: 1px solid ${({ theme }) => theme.palette.divider};
background-color: ${({ theme }) => theme.palette.background.default};
margin-bottom: 16px;
- ${SpecialPadding}
+ padding: 0 24px;
+ @media (max-width: ${IMAGE_CONTAINER_MAX_WIDTH * MIN_COLUMNS}px) {
+ padding: 0 4px;
+ }
`;
export default NavbarBase;
diff --git a/src/components/PasswordStrength.tsx b/src/components/PasswordStrength.tsx
index a96374d3e..fa1d1c0d1 100644
--- a/src/components/PasswordStrength.tsx
+++ b/src/components/PasswordStrength.tsx
@@ -28,7 +28,9 @@ export const PasswordStrengthHint = ({
})}
textAlign={'left'}
flex={1}>
- {password ? t('PASSPHRASE_STRENGTH', { passwordStrength }) : ''}
+ {password
+ ? t('PASSPHRASE_STRENGTH', { context: passwordStrength })
+ : ''}
);
diff --git a/src/components/PhotoList.tsx b/src/components/PhotoList.tsx
index e86f66484..3c293fe7a 100644
--- a/src/components/PhotoList.tsx
+++ b/src/components/PhotoList.tsx
@@ -19,7 +19,6 @@ import { DeduplicateContext } from 'pages/deduplicate';
import { FlexWrapper } from './Container';
import { Typography } from '@mui/material';
import { GalleryContext } from 'pages/gallery';
-import { SpecialPadding } from 'styles/SpecialPadding';
import { formatDate } from 'utils/time/format';
import { Trans } from 'react-i18next';
import { t } from 'i18next';
@@ -111,7 +110,10 @@ const ListContainer = styled(Box)<{
grid-column-gap: ${GAP_BTW_TILES}px;
width: 100%;
color: #fff;
- ${SpecialPadding}
+ padding: 0 24px;
+ @media (max-width: ${IMAGE_CONTAINER_MAX_WIDTH * MIN_COLUMNS}px) {
+ padding: 0 4px;
+ }
`;
const ListItemContainer = styled(FlexWrapper)<{ span: number }>`
diff --git a/src/components/PhotoViewer/FileInfo/RenderInfoItem.tsx b/src/components/PhotoViewer/FileInfo/RenderInfoItem.tsx
deleted file mode 100644
index a538df52f..000000000
--- a/src/components/PhotoViewer/FileInfo/RenderInfoItem.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import React from 'react';
-import { Label, Row, Value } from 'components/Container';
-
-export const RenderInfoItem = (label: string, value: string | JSX.Element) => (
-
- {label}
- {value}
-
-);
diff --git a/src/components/Search/SearchBar/styledComponents.tsx b/src/components/Search/SearchBar/styledComponents.tsx
index 07f183ffb..5723671d4 100644
--- a/src/components/Search/SearchBar/styledComponents.tsx
+++ b/src/components/Search/SearchBar/styledComponents.tsx
@@ -4,10 +4,13 @@ import {
FluidContainer,
} from 'components/Container';
import { css, styled } from '@mui/material';
-import { SpecialPadding } from 'styles/SpecialPadding';
+import { IMAGE_CONTAINER_MAX_WIDTH, MIN_COLUMNS } from 'constants/gallery';
export const SearchBarWrapper = styled(FlexWrapper)`
- ${SpecialPadding}
+ padding: 0 24px;
+ @media (max-width: ${IMAGE_CONTAINER_MAX_WIDTH * MIN_COLUMNS}px) {
+ padding: 0 4px;
+ }
`;
export const SearchMobileBox = styled(FluidContainer)`
diff --git a/src/components/Sidebar/Preferences/LanguageSelector.tsx b/src/components/Sidebar/Preferences/LanguageSelector.tsx
index 74b39d367..5f67d649b 100644
--- a/src/components/Sidebar/Preferences/LanguageSelector.tsx
+++ b/src/components/Sidebar/Preferences/LanguageSelector.tsx
@@ -1,9 +1,8 @@
-import { OptionWithDivider } from 'components/Collections/CollectionShare/publicShare/manage/selectComponents/OptionWithDivider';
+import DropdownInput, { DropdownOption } from 'components/DropdownInput';
import { Language } from 'constants/locale';
import { useLocalState } from 'hooks/useLocalState';
+import { t } from 'i18next';
import { useRouter } from 'next/router';
-import Select from 'react-select';
-import { DropdownStyle } from 'styles/dropdown';
import { getBestPossibleUserLocale } from 'utils/i18n';
import { LS_KEYS } from 'utils/storage/localStorage';
@@ -16,7 +15,7 @@ const getLocaleDisplayName = (l: Language) => {
}
};
-const getLanguageOptions = () => {
+const getLanguageOptions = (): DropdownOption[] => {
return Object.values(Language).map((lang) => ({
label: getLocaleDisplayName(lang),
value: lang,
@@ -37,19 +36,12 @@ export const LanguageSelector = () => {
};
return (
- updateCurrentLocale(e.value)}
- styles={DropdownStyle}
+ label={t('LANGUAGE')}
+ labelProps={{ color: 'text.secondary' }}
+ selectedValue={userLocale}
+ setSelectedValue={updateCurrentLocale}
/>
);
};
diff --git a/src/components/Sidebar/Preferences/index.tsx b/src/components/Sidebar/Preferences/index.tsx
index e3a10a1da..c87b6ab55 100644
--- a/src/components/Sidebar/Preferences/index.tsx
+++ b/src/components/Sidebar/Preferences/index.tsx
@@ -1,7 +1,6 @@
import ChevronRight from '@mui/icons-material/ChevronRight';
import { Box, DialogProps, Stack } from '@mui/material';
import { EnteDrawer } from 'components/EnteDrawer';
-import MenuSectionTitle from 'components/Menu/MenuSectionTitle';
import Titlebar from 'components/Titlebar';
import isElectron from 'is-electron';
import { useState } from 'react';
@@ -46,10 +45,7 @@ export default function Preferences({ open, onClose, onRootClose }) {
/>
-
-
-
-
+
{isElectron() && (
(
key: LS_KEYS,
initialValue?: T
): [T, Dispatch>] {
- const [value, setValue] = useState();
+ const [value, setValue] = useState(initialValue);
useEffect(() => {
const { value } = getData(key) ?? {};
- setValue(value ?? initialValue);
+ if (value) {
+ setValue(value);
+ }
}, []);
useEffect(() => {
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index a9d68dcdc..22cd04ef1 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -25,9 +25,11 @@ import { styled, ThemeProvider } from '@mui/material/styles';
import darkThemeOptions from 'themes/darkThemeOptions';
import lightThemeOptions from 'themes/lightThemeOptions';
import { CssBaseline, useMediaQuery } from '@mui/material';
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import * as types from 'styled-components/cssprop'; // need to css prop on styled component
-import { SetDialogBoxAttributes, DialogBoxAttributes } from 'types/dialogBox';
+import {
+ SetDialogBoxAttributes,
+ DialogBoxAttributes,
+ DialogBoxAttributesV2,
+} from 'types/dialogBox';
import {
getFamilyPortalRedirectURL,
getRoadmapRedirectURL,
@@ -56,6 +58,10 @@ import { SetTheme } from 'types/theme';
import { useLocalState } from 'hooks/useLocalState';
import { THEME_COLOR } from 'constants/theme';
import { setupI18n } from 'i18n';
+import createEmotionCache from 'themes/createEmotionCache';
+import { CacheProvider, EmotionCache } from '@emotion/react';
+import { AppProps } from 'next/app';
+import DialogBoxV2 from 'components/DialogBoxV2';
export const MessageContainer = styled('div')`
background-color: #111;
@@ -94,6 +100,7 @@ type AppContextType = {
theme: THEME_COLOR;
setTheme: SetTheme;
somethingWentWrong: () => void;
+ setDialogBoxAttributesV2: (attributes: DialogBoxAttributesV2) => void;
};
export enum FLASH_MESSAGE_TYPE {
@@ -115,7 +122,19 @@ const redirectMap = new Map([
const APP_TITLE = 'ente Photos';
-export default function App({ Component, err }) {
+// Client-side cache, shared for the whole session of the user in the browser.
+const clientSideEmotionCache = createEmotionCache();
+
+export interface EnteAppProps extends AppProps {
+ emotionCache?: EmotionCache;
+}
+
+export default function App(props) {
+ const {
+ Component,
+ emotionCache = clientSideEmotionCache,
+ pageProps,
+ } = props;
const router = useRouter();
const [isI18nReady, setIsI18nReady] = useState(false);
const [loading, setLoading] = useState(false);
@@ -131,7 +150,11 @@ export default function App({ Component, err }) {
const isLoadingBarRunning = useRef(false);
const loadingBar = useRef(null);
const [dialogMessage, setDialogMessage] = useState();
+ const [dialogBoxAttributeV2, setDialogBoxAttributesV2] =
+ useState();
+ useState(null);
const [messageDialogView, setMessageDialogView] = useState(false);
+ const [dialogBoxV2View, setDialogBoxV2View] = useState(false);
const [isFolderSyncRunning, setIsFolderSyncRunning] = useState(false);
const [watchFolderView, setWatchFolderView] = useState(false);
const [watchFolderFiles, setWatchFolderFiles] = useState(null);
@@ -281,6 +304,10 @@ export default function App({ Component, err }) {
setMessageDialogView(true);
}, [dialogMessage]);
+ useEffect(() => {
+ setDialogBoxV2View(true);
+ }, [dialogBoxV2View]);
+
useEffect(() => {
setNotificationView(true);
}, [notificationAttributes]);
@@ -314,6 +341,7 @@ export default function App({ Component, err }) {
};
const closeMessageDialog = () => setMessageDialogView(false);
+ const closeDialogBoxV2 = () => setDialogBoxV2View(false);
const somethingWentWrong = () =>
setDialogMessage({
@@ -323,7 +351,7 @@ export default function App({ Component, err }) {
});
return (
- <>
+
{isI18nReady ? t('TITLE') : APP_TITLE}
+
{loading || !isI18nReady ? (
@@ -411,10 +446,10 @@ export default function App({ Component, err }) {
) : (
-
+
)}
- >
+
);
}
diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx
index 21fc9bdd8..83925b400 100644
--- a/src/pages/_document.tsx
+++ b/src/pages/_document.tsx
@@ -1,66 +1,110 @@
import React from 'react';
-import Document, { Html, Head, Main, NextScript } from 'next/document';
-import { ServerStyleSheet } from 'styled-components';
+import Document, {
+ Html,
+ Head,
+ Main,
+ NextScript,
+ DocumentProps,
+ DocumentContext,
+} from 'next/document';
-export default class MyDocument extends Document {
- static async getInitialProps(ctx) {
- const sheet = new ServerStyleSheet();
- const originalRenderPage = ctx.renderPage;
+import createEmotionServer from '@emotion/server/create-instance';
+import { AppType } from 'next/app';
+import createEmotionCache from 'themes/createEmotionCache';
+import { EnteAppProps } from './_app';
- try {
- ctx.renderPage = () =>
- originalRenderPage({
- enhanceApp: (App) => (props) =>
- sheet.collectStyles( ),
- });
-
- const initialProps = await Document.getInitialProps(ctx);
- return {
- ...initialProps,
- styles: (
- <>
- {initialProps.styles}
- {sheet.getStyleElement()}
- >
- ),
- };
- } finally {
- sheet.seal();
- }
- }
-
- render() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
+interface EnteDocumentProps extends DocumentProps {
+ emotionStyleTags: JSX.Element[];
}
+
+export default function EnteDocument({ emotionStyleTags }: EnteDocumentProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+ {emotionStyleTags}
+
+
+
+
+
+
+ );
+}
+
+// `getInitialProps` belongs to `_document` (instead of `_app`),
+// it's compatible with static-site generation (SSG).
+EnteDocument.getInitialProps = async (ctx: DocumentContext) => {
+ // Resolution order
+ //
+ // On the server:
+ // 1. app.getInitialProps
+ // 2. page.getInitialProps
+ // 3. document.getInitialProps
+ // 4. app.render
+ // 5. page.render
+ // 6. document.render
+ //
+ // On the server with error:
+ // 1. document.getInitialProps
+ // 2. app.render
+ // 3. page.render
+ // 4. document.render
+ //
+ // On the client
+ // 1. app.getInitialProps
+ // 2. page.getInitialProps
+ // 3. app.render
+ // 4. page.render
+
+ const originalRenderPage = ctx.renderPage;
+
+ // You can consider sharing the same Emotion cache between all the SSR requests to speed up performance.
+ // However, be aware that it can have global side effects.
+ const cache = createEmotionCache();
+ // eslint-disable-next-line @typescript-eslint/unbound-method
+ const { extractCriticalToChunks } = createEmotionServer(cache);
+
+ ctx.renderPage = () =>
+ originalRenderPage({
+ enhanceApp: (
+ App: React.ComponentType<
+ React.ComponentProps & EnteAppProps
+ >
+ ) =>
+ function EnhanceApp(props) {
+ return ;
+ },
+ });
+
+ const initialProps = await Document.getInitialProps(ctx);
+ // This is important. It prevents Emotion to render invalid HTML.
+ // See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153
+ const emotionStyles = extractCriticalToChunks(initialProps.html);
+ const emotionStyleTags = emotionStyles.styles.map((style) => (
+
+ ));
+
+ return {
+ ...initialProps,
+ emotionStyleTags,
+ };
+};
diff --git a/src/services/exportService.ts b/src/services/exportService.ts
index b4537c5dc..36f7a6ea2 100644
--- a/src/services/exportService.ts
+++ b/src/services/exportService.ts
@@ -1,8 +1,6 @@
import { runningInBrowser } from 'utils/common';
import {
- getExportQueuedFiles,
- getExportFailedFiles,
- getFilesUploadedAfterLastExport,
+ getUnExportedFiles,
dedupe,
getGoogleLikeMetadataFile,
getExportRecordFileUID,
@@ -15,7 +13,6 @@ import {
getOldFileMetadataSavePath,
getExportedFiles,
getMetadataFolderPath,
- getCollectionsCreatedAfterLastExport,
getCollectionsRenamedAfterLastExport,
getCollectionIDPathMapFromExportRecord,
} from 'utils/export';
@@ -34,6 +31,7 @@ import { decodeMotionPhoto } from './motionPhotoService';
import {
generateStreamFromArrayBuffer,
getFileExtension,
+ getPersonalFiles,
mergeMetadata,
} from 'utils/file';
@@ -41,62 +39,147 @@ import { updateFileCreationDateInEXIF } from './upload/exifService';
import QueueProcessor from './queueProcessor';
import { Collection } from 'types/collection';
import {
- ExportProgress,
+ CollectionIDNameMap,
CollectionIDPathMap,
+ ExportProgress,
ExportRecord,
+ ExportRecordV1,
+ FileExportStats,
} from 'types/export';
import { User } from 'types/user';
import { FILE_TYPE, TYPE_JPEG, TYPE_JPG } from 'constants/file';
-import { ExportType, ExportNotification, RecordType } from 'constants/export';
+import { RecordType } from 'constants/export';
import { ElectronAPIs } from 'types/electron';
import { CustomError } from 'utils/error';
import { addLogLine } from 'utils/logging';
+import { t } from 'i18next';
+import { eventBus, Events } from './events';
+import { getCollectionNameMap } from 'utils/collection';
-const LATEST_EXPORT_VERSION = 1;
const EXPORT_RECORD_FILE_NAME = 'export_status.json';
-class ExportService {
- electronAPIs: ElectronAPIs;
+export const ENTE_EXPORT_DIRECTORY = 'ente Photos';
- private exportInProgress: Promise<{ paused: boolean }> = null;
+class ExportService {
+ private electronAPIs: ElectronAPIs;
+ private exportInProgress: Promise = null;
private exportRecordUpdater = new QueueProcessor(1);
private stopExport: boolean = false;
- private pauseExport: boolean = false;
private allElectronAPIsExist: boolean = false;
private fileReader: FileReader = null;
+ private continuousExportEventHandler: () => void;
constructor() {
this.electronAPIs = runningInBrowser() && window['ElectronAPIs'];
this.allElectronAPIsExist = !!this.electronAPIs?.exists;
}
- async selectExportDirectory() {
+
+ async changeExportDirectory(callback: (newExportDir: string) => void) {
try {
- return await this.electronAPIs.selectRootDirectory();
+ const newRootDir = await this.electronAPIs.selectRootDirectory();
+ if (!newRootDir) {
+ return;
+ }
+ const newExportDir = `${newRootDir}/${ENTE_EXPORT_DIRECTORY}`;
+ await this.electronAPIs.checkExistsAndCreateDir(newExportDir);
+ callback(newExportDir);
} catch (e) {
- logError(e, 'failed to selectExportDirectory ');
+ logError(e, 'changeExportDirectory failed');
+ }
+ }
+
+ async openExportDirectory(exportFolder: string) {
+ try {
+ await this.electronAPIs.openDirectory(exportFolder);
+ } catch (e) {
+ logError(e, 'openExportDirectory failed');
+ }
+ }
+
+ enableContinuousExport(startExport: () => Promise) {
+ try {
+ if (this.continuousExportEventHandler) {
+ addLogLine('continuous export already enabled');
+ return;
+ }
+ const reRunNeeded = { current: false };
+ this.continuousExportEventHandler = async () => {
+ try {
+ addLogLine('continuous export triggered');
+ if (this.exportInProgress) {
+ addLogLine('export in progress, scheduling re-run');
+ reRunNeeded.current = true;
+ return;
+ }
+ await startExport();
+ if (reRunNeeded.current) {
+ reRunNeeded.current = false;
+ addLogLine('re-running export');
+ setTimeout(this.continuousExportEventHandler, 0);
+ }
+ } catch (e) {
+ logError(e, 'continuous export failed');
+ }
+ };
+ this.continuousExportEventHandler();
+ eventBus.addListener(
+ Events.LOCAL_FILES_UPDATED,
+ this.continuousExportEventHandler
+ );
+ } catch (e) {
+ logError(e, 'failed to enableContinuousExport ');
throw e;
}
}
+ disableContinuousExport() {
+ try {
+ if (!this.continuousExportEventHandler) {
+ addLogLine('continuous export already disabled');
+ return;
+ }
+ eventBus.removeListener(
+ Events.LOCAL_FILES_UPDATED,
+ this.continuousExportEventHandler
+ );
+ this.continuousExportEventHandler = null;
+ } catch (e) {
+ logError(e, 'failed to disableContinuousExport');
+ throw e;
+ }
+ }
+
+ getFileExportStats = async (): Promise => {
+ try {
+ const exportRecord = await this.getExportRecord();
+ const userPersonalFiles = await getPersonalFiles();
+ const unExportedFiles = getUnExportedFiles(
+ userPersonalFiles,
+ exportRecord
+ );
+ return {
+ totalCount: userPersonalFiles.length,
+ pendingCount: unExportedFiles.length,
+ };
+ } catch (e) {
+ logError(e, 'getUpdateFileLists failed');
+ throw e;
+ }
+ };
+
stopRunningExport() {
this.stopExport = true;
}
- pauseRunningExport() {
- this.pauseExport = true;
- }
- async exportFiles(
- updateProgress: (progress: ExportProgress) => Promise,
- exportType: ExportType
- ) {
+
+ async exportFiles(updateProgress: (progress: ExportProgress) => void) {
try {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
if (this.exportInProgress) {
this.electronAPIs.sendNotification(
- ExportNotification.IN_PROGRESS
+ t('EXPORT_NOTIFICATION.IN_PROGRESS')
);
return await this.exportInProgress;
}
- this.electronAPIs.showOnTray('starting export');
const exportDir = getData(LS_KEYS.EXPORT)?.folder;
if (!exportDir) {
// no-export folder set
@@ -104,7 +187,6 @@ class ExportService {
}
const user: User = getData(LS_KEYS.USER);
- let filesToExport: EnteFile[];
const localFiles = await getLocalFiles();
const userPersonalFiles = localFiles
.filter((file) => file.ownerID === user?.id)
@@ -130,48 +212,25 @@ class ExportService {
}
const exportRecord = await this.getExportRecord(exportDir);
- addLogLine(
- `export stats -> progress: ${JSON.stringify(
- exportRecord.progress
- )} stage:${exportRecord.stage} queuedFilesCount: ${
- exportRecord?.queuedFiles?.length
- } exportedFiles: ${exportRecord?.exportedFiles?.length}
- failedFiles: ${exportRecord?.failedFiles?.length}`
+ const filesToExport = getUnExportedFiles(
+ userPersonalFiles,
+ exportRecord
);
- if (exportType === ExportType.NEW) {
- filesToExport = getFilesUploadedAfterLastExport(
- userPersonalFiles,
- exportRecord
- );
- } else if (exportType === ExportType.RETRY_FAILED) {
- filesToExport = getExportFailedFiles(
- userPersonalFiles,
- exportRecord
- );
- } else {
- filesToExport = getExportQueuedFiles(
- userPersonalFiles,
- exportRecord
- );
- }
+
addLogLine(
- `starting export, type: ${exportType}, filesToExportCount: ${filesToExport?.length}, userPersonalFileCount: ${userPersonalFiles?.length}`
+ `starting export, filesToExportCount: ${filesToExport?.length}, userPersonalFileCount: ${userPersonalFiles?.length}`
);
const collectionIDPathMap: CollectionIDPathMap =
getCollectionIDPathMapFromExportRecord(exportRecord);
- const newCollections = getCollectionsCreatedAfterLastExport(
- userCollections,
- exportRecord
- );
-
+ const collectionIDNameMap = getCollectionNameMap(collections);
const renamedCollections = getCollectionsRenamedAfterLastExport(
userCollections,
exportRecord
);
this.exportInProgress = this.fileExporter(
filesToExport,
- newCollections,
+ collectionIDNameMap,
renamedCollections,
collectionIDPathMap,
updateProgress,
@@ -189,20 +248,13 @@ class ExportService {
async fileExporter(
files: EnteFile[],
- newCollections: Collection[],
+ collectionIDNameMap: CollectionIDNameMap,
renamedCollections: Collection[],
collectionIDPathMap: CollectionIDPathMap,
- updateProgress: (progress: ExportProgress) => Promise,
+ updateProgress: (progress: ExportProgress) => void,
exportDir: string
- ): Promise<{ paused: boolean }> {
+ ): Promise {
try {
- if (newCollections?.length) {
- await this.createNewCollectionFolders(
- newCollections,
- exportDir,
- collectionIDPathMap
- );
- }
if (
renamedCollections?.length &&
this.checkAllElectronAPIsExists()
@@ -215,44 +267,37 @@ class ExportService {
}
if (!files?.length) {
this.electronAPIs.sendNotification(
- ExportNotification.UP_TO_DATE
+ t('EXPORT_NOTIFICATION.UP_TO_DATE')
);
- return { paused: false };
+ return;
}
this.stopExport = false;
- this.pauseExport = false;
- await this.addFilesQueuedRecord(exportDir, files);
- const failedFileCount = 0;
-
- this.electronAPIs.showOnTray({
- export_progress: `0 / ${files.length} files exported`,
- });
- await updateProgress({
- current: 0,
- total: files.length,
- });
- this.electronAPIs.sendNotification(ExportNotification.START);
-
- for (const [index, file] of files.entries()) {
- if (this.stopExport || this.pauseExport) {
- if (this.pauseExport) {
- this.electronAPIs.showOnTray({
- export_progress: `${index} / ${files.length} files exported (paused)`,
- paused: true,
- });
- }
+ this.electronAPIs.sendNotification(t('EXPORT_NOTIFICATION.START'));
+ let success = 0;
+ for (const file of files) {
+ if (this.stopExport) {
break;
}
- const collectionPath = collectionIDPathMap.get(
- file.collectionID
- );
try {
+ let collectionPath = collectionIDPathMap.get(
+ file.collectionID
+ );
+ if (!collectionPath || !this.exists(collectionPath)) {
+ collectionPath = await this.createNewCollectionFolder(
+ exportDir,
+ file.collectionID,
+ collectionIDNameMap,
+ collectionIDPathMap
+ );
+ }
await this.downloadAndSave(file, collectionPath);
await this.addFileExportedRecord(
exportDir,
file,
RecordType.SUCCESS
);
+ success++;
+ updateProgress({ current: success, total: files.length });
} catch (e) {
logError(e, 'export failed for a file');
if (
@@ -267,42 +312,17 @@ class ExportService {
RecordType.FAILED
);
}
- this.electronAPIs.showOnTray({
- export_progress: `${index + 1} / ${
- files.length
- } files exported`,
- });
- await updateProgress({
- current: index + 1,
- total: files.length,
- });
}
- if (this.stopExport) {
- this.electronAPIs.sendNotification(ExportNotification.ABORT);
- this.electronAPIs.showOnTray();
- } else if (this.pauseExport) {
- this.electronAPIs.sendNotification(ExportNotification.PAUSE);
- return { paused: true };
- } else if (failedFileCount > 0) {
- this.electronAPIs.sendNotification(ExportNotification.FAILED);
- this.electronAPIs.showOnTray({
- retry_export: `Retry failed exports`,
- });
- } else {
- this.electronAPIs.sendNotification(ExportNotification.FINISH);
- this.electronAPIs.showOnTray();
+ if (!this.stopExport) {
+ this.electronAPIs.sendNotification(
+ t('EXPORT_NOTIFICATION.FINISH')
+ );
}
- return { paused: false };
} catch (e) {
logError(e, 'fileExporter failed');
throw e;
}
}
- async addFilesQueuedRecord(folder: string, files: EnteFile[]) {
- const exportRecord = await this.getExportRecord(folder);
- exportRecord.queuedFiles = files.map(getExportRecordFileUID);
- await this.updateExportRecord(exportRecord, folder);
- }
async addFileExportedRecord(
folder: string,
@@ -312,29 +332,13 @@ class ExportService {
try {
const fileUID = getExportRecordFileUID(file);
const exportRecord = await this.getExportRecord(folder);
- exportRecord.queuedFiles = exportRecord.queuedFiles.filter(
- (queuedFilesUID) => queuedFilesUID !== fileUID
- );
if (type === RecordType.SUCCESS) {
if (!exportRecord.exportedFiles) {
exportRecord.exportedFiles = [];
}
exportRecord.exportedFiles.push(fileUID);
- exportRecord.failedFiles &&
- (exportRecord.failedFiles = exportRecord.failedFiles.filter(
- (FailedFileUID) => FailedFileUID !== fileUID
- ));
- } else {
- if (!exportRecord.failedFiles) {
- exportRecord.failedFiles = [];
- }
- if (!exportRecord.failedFiles.find((x) => x === fileUID)) {
- exportRecord.failedFiles.push(fileUID);
- }
}
exportRecord.exportedFiles = dedupe(exportRecord.exportedFiles);
- exportRecord.queuedFiles = dedupe(exportRecord.queuedFiles);
- exportRecord.failedFiles = dedupe(exportRecord.failedFiles);
await this.updateExportRecord(exportRecord, folder);
} catch (e) {
logError(e, 'addFileExportedRecord failed');
@@ -344,7 +348,7 @@ class ExportService {
async addCollectionExportedRecord(
folder: string,
- collection: Collection,
+ collectionID: number,
collectionFolderPath: string
) {
const exportRecord = await this.getExportRecord(folder);
@@ -353,20 +357,23 @@ class ExportService {
}
exportRecord.exportedCollectionPaths = {
...exportRecord.exportedCollectionPaths,
- [collection.id]: collectionFolderPath,
+ [collectionID]: collectionFolderPath,
};
await this.updateExportRecord(exportRecord, folder);
}
- async updateExportRecord(newData: ExportRecord, folder?: string) {
+ async updateExportRecord(newData: Partial, folder?: string) {
const response = this.exportRecordUpdater.queueUpRequest(() =>
this.updateExportRecordHelper(folder, newData)
);
await response.promise;
}
- async updateExportRecordHelper(folder: string, newData: ExportRecord) {
+ async updateExportRecordHelper(
+ folder: string,
+ newData: Partial
+ ) {
try {
if (!folder) {
folder = getData(LS_KEYS.EXPORT)?.folder;
@@ -389,49 +396,45 @@ class ExportService {
folder = getData(LS_KEYS.EXPORT)?.folder;
}
if (!folder) {
- throw Error(CustomError.NO_EXPORT_FOLDER_SELECTED);
+ return null;
}
const exportFolderExists = this.exists(folder);
if (!exportFolderExists) {
- throw Error(CustomError.EXPORT_FOLDER_DOES_NOT_EXIST);
+ return null;
}
const recordFile = await this.electronAPIs.getExportRecord(
`${folder}/${EXPORT_RECORD_FILE_NAME}`
);
- if (recordFile) {
- return JSON.parse(recordFile);
- } else {
- return {} as ExportRecord;
- }
+ return JSON.parse(recordFile);
} catch (e) {
logError(e, 'export Record JSON parsing failed ');
throw e;
}
}
- async createNewCollectionFolders(
- newCollections: Collection[],
+ async createNewCollectionFolder(
exportFolder: string,
+ collectionID: number,
+ collectionIDNameMap: CollectionIDNameMap,
collectionIDPathMap: CollectionIDPathMap
) {
- for (const collection of newCollections) {
- const collectionFolderPath = getUniqueCollectionFolderPath(
- exportFolder,
- collection
- );
- await this.electronAPIs.checkExistsAndCreateCollectionDir(
- collectionFolderPath
- );
- await this.electronAPIs.checkExistsAndCreateCollectionDir(
- getMetadataFolderPath(collectionFolderPath)
- );
- await this.addCollectionExportedRecord(
- exportFolder,
- collection,
- collectionFolderPath
- );
- collectionIDPathMap.set(collection.id, collectionFolderPath);
- }
+ const collectionName = collectionIDNameMap.get(collectionID);
+ const collectionFolderPath = getUniqueCollectionFolderPath(
+ exportFolder,
+ collectionID,
+ collectionName
+ );
+ await this.electronAPIs.checkExistsAndCreateDir(collectionFolderPath);
+ await this.electronAPIs.checkExistsAndCreateDir(
+ getMetadataFolderPath(collectionFolderPath)
+ );
+ await this.addCollectionExportedRecord(
+ exportFolder,
+ collectionID,
+ collectionFolderPath
+ );
+ collectionIDPathMap.set(collectionID, collectionFolderPath);
+ return collectionFolderPath;
}
async renameCollectionFolders(
renamedCollections: Collection[],
@@ -445,7 +448,8 @@ class ExportService {
const newCollectionFolderPath = getUniqueCollectionFolderPath(
exportFolder,
- collection
+ collection.id,
+ collection.name
);
await this.electronAPIs.checkExistsAndRename(
oldCollectionFolderPath,
@@ -454,7 +458,7 @@ class ExportService {
await this.addCollectionExportedRecord(
exportFolder,
- collection,
+ collection.id,
newCollectionFolderPath
);
collectionIDPathMap.set(collection.id, newCollectionFolderPath);
@@ -571,10 +575,10 @@ class ExportService {
private async migrateExport(
exportDir: string,
collections: Collection[],
- allFiles: EnteFile[]
+ files: EnteFile[]
) {
const exportRecord = await this.getExportRecord(exportDir);
- const currentVersion = exportRecord?.version ?? 0;
+ let currentVersion = exportRecord?.version ?? 0;
if (currentVersion === 0) {
const collectionIDPathMap = new Map();
@@ -584,12 +588,19 @@ class ExportService {
collectionIDPathMap
);
await this.migrateFiles(
- getExportedFiles(allFiles, exportRecord),
+ getExportedFiles(files, exportRecord),
collectionIDPathMap
);
-
+ currentVersion++;
await this.updateExportRecord({
- version: LATEST_EXPORT_VERSION,
+ version: currentVersion,
+ });
+ }
+ if (currentVersion === 1) {
+ await this.removeDeprecatedExportRecordProperties();
+ currentVersion++;
+ await this.updateExportRecord({
+ version: currentVersion,
});
}
}
@@ -606,11 +617,13 @@ class ExportService {
for (const collection of collections) {
const oldCollectionFolderPath = getOldCollectionFolderPath(
exportDir,
- collection
+ collection.id,
+ collection.name
);
const newCollectionFolderPath = getUniqueCollectionFolderPath(
exportDir,
- collection
+ collection.id,
+ collection.name
);
collectionIDPathMap.set(collection.id, newCollectionFolderPath);
if (this.electronAPIs.exists(oldCollectionFolderPath)) {
@@ -620,7 +633,7 @@ class ExportService {
);
await this.addCollectionExportedRecord(
exportDir,
- collection,
+ collection.id,
newCollectionFolderPath
);
}
@@ -670,5 +683,19 @@ class ExportService {
);
}
}
+
+ private async removeDeprecatedExportRecordProperties() {
+ const exportRecord = (await this.getExportRecord()) as ExportRecordV1;
+ if (exportRecord?.queuedFiles) {
+ exportRecord.queuedFiles = undefined;
+ }
+ if (exportRecord?.progress) {
+ exportRecord.progress = undefined;
+ }
+ if (exportRecord?.failedFiles) {
+ exportRecord.failedFiles = undefined;
+ }
+ await this.updateExportRecord(exportRecord);
+ }
}
export default new ExportService();
diff --git a/src/styles/SpecialPadding.ts b/src/styles/SpecialPadding.ts
deleted file mode 100644
index e508d73dc..000000000
--- a/src/styles/SpecialPadding.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { IMAGE_CONTAINER_MAX_WIDTH, MIN_COLUMNS } from 'constants/gallery';
-import { css } from 'styled-components';
-
-export const SpecialPadding = css`
- padding: 0 24px;
- @media (max-width: ${IMAGE_CONTAINER_MAX_WIDTH * MIN_COLUMNS}px) {
- padding: 0 4px;
- }
-`;
diff --git a/src/themes/createEmotionCache.ts b/src/themes/createEmotionCache.ts
new file mode 100644
index 000000000..1bd96f850
--- /dev/null
+++ b/src/themes/createEmotionCache.ts
@@ -0,0 +1,19 @@
+import createCache from '@emotion/cache';
+
+const isBrowser = typeof document !== 'undefined';
+
+// On the client side, Create a meta tag at the top of the and set it as insertionPoint.
+// This assures that MUI styles are loaded first.
+// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
+export default function createEmotionCache() {
+ let insertionPoint;
+
+ if (isBrowser) {
+ const emotionInsertionPoint = document.querySelector(
+ 'meta[name="emotion-insertion-point"]'
+ );
+ insertionPoint = emotionInsertionPoint ?? undefined;
+ }
+
+ return createCache({ key: 'mui-style', insertionPoint });
+}
diff --git a/src/themes/darkThemeOptions.tsx b/src/themes/darkThemeOptions.tsx
index 7d52c4d92..133795e88 100644
--- a/src/themes/darkThemeOptions.tsx
+++ b/src/themes/darkThemeOptions.tsx
@@ -180,7 +180,7 @@ const darkThemeOptions = createTheme({
},
styleOverrides: {
root: {
- padding: '12px 16px',
+ padding: '14px 16px',
borderRadius: '4px',
},
startIcon: {
diff --git a/src/types/dialogBox/index.ts b/src/types/dialogBox/index.ts
index 0cbc20d30..ca737ba3b 100644
--- a/src/types/dialogBox/index.ts
+++ b/src/types/dialogBox/index.ts
@@ -14,7 +14,7 @@ export interface DialogBoxAttributes {
proceed?: {
text: string;
action: () => void;
- variant: ButtonProps['color'];
+ variant?: ButtonProps['color'];
disabled?: boolean;
};
secondary?: {
@@ -28,3 +28,39 @@ export interface DialogBoxAttributes {
export type SetDialogBoxAttributes = React.Dispatch<
React.SetStateAction
>;
+
+export interface DialogBoxAttributesV2 {
+ icon?: React.ReactNode;
+ title?: string;
+ staticBackdrop?: boolean;
+ nonClosable?: boolean;
+ content?: any;
+ close?: {
+ text?: string;
+ variant?: ButtonProps['color'];
+ action?: () => void;
+ };
+ proceed?: {
+ text: string;
+ action: () => void;
+ variant?: ButtonProps['color'];
+ disabled?: boolean;
+ };
+ secondary?: {
+ text: string;
+ action: () => void;
+ variant?: ButtonProps['color'];
+ disabled?: boolean;
+ };
+ buttons?: {
+ text: string;
+ action: () => void;
+ variant: ButtonProps['color'];
+ disabled?: boolean;
+ }[];
+ buttonDirection?: 'row' | 'column';
+}
+
+export type SetDialogBoxAttributesV2 = React.Dispatch<
+ React.SetStateAction
+>;
diff --git a/src/types/electron/index.ts b/src/types/electron/index.ts
index 4a50a48db..dc7d41511 100644
--- a/src/types/electron/index.ts
+++ b/src/types/electron/index.ts
@@ -9,7 +9,7 @@ export interface AppUpdateInfo {
export interface ElectronAPIs {
exists: (path: string) => boolean;
- checkExistsAndCreateCollectionDir: (dirPath: string) => Promise;
+ checkExistsAndCreateDir: (dirPath: string) => Promise;
checkExistsAndRename: (
oldDirPath: string,
newDirPath: string
@@ -21,11 +21,6 @@ export interface ElectronAPIs {
saveFileToDisk: (path: string, file: any) => Promise;
selectRootDirectory: () => Promise;
sendNotification: (content: string) => void;
- showOnTray: (content?: any) => void;
- registerResumeExportListener: (resumeExport: () => void) => void;
- registerStopExportListener: (abortExport: () => void) => void;
- registerPauseExportListener: (pauseExport: () => void) => void;
- registerRetryFailedExportListener: (retryFailedExport: () => void) => void;
getExportRecord: (filePath: string) => Promise;
setExportRecord: (filePath: string, data: string) => Promise;
showUploadFilesDialog: () => Promise;
@@ -94,4 +89,5 @@ export interface ElectronAPIs {
) => Promise;
logRendererProcessMemoryUsage: (message: string) => Promise;
registerForegroundEventListener: (onForeground: () => void) => void;
+ openDirectory: (dirPath: string) => Promise;
}
diff --git a/src/types/export/index.ts b/src/types/export/index.ts
index baf210f4c..b607e0c77 100644
--- a/src/types/export/index.ts
+++ b/src/types/export/index.ts
@@ -1,5 +1,6 @@
import { ExportStage } from 'constants/export';
+export type CollectionIDNameMap = Map;
export type CollectionIDPathMap = Map;
export interface ExportProgress {
current: number;
@@ -8,12 +9,12 @@ export interface ExportProgress {
export interface ExportedCollectionPaths {
[collectionID: number]: string;
}
-export interface ExportStats {
- failed: number;
- success: number;
+export interface FileExportStats {
+ totalCount: number;
+ pendingCount: number;
}
-export interface ExportRecord {
+export interface ExportRecordV1 {
version?: number;
stage?: ExportStage;
lastAttemptTimestamp?: number;
@@ -23,3 +24,16 @@ export interface ExportRecord {
failedFiles?: string[];
exportedCollectionPaths?: ExportedCollectionPaths;
}
+
+export interface ExportRecord {
+ version: number;
+ stage: ExportStage;
+ lastAttemptTimestamp: number;
+ exportedFiles: string[];
+ exportedCollectionPaths: ExportedCollectionPaths;
+}
+
+export interface ExportSettings {
+ folder: string;
+ continuousExport: boolean;
+}
diff --git a/src/utils/collection/index.ts b/src/utils/collection/index.ts
index 205773e06..79fd9af98 100644
--- a/src/utils/collection/index.ts
+++ b/src/utils/collection/index.ts
@@ -264,3 +264,11 @@ export function isValidMoveTarget(
!isIncomingShare(targetCollection, user)
);
}
+
+export function getCollectionNameMap(
+ collections: Collection[]
+): Map {
+ return new Map(
+ collections.map((collection) => [collection.id, collection.name])
+ );
+}
diff --git a/src/utils/error/ui.ts b/src/utils/error/ui.ts
index 0142f10e3..86ab4b4c8 100644
--- a/src/utils/error/ui.ts
+++ b/src/utils/error/ui.ts
@@ -16,7 +16,7 @@ export const handleSharingErrors = (error) => {
errorMessage = t('USER_DOES_NOT_EXIST');
break;
default:
- errorMessage = parsedError.message;
+ errorMessage = `${t('UNKNOWN_ERROR')} ${parsedError.message}`;
}
return errorMessage;
};
diff --git a/src/utils/export/index.ts b/src/utils/export/index.ts
index 5f272a8fb..14021e281 100644
--- a/src/utils/export/index.ts
+++ b/src/utils/export/index.ts
@@ -13,20 +13,6 @@ import { formatDateTimeShort } from 'utils/time/format';
export const getExportRecordFileUID = (file: EnteFile) =>
`${file.id}_${file.collectionID}_${file.updationTime}`;
-export const getExportQueuedFiles = (
- allFiles: EnteFile[],
- exportRecord: ExportRecord
-) => {
- const queuedFiles = new Set(exportRecord?.queuedFiles);
- const unExportedFiles = allFiles.filter((file) => {
- if (queuedFiles.has(getExportRecordFileUID(file))) {
- return true;
- }
- return false;
- });
- return unExportedFiles;
-};
-
export const getCollectionsCreatedAfterLastExport = (
collections: Collection[],
exportRecord: ExportRecord
@@ -79,7 +65,7 @@ export const getCollectionsRenamedAfterLastExport = (
return renamedCollections;
};
-export const getFilesUploadedAfterLastExport = (
+export const getUnExportedFiles = (
allFiles: EnteFile[],
exportRecord: ExportRecord
) => {
@@ -107,20 +93,6 @@ export const getExportedFiles = (
return exportedFiles;
};
-export const getExportFailedFiles = (
- allFiles: EnteFile[],
- exportRecord: ExportRecord
-) => {
- const failedFiles = new Set(exportRecord?.failedFiles);
- const filesToExport = allFiles.filter((file) => {
- if (failedFiles.has(getExportRecordFileUID(file))) {
- return true;
- }
- return false;
- });
- return filesToExport;
-};
-
export const dedupe = (files: string[]) => {
const fileSet = new Set(files);
return Array.from(fileSet);
@@ -166,16 +138,17 @@ export const sanitizeName = (name: string) =>
export const getUniqueCollectionFolderPath = (
dir: string,
- collection: Collection
+ collectionID: number,
+ collectionName: string
): string => {
if (!exportService.checkAllElectronAPIsExists()) {
- return getOldCollectionFolderPath(dir, collection);
+ return getOldCollectionFolderPath(dir, collectionID, collectionName);
}
- let collectionFolderPath = `${dir}/${sanitizeName(collection.name)}`;
+ let collectionFolderPath = `${dir}/${sanitizeName(collectionName)}`;
let count = 1;
while (exportService.exists(collectionFolderPath)) {
collectionFolderPath = `${dir}/${sanitizeName(
- collection.name
+ collectionName
)}(${count})`;
count++;
}
@@ -224,8 +197,9 @@ export const getFileSavePath = (
export const getOldCollectionFolderPath = (
dir: string,
- collection: Collection
-) => `${dir}/${collection.id}_${oldSanitizeName(collection.name)}`;
+ collectionID: number,
+ collectionName: string
+) => `${dir}/${collectionID}_${oldSanitizeName(collectionName)}`;
export const getOldFileSavePath = (
collectionFolderPath: string,
diff --git a/src/utils/file/index.ts b/src/utils/file/index.ts
index fd4aaf2e9..6789b399c 100644
--- a/src/utils/file/index.ts
+++ b/src/utils/file/index.ts
@@ -31,6 +31,7 @@ import { addLogLine } from 'utils/logging';
import { CustomError } from 'utils/error';
import { convertBytesToHumanReadable } from './size';
import ComlinkCryptoWorker from 'utils/comlink/ComlinkCryptoWorker';
+import { getLocalFiles } from 'services/fileService';
const WAIT_TIME_IMAGE_CONVERSION = 30 * 1000;
@@ -578,3 +579,12 @@ export function getLatestVersionFiles(files: EnteFile[]) {
(file) => !file.isDeleted
);
}
+
+export async function getPersonalFiles() {
+ const files = await getLocalFiles();
+ const user: User = getData(LS_KEYS.USER);
+ if (!user?.id) {
+ throw Error('user missing');
+ }
+ return files.filter((file) => file.ownerID === user.id);
+}
diff --git a/tsconfig.json b/tsconfig.json
index 203589ff1..770160529 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,8 +1,5 @@
{
"compilerOptions": {
- "paths": {
- "@mui/styled-engine": ["./node_modules/@mui/styled-engine-sc"]
- },
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext", "webworker"],
"allowJs": true,
@@ -23,8 +20,9 @@
"jsx": "preserve",
"baseUrl": "./src",
"downlevelIteration": true,
+ "jsxImportSource": "@emotion/react",
"incremental": true
},
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js"],
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules", "out", ".next", "thirdparty"]
}
diff --git a/yarn.lock b/yarn.lock
index 3150a4da1..11eeb62d6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,71 +2,86 @@
# yarn lockfile v1
-"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5":
+"@babel/code-frame@^7.0.0":
version "7.14.5"
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz"
integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==
dependencies:
"@babel/highlight" "^7.14.5"
-"@babel/generator@^7.15.4":
- version "7.15.4"
- resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz"
- integrity sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==
+"@babel/code-frame@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a"
+ integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==
dependencies:
- "@babel/types" "^7.15.4"
+ "@babel/highlight" "^7.18.6"
+
+"@babel/generator@^7.21.3":
+ version "7.21.3"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.3.tgz#232359d0874b392df04045d72ce2fd9bb5045fce"
+ integrity sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==
+ dependencies:
+ "@babel/types" "^7.21.3"
+ "@jridgewell/gen-mapping" "^0.3.2"
+ "@jridgewell/trace-mapping" "^0.3.17"
jsesc "^2.5.1"
- source-map "^0.5.0"
-"@babel/helper-annotate-as-pure@^7.0.0":
- version "7.15.4"
- resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz"
- integrity sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==
+"@babel/helper-annotate-as-pure@^7.16.0":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb"
+ integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==
dependencies:
- "@babel/types" "^7.15.4"
+ "@babel/types" "^7.18.6"
-"@babel/helper-function-name@^7.15.4":
- version "7.15.4"
- resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz"
- integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==
+"@babel/helper-environment-visitor@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
+ integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
+
+"@babel/helper-function-name@^7.21.0":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4"
+ integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==
dependencies:
- "@babel/helper-get-function-arity" "^7.15.4"
- "@babel/template" "^7.15.4"
- "@babel/types" "^7.15.4"
+ "@babel/template" "^7.20.7"
+ "@babel/types" "^7.21.0"
-"@babel/helper-get-function-arity@^7.15.4":
- version "7.15.4"
- resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz"
- integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==
+"@babel/helper-hoist-variables@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678"
+ integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==
dependencies:
- "@babel/types" "^7.15.4"
+ "@babel/types" "^7.18.6"
-"@babel/helper-hoist-variables@^7.15.4":
- version "7.15.4"
- resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz"
- integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==
+"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.16.0", "@babel/helper-module-imports@^7.16.7":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
+ integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
dependencies:
- "@babel/types" "^7.15.4"
+ "@babel/types" "^7.18.6"
-"@babel/helper-module-imports@^7.0.0":
- version "7.15.4"
- resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz"
- integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==
+"@babel/helper-split-export-declaration@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075"
+ integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==
dependencies:
- "@babel/types" "^7.15.4"
+ "@babel/types" "^7.18.6"
-"@babel/helper-split-export-declaration@^7.15.4":
- version "7.15.4"
- resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz"
- integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==
- dependencies:
- "@babel/types" "^7.15.4"
+"@babel/helper-string-parser@^7.19.4":
+ version "7.19.4"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63"
+ integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==
-"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9":
+"@babel/helper-validator-identifier@^7.14.5":
version "7.16.7"
resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz"
integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
+"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1":
+ version "7.19.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
+ integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
+
"@babel/highlight@^7.14.5":
version "7.14.5"
resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz"
@@ -76,18 +91,34 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@^7.15.4":
- version "7.15.6"
- resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.15.6.tgz"
- integrity sha512-S/TSCcsRuCkmpUuoWijua0Snt+f3ewU/8spLo+4AXJCZfT0bVCzLD5MuOKdrx0mlAptbKzn5AdgEIIKXxXkz9Q==
+"@babel/highlight@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf"
+ integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.18.6"
+ chalk "^2.0.0"
+ js-tokens "^4.0.0"
-"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.5", "@babel/runtime@^7.12.0", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.8", "@babel/runtime@^7.14.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.7":
+"@babel/parser@^7.20.7", "@babel/parser@^7.21.3":
+ version "7.21.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.3.tgz#1d285d67a19162ff9daa358d4cb41d50c06220b3"
+ integrity sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==
+
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.14.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.7":
version "7.15.4"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz"
integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.6", "@babel/runtime@^7.21.0":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
+ integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
+ dependencies:
+ regenerator-runtime "^0.13.11"
+
"@babel/runtime@^7.17.2":
version "7.17.9"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
@@ -95,13 +126,6 @@
dependencies:
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.20.6":
- version "7.21.0"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
- integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
- dependencies:
- regenerator-runtime "^0.13.11"
-
"@babel/runtime@^7.20.7":
version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd"
@@ -109,36 +133,38 @@
dependencies:
regenerator-runtime "^0.13.11"
-"@babel/template@^7.15.4":
- version "7.15.4"
- resolved "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz"
- integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==
+"@babel/template@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8"
+ integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==
dependencies:
- "@babel/code-frame" "^7.14.5"
- "@babel/parser" "^7.15.4"
- "@babel/types" "^7.15.4"
+ "@babel/code-frame" "^7.18.6"
+ "@babel/parser" "^7.20.7"
+ "@babel/types" "^7.20.7"
"@babel/traverse@^7.4.5":
- version "7.15.4"
- resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz"
- integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==
+ version "7.21.3"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.3.tgz#4747c5e7903d224be71f90788b06798331896f67"
+ integrity sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==
dependencies:
- "@babel/code-frame" "^7.14.5"
- "@babel/generator" "^7.15.4"
- "@babel/helper-function-name" "^7.15.4"
- "@babel/helper-hoist-variables" "^7.15.4"
- "@babel/helper-split-export-declaration" "^7.15.4"
- "@babel/parser" "^7.15.4"
- "@babel/types" "^7.15.4"
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.21.3"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-function-name" "^7.21.0"
+ "@babel/helper-hoist-variables" "^7.18.6"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/parser" "^7.21.3"
+ "@babel/types" "^7.21.3"
debug "^4.1.0"
globals "^11.1.0"
-"@babel/types@^7.15.4":
- version "7.15.6"
- resolved "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz"
- integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==
+"@babel/types@^7.18.6", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.3":
+ version "7.21.3"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.3.tgz#4865a5357ce40f64e3400b0f3b737dc6d4f64d05"
+ integrity sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==
dependencies:
- "@babel/helper-validator-identifier" "^7.14.9"
+ "@babel/helper-string-parser" "^7.19.4"
+ "@babel/helper-validator-identifier" "^7.19.1"
to-fast-properties "^2.0.0"
"@date-io/core@^2.14.0":
@@ -174,23 +200,52 @@
dependencies:
"@date-io/core" "^2.14.0"
-"@emotion/cache@^11.4.0":
- version "11.4.0"
- resolved "https://registry.npmjs.org/@emotion/cache/-/cache-11.4.0.tgz"
- integrity sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==
+"@emotion/babel-plugin@^11.10.6":
+ version "11.10.6"
+ resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz#a68ee4b019d661d6f37dec4b8903255766925ead"
+ integrity sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==
dependencies:
- "@emotion/memoize" "^0.7.4"
- "@emotion/sheet" "^1.0.0"
- "@emotion/utils" "^1.0.0"
- "@emotion/weak-memoize" "^0.2.5"
- stylis "^4.0.3"
+ "@babel/helper-module-imports" "^7.16.7"
+ "@babel/runtime" "^7.18.3"
+ "@emotion/hash" "^0.9.0"
+ "@emotion/memoize" "^0.8.0"
+ "@emotion/serialize" "^1.1.1"
+ babel-plugin-macros "^3.1.0"
+ convert-source-map "^1.5.0"
+ escape-string-regexp "^4.0.0"
+ find-root "^1.1.0"
+ source-map "^0.5.7"
+ stylis "4.1.3"
+
+"@emotion/cache@^11.10.5", "@emotion/cache@^11.4.0":
+ version "11.10.5"
+ resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.5.tgz#c142da9351f94e47527ed458f7bbbbe40bb13c12"
+ integrity sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==
+ dependencies:
+ "@emotion/memoize" "^0.8.0"
+ "@emotion/sheet" "^1.2.1"
+ "@emotion/utils" "^1.2.0"
+ "@emotion/weak-memoize" "^0.3.0"
+ stylis "4.1.3"
"@emotion/hash@^0.8.0":
version "0.8.0"
resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz"
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
-"@emotion/is-prop-valid@^1.1.0", "@emotion/is-prop-valid@^1.1.2":
+"@emotion/hash@^0.9.0":
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.0.tgz#c5153d50401ee3c027a57a177bc269b16d889cb7"
+ integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==
+
+"@emotion/is-prop-valid@^1.1.0", "@emotion/is-prop-valid@^1.2.0":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz#7f2d35c97891669f7e276eb71c83376a5dc44c83"
+ integrity sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==
+ dependencies:
+ "@emotion/memoize" "^0.8.0"
+
+"@emotion/is-prop-valid@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.1.2.tgz#34ad6e98e871aa6f7a20469b602911b8b11b3a95"
integrity sha512-3QnhqeL+WW88YjYbQL5gUIkthuMw7a0NGbZ7wfFVk2kg/CK5w8w5FFa0RzWjyY1+sujN0NWbtSHH6OJmWHtJpQ==
@@ -202,20 +257,26 @@
resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz"
integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
-"@emotion/react@^11.1.1":
- version "11.4.1"
- resolved "https://registry.npmjs.org/@emotion/react/-/react-11.4.1.tgz"
- integrity sha512-pRegcsuGYj4FCdZN6j5vqCALkNytdrKw3TZMekTzNXixRg4wkLsU5QEaBG5LC6l01Vppxlp7FE3aTHpIG5phLg==
+"@emotion/memoize@^0.8.0":
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f"
+ integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==
+
+"@emotion/react@^11.1.1", "@emotion/react@^11.10.6":
+ version "11.10.6"
+ resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.6.tgz#dbe5e650ab0f3b1d2e592e6ab1e006e75fd9ac11"
+ integrity sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==
dependencies:
- "@babel/runtime" "^7.13.10"
- "@emotion/cache" "^11.4.0"
- "@emotion/serialize" "^1.0.2"
- "@emotion/sheet" "^1.0.2"
- "@emotion/utils" "^1.0.0"
- "@emotion/weak-memoize" "^0.2.5"
+ "@babel/runtime" "^7.18.3"
+ "@emotion/babel-plugin" "^11.10.6"
+ "@emotion/cache" "^11.10.5"
+ "@emotion/serialize" "^1.1.1"
+ "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0"
+ "@emotion/utils" "^1.2.0"
+ "@emotion/weak-memoize" "^0.3.0"
hoist-non-react-statics "^3.3.1"
-"@emotion/serialize@^1.0.0", "@emotion/serialize@^1.0.2":
+"@emotion/serialize@^1.0.0":
version "1.0.2"
resolved "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz"
integrity sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==
@@ -226,14 +287,47 @@
"@emotion/utils" "^1.0.0"
csstype "^3.0.2"
-"@emotion/sheet@^1.0.0", "@emotion/sheet@^1.0.2":
- version "1.0.2"
- resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.0.2.tgz"
- integrity sha512-QQPB1B70JEVUHuNtzjHftMGv6eC3Y9wqavyarj4x4lg47RACkeSfNo5pxIOKizwS9AEFLohsqoaxGQj4p0vSIw==
+"@emotion/serialize@^1.1.1":
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.1.tgz#0595701b1902feded8a96d293b26be3f5c1a5cf0"
+ integrity sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==
+ dependencies:
+ "@emotion/hash" "^0.9.0"
+ "@emotion/memoize" "^0.8.0"
+ "@emotion/unitless" "^0.8.0"
+ "@emotion/utils" "^1.2.0"
+ csstype "^3.0.2"
+
+"@emotion/server@^11.10.0":
+ version "11.10.0"
+ resolved "https://registry.yarnpkg.com/@emotion/server/-/server-11.10.0.tgz#3edc075b672c75426f682d56aadc6404fb1f6648"
+ integrity sha512-MTvJ21JPo9aS02GdjFW4nhdwOi2tNNpMmAM/YED0pkxzjDNi5WbiTwXqaCnvLc2Lr8NFtjhT0az1vTJyLIHYcw==
+ dependencies:
+ "@emotion/utils" "^1.2.0"
+ html-tokenize "^2.0.0"
+ multipipe "^1.0.2"
+ through "^2.3.8"
+
+"@emotion/sheet@^1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.1.tgz#0767e0305230e894897cadb6c8df2c51e61a6c2c"
+ integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==
+
+"@emotion/styled@^11.10.6":
+ version "11.10.6"
+ resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.6.tgz#d886afdc51ef4d66c787ebde848f3cc8b117ebba"
+ integrity sha512-OXtBzOmDSJo5Q0AFemHCfl+bUueT8BIcPSxu0EGTpGk6DmI5dnhSzQANm1e1ze0YZL7TDyAyy6s/b/zmGOS3Og==
+ dependencies:
+ "@babel/runtime" "^7.18.3"
+ "@emotion/babel-plugin" "^11.10.6"
+ "@emotion/is-prop-valid" "^1.2.0"
+ "@emotion/serialize" "^1.1.1"
+ "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0"
+ "@emotion/utils" "^1.2.0"
"@emotion/stylis@^0.8.4":
version "0.8.5"
- resolved "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz"
+ resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04"
integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
"@emotion/unitless@^0.7.4", "@emotion/unitless@^0.7.5":
@@ -241,15 +335,30 @@
resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz"
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
+"@emotion/unitless@^0.8.0":
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db"
+ integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==
+
+"@emotion/use-insertion-effect-with-fallbacks@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz#ffadaec35dbb7885bd54de3fa267ab2f860294df"
+ integrity sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==
+
"@emotion/utils@^1.0.0":
version "1.0.0"
resolved "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz"
integrity sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA==
-"@emotion/weak-memoize@^0.2.5":
- version "0.2.5"
- resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz"
- integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
+"@emotion/utils@^1.2.0":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561"
+ integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==
+
+"@emotion/weak-memoize@^0.3.0":
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb"
+ integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==
"@eslint/eslintrc@^1.4.1":
version "1.4.1"
@@ -285,6 +394,38 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
+"@jridgewell/gen-mapping@^0.3.2":
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
+ integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
+ dependencies:
+ "@jridgewell/set-array" "^1.0.1"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@jridgewell/resolve-uri@3.1.0":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
+ integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
+
+"@jridgewell/set-array@^1.0.1":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
+ integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
+
+"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10":
+ version "1.4.14"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
+ integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
+
+"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9":
+ version "0.3.17"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985"
+ integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==
+ dependencies:
+ "@jridgewell/resolve-uri" "3.1.0"
+ "@jridgewell/sourcemap-codec" "1.4.14"
+
"@mui/base@5.0.0-alpha.77":
version "5.0.0-alpha.77"
resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-alpha.77.tgz#a88985597708c354520579e4f76e617b29f8f593"
@@ -333,13 +474,13 @@
"@mui/utils" "^5.6.1"
prop-types "^15.7.2"
-"@mui/styled-engine-sc@^5.6.1", "@mui/styled-engine@^5.6.1", "@mui/styled-engine@npm:@mui/styled-engine-sc@latest":
- name "@mui/styled-engine"
- version "5.6.1"
- resolved "https://registry.yarnpkg.com/@mui/styled-engine-sc/-/styled-engine-sc-5.6.1.tgz#d9505c005eeefa5c7d7ef9c03e63324db889ee09"
- integrity sha512-BMY5Pb8YgOxvvwg9s6mPeDgzha4244/KgRmHvTVPBmvqypbiLPApR6SNyYON+1/3kLHt3TpmxrlRY3jPiZF2QQ==
+"@mui/styled-engine@^5.6.1":
+ version "5.11.11"
+ resolved "https://registry.yarnpkg.com/@mui/styled-engine-sc/-/styled-engine-sc-5.11.11.tgz#030882bf991bd11e1a46efba7382ccbfdf7826d2"
+ integrity sha512-6+HsfcKHlhjQklDoEup7Itl+Xgn+BCsqEpIdIIhlxED4YlOZ38xghxIKrx78XFZznTorbhAspUgDDKIaB5vDMg==
dependencies:
- prop-types "^15.7.2"
+ "@babel/runtime" "^7.21.0"
+ prop-types "^15.8.1"
"@mui/system@^5.6.2":
version "5.6.2"
@@ -770,14 +911,6 @@
resolved "https://registry.npmjs.org/@types/debounce-promise/-/debounce-promise-3.1.4.tgz"
integrity sha512-9SEVY3nsz+uMN2DwDocftB5TAgZe7D0cOzxxRhpotWs6T4QFqRaTXpXbOSzbk31/7iYcfCkJJPwWGzTxyuGhCg==
-"@types/hoist-non-react-statics@*":
- version "3.3.1"
- resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz"
- integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
- dependencies:
- "@types/react" "*"
- hoist-non-react-statics "^3.3.0"
-
"@types/http-proxy@^1.17.5":
version "1.17.9"
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a"
@@ -965,15 +1098,6 @@
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91"
integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==
-"@types/styled-components@^5.1.25":
- version "5.1.25"
- resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.25.tgz#0177c4ab5fa7c6ed0565d36f597393dae3f380ad"
- integrity sha512-fgwl+0Pa8pdkwXRoVPP9JbqF0Ivo9llnmsm+7TCI330kbPIFd9qv1Lrhr37shf4tnxCOSu+/IgqM7uJXLWZZNQ==
- dependencies:
- "@types/hoist-non-react-statics" "*"
- "@types/react" "*"
- csstype "^3.0.2"
-
"@types/trusted-types@^2.0.2":
version "2.0.2"
resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz"
@@ -1305,20 +1429,30 @@ axobject-query@^3.1.1:
dependencies:
deep-equal "^2.0.5"
-"babel-plugin-styled-components@>= 1.12.0":
- version "1.13.2"
- resolved "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.2.tgz"
- integrity sha512-Vb1R3d4g+MUfPQPVDMCGjm3cDocJEUTR7Xq7QS95JWWeksN1wdFRYpD2kulDgI3Huuaf1CZd+NK4KQmqUFh5dA==
+babel-plugin-macros@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1"
+ integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==
dependencies:
- "@babel/helper-annotate-as-pure" "^7.0.0"
- "@babel/helper-module-imports" "^7.0.0"
+ "@babel/runtime" "^7.12.5"
+ cosmiconfig "^7.0.0"
+ resolve "^1.19.0"
+
+"babel-plugin-styled-components@>= 1.12.0":
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz#c81ef34b713f9da2b7d3f5550df0d1e19e798086"
+ integrity sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.16.0"
+ "@babel/helper-module-imports" "^7.16.0"
babel-plugin-syntax-jsx "^6.18.0"
lodash "^4.17.11"
+ picomatch "^2.3.0"
babel-plugin-syntax-jsx@^6.18.0:
version "6.18.0"
- resolved "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz"
- integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
+ integrity sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==
balanced-match@^1.0.0:
version "1.0.2"
@@ -1374,6 +1508,11 @@ bs58@^4.0.1:
dependencies:
base-x "^3.0.2"
+buffer-from@~0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-0.1.2.tgz#15f4b9bcef012044df31142c14333caf6e0260d0"
+ integrity sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==
+
call-bind@^1.0.0, call-bind@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz"
@@ -1388,9 +1527,9 @@ callsites@^3.0.0:
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
camelize@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz"
- integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3"
+ integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==
caniuse-lite@^1.0.30001406:
version "1.0.30001444"
@@ -1518,6 +1657,11 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0:
resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz"
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
+convert-source-map@^1.5.0:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
+ integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
+
cookie@^0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz"
@@ -1580,13 +1724,13 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
css-color-keywords@^1.0.0:
version "1.0.0"
- resolved "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz"
- integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=
+ resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
+ integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==
css-to-react-native@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz"
- integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32"
+ integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==
dependencies:
camelize "^1.0.0"
css-color-keywords "^1.0.0"
@@ -1627,7 +1771,7 @@ debounce-promise@^3.1.2:
resolved "https://registry.npmjs.org/debounce-promise/-/debounce-promise-3.1.2.tgz"
integrity sha512-rZHcgBkbYavBeD9ej6sP56XfG53d51CD4dnaw989YX/nZ/ZJfgRx/9ePKmTNiUiyQvh4mtrMoS3OAWW+yoYtpg==
-debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1:
+debug@4, debug@^4.1.1, debug@^4.3.1:
version "4.3.2"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz"
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
@@ -1641,7 +1785,7 @@ debug@^3.2.7:
dependencies:
ms "^2.1.1"
-debug@^4.3.2, debug@^4.3.4:
+debug@^4.1.0, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -1745,6 +1889,13 @@ dom-helpers@^5.0.1, dom-helpers@^5.2.0, dom-helpers@^5.2.1:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"
+duplexer2@^0.1.2:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
+ integrity sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==
+ dependencies:
+ readable-stream "^2.0.2"
+
duplexer@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
@@ -2239,6 +2390,11 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
+find-root@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
+ integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
+
find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
@@ -2411,7 +2567,7 @@ glob@7.1.7, glob@^7.1.3:
globals@^11.1.0:
version "11.12.0"
- resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
globals@^13.19.0:
@@ -2592,6 +2748,17 @@ html-parse-stringify@^3.0.1:
dependencies:
void-elements "3.1.0"
+html-tokenize@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/html-tokenize/-/html-tokenize-2.0.1.tgz#c3b2ea6e2837d4f8c06693393e9d2a12c960be5f"
+ integrity sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w==
+ dependencies:
+ buffer-from "~0.1.1"
+ inherits "~2.0.1"
+ minimist "~1.2.5"
+ readable-stream "~1.0.27-1"
+ through2 "~0.4.1"
+
http-proxy-middleware@^1.0.5:
version "1.3.1"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz#43700d6d9eecb7419bf086a128d0f7205d9eb665"
@@ -2695,7 +2862,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
+inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -2978,6 +3145,11 @@ is-wsl@^2.2.0:
dependencies:
is-docker "^2.0.0"
+isarray@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
+ integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==
+
isarray@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
@@ -3017,7 +3189,7 @@ js-yaml@^4.1.0:
jsesc@^2.5.1:
version "2.5.2"
- resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
json-parse-even-better-errors@^2.3.0:
@@ -3295,7 +3467,7 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
-minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6:
+minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6, minimist@~1.2.5:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
@@ -3347,6 +3519,14 @@ ms@2.1.2, ms@^2.1.1:
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+multipipe@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-1.0.2.tgz#cc13efd833c9cda99f224f868461b8e1a3fd939d"
+ integrity sha512-6uiC9OvY71vzSGX8lZvSqscE7ft9nPupJ8fMjrCNRAUy2LREUW42UL+V/NTrogr6rFgRydUrCX4ZitfpSNkSCQ==
+ dependencies:
+ duplexer2 "^0.1.2"
+ object-assign "^4.1.0"
+
nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
@@ -3461,6 +3641,11 @@ object-keys@^1.0.12, object-keys@^1.1.1:
resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
+object-keys@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336"
+ integrity sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw==
+
object.assign@^4.1.2:
version "4.1.2"
resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz"
@@ -3673,7 +3858,7 @@ picomatch@^2.2.3:
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz"
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
-picomatch@^2.3.1:
+picomatch@^2.3.0, picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
@@ -3696,9 +3881,9 @@ pngjs@^3.4.0:
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
postcss-value-parser@^4.0.2:
- version "4.1.0"
- resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz"
- integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
+ integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@8.4.14:
version "8.4.14"
@@ -3737,16 +3922,7 @@ prop-types-extra@^1.1.0:
react-is "^16.3.2"
warning "^4.0.0"
-prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
- version "15.7.2"
- resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz"
- integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
- dependencies:
- loose-envify "^1.4.0"
- object-assign "^4.1.1"
- react-is "^16.8.1"
-
-prop-types@^15.8.1:
+prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -3755,6 +3931,15 @@ prop-types@^15.8.1:
object-assign "^4.1.1"
react-is "^16.13.1"
+prop-types@^15.6.2, prop-types@^15.7.2:
+ version "15.7.2"
+ resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz"
+ integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
+ dependencies:
+ loose-envify "^1.4.0"
+ object-assign "^4.1.1"
+ react-is "^16.8.1"
+
property-expr@^2.0.2:
version "2.0.4"
resolved "https://registry.npmjs.org/property-expr/-/property-expr-2.0.4.tgz"
@@ -3854,7 +4039,7 @@ react-i18next@^12.2.0:
react-input-autosize@^3.0.0:
version "3.0.0"
- resolved "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-3.0.0.tgz"
+ resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-3.0.0.tgz#6b5898c790d4478d69420b55441fcc31d5c50a85"
integrity sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg==
dependencies:
prop-types "^15.5.8"
@@ -3908,7 +4093,7 @@ react-popper@^2.2.5:
react-select@^4.3.1:
version "4.3.1"
- resolved "https://registry.npmjs.org/react-select/-/react-select-4.3.1.tgz"
+ resolved "https://registry.yarnpkg.com/react-select/-/react-select-4.3.1.tgz#389fc07c9bc7cf7d3c377b7a05ea18cd7399cb81"
integrity sha512-HBBd0dYwkF5aZk1zP81Wx5UsLIIT2lSvAY2JiJo199LjoLHoivjn9//KsmvQMEFGNhe58xyuOITjfxKCcGc62Q==
dependencies:
"@babel/runtime" "^7.12.0"
@@ -3929,7 +4114,17 @@ react-top-loading-bar@^2.0.1:
resolved "https://registry.npmjs.org/react-top-loading-bar/-/react-top-loading-bar-2.0.1.tgz"
integrity sha512-wkRlK9Rte4TU817GDcjlsCoDOxrrnvsNvK609FKyio0EIrmmqjQDz5DB8HbN88CHNZBy5Lh/OBALc03ioWFPuQ==
-react-transition-group@^4.3.0, react-transition-group@^4.4.1, react-transition-group@^4.4.2:
+react-transition-group@^4.3.0:
+ version "4.4.5"
+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
+ integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
+ dependencies:
+ "@babel/runtime" "^7.5.5"
+ dom-helpers "^5.0.1"
+ loose-envify "^1.4.0"
+ prop-types "^15.6.2"
+
+react-transition-group@^4.4.1, react-transition-group@^4.4.2:
version "4.4.2"
resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz"
integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
@@ -3959,6 +4154,19 @@ react@^18.2.0:
dependencies:
loose-envify "^1.1.0"
+readable-stream@^2.0.2:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
+ integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.1.1"
+ util-deprecate "~1.0.1"
+
readable-stream@^2.0.6, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
@@ -3981,6 +4189,16 @@ readable-stream@^3.6.0:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
+readable-stream@~1.0.17, readable-stream@~1.0.27-1:
+ version "1.0.34"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
+ integrity sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.1"
+ isarray "0.0.1"
+ string_decoder "~0.10.x"
+
readable-web-to-node-stream@^3.0.0:
version "3.0.2"
resolved "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz"
@@ -4022,15 +4240,7 @@ resolve-from@^4.0.0:
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
-resolve@^1.20.0:
- version "1.20.0"
- resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz"
- integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
- dependencies:
- is-core-module "^2.2.0"
- path-parse "^1.0.6"
-
-resolve@^1.22.1:
+resolve@^1.19.0, resolve@^1.22.1:
version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@@ -4039,6 +4249,14 @@ resolve@^1.22.1:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
+resolve@^1.20.0:
+ version "1.20.0"
+ resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz"
+ integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
+ dependencies:
+ is-core-module "^2.2.0"
+ path-parse "^1.0.6"
+
resolve@^2.0.0-next.4:
version "2.0.0-next.4"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660"
@@ -4175,7 +4393,7 @@ sha.js@^2.4.0, sha.js@^2.4.8:
shallowequal@^1.1.0:
version "1.1.0"
- resolved "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz"
+ resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
shebang-command@^2.0.0:
@@ -4251,10 +4469,10 @@ source-map-js@^1.0.2:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
-source-map@^0.5.0:
+source-map@^0.5.7:
version "0.5.7"
- resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
- integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+ integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
stop-iteration-iterator@^1.0.0:
version "1.0.0"
@@ -4349,6 +4567,11 @@ string_decoder@^1.1.1:
dependencies:
safe-buffer "~5.2.0"
+string_decoder@~0.10.x:
+ version "0.10.31"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
+ integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==
+
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
@@ -4417,9 +4640,9 @@ strtok3@^6.2.4:
peek-readable "^4.0.1"
styled-components@^5.3.5:
- version "5.3.5"
- resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.5.tgz#a750a398d01f1ca73af16a241dec3da6deae5ec4"
- integrity sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg==
+ version "5.3.9"
+ resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.9.tgz#641af2a8bb89904de708c71b439caa9633e8f0ba"
+ integrity sha512-Aj3kb13B75DQBo2oRwRa/APdB5rSmwUfN5exyarpX+x/tlM/rwZA2vVk2vQgVSP6WKaZJHWwiFrzgHt+CLtB4A==
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@babel/traverse" "^7.4.5"
@@ -4439,10 +4662,10 @@ styled-jsx@5.1.1:
dependencies:
client-only "0.0.1"
-stylis@^4.0.3:
- version "4.0.10"
- resolved "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz"
- integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==
+stylis@4.1.3:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.3.tgz#fd2fbe79f5fed17c55269e16ed8da14c84d069f7"
+ integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==
supports-color@^5.3.0, supports-color@^5.5.0:
version "5.5.0"
@@ -4486,6 +4709,14 @@ text-table@^0.2.0:
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
+through2@~0.4.1:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b"
+ integrity sha512-45Llu+EwHKtAZYTPPVn3XZHBgakWMN3rokhEv5hu596XP+cNgplMg+Gj+1nmAvj+L0K7+N49zBKx5rah5u0QIQ==
+ dependencies:
+ readable-stream "~1.0.17"
+ xtend "~2.1.1"
+
through@^2.3.8:
version "2.3.8"
resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
@@ -4856,6 +5087,13 @@ xml-js@^1.6.11:
dependencies:
sax "^1.2.4"
+xtend@~2.1.1:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b"
+ integrity sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==
+ dependencies:
+ object-keys "~0.4.0"
+
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"