diff --git a/i18n/de.po b/i18n/de.po
index 529d16a..08f4c20 100644
--- a/i18n/de.po
+++ b/i18n/de.po
@@ -775,7 +775,7 @@ msgstr "Gesamtzeit"
#: src/components/CanvasItem.jsx:54
msgid "Ranked"
-msgstr ""
+msgstr "Gewertet"
#: src/components/CanvasItem.jsx:56
msgid "Requirements"
diff --git a/i18n/dz.po b/i18n/dz.po
new file mode 100644
index 0000000..e7ec0c6
--- /dev/null
+++ b/i18n/dz.po
@@ -0,0 +1,1087 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+"Project-Id-Version: \n"
+"PO-Revision-Date: 2021-01-31 11:31+0100\n"
+"Last-Translator: \n"
+"Language-Team: Dzongkha\n"
+"Language: dz\n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+"POT-Creation-Date: \n"
+"X-Generator: Poedit 2.3\n"
+
+#: src/components/CoordinatesBox.jsx:37 src/controls/keypress.js:59
+msgid "Copied!"
+msgstr "དཔེ་གྲངས།"
+
+#: src/ui/placePixel.js:53
+msgid "Error :("
+msgstr "དཀའ་ངལ་ཅན།"
+
+#: src/ui/placePixel.js:54
+msgid "Didn't get an answer from pixelplanet. Maybe try to refresh?"
+msgstr "དཀའ་ངལ་ཅན། གདོང་ཤོག་གནས་ཚུལ་རྩ་ཅན།"
+
+#: src/ui/placePixel.js:56 src/ui/placePixel.js:265
+msgid "OK"
+msgstr "བཏུབ་ག་མི་བཏུབ་ཟེར་མི་འདི"
+
+#: src/ui/placePixel.js:206
+msgid "Invalid Canvas"
+msgstr "ཆ་གནས་མེདཔ། རྒྱ་ལས་ཐོན་པའི་ཁ་ཤ་དར་རས།"
+
+#: src/ui/placePixel.js:207
+msgid "This canvas doesn't exist"
+msgstr "ནཱི། རྒྱ་ལས་ཐོན་པའི་ཁ་ཤ་དར་རས། དབྱེ་བ་མེད་པའི་དོན། ཁོ་དང་ང་ལུ་ཡོན་ཏན་གྱི་ཁྱད་པར་མེད།"
+
+#: src/ui/placePixel.js:210 src/ui/placePixel.js:214 src/ui/placePixel.js:218
+msgid "Invalid Coordinates"
+msgstr "དཀའ་ངལ་ཅན། གནས་མིང༌།"
+
+#: src/ui/placePixel.js:211
+msgid "x out of bounds"
+msgstr "x ཕྱི་ནང་གཉིས་ཀྱི་ཕྱི། ཆ་གནས་མེདཔ།"
+
+#: src/ui/placePixel.js:215
+msgid "y out of bounds"
+msgstr "y ཕྱི་ནང་གཉིས་ཀྱི་ཕྱི། ཆ་གནས་མེདཔ།"
+
+#: src/ui/placePixel.js:219
+msgid "z out of bounds"
+msgstr "z ཕྱི་ནང་གཉིས་ཀྱི་ཕྱི། ཆ་གནས་མེདཔ།"
+
+#: src/ui/placePixel.js:222
+msgid "Wrong Color"
+msgstr "ཁ་ན་མ་ཐོ་བ། ཁ་དོག་དཀར་སེར་དམར་ལྗང་གི་ཚོན།"
+
+#: src/ui/placePixel.js:223
+msgid "Invalid color selected"
+msgstr "ཆ་གནས་མེདཔ། ཁ་དོག་དཀར་སེར་དམར་ལྗང་གི་ཚོན། གོམས་ཚུད་ཚུདཔ།"
+
+#: src/ui/placePixel.js:226
+msgid "Just for registered Users"
+msgstr "ཁོ་ན། ཁ་དམ་དྲགས། ཐོ་བཀོད་བཀོདཔ། སྤྱོད་མི།"
+
+#: src/ui/placePixel.js:227
+msgid "You have to be logged in to place on this canvas"
+msgstr "དགོ། རྩིས་ཁ། རྒྱུ་མཚན། དོན་དག ཁག་ཆེ་བའི་དོན་དག་ཚུ།"
+
+#: src/ui/placePixel.js:230
+msgid "Place more :)"
+msgstr "གནད་དོན། ཡང་བསྐྱར་གྱི་དོན་ལུ་འཇུགཔ་ཨིན།"
+
+#: src/ui/placePixel.js:232
+msgid "You can not access this canvas yet. You need to place more pixels"
+msgstr ""
+
+#: src/ui/placePixel.js:235
+msgid "Pixel protected!"
+msgstr ""
+
+#: src/ui/placePixel.js:251
+msgid "No Proxies Allowed :("
+msgstr "ཅི་ཡང་མེནམ། རྫུན་པ་དང་དོན་གཅིག ངོ་མ་མིན་པ། རང་གི་ངོ་རྟགས། ངོ་འཐུས།"
+
+#: src/ui/placePixel.js:252
+msgid "You are using a Proxy."
+msgstr "ཁྱེད། གཡོ་སྒྱུ་དང་མགོ་སྐོར་གྱི་མིང་ཅིག་ཨིན། གློག་རིག་ཡོངས་འབྲེལ། ངོ་རྟགས། "
+
+#: src/ui/placePixel.js:255
+msgid "Weird"
+msgstr "གཞན་དང་མ་འདྲ་བའི་མི།"
+
+#: src/ui/placePixel.js:256
+msgid "Couldn't set Pixel"
+msgstr "བྱ་བ་མ་འོངསམ། གསར་བཙུགས། གློག་རིག་ཡོངས་འབྲེལ། ཁག་ཚན།"
+
+#: src/ui/placePixel.js:262
+#, javascript-format
+msgid "Error ${ retCode }"
+msgstr "འཛོལ་བ། ${ retCode }"
+
+#: src/components/Admintools.jsx:219 src/components/ChannelContextMenu.jsx:85
+#: src/components/ModalRoot.jsx:60
+msgid "Close"
+msgstr "ཁེ་བཙོང༌།"
+
+#: src/components/ExpandMenuButton.jsx:19
+msgid "Close Menu"
+msgstr "ཁེ་བཙོང༌། གློག་རིམ་དཀར་ཆག"
+
+#: src/components/ExpandMenuButton.jsx:19
+msgid "Open Menu"
+msgstr "ཀུན་མཐོང་མཛད་རིམ། གློག་རིམ་དཀར་ཆག"
+
+#: src/components/ChatButton.jsx:61
+msgid "Close Chat"
+msgstr " ཁེ་བཙོང༌། ཁ་ལན།"
+
+#: src/components/ChatButton.jsx:61
+msgid "Open Chat"
+msgstr "ཀུན་མཐོང་མཛད་རིམ། ཁ་ལན།"
+
+#: src/components/Converter.jsx:609 src/components/CoordinatesBox.jsx:26
+msgid "Copy to Clipboard"
+msgstr "ཀ་དཔེ། ཨིན།འདུགཡོད། ཆོས་རྒྱུགས་བཀོད་ཚོགས།"
+
+#: src/components/OnlineBox.jsx:22
+msgid "User online"
+msgstr "གཟུགས་ཀྱི་ཡན་ལག ཁར་ཁིར།"
+
+#: src/components/OnlineBox.jsx:25
+msgid "Pixels placed"
+msgstr "གློག་རིག་ཡོངས་འབྲེལ། སྐུ་དང་མཆོད་རྟེན་གྱི་སྲོག་ཤིང༌།"
+
+#: src/components/CanvasSelectModal.jsx:67
+#: src/components/CanvasSwitchButton.jsx:20
+msgid "Canvas Selection"
+msgstr ""
+
+#: src/components/DownloadButton.jsx:37
+msgid "Make Screenshot"
+msgstr ""
+
+#: src/components/LogInButton.jsx:20 src/components/UserAreaModal.jsx:160
+msgid "User Area"
+msgstr ""
+
+#: src/components/SettingsButton.jsx:20 src/components/SettingsModal.jsx:267
+msgid "Settings"
+msgstr ""
+
+#: src/components/HelpButton.jsx:20
+msgid "Help"
+msgstr ""
+
+#: src/components/Chat.jsx:143
+msgid "Channel settings"
+msgstr ""
+
+#: src/components/Chat.jsx:152
+msgid "maximize"
+msgstr ""
+
+#: src/components/Chat.jsx:168
+msgid "Start chatting here"
+msgstr ""
+
+#: src/components/Chat.jsx:200
+msgid "Chat here"
+msgstr ""
+
+#: src/components/Chat.jsx:220
+msgid "You must be logged in to chat"
+msgstr ""
+
+#: src/components/PalselButton.jsx:25
+msgid "Close Palette"
+msgstr ""
+
+#: src/components/PalselButton.jsx:25
+msgid "Open Palette"
+msgstr ""
+
+#: src/components/GlobeButton.jsx:31
+msgid "Globe View"
+msgstr ""
+
+#: src/components/UserContextMenu.jsx:72
+msgid "Ping"
+msgstr ""
+
+#: src/components/UserContextMenu.jsx:97
+msgid "DM"
+msgstr ""
+
+#: src/components/UserContextMenu.jsx:107
+msgid "Block"
+msgstr ""
+
+#: src/components/HelpModal.jsx:34 src/components/HelpModal.jsx:35
+msgid "Privacy Policy"
+msgstr ""
+
+#: src/components/HelpModal.jsx:36 src/components/HelpModal.jsx:37
+msgid "Terms of Service"
+msgstr ""
+
+#: src/components/HelpModal.jsx:40
+msgid "your IP"
+msgstr ""
+
+#: src/components/HelpModal.jsx:46
+msgid "Place color pixels on a large canvas with other players online!"
+msgstr ""
+
+#: src/components/HelpModal.jsx:47
+msgid ""
+"Our main canvas is a huge worldmap, you can place wherever you like, but you "
+"will have to wait a specific Cooldown between pixels. You can check out the "
+"cooldown and requiremnts on the Canvas Selection menu (globe button on top). "
+"Some canvases have a different cooldown for replacing a user-set pixels than "
+"placing on a unset pixel. i.e. 4s/7s means 4s on fresh pixels and 7s on "
+"already set pixels."
+msgstr ""
+
+#: src/components/HelpModal.jsx:51
+msgid ""
+"Higher zoomlevels take some time to update, the 3D globe gets updated at "
+"least once per day."
+msgstr ""
+
+#: src/components/HelpModal.jsx:52
+msgid "Have fun!"
+msgstr ""
+
+#: src/components/HelpModal.jsx:54
+msgid "recommended"
+msgstr ""
+
+#: src/components/HelpModal.jsx:55
+msgid "Source on "
+msgstr ""
+
+#: src/components/HelpModal.jsx:56
+msgid "Map Data"
+msgstr ""
+
+#: src/components/HelpModal.jsx:57
+msgid ""
+"The bare map data that we use, together with converted OpenStreetMap tiles "
+"for orientation, can be downloaded from mega.nz here: "
+msgstr ""
+
+#: src/components/HelpModal.jsx:59
+msgid "Detected as Proxy?"
+msgstr ""
+
+#: src/components/HelpModal.jsx:61
+#, javascript-format
+msgid ""
+"If you got detected as proxy, but you are none, please go to our "
+"${ guildedLink } or send us an e-mail with ${ getIPLink } to ${ mailLink }. "
+"Do not post your IP anywhere else. We are sorry for the inconvenience."
+msgstr ""
+
+#: src/components/HelpModal.jsx:63 src/components/HelpModal.jsx:80
+msgid "Controls"
+msgstr ""
+
+#: src/components/HelpModal.jsx:65
+msgid "Click a color in palette to select it"
+msgstr ""
+
+#: src/components/HelpModal.jsx:66
+#, javascript-format
+msgid "Press ${ bindG } to toggle grid"
+msgstr ""
+
+#: src/components/HelpModal.jsx:67
+msgid "Press ${ bindX } to toggle showing of pixel activity"
+msgstr ""
+
+#: src/components/HelpModal.jsx:68
+#, javascript-format
+msgid "Press ${ bindH } to toggle historical view"
+msgstr ""
+
+#: src/components/HelpModal.jsx:69
+msgid "Press ${ bindR } to copy coordinates"
+msgstr ""
+
+#: src/components/HelpModal.jsx:70
+#, javascript-format
+msgid "Press ${ bindQ } or ${ bindE } to zoom"
+msgstr ""
+
+#: src/components/HelpModal.jsx:71 src/components/HelpModal.jsx:82
+#, javascript-format
+msgid "Press ${ bindW }, ${ bindA }, ${ bindS }, ${ bindD } to move"
+msgstr ""
+
+#: src/components/HelpModal.jsx:72 src/components/HelpModal.jsx:83
+#, javascript-format
+msgid ""
+"Press ${ bindAUp }, ${ bindALeft }, ${ bindADown }, ${ bindARight } to move"
+msgstr ""
+
+#: src/components/HelpModal.jsx:73
+msgid "Drag ${ mouseSymbol } mouse or ${ touchSymbol } pan to move"
+msgstr ""
+
+#: src/components/HelpModal.jsx:74
+#, javascript-format
+msgid "Scroll ${ mouseSymbol } mouse wheel or ${ touchSymbol } pinch to zoom"
+msgstr ""
+
+#: src/components/HelpModal.jsx:75
+msgid "Hold left ${ bindShift } for placing while moving mouse"
+msgstr ""
+
+#: src/components/HelpModal.jsx:76
+#, javascript-format
+msgid ""
+"Hold right ${ bindShift } for placing while moving mouse according to "
+"historical view"
+msgstr ""
+
+#: src/components/HelpModal.jsx:77 src/components/HelpModal.jsx:88
+#, javascript-format
+msgid "${ mouseSymbol } Left click or ${ touchSymbol } tap to place a pixel"
+msgstr ""
+
+#: src/components/HelpModal.jsx:78 src/components/HelpModal.jsx:90
+msgid ""
+"Click ${ mouseSymbol } middle mouse button or ${ touchSymbol } long-tap to "
+"select current hovering color"
+msgstr ""
+
+#: src/components/HelpModal.jsx:84
+msgid "Press ${ bindE } and ${ bindC } to fly up and down"
+msgstr ""
+
+#: src/components/HelpModal.jsx:85
+#, javascript-format
+msgid "${ mouseSymbol } Hold left mouse button and drag mouse to rotate"
+msgstr ""
+
+#: src/components/HelpModal.jsx:86
+#, javascript-format
+msgid ""
+"${ mouseSymbol } Scroll mouse wheel or hold ${ mouseSymbol } middle mouse "
+"button and drag to zoom"
+msgstr ""
+
+#: src/components/HelpModal.jsx:87
+msgid "${ mouseSymbol } Right click and drag mouse to pan"
+msgstr ""
+
+#: src/components/HelpModal.jsx:89
+#, javascript-format
+msgid ""
+"${ mouseSymbol } Right click or ${ touchSymbol } double-tap to remove a pixel"
+msgstr ""
+
+#: src/components/HelpModal.jsx:92
+msgid "Partners:"
+msgstr ""
+
+#: src/components/HelpModal.jsx:97
+#, javascript-format
+msgid ""
+"This site is protected by reCAPTCHA and the Google ${ reCaptchaPP } and "
+"${ reCaptchaTOS } apply."
+msgstr ""
+
+#: src/components/HelpModal.jsx:103
+msgid ""
+"This site is protected by hCAPTCHA and its ${ hCaptchaPP } and "
+"${ hCaptchaTOS } apply."
+msgstr ""
+
+#: src/components/HelpModal.jsx:113
+msgid "Welcome to PixelPlanet.fun"
+msgstr ""
+
+#: src/components/ChannelContextMenu.jsx:73
+msgid "Mute"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:123
+msgid "Show Grid"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:124
+msgid "Turn on grid to highlight pixel borders."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:130
+msgid "Show Pixel Activity"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:131
+msgid "Show circles where pixels are placed."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:137
+msgid "Disable Game Sounds"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:139
+msgid "All sound effects will be disabled."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:145
+msgid "Enable chat notifications"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:146
+msgid "Play a sound when new chat messages arrive"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:151
+msgid "Auto Zoom In"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:153
+msgid ""
+"Zoom in instead of placing a pixel when you tap the canvas and your zoom is "
+"small."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:158
+msgid "Compact Palette"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:160
+msgid "Display Palette in a compact form that takes less screen space."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:165
+msgid "Potato Mode"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:166
+msgid "For when you are playing on a potato."
+msgstr ""
+
+#: src/components/Converter.jsx:423 src/components/SettingsModal.jsx:171
+msgid "Light Grid"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:172
+msgid "Show Grid in white instead of black."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:179
+msgid "Historical View"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:180
+msgid "Check out past versions of the canvas."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:188
+msgid "Themes"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:189
+msgid "How pixelplanet should look like."
+msgstr ""
+
+#: src/components/RegisterModal.jsx:18
+msgid "Register new account here"
+msgstr ""
+
+#: src/components/ForgotPasswordModal.jsx:20
+#: src/components/RegisterModal.jsx:21 src/components/UserAreaModal.jsx:130
+msgid "Consider joining us on Guilded:"
+msgstr ""
+
+#: src/components/RegisterModal.jsx:38
+msgid "Register New Account"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:33
+msgid "Login to access more features and stats."
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:35
+msgid "Login with Name or Mail:"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:42
+msgid "I forgot my Password."
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:43
+msgid "or login with:"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:84
+msgid "or register here:"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:85
+msgid "Register"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:107
+msgid "Profile"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:113
+msgid "Ranking"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:116
+msgid "Converter"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:122
+msgid "Admintools"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:122
+msgid "Modtools"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:123
+msgid "Loading..."
+msgstr ""
+
+#: src/components/ArchiveModal.jsx:20
+msgid ""
+"While we tend to not delete canvases, some canvases are started for fun or "
+"as a request by users who currently like a meme. Those canvases can get "
+"boring after a while and after weeks of no major change and if they really "
+"aren't worth being kept active, we decide to remove them."
+msgstr ""
+
+#: src/components/ArchiveModal.jsx:22
+msgid ""
+"Here we collect those canvases to archive them in a proper way (which is "
+"currently just one)."
+msgstr ""
+
+#: src/components/ArchiveModal.jsx:24
+msgid "Political Compass Canvas"
+msgstr ""
+
+#: src/components/ArchiveModal.jsx:31
+msgid ""
+"This canvas got requested during a time of political conflicts on the main "
+"Earth canvas. It was a 1024x1024 representation of the political compass "
+"with a 5s coolodwn and 60s stacking. It got launched on May 11th and "
+"remained active for months till it got shut down on November 30th."
+msgstr ""
+
+#: src/components/ArchiveModal.jsx:32
+msgid ""
+"We decided to archive it as a timelapse with lossless encoded webm. Taking a "
+"screenshot from the timelapse results in a perfect 1:1 representation of how "
+"the canvas was at that time."
+msgstr ""
+
+#: src/components/ArchiveModal.jsx:50
+msgid "Canvas Archive"
+msgstr ""
+
+#: src/components/CanvasSelectModal.jsx:29
+msgid ""
+"Select the canvas you want to use. Every canvas is unique and has different "
+"palettes, cooldown and requirements. Archive of closed canvases can be "
+"accessed here:"
+msgstr ""
+
+#: src/components/CanvasSelectModal.jsx:37
+msgid "Archive"
+msgstr ""
+
+#: src/components/ForgotPasswordModal.jsx:16
+msgid "Enter your mail adress and we will send you a new password:"
+msgstr ""
+
+#: src/components/ForgotPasswordModal.jsx:37
+msgid "Restore my Password"
+msgstr ""
+
+#: src/components/ChatModal.jsx:35
+msgid "Chat"
+msgstr ""
+
+#: src/components/ChangeMail.jsx:104 src/components/ChangeName.jsx:82
+#: src/components/ChangePassword.jsx:120 src/components/DeleteAccount.jsx:82
+#: src/components/LogInForm.jsx:97 src/components/NewPasswordForm.jsx:93
+#: src/components/SignUpForm.jsx:118
+msgid "Error"
+msgstr ""
+
+#: src/components/LogInForm.jsx:104
+msgid "Name or Email"
+msgstr ""
+
+#: src/components/ChangeMail.jsx:112 src/components/DeleteAccount.jsx:89
+#: src/components/LogInForm.jsx:111 src/components/SignUpForm.jsx:140
+msgid "Password"
+msgstr ""
+
+#: src/components/LogInForm.jsx:115
+msgid "LogIn"
+msgstr ""
+
+#: src/components/UserArea.jsx:57
+msgid "Todays Placed Pixels"
+msgstr ""
+
+#: src/components/UserArea.jsx:61
+msgid "Daily Rank"
+msgstr ""
+
+#: src/components/UserArea.jsx:66
+msgid "Placed Pixels"
+msgstr ""
+
+#: src/components/UserArea.jsx:70
+msgid "Total Rank"
+msgstr ""
+
+#: src/components/UserArea.jsx:75
+#, javascript-format
+msgid "Your name is: ${ name }"
+msgstr ""
+
+#: src/components/UserArea.jsx:81
+msgid "Log out"
+msgstr ""
+
+#: src/components/UserArea.jsx:93
+msgid "Change Username"
+msgstr ""
+
+#: src/components/UserArea.jsx:108
+msgid "Change Mail"
+msgstr ""
+
+#: src/components/UserArea.jsx:122
+msgid "Change Password"
+msgstr ""
+
+#: src/components/UserArea.jsx:134
+msgid "Delete Account"
+msgstr ""
+
+#: src/components/UserArea.jsx:147
+msgid "Social Settings"
+msgstr ""
+
+#: src/components/Rankings.jsx:37
+msgid "Total"
+msgstr ""
+
+#: src/components/Rankings.jsx:45
+msgid "Daily"
+msgstr ""
+
+#: src/components/Rankings.jsx:49
+msgid "Ranking updates every 5 min. Daily rankings get reset at midnight UTC."
+msgstr ""
+
+#: src/components/CanvasItem.jsx:46
+msgid "Cooldown"
+msgstr ""
+
+#: src/components/CanvasItem.jsx:52
+msgid "Stacking till"
+msgstr ""
+
+#: src/components/CanvasItem.jsx:54
+msgid "Ranked"
+msgstr ""
+
+#: src/components/CanvasItem.jsx:56
+msgid "Requirements"
+msgstr ""
+
+#: src/components/CanvasItem.jsx:58
+msgid "User Account"
+msgstr ""
+
+#: src/components/CanvasItem.jsx:60
+#, javascript-format
+msgid "and ${ canvas.req } Pixels set"
+msgstr ""
+
+#: src/components/CanvasItem.jsx:64
+msgid "Dimensions"
+msgstr ""
+
+#: src/components/NewPasswordForm.jsx:83
+msgid "Sent you a mail with instructions to reset your password."
+msgstr ""
+
+#: src/components/NewPasswordForm.jsx:100 src/components/SignUpForm.jsx:133
+msgid "Email"
+msgstr ""
+
+#: src/components/Admintools.jsx:306 src/components/Admintools.jsx:387
+#: src/components/Admintools.jsx:461 src/components/Admintools.jsx:505
+#: src/components/Admintools.jsx:589 src/components/NewPasswordForm.jsx:104
+#: src/components/SignUpForm.jsx:152
+msgid "Submit"
+msgstr ""
+
+#: src/components/ChangeMail.jsx:125 src/components/ChangeName.jsx:94
+#: src/components/ChangePassword.jsx:152 src/components/DeleteAccount.jsx:95
+#: src/components/NewPasswordForm.jsx:106 src/components/SignUpForm.jsx:158
+msgid "Cancel"
+msgstr ""
+
+#: src/components/SignUpForm.jsx:126
+msgid "Name"
+msgstr ""
+
+#: src/components/SignUpForm.jsx:149
+msgid "Confirm Password"
+msgstr ""
+
+#: src/components/Admintools.jsx:179
+msgid "Build image on canvas."
+msgstr ""
+
+#: src/components/Admintools.jsx:182
+msgid "Build image and set it to protected."
+msgstr ""
+
+#: src/components/Admintools.jsx:185
+msgid "Build image, but reset cooldown to unset-pixel cd."
+msgstr ""
+
+#: src/components/Admintools.jsx:248
+msgid "Image Upload"
+msgstr ""
+
+#: src/components/Admintools.jsx:249
+msgid "Upload images to canvas"
+msgstr ""
+
+#: src/components/Admintools.jsx:251
+msgid "File"
+msgstr ""
+
+#: src/components/Admintools.jsx:271
+msgid "Coordinates in X_Y format:"
+msgstr ""
+
+#: src/components/Admintools.jsx:311
+msgid "Pixel Protection"
+msgstr ""
+
+#: src/components/Admintools.jsx:313
+msgid ""
+"Set protection of areas (if you need finer grained control, "
+"use protect with image upload and alpha layers)"
+msgstr ""
+
+#: src/components/Admintools.jsx:392
+msgid "Rollback to Date"
+msgstr ""
+
+#: src/components/Admintools.jsx:394
+msgid "Rollback an area of the canvas to a set date (00:00 UTC)"
+msgstr ""
+
+#: src/components/Admintools.jsx:468
+msgid "IP Actions"
+msgstr ""
+
+#: src/components/Admintools.jsx:470
+msgid "Do stuff with IPs (one IP per line)"
+msgstr ""
+
+#: src/components/Admintools.jsx:510
+msgid "Manage Moderators"
+msgstr ""
+
+#: src/components/Admintools.jsx:512
+msgid "Remove Moderator"
+msgstr ""
+
+#: src/components/Admintools.jsx:544
+msgid "There are no mods"
+msgstr ""
+
+#: src/components/Admintools.jsx:549
+msgid "Assign new Mod"
+msgstr ""
+
+#: src/components/Admintools.jsx:552
+msgid "Enter UserName of new Mod"
+msgstr ""
+
+#: src/components/Admintools.jsx:561
+msgid "User Name"
+msgstr ""
+
+#: src/components/Converter.jsx:274
+msgid "Choose Canvas"
+msgstr ""
+
+#: src/components/Converter.jsx:300
+msgid "Palette Download"
+msgstr ""
+
+#: src/components/Converter.jsx:302
+#, javascript-format
+msgid "Palette for ${ gimpLink }"
+msgstr ""
+
+#: src/components/Converter.jsx:320
+#, javascript-format
+msgid "Credit for the Palette of the Moon goes to ${ starhouseLink }."
+msgstr ""
+
+#: src/components/Converter.jsx:323
+msgid "Image Converter"
+msgstr ""
+
+#: src/components/Converter.jsx:324
+msgid "Convert an image to canvas colors"
+msgstr ""
+
+#: src/components/Converter.jsx:335
+msgid "Choose Strategy"
+msgstr ""
+
+#: src/components/Converter.jsx:362
+msgid "Choose Color Mode"
+msgstr ""
+
+#: src/components/Converter.jsx:400
+msgid "Add Grid (uncheck if you need a 1:1 template)"
+msgstr ""
+
+#: src/components/Converter.jsx:425 src/components/Converter.jsx:441
+msgid "Offset"
+msgstr ""
+
+#: src/components/Converter.jsx:471
+msgid "Scale Image"
+msgstr ""
+
+#: src/components/Converter.jsx:483
+msgid "Width"
+msgstr ""
+
+#: src/components/Converter.jsx:513
+msgid "Height"
+msgstr ""
+
+#: src/components/Converter.jsx:551
+msgid "Keep Ratio"
+msgstr ""
+
+#: src/components/Converter.jsx:564
+msgid "Anti Aliasing"
+msgstr ""
+
+#: src/components/Converter.jsx:578
+msgid "Reset"
+msgstr ""
+
+#: src/components/Converter.jsx:597
+msgid "Download Template"
+msgstr ""
+
+#: src/utils/validation.js:18
+msgid "Email can't be empty."
+msgstr ""
+
+#: src/utils/validation.js:19
+msgid "Email should be at least 5 characters long."
+msgstr ""
+
+#: src/utils/validation.js:20
+msgid "Email can't be longer than 40 characters."
+msgstr ""
+
+#: src/utils/validation.js:21
+msgid "Email should at least contain a dot"
+msgstr ""
+
+#: src/utils/validation.js:23
+msgid "Email should contain a @"
+msgstr ""
+
+#: src/utils/validation.js:30
+msgid "Name can't be empty."
+msgstr ""
+
+#: src/utils/validation.js:31
+msgid "Name must be at least 4 characters long"
+msgstr ""
+
+#: src/utils/validation.js:32
+msgid "Name must be shorter than 26 characters"
+msgstr ""
+
+#: src/utils/validation.js:39
+msgid "Name contains invalid character like @, /, \\ or #"
+msgstr ""
+
+#: src/utils/validation.js:54
+msgid "No password given."
+msgstr ""
+
+#: src/utils/validation.js:57
+msgid "Password must be at least 6 characters long."
+msgstr ""
+
+#: src/utils/validation.js:60
+msgid "Password must be shorter than 60 characters."
+msgstr ""
+
+#: src/utils/validation.js:74
+msgid "Could not connect to server, please try again later :("
+msgstr ""
+
+#: src/utils/validation.js:80
+msgid "I think we experienced some error :("
+msgstr ""
+
+#: src/components/SocialSettings.jsx:39
+msgid "Block all Private Messages"
+msgstr ""
+
+#: src/components/SocialSettings.jsx:57
+msgid "Unblock Users"
+msgstr ""
+
+#: src/components/SocialSettings.jsx:81
+msgid "You have no users blocked"
+msgstr ""
+
+#: src/components/ChangeMail.jsx:89
+msgid ""
+"Changed Mail successfully. We sent you a verification mail, "
+"please verify your new mail adress."
+msgstr ""
+
+#: src/components/ChangeMail.jsx:119
+msgid "New Mail"
+msgstr ""
+
+#: src/components/ChangeMail.jsx:123 src/components/ChangeName.jsx:92
+#: src/components/ChangePassword.jsx:150
+msgid "Save"
+msgstr ""
+
+#: src/components/ChangePassword.jsx:18
+msgid "Passwords do not match."
+msgstr ""
+
+#: src/components/ChangePassword.jsx:103
+msgid "Changed Password successfully."
+msgstr ""
+
+#: src/components/ChangePassword.jsx:129
+msgid "Old Password"
+msgstr ""
+
+#: src/components/ChangePassword.jsx:137
+msgid "New Password"
+msgstr ""
+
+#: src/components/ChangePassword.jsx:146
+msgid "Confirm New Password"
+msgstr ""
+
+#: src/components/DeleteAccount.jsx:93
+msgid "Yes, Delete My Account!"
+msgstr ""
+
+#: src/components/UserMessages.jsx:41
+msgid "A new verification mail is getting sent to you."
+msgstr ""
+
+#: src/components/UserMessages.jsx:75
+msgid "You successfully linked your mc account."
+msgstr ""
+
+#: src/components/UserMessages.jsx:76
+msgid "You denied."
+msgstr ""
+
+#: src/components/UserMessages.jsx:94
+msgid ""
+"Please verify your mail address \n"
+"or your account could get deleted after a few days."
+msgstr ""
+
+#: src/components/UserMessages.jsx:111
+msgid "Click here to request a new verification mail."
+msgstr ""
+
+#: src/components/UserMessages.jsx:120
+#, javascript-format
+msgid "You requested to link your mc account ${ minecraftname }."
+msgstr ""
+
+#: src/components/UserMessages.jsx:140
+msgid "Accept"
+msgstr ""
+
+#: src/components/UserMessages.jsx:150
+msgid "Deny"
+msgstr ""
+
+#: src/components/ChangeName.jsx:88
+msgid "New Username"
+msgstr ""
+
+#: src/components/HelpModal.jsx:15 src/components/SettingsModal.jsx:125
+msgctxt "keybinds"
+msgid "G"
+msgstr ""
+
+#: src/components/HelpModal.jsx:16 src/components/SettingsModal.jsx:132
+msgctxt "keybinds"
+msgid "X"
+msgstr ""
+
+#: src/components/HelpModal.jsx:17 src/components/SettingsModal.jsx:182
+msgctxt "keybinds"
+msgid "H"
+msgstr ""
+
+#: src/components/HelpModal.jsx:18
+msgctxt "keybinds"
+msgid "R"
+msgstr ""
+
+#: src/components/HelpModal.jsx:19
+msgctxt "keybinds"
+msgid "Q"
+msgstr ""
+
+#: src/components/HelpModal.jsx:20
+msgctxt "keybinds"
+msgid "E"
+msgstr ""
+
+#: src/components/HelpModal.jsx:21
+msgctxt "keybinds"
+msgid "W"
+msgstr ""
+
+#: src/components/HelpModal.jsx:22
+msgctxt "keybinds"
+msgid "A"
+msgstr ""
+
+#: src/components/HelpModal.jsx:23
+msgctxt "keybinds"
+msgid "S"
+msgstr ""
+
+#: src/components/HelpModal.jsx:24
+msgctxt "keybinds"
+msgid "D"
+msgstr ""
+
+#: src/components/HelpModal.jsx:31
+msgctxt "keybinds"
+msgid "Shift"
+msgstr ""
+
+#: src/components/HelpModal.jsx:32
+msgctxt "keybinds"
+msgid "C"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:140
+msgctxt "keybinds"
+msgid "M"
+msgstr ""
diff --git a/i18n/ssr-de.po b/i18n/ssr-de.po
index e5d7569..99e2fc4 100644
--- a/i18n/ssr-de.po
+++ b/i18n/ssr-de.po
@@ -12,6 +12,62 @@ msgstr ""
"Plural-Forms: nplurals = 2; plural = (n != 1);\n"
"X-Generator: Poedit 2.3\n"
+#: src/core/ChatProvider.js:243
+msgid "You can not send chat messages with proxy"
+msgstr "Du kannst keine Nachrichten senden wenn du ein Proxy benutzt"
+
+#: src/core/ChatProvider.js:248
+msgid "Couldn't send your message, pls log out and back in again."
+msgstr "Konnte die Nachricht nicht senden, bitte logge duch aus und wieder an."
+
+#: src/core/ChatProvider.js:262
+#, javascript-format
+msgid "You are sending messages too fast, you have to wait ${ waitTime }s :("
+msgstr "Du sendest zu viele Nachrichten, du musst ${ waitTime }s warten :("
+
+#: src/core/ChatProvider.js:266
+msgid "You don't have access to this channel"
+msgstr "Du hast keinen Zugriff zu diesen Kanal"
+
+#: src/core/ChatProvider.js:282
+msgid "Your mail has to be verified in order to chat"
+msgstr "E-Mail muss verifiziert sein um Nachrichten zu senden"
+
+#: src/core/ChatProvider.js:287
+msgid "You are permanently muted, join our guilded to apppeal the mute"
+msgstr ""
+"Du bsit permanent stummgeschaltet, gehe zu unser guilded um dagegen "
+"einzusprechen"
+
+#: src/core/ChatProvider.js:292
+#, javascript-format
+msgid "You are muted for another ${ timeMin } minutes"
+msgstr "Du bist für ${ timeMin } Minuten stummgeschaltet"
+
+#: src/core/ChatProvider.js:294
+msgid "You are muted for another ${ muted } seconds"
+msgstr "Du bist for ${ muted } Sekunden stummgeschaltet"
+
+#: src/core/ChatProvider.js:302
+msgid "Ow no! Spam protection decided to mute you"
+msgstr "Oh nein! Spam-Schutz hat dich stummgeschaltet"
+
+#: src/core/ChatProvider.js:313
+msgid "You can't send a message this long :("
+msgstr "Do kannst keine so langen Nachrichten senden"
+
+#: src/core/ChatProvider.js:317
+msgid "Please use int channel"
+msgstr "Bitte benutze int Kanal"
+
+#: src/core/ChatProvider.js:321
+msgid "Your country is temporary muted from chat"
+msgstr "Dein Land ist temporär stummgeschaltet"
+
+#: src/core/ChatProvider.js:329
+msgid "Stop flooding."
+msgstr "Stoppe zu spamen."
+
#: src/ssr-components/Main.jsx:53
msgid "PixelPlanet.fun"
msgstr "PixelPlanet.Fun"
@@ -141,7 +197,7 @@ msgid ""
"next 30min here: "
msgstr ""
"Du hast ein neues Passwort beantragt. Du kannst es nun während der nächsten "
-"30min hier ändern:"
+"30min hier ändern"
#: src/core/mail.js:128 src/ssr-components/PasswordReset.jsx:19
#: src/ssr-components/PasswordReset.jsx:28
@@ -237,7 +293,7 @@ msgstr "Passwort muss mindestens 6 Zeichen lang sein."
#: src/utils/validation.js:60
msgid "Password must be shorter than 60 characters."
-msgstr "Passwort muss kürzer als 60 Zeichen sein"
+msgstr "Passwort muss kürzer als 60 Zeichen sein."
#: src/utils/validation.js:74
msgid "Could not connect to server, please try again later :("
@@ -302,7 +358,7 @@ msgstr "Du wirst automatisch weitergeleitet nach 15s"
#: src/ssr-components/RedirectionPage.jsx:21
#, javascript-format
msgid "Or ${ clickHere } to go back to pixelplanet"
-msgstr "oder ${ clickHere } um zu pixelplanet zurückzukehren"
+msgstr "Oder ${ clickHere } um zu pixelplanet zurückzukehren"
#: src/ssr-components/RedirectionPage.jsx:25
msgid "PixelPlanet.fun Accounts"
diff --git a/i18n/template-ssr.pot b/i18n/template-ssr.pot
index b89d32b..36b4b09 100644
--- a/i18n/template-ssr.pot
+++ b/i18n/template-ssr.pot
@@ -3,6 +3,60 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
+#: src/core/ChatProvider.js:243
+msgid "You can not send chat messages with proxy"
+msgstr ""
+
+#: src/core/ChatProvider.js:248
+msgid "Couldn't send your message, pls log out and back in again."
+msgstr ""
+
+#: src/core/ChatProvider.js:262
+#, javascript-format
+msgid "You are sending messages too fast, you have to wait ${ waitTime }s :("
+msgstr ""
+
+#: src/core/ChatProvider.js:266
+msgid "You don't have access to this channel"
+msgstr ""
+
+#: src/core/ChatProvider.js:282
+msgid "Your mail has to be verified in order to chat"
+msgstr ""
+
+#: src/core/ChatProvider.js:287
+msgid "You are permanently muted, join our guilded to apppeal the mute"
+msgstr ""
+
+#: src/core/ChatProvider.js:292
+#, javascript-format
+msgid "You are muted for another ${ timeMin } minutes"
+msgstr ""
+
+#: src/core/ChatProvider.js:294
+msgid "You are muted for another ${ muted } seconds"
+msgstr ""
+
+#: src/core/ChatProvider.js:302
+msgid "Ow no! Spam protection decided to mute you"
+msgstr ""
+
+#: src/core/ChatProvider.js:313
+msgid "You can't send a message this long :("
+msgstr ""
+
+#: src/core/ChatProvider.js:317
+msgid "Please use int channel"
+msgstr ""
+
+#: src/core/ChatProvider.js:321
+msgid "Your country is temporary muted from chat"
+msgstr ""
+
+#: src/core/ChatProvider.js:329
+msgid "Stop flooding."
+msgstr ""
+
#: src/ssr-components/Main.jsx:53
msgid "PixelPlanet.fun"
msgstr ""
diff --git a/i18n/template.pot b/i18n/template.pot
index b73991f..b8c1609 100644
--- a/i18n/template.pot
+++ b/i18n/template.pot
@@ -3,141 +3,130 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
-#: src/components/CoordinatesBox.jsx:37
-#: src/controls/keypress.js:59
-msgid "Copied!"
+#: src/components/ForgotPasswordModal.jsx:16
+msgid "Enter your mail adress and we will send you a new password:"
msgstr ""
-#: src/ui/placePixel.js:53
-msgid "Error :("
+#: src/components/ForgotPasswordModal.jsx:20
+#: src/components/RegisterModal.jsx:21
+#: src/components/UserAreaModal.jsx:130
+msgid "Consider joining us on Guilded:"
msgstr ""
-#: src/ui/placePixel.js:54
-msgid "Didn't get an answer from pixelplanet. Maybe try to refresh?"
+#: src/components/ForgotPasswordModal.jsx:37
+msgid "Restore my Password"
msgstr ""
-#: src/ui/placePixel.js:56
-#: src/ui/placePixel.js:265
-msgid "OK"
+#: src/components/ArchiveModal.jsx:20
+msgid ""
+"While we tend to not delete canvases, some canvases are started for fun or "
+"as a request by users who currently like a meme. Those canvases can get "
+"boring after a while and after weeks of no major change and if they really "
+"aren't worth being kept active, we decide to remove them."
msgstr ""
-#: src/ui/placePixel.js:206
-msgid "Invalid Canvas"
+#: src/components/ArchiveModal.jsx:22
+msgid ""
+"Here we collect those canvases to archive them in a proper way (which is "
+"currently just one)."
msgstr ""
-#: src/ui/placePixel.js:207
-msgid "This canvas doesn't exist"
+#: src/components/ArchiveModal.jsx:24
+msgid "Political Compass Canvas"
msgstr ""
-#: src/ui/placePixel.js:210
-#: src/ui/placePixel.js:214
-#: src/ui/placePixel.js:218
-msgid "Invalid Coordinates"
+#: src/components/ArchiveModal.jsx:31
+msgid ""
+"This canvas got requested during a time of political conflicts on the main "
+"Earth canvas. It was a 1024x1024 representation of the political compass "
+"with a 5s coolodwn and 60s stacking. It got launched on May 11th and "
+"remained active for months till it got shut down on November 30th."
msgstr ""
-#: src/ui/placePixel.js:211
-msgid "x out of bounds"
+#: src/components/ArchiveModal.jsx:32
+msgid ""
+"We decided to archive it as a timelapse with lossless encoded webm. Taking "
+"a screenshot from the timelapse results in a perfect 1:1 representation of "
+"how the canvas was at that time."
msgstr ""
-#: src/ui/placePixel.js:215
-msgid "y out of bounds"
+#: src/components/ArchiveModal.jsx:50
+msgid "Canvas Archive"
msgstr ""
-#: src/ui/placePixel.js:219
-msgid "z out of bounds"
+#: src/components/CanvasSelectModal.jsx:29
+msgid ""
+"Select the canvas you want to use. Every canvas is unique and has different "
+"palettes, cooldown and requirements. Archive of closed canvases can be "
+"accessed here:"
msgstr ""
-#: src/ui/placePixel.js:222
-msgid "Wrong Color"
-msgstr ""
-
-#: src/ui/placePixel.js:223
-msgid "Invalid color selected"
-msgstr ""
-
-#: src/ui/placePixel.js:226
-msgid "Just for registered Users"
-msgstr ""
-
-#: src/ui/placePixel.js:227
-msgid "You have to be logged in to place on this canvas"
-msgstr ""
-
-#: src/ui/placePixel.js:230
-msgid "Place more :)"
-msgstr ""
-
-#: src/ui/placePixel.js:232
-msgid "You can not access this canvas yet. You need to place more pixels"
-msgstr ""
-
-#: src/ui/placePixel.js:235
-msgid "Pixel protected!"
-msgstr ""
-
-#: src/ui/placePixel.js:251
-msgid "No Proxies Allowed :("
-msgstr ""
-
-#: src/ui/placePixel.js:252
-msgid "You are using a Proxy."
-msgstr ""
-
-#: src/ui/placePixel.js:255
-msgid "Weird"
-msgstr ""
-
-#: src/ui/placePixel.js:256
-msgid "Couldn't set Pixel"
-msgstr ""
-
-#: src/ui/placePixel.js:262
-#, javascript-format
-msgid "Error ${ retCode }"
-msgstr ""
-
-#: src/components/Admintools.jsx:219
-#: src/components/ChannelContextMenu.jsx:85
-#: src/components/ModalRoot.jsx:60
-msgid "Close"
-msgstr ""
-
-#: src/components/ExpandMenuButton.jsx:19
-msgid "Close Menu"
-msgstr ""
-
-#: src/components/ExpandMenuButton.jsx:19
-msgid "Open Menu"
-msgstr ""
-
-#: src/components/ChatButton.jsx:61
-msgid "Close Chat"
-msgstr ""
-
-#: src/components/ChatButton.jsx:61
-msgid "Open Chat"
-msgstr ""
-
-#: src/components/Converter.jsx:609
-#: src/components/CoordinatesBox.jsx:26
-msgid "Copy to Clipboard"
-msgstr ""
-
-#: src/components/OnlineBox.jsx:22
-msgid "User online"
-msgstr ""
-
-#: src/components/OnlineBox.jsx:25
-msgid "Pixels placed"
+#: src/components/CanvasSelectModal.jsx:37
+msgid "Archive"
msgstr ""
#: src/components/CanvasSelectModal.jsx:67
-#: src/components/CanvasSwitchButton.jsx:20
msgid "Canvas Selection"
msgstr ""
-#: src/components/DownloadButton.jsx:37
-msgid "Make Screenshot"
+#: src/components/ChatModal.jsx:35
+msgid "Chat"
+msgstr ""
+
+#: src/components/RegisterModal.jsx:18
+msgid "Register new account here"
+msgstr ""
+
+#: src/components/RegisterModal.jsx:38
+msgid "Register New Account"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:33
+msgid "Login to access more features and stats."
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:35
+msgid "Login with Name or Mail:"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:42
+msgid "I forgot my Password."
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:43
+msgid "or login with:"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:84
+msgid "or register here:"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:85
+msgid "Register"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:107
+msgid "Profile"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:113
+msgid "Ranking"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:116
+msgid "Converter"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:122
+msgid "Admintools"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:122
+msgid "Modtools"
+msgstr ""
+
+#: src/components/UserAreaModal.jsx:123
+msgid "Loading..."
msgstr ""
#: src/components/LogInButton.jsx:20
@@ -145,59 +134,93 @@ msgstr ""
msgid "User Area"
msgstr ""
+#: src/components/SettingsModal.jsx:123
+msgid "Show Grid"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:124
+msgid "Turn on grid to highlight pixel borders."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:130
+msgid "Show Pixel Activity"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:131
+msgid "Show circles where pixels are placed."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:137
+msgid "Disable Game Sounds"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:139
+msgid "All sound effects will be disabled."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:145
+msgid "Enable chat notifications"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:146
+msgid "Play a sound when new chat messages arrive"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:151
+msgid "Auto Zoom In"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:153
+msgid ""
+"Zoom in instead of placing a pixel when you tap the canvas and your zoom is "
+"small."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:158
+msgid "Compact Palette"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:160
+msgid "Display Palette in a compact form that takes less screen space."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:165
+msgid "Potato Mode"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:166
+msgid "For when you are playing on a potato."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:171
+msgid "Light Grid"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:172
+msgid "Show Grid in white instead of black."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:179
+msgid "Historical View"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:180
+msgid "Check out past versions of the canvas."
+msgstr ""
+
+#: src/components/SettingsModal.jsx:188
+msgid "Themes"
+msgstr ""
+
+#: src/components/SettingsModal.jsx:189
+msgid "How pixelplanet should look like."
+msgstr ""
+
#: src/components/SettingsButton.jsx:20
#: src/components/SettingsModal.jsx:267
msgid "Settings"
msgstr ""
-#: src/components/HelpButton.jsx:20
-msgid "Help"
-msgstr ""
-
-#: src/components/Chat.jsx:143
-msgid "Channel settings"
-msgstr ""
-
-#: src/components/Chat.jsx:152
-msgid "maximize"
-msgstr ""
-
-#: src/components/Chat.jsx:168
-msgid "Start chatting here"
-msgstr ""
-
-#: src/components/Chat.jsx:200
-msgid "Chat here"
-msgstr ""
-
-#: src/components/Chat.jsx:220
-msgid "You must be logged in to chat"
-msgstr ""
-
-#: src/components/PalselButton.jsx:25
-msgid "Close Palette"
-msgstr ""
-
-#: src/components/PalselButton.jsx:25
-msgid "Open Palette"
-msgstr ""
-
-#: src/components/GlobeButton.jsx:31
-msgid "Globe View"
-msgstr ""
-
-#: src/components/UserContextMenu.jsx:72
-msgid "Ping"
-msgstr ""
-
-#: src/components/UserContextMenu.jsx:97
-msgid "DM"
-msgstr ""
-
-#: src/components/UserContextMenu.jsx:107
-msgid "Block"
-msgstr ""
-
#: src/components/HelpModal.jsx:34
#: src/components/HelpModal.jsx:35
msgid "Privacy Policy"
@@ -395,652 +418,60 @@ msgstr ""
msgid "Mute"
msgstr ""
-#: src/components/SettingsModal.jsx:123
-msgid "Show Grid"
+#: src/components/ChannelContextMenu.jsx:85
+msgid "Close"
msgstr ""
-#: src/components/SettingsModal.jsx:124
-msgid "Turn on grid to highlight pixel borders."
+#: src/components/UserContextMenu.jsx:72
+msgid "Ping"
msgstr ""
-#: src/components/SettingsModal.jsx:130
-msgid "Show Pixel Activity"
+#: src/components/UserContextMenu.jsx:97
+msgid "DM"
msgstr ""
-#: src/components/SettingsModal.jsx:131
-msgid "Show circles where pixels are placed."
+#: src/components/UserContextMenu.jsx:107
+msgid "Block"
msgstr ""
-#: src/components/SettingsModal.jsx:137
-msgid "Disable Game Sounds"
+#: src/components/PalselButton.jsx:25
+msgid "Close Palette"
msgstr ""
-#: src/components/SettingsModal.jsx:139
-msgid "All sound effects will be disabled."
+#: src/components/PalselButton.jsx:25
+msgid "Open Palette"
msgstr ""
-#: src/components/SettingsModal.jsx:145
-msgid "Enable chat notifications"
+#: src/components/GlobeButton.jsx:31
+msgid "Globe View"
msgstr ""
-#: src/components/SettingsModal.jsx:146
-msgid "Play a sound when new chat messages arrive"
+#: src/components/DownloadButton.jsx:37
+msgid "Make Screenshot"
msgstr ""
-#: src/components/SettingsModal.jsx:151
-msgid "Auto Zoom In"
+#: src/components/HelpButton.jsx:20
+msgid "Help"
msgstr ""
-#: src/components/SettingsModal.jsx:153
-msgid ""
-"Zoom in instead of placing a pixel when you tap the canvas and your zoom is "
-"small."
+#: src/components/Chat.jsx:143
+msgid "Channel settings"
msgstr ""
-#: src/components/SettingsModal.jsx:158
-msgid "Compact Palette"
+#: src/components/Chat.jsx:152
+msgid "maximize"
msgstr ""
-#: src/components/SettingsModal.jsx:160
-msgid "Display Palette in a compact form that takes less screen space."
+#: src/components/Chat.jsx:168
+msgid "Start chatting here"
msgstr ""
-#: src/components/SettingsModal.jsx:165
-msgid "Potato Mode"
+#: src/components/Chat.jsx:200
+msgid "Chat here"
msgstr ""
-#: src/components/SettingsModal.jsx:166
-msgid "For when you are playing on a potato."
-msgstr ""
-
-#: src/components/Converter.jsx:423
-#: src/components/SettingsModal.jsx:171
-msgid "Light Grid"
-msgstr ""
-
-#: src/components/SettingsModal.jsx:172
-msgid "Show Grid in white instead of black."
-msgstr ""
-
-#: src/components/SettingsModal.jsx:179
-msgid "Historical View"
-msgstr ""
-
-#: src/components/SettingsModal.jsx:180
-msgid "Check out past versions of the canvas."
-msgstr ""
-
-#: src/components/SettingsModal.jsx:188
-msgid "Themes"
-msgstr ""
-
-#: src/components/SettingsModal.jsx:189
-msgid "How pixelplanet should look like."
-msgstr ""
-
-#: src/components/RegisterModal.jsx:18
-msgid "Register new account here"
-msgstr ""
-
-#: src/components/ForgotPasswordModal.jsx:20
-#: src/components/RegisterModal.jsx:21
-#: src/components/UserAreaModal.jsx:130
-msgid "Consider joining us on Guilded:"
-msgstr ""
-
-#: src/components/RegisterModal.jsx:38
-msgid "Register New Account"
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:33
-msgid "Login to access more features and stats."
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:35
-msgid "Login with Name or Mail:"
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:42
-msgid "I forgot my Password."
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:43
-msgid "or login with:"
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:84
-msgid "or register here:"
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:85
-msgid "Register"
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:107
-msgid "Profile"
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:113
-msgid "Ranking"
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:116
-msgid "Converter"
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:122
-msgid "Admintools"
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:122
-msgid "Modtools"
-msgstr ""
-
-#: src/components/UserAreaModal.jsx:123
-msgid "Loading..."
-msgstr ""
-
-#: src/components/ArchiveModal.jsx:20
-msgid ""
-"While we tend to not delete canvases, some canvases are started for fun or "
-"as a request by users who currently like a meme. Those canvases can get "
-"boring after a while and after weeks of no major change and if they really "
-"aren't worth being kept active, we decide to remove them."
-msgstr ""
-
-#: src/components/ArchiveModal.jsx:22
-msgid ""
-"Here we collect those canvases to archive them in a proper way (which is "
-"currently just one)."
-msgstr ""
-
-#: src/components/ArchiveModal.jsx:24
-msgid "Political Compass Canvas"
-msgstr ""
-
-#: src/components/ArchiveModal.jsx:31
-msgid ""
-"This canvas got requested during a time of political conflicts on the main "
-"Earth canvas. It was a 1024x1024 representation of the political compass "
-"with a 5s coolodwn and 60s stacking. It got launched on May 11th and "
-"remained active for months till it got shut down on November 30th."
-msgstr ""
-
-#: src/components/ArchiveModal.jsx:32
-msgid ""
-"We decided to archive it as a timelapse with lossless encoded webm. Taking "
-"a screenshot from the timelapse results in a perfect 1:1 representation of "
-"how the canvas was at that time."
-msgstr ""
-
-#: src/components/ArchiveModal.jsx:50
-msgid "Canvas Archive"
-msgstr ""
-
-#: src/components/CanvasSelectModal.jsx:29
-msgid ""
-"Select the canvas you want to use. Every canvas is unique and has different "
-"palettes, cooldown and requirements. Archive of closed canvases can be "
-"accessed here:"
-msgstr ""
-
-#: src/components/CanvasSelectModal.jsx:37
-msgid "Archive"
-msgstr ""
-
-#: src/components/ForgotPasswordModal.jsx:16
-msgid "Enter your mail adress and we will send you a new password:"
-msgstr ""
-
-#: src/components/ForgotPasswordModal.jsx:37
-msgid "Restore my Password"
-msgstr ""
-
-#: src/components/ChatModal.jsx:35
-msgid "Chat"
-msgstr ""
-
-#: src/components/ChangeMail.jsx:104
-#: src/components/ChangeName.jsx:82
-#: src/components/ChangePassword.jsx:120
-#: src/components/DeleteAccount.jsx:82
-#: src/components/LogInForm.jsx:97
-#: src/components/NewPasswordForm.jsx:93
-#: src/components/SignUpForm.jsx:118
-msgid "Error"
-msgstr ""
-
-#: src/components/LogInForm.jsx:104
-msgid "Name or Email"
-msgstr ""
-
-#: src/components/ChangeMail.jsx:112
-#: src/components/DeleteAccount.jsx:89
-#: src/components/LogInForm.jsx:111
-#: src/components/SignUpForm.jsx:140
-msgid "Password"
-msgstr ""
-
-#: src/components/LogInForm.jsx:115
-msgid "LogIn"
-msgstr ""
-
-#: src/components/UserArea.jsx:57
-msgid "Todays Placed Pixels"
-msgstr ""
-
-#: src/components/UserArea.jsx:61
-msgid "Daily Rank"
-msgstr ""
-
-#: src/components/UserArea.jsx:66
-msgid "Placed Pixels"
-msgstr ""
-
-#: src/components/UserArea.jsx:70
-msgid "Total Rank"
-msgstr ""
-
-#: src/components/UserArea.jsx:75
-#, javascript-format
-msgid "Your name is: ${ name }"
-msgstr ""
-
-#: src/components/UserArea.jsx:81
-msgid "Log out"
-msgstr ""
-
-#: src/components/UserArea.jsx:93
-msgid "Change Username"
-msgstr ""
-
-#: src/components/UserArea.jsx:108
-msgid "Change Mail"
-msgstr ""
-
-#: src/components/UserArea.jsx:122
-msgid "Change Password"
-msgstr ""
-
-#: src/components/UserArea.jsx:134
-msgid "Delete Account"
-msgstr ""
-
-#: src/components/UserArea.jsx:147
-msgid "Social Settings"
-msgstr ""
-
-#: src/components/Rankings.jsx:37
-msgid "Total"
-msgstr ""
-
-#: src/components/Rankings.jsx:45
-msgid "Daily"
-msgstr ""
-
-#: src/components/Rankings.jsx:49
-msgid "Ranking updates every 5 min. Daily rankings get reset at midnight UTC."
-msgstr ""
-
-#: src/components/CanvasItem.jsx:46
-msgid "Cooldown"
-msgstr ""
-
-#: src/components/CanvasItem.jsx:52
-msgid "Stacking till"
-msgstr ""
-
-#: src/components/CanvasItem.jsx:54
-msgid "Ranked"
-msgstr ""
-
-#: src/components/CanvasItem.jsx:56
-msgid "Requirements"
-msgstr ""
-
-#: src/components/CanvasItem.jsx:58
-msgid "User Account"
-msgstr ""
-
-#: src/components/CanvasItem.jsx:60
-#, javascript-format
-msgid "and ${ canvas.req } Pixels set"
-msgstr ""
-
-#: src/components/CanvasItem.jsx:64
-msgid "Dimensions"
-msgstr ""
-
-#: src/components/NewPasswordForm.jsx:83
-msgid "Sent you a mail with instructions to reset your password."
-msgstr ""
-
-#: src/components/NewPasswordForm.jsx:100
-#: src/components/SignUpForm.jsx:133
-msgid "Email"
-msgstr ""
-
-#: src/components/Admintools.jsx:306
-#: src/components/Admintools.jsx:387
-#: src/components/Admintools.jsx:461
-#: src/components/Admintools.jsx:505
-#: src/components/Admintools.jsx:589
-#: src/components/NewPasswordForm.jsx:104
-#: src/components/SignUpForm.jsx:152
-msgid "Submit"
-msgstr ""
-
-#: src/components/ChangeMail.jsx:125
-#: src/components/ChangeName.jsx:94
-#: src/components/ChangePassword.jsx:152
-#: src/components/DeleteAccount.jsx:95
-#: src/components/NewPasswordForm.jsx:106
-#: src/components/SignUpForm.jsx:158
-msgid "Cancel"
-msgstr ""
-
-#: src/components/SignUpForm.jsx:126
-msgid "Name"
-msgstr ""
-
-#: src/components/SignUpForm.jsx:149
-msgid "Confirm Password"
-msgstr ""
-
-#: src/components/Admintools.jsx:179
-msgid "Build image on canvas."
-msgstr ""
-
-#: src/components/Admintools.jsx:182
-msgid "Build image and set it to protected."
-msgstr ""
-
-#: src/components/Admintools.jsx:185
-msgid "Build image, but reset cooldown to unset-pixel cd."
-msgstr ""
-
-#: src/components/Admintools.jsx:248
-msgid "Image Upload"
-msgstr ""
-
-#: src/components/Admintools.jsx:249
-msgid "Upload images to canvas"
-msgstr ""
-
-#: src/components/Admintools.jsx:251
-msgid "File"
-msgstr ""
-
-#: src/components/Admintools.jsx:271
-msgid "Coordinates in X_Y format:"
-msgstr ""
-
-#: src/components/Admintools.jsx:311
-msgid "Pixel Protection"
-msgstr ""
-
-#: src/components/Admintools.jsx:313
-msgid ""
-"Set protection of areas (if you need finer grained control, "
-"use protect with image upload and alpha layers)"
-msgstr ""
-
-#: src/components/Admintools.jsx:392
-msgid "Rollback to Date"
-msgstr ""
-
-#: src/components/Admintools.jsx:394
-msgid "Rollback an area of the canvas to a set date (00:00 UTC)"
-msgstr ""
-
-#: src/components/Admintools.jsx:468
-msgid "IP Actions"
-msgstr ""
-
-#: src/components/Admintools.jsx:470
-msgid "Do stuff with IPs (one IP per line)"
-msgstr ""
-
-#: src/components/Admintools.jsx:510
-msgid "Manage Moderators"
-msgstr ""
-
-#: src/components/Admintools.jsx:512
-msgid "Remove Moderator"
-msgstr ""
-
-#: src/components/Admintools.jsx:544
-msgid "There are no mods"
-msgstr ""
-
-#: src/components/Admintools.jsx:549
-msgid "Assign new Mod"
-msgstr ""
-
-#: src/components/Admintools.jsx:552
-msgid "Enter UserName of new Mod"
-msgstr ""
-
-#: src/components/Admintools.jsx:561
-msgid "User Name"
-msgstr ""
-
-#: src/components/Converter.jsx:274
-msgid "Choose Canvas"
-msgstr ""
-
-#: src/components/Converter.jsx:300
-msgid "Palette Download"
-msgstr ""
-
-#: src/components/Converter.jsx:302
-#, javascript-format
-msgid "Palette for ${ gimpLink }"
-msgstr ""
-
-#: src/components/Converter.jsx:320
-#, javascript-format
-msgid "Credit for the Palette of the Moon goes to ${ starhouseLink }."
-msgstr ""
-
-#: src/components/Converter.jsx:323
-msgid "Image Converter"
-msgstr ""
-
-#: src/components/Converter.jsx:324
-msgid "Convert an image to canvas colors"
-msgstr ""
-
-#: src/components/Converter.jsx:335
-msgid "Choose Strategy"
-msgstr ""
-
-#: src/components/Converter.jsx:362
-msgid "Choose Color Mode"
-msgstr ""
-
-#: src/components/Converter.jsx:400
-msgid "Add Grid (uncheck if you need a 1:1 template)"
-msgstr ""
-
-#: src/components/Converter.jsx:425
-#: src/components/Converter.jsx:441
-msgid "Offset"
-msgstr ""
-
-#: src/components/Converter.jsx:471
-msgid "Scale Image"
-msgstr ""
-
-#: src/components/Converter.jsx:483
-msgid "Width"
-msgstr ""
-
-#: src/components/Converter.jsx:513
-msgid "Height"
-msgstr ""
-
-#: src/components/Converter.jsx:551
-msgid "Keep Ratio"
-msgstr ""
-
-#: src/components/Converter.jsx:564
-msgid "Anti Aliasing"
-msgstr ""
-
-#: src/components/Converter.jsx:578
-msgid "Reset"
-msgstr ""
-
-#: src/components/Converter.jsx:597
-msgid "Download Template"
-msgstr ""
-
-#: src/utils/validation.js:18
-msgid "Email can't be empty."
-msgstr ""
-
-#: src/utils/validation.js:19
-msgid "Email should be at least 5 characters long."
-msgstr ""
-
-#: src/utils/validation.js:20
-msgid "Email can't be longer than 40 characters."
-msgstr ""
-
-#: src/utils/validation.js:21
-msgid "Email should at least contain a dot"
-msgstr ""
-
-#: src/utils/validation.js:23
-msgid "Email should contain a @"
-msgstr ""
-
-#: src/utils/validation.js:30
-msgid "Name can't be empty."
-msgstr ""
-
-#: src/utils/validation.js:31
-msgid "Name must be at least 4 characters long"
-msgstr ""
-
-#: src/utils/validation.js:32
-msgid "Name must be shorter than 26 characters"
-msgstr ""
-
-#: src/utils/validation.js:39
-msgid "Name contains invalid character like @, /, \\ or #"
-msgstr ""
-
-#: src/utils/validation.js:54
-msgid "No password given."
-msgstr ""
-
-#: src/utils/validation.js:57
-msgid "Password must be at least 6 characters long."
-msgstr ""
-
-#: src/utils/validation.js:60
-msgid "Password must be shorter than 60 characters."
-msgstr ""
-
-#: src/utils/validation.js:74
-msgid "Could not connect to server, please try again later :("
-msgstr ""
-
-#: src/utils/validation.js:80
-msgid "I think we experienced some error :("
-msgstr ""
-
-#: src/components/SocialSettings.jsx:39
-msgid "Block all Private Messages"
-msgstr ""
-
-#: src/components/SocialSettings.jsx:57
-msgid "Unblock Users"
-msgstr ""
-
-#: src/components/SocialSettings.jsx:81
-msgid "You have no users blocked"
-msgstr ""
-
-#: src/components/ChangeMail.jsx:89
-msgid ""
-"Changed Mail successfully. We sent you a verification mail, "
-"please verify your new mail adress."
-msgstr ""
-
-#: src/components/ChangeMail.jsx:119
-msgid "New Mail"
-msgstr ""
-
-#: src/components/ChangeMail.jsx:123
-#: src/components/ChangeName.jsx:92
-#: src/components/ChangePassword.jsx:150
-msgid "Save"
-msgstr ""
-
-#: src/components/ChangePassword.jsx:18
-msgid "Passwords do not match."
-msgstr ""
-
-#: src/components/ChangePassword.jsx:103
-msgid "Changed Password successfully."
-msgstr ""
-
-#: src/components/ChangePassword.jsx:129
-msgid "Old Password"
-msgstr ""
-
-#: src/components/ChangePassword.jsx:137
-msgid "New Password"
-msgstr ""
-
-#: src/components/ChangePassword.jsx:146
-msgid "Confirm New Password"
-msgstr ""
-
-#: src/components/DeleteAccount.jsx:93
-msgid "Yes, Delete My Account!"
-msgstr ""
-
-#: src/components/UserMessages.jsx:41
-msgid "A new verification mail is getting sent to you."
-msgstr ""
-
-#: src/components/UserMessages.jsx:75
-msgid "You successfully linked your mc account."
-msgstr ""
-
-#: src/components/UserMessages.jsx:76
-msgid "You denied."
-msgstr ""
-
-#: src/components/UserMessages.jsx:94
-msgid ""
-"Please verify your mail address \n"
-"or your account could get deleted after a few days."
-msgstr ""
-
-#: src/components/UserMessages.jsx:111
-msgid "Click here to request a new verification mail."
-msgstr ""
-
-#: src/components/UserMessages.jsx:120
-#, javascript-format
-msgid "You requested to link your mc account ${ minecraftname }."
-msgstr ""
-
-#: src/components/UserMessages.jsx:140
-msgid "Accept"
-msgstr ""
-
-#: src/components/UserMessages.jsx:150
-msgid "Deny"
-msgstr ""
-
-#: src/components/ChangeName.jsx:88
-msgid "New Username"
+#: src/components/Chat.jsx:220
+msgid "You must be logged in to chat"
msgstr ""
#: src/components/HelpModal.jsx:15
@@ -1055,6 +486,11 @@ msgctxt "keybinds"
msgid "X"
msgstr ""
+#: src/components/SettingsModal.jsx:140
+msgctxt "keybinds"
+msgid "M"
+msgstr ""
+
#: src/components/HelpModal.jsx:17
#: src/components/SettingsModal.jsx:182
msgctxt "keybinds"
@@ -1104,9 +540,4 @@ msgstr ""
#: src/components/HelpModal.jsx:32
msgctxt "keybinds"
msgid "C"
-msgstr ""
-
-#: src/components/SettingsModal.jsx:140
-msgctxt "keybinds"
-msgid "M"
msgstr ""
\ No newline at end of file
diff --git a/i18n/template.txt b/i18n/template.txt
new file mode 100644
index 0000000..fb3a23d
--- /dev/null
+++ b/i18n/template.txt
@@ -0,0 +1,677 @@
+"Copied!"
+
+"Error :("
+
+"Didn't get an answer from pixelplanet. Maybe try to refresh?"
+
+"OK"
+
+"Invalid Canvas"
+
+"This canvas doesn't exist"
+
+"Invalid Coordinates"
+
+"x out of bounds"
+
+"y out of bounds"
+
+"z out of bounds"
+
+"Wrong Color"
+
+"Invalid color selected"
+
+"Just for registered Users"
+
+"You have to be logged in to place on this canvas"
+
+"Place more :)"
+
+"You can not access this canvas yet. You need to place more pixels"
+
+"Pixel protected!"
+
+"No Proxies Allowed :("
+
+"You are using a Proxy."
+
+"Weird"
+
+"Couldn't set Pixel"
+
+"Error ${ retCode }"
+
+"Close"
+
+"Close Menu"
+
+"Open Menu"
+
+"Close Chat"
+
+"Open Chat"
+
+"Copy to Clipboard"
+
+"User online"
+
+"Pixels placed"
+
+"Canvas Selection"
+
+"Make Screenshot"
+
+"User Area"
+
+"Settings"
+
+"Help"
+
+"Channel settings"
+
+"maximize"
+
+"Start chatting here"
+
+"Chat here"
+
+"You must be logged in to chat"
+
+"Close Palette"
+
+"Open Palette"
+
+"Globe View"
+
+"Ping"
+
+"DM"
+
+"Block"
+
+"Privacy Policy"
+
+"Terms of Service"
+
+"your IP"
+
+"Place color pixels on a large canvas with other players online!"
+
+""
+"Our main canvas is a huge worldmap, you can place wherever you like, but "
+"you will have to wait a specific Cooldown between pixels. You can check out "
+"the cooldown and requiremnts on the Canvas Selection menu (globe button on "
+"top). Some canvases have a different cooldown for replacing a user-set "
+"pixels than placing on a unset pixel. i.e. 4s/7s means 4s on fresh pixels "
+"and 7s on already set pixels."
+
+""
+"Higher zoomlevels take some time to update, the 3D globe gets updated at "
+"least once per day."
+
+"Have fun!"
+
+"recommended"
+
+"Source on "
+
+"Map Data"
+
+""
+"The bare map data that we use, together with converted OpenStreetMap tiles "
+"for orientation, can be downloaded from mega.nz here: "
+
+"Detected as Proxy?"
+
+""
+"If you got detected as proxy, but you are none, please go to our ${ "
+"guildedLink } or send us an e-mail with ${ getIPLink } to ${ mailLink }. Do "
+"not post your IP anywhere else. We are sorry for the inconvenience."
+
+"Controls"
+
+"Click a color in palette to select it"
+
+"Press ${ bindG } to toggle grid"
+
+"Press ${ bindX } to toggle showing of pixel activity"
+
+"Press ${ bindH } to toggle historical view"
+
+"Press ${ bindR } to copy coordinates"
+
+"Press ${ bindQ } or ${ bindE } to zoom"
+
+"Press ${ bindW }, ${ bindA }, ${ bindS }, ${ bindD } to move"
+
+"Press ${ bindAUp }, ${ bindALeft }, ${ bindADown }, ${ bindARight } to move"
+
+"Drag ${ mouseSymbol } mouse or ${ touchSymbol } pan to move"
+
+"Scroll ${ mouseSymbol } mouse wheel or ${ touchSymbol } pinch to zoom"
+
+"Hold left ${ bindShift } for placing while moving mouse"
+
+""
+"Hold right ${ bindShift } for placing while moving mouse according to "
+"historical view"
+
+"${ mouseSymbol } Left click or ${ touchSymbol } tap to place a pixel"
+
+""
+"Click ${ mouseSymbol } middle mouse button or ${ touchSymbol } long-tap to "
+"select current hovering color"
+
+"Press ${ bindE } and ${ bindC } to fly up and down"
+
+"${ mouseSymbol } Hold left mouse button and drag mouse to rotate"
+
+""
+"${ mouseSymbol } Scroll mouse wheel or hold ${ mouseSymbol } middle mouse "
+"button and drag to zoom"
+
+"${ mouseSymbol } Right click and drag mouse to pan"
+
+""
+"${ mouseSymbol } Right click or ${ touchSymbol } double-tap to remove a "
+"pixel"
+
+"Partners:"
+
+""
+"This site is protected by reCAPTCHA and the Google ${ reCaptchaPP } and ${ "
+"reCaptchaTOS } apply."
+
+""
+"This site is protected by hCAPTCHA and its ${ hCaptchaPP } and ${ "
+"hCaptchaTOS } apply."
+
+"Welcome to PixelPlanet.fun"
+
+"Mute"
+
+"Show Grid"
+
+"Turn on grid to highlight pixel borders."
+
+"Show Pixel Activity"
+
+"Show circles where pixels are placed."
+
+"Disable Game Sounds"
+
+"All sound effects will be disabled."
+
+"Enable chat notifications"
+
+"Play a sound when new chat messages arrive"
+
+"Auto Zoom In"
+
+""
+"Zoom in instead of placing a pixel when you tap the canvas and your zoom is "
+"small."
+
+"Compact Palette"
+
+"Display Palette in a compact form that takes less screen space."
+
+"Potato Mode"
+
+"For when you are playing on a potato."
+
+"Light Grid"
+
+"Show Grid in white instead of black."
+
+"Historical View"
+
+"Check out past versions of the canvas."
+
+"Themes"
+
+"How pixelplanet should look like."
+
+"Register new account here"
+
+"Consider joining us on Guilded:"
+
+"Register New Account"
+
+"Login to access more features and stats."
+
+"Login with Name or Mail:"
+
+"I forgot my Password."
+
+"or login with:"
+
+"or register here:"
+
+"Register"
+
+"Profile"
+
+"Ranking"
+
+"Converter"
+
+"Admintools"
+
+"Modtools"
+
+"Loading..."
+
+""
+"While we tend to not delete canvases, some canvases are started for fun or "
+"as a request by users who currently like a meme. Those canvases can get "
+"boring after a while and after weeks of no major change and if they really "
+"aren't worth being kept active, we decide to remove them."
+
+""
+"Here we collect those canvases to archive them in a proper way (which is "
+"currently just one)."
+
+"Political Compass Canvas"
+
+""
+"This canvas got requested during a time of political conflicts on the main "
+"Earth canvas. It was a 1024x1024 representation of the political compass "
+"with a 5s coolodwn and 60s stacking. It got launched on May 11th and "
+"remained active for months till it got shut down on November 30th."
+
+""
+"We decided to archive it as a timelapse with lossless encoded webm. Taking "
+"a screenshot from the timelapse results in a perfect 1:1 representation of "
+"how the canvas was at that time."
+
+"Canvas Archive"
+
+""
+"Select the canvas you want to use. Every canvas is unique and has different "
+"palettes, cooldown and requirements. Archive of closed canvases can be "
+"accessed here:"
+
+"Archive"
+
+"Enter your mail adress and we will send you a new password:"
+
+"Restore my Password"
+
+"Chat"
+
+"Error"
+
+"Name or Email"
+
+"Password"
+
+"LogIn"
+
+"Todays Placed Pixels"
+
+"Daily Rank"
+
+"Placed Pixels"
+
+"Total Rank"
+
+"Your name is: ${ name }"
+
+"Log out"
+
+"Change Username"
+
+"Change Mail"
+
+"Change Password"
+
+"Delete Account"
+
+"Social Settings"
+
+"Total"
+
+"Daily"
+
+"Ranking updates every 5 min. Daily rankings get reset at midnight UTC."
+
+"Cooldown"
+
+"Stacking till"
+
+"Ranked"
+
+"Requirements"
+
+"User Account"
+
+"and ${ canvas.req } Pixels set"
+
+"Dimensions"
+
+"Sent you a mail with instructions to reset your password."
+
+"Email"
+
+"Submit"
+
+"Cancel"
+
+"Name"
+
+"Confirm Password"
+
+"Build image on canvas."
+
+"Build image and set it to protected."
+
+"Build image, but reset cooldown to unset-pixel cd."
+
+"Image Upload"
+
+"Upload images to canvas"
+
+"File"
+
+"Coordinates in X_Y format:"
+
+"Pixel Protection"
+
+""
+"Set protection of areas (if you need finer grained control, "
+"use protect with image upload and alpha layers)"
+
+"Rollback to Date"
+
+"Rollback an area of the canvas to a set date (00:00 UTC)"
+
+"IP Actions"
+
+"Do stuff with IPs (one IP per line)"
+
+"Manage Moderators"
+
+"Remove Moderator"
+
+"There are no mods"
+
+"Assign new Mod"
+
+"Enter UserName of new Mod"
+
+"User Name"
+
+"Choose Canvas"
+
+"Palette Download"
+
+"Palette for ${ gimpLink }"
+
+"Credit for the Palette of the Moon goes to ${ starhouseLink }."
+
+"Image Converter"
+
+"Convert an image to canvas colors"
+
+"Choose Strategy"
+
+"Choose Color Mode"
+
+"Add Grid (uncheck if you need a 1:1 template)"
+
+"Offset"
+
+"Scale Image"
+
+"Width"
+
+"Height"
+
+"Keep Ratio"
+
+"Anti Aliasing"
+
+"Reset"
+
+"Download Template"
+
+"Email can't be empty."
+
+"Email should be at least 5 characters long."
+
+"Email can't be longer than 40 characters."
+
+"Email should at least contain a dot"
+
+"Email should contain a @"
+
+"Name can't be empty."
+
+"Name must be at least 4 characters long"
+
+"Name must be shorter than 26 characters"
+
+"Name contains invalid character like @, /, \\ or #"
+
+"No password given."
+
+"Password must be at least 6 characters long."
+
+"Password must be shorter than 60 characters."
+
+"Could not connect to server, please try again later :("
+
+"I think we experienced some error :("
+
+"Block all Private Messages"
+
+"Unblock Users"
+
+"You have no users blocked"
+
+""
+"Changed Mail successfully. We sent you a verification mail, "
+"please verify your new mail adress."
+
+"New Mail"
+
+"Save"
+
+"Passwords do not match."
+
+"Changed Password successfully."
+
+"Old Password"
+
+"New Password"
+
+"Confirm New Password"
+
+"Yes, Delete My Account!"
+
+"A new verification mail is getting sent to you."
+
+"You successfully linked your mc account."
+
+"You denied."
+
+""
+"Please verify your mail address \n"
+"or your account could get deleted after a few days."
+
+"Click here to request a new verification mail."
+
+"You requested to link your mc account ${ minecraftname }."
+
+"Accept"
+
+"Deny"
+
+"New Username"
+
+"Place color pixels on an map styled canvas with other players online"
+
+"Double click on globe to go back."
+
+"Loading..."
+
+"PixelPlanet.Fun 3DGlobe"
+
+"A 3D globe of our whole map"
+
+"You sent an empty password or invalid data :("
+
+"This password-reset link isn't valid anymore :("
+
+"Your passwords do not match :("
+
+"User doesn't exist in our database :("
+
+"Passowrd successfully changed."
+
+"Invalid url :( Please check your mail again."
+
+"This passwort reset link is wrong or already expired, please request a new "
+"one (Note: you can use those links just once)"
+
+""
+"We already sent you a verification mail, you can request another one in ${ "
+"minLeft } minutes."
+
+"Welcome ${ name } to PixelPlanet, plese verify your mail"
+
+"Hello ${ name }"
+
+""
+"welcome to our little community of pixelplacers, to use your account, you "
+"have to verify your mail. You can do that here: "
+
+"Click to Verify"
+
+"Or by copying following url:"
+
+"Have fun and don't hesitate to contact us if you encouter any problems :)"
+
+"Thanks"
+
+""
+"We already sent you a mail with instructions. Please wait before requesting "
+"another mail."
+
+"Couldn't find this mail in our database"
+
+"You forgot your password for PixelPlanet? Get a new one here"
+
+"Hello"
+
+""
+"You requested to get a new password. You can change your password within "
+"the next 30min here: "
+
+"Reset Password"
+
+""
+"If you did not request this mail, please just ignore it (the ip that "
+"requested this mail was ${ ip })."
+
+"Click here"
+
+"to go back to pixelplanet"
+
+"Hello ${ name }, you can set your new password here:"
+
+"New Password"
+
+"Confirm New Password"
+
+"Submit"
+
+"PixelPlanet.fun Password Reset"
+
+"Reset your password here"
+
+"Email can't be empty."
+
+"Email should be at least 5 characters long."
+
+"Email can't be longer than 40 characters."
+
+"Email should at least contain a dot"
+
+"Email should contain a @"
+
+"Name can't be empty."
+
+"Name must be at least 4 characters long"
+
+"Name must be shorter than 26 characters"
+
+"Name contains invalid character like @, /, \\ or #"
+
+"No password given."
+
+"Password must be at least 6 characters long."
+
+"Password must be shorter than 60 characters."
+
+"Could not connect to server, please try again later :("
+
+"I think we experienced some error :("
+
+"You are not authenticated."
+
+"Incorrect password!"
+
+"You are not even logged in."
+
+"Mail verification"
+
+"You are now verified :)"
+
+""
+"Your mail verification code is invalid or already expired :(, please "
+"request a new one."
+
+"E-Mail already in use."
+
+"Username already in use."
+
+"Failed to create new user :("
+
+"Failed to establish session after register :("
+
+"You will be automatically redirected after 15s"
+
+"Or ${ clickHere } to go back to pixelplanet"
+
+"PixelPlanet.fun Accounts"
+
+"Earth"
+
+"Moon"
+
+"3D Canvas"
+
+"Coronavirus"
+
+"PixelZone"
+
+"PixelCanvas"
+
+"1bit"
+
+"Our main canvas, a huge map of the world. Place everywhere you like"
+
+"Moon canvas. Safe space for art. No flags or large text (unless part of art)"
+
+"Place Voxels on a 3D canvas with others"
+
+"Special canvas to spread awareness of SARS-CoV2"
+
+"Mirror of PixelZone"
+
+"Mirror of PixelCanvas"
+
+"Black and White canvas"
diff --git a/package-lock.json b/package-lock.json
index 9e39269..6799751 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3562,6 +3562,12 @@
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
"dev": true
},
+ "easy-stack": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz",
+ "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==",
+ "dev": true
+ },
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -3651,6 +3657,15 @@
"integrity": "sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA==",
"dev": true
},
+ "errno": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+ "dev": true,
+ "requires": {
+ "prr": "~1.0.1"
+ }
+ },
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -4306,6 +4321,12 @@
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
+ "event-pubsub": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz",
+ "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==",
+ "dev": true
+ },
"events": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
@@ -5477,6 +5498,21 @@
"resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz",
"integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg=="
},
+ "js-message": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
+ "integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==",
+ "dev": true
+ },
+ "js-queue": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.2.tgz",
+ "integrity": "sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==",
+ "dev": true,
+ "requires": {
+ "easy-stack": "^1.0.1"
+ }
+ },
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -5524,6 +5560,15 @@
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
},
+ "json-stable-stringify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+ "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+ "dev": true,
+ "requires": {
+ "jsonify": "~0.0.0"
+ }
+ },
"json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
@@ -5538,6 +5583,12 @@
"minimist": "^1.2.5"
}
},
+ "jsonify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+ "dev": true
+ },
"jsx-ast-utils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.1.0.tgz",
@@ -5834,12 +5885,30 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
},
+ "lodash.assign": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
+ "dev": true
+ },
"lodash.clonedeep": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
"dev": true
},
+ "lodash.endswith": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/lodash.endswith/-/lodash.endswith-4.2.1.tgz",
+ "integrity": "sha1-/tWawXOO0+I27dcGTsRWRIs3vAk=",
+ "dev": true
+ },
+ "lodash.flatten": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
+ "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=",
+ "dev": true
+ },
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
@@ -6312,6 +6381,17 @@
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
"integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg=="
},
+ "node-ipc": {
+ "version": "9.1.3",
+ "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.3.tgz",
+ "integrity": "sha512-8RS4RZyS/KMKKYG8mrje+cLxwATe9dBCuOiqKFSWND4oOuKytfuKCiR9yinvhoXF/nGdX/WnbywaUee+9U87zA==",
+ "dev": true,
+ "requires": {
+ "event-pubsub": "4.3.0",
+ "js-message": "1.0.7",
+ "js-queue": "2.0.2"
+ }
+ },
"node-modules-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
@@ -6850,6 +6930,59 @@
"semver": "^5.1.0"
}
},
+ "parallel-webpack": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/parallel-webpack/-/parallel-webpack-2.6.0.tgz",
+ "integrity": "sha512-aOOLfQ40yWWRt8214F0zNWp0DWbeCs7tJaEur0/XUlYU8Yht1sMTYt+eNrbY4VkM4O/SRSme7cdZJTtIantiOw==",
+ "dev": true,
+ "requires": {
+ "ajv": "^4.9.2",
+ "bluebird": "^3.0.6",
+ "chalk": "^1.1.1",
+ "interpret": "^1.0.1",
+ "lodash.assign": "^4.0.8",
+ "lodash.endswith": "^4.0.1",
+ "lodash.flatten": "^4.2.0",
+ "minimist": "^1.2.0",
+ "node-ipc": "^9.1.0",
+ "pluralize": "^1.2.1",
+ "supports-color": "^3.1.2",
+ "worker-farm": "^1.3.1"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+ "dev": true,
+ "requires": {
+ "co": "^4.6.0",
+ "json-stable-stringify": "^1.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "^1.0.0"
+ }
+ }
+ }
+ },
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -7123,6 +7256,12 @@
"resolved": "https://registry.npmjs.org/plural-forms/-/plural-forms-0.5.3.tgz",
"integrity": "sha512-t/hkjsTeDwaK9n/z6tUiSHySTC8sPnTiS5YF3Y5p4L+eomzXh7O0vEemkjwb68/82w0Rjw4uED3X84X7vXf9lg=="
},
+ "pluralize": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
+ "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=",
+ "dev": true
+ },
"postcss": {
"version": "8.1.10",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.1.10.tgz",
@@ -7287,6 +7426,12 @@
"ipaddr.js": "1.9.1"
}
},
+ "prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+ "dev": true
+ },
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
@@ -10090,6 +10235,15 @@
"typical": "^5.0.0"
}
},
+ "worker-farm": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+ "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
+ "dev": true,
+ "requires": {
+ "errno": "~0.1.7"
+ }
+ },
"wrap-ansi": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
diff --git a/package.json b/package.json
index 20340b1..65cfa40 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"scripts": {
"build": "babel-node scripts/run prebuild && npm run webpack",
"clean": "babel-node scripts/run clean",
- "webpack": "webpack --config webpack.config.web.babel.js && webpack --config webpack.config.client.babel.js",
+ "webpack": "webpack --config ./webpack.config.web.babel.js && parallel-webpack --config ./webpack.config.client.babel.js",
"babel-node": "cd $INIT_CWD && babel-node",
"lint": "cd $INIT_CWD && eslint --ext .jsx --ext .js",
"lint:src": "eslint --ext .jsx --ext .js src",
@@ -133,6 +133,7 @@
"json-loader": "^0.5.4",
"mkdirp": "^1.0.4",
"npm-check": "^5.9.2",
+ "parallel-webpack": "^2.6.0",
"react-hot-loader": "^4.13.0",
"react-svg-loader": "^3.0.3",
"rimraf": "^3.0.2",
diff --git a/src/components/ChatMessage.jsx b/src/components/ChatMessage.jsx
index d1e1cff..483d659 100644
--- a/src/components/ChatMessage.jsx
+++ b/src/components/ChatMessage.jsx
@@ -82,6 +82,14 @@ function ChatMessage({
return ({txt});
} if (type === 'c') {
return ({txt});
+ } if (type === 'l') {
+ return (
+ {txt}
+ );
} if (type === 'p') {
return (
4
- && message === message.toUpperCase()
- && message !== message.toLowerCase()
- ) {
- return 'Stop shouting';
+ if (!user.regUser.verified) {
+ return t`Your mail has to be verified in order to chat`;
}
const muted = await ChatProvider.checkIfMuted(user);
if (muted === -1) {
- return 'You are permanently muted, join our guilded to apppeal the mute';
+ return t`You are permanently muted, join our guilded to apppeal the mute`;
}
if (muted > 0) {
if (muted > 120) {
const timeMin = Math.round(muted / 60);
- return `You are muted for another ${timeMin} minutes`;
+ return t`You are muted for another ${timeMin} minutes`;
}
- return `You are muted for another ${muted} seconds`;
+ return t`You are muted for another ${muted} seconds`;
}
for (let i = 0; i < this.filters.length; i += 1) {
@@ -285,7 +299,7 @@ export class ChatProvider {
const count = (message.match(filter.regexp) || []).length;
if (count >= filter.matches) {
this.mute(name, channelId, 30);
- return 'Ow no! Spam protection decided to mute you';
+ return t`Ow no! Spam protection decided to mute you`;
}
}
@@ -294,21 +308,17 @@ export class ChatProvider {
message = message.replace(subsitute.regexp, subsitute.replace);
}
- if (message.includes('http')) {
- return 'no shitty links pls';
- }
-
if (message.length > 200) {
// eslint-disable-next-line max-len
- return 'You can\'t send a message this long :(';
+ return t`You can\'t send a message this long :(`;
}
if (message.match(this.cyrillic) && channelId === this.enChannelId) {
- return 'Please use int channel';
+ return t`Please use int channel`;
}
if (this.mutedCountries.includes(country)) {
- return 'Your country is temporary muted from chat';
+ return t`Your country is temporary muted from chat`;
}
if (user.last_message && user.last_message === message) {
@@ -316,7 +326,7 @@ export class ChatProvider {
if (user.message_repeat >= 4) {
this.mute(name, channelId, 60);
user.message_repeat = 0;
- return 'Stop flooding.';
+ return t`Stop flooding.`;
}
} else {
user.message_repeat = 0;
diff --git a/src/core/chatMessageFilter.js b/src/core/chatMessageFilter.js
index 26707c3..fb80ca7 100644
--- a/src/core/chatMessageFilter.js
+++ b/src/core/chatMessageFilter.js
@@ -8,14 +8,17 @@
* splits chat message into array of what it represents
* [[type, text],[type, text], ...]
* type:
+ * 'l': external link
* 't': text
* 'p': ping
- * 'c': coordinates
+ * 'c': coordinates or ppfun link
* 'm': mention of somebody else
* nameRegExp has to be in the form of:
new RegExp(`(^|\\s+)(@${ownName})(\\s+|$)`, 'g');
*/
-const linkRegExp = /(#[a-z]*,-?[0-9]*,-?[0-9]*(,-?[0-9]+)?)/gi;
+// eslint-disable-next-line
+const linkRegExp = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi;
+const ppLinkRegExp = /(#[a-z]*,-?[0-9]*,-?[0-9]*(,-?[0-9]+)?)/gi;
const linkRegExpFilter = (val, ind) => ((ind % 3) !== 2);
const mentionRegExp = /(^|\s)(@\S+)/g;
const spaceFilter = (val, ind) => (val !== ' ' && (ind !== 0 | val !== ''));
@@ -49,10 +52,11 @@ function splitChatMessage(message, nameRegExp = null) {
return null;
}
let arr = [['t', message.trim()]];
- arr = splitChatMessageRegexp(arr, linkRegExp, 'c', linkRegExpFilter);
+ arr = splitChatMessageRegexp(arr, ppLinkRegExp, 'c', linkRegExpFilter);
if (nameRegExp) {
arr = splitChatMessageRegexp(arr, nameRegExp, 'p', spaceFilter);
}
+ arr = splitChatMessageRegexp(arr, linkRegExp, 'l', linkRegExpFilter);
arr = splitChatMessageRegexp(arr, mentionRegExp, 'm', spaceFilter);
return arr;
}
diff --git a/src/socket/SocketServer.js b/src/socket/SocketServer.js
index 13fd1b9..f67d1ad 100644
--- a/src/socket/SocketServer.js
+++ b/src/socket/SocketServer.js
@@ -340,6 +340,7 @@ class SocketServer extends WebSocketEvents {
user,
message,
channelId,
+ user.ttag,
);
if (errorMsg) {
ws.send(JSON.stringify([
diff --git a/src/socket/verifyClient.js b/src/socket/verifyClient.js
index f09e27f..d6fd682 100644
--- a/src/socket/verifyClient.js
+++ b/src/socket/verifyClient.js
@@ -7,6 +7,7 @@ import express from 'express';
import session from '../core/session';
import passport from '../core/passport';
import User from '../data/models/User';
+import { expressTTag } from '../core/ttag';
import { getIPFromRequest } from '../utils/ip';
const router = express.Router();
@@ -16,6 +17,8 @@ router.use(session);
router.use(passport.initialize());
router.use(passport.session());
+router.use(expressTTag);
+
function authenticateClient(req) {
return new Promise(
@@ -26,6 +29,7 @@ function authenticateClient(req) {
const user = (req.user) ? req.user
: new User(null, getIPFromRequest(req));
user.setCountry(countryCode);
+ user.ttag = req.ttag;
resolve(user);
});
}),
diff --git a/webpack.config.client.babel.js b/webpack.config.client.babel.js
index 5659d9d..70f2f28 100644
--- a/webpack.config.client.babel.js
+++ b/webpack.config.client.babel.js
@@ -113,7 +113,7 @@ export function buildWebpackClientConfig(development, analyze, locale) {
path.resolve(__dirname, 'src'),
],
options: {
- cacheDirectory: development,
+ cacheDirectory: true,
babelrc: false,
presets: [
['@babel/preset-env', {
@@ -194,7 +194,18 @@ export function buildWebpackClientConfig(development, analyze, locale) {
chunkModules: false,
},
- cache: true,
+ /*
+ * this does not much tbqh
+ cache: {
+ type: 'filesystem',
+ cacheDirectory: path.resolve(
+ __dirname,
+ 'node_modules',
+ '.cache',
+ 'webpack',
+ ),
+ },
+ */
};
}