Compare commits
	
		
			472 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					c40b630530 | ||
| 
						 | 
					7fc0698ecf | ||
| 
						 | 
					4f3c8b940e | ||
| 
						 | 
					1855ab60f1 | ||
| 
						 | 
					af4f1a7bd6 | ||
| 
						 | 
					8646a9c49c | ||
| 
						 | 
					8d7c033cf5 | ||
| 
						 | 
					b8900e32de | ||
| 
						 | 
					d48c25d2c9 | ||
| 
						 | 
					a87c5899c5 | ||
| 
						 | 
					147ad69864 | ||
| 
						 | 
					c146006476 | ||
| 
						 | 
					a0f10d7ca1 | ||
| 
						 | 
					299b91edc4 | ||
| 
						 | 
					95c89ca6db | ||
| 
						 | 
					7fe0d71e7f | ||
| 
						 | 
					fbbb506e86 | ||
| 
						 | 
					ec80b06a45 | ||
| 
						 | 
					41e1619f1f | ||
| 
						 | 
					ba6a9c6a93 | ||
| 
						 | 
					18571c52fb | ||
| 
						 | 
					5d5dfeaa83 | ||
| 
						 | 
					3669d8c0f3 | ||
| 
						 | 
					69d72819c6 | ||
| 
						 | 
					54dcc10250 | ||
| 
						 | 
					1edfce8f73 | ||
| 
						 | 
					675e573a8c | ||
| 
						 | 
					1080fa63a9 | ||
| 
						 | 
					8047086988 | ||
| 
						 | 
					449b9f7fa0 | ||
| 
						 | 
					b7a15bf6ca | ||
| 
						 | 
					7c3873887d | ||
| 
						 | 
					247ea4cf12 | ||
| 
						 | 
					0b7af5c669 | ||
| 
						 | 
					2b62a4e2e5 | ||
| 
						 | 
					65bfa3c0d6 | ||
| 
						 | 
					84db15694d | ||
| 
						 | 
					746189ba37 | ||
| 
						 | 
					74e845b3ac | ||
| 
						 | 
					90fe70540e | ||
| 
						 | 
					f28af75191 | ||
| 
						 | 
					924bb2bc70 | ||
| 
						 | 
					19d60f3d51 | ||
| 
						 | 
					6903476868 | ||
| 
						 | 
					cf0dccc209 | ||
| 
						 | 
					cfd959129d | ||
| 
						 | 
					819287951c | ||
| 
						 | 
					e136193925 | ||
| 
						 | 
					8c631864d9 | ||
| 
						 | 
					d7d0f6ae2e | ||
| 
						 | 
					b83b3fb9d1 | ||
| 
						 | 
					dfce5bc0af | ||
| 
						 | 
					3487ddabea | ||
| 
						 | 
					2dbff75e7a | ||
| 
						 | 
					02465ded9f | ||
| 
						 | 
					ffcd387945 | ||
| 
						 | 
					4806346707 | ||
| 
						 | 
					31c3f6abf7 | ||
| 
						 | 
					83e47fdd60 | ||
| 
						 | 
					340ce7fa4c | ||
| 
						 | 
					ac86fee9b4 | ||
| 
						 | 
					6dfa283d7a | ||
| 
						 | 
					0cce8a4d21 | ||
| 
						 | 
					1c6d9ab2ef | ||
| 
						 | 
					6ca265e579 | ||
| 
						 | 
					c612c4bf18 | ||
| 
						 | 
					481a791a60 | ||
| 
						 | 
					cb516c2943 | ||
| 
						 | 
					c0abd6f0c0 | ||
| 
						 | 
					47695ed685 | ||
| 
						 | 
					4ca8020ef5 | ||
| 
						 | 
					bfac83d5b8 | ||
| 
						 | 
					4cd2e55fd3 | ||
| 
						 | 
					61c7e7bc48 | ||
| 
						 | 
					bef41718e2 | ||
| 
						 | 
					5b4b52bb97 | ||
| 
						 | 
					8901b6d774 | ||
| 
						 | 
					e3a24e9215 | ||
| 
						 | 
					a515c1f53e | ||
| 
						 | 
					2e22874dec | ||
| 
						 | 
					30f0b1c30d | ||
| 
						 | 
					600aea4dbb | ||
| 
						 | 
					f5d53d784d | ||
| 
						 | 
					1061e1f7ae | ||
| 
						 | 
					1d5fc04aa6 | ||
| 
						 | 
					d1cf0c7998 | ||
| 
						 | 
					84218abf2b | ||
| 
						 | 
					5bebdb2511 | ||
| 
						 | 
					9c8e9b4165 | ||
| 
						 | 
					7b786bfde3 | ||
| 
						 | 
					42a08642a4 | ||
| 
						 | 
					e88f7ca7b2 | ||
| 
						 | 
					c26ed1421b | ||
| 
						 | 
					ed2f94a3c1 | ||
| 
						 | 
					daba7fe87c | ||
| 
						 | 
					afc9caf7bf | ||
| 
						 | 
					67697a7aa6 | ||
| 
						 | 
					1623d9e70c | ||
| 
						 | 
					c304351335 | ||
| 
						 | 
					c1520763c6 | ||
| 
						 | 
					4853bc9414 | ||
| 
						 | 
					e7c865f8e3 | ||
| 
						 | 
					46cb377bc2 | ||
| 
						 | 
					373a5ba3e1 | ||
| 
						 | 
					3bedef67c8 | ||
| 
						 | 
					17ea19ada8 | ||
| 
						 | 
					1f5b2285fd | ||
| 
						 | 
					17f0001966 | ||
| 
						 | 
					04ba09a6af | ||
| 
						 | 
					70d2744319 | ||
| 
						 | 
					6b2f0929ec | ||
| 
						 | 
					f2629bd3f2 | ||
| 
						 | 
					9e6c29c3c0 | ||
| 
						 | 
					abda973094 | ||
| 
						 | 
					86b08dd5bd | ||
| 
						 | 
					617e331f0f | ||
| 
						 | 
					cc438a9372 | ||
| 
						 | 
					b0fb218bfd | ||
| 
						 | 
					fc85a607e6 | ||
| 
						 | 
					fb244c45e3 | ||
| 
						 | 
					c123784c54 | ||
| 
						 | 
					342a5276fc | ||
| 
						 | 
					51a32846ee | ||
| 
						 | 
					35865429a8 | ||
| 
						 | 
					aadd5b95b8 | ||
| 
						 | 
					f9f2ca51ac | ||
| 
						 | 
					1cb93a8c10 | ||
| 
						 | 
					7e5dbb2ba5 | ||
| 
						 | 
					2772e3d80e | ||
| 
						 | 
					223c578734 | ||
| 
						 | 
					d01315dee2 | ||
| 
						 | 
					7dafb4ce4c | ||
| 
						 | 
					9671db9b14 | ||
| 
						 | 
					bec559f67c | ||
| 
						 | 
					14053c1394 | ||
| 
						 | 
					55e4b1c828 | ||
| 
						 | 
					dda3421159 | ||
| 
						 | 
					45e7488e60 | ||
| 
						 | 
					30c7bd66b7 | ||
| 
						 | 
					af4f5bdac0 | ||
| 
						 | 
					3d1a8cc341 | ||
| 
						 | 
					0e52fb2544 | ||
| 
						 | 
					e6d6c0a17c | ||
| 
						 | 
					cfd2d47e00 | ||
| 
						 | 
					83301a879d | ||
| 
						 | 
					d7881ba129 | ||
| 
						 | 
					b9fef1edf7 | ||
| 
						 | 
					2c606f7b23 | ||
| 
						 | 
					03797607ed | ||
| 
						 | 
					254b7f500d | ||
| 
						 | 
					51edd51bf2 | ||
| 
						 | 
					0d403f4a3f | ||
| 
						 | 
					0fa134addd | ||
| 
						 | 
					7002270084 | ||
| 
						 | 
					1c5452d047 | ||
| 
						 | 
					f0d62c07bf | ||
| 
						 | 
					496ca55bba | ||
| 
						 | 
					79cfba226b | ||
| 
						 | 
					f69b60dffe | ||
| 
						 | 
					513385133f | ||
| 
						 | 
					6f1e2f6636 | ||
| 
						 | 
					8ae94c034d | ||
| 
						 | 
					cd9696f25e | ||
| 
						 | 
					d62a6bab41 | ||
| 
						 | 
					20df002746 | ||
| 
						 | 
					fa6b01546e | ||
| 
						 | 
					91b37a6e52 | ||
| 
						 | 
					d8171d7c8b | ||
| 
						 | 
					fa96e2daf1 | ||
| 
						 | 
					87708c3b84 | ||
| 
						 | 
					6319023cc9 | ||
| 
						 | 
					efad9d1b60 | ||
| 
						 | 
					a1dea657fa | ||
| 
						 | 
					6b1b75717b | ||
| 
						 | 
					efe08e0bd3 | ||
| 
						 | 
					62892c4894 | ||
| 
						 | 
					0c2a62da11 | ||
| 
						 | 
					5bc9e9aadd | ||
| 
						 | 
					112c33d35b | ||
| 
						 | 
					864da3030f | ||
| 
						 | 
					f2e719b361 | ||
| 
						 | 
					6aab515389 | ||
| 
						 | 
					819b535ab0 | ||
| 
						 | 
					60e95ac2ac | ||
| 
						 | 
					9b94ddff0a | ||
| 
						 | 
					174f8022eb | ||
| 
						 | 
					ddc3c5ba68 | ||
| 
						 | 
					a7e6b766be | ||
| 
						 | 
					befc35a3ac | ||
| 
						 | 
					2e9bbf389e | ||
| 
						 | 
					80b5fda292 | ||
| 
						 | 
					c48cbd95f6 | ||
| 
						 | 
					931bdc6aac | ||
| 
						 | 
					7f81506c8b | ||
| 
						 | 
					b4b9e76c8d | ||
| 
						 | 
					e5a3dcf868 | ||
| 
						 | 
					825648535c | ||
| 
						 | 
					5cbc908ba3 | ||
| 
						 | 
					895cf53ee1 | ||
| 
						 | 
					e41f74e77c | ||
| 
						 | 
					c21caad1c5 | ||
| 
						 | 
					86fcd3a378 | ||
| 
						 | 
					2b3687b3cb | ||
| 
						 | 
					5d61c7c691 | ||
| 
						 | 
					1bb266e7c7 | ||
| 
						 | 
					1fca8d322c | ||
| 
						 | 
					325cd03a59 | ||
| 
						 | 
					2f7e6baa05 | ||
| 
						 | 
					d252e066fe | ||
| 
						 | 
					fe7bd9ab3c | ||
| 
						 | 
					84e3f41305 | ||
| 
						 | 
					3e8cccad0d | ||
| 
						 | 
					a2b94d67f7 | ||
| 
						 | 
					6ab61e73b0 | ||
| 
						 | 
					051c6973af | ||
| 
						 | 
					806a49ec3d | ||
| 
						 | 
					3829fe128a | ||
| 
						 | 
					649177985d | ||
| 
						 | 
					c15148b23c | ||
| 
						 | 
					261a3f5d91 | ||
| 
						 | 
					256ba78ba5 | ||
| 
						 | 
					04aff8866e | ||
| 
						 | 
					1a51b98700 | ||
| 
						 | 
					f64100226d | ||
| 
						 | 
					b7805e48a6 | ||
| 
						 | 
					0d9556620d | ||
| 
						 | 
					a51828a7a2 | ||
| 
						 | 
					7e2009f408 | ||
| 
						 | 
					008d950a39 | ||
| 
						 | 
					22d5862afb | ||
| 
						 | 
					de569147a5 | ||
| 
						 | 
					a82c3db750 | ||
| 
						 | 
					80706d10af | ||
| 
						 | 
					93f01ed4df | ||
| 
						 | 
					a3a28e5557 | ||
| 
						 | 
					8948a0d3a4 | ||
| 
						 | 
					d849ea9b41 | ||
| 
						 | 
					0144575f3f | ||
| 
						 | 
					bdbe646ca7 | ||
| 
						 | 
					1a1483a242 | ||
| 
						 | 
					962346785b | ||
| 
						 | 
					a73da3cd70 | ||
| 
						 | 
					9c27d0ae3f | ||
| 
						 | 
					525d5218c1 | ||
| 
						 | 
					e23b13ec7f | ||
| 
						 | 
					29b000e03c | ||
| 
						 | 
					6a7b0df810 | ||
| 
						 | 
					4142de9195 | ||
| 
						 | 
					9195e1be00 | ||
| 
						 | 
					75382d13fd | ||
| 
						 | 
					d444280a28 | ||
| 
						 | 
					52fc0fe04a | ||
| 
						 | 
					216bebadf1 | ||
| 
						 | 
					a5592931cb | ||
| 
						 | 
					a2228417ff | ||
| 
						 | 
					3e1e292c3e | ||
| 
						 | 
					f2f039ae9e | ||
| 
						 | 
					29dde1eda0 | ||
| 
						 | 
					45d3792ce0 | ||
| 
						 | 
					875d0aaebb | ||
| 
						 | 
					26c9d8ff6f | ||
| 
						 | 
					5e3372e932 | ||
| 
						 | 
					f7069dcd18 | ||
| 
						 | 
					560bb65384 | ||
| 
						 | 
					50cd6a036e | ||
| 
						 | 
					441ab2b5f8 | ||
| 
						 | 
					ba5ed188a1 | ||
| 
						 | 
					72e672f08d | ||
| 
						 | 
					120474ec6a | ||
| 
						 | 
					eee57c47f5 | ||
| 
						 | 
					4c160869b8 | ||
| 
						 | 
					3720a7fbe0 | ||
| 
						 | 
					7afa541a53 | ||
| 
						 | 
					6f979c8275 | ||
| 
						 | 
					d399241e65 | ||
| 
						 | 
					e85dec030a | ||
| 
						 | 
					d0220764cc | ||
| 
						 | 
					75c1df9531 | ||
| 
						 | 
					bca7156d6b | ||
| 
						 | 
					64277b7157 | ||
| 
						 | 
					4a72543f65 | ||
| 
						 | 
					5b84d29807 | ||
| 
						 | 
					a11061ec2b | ||
| 
						 | 
					24cfb93b2e | ||
| 
						 | 
					502b42d63a | ||
| 
						 | 
					612672b79c | ||
| 
						 | 
					abc670e1b1 | ||
| 
						 | 
					d589ccdd01 | ||
| 
						 | 
					acb07d9f7d | ||
| 
						 | 
					f4d2186719 | ||
| 
						 | 
					d0ede5c665 | ||
| 
						 | 
					554cbb5e9b | ||
| 
						 | 
					dbd32a56bf | ||
| 
						 | 
					7f500235c6 | ||
| 
						 | 
					39a58084c8 | ||
| 
						 | 
					cde0fde836 | ||
| 
						 | 
					e70cca0fda | ||
| 
						 | 
					919bd7eb82 | ||
| 
						 | 
					312cff3d6f | ||
| 
						 | 
					0d86eef3d7 | ||
| 
						 | 
					13acf570e7 | ||
| 
						 | 
					fa17623fa8 | ||
| 
						 | 
					06fd525950 | ||
| 
						 | 
					4805b5115a | ||
| 
						 | 
					108dcb3e61 | ||
| 
						 | 
					780d272535 | ||
| 
						 | 
					02ea4b81a5 | ||
| 
						 | 
					7c1bdc6d36 | ||
| 
						 | 
					78c7b8b836 | ||
| 
						 | 
					227da30acb | ||
| 
						 | 
					610805026f | ||
| 
						 | 
					c02399c3d2 | ||
| 
						 | 
					e0799d4153 | ||
| 
						 | 
					6df83f1aa9 | ||
| 
						 | 
					efb5ad1d9b | ||
| 
						 | 
					716976f016 | ||
| 
						 | 
					7892f41b84 | ||
| 
						 | 
					d549e03b3f | ||
| 
						 | 
					c511ef21ff | ||
| 
						 | 
					d64dc45899 | ||
| 
						 | 
					bcb0588409 | ||
| 
						 | 
					0975959eb9 | ||
| 
						 | 
					e985a6d9d3 | ||
| 
						 | 
					b893305974 | ||
| 
						 | 
					724fdd44e4 | ||
| 
						 | 
					b480ef669c | ||
| 
						 | 
					4b145da046 | ||
| 
						 | 
					83d168ece3 | ||
| 
						 | 
					ae44fe7818 | ||
| 
						 | 
					f8981b3acb | ||
| 
						 | 
					050b324885 | ||
| 
						 | 
					e74c0df6c6 | ||
| 
						 | 
					22d0d11895 | ||
| 
						 | 
					80d0c0cf74 | ||
| 
						 | 
					518646b925 | ||
| 
						 | 
					479d7e0087 | ||
| 
						 | 
					8ea1a555f4 | ||
| 
						 | 
					04024dc37c | ||
| 
						 | 
					060ff9288f | ||
| 
						 | 
					197116ee78 | ||
| 
						 | 
					a1e0015257 | ||
| 
						 | 
					7e701ef9e0 | ||
| 
						 | 
					3d6fb661bb | ||
| 
						 | 
					fc372496da | ||
| 
						 | 
					ad7258fe9c | ||
| 
						 | 
					bd707cb2a8 | ||
| 
						 | 
					1839b5f205 | ||
| 
						 | 
					02b47f963c | ||
| 
						 | 
					f8a7f9378a | ||
| 
						 | 
					65cb253be4 | ||
| 
						 | 
					a12356b24b | ||
| 
						 | 
					6a67ad7f93 | ||
| 
						 | 
					140a7f0b1c | ||
| 
						 | 
					00159bc6b5 | ||
| 
						 | 
					9542260103 | ||
| 
						 | 
					72074578df | ||
| 
						 | 
					3b4750a988 | ||
| 
						 | 
					aeec5f0163 | ||
| 
						 | 
					9c94d8c8d6 | ||
| 
						 | 
					581712a2c8 | ||
| 
						 | 
					b25b51aaca | ||
| 
						 | 
					fb97e13a61 | ||
| 
						 | 
					36e154fdb2 | ||
| 
						 | 
					ca273a24b4 | ||
| 
						 | 
					d828bf2889 | ||
| 
						 | 
					87efccef18 | ||
| 
						 | 
					e0bf522e7f | ||
| 
						 | 
					5b1cd3bd3c | ||
| 
						 | 
					f00489196d | ||
| 
						 | 
					dd53bf7e51 | ||
| 
						 | 
					35a6da26d2 | ||
| 
						 | 
					c8c8748a0b | ||
| 
						 | 
					46d0065a90 | ||
| 
						 | 
					990b0180a8 | ||
| 
						 | 
					f3bfb72251 | ||
| 
						 | 
					0358a7edc6 | ||
| 
						 | 
					37f99fca04 | ||
| 
						 | 
					50dfc8ab82 | ||
| 
						 | 
					c70c739b0c | ||
| 
						 | 
					5918285326 | ||
| 
						 | 
					b1dead1186 | ||
| 
						 | 
					3e36e132c3 | ||
| 
						 | 
					fa8d1809e7 | ||
| 
						 | 
					e12b668d04 | ||
| 
						 | 
					e5506f7d8c | ||
| 
						 | 
					b1ac7e5cb3 | ||
| 
						 | 
					ffd164a5f3 | ||
| 
						 | 
					cb27414026 | ||
| 
						 | 
					e320912f33 | ||
| 
						 | 
					d23aaae698 | ||
| 
						 | 
					120c0fe848 | ||
| 
						 | 
					34857b9520 | ||
| 
						 | 
					a87dcece4c | ||
| 
						 | 
					01e2479004 | ||
| 
						 | 
					0fd63fe091 | ||
| 
						 | 
					cc98801c67 | ||
| 
						 | 
					2724d74108 | ||
| 
						 | 
					6d0c0d3a5f | ||
| 
						 | 
					15f8f63317 | ||
| 
						 | 
					d970d65968 | ||
| 
						 | 
					04d359691b | ||
| 
						 | 
					bfc519944a | ||
| 
						 | 
					9f69fd14a2 | ||
| 
						 | 
					85058787b2 | ||
| 
						 | 
					ec851623e0 | ||
| 
						 | 
					e05429a3ec | ||
| 
						 | 
					f651c41816 | ||
| 
						 | 
					6b88d99ae2 | ||
| 
						 | 
					814469cdca | ||
| 
						 | 
					536bf8f141 | ||
| 
						 | 
					6a27290815 | ||
| 
						 | 
					7dde3465e2 | ||
| 
						 | 
					0206a4ac83 | ||
| 
						 | 
					380f5a972c | ||
| 
						 | 
					407467a236 | ||
| 
						 | 
					bcfa9e18bf | ||
| 
						 | 
					69b730e91a | ||
| 
						 | 
					6c6c003d68 | ||
| 
						 | 
					fd652b70d6 | ||
| 
						 | 
					804a5ab6a8 | ||
| 
						 | 
					d984a1aa19 | ||
| 
						 | 
					e05b5a6ab8 | ||
| 
						 | 
					3ff84db421 | ||
| 
						 | 
					74ca73ecb4 | ||
| 
						 | 
					37032f68ae | ||
| 
						 | 
					21d3605737 | ||
| 
						 | 
					0a7c1caf43 | ||
| 
						 | 
					24b57335fa | ||
| 
						 | 
					9f981d875a | ||
| 
						 | 
					6dcc3800e0 | ||
| 
						 | 
					44e9be5a1c | ||
| 
						 | 
					6a8c560d21 | ||
| 
						 | 
					0afe8c6b34 | ||
| 
						 | 
					0f5d7f52a0 | ||
| 
						 | 
					aaaefa0ee2 | ||
| 
						 | 
					276929bc7e | ||
| 
						 | 
					32882f1397 | ||
| 
						 | 
					7dc380c485 | ||
| 
						 | 
					49aaa9a5d3 | ||
| 
						 | 
					84462eb3f2 | ||
| 
						 | 
					91709ca979 | ||
| 
						 | 
					9ece71e652 | ||
| 
						 | 
					4e93f6c6ff | ||
| 
						 | 
					ad9f1fb7c7 | ||
| 
						 | 
					abaeea6d8b | ||
| 
						 | 
					8efbcc4c6b | ||
| 
						 | 
					8ef31cab8c | ||
| 
						 | 
					37ae53e55c | ||
| 
						 | 
					d01f06bdf4 | ||
| 
						 | 
					0d4a8d118a | ||
| 
						 | 
					7e6ec83b1f | ||
| 
						 | 
					9eb515cfae | ||
| 
						 | 
					d0da019a21 | ||
| 
						 | 
					57a13c9ad3 | ||
| 
						 | 
					7f39100634 | ||
| 
						 | 
					9ab96ef39a | ||
| 
						 | 
					ed21d797a6 | ||
| 
						 | 
					15960746bb | ||
| 
						 | 
					e0f1e3ca71 | ||
| 
						 | 
					51d0524182 | ||
| 
						 | 
					16801aa5c4 | ||
| 
						 | 
					cd23f66834 | ||
| 
						 | 
					cc5d2b2875 | ||
| 
						 | 
					94ef03db9e | ||
| 
						 | 
					038bd100b2 | ||
| 
						 | 
					3b5c3f086a | ||
| 
						 | 
					a136715111 | ||
| 
						 | 
					daa22d68fa | ||
| 
						 | 
					f24d202024 | ||
| 
						 | 
					d3e0b8574b | ||
| 
						 | 
					f4482cc34a | ||
| 
						 | 
					3ff226cd6b | 
@@ -13,7 +13,3 @@ redis:
 | 
			
		||||
  host: localhost
 | 
			
		||||
  port: 6379
 | 
			
		||||
  pass: ''
 | 
			
		||||
elasticsearch:
 | 
			
		||||
  host: localhost
 | 
			
		||||
  port: 9200
 | 
			
		||||
  pass: ''
 | 
			
		||||
@@ -9,11 +9,8 @@ mongodb:
 | 
			
		||||
  db: test-misskey
 | 
			
		||||
  user: admin
 | 
			
		||||
  pass: ''
 | 
			
		||||
# __REDIS__
 | 
			
		||||
redis:
 | 
			
		||||
  host: localhost
 | 
			
		||||
  port: 6379
 | 
			
		||||
  pass: ''
 | 
			
		||||
elasticsearch:
 | 
			
		||||
  host: localhost
 | 
			
		||||
  port: 9200
 | 
			
		||||
  pass: ''
 | 
			
		||||
							
								
								
									
										137
									
								
								.circleci/config.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								.circleci/config.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
			
		||||
version: 2.1
 | 
			
		||||
 | 
			
		||||
general:
 | 
			
		||||
  branches:
 | 
			
		||||
    ignore:
 | 
			
		||||
      - l10n_develop
 | 
			
		||||
      - imgbot
 | 
			
		||||
 | 
			
		||||
executors:
 | 
			
		||||
  default:
 | 
			
		||||
    working_directory: /tmp/workspace
 | 
			
		||||
    docker:
 | 
			
		||||
      - image: misskey/ci:latest
 | 
			
		||||
      - image: circleci/mongo:latest
 | 
			
		||||
      - image: circleci/redis:latest
 | 
			
		||||
  docker:
 | 
			
		||||
    working_directory: /tmp/workspace
 | 
			
		||||
    docker:
 | 
			
		||||
      - image: docker:latest
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    executor: default
 | 
			
		||||
    steps:
 | 
			
		||||
      - checkout
 | 
			
		||||
      - restore_cache:
 | 
			
		||||
          name: Restore npm package caches
 | 
			
		||||
          keys:
 | 
			
		||||
            - npm-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "package-lock.json" }}-
 | 
			
		||||
            - npm-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-
 | 
			
		||||
            - npm-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-
 | 
			
		||||
            - npm-v1-arch-{{ arch }}-
 | 
			
		||||
            - npm-v1-
 | 
			
		||||
      - run:
 | 
			
		||||
          name: Install Dependencies
 | 
			
		||||
          command: |
 | 
			
		||||
            npm install
 | 
			
		||||
      - run:
 | 
			
		||||
          name: Configure
 | 
			
		||||
          command: |
 | 
			
		||||
            cp .ci/default.yml .config
 | 
			
		||||
            cp .ci/test.yml .config
 | 
			
		||||
      - run:
 | 
			
		||||
          name: Build
 | 
			
		||||
          command: |
 | 
			
		||||
            npm run build || (echo -e '\033[0;34mRebuild modules\033[0;39m' && ls -1A node_modules | grep '^[^@]' | xargs npm rebuild && ls -1A node_modules | grep '^@' | xargs -I%1 sh -c 'ls -1A node_modules/'%1' | xargs -P0 -I%2 npm rebuild node_modules/'%1'/%2' && npm run build)
 | 
			
		||||
            ls -1ARl node_modules > ls
 | 
			
		||||
      - save_cache:
 | 
			
		||||
          name: Cache npm packages
 | 
			
		||||
          key: npm-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "package-lock.json" }}-ls-{{ checksum "ls" }}
 | 
			
		||||
          paths:
 | 
			
		||||
            - node_modules
 | 
			
		||||
      - store_artifacts:
 | 
			
		||||
          path: built
 | 
			
		||||
      - persist_to_workspace:
 | 
			
		||||
          root: .
 | 
			
		||||
          paths:
 | 
			
		||||
            - .
 | 
			
		||||
  test:
 | 
			
		||||
    parameters:
 | 
			
		||||
      without_redis:
 | 
			
		||||
        type: string
 | 
			
		||||
        default: ""
 | 
			
		||||
    executor: default
 | 
			
		||||
    steps:
 | 
			
		||||
      - attach_workspace:
 | 
			
		||||
          at: /tmp/workspace
 | 
			
		||||
      - when:
 | 
			
		||||
          condition: <<parameters.without_redis>>
 | 
			
		||||
          steps:
 | 
			
		||||
            - run:
 | 
			
		||||
                name: Configure
 | 
			
		||||
                command: |
 | 
			
		||||
                  mv .config/test.yml .config/test_redis.yml
 | 
			
		||||
                  touch .config/test.yml
 | 
			
		||||
                  cat .config/test_redis.yml | while IFS= read line; do if [[ "$line" = '# __REDIS__' ]]; then break; else echo "$line" >> .config/test.yml; fi; done
 | 
			
		||||
      - run:
 | 
			
		||||
          name: Test
 | 
			
		||||
          command: |
 | 
			
		||||
            npm run test || (npm rebuild && npm run test) || ((node-gyp configure && node-gyp build && npm run build || (echo -e '\033[0;34mRebuild modules\033[0;39m' && ls -1A node_modules | grep '^[^@]' | xargs npm rebuild && ls -1A node_modules | grep '^@' | xargs -I%1 sh -c 'ls -1A node_modules/'%1' | xargs -P0 -I%2 npm rebuild node_modules/'%1'/%2' && npm run build)) && npm run test)
 | 
			
		||||
            ls -1ARl node_modules > ls
 | 
			
		||||
      - save_cache:
 | 
			
		||||
          name: Cache npm packages
 | 
			
		||||
          key: npm-v1-arch-{{ arch }}-env-{{ .Environment.variableName }}-package-{{ checksum "package.json" }}-lock-{{ checksum "package-lock.json" }}-ls-{{ checksum "ls" }}
 | 
			
		||||
          paths:
 | 
			
		||||
            - node_modules
 | 
			
		||||
 | 
			
		||||
  docker:
 | 
			
		||||
    parameters:
 | 
			
		||||
      with_deploy:
 | 
			
		||||
        type: string
 | 
			
		||||
        default: ""
 | 
			
		||||
    executor: docker
 | 
			
		||||
    steps:
 | 
			
		||||
      - checkout
 | 
			
		||||
      - setup_remote_docker
 | 
			
		||||
      - run:
 | 
			
		||||
          name: Build
 | 
			
		||||
          command: |
 | 
			
		||||
            docker build . | tee docker.log
 | 
			
		||||
            tail -n 1 docker.log | read __Successfully __built tag
 | 
			
		||||
      - when:
 | 
			
		||||
          condition: <<parameters.with_deploy>>
 | 
			
		||||
          steps:
 | 
			
		||||
            - run:
 | 
			
		||||
                name: Deploy
 | 
			
		||||
                command: |
 | 
			
		||||
                  if [ "$DOCKERHUB_USERNAME$DOCKERHUB_PASSWORD" ]
 | 
			
		||||
                   then
 | 
			
		||||
                    docker tag $tag misskey/misskey
 | 
			
		||||
                    docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD
 | 
			
		||||
                    docker push misskey/misskey
 | 
			
		||||
                   else
 | 
			
		||||
                    echo -e '\033[0;33mAborted deploying to Docker Hub\033[0;39m'
 | 
			
		||||
                  fi
 | 
			
		||||
 | 
			
		||||
workflows:
 | 
			
		||||
  version: 2
 | 
			
		||||
  build-and-test:
 | 
			
		||||
    jobs:
 | 
			
		||||
      - build
 | 
			
		||||
      - test:
 | 
			
		||||
          requires:
 | 
			
		||||
            - build
 | 
			
		||||
      - test:
 | 
			
		||||
          without_redis: "true"
 | 
			
		||||
          requires:
 | 
			
		||||
            - build
 | 
			
		||||
      - docker:
 | 
			
		||||
          filters:
 | 
			
		||||
            branches:
 | 
			
		||||
              ignore: master
 | 
			
		||||
      - docker:
 | 
			
		||||
          with_deploy: "true"
 | 
			
		||||
          filters:
 | 
			
		||||
            branches:
 | 
			
		||||
              only: master
 | 
			
		||||
@@ -1,6 +1,3 @@
 | 
			
		||||
name: example-instance-name # Name of your instance
 | 
			
		||||
description: example-description # Description of your instance
 | 
			
		||||
 | 
			
		||||
maintainer:
 | 
			
		||||
  name: example-maitainer-name # Your name
 | 
			
		||||
  url: http://example.com/ # Your contact (http or mailto)
 | 
			
		||||
@@ -25,7 +22,7 @@ url: https://example.tld/
 | 
			
		||||
#   +------+      |+-------------+      +----------------+|
 | 
			
		||||
#                 +---------------------------------------+
 | 
			
		||||
#
 | 
			
		||||
#   You need to setup reverse proxy. (eg. Nginx)
 | 
			
		||||
#   You need to setup reverse proxy. (eg. nginx)
 | 
			
		||||
#   You do not define 'https' section.
 | 
			
		||||
 | 
			
		||||
# Option 2: Standalone
 | 
			
		||||
@@ -148,6 +145,12 @@ drive:
 | 
			
		||||
#  consumer_key: example-twitter-consumer-key
 | 
			
		||||
#  consumer_secret: example-twitter-consumer-secret-key
 | 
			
		||||
 | 
			
		||||
# GitHub integration
 | 
			
		||||
# You need to set the oauth callback url as : https://<your-misskey-instance>/api/gh/cb
 | 
			
		||||
#github:
 | 
			
		||||
#  client_id: example-github-client-id
 | 
			
		||||
#  client_secret: example-github-client-secret
 | 
			
		||||
 | 
			
		||||
# Ghost
 | 
			
		||||
# Ghost account is an account used for the purpose of delegating
 | 
			
		||||
# followers when putting users in the list.
 | 
			
		||||
@@ -164,3 +167,6 @@ drive:
 | 
			
		||||
#  external: true
 | 
			
		||||
#  engine: http://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}
 | 
			
		||||
#  timeout: 300000
 | 
			
		||||
 | 
			
		||||
# Max allowed note text length in charactors
 | 
			
		||||
maxNoteTextLength: 1000
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ branches:
 | 
			
		||||
language: node_js
 | 
			
		||||
 | 
			
		||||
node_js:
 | 
			
		||||
  - 10.1.0
 | 
			
		||||
  - 11.0.0
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  - CXX=g++-4.8 NODE_ENV=production
 | 
			
		||||
@@ -35,7 +35,7 @@ before_script:
 | 
			
		||||
  - npm install
 | 
			
		||||
 | 
			
		||||
  # 設定ファイルを配置
 | 
			
		||||
  - cp ./.travis/default.yml ./.config
 | 
			
		||||
  - cp ./.travis/test.yml ./.config
 | 
			
		||||
  - cp ./.ci/default.yml ./.config
 | 
			
		||||
  - cp ./.ci/test.yml ./.config
 | 
			
		||||
 | 
			
		||||
  - travis_wait npm run build
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								Dockerfile
									
									
									
									
									
								
							@@ -1,28 +1,44 @@
 | 
			
		||||
FROM alpine:edge AS base
 | 
			
		||||
FROM alpine:3.8 AS base
 | 
			
		||||
 | 
			
		||||
ENV NODE_ENV=production
 | 
			
		||||
 | 
			
		||||
RUN apk add --no-cache nodejs nodejs-npm
 | 
			
		||||
RUN apk add vips fftw --update-cache --repository https://dl-3.alpinelinux.org/alpine/edge/testing/
 | 
			
		||||
RUN apk add --no-cache nodejs nodejs-npm zlib
 | 
			
		||||
RUN npm i -g npm@latest
 | 
			
		||||
 | 
			
		||||
WORKDIR /misskey
 | 
			
		||||
COPY . ./
 | 
			
		||||
 | 
			
		||||
FROM base AS builder
 | 
			
		||||
 | 
			
		||||
RUN apk add --no-cache	gcc g++ python autoconf automake file make nasm
 | 
			
		||||
RUN apk add vips-dev fftw-dev --update-cache --repository https://dl-3.alpinelinux.org/alpine/edge/testing/
 | 
			
		||||
RUN npm install \
 | 
			
		||||
    && npm install -g node-gyp \
 | 
			
		||||
    && node-gyp configure \
 | 
			
		||||
    && node-gyp build \
 | 
			
		||||
    && npm run build
 | 
			
		||||
RUN apk add --no-cache \
 | 
			
		||||
    gcc \
 | 
			
		||||
    g++ \
 | 
			
		||||
    libc-dev \
 | 
			
		||||
    python \
 | 
			
		||||
    autoconf \
 | 
			
		||||
    automake \
 | 
			
		||||
    file \
 | 
			
		||||
    make \
 | 
			
		||||
    nasm \
 | 
			
		||||
    pkgconfig \
 | 
			
		||||
    libtool \
 | 
			
		||||
    zlib-dev
 | 
			
		||||
RUN npm i -g node-gyp
 | 
			
		||||
 | 
			
		||||
COPY ./package.json ./
 | 
			
		||||
RUN npm i
 | 
			
		||||
 | 
			
		||||
COPY . ./
 | 
			
		||||
RUN node-gyp configure \
 | 
			
		||||
 && node-gyp build \
 | 
			
		||||
 && npm run build
 | 
			
		||||
 | 
			
		||||
FROM base AS runner
 | 
			
		||||
 | 
			
		||||
COPY --from=builder /misskey/built ./built
 | 
			
		||||
COPY --from=builder /misskey/node_modules ./node_modules
 | 
			
		||||
 | 
			
		||||
RUN apk add --no-cache tini
 | 
			
		||||
ENTRYPOINT ["/sbin/tini", "--"]
 | 
			
		||||
 | 
			
		||||
COPY --from=builder /misskey/node_modules ./node_modules
 | 
			
		||||
COPY --from=builder /misskey/built ./built
 | 
			
		||||
COPY . ./
 | 
			
		||||
 | 
			
		||||
CMD ["npm", "start"]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								README.md
									
									
									
									
									
								
							@@ -3,9 +3,10 @@
 | 
			
		||||
[](https://misskey.xyz/)
 | 
			
		||||
================================================================
 | 
			
		||||
 | 
			
		||||
[](https://circleci.com/gh/syuilo/misskey)
 | 
			
		||||
[![][travis-badge]][travis-link]
 | 
			
		||||
[![][dependencies-badge]][dependencies-link]
 | 
			
		||||
[](http://makeapullrequest.com) [](https://greenkeeper.io/)
 | 
			
		||||
[](http://makeapullrequest.com)
 | 
			
		||||
 | 
			
		||||
**Sophisticated microblogging platform, evolving forever.**
 | 
			
		||||
 | 
			
		||||
@@ -71,39 +72,46 @@ Please see [Contribution guide](./CONTRIBUTING.md).
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
<!-- PATREON_START -->
 | 
			
		||||
<table><tr>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJ3IjoyMDB9/patreon-media/p/user/619786/32cf01444db24e578cd1982c197f6fc6/1?token-time=2145916800&token-hash=CXe9AqlZy9AsYfiWd3OBYVOzvODoN47Litz0Tu4BFpU%3D" alt="Gargron"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12731202/0995c46cdcb54153ab5f073f5869b70a/1?token-time=2145916800&token-hash=Yd60FK_SWfQO56SeiJpy1tDHOnCV4xdEywQe8gn5_Wo%3D" alt="negao"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13099460/43cecdbaa63a40d79bf50a96b9910b9d/1?token-time=2145916800&token-hash=d6P5MWHHsCMxUuBAEPAoVc5wLUR19mIhqAq7Ma9h9rI%3D" alt="ne_moni"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12913507/f7181eacafe8469a93033d85f5969c29/2?token-time=2145916800&token-hash=mgPdX9TqZxEg4TTPuc477dxhIgYk9246qafjWZEqZ7g%3D" alt="Melilot"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12999811/5f349fafcce44dd1824a8b1ebbec4564/2?token-time=2145916800&token-hash=rwZ8qvbm_kpA4ib3kc07tVKupXeySpY5ATQFGxfL9v0%3D" alt="Xeltica"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/3384329/8b713330cb27404ea6e9fac50ff96efe/1?token-time=2145916800&token-hash=0eu4-m1gTWA9PhptVZt6rdKcusqcD7RB87rJT23VVFI%3D" alt="べすれい"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12021162/963128bb8d14476dbd8407943db8f31a/1?token-time=2145916800&token-hash=GgJ_NmUB6_nnRNLVGUWjV-WX91On7BOu59LKncYV9fE%3D" alt="gutfuckllc"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/11357794/923ce94cd8c44ba788ee931907881839/1?token-time=2145916800&token-hash=I8lJVM8LeW6TSo5W6uIIRZ42cw83zp1wK_FsbzY0mcQ%3D" alt="mydarkstar"></td>
 | 
			
		||||
<td><img src="https://c8.patreon.com/2/100/12718187" alt="Peter G."></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13039004/509d0c412eb14ae08d6a812a3054f7d6/1?token-time=2145916800&token-hash=zwSu01tOtn5xTUucDZHuPsCxF2HBEMVs9ROJKTlEV_o%3D" alt="nemu"></td>
 | 
			
		||||
</tr><tr>
 | 
			
		||||
<td><a href="https://www.patreon.com/mastodon">Gargron</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/negao">negao</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/user?u=13099460">ne_moni</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/user?u=12913507">Melilot</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/AxellaMC">Xeltica</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/user?u=3384329">べすれい</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/gutfuckllc">gutfuckllc</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/mydarkstar">mydarkstar</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/user?u=12718187">Peter G.</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/user?u=13039004">nemu</a></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
<table><tr>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/2?token-time=2145916800&token-hash=zElv7ZcPL3viGsXbNG_KWiKrbV0vvw1gk0panx8DJoo%3D" alt="Naoki Kosaka"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13039004/509d0c412eb14ae08d6a812a3054f7d6/1?token-time=2145916800&token-hash=zwSu01tOtn5xTUucDZHuPsCxF2HBEMVs9ROJKTlEV_o%3D" alt="nemu"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/5881381/6235ca5d3fb04c8e95ef5b4ff2abcc18/3?token-time=2145916800&token-hash=qsdn0-e6yLaLI6hUX9JAkyTR6a5UdnSp7T1foniBvGQ%3D" alt="YUKIMOCHI"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/8241184/39e18850e87a449e9c9a71acb3310ebd/2?token-time=2145916800&token-hash=iUXOQzRyJDv3PJxwS7Mjwg1459dzh2trOq6NFtXu_OM%3D" alt="Acid Chicken"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/13034746/c711c7f58e204ecfbc2fd646bc8a4eee/1?token-time=2145916800&token-hash=UERBN4OyP7Nh5XwwdDg0N0IE5cD6_qUQMO81Z5Wizso%3D" alt="Hiratake"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/10789744/97175095d8f04c0f86225ff47cb98d40/1?token-time=2145916800&token-hash=P4BIzCX2I1CkEP66ottfhsC8Wr6BUSamjA-vq3pLqFI%3D" alt="Naoki Hirayama"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/4503830/ccf2cc867ea64de0b524bb2e24b9a1cb/1?token-time=2145916800&token-hash=S1zP0QyLU52Dqq6dtc9qNYyWfW86XrYHiR4NMbeOrnA%3D" alt="dansup"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/619786/32cf01444db24e578cd1982c197f6fc6/1?token-time=2145916800&token-hash=tB1e_r8RlZ5sFL0KV_e8dugapxatNBRK1Z3h67TO1g8%3D" alt="Gargron"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/5731881/4b6038e6cda34c04b83a5fcce3806a93/1?token-time=2145916800&token-hash=VZUtwrjQa8Jml4twCjHYQQZ64wHEY4oIlGl7Kc-VYUQ%3D" alt="Nokotaro Takeda"></td>
 | 
			
		||||
<td><img src="https://c10.patreonusercontent.com/3/eyJoIjoxMDAsInciOjEwMH0%3D/patreon-media/p/user/12531784/93a45137841849329ba692da92ac7c60/1?token-time=2145916800&token-hash=tMosUojzUYJCH_3t--tvYA-SMCyrS__hzSndyaRSnbo%3D" alt="Takashi Shibuya"></td>
 | 
			
		||||
</tr><tr>
 | 
			
		||||
<td><a href="https://www.patreon.com/user?u=5881381">Naoki Kosaka</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/user?u=13039004">nemu</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/yukimochi">YUKIMOCHI</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/acid_chicken">Acid Chicken</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/hiratake">Hiratake</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/spinlock">Naoki Hirayama</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/dansup">dansup</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/mastodon">Gargron</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/takenoko">Nokotaro Takeda</a></td>
 | 
			
		||||
<td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td>
 | 
			
		||||
</tr></table>
 | 
			
		||||
<table><tr>
 | 
			
		||||
</tr><tr>
 | 
			
		||||
</tr></table>
 | 
			
		||||
 | 
			
		||||
**Last updated:** Tue, 02 Oct 2018 09:25:07 UTC
 | 
			
		||||
**Last updated:** Wed, 31 Oct 2018 23:21:06 UTC
 | 
			
		||||
<!-- PATREON_END -->
 | 
			
		||||
 | 
			
		||||
:four_leaf_clover: Copyright
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +0,0 @@
 | 
			
		||||
const deleteUser = require('../built/models/user').deleteUser;
 | 
			
		||||
 | 
			
		||||
const args = process.argv.slice(2);
 | 
			
		||||
 | 
			
		||||
const userId = args[0];
 | 
			
		||||
 | 
			
		||||
console.log(`deleting ${userId}...`);
 | 
			
		||||
 | 
			
		||||
deleteUser(userId).then(() => {
 | 
			
		||||
	console.log('done');
 | 
			
		||||
}, e => {
 | 
			
		||||
	console.error(e);
 | 
			
		||||
});
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
const mongo = require('mongodb');
 | 
			
		||||
const User = require('../built/models/user').default;
 | 
			
		||||
 | 
			
		||||
const args = process.argv.slice(2);
 | 
			
		||||
 | 
			
		||||
const user = args[0];
 | 
			
		||||
 | 
			
		||||
const q = user.startsWith('@') ? {
 | 
			
		||||
	username: user.split('@')[1],
 | 
			
		||||
	host: user.split('@')[2] || null
 | 
			
		||||
} : { _id: new mongo.ObjectID(user) };
 | 
			
		||||
 | 
			
		||||
console.log(`Mark as verfied ${user}...`);
 | 
			
		||||
 | 
			
		||||
User.update(q, {
 | 
			
		||||
	$set: {
 | 
			
		||||
		isVerified: true
 | 
			
		||||
	}
 | 
			
		||||
}).then(() => {
 | 
			
		||||
	console.log(`Done ${user}`);
 | 
			
		||||
}, e => {
 | 
			
		||||
	console.error(e);
 | 
			
		||||
});
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
const { default: Note } = require('../built/models/note');
 | 
			
		||||
const { default: Meta } = require('../built/models/meta');
 | 
			
		||||
const { default: User } = require('../built/models/user');
 | 
			
		||||
 | 
			
		||||
async function main() {
 | 
			
		||||
	const meta = await Meta.findOne({});
 | 
			
		||||
 | 
			
		||||
	const notesCount = await Note.count();
 | 
			
		||||
 | 
			
		||||
	const usersCount = await User.count();
 | 
			
		||||
 | 
			
		||||
	const originalNotesCount = await Note.count({
 | 
			
		||||
		'_user.host': null
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const originalUsersCount = await User.count({
 | 
			
		||||
		host: null
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	const stats = {
 | 
			
		||||
		notesCount,
 | 
			
		||||
		usersCount,
 | 
			
		||||
		originalNotesCount,
 | 
			
		||||
		originalUsersCount
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	if (meta) {
 | 
			
		||||
		await Meta.update({}, {
 | 
			
		||||
			$set: {
 | 
			
		||||
				stats
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	} else {
 | 
			
		||||
		await Meta.insert({
 | 
			
		||||
			stats
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
main().then(() => {
 | 
			
		||||
	console.log('done');
 | 
			
		||||
}).catch(console.error);
 | 
			
		||||
@@ -6,7 +6,7 @@ services:
 | 
			
		||||
    restart: always
 | 
			
		||||
    links:
 | 
			
		||||
      - mongo
 | 
			
		||||
      - redis
 | 
			
		||||
#      - redis
 | 
			
		||||
#      - es
 | 
			
		||||
    ports:
 | 
			
		||||
      - "127.0.0.1:3000:3000"
 | 
			
		||||
@@ -14,18 +14,18 @@ services:
 | 
			
		||||
      - internal_network
 | 
			
		||||
      - external_network
 | 
			
		||||
 | 
			
		||||
  redis:
 | 
			
		||||
    restart: always
 | 
			
		||||
    image: redis:4.0-alpine
 | 
			
		||||
    networks:
 | 
			
		||||
      - internal_network
 | 
			
		||||
#  redis:
 | 
			
		||||
#    restart: always
 | 
			
		||||
#    image: redis:4.0-alpine
 | 
			
		||||
#    networks:
 | 
			
		||||
#      - internal_network
 | 
			
		||||
### Uncomment to enable Redis persistance
 | 
			
		||||
#    volumes:
 | 
			
		||||
#      - ./redis:/data
 | 
			
		||||
##    volumes:
 | 
			
		||||
##      - ./redis:/data
 | 
			
		||||
 | 
			
		||||
  mongo:
 | 
			
		||||
    restart: always
 | 
			
		||||
    image: mongo:4.1-bionic
 | 
			
		||||
    image: mongo:4.1
 | 
			
		||||
    networks:
 | 
			
		||||
      - internal_network
 | 
			
		||||
    environment:
 | 
			
		||||
 
 | 
			
		||||
@@ -7,23 +7,29 @@ This guide describes how to install and setup Misskey with Docker.
 | 
			
		||||
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
*1.* Make configuration files
 | 
			
		||||
*1.* Download Misskey
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
1. `git clone -b master git://github.com/syuilo/misskey.git` Clone Misskey repository's master branch.
 | 
			
		||||
2. `cd misskey` Move to misskey directory.
 | 
			
		||||
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` Checkout to the [latest release](https://github.com/syuilo/misskey/releases/latest) tag.
 | 
			
		||||
 | 
			
		||||
*2.* Make configuration files
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
1. `cp .config/example.yml .config/default.yml` Copy the `.config/example.yml` and rename it to `default.yml`.
 | 
			
		||||
2. `cp .config/mongo_initdb_example.js .config/mongo_initdb.js` Copy the `.config/mongo_initdb_example.js` and rename it to `mongo_initdb.js`.
 | 
			
		||||
2. Edit `default.yml` and `mongo_initdb.js`.
 | 
			
		||||
 | 
			
		||||
*2.* Configure Docker
 | 
			
		||||
*3.* Configure Docker
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
Edit `docker-compose.yml`.
 | 
			
		||||
 | 
			
		||||
*3.* Build Misskey
 | 
			
		||||
*4.* Build Misskey
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
Build misskey with the following:
 | 
			
		||||
 | 
			
		||||
`docker-compose build`
 | 
			
		||||
 | 
			
		||||
*4.* That is it.
 | 
			
		||||
*5.* That is it.
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
Well done! Now, you have an environment that run to Misskey.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,23 +7,29 @@ Dockerを使ったMisskey構築方法
 | 
			
		||||
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
*1.* 設定ファイルを作成する
 | 
			
		||||
*1.* Misskeyのダウンロード
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
1. `git clone -b master git://github.com/syuilo/misskey.git` masterブランチからMisskeyレポジトリをクローン
 | 
			
		||||
2. `cd misskey` misskeyディレクトリに移動
 | 
			
		||||
3. `git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)` [最新のリリース](https://github.com/syuilo/misskey/releases/latest)を確認
 | 
			
		||||
 | 
			
		||||
*2.* 設定ファイルを作成する
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
1. `cp .config/example.yml .config/default.yml` `.config/example.yml`をコピーし名前を`default.yml`にする
 | 
			
		||||
2. `cp .config/mongo_initdb_example.js .config/mongo_initdb.js` `.config/mongo_initdb_example.js`をコピーし名前を`mongo_initdb.js`にする
 | 
			
		||||
3. `default.yml`と`mongo_initdb.js`を編集する
 | 
			
		||||
 | 
			
		||||
*2.* Dockerの設定
 | 
			
		||||
*3.* Dockerの設定
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
`docker-compose.yml`を編集してください。
 | 
			
		||||
 | 
			
		||||
*3.* Misskeyのビルド
 | 
			
		||||
*4.* Misskeyのビルド
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
次のコマンドでMisskeyをビルドしてください:
 | 
			
		||||
 | 
			
		||||
`docker-compose build`
 | 
			
		||||
 | 
			
		||||
*4.* 以上です!
 | 
			
		||||
*5.* 以上です!
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
お疲れ様でした。これでMisskeyを動かす準備は整いました。
 | 
			
		||||
 | 
			
		||||
@@ -45,4 +51,4 @@ Dockerを使ったMisskey構築方法
 | 
			
		||||
 | 
			
		||||
----------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
なにかお困りのことがありましたらお気軽にご連絡ください。
 | 
			
		||||
なにかお困りのことがありましたらお気軽にご連絡ください。
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,10 @@ If you find an untranslated part on Misskey:
 | 
			
		||||
4. Add the text property using the `foo` keyword below the path that you found or created in step 2. Make sure to type your text in quotation marks. Text should always be inside of quotes.
 | 
			
		||||
	-   For example, in this case we add timeline: `timeline: "タイムライン"` to `locales/ja-JP.yml`.
 | 
			
		||||
 | 
			
		||||
5. And done!
 | 
			
		||||
5. When you add text to the ja-JP file (of syuilo/misskey), it will automatically be applied to all other local language files within 24-48 hours. Translations added in ja-JP file should contain the original Japanese strings (example see step 4). 
 | 
			
		||||
 | 
			
		||||
6. The new strings will automatically appear in the localized language files in the original Japanese text. After that, please go to [CrowdIn](https://crowdin.com/project/misskey) to do the localized translations in your language.
 | 
			
		||||
 | 
			
		||||
7. And done!
 | 
			
		||||
 | 
			
		||||
For more details, please refer to this [commit](https://github.com/syuilo/misskey/commit/10f6d5980fa7692ccb45fbc5f843458b69b7607c).
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{}年前"
 | 
			
		||||
  month-and-day: "{month}月 {day}日"
 | 
			
		||||
  trash: "ゴミ箱"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "日"
 | 
			
		||||
    monday: "月"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "左に重ねる"
 | 
			
		||||
    pop-right: "右に出す"
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "<i>{{ app.name }}</i>があなたのアカウントにアクセスすることを<b>許可</b>しますか?"
 | 
			
		||||
  permission-ask: "このアプリは次の権限を要求しています:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "決定"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "アイコン"
 | 
			
		||||
  banner: "バナー"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "名前を変更"
 | 
			
		||||
    rename-folder: "フォルダ名の変更"
 | 
			
		||||
    input-new-folder-name: "新しいフォルダ名を入力してください"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  load-more: "もっと読み込む"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  notification: "通知"
 | 
			
		||||
  apps: "アプリ"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "セキュリティ"
 | 
			
		||||
  signin: "サインイン履歴"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
@@ -847,21 +849,33 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "設定が完了しました!"
 | 
			
		||||
  failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
 | 
			
		||||
  info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはありません"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "中"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "ミュートしているユーザーはいません"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "さん"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  lists: "リスト"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "閉じる"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿のみ"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしています"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "他を見る"
 | 
			
		||||
  no-one: "いません!"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  folder-count: "フォルダ"
 | 
			
		||||
  count-separator: "、"
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "メッセージ"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "リスト"
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  more: "もっと見る"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めましょう"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "フォローされています"
 | 
			
		||||
  following: "フォロー"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  media: "メディア"
 | 
			
		||||
  is-suspended: "このユーザーは凍結されています。"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "最近の投稿"
 | 
			
		||||
  images: "画像"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "vor {} Jahr{0:en}"
 | 
			
		||||
  month-and-day: "{day}/{month}"
 | 
			
		||||
  trash: "Papierkorb"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "So"
 | 
			
		||||
    monday: "Mo"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "Nach links schichten"
 | 
			
		||||
    pop-right: "Rechts andocken"
 | 
			
		||||
  dev: "Fehler beim Erstellen der Applikation. Bitte versuche es erneut."
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "<i>{{ app.name }}</i>があなたのアカウントにアクセスすることを<b>許可</b>しますか?"
 | 
			
		||||
  permission-ask: "このアプリは次の権限を要求しています:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "Netzwerk"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "OK"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "benutzt"
 | 
			
		||||
  drive: "Speicher"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "Avatar"
 | 
			
		||||
  banner: "Banner"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "Umbenennen"
 | 
			
		||||
    rename-folder: "Ordner umbenennen"
 | 
			
		||||
    input-new-folder-name: "Namen für neuen Ordner eingeben"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "Laufwerk"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "Suchen"
 | 
			
		||||
  load-more: "Mehr laden"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "Profil"
 | 
			
		||||
  notification: "Mitteilungen"
 | 
			
		||||
  apps: "In App öffnen"
 | 
			
		||||
  mute: "Stummschalten"
 | 
			
		||||
  drive: "Dateien vom Drive anfügen"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "Sicherheit"
 | 
			
		||||
  signin: "サインイン履歴"
 | 
			
		||||
  password: "Passwort"
 | 
			
		||||
@@ -847,27 +849,39 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "設定が完了しました!"
 | 
			
		||||
  failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
 | 
			
		||||
  info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "Bitte Passwort eingeben"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはありません"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "中"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "ミュートしているユーザーはいません"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  reset: "Passwort ändern"
 | 
			
		||||
  enter-current-password: "Derzeitiges Passwort eingeben"
 | 
			
		||||
  enter-new-password: "Neues Passwort eingeben"
 | 
			
		||||
  enter-new-password-again: "Neues Passwort erneut eingeben"
 | 
			
		||||
  not-match: "Passwörter stimmen nicht überein."
 | 
			
		||||
  changed: "Passwort geändert"
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
  enter-new-password-again: "もう一度新しいパスワードを入力してください"
 | 
			
		||||
  not-match: "新しいパスワードが一致しません"
 | 
			
		||||
  changed: "パスワードを変更しました"
 | 
			
		||||
desktop/views/components/sub-note-content.vue:
 | 
			
		||||
  private: "この投稿は非公開です"
 | 
			
		||||
  deleted: "この投稿は削除されました"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "さん"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "Dein Profil"
 | 
			
		||||
  drive: "Speicher"
 | 
			
		||||
  favorites: "Favoriten"
 | 
			
		||||
  lists: "Listen"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "閉じる"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿のみ"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしています"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "他を見る"
 | 
			
		||||
  no-one: "いません!"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  folder-count: "フォルダ"
 | 
			
		||||
  count-separator: "、"
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "メッセージ"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "リスト"
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  more: "Mehr laden"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めましょう"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "フォローされています"
 | 
			
		||||
  following: "フォロー"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  media: "メディア"
 | 
			
		||||
  is-suspended: "このユーザーは凍結されています。"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "最近の投稿"
 | 
			
		||||
  images: "画像"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{}year(s) ago"
 | 
			
		||||
  month-and-day: "{month}/{day}"
 | 
			
		||||
  trash: "Trash"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "S"
 | 
			
		||||
    monday: "M"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "Stack to the left"
 | 
			
		||||
    pop-right: "Dock on the right"
 | 
			
		||||
  dev: "Failed to create the application. Please try again."
 | 
			
		||||
  ai-chan-kawaii: "Ai-chan kawaii!"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "Would you <b>allow</b> <i>{{ app.name }}</i> to access your account?"
 | 
			
		||||
  permission-ask: "This application requires the following permissions:"
 | 
			
		||||
@@ -248,7 +250,7 @@ common/views/components/games/reversi/reversi.room.vue:
 | 
			
		||||
  this-game-is-started-soon: "The game will begin in seconds"
 | 
			
		||||
  waiting-for-other: "Waiting for the opponent"
 | 
			
		||||
  waiting-for-me: "Waiting for the your preparation"
 | 
			
		||||
  waiting-for-both: "Prepareing"
 | 
			
		||||
  waiting-for-both: "Preparing"
 | 
			
		||||
  cancel: "Cancel"
 | 
			
		||||
  ready: "Ready"
 | 
			
		||||
  cancel-ready: "Cancel \"Ready\""
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "Charts"
 | 
			
		||||
  per-day: "per Day"
 | 
			
		||||
  per-hour: "per Hour"
 | 
			
		||||
  federation: "Federation"
 | 
			
		||||
  notes: "Posts"
 | 
			
		||||
  users: "Users"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  network: "Network"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "The number of instances: increase/decrease"
 | 
			
		||||
    federation-instances-total: "Total number of instances"
 | 
			
		||||
    notes: "The number of posts: increase/decrease (Combined)"
 | 
			
		||||
    local-notes: "The number of posts: increase/decrease (Local)"
 | 
			
		||||
    remote-notes: "The number of posts: increase/decrease (Remote)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "OK"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "used"
 | 
			
		||||
  drive: "Media storage"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "Avatar"
 | 
			
		||||
  banner: "Banner"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "Rename"
 | 
			
		||||
    rename-folder: "Rename folder"
 | 
			
		||||
    input-new-folder-name: "Enter new name"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "Media storage"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "Search"
 | 
			
		||||
  load-more: "Load more"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "Profile"
 | 
			
		||||
  notification: "Notification"
 | 
			
		||||
  apps: "Apps"
 | 
			
		||||
  mute: "Mute"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  mute-and-block: "Mute / Block"
 | 
			
		||||
  blocking: "Blocking"
 | 
			
		||||
  security: "Security"
 | 
			
		||||
  signin: "Sign in history"
 | 
			
		||||
  password: "Password"
 | 
			
		||||
@@ -847,27 +849,39 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "Settings saved!"
 | 
			
		||||
  failed: "Failed to setup. Please ensure that the token is correct."
 | 
			
		||||
  info: "From the next time you sign in to Misskey, the token displayed on your device will be necessary too, as well as the password."
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "To access the API, set this token as the key 'i' of request parameters."
 | 
			
		||||
  caution: "Do not enter this token to any apps nor tell this token to others otherwise your account may get compromised."
 | 
			
		||||
  regeneration-of-token: "If your token gets leaked, you can regenerate it."
 | 
			
		||||
  regenerate-token: "Regenerate the token"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "Please enter the password"
 | 
			
		||||
  enter-password: "Enter the password"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'API console'
 | 
			
		||||
    endpoint: 'Endpoint'
 | 
			
		||||
    parameter: 'Parameters'
 | 
			
		||||
    send: 'Send'
 | 
			
		||||
    sending: 'Sending'
 | 
			
		||||
    response: 'Result'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "No linked applications"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "Max"
 | 
			
		||||
  in-use: "In use"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "No muted users"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  stats: "Statistics"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "Mute / Block"
 | 
			
		||||
  mute: "Mute"
 | 
			
		||||
  block: "Blocking"
 | 
			
		||||
  no-muted-users: "No muted users"
 | 
			
		||||
  no-blocked-users: "No blocked users"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "Change password"
 | 
			
		||||
  enter-current-password: "Enter the current password"
 | 
			
		||||
  enter-new-password: "Enter the new password"
 | 
			
		||||
  enter-new-password-again: "Enter new password again"
 | 
			
		||||
  enter-new-password-again: "Enter the new password again"
 | 
			
		||||
  not-match: "The new passwords do not match"
 | 
			
		||||
  changed: "Password updated"
 | 
			
		||||
  changed: "Password changed"
 | 
			
		||||
desktop/views/components/sub-note-content.vue:
 | 
			
		||||
  private: "This post is private"
 | 
			
		||||
  deleted: "This post has been deleted"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "-san"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "Your profile"
 | 
			
		||||
  drive: "Media storage"
 | 
			
		||||
  favorites: "Favorites"
 | 
			
		||||
  lists: "Lists"
 | 
			
		||||
  follow-requests: "Follow requests"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "Pop-out"
 | 
			
		||||
  close: "Close"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "Dashboard"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  instance: "Instance"
 | 
			
		||||
  emoji: "Emoji"
 | 
			
		||||
  users: "Users"
 | 
			
		||||
  update: "Updates"
 | 
			
		||||
  update: "Update"
 | 
			
		||||
  announcements: "Announcements"
 | 
			
		||||
  hashtags: "Hashtags"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Back to Misskey"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "Dashboard"
 | 
			
		||||
  all-users: "All Users"
 | 
			
		||||
  original-users: "Users on this instance"
 | 
			
		||||
  all-notes: "All the posts"
 | 
			
		||||
  original-notes: "Posts on this instance"
 | 
			
		||||
  accounts: "Accounts"
 | 
			
		||||
  notes: "Notes"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  instances: "Instances"
 | 
			
		||||
  this-instance: "This instance"
 | 
			
		||||
  federated: "Federated"
 | 
			
		||||
  invite: "Invite"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "Chart"
 | 
			
		||||
  per-day: "per Day"
 | 
			
		||||
  per-hour: "per Hour"
 | 
			
		||||
  federation: "Federation"
 | 
			
		||||
  notes: "Posts"
 | 
			
		||||
  users: "Users"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  network: "Network"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "The number of instances: increase/decrease"
 | 
			
		||||
    federation-instances-total: "Total number of instances"
 | 
			
		||||
    notes: "The number of posts: increase/decrease (Combined)"
 | 
			
		||||
    local-notes: "The number of posts: increase/decrease (Local)"
 | 
			
		||||
    remote-notes: "The number of posts: increase/decrease (Remote)"
 | 
			
		||||
    notes-total: "Total posts"
 | 
			
		||||
    users: "The number of users: increase/decrease"
 | 
			
		||||
    users-total: "Total users"
 | 
			
		||||
    drive: "Capacity used as the storage: increase/decrease"
 | 
			
		||||
    drive-total: "Total usage of Drive"
 | 
			
		||||
    drive-files: "The number of files on the storage: increase/decrease"
 | 
			
		||||
    drive-files-total: "Total number of files on Drive"
 | 
			
		||||
    network-requests: "Requests"
 | 
			
		||||
    network-time: "Response time"
 | 
			
		||||
    network-usage: "Traffic"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "Suspend a user"
 | 
			
		||||
  suspend: "Suspend"
 | 
			
		||||
  suspended: "Successfully suspended."
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "Unsuspend users"
 | 
			
		||||
  unsuspend: "Unsuspend"
 | 
			
		||||
  unsuspended: "The user has successfully unsuspended."
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "User account verification settings"
 | 
			
		||||
  verify: "Verify account"
 | 
			
		||||
  verified: "The account is now being verified"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "User account unverification settings"
 | 
			
		||||
  unverify: "Unverify account"
 | 
			
		||||
  unverified: "The account is now being unverified"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "Add emoji"
 | 
			
		||||
    name: "Emoji name"
 | 
			
		||||
    name-desc: "You can use the characters a~z 0~9 _"
 | 
			
		||||
    aliases: "Aliases"
 | 
			
		||||
    aliases-desc: "You can add more than one, separated by spaces."
 | 
			
		||||
    url: "Image URL"
 | 
			
		||||
    add: "Add"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "Emojis"
 | 
			
		||||
    update: "Update"
 | 
			
		||||
    remove: "Remove"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "Announcements"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "Save"
 | 
			
		||||
  remove: "Remove"
 | 
			
		||||
  add: "Add"
 | 
			
		||||
  title: "Title"
 | 
			
		||||
  text: "Content"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "Only media posts"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "Mute"
 | 
			
		||||
  muted: "Muting"
 | 
			
		||||
  unmute: "Unmute"
 | 
			
		||||
  block: "Block"
 | 
			
		||||
  unblock: "Unblock"
 | 
			
		||||
  block-confirm: "Are you sure block this user?"
 | 
			
		||||
  push-to-a-list: "Add to list"
 | 
			
		||||
  list-pushed: "Successfully added {user} to {list}."
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "refresh"
 | 
			
		||||
  no-one: "Anyone!"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "Media storage"
 | 
			
		||||
  used: "used"
 | 
			
		||||
  folder-count: "Folder(s)"
 | 
			
		||||
  count-separator: ", "
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "Messages"
 | 
			
		||||
  follow-requests: "Follow requests"
 | 
			
		||||
  search: "Search"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  favorites: "Favorites"
 | 
			
		||||
  user-lists: "Lists"
 | 
			
		||||
  widgets: "Widgets"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "Lists"
 | 
			
		||||
  enter-list-name: "Enter a name of the list to make"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  more: "Load more"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "Your account is now ready! 📦"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "Sounds"
 | 
			
		||||
  enable-sounds: "Enable sounds"
 | 
			
		||||
  mark-as-read-all-unread-notes: "Mark all posts as read"
 | 
			
		||||
  password: "Password"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "Follows you"
 | 
			
		||||
  following: "Following"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "Timeline"
 | 
			
		||||
  media: "Media"
 | 
			
		||||
  is-suspended: "This account has been suspended."
 | 
			
		||||
  mute: "Mute"
 | 
			
		||||
  unmute: "Unmute"
 | 
			
		||||
  block: "Block"
 | 
			
		||||
  unblock: "Unblock"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "Recent notes"
 | 
			
		||||
  images: "Images"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "Hace {} año(s)"
 | 
			
		||||
  month-and-day: "{day} de {month}"
 | 
			
		||||
  trash: "Papelera"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "domingo"
 | 
			
		||||
    monday: "lunes"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "A la izqda."
 | 
			
		||||
    pop-right: "A la dcha."
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "¿Deseas <b>permitir</b> a <i>{{ app.name }}</i> acceder a tu cuenta?"
 | 
			
		||||
  permission-ask: "La aplicación requiere los siguientes permisos:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "Gráficos"
 | 
			
		||||
  per-day: "por día"
 | 
			
		||||
  per-hour: "por hora"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "Publicaciones"
 | 
			
		||||
  users: "Usuarios"
 | 
			
		||||
  drive: "Unidad"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "Número de publicaciones: aumentar/disminuir (Combinado)"
 | 
			
		||||
    local-notes: "Número de publicaciones: aumentar/disminuir (Local)"
 | 
			
		||||
    remote-notes: "Número de publicaciones: aumentar/disminuir (Remoto)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "OK"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "usado"
 | 
			
		||||
  drive: "Disco"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "Avatar"
 | 
			
		||||
  banner: "Banner"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "Renombrar"
 | 
			
		||||
    rename-folder: "Renombrar carpeta"
 | 
			
		||||
    input-new-folder-name: "Escribe el nombre nuevo"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "Disco"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "Buscar"
 | 
			
		||||
  load-more: "Cargar más"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "Perfil"
 | 
			
		||||
  notification: "Notificación"
 | 
			
		||||
  apps: "Aplicaciones"
 | 
			
		||||
  mute: "Silenciar"
 | 
			
		||||
  drive: "Disco"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "Seguridad"
 | 
			
		||||
  signin: "Historial de inicios de sesión"
 | 
			
		||||
  password: "Contraseña"
 | 
			
		||||
@@ -847,27 +849,39 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "¡Configuraciones guardadas!"
 | 
			
		||||
  failed: "Error al configurar. Por favor asegúrate de que el token es correcto."
 | 
			
		||||
  info: "Desde ahora, ingresa el token que se muestra en tu dispositivo adicionalmente a tu contraseña cuando inicies sesión en Misskey"
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
  intro: "Para acceder al API, configura este token como la letra \"i\" de los parámetros requeridos."
 | 
			
		||||
  caution: "Por favor no muestres este token a otros (no lo ingreses en otro lugar que no sea aquí). De otra forma, tu cuenta puede llegar a ser comprometida."
 | 
			
		||||
  regeneration-of-token: "En el caso no deseado de que este token lo tenga otra persona, puedes regenerarlo."
 | 
			
		||||
  regenerate-token: "Regenerar el token"
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "Por favor ingresa tu contraseña"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "No hay aplicaciones asociadas"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "Max"
 | 
			
		||||
  in-use: "en uso."
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "No hay usuarios silenciados"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  reset: "Cambiar contraseña"
 | 
			
		||||
  enter-current-password: "Ingresar contraseña actual"
 | 
			
		||||
  enter-new-password: "Ingresar nueva contraseña"
 | 
			
		||||
  enter-new-password-again: "Ingresar nueva contraseña de nuevo"
 | 
			
		||||
  not-match: "Las nuevas contraseñas no se corresponden consigo mismas"
 | 
			
		||||
  changed: "Contraseña actualizada"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
  enter-new-password-again: "もう一度新しいパスワードを入力してください"
 | 
			
		||||
  not-match: "新しいパスワードが一致しません"
 | 
			
		||||
  changed: "パスワードを変更しました"
 | 
			
		||||
desktop/views/components/sub-note-content.vue:
 | 
			
		||||
  private: "この投稿は非公開です"
 | 
			
		||||
  deleted: "この投稿は削除されました"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "-san"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "Tu perfil"
 | 
			
		||||
  drive: "Unidad"
 | 
			
		||||
  favorites: "Favoritos"
 | 
			
		||||
  lists: "Listas"
 | 
			
		||||
  follow-requests: "Solicitudes de seguimiento"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "閉じる"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿のみ"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしています"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "他を見る"
 | 
			
		||||
  no-one: "いません!"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  folder-count: "フォルダ"
 | 
			
		||||
  count-separator: "、"
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "メッセージ"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "リスト"
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  more: "もっと見る"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めましょう"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "フォローされています"
 | 
			
		||||
  following: "フォロー"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  media: "メディア"
 | 
			
		||||
  is-suspended: "このユーザーは凍結されています。"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "最近の投稿"
 | 
			
		||||
  images: "画像"
 | 
			
		||||
 
 | 
			
		||||
@@ -28,11 +28,11 @@ common:
 | 
			
		||||
  BSoD:
 | 
			
		||||
    fatal-error: ":( 致命的な問題が発生しました。"
 | 
			
		||||
    update-browser-os: "お使いのブラウザ(またはOS)のバージョンを更新すると解決する可能性があります。"
 | 
			
		||||
    error-code: "エラーコード"
 | 
			
		||||
    browser-version: "ブラウザ バージョン"
 | 
			
		||||
    client-version: "クライアント バージョン"
 | 
			
		||||
    error-code: "Code d’erreur"
 | 
			
		||||
    browser-version: "Version du navigateur"
 | 
			
		||||
    client-version: "La version du client"
 | 
			
		||||
    email-support: "問題が解決しない場合は、上記の情報をお書き添えの上 syuilotan@yahoo.co.jp までご連絡ください。"
 | 
			
		||||
    thanks: "Thank you for using Misskey."
 | 
			
		||||
    thanks: "Merci d’avoir choisi d’utiliser Misskey."
 | 
			
		||||
  got-it: "J'ai compris !"
 | 
			
		||||
  customization-tips:
 | 
			
		||||
    title: "Conseils de personnalisation"
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "Il y a {} an·s"
 | 
			
		||||
  month-and-day: "{month} mois/{day} jour"
 | 
			
		||||
  trash: "Corbeille"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "D"
 | 
			
		||||
    monday: "L"
 | 
			
		||||
@@ -123,12 +124,12 @@ common:
 | 
			
		||||
  reduce-motion: "Réduire les animations dans l’interface utilisateur"
 | 
			
		||||
  this-setting-is-this-device-only: "Uniquement sur cet appareil"
 | 
			
		||||
  do-not-use-in-production: 'Il s’agit d’une version de développement. Ne pas utiliser dans un environnement de production.'
 | 
			
		||||
  is-remote-user: "このユーザー情報はコピーです。"
 | 
			
		||||
  is-remote-user: "Ces informations utilisateur ont été copiées."
 | 
			
		||||
  is-remote-post: "この投稿情報はコピーです。"
 | 
			
		||||
  view-on-remote: "正確な情報を見る"
 | 
			
		||||
  view-on-remote: "Consulter le profil complet"
 | 
			
		||||
  error:
 | 
			
		||||
    title: '問題が発生しました'
 | 
			
		||||
    retry: 'やり直す'
 | 
			
		||||
    title: 'Une erreur est survenue'
 | 
			
		||||
    retry: 'Réessayer'
 | 
			
		||||
  reversi:
 | 
			
		||||
    drawn: "Partie nulle"
 | 
			
		||||
    my-turn: "C’est votre tour"
 | 
			
		||||
@@ -184,7 +185,8 @@ common:
 | 
			
		||||
    rename: "Renommer"
 | 
			
		||||
    stack-left: "Vers la gauche"
 | 
			
		||||
    pop-right: "Vers la droite"
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  dev: "Échec lors de la création de l’application. Veuillez réessayer."
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "Désirez-vous <b>autoriser</b> <i>{{ app.name }}</i> à avoir accès à votre compte ?"
 | 
			
		||||
  permission-ask: "Cette application nécessite les autorisations suivantes :"
 | 
			
		||||
@@ -443,7 +445,7 @@ common/views/components/profile-editor.vue:
 | 
			
		||||
  is-cat: "Ce compte est un Chat"
 | 
			
		||||
  is-bot: "Ce compte est un Bot"
 | 
			
		||||
  is-locked: "Demandes d’abonnements requièrent l’approbation"
 | 
			
		||||
  careful-bot: "Botからのフォローだけ承認制にする"
 | 
			
		||||
  careful-bot: "Les demandes d’abonnements venant de Bots requièrent l’approbation"
 | 
			
		||||
  advanced: "Avancé"
 | 
			
		||||
  privacy: "Vie privée"
 | 
			
		||||
  save: "Mettre à jour le profil"
 | 
			
		||||
@@ -500,7 +502,7 @@ common/views/widgets/tips.vue:
 | 
			
		||||
  tips-line14: "ホームのカスタマイズ中、ウィジェットを右クリックしてデザインを変更できます"
 | 
			
		||||
  tips-line17: "Vous pouvez mettre un texte en surbrillance en le mettant entre ** **"
 | 
			
		||||
  tips-line19: "Plusieurs fenêtres peuvent être détachées en dehors du navigateur."
 | 
			
		||||
  tips-line20: "カレンダーウィジェットのパーセンテージは、経過の割合を示しています"
 | 
			
		||||
  tips-line20: "Pourcentage sur le widget calendrier qui indique le pourcentage de temps passé"
 | 
			
		||||
  tips-line21: "Vous pouvez aussi utiliser l'API pour développer des Bots."
 | 
			
		||||
  tips-line23: "Mayu est mignone avec ses sourcils."
 | 
			
		||||
  tips-line24: "Misskey a vu le jour en 2014"
 | 
			
		||||
@@ -541,21 +543,24 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "Graphiques"
 | 
			
		||||
  per-day: "par jour"
 | 
			
		||||
  per-hour: "par heure"
 | 
			
		||||
  federation: "Fédération"
 | 
			
		||||
  notes: "Publications"
 | 
			
		||||
  users: "Utilisateurs"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  network: "Réseau"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "Nombre d’instances : augmentation/diminution"
 | 
			
		||||
    federation-instances-total: "Nombre total d’instances"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "Total des notes"
 | 
			
		||||
    users: "Nombre d’utilisateurs·trices : augmentation/diminution"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    users-total: "Nombre total des utilisateurs·rices"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-total: "Utilisation totale du lecteur"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    drive-files-total: "Nombre total de fichiers sur le lecteur"
 | 
			
		||||
    network-requests: "Requêtes"
 | 
			
		||||
    network-time: "Temps de réponse"
 | 
			
		||||
    network-usage: "Traffic"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "OK"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "utilisé"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "Avatar"
 | 
			
		||||
  banner: "Bannière"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "Renommer"
 | 
			
		||||
    rename-folder: "Renommer le dossier"
 | 
			
		||||
    input-new-folder-name: "Entrer un nouveau nom"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "Rechercher"
 | 
			
		||||
  load-more: "Afficher plus"
 | 
			
		||||
@@ -678,10 +680,10 @@ desktop/views/components/note.vue:
 | 
			
		||||
  reposted-by: "Partagé par {}"
 | 
			
		||||
  reply: "Répondre"
 | 
			
		||||
  renote: "Partager"
 | 
			
		||||
  add-reaction: "リアクション"
 | 
			
		||||
  detail: "詳細"
 | 
			
		||||
  private: "この投稿は非公開です"
 | 
			
		||||
  deleted: "この投稿は削除されました"
 | 
			
		||||
  add-reaction: "Ajouter votre réaction"
 | 
			
		||||
  detail: "Détails"
 | 
			
		||||
  private: "Cette publication est privée"
 | 
			
		||||
  deleted: "Cette publication a été supprimée"
 | 
			
		||||
desktop/views/components/notes.vue:
 | 
			
		||||
  error: "Échec du chargement."
 | 
			
		||||
  retry: "Réessayer"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "Profil"
 | 
			
		||||
  notification: "Notification"
 | 
			
		||||
  apps: "Applications"
 | 
			
		||||
  mute: "Mettre en sourdine"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "Sécurité"
 | 
			
		||||
  signin: "Historique de connexion"
 | 
			
		||||
  password: "Mot de Passe"
 | 
			
		||||
@@ -765,7 +767,7 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  deck-default: "デッキをデフォルトのUIにする"
 | 
			
		||||
  display: "Affichage et design"
 | 
			
		||||
  customize: "Personnaliser l'Accueil"
 | 
			
		||||
  wallpaper: "壁紙"
 | 
			
		||||
  wallpaper: "Arrière plan"
 | 
			
		||||
  choose-wallpaper: "Sélectionner un fond d'écran"
 | 
			
		||||
  delete-wallpaper: "Supprimer le fond d'écran"
 | 
			
		||||
  dark-mode: "Mode nuit"
 | 
			
		||||
@@ -777,14 +779,14 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  suggest-recent-hashtags: "Afficher les hashtags populaires dans le champs de saisie"
 | 
			
		||||
  show-clock-on-header: "Afficher l'horloge à droite sur le coté supérieur"
 | 
			
		||||
  show-reply-target: "Afficher les réponses"
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  timeline: "Chronologie"
 | 
			
		||||
  show-my-renotes: "Afficher mes republications dans le fil"
 | 
			
		||||
  show-renoted-my-notes: "Afficher mes republications dans les fils"
 | 
			
		||||
  show-local-renotes: "ローカルの投稿のRenoteをタイムラインに表示する"
 | 
			
		||||
  show-local-renotes: "Afficher les partages locaux sur les fils"
 | 
			
		||||
  show-maps: "Afficher la carte"
 | 
			
		||||
  deck-column-align: "デッキのカラムの位置"
 | 
			
		||||
  deck-column-align-center: "中央"
 | 
			
		||||
  deck-column-align-left: "左"
 | 
			
		||||
  deck-column-align-center: "Centrer"
 | 
			
		||||
  deck-column-align-left: "À gauche"
 | 
			
		||||
  sound: "Son"
 | 
			
		||||
  enable-sounds: "Activer le son"
 | 
			
		||||
  enable-sounds-desc: "Jouer un son lorsque vous recevez un message. Ce paramètre est sauvegardé dans le navigateur."
 | 
			
		||||
@@ -825,7 +827,7 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  tools: "Outils"
 | 
			
		||||
  task-manager: "Gestionnaire de tâches"
 | 
			
		||||
  third-parties: "Services tiers"
 | 
			
		||||
  navbar-position: "ナビゲーションバーの位置"
 | 
			
		||||
  navbar-position: "Position de la barre de navigation"
 | 
			
		||||
  navbar-position-top: "En haut"
 | 
			
		||||
  navbar-position-left: "à gauche"
 | 
			
		||||
  navbar-position-right: "à droite"
 | 
			
		||||
@@ -847,26 +849,38 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "L'operation a été complétée avec succès!"
 | 
			
		||||
  failed: "L'operation a échoué. Veuillez vous assurer que le token a été entrer correctement."
 | 
			
		||||
  info: "À partir de maintenant, à chaque fois que vous vous connecter entrez votre mot de passe ainsi que le token généré sur votre appareil."
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "Si votre jeton est compromis, vous pouvez le régénérer."
 | 
			
		||||
  regenerate-token: "Regenerer le token"
 | 
			
		||||
  regenerate-token: "Régénérer le jeton"
 | 
			
		||||
  token: "Jeton :"
 | 
			
		||||
  enter-password: "Veuillez entrer le mot de passe"
 | 
			
		||||
  enter-password: "Entrez le mot de passe"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'Console API'
 | 
			
		||||
    endpoint: 'Point de terminaison'
 | 
			
		||||
    parameter: 'Paramètres'
 | 
			
		||||
    send: 'Envoyer'
 | 
			
		||||
    sending: 'Envoi en cours'
 | 
			
		||||
    response: 'Résultat'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "Aucune application autorisée"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "Maximum"
 | 
			
		||||
  in-use: "en cours d’utilisation"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "Aucun utilisateurs mis en sourdine"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  reset: "Changer votre mot de passe"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "Maximale"
 | 
			
		||||
  in-use: "utilisé"
 | 
			
		||||
  stats: "Statistiques"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "Silencer / Bloquer"
 | 
			
		||||
  mute: "Mettre en sourdine"
 | 
			
		||||
  block: "En cours blocage"
 | 
			
		||||
  no-muted-users: "Aucun utilisateur·rice n’est mis·e en sourdine"
 | 
			
		||||
  no-blocked-users: "Aucun utilisateur·rice n’est bloqué·e"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "Modifier le mot de passe"
 | 
			
		||||
  enter-current-password: "Entrez votre mot de passe actuel"
 | 
			
		||||
  enter-new-password: "Entrez votre nouveau mot de passe"
 | 
			
		||||
  enter-new-password: "Saisissez le nouveau mot de passe"
 | 
			
		||||
  enter-new-password-again: "Entrez à nouveau le nouveau mot de passe"
 | 
			
		||||
  not-match: "Le nouveau mot de passe ne correspond pas."
 | 
			
		||||
  not-match: "Les nouveaux mots de passe ne sont pas identiques"
 | 
			
		||||
  changed: "Mot de passe modifié avec succès"
 | 
			
		||||
desktop/views/components/sub-note-content.vue:
 | 
			
		||||
  private: "cette publication est privée"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "M."
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "Votre profil"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  favorites: "Favorites"
 | 
			
		||||
  lists: "Listes"
 | 
			
		||||
  follow-requests: "Demandes de suivi"
 | 
			
		||||
@@ -934,56 +947,100 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "Fermer"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "Tableau de bord"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  instance: "Instance"
 | 
			
		||||
  emoji: "Emoji"
 | 
			
		||||
  users: "Utilisateur·rice·s"
 | 
			
		||||
  update: "Mises à jour"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  update: "Mise à jour"
 | 
			
		||||
  announcements: "Annonces"
 | 
			
		||||
  hashtags: "Hashtags"
 | 
			
		||||
  back-to-misskey: "Retour vers Misskey"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "Tableau de bord"
 | 
			
		||||
  all-users: "Toutes les utilisateurrices"
 | 
			
		||||
  original-users: "Utilisateur·rice·s sur cette instance"
 | 
			
		||||
  all-notes: "Toutes les publications"
 | 
			
		||||
  original-notes: "Publications sur cette instance"
 | 
			
		||||
  invite: "Invitation"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
  accounts: "Comptes"
 | 
			
		||||
  notes: "Notes"
 | 
			
		||||
  drive: "Lecteur"
 | 
			
		||||
  instances: "Instances"
 | 
			
		||||
  this-instance: "Cette instance"
 | 
			
		||||
  federated: "Fédérées"
 | 
			
		||||
  invite: "Inviter"
 | 
			
		||||
  banner-url: "URL de la bannière"
 | 
			
		||||
  disableRegistration: "Désactiver l’enregistrement de nouveaux utilisateur·rice·s"
 | 
			
		||||
  disableLocalTimeline: "Désactiver le fil local"
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "Graph"
 | 
			
		||||
  per-day: "par jour"
 | 
			
		||||
  per-hour: "par heure"
 | 
			
		||||
  federation: "Fédération"
 | 
			
		||||
  notes: "Publications"
 | 
			
		||||
  users: "Utilisateur·rice·s"
 | 
			
		||||
  drive: "Lecteur"
 | 
			
		||||
  network: "Réseau"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "Nombre d’instances : augmentation/diminution"
 | 
			
		||||
    federation-instances-total: "Nombre total d’instances"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "Total des publications"
 | 
			
		||||
    users: "Nombre d’utilisateur·rice·s : augmentation/diminution"
 | 
			
		||||
    users-total: "Nombre total des utilisateur·rice·s"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "Utilisation totale du lecteur"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "Nombre total de fichiers sur le lecteur"
 | 
			
		||||
    network-requests: "Requêtes"
 | 
			
		||||
    network-time: "Temps de réponse"
 | 
			
		||||
    network-usage: "Traffic"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "Suspendre un·e utilisateur·rice"
 | 
			
		||||
  suspend: "Suspendre"
 | 
			
		||||
  suspended: "Suspendu avec succès"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  suspended: "Suspendu·e avec succès."
 | 
			
		||||
  unsuspend-user: "Lever la suspension d’utilisateur·rice·s"
 | 
			
		||||
  unsuspend: "Suspension levée"
 | 
			
		||||
  unsuspended: "La suspension de l’utilisateur·rice a été levée avec succès"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "Paramètres de vérification du compte utilisateur"
 | 
			
		||||
  verify: "Vérification du compte"
 | 
			
		||||
  verified: "Le compte a été vérifié"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "Ôter la vérification du compte"
 | 
			
		||||
  unverified: "Ce compte n'est pas vérifié"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
  unverified: "Ce compte n'est plus vérifié"
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "Ajouter un émoji"
 | 
			
		||||
    name: "Nom de l’émoji"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "Aliases"
 | 
			
		||||
    aliases-desc: "Vous pouvez définir plus d’un, séparés par des espaces."
 | 
			
		||||
    url: "URL de l’image"
 | 
			
		||||
    add: "Ajouter"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "Annonces"
 | 
			
		||||
  save: "Enregistrer"
 | 
			
		||||
  remove: "Supprimer"
 | 
			
		||||
  add: "Ajouter"
 | 
			
		||||
  title: "Titre"
 | 
			
		||||
  text: "Contenu"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Tags cachés"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "Les publications médias uniquement"
 | 
			
		||||
  is-media-view: "Vue média"
 | 
			
		||||
  edit: "Options"
 | 
			
		||||
desktop/views/pages/deck/deck.user-column.vue:
 | 
			
		||||
  posts: "投稿"
 | 
			
		||||
  following: "フォロー"
 | 
			
		||||
  followers: "フォロワー"
 | 
			
		||||
  images: "画像"
 | 
			
		||||
  activity: "アクティビティ"
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  pinned-notes: "ピン留めされた投稿"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  posts: "Publications"
 | 
			
		||||
  following: "Suit"
 | 
			
		||||
  followers: "Abonné·e·s"
 | 
			
		||||
  images: "Images"
 | 
			
		||||
  activity: "Activité"
 | 
			
		||||
  timeline: "Chronologie"
 | 
			
		||||
  pinned-notes: "Publications épinglées"
 | 
			
		||||
  push-to-a-list: "Ajouter à la liste"
 | 
			
		||||
desktop/views/pages/stats/stats.vue:
 | 
			
		||||
  all-users: "Toutes les utilisateurrices"
 | 
			
		||||
  original-users: "Utilisateur·rice·s sur cette instance"
 | 
			
		||||
@@ -1036,7 +1093,7 @@ desktop/views/pages/user/user.friends.vue:
 | 
			
		||||
  no-users: "Pas d'utilisateurs"
 | 
			
		||||
desktop/views/pages/user/user.vue:
 | 
			
		||||
  is-suspended: "Ce compte a été suspendu."
 | 
			
		||||
  last-used-at: "最終アクセス"
 | 
			
		||||
  last-used-at: "Actif·ive pour la dernière fois"
 | 
			
		||||
desktop/views/pages/user/user.photos.vue:
 | 
			
		||||
  title: "Photos"
 | 
			
		||||
  loading: "Chargement en cours"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "Mettre en sourdine"
 | 
			
		||||
  muted: "Muting"
 | 
			
		||||
  unmute: "Enlever la sourdine"
 | 
			
		||||
  block: "Bloquer"
 | 
			
		||||
  unblock: "Débloquer"
 | 
			
		||||
  block-confirm: "Bloquer cet utilisateur ?"
 | 
			
		||||
  push-to-a-list: "Ajouter à la liste"
 | 
			
		||||
  list-pushed: "Vous avez ajouté {user} à la liste {list}."
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1056,10 +1116,10 @@ desktop/views/pages/user/user.header.vue:
 | 
			
		||||
  following: "Suit"
 | 
			
		||||
  followers: "Abonné·e·s"
 | 
			
		||||
  is-bot: "Ce compte est un Bot"
 | 
			
		||||
  years-old: "歳"
 | 
			
		||||
  year: "年"
 | 
			
		||||
  month: "月"
 | 
			
		||||
  day: "日"
 | 
			
		||||
  years-old: "ans d’âge"
 | 
			
		||||
  year: "Année"
 | 
			
		||||
  month: "Mois"
 | 
			
		||||
  day: "Jour"
 | 
			
		||||
desktop/views/pages/user/user.timeline.vue:
 | 
			
		||||
  default: "Publications"
 | 
			
		||||
  with-replies: "Publications et réponses"
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "Afficher d'autres"
 | 
			
		||||
  no-one: "Personne"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  used: "utilisé"
 | 
			
		||||
  folder-count: "Dossier(s)"
 | 
			
		||||
  count-separator: ", "
 | 
			
		||||
@@ -1119,8 +1178,8 @@ mobile/views/components/drive.file-detail.vue:
 | 
			
		||||
  hash: "Hash (md5)"
 | 
			
		||||
  exif: "EXIF"
 | 
			
		||||
  nsfw: "CW"
 | 
			
		||||
  mark-as-sensitive: "閲覧注意に設定"
 | 
			
		||||
  unmark-as-sensitive: "閲覧注意を解除"
 | 
			
		||||
  mark-as-sensitive: "Marquer comme sensible"
 | 
			
		||||
  unmark-as-sensitive: "Ne pas marquer comme sensible"
 | 
			
		||||
mobile/views/components/media-image.vue:
 | 
			
		||||
  sensitive: "Le contenu est NSFW"
 | 
			
		||||
  click-to-show: "Cliquer pour afficher"
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "Messages"
 | 
			
		||||
  follow-requests: "Demandes d'abonnement"
 | 
			
		||||
  search: "Rechercher"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  favorites: "Favoris"
 | 
			
		||||
  user-lists: "Listes"
 | 
			
		||||
  widgets: "Modules"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "Listes"
 | 
			
		||||
  enter-list-name: "Nom de la liste"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  more: "Afficher plus ..."
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "Votre compte est prêt ! 📦"
 | 
			
		||||
@@ -1282,8 +1339,8 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  timeline: "Fil d'actualité"
 | 
			
		||||
  show-reply-target: "Afficher les réponses"
 | 
			
		||||
  show-my-renotes: "Afficher mes republications"
 | 
			
		||||
  show-renoted-my-notes: "自分の投稿のRenoteを表示する"
 | 
			
		||||
  show-local-renotes: "ローカルの投稿のRenoteを表示する"
 | 
			
		||||
  show-renoted-my-notes: "Afficher mes publications partagées"
 | 
			
		||||
  show-local-renotes: "Afficher les publications partagées localement"
 | 
			
		||||
  post-style: "Style de la publication"
 | 
			
		||||
  post-style-standard: "Standard"
 | 
			
		||||
  post-style-smart: "Intelligent"
 | 
			
		||||
@@ -1316,7 +1373,8 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  signout: "Déconnexion"
 | 
			
		||||
  sound: "Sons"
 | 
			
		||||
  enable-sounds: "Activer les sons"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "Marquer toutes les publications comme lues"
 | 
			
		||||
  password: "Mot de Passe"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "Vous suit"
 | 
			
		||||
  following: "Abonnements"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "Fil d'actualité"
 | 
			
		||||
  media: "Media"
 | 
			
		||||
  is-suspended: "This account has been suspended."
 | 
			
		||||
  mute: "Mettre en sourdine"
 | 
			
		||||
  unmute: "Enlever la sourdine"
 | 
			
		||||
  block: "Bloquer"
 | 
			
		||||
  unblock: "Débloquer"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "Notes récentes"
 | 
			
		||||
  images: "Images"
 | 
			
		||||
@@ -1372,28 +1434,28 @@ docs:
 | 
			
		||||
dev/views/index.vue:
 | 
			
		||||
  manage-apps: "Gestion des applications"
 | 
			
		||||
dev/views/apps.vue:
 | 
			
		||||
  manage-apps: "アプリを管理"
 | 
			
		||||
  create-app: "アプリ作成"
 | 
			
		||||
  app-missing: "アプリなし"
 | 
			
		||||
  manage-apps: "Gestion des applications"
 | 
			
		||||
  create-app: "Créer une app"
 | 
			
		||||
  app-missing: "Aucune application"
 | 
			
		||||
dev/views/new-app.vue:
 | 
			
		||||
  create-app: "アプリケーションの作成"
 | 
			
		||||
  app-name: "アプリケーション名"
 | 
			
		||||
  app-name-desc: "あなたのアプリの名称。"
 | 
			
		||||
  app-name-ex: "ex) Misskey for iOS"
 | 
			
		||||
  app-overview: "アプリの概要"
 | 
			
		||||
  app-desc: "あなたのアプリの簡単な説明や紹介。"
 | 
			
		||||
  app-desc-ex: "ex) Misskey iOSクライアント。"
 | 
			
		||||
  create-app: "Création d’une application"
 | 
			
		||||
  app-name: "Nom de l’application"
 | 
			
		||||
  app-name-desc: "Le nom de votre application"
 | 
			
		||||
  app-name-ex: "p. ex. Misskey pour iOS"
 | 
			
		||||
  app-overview: "Description courte de l’application"
 | 
			
		||||
  app-desc: "Brève description introductive à votre application."
 | 
			
		||||
  app-desc-ex: "p. ex) Misskey pour iOS"
 | 
			
		||||
  callback-url: "コールバックURL (オプション)"
 | 
			
		||||
  callback-url-desc: "ユーザーが認証フォームで認証した際にリダイレクトするURLを設定できます。"
 | 
			
		||||
  authority: "権限"
 | 
			
		||||
  authority: "Autorisations "
 | 
			
		||||
  authority-desc: "ここで要求した機能だけがAPIからアクセスできます。"
 | 
			
		||||
  authority-warning: "アプリ作成後も変更できますが、新たな権限を付与する場合、その時点で関連付けられているユーザーキーはすべて無効になります。"
 | 
			
		||||
  account-read: "アカウントの情報を見る。"
 | 
			
		||||
  account-write: "アカウントの情報を操作する。"
 | 
			
		||||
  note-write: "投稿する。"
 | 
			
		||||
  reaction-write: "リアクションしたりリアクションをキャンセルする。"
 | 
			
		||||
  following-write: "フォローしたりフォロー解除する。"
 | 
			
		||||
  drive-read: "ドライブを見る。"
 | 
			
		||||
  drive-write: "ドライブを操作する。"
 | 
			
		||||
  notification-read: "通知を見る。"
 | 
			
		||||
  notification-write: "通知を操作する。"
 | 
			
		||||
  account-read: "Afficher les informations du compte"
 | 
			
		||||
  account-write: "Modifications des informations du compte"
 | 
			
		||||
  note-write: "Publications."
 | 
			
		||||
  reaction-write: "Ajout et suppression de réactions."
 | 
			
		||||
  following-write: "S’abonner et se désabonner."
 | 
			
		||||
  drive-read: "Lecture du Drive."
 | 
			
		||||
  drive-write: "Téléversement/suppression des fichiers de votre Lecteur."
 | 
			
		||||
  notification-read: "Lire vos notifications."
 | 
			
		||||
  notification-write: "Gestion de vos notifications."
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{}年前"
 | 
			
		||||
  month-and-day: "{month}月 {day}日"
 | 
			
		||||
  trash: "ゴミ箱"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "日"
 | 
			
		||||
    monday: "月"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "左に重ねる"
 | 
			
		||||
    pop-right: "右に出す"
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "<i>{{ app.name }}</i>があなたのアカウントにアクセスすることを<b>許可</b>しますか?"
 | 
			
		||||
  permission-ask: "このアプリは次の権限を要求しています:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "決定"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "アイコン"
 | 
			
		||||
  banner: "バナー"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "名前を変更"
 | 
			
		||||
    rename-folder: "フォルダ名の変更"
 | 
			
		||||
    input-new-folder-name: "新しいフォルダ名を入力してください"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  load-more: "もっと読み込む"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  notification: "通知"
 | 
			
		||||
  apps: "アプリ"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "セキュリティ"
 | 
			
		||||
  signin: "サインイン履歴"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
@@ -847,21 +849,33 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "設定が完了しました!"
 | 
			
		||||
  failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
 | 
			
		||||
  info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはありません"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "中"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "ミュートしているユーザーはいません"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "さん"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  lists: "リスト"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "閉じる"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿のみ"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしています"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "他を見る"
 | 
			
		||||
  no-one: "いません!"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  folder-count: "フォルダ"
 | 
			
		||||
  count-separator: "、"
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "メッセージ"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "リスト"
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  more: "もっと見る"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めましょう"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "フォローされています"
 | 
			
		||||
  following: "フォロー"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  media: "メディア"
 | 
			
		||||
  is-suspended: "このユーザーは凍結されています。"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "最近の投稿"
 | 
			
		||||
  images: "画像"
 | 
			
		||||
 
 | 
			
		||||
@@ -64,6 +64,7 @@ common:
 | 
			
		||||
  month-and-day: "{month}月 {day}日"
 | 
			
		||||
 | 
			
		||||
  trash: "ゴミ箱"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "日"
 | 
			
		||||
@@ -200,6 +201,7 @@ common:
 | 
			
		||||
    pop-right: "右に出す"
 | 
			
		||||
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "<i>{{ app.name }}</i>があなたのアカウントにアクセスすることを<b>許可</b>しますか?"
 | 
			
		||||
@@ -415,6 +417,7 @@ common/views/components/signin.vue:
 | 
			
		||||
  signin: "サインイン"
 | 
			
		||||
  or: "または"
 | 
			
		||||
  signin-with-twitter: "Twitterでログイン"
 | 
			
		||||
  signin-with-github: "GitHubでログイン"
 | 
			
		||||
  login-failed: "ログインできませんでした。ユーザー名とパスワードを確認してください。"
 | 
			
		||||
 | 
			
		||||
common/views/components/signup.vue:
 | 
			
		||||
@@ -458,6 +461,14 @@ common/views/components/twitter-setting.vue:
 | 
			
		||||
  connect: "Twitterと接続する"
 | 
			
		||||
  disconnect: "切断する"
 | 
			
		||||
 | 
			
		||||
common/views/components/github-setting.vue:
 | 
			
		||||
  description: "お使いのGitHubアカウントをお使いのMisskeyアカウントに接続しておくと、プロフィールでGitHubアカウント情報が表示されるようになったり、GitHubを用いた便利なサインインを利用できるようになります。"
 | 
			
		||||
  connected-to: "次のGitHubアカウントに接続されています"
 | 
			
		||||
  detail: "詳細..."
 | 
			
		||||
  reconnect: "再接続する"
 | 
			
		||||
  connect: "GitHubと接続する"
 | 
			
		||||
  disconnect: "切断する"
 | 
			
		||||
 | 
			
		||||
common/views/components/uploader.vue:
 | 
			
		||||
  waiting: "待機中"
 | 
			
		||||
 | 
			
		||||
@@ -597,29 +608,6 @@ desktop/views/components/calendar.vue:
 | 
			
		||||
  next: "次の月"
 | 
			
		||||
  go: "クリックして時間遡行"
 | 
			
		||||
 | 
			
		||||
desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
 | 
			
		||||
desktop/views/components/choose-file-from-drive-window.vue:
 | 
			
		||||
  choose-file: "ファイル選択中"
 | 
			
		||||
  upload: "PCからドライブにファイルをアップロード"
 | 
			
		||||
@@ -639,7 +627,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "アイコン"
 | 
			
		||||
@@ -672,9 +659,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename-folder: "フォルダ名の変更"
 | 
			
		||||
    input-new-folder-name: "新しいフォルダ名を入力してください"
 | 
			
		||||
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  load-more: "もっと読み込む"
 | 
			
		||||
@@ -832,8 +816,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  notification: "通知"
 | 
			
		||||
  apps: "アプリ"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "セキュリティ"
 | 
			
		||||
  signin: "サインイン履歴"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
@@ -951,25 +935,37 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
 | 
			
		||||
  info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
 | 
			
		||||
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはありません"
 | 
			
		||||
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "中"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "ミュートしているユーザーはいません"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
@@ -1005,7 +1001,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  lists: "リスト"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
@@ -1058,49 +1053,98 @@ desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "閉じる"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/instance.vue:
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  instance-name: "インスタンス名"
 | 
			
		||||
  instance-description: "インスタンスの紹介"
 | 
			
		||||
  banner-url: "バナー画像URL"
 | 
			
		||||
  disableRegistration: "ユーザー登録の受付を停止する"
 | 
			
		||||
  disableLocalTimeline: "ローカルタイムラインを無効にする"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  save: "保存"
 | 
			
		||||
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
@@ -1118,12 +1162,6 @@ desktop/views/pages/deck/deck.user-column.vue:
 | 
			
		||||
  pinned-notes: "ピン留めされた投稿"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/stats/stats.vue:
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
 | 
			
		||||
desktop/views/pages/welcome.vue:
 | 
			
		||||
  about: "詳しく..."
 | 
			
		||||
  gotit: "わかった"
 | 
			
		||||
@@ -1198,6 +1236,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしています"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
 | 
			
		||||
@@ -1248,7 +1289,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  no-one: "いません!"
 | 
			
		||||
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  folder-count: "フォルダ"
 | 
			
		||||
  count-separator: "、"
 | 
			
		||||
@@ -1372,7 +1412,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "メッセージ"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1400,7 +1439,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  more: "もっと見る"
 | 
			
		||||
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
@@ -1505,6 +1543,10 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  twitter-connect: "Twitterアカウントに接続する"
 | 
			
		||||
  twitter-reconnect: "再接続する"
 | 
			
		||||
  twitter-disconnect: "切断する"
 | 
			
		||||
  github: "GitHub連携"
 | 
			
		||||
  github-connect: "GitHubアカウントに接続する"
 | 
			
		||||
  github-reconnect: "再接続する"
 | 
			
		||||
  github-disconnect: "切断する"
 | 
			
		||||
  update: "Misskey Update"
 | 
			
		||||
  version: "バージョン:"
 | 
			
		||||
  latest-version: "最新のバージョン:"
 | 
			
		||||
@@ -1519,6 +1561,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "フォローされています"
 | 
			
		||||
@@ -1529,6 +1572,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  media: "メディア"
 | 
			
		||||
  is-suspended: "このユーザーは凍結されています。"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "最近の投稿"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{}年前"
 | 
			
		||||
  month-and-day: "{month}月 {day}日"
 | 
			
		||||
  trash: "ゴミ箱"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "日"
 | 
			
		||||
    monday: "月"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "左に重ねんで!"
 | 
			
		||||
    pop-right: "右に出すで!"
 | 
			
		||||
  dev: "アプリの作成あかんかったわ。もっぺんやってみて。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃめっさべっぴんさんや"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "<i>{{ app.name }}</i>があんさんのアカウントにアクセスすんのを<b>許可</b>してもええか?"
 | 
			
		||||
  permission-ask: "このアプリは次の権限を要求してんで:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減(統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "そうする"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "使うとる"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "アイコン"
 | 
			
		||||
  banner: "バナー"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "名前を変えるで"
 | 
			
		||||
    rename-folder: "フォルダ名を変えるで"
 | 
			
		||||
    input-new-folder-name: "新しいフォルダ名を入力してや"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  load-more: "もっとあらへんのか!"
 | 
			
		||||
@@ -740,9 +742,9 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  notification: "通知"
 | 
			
		||||
  apps: "アプリ"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  security: "守護神セキュリティ"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "セキュリティ"
 | 
			
		||||
  signin: "こんな感じでサインインしたらしいで"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
  2fa: "二段階認証"
 | 
			
		||||
@@ -847,25 +849,37 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "設定が完了したで!"
 | 
			
		||||
  failed: "なんか設定に失敗したで。トークンを間違えとらんか確認してや。"
 | 
			
		||||
  info: "次のサインインからは、パスワードに加えてデバイスに出とるトークンを入力してな。"
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」っちゅうキーでパラメータに付加してリクエストしてや。"
 | 
			
		||||
  caution: "アカウントを不正利用されるかも知れんから、このトークンは第三者に教えたらあかんで(アプリなどにも入力しんといてな)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたとかその可能性があったらトークンを再生成できるで。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "トークン:"
 | 
			
		||||
  enter-password: "パスワードを入力してや"
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "API使うんやったらこのトークンを「i」っちゅうパラメータにくっつけてリクエストできるで。"
 | 
			
		||||
  caution: "アカウント勝手にいじられるかも知れんから、このトークンは教えたらあかんし、アプリにも書いたらあかんで(これはフリちゃうで)"
 | 
			
		||||
  regeneration-of-token: "トークン漏れてもうたんやったらもっかい生成できるで。"
 | 
			
		||||
  regenerate-token: "トークンもっかい生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "パスワードを入れてや"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送る'
 | 
			
		||||
    sending: '応答待っとる'
 | 
			
		||||
    response: 'こんなん返ってきたわ'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはあらへんで"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "中"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "ミュートしているユーザーはおらんで"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使うとる"
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしとるユーザーはおらんで"
 | 
			
		||||
  no-blocked-users: "ブロックしとるユーザーはおらんで"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワード変える"
 | 
			
		||||
  enter-current-password: "今のパスワードを入れてや"
 | 
			
		||||
  enter-new-password: "さらのパスワード入れてや"
 | 
			
		||||
  enter-new-password-again: "もういっぺんさらのパスワードを入れてや"
 | 
			
		||||
  enter-new-password: "こんどのパスワード入れてや"
 | 
			
		||||
  enter-new-password-again: "もっぺん入れてや"
 | 
			
		||||
  not-match: "パスワードがおうとらん"
 | 
			
		||||
  changed: "パスワード変えたわ"
 | 
			
		||||
desktop/views/components/sub-note-content.vue:
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "はん"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  lists: "リスト"
 | 
			
		||||
  follow-requests: "フォロー許してくれや!言うてみる"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "さいなら"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  announcements: "知っといてや"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "知り合い全員や"
 | 
			
		||||
  original-users: "ここの人らだけ"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "ワイのインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "来てや"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減(統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結したで"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除したで"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしたで"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウントにせーへん"
 | 
			
		||||
  unverify: "公式アカウントにはさせへんで"
 | 
			
		||||
  unverified: "公式アカウントを解除したで"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿だけや"
 | 
			
		||||
@@ -980,10 +1037,10 @@ desktop/views/pages/deck/deck.user-column.vue:
 | 
			
		||||
  following: "フォロー"
 | 
			
		||||
  followers: "フォロワー"
 | 
			
		||||
  images: "画像"
 | 
			
		||||
  activity: "アクティビティ"
 | 
			
		||||
  activity: "やっとること"
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  pinned-notes: "ピン留めされた投稿"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  pinned-notes: "ピン留めしはった投稿"
 | 
			
		||||
  push-to-a-list: "リストに入れたる"
 | 
			
		||||
desktop/views/pages/stats/stats.vue:
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "ここの人らだけ"
 | 
			
		||||
@@ -1036,7 +1093,7 @@ desktop/views/pages/user/user.friends.vue:
 | 
			
		||||
  no-users: "よう話すツレは居らん"
 | 
			
		||||
desktop/views/pages/user/user.vue:
 | 
			
		||||
  is-suspended: "このユーザーはあかんわ。凍結されとる。"
 | 
			
		||||
  last-used-at: "最終アクセス"
 | 
			
		||||
  last-used-at: "最後いつ来はった?"
 | 
			
		||||
desktop/views/pages/user/user.photos.vue:
 | 
			
		||||
  title: "写真"
 | 
			
		||||
  loading: "読み込んどります"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしとるで"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加したで。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "他を見る"
 | 
			
		||||
  no-one: "おらん!"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  used: "使うとる"
 | 
			
		||||
  folder-count: "フォルダ"
 | 
			
		||||
  count-separator: "、"
 | 
			
		||||
@@ -1119,8 +1178,8 @@ mobile/views/components/drive.file-detail.vue:
 | 
			
		||||
  hash: "ハッシュ(md5)"
 | 
			
		||||
  exif: "EXIF"
 | 
			
		||||
  nsfw: "ちょっと見せられへんわ"
 | 
			
		||||
  mark-as-sensitive: "閲覧注意に設定"
 | 
			
		||||
  unmark-as-sensitive: "閲覧注意を解除"
 | 
			
		||||
  mark-as-sensitive: "見たらあかん感じにしとく"
 | 
			
		||||
  unmark-as-sensitive: "やっぱ見せたるわ"
 | 
			
		||||
mobile/views/components/media-image.vue:
 | 
			
		||||
  sensitive: "見たらあかんで"
 | 
			
		||||
  click-to-show: "押してみ、見せたるわ"
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "メッセージ"
 | 
			
		||||
  follow-requests: "フォロー許してくれや!言うてみる"
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "リスト"
 | 
			
		||||
  enter-list-name: "リスト名を入力してや"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  more: "もっとあるやろ!"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めようや"
 | 
			
		||||
@@ -1316,7 +1373,8 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  signout: "さいなら"
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンド鳴らす"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "全部もう読んだわ"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "フォローされとるで"
 | 
			
		||||
  following: "フォロー"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  media: "メディア"
 | 
			
		||||
  is-suspended: "このユーザーはあかんわ。凍結されとる。"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロックやめたる"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "最近儲かりまっか?"
 | 
			
		||||
  images: "画像"
 | 
			
		||||
@@ -1373,27 +1435,27 @@ dev/views/index.vue:
 | 
			
		||||
  manage-apps: "アプリの管理"
 | 
			
		||||
dev/views/apps.vue:
 | 
			
		||||
  manage-apps: "アプリを管理"
 | 
			
		||||
  create-app: "アプリ作成"
 | 
			
		||||
  app-missing: "アプリなし"
 | 
			
		||||
  create-app: "アプリ作る"
 | 
			
		||||
  app-missing: "アプリあらへん"
 | 
			
		||||
dev/views/new-app.vue:
 | 
			
		||||
  create-app: "アプリケーションの作成"
 | 
			
		||||
  app-name: "アプリケーション名"
 | 
			
		||||
  app-name-desc: "あなたのアプリの名称。"
 | 
			
		||||
  app-name-ex: "ex) Misskey for iOS"
 | 
			
		||||
  app-overview: "アプリの概要"
 | 
			
		||||
  app-desc: "あなたのアプリの簡単な説明や紹介。"
 | 
			
		||||
  app-desc-ex: "ex) Misskey iOSクライアント。"
 | 
			
		||||
  callback-url: "コールバックURL (オプション)"
 | 
			
		||||
  callback-url-desc: "ユーザーが認証フォームで認証した際にリダイレクトするURLを設定できます。"
 | 
			
		||||
  create-app: "アプリケーション作る"
 | 
			
		||||
  app-name: "アプリケーションの名前"
 | 
			
		||||
  app-name-desc: "あんたのアプリの名前。"
 | 
			
		||||
  app-name-ex: "ex) 関西ミスキー保安協会"
 | 
			
		||||
  app-overview: "このアプリどんなん?"
 | 
			
		||||
  app-desc: "あんたのアプリどんなんか教えて"
 | 
			
		||||
  app-desc-ex: "ex) 関西人なら誰でも口ずさめるこのCMがついにMisskeyへ。"
 | 
			
		||||
  callback-url: "コールバックURL (無くてもええで)"
 | 
			
		||||
  callback-url-desc: "ユーザーが認証フォームで認証した後どこに連れてくかを設定できるで"
 | 
			
		||||
  authority: "権限"
 | 
			
		||||
  authority-desc: "ここで要求した機能だけがAPIからアクセスできます。"
 | 
			
		||||
  authority-warning: "アプリ作成後も変更できますが、新たな権限を付与する場合、その時点で関連付けられているユーザーキーはすべて無効になります。"
 | 
			
		||||
  account-read: "アカウントの情報を見る。"
 | 
			
		||||
  account-write: "アカウントの情報を操作する。"
 | 
			
		||||
  note-write: "投稿する。"
 | 
			
		||||
  reaction-write: "リアクションしたりリアクションをキャンセルする。"
 | 
			
		||||
  following-write: "フォローしたりフォロー解除する。"
 | 
			
		||||
  drive-read: "ドライブを見る。"
 | 
			
		||||
  drive-write: "ドライブを操作する。"
 | 
			
		||||
  notification-read: "通知を見る。"
 | 
			
		||||
  notification-write: "通知を操作する。"
 | 
			
		||||
  authority-desc: "ここにチェックした機能しかAPIからアクセスできひんから気ぃつけてな"
 | 
			
		||||
  authority-warning: "アプリ作った後でも変えれるけど、新しいやつ追加したらそん時関連付いてるユーザーキーは全部ほかされるで。"
 | 
			
		||||
  account-read: "アカウントの情報見せて"
 | 
			
		||||
  account-write: "アカウントの情報いじらせて"
 | 
			
		||||
  note-write: "投稿させて"
 | 
			
		||||
  reaction-write: "リアクションしたりそれをキャンセルさせて"
 | 
			
		||||
  following-write: "フォローとかフォロー解除させて"
 | 
			
		||||
  drive-read: "ドライブ見せて"
 | 
			
		||||
  drive-write: "ドライブいじらせて"
 | 
			
		||||
  notification-read: "通知見せて"
 | 
			
		||||
  notification-write: "通知いじらせて"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{}년전"
 | 
			
		||||
  month-and-day: "{month}월 {day}일"
 | 
			
		||||
  trash: "휴지통"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "일"
 | 
			
		||||
    monday: "월"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "左に重ねる"
 | 
			
		||||
    pop-right: "右に出す"
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "<i>{{ app.name }}</i>があなたのアカウントにアクセスすることを<b>許可</b>しますか?"
 | 
			
		||||
  permission-ask: "このアプリは次の権限を要求しています:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "決定"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "アイコン"
 | 
			
		||||
  banner: "バナー"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "名前を変更"
 | 
			
		||||
    rename-folder: "フォルダ名の変更"
 | 
			
		||||
    input-new-folder-name: "新しいフォルダ名を入力してください"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  load-more: "もっと読み込む"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  notification: "通知"
 | 
			
		||||
  apps: "アプリ"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "セキュリティ"
 | 
			
		||||
  signin: "サインイン履歴"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
@@ -847,21 +849,33 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "設定が完了しました!"
 | 
			
		||||
  failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
 | 
			
		||||
  info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはありません"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "中"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "ミュートしているユーザーはいません"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "さん"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  lists: "リスト"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "閉じる"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿のみ"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしています"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "他を見る"
 | 
			
		||||
  no-one: "いません!"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  folder-count: "フォルダ"
 | 
			
		||||
  count-separator: "、"
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "メッセージ"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "リスト"
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  more: "もっと見る"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めましょう"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "フォローされています"
 | 
			
		||||
  following: "フォロー"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  media: "メディア"
 | 
			
		||||
  is-suspended: "このユーザーは凍結されています。"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "最近の投稿"
 | 
			
		||||
  images: "画像"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{}jaar geleden"
 | 
			
		||||
  month-and-day: "{month}月 {day}日"
 | 
			
		||||
  trash: "ゴミ箱"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "Z"
 | 
			
		||||
    monday: "M"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "左に重ねる"
 | 
			
		||||
    pop-right: "右に出す"
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "<i>{{ app.name }}</i>があなたのアカウントにアクセスすることを<b>許可</b>しますか?"
 | 
			
		||||
  permission-ask: "このアプリは次の権限を要求しています:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "Oké"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "gebruikt"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "Gebruikersafbeelding"
 | 
			
		||||
  banner: "Omslagfoto"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "Naam wijzigen"
 | 
			
		||||
    rename-folder: "Mapnaam wijzigen"
 | 
			
		||||
    input-new-folder-name: "Voer een nieuwe naam in"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "Zoeken"
 | 
			
		||||
  load-more: "Meer laden"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "Profiel"
 | 
			
		||||
  notification: "Melding"
 | 
			
		||||
  apps: "Apps"
 | 
			
		||||
  mute: "Dempen"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "Beveiliging"
 | 
			
		||||
  signin: "Inloggeschiedenis"
 | 
			
		||||
  password: "Wachtwoord"
 | 
			
		||||
@@ -847,27 +849,39 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "Instellen voltooid!"
 | 
			
		||||
  failed: "Instellen mislukt. Zorg ervoor dat de sleutel juist is."
 | 
			
		||||
  info: "Vanaf nu moet je ook de op je apparaat getoonde sleutel tonen bij het inloggen op Misskey."
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
  intro: "Als je toegang wilt tot de API, stel deze sleutel dan in als 'i' bij de verzoekparameters."
 | 
			
		||||
  caution: "Laat deze sleutel niet zien aan derde partijen (en voer hem nergens anders in dan hier), anders kan je account gehackt worden."
 | 
			
		||||
  regeneration-of-token: "Mocht deze sleutel tóch uitlekken, dan kun je hem opnieuw genereren."
 | 
			
		||||
  regenerate-token: "Sleutel opnieuw genereren"
 | 
			
		||||
  token: "Sleutel:"
 | 
			
		||||
  enter-password: "Voer je wachtwoord in"
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはありません"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "中"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "Geen gedempte gebruikers"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  reset: "Wachtwoord wijzigen"
 | 
			
		||||
  enter-current-password: "Voer je huidige wachtwoord in"
 | 
			
		||||
  enter-new-password: "Voer je nieuwe wachtwoord in"
 | 
			
		||||
  enter-new-password-again: "Voer je nieuwe wachtwoord nogmaals in"
 | 
			
		||||
  not-match: "Het nieuwe wachtwoord komt niet overeen"
 | 
			
		||||
  changed: "Wachtwoord bijgewerkt"
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
  enter-new-password-again: "もう一度新しいパスワードを入力してください"
 | 
			
		||||
  not-match: "新しいパスワードが一致しません"
 | 
			
		||||
  changed: "パスワードを変更しました"
 | 
			
		||||
desktop/views/components/sub-note-content.vue:
 | 
			
		||||
  private: "この投稿は非公開です"
 | 
			
		||||
  deleted: "この投稿は削除されました"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "さん"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "Je profiel"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  favorites: "Favorieten"
 | 
			
		||||
  lists: "Lijsten"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "Uitvouwen"
 | 
			
		||||
  close: "Sluiten"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿のみ"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "Dempen"
 | 
			
		||||
  muted: "Dempend"
 | 
			
		||||
  unmute: "Ontdempen"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "Anderen tonen"
 | 
			
		||||
  no-one: "Niemand"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  used: "gebruikt"
 | 
			
		||||
  folder-count: "Map(pen)"
 | 
			
		||||
  count-separator: ", "
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "Gesprekken"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "Zoeken"
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "リスト"
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "Drive"
 | 
			
		||||
  more: "もっと見る"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めましょう"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "Volgt jou"
 | 
			
		||||
  following: "Volgend"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "Tijdlijn"
 | 
			
		||||
  media: "Media"
 | 
			
		||||
  is-suspended: "Dit account is geschorst."
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "Recente notities"
 | 
			
		||||
  images: "Afbeeldingen"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{} år siden"
 | 
			
		||||
  month-and-day: "{day}/{month}"
 | 
			
		||||
  trash: "Papirkurv"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "S"
 | 
			
		||||
    monday: "M"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "左に重ねる"
 | 
			
		||||
    pop-right: "Til høyre"
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "<i>{{ app.name }}</i>があなたのアカウントにアクセスすることを<b>許可</b>しますか?"
 | 
			
		||||
  permission-ask: "このアプリは次の権限を要求しています:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "Diagrammer"
 | 
			
		||||
  per-day: "per dag"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "Innlegg"
 | 
			
		||||
  users: "Brukere"
 | 
			
		||||
  drive: "Disk"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "Ok"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "brukt"
 | 
			
		||||
  drive: "Disk"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "Avatar"
 | 
			
		||||
  banner: "Banner"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "Endre navn"
 | 
			
		||||
    rename-folder: "フォルダ名の変更"
 | 
			
		||||
    input-new-folder-name: "新しいフォルダ名を入力してください"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "Disk"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "Søk"
 | 
			
		||||
  load-more: "もっと読み込む"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  notification: "Notifikasjon"
 | 
			
		||||
  apps: "Apper"
 | 
			
		||||
  mute: "Demp"
 | 
			
		||||
  drive: "Disk"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "セキュリティ"
 | 
			
		||||
  signin: "サインイン履歴"
 | 
			
		||||
  password: "Passord"
 | 
			
		||||
@@ -847,21 +849,33 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "設定が完了しました!"
 | 
			
		||||
  failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
 | 
			
		||||
  info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはありません"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "Maks"
 | 
			
		||||
  in-use: "I bruk"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "ミュートしているユーザーはいません"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "-san"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  drive: "Disk"
 | 
			
		||||
  favorites: "Favoritter"
 | 
			
		||||
  lists: "Lister"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "Lukk"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "Disk"
 | 
			
		||||
  users: "Brukere"
 | 
			
		||||
  update: "Oppdater"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  invite: "Inviter"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "Suspender"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿のみ"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしています"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "Oppdater"
 | 
			
		||||
  no-one: "Ingen"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "Disk"
 | 
			
		||||
  used: "brukt"
 | 
			
		||||
  folder-count: "Mappe(r)"
 | 
			
		||||
  count-separator: ","
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "Meldinger"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "Søk"
 | 
			
		||||
  drive: "Disk"
 | 
			
		||||
  favorites: "Favoritter"
 | 
			
		||||
  user-lists: "Lister"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "Lister"
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "Disk"
 | 
			
		||||
  more: "Vis mer"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めましょう"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "Lyder"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "フォローされています"
 | 
			
		||||
  following: "Følger"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  media: "Media"
 | 
			
		||||
  is-suspended: "このユーザーは凍結されています。"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "Nylige innlegg"
 | 
			
		||||
  images: "Bilder"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{} lat temu"
 | 
			
		||||
  month-and-day: "{month}-{day}"
 | 
			
		||||
  trash: "Kosz"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "N"
 | 
			
		||||
    monday: "Pn"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "Przypnij do lewej"
 | 
			
		||||
    pop-right: "Odepnij w prawo"
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "Czy chcesz <b>zezwolić</b> <i>{{ app.name }}</i> na dostęp do Twojego konta?"
 | 
			
		||||
  permission-ask: "Ta aplikacja wymaga następujących uprawnień:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "OK"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "wykorzystane"
 | 
			
		||||
  drive: "Dysk"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "Awatar"
 | 
			
		||||
  banner: "Baner"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "Zmień nazwę"
 | 
			
		||||
    rename-folder: "Zmień nazwę katalogu"
 | 
			
		||||
    input-new-folder-name: "Wprowadź nową nazwę"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "Dysk"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "Szukaj"
 | 
			
		||||
  load-more: "Załaduj więcej"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "Profil"
 | 
			
		||||
  notification: "Powiadomienia"
 | 
			
		||||
  apps: "Aplikacje"
 | 
			
		||||
  mute: "Wyciszanie"
 | 
			
		||||
  drive: "Dysk"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "Bezpieczeństwo"
 | 
			
		||||
  signin: "Historia logowań"
 | 
			
		||||
  password: "Hasło"
 | 
			
		||||
@@ -847,27 +849,39 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "Pomyślnie ukończono konfigurację!"
 | 
			
		||||
  failed: "Nie udało się skonfigurować uwierzytelniania dwuetapowego, upewnij się że wprowadziłeś prawidłowy token."
 | 
			
		||||
  info: "Od teraz, wprowadzaj token wyświetlany na urządzeniu przy każdym logowaniu do Misskey."
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
  intro: "Aby uzyskać dostęp do API, ustaw ten token jako klucz 'i' parametrów żądań."
 | 
			
		||||
  caution: "Nie pokazuj tego tokenu osobom trzecim (nie wprowadzaj go nigdzie indziej), aby konto nie trafiło w niepowołane ręce."
 | 
			
		||||
  regeneration-of-token: "W przypadku wycieku tokenu, możesz wygenerować nowy."
 | 
			
		||||
  regenerate-token: "Wygeneruj nowy token"
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "Wprowadź hasło"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "Brak zautoryzowanych aplikacji"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "Maksymalnie"
 | 
			
		||||
  in-use: " w użyciu."
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "Brak wyciszonych użytkowników"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  reset: "Zmień hasło"
 | 
			
		||||
  enter-current-password: "Wprowadź obecne hasło"
 | 
			
		||||
  enter-new-password: "Wprowadź nowe hasło"
 | 
			
		||||
  enter-new-password-again: "Wprowadź ponownie nowe hasło"
 | 
			
		||||
  not-match: "Nowe hasła nie pasują do siebie"
 | 
			
		||||
  changed: "Pomyślnie zmieniono hasło"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
  enter-new-password-again: "もう一度新しいパスワードを入力してください"
 | 
			
		||||
  not-match: "新しいパスワードが一致しません"
 | 
			
		||||
  changed: "パスワードを変更しました"
 | 
			
		||||
desktop/views/components/sub-note-content.vue:
 | 
			
		||||
  private: "ten wpis jest prywatny"
 | 
			
		||||
  deleted: "ten wpis został usunięty"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "さん"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "Twój profil"
 | 
			
		||||
  drive: "Dysk"
 | 
			
		||||
  favorites: "Ulubione"
 | 
			
		||||
  lists: "Listy"
 | 
			
		||||
  follow-requests: "Prośby o śledzenie"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "Pop-out"
 | 
			
		||||
  close: "Zamknij"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "Tylko wpisy z zawartością multimedialną"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "Wycisz"
 | 
			
		||||
  muted: "Wyciszyłeś"
 | 
			
		||||
  unmute: "Cofnij wyciszenie"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "Dodaj do listy"
 | 
			
		||||
  list-pushed: "Dodałeś(-aś) {user} do {list}."
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "Pokaż innych"
 | 
			
		||||
  no-one: "Pusto"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "Dysk"
 | 
			
		||||
  used: "użyto"
 | 
			
		||||
  folder-count: "Katalog(i)"
 | 
			
		||||
  count-separator: ", "
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "Wiadomości"
 | 
			
		||||
  follow-requests: "Prośby o śledzenie"
 | 
			
		||||
  search: "Szukaj"
 | 
			
		||||
  drive: "Dysk"
 | 
			
		||||
  favorites: "Ulubione"
 | 
			
		||||
  user-lists: "Listy"
 | 
			
		||||
  widgets: "Widżety"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "Listy"
 | 
			
		||||
  enter-list-name: "Wprowadź nazwę listy"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "Dysk"
 | 
			
		||||
  more: "Załaduj więcej"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "Rozpocznijmy! 📦"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "Śledzi Cię"
 | 
			
		||||
  following: "Śledzeni"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "Oś czasu"
 | 
			
		||||
  media: "Multimedia"
 | 
			
		||||
  is-suspended: "To konto zostało zablokowane"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "Ostatnie wpisy"
 | 
			
		||||
  images: "Zdjęcia"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{} ano(s) atrás"
 | 
			
		||||
  month-and-day: "{day}/{month}"
 | 
			
		||||
  trash: "Lixo"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "Dom"
 | 
			
		||||
    monday: "Seg"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "左に重ねる"
 | 
			
		||||
    pop-right: "Acoplar à direita"
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "Você <b>permite</b> que <i>{{ app.name }}</i> acesse sua conta?"
 | 
			
		||||
  permission-ask: "Este aplicativo precisa das seguintes permissões:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "決定"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "アイコン"
 | 
			
		||||
  banner: "バナー"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "名前を変更"
 | 
			
		||||
    rename-folder: "フォルダ名の変更"
 | 
			
		||||
    input-new-folder-name: "新しいフォルダ名を入力してください"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  load-more: "もっと読み込む"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  notification: "通知"
 | 
			
		||||
  apps: "アプリ"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "セキュリティ"
 | 
			
		||||
  signin: "サインイン履歴"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
@@ -847,21 +849,33 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "設定が完了しました!"
 | 
			
		||||
  failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
 | 
			
		||||
  info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはありません"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "中"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "ミュートしているユーザーはいません"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "さん"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  lists: "リスト"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "閉じる"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  users: "Usuários"
 | 
			
		||||
  update: "Actualizações"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "Todos os usuários"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿のみ"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしています"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "他を見る"
 | 
			
		||||
  no-one: "いません!"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  folder-count: "フォルダ"
 | 
			
		||||
  count-separator: "、"
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "メッセージ"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "リスト"
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  more: "もっと見る"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めましょう"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "Sons"
 | 
			
		||||
  enable-sounds: "Ativar sons"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "Te segue"
 | 
			
		||||
  following: "Seguindo"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "Linha do tempo"
 | 
			
		||||
  media: "Mídia"
 | 
			
		||||
  is-suspended: "Esta conta foi suspensa"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "Notas recentes"
 | 
			
		||||
  images: "Imagens"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{}年前"
 | 
			
		||||
  month-and-day: "{month}月 {day}日"
 | 
			
		||||
  trash: "ゴミ箱"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "日"
 | 
			
		||||
    monday: "月"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "左に重ねる"
 | 
			
		||||
    pop-right: "右に出す"
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "<i>{{ app.name }}</i>があなたのアカウントにアクセスすることを<b>許可</b>しますか?"
 | 
			
		||||
  permission-ask: "このアプリは次の権限を要求しています:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "決定"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "アイコン"
 | 
			
		||||
  banner: "バナー"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "名前を変更"
 | 
			
		||||
    rename-folder: "フォルダ名の変更"
 | 
			
		||||
    input-new-folder-name: "新しいフォルダ名を入力してください"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  load-more: "もっと読み込む"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  notification: "通知"
 | 
			
		||||
  apps: "アプリ"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "セキュリティ"
 | 
			
		||||
  signin: "サインイン履歴"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
@@ -847,21 +849,33 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "設定が完了しました!"
 | 
			
		||||
  failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
 | 
			
		||||
  info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはありません"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "中"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "ミュートしているユーザーはいません"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "さん"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  lists: "リスト"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "閉じる"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿のみ"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしています"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "他を見る"
 | 
			
		||||
  no-one: "いません!"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  folder-count: "フォルダ"
 | 
			
		||||
  count-separator: "、"
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "メッセージ"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "リスト"
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  more: "もっと見る"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めましょう"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "フォローされています"
 | 
			
		||||
  following: "フォロー"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  media: "メディア"
 | 
			
		||||
  is-suspended: "このユーザーは凍結されています。"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "最近の投稿"
 | 
			
		||||
  images: "画像"
 | 
			
		||||
 
 | 
			
		||||
@@ -62,6 +62,7 @@ common:
 | 
			
		||||
    years_ago: "{}年前"
 | 
			
		||||
  month-and-day: "{month}月 {day}日"
 | 
			
		||||
  trash: "ゴミ箱"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  weekday-short:
 | 
			
		||||
    sunday: "日"
 | 
			
		||||
    monday: "月"
 | 
			
		||||
@@ -185,6 +186,7 @@ common:
 | 
			
		||||
    stack-left: "左に重ねる"
 | 
			
		||||
    pop-right: "右に出す"
 | 
			
		||||
  dev: "アプリの作成に失敗しました。再度お試しください。"
 | 
			
		||||
  ai-chan-kawaii: "藍ちゃかわいい"
 | 
			
		||||
auth/views/form.vue:
 | 
			
		||||
  share-access: "<i>{{ app.name }}</i>があなたのアカウントにアクセスすることを<b>許可</b>しますか?"
 | 
			
		||||
  permission-ask: "このアプリは次の権限を要求しています:"
 | 
			
		||||
@@ -541,11 +543,14 @@ desktop/views/components/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
@@ -575,7 +580,6 @@ desktop/views/components/crop-window.vue:
 | 
			
		||||
  ok: "決定"
 | 
			
		||||
desktop/views/components/drive-window.vue:
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.file.vue:
 | 
			
		||||
  avatar: "アイコン"
 | 
			
		||||
  banner: "バナー"
 | 
			
		||||
@@ -605,8 +609,6 @@ desktop/views/components/drive.folder.vue:
 | 
			
		||||
    rename: "名前を変更"
 | 
			
		||||
    rename-folder: "フォルダ名の変更"
 | 
			
		||||
    input-new-folder-name: "新しいフォルダ名を入力してください"
 | 
			
		||||
desktop/views/components/drive.nav-folder.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
desktop/views/components/drive.vue:
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  load-more: "もっと読み込む"
 | 
			
		||||
@@ -740,8 +742,8 @@ desktop/views/components/settings.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  notification: "通知"
 | 
			
		||||
  apps: "アプリ"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  mute-and-block: "ミュート/ブロック"
 | 
			
		||||
  blocking: "ブロック"
 | 
			
		||||
  security: "セキュリティ"
 | 
			
		||||
  signin: "サインイン履歴"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
@@ -847,21 +849,33 @@ desktop/views/components/settings.2fa.vue:
 | 
			
		||||
  success: "設定が完了しました!"
 | 
			
		||||
  failed: "設定に失敗しました。トークンに誤りがないかご確認ください。"
 | 
			
		||||
  info: "次回サインインからは、同様にパスワードに加えてデバイスに表示されているトークンを入力します。"
 | 
			
		||||
desktop/views/components/settings.api.vue:
 | 
			
		||||
common/views/components/api-settings.vue:
 | 
			
		||||
  intro: "APIを利用するには、上記のトークンを「i」というキーでパラメータに付加してリクエストします。"
 | 
			
		||||
  caution: "アカウントを不正利用される可能性があるため、このトークンは第三者に教えないでください(アプリなどにも入力しないでください)。"
 | 
			
		||||
  regeneration-of-token: "万が一このトークンが漏れたりその可能性がある場合はトークンを再生成できます。"
 | 
			
		||||
  regenerate-token: "トークンを再生成"
 | 
			
		||||
  token: "Token:"
 | 
			
		||||
  enter-password: "パスワードを入力してください"
 | 
			
		||||
  console:
 | 
			
		||||
    title: 'APIコンソール'
 | 
			
		||||
    endpoint: 'エンドポイント'
 | 
			
		||||
    parameter: 'パラメータ'
 | 
			
		||||
    send: '送信'
 | 
			
		||||
    sending: '応答待ち'
 | 
			
		||||
    response: '結果'
 | 
			
		||||
desktop/views/components/settings.apps.vue:
 | 
			
		||||
  no-apps: "連携しているアプリケーションはありません"
 | 
			
		||||
desktop/views/components/settings.drive.vue:
 | 
			
		||||
  max: "中"
 | 
			
		||||
common/views/components/drive-settings.vue:
 | 
			
		||||
  max: "容量"
 | 
			
		||||
  in-use: "使用中"
 | 
			
		||||
desktop/views/components/settings.mute.vue:
 | 
			
		||||
  no-users: "ミュートしているユーザーはいません"
 | 
			
		||||
desktop/views/components/settings.password.vue:
 | 
			
		||||
  stats: "統計"
 | 
			
		||||
common/views/components/mute-and-block.vue:
 | 
			
		||||
  mute-and-block: "ミュートとブロック"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  no-muted-users: "ミュートしているユーザーはいません"
 | 
			
		||||
  no-blocked-users: "ブロックしているユーザーはいません"
 | 
			
		||||
common/views/components/password-settings.vue:
 | 
			
		||||
  reset: "パスワードを変更する"
 | 
			
		||||
  enter-current-password: "現在のパスワードを入力してください"
 | 
			
		||||
  enter-new-password: "新しいパスワードを入力してください"
 | 
			
		||||
@@ -892,7 +906,6 @@ desktop/views/components/ui.header.vue:
 | 
			
		||||
  adjective: "さん"
 | 
			
		||||
desktop/views/components/ui.header.account.vue:
 | 
			
		||||
  profile: "プロフィール"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  lists: "リスト"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
@@ -934,42 +947,86 @@ desktop/views/components/users-list-item.vue:
 | 
			
		||||
desktop/views/components/window.vue:
 | 
			
		||||
  popout: "ポップアウト"
 | 
			
		||||
  close: "閉じる"
 | 
			
		||||
desktop/views/pages/admin/admin.vue:
 | 
			
		||||
admin/views/index.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instance: "インスタンス"
 | 
			
		||||
  emoji: "カスタム絵文字"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  update: "更新"
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
  hashtags: "ハッシュタグ"
 | 
			
		||||
desktop/views/pages/admin/admin.dashboard.vue:
 | 
			
		||||
  back-to-misskey: "Misskeyに戻る"
 | 
			
		||||
admin/views/dashboard.vue:
 | 
			
		||||
  dashboard: "ダッシュボード"
 | 
			
		||||
  all-users: "全てのユーザー"
 | 
			
		||||
  original-users: "このインスタンスのユーザー"
 | 
			
		||||
  all-notes: "全ての投稿"
 | 
			
		||||
  original-notes: "このインスタンスの投稿"
 | 
			
		||||
  accounts: "アカウント"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  instances: "インスタンス"
 | 
			
		||||
  this-instance: "このインスタンス"
 | 
			
		||||
  federated: "連合"
 | 
			
		||||
  invite: "招待"
 | 
			
		||||
  banner-url: "Banner URL"
 | 
			
		||||
  disableRegistration: "Disable new user registration"
 | 
			
		||||
  disableLocalTimeline: "Disable the local timeline"
 | 
			
		||||
desktop/views/pages/admin/admin.suspend-user.vue:
 | 
			
		||||
admin/views/charts.vue:
 | 
			
		||||
  title: "チャート"
 | 
			
		||||
  per-day: "1日ごと"
 | 
			
		||||
  per-hour: "1時間ごと"
 | 
			
		||||
  federation: "フェデレーション"
 | 
			
		||||
  notes: "投稿"
 | 
			
		||||
  users: "ユーザー"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  network: "ネットワーク"
 | 
			
		||||
  charts:
 | 
			
		||||
    federation-instances: "インスタンスの増減"
 | 
			
		||||
    federation-instances-total: "インスタンスの積算"
 | 
			
		||||
    notes: "投稿の増減 (統合)"
 | 
			
		||||
    local-notes: "投稿の増減 (ローカル)"
 | 
			
		||||
    remote-notes: "投稿の増減 (リモート)"
 | 
			
		||||
    notes-total: "投稿の積算"
 | 
			
		||||
    users: "ユーザーの増減"
 | 
			
		||||
    users-total: "ユーザーの積算"
 | 
			
		||||
    drive: "ドライブ使用量の増減"
 | 
			
		||||
    drive-total: "ドライブ使用量の積算"
 | 
			
		||||
    drive-files: "ドライブのファイル数の増減"
 | 
			
		||||
    drive-files-total: "ドライブのファイル数の積算"
 | 
			
		||||
    network-requests: "リクエスト"
 | 
			
		||||
    network-time: "応答時間"
 | 
			
		||||
    network-usage: "通信量"
 | 
			
		||||
admin/views/users.vue:
 | 
			
		||||
  suspend-user: "ユーザーの凍結"
 | 
			
		||||
  suspend: "凍結"
 | 
			
		||||
  suspended: "凍結しました"
 | 
			
		||||
desktop/views/pages/admin/admin.unsuspend-user.vue:
 | 
			
		||||
  unsuspend-user: "ユーザーの凍結の解除"
 | 
			
		||||
  unsuspend: "凍結の解除"
 | 
			
		||||
  unsuspended: "凍結を解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.verify-user.vue:
 | 
			
		||||
  verify-user: "ユーザーの公式アカウント設定"
 | 
			
		||||
  verify: "公式アカウントにする"
 | 
			
		||||
  verified: "公式アカウントにしました"
 | 
			
		||||
desktop/views/pages/admin/admin.unverify-user.vue:
 | 
			
		||||
  unverify-user: "ユーザーの公式アカウント解除"
 | 
			
		||||
  unverify: "公式アカウントを解除する"
 | 
			
		||||
  unverified: "公式アカウントを解除しました"
 | 
			
		||||
desktop/views/pages/admin/admin.announcements.vue:
 | 
			
		||||
admin/views/emoji.vue:
 | 
			
		||||
  add-emoji:
 | 
			
		||||
    title: "絵文字の登録"
 | 
			
		||||
    name: "絵文字名"
 | 
			
		||||
    name-desc: "a~z 0~9 _ の文字が使えます。"
 | 
			
		||||
    aliases: "エイリアス"
 | 
			
		||||
    aliases-desc: "スペースで区切って複数設定できます。"
 | 
			
		||||
    url: "絵文字画像URL"
 | 
			
		||||
    add: "追加"
 | 
			
		||||
  emojis:
 | 
			
		||||
    title: "絵文字一覧"
 | 
			
		||||
    update: "更新"
 | 
			
		||||
    remove: "削除"
 | 
			
		||||
admin/views/announcements.vue:
 | 
			
		||||
  announcements: "お知らせ"
 | 
			
		||||
desktop/views/pages/admin/admin.hashtags.vue:
 | 
			
		||||
  save: "保存"
 | 
			
		||||
  remove: "削除"
 | 
			
		||||
  add: "追加"
 | 
			
		||||
  title: "タイトル"
 | 
			
		||||
  text: "内容"
 | 
			
		||||
admin/views/hashtags.vue:
 | 
			
		||||
  hided-tags: "Hidden Tags"
 | 
			
		||||
desktop/views/pages/deck/deck.tl-column.vue:
 | 
			
		||||
  is-media-only: "メディア投稿のみ"
 | 
			
		||||
@@ -1049,6 +1106,9 @@ desktop/views/pages/user/user.profile.vue:
 | 
			
		||||
  mute: "ミュートする"
 | 
			
		||||
  muted: "ミュートしています"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロックする"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
  block-confirm: "このユーザーをブロックしますか?"
 | 
			
		||||
  push-to-a-list: "リストに追加"
 | 
			
		||||
  list-pushed: "{user}を{list}に追加しました。"
 | 
			
		||||
desktop/views/pages/user/user.header.vue:
 | 
			
		||||
@@ -1089,7 +1149,6 @@ desktop/views/widgets/users.vue:
 | 
			
		||||
  refresh: "他を見る"
 | 
			
		||||
  no-one: "いません!"
 | 
			
		||||
mobile/views/components/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  used: "使用中"
 | 
			
		||||
  folder-count: "フォルダ"
 | 
			
		||||
  count-separator: "、"
 | 
			
		||||
@@ -1193,7 +1252,6 @@ mobile/views/components/ui.nav.vue:
 | 
			
		||||
  messaging: "メッセージ"
 | 
			
		||||
  follow-requests: "フォロー申請"
 | 
			
		||||
  search: "検索"
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  favorites: "お気に入り"
 | 
			
		||||
  user-lists: "リスト"
 | 
			
		||||
  widgets: "ウィジェット"
 | 
			
		||||
@@ -1216,7 +1274,6 @@ mobile/views/pages/user-lists.vue:
 | 
			
		||||
  title: "リスト"
 | 
			
		||||
  enter-list-name: "リスト名を入力してください"
 | 
			
		||||
mobile/views/pages/drive.vue:
 | 
			
		||||
  drive: "ドライブ"
 | 
			
		||||
  more: "もっと見る"
 | 
			
		||||
mobile/views/pages/signup.vue:
 | 
			
		||||
  lets-start: "📦 始めましょう"
 | 
			
		||||
@@ -1317,6 +1374,7 @@ mobile/views/pages/settings.vue:
 | 
			
		||||
  sound: "サウンド"
 | 
			
		||||
  enable-sounds: "サウンドを有効にする"
 | 
			
		||||
  mark-as-read-all-unread-notes: "すべての投稿を既読にする"
 | 
			
		||||
  password: "パスワード"
 | 
			
		||||
mobile/views/pages/user.vue:
 | 
			
		||||
  follows-you: "フォローされています"
 | 
			
		||||
  following: "フォロー"
 | 
			
		||||
@@ -1326,6 +1384,10 @@ mobile/views/pages/user.vue:
 | 
			
		||||
  timeline: "タイムライン"
 | 
			
		||||
  media: "メディア"
 | 
			
		||||
  is-suspended: "このユーザーは凍結されています。"
 | 
			
		||||
  mute: "ミュート"
 | 
			
		||||
  unmute: "ミュート解除"
 | 
			
		||||
  block: "ブロック"
 | 
			
		||||
  unblock: "ブロック解除"
 | 
			
		||||
mobile/views/pages/user/home.vue:
 | 
			
		||||
  recent-notes: "最近の投稿"
 | 
			
		||||
  images: "画像"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								package.json
									
									
									
									
									
								
							@@ -1,8 +1,8 @@
 | 
			
		||||
{
 | 
			
		||||
	"name": "misskey",
 | 
			
		||||
	"author": "syuilo <i@syuilo.com>",
 | 
			
		||||
	"version": "10.30.2",
 | 
			
		||||
	"clientVersion": "1.0.11041",
 | 
			
		||||
	"version": "10.38.5",
 | 
			
		||||
	"clientVersion": "1.0.11513",
 | 
			
		||||
	"codename": "nighthike",
 | 
			
		||||
	"main": "./built/index.js",
 | 
			
		||||
	"private": true,
 | 
			
		||||
@@ -58,23 +58,24 @@
 | 
			
		||||
		"@types/koa__cors": "2.2.3",
 | 
			
		||||
		"@types/minio": "7.0.0",
 | 
			
		||||
		"@types/mkdirp": "0.5.2",
 | 
			
		||||
		"@types/mocha": "5.2.3",
 | 
			
		||||
		"@types/mocha": "5.2.5",
 | 
			
		||||
		"@types/mongodb": "3.1.12",
 | 
			
		||||
		"@types/ms": "0.7.30",
 | 
			
		||||
		"@types/node": "10.12.0",
 | 
			
		||||
		"@types/node": "10.12.2",
 | 
			
		||||
		"@types/oauth": "0.9.1",
 | 
			
		||||
		"@types/portscanner": "2.1.0",
 | 
			
		||||
		"@types/pug": "2.0.4",
 | 
			
		||||
		"@types/qrcode": "1.3.0",
 | 
			
		||||
		"@types/ratelimiter": "2.1.28",
 | 
			
		||||
		"@types/redis": "2.8.7",
 | 
			
		||||
		"@types/request": "2.47.1",
 | 
			
		||||
		"@types/request": "2.48.0",
 | 
			
		||||
		"@types/request-promise-native": "1.0.15",
 | 
			
		||||
		"@types/rimraf": "2.0.2",
 | 
			
		||||
		"@types/seedrandom": "2.4.27",
 | 
			
		||||
		"@types/sharp": "0.21.0",
 | 
			
		||||
		"@types/showdown": "1.7.5",
 | 
			
		||||
		"@types/single-line-log": "1.1.0",
 | 
			
		||||
		"@types/speakeasy": "2.0.2",
 | 
			
		||||
		"@types/speakeasy": "2.0.3",
 | 
			
		||||
		"@types/systeminformation": "3.23.0",
 | 
			
		||||
		"@types/tinycolor2": "1.4.1",
 | 
			
		||||
		"@types/tmp": "0.0.33",
 | 
			
		||||
@@ -84,37 +85,34 @@
 | 
			
		||||
		"@types/websocket": "0.0.40",
 | 
			
		||||
		"@types/ws": "6.0.1",
 | 
			
		||||
		"animejs": "2.2.0",
 | 
			
		||||
		"apexcharts": "2.1.5",
 | 
			
		||||
		"apexcharts": "2.1.9",
 | 
			
		||||
		"autobind-decorator": "2.1.0",
 | 
			
		||||
		"autosize": "4.0.2",
 | 
			
		||||
		"autwh": "0.1.0",
 | 
			
		||||
		"bcryptjs": "2.4.3",
 | 
			
		||||
		"bee-queue": "1.2.2",
 | 
			
		||||
		"bootstrap-vue": "2.0.0-rc.11",
 | 
			
		||||
		"cafy": "11.3.0",
 | 
			
		||||
		"cafy": "12.0.0",
 | 
			
		||||
		"chai": "4.2.0",
 | 
			
		||||
		"chai-http": "4.2.0",
 | 
			
		||||
		"chalk": "2.4.1",
 | 
			
		||||
		"chart.js": "2.7.3",
 | 
			
		||||
		"commander": "2.19.0",
 | 
			
		||||
		"crc-32": "1.2.0",
 | 
			
		||||
		"css-loader": "1.0.0",
 | 
			
		||||
		"css-loader": "1.0.1",
 | 
			
		||||
		"dateformat": "3.0.3",
 | 
			
		||||
		"debug": "4.1.0",
 | 
			
		||||
		"deep-equal": "1.0.1",
 | 
			
		||||
		"deepcopy": "0.6.3",
 | 
			
		||||
		"diskusage": "0.2.5",
 | 
			
		||||
		"dompurify": "1.0.5",
 | 
			
		||||
		"double-ended-queue": "2.1.0-0",
 | 
			
		||||
		"elasticsearch": "15.1.1",
 | 
			
		||||
		"elasticsearch": "15.2.0",
 | 
			
		||||
		"emojilib": "2.3.0",
 | 
			
		||||
		"escape-regexp": "0.0.1",
 | 
			
		||||
		"eslint": "5.0.1",
 | 
			
		||||
		"eslint": "5.8.0",
 | 
			
		||||
		"eslint-plugin-vue": "4.7.1",
 | 
			
		||||
		"eventemitter3": "3.1.0",
 | 
			
		||||
		"exif-js": "2.3.0",
 | 
			
		||||
		"file-loader": "2.0.0",
 | 
			
		||||
		"file-type": "10.1.0",
 | 
			
		||||
		"file-type": "10.3.0",
 | 
			
		||||
		"fuckadblock": "3.2.1",
 | 
			
		||||
		"gulp": "3.9.1",
 | 
			
		||||
		"gulp-cssnano": "2.1.3",
 | 
			
		||||
@@ -131,17 +129,16 @@
 | 
			
		||||
		"gulp-uglify": "3.0.1",
 | 
			
		||||
		"gulp-util": "3.0.8",
 | 
			
		||||
		"hard-source-webpack-plugin": "0.12.0",
 | 
			
		||||
		"highlight.js": "9.12.0",
 | 
			
		||||
		"html-minifier": "3.5.20",
 | 
			
		||||
		"html-minifier": "3.5.21",
 | 
			
		||||
		"http-signature": "1.2.0",
 | 
			
		||||
		"insert-text-at-cursor": "0.1.1",
 | 
			
		||||
		"is-root": "2.0.0",
 | 
			
		||||
		"is-url": "1.2.4",
 | 
			
		||||
		"js-yaml": "3.12.0",
 | 
			
		||||
		"jsdom": "12.2.0",
 | 
			
		||||
		"jsdom": "13.0.0",
 | 
			
		||||
		"json5": "2.1.0",
 | 
			
		||||
		"json5-loader": "1.0.1",
 | 
			
		||||
		"koa": "2.5.1",
 | 
			
		||||
		"koa": "2.6.1",
 | 
			
		||||
		"koa-bodyparser": "4.2.1",
 | 
			
		||||
		"koa-compress": "3.0.0",
 | 
			
		||||
		"koa-favicon": "2.0.1",
 | 
			
		||||
@@ -154,7 +151,6 @@
 | 
			
		||||
		"koa-slow": "2.1.0",
 | 
			
		||||
		"koa-views": "6.1.4",
 | 
			
		||||
		"loader-utils": "1.1.0",
 | 
			
		||||
		"lodash.assign": "4.2.0",
 | 
			
		||||
		"mecab-async": "0.1.2",
 | 
			
		||||
		"merge-options": "1.0.1",
 | 
			
		||||
		"minio": "7.0.1",
 | 
			
		||||
@@ -205,17 +201,16 @@
 | 
			
		||||
		"textarea-caret": "3.1.0",
 | 
			
		||||
		"tinycolor2": "1.4.1",
 | 
			
		||||
		"tmp": "0.0.33",
 | 
			
		||||
		"ts-loader": "4.4.1",
 | 
			
		||||
		"ts-loader": "5.3.0",
 | 
			
		||||
		"ts-node": "7.0.1",
 | 
			
		||||
		"tslint": "5.10.0",
 | 
			
		||||
		"typescript": "2.9.2",
 | 
			
		||||
		"typescript-eslint-parser": "20.0.0",
 | 
			
		||||
		"typescript": "3.1.5",
 | 
			
		||||
		"typescript-eslint-parser": "20.1.1",
 | 
			
		||||
		"uglify-es": "3.3.9",
 | 
			
		||||
		"url-loader": "1.1.2",
 | 
			
		||||
		"uuid": "3.3.2",
 | 
			
		||||
		"v-animate-css": "0.0.2",
 | 
			
		||||
		"vue": "2.5.17",
 | 
			
		||||
		"vue-chartjs": "3.4.0",
 | 
			
		||||
		"vue-color": "2.7.0",
 | 
			
		||||
		"vue-content-loading": "1.5.3",
 | 
			
		||||
		"vue-cropperjs": "2.2.2",
 | 
			
		||||
@@ -233,17 +228,10 @@
 | 
			
		||||
		"vuex-persistedstate": "2.5.4",
 | 
			
		||||
		"web-push": "3.3.3",
 | 
			
		||||
		"webfinger.js": "2.6.6",
 | 
			
		||||
		"webpack": "4.22.0",
 | 
			
		||||
		"webpack": "4.23.1",
 | 
			
		||||
		"webpack-cli": "3.1.2",
 | 
			
		||||
		"websocket": "1.0.28",
 | 
			
		||||
		"ws": "6.1.0",
 | 
			
		||||
		"xev": "2.0.1"
 | 
			
		||||
	},
 | 
			
		||||
	"greenkeeper": {
 | 
			
		||||
		"ignore": [
 | 
			
		||||
			"deepcopy",
 | 
			
		||||
			"cafy",
 | 
			
		||||
			"@types/gulp"
 | 
			
		||||
		]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										66
									
								
								src/chart/federation.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/chart/federation.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
import autobind from 'autobind-decorator';
 | 
			
		||||
import Chart, { Obj } from '.';
 | 
			
		||||
import Instance from '../models/instance';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * フェデレーションに関するチャート
 | 
			
		||||
 */
 | 
			
		||||
type FederationLog = {
 | 
			
		||||
	instance: {
 | 
			
		||||
		/**
 | 
			
		||||
		 * インスタンス数の合計
 | 
			
		||||
		 */
 | 
			
		||||
		total: number;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * 増加インスタンス数
 | 
			
		||||
		 */
 | 
			
		||||
		inc: number;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * 減少インスタンス数
 | 
			
		||||
		 */
 | 
			
		||||
		dec: number;
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class FederationChart extends Chart<FederationLog> {
 | 
			
		||||
	constructor() {
 | 
			
		||||
		super('federation');
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@autobind
 | 
			
		||||
	protected async getTemplate(init: boolean, latest?: FederationLog): Promise<FederationLog> {
 | 
			
		||||
		const [total] = init ? await Promise.all([
 | 
			
		||||
			Instance.count({})
 | 
			
		||||
		]) : [
 | 
			
		||||
			latest ? latest.instance.total : 0
 | 
			
		||||
		];
 | 
			
		||||
 | 
			
		||||
		return {
 | 
			
		||||
			instance: {
 | 
			
		||||
				total: total,
 | 
			
		||||
				inc: 0,
 | 
			
		||||
				dec: 0
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@autobind
 | 
			
		||||
	public async update(isAdditional: boolean) {
 | 
			
		||||
		const update: Obj = {};
 | 
			
		||||
 | 
			
		||||
		update.total = isAdditional ? 1 : -1;
 | 
			
		||||
		if (isAdditional) {
 | 
			
		||||
			update.inc = 1;
 | 
			
		||||
		} else {
 | 
			
		||||
			update.dec = 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		await this.inc({
 | 
			
		||||
			instance: update
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default new FederationChart();
 | 
			
		||||
@@ -20,7 +20,6 @@ type ArrayValue<T> = {
 | 
			
		||||
 | 
			
		||||
type Span = 'day' | 'hour';
 | 
			
		||||
 | 
			
		||||
//#region Chart Core
 | 
			
		||||
type Log<T extends Obj> = {
 | 
			
		||||
	_id: mongo.ObjectID;
 | 
			
		||||
 | 
			
		||||
@@ -87,13 +86,33 @@ export default abstract class Chart<T> {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@autobind
 | 
			
		||||
	private async getCurrentLog(span: Span, group?: any): Promise<Log<T>> {
 | 
			
		||||
	private getCurrentDate(): [number, number, number, number] {
 | 
			
		||||
		const now = new Date();
 | 
			
		||||
 | 
			
		||||
		const y = now.getFullYear();
 | 
			
		||||
		const m = now.getMonth();
 | 
			
		||||
		const d = now.getDate();
 | 
			
		||||
		const h = now.getHours();
 | 
			
		||||
 | 
			
		||||
		return [y, m, d, h];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@autobind
 | 
			
		||||
	private getLatestLog(span: Span, group?: any): Promise<Log<T>> {
 | 
			
		||||
		return this.collection.findOne({
 | 
			
		||||
			group: group,
 | 
			
		||||
			span: span
 | 
			
		||||
		}, {
 | 
			
		||||
			sort: {
 | 
			
		||||
				date: -1
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@autobind
 | 
			
		||||
	private async getCurrentLog(span: Span, group?: any): Promise<Log<T>> {
 | 
			
		||||
		const [y, m, d, h] = this.getCurrentDate();
 | 
			
		||||
 | 
			
		||||
		const current =
 | 
			
		||||
			span == 'day' ? new Date(y, m, d) :
 | 
			
		||||
			span == 'hour' ? new Date(y, m, d, h) :
 | 
			
		||||
@@ -106,53 +125,55 @@ export default abstract class Chart<T> {
 | 
			
		||||
			date: current
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		if (currentLog) {
 | 
			
		||||
		// ログがあればそれを返して終了
 | 
			
		||||
		if (currentLog != null) {
 | 
			
		||||
			return currentLog;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		let log: Log<T>;
 | 
			
		||||
		let data: T;
 | 
			
		||||
 | 
			
		||||
		// 集計期間が変わってから、初めてのチャート更新なら
 | 
			
		||||
		// 最も最近のログを持ってくる
 | 
			
		||||
		// * 例えば集計期間が「日」である場合で考えると、
 | 
			
		||||
		// * 昨日何もチャートを更新するような出来事がなかった場合は、
 | 
			
		||||
		// * ログがそもそも作られずドキュメントが存在しないということがあり得るため、
 | 
			
		||||
		// * 「昨日の」と決め打ちせずに「もっとも最近の」とします
 | 
			
		||||
		const latest = await this.collection.findOne({
 | 
			
		||||
			group: group,
 | 
			
		||||
			span: span
 | 
			
		||||
		}, {
 | 
			
		||||
			sort: {
 | 
			
		||||
				date: -1
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		const latest = await this.getLatestLog(span, group);
 | 
			
		||||
 | 
			
		||||
		if (latest) {
 | 
			
		||||
			// 現在のログを初期挿入
 | 
			
		||||
			const data = await this.getTemplate(false, latest.data);
 | 
			
		||||
 | 
			
		||||
			const log = await this.collection.insert({
 | 
			
		||||
				group: group,
 | 
			
		||||
				span: span,
 | 
			
		||||
				date: current,
 | 
			
		||||
				data: data
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			return log;
 | 
			
		||||
		if (latest != null) {
 | 
			
		||||
			// 空ログデータを作成
 | 
			
		||||
			data = await this.getTemplate(false, latest.data);
 | 
			
		||||
		} else {
 | 
			
		||||
			// ログが存在しなかったら
 | 
			
		||||
			// * Misskeyインスタンスを建てて初めてのチャート更新時など
 | 
			
		||||
			// (Misskeyインスタンスを建てて初めてのチャート更新時など
 | 
			
		||||
			// または何らかの理由でチャートコレクションを抹消した場合)
 | 
			
		||||
 | 
			
		||||
			// 空のログを作成
 | 
			
		||||
			const data = await this.getTemplate(true, null, group);
 | 
			
		||||
			// 初期ログデータを作成
 | 
			
		||||
			data = await this.getTemplate(true, null, group);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			const log = await this.collection.insert({
 | 
			
		||||
		try {
 | 
			
		||||
			// 新規ログ挿入
 | 
			
		||||
			log = await this.collection.insert({
 | 
			
		||||
				group: group,
 | 
			
		||||
				span: span,
 | 
			
		||||
				date: current,
 | 
			
		||||
				data: data
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			return log;
 | 
			
		||||
		} catch (e) {
 | 
			
		||||
			// 11000 is duplicate key error
 | 
			
		||||
			// 並列動作している他のチャートエンジンプロセスと処理が重なる場合がある
 | 
			
		||||
			// その場合は再度最も新しいログを持ってくる
 | 
			
		||||
			if (e.code === 11000) {
 | 
			
		||||
				log = await this.getLatestLog(span, group);
 | 
			
		||||
			} else {
 | 
			
		||||
				console.error(e);
 | 
			
		||||
				throw e;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return log;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@autobind
 | 
			
		||||
@@ -173,6 +194,7 @@ export default abstract class Chart<T> {
 | 
			
		||||
				};
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// ログ更新
 | 
			
		||||
			this.collection.update({
 | 
			
		||||
				_id: log._id
 | 
			
		||||
			}, query);
 | 
			
		||||
@@ -200,17 +222,15 @@ export default abstract class Chart<T> {
 | 
			
		||||
	public async getChart(span: Span, range: number, group?: any): Promise<ArrayValue<T>> {
 | 
			
		||||
		const promisedChart: Promise<T>[] = [];
 | 
			
		||||
 | 
			
		||||
		const now = new Date();
 | 
			
		||||
		const y = now.getFullYear();
 | 
			
		||||
		const m = now.getMonth();
 | 
			
		||||
		const d = now.getDate();
 | 
			
		||||
		const h = now.getHours();
 | 
			
		||||
		const [y, m, d, h] = this.getCurrentDate();
 | 
			
		||||
 | 
			
		||||
		const gt =
 | 
			
		||||
			span == 'day' ? new Date(y, m, d - range) :
 | 
			
		||||
			span == 'hour' ? new Date(y, m, d, h - range) : null;
 | 
			
		||||
			span == 'hour' ? new Date(y, m, d, h - range) :
 | 
			
		||||
			null;
 | 
			
		||||
 | 
			
		||||
		const logs = await this.collection.find({
 | 
			
		||||
		// ログ取得
 | 
			
		||||
		let logs = await this.collection.find({
 | 
			
		||||
			group: group,
 | 
			
		||||
			span: span,
 | 
			
		||||
			date: {
 | 
			
		||||
@@ -225,6 +245,28 @@ export default abstract class Chart<T> {
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		// 要求された範囲にログがひとつもなかったら
 | 
			
		||||
		if (logs.length == 0) {
 | 
			
		||||
			// もっとも新しいログを持ってくる
 | 
			
		||||
			// (すくなくともひとつログが無いと隙間埋めできないため)
 | 
			
		||||
			const recentLog = await this.collection.findOne({
 | 
			
		||||
				group: group,
 | 
			
		||||
				span: span
 | 
			
		||||
			}, {
 | 
			
		||||
				sort: {
 | 
			
		||||
					date: -1
 | 
			
		||||
				},
 | 
			
		||||
				fields: {
 | 
			
		||||
					_id: 0
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			if (recentLog) {
 | 
			
		||||
				logs = [recentLog];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// 整形
 | 
			
		||||
		for (let i = (range - 1); i >= 0; i--) {
 | 
			
		||||
			const current =
 | 
			
		||||
				span == 'day' ? new Date(y, m, d - i) :
 | 
			
		||||
@@ -235,7 +277,8 @@ export default abstract class Chart<T> {
 | 
			
		||||
 | 
			
		||||
			if (log) {
 | 
			
		||||
				promisedChart.unshift(Promise.resolve(log.data));
 | 
			
		||||
			} else { // 隙間埋め
 | 
			
		||||
			} else {
 | 
			
		||||
				// 隙間埋め
 | 
			
		||||
				const latest = logs.find(l => l.date.getTime() < current.getTime());
 | 
			
		||||
				promisedChart.unshift(this.getTemplate(false, latest ? latest.data : null));
 | 
			
		||||
			}
 | 
			
		||||
@@ -247,14 +290,11 @@ export default abstract class Chart<T> {
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * [{
 | 
			
		||||
		 * 	xxxxx: 1,
 | 
			
		||||
		 * 	yyyyy: 5
 | 
			
		||||
		 * 	xxxxx: 1, yyyyy: 5
 | 
			
		||||
		 * }, {
 | 
			
		||||
		 * 	xxxxx: 2,
 | 
			
		||||
		 * 	yyyyy: 6
 | 
			
		||||
		 * 	xxxxx: 2, yyyyy: 6
 | 
			
		||||
		 * }, {
 | 
			
		||||
		 * 	xxxxx: 3,
 | 
			
		||||
		 * 	yyyyy: 7
 | 
			
		||||
		 * 	xxxxx: 3, yyyyy: 7
 | 
			
		||||
		 * }]
 | 
			
		||||
		 *
 | 
			
		||||
		 * を
 | 
			
		||||
@@ -282,4 +322,3 @@ export default abstract class Chart<T> {
 | 
			
		||||
		return res;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
//#endregion
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										150
									
								
								src/client/app/admin/assets/header-icon.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								src/client/app/admin/assets/header-icon.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
 | 
			
		||||
 | 
			
		||||
<svg
 | 
			
		||||
   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
			
		||||
   xmlns:cc="http://creativecommons.org/ns#"
 | 
			
		||||
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   width="512"
 | 
			
		||||
   height="512"
 | 
			
		||||
   viewBox="0 0 135.46667 135.46667"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   id="svg8"
 | 
			
		||||
   inkscape:version="0.92.1 r15371"
 | 
			
		||||
   sodipodi:docname="header-icon.dark.svg"
 | 
			
		||||
   inkscape:export-filename="C:\Users\syuilo\projects\misskey\assets\favicon\32.png"
 | 
			
		||||
   inkscape:export-xdpi="6"
 | 
			
		||||
   inkscape:export-ydpi="6">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs2">
 | 
			
		||||
    <inkscape:path-effect
 | 
			
		||||
       effect="simplify"
 | 
			
		||||
       id="path-effect5115"
 | 
			
		||||
       is_visible="true"
 | 
			
		||||
       steps="1"
 | 
			
		||||
       threshold="0.000408163"
 | 
			
		||||
       smooth_angles="360"
 | 
			
		||||
       helper_size="0"
 | 
			
		||||
       simplify_individual_paths="false"
 | 
			
		||||
       simplify_just_coalesce="false"
 | 
			
		||||
       simplifyindividualpaths="false"
 | 
			
		||||
       simplifyJustCoalesce="false" />
 | 
			
		||||
    <inkscape:path-effect
 | 
			
		||||
       effect="simplify"
 | 
			
		||||
       id="path-effect5111"
 | 
			
		||||
       is_visible="true"
 | 
			
		||||
       steps="1"
 | 
			
		||||
       threshold="0.000408163"
 | 
			
		||||
       smooth_angles="360"
 | 
			
		||||
       helper_size="0"
 | 
			
		||||
       simplify_individual_paths="false"
 | 
			
		||||
       simplify_just_coalesce="false"
 | 
			
		||||
       simplifyindividualpaths="false"
 | 
			
		||||
       simplifyJustCoalesce="false" />
 | 
			
		||||
    <inkscape:path-effect
 | 
			
		||||
       effect="simplify"
 | 
			
		||||
       id="path-effect5104"
 | 
			
		||||
       is_visible="true"
 | 
			
		||||
       steps="1"
 | 
			
		||||
       threshold="0.000408163"
 | 
			
		||||
       smooth_angles="360"
 | 
			
		||||
       helper_size="0"
 | 
			
		||||
       simplify_individual_paths="false"
 | 
			
		||||
       simplify_just_coalesce="false"
 | 
			
		||||
       simplifyindividualpaths="false"
 | 
			
		||||
       simplifyJustCoalesce="false" />
 | 
			
		||||
  </defs>
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="base"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:zoom="1.4142136"
 | 
			
		||||
     inkscape:cx="114.309"
 | 
			
		||||
     inkscape:cy="251.50613"
 | 
			
		||||
     inkscape:document-units="px"
 | 
			
		||||
     inkscape:current-layer="g4502"
 | 
			
		||||
     showgrid="true"
 | 
			
		||||
     units="px"
 | 
			
		||||
     inkscape:snap-bbox="true"
 | 
			
		||||
     inkscape:bbox-nodes="true"
 | 
			
		||||
     inkscape:snap-bbox-edge-midpoints="false"
 | 
			
		||||
     inkscape:snap-smooth-nodes="true"
 | 
			
		||||
     inkscape:snap-center="true"
 | 
			
		||||
     inkscape:snap-page="true"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1027"
 | 
			
		||||
     inkscape:window-x="-8"
 | 
			
		||||
     inkscape:window-y="1072"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:snap-object-midpoints="true"
 | 
			
		||||
     inkscape:snap-midpoints="true"
 | 
			
		||||
     inkscape:object-paths="true"
 | 
			
		||||
     fit-margin-top="0"
 | 
			
		||||
     fit-margin-left="0"
 | 
			
		||||
     fit-margin-right="0"
 | 
			
		||||
     fit-margin-bottom="0"
 | 
			
		||||
     objecttolerance="1"
 | 
			
		||||
     guidetolerance="1"
 | 
			
		||||
     inkscape:snap-nodes="false"
 | 
			
		||||
     inkscape:snap-others="false">
 | 
			
		||||
    <inkscape:grid
 | 
			
		||||
       type="xygrid"
 | 
			
		||||
       id="grid4504"
 | 
			
		||||
       spacingx="4.2333334"
 | 
			
		||||
       spacingy="4.2333334"
 | 
			
		||||
       empcolor="#ff3fff"
 | 
			
		||||
       empopacity="0.25098039"
 | 
			
		||||
       empspacing="4" />
 | 
			
		||||
  </sodipodi:namedview>
 | 
			
		||||
  <metadata
 | 
			
		||||
     id="metadata5">
 | 
			
		||||
    <rdf:RDF>
 | 
			
		||||
      <cc:Work
 | 
			
		||||
         rdf:about="">
 | 
			
		||||
        <dc:format>image/svg+xml</dc:format>
 | 
			
		||||
        <dc:type
 | 
			
		||||
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
        <dc:title></dc:title>
 | 
			
		||||
      </cc:Work>
 | 
			
		||||
    </rdf:RDF>
 | 
			
		||||
  </metadata>
 | 
			
		||||
  <g
 | 
			
		||||
     inkscape:label="レイヤー 1"
 | 
			
		||||
     inkscape:groupmode="layer"
 | 
			
		||||
     id="layer1"
 | 
			
		||||
     transform="translate(-30.809093,-111.78601)">
 | 
			
		||||
    <g
 | 
			
		||||
       id="g4502"
 | 
			
		||||
       transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)">
 | 
			
		||||
      <g
 | 
			
		||||
         style="fill-opacity:1"
 | 
			
		||||
         transform="translate(-1.3333333e-6,-1.3439941e-6)"
 | 
			
		||||
         id="g5125">
 | 
			
		||||
        <g
 | 
			
		||||
           transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)"
 | 
			
		||||
           id="text4489"
 | 
			
		||||
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
 | 
			
		||||
           aria-label="Mi">
 | 
			
		||||
          <path
 | 
			
		||||
             sodipodi:nodetypes="zccssscssccscczzzccsccsscscsccz"
 | 
			
		||||
             inkscape:connector-curvature="0"
 | 
			
		||||
             id="path5210"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill-opacity:1;stroke-width:0.28950602px"
 | 
			
		||||
             d="m 75.196381,231.17126 c -5.855419,0.0202 -10.885068,-3.50766 -13.2572,-7.61584 -1.266603,-1.79454 -3.772419,-2.43291 -3.807919,0 v 11.2332 c 0,4.51309 -1.645397,8.41504 -4.936191,11.70583 -3.196772,3.19677 -7.098714,4.79516 -11.705826,4.79516 -4.513089,0 -8.415031,-1.59839 -11.705825,-4.79516 -3.196772,-3.29079 -4.795158,-7.19274 -4.795158,-11.70583 v -61.7729 c 0,-3.47884 0.987238,-6.6286 2.961715,-9.44928 2.068499,-2.91471 4.701135,-4.9362 7.897906,-6.06447 1.786431,-0.65816 3.666885,-0.98724 5.641362,-0.98724 5.077225,0 9.308247,1.97448 12.693064,5.92343 1.786431,1.97448 2.820681,3.00873 3.102749,3.10275 0,0 13.408119,16.21319 13.78421,16.49526 0.376091,0.28206 1.480789,2.43848 4.127113,2.43848 2.646324,0 3.89218,-2.15642 4.26827,-2.43848 0.376091,-0.28207 13.784088,-16.49526 13.784088,-16.49526 0.09402,0.094 1.081261,-0.94022 2.961715,-3.10275 3.478837,-3.94895 7.756866,-5.92343 12.834096,-5.92343 1.88045,0 3.76091,0.32908 5.64136,0.98724 3.19677,1.12827 5.7824,3.14976 7.75688,6.06447 2.06849,2.82068 3.10274,5.97044 3.10274,9.44928 v 61.7729 c 0,4.51309 -1.6454,8.41504 -4.93619,11.70583 -3.19677,3.19677 -7.09871,4.79516 -11.70582,4.79516 -4.51309,0 -8.41504,-1.59839 -11.705828,-4.79516 -3.196772,-3.29079 -4.795158,-7.19274 -4.795158,-11.70583 v -11.2332 c -0.277898,-3.06563 -2.987588,-1.13379 -3.948953,0 -2.538613,4.70114 -7.401781,7.59567 -13.2572,7.61584 z" />
 | 
			
		||||
          <path
 | 
			
		||||
             inkscape:connector-curvature="0"
 | 
			
		||||
             id="path5212"
 | 
			
		||||
             style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill-opacity:1;stroke-width:0.28950602px"
 | 
			
		||||
             d="m 145.83461,185.00361 q -5.92343,0 -10.15445,-4.08999 -4.08999,-4.23102 -4.08999,-10.15445 0,-5.92343 4.08999,-10.01342 4.23102,-4.23102 10.15445,-4.23102 5.92343,0 10.15445,4.23102 4.23102,4.08999 4.23102,10.01342 0,5.92343 -4.23102,10.15445 -4.23102,4.08999 -10.15445,4.08999 z m 0.14103,2.82068 q 5.92343,0 10.01342,4.23102 4.23102,4.23102 4.23102,10.15445 v 34.83541 q 0,5.92343 -4.23102,10.15445 -4.08999,4.08999 -10.01342,4.08999 -5.92343,0 -10.15445,-4.08999 -4.23102,-4.23102 -4.23102,-10.15445 v -34.83541 q 0,-5.92343 4.23102,-10.15445 4.23102,-4.23102 10.15445,-4.23102 z" />
 | 
			
		||||
        </g>
 | 
			
		||||
      </g>
 | 
			
		||||
    </g>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 7.0 KiB  | 
							
								
								
									
										27
									
								
								src/client/app/admin/script.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/client/app/admin/script.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Admin
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import VueRouter from 'vue-router';
 | 
			
		||||
 | 
			
		||||
// Style
 | 
			
		||||
import './style.styl';
 | 
			
		||||
 | 
			
		||||
import init from '../init';
 | 
			
		||||
import Index from './views/index.vue';
 | 
			
		||||
 | 
			
		||||
init(launch => {
 | 
			
		||||
	document.title = 'Admin';
 | 
			
		||||
 | 
			
		||||
	// Init router
 | 
			
		||||
	const router = new VueRouter({
 | 
			
		||||
		mode: 'history',
 | 
			
		||||
		base: '/admin/',
 | 
			
		||||
		routes: [
 | 
			
		||||
			{ path: '/', component: Index },
 | 
			
		||||
		]
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	// Launch the app
 | 
			
		||||
	launch(router);
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										6
									
								
								src/client/app/admin/style.styl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/client/app/admin/style.styl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
@import "../app"
 | 
			
		||||
@import "../reset"
 | 
			
		||||
 | 
			
		||||
html
 | 
			
		||||
	height 100%
 | 
			
		||||
	background var(--bg)
 | 
			
		||||
							
								
								
									
										71
									
								
								src/client/app/admin/views/announcements.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/client/app/admin/views/announcements.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="cdeuzmsthagexbkpofbmatmugjuvogfb">
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%fa:broadcast-tower% %i18n:@announcements%</div>
 | 
			
		||||
		<section v-for="(announcement, i) in announcements" class="fit-top">
 | 
			
		||||
			<ui-input v-model="announcement.title" @change="save">
 | 
			
		||||
				<span>%i18n:@title%</span>
 | 
			
		||||
			</ui-input>
 | 
			
		||||
			<ui-textarea v-model="announcement.text">
 | 
			
		||||
				<span>%i18n:@text%</span>
 | 
			
		||||
			</ui-textarea>
 | 
			
		||||
			<ui-horizon-group>
 | 
			
		||||
				<ui-button @click="save">%fa:save R% %i18n:@save%</ui-button>
 | 
			
		||||
				<ui-button @click="remove(i)">%fa:trash-alt R% %i18n:@remove%</ui-button>
 | 
			
		||||
			</ui-horizon-group>
 | 
			
		||||
		</section>
 | 
			
		||||
		<section>
 | 
			
		||||
			<ui-button @click="add">%fa:plus% %i18n:@add%</ui-button>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			announcements: [],
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	created() {
 | 
			
		||||
		(this as any).os.getMeta().then(meta => {
 | 
			
		||||
			this.announcements = meta.broadcasts;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		add() {
 | 
			
		||||
			this.announcements.push({
 | 
			
		||||
				title: '',
 | 
			
		||||
				text: ''
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		remove(i) {
 | 
			
		||||
			this.announcements = this.announcements.filter((_, j) => j !== i);
 | 
			
		||||
			this.save();
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		save() {
 | 
			
		||||
			(this as any).api('admin/update-meta', {
 | 
			
		||||
				broadcasts: this.announcements
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Saved` });
 | 
			
		||||
			}).catch(e => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.cdeuzmsthagexbkpofbmatmugjuvogfb
 | 
			
		||||
	@media (min-width 500px)
 | 
			
		||||
		padding 16px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										105
									
								
								src/client/app/admin/views/ap-log.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/client/app/admin/views/ap-log.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="hyhctythnmwihguaaapnbrbszsjqxpio">
 | 
			
		||||
	<table>
 | 
			
		||||
		<thead>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<th>%fa:exchange-alt% In/Out</th>
 | 
			
		||||
				<th>%fa:server% Host</th>
 | 
			
		||||
				<th>%fa:bolt% Activity</th>
 | 
			
		||||
				<th>%fa:user% Actor</th>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</thead>
 | 
			
		||||
		<tbody>
 | 
			
		||||
			<tr v-for="log in logs" :key="log.id">
 | 
			
		||||
				<td :class="log.direction">{{ log.direction == 'in' ? '<' : '>' }} {{ log.direction }}</td>
 | 
			
		||||
				<td>{{ log.host }}</td>
 | 
			
		||||
				<td>{{ log.activity }}</td>
 | 
			
		||||
				<td>@{{ log.actor }}</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</tbody>
 | 
			
		||||
	</table>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			logs: [],
 | 
			
		||||
			connection: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.connection = (this as any).os.stream.useSharedConnection('apLog');
 | 
			
		||||
		this.connection.on('log', this.onLog);
 | 
			
		||||
		this.connection.on('logs', this.onLogs);
 | 
			
		||||
		this.connection.send('requestLog', {
 | 
			
		||||
			id: Math.random().toString().substr(2, 8),
 | 
			
		||||
			length: 50
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
		this.connection.dispose();
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		onLog(log) {
 | 
			
		||||
			log.id = Math.random();
 | 
			
		||||
			this.logs.unshift(log);
 | 
			
		||||
			if (this.logs.length > 50) this.logs.pop();
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		onLogs(logs) {
 | 
			
		||||
			logs.reverse().forEach(log => this.onLog(log));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.hyhctythnmwihguaaapnbrbszsjqxpio
 | 
			
		||||
	display block
 | 
			
		||||
	padding 12px 16px 16px 16px
 | 
			
		||||
	height 250px
 | 
			
		||||
	overflow hidden
 | 
			
		||||
	box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
 | 
			
		||||
	background var(--adminDashboardCardBg)
 | 
			
		||||
	border-radius 8px
 | 
			
		||||
 | 
			
		||||
	> table
 | 
			
		||||
		width 100%
 | 
			
		||||
		max-width 100%
 | 
			
		||||
		overflow auto
 | 
			
		||||
		border-spacing 0
 | 
			
		||||
		border-collapse collapse
 | 
			
		||||
		color var(--adminDashboardCardFg)
 | 
			
		||||
		font-size 14px
 | 
			
		||||
 | 
			
		||||
		thead
 | 
			
		||||
			border-bottom solid 1px var(--adminDashboardCardDivider)
 | 
			
		||||
 | 
			
		||||
			tr
 | 
			
		||||
				th
 | 
			
		||||
					font-weight normal
 | 
			
		||||
					text-align left
 | 
			
		||||
 | 
			
		||||
		tbody
 | 
			
		||||
			tr
 | 
			
		||||
				&:nth-child(odd)
 | 
			
		||||
					background rgba(0, 0, 0, 0.025)
 | 
			
		||||
 | 
			
		||||
		th, td
 | 
			
		||||
			padding 8px 16px
 | 
			
		||||
			min-width 128px
 | 
			
		||||
 | 
			
		||||
		td.in
 | 
			
		||||
			color #d26755
 | 
			
		||||
 | 
			
		||||
		td.out
 | 
			
		||||
			color #55bb83
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										469
									
								
								src/client/app/admin/views/charts.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										469
									
								
								src/client/app/admin/views/charts.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,469 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="qvgidhudpqhjttdhxubzuyrhyzgslujw">
 | 
			
		||||
	<header>
 | 
			
		||||
		<b>%fa:chart-bar R% %i18n:@title%:</b>
 | 
			
		||||
		<select v-model="src">
 | 
			
		||||
			<optgroup label="%i18n:@federation%">
 | 
			
		||||
				<option value="federation-instances">%i18n:@charts.federation-instances%</option>
 | 
			
		||||
				<option value="federation-instances-total">%i18n:@charts.federation-instances-total%</option>
 | 
			
		||||
			</optgroup>
 | 
			
		||||
			<optgroup label="%i18n:@users%">
 | 
			
		||||
				<option value="users">%i18n:@charts.users%</option>
 | 
			
		||||
				<option value="users-total">%i18n:@charts.users-total%</option>
 | 
			
		||||
			</optgroup>
 | 
			
		||||
			<optgroup label="%i18n:@notes%">
 | 
			
		||||
				<option value="notes">%i18n:@charts.notes%</option>
 | 
			
		||||
				<option value="local-notes">%i18n:@charts.local-notes%</option>
 | 
			
		||||
				<option value="remote-notes">%i18n:@charts.remote-notes%</option>
 | 
			
		||||
				<option value="notes-total">%i18n:@charts.notes-total%</option>
 | 
			
		||||
			</optgroup>
 | 
			
		||||
			<optgroup label="%i18n:@drive%">
 | 
			
		||||
				<option value="drive-files">%i18n:@charts.drive-files%</option>
 | 
			
		||||
				<option value="drive-files-total">%i18n:@charts.drive-files-total%</option>
 | 
			
		||||
				<option value="drive">%i18n:@charts.drive%</option>
 | 
			
		||||
				<option value="drive-total">%i18n:@charts.drive-total%</option>
 | 
			
		||||
			</optgroup>
 | 
			
		||||
			<optgroup label="%i18n:@network%">
 | 
			
		||||
				<option value="network-requests">%i18n:@charts.network-requests%</option>
 | 
			
		||||
				<option value="network-time">%i18n:@charts.network-time%</option>
 | 
			
		||||
				<option value="network-usage">%i18n:@charts.network-usage%</option>
 | 
			
		||||
			</optgroup>
 | 
			
		||||
		</select>
 | 
			
		||||
		<div>
 | 
			
		||||
			<span @click="span = 'day'" :class="{ active: span == 'day' }">%i18n:@per-day%</span> | <span @click="span = 'hour'" :class="{ active: span == 'hour' }">%i18n:@per-hour%</span>
 | 
			
		||||
		</div>
 | 
			
		||||
	</header>
 | 
			
		||||
	<div ref="chart"></div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import * as tinycolor from 'tinycolor2';
 | 
			
		||||
import * as ApexCharts from 'apexcharts';
 | 
			
		||||
 | 
			
		||||
const limit = 90;
 | 
			
		||||
 | 
			
		||||
const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b));
 | 
			
		||||
const negate = arr => arr.map(x => -x);
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			chart: null,
 | 
			
		||||
			src: 'notes',
 | 
			
		||||
			span: 'hour',
 | 
			
		||||
			chartInstance: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	computed: {
 | 
			
		||||
		data(): any {
 | 
			
		||||
			if (this.chart == null) return null;
 | 
			
		||||
			switch (this.src) {
 | 
			
		||||
				case 'federation-instances': return this.federationInstancesChart(false);
 | 
			
		||||
				case 'federation-instances-total': return this.federationInstancesChart(true);
 | 
			
		||||
				case 'users': return this.usersChart(false);
 | 
			
		||||
				case 'users-total': return this.usersChart(true);
 | 
			
		||||
				case 'notes': return this.notesChart('combined');
 | 
			
		||||
				case 'local-notes': return this.notesChart('local');
 | 
			
		||||
				case 'remote-notes': return this.notesChart('remote');
 | 
			
		||||
				case 'notes-total': return this.notesTotalChart();
 | 
			
		||||
				case 'drive': return this.driveChart();
 | 
			
		||||
				case 'drive-total': return this.driveTotalChart();
 | 
			
		||||
				case 'drive-files': return this.driveFilesChart();
 | 
			
		||||
				case 'drive-files-total': return this.driveFilesTotalChart();
 | 
			
		||||
				case 'network-requests': return this.networkRequestsChart();
 | 
			
		||||
				case 'network-time': return this.networkTimeChart();
 | 
			
		||||
				case 'network-usage': return this.networkUsageChart();
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		stats(): any[] {
 | 
			
		||||
			const stats =
 | 
			
		||||
				this.span == 'day' ? this.chart.perDay :
 | 
			
		||||
				this.span == 'hour' ? this.chart.perHour :
 | 
			
		||||
				null;
 | 
			
		||||
 | 
			
		||||
			return stats;
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	watch: {
 | 
			
		||||
		src() {
 | 
			
		||||
			this.render();
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		span() {
 | 
			
		||||
			this.render();
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	async mounted() {
 | 
			
		||||
		this.now = new Date();
 | 
			
		||||
 | 
			
		||||
		const [perHour, perDay] = await Promise.all([Promise.all([
 | 
			
		||||
			(this as any).api('charts/federation', { limit: limit, span: 'hour' }),
 | 
			
		||||
			(this as any).api('charts/users', { limit: limit, span: 'hour' }),
 | 
			
		||||
			(this as any).api('charts/notes', { limit: limit, span: 'hour' }),
 | 
			
		||||
			(this as any).api('charts/drive', { limit: limit, span: 'hour' }),
 | 
			
		||||
			(this as any).api('charts/network', { limit: limit, span: 'hour' })
 | 
			
		||||
		]), Promise.all([
 | 
			
		||||
			(this as any).api('charts/federation', { limit: limit, span: 'day' }),
 | 
			
		||||
			(this as any).api('charts/users', { limit: limit, span: 'day' }),
 | 
			
		||||
			(this as any).api('charts/notes', { limit: limit, span: 'day' }),
 | 
			
		||||
			(this as any).api('charts/drive', { limit: limit, span: 'day' }),
 | 
			
		||||
			(this as any).api('charts/network', { limit: limit, span: 'day' })
 | 
			
		||||
		])]);
 | 
			
		||||
 | 
			
		||||
		const chart = {
 | 
			
		||||
			perHour: {
 | 
			
		||||
				federation: perHour[0],
 | 
			
		||||
				users: perHour[1],
 | 
			
		||||
				notes: perHour[2],
 | 
			
		||||
				drive: perHour[3],
 | 
			
		||||
				network: perHour[4]
 | 
			
		||||
			},
 | 
			
		||||
			perDay: {
 | 
			
		||||
				federation: perDay[0],
 | 
			
		||||
				users: perDay[1],
 | 
			
		||||
				notes: perDay[2],
 | 
			
		||||
				drive: perDay[3],
 | 
			
		||||
				network: perDay[4]
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.chart = chart;
 | 
			
		||||
 | 
			
		||||
		this.render();
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		setSrc(src) {
 | 
			
		||||
			this.src = src;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		render() {
 | 
			
		||||
			if (this.chartInstance) {
 | 
			
		||||
				this.chartInstance.destroy();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this.chartInstance = new ApexCharts(this.$refs.chart, {
 | 
			
		||||
				chart: {
 | 
			
		||||
					type: 'area',
 | 
			
		||||
					height: 300,
 | 
			
		||||
					animations: {
 | 
			
		||||
						dynamicAnimation: {
 | 
			
		||||
							enabled: false
 | 
			
		||||
						}
 | 
			
		||||
					},
 | 
			
		||||
					toolbar: {
 | 
			
		||||
						show: false
 | 
			
		||||
					},
 | 
			
		||||
					zoom: {
 | 
			
		||||
						enabled: false
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
				dataLabels: {
 | 
			
		||||
					enabled: false
 | 
			
		||||
				},
 | 
			
		||||
				grid: {
 | 
			
		||||
					clipMarkers: false,
 | 
			
		||||
					borderColor: 'rgba(0, 0, 0, 0.1)'
 | 
			
		||||
				},
 | 
			
		||||
				stroke: {
 | 
			
		||||
					curve: 'straight',
 | 
			
		||||
					width: 2
 | 
			
		||||
				},
 | 
			
		||||
				legend: {
 | 
			
		||||
					labels: {
 | 
			
		||||
						color: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				xaxis: {
 | 
			
		||||
					type: 'datetime',
 | 
			
		||||
					labels: {
 | 
			
		||||
						style: {
 | 
			
		||||
							colors: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
 | 
			
		||||
						}
 | 
			
		||||
					},
 | 
			
		||||
					axisBorder: {
 | 
			
		||||
						color: 'rgba(0, 0, 0, 0.1)'
 | 
			
		||||
					},
 | 
			
		||||
					axisTicks: {
 | 
			
		||||
						color: 'rgba(0, 0, 0, 0.1)'
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				yaxis: {
 | 
			
		||||
					labels: {
 | 
			
		||||
						formatter: this.data.bytes ? v => Vue.filter('bytes')(v, 0) : v => Vue.filter('number')(v),
 | 
			
		||||
						style: {
 | 
			
		||||
							color: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
				series: this.data.series
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.chartInstance.render();
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		getDate(i: number) {
 | 
			
		||||
			const y = this.now.getFullYear();
 | 
			
		||||
			const m = this.now.getMonth();
 | 
			
		||||
			const d = this.now.getDate();
 | 
			
		||||
			const h = this.now.getHours();
 | 
			
		||||
 | 
			
		||||
			return (
 | 
			
		||||
				this.span == 'day' ? new Date(y, m, d - i) :
 | 
			
		||||
				this.span == 'hour' ? new Date(y, m, d, h - i) :
 | 
			
		||||
				null
 | 
			
		||||
			);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		format(arr) {
 | 
			
		||||
			return arr.map((v, i) => ({ x: this.getDate(i).getTime(), y: v }));
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		federationInstancesChart(total: boolean): any {
 | 
			
		||||
			return {
 | 
			
		||||
				series: [{
 | 
			
		||||
					data: this.format(total
 | 
			
		||||
						? this.stats.federation.instance.total
 | 
			
		||||
						: sum(this.stats.federation.instance.inc, negate(this.stats.federation.instance.dec))
 | 
			
		||||
					)
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		notesChart(type: string): any {
 | 
			
		||||
			return {
 | 
			
		||||
				series: [{
 | 
			
		||||
					name: 'All',
 | 
			
		||||
					type: 'line',
 | 
			
		||||
					data: this.format(type == 'combined'
 | 
			
		||||
						? sum(this.stats.notes.local.inc, negate(this.stats.notes.local.dec), this.stats.notes.remote.inc, negate(this.stats.notes.remote.dec))
 | 
			
		||||
						: sum(this.stats.notes[type].inc, negate(this.stats.notes[type].dec))
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Renotes',
 | 
			
		||||
					type: 'area',
 | 
			
		||||
					data: this.format(type == 'combined'
 | 
			
		||||
						? sum(this.stats.notes.local.diffs.renote, this.stats.notes.remote.diffs.renote)
 | 
			
		||||
						: this.stats.notes[type].diffs.renote
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Replies',
 | 
			
		||||
					type: 'area',
 | 
			
		||||
					data: this.format(type == 'combined'
 | 
			
		||||
						? sum(this.stats.notes.local.diffs.reply, this.stats.notes.remote.diffs.reply)
 | 
			
		||||
						: this.stats.notes[type].diffs.reply
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Normal',
 | 
			
		||||
					type: 'area',
 | 
			
		||||
					data: this.format(type == 'combined'
 | 
			
		||||
						? sum(this.stats.notes.local.diffs.normal, this.stats.notes.remote.diffs.normal)
 | 
			
		||||
						: this.stats.notes[type].diffs.normal
 | 
			
		||||
					)
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		notesTotalChart(): any {
 | 
			
		||||
			return {
 | 
			
		||||
				series: [{
 | 
			
		||||
					name: 'Combined',
 | 
			
		||||
					data: this.format(sum(this.stats.notes.local.total, this.stats.notes.remote.total))
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Local',
 | 
			
		||||
					data: this.format(this.stats.notes.local.total)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Remote',
 | 
			
		||||
					data: this.format(this.stats.notes.remote.total)
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		usersChart(total: boolean): any {
 | 
			
		||||
			return {
 | 
			
		||||
				series: [{
 | 
			
		||||
					name: 'Combined',
 | 
			
		||||
					data: this.format(total
 | 
			
		||||
						? sum(this.stats.users.local.total, this.stats.users.remote.total)
 | 
			
		||||
						: sum(this.stats.users.local.inc, negate(this.stats.users.local.dec), this.stats.users.remote.inc, negate(this.stats.users.remote.dec))
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Local',
 | 
			
		||||
					data: this.format(total
 | 
			
		||||
						? this.stats.users.local.total
 | 
			
		||||
						: sum(this.stats.users.local.inc, negate(this.stats.users.local.dec))
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Remote',
 | 
			
		||||
					data: this.format(total
 | 
			
		||||
						? this.stats.users.remote.total
 | 
			
		||||
						: sum(this.stats.users.remote.inc, negate(this.stats.users.remote.dec))
 | 
			
		||||
					)
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		driveChart(): any {
 | 
			
		||||
			return {
 | 
			
		||||
				bytes: true,
 | 
			
		||||
				series: [{
 | 
			
		||||
					name: 'All',
 | 
			
		||||
					data: this.format(
 | 
			
		||||
						sum(
 | 
			
		||||
							this.stats.drive.local.incSize,
 | 
			
		||||
							negate(this.stats.drive.local.decSize),
 | 
			
		||||
							this.stats.drive.remote.incSize,
 | 
			
		||||
							negate(this.stats.drive.remote.decSize)
 | 
			
		||||
						)
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Local +',
 | 
			
		||||
					data: this.format(this.stats.drive.local.incSize)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Local -',
 | 
			
		||||
					data: this.format(negate(this.stats.drive.local.decSize))
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Remote +',
 | 
			
		||||
					data: this.format(this.stats.drive.remote.incSize)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Remote -',
 | 
			
		||||
					data: this.format(negate(this.stats.drive.remote.decSize))
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		driveTotalChart(): any {
 | 
			
		||||
			return {
 | 
			
		||||
				bytes: true,
 | 
			
		||||
				series: [{
 | 
			
		||||
					name: 'Combined',
 | 
			
		||||
					data: this.format(sum(this.stats.drive.local.totalSize, this.stats.drive.remote.totalSize))
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Local',
 | 
			
		||||
					data: this.format(this.stats.drive.local.totalSize)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Remote',
 | 
			
		||||
					data: this.format(this.stats.drive.remote.totalSize)
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		driveFilesChart(): any {
 | 
			
		||||
			return {
 | 
			
		||||
				series: [{
 | 
			
		||||
					name: 'All',
 | 
			
		||||
					data: this.format(
 | 
			
		||||
						sum(
 | 
			
		||||
							this.stats.drive.local.incCount,
 | 
			
		||||
							negate(this.stats.drive.local.decCount),
 | 
			
		||||
							this.stats.drive.remote.incCount,
 | 
			
		||||
							negate(this.stats.drive.remote.decCount)
 | 
			
		||||
						)
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Local +',
 | 
			
		||||
					data: this.format(this.stats.drive.local.incCount)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Local -',
 | 
			
		||||
					data: this.format(negate(this.stats.drive.local.decCount))
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Remote +',
 | 
			
		||||
					data: this.format(this.stats.drive.remote.incCount)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Remote -',
 | 
			
		||||
					data: this.format(negate(this.stats.drive.remote.decCount))
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		driveFilesTotalChart(): any {
 | 
			
		||||
			return {
 | 
			
		||||
				series: [{
 | 
			
		||||
					name: 'Combined',
 | 
			
		||||
					data: this.format(sum(this.stats.drive.local.totalCount, this.stats.drive.remote.totalCount))
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Local',
 | 
			
		||||
					data: this.format(this.stats.drive.local.totalCount)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Remote',
 | 
			
		||||
					data: this.format(this.stats.drive.remote.totalCount)
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		networkRequestsChart(): any {
 | 
			
		||||
			return {
 | 
			
		||||
				series: [{
 | 
			
		||||
					name: 'Incoming',
 | 
			
		||||
					data: this.format(this.stats.network.incomingRequests)
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		networkTimeChart(): any {
 | 
			
		||||
			const data = [];
 | 
			
		||||
 | 
			
		||||
			for (let i = 0; i < limit; i++) {
 | 
			
		||||
				data.push(this.stats.network.incomingRequests[i] != 0 ? (this.stats.network.totalTime[i] / this.stats.network.incomingRequests[i]) : 0);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return {
 | 
			
		||||
				series: [{
 | 
			
		||||
					name: 'Avg time',
 | 
			
		||||
					data: this.format(data)
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		networkUsageChart(): any {
 | 
			
		||||
			return {
 | 
			
		||||
				bytes: true,
 | 
			
		||||
				series: [{
 | 
			
		||||
					name: 'Incoming',
 | 
			
		||||
					data: this.format(this.stats.network.incomingBytes)
 | 
			
		||||
				}, {
 | 
			
		||||
					name: 'Outgoing',
 | 
			
		||||
					data: this.format(this.stats.network.outgoingBytes)
 | 
			
		||||
				}]
 | 
			
		||||
			};
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.qvgidhudpqhjttdhxubzuyrhyzgslujw
 | 
			
		||||
	display block
 | 
			
		||||
	flex 1
 | 
			
		||||
	padding 32px 24px
 | 
			
		||||
	padding-bottom 0
 | 
			
		||||
	box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
 | 
			
		||||
	background var(--face)
 | 
			
		||||
	border-radius 8px
 | 
			
		||||
 | 
			
		||||
	> header
 | 
			
		||||
		display flex
 | 
			
		||||
		margin 0 8px
 | 
			
		||||
		padding 0 0 8px 0
 | 
			
		||||
		font-size 1em
 | 
			
		||||
		color var(--adminDashboardCardFg)
 | 
			
		||||
		border-bottom solid 1px var(--adminDashboardCardDivider)
 | 
			
		||||
 | 
			
		||||
		> b
 | 
			
		||||
			margin-right 8px
 | 
			
		||||
 | 
			
		||||
		> *:last-child
 | 
			
		||||
			margin-left auto
 | 
			
		||||
 | 
			
		||||
			*
 | 
			
		||||
				&:not(.active)
 | 
			
		||||
					color var(--primary)
 | 
			
		||||
					cursor pointer
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										180
									
								
								src/client/app/admin/views/cpu-memory.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								src/client/app/admin/views/cpu-memory.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,180 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="zyknedwtlthezamcjlolyusmipqmjgxz">
 | 
			
		||||
	<div>
 | 
			
		||||
		<header>
 | 
			
		||||
			<span>%fa:microchip% CPU <span>{{ cpuP }}%</span></span>
 | 
			
		||||
			<span v-if="meta">{{ meta.cpu.model }}</span>
 | 
			
		||||
		</header>
 | 
			
		||||
		<div ref="cpu"></div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div>
 | 
			
		||||
		<header>
 | 
			
		||||
			<span>%fa:memory% MEM <span>{{ memP }}%</span></span>
 | 
			
		||||
			<span v-if="meta"></span>
 | 
			
		||||
		</header>
 | 
			
		||||
		<div ref="mem"></div>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import * as ApexCharts from 'apexcharts';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['connection'],
 | 
			
		||||
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			stats: [],
 | 
			
		||||
			cpuChart: null,
 | 
			
		||||
			memChart: null,
 | 
			
		||||
			cpuP: '',
 | 
			
		||||
			memP: '',
 | 
			
		||||
			meta: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	watch: {
 | 
			
		||||
		stats(stats) {
 | 
			
		||||
			this.cpuChart.updateSeries([{
 | 
			
		||||
				data: stats.map((x, i) => ({ x: i, y: x.cpu_usage }))
 | 
			
		||||
			}]);
 | 
			
		||||
			this.memChart.updateSeries([{
 | 
			
		||||
				data: stats.map((x, i) => ({ x: i, y: (x.mem.used / x.mem.total) }))
 | 
			
		||||
			}]);
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	mounted() {
 | 
			
		||||
		(this as any).os.getMeta().then(meta => {
 | 
			
		||||
			this.meta = meta;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		this.connection.on('stats', this.onStats);
 | 
			
		||||
		this.connection.on('statsLog', this.onStatsLog);
 | 
			
		||||
		this.connection.send('requestLog', {
 | 
			
		||||
			id: Math.random().toString().substr(2, 8),
 | 
			
		||||
			length: 200
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		const chartOpts = {
 | 
			
		||||
			chart: {
 | 
			
		||||
				type: 'area',
 | 
			
		||||
				height: 200,
 | 
			
		||||
				animations: {
 | 
			
		||||
					dynamicAnimation: {
 | 
			
		||||
						enabled: false
 | 
			
		||||
					}
 | 
			
		||||
				},
 | 
			
		||||
				toolbar: {
 | 
			
		||||
					show: false
 | 
			
		||||
				},
 | 
			
		||||
				zoom: {
 | 
			
		||||
					enabled: false
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			dataLabels: {
 | 
			
		||||
				enabled: false
 | 
			
		||||
			},
 | 
			
		||||
			grid: {
 | 
			
		||||
				clipMarkers: false,
 | 
			
		||||
				borderColor: 'rgba(0, 0, 0, 0.1)'
 | 
			
		||||
			},
 | 
			
		||||
			stroke: {
 | 
			
		||||
				curve: 'straight',
 | 
			
		||||
				width: 2
 | 
			
		||||
			},
 | 
			
		||||
			tooltip: {
 | 
			
		||||
				enabled: false
 | 
			
		||||
			},
 | 
			
		||||
			series: [{
 | 
			
		||||
				data: []
 | 
			
		||||
			}],
 | 
			
		||||
			xaxis: {
 | 
			
		||||
				type: 'numeric',
 | 
			
		||||
				labels: {
 | 
			
		||||
					show: false
 | 
			
		||||
				},
 | 
			
		||||
				tooltip: {
 | 
			
		||||
					enabled: false
 | 
			
		||||
				}
 | 
			
		||||
			},
 | 
			
		||||
			yaxis: {
 | 
			
		||||
				show: false,
 | 
			
		||||
				min: 0,
 | 
			
		||||
				max: 1
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.cpuChart = new ApexCharts(this.$refs.cpu, chartOpts);
 | 
			
		||||
		this.memChart = new ApexCharts(this.$refs.mem, chartOpts);
 | 
			
		||||
 | 
			
		||||
		this.cpuChart.render();
 | 
			
		||||
		this.memChart.render();
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
		this.connection.off('stats', this.onStats);
 | 
			
		||||
		this.connection.off('statsLog', this.onStatsLog);
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		onStats(stats) {
 | 
			
		||||
			this.stats.push(stats);
 | 
			
		||||
			if (this.stats.length > 200) this.stats.shift();
 | 
			
		||||
 | 
			
		||||
			this.cpuP = (stats.cpu_usage * 100).toFixed(0);
 | 
			
		||||
			this.memP = (stats.mem.used / stats.mem.total * 100).toFixed(0);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		onStatsLog(statsLog) {
 | 
			
		||||
			statsLog.reverse().forEach(stats => this.onStats(stats));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.zyknedwtlthezamcjlolyusmipqmjgxz
 | 
			
		||||
	display flex
 | 
			
		||||
 | 
			
		||||
	> div
 | 
			
		||||
		display block
 | 
			
		||||
		flex 1
 | 
			
		||||
		padding 20px 12px 0 12px
 | 
			
		||||
		box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
 | 
			
		||||
		background var(--face)
 | 
			
		||||
		border-radius 8px
 | 
			
		||||
 | 
			
		||||
		&:first-child
 | 
			
		||||
			margin-right 16px
 | 
			
		||||
 | 
			
		||||
		> header
 | 
			
		||||
			display flex
 | 
			
		||||
			padding 0 8px
 | 
			
		||||
			margin-bottom -16px
 | 
			
		||||
			color var(--adminDashboardCardFg)
 | 
			
		||||
			font-size 14px
 | 
			
		||||
 | 
			
		||||
			> span
 | 
			
		||||
				&:last-child
 | 
			
		||||
					margin-left auto
 | 
			
		||||
					opacity 0.7
 | 
			
		||||
 | 
			
		||||
				> span
 | 
			
		||||
					opacity 0.7
 | 
			
		||||
 | 
			
		||||
		> div
 | 
			
		||||
			margin-bottom -10px
 | 
			
		||||
 | 
			
		||||
	@media (max-width 1000px)
 | 
			
		||||
		display block
 | 
			
		||||
		margin-bottom 26px
 | 
			
		||||
 | 
			
		||||
		> div
 | 
			
		||||
			&:first-child
 | 
			
		||||
				margin-right 0
 | 
			
		||||
				margin-bottom 26px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										236
									
								
								src/client/app/admin/views/dashboard.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								src/client/app/admin/views/dashboard.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,236 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="obdskegsannmntldydackcpzezagxqfy">
 | 
			
		||||
	<header v-if="meta">
 | 
			
		||||
		<p><b>Misskey</b><span>{{ meta.version }}</span></p>
 | 
			
		||||
		<p><b>Machine</b><span>{{ meta.machine }}</span></p>
 | 
			
		||||
		<p><b>OS</b><span>{{ meta.os }}</span></p>
 | 
			
		||||
		<p><b>Node</b><span>{{ meta.node }}</span></p>
 | 
			
		||||
		<p>%i18n:common.ai-chan-kawaii%</p>
 | 
			
		||||
	</header>
 | 
			
		||||
 | 
			
		||||
	<div v-if="stats" class="stats">
 | 
			
		||||
		<div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<div>%fa:user%</div>
 | 
			
		||||
				<div>
 | 
			
		||||
					<span>%i18n:@accounts%</span>
 | 
			
		||||
					<b class="primary">{{ stats.originalUsersCount | number }}</b>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<span>%fa:home% %i18n:@this-instance%</span>
 | 
			
		||||
				<span @click="setChartSrc('users')">%fa:chart-bar R%</span>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<div>%fa:pencil-alt%</div>
 | 
			
		||||
				<div>
 | 
			
		||||
					<span>%i18n:@notes%</span>
 | 
			
		||||
					<b class="primary">{{ stats.originalNotesCount | number }}</b>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<span>%fa:home% %i18n:@this-instance%</span>
 | 
			
		||||
				<span @click="setChartSrc('notes')">%fa:chart-bar R%</span>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<div>%fa:database%</div>
 | 
			
		||||
				<div>
 | 
			
		||||
					<span>%i18n:@drive%</span>
 | 
			
		||||
					<b>{{ stats.driveUsageLocal | bytes }}</b>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<span>%fa:home% %i18n:@this-instance%</span>
 | 
			
		||||
				<span @click="setChartSrc('drive')">%fa:chart-bar R%</span>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<div>%fa:hdd R%</div>
 | 
			
		||||
				<div>
 | 
			
		||||
					<span>%i18n:@instances%</span>
 | 
			
		||||
					<b>{{ stats.instances | number }}</b>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<span>%fa:globe% %i18n:@federated%</span>
 | 
			
		||||
				<span @click="setChartSrc('federation-instances-total')">%fa:chart-bar R%</span>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<div class="charts">
 | 
			
		||||
		<x-charts ref="charts"/>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<div class="cpu-memory">
 | 
			
		||||
		<x-cpu-memory :connection="connection"/>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<div class="ap">
 | 
			
		||||
		<x-ap-log/>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
import XCpuMemory from "./cpu-memory.vue";
 | 
			
		||||
import XCharts from "./charts.vue";
 | 
			
		||||
import XApLog from "./ap-log.vue";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	components: {
 | 
			
		||||
		XCpuMemory,
 | 
			
		||||
		XCharts,
 | 
			
		||||
		XApLog
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			stats: null,
 | 
			
		||||
			connection: null,
 | 
			
		||||
			meta: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	created() {
 | 
			
		||||
		this.connection = (this as any).os.stream.useSharedConnection('serverStats');
 | 
			
		||||
 | 
			
		||||
		(this as any).os.getMeta().then(meta => {
 | 
			
		||||
			this.meta = meta;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		(this as any).api('stats').then(stats => {
 | 
			
		||||
			this.stats = stats;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
		this.connection.dispose();
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		setChartSrc(src) {
 | 
			
		||||
			this.$refs.charts.setSrc(src);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.obdskegsannmntldydackcpzezagxqfy
 | 
			
		||||
	padding 16px
 | 
			
		||||
 | 
			
		||||
	@media (min-width 500px)
 | 
			
		||||
		padding 32px
 | 
			
		||||
 | 
			
		||||
	> header
 | 
			
		||||
		display flex
 | 
			
		||||
		margin-bottom 16px
 | 
			
		||||
		padding-bottom 16px
 | 
			
		||||
		border-bottom solid 1px var(--adminDashboardHeaderBorder)
 | 
			
		||||
		color var(--adminDashboardHeaderFg)
 | 
			
		||||
		font-size 14px
 | 
			
		||||
		white-space nowrap
 | 
			
		||||
 | 
			
		||||
		@media (max-width 1000px)
 | 
			
		||||
			display none
 | 
			
		||||
 | 
			
		||||
		> p
 | 
			
		||||
			display block
 | 
			
		||||
			margin 0 32px 0 0
 | 
			
		||||
			overflow hidden
 | 
			
		||||
			text-overflow ellipsis
 | 
			
		||||
 | 
			
		||||
			> b
 | 
			
		||||
				&:after
 | 
			
		||||
					content ':'
 | 
			
		||||
					margin-right 8px
 | 
			
		||||
 | 
			
		||||
			&:last-child
 | 
			
		||||
				margin-left auto
 | 
			
		||||
				margin-right 0
 | 
			
		||||
 | 
			
		||||
	> .stats
 | 
			
		||||
		display flex
 | 
			
		||||
		justify-content space-between
 | 
			
		||||
		margin-bottom 16px
 | 
			
		||||
 | 
			
		||||
		> div
 | 
			
		||||
			flex 1
 | 
			
		||||
			margin-right 16px
 | 
			
		||||
			color var(--adminDashboardCardFg)
 | 
			
		||||
			box-shadow 0 2px 4px rgba(0, 0, 0, 0.1)
 | 
			
		||||
			background var(--adminDashboardCardBg)
 | 
			
		||||
			border-radius 8px
 | 
			
		||||
 | 
			
		||||
			&:last-child
 | 
			
		||||
				margin-right 0
 | 
			
		||||
 | 
			
		||||
			> div:first-child
 | 
			
		||||
				display flex
 | 
			
		||||
				align-items center
 | 
			
		||||
				text-align center
 | 
			
		||||
 | 
			
		||||
				&:last-child
 | 
			
		||||
					margin-right 0
 | 
			
		||||
 | 
			
		||||
				> div:first-child
 | 
			
		||||
					padding 16px 24px
 | 
			
		||||
					font-size 28px
 | 
			
		||||
 | 
			
		||||
				> div:last-child
 | 
			
		||||
					flex 1
 | 
			
		||||
					padding 16px 32px 16px 0
 | 
			
		||||
					text-align right
 | 
			
		||||
 | 
			
		||||
					> span
 | 
			
		||||
						font-size 70%
 | 
			
		||||
						opacity 0.7
 | 
			
		||||
 | 
			
		||||
					> b
 | 
			
		||||
						display block
 | 
			
		||||
 | 
			
		||||
						&.primary
 | 
			
		||||
							color var(--primary)
 | 
			
		||||
 | 
			
		||||
			> div:last-child
 | 
			
		||||
				display flex
 | 
			
		||||
				padding 6px 16px
 | 
			
		||||
				border-top solid 1px var(--adminDashboardCardDivider)
 | 
			
		||||
 | 
			
		||||
				> span
 | 
			
		||||
					font-size 70%
 | 
			
		||||
					opacity 0.7
 | 
			
		||||
 | 
			
		||||
					&:last-child
 | 
			
		||||
						margin-left auto
 | 
			
		||||
						cursor pointer
 | 
			
		||||
 | 
			
		||||
		@media (max-width 900px)
 | 
			
		||||
			display grid
 | 
			
		||||
			grid-template-columns 1fr 1fr
 | 
			
		||||
			grid-template-rows 1fr 1fr
 | 
			
		||||
			gap 16px
 | 
			
		||||
 | 
			
		||||
			> div
 | 
			
		||||
				margin-right 0
 | 
			
		||||
 | 
			
		||||
		@media (max-width 500px)
 | 
			
		||||
			display block
 | 
			
		||||
 | 
			
		||||
			> div:not(:last-child)
 | 
			
		||||
				margin-bottom 16px
 | 
			
		||||
 | 
			
		||||
	> .charts
 | 
			
		||||
		margin-bottom 16px
 | 
			
		||||
 | 
			
		||||
	> .cpu-memory
 | 
			
		||||
		margin-bottom 16px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										117
									
								
								src/client/app/admin/views/emoji.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/client/app/admin/views/emoji.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="tumhkfkmgtvzljezfvmgkeurkfncshbe">
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%fa:plus% %i18n:@add-emoji.title%</div>
 | 
			
		||||
		<section class="fit-top">
 | 
			
		||||
			<ui-horizon-group inputs>
 | 
			
		||||
				<ui-input v-model="name">
 | 
			
		||||
					<span>%i18n:@add-emoji.name%</span>
 | 
			
		||||
					<span slot="text">%i18n:@add-emoji.name-desc%</span>
 | 
			
		||||
				</ui-input>
 | 
			
		||||
				<ui-input v-model="aliases">
 | 
			
		||||
					<span>%i18n:@add-emoji.aliases%</span>
 | 
			
		||||
					<span slot="text">%i18n:@add-emoji.aliases-desc%</span>
 | 
			
		||||
				</ui-input>
 | 
			
		||||
			</ui-horizon-group>
 | 
			
		||||
			<ui-input v-model="url">
 | 
			
		||||
				<span>%i18n:@add-emoji.url%</span>
 | 
			
		||||
			</ui-input>
 | 
			
		||||
			<ui-button @click="add">%i18n:@add-emoji.add%</ui-button>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%fa:grin R% %i18n:@emojis.title%</div>
 | 
			
		||||
		<section v-for="emoji in emojis">
 | 
			
		||||
			<img :src="emoji.url" :alt="emoji.name" style="width: 64px;"/>
 | 
			
		||||
			<ui-horizon-group inputs>
 | 
			
		||||
				<ui-input v-model="emoji.name">
 | 
			
		||||
					<span>%i18n:@add-emoji.name%</span>
 | 
			
		||||
				</ui-input>
 | 
			
		||||
				<ui-input v-model="emoji.aliases">
 | 
			
		||||
					<span>%i18n:@add-emoji.aliases%</span>
 | 
			
		||||
				</ui-input>
 | 
			
		||||
			</ui-horizon-group>
 | 
			
		||||
			<ui-input v-model="emoji.url">
 | 
			
		||||
				<span>%i18n:@add-emoji.url%</span>
 | 
			
		||||
			</ui-input>
 | 
			
		||||
			<ui-horizon-group>
 | 
			
		||||
				<ui-button @click="updateEmoji(emoji)">%fa:save R% %i18n:@emojis.update%</ui-button>
 | 
			
		||||
				<ui-button @click="removeEmoji(emoji)">%fa:trash-alt R% %i18n:@emojis.remove%</ui-button>
 | 
			
		||||
			</ui-horizon-group>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			name: '',
 | 
			
		||||
			url: '',
 | 
			
		||||
			aliases: '',
 | 
			
		||||
			emojis: []
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.fetchEmojis();
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		add() {
 | 
			
		||||
			(this as any).api('admin/emoji/add', {
 | 
			
		||||
				name: this.name,
 | 
			
		||||
				url: this.url,
 | 
			
		||||
				aliases: this.aliases.split(' ')
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Added` });
 | 
			
		||||
				this.fetchEmojis();
 | 
			
		||||
			}).catch(e => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		fetchEmojis() {
 | 
			
		||||
			(this as any).api('admin/emoji/list').then(emojis => {
 | 
			
		||||
				emojis.forEach(e => e.aliases = (e.aliases || []).join(' '));
 | 
			
		||||
				this.emojis = emojis;
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		updateEmoji(emoji) {
 | 
			
		||||
			(this as any).api('admin/emoji/update', {
 | 
			
		||||
				id: emoji.id,
 | 
			
		||||
				name: emoji.name,
 | 
			
		||||
				url: emoji.url,
 | 
			
		||||
				aliases: emoji.aliases.split(' ')
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Updated` });
 | 
			
		||||
			}).catch(e => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		removeEmoji(emoji) {
 | 
			
		||||
			(this as any).api('admin/emoji/remove', {
 | 
			
		||||
				id: emoji.id
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Removed` });
 | 
			
		||||
				this.fetchEmojis();
 | 
			
		||||
			}).catch(e => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.tumhkfkmgtvzljezfvmgkeurkfncshbe
 | 
			
		||||
	@media (min-width 500px)
 | 
			
		||||
		padding 16px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,8 +1,12 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="jdnqwkzlnxcfftthoybjxrebyolvoucw mk-admin-card">
 | 
			
		||||
	<header>%i18n:@hided-tags%</header>
 | 
			
		||||
	<textarea v-model="hidedTags"></textarea>
 | 
			
		||||
	<button class="ui" @click="save">%i18n:@save%</button>
 | 
			
		||||
<div>
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%i18n:@hided-tags%</div>
 | 
			
		||||
		<section>
 | 
			
		||||
			<textarea class="jdnqwkzlnxcfftthoybjxrebyolvoucw" v-model="hidedTags"></textarea>
 | 
			
		||||
			<ui-button @click="save">%i18n:@save%</ui-button>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
@@ -25,9 +29,9 @@ export default Vue.extend({
 | 
			
		||||
			(this as any).api('admin/update-meta', {
 | 
			
		||||
				hidedTags: this.hidedTags.split('\n')
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Saved` });
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Saved` });
 | 
			
		||||
			}).catch(e => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -35,11 +39,8 @@ export default Vue.extend({
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.jdnqwkzlnxcfftthoybjxrebyolvoucw
 | 
			
		||||
	textarea
 | 
			
		||||
		width 100%
 | 
			
		||||
		min-height 300px
 | 
			
		||||
	width 100%
 | 
			
		||||
	min-height 300px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										260
									
								
								src/client/app/admin/views/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								src/client/app/admin/views/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,260 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-admin" :class="{ isMobile }">
 | 
			
		||||
	<header v-show="isMobile">
 | 
			
		||||
		<button class="nav" @click="navOpend = true">%fa:bars%</button>
 | 
			
		||||
		<span>MisskeyMyAdmin</span>
 | 
			
		||||
	</header>
 | 
			
		||||
	<div class="nav-backdrop"
 | 
			
		||||
		v-if="navOpend && isMobile"
 | 
			
		||||
		@click="navOpend = false"
 | 
			
		||||
		@touchstart="navOpend = false"
 | 
			
		||||
	></div>
 | 
			
		||||
	<nav v-show="navOpend">
 | 
			
		||||
		<div class="mi">
 | 
			
		||||
			<img svg-inline src="../assets/header-icon.svg"/>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="me">
 | 
			
		||||
			<img class="avatar" :src="$store.state.i.avatarUrl" alt="avatar"/>
 | 
			
		||||
			<p class="name">{{ $store.state.i | userName }}</p>
 | 
			
		||||
		</div>
 | 
			
		||||
		<ul>
 | 
			
		||||
			<li @click="nav('dashboard')" :class="{ active: page == 'dashboard' }">%fa:home .fw%%i18n:@dashboard%</li>
 | 
			
		||||
			<li @click="nav('instance')" :class="{ active: page == 'instance' }">%fa:cog .fw%%i18n:@instance%</li>
 | 
			
		||||
			<li @click="nav('users')" :class="{ active: page == 'users' }">%fa:users .fw%%i18n:@users%</li>
 | 
			
		||||
			<li @click="nav('emoji')" :class="{ active: page == 'emoji' }">%fa:grin R .fw%%i18n:@emoji%</li>
 | 
			
		||||
			<li @click="nav('announcements')" :class="{ active: page == 'announcements' }">%fa:broadcast-tower .fw%%i18n:@announcements%</li>
 | 
			
		||||
			<li @click="nav('hashtags')" :class="{ active: page == 'hashtags' }">%fa:hashtag .fw%%i18n:@hashtags%</li>
 | 
			
		||||
 | 
			
		||||
			<!-- <li @click="nav('drive')" :class="{ active: page == 'drive' }">%fa:cloud .fw%%i18n:common.drive%</li> -->
 | 
			
		||||
			<!-- <li @click="nav('update')" :class="{ active: page == 'update' }">%i18n:@update%</li> -->
 | 
			
		||||
		</ul>
 | 
			
		||||
		<div class="back-to-misskey">
 | 
			
		||||
			<a href="/">%fa:arrow-left% %i18n:@back-to-misskey%</a>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="version">
 | 
			
		||||
			<small>Misskey {{ version }}</small>
 | 
			
		||||
		</div>
 | 
			
		||||
	</nav>
 | 
			
		||||
	<main>
 | 
			
		||||
		<div v-show="page == 'dashboard'"><x-dashboard/></div>
 | 
			
		||||
		<div v-show="page == 'instance'"><x-instance/></div>
 | 
			
		||||
		<div v-if="page == 'users'"><x-users/></div>
 | 
			
		||||
		<div v-show="page == 'emoji'"><x-emoji/></div>
 | 
			
		||||
		<div v-show="page == 'announcements'"><x-announcements/></div>
 | 
			
		||||
		<div v-show="page == 'hashtags'"><x-hashtags/></div>
 | 
			
		||||
		<div v-if="page == 'drive'"></div>
 | 
			
		||||
		<div v-if="page == 'update'"></div>
 | 
			
		||||
	</main>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
import { version } from '../../config';
 | 
			
		||||
import XDashboard from "./dashboard.vue";
 | 
			
		||||
import XInstance from "./instance.vue";
 | 
			
		||||
import XEmoji from "./emoji.vue";
 | 
			
		||||
import XAnnouncements from "./announcements.vue";
 | 
			
		||||
import XHashtags from "./hashtags.vue";
 | 
			
		||||
import XUsers from "./users.vue";
 | 
			
		||||
 | 
			
		||||
// Detect the user agent
 | 
			
		||||
const ua = navigator.userAgent.toLowerCase();
 | 
			
		||||
const isMobile = /mobile|iphone|ipad|android/.test(ua);
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	components: {
 | 
			
		||||
		XDashboard,
 | 
			
		||||
		XInstance,
 | 
			
		||||
		XEmoji,
 | 
			
		||||
		XAnnouncements,
 | 
			
		||||
		XHashtags,
 | 
			
		||||
		XUsers
 | 
			
		||||
	},
 | 
			
		||||
	provide: {
 | 
			
		||||
		isMobile
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			page: 'dashboard',
 | 
			
		||||
			version,
 | 
			
		||||
			isMobile,
 | 
			
		||||
			navOpend: !isMobile
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		nav(page: string) {
 | 
			
		||||
			this.page = page;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus">
 | 
			
		||||
.mk-admin
 | 
			
		||||
	$headerHeight = 48px
 | 
			
		||||
 | 
			
		||||
	display flex
 | 
			
		||||
	height 100%
 | 
			
		||||
 | 
			
		||||
	> header
 | 
			
		||||
		position fixed
 | 
			
		||||
		top 0
 | 
			
		||||
		z-index 10000
 | 
			
		||||
		width 100%
 | 
			
		||||
		color var(--mobileHeaderFg)
 | 
			
		||||
		background-color var(--mobileHeaderBg)
 | 
			
		||||
		box-shadow 0 1px 0 rgba(#000, 0.075)
 | 
			
		||||
 | 
			
		||||
		&, *
 | 
			
		||||
			user-select none
 | 
			
		||||
 | 
			
		||||
		> span
 | 
			
		||||
			display block
 | 
			
		||||
			line-height $headerHeight
 | 
			
		||||
			text-align center
 | 
			
		||||
 | 
			
		||||
		> .nav
 | 
			
		||||
			display block
 | 
			
		||||
			position absolute
 | 
			
		||||
			top 0
 | 
			
		||||
			left 0
 | 
			
		||||
			z-index 10001
 | 
			
		||||
			padding 0
 | 
			
		||||
			width $headerHeight
 | 
			
		||||
			font-size 1.4em
 | 
			
		||||
			line-height $headerHeight
 | 
			
		||||
			border-right solid 1px rgba(#000, 0.1)
 | 
			
		||||
 | 
			
		||||
			> [data-fa]
 | 
			
		||||
				transition all 0.2s ease
 | 
			
		||||
 | 
			
		||||
	> nav
 | 
			
		||||
		position fixed
 | 
			
		||||
		z-index 20001
 | 
			
		||||
		top 0
 | 
			
		||||
		left 0
 | 
			
		||||
		width 250px
 | 
			
		||||
		height 100vh
 | 
			
		||||
		overflow auto
 | 
			
		||||
		background #333
 | 
			
		||||
		color #fff
 | 
			
		||||
 | 
			
		||||
		> .mi
 | 
			
		||||
			text-align center
 | 
			
		||||
 | 
			
		||||
			> svg
 | 
			
		||||
				width 24px
 | 
			
		||||
				height 82px
 | 
			
		||||
				vertical-align top
 | 
			
		||||
				fill #fff
 | 
			
		||||
				opacity 0.7
 | 
			
		||||
 | 
			
		||||
		> .me
 | 
			
		||||
			display flex
 | 
			
		||||
			margin 0 16px 16px 16px
 | 
			
		||||
			padding 16px 0
 | 
			
		||||
			align-items center
 | 
			
		||||
			border-top solid 1px #555
 | 
			
		||||
			border-bottom solid 1px #555
 | 
			
		||||
 | 
			
		||||
			> .avatar
 | 
			
		||||
				height 48px
 | 
			
		||||
				border-radius 100%
 | 
			
		||||
				vertical-align middle
 | 
			
		||||
 | 
			
		||||
			> .name
 | 
			
		||||
				margin 0 16px
 | 
			
		||||
				padding 0
 | 
			
		||||
				color #fff
 | 
			
		||||
				overflow hidden
 | 
			
		||||
				text-overflow ellipsis
 | 
			
		||||
				white-space nowrap
 | 
			
		||||
				font-size 15px
 | 
			
		||||
 | 
			
		||||
		> .back-to-misskey
 | 
			
		||||
			margin 16px 16px 0 16px
 | 
			
		||||
			padding 0
 | 
			
		||||
			border-top solid 1px #555
 | 
			
		||||
 | 
			
		||||
			> a
 | 
			
		||||
				display block
 | 
			
		||||
				padding 16px 4px
 | 
			
		||||
				color inherit
 | 
			
		||||
				text-decoration none
 | 
			
		||||
				color #eee
 | 
			
		||||
				font-size 15px
 | 
			
		||||
 | 
			
		||||
				&:hover
 | 
			
		||||
					color #fff
 | 
			
		||||
 | 
			
		||||
				> [data-fa]
 | 
			
		||||
					margin-right 6px
 | 
			
		||||
 | 
			
		||||
		> .version
 | 
			
		||||
			margin 0 16px 16px 16px
 | 
			
		||||
			padding-top 16px
 | 
			
		||||
			border-top solid 1px #555
 | 
			
		||||
			text-align center
 | 
			
		||||
 | 
			
		||||
			> small
 | 
			
		||||
				opacity 0.7
 | 
			
		||||
 | 
			
		||||
		> ul
 | 
			
		||||
			margin 0
 | 
			
		||||
			padding 0
 | 
			
		||||
			list-style none
 | 
			
		||||
			font-size 15px
 | 
			
		||||
 | 
			
		||||
			> li
 | 
			
		||||
				display block
 | 
			
		||||
				padding 10px 16px
 | 
			
		||||
				margin 0
 | 
			
		||||
				cursor pointer
 | 
			
		||||
				user-select none
 | 
			
		||||
				color #eee
 | 
			
		||||
				transition margin-left 0.2s ease
 | 
			
		||||
 | 
			
		||||
				&:hover
 | 
			
		||||
					color #fff
 | 
			
		||||
 | 
			
		||||
				> [data-fa]
 | 
			
		||||
					margin-right 6px
 | 
			
		||||
 | 
			
		||||
				&.active
 | 
			
		||||
					margin-left 8px
 | 
			
		||||
					color var(--primary) !important
 | 
			
		||||
 | 
			
		||||
					&:after
 | 
			
		||||
						content ""
 | 
			
		||||
						display block
 | 
			
		||||
						position absolute
 | 
			
		||||
						top 0
 | 
			
		||||
						right 0
 | 
			
		||||
						bottom 0
 | 
			
		||||
						margin auto 0
 | 
			
		||||
						height 0
 | 
			
		||||
						border-top solid 16px transparent
 | 
			
		||||
						border-right solid 16px var(--bg)
 | 
			
		||||
						border-bottom solid 16px transparent
 | 
			
		||||
						border-left solid 16px transparent
 | 
			
		||||
 | 
			
		||||
	> .nav-backdrop
 | 
			
		||||
		position fixed
 | 
			
		||||
		top 0
 | 
			
		||||
		left 0
 | 
			
		||||
		z-index 20000
 | 
			
		||||
		width 100%
 | 
			
		||||
		height 100%
 | 
			
		||||
		background var(--mobileNavBackdrop)
 | 
			
		||||
 | 
			
		||||
	> main
 | 
			
		||||
		width 100%
 | 
			
		||||
		padding 0 0 0 250px
 | 
			
		||||
		max-width 1300px
 | 
			
		||||
 | 
			
		||||
	&.isMobile
 | 
			
		||||
		> main
 | 
			
		||||
			padding $headerHeight 0 0 0
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										85
									
								
								src/client/app/admin/views/instance.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/client/app/admin/views/instance.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="axbwjelsbymowqjyywpirzhdlszoncqs">
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%fa:cog% %i18n:@instance%</div>
 | 
			
		||||
		<section class="fit-top">
 | 
			
		||||
			<ui-input v-model="name">%i18n:@instance-name%</ui-input>
 | 
			
		||||
			<ui-textarea v-model="description">%i18n:@instance-description%</ui-textarea>
 | 
			
		||||
			<ui-input v-model="bannerUrl">%i18n:@banner-url%</ui-input>
 | 
			
		||||
			<ui-button @click="updateMeta">%i18n:@save%</ui-button>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%i18n:@disable-registration%</div>
 | 
			
		||||
		<section>
 | 
			
		||||
			<input type="checkbox" v-model="disableRegistration" @change="updateMeta">
 | 
			
		||||
			<button class="ui" @click="invite">%i18n:@invite%</button>
 | 
			
		||||
			<p v-if="inviteCode">Code: <code>{{ inviteCode }}</code></p>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%i18n:@disable-local-timeline%</div>
 | 
			
		||||
		<section>
 | 
			
		||||
			<input type="checkbox" v-model="disableLocalTimeline" @change="updateMeta">
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			disableRegistration: false,
 | 
			
		||||
			disableLocalTimeline: false,
 | 
			
		||||
			bannerUrl: null,
 | 
			
		||||
			name: null,
 | 
			
		||||
			description: null,
 | 
			
		||||
			inviteCode: null,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	created() {
 | 
			
		||||
		(this as any).os.getMeta().then(meta => {
 | 
			
		||||
			this.bannerUrl = meta.bannerUrl;
 | 
			
		||||
			this.name = meta.name;
 | 
			
		||||
			this.description = meta.description;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		invite() {
 | 
			
		||||
			(this as any).api('admin/invite').then(x => {
 | 
			
		||||
				this.inviteCode = x.code;
 | 
			
		||||
			}).catch(e => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		updateMeta() {
 | 
			
		||||
			(this as any).api('admin/update-meta', {
 | 
			
		||||
				disableRegistration: this.disableRegistration,
 | 
			
		||||
				disableLocalTimeline: this.disableLocalTimeline,
 | 
			
		||||
				bannerUrl: this.bannerUrl,
 | 
			
		||||
				name: this.name,
 | 
			
		||||
				description: this.description
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Saved` });
 | 
			
		||||
			}).catch(e => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.axbwjelsbymowqjyywpirzhdlszoncqs
 | 
			
		||||
	@media (min-width 500px)
 | 
			
		||||
		padding 16px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										136
									
								
								src/client/app/admin/views/users.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								src/client/app/admin/views/users.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="ucnffhbtogqgscfmqcymwmmupoknpfsw">
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%i18n:@verify-user%</div>
 | 
			
		||||
		<section class="fit-top">
 | 
			
		||||
			<ui-input v-model="verifyUsername" type="text">
 | 
			
		||||
				<span slot="prefix">@</span>
 | 
			
		||||
			</ui-input>
 | 
			
		||||
			<ui-button @click="verifyUser" :disabled="verifying">%i18n:@verify%</ui-button>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%i18n:@unverify-user%</div>
 | 
			
		||||
		<section class="fit-top">
 | 
			
		||||
			<ui-input v-model="unverifyUsername" type="text">
 | 
			
		||||
				<span slot="prefix">@</span>
 | 
			
		||||
			</ui-input>
 | 
			
		||||
			<ui-button @click="unverifyUser" :disabled="unverifying">%i18n:@unverify%</ui-button>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%i18n:@suspend-user%</div>
 | 
			
		||||
		<section class="fit-top">
 | 
			
		||||
			<ui-input v-model="suspendUsername" type="text">
 | 
			
		||||
				<span slot="prefix">@</span>
 | 
			
		||||
			</ui-input>
 | 
			
		||||
			<ui-button @click="suspendUser" :disabled="suspending">%i18n:@suspend%</ui-button>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
 | 
			
		||||
	<ui-card>
 | 
			
		||||
		<div slot="title">%i18n:@unsuspend-user%</div>
 | 
			
		||||
		<section class="fit-top">
 | 
			
		||||
			<ui-input v-model="unsuspendUsername" type="text">
 | 
			
		||||
				<span slot="prefix">@</span>
 | 
			
		||||
			</ui-input>
 | 
			
		||||
			<ui-button @click="unsuspendUser" :disabled="unsuspending">%i18n:@unsuspend%</ui-button>
 | 
			
		||||
		</section>
 | 
			
		||||
	</ui-card>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
import parseAcct from "../../../../misc/acct/parse";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			verifyUsername: null,
 | 
			
		||||
			verifying: false,
 | 
			
		||||
			unverifyUsername: null,
 | 
			
		||||
			unverifying: false,
 | 
			
		||||
			suspendUsername: null,
 | 
			
		||||
			suspending: false,
 | 
			
		||||
			unsuspendUsername: null,
 | 
			
		||||
			unsuspending: false
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		async verifyUser() {
 | 
			
		||||
			this.verifying = true;
 | 
			
		||||
 | 
			
		||||
			const process = async () => {
 | 
			
		||||
				const user = await (this as any).os.api('users/show', parseAcct(this.verifyUsername));
 | 
			
		||||
				await (this as any).os.api('admin/verify-user', { userId: user.id });
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: '%i18n:@verified%' });
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			await process().catch(e => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed: ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.verifying = false;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		async unverifyUser() {
 | 
			
		||||
			this.unverifying = true;
 | 
			
		||||
 | 
			
		||||
			const process = async () => {
 | 
			
		||||
				const user = await (this as any).os.api('users/show', parseAcct(this.unverifyUsername));
 | 
			
		||||
				await (this as any).os.api('admin/unverify-user', { userId: user.id });
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: '%i18n:@unverified%' });
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			await process().catch(e => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed: ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.unverifying = false;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		async suspendUser() {
 | 
			
		||||
			this.suspending = true;
 | 
			
		||||
 | 
			
		||||
			const process = async () => {
 | 
			
		||||
				const user = await (this as any).os.api('users/show', parseAcct(this.suspendUsername));
 | 
			
		||||
				await (this as any).os.api('admin/suspend-user', { userId: user.id });
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: '%i18n:@suspended%' });
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			await process().catch(e => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed: ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.suspending = false;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		async unsuspendUser() {
 | 
			
		||||
			this.unsuspending = true;
 | 
			
		||||
 | 
			
		||||
			const process = async () => {
 | 
			
		||||
				const user = await (this as any).os.api('users/show', parseAcct(this.unsuspendUsername));
 | 
			
		||||
				await (this as any).os.api('admin/unsuspend-user', { userId: user.id });
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: '%i18n:@unsuspended%' });
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			await process().catch(e => {
 | 
			
		||||
				//(this as any).os.apis.dialog({ text: `Failed: ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.unsuspending = false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.ucnffhbtogqgscfmqcymwmmupoknpfsw
 | 
			
		||||
	@media (min-width 500px)
 | 
			
		||||
		padding 16px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -46,6 +46,7 @@
 | 
			
		||||
	if (`${url.pathname}/`.startsWith('/docs/')) app = 'docs';
 | 
			
		||||
	if (`${url.pathname}/`.startsWith('/dev/')) app = 'dev';
 | 
			
		||||
	if (`${url.pathname}/`.startsWith('/auth/')) app = 'auth';
 | 
			
		||||
	if (`${url.pathname}/`.startsWith('/admin/')) app = 'admin';
 | 
			
		||||
	//#endregion
 | 
			
		||||
 | 
			
		||||
	//#region Detect the user language
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
import MiOS from '../../mios';
 | 
			
		||||
import { version as current } from '../../config';
 | 
			
		||||
import { clientVersion as current } from '../../config';
 | 
			
		||||
 | 
			
		||||
export default async function(mios: MiOS, force = false, silent = false) {
 | 
			
		||||
	const meta = await mios.getMeta(force);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										72
									
								
								src/client/app/common/views/components/api-settings.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/client/app/common/views/components/api-settings.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
<template>
 | 
			
		||||
<ui-card>
 | 
			
		||||
	<div slot="title">%fa:key% API</div>
 | 
			
		||||
 | 
			
		||||
	<section class="fit-top">
 | 
			
		||||
		<ui-input :value="$store.state.i.token" readonly>
 | 
			
		||||
			<span>%i18n:@token%</span>
 | 
			
		||||
		</ui-input>
 | 
			
		||||
		<p>%i18n:@intro%</p>
 | 
			
		||||
		<ui-info warn>%i18n:@caution%</ui-info>
 | 
			
		||||
		<p>%i18n:@regeneration-of-token%</p>
 | 
			
		||||
		<ui-button @click="regenerateToken">%fa:sync-alt% %i18n:@regenerate-token%</ui-button>
 | 
			
		||||
	</section>
 | 
			
		||||
 | 
			
		||||
	<section>
 | 
			
		||||
		<header>%fa:terminal% %i18n:@console.title%</header>
 | 
			
		||||
		<ui-input v-model="endpoint">
 | 
			
		||||
			<span>%i18n:@console.endpoint%</span>
 | 
			
		||||
		</ui-input>
 | 
			
		||||
		<ui-textarea v-model="body">
 | 
			
		||||
			<span>%i18n:@console.parameter% (JSON or JSON5)</span>
 | 
			
		||||
		</ui-textarea>
 | 
			
		||||
		<ui-button @click="send" :disabled="sending">
 | 
			
		||||
			<template v-if="sending">%i18n:@console.sending%</template>
 | 
			
		||||
			<template v-else>%fa:paper-plane% %i18n:@console.send%</template>
 | 
			
		||||
		</ui-button>
 | 
			
		||||
		<ui-textarea v-if="res" v-model="res" readonly tall>
 | 
			
		||||
			<span>%i18n:@console.response%</span>
 | 
			
		||||
		</ui-textarea>
 | 
			
		||||
	</section>
 | 
			
		||||
</ui-card>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import * as JSON5 from 'json5';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			endpoint: '',
 | 
			
		||||
			body: '{}',
 | 
			
		||||
			res: null,
 | 
			
		||||
			sending: false
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		regenerateToken() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@enter-password%',
 | 
			
		||||
				type: 'password'
 | 
			
		||||
			}).then(password => {
 | 
			
		||||
				(this as any).api('i/regenerate_token', {
 | 
			
		||||
					password: password
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		send() {
 | 
			
		||||
			this.sending = true;
 | 
			
		||||
			(this as any).api(this.endpoint, JSON5.parse(this.body)).then(res => {
 | 
			
		||||
				this.sending = false;
 | 
			
		||||
				this.res = JSON5.stringify(res, null, 2);
 | 
			
		||||
			}, err => {
 | 
			
		||||
				this.sending = false;
 | 
			
		||||
				this.res = JSON5.stringify(err, null, 2);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
@@ -14,9 +14,10 @@
 | 
			
		||||
	</ol>
 | 
			
		||||
	<ol class="emojis" ref="suggests" v-if="emojis.length > 0">
 | 
			
		||||
		<li v-for="emoji in emojis" @click="complete(type, emoji.emoji)" @keydown="onKeydown" tabindex="-1">
 | 
			
		||||
			<span class="emoji">{{ emoji.emoji }}</span>
 | 
			
		||||
			<span class="emoji" v-if="emoji.url"><img :src="emoji.url" :alt="emoji.emoji"/></span>
 | 
			
		||||
			<span class="emoji" v-else>{{ emoji.emoji }}</span>
 | 
			
		||||
			<span class="name" v-html="emoji.name.replace(q, `<b>${q}</b>`)"></span>
 | 
			
		||||
			<span class="alias" v-if="emoji.alias">({{ emoji.alias }})</span>
 | 
			
		||||
			<span class="alias" v-if="emoji.aliasOf">({{ emoji.aliasOf }})</span>
 | 
			
		||||
		</li>
 | 
			
		||||
	</ol>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -27,14 +28,21 @@ import Vue from 'vue';
 | 
			
		||||
import * as emojilib from 'emojilib';
 | 
			
		||||
import contains from '../../../common/scripts/contains';
 | 
			
		||||
 | 
			
		||||
type EmojiDef = {
 | 
			
		||||
	emoji: string;
 | 
			
		||||
	name: string;
 | 
			
		||||
	aliasOf?: string;
 | 
			
		||||
	url?: string;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const lib = Object.entries(emojilib.lib).filter((x: any) => {
 | 
			
		||||
	return x[1].category != 'flags';
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const emjdb = lib.map((x: any) => ({
 | 
			
		||||
const emjdb: EmojiDef[] = lib.map((x: any) => ({
 | 
			
		||||
	emoji: x[1].char,
 | 
			
		||||
	name: x[0],
 | 
			
		||||
	alias: null
 | 
			
		||||
	aliasOf: null
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
lib.forEach((x: any) => {
 | 
			
		||||
@@ -43,7 +51,7 @@ lib.forEach((x: any) => {
 | 
			
		||||
			emjdb.push({
 | 
			
		||||
				emoji: x[1].char,
 | 
			
		||||
				name: k,
 | 
			
		||||
				alias: x[0]
 | 
			
		||||
				aliasOf: x[0]
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
@@ -61,7 +69,8 @@ export default Vue.extend({
 | 
			
		||||
			hashtags: [],
 | 
			
		||||
			emojis: [],
 | 
			
		||||
			select: -1,
 | 
			
		||||
			emojilib
 | 
			
		||||
			emojilib,
 | 
			
		||||
			emojiDb: [] as EmojiDef[]
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
@@ -90,6 +99,34 @@ export default Vue.extend({
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	mounted() {
 | 
			
		||||
		//#region Construct Emoji DB
 | 
			
		||||
		const customEmojis = (this.os.getMetaSync() || { emojis: [] }).emojis || [];
 | 
			
		||||
		const emojiDefinitions: EmojiDef[] = [];
 | 
			
		||||
 | 
			
		||||
		customEmojis.forEach(x => {
 | 
			
		||||
			emojiDefinitions.push({
 | 
			
		||||
				name: x.name,
 | 
			
		||||
				emoji: `:${x.name}:`,
 | 
			
		||||
				url: x.url
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			if (x.aliases) {
 | 
			
		||||
				x.aliases.forEach(alias => {
 | 
			
		||||
					emojiDefinitions.push({
 | 
			
		||||
						name: alias,
 | 
			
		||||
						aliasOf: x.name,
 | 
			
		||||
						emoji: `:${x.name}:`,
 | 
			
		||||
						url: x.url
 | 
			
		||||
					});
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		emojiDefinitions.sort((a, b) => a.name.length - b.name.length);
 | 
			
		||||
 | 
			
		||||
		this.emojiDb = emojiDefinitions.concat(emjdb);
 | 
			
		||||
		//#endregion
 | 
			
		||||
 | 
			
		||||
		this.textarea.addEventListener('keydown', this.onKeydown);
 | 
			
		||||
 | 
			
		||||
		Array.from(document.querySelectorAll('body *')).forEach(el => {
 | 
			
		||||
@@ -169,22 +206,25 @@ export default Vue.extend({
 | 
			
		||||
				}
 | 
			
		||||
			} else if (this.type == 'emoji') {
 | 
			
		||||
				const matched = [];
 | 
			
		||||
				emjdb.some(x => {
 | 
			
		||||
					if (x.name.indexOf(this.q) == 0 && !x.alias && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
 | 
			
		||||
					return matched.length == 30;
 | 
			
		||||
				const max = 30;
 | 
			
		||||
 | 
			
		||||
				this.emojiDb.some(x => {
 | 
			
		||||
					if (x.name.startsWith(this.q) && !x.aliasOf && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
 | 
			
		||||
					return matched.length == max;
 | 
			
		||||
				});
 | 
			
		||||
				if (matched.length < 30) {
 | 
			
		||||
					emjdb.some(x => {
 | 
			
		||||
						if (x.name.indexOf(this.q) == 0 && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
 | 
			
		||||
						return matched.length == 30;
 | 
			
		||||
				if (matched.length < max) {
 | 
			
		||||
					this.emojiDb.some(x => {
 | 
			
		||||
						if (x.name.startsWith(this.q) && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
 | 
			
		||||
						return matched.length == max;
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
				if (matched.length < 30) {
 | 
			
		||||
					emjdb.some(x => {
 | 
			
		||||
						if (x.name.indexOf(this.q) > -1 && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
 | 
			
		||||
						return matched.length == 30;
 | 
			
		||||
				if (matched.length < max) {
 | 
			
		||||
					this.emojiDb.some(x => {
 | 
			
		||||
						if (x.name.includes(this.q) && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
 | 
			
		||||
						return matched.length == max;
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				this.emojis = matched;
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
@@ -340,6 +380,10 @@ export default Vue.extend({
 | 
			
		||||
			margin 0 4px 0 0
 | 
			
		||||
			width 24px
 | 
			
		||||
 | 
			
		||||
			> img
 | 
			
		||||
				width 24px
 | 
			
		||||
				vertical-align bottom
 | 
			
		||||
 | 
			
		||||
		.name
 | 
			
		||||
			color var(--autocompleteItemText)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										171
									
								
								src/client/app/common/views/components/drive-settings.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								src/client/app/common/views/components/drive-settings.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,171 @@
 | 
			
		||||
<template>
 | 
			
		||||
<ui-card>
 | 
			
		||||
	<div slot="title">%fa:cloud% %i18n:common.drive%</div>
 | 
			
		||||
 | 
			
		||||
	<section v-if="!fetching" class="juakhbxthdewydyreaphkepoxgxvfogn">
 | 
			
		||||
		<div class="meter"><div :style="meterStyle"></div></div>
 | 
			
		||||
		<p>%i18n:@max%: <b>{{ capacity | bytes }}</b> %i18n:@in-use%: <b>{{ usage | bytes }}</b></p>
 | 
			
		||||
	</section>
 | 
			
		||||
 | 
			
		||||
	<section>
 | 
			
		||||
		<header>%i18n:@stats%</header>
 | 
			
		||||
		<div ref="chart" style="margin-bottom: -16px; color: #000;"></div>
 | 
			
		||||
	</section>
 | 
			
		||||
</ui-card>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import * as tinycolor from 'tinycolor2';
 | 
			
		||||
import * as ApexCharts from 'apexcharts';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			usage: null,
 | 
			
		||||
			capacity: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	computed: {
 | 
			
		||||
		meterStyle(): any {
 | 
			
		||||
			return {
 | 
			
		||||
				width: `${this.usage / this.capacity * 100}%`,
 | 
			
		||||
				background: tinycolor({
 | 
			
		||||
					h: 180 - (this.usage / this.capacity * 180),
 | 
			
		||||
					s: 0.7,
 | 
			
		||||
					l: 0.5
 | 
			
		||||
				})
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	mounted() {
 | 
			
		||||
		(this as any).api('drive').then(info => {
 | 
			
		||||
			this.capacity = info.capacity;
 | 
			
		||||
			this.usage = info.usage;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
 | 
			
		||||
			this.$nextTick(() => {
 | 
			
		||||
				this.renderChart();
 | 
			
		||||
			});
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		renderChart() {
 | 
			
		||||
			(this as any).api('charts/user/drive', {
 | 
			
		||||
				userId: this.$store.state.i.id,
 | 
			
		||||
				span: 'day',
 | 
			
		||||
				limit: 21
 | 
			
		||||
			}).then(stats => {
 | 
			
		||||
				const addition = [];
 | 
			
		||||
				const deletion = [];
 | 
			
		||||
 | 
			
		||||
				const now = new Date();
 | 
			
		||||
				const y = now.getFullYear();
 | 
			
		||||
				const m = now.getMonth();
 | 
			
		||||
				const d = now.getDate();
 | 
			
		||||
 | 
			
		||||
				for (let i = 0; i < 21; i++) {
 | 
			
		||||
					const x = new Date(y, m, d - i);
 | 
			
		||||
					addition.push([
 | 
			
		||||
						x,
 | 
			
		||||
						stats.incSize[i]
 | 
			
		||||
					]);
 | 
			
		||||
					deletion.push([
 | 
			
		||||
						x,
 | 
			
		||||
						-stats.decSize[i]
 | 
			
		||||
					]);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				const chart = new ApexCharts(this.$refs.chart, {
 | 
			
		||||
					chart: {
 | 
			
		||||
						type: 'bar',
 | 
			
		||||
						stacked: true,
 | 
			
		||||
						height: 150,
 | 
			
		||||
						zoom: {
 | 
			
		||||
							enabled: false
 | 
			
		||||
						}
 | 
			
		||||
					},
 | 
			
		||||
					plotOptions: {
 | 
			
		||||
						bar: {
 | 
			
		||||
							columnWidth: '90%',
 | 
			
		||||
							endingShape: 'rounded'
 | 
			
		||||
						}
 | 
			
		||||
					},
 | 
			
		||||
					grid: {
 | 
			
		||||
						clipMarkers: false,
 | 
			
		||||
						borderColor: 'rgba(0, 0, 0, 0.1)'
 | 
			
		||||
					},
 | 
			
		||||
					tooltip: {
 | 
			
		||||
						shared: true,
 | 
			
		||||
						intersect: false
 | 
			
		||||
					},
 | 
			
		||||
					dataLabels: {
 | 
			
		||||
						enabled: false
 | 
			
		||||
					},
 | 
			
		||||
					legend: {
 | 
			
		||||
						show: false
 | 
			
		||||
					},
 | 
			
		||||
					series: [{
 | 
			
		||||
						name: 'Additions',
 | 
			
		||||
						data: addition
 | 
			
		||||
					}, {
 | 
			
		||||
						name: 'Deletions',
 | 
			
		||||
						data: deletion
 | 
			
		||||
					}],
 | 
			
		||||
					xaxis: {
 | 
			
		||||
						type: 'datetime',
 | 
			
		||||
						labels: {
 | 
			
		||||
							style: {
 | 
			
		||||
								colors: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
 | 
			
		||||
							}
 | 
			
		||||
						},
 | 
			
		||||
						axisBorder: {
 | 
			
		||||
							color: 'rgba(0, 0, 0, 0.1)'
 | 
			
		||||
						},
 | 
			
		||||
						axisTicks: {
 | 
			
		||||
							color: 'rgba(0, 0, 0, 0.1)'
 | 
			
		||||
						},
 | 
			
		||||
						crosshairs: {
 | 
			
		||||
							width: 1,
 | 
			
		||||
							opacity: 1
 | 
			
		||||
						}
 | 
			
		||||
					},
 | 
			
		||||
					yaxis: {
 | 
			
		||||
						labels: {
 | 
			
		||||
							formatter: v => Vue.filter('bytes')(v, 0),
 | 
			
		||||
							style: {
 | 
			
		||||
								color: tinycolor(getComputedStyle(document.documentElement).getPropertyValue('--text')).toRgbString()
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				chart.render();
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.juakhbxthdewydyreaphkepoxgxvfogn
 | 
			
		||||
	> .meter
 | 
			
		||||
		$size = 12px
 | 
			
		||||
 | 
			
		||||
		margin-bottom 16px
 | 
			
		||||
		background rgba(0, 0, 0, 0.1)
 | 
			
		||||
		border-radius ($size / 2)
 | 
			
		||||
		overflow hidden
 | 
			
		||||
 | 
			
		||||
		> div
 | 
			
		||||
			height $size
 | 
			
		||||
			border-radius ($size / 2)
 | 
			
		||||
 | 
			
		||||
	> p
 | 
			
		||||
		margin 0
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										19
									
								
								src/client/app/common/views/components/error.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/client/app/common/views/components/error.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="wjqjnyhzogztorhrdgcpqlkxhkmuetgj">
 | 
			
		||||
	<p>%fa:exclamation-triangle% %i18n:common.error.title%</p>
 | 
			
		||||
	<ui-button @click="() => $emit('retry')">%i18n:common.error.retry%</ui-button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.wjqjnyhzogztorhrdgcpqlkxhkmuetgj
 | 
			
		||||
	max-width 350px
 | 
			
		||||
	margin 0 auto
 | 
			
		||||
	padding 32px
 | 
			
		||||
	text-align center
 | 
			
		||||
	color var(--text)
 | 
			
		||||
 | 
			
		||||
	> p
 | 
			
		||||
		margin 0 0 8px 0
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
<a class="a" href="https://github.com/syuilo/misskey" target="_blank" title="View source on Github">
 | 
			
		||||
<a class="a" href="https://github.com/syuilo/misskey" target="_blank" title="View source on GitHub">
 | 
			
		||||
	<svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="aria-hidden">
 | 
			
		||||
		<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
 | 
			
		||||
		<path class="octo-arm" d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor"></path>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										63
									
								
								src/client/app/common/views/components/github-setting.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/client/app/common/views/components/github-setting.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-github-setting">
 | 
			
		||||
	<p>%i18n:@description%<a :href="`${docsUrl}/link-to-github`" target="_blank">%i18n:@detail%</a></p>
 | 
			
		||||
	<p class="account" v-if="$store.state.i.github" :title="`GitHub ID: ${$store.state.i.github.id}`">%i18n:@connected-to%: <a :href="`https://github.com/${$store.state.i.github.login}`" target="_blank">@{{ $store.state.i.github.login }}</a></p>
 | 
			
		||||
	<p>
 | 
			
		||||
		<a :href="`${apiUrl}/connect/github`" target="_blank" @click.prevent="connect">{{ $store.state.i.github ? '%i18n:@reconnect%' : '%i18n:@connect%' }}</a>
 | 
			
		||||
		<span v-if="$store.state.i.github"> or </span>
 | 
			
		||||
		<a :href="`${apiUrl}/disconnect/github`" target="_blank" v-if="$store.state.i.github" @click.prevent="disconnect">%i18n:@disconnect%</a>
 | 
			
		||||
	</p>
 | 
			
		||||
	<p class="id" v-if="$store.state.i.github">GitHub ID: {{ $store.state.i.github.id }}</p>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import { apiUrl, docsUrl } from '../../../config';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			form: null,
 | 
			
		||||
			apiUrl,
 | 
			
		||||
			docsUrl
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.$watch('$store.state.i', () => {
 | 
			
		||||
			if (this.$store.state.i.github && this.form)
 | 
			
		||||
				this.form.close();
 | 
			
		||||
		}, {
 | 
			
		||||
			deep: true
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		connect() {
 | 
			
		||||
			this.form = window.open(apiUrl + '/connect/github',
 | 
			
		||||
				'github_connect_window',
 | 
			
		||||
				'height=570, width=520');
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		disconnect() {
 | 
			
		||||
			window.open(apiUrl + '/disconnect/github',
 | 
			
		||||
				'github_disconnect_window',
 | 
			
		||||
				'height=570, width=520');
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.mk-github-setting
 | 
			
		||||
	.account
 | 
			
		||||
		border solid 1px #e1e8ed
 | 
			
		||||
		border-radius 4px
 | 
			
		||||
		padding 16px
 | 
			
		||||
 | 
			
		||||
		a
 | 
			
		||||
			font-weight bold
 | 
			
		||||
			color inherit
 | 
			
		||||
 | 
			
		||||
	.id
 | 
			
		||||
		color #8899a6
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,5 +1,10 @@
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
import muteAndBlock from './mute-and-block.vue';
 | 
			
		||||
import error from './error.vue';
 | 
			
		||||
import apiSettings from './api-settings.vue';
 | 
			
		||||
import passwordSettings from './password-settings.vue';
 | 
			
		||||
import driveSettings from './drive-settings.vue';
 | 
			
		||||
import profileEditor from './profile-editor.vue';
 | 
			
		||||
import noteSkeleton from './note-skeleton.vue';
 | 
			
		||||
import theme from './theme.vue';
 | 
			
		||||
@@ -32,20 +37,28 @@ import messaging from './messaging.vue';
 | 
			
		||||
import messagingRoom from './messaging-room.vue';
 | 
			
		||||
import urlPreview from './url-preview.vue';
 | 
			
		||||
import twitterSetting from './twitter-setting.vue';
 | 
			
		||||
import githubSetting from './github-setting.vue';
 | 
			
		||||
import fileTypeIcon from './file-type-icon.vue';
 | 
			
		||||
import Reversi from './games/reversi/reversi.vue';
 | 
			
		||||
import welcomeTimeline from './welcome-timeline.vue';
 | 
			
		||||
import uiInput from './ui/input.vue';
 | 
			
		||||
import uiButton from './ui/button.vue';
 | 
			
		||||
import uiHorizonGroup from './ui/horizon-group.vue';
 | 
			
		||||
import uiCard from './ui/card.vue';
 | 
			
		||||
import uiForm from './ui/form.vue';
 | 
			
		||||
import uiTextarea from './ui/textarea.vue';
 | 
			
		||||
import uiSwitch from './ui/switch.vue';
 | 
			
		||||
import uiRadio from './ui/radio.vue';
 | 
			
		||||
import uiSelect from './ui/select.vue';
 | 
			
		||||
import uiInfo from './ui/info.vue';
 | 
			
		||||
import formButton from './ui/form/button.vue';
 | 
			
		||||
import formRadio from './ui/form/radio.vue';
 | 
			
		||||
 | 
			
		||||
Vue.component('mk-mute-and-block', muteAndBlock);
 | 
			
		||||
Vue.component('mk-error', error);
 | 
			
		||||
Vue.component('mk-api-settings', apiSettings);
 | 
			
		||||
Vue.component('mk-password-settings', passwordSettings);
 | 
			
		||||
Vue.component('mk-drive-settings', driveSettings);
 | 
			
		||||
Vue.component('mk-profile-editor', profileEditor);
 | 
			
		||||
Vue.component('mk-note-skeleton', noteSkeleton);
 | 
			
		||||
Vue.component('mk-theme', theme);
 | 
			
		||||
@@ -78,16 +91,19 @@ Vue.component('mk-messaging', messaging);
 | 
			
		||||
Vue.component('mk-messaging-room', messagingRoom);
 | 
			
		||||
Vue.component('mk-url-preview', urlPreview);
 | 
			
		||||
Vue.component('mk-twitter-setting', twitterSetting);
 | 
			
		||||
Vue.component('mk-github-setting', githubSetting);
 | 
			
		||||
Vue.component('mk-file-type-icon', fileTypeIcon);
 | 
			
		||||
Vue.component('mk-reversi', Reversi);
 | 
			
		||||
Vue.component('mk-welcome-timeline', welcomeTimeline);
 | 
			
		||||
Vue.component('ui-input', uiInput);
 | 
			
		||||
Vue.component('ui-button', uiButton);
 | 
			
		||||
Vue.component('ui-horizon-group', uiHorizonGroup);
 | 
			
		||||
Vue.component('ui-card', uiCard);
 | 
			
		||||
Vue.component('ui-form', uiForm);
 | 
			
		||||
Vue.component('ui-textarea', uiTextarea);
 | 
			
		||||
Vue.component('ui-switch', uiSwitch);
 | 
			
		||||
Vue.component('ui-radio', uiRadio);
 | 
			
		||||
Vue.component('ui-select', uiSelect);
 | 
			
		||||
Vue.component('ui-info', uiInfo);
 | 
			
		||||
Vue.component('form-button', formButton);
 | 
			
		||||
Vue.component('form-radio', formRadio);
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,6 @@ import * as emojilib from 'emojilib';
 | 
			
		||||
import { length } from 'stringz';
 | 
			
		||||
import parse from '../../../../../mfm/parse';
 | 
			
		||||
import getAcct from '../../../../../misc/acct/render';
 | 
			
		||||
import { url } from '../../../config';
 | 
			
		||||
import MkUrl from './url.vue';
 | 
			
		||||
import MkGoogle from './google.vue';
 | 
			
		||||
import { concat } from '../../../../../prelude/array';
 | 
			
		||||
@@ -25,6 +24,9 @@ export default Vue.component('misskey-flavored-markdown', {
 | 
			
		||||
		i: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
			default: null
 | 
			
		||||
		},
 | 
			
		||||
		customEmojis: {
 | 
			
		||||
			required: false,
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
@@ -186,6 +188,22 @@ export default Vue.component('misskey-flavored-markdown', {
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				case 'emoji': {
 | 
			
		||||
					//#region カスタム絵文字
 | 
			
		||||
					if (this.customEmojis != null) {
 | 
			
		||||
						const customEmoji = this.customEmojis.find(e => e.name == token.emoji || (e.aliases || []).includes(token.emoji));
 | 
			
		||||
						if (customEmoji) {
 | 
			
		||||
							return [createElement('img', {
 | 
			
		||||
								attrs: {
 | 
			
		||||
									src: customEmoji.url,
 | 
			
		||||
									alt: token.emoji,
 | 
			
		||||
									title: token.emoji,
 | 
			
		||||
									style: 'height: 2.5em; vertical-align: middle;'
 | 
			
		||||
								}
 | 
			
		||||
							})];
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					//#endregion
 | 
			
		||||
 | 
			
		||||
					const emoji = emojilib.lib[token.emoji];
 | 
			
		||||
					return [createElement('span', emoji ? emoji.char : token.content)];
 | 
			
		||||
				}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								src/client/app/common/views/components/mute-and-block.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/client/app/common/views/components/mute-and-block.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
<template>
 | 
			
		||||
<ui-card>
 | 
			
		||||
	<div slot="title">%fa:ban% %i18n:@mute-and-block%</div>
 | 
			
		||||
 | 
			
		||||
	<section>
 | 
			
		||||
		<header>%i18n:@mute%</header>
 | 
			
		||||
		<ui-info v-if="!muteFetching && mute.length == 0">%i18n:@no-muted-users%</ui-info>
 | 
			
		||||
		<div class="users" v-if="mute.length != 0">
 | 
			
		||||
			<div v-for="user in mute" :key="user.id">
 | 
			
		||||
				<p><b>{{ user | userName }}</b> @{{ user | acct }}</p>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
 | 
			
		||||
	<section>
 | 
			
		||||
		<header>%i18n:@block%</header>
 | 
			
		||||
		<ui-info v-if="!blockFetching && block.length == 0">%i18n:@no-blocked-users%</ui-info>
 | 
			
		||||
		<div class="users" v-if="block.length != 0">
 | 
			
		||||
			<div v-for="user in block" :key="user.id">
 | 
			
		||||
				<p><b>{{ user | userName }}</b> @{{ user | acct }}</p>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</section>
 | 
			
		||||
</ui-card>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			muteFetching: true,
 | 
			
		||||
			blockFetching: true,
 | 
			
		||||
			mute: [],
 | 
			
		||||
			block: []
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	mounted() {
 | 
			
		||||
		(this as any).api('mute/list').then(mute => {
 | 
			
		||||
			this.mute = mute.map(x => x.mutee);
 | 
			
		||||
			this.muteFetching = false;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		(this as any).api('blocking/list').then(blocking => {
 | 
			
		||||
			this.block = blocking.map(x => x.blockee);
 | 
			
		||||
			this.blockFetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
@@ -2,8 +2,6 @@
 | 
			
		||||
<span class="mk-nav">
 | 
			
		||||
	<a :href="aboutUrl">%i18n:@about%</a>
 | 
			
		||||
	<i>・</i>
 | 
			
		||||
	<a href="/stats">%i18n:@stats%</a>
 | 
			
		||||
	<i>・</i>
 | 
			
		||||
	<a :href="repositoryUrl">%i18n:@repository%</a>
 | 
			
		||||
	<i>・</i>
 | 
			
		||||
	<a :href="feedbackUrl" target="_blank">%i18n:@feedback%</a>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,11 @@
 | 
			
		||||
<header class="bvonvjxbwzaiskogyhbwgyxvcgserpmu">
 | 
			
		||||
	<mk-avatar class="avatar" :user="note.user" v-if="$store.state.device.postStyle == 'smart'"/>
 | 
			
		||||
	<router-link class="name" :to="note.user | userPage" v-user-preview="note.user.id">{{ note.user | userName }}</router-link>
 | 
			
		||||
	<span class="is-verified" v-if="note.user.isVerified" title="%i18n:common.verified-user%">%fa:star%</span>
 | 
			
		||||
	<span class="is-admin" v-if="note.user.isAdmin">admin</span>
 | 
			
		||||
	<span class="is-bot" v-if="note.user.isBot">bot</span>
 | 
			
		||||
	<span class="is-cat" v-if="note.user.isCat">cat</span>
 | 
			
		||||
	<span class="username"><mk-acct :user="note.user"/></span>
 | 
			
		||||
	<span class="is-verified" v-if="note.user.isVerified" title="%i18n:common.verified-user%">%fa:star%</span>
 | 
			
		||||
	<div class="info">
 | 
			
		||||
		<span class="app" v-if="note.app && !mini">via <b>{{ note.app.name }}</b></span>
 | 
			
		||||
		<span class="mobile" v-if="note.viaMobile">%fa:mobile-alt%</span>
 | 
			
		||||
@@ -68,10 +68,6 @@ export default Vue.extend({
 | 
			
		||||
		&:hover
 | 
			
		||||
			text-decoration underline
 | 
			
		||||
 | 
			
		||||
	> .is-verified
 | 
			
		||||
		margin-right 8px
 | 
			
		||||
		color #4dabf7
 | 
			
		||||
 | 
			
		||||
	> .is-admin
 | 
			
		||||
	> .is-bot
 | 
			
		||||
	> .is-cat
 | 
			
		||||
@@ -95,6 +91,10 @@ export default Vue.extend({
 | 
			
		||||
		color var(--noteHeaderAcct)
 | 
			
		||||
		flex-shrink 2147483647
 | 
			
		||||
 | 
			
		||||
	> .is-verified
 | 
			
		||||
		margin 0 .5em 0 0
 | 
			
		||||
		color #4dabf7
 | 
			
		||||
 | 
			
		||||
	> .info
 | 
			
		||||
		margin-left auto
 | 
			
		||||
		font-size 0.9em
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
	<ui-input v-if="user && user.twoFactorEnabled" v-model="token" type="number" required styl="fill"/>
 | 
			
		||||
	<ui-button type="submit" :disabled="signing">{{ signing ? '%i18n:@signing-in%' : '%i18n:@signin%' }}</ui-button>
 | 
			
		||||
	<p style="margin: 8px 0;">%i18n:@or% <a :href="`${apiUrl}/signin/twitter`">%i18n:@signin-with-twitter%</a></p>
 | 
			
		||||
	<p style="margin: 8px 0;">%i18n:@or% <a :href="`${apiUrl}/signin/github`">%i18n:@signin-with-github%</a></p>
 | 
			
		||||
</form>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,10 @@
 | 
			
		||||
<template>
 | 
			
		||||
<component class="dmtdnykelhudezerjlfpbhgovrgnqqgr" :is="link ? 'a' : 'button'" :class="[styl, { inline, primary }]" :type="type" @click="$emit('click')">
 | 
			
		||||
<component class="dmtdnykelhudezerjlfpbhgovrgnqqgr"
 | 
			
		||||
	:is="link ? 'a' : 'button'"
 | 
			
		||||
	:class="[styl, { inline, primary }]"
 | 
			
		||||
	:type="type"
 | 
			
		||||
	@click="$emit('click')"
 | 
			
		||||
>
 | 
			
		||||
	<slot></slot>
 | 
			
		||||
</component>
 | 
			
		||||
</template>
 | 
			
		||||
@@ -7,6 +12,7 @@
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	inject: ['horizonGrouped'],
 | 
			
		||||
	props: {
 | 
			
		||||
		type: {
 | 
			
		||||
			type: String,
 | 
			
		||||
@@ -20,7 +26,9 @@ export default Vue.extend({
 | 
			
		||||
		inline: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false
 | 
			
		||||
			default(): boolean {
 | 
			
		||||
				return this.horizonGrouped;
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		link: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								src/client/app/common/views/components/ui/horizon-group.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/client/app/common/views/components/ui/horizon-group.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="pfzekjfwkwvadvlujpdnnxfggqgqjoze" :class="{ inputs }">
 | 
			
		||||
	<slot></slot>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	provide: {
 | 
			
		||||
		horizonGrouped: true
 | 
			
		||||
	},
 | 
			
		||||
	props: {
 | 
			
		||||
		inputs: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.pfzekjfwkwvadvlujpdnnxfggqgqjoze
 | 
			
		||||
	display flex
 | 
			
		||||
 | 
			
		||||
	&.inputs
 | 
			
		||||
		margin 32px 0
 | 
			
		||||
 | 
			
		||||
	> *
 | 
			
		||||
		flex 1
 | 
			
		||||
 | 
			
		||||
		&:not(:last-child)
 | 
			
		||||
			margin-right 16px
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										43
									
								
								src/client/app/common/views/components/ui/info.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/client/app/common/views/components/ui/info.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="ymxyweixqwsxauxldgpvecjepnwxbylu" :class="{ warn }">
 | 
			
		||||
	<i v-if="warn">%fa:exclamation-triangle%</i>
 | 
			
		||||
	<i v-else>%fa:info-circle%</i>
 | 
			
		||||
	<slot></slot>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: {
 | 
			
		||||
		warn: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.ymxyweixqwsxauxldgpvecjepnwxbylu
 | 
			
		||||
	margin 16px 0
 | 
			
		||||
	padding 16px
 | 
			
		||||
	font-size 90%
 | 
			
		||||
	background var(--infoBg)
 | 
			
		||||
	color var(--infoFg)
 | 
			
		||||
 | 
			
		||||
	&.warn
 | 
			
		||||
		background var(--infoWarnBg)
 | 
			
		||||
		color var(--infoWarnFg)
 | 
			
		||||
 | 
			
		||||
	&:first-child
 | 
			
		||||
		margin-top 0
 | 
			
		||||
 | 
			
		||||
	&:last-child
 | 
			
		||||
		margin-bottom 0
 | 
			
		||||
 | 
			
		||||
	> i
 | 
			
		||||
		margin-right 4px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="ui-input" :class="[{ focused, filled }, styl]">
 | 
			
		||||
<div class="ui-input" :class="[{ focused, filled, inline }, styl]">
 | 
			
		||||
	<div class="icon" ref="icon"><slot name="icon"></slot></div>
 | 
			
		||||
	<div class="input">
 | 
			
		||||
		<div class="password-meter" v-if="withPasswordMeter" v-show="passwordStrength != ''" :data-strength="passwordStrength">
 | 
			
		||||
@@ -41,6 +41,7 @@ import Vue from 'vue';
 | 
			
		||||
const getPasswordStrength = require('syuilo-password-strength');
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	inject: ['horizonGrouped'],
 | 
			
		||||
	props: {
 | 
			
		||||
		value: {
 | 
			
		||||
			required: false
 | 
			
		||||
@@ -72,6 +73,13 @@ export default Vue.extend({
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false
 | 
			
		||||
		},
 | 
			
		||||
		inline: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default(): boolean {
 | 
			
		||||
				return this.horizonGrouped;
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		styl: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			required: false,
 | 
			
		||||
@@ -337,4 +345,8 @@ root(fill)
 | 
			
		||||
	&:not(.fill)
 | 
			
		||||
		root(false)
 | 
			
		||||
 | 
			
		||||
	&.inline
 | 
			
		||||
		display inline-block
 | 
			
		||||
		margin 0
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,17 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="ui-textarea" :class="{ focused, filled }">
 | 
			
		||||
<div class="ui-textarea" :class="{ focused, filled, tall }">
 | 
			
		||||
	<div class="input">
 | 
			
		||||
		<span class="label" ref="label"><slot></slot></span>
 | 
			
		||||
		<textarea ref="input"
 | 
			
		||||
				:value="value"
 | 
			
		||||
				:required="required"
 | 
			
		||||
				:readonly="readonly"
 | 
			
		||||
				:pattern="pattern"
 | 
			
		||||
				:autocomplete="autocomplete"
 | 
			
		||||
				@input="$emit('input', $event.target.value)"
 | 
			
		||||
				@focus="focused = true"
 | 
			
		||||
				@blur="focused = false">
 | 
			
		||||
		</textarea>
 | 
			
		||||
			:value="value"
 | 
			
		||||
			:required="required"
 | 
			
		||||
			:readonly="readonly"
 | 
			
		||||
			:pattern="pattern"
 | 
			
		||||
			:autocomplete="autocomplete"
 | 
			
		||||
			@input="$emit('input', $event.target.value)"
 | 
			
		||||
			@focus="focused = true"
 | 
			
		||||
			@blur="focused = false"
 | 
			
		||||
		></textarea>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="text"><slot name="text"></slot></div>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -41,7 +41,12 @@ export default Vue.extend({
 | 
			
		||||
		autocomplete: {
 | 
			
		||||
			type: String,
 | 
			
		||||
			required: false
 | 
			
		||||
		}
 | 
			
		||||
		},
 | 
			
		||||
		tall: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
			required: false,
 | 
			
		||||
			default: false
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
@@ -66,6 +71,9 @@ export default Vue.extend({
 | 
			
		||||
root(fill)
 | 
			
		||||
	margin 42px 0 32px 0
 | 
			
		||||
 | 
			
		||||
	&:last-child
 | 
			
		||||
		margin-bottom 0
 | 
			
		||||
 | 
			
		||||
	> .input
 | 
			
		||||
		padding 12px
 | 
			
		||||
 | 
			
		||||
@@ -157,6 +165,11 @@ root(fill)
 | 
			
		||||
				left 0 !important
 | 
			
		||||
				transform scale(0.75)
 | 
			
		||||
 | 
			
		||||
	&.tall
 | 
			
		||||
		> .input
 | 
			
		||||
			> textarea
 | 
			
		||||
				min-height 200px
 | 
			
		||||
 | 
			
		||||
.ui-textarea.fill
 | 
			
		||||
	root(true)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
					</div>
 | 
			
		||||
				</header>
 | 
			
		||||
				<div class="text">
 | 
			
		||||
					<misskey-flavored-markdown v-if="note.text" :text="note.text"/>
 | 
			
		||||
					<misskey-flavored-markdown v-if="note.text" :text="note.text" :customEmojis="note.emojis"/>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -222,13 +222,15 @@ class Autocomplete {
 | 
			
		||||
			const trimmedBefore = before.substring(0, before.lastIndexOf(':'));
 | 
			
		||||
			const after = source.substr(caret);
 | 
			
		||||
 | 
			
		||||
			if (value.startsWith(':')) value = value + ' ';
 | 
			
		||||
 | 
			
		||||
			// 挿入
 | 
			
		||||
			this.text = trimmedBefore + value + after;
 | 
			
		||||
 | 
			
		||||
			// キャレットを戻す
 | 
			
		||||
			this.vm.$nextTick(() => {
 | 
			
		||||
				this.textarea.focus();
 | 
			
		||||
				const pos = trimmedBefore.length + 1;
 | 
			
		||||
				const pos = trimmedBefore.length + (value.startsWith(':') ? value.length : 1);
 | 
			
		||||
				this.textarea.setSelectionRange(pos, pos);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
Vue.filter('bytes', (v, digits = 0) => {
 | 
			
		||||
	if (v == null) return '?';
 | 
			
		||||
	const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
 | 
			
		||||
	if (v == 0) return '0';
 | 
			
		||||
	const isMinus = v < 0;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
Vue.filter('number', (n) => {
 | 
			
		||||
	if (n == null) return 'N/A';
 | 
			
		||||
	return n.toLocaleString();
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { version, codename } from '../../../config';
 | 
			
		||||
import { clientVersion as version, codename } from '../../../config';
 | 
			
		||||
import define from '../../../common/define-widget';
 | 
			
		||||
export default define({
 | 
			
		||||
	name: 'version'
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ declare const _LANGS_: string;
 | 
			
		||||
declare const _THEME_COLOR_: string;
 | 
			
		||||
declare const _COPYRIGHT_: string;
 | 
			
		||||
declare const _VERSION_: string;
 | 
			
		||||
declare const _CLIENT_VERSION_: string;
 | 
			
		||||
declare const _CODENAME_: string;
 | 
			
		||||
declare const _ENV_: string;
 | 
			
		||||
 | 
			
		||||
@@ -18,5 +19,6 @@ export const langs = _LANGS_;
 | 
			
		||||
export const themeColor = _THEME_COLOR_;
 | 
			
		||||
export const copyright = _COPYRIGHT_;
 | 
			
		||||
export const version = _VERSION_;
 | 
			
		||||
export const clientVersion = _CLIENT_VERSION_;
 | 
			
		||||
export const codename = _CODENAME_;
 | 
			
		||||
export const env = _ENV_;
 | 
			
		||||
 
 | 
			
		||||
@@ -23,8 +23,6 @@ import updateBanner from './api/update-banner';
 | 
			
		||||
import MkIndex from './views/pages/index.vue';
 | 
			
		||||
import MkHome from './views/pages/home.vue';
 | 
			
		||||
import MkDeck from './views/pages/deck/deck.vue';
 | 
			
		||||
import MkAdmin from './views/pages/admin/admin.vue';
 | 
			
		||||
import MkStats from './views/pages/stats/stats.vue';
 | 
			
		||||
import MkUser from './views/pages/user/user.vue';
 | 
			
		||||
import MkFavorites from './views/pages/favorites.vue';
 | 
			
		||||
import MkSelectDrive from './views/pages/selectdrive.vue';
 | 
			
		||||
@@ -57,8 +55,6 @@ init(async (launch) => {
 | 
			
		||||
			{ path: '/', name: 'index', component: MkIndex },
 | 
			
		||||
			{ path: '/home', name: 'home', component: MkHome },
 | 
			
		||||
			{ path: '/deck', name: 'deck', component: MkDeck },
 | 
			
		||||
			{ path: '/admin', name: 'admin', component: MkAdmin },
 | 
			
		||||
			{ path: '/stats', name: 'stats', component: MkStats },
 | 
			
		||||
			{ path: '/i/customize-home', component: MkHomeCustomize },
 | 
			
		||||
			{ path: '/i/favorites', component: MkFavorites },
 | 
			
		||||
			{ path: '/i/messaging/:user', component: MkMessagingRoom },
 | 
			
		||||
 
 | 
			
		||||
@@ -32,9 +32,21 @@ export default Vue.extend({
 | 
			
		||||
		this.data.forEach(d => d.total = d.notes + d.replies + d.renotes);
 | 
			
		||||
		const peak = Math.max.apply(null, this.data.map(d => d.total));
 | 
			
		||||
 | 
			
		||||
		const now = new Date();
 | 
			
		||||
		const year = now.getFullYear();
 | 
			
		||||
		const month = now.getMonth();
 | 
			
		||||
		const day = now.getDate();
 | 
			
		||||
 | 
			
		||||
		let x = 0;
 | 
			
		||||
		this.data.slice().reverse().forEach(d => {
 | 
			
		||||
		this.data.slice().reverse().forEach((d, i) => {
 | 
			
		||||
			d.x = x;
 | 
			
		||||
 | 
			
		||||
			const date = new Date(year, month, day - i);
 | 
			
		||||
			d.date = {
 | 
			
		||||
				year: date.getFullYear(),
 | 
			
		||||
				month: date.getMonth(),
 | 
			
		||||
				day: date.getDate()
 | 
			
		||||
			};
 | 
			
		||||
			d.date.weekday = (new Date(d.date.year, d.date.month - 1, d.date.day)).getDay();
 | 
			
		||||
 | 
			
		||||
			d.v = peak == 0 ? 0 : d.total / (peak / 2);
 | 
			
		||||
 
 | 
			
		||||
@@ -43,11 +43,17 @@ export default Vue.extend({
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		(this as any).api('aggregation/users/activity', {
 | 
			
		||||
		(this as any).api('charts/user/notes', {
 | 
			
		||||
			userId: this.user.id,
 | 
			
		||||
			limit: 20 * 7
 | 
			
		||||
			span: 'day',
 | 
			
		||||
			limit: 7 * 20
 | 
			
		||||
		}).then(activity => {
 | 
			
		||||
			this.activity = activity;
 | 
			
		||||
			this.activity = activity.diffs.normal.map((_, i) => ({
 | 
			
		||||
				total: activity.diffs.normal[i] + activity.diffs.reply[i] + activity.diffs.renote[i],
 | 
			
		||||
				notes: activity.diffs.normal[i],
 | 
			
		||||
				replies: activity.diffs.reply[i],
 | 
			
		||||
				renotes: activity.diffs.renote[i]
 | 
			
		||||
			}));
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import { Line } from 'vue-chartjs';
 | 
			
		||||
import * as mergeOptions from 'merge-options';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	extends: Line,
 | 
			
		||||
	props: {
 | 
			
		||||
		data: {
 | 
			
		||||
			required: true
 | 
			
		||||
		},
 | 
			
		||||
		opts: {
 | 
			
		||||
			required: false
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	watch: {
 | 
			
		||||
		data() {
 | 
			
		||||
			this.render();
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.render();
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		render() {
 | 
			
		||||
			this.renderChart(this.data, mergeOptions({
 | 
			
		||||
				responsive: true,
 | 
			
		||||
				maintainAspectRatio: false,
 | 
			
		||||
				scales: {
 | 
			
		||||
					xAxes: [{
 | 
			
		||||
						type: 'time',
 | 
			
		||||
						distribution: 'series'
 | 
			
		||||
					}]
 | 
			
		||||
				},
 | 
			
		||||
				tooltips: {
 | 
			
		||||
					intersect: false,
 | 
			
		||||
					mode: 'index',
 | 
			
		||||
					position: 'nearest'
 | 
			
		||||
				}
 | 
			
		||||
			}, this.opts || {}));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
@@ -1,696 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="gkgckalzgidaygcxnugepioremxvxvpt">
 | 
			
		||||
	<header>
 | 
			
		||||
		<b>%i18n:@title%:</b>
 | 
			
		||||
		<select v-model="chartType">
 | 
			
		||||
			<optgroup label="%i18n:@users%">
 | 
			
		||||
				<option value="users">%i18n:@charts.users%</option>
 | 
			
		||||
				<option value="users-total">%i18n:@charts.users-total%</option>
 | 
			
		||||
			</optgroup>
 | 
			
		||||
			<optgroup label="%i18n:@notes%">
 | 
			
		||||
				<option value="notes">%i18n:@charts.notes%</option>
 | 
			
		||||
				<option value="local-notes">%i18n:@charts.local-notes%</option>
 | 
			
		||||
				<option value="remote-notes">%i18n:@charts.remote-notes%</option>
 | 
			
		||||
				<option value="notes-total">%i18n:@charts.notes-total%</option>
 | 
			
		||||
			</optgroup>
 | 
			
		||||
			<optgroup label="%i18n:@drive%">
 | 
			
		||||
				<option value="drive-files">%i18n:@charts.drive-files%</option>
 | 
			
		||||
				<option value="drive-files-total">%i18n:@charts.drive-files-total%</option>
 | 
			
		||||
				<option value="drive">%i18n:@charts.drive%</option>
 | 
			
		||||
				<option value="drive-total">%i18n:@charts.drive-total%</option>
 | 
			
		||||
			</optgroup>
 | 
			
		||||
			<optgroup label="%i18n:@network%">
 | 
			
		||||
				<option value="network-requests">%i18n:@charts.network-requests%</option>
 | 
			
		||||
				<option value="network-time">%i18n:@charts.network-time%</option>
 | 
			
		||||
				<option value="network-usage">%i18n:@charts.network-usage%</option>
 | 
			
		||||
			</optgroup>
 | 
			
		||||
		</select>
 | 
			
		||||
		<div>
 | 
			
		||||
			<span @click="span = 'day'" :class="{ active: span == 'day' }">%i18n:@per-day%</span> | <span @click="span = 'hour'" :class="{ active: span == 'hour' }">%i18n:@per-hour%</span>
 | 
			
		||||
		</div>
 | 
			
		||||
	</header>
 | 
			
		||||
	<div>
 | 
			
		||||
		<x-chart v-if="chart" :data="data[0]" :opts="data[1]"/>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import XChart from './charts.chart.ts';
 | 
			
		||||
 | 
			
		||||
const colors = {
 | 
			
		||||
	local: 'rgb(246, 88, 79)',
 | 
			
		||||
	remote: 'rgb(65, 221, 222)',
 | 
			
		||||
 | 
			
		||||
	localPlus: 'rgb(52, 178, 118)',
 | 
			
		||||
	remotePlus: 'rgb(158, 255, 209)',
 | 
			
		||||
	localMinus: 'rgb(255, 97, 74)',
 | 
			
		||||
	remoteMinus: 'rgb(255, 149, 134)',
 | 
			
		||||
 | 
			
		||||
	incoming: 'rgb(52, 178, 118)',
 | 
			
		||||
	outgoing: 'rgb(255, 97, 74)',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const rgba = (color: string): string => {
 | 
			
		||||
	return color.replace('rgb', 'rgba').replace(')', ', 0.1)');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const limit = 35;
 | 
			
		||||
 | 
			
		||||
const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b));
 | 
			
		||||
const negate = arr => arr.map(x => -x);
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	components: {
 | 
			
		||||
		XChart
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			now: null,
 | 
			
		||||
			chart: null,
 | 
			
		||||
			chartType: 'notes',
 | 
			
		||||
			span: 'hour'
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	computed: {
 | 
			
		||||
		data(): any {
 | 
			
		||||
			if (this.chart == null) return null;
 | 
			
		||||
			switch (this.chartType) {
 | 
			
		||||
				case 'users': return this.usersChart(false);
 | 
			
		||||
				case 'users-total': return this.usersChart(true);
 | 
			
		||||
				case 'notes': return this.notesChart('combined');
 | 
			
		||||
				case 'local-notes': return this.notesChart('local');
 | 
			
		||||
				case 'remote-notes': return this.notesChart('remote');
 | 
			
		||||
				case 'notes-total': return this.notesTotalChart();
 | 
			
		||||
				case 'drive': return this.driveChart();
 | 
			
		||||
				case 'drive-total': return this.driveTotalChart();
 | 
			
		||||
				case 'drive-files': return this.driveFilesChart();
 | 
			
		||||
				case 'drive-files-total': return this.driveFilesTotalChart();
 | 
			
		||||
				case 'network-requests': return this.networkRequestsChart();
 | 
			
		||||
				case 'network-time': return this.networkTimeChart();
 | 
			
		||||
				case 'network-usage': return this.networkUsageChart();
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		stats(): any[] {
 | 
			
		||||
			const stats =
 | 
			
		||||
				this.span == 'day' ? this.chart.perDay :
 | 
			
		||||
				this.span == 'hour' ? this.chart.perHour :
 | 
			
		||||
				null;
 | 
			
		||||
 | 
			
		||||
			return stats;
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	async created() {
 | 
			
		||||
		this.now = new Date();
 | 
			
		||||
 | 
			
		||||
		const [perHour, perDay] = await Promise.all([Promise.all([
 | 
			
		||||
			(this as any).api('charts/users', { limit: limit, span: 'hour' }),
 | 
			
		||||
			(this as any).api('charts/notes', { limit: limit, span: 'hour' }),
 | 
			
		||||
			(this as any).api('charts/drive', { limit: limit, span: 'hour' }),
 | 
			
		||||
			(this as any).api('charts/network', { limit: limit, span: 'hour' })
 | 
			
		||||
		]), Promise.all([
 | 
			
		||||
			(this as any).api('charts/users', { limit: limit, span: 'day' }),
 | 
			
		||||
			(this as any).api('charts/notes', { limit: limit, span: 'day' }),
 | 
			
		||||
			(this as any).api('charts/drive', { limit: limit, span: 'day' }),
 | 
			
		||||
			(this as any).api('charts/network', { limit: limit, span: 'day' })
 | 
			
		||||
		])]);
 | 
			
		||||
 | 
			
		||||
		const chart = {
 | 
			
		||||
			perHour: {
 | 
			
		||||
				users: perHour[0],
 | 
			
		||||
				notes: perHour[1],
 | 
			
		||||
				drive: perHour[2],
 | 
			
		||||
				network: perHour[3]
 | 
			
		||||
			},
 | 
			
		||||
			perDay: {
 | 
			
		||||
				users: perDay[0],
 | 
			
		||||
				notes: perDay[1],
 | 
			
		||||
				drive: perDay[2],
 | 
			
		||||
				network: perDay[3]
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		this.chart = chart;
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		getDate(i: number) {
 | 
			
		||||
			const y = this.now.getFullYear();
 | 
			
		||||
			const m = this.now.getMonth();
 | 
			
		||||
			const d = this.now.getDate();
 | 
			
		||||
			const h = this.now.getHours();
 | 
			
		||||
 | 
			
		||||
			return (
 | 
			
		||||
				this.span == 'day' ? new Date(y, m, d - i) :
 | 
			
		||||
				this.span == 'hour' ? new Date(y, m, d, h - i) :
 | 
			
		||||
				null
 | 
			
		||||
			);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		format(arr) {
 | 
			
		||||
			return arr.map((v, i) => ({ t: this.getDate(i).getTime(), y: v }));
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		notesChart(type: string): any {
 | 
			
		||||
			return [{
 | 
			
		||||
				datasets: [{
 | 
			
		||||
					label: 'All',
 | 
			
		||||
					fill: false,
 | 
			
		||||
					borderColor: '#555',
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					borderDash: [4, 4],
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(type == 'combined'
 | 
			
		||||
						? sum(this.stats.notes.local.inc, negate(this.stats.notes.local.dec), this.stats.notes.remote.inc, negate(this.stats.notes.remote.dec))
 | 
			
		||||
						: sum(this.stats.notes[type].inc, negate(this.stats.notes[type].dec))
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Renotes',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: 'rgba(161, 222, 65, 0.1)',
 | 
			
		||||
					borderColor: '#a1de41',
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(type == 'combined'
 | 
			
		||||
						? sum(this.stats.notes.local.diffs.renote, this.stats.notes.remote.diffs.renote)
 | 
			
		||||
						: this.stats.notes[type].diffs.renote
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Replies',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: 'rgba(247, 121, 108, 0.1)',
 | 
			
		||||
					borderColor: '#f7796c',
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(type == 'combined'
 | 
			
		||||
						? sum(this.stats.notes.local.diffs.reply, this.stats.notes.remote.diffs.reply)
 | 
			
		||||
						: this.stats.notes[type].diffs.reply
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Normal',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: 'rgba(65, 221, 222, 0.1)',
 | 
			
		||||
					borderColor: '#41ddde',
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(type == 'combined'
 | 
			
		||||
						? sum(this.stats.notes.local.diffs.normal, this.stats.notes.remote.diffs.normal)
 | 
			
		||||
						: this.stats.notes[type].diffs.normal
 | 
			
		||||
					)
 | 
			
		||||
				}]
 | 
			
		||||
			}, {
 | 
			
		||||
				scales: {
 | 
			
		||||
					yAxes: [{
 | 
			
		||||
						ticks: {
 | 
			
		||||
							callback: value => {
 | 
			
		||||
								return Vue.filter('number')(value);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}]
 | 
			
		||||
				},
 | 
			
		||||
				tooltips: {
 | 
			
		||||
					callbacks: {
 | 
			
		||||
						label: (tooltipItem, data) => {
 | 
			
		||||
							const label = data.datasets[tooltipItem.datasetIndex].label || '';
 | 
			
		||||
							return `${label}: ${Vue.filter('number')(tooltipItem.yLabel)}`;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}];
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		notesTotalChart(): any {
 | 
			
		||||
			return [{
 | 
			
		||||
				datasets: [{
 | 
			
		||||
					label: 'Combined',
 | 
			
		||||
					fill: false,
 | 
			
		||||
					borderColor: '#555',
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					borderDash: [4, 4],
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(sum(this.stats.notes.local.total, this.stats.notes.remote.total))
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Local',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.local),
 | 
			
		||||
					borderColor: colors.local,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.notes.local.total)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Remote',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.remote),
 | 
			
		||||
					borderColor: colors.remote,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.notes.remote.total)
 | 
			
		||||
				}]
 | 
			
		||||
			}, {
 | 
			
		||||
				scales: {
 | 
			
		||||
					yAxes: [{
 | 
			
		||||
						ticks: {
 | 
			
		||||
							callback: value => {
 | 
			
		||||
								return Vue.filter('number')(value);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}]
 | 
			
		||||
				},
 | 
			
		||||
				tooltips: {
 | 
			
		||||
					callbacks: {
 | 
			
		||||
						label: (tooltipItem, data) => {
 | 
			
		||||
							const label = data.datasets[tooltipItem.datasetIndex].label || '';
 | 
			
		||||
							return `${label}: ${Vue.filter('number')(tooltipItem.yLabel)}`;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}];
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		usersChart(total: boolean): any {
 | 
			
		||||
			return [{
 | 
			
		||||
				datasets: [{
 | 
			
		||||
					label: 'Combined',
 | 
			
		||||
					fill: false,
 | 
			
		||||
					borderColor: '#555',
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					borderDash: [4, 4],
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(total
 | 
			
		||||
						? sum(this.stats.users.local.total, this.stats.users.remote.total)
 | 
			
		||||
						: sum(this.stats.users.local.inc, negate(this.stats.users.local.dec), this.stats.users.remote.inc, negate(this.stats.users.remote.dec))
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Local',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.local),
 | 
			
		||||
					borderColor: colors.local,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(total
 | 
			
		||||
						? this.stats.users.local.total
 | 
			
		||||
						: sum(this.stats.users.local.inc, negate(this.stats.users.local.dec))
 | 
			
		||||
					)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Remote',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.remote),
 | 
			
		||||
					borderColor: colors.remote,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(total
 | 
			
		||||
						? this.stats.users.remote.total
 | 
			
		||||
						: sum(this.stats.users.remote.inc, negate(this.stats.users.remote.dec))
 | 
			
		||||
					)
 | 
			
		||||
				}]
 | 
			
		||||
			}, {
 | 
			
		||||
				scales: {
 | 
			
		||||
					yAxes: [{
 | 
			
		||||
						ticks: {
 | 
			
		||||
							callback: value => {
 | 
			
		||||
								return Vue.filter('number')(value);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}]
 | 
			
		||||
				},
 | 
			
		||||
				tooltips: {
 | 
			
		||||
					callbacks: {
 | 
			
		||||
						label: (tooltipItem, data) => {
 | 
			
		||||
							const label = data.datasets[tooltipItem.datasetIndex].label || '';
 | 
			
		||||
							return `${label}: ${Vue.filter('number')(tooltipItem.yLabel)}`;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}];
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		driveChart(): any {
 | 
			
		||||
			return [{
 | 
			
		||||
				datasets: [{
 | 
			
		||||
					label: 'All',
 | 
			
		||||
					fill: false,
 | 
			
		||||
					borderColor: '#555',
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					borderDash: [4, 4],
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(sum(this.stats.drive.local.incSize, negate(this.stats.drive.local.decSize), this.stats.drive.remote.incSize, negate(this.stats.drive.remote.decSize)))
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Local +',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.localPlus),
 | 
			
		||||
					borderColor: colors.localPlus,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.drive.local.incSize)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Local -',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.localMinus),
 | 
			
		||||
					borderColor: colors.localMinus,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(negate(this.stats.drive.local.decSize))
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Remote +',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.remotePlus),
 | 
			
		||||
					borderColor: colors.remotePlus,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.drive.remote.incSize)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Remote -',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.remoteMinus),
 | 
			
		||||
					borderColor: colors.remoteMinus,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(negate(this.stats.drive.remote.decSize))
 | 
			
		||||
				}]
 | 
			
		||||
			}, {
 | 
			
		||||
				scales: {
 | 
			
		||||
					yAxes: [{
 | 
			
		||||
						ticks: {
 | 
			
		||||
							callback: value => {
 | 
			
		||||
								return Vue.filter('bytes')(value, 1);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}]
 | 
			
		||||
				},
 | 
			
		||||
				tooltips: {
 | 
			
		||||
					callbacks: {
 | 
			
		||||
						label: (tooltipItem, data) => {
 | 
			
		||||
							const label = data.datasets[tooltipItem.datasetIndex].label || '';
 | 
			
		||||
							return `${label}: ${Vue.filter('bytes')(tooltipItem.yLabel, 1)}`;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}];
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		driveTotalChart(): any {
 | 
			
		||||
			return [{
 | 
			
		||||
				datasets: [{
 | 
			
		||||
					label: 'Combined',
 | 
			
		||||
					fill: false,
 | 
			
		||||
					borderColor: '#555',
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					borderDash: [4, 4],
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(sum(this.stats.drive.local.totalSize, this.stats.drive.remote.totalSize))
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Local',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.local),
 | 
			
		||||
					borderColor: colors.local,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.drive.local.totalSize)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Remote',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.remote),
 | 
			
		||||
					borderColor: colors.remote,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.drive.remote.totalSize)
 | 
			
		||||
				}]
 | 
			
		||||
			}, {
 | 
			
		||||
				scales: {
 | 
			
		||||
					yAxes: [{
 | 
			
		||||
						ticks: {
 | 
			
		||||
							callback: value => {
 | 
			
		||||
								return Vue.filter('bytes')(value, 1);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}]
 | 
			
		||||
				},
 | 
			
		||||
				tooltips: {
 | 
			
		||||
					callbacks: {
 | 
			
		||||
						label: (tooltipItem, data) => {
 | 
			
		||||
							const label = data.datasets[tooltipItem.datasetIndex].label || '';
 | 
			
		||||
							return `${label}: ${Vue.filter('bytes')(tooltipItem.yLabel, 1)}`;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}];
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		driveFilesChart(): any {
 | 
			
		||||
			return [{
 | 
			
		||||
				datasets: [{
 | 
			
		||||
					label: 'All',
 | 
			
		||||
					fill: false,
 | 
			
		||||
					borderColor: '#555',
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					borderDash: [4, 4],
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(sum(this.stats.drive.local.incCount, negate(this.stats.drive.local.decCount), this.stats.drive.remote.incCount, negate(this.stats.drive.remote.decCount)))
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Local +',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.localPlus),
 | 
			
		||||
					borderColor: colors.localPlus,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.drive.local.incCount)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Local -',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.localMinus),
 | 
			
		||||
					borderColor: colors.localMinus,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(negate(this.stats.drive.local.decCount))
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Remote +',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.remotePlus),
 | 
			
		||||
					borderColor: colors.remotePlus,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.drive.remote.incCount)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Remote -',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.remoteMinus),
 | 
			
		||||
					borderColor: colors.remoteMinus,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(negate(this.stats.drive.remote.decCount))
 | 
			
		||||
				}]
 | 
			
		||||
			}, {
 | 
			
		||||
				scales: {
 | 
			
		||||
					yAxes: [{
 | 
			
		||||
						ticks: {
 | 
			
		||||
							callback: value => {
 | 
			
		||||
								return Vue.filter('number')(value);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}]
 | 
			
		||||
				},
 | 
			
		||||
				tooltips: {
 | 
			
		||||
					callbacks: {
 | 
			
		||||
						label: (tooltipItem, data) => {
 | 
			
		||||
							const label = data.datasets[tooltipItem.datasetIndex].label || '';
 | 
			
		||||
							return `${label}: ${Vue.filter('number')(tooltipItem.yLabel)}`;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}];
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		driveFilesTotalChart(): any {
 | 
			
		||||
			return [{
 | 
			
		||||
				datasets: [{
 | 
			
		||||
					label: 'Combined',
 | 
			
		||||
					fill: false,
 | 
			
		||||
					borderColor: '#555',
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					borderDash: [4, 4],
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(sum(this.stats.drive.local.totalCount, this.stats.drive.remote.totalCount))
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Local',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.local),
 | 
			
		||||
					borderColor: colors.local,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.drive.local.totalCount)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Remote',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.remote),
 | 
			
		||||
					borderColor: colors.remote,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.drive.remote.totalCount)
 | 
			
		||||
				}]
 | 
			
		||||
			}, {
 | 
			
		||||
				scales: {
 | 
			
		||||
					yAxes: [{
 | 
			
		||||
						ticks: {
 | 
			
		||||
							callback: value => {
 | 
			
		||||
								return Vue.filter('number')(value);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}]
 | 
			
		||||
				},
 | 
			
		||||
				tooltips: {
 | 
			
		||||
					callbacks: {
 | 
			
		||||
						label: (tooltipItem, data) => {
 | 
			
		||||
							const label = data.datasets[tooltipItem.datasetIndex].label || '';
 | 
			
		||||
							return `${label}: ${Vue.filter('number')(tooltipItem.yLabel)}`;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}];
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		networkRequestsChart(): any {
 | 
			
		||||
			return [{
 | 
			
		||||
				datasets: [{
 | 
			
		||||
					label: 'Incoming',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.localPlus),
 | 
			
		||||
					borderColor: colors.localPlus,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.network.incomingRequests)
 | 
			
		||||
				}]
 | 
			
		||||
			}];
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		networkTimeChart(): any {
 | 
			
		||||
			const data = [];
 | 
			
		||||
 | 
			
		||||
			for (let i = 0; i < limit; i++) {
 | 
			
		||||
				data.push(this.stats.network.incomingRequests[i] != 0 ? (this.stats.network.totalTime[i] / this.stats.network.incomingRequests[i]) : 0);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return [{
 | 
			
		||||
				datasets: [{
 | 
			
		||||
					label: 'Avg time (ms)',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.localPlus),
 | 
			
		||||
					borderColor: colors.localPlus,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(data)
 | 
			
		||||
				}]
 | 
			
		||||
			}];
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		networkUsageChart(): any {
 | 
			
		||||
			return [{
 | 
			
		||||
				datasets: [{
 | 
			
		||||
					label: 'Incoming',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.incoming),
 | 
			
		||||
					borderColor: colors.incoming,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.network.incomingBytes)
 | 
			
		||||
				}, {
 | 
			
		||||
					label: 'Outgoing',
 | 
			
		||||
					fill: true,
 | 
			
		||||
					backgroundColor: rgba(colors.outgoing),
 | 
			
		||||
					borderColor: colors.outgoing,
 | 
			
		||||
					borderWidth: 2,
 | 
			
		||||
					pointBackgroundColor: '#fff',
 | 
			
		||||
					lineTension: 0,
 | 
			
		||||
					data: this.format(this.stats.network.outgoingBytes)
 | 
			
		||||
				}]
 | 
			
		||||
			}, {
 | 
			
		||||
				scales: {
 | 
			
		||||
					yAxes: [{
 | 
			
		||||
						ticks: {
 | 
			
		||||
							callback: value => {
 | 
			
		||||
								return Vue.filter('bytes')(value, 1);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}]
 | 
			
		||||
				},
 | 
			
		||||
				tooltips: {
 | 
			
		||||
					callbacks: {
 | 
			
		||||
						label: (tooltipItem, data) => {
 | 
			
		||||
							const label = data.datasets[tooltipItem.datasetIndex].label || '';
 | 
			
		||||
							return `${label}: ${Vue.filter('bytes')(tooltipItem.yLabel, 1)}`;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}];
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.gkgckalzgidaygcxnugepioremxvxvpt
 | 
			
		||||
	padding 32px
 | 
			
		||||
	background #fff
 | 
			
		||||
	box-shadow 0 2px 8px rgba(#000, 0.1)
 | 
			
		||||
 | 
			
		||||
	*
 | 
			
		||||
		user-select none
 | 
			
		||||
 | 
			
		||||
	> header
 | 
			
		||||
		display flex
 | 
			
		||||
		margin 0 0 1em 0
 | 
			
		||||
		padding 0 0 8px 0
 | 
			
		||||
		font-size 1em
 | 
			
		||||
		color #555
 | 
			
		||||
		border-bottom solid 1px #eee
 | 
			
		||||
 | 
			
		||||
		> b
 | 
			
		||||
			margin-right 8px
 | 
			
		||||
 | 
			
		||||
		> *:last-child
 | 
			
		||||
			margin-left auto
 | 
			
		||||
 | 
			
		||||
			*
 | 
			
		||||
				&:not(.active)
 | 
			
		||||
					color var(--primary)
 | 
			
		||||
					cursor pointer
 | 
			
		||||
 | 
			
		||||
	> div
 | 
			
		||||
		> *
 | 
			
		||||
			display block
 | 
			
		||||
			height 350px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
<mk-window ref="window" @closed="destroyDom" width="800px" height="500px" :popout-url="popout">
 | 
			
		||||
	<template slot="header">
 | 
			
		||||
		<p v-if="usage" :class="$style.info"><b>{{ usage.toFixed(1) }}%</b> %i18n:@used%</p>
 | 
			
		||||
		<span :class="$style.title">%fa:cloud%%i18n:@drive%</span>
 | 
			
		||||
		<span :class="$style.title">%fa:cloud%%i18n:common.drive%</span>
 | 
			
		||||
	</template>
 | 
			
		||||
	<mk-drive :class="$style.browser" multiple :init-folder="folder" ref="browser"/>
 | 
			
		||||
</mk-window>
 | 
			
		||||
 
 | 
			
		||||
@@ -67,12 +67,12 @@ export default Vue.extend({
 | 
			
		||||
				text: '%i18n:@contextmenu.rename%',
 | 
			
		||||
				icon: '%fa:i-cursor%',
 | 
			
		||||
				action: this.rename
 | 
			
		||||
			}/*, null, {
 | 
			
		||||
			}, null, {
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:common.delete%',
 | 
			
		||||
				icon: '%fa:R trash-alt%',
 | 
			
		||||
				action: this.deleteFolder
 | 
			
		||||
			}*/], {
 | 
			
		||||
			}], {
 | 
			
		||||
					closed: () => {
 | 
			
		||||
						this.isContextmenuShowing = false;
 | 
			
		||||
					}
 | 
			
		||||
@@ -207,7 +207,9 @@ export default Vue.extend({
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		deleteFolder() {
 | 
			
		||||
			alert('not implemented yet');
 | 
			
		||||
			(this as any).api('drive/folders/delete', {
 | 
			
		||||
				folderId: this.folder.id
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
	@drop.stop="onDrop"
 | 
			
		||||
>
 | 
			
		||||
	<template v-if="folder == null">%fa:cloud%</template>
 | 
			
		||||
	<span>{{ folder == null ? '%i18n:@drive%' : folder.name }}</span>
 | 
			
		||||
	<span>{{ folder == null ? '%i18n:common.drive%' : folder.name }}</span>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -98,7 +98,7 @@ export default Vue.extend({
 | 
			
		||||
			hierarchyFolders: [],
 | 
			
		||||
			selectedFiles: [],
 | 
			
		||||
			uploadings: [],
 | 
			
		||||
			connection: null
 | 
			
		||||
			connection: null,
 | 
			
		||||
 | 
			
		||||
			/**
 | 
			
		||||
			 * ドロップされようとしているか
 | 
			
		||||
@@ -122,6 +122,7 @@ export default Vue.extend({
 | 
			
		||||
		this.connection.on('fileDeleted', this.onStreamDriveFileDeleted);
 | 
			
		||||
		this.connection.on('folderCreated', this.onStreamDriveFolderCreated);
 | 
			
		||||
		this.connection.on('folderUpdated', this.onStreamDriveFolderUpdated);
 | 
			
		||||
		this.connection.on('folderDeleted', this.onStreamDriveFolderDeleted);
 | 
			
		||||
 | 
			
		||||
		if (this.initFolder) {
 | 
			
		||||
			this.move(this.initFolder);
 | 
			
		||||
@@ -182,6 +183,10 @@ export default Vue.extend({
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		onStreamDriveFolderDeleted(folderId) {
 | 
			
		||||
			this.removeFolder(folderId);
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		onChangeUploaderUploads(uploads) {
 | 
			
		||||
			this.uploadings = uploads;
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -40,8 +40,8 @@ export default Vue.extend({
 | 
			
		||||
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.connection = (this as any).os.stream.useSharedConnection('main');
 | 
			
		||||
		this.connection.on('follow', this.onFollow);
 | 
			
		||||
		this.connection.on('unfollow', this.onUnfollow);
 | 
			
		||||
		this.connection.on('follow', this.onFollowChange);
 | 
			
		||||
		this.connection.on('unfollow', this.onFollowChange);
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
@@ -49,17 +49,11 @@ export default Vue.extend({
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
		onFollow(user) {
 | 
			
		||||
			if (user.id == this.u.id) {
 | 
			
		||||
				this.u.isFollowing = user.isFollowing;
 | 
			
		||||
				this.u.hasPendingFollowRequestFromYou = user.hasPendingFollowRequestFromYou;
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		onUnfollow(user) {
 | 
			
		||||
		onFollowChange(user) {
 | 
			
		||||
			if (user.id == this.u.id) {
 | 
			
		||||
				this.u.isFollowing = user.isFollowing;
 | 
			
		||||
				this.u.hasPendingFollowRequestFromYou = user.hasPendingFollowRequestFromYou;
 | 
			
		||||
				this.$forceUpdate();
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@
 | 
			
		||||
				<div class="text">
 | 
			
		||||
					<span v-if="p.isHidden" style="opacity: 0.5">%i18n:@private%</span>
 | 
			
		||||
					<span v-if="p.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
 | 
			
		||||
					<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i"/>
 | 
			
		||||
					<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i" :customEmojis="p.emojis" />
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="files" v-if="p.files.length > 0">
 | 
			
		||||
					<mk-media-list :media-list="p.files" :raw="true"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@
 | 
			
		||||
					<div class="text">
 | 
			
		||||
						<span v-if="appearNote.isHidden" style="opacity: 0.5">%i18n:@private%</span>
 | 
			
		||||
						<a class="reply" v-if="appearNote.reply">%fa:reply%</a>
 | 
			
		||||
						<misskey-flavored-markdown v-if="appearNote.text" :text="appearNote.text" :i="$store.state.i" :class="$style.text"/>
 | 
			
		||||
						<misskey-flavored-markdown v-if="appearNote.text" :text="appearNote.text" :i="$store.state.i" :class="$style.text" :customEmojis="appearNote.emojis"/>
 | 
			
		||||
						<a class="rp" v-if="appearNote.renote">RN:</a>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="files" v-if="appearNote.files.length > 0">
 | 
			
		||||
 
 | 
			
		||||
@@ -4,10 +4,7 @@
 | 
			
		||||
 | 
			
		||||
	<slot name="empty" v-if="notes.length == 0 && !fetching && requestInitPromise == null"></slot>
 | 
			
		||||
 | 
			
		||||
	<div v-if="!fetching && requestInitPromise != null" class="error">
 | 
			
		||||
		<p>%fa:exclamation-triangle% %i18n:common.error.title%</p>
 | 
			
		||||
		<ui-button @click="resolveInitPromise">%i18n:common.error.retry%</ui-button>
 | 
			
		||||
	</div>
 | 
			
		||||
	<mk-error v-if="!fetching && requestInitPromise != null" @retry="resolveInitPromise"/>
 | 
			
		||||
 | 
			
		||||
	<div class="placeholder" v-if="fetching">
 | 
			
		||||
		<template v-for="i in 10">
 | 
			
		||||
@@ -215,16 +212,6 @@ export default Vue.extend({
 | 
			
		||||
		> *
 | 
			
		||||
			transition transform .3s ease, opacity .3s ease
 | 
			
		||||
 | 
			
		||||
	> .error
 | 
			
		||||
		max-width 300px
 | 
			
		||||
		margin 0 auto
 | 
			
		||||
		padding 32px
 | 
			
		||||
		text-align center
 | 
			
		||||
		color var(--text)
 | 
			
		||||
 | 
			
		||||
		> p
 | 
			
		||||
			margin 0 0 8px 0
 | 
			
		||||
 | 
			
		||||
	> .placeholder
 | 
			
		||||
		padding 32px
 | 
			
		||||
		opacity 0.3
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@
 | 
			
		||||
		<span v-if="visibility === 'specified'">%fa:envelope%</span>
 | 
			
		||||
		<span v-if="visibility === 'private'">%fa:lock%</span>
 | 
			
		||||
	</button>
 | 
			
		||||
	<p class="text-count" :class="{ over: this.trimmedLength(text) > 1000 }">{{ 1000 - this.trimmedLength(text) }}</p>
 | 
			
		||||
	<p class="text-count" :class="{ over: this.trimmedLength(text) > this.maxNoteTextLength }">{{ this.maxNoteTextLength - this.trimmedLength(text) }}</p>
 | 
			
		||||
	<button :class="{ posting }" class="submit" :disabled="!canPost" @click="post">
 | 
			
		||||
		{{ posting ? '%i18n:@posting%' : submitText }}<mk-ellipsis v-if="posting"/>
 | 
			
		||||
	</button>
 | 
			
		||||
@@ -107,10 +107,17 @@ export default Vue.extend({
 | 
			
		||||
			visibleUsers: [],
 | 
			
		||||
			autocomplete: null,
 | 
			
		||||
			draghover: false,
 | 
			
		||||
			recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]')
 | 
			
		||||
			recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]'),
 | 
			
		||||
			maxNoteTextLength: 1000
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	created() {
 | 
			
		||||
		(this as any).os.getMeta().then(meta => {
 | 
			
		||||
			this.maxNoteTextLength = meta.maxNoteTextLength;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	computed: {
 | 
			
		||||
		draftId(): string {
 | 
			
		||||
			return this.renote
 | 
			
		||||
@@ -149,7 +156,7 @@ export default Vue.extend({
 | 
			
		||||
		canPost(): boolean {
 | 
			
		||||
			return !this.posting &&
 | 
			
		||||
				(1 <= this.text.length || 1 <= this.files.length || this.poll || this.renote) &&
 | 
			
		||||
				(length(this.text.trim()) <= 1000);
 | 
			
		||||
				(length(this.text.trim()) <= this.maxNoteTextLength);
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="2fa">
 | 
			
		||||
	<p>%i18n:@intro%<a href="%i18n:@url%" target="_blank">%i18n:@detail%</a></p>
 | 
			
		||||
	<div class="ui info warn"><p>%fa:exclamation-triangle%%i18n:@caution%</p></div>
 | 
			
		||||
	<p style="margin-top:0;">%i18n:@intro%<a href="%i18n:@url%" target="_blank">%i18n:@detail%</a></p>
 | 
			
		||||
	<ui-info warn>%i18n:@caution%</ui-info>
 | 
			
		||||
	<p v-if="!data && !$store.state.i.twoFactorEnabled"><ui-button @click="register">%i18n:@register%</ui-button></p>
 | 
			
		||||
	<template v-if="$store.state.i.twoFactorEnabled">
 | 
			
		||||
		<p>%i18n:@already-registered%</p>
 | 
			
		||||
@@ -72,9 +72,3 @@ export default Vue.extend({
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.2fa
 | 
			
		||||
	color #4a535a
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,40 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="root api">
 | 
			
		||||
	<ui-input :value="$store.state.i.token" readonly>
 | 
			
		||||
		<span>%i18n:@token%</span>
 | 
			
		||||
	</ui-input>
 | 
			
		||||
	<p>%i18n:@intro%</p>
 | 
			
		||||
	<div class="ui info warn"><p>%fa:exclamation-triangle%%i18n:@caution%</p></div>
 | 
			
		||||
	<p>%i18n:@regeneration-of-token%</p>
 | 
			
		||||
	<ui-button @click="regenerateToken">%i18n:@regenerate-token%</ui-button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	methods: {
 | 
			
		||||
		regenerateToken() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@enter-password%',
 | 
			
		||||
				type: 'password'
 | 
			
		||||
			}).then(password => {
 | 
			
		||||
				(this as any).api('i/regenerate_token', {
 | 
			
		||||
					password: password
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.root.api
 | 
			
		||||
	code
 | 
			
		||||
		display inline-block
 | 
			
		||||
		padding 4px 6px
 | 
			
		||||
		color #555
 | 
			
		||||
		background #eee
 | 
			
		||||
		border-radius 2px
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,8 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="root">
 | 
			
		||||
	<div class="none ui info" v-if="!fetching && apps.length == 0">
 | 
			
		||||
		<p>%fa:info-circle%%i18n:@no-apps%</p>
 | 
			
		||||
	</div>
 | 
			
		||||
	<ui-info v-if="!fetching && apps.length == 0">%i18n:@no-apps%</ui-info>
 | 
			
		||||
	<div class="apps" v-if="apps.length != 0">
 | 
			
		||||
		<div v-for="app in apps">
 | 
			
		||||
			<p><b>{{ app.name }}</b></p>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="root">
 | 
			
		||||
	<template v-if="!fetching">
 | 
			
		||||
		<p><b>{{ capacity | bytes }}</b>%i18n:@max%<b>{{ usage | bytes }}</b>%i18n:@in-use%</p>
 | 
			
		||||
	</template>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			usage: null,
 | 
			
		||||
			capacity: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		(this as any).api('drive').then(info => {
 | 
			
		||||
			this.capacity = info.capacity;
 | 
			
		||||
			this.usage = info.usage;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.root
 | 
			
		||||
	> p
 | 
			
		||||
		> b
 | 
			
		||||
			margin 0 8px
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div>
 | 
			
		||||
	<div class="none ui info" v-if="!fetching && users.length == 0">
 | 
			
		||||
		<p>%fa:info-circle%%i18n:@no-users%</p>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="users" v-if="users.length != 0">
 | 
			
		||||
		<div v-for="user in users" :key="user.id">
 | 
			
		||||
			<p><b>{{ user | userName }}</b> @{{ user | acct }}</p>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
			users: []
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		(this as any).api('mute/list').then(x => {
 | 
			
		||||
			this.users = x.users;
 | 
			
		||||
			this.fetching = false;
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
@@ -5,9 +5,9 @@
 | 
			
		||||
		<p :class="{ active: page == 'theme' }" @mousedown="page = 'theme'">%fa:palette .fw%%i18n:@theme%</p>
 | 
			
		||||
		<p :class="{ active: page == 'web' }" @mousedown="page = 'web'">%fa:desktop .fw%Web</p>
 | 
			
		||||
		<p :class="{ active: page == 'notification' }" @mousedown="page = 'notification'">%fa:R bell .fw%%i18n:@notification%</p>
 | 
			
		||||
		<p :class="{ active: page == 'drive' }" @mousedown="page = 'drive'">%fa:cloud .fw%%i18n:@drive%</p>
 | 
			
		||||
		<p :class="{ active: page == 'drive' }" @mousedown="page = 'drive'">%fa:cloud .fw%%i18n:common.drive%</p>
 | 
			
		||||
		<p :class="{ active: page == 'hashtags' }" @mousedown="page = 'hashtags'">%fa:hashtag .fw%%i18n:@tags%</p>
 | 
			
		||||
		<p :class="{ active: page == 'mute' }" @mousedown="page = 'mute'">%fa:ban .fw%%i18n:@mute%</p>
 | 
			
		||||
		<p :class="{ active: page == 'muteAndBlock' }" @mousedown="page = 'muteAndBlock'">%fa:ban .fw%%i18n:@mute-and-block%</p>
 | 
			
		||||
		<p :class="{ active: page == 'apps' }" @mousedown="page = 'apps'">%fa:puzzle-piece .fw%%i18n:@apps%</p>
 | 
			
		||||
		<p :class="{ active: page == 'security' }" @mousedown="page = 'security'">%fa:unlock-alt .fw%%i18n:@security%</p>
 | 
			
		||||
		<p :class="{ active: page == 'api' }" @mousedown="page = 'api'">%fa:key .fw%API</p>
 | 
			
		||||
@@ -23,6 +23,13 @@
 | 
			
		||||
					<mk-twitter-setting/>
 | 
			
		||||
				</section>
 | 
			
		||||
			</ui-card>
 | 
			
		||||
 | 
			
		||||
			<ui-card>
 | 
			
		||||
				<div slot="title">%fa:B github% %i18n:@github%</div>
 | 
			
		||||
				<section>
 | 
			
		||||
					<mk-github-setting/>
 | 
			
		||||
				</section>
 | 
			
		||||
			</ui-card>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="theme" v-show="page == 'theme'">
 | 
			
		||||
@@ -189,12 +196,9 @@
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="drive" v-show="page == 'drive'">
 | 
			
		||||
			<div slot="title">%fa:cloud% %i18n:@drive%</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<x-drive/>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
		<div class="drive" v-if="page == 'drive'">
 | 
			
		||||
			<mk-drive-settings/>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="hashtags" v-show="page == 'hashtags'">
 | 
			
		||||
			<div slot="title">%fa:hashtag% %i18n:@tags%</div>
 | 
			
		||||
@@ -203,12 +207,9 @@
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="mute" v-show="page == 'mute'">
 | 
			
		||||
			<div slot="title">%fa:ban% %i18n:@mute%</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<x-mute/>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
		<div class="muteAndBlock" v-show="page == 'muteAndBlock'">
 | 
			
		||||
			<mk-mute-and-block/>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="apps" v-show="page == 'apps'">
 | 
			
		||||
			<div slot="title">%fa:puzzle-piece% %i18n:@apps%</div>
 | 
			
		||||
@@ -220,7 +221,7 @@
 | 
			
		||||
		<ui-card class="password" v-show="page == 'security'">
 | 
			
		||||
			<div slot="title">%fa:unlock-alt% %i18n:@password%</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<x-password/>
 | 
			
		||||
				<mk-password-settings/>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
@@ -238,12 +239,9 @@
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="api" v-show="page == 'api'">
 | 
			
		||||
			<div slot="title">%fa:key% API</div>
 | 
			
		||||
			<section class="fit-top">
 | 
			
		||||
				<x-api/>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
		<div class="api" v-show="page == 'api'">
 | 
			
		||||
			<mk-api-settings/>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="other" v-show="page == 'other'">
 | 
			
		||||
			<div slot="title">%fa:info-circle% %i18n:@about%</div>
 | 
			
		||||
@@ -295,26 +293,18 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import XMute from './settings.mute.vue';
 | 
			
		||||
import XPassword from './settings.password.vue';
 | 
			
		||||
import X2fa from './settings.2fa.vue';
 | 
			
		||||
import XApi from './settings.api.vue';
 | 
			
		||||
import XApps from './settings.apps.vue';
 | 
			
		||||
import XSignins from './settings.signins.vue';
 | 
			
		||||
import XDrive from './settings.drive.vue';
 | 
			
		||||
import XTags from './settings.tags.vue';
 | 
			
		||||
import { url, langs, version } from '../../../config';
 | 
			
		||||
import { url, langs, clientVersion as version } from '../../../config';
 | 
			
		||||
import checkForUpdate from '../../../common/scripts/check-for-update';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	components: {
 | 
			
		||||
		XMute,
 | 
			
		||||
		XPassword,
 | 
			
		||||
		X2fa,
 | 
			
		||||
		XApi,
 | 
			
		||||
		XApps,
 | 
			
		||||
		XSignins,
 | 
			
		||||
		XDrive,
 | 
			
		||||
		XTags
 | 
			
		||||
	},
 | 
			
		||||
	props: {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
		<span v-if="note.isHidden" style="opacity: 0.5">%i18n:@private%</span>
 | 
			
		||||
		<span v-if="note.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
 | 
			
		||||
		<a class="reply" v-if="note.replyId">%fa:reply%</a>
 | 
			
		||||
		<misskey-flavored-markdown v-if="note.text" :text="note.text" :i="$store.state.i"/>
 | 
			
		||||
		<misskey-flavored-markdown v-if="note.text" :text="note.text" :i="$store.state.i" :customEmojis="note.emojis"/>
 | 
			
		||||
		<a class="rp" v-if="note.renoteId" :href="`/notes/${note.renoteId}`">RN: ...</a>
 | 
			
		||||
	</div>
 | 
			
		||||
	<details v-if="note.files.length > 0">
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
					<router-link :to="`/@${ $store.state.i.username }`">%fa:user%<span>%i18n:@profile%</span>%fa:angle-right%</router-link>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li @click="drive">
 | 
			
		||||
					<p>%fa:cloud%<span>%i18n:@drive%</span>%fa:angle-right%</p>
 | 
			
		||||
					<p>%fa:cloud%<span>%i18n:common.drive%</span>%fa:angle-right%</p>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li>
 | 
			
		||||
					<router-link to="/i/favorites">%fa:star%<span>%i18n:@favorites%</span>%fa:angle-right%</router-link>
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
					<p>%fa:cog%<span>%i18n:@settings%</span>%fa:angle-right%</p>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li v-if="$store.state.i.isAdmin">
 | 
			
		||||
					<router-link to="/admin">%fa:terminal%<span>%i18n:@admin%</span>%fa:angle-right%</router-link>
 | 
			
		||||
					<a href="/admin">%fa:terminal%<span>%i18n:@admin%</span>%fa:angle-right%</a>
 | 
			
		||||
				</li>
 | 
			
		||||
			</ul>
 | 
			
		||||
			<ul>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="qldxjjsrseehkusjuoooapmsprvfrxyl mk-admin-card">
 | 
			
		||||
	<header>%i18n:@announcements%</header>
 | 
			
		||||
	<textarea v-model="broadcasts" placeholder='[ { "title": "Title1", "text": "Text1" }, { "title": "Title2", "text": "Text2" } ]'></textarea>
 | 
			
		||||
	<button class="ui" @click="save">%i18n:@save%</button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			broadcasts: '',
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	created() {
 | 
			
		||||
		(this as any).os.getMeta().then(meta => {
 | 
			
		||||
			this.broadcasts = JSON.stringify(meta.broadcasts, null, '  ');
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		save() {
 | 
			
		||||
			let json;
 | 
			
		||||
 | 
			
		||||
			try {
 | 
			
		||||
				json = JSON.parse(this.broadcasts);
 | 
			
		||||
			} catch (e) {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Failed: ${e}` });
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			(this as any).api('admin/update-meta', {
 | 
			
		||||
				broadcasts: json
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Saved` });
 | 
			
		||||
			}.catch(e => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.qldxjjsrseehkusjuoooapmsprvfrxyl
 | 
			
		||||
	textarea
 | 
			
		||||
		width 100%
 | 
			
		||||
		min-height 300px
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,137 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="zyknedwtlthezamcjlolyusmipqmjgxz">
 | 
			
		||||
	<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`">
 | 
			
		||||
		<defs>
 | 
			
		||||
			<linearGradient :id="cpuGradientId" x1="0" x2="0" y1="1" y2="0">
 | 
			
		||||
				<stop offset="0%" stop-color="hsl(180, 80%, 70%)"></stop>
 | 
			
		||||
				<stop offset="100%" stop-color="hsl(0, 80%, 70%)"></stop>
 | 
			
		||||
			</linearGradient>
 | 
			
		||||
			<mask :id="cpuMaskId" x="0" y="0" :width="viewBoxX" :height="viewBoxY">
 | 
			
		||||
				<polygon
 | 
			
		||||
					:points="cpuPolygonPoints"
 | 
			
		||||
					fill="#fff"
 | 
			
		||||
					fill-opacity="0.5"/>
 | 
			
		||||
				<polyline
 | 
			
		||||
					:points="cpuPolylinePoints"
 | 
			
		||||
					fill="none"
 | 
			
		||||
					stroke="#fff"
 | 
			
		||||
					stroke-width="1"/>
 | 
			
		||||
			</mask>
 | 
			
		||||
		</defs>
 | 
			
		||||
		<rect
 | 
			
		||||
			x="0" y="0"
 | 
			
		||||
			:width="viewBoxX" :height="viewBoxY"
 | 
			
		||||
			:style="`stroke: none; fill: url(#${ cpuGradientId }); mask: url(#${ cpuMaskId })`"/>
 | 
			
		||||
		<text x="1" y="12">CPU <tspan>{{ cpuP }}%</tspan></text>
 | 
			
		||||
	</svg>
 | 
			
		||||
	<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`">
 | 
			
		||||
		<defs>
 | 
			
		||||
			<linearGradient :id="memGradientId" x1="0" x2="0" y1="1" y2="0">
 | 
			
		||||
				<stop offset="0%" stop-color="hsl(180, 80%, 70%)"></stop>
 | 
			
		||||
				<stop offset="100%" stop-color="hsl(0, 80%, 70%)"></stop>
 | 
			
		||||
			</linearGradient>
 | 
			
		||||
			<mask :id="memMaskId" x="0" y="0" :width="viewBoxX" :height="viewBoxY">
 | 
			
		||||
				<polygon
 | 
			
		||||
					:points="memPolygonPoints"
 | 
			
		||||
					fill="#fff"
 | 
			
		||||
					fill-opacity="0.5"/>
 | 
			
		||||
				<polyline
 | 
			
		||||
					:points="memPolylinePoints"
 | 
			
		||||
					fill="none"
 | 
			
		||||
					stroke="#fff"
 | 
			
		||||
					stroke-width="1"/>
 | 
			
		||||
			</mask>
 | 
			
		||||
		</defs>
 | 
			
		||||
		<rect
 | 
			
		||||
			x="0" y="0"
 | 
			
		||||
			:width="viewBoxX" :height="viewBoxY"
 | 
			
		||||
			:style="`stroke: none; fill: url(#${ memGradientId }); mask: url(#${ memMaskId })`"/>
 | 
			
		||||
		<text x="1" y="12">MEM <tspan>{{ memP }}%</tspan></text>
 | 
			
		||||
	</svg>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import * as uuid from 'uuid';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	props: ['connection'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			viewBoxX: 200,
 | 
			
		||||
			viewBoxY: 70,
 | 
			
		||||
			stats: [],
 | 
			
		||||
			cpuGradientId: uuid(),
 | 
			
		||||
			cpuMaskId: uuid(),
 | 
			
		||||
			memGradientId: uuid(),
 | 
			
		||||
			memMaskId: uuid(),
 | 
			
		||||
			cpuPolylinePoints: '',
 | 
			
		||||
			memPolylinePoints: '',
 | 
			
		||||
			cpuPolygonPoints: '',
 | 
			
		||||
			memPolygonPoints: '',
 | 
			
		||||
			cpuP: '',
 | 
			
		||||
			memP: ''
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		this.connection.on('stats', this.onStats);
 | 
			
		||||
		this.connection.on('statsLog', this.onStatsLog);
 | 
			
		||||
		this.connection.send('requestLog', {
 | 
			
		||||
			id: Math.random().toString().substr(2, 8),
 | 
			
		||||
			length: 200
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
		this.connection.off('stats', this.onStats);
 | 
			
		||||
		this.connection.off('statsLog', this.onStatsLog);
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		onStats(stats) {
 | 
			
		||||
			this.stats.push(stats);
 | 
			
		||||
			if (this.stats.length > 200) this.stats.shift();
 | 
			
		||||
 | 
			
		||||
			const cpuPolylinePoints = this.stats.map((s, i) => [this.viewBoxX - ((this.stats.length - 1) - i), (1 - s.cpu_usage) * this.viewBoxY]);
 | 
			
		||||
			const memPolylinePoints = this.stats.map((s, i) => [this.viewBoxX - ((this.stats.length - 1) - i), (1 - (s.mem.used / s.mem.total)) * this.viewBoxY]);
 | 
			
		||||
			this.cpuPolylinePoints = cpuPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
 | 
			
		||||
			this.memPolylinePoints = memPolylinePoints.map(xy => `${xy[0]},${xy[1]}`).join(' ');
 | 
			
		||||
 | 
			
		||||
			this.cpuPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${this.viewBoxY} ${this.cpuPolylinePoints} ${this.viewBoxX},${this.viewBoxY}`;
 | 
			
		||||
			this.memPolygonPoints = `${this.viewBoxX - (this.stats.length - 1)},${this.viewBoxY} ${this.memPolylinePoints} ${this.viewBoxX},${this.viewBoxY}`;
 | 
			
		||||
 | 
			
		||||
			this.cpuP = (stats.cpu_usage * 100).toFixed(0);
 | 
			
		||||
			this.memP = (stats.mem.used / stats.mem.total * 100).toFixed(0);
 | 
			
		||||
		},
 | 
			
		||||
		onStatsLog(statsLog) {
 | 
			
		||||
			statsLog.reverse().forEach(stats => this.onStats(stats));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
.zyknedwtlthezamcjlolyusmipqmjgxz
 | 
			
		||||
	> svg
 | 
			
		||||
		display block
 | 
			
		||||
		width 50%
 | 
			
		||||
		float left
 | 
			
		||||
 | 
			
		||||
		&:first-child
 | 
			
		||||
			padding-right 5px
 | 
			
		||||
 | 
			
		||||
		&:last-child
 | 
			
		||||
			padding-left 5px
 | 
			
		||||
 | 
			
		||||
		> text
 | 
			
		||||
			font-size 10px
 | 
			
		||||
			fill var(--chartCaption)
 | 
			
		||||
 | 
			
		||||
			> tspan
 | 
			
		||||
				opacity 0.5
 | 
			
		||||
 | 
			
		||||
	&:after
 | 
			
		||||
		content ""
 | 
			
		||||
		display block
 | 
			
		||||
		clear both
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,135 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="obdskegsannmntldydackcpzezagxqfy mk-admin-card">
 | 
			
		||||
	<header>%i18n:@dashboard%</header>
 | 
			
		||||
 | 
			
		||||
	<div v-if="stats" class="stats">
 | 
			
		||||
		<div><b>%fa:user% {{ stats.originalUsersCount | number }}</b><span>%i18n:@original-users%</span></div>
 | 
			
		||||
		<div><span>%fa:user% {{ stats.usersCount | number }}</span><span>%i18n:@all-users%</span></div>
 | 
			
		||||
		<div><b>%fa:pencil-alt% {{ stats.originalNotesCount | number }}</b><span>%i18n:@original-notes%</span></div>
 | 
			
		||||
		<div><span>%fa:pencil-alt% {{ stats.notesCount | number }}</span><span>%i18n:@all-notes%</span></div>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<div class="cpu-memory">
 | 
			
		||||
		<x-cpu-memory :connection="connection"/>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<div v-if="this.$store.state.i && this.$store.state.i.isAdmin" class="form">
 | 
			
		||||
		<div>
 | 
			
		||||
			<label>
 | 
			
		||||
				<p>%i18n:@banner-url%</p>
 | 
			
		||||
				<input v-model="bannerUrl">
 | 
			
		||||
			</label>
 | 
			
		||||
			<button class="ui" @click="updateMeta">%i18n:@save%</button>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<div>
 | 
			
		||||
			<label>
 | 
			
		||||
				<input type="checkbox" v-model="disableRegistration" @change="updateMeta">
 | 
			
		||||
				<span>%i18n:@disableRegistration%</span>
 | 
			
		||||
			</label>
 | 
			
		||||
			<button class="ui" @click="invite">%i18n:@invite%</button>
 | 
			
		||||
			<p v-if="inviteCode">Code: <code>{{ inviteCode }}</code></p>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<div>
 | 
			
		||||
			<label>
 | 
			
		||||
				<input type="checkbox" v-model="disableLocalTimeline" @change="updateMeta">
 | 
			
		||||
				<span>%i18n:@disableLocalTimeline%</span>
 | 
			
		||||
			</label>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
import XCpuMemory from "./admin.cpu-memory.vue";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	components: {
 | 
			
		||||
		XCpuMemory
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			stats: null,
 | 
			
		||||
			disableRegistration: false,
 | 
			
		||||
			disableLocalTimeline: false,
 | 
			
		||||
			bannerUrl: null,
 | 
			
		||||
			inviteCode: null,
 | 
			
		||||
			connection: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	created() {
 | 
			
		||||
		this.connection = (this as any).os.stream.useSharedConnection('serverStats');
 | 
			
		||||
 | 
			
		||||
		(this as any).os.getMeta().then(meta => {
 | 
			
		||||
			this.disableRegistration = meta.disableRegistration;
 | 
			
		||||
			this.disableLocalTimeline = meta.disableLocalTimeline;
 | 
			
		||||
			this.bannerUrl = meta.bannerUrl;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		(this as any).api('stats').then(stats => {
 | 
			
		||||
			this.stats = stats;
 | 
			
		||||
		});
 | 
			
		||||
	},
 | 
			
		||||
	beforeDestroy() {
 | 
			
		||||
		this.connection.dispose();
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		invite() {
 | 
			
		||||
			(this as any).api('admin/invite').then(x => {
 | 
			
		||||
				this.inviteCode = x.code;
 | 
			
		||||
			}).catch(e => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		updateMeta() {
 | 
			
		||||
			(this as any).api('admin/update-meta', {
 | 
			
		||||
				disableRegistration: this.disableRegistration,
 | 
			
		||||
				disableLocalTimeline: this.disableLocalTimeline,
 | 
			
		||||
				bannerUrl: this.bannerUrl
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Saved` });
 | 
			
		||||
			}).catch(e => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Failed ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.obdskegsannmntldydackcpzezagxqfy
 | 
			
		||||
	> .stats
 | 
			
		||||
		display flex
 | 
			
		||||
		justify-content center
 | 
			
		||||
		margin-bottom 16px
 | 
			
		||||
		padding 16px
 | 
			
		||||
		border solid 1px #eee
 | 
			
		||||
		border-radius 8px
 | 
			
		||||
 | 
			
		||||
		> div
 | 
			
		||||
			flex 1
 | 
			
		||||
			text-align center
 | 
			
		||||
 | 
			
		||||
			> *:first-child
 | 
			
		||||
				display block
 | 
			
		||||
				color var(--primary)
 | 
			
		||||
 | 
			
		||||
			> *:last-child
 | 
			
		||||
				font-size 70%
 | 
			
		||||
 | 
			
		||||
	> .cpu-memory
 | 
			
		||||
		margin-bottom 16px
 | 
			
		||||
		padding 16px
 | 
			
		||||
		border solid 1px #eee
 | 
			
		||||
		border-radius: 8px
 | 
			
		||||
 | 
			
		||||
	> .form
 | 
			
		||||
		> div
 | 
			
		||||
			padding 16px
 | 
			
		||||
			border-bottom solid 1px #eee
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,57 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-admin-card">
 | 
			
		||||
	<header>%i18n:@suspend-user%</header>
 | 
			
		||||
	<input v-model="username" type="text" class="ui"/>
 | 
			
		||||
	<button class="ui" @click="suspendUser" :disabled="suspending">%i18n:@suspend%</button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
import parseAcct from "../../../../../../misc/acct/parse";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			username: null,
 | 
			
		||||
			suspending: false
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		async suspendUser() {
 | 
			
		||||
			this.suspending = true;
 | 
			
		||||
 | 
			
		||||
			const process = async () => {
 | 
			
		||||
				const user = await (this as any).os.api(
 | 
			
		||||
					"users/show",
 | 
			
		||||
					parseAcct(this.username)
 | 
			
		||||
				);
 | 
			
		||||
 | 
			
		||||
				await (this as any).os.api("admin/suspend-user", {
 | 
			
		||||
					userId: user.id
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				(this as any).os.apis.dialog({ text: "%i18n:@suspended%" });
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			await process().catch(e => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Failed: ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.suspending = false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
header
 | 
			
		||||
	margin 10px 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
button
 | 
			
		||||
	margin 16px 0
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,58 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-admin-card">
 | 
			
		||||
	<header>%i18n:@unsuspend-user%</header>
 | 
			
		||||
	<input v-model="username" type="text" class="ui"/>
 | 
			
		||||
	<button class="ui" @click="unsuspendUser" :disabled="unsuspending">%i18n:@unsuspend%</button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
import parseAcct from "../../../../../../misc/acct/parse";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			username: null,
 | 
			
		||||
			unsuspending: false
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		async unsuspendUser() {
 | 
			
		||||
			this.unsuspending = true;
 | 
			
		||||
 | 
			
		||||
			const process = async () => {
 | 
			
		||||
				const user = await (this as any).os.api(
 | 
			
		||||
					"users/show",
 | 
			
		||||
					parseAcct(this.username)
 | 
			
		||||
				);
 | 
			
		||||
 | 
			
		||||
				await (this as any).os.api("admin/unsuspend-user", {
 | 
			
		||||
					userId: user.id
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				(this as any).os.apis.dialog({ text: "%i18n:@unsuspended%" });
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			await process().catch(e => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Failed: ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.unsuspending = false;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
header
 | 
			
		||||
	margin 10px 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
button
 | 
			
		||||
	margin 16px 0
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,57 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-admin-card">
 | 
			
		||||
	<header>%i18n:@unverify-user%</header>
 | 
			
		||||
	<input v-model="username" type="text" class="ui"/>
 | 
			
		||||
	<button class="ui" @click="unverifyUser" :disabled="unverifying">%i18n:@unverify%</button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
import parseAcct from "../../../../../../misc/acct/parse";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			username: null,
 | 
			
		||||
			unverifying: false
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		async unverifyUser() {
 | 
			
		||||
			this.unverifying = true;
 | 
			
		||||
 | 
			
		||||
			const process = async () => {
 | 
			
		||||
				const user = await (this as any).os.api(
 | 
			
		||||
					"users/show",
 | 
			
		||||
					parseAcct(this.username)
 | 
			
		||||
				);
 | 
			
		||||
 | 
			
		||||
				await (this as any).os.api("admin/unverify-user", {
 | 
			
		||||
					userId: user.id
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				(this as any).os.apis.dialog({ text: "%i18n:@unverified%" });
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			await process().catch(e => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Failed: ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.unverifying = false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
header
 | 
			
		||||
	margin 10px 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
button
 | 
			
		||||
	margin 16px 0
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
@@ -1,57 +0,0 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-admin-card">
 | 
			
		||||
	<header>%i18n:@verify-user%</header>
 | 
			
		||||
	<input v-model="username" type="text" class="ui"/>
 | 
			
		||||
	<button class="ui" @click="verifyUser" :disabled="verifying">%i18n:@verify%</button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from "vue";
 | 
			
		||||
import parseAcct from "../../../../../../misc/acct/parse";
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			username: null,
 | 
			
		||||
			verifying: false
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		async verifyUser() {
 | 
			
		||||
			this.verifying = true;
 | 
			
		||||
 | 
			
		||||
			const process = async () => {
 | 
			
		||||
				const user = await (this as any).os.api(
 | 
			
		||||
					"users/show",
 | 
			
		||||
					parseAcct(this.username)
 | 
			
		||||
				);
 | 
			
		||||
 | 
			
		||||
				await (this as any).os.api("admin/verify-user", {
 | 
			
		||||
					userId: user.id
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				(this as any).os.apis.dialog({ text: "%i18n:@verified%" });
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			await process().catch(e => {
 | 
			
		||||
				(this as any).os.apis.dialog({ text: `Failed: ${e}` });
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			this.verifying = false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" scoped>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
header
 | 
			
		||||
	margin 10px 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
button
 | 
			
		||||
	margin 16px 0
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user