diff --git a/.hgtags b/.hgtags
new file mode 100644
index 0000000000..3cb1bc5ae1
--- /dev/null
+++ b/.hgtags
@@ -0,0 +1,423 @@
+c835144ba5fd172c9aa8714683e69ca60bc894bc 3.8.0
+20712dc81634af43f9e0ebb41b0dcea50ccffdd2 4.0.0
+963504a30207af5877c11368ac5dadbc5d28fee1 4.2.0
+1fea2b717dd8d57d0a233c19d7f1eec35bdde0fa 4.4.0
+16a536201007ba66d36040a34e79a8998c4051f8 4.6.0
+08b000057b0b5a69f4034f2e1f5c7f2f7f23276f 4.8.0
+47edb75271514576ea775d28dc286a120675aa32 5.0.0
+4074fcefe73deec0b4dcd8b2e29f6c3c8eade611 5.2.0
+2d6d3a648c1dc1711adcc7bd3ff0930949b3076a 5.4.0
+513d2f77dc3bb1f5335af4faf233ccaa1711ac82 5.6.0
+e013e9930e2f27e5205b93f39d49f3604ae07901 5.8.0
+031cd536bd9f4e89345876c2d438626c57fbb33c 6.0.0
+ca49dcd87a916c997b5fe8bfc79c3195766bd4be 6.0.1
+a8121f01d452fd877749cf304dd691618553fccb 6.0.2
+90177ab7f46ac9703f9130f36f87d696774506be 6.0.3
+c1b6c469704c89d22f838a7c387f8ce2db6c04e8 6.0.4
+d37b211c91cc908fb3dbdc3ea8b52af50ef325a2 6.0.5
+76abf46e661d7f2b5d95bf13fddf107f31d47105 6.0.6
+722e116a59f5a1ba61aede38920e03a05a7d7ce4 6.0.7
+262af554d965998030b6b5b9441bc9469dab2311 6.0.8
+caafedc5aba43c65c49eeddf28ee41d8d35d2108 6.0.9
+a29aac850db9e9d55cc33f3ef1fff7af05043fc8 6.0.10
+c1f4671012217e27ee6fedb519da6eecb6b164d8 6.0.11
+2d40a627f2215c62800149562d033a18d550eabc 6.0.12
+31cb176af93153cff7f9b0ad024ce2d3ecac44c1 6.0.13
+440b2885e1659393f469358808a8b83ccb08c12c 6.0.14
+845114a2dc0253d6cb66883089996adffed70188 6.0.15
+89d9b0b02548363e7dfc984e594d09eff061e29c 6.0.16
+f95deaf6c5404e617fe522d98520c1ba829c64b3 6.0.17
+056876b48b55163bfb276ed713fbc8d3c7ec3209 6.0.18
+3fc2510a1f70752c9489a924727c11951eb5171f 6.0.19
+1491afc63d061116473998f40335b1901c62f7c8 6.0.20
+8f4439b7d4a4908f44c9e6d93b3a45fd8fd39350 6.0.21
+0263312e30f850a6637f1c920dbff1c929bf9ded 6.0.22
+5b249c3acf2243f294089418a325bbdcab7c57ad 6.0.23
+7fd7e8a5ae84dab88f322e900d26cbd2e7115292 6.0.24
+0000000000000000000000000000000000000000 3.8.0
+c835144ba5fd172c9aa8714683e69ca60bc894bc sao-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+20712dc81634af43f9e0ebb41b0dcea50ccffdd2 sao-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+963504a30207af5877c11368ac5dadbc5d28fee1 sao-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+1fea2b717dd8d57d0a233c19d7f1eec35bdde0fa sao-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+16a536201007ba66d36040a34e79a8998c4051f8 sao-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+08b000057b0b5a69f4034f2e1f5c7f2f7f23276f sao-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+47edb75271514576ea775d28dc286a120675aa32 sao-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+4074fcefe73deec0b4dcd8b2e29f6c3c8eade611 sao-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+2d6d3a648c1dc1711adcc7bd3ff0930949b3076a sao-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+513d2f77dc3bb1f5335af4faf233ccaa1711ac82 sao-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+e013e9930e2f27e5205b93f39d49f3604ae07901 sao-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+031cd536bd9f4e89345876c2d438626c57fbb33c sao-6.0.0
+0000000000000000000000000000000000000000 6.0.1
+ca49dcd87a916c997b5fe8bfc79c3195766bd4be sao-6.0.1
+0000000000000000000000000000000000000000 6.0.10
+a29aac850db9e9d55cc33f3ef1fff7af05043fc8 sao-6.0.10
+0000000000000000000000000000000000000000 6.0.11
+c1f4671012217e27ee6fedb519da6eecb6b164d8 sao-6.0.11
+0000000000000000000000000000000000000000 6.0.12
+2d40a627f2215c62800149562d033a18d550eabc sao-6.0.12
+0000000000000000000000000000000000000000 6.0.13
+31cb176af93153cff7f9b0ad024ce2d3ecac44c1 sao-6.0.13
+0000000000000000000000000000000000000000 6.0.14
+440b2885e1659393f469358808a8b83ccb08c12c sao-6.0.14
+0000000000000000000000000000000000000000 6.0.15
+845114a2dc0253d6cb66883089996adffed70188 sao-6.0.15
+0000000000000000000000000000000000000000 6.0.16
+89d9b0b02548363e7dfc984e594d09eff061e29c sao-6.0.16
+0000000000000000000000000000000000000000 6.0.17
+f95deaf6c5404e617fe522d98520c1ba829c64b3 sao-6.0.17
+0000000000000000000000000000000000000000 6.0.18
+056876b48b55163bfb276ed713fbc8d3c7ec3209 sao-6.0.18
+0000000000000000000000000000000000000000 6.0.19
+3fc2510a1f70752c9489a924727c11951eb5171f sao-6.0.19
+0000000000000000000000000000000000000000 6.0.2
+a8121f01d452fd877749cf304dd691618553fccb sao-6.0.2
+0000000000000000000000000000000000000000 6.0.20
+1491afc63d061116473998f40335b1901c62f7c8 sao-6.0.20
+0000000000000000000000000000000000000000 6.0.21
+8f4439b7d4a4908f44c9e6d93b3a45fd8fd39350 sao-6.0.21
+0000000000000000000000000000000000000000 6.0.22
+0263312e30f850a6637f1c920dbff1c929bf9ded sao-6.0.22
+0000000000000000000000000000000000000000 6.0.23
+5b249c3acf2243f294089418a325bbdcab7c57ad sao-6.0.23
+0000000000000000000000000000000000000000 6.0.24
+7fd7e8a5ae84dab88f322e900d26cbd2e7115292 sao-6.0.24
+0000000000000000000000000000000000000000 6.0.3
+90177ab7f46ac9703f9130f36f87d696774506be sao-6.0.3
+0000000000000000000000000000000000000000 6.0.4
+c1b6c469704c89d22f838a7c387f8ce2db6c04e8 sao-6.0.4
+0000000000000000000000000000000000000000 6.0.5
+d37b211c91cc908fb3dbdc3ea8b52af50ef325a2 sao-6.0.5
+0000000000000000000000000000000000000000 6.0.6
+76abf46e661d7f2b5d95bf13fddf107f31d47105 sao-6.0.6
+0000000000000000000000000000000000000000 6.0.7
+722e116a59f5a1ba61aede38920e03a05a7d7ce4 sao-6.0.7
+0000000000000000000000000000000000000000 6.0.8
+262af554d965998030b6b5b9441bc9469dab2311 sao-6.0.8
+0000000000000000000000000000000000000000 6.0.9
+caafedc5aba43c65c49eeddf28ee41d8d35d2108 sao-6.0.9
+4b876ac37410e223bc3628256425d80398d051c6 4.8.0
+144f9950fba568bd77ac0eecd02c7b0d0a98ba87 5.0.0
+ed88584857aa1b39459a420270c0253d460cfe48 5.2.0
+ed46c63b027820aa6e605bb53040f4ed4d133813 5.4.0
+d2db68823a8225ff32842da4e948c1c01197e5cc 5.6.0
+eeab3256f17f6b9bc111d74d6d7f984e75d70f17 5.8.0
+4d33daf649c10711b782ef82b71e49d1a725ccee 6.0.0
+ed86455b7bf99bb7a18309e809adc54e6a4864d8 6.0.1
+0000000000000000000000000000000000000000 4.8.0
+4b876ac37410e223bc3628256425d80398d051c6 trytond-gis-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+144f9950fba568bd77ac0eecd02c7b0d0a98ba87 trytond-gis-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+ed88584857aa1b39459a420270c0253d460cfe48 trytond-gis-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+ed46c63b027820aa6e605bb53040f4ed4d133813 trytond-gis-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+d2db68823a8225ff32842da4e948c1c01197e5cc trytond-gis-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+eeab3256f17f6b9bc111d74d6d7f984e75d70f17 trytond-gis-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+4d33daf649c10711b782ef82b71e49d1a725ccee trytond-gis-6.0.0
+0000000000000000000000000000000000000000 6.0.1
+ed86455b7bf99bb7a18309e809adc54e6a4864d8 trytond-gis-6.0.1
+951bb3311b916cb893adc5294cfb3216d2940169 1.0.0
+9f5ce178a7c403a0865fd4b6c1a82a911df0e998 1.2.0
+e2d31d59de7745de70199b7c340d78b7c4775723 1.4.0
+64691214959ac19983f3b3d1dbb89ff693d1545c 1.6.0
+af3a6063b46bf8739a513a06400fbb9858b5869b 1.8.0
+3475040a8fe081b1b8609350186b779cc640fba4 2.0.0
+1df3f0702c621e65279af52d1f87725747ae8fa4 2.2.0
+640af4420c8eace7ee59a432bec54692f4808b20 2.4.0
+36530840a1d0dce354bbaa58ec849a409d306d83 2.6.0
+2893d6c3efd6df3759ab09a28ea16773a160118e 2.8.0
+759c6ff44b90b8c685e9d9a4124bcd85af204649 3.0.0
+b3d84aa2c3a6ed3b76bfb58a40fc687f68824c29 3.2.0
+f0a9fa755cde703be54efd747f376b096ea8316c 3.4.0
+1e4ba5a3f16e6afd59131b49841eb004e706619d 3.6.0
+0a29a9dba7f56fbdef067772eea3f037934999c9 3.8.0
+49a0caa894dae201ed4ec707f277d9859b5521fb 4.0.0
+eb8949ec5bcedba563b5799f1315a0cecfee61f6 4.2.0
+f253ce8ed02f4c46a69b8b2f29311ad8959698be 4.4.0
+e7a6d0e8002237f624ecc8a45a6a472f7baadd08 4.6.0
+321b0104a732419c11aa4926785502e0615b89c9 4.8.0
+e8cadc044d59edff8a2ca73932c723d507517ec8 5.0.0
+ef34e4e92d45ab2b2b2956bbb6aa8b3ca259eb13 5.2.0
+32170ff46339dbc8609225791ab737a0f3eb0291 5.4.0
+5738a22adbb45390167194e4089adc46c6b638a3 5.6.0
+e21456b81972188261b8a6fc876afc18f641c85b 5.8.0
+2164597ffa5f4f0443e4804944b30f5491070990 6.0.0
+12a321529713d3e0b04fa94883baf66bddf76b75 6.0.1
+10e05cdf4fb3fcd545d8b47d03df8cfb78b38a76 6.0.2
+7b3f3676cf9d72147edcdb0cd477b77b1af7af9e 6.0.3
+68ea8ab81fc3d67e3efe925c3694644a46b7c111 6.0.4
+133f0b26de213e0b5668ae891e176de8f79025fc 6.0.5
+1719ce1a669285333424c02c9e3e45fd636b995c 6.0.6
+67fe2d478dbf413873c0919cfd5d6f3f6f4c2275 6.0.7
+ed230154446f04aed350b7fd0d416a80145645ee 6.0.8
+df3e4a189c249ff54e118a4943c03ecaab5fee60 6.0.9
+32f14e8a77caa727f2dfcec93aa15e05f45ad0b6 6.0.10
+6cb11cbdabc3b93d9698fc17653e8cb24b8154d4 6.0.11
+f34c0f0f0010e95ba38d3378f2e86d7e7a966516 6.0.12
+c1e2890b414d6d9c0bae303577fb784c8e8c715b 6.0.13
+78607bfea2986fe335c98a6ef87905cded1f5b2d 6.0.14
+26fba5237ff3ec9aed2d8aebdc1115e595e76c0b 6.0.15
+c4cf78bb401aec7d52a007eb7bda958658edaf95 6.0.16
+246ad7a2addde11a7b3e828ace36cf5fb1bc6696 6.0.17
+ca63f7f2eef1998de82eae76636c00211f0e3a80 6.0.18
+2973349bc8ca02dc5aba4fbf6a2e4ba270af9780 6.0.19
+9d5f5e04e2b0105bf4ca644bf98811d267054514 6.0.20
+221212011e95b8004c93ec76d21f5ffa12e866ee 6.0.21
+3ff41e43408ddccd4ce91170b6536a2f5cd0112b 6.0.22
+7d81a0faef794489d63fb164d0fb2ba2196c878b 6.0.23
+9b36d68c67a48a2203ef3598f5379d708781dc9e 6.0.24
+0000000000000000000000000000000000000000 1.0.0
+951bb3311b916cb893adc5294cfb3216d2940169 trytond-1.0.0
+0000000000000000000000000000000000000000 1.2.0
+9f5ce178a7c403a0865fd4b6c1a82a911df0e998 trytond-1.2.0
+0000000000000000000000000000000000000000 1.4.0
+e2d31d59de7745de70199b7c340d78b7c4775723 trytond-1.4.0
+0000000000000000000000000000000000000000 1.6.0
+64691214959ac19983f3b3d1dbb89ff693d1545c trytond-1.6.0
+0000000000000000000000000000000000000000 1.8.0
+af3a6063b46bf8739a513a06400fbb9858b5869b trytond-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+3475040a8fe081b1b8609350186b779cc640fba4 trytond-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+1df3f0702c621e65279af52d1f87725747ae8fa4 trytond-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+640af4420c8eace7ee59a432bec54692f4808b20 trytond-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+36530840a1d0dce354bbaa58ec849a409d306d83 trytond-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+2893d6c3efd6df3759ab09a28ea16773a160118e trytond-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+759c6ff44b90b8c685e9d9a4124bcd85af204649 trytond-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+b3d84aa2c3a6ed3b76bfb58a40fc687f68824c29 trytond-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+f0a9fa755cde703be54efd747f376b096ea8316c trytond-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+1e4ba5a3f16e6afd59131b49841eb004e706619d trytond-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+0a29a9dba7f56fbdef067772eea3f037934999c9 trytond-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+49a0caa894dae201ed4ec707f277d9859b5521fb trytond-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+eb8949ec5bcedba563b5799f1315a0cecfee61f6 trytond-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+f253ce8ed02f4c46a69b8b2f29311ad8959698be trytond-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+e7a6d0e8002237f624ecc8a45a6a472f7baadd08 trytond-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+321b0104a732419c11aa4926785502e0615b89c9 trytond-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+e8cadc044d59edff8a2ca73932c723d507517ec8 trytond-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+ef34e4e92d45ab2b2b2956bbb6aa8b3ca259eb13 trytond-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+32170ff46339dbc8609225791ab737a0f3eb0291 trytond-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+5738a22adbb45390167194e4089adc46c6b638a3 trytond-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+e21456b81972188261b8a6fc876afc18f641c85b trytond-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+2164597ffa5f4f0443e4804944b30f5491070990 trytond-6.0.0
+0000000000000000000000000000000000000000 6.0.1
+12a321529713d3e0b04fa94883baf66bddf76b75 trytond-6.0.1
+0000000000000000000000000000000000000000 6.0.10
+32f14e8a77caa727f2dfcec93aa15e05f45ad0b6 trytond-6.0.10
+0000000000000000000000000000000000000000 6.0.11
+6cb11cbdabc3b93d9698fc17653e8cb24b8154d4 trytond-6.0.11
+0000000000000000000000000000000000000000 6.0.12
+f34c0f0f0010e95ba38d3378f2e86d7e7a966516 trytond-6.0.12
+0000000000000000000000000000000000000000 6.0.13
+c1e2890b414d6d9c0bae303577fb784c8e8c715b trytond-6.0.13
+0000000000000000000000000000000000000000 6.0.14
+78607bfea2986fe335c98a6ef87905cded1f5b2d trytond-6.0.14
+0000000000000000000000000000000000000000 6.0.15
+26fba5237ff3ec9aed2d8aebdc1115e595e76c0b trytond-6.0.15
+0000000000000000000000000000000000000000 6.0.16
+c4cf78bb401aec7d52a007eb7bda958658edaf95 trytond-6.0.16
+0000000000000000000000000000000000000000 6.0.17
+246ad7a2addde11a7b3e828ace36cf5fb1bc6696 trytond-6.0.17
+0000000000000000000000000000000000000000 6.0.18
+ca63f7f2eef1998de82eae76636c00211f0e3a80 trytond-6.0.18
+0000000000000000000000000000000000000000 6.0.19
+2973349bc8ca02dc5aba4fbf6a2e4ba270af9780 trytond-6.0.19
+0000000000000000000000000000000000000000 6.0.2
+10e05cdf4fb3fcd545d8b47d03df8cfb78b38a76 trytond-6.0.2
+0000000000000000000000000000000000000000 6.0.20
+9d5f5e04e2b0105bf4ca644bf98811d267054514 trytond-6.0.20
+0000000000000000000000000000000000000000 6.0.21
+221212011e95b8004c93ec76d21f5ffa12e866ee trytond-6.0.21
+0000000000000000000000000000000000000000 6.0.22
+3ff41e43408ddccd4ce91170b6536a2f5cd0112b trytond-6.0.22
+0000000000000000000000000000000000000000 6.0.23
+7d81a0faef794489d63fb164d0fb2ba2196c878b trytond-6.0.23
+0000000000000000000000000000000000000000 6.0.24
+9b36d68c67a48a2203ef3598f5379d708781dc9e trytond-6.0.24
+0000000000000000000000000000000000000000 6.0.3
+7b3f3676cf9d72147edcdb0cd477b77b1af7af9e trytond-6.0.3
+0000000000000000000000000000000000000000 6.0.4
+68ea8ab81fc3d67e3efe925c3694644a46b7c111 trytond-6.0.4
+0000000000000000000000000000000000000000 6.0.5
+133f0b26de213e0b5668ae891e176de8f79025fc trytond-6.0.5
+0000000000000000000000000000000000000000 6.0.6
+1719ce1a669285333424c02c9e3e45fd636b995c trytond-6.0.6
+0000000000000000000000000000000000000000 6.0.7
+67fe2d478dbf413873c0919cfd5d6f3f6f4c2275 trytond-6.0.7
+0000000000000000000000000000000000000000 6.0.8
+ed230154446f04aed350b7fd0d416a80145645ee trytond-6.0.8
+0000000000000000000000000000000000000000 6.0.9
+df3e4a189c249ff54e118a4943c03ecaab5fee60 trytond-6.0.9
+923b3073b686c6dc5a921d0561c934adf3eeb879 1.0.0
+9a6434d63616f46520b6fa1b2be31906ff6f4f6a 1.2.0
+de84c1443d4bad908eabb99c381578b988c2117f 1.4.0
+3976912b23dfc5db2525d4c2e55d17f099d9492d 1.6.0
+8aa050da53cbdfabe1353a37da91c011b7fff549 1.8.0
+1876747b3f963ba6011b4bcf6968e681624c6e24 2.0.0
+5364f8ca6cd2cccfb5f7f39c69bb20bae2b5f495 2.2.0
+fe15da23f7333e0e90d2693aadddf6bed53ed602 2.4.0
+d069f9f1cdc3fea39e71415268582abb2b333ea1 2.6.0
+21fbf8bd36096d926c472acfecd3963369204af8 2.8.0
+9197d90b0257ec7c4576a38092fd592b3e87f7a4 3.0.0
+9721289ee2fdaab8b990de9327c3eab87363c88c 3.2.0
+8e5cba59137f9d0a063fa6d7855e09a51bc5889c 3.4.0
+1ac658605d42d82988cfb232afebfe359aba7776 3.6.0
+f4b9c8a84cf61935afec788c3c639982731452ef 3.8.0
+44d8ed92ff90cf98c4c01d37f12d344d9d66e7f1 4.0.0
+94037cff031ef897c9533a579356977c8a3cf695 4.2.0
+763dc5d8e1d7e483edbf9977dd96afc114555555 4.4.0
+d7ed5002e47249d019fbc546f6ac562db44c54f2 4.6.0
+2a2b48ea60fbb5201ea12443000d3a106a2fa27c 4.8.0
+70ade9d1fe04c734fe2dd7d35dd75b13f1af902a 5.0.0
+d5652dee45a43fccc1f33d39050af6e00e073273 5.2.0
+9f3fbb33df184ca19350cc71054dd9afd55f1cb7 5.4.0
+45d3f736ffb4396ee0dac0e2110fcc17237337ba 5.6.0
+df9de0ceeb27b38b165da7526accad0ad6682e86 5.8.0
+d18d03f0c540dfd2aae81dfaac048378a62c0ef6 6.0.0
+6cdc11292120ffb6df929721adfd738c4916a594 6.0.1
+23df79b60988e64c45be329933d803e0add7ae20 6.0.2
+5ab29a68b330847559add6204df341aeec38c223 6.0.3
+4493ce6c2dfcebde5701360689c635dbd6253d10 6.0.4
+0a8b71b80cc781e88f6a5a7467be9cdb3de50562 6.0.5
+be96d41f66a7bae727ecaf072a955ada01cd73e8 6.0.6
+0d0d910f4edfa1e493d8526dea6bc5f2ad78c30e 6.0.7
+1f7935eb899fb1ccdd363a085ba3a7a24349a3be 6.0.8
+375c664763440caa3f3ac4cdff2f694eedab7f7c 6.0.9
+a8f9ff596e3476c4fa73002524a78011b62b7fb8 6.0.10
+986c3f1e1d5ee57983adf34bf84c348abdba5b42 6.0.11
+e2cd492204aa2dd300eaaad5caca022b0114bea2 6.0.12
+1cbf7901b52d92f993ceba19357085386475c08d 6.0.13
+1474928ec1aa12d34e5fd79675bb284890bafd76 6.0.14
+0ee8d81a43a12bdd3064bcc100ef4a35ab86bfdb 6.0.15
+d1f3f6a0d5722332cddd2cb0837a266e5f5a1881 6.0.16
+dd458525c9d4c92eca991b832f06ec46a639c3a4 6.0.17
+40c3f7f6d487197698ac644ef28fa09dbce7e46a 6.0.18
+bd7b3f9a3c2f9cda09c2d5f89ed1c1f92dd78ff3 6.0.19
+4b448222df4c6c37b0223112c0c2c14f09675d34 6.0.20
+90566b9897fd57fb36e427dd7d8f2bbfa0a9ed5f 6.0.21
+0000000000000000000000000000000000000000 1.0.0
+923b3073b686c6dc5a921d0561c934adf3eeb879 tryton-1.0.0
+0000000000000000000000000000000000000000 1.2.0
+9a6434d63616f46520b6fa1b2be31906ff6f4f6a tryton-1.2.0
+0000000000000000000000000000000000000000 1.4.0
+de84c1443d4bad908eabb99c381578b988c2117f tryton-1.4.0
+0000000000000000000000000000000000000000 1.6.0
+3976912b23dfc5db2525d4c2e55d17f099d9492d tryton-1.6.0
+0000000000000000000000000000000000000000 1.8.0
+8aa050da53cbdfabe1353a37da91c011b7fff549 tryton-1.8.0
+0000000000000000000000000000000000000000 2.0.0
+1876747b3f963ba6011b4bcf6968e681624c6e24 tryton-2.0.0
+0000000000000000000000000000000000000000 2.2.0
+5364f8ca6cd2cccfb5f7f39c69bb20bae2b5f495 tryton-2.2.0
+0000000000000000000000000000000000000000 2.4.0
+fe15da23f7333e0e90d2693aadddf6bed53ed602 tryton-2.4.0
+0000000000000000000000000000000000000000 2.6.0
+d069f9f1cdc3fea39e71415268582abb2b333ea1 tryton-2.6.0
+0000000000000000000000000000000000000000 2.8.0
+21fbf8bd36096d926c472acfecd3963369204af8 tryton-2.8.0
+0000000000000000000000000000000000000000 3.0.0
+9197d90b0257ec7c4576a38092fd592b3e87f7a4 tryton-3.0.0
+0000000000000000000000000000000000000000 3.2.0
+9721289ee2fdaab8b990de9327c3eab87363c88c tryton-3.2.0
+0000000000000000000000000000000000000000 3.4.0
+8e5cba59137f9d0a063fa6d7855e09a51bc5889c tryton-3.4.0
+0000000000000000000000000000000000000000 3.6.0
+1ac658605d42d82988cfb232afebfe359aba7776 tryton-3.6.0
+0000000000000000000000000000000000000000 3.8.0
+f4b9c8a84cf61935afec788c3c639982731452ef tryton-3.8.0
+0000000000000000000000000000000000000000 4.0.0
+44d8ed92ff90cf98c4c01d37f12d344d9d66e7f1 tryton-4.0.0
+0000000000000000000000000000000000000000 4.2.0
+94037cff031ef897c9533a579356977c8a3cf695 tryton-4.2.0
+0000000000000000000000000000000000000000 4.4.0
+763dc5d8e1d7e483edbf9977dd96afc114555555 tryton-4.4.0
+0000000000000000000000000000000000000000 4.6.0
+d7ed5002e47249d019fbc546f6ac562db44c54f2 tryton-4.6.0
+0000000000000000000000000000000000000000 4.8.0
+2a2b48ea60fbb5201ea12443000d3a106a2fa27c tryton-4.8.0
+0000000000000000000000000000000000000000 5.0.0
+70ade9d1fe04c734fe2dd7d35dd75b13f1af902a tryton-5.0.0
+0000000000000000000000000000000000000000 5.2.0
+d5652dee45a43fccc1f33d39050af6e00e073273 tryton-5.2.0
+0000000000000000000000000000000000000000 5.4.0
+9f3fbb33df184ca19350cc71054dd9afd55f1cb7 tryton-5.4.0
+0000000000000000000000000000000000000000 5.6.0
+45d3f736ffb4396ee0dac0e2110fcc17237337ba tryton-5.6.0
+0000000000000000000000000000000000000000 5.8.0
+df9de0ceeb27b38b165da7526accad0ad6682e86 tryton-5.8.0
+0000000000000000000000000000000000000000 6.0.0
+d18d03f0c540dfd2aae81dfaac048378a62c0ef6 tryton-6.0.0
+0000000000000000000000000000000000000000 6.0.1
+6cdc11292120ffb6df929721adfd738c4916a594 tryton-6.0.1
+0000000000000000000000000000000000000000 6.0.10
+a8f9ff596e3476c4fa73002524a78011b62b7fb8 tryton-6.0.10
+0000000000000000000000000000000000000000 6.0.11
+986c3f1e1d5ee57983adf34bf84c348abdba5b42 tryton-6.0.11
+0000000000000000000000000000000000000000 6.0.12
+e2cd492204aa2dd300eaaad5caca022b0114bea2 tryton-6.0.12
+0000000000000000000000000000000000000000 6.0.13
+1cbf7901b52d92f993ceba19357085386475c08d tryton-6.0.13
+0000000000000000000000000000000000000000 6.0.14
+1474928ec1aa12d34e5fd79675bb284890bafd76 tryton-6.0.14
+0000000000000000000000000000000000000000 6.0.15
+0ee8d81a43a12bdd3064bcc100ef4a35ab86bfdb tryton-6.0.15
+0000000000000000000000000000000000000000 6.0.16
+d1f3f6a0d5722332cddd2cb0837a266e5f5a1881 tryton-6.0.16
+0000000000000000000000000000000000000000 6.0.17
+dd458525c9d4c92eca991b832f06ec46a639c3a4 tryton-6.0.17
+0000000000000000000000000000000000000000 6.0.18
+40c3f7f6d487197698ac644ef28fa09dbce7e46a tryton-6.0.18
+0000000000000000000000000000000000000000 6.0.19
+bd7b3f9a3c2f9cda09c2d5f89ed1c1f92dd78ff3 tryton-6.0.19
+0000000000000000000000000000000000000000 6.0.2
+23df79b60988e64c45be329933d803e0add7ae20 tryton-6.0.2
+0000000000000000000000000000000000000000 6.0.20
+4b448222df4c6c37b0223112c0c2c14f09675d34 tryton-6.0.20
+0000000000000000000000000000000000000000 6.0.21
+90566b9897fd57fb36e427dd7d8f2bbfa0a9ed5f tryton-6.0.21
+0000000000000000000000000000000000000000 6.0.3
+5ab29a68b330847559add6204df341aeec38c223 tryton-6.0.3
+0000000000000000000000000000000000000000 6.0.4
+4493ce6c2dfcebde5701360689c635dbd6253d10 tryton-6.0.4
+0000000000000000000000000000000000000000 6.0.5
+0a8b71b80cc781e88f6a5a7467be9cdb3de50562 tryton-6.0.5
+0000000000000000000000000000000000000000 6.0.6
+be96d41f66a7bae727ecaf072a955ada01cd73e8 tryton-6.0.6
+0000000000000000000000000000000000000000 6.0.7
+0d0d910f4edfa1e493d8526dea6bc5f2ad78c30e tryton-6.0.7
+0000000000000000000000000000000000000000 6.0.8
+1f7935eb899fb1ccdd363a085ba3a7a24349a3be tryton-6.0.8
+0000000000000000000000000000000000000000 6.0.9
+375c664763440caa3f3ac4cdff2f694eedab7f7c tryton-6.0.9
diff --git a/sao/.bower_allow_root.sh b/sao/.bower_allow_root.sh
new file mode 100755
index 0000000000..fc17f19c58
--- /dev/null
+++ b/sao/.bower_allow_root.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo '{ "allow_root": true }' > ~/.bowerrc
diff --git a/sao/.drone.yml b/sao/.drone.yml
new file mode 100644
index 0000000000..e2a994d6b3
--- /dev/null
+++ b/sao/.drone.yml
@@ -0,0 +1,17 @@
+clone:
+ hg:
+ image: plugins/hg
+ environment:
+ - HG_SHARE_POOL=/root/.cache/hg
+ volumes:
+ - cache:/root/.cache
+
+pipeline:
+ npm:
+ image: tryton/sao-test
+ commands:
+ - sh .bower_allow_root.sh
+ - npm -s install --unsafe-perm --legacy-peer-deps
+ - npm test
+ volumes:
+ - cache-npm:/root/.npm
diff --git a/sao/CHANGELOG b/sao/CHANGELOG
new file mode 100644
index 0000000000..90008764ad
--- /dev/null
+++ b/sao/CHANGELOG
@@ -0,0 +1,274 @@
+Version 6.0.24 - 2022-12-06
+---------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.23 - 2022-11-05
+---------------------------
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.22 - 2022-10-17
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.21 - 2022-08-17
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.20 - 2022-07-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.19 - 2022-06-15
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.18 - 2022-06-03
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.17 - 2022-05-06
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.16 - 2022-04-15
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.15 - 2022-03-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.14 - 2022-02-16
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.13 - 2022-02-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.12 - 2022-01-15
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.11 - 2022-01-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.10 - 2021-12-03
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.9 - 2021-11-04
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.8 - 2021-10-15
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.7 - 2021-10-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.6 - 2021-09-16
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.5 - 2021-09-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.4 - 2021-08-05
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.3 - 2021-07-21
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.2 - 2021-07-01
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.1 - 2021-06-17
+* Bug fixes (see mercurial logs for details)
+
+Version 6.0.0 - 2021-05-03
+* Bug fixes (see mercurial logs for details)
+* Use appropriate types for email and url widgets
+* Add completion on xxx2Many and Dict
+* Add attachment preview
+* Support document widget
+* Support icon of type URL
+* Allow sending email with existing attachments
+* Add paths and model context to action data
+* Add indentation in CSV export of tree
+* Manage which records to use for actions
+* Add drag and drop on CSV export and import
+* Remove tempusdominus dependency
+* Handle device cookie
+* Add breadcrumb as title of window form
+* Manage help for each selection
+* Display revision on dialog
+* Support empty value for timedelta converter
+* Unify PYSON string format
+
+Version 5.8.0 - 2020-11-02
+* Bug fixes (see mercurial logs for details)
+* Format timedelta in CSV export
+* Manage symbol widget
+* Fallback to model name as title
+* Set treeview footer sticky on bottom
+* Add get, in_ and contains methods to PYSON
+* Manage deletable and writable state
+* Support e-mail template
+* Always encode CSV export in UTF-8
+* Use tempusdominus and Popper for date time picker
+* Support PYSON comparison of date and datetime
+* Customize bootstrap default style
+* Set field's name as input's name attribute
+* Position copied records based on order
+* Sanitize translated RichtText fields content (issue9453)
+* Allow configuration of default colors for graph and calendar
+* Sanitize RichtText fields content (issue9405)
+* Escape external string (issue9394)
+* Keep context in sessionStorage
+* Use existing context for get_preferences
+* Escape external strings (issue9351)
+* Add context to export URL
+* Allow changes to editable tree checkboxes without first selecting the line
+
+Version 5.6.0 - 2020-05-04
+* Bug fixes (see mercurial logs for details)
+* Support link button on form
+* Add URL for the current export
+* Add option to export listed records
+* Set treeview header sticky on top
+* Add noreferrer noopener to external URL (issue9089)
+* Manage readonly dates in calendar view
+* Manage editable on calendar view
+* Manage named separator as label
+* Add MultiSelection entry to Dict field
+* Position new record based on order
+* Reset display_size of TreeView when group is cleared or changed
+* Allow relation field to be selected in CSV export
+* Hide empty cell on small screen
+* Support validate attribute of wizard's Button
+* Add infinite scroll
+
+Version 5.4.0 - 2019-11-04
+* Bug fixes (see mercurial logs for details)
+* Support visual context on tree view
+* Support multiselection field
+* Support dot notation on PYSON Eval
+* Manage sequence
+* Add drag and drop on tree views
+* Support expand on column
+* Set minimal width for columns
+* Order Dict keys by sequence
+* Support relation fields in domain parser
+* Add view modified
+* Add Dict widget for tree view
+
+Version 5.2.0 - 2019-05-06
+* Bug fixes (see mercurial logs for details)
+* Add domain inversion for reference fields
+* Add list-form view
+* Support HTML widget
+* Use locale format for data export
+* Add day view on calendar
+* Add CSV exports into print toolbar
+* Display unread and total of notes
+* Use resources method
+* Rename roundup.url configuration to bug.url
+* Use separate XML parser in Views
+* Add range selection with Shift-click
+* Use between numbers in filter box
+* Fill 'to' with 'from' value on filter box
+* Add tab domain in URL
+* Use properties
+* Allow sao classes to use javascript properties
+* Improve layout of CSV import/export
+* Add support for height and width on notebook
+* Use tab key for tab navigation
+* Use record and field properties of widget instead of method arguments
+* Reduce offset when no search result
+* Add support for plugins
+* Add support for expand, height and width attributes
+* Add drag & drop support on attachment button
+
+Version 5.0.0 - 2018-10-01
+* Bug fixes (see mercurial logs for details)
+* Prevent similar tab
+* Remove dialog for input file
+* Use dropdown for attachment
+* Manage icons in input
+* Support RTL language direction
+* Apply factor on domain parser
+* Use tab name in CSV Export/Import
+* Add bus management
+* Load custom CSS and Javascript
+* New icons
+* Support timestamp field
+* Validate dictionary items
+* Add (i)like support to domain inversion
+* Improve loading strategy by using views
+* Add support of width attribute on tree view
+* Use non conflicting keyboard shortcuts
+* Use the context to get the suffix of window name
+* Call on_change methods after setting default dtstart on calendar view
+* Allow to open in new tab Many2One and Reference with CTRL key
+* Store session in browser storage
+* Increase the space available for tab list
+* Allow to toggle menu on large screen
+* Manage URL and history
+
+Version 4.8.0 - 2018-04-23
+* Bug fixes (see mercurial logs for details)
+* Manage active field on search widget
+* Add position and length on list view
+* Reset record to its original state when discarding the popup window
+* Add support of expand attribute on group tag
+* Add the context model name in the screen context
+* Add sum of records on list view
+* Add shortcuts to Date and DateTime widgets
+* Use limit to expand tree
+* Use spellcheck and lang attributes for textbox widget
+* Support icon on page
+* Add keyword attribute to button tag
+* Support field name on image tag
+* Use input number and toLocaleString for numeric fields
+* Show related record names for all windows
+* Allow to edit Many2One from tree view
+* Use translated values when exporting Reference and Selection fields
+
+Version 4.6.0 - 2017-10-30
+* Bug fixes (see mercurial logs for details)
+* Allow to export model and record name of Reference fields
+* Re-position buttons on Binary/Image widget
+* Set focus on first visible input when modal is shown
+* Improve treeview headers
+* Add keyboard shortcuts
+* Update states of both toolbar and menu
+* Improve toolbar order
+* Use login details in title
+
+Version 4.4.0 - 2017-05-01
+* Bug fixes (see mercurial logs for details)
+* Manage help attribute on tree views
+* Manage color attribute on graph view
+* Add support for size on Many2Many
+* Allow to show plain text in password field
+
+Version 4.2.0 - 2016-11-28
+* Bug fixes (see mercurial logs for details)
+* Add PYSON Widget
+* Add CSV Import/Export
+* Manage translated field
+* Add favorites menu
+* Show records names in wizard title
+* Add support for datetime_field to Many2One, Reference
+* Add calendar view
+* Move info-bar to the top
+* Add noeval to PYSONDecoder
+* Add support for pyson_order on action window
+* Make datetimepicker locale aware
+* Restore tab default order when no manual change
+* Add support for column sorting
+* Manage confirm attribute on buttons
+* Call autocompletion when setting record value
+* Limit readonly state for xxx2Many
+* Simplify login with single database
+* Show records names in relate window title
+* Add support for count on Action Window Domains
+* Manage custom login process
+* Add erase on Many2One
+* Re-position icons on Many2One widget
+
+Version 4.0.0 - 2016-05-02
+* Bug fixes (see mercurial logs for details)
+* Timedelta uses 30 days for month
+* Manage context model of ir.action.act_window
+* Add Note
+
+Version 3.8.0 - 2015-11-02
+* Initial release
diff --git a/sao/COPYRIGHT b/sao/COPYRIGHT
new file mode 100644
index 0000000000..ae353044d7
--- /dev/null
+++ b/sao/COPYRIGHT
@@ -0,0 +1,21 @@
+Copyright (C) 2012-2022 Nicolas Évrard.
+Copyright (C) 2012-2022 Cédric Krier.
+Copyright (C) 2012-2014 Bertrand Chenal.
+Copyright (C) 2012-2022 B2CK SPRL.
+Copyright (C) 2019 Jitbit.
+Copyright (C) 2013 Thomas Park
+Copyright (C) 2020-2021 Maxime Richez
+Copyright (C) 2020-2021 SALUC SA
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
diff --git a/sao/Gruntfile.js b/sao/Gruntfile.js
new file mode 100644
index 0000000000..c33d334a8e
--- /dev/null
+++ b/sao/Gruntfile.js
@@ -0,0 +1,182 @@
+module.exports = function(grunt) {
+
+ var _ = grunt.util._;
+ var locales = ["bg", "ca", "cs", "de", "es", "es_419", "fr", "fa", "hu",
+ "it", "lo", "lt", "nl", "pl", "pt", "ru", "sl", "zh_CN"];
+ var jsfiles = [
+ 'src/sao.js',
+ 'src/rpc.js',
+ 'src/pyson.js',
+ 'src/session.js',
+ 'src/common.js',
+ 'src/model.js',
+ 'src/tab.js',
+ 'src/screen.js',
+ 'src/view.js',
+ 'src/view/form.js',
+ 'src/view/tree.js',
+ 'src/view/graph.js',
+ 'src/view/calendar.js',
+ 'src/view/list_form.js',
+ 'src/action.js',
+ 'src/window.js',
+ 'src/wizard.js',
+ 'src/board.js',
+ 'src/bus.js',
+ 'src/plugins.js',
+ 'src/html_sanitizer.js'
+ ];
+ var less_paths = [
+ 'src',
+ 'bower_components',
+ 'bower_components/bootstrap',
+ 'bower_components/bootstrap/less',
+ 'bower_components/bootstrap-rtl-ondemand/less',
+ ];
+
+ // Project configuration.
+ grunt.initConfig({
+ pkg: grunt.file.readJSON('package.json'),
+ xgettext: {
+ locale: {
+ files: {
+ javascript: jsfiles
+ },
+ options: {
+ functionName: "Sao.i18n.gettext",
+ potFile: "locale/messages.pot"
+ },
+ }
+ },
+ shell: {
+ options: {
+ failOnError: true
+ },
+ msgmerge: {
+ command: _.map(locales, function(locale) {
+ var po = "locale/" + locale + ".po";
+ return "msgmerge -U " + po + " locale/messages.pot;";
+ }).join("")
+ }
+ },
+ po2json: {
+ options: {
+ format: 'raw'
+ },
+ all: {
+ src: ['locale/*.po'],
+ dest: 'locale/'
+ }
+ },
+ concat: {
+ dist: {
+ src: jsfiles,
+ dest: 'dist/<%= pkg.name %>.js'
+ }
+ },
+ jshint: {
+ dist: {
+ options: {
+ jshintrc: 'src/.jshintrc'
+ },
+ src: ['dist/<%= pkg.name %>.js']
+ },
+ grunt: {
+ src: ['Gruntfile.js']
+ },
+ tests: {
+ options: {
+ jshintrc: 'tests/.jshintrc'
+ },
+ src: ['tests/*.js']
+ }
+ },
+ uglify: {
+ options: {
+ banner: '/*! <%= pkg.name %>-<%= pkg.version %> | GPL-3\n' +
+ 'This file is part of Tryton. ' +
+ 'The COPYRIGHT file at the top level of\n' +
+ 'this repository contains the full copyright notices ' +
+ 'and license terms. */\n'
+ },
+ dist: {
+ src: 'dist/<%= pkg.name %>.js',
+ dest: 'dist/<%= pkg.name %>.min.js'
+ }
+ },
+ less: {
+ dev: {
+ options: {
+ paths: less_paths,
+ },
+ files: {
+ 'dist/<%= pkg.name %>.css': 'src/sao.less'
+ }
+ },
+ 'default': {
+ options: {
+ paths: less_paths,
+ yuicompress: true
+ },
+ files: {
+ 'dist/<%= pkg.name %>.min.css': 'src/sao.less'
+ }
+ }
+ },
+ watch: {
+ scripts: {
+ files: ['src/**/*.js'],
+ tasks: ['concat', 'jshint']
+ },
+ styles: {
+ files: ['src/*.less'],
+ tasks: 'less:dev'
+ }
+ },
+ qunit: {
+ options: {
+ timeout: 300000,
+ puppeteer: {
+ headless: true,
+ args: [
+ '--no-sandbox',
+ ],
+ env: {
+ TZ: 'UTC',
+ },
+ },
+ },
+ all: ['tests/*.html']
+ }
+ });
+
+ grunt.loadNpmTasks('grunt-contrib-concat');
+ grunt.loadNpmTasks('grunt-contrib-jshint');
+ grunt.loadNpmTasks('grunt-contrib-uglify');
+ grunt.loadNpmTasks('grunt-contrib-less');
+ grunt.loadNpmTasks('grunt-po2json');
+
+ grunt.registerTask('default', 'Build for production.', function() {
+ grunt.task.run(['concat', 'jshint', 'uglify', 'less', 'po2json']);
+ });
+ grunt.registerTask('dev', 'Build for development.', function() {
+ grunt.task.run(['concat', 'jshint', 'less:dev']);
+ });
+ grunt.registerTask('devwatch', 'Watch development', function() {
+ grunt.loadNpmTasks('grunt-contrib-watch');
+ grunt.task.run(['watch']);
+ });
+ grunt.registerTask('msgmerge', 'Update locale messages.', function() {
+ grunt.loadNpmTasks('grunt-shell');
+ grunt.task.run(['shell:msgmerge']);
+ });
+ grunt.registerTask('xgettext', ' Extracts translatable messages', function() {
+ grunt.loadNpmTasks('grunt-xgettext');
+ grunt.task.run(['xgettext']);
+ });
+ grunt.registerTask('test', 'Run tests', function() {
+ grunt.loadNpmTasks('grunt-contrib-qunit');
+ grunt.task.run(['concat', 'jshint', 'less:dev', 'qunit']);
+ });
+
+};
diff --git a/sao/LICENSE b/sao/LICENSE
new file mode 100644
index 0000000000..94a9ed024d
--- /dev/null
+++ b/sao/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/sao/README.md b/sao/README.md
new file mode 100644
index 0000000000..c4bb4865ab
--- /dev/null
+++ b/sao/README.md
@@ -0,0 +1,29 @@
+sao
+===
+
+Prerequisites
+-------------
+
+ * Node.js 0.8.0 or later (http://nodejs.org/)
+
+Installation
+------------
+
+Once you've downloaded and unpacked the sao source release, enter the directory
+where the archive was unpacked, and run:
+
+ $ npm install --production --legacy-peer-deps
+
+Development
+...........
+
+For development, you have to run instead:
+
+ $ npm install --legacy-peer-deps
+ $ grunt dev
+
+Setup
+-----
+
+Note that the entry `root` in the section `[web]` of `trytond.conf` must be set
+to the directory where the package was unpacked.
diff --git a/sao/bower.json b/sao/bower.json
new file mode 100644
index 0000000000..4933c615cc
--- /dev/null
+++ b/sao/bower.json
@@ -0,0 +1,32 @@
+{
+ "name": "sao",
+ "version": "0.0.0",
+ "authors": [
+ "Tryton"
+ ],
+ "description": "Web client for Tryton",
+ "license": "GPL",
+ "homepage": "http://www.tryton.org/",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "jquery": "^3",
+ "bootstrap": "^3.3.7",
+ "moment": "^2.10",
+ "gettext.js": "^0.7",
+ "c3": "^0.7",
+ "papaparse": "^5.0",
+ "fullcalendar": "^3.10.2",
+ "mousetrap": "^1.6",
+ "bootstrap-rtl-ondemand": "^3.3.4-ondemand",
+ "Sortable": "sortablejs#^1.8.4"
+ },
+ "devDependencies": {
+ "qunit": "^1.18"
+ }
+}
diff --git a/sao/images/LICENSE b/sao/images/LICENSE
new file mode 100644
index 0000000000..7a4a3ea242
--- /dev/null
+++ b/sao/images/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
\ No newline at end of file
diff --git a/sao/images/tryton-add.svg b/sao/images/tryton-add.svg
new file mode 100644
index 0000000000..08cc2308c8
--- /dev/null
+++ b/sao/images/tryton-add.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-archive.svg b/sao/images/tryton-archive.svg
new file mode 100644
index 0000000000..a5d45991b7
--- /dev/null
+++ b/sao/images/tryton-archive.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-arrow-down.svg b/sao/images/tryton-arrow-down.svg
new file mode 100644
index 0000000000..c1204da1cd
--- /dev/null
+++ b/sao/images/tryton-arrow-down.svg
@@ -0,0 +1,7 @@
+
+
+
diff --git a/sao/images/tryton-arrow-left.svg b/sao/images/tryton-arrow-left.svg
new file mode 100644
index 0000000000..e084870266
--- /dev/null
+++ b/sao/images/tryton-arrow-left.svg
@@ -0,0 +1,7 @@
+
+
+
diff --git a/sao/images/tryton-arrow-right.svg b/sao/images/tryton-arrow-right.svg
new file mode 100644
index 0000000000..0f56374381
--- /dev/null
+++ b/sao/images/tryton-arrow-right.svg
@@ -0,0 +1,7 @@
+
+
+
diff --git a/sao/images/tryton-arrow-up.svg b/sao/images/tryton-arrow-up.svg
new file mode 100644
index 0000000000..b3d21d3434
--- /dev/null
+++ b/sao/images/tryton-arrow-up.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-attach.svg b/sao/images/tryton-attach.svg
new file mode 100644
index 0000000000..23979032c2
--- /dev/null
+++ b/sao/images/tryton-attach.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-back.svg b/sao/images/tryton-back.svg
new file mode 100644
index 0000000000..7ff9f9c11a
--- /dev/null
+++ b/sao/images/tryton-back.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-bookmark-border.svg b/sao/images/tryton-bookmark-border.svg
new file mode 100644
index 0000000000..abcd01628a
--- /dev/null
+++ b/sao/images/tryton-bookmark-border.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-bookmark.svg b/sao/images/tryton-bookmark.svg
new file mode 100644
index 0000000000..8b5a0a5539
--- /dev/null
+++ b/sao/images/tryton-bookmark.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-bookmarks.svg b/sao/images/tryton-bookmarks.svg
new file mode 100644
index 0000000000..79839be669
--- /dev/null
+++ b/sao/images/tryton-bookmarks.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-cancel.svg b/sao/images/tryton-cancel.svg
new file mode 100644
index 0000000000..b2dac49d45
--- /dev/null
+++ b/sao/images/tryton-cancel.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-clear.svg b/sao/images/tryton-clear.svg
new file mode 100644
index 0000000000..289d406e75
--- /dev/null
+++ b/sao/images/tryton-clear.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-close.svg b/sao/images/tryton-close.svg
new file mode 100644
index 0000000000..289d406e75
--- /dev/null
+++ b/sao/images/tryton-close.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-copy.svg b/sao/images/tryton-copy.svg
new file mode 100644
index 0000000000..dbd8b0cfc2
--- /dev/null
+++ b/sao/images/tryton-copy.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-create.svg b/sao/images/tryton-create.svg
new file mode 100644
index 0000000000..f1b885f1c2
--- /dev/null
+++ b/sao/images/tryton-create.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-date.svg b/sao/images/tryton-date.svg
new file mode 100644
index 0000000000..1aab65c4e6
--- /dev/null
+++ b/sao/images/tryton-date.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-delete.svg b/sao/images/tryton-delete.svg
new file mode 100644
index 0000000000..9308f4df56
--- /dev/null
+++ b/sao/images/tryton-delete.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-drag.svg b/sao/images/tryton-drag.svg
new file mode 100644
index 0000000000..b8d36b16f0
--- /dev/null
+++ b/sao/images/tryton-drag.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/sao/images/tryton-email.svg b/sao/images/tryton-email.svg
new file mode 100644
index 0000000000..e1560c6374
--- /dev/null
+++ b/sao/images/tryton-email.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-error.svg b/sao/images/tryton-error.svg
new file mode 100644
index 0000000000..19c6c83163
--- /dev/null
+++ b/sao/images/tryton-error.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-exit.svg b/sao/images/tryton-exit.svg
new file mode 100644
index 0000000000..dbd95bfd9c
--- /dev/null
+++ b/sao/images/tryton-exit.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-export.svg b/sao/images/tryton-export.svg
new file mode 100644
index 0000000000..41628798b2
--- /dev/null
+++ b/sao/images/tryton-export.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-filter.svg b/sao/images/tryton-filter.svg
new file mode 100644
index 0000000000..f0a2e4f31f
--- /dev/null
+++ b/sao/images/tryton-filter.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-format-align-center.svg b/sao/images/tryton-format-align-center.svg
new file mode 100644
index 0000000000..75873e9185
--- /dev/null
+++ b/sao/images/tryton-format-align-center.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-format-align-justify.svg b/sao/images/tryton-format-align-justify.svg
new file mode 100644
index 0000000000..288727edfc
--- /dev/null
+++ b/sao/images/tryton-format-align-justify.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-format-align-left.svg b/sao/images/tryton-format-align-left.svg
new file mode 100644
index 0000000000..97645a3295
--- /dev/null
+++ b/sao/images/tryton-format-align-left.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-format-align-right.svg b/sao/images/tryton-format-align-right.svg
new file mode 100644
index 0000000000..c073397046
--- /dev/null
+++ b/sao/images/tryton-format-align-right.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-format-bold.svg b/sao/images/tryton-format-bold.svg
new file mode 100644
index 0000000000..ca6b4b63ce
--- /dev/null
+++ b/sao/images/tryton-format-bold.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-format-color-text.svg b/sao/images/tryton-format-color-text.svg
new file mode 100644
index 0000000000..4bda2cb107
--- /dev/null
+++ b/sao/images/tryton-format-color-text.svg
@@ -0,0 +1,5 @@
+
diff --git a/sao/images/tryton-format-italic.svg b/sao/images/tryton-format-italic.svg
new file mode 100644
index 0000000000..fa65b97d56
--- /dev/null
+++ b/sao/images/tryton-format-italic.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-format-underline.svg b/sao/images/tryton-format-underline.svg
new file mode 100644
index 0000000000..8615187f44
--- /dev/null
+++ b/sao/images/tryton-format-underline.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-forward.svg b/sao/images/tryton-forward.svg
new file mode 100644
index 0000000000..2ca445703a
--- /dev/null
+++ b/sao/images/tryton-forward.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-history.svg b/sao/images/tryton-history.svg
new file mode 100644
index 0000000000..05f201a445
--- /dev/null
+++ b/sao/images/tryton-history.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-icon.png b/sao/images/tryton-icon.png
new file mode 100644
index 0000000000..f26821a927
Binary files /dev/null and b/sao/images/tryton-icon.png differ
diff --git a/sao/images/tryton-import.svg b/sao/images/tryton-import.svg
new file mode 100644
index 0000000000..f093479f99
--- /dev/null
+++ b/sao/images/tryton-import.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-info.svg b/sao/images/tryton-info.svg
new file mode 100644
index 0000000000..5b31235b88
--- /dev/null
+++ b/sao/images/tryton-info.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-launch.svg b/sao/images/tryton-launch.svg
new file mode 100644
index 0000000000..7479e92628
--- /dev/null
+++ b/sao/images/tryton-launch.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-link.svg b/sao/images/tryton-link.svg
new file mode 100644
index 0000000000..08d13d80da
--- /dev/null
+++ b/sao/images/tryton-link.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-log.svg b/sao/images/tryton-log.svg
new file mode 100644
index 0000000000..3bcd81e84c
--- /dev/null
+++ b/sao/images/tryton-log.svg
@@ -0,0 +1,5 @@
+
diff --git a/sao/images/tryton-menu.svg b/sao/images/tryton-menu.svg
new file mode 100644
index 0000000000..37e9cfb552
--- /dev/null
+++ b/sao/images/tryton-menu.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-note.svg b/sao/images/tryton-note.svg
new file mode 100644
index 0000000000..a10719ede4
--- /dev/null
+++ b/sao/images/tryton-note.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-ok.svg b/sao/images/tryton-ok.svg
new file mode 100644
index 0000000000..535ff0390a
--- /dev/null
+++ b/sao/images/tryton-ok.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-open.svg b/sao/images/tryton-open.svg
new file mode 100644
index 0000000000..f33176ea28
--- /dev/null
+++ b/sao/images/tryton-open.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-print.svg b/sao/images/tryton-print.svg
new file mode 100644
index 0000000000..7ffc5851fd
--- /dev/null
+++ b/sao/images/tryton-print.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-public.svg b/sao/images/tryton-public.svg
new file mode 100644
index 0000000000..24d6e503ed
--- /dev/null
+++ b/sao/images/tryton-public.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-question.svg b/sao/images/tryton-question.svg
new file mode 100644
index 0000000000..ac7a46002d
--- /dev/null
+++ b/sao/images/tryton-question.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/sao/images/tryton-refresh.svg b/sao/images/tryton-refresh.svg
new file mode 100644
index 0000000000..e9618ab4f9
--- /dev/null
+++ b/sao/images/tryton-refresh.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-remove.svg b/sao/images/tryton-remove.svg
new file mode 100644
index 0000000000..ab7f7ba90e
--- /dev/null
+++ b/sao/images/tryton-remove.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-save.svg b/sao/images/tryton-save.svg
new file mode 100644
index 0000000000..3754a0cf0d
--- /dev/null
+++ b/sao/images/tryton-save.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-search.svg b/sao/images/tryton-search.svg
new file mode 100644
index 0000000000..6859898f79
--- /dev/null
+++ b/sao/images/tryton-search.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-send.svg b/sao/images/tryton-send.svg
new file mode 100644
index 0000000000..033ab7a11a
--- /dev/null
+++ b/sao/images/tryton-send.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/sao/images/tryton-star-border.svg b/sao/images/tryton-star-border.svg
new file mode 100644
index 0000000000..21862f2cd7
--- /dev/null
+++ b/sao/images/tryton-star-border.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-star.svg b/sao/images/tryton-star.svg
new file mode 100644
index 0000000000..2b5e942ef8
--- /dev/null
+++ b/sao/images/tryton-star.svg
@@ -0,0 +1,5 @@
+
diff --git a/sao/images/tryton-switch.svg b/sao/images/tryton-switch.svg
new file mode 100644
index 0000000000..cc607585b9
--- /dev/null
+++ b/sao/images/tryton-switch.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-translate.svg b/sao/images/tryton-translate.svg
new file mode 100644
index 0000000000..e0ed1220a3
--- /dev/null
+++ b/sao/images/tryton-translate.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-unarchive.svg b/sao/images/tryton-unarchive.svg
new file mode 100644
index 0000000000..765b534c0a
--- /dev/null
+++ b/sao/images/tryton-unarchive.svg
@@ -0,0 +1,9 @@
+
diff --git a/sao/images/tryton-undo.svg b/sao/images/tryton-undo.svg
new file mode 100644
index 0000000000..6763ef40d0
--- /dev/null
+++ b/sao/images/tryton-undo.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/images/tryton-warning.svg b/sao/images/tryton-warning.svg
new file mode 100644
index 0000000000..4a0fa05996
--- /dev/null
+++ b/sao/images/tryton-warning.svg
@@ -0,0 +1,4 @@
+
diff --git a/sao/index.html b/sao/index.html
new file mode 100644
index 0000000000..302f961cf4
--- /dev/null
+++ b/sao/index.html
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+ Tryton
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sao/locale/bg.po b/sao/locale/bg.po
new file mode 100644
index 0000000000..f49926a686
--- /dev/null
+++ b/sao/locale/bg.po
@@ -0,0 +1,649 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr ""
+
+msgid "Manage..."
+msgstr ""
+
+msgid "Logout"
+msgstr ""
+
+msgid "Action"
+msgstr ""
+
+msgid "New"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Switch"
+msgstr ""
+
+msgid "Reload/Undo"
+msgstr ""
+
+msgid "Duplicate"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
+msgid "Search"
+msgstr ""
+
+msgid "Close Tab"
+msgstr ""
+
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
+msgid "Relate"
+msgstr ""
+
+msgid "Print"
+msgstr ""
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr ""
+
+msgid "Next tab"
+msgstr ""
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr ""
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr ""
+
+msgid "User name"
+msgstr ""
+
+msgid "Database"
+msgstr ""
+
+msgid "Your selection:"
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Y"
+msgstr ""
+
+msgid "M"
+msgstr ""
+
+msgid "w"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "h"
+msgstr ""
+
+msgid "m"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "By: "
+msgstr ""
+
+#, fuzzy
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "True"
+msgstr ""
+
+msgid "t"
+msgstr ""
+
+msgid "False"
+msgstr ""
+
+msgid "Message: "
+msgstr ""
+
+msgid "Warning: "
+msgstr ""
+
+msgid "Always ignore this warning."
+msgstr ""
+
+msgid "Do you want to proceed?"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Confirmation: "
+msgstr ""
+
+msgid "Concurrency Exception"
+msgstr ""
+
+msgid "Write Concurrency Warning: "
+msgstr ""
+
+msgid "This record has been modified while you were editing it."
+msgstr ""
+
+msgid "Choose:"
+msgstr ""
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr ""
+
+msgid "\"Compare\" to see the modified version;"
+msgstr ""
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Compare: %1"
+msgstr ""
+
+msgid "Write Anyway"
+msgstr ""
+
+msgid "Application Error"
+msgstr ""
+
+msgid "Report Bug"
+msgstr ""
+
+msgid "Processing"
+msgstr ""
+
+msgid "Search..."
+msgstr ""
+
+msgid "Create..."
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Switch view"
+msgstr ""
+
+msgid "Previous Record"
+msgstr ""
+
+msgid "Next Record"
+msgstr ""
+
+msgid "Create a new record"
+msgstr ""
+
+msgid "Save this record"
+msgstr ""
+
+msgid "Reload"
+msgstr ""
+
+msgid "View Logs..."
+msgstr ""
+
+msgid "Show revisions..."
+msgstr ""
+
+msgid "Add an attachment to the record"
+msgstr ""
+
+msgid "Add a note to the record"
+msgstr ""
+
+msgid "E-Mail..."
+msgstr ""
+
+msgid "Send an e-mail using the record"
+msgstr ""
+
+msgid "Export"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+
+msgid "Launch action"
+msgstr ""
+
+msgid "Open related records"
+msgstr ""
+
+msgid "Print report"
+msgstr ""
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+
+msgid "Record saved."
+msgstr ""
+
+msgid "Working now on the duplicated record(s)."
+msgstr ""
+
+msgid "Are you sure to remove this record?"
+msgstr ""
+
+msgid "Are you sure to remove those records?"
+msgstr ""
+
+msgid "Records removed."
+msgstr ""
+
+msgid "Records not removed."
+msgstr ""
+
+msgid "You have to select one record."
+msgstr ""
+
+msgid "ID:"
+msgstr ""
+
+msgid "Created by:"
+msgstr ""
+
+msgid "Created at:"
+msgstr ""
+
+msgid "Edited by:"
+msgstr ""
+
+msgid "Edited at:"
+msgstr ""
+
+msgid "Model: "
+msgstr ""
+
+msgid "Add..."
+msgstr ""
+
+msgid "Preview"
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Attachment (%1)"
+msgstr ""
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr ""
+
+msgid "Filters"
+msgstr ""
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr ""
+
+msgid "Remove this bookmark"
+msgstr ""
+
+msgid "Bookmark this filter"
+msgstr ""
+
+msgid "Bookmark Name:"
+msgstr ""
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr ""
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "Created by"
+msgstr ""
+
+msgid "Created at"
+msgstr ""
+
+msgid "Modified by"
+msgstr ""
+
+msgid "Modified at"
+msgstr ""
+
+msgid "\"%1\" is required."
+msgstr ""
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr ""
+
+msgid "The values of \"%1\" are not valid."
+msgstr ""
+
+msgid "Pre-validation"
+msgstr ""
+
+msgid ":"
+msgstr ""
+
+msgid "Translate"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Fuzzy"
+msgstr ""
+
+msgid "You need to save the record before adding translations."
+msgstr ""
+
+msgid "No other language available."
+msgstr ""
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Open"
+msgstr ""
+
+msgid "Undelete"
+msgstr ""
+
+msgid "Save As"
+msgstr ""
+
+msgid "Save As..."
+msgstr ""
+
+msgid "Select"
+msgstr ""
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr ""
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr ""
+
+#, fuzzy
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr ""
+
+msgid "Today"
+msgstr ""
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr ""
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr ""
+
+msgid "Select your action"
+msgstr ""
+
+msgid "No action defined."
+msgstr ""
+
+msgid "Attachments (%1)"
+msgstr ""
+
+msgid "Notes (%1)"
+msgstr ""
+
+msgid "Search %1"
+msgstr ""
+
+msgid "Revision"
+msgstr ""
+
+msgid "All Fields"
+msgstr ""
+
+msgid "Fields Selected"
+msgstr ""
+
+msgid "CSV Parameters"
+msgstr ""
+
+msgid "Delimiter:"
+msgstr ""
+
+msgid "Quote Char:"
+msgstr ""
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr ""
+
+msgid "File to Import"
+msgstr ""
+
+msgid "Encoding:"
+msgstr ""
+
+msgid "Lines to Skip:"
+msgstr ""
+
+msgid "You must select an import file first."
+msgstr ""
+
+msgid "An error occured in loading the file."
+msgstr ""
+
+msgid "Error processing the file at field %1."
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Error occured in loading the file"
+msgstr ""
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr ""
+
+msgid "URL Export"
+msgstr ""
+
+msgid "Delete Export"
+msgstr ""
+
+msgid "Predefined Exports"
+msgstr ""
+
+msgid "Selected Records"
+msgstr ""
+
+msgid "Listed Records"
+msgstr ""
+
+msgid "Export:"
+msgstr ""
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr ""
+
+msgid "%1 (string)"
+msgstr ""
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr ""
+
+msgid "Override %1 definition?"
+msgstr ""
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+msgid "Reports"
+msgstr ""
+
+msgid "Attachments"
+msgstr ""
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+msgid "Remove File"
+msgstr ""
+
+msgid "Wizard"
+msgstr ""
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/ca.po b/sao/locale/ca.po
new file mode 100644
index 0000000000..42a3a5698c
--- /dev/null
+++ b/sao/locale/ca.po
@@ -0,0 +1,667 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 15 2019 16:53:42 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 01 2019 13:14:07 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Mar 01 2019 00:18:48 GMT+0100 (CET)
+# Generated by grunt-xgettext on Fri Feb 01 2019 00:07:47 GMT+0100 (CET)
+# Generated by grunt-xgettext on Tue Jan 01 2019 00:13:07 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sat Dec 01 2018 00:17:31 GMT+0100 (CET)
+# Generated by grunt-xgettext on Thu Nov 01 2018 00:08:43 GMT+0100 (CET)
+# Generated by grunt-xgettext on Mon Oct 01 2018 00:07:22 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Sep 14 2018 22:59:37 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sun Sep 09 2018 10:24:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Sep 04 2018 13:54:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 14 2018 17:56:54 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Apr 06 2018 22:57:49 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Oct 09 2017 19:35:04 GMT+0200 (CEST)
+msgid "Are your sure to leave?"
+msgstr "Esteu segur que voleu sortir?"
+
+msgid "Favorites"
+msgstr "Preferits"
+
+msgid "Manage..."
+msgstr "Gestiona..."
+
+# Generated by grunt-xgettext on Thu Mar 31 2016 17:50:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Oct 16 2015 17:37:32 GMT+0200 (CEST)
+msgid "Logout"
+msgstr "Sortir"
+
+msgid "Action"
+msgstr "Acció"
+
+msgid "New"
+msgstr "Nou"
+
+msgid "Save"
+msgstr "Desa"
+
+msgid "Switch"
+msgstr "Canvia la vista"
+
+msgid "Reload/Undo"
+msgstr "Recarrega/Desfés"
+
+msgid "Duplicate"
+msgstr "Duplica"
+
+msgid "Delete"
+msgstr "Elimina"
+
+msgid "Previous"
+msgstr "Anterior"
+
+msgid "Next"
+msgstr "Següent"
+
+msgid "Search"
+msgstr "Cerca"
+
+msgid "Close Tab"
+msgstr "Tanca pestanya"
+
+msgid "Attachment"
+msgstr "Adjunt"
+
+msgid "Note"
+msgstr "Nota"
+
+msgid "Relate"
+msgstr "Relacionat"
+
+msgid "Print"
+msgstr "Imprimeix"
+
+msgid "E-Mail"
+msgstr "Correu electrònic"
+
+msgid "Previous tab"
+msgstr "Pestanya anterior"
+
+msgid "Next tab"
+msgstr "Pestanya següent"
+
+msgid "Global search"
+msgstr "Cerca global"
+
+msgid "Show this help"
+msgstr "Mostra aquesta ajuda"
+
+msgid "Keyboard shortcuts"
+msgstr "Dreceres de teclat"
+
+msgid "Close"
+msgstr "Tanca"
+
+msgid "Global shortcuts"
+msgstr "Dreceres globals"
+
+msgid "Tab shortcuts"
+msgstr "Dreceres de la pestanya"
+
+msgid "Unable to reach the server."
+msgstr "No s'ha pogut connectar amb el servidor."
+
+msgid "Too many requests. Try again later."
+msgstr "Massa peticions. Proveu-ho de nou més tard."
+
+msgid "Login"
+msgstr "Accedeix"
+
+msgid "User name"
+msgstr "Nom d'usuari"
+
+msgid "Database"
+msgstr "Base de dades"
+
+msgid "Your selection:"
+msgstr "La vostra selecció:"
+
+msgid "Cancel"
+msgstr "Cancel·la"
+
+msgid "OK"
+msgstr "D'acord"
+
+msgid "Y"
+msgstr "A"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "S"
+
+msgid "d"
+msgstr "d"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "Per: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "a"
+
+msgid "Yes"
+msgstr "Si"
+
+msgid "True"
+msgstr "Verdader"
+
+msgid "t"
+msgstr "v"
+
+msgid "False"
+msgstr "Fals"
+
+msgid "Message: "
+msgstr "Missatge: "
+
+msgid "Warning: "
+msgstr "Avs: "
+
+msgid "Always ignore this warning."
+msgstr "Ignora sempre aquest advertiment."
+
+msgid "Do you want to proceed?"
+msgstr "Voleu continuar?"
+
+msgid "No"
+msgstr "No"
+
+msgid "Confirmation: "
+msgstr "Confirmaci: "
+
+msgid "Concurrency Exception"
+msgstr "Excepció de concurrència"
+
+msgid "Write Concurrency Warning: "
+msgstr "Avís de concurrència d'escriptura: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "Aquest registre ha estat modificat mentre l'editàveu."
+
+msgid "Choose:"
+msgstr "Trieu:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"Cancel·la\" per no desar;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"Compara\" per veure la versi modificada;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"Desa de totes formes\" per desar els vostres canvis."
+
+msgid "Compare"
+msgstr "Compara"
+
+msgid "Compare: %1"
+msgstr "Compara: %1"
+
+msgid "Write Anyway"
+msgstr "Desa de totes formes"
+
+msgid "Application Error"
+msgstr "Error d'aplicació"
+
+msgid "Report Bug"
+msgstr "Informa de l'error"
+
+msgid "Processing"
+msgstr "Processant"
+
+msgid "Search..."
+msgstr "Cerca..."
+
+msgid "Create..."
+msgstr "Crea..."
+
+msgid "Download"
+msgstr "Baixa"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Tipus de lletra"
+
+msgid "Size"
+msgstr "Mida"
+
+msgid "Switch view"
+msgstr "Canvia la vista"
+
+msgid "Previous Record"
+msgstr "Registre anterior"
+
+msgid "Next Record"
+msgstr "Registre següent"
+
+msgid "Create a new record"
+msgstr "Crea un nou registre"
+
+msgid "Save this record"
+msgstr "Desa aquest registre"
+
+msgid "Reload"
+msgstr "Recarrega"
+
+msgid "View Logs..."
+msgstr "Veure registre..."
+
+msgid "Show revisions..."
+msgstr "Mostra revisions..."
+
+msgid "Add an attachment to the record"
+msgstr "Afegeix un adjunt al registre"
+
+msgid "Add a note to the record"
+msgstr "Afegeix una nota al registre"
+
+msgid "E-Mail..."
+msgstr "Correu electrònic..."
+
+msgid "Send an e-mail using the record"
+msgstr "Envia un correu electrònic utilitzant el registre"
+
+msgid "Export"
+msgstr "Exporta"
+
+msgid "Import"
+msgstr "Importa"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"L'acció seleccionada requereix tancar totes les pestanyes.\n"
+"Voleu continuar?"
+
+msgid "Launch action"
+msgstr "Executa acció"
+
+msgid "Open related records"
+msgstr "Obre registres relacionats"
+
+msgid "Print report"
+msgstr "Imprimeix informe"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Aquest registre ha estat modificat.\n"
+"Voleu desar-lo?"
+
+msgid "Record saved."
+msgstr "Registre desat."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Està treballant amb un registre(s) duplicat."
+
+msgid "Are you sure to remove this record?"
+msgstr "Esteu segur que voleu eliminar aquest registre?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Esteu segur que voleu eliminar aquests registres?"
+
+msgid "Records removed."
+msgstr "Registres eliminats."
+
+msgid "Records not removed."
+msgstr "Els registres no s'han eliminat."
+
+msgid "You have to select one record."
+msgstr "Ha de seleccionar un registre."
+
+msgid "ID:"
+msgstr "Identificador:"
+
+msgid "Created by:"
+msgstr "Creat per:"
+
+msgid "Created at:"
+msgstr "Creat el:"
+
+msgid "Edited by:"
+msgstr "Editat per:"
+
+msgid "Edited at:"
+msgstr "Editat el:"
+
+msgid "Model: "
+msgstr "Model: "
+
+msgid "Add..."
+msgstr "Afegeix..."
+
+msgid "Preview"
+msgstr "Previsualitza"
+
+msgid "Template"
+msgstr "Plantilla"
+
+msgid "Attachment (%1)"
+msgstr "Adjunts (%1)"
+
+msgid "Note (%1/%2)"
+msgstr "Nota (%1/%2)"
+
+msgid " of "
+msgstr " de "
+
+msgid "Filters"
+msgstr "Filtres"
+
+msgid "Clear Search"
+msgstr "Netejar la cerca"
+
+msgid "Bookmarks"
+msgstr "Cerques preferides"
+
+msgid "Remove this bookmark"
+msgstr "Elimina de les cerques preferides"
+
+msgid "Bookmark this filter"
+msgstr "Desa com a cerca preferida"
+
+msgid "Bookmark Name:"
+msgstr "Nom de la cerca preferida:"
+
+msgid "Show active records"
+msgstr "Mostra registres actius"
+
+msgid "Show inactive records"
+msgstr "Mostra registres inactius"
+
+msgid "Find"
+msgstr "Cerca"
+
+msgid "From"
+msgstr "De"
+
+msgid "To"
+msgstr "A"
+
+msgid "Open the calendar"
+msgstr "Obre el calendari"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Created by"
+msgstr "Creat per"
+
+msgid "Created at"
+msgstr "Creat el"
+
+msgid "Modified by"
+msgstr "Modificat per"
+
+msgid "Modified at"
+msgstr "Modificat el"
+
+msgid "\"%1\" is required."
+msgstr "\"%1\" s obligatori."
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" no és vàlid segons el seu domini."
+
+msgid "The values of \"%1\" are not valid."
+msgstr "Els valors de \"%1\" no són vàlids."
+
+msgid "Pre-validation"
+msgstr "Prevalidació"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Tradueix"
+
+msgid "Edit"
+msgstr "Edita"
+
+msgid "Fuzzy"
+msgstr "Dubtosa"
+
+msgid "You need to save the record before adding translations."
+msgstr "Heu de desar el registre abans d'afegir traduccions."
+
+msgid "No other language available."
+msgstr "No hi ha cap altre idioma disponible."
+
+msgid "Show"
+msgstr "Mostra"
+
+msgid "Hide"
+msgstr "Amaga"
+
+msgid "Open the record"
+msgstr "Obre el registre"
+
+msgid "Clear the field"
+msgstr "Buida el camp"
+
+msgid "Search a record"
+msgstr "Cerca un registre"
+
+msgid "Add"
+msgstr "Afegeix"
+
+msgid "Remove"
+msgstr "Elimina"
+
+msgid "Open"
+msgstr "Obre"
+
+msgid "Undelete"
+msgstr "Recupera"
+
+msgid "Save As"
+msgstr "Anomena i desa"
+
+msgid "Save As..."
+msgstr "Desa com..."
+
+msgid "Select"
+msgstr "Selecciona"
+
+msgid "Select..."
+msgstr "Selecciona..."
+
+msgid "Clear"
+msgstr "Neteja"
+
+msgid "Choose a language"
+msgstr "Escull un idioma"
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "Més"
+
+msgid "Today"
+msgstr "Avui"
+
+msgid "Month"
+msgstr "Mes"
+
+msgid "Week"
+msgstr "Setmana"
+
+msgid "Day"
+msgstr "Dia"
+
+msgid ",..."
+msgstr ",..."
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Seleccioneu la vostra acció"
+
+msgid "No action defined."
+msgstr "No s'ha definit cap acció."
+
+msgid "Attachments (%1)"
+msgstr "Adjunts (%1)"
+
+msgid "Notes (%1)"
+msgstr "Notes (%1)"
+
+msgid "Search %1"
+msgstr "Cerca %1"
+
+msgid "Revision"
+msgstr "Revisió"
+
+msgid "All Fields"
+msgstr "Tots els camps"
+
+msgid "Fields Selected"
+msgstr "Camps seleccionats"
+
+msgid "CSV Parameters"
+msgstr "Paràmetres CSV"
+
+msgid "Delimiter:"
+msgstr "Separador:"
+
+msgid "Quote Char:"
+msgstr "Delimitador de text:"
+
+msgid "CSV Import: %1"
+msgstr "Importació CSV: %1"
+
+msgid "Auto-Detect"
+msgstr "Detecta automàticament"
+
+msgid "File to Import"
+msgstr "Fitxer a importar"
+
+msgid "Encoding:"
+msgstr "Codificació:"
+
+msgid "Lines to Skip:"
+msgstr "Línies a ometre:"
+
+msgid "You must select an import file first."
+msgstr "Primer heu de seleccionar un fitxer a importar."
+
+msgid "An error occured in loading the file."
+msgstr "S'ha produït un error al carregar el fitxer."
+
+msgid "Error processing the file at field %1."
+msgstr "S'ha produït un error al processar el fitxer al camp %1."
+
+msgid "Error"
+msgstr "Error"
+
+msgid "Error occured in loading the file"
+msgstr "S'ha produït un error al carregar el fitxer"
+
+msgid "CSV Export: %1"
+msgstr "Exportació CSV: %1"
+
+msgid "Save Export"
+msgstr "Desa l'exportació"
+
+msgid "URL Export"
+msgstr "URL Exportació"
+
+msgid "Delete Export"
+msgstr "Elimina l'exportació"
+
+msgid "Predefined Exports"
+msgstr "Exportacions predefinides"
+
+msgid "Selected Records"
+msgstr "Registres seleccionats"
+
+msgid "Listed Records"
+msgstr "Registres llistats"
+
+msgid "Export:"
+msgstr "Exportar:"
+
+msgid "Ignore search limit"
+msgstr "Ignora límit de cerca"
+
+msgid "Use locale format"
+msgstr "Utilitza format local"
+
+msgid "Add Field Names"
+msgstr "Afegeix noms dels camps"
+
+msgid "%1 (string)"
+msgstr "%1 (cadena)"
+
+msgid "%1 (model name)"
+msgstr "%1 (nom del model)"
+
+msgid "%1 (record name)"
+msgstr "%1 (nom del registre)"
+
+msgid "What is the name of this export?"
+msgstr "Quin és el nom d'aquesta exportació?"
+
+msgid "Override %1 definition?"
+msgstr "Voleu sobreescriure la definició %1?"
+
+msgid "E-mail %1"
+msgstr "Correu electrònic %1"
+
+msgid "To:"
+msgstr "A:"
+
+msgid "Cc:"
+msgstr "Cc:"
+
+msgid "Bcc:"
+msgstr "Cco:"
+
+msgid "Subject:"
+msgstr "Assumpte:"
+
+msgid "Reports"
+msgstr "Informes"
+
+msgid "Attachments"
+msgstr "Adjunts"
+
+msgid "Files"
+msgstr "Fitxers"
+
+msgid "Send"
+msgstr "Envia"
+
+msgid "Remove File"
+msgstr "Elimina fitxer"
+
+msgid "Wizard"
+msgstr "Assistent"
+
+msgid "Translate view"
+msgstr "Tradueix la vista"
diff --git a/sao/locale/cs.po b/sao/locale/cs.po
new file mode 100644
index 0000000000..f49926a686
--- /dev/null
+++ b/sao/locale/cs.po
@@ -0,0 +1,649 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr ""
+
+msgid "Manage..."
+msgstr ""
+
+msgid "Logout"
+msgstr ""
+
+msgid "Action"
+msgstr ""
+
+msgid "New"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Switch"
+msgstr ""
+
+msgid "Reload/Undo"
+msgstr ""
+
+msgid "Duplicate"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
+msgid "Search"
+msgstr ""
+
+msgid "Close Tab"
+msgstr ""
+
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
+msgid "Relate"
+msgstr ""
+
+msgid "Print"
+msgstr ""
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr ""
+
+msgid "Next tab"
+msgstr ""
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr ""
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr ""
+
+msgid "User name"
+msgstr ""
+
+msgid "Database"
+msgstr ""
+
+msgid "Your selection:"
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Y"
+msgstr ""
+
+msgid "M"
+msgstr ""
+
+msgid "w"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "h"
+msgstr ""
+
+msgid "m"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "By: "
+msgstr ""
+
+#, fuzzy
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "True"
+msgstr ""
+
+msgid "t"
+msgstr ""
+
+msgid "False"
+msgstr ""
+
+msgid "Message: "
+msgstr ""
+
+msgid "Warning: "
+msgstr ""
+
+msgid "Always ignore this warning."
+msgstr ""
+
+msgid "Do you want to proceed?"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Confirmation: "
+msgstr ""
+
+msgid "Concurrency Exception"
+msgstr ""
+
+msgid "Write Concurrency Warning: "
+msgstr ""
+
+msgid "This record has been modified while you were editing it."
+msgstr ""
+
+msgid "Choose:"
+msgstr ""
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr ""
+
+msgid "\"Compare\" to see the modified version;"
+msgstr ""
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Compare: %1"
+msgstr ""
+
+msgid "Write Anyway"
+msgstr ""
+
+msgid "Application Error"
+msgstr ""
+
+msgid "Report Bug"
+msgstr ""
+
+msgid "Processing"
+msgstr ""
+
+msgid "Search..."
+msgstr ""
+
+msgid "Create..."
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Switch view"
+msgstr ""
+
+msgid "Previous Record"
+msgstr ""
+
+msgid "Next Record"
+msgstr ""
+
+msgid "Create a new record"
+msgstr ""
+
+msgid "Save this record"
+msgstr ""
+
+msgid "Reload"
+msgstr ""
+
+msgid "View Logs..."
+msgstr ""
+
+msgid "Show revisions..."
+msgstr ""
+
+msgid "Add an attachment to the record"
+msgstr ""
+
+msgid "Add a note to the record"
+msgstr ""
+
+msgid "E-Mail..."
+msgstr ""
+
+msgid "Send an e-mail using the record"
+msgstr ""
+
+msgid "Export"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+
+msgid "Launch action"
+msgstr ""
+
+msgid "Open related records"
+msgstr ""
+
+msgid "Print report"
+msgstr ""
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+
+msgid "Record saved."
+msgstr ""
+
+msgid "Working now on the duplicated record(s)."
+msgstr ""
+
+msgid "Are you sure to remove this record?"
+msgstr ""
+
+msgid "Are you sure to remove those records?"
+msgstr ""
+
+msgid "Records removed."
+msgstr ""
+
+msgid "Records not removed."
+msgstr ""
+
+msgid "You have to select one record."
+msgstr ""
+
+msgid "ID:"
+msgstr ""
+
+msgid "Created by:"
+msgstr ""
+
+msgid "Created at:"
+msgstr ""
+
+msgid "Edited by:"
+msgstr ""
+
+msgid "Edited at:"
+msgstr ""
+
+msgid "Model: "
+msgstr ""
+
+msgid "Add..."
+msgstr ""
+
+msgid "Preview"
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Attachment (%1)"
+msgstr ""
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr ""
+
+msgid "Filters"
+msgstr ""
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr ""
+
+msgid "Remove this bookmark"
+msgstr ""
+
+msgid "Bookmark this filter"
+msgstr ""
+
+msgid "Bookmark Name:"
+msgstr ""
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr ""
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "Created by"
+msgstr ""
+
+msgid "Created at"
+msgstr ""
+
+msgid "Modified by"
+msgstr ""
+
+msgid "Modified at"
+msgstr ""
+
+msgid "\"%1\" is required."
+msgstr ""
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr ""
+
+msgid "The values of \"%1\" are not valid."
+msgstr ""
+
+msgid "Pre-validation"
+msgstr ""
+
+msgid ":"
+msgstr ""
+
+msgid "Translate"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Fuzzy"
+msgstr ""
+
+msgid "You need to save the record before adding translations."
+msgstr ""
+
+msgid "No other language available."
+msgstr ""
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Open"
+msgstr ""
+
+msgid "Undelete"
+msgstr ""
+
+msgid "Save As"
+msgstr ""
+
+msgid "Save As..."
+msgstr ""
+
+msgid "Select"
+msgstr ""
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr ""
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr ""
+
+#, fuzzy
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr ""
+
+msgid "Today"
+msgstr ""
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr ""
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr ""
+
+msgid "Select your action"
+msgstr ""
+
+msgid "No action defined."
+msgstr ""
+
+msgid "Attachments (%1)"
+msgstr ""
+
+msgid "Notes (%1)"
+msgstr ""
+
+msgid "Search %1"
+msgstr ""
+
+msgid "Revision"
+msgstr ""
+
+msgid "All Fields"
+msgstr ""
+
+msgid "Fields Selected"
+msgstr ""
+
+msgid "CSV Parameters"
+msgstr ""
+
+msgid "Delimiter:"
+msgstr ""
+
+msgid "Quote Char:"
+msgstr ""
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr ""
+
+msgid "File to Import"
+msgstr ""
+
+msgid "Encoding:"
+msgstr ""
+
+msgid "Lines to Skip:"
+msgstr ""
+
+msgid "You must select an import file first."
+msgstr ""
+
+msgid "An error occured in loading the file."
+msgstr ""
+
+msgid "Error processing the file at field %1."
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Error occured in loading the file"
+msgstr ""
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr ""
+
+msgid "URL Export"
+msgstr ""
+
+msgid "Delete Export"
+msgstr ""
+
+msgid "Predefined Exports"
+msgstr ""
+
+msgid "Selected Records"
+msgstr ""
+
+msgid "Listed Records"
+msgstr ""
+
+msgid "Export:"
+msgstr ""
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr ""
+
+msgid "%1 (string)"
+msgstr ""
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr ""
+
+msgid "Override %1 definition?"
+msgstr ""
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+msgid "Reports"
+msgstr ""
+
+msgid "Attachments"
+msgstr ""
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+msgid "Remove File"
+msgstr ""
+
+msgid "Wizard"
+msgstr ""
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/de.po b/sao/locale/de.po
new file mode 100644
index 0000000000..29fd9500a2
--- /dev/null
+++ b/sao/locale/de.po
@@ -0,0 +1,686 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 15 2019 16:53:42 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 01 2019 13:14:07 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Mar 01 2019 00:18:48 GMT+0100 (CET)
+# Generated by grunt-xgettext on Fri Feb 01 2019 00:07:47 GMT+0100 (CET)
+# Generated by grunt-xgettext on Tue Jan 01 2019 00:13:07 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sat Dec 01 2018 00:17:31 GMT+0100 (CET)
+# Generated by grunt-xgettext on Thu Nov 01 2018 00:08:43 GMT+0100 (CET)
+# Generated by grunt-xgettext on Mon Oct 01 2018 00:07:22 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Sep 14 2018 22:59:37 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sun Sep 09 2018 10:24:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Sep 04 2018 13:54:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 14 2018 17:56:54 GMT+0200 (CEST)
+msgid "Are your sure to leave?"
+msgstr "Wollen Sie die Seite wirklich verlassen?"
+
+msgid "Favorites"
+msgstr "Favoriten"
+
+msgid "Manage..."
+msgstr "Verwalten..."
+
+# Generated by grunt-xgettext on Thu Mar 31 2016 17:50:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Oct 16 2015 17:37:32 GMT+0200 (CEST)
+msgid "Logout"
+msgstr "Abmelden"
+
+msgid "Action"
+msgstr "Aktion"
+
+msgid "New"
+msgstr "Neu"
+
+msgid "Save"
+msgstr "Speichern"
+
+msgid "Switch"
+msgstr "Ansicht wechseln"
+
+msgid "Reload/Undo"
+msgstr "Neu laden/Rückgängig"
+
+msgid "Duplicate"
+msgstr "Duplizieren"
+
+msgid "Delete"
+msgstr "Löschen"
+
+msgid "Previous"
+msgstr "Vorheriger"
+
+msgid "Next"
+msgstr "Nächster"
+
+msgid "Search"
+msgstr "Suchen"
+
+msgid "Close Tab"
+msgstr "Registerkarte schließen"
+
+msgid "Attachment"
+msgstr "Anhang"
+
+msgid "Note"
+msgstr "Notiz"
+
+msgid "Relate"
+msgstr "Beziehung"
+
+msgid "Print"
+msgstr "Drucken"
+
+msgid "E-Mail"
+msgstr "E-Mail"
+
+msgid "Previous tab"
+msgstr "Vorherige Registerkarte"
+
+msgid "Next tab"
+msgstr "Nächste Registerkarte"
+
+msgid "Global search"
+msgstr "Golbale Suche"
+
+msgid "Show this help"
+msgstr "Diese Hilfe anzeigen"
+
+msgid "Keyboard shortcuts"
+msgstr "Tastenkombinationen"
+
+msgid "Close"
+msgstr "Schließen"
+
+msgid "Global shortcuts"
+msgstr "Globale Tastenkombinationen"
+
+msgid "Tab shortcuts"
+msgstr "Registerkarten Tastenkombinationen"
+
+msgid "Unable to reach the server."
+msgstr "Kann nicht zum Server verbinden."
+
+msgid "Too many requests. Try again later."
+msgstr "Zu viele Anfragen. Bitte versuchen Sie es später erneut."
+
+msgid "Login"
+msgstr "Log-in"
+
+msgid "User name"
+msgstr "Benutzername"
+
+msgid "Database"
+msgstr "Datenbank"
+
+msgid "Your selection:"
+msgstr "Ihre Auswahl:"
+
+msgid "Cancel"
+msgstr "Abbrechen"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Y"
+msgstr "J"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "W"
+
+msgid "d"
+msgstr "t"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "Von: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "J"
+
+msgid "Yes"
+msgstr "Ja"
+
+msgid "True"
+msgstr "Wahr"
+
+msgid "t"
+msgstr "w"
+
+msgid "False"
+msgstr "Falsch"
+
+msgid "Message: "
+msgstr "Nachricht: "
+
+msgid "Warning: "
+msgstr "Warnung: "
+
+msgid "Always ignore this warning."
+msgstr "Diese Warnung künftig nicht mehr anzeigen."
+
+msgid "Do you want to proceed?"
+msgstr "Fortfahren?"
+
+msgid "No"
+msgstr "Nein"
+
+msgid "Confirmation: "
+msgstr "Bestätigung: "
+
+msgid "Concurrency Exception"
+msgstr "Aktualisierungskonflikt"
+
+msgid "Write Concurrency Warning: "
+msgstr "Aktualisierungskonflikt beim Schreiben des aktuellen Datensatzes: "
+
+msgid "This record has been modified while you were editing it."
+msgstr ""
+"Dieser Datensatz wurde anderweitig geändert, während Sie ihn bearbeitet "
+"haben."
+
+msgid "Choose:"
+msgstr "Lösungsmöglichkeiten:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"Abbrechen\" um den Speichervorgang abzubrechen;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"Vergleichen\" um die geänderte Version des Datensatzes zu betrachten;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr ""
+"- \"Überschreiben\" um die gespeicherte Version mit Ihrer Version zu "
+"überschreiben."
+
+msgid "Compare"
+msgstr "Vergleichen"
+
+msgid "Compare: %1"
+msgstr "Vergleichen: %s"
+
+msgid "Write Anyway"
+msgstr "Überschreiben"
+
+msgid "Application Error"
+msgstr "Anwendungsfehler"
+
+msgid "Report Bug"
+msgstr "Fehler melden"
+
+msgid "Processing"
+msgstr "Verarbeitung läuft…"
+
+msgid "Search..."
+msgstr "Suche..."
+
+msgid "Create..."
+msgstr "Erstellen..."
+
+msgid "Download"
+msgstr "Herunterladen"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Schriftart"
+
+msgid "Size"
+msgstr "Größe"
+
+msgid "Switch view"
+msgstr "Ansicht wechseln"
+
+msgid "Previous Record"
+msgstr "Vorheriger Datensatz"
+
+msgid "Next Record"
+msgstr "Nächster Datensatz"
+
+msgid "Create a new record"
+msgstr "Neuen Datensatz erstellen"
+
+msgid "Save this record"
+msgstr "Diesen Datensatz speichern"
+
+msgid "Reload"
+msgstr "Neu laden"
+
+msgid "View Logs..."
+msgstr "Protokoll ansehen..."
+
+msgid "Show revisions..."
+msgstr "Bearbeitungen anzeigen..."
+
+msgid "Add an attachment to the record"
+msgstr "Einen Anhang zum Datensatz hinzufügen"
+
+msgid "Add a note to the record"
+msgstr "Eine Notiz zu einem Datensatz hinzufügen"
+
+msgid "E-Mail..."
+msgstr "E-Mail..."
+
+msgid "Send an e-mail using the record"
+msgstr "Eine E-Mail basierend auf diesem Datensatz versenden"
+
+msgid "Export"
+msgstr "Export"
+
+msgid "Import"
+msgstr "Import"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"Die folgende Aktion erfordert die Schließung aller Registerkarten.\n"
+"Fortfahren?"
+
+msgid "Launch action"
+msgstr "Aktion ausführen"
+
+msgid "Open related records"
+msgstr "Datensätze einer Beziehung öffnen"
+
+msgid "Print report"
+msgstr "Bericht drucken"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Datensatz geändert.\n"
+"Soll der Datensatz gespeichert werden?"
+
+msgid "Record saved."
+msgstr "Der Datensatz wurde gespeichert."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Sie arbeiten nun an dem/den duplizierten Datensatz/Datensätzen."
+
+msgid "Are you sure to remove this record?"
+msgstr "Möchten Sie diesen Datensatz wirklich löschen?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Möchten Sie diese Datensätze wirklich löschen?"
+
+msgid "Records removed."
+msgstr "Die Datensätze wurden gelöscht."
+
+msgid "Records not removed."
+msgstr "Die Datensätze wurden nicht gelöscht."
+
+msgid "You have to select one record."
+msgstr "Ein Datensatz muss ausgewählt werden."
+
+msgid "ID:"
+msgstr "ID:"
+
+msgid "Created by:"
+msgstr "Erstellt von:"
+
+msgid "Created at:"
+msgstr "Erstellt am:"
+
+msgid "Edited by:"
+msgstr "Bearbeitet von:"
+
+msgid "Edited at:"
+msgstr "Zuletzt bearbeitet am:"
+
+msgid "Model: "
+msgstr "Modell: "
+
+msgid "Add..."
+msgstr "Hinzufügen..."
+
+msgid "Preview"
+msgstr "Vorschau"
+
+msgid "Template"
+msgstr "Vorlage"
+
+msgid "Attachment (%1)"
+msgstr "Anhänge (%1)"
+
+msgid "Note (%1/%2)"
+msgstr "Notiz (%1/%2)"
+
+msgid " of "
+msgstr " von "
+
+msgid "Filters"
+msgstr "Filter"
+
+msgid "Clear Search"
+msgstr "Suchfeld leeren"
+
+msgid "Bookmarks"
+msgstr "Lesezeichen"
+
+msgid "Remove this bookmark"
+msgstr "Dieses Lesezeichen entfernen"
+
+msgid "Bookmark this filter"
+msgstr "Diesen Filter als Lesezeichen hinzufügen"
+
+msgid "Bookmark Name:"
+msgstr "Lesezeichenname:"
+
+msgid "Show active records"
+msgstr "Aktive Datensätze anzeigen"
+
+msgid "Show inactive records"
+msgstr "Inaktive Datensätze anzeigen"
+
+msgid "Find"
+msgstr "Suchen"
+
+msgid "From"
+msgstr "Von"
+
+msgid "To"
+msgstr "An"
+
+msgid "Open the calendar"
+msgstr "Kalender öffnen"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Created by"
+msgstr "Erstellt von"
+
+msgid "Created at"
+msgstr "Erstellt am"
+
+msgid "Modified by"
+msgstr "Zuletzt verändert von"
+
+msgid "Modified at"
+msgstr "Zuletzt verändert am"
+
+msgid "\"%1\" is required."
+msgstr "\"%1\" ist erforderlich."
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" liegt nicht im gültigen Wertebereich (Domain)."
+
+msgid "The values of \"%1\" are not valid."
+msgstr "Die Werte von \"%1\" sind ungültig."
+
+msgid "Pre-validation"
+msgstr "Vorvalidierung"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Übersetzen"
+
+msgid "Edit"
+msgstr "Bearbeiten"
+
+msgid "Fuzzy"
+msgstr "Fuzzy"
+
+msgid "You need to save the record before adding translations."
+msgstr ""
+"Der Datensatz muss gespeichert werden, bevor eine Übersetzung hinzugefügt "
+"werden kann."
+
+msgid "No other language available."
+msgstr "Keine weitere Sprache verfügbar."
+
+msgid "Show"
+msgstr "Anzeigen"
+
+msgid "Hide"
+msgstr "Ausblenden"
+
+msgid "Open the record"
+msgstr "Datensatz öffnen"
+
+msgid "Clear the field"
+msgstr "Feldinhalt löschen"
+
+msgid "Search a record"
+msgstr "Datensatz suchen"
+
+msgid "Add"
+msgstr "Hinzufügen"
+
+msgid "Remove"
+msgstr "Entfernen"
+
+msgid "Open"
+msgstr "Öffnen"
+
+msgid "Undelete"
+msgstr "Löschung rückgängig machen"
+
+msgid "Save As"
+msgstr "Speichern unter…"
+
+msgid "Save As..."
+msgstr "Speichern unter..."
+
+msgid "Select"
+msgstr "Auswählen"
+
+msgid "Select..."
+msgstr "Auswählen..."
+
+msgid "Clear"
+msgstr "Leeren"
+
+msgid "Choose a language"
+msgstr "Sprache auswählen"
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "Mehr"
+
+msgid "Today"
+msgstr "Heute"
+
+msgid "Month"
+msgstr "Monat"
+
+msgid "Week"
+msgstr "Woche"
+
+msgid "Day"
+msgstr "Tag"
+
+msgid ",..."
+msgstr ",..."
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Aktion wählen"
+
+msgid "No action defined."
+msgstr "Keine Aktion definiert."
+
+msgid "Attachments (%1)"
+msgstr "Anhänge (%1)"
+
+msgid "Notes (%1)"
+msgstr "Notizen (%1)"
+
+msgid "Search %1"
+msgstr "Suche %1"
+
+msgid "Revision"
+msgstr "Bearbeitung"
+
+msgid "All Fields"
+msgstr "Alle Felder"
+
+msgid "Fields Selected"
+msgstr "Ausgewählte Felder"
+
+msgid "CSV Parameters"
+msgstr "CSV-Parameter"
+
+msgid "Delimiter:"
+msgstr "Feldtrenner:"
+
+msgid "Quote Char:"
+msgstr "Anführungszeichen:"
+
+msgid "CSV Import: %1"
+msgstr "CSV-Import: %1"
+
+msgid "Auto-Detect"
+msgstr "Automatische Erkennung"
+
+msgid "File to Import"
+msgstr "Zu importierende Datei"
+
+msgid "Encoding:"
+msgstr "Zeichenkodierung:"
+
+msgid "Lines to Skip:"
+msgstr "Zu überspringende Zeilen:"
+
+msgid "You must select an import file first."
+msgstr "Es muss zuerst eine Importdatei ausgewählt werden."
+
+msgid "An error occured in loading the file."
+msgstr "Fehler beim Öffnen der CSV-Datei."
+
+msgid "Error processing the file at field %1."
+msgstr "Fehler bei der Verarbeitung der Datei in Feld %1."
+
+msgid "Error"
+msgstr "Fehler"
+
+msgid "Error occured in loading the file"
+msgstr "Fehler beim Öffnen der CSV-Datei"
+
+msgid "CSV Export: %1"
+msgstr "CSV-Export: %1"
+
+msgid "Save Export"
+msgstr "Exportkonfiguration speichern"
+
+msgid "URL Export"
+msgstr "URL-Export"
+
+msgid "Delete Export"
+msgstr "Exportkonfiguration löschen"
+
+msgid "Predefined Exports"
+msgstr "Vordefinierte Exporte"
+
+msgid "Selected Records"
+msgstr "Ausgewählte Datensätze"
+
+msgid "Listed Records"
+msgstr "Angezeigte Datensätze"
+
+msgid "Export:"
+msgstr "Export:"
+
+msgid "Ignore search limit"
+msgstr "Suchlimit ignorieren"
+
+msgid "Use locale format"
+msgstr "Lokales Format verwenden"
+
+msgid "Add Field Names"
+msgstr "Feldnamen hinzufügen"
+
+msgid "%1 (string)"
+msgstr "%1 (string)"
+
+msgid "%1 (model name)"
+msgstr "%1 (Bezeichnung des Datensatzes)"
+
+msgid "%1 (record name)"
+msgstr "%1 (Bezeichnung des Datensatzes)"
+
+msgid "What is the name of this export?"
+msgstr "Wie soll der Name des Exports lauten?"
+
+msgid "Override %1 definition?"
+msgstr "Definition von %1 nicht berücksichtigen?"
+
+msgid "E-mail %1"
+msgstr "E-Mail %1"
+
+msgid "To:"
+msgstr "An:"
+
+msgid "Cc:"
+msgstr "Cc:"
+
+msgid "Bcc:"
+msgstr "Bcc:"
+
+msgid "Subject:"
+msgstr "Betreff:"
+
+msgid "Reports"
+msgstr "Berichte"
+
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2020-10-27 20:46+0000\n"
+"PO-Revision-Date: 2020-10-27 20:46+0000\n"
+"Last-Translator: Korbinian Preisler \n"
+"Language-Team: LANGUAGE \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 4.2.2\n"
+
+msgid "Attachments"
+msgstr "Anhänge"
+
+msgid "Files"
+msgstr "Dateien"
+
+msgid "Send"
+msgstr "Senden"
+
+msgid "Remove File"
+msgstr "Datei entfernen"
+
+msgid "Wizard"
+msgstr "Assistent"
+
+msgid "Translate view"
+msgstr "Aktuelle Sicht übersetzen"
diff --git a/sao/locale/es.po b/sao/locale/es.po
new file mode 100644
index 0000000000..f735b02afa
--- /dev/null
+++ b/sao/locale/es.po
@@ -0,0 +1,666 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 15 2019 16:53:42 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 01 2019 13:14:07 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Mar 01 2019 00:18:48 GMT+0100 (CET)
+# Generated by grunt-xgettext on Fri Feb 01 2019 00:07:47 GMT+0100 (CET)
+# Generated by grunt-xgettext on Tue Jan 01 2019 00:13:07 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sat Dec 01 2018 00:17:31 GMT+0100 (CET)
+# Generated by grunt-xgettext on Thu Nov 01 2018 00:08:43 GMT+0100 (CET)
+# Generated by grunt-xgettext on Mon Oct 01 2018 00:07:22 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Sep 14 2018 22:59:37 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sun Sep 09 2018 10:24:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Sep 04 2018 13:54:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 14 2018 17:56:54 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Apr 06 2018 22:57:49 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Oct 09 2017 19:35:04 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr "¿Está seguro que quiere salir?"
+
+msgid "Favorites"
+msgstr "Favoritos"
+
+msgid "Manage..."
+msgstr "Gestionar..."
+
+# Generated by grunt-xgettext on Thu Mar 31 2016 17:50:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Oct 16 2015 17:37:32 GMT+0200 (CEST)
+msgid "Logout"
+msgstr "Cerrar sesión"
+
+msgid "Action"
+msgstr "Acción"
+
+msgid "New"
+msgstr "Nuevo"
+
+msgid "Save"
+msgstr "Guardar"
+
+msgid "Switch"
+msgstr "Cambiar"
+
+msgid "Reload/Undo"
+msgstr "Recargar/Deshacer"
+
+msgid "Duplicate"
+msgstr "Duplicar"
+
+msgid "Delete"
+msgstr "Eliminar"
+
+msgid "Previous"
+msgstr "Anterior"
+
+msgid "Next"
+msgstr "Siguiente"
+
+msgid "Search"
+msgstr "Buscar"
+
+msgid "Close Tab"
+msgstr "Cerrar pestaña"
+
+msgid "Attachment"
+msgstr "Adjunto"
+
+msgid "Note"
+msgstr "Nota"
+
+msgid "Relate"
+msgstr "Relacionado"
+
+msgid "Print"
+msgstr "Imprimir"
+
+msgid "E-Mail"
+msgstr "Correo electrónico"
+
+msgid "Previous tab"
+msgstr "Pestaña anterior"
+
+msgid "Next tab"
+msgstr "Pestaña siguiente"
+
+msgid "Global search"
+msgstr "Búsqueda global"
+
+msgid "Show this help"
+msgstr "Muestra esta ayuda"
+
+msgid "Keyboard shortcuts"
+msgstr "Atajos de teclado"
+
+msgid "Close"
+msgstr "Cerrar"
+
+msgid "Global shortcuts"
+msgstr "Atajos globales"
+
+msgid "Tab shortcuts"
+msgstr "Atajos de las pestañas"
+
+msgid "Unable to reach the server."
+msgstr "No es posible conectar con el servidor."
+
+msgid "Too many requests. Try again later."
+msgstr "Demasiadas peticiones. Inténtelo de nuevo más tarde."
+
+msgid "Login"
+msgstr "Acceder"
+
+msgid "User name"
+msgstr "Nombre de usuario"
+
+msgid "Database"
+msgstr "Base de datos"
+
+msgid "Your selection:"
+msgstr "Su selección:"
+
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgid "OK"
+msgstr "Aceptar"
+
+msgid "Y"
+msgstr "A"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "S"
+
+msgid "d"
+msgstr "d"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "Por: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "a"
+
+msgid "Yes"
+msgstr "Sí"
+
+msgid "True"
+msgstr "Verdadero"
+
+msgid "t"
+msgstr "v"
+
+msgid "False"
+msgstr "Falso"
+
+msgid "Message: "
+msgstr "Mensaje: "
+
+msgid "Warning: "
+msgstr "Aviso: "
+
+msgid "Always ignore this warning."
+msgstr "Ignorar siempre esta advertencia."
+
+msgid "Do you want to proceed?"
+msgstr "¿Desea continuar?"
+
+msgid "No"
+msgstr "No"
+
+msgid "Confirmation: "
+msgstr "Confirmación: "
+
+msgid "Concurrency Exception"
+msgstr "Excepción de concurrencia"
+
+msgid "Write Concurrency Warning: "
+msgstr "Aviso de concurrencia de escritura: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "Este registro ha sido modificado mientras lo editaba."
+
+msgid "Choose:"
+msgstr "Elija:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"Cancelar\" para no guardar;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"Comparar\" para ver la versión modificada;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"Guardar de todas formas\" para guardar sus cambios."
+
+msgid "Compare"
+msgstr "Comparar"
+
+msgid "Compare: %1"
+msgstr "Comparar: %1"
+
+msgid "Write Anyway"
+msgstr "Guardar de todas formas"
+
+msgid "Application Error"
+msgstr "Error de aplicación"
+
+msgid "Report Bug"
+msgstr "Informar del error"
+
+msgid "Processing"
+msgstr "Procesando"
+
+msgid "Search..."
+msgstr "Buscar…"
+
+msgid "Create..."
+msgstr "Crear..."
+
+msgid "Download"
+msgstr "Descargar"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Tipo de letra"
+
+msgid "Size"
+msgstr "Tamaño"
+
+msgid "Switch view"
+msgstr "Cambiar de vista"
+
+msgid "Previous Record"
+msgstr "Registro anterior"
+
+msgid "Next Record"
+msgstr "Registro siguiente"
+
+msgid "Create a new record"
+msgstr "Crear un nuevo registro"
+
+msgid "Save this record"
+msgstr "Guardar este registro"
+
+msgid "Reload"
+msgstr "Recargar"
+
+msgid "View Logs..."
+msgstr "Ver registro..."
+
+msgid "Show revisions..."
+msgstr "Mostrar revisiones..."
+
+msgid "Add an attachment to the record"
+msgstr "Añadir un adjunto al registro"
+
+msgid "Add a note to the record"
+msgstr "Añadir una nota al registro"
+
+msgid "E-Mail..."
+msgstr "Correo electrónico..."
+
+msgid "Send an e-mail using the record"
+msgstr "Enviar un correo electrónico usando el registro"
+
+msgid "Export"
+msgstr "Exportar"
+
+msgid "Import"
+msgstr "Importar"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"La acción seleccionada requiere cerrar todas las pestañas.\n"
+"¿Desea continuar?"
+
+msgid "Launch action"
+msgstr "Ejecutar acción"
+
+msgid "Open related records"
+msgstr "Abrir registros relacionados"
+
+msgid "Print report"
+msgstr "Imprimir informe"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Este registro ha sido modificado.\n"
+"¿Desea guardarlo?"
+
+msgid "Record saved."
+msgstr "Registro guardado."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Ahora está trabajando en el/los registro(s) duplicado(s)."
+
+msgid "Are you sure to remove this record?"
+msgstr "¿Está seguro que quiere eliminar este registro?"
+
+msgid "Are you sure to remove those records?"
+msgstr "¿Está seguro que quiere eliminar estos registros?"
+
+msgid "Records removed."
+msgstr "Registros eliminados."
+
+msgid "Records not removed."
+msgstr "Los registros no se han eliminado."
+
+msgid "You have to select one record."
+msgstr "Debe elegir un registro."
+
+msgid "ID:"
+msgstr "ID:"
+
+msgid "Created by:"
+msgstr "Creado por:"
+
+msgid "Created at:"
+msgstr "Creado el:"
+
+msgid "Edited by:"
+msgstr "Editado por:"
+
+msgid "Edited at:"
+msgstr "Editado el:"
+
+msgid "Model: "
+msgstr "Modelo: "
+
+msgid "Add..."
+msgstr "Añadir..."
+
+msgid "Preview"
+msgstr "Previsualizar"
+
+msgid "Template"
+msgstr "Plantilla"
+
+msgid "Attachment (%1)"
+msgstr "Adjuntos (%1)"
+
+msgid "Note (%1/%2)"
+msgstr "Nota (%1/%2)"
+
+msgid " of "
+msgstr " de "
+
+msgid "Filters"
+msgstr "Filtros"
+
+msgid "Clear Search"
+msgstr "Limpiar la búsqueda"
+
+msgid "Bookmarks"
+msgstr "Búsquedas favoritas"
+
+msgid "Remove this bookmark"
+msgstr "Eliminar de las búsquedas favoritas"
+
+msgid "Bookmark this filter"
+msgstr "Guardar como búsqueda favorita"
+
+msgid "Bookmark Name:"
+msgstr "Nombre de la búsqueda favorita:"
+
+msgid "Show active records"
+msgstr "Mostrar registros activos"
+
+msgid "Show inactive records"
+msgstr "Mostrar registros inactivos"
+
+msgid "Find"
+msgstr "Buscar"
+
+msgid "From"
+msgstr "De"
+
+msgid "To"
+msgstr "A"
+
+msgid "Open the calendar"
+msgstr "Abrir el calendario"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Created by"
+msgstr "Creado por"
+
+msgid "Created at"
+msgstr "Creado el"
+
+msgid "Modified by"
+msgstr "Modifcador por"
+
+msgid "Modified at"
+msgstr "Modificado el"
+
+msgid "\"%1\" is required."
+msgstr "\"%1\" es obligatorio."
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" no es válido según su dominio."
+
+msgid "The values of \"%1\" are not valid."
+msgstr "Los valores de \"%1\" no son válidos."
+
+msgid "Pre-validation"
+msgstr "Prevalidación"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Traducir"
+
+msgid "Edit"
+msgstr "Editar"
+
+msgid "Fuzzy"
+msgstr "Dudoso"
+
+msgid "You need to save the record before adding translations."
+msgstr "Debe guardar el registro antes de añadir traducciones."
+
+msgid "No other language available."
+msgstr "No hay otro idioma disponible."
+
+msgid "Show"
+msgstr "Mostrar"
+
+msgid "Hide"
+msgstr "Ocultar"
+
+msgid "Open the record"
+msgstr "Abrir el registro"
+
+msgid "Clear the field"
+msgstr "Vacíar el campo"
+
+msgid "Search a record"
+msgstr "Buscar un registro"
+
+msgid "Add"
+msgstr "Añadir"
+
+msgid "Remove"
+msgstr "Eliminar"
+
+msgid "Open"
+msgstr "Abrir"
+
+msgid "Undelete"
+msgstr "Recuperar"
+
+msgid "Save As"
+msgstr "Guardar como"
+
+msgid "Save As..."
+msgstr "Guardar como..."
+
+msgid "Select"
+msgstr "Seleccionar"
+
+msgid "Select..."
+msgstr "Seleccionar…"
+
+msgid "Clear"
+msgstr "Limpiar"
+
+msgid "Choose a language"
+msgstr "Escoja un lenguaje"
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "Más"
+
+msgid "Today"
+msgstr "Hoy"
+
+msgid "Month"
+msgstr "Mes"
+
+msgid "Week"
+msgstr "Semana"
+
+msgid "Day"
+msgstr "Día"
+
+msgid ",..."
+msgstr ",..."
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Seleccione su acción"
+
+msgid "No action defined."
+msgstr "No se ha definido ninguna acción."
+
+msgid "Attachments (%1)"
+msgstr "Adjuntos (%1)"
+
+msgid "Notes (%1)"
+msgstr "Notas (%1)"
+
+msgid "Search %1"
+msgstr "Buscar %1"
+
+msgid "Revision"
+msgstr "Revisión"
+
+msgid "All Fields"
+msgstr "Todos los campos"
+
+msgid "Fields Selected"
+msgstr "Campos selecionados"
+
+msgid "CSV Parameters"
+msgstr "Parámetros CSV"
+
+msgid "Delimiter:"
+msgstr "Separador:"
+
+msgid "Quote Char:"
+msgstr "Delimitador del texto:"
+
+msgid "CSV Import: %1"
+msgstr "Importación CSV: %1"
+
+msgid "Auto-Detect"
+msgstr "Detectar automáticamente"
+
+msgid "File to Import"
+msgstr "Fichero a importar"
+
+msgid "Encoding:"
+msgstr "Codificación:"
+
+msgid "Lines to Skip:"
+msgstr "Líneas a omitir:"
+
+msgid "You must select an import file first."
+msgstr "Primero debe elegir un archivo a importar."
+
+msgid "An error occured in loading the file."
+msgstr "Ha ocurrido un error al cargar el fichero."
+
+msgid "Error processing the file at field %1."
+msgstr "Error procesando el fichero en el campo %1."
+
+msgid "Error"
+msgstr "Error"
+
+msgid "Error occured in loading the file"
+msgstr "Ha ocurrido un al cargar el fichero"
+
+msgid "CSV Export: %1"
+msgstr "Exportación CSV: %1"
+
+msgid "Save Export"
+msgstr "Guardar exportación"
+
+msgid "URL Export"
+msgstr "URL exportación"
+
+msgid "Delete Export"
+msgstr "Eliminar exportación"
+
+msgid "Predefined Exports"
+msgstr "Exportaciones predefinidas"
+
+msgid "Selected Records"
+msgstr "Registros seleccionados"
+
+msgid "Listed Records"
+msgstr "Registros listados"
+
+msgid "Export:"
+msgstr "Exportar:"
+
+msgid "Ignore search limit"
+msgstr "Ignorar límite de búsqueda"
+
+msgid "Use locale format"
+msgstr "Usar formato local"
+
+msgid "Add Field Names"
+msgstr "Añadir nombres de los campos"
+
+msgid "%1 (string)"
+msgstr "%1 (cadena)"
+
+msgid "%1 (model name)"
+msgstr "%1 (nombre del modelo)"
+
+msgid "%1 (record name)"
+msgstr "%1 (nombre del registro)"
+
+msgid "What is the name of this export?"
+msgstr "¿Cuál es el nombre de esta exportación?"
+
+msgid "Override %1 definition?"
+msgstr "Queréis sobrescribir la definición de %1?"
+
+msgid "E-mail %1"
+msgstr "Correo electrónico %1"
+
+msgid "To:"
+msgstr "A:"
+
+msgid "Cc:"
+msgstr "Cc:"
+
+msgid "Bcc:"
+msgstr "CCo:"
+
+msgid "Subject:"
+msgstr "Asunto:"
+
+msgid "Reports"
+msgstr "Informes"
+
+msgid "Attachments"
+msgstr "Adjuntos"
+
+msgid "Files"
+msgstr "Archivos"
+
+msgid "Send"
+msgstr "Enviar"
+
+msgid "Remove File"
+msgstr "Eliminar archivo"
+
+msgid "Wizard"
+msgstr "Asistente"
+
+msgid "Translate view"
+msgstr "Traducir vista"
diff --git a/sao/locale/es_419.po b/sao/locale/es_419.po
new file mode 100644
index 0000000000..7c20f559cd
--- /dev/null
+++ b/sao/locale/es_419.po
@@ -0,0 +1,669 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 15 2019 16:53:42 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 01 2019 13:14:07 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Mar 01 2019 00:18:48 GMT+0100 (CET)
+# Generated by grunt-xgettext on Fri Feb 01 2019 00:07:47 GMT+0100 (CET)
+# Generated by grunt-xgettext on Tue Jan 01 2019 00:13:07 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sat Dec 01 2018 00:17:31 GMT+0100 (CET)
+# Generated by grunt-xgettext on Thu Nov 01 2018 00:08:43 GMT+0100 (CET)
+# Generated by grunt-xgettext on Mon Oct 01 2018 00:07:22 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Sep 14 2018 22:59:37 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sun Sep 09 2018 10:24:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Sep 04 2018 13:54:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 14 2018 17:56:54 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr ""
+
+msgid "Manage..."
+msgstr ""
+
+msgid "Logout"
+msgstr ""
+
+msgid "Action"
+msgstr ""
+
+msgid "New"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Switch"
+msgstr ""
+
+msgid "Reload/Undo"
+msgstr ""
+
+msgid "Duplicate"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
+msgid "Search"
+msgstr ""
+
+msgid "Close Tab"
+msgstr ""
+
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
+msgid "Relate"
+msgstr ""
+
+msgid "Print"
+msgstr ""
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr ""
+
+msgid "Next tab"
+msgstr ""
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr ""
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr ""
+
+msgid "User name"
+msgstr ""
+
+msgid "Database"
+msgstr ""
+
+msgid "Your selection:"
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Y"
+msgstr ""
+
+msgid "M"
+msgstr ""
+
+msgid "w"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "h"
+msgstr ""
+
+msgid "m"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "By: "
+msgstr ""
+
+msgid ", "
+msgstr ""
+
+msgid "y"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "True"
+msgstr ""
+
+msgid "t"
+msgstr ""
+
+msgid "False"
+msgstr ""
+
+msgid "Message: "
+msgstr ""
+
+msgid "Warning: "
+msgstr ""
+
+msgid "Always ignore this warning."
+msgstr ""
+
+msgid "Do you want to proceed?"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Confirmation: "
+msgstr ""
+
+msgid "Concurrency Exception"
+msgstr ""
+
+msgid "Write Concurrency Warning: "
+msgstr ""
+
+msgid "This record has been modified while you were editing it."
+msgstr ""
+
+msgid "Choose:"
+msgstr ""
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr ""
+
+msgid "\"Compare\" to see the modified version;"
+msgstr ""
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Compare: %1"
+msgstr ""
+
+msgid "Write Anyway"
+msgstr ""
+
+msgid "Application Error"
+msgstr ""
+
+msgid "Report Bug"
+msgstr ""
+
+msgid "Processing"
+msgstr ""
+
+msgid "Search..."
+msgstr ""
+
+msgid "Create..."
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid "..."
+msgstr ""
+
+msgid "Font"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Switch view"
+msgstr ""
+
+msgid "Previous Record"
+msgstr ""
+
+msgid "Next Record"
+msgstr ""
+
+msgid "Create a new record"
+msgstr ""
+
+msgid "Save this record"
+msgstr ""
+
+msgid "Reload"
+msgstr ""
+
+msgid "View Logs..."
+msgstr ""
+
+msgid "Show revisions..."
+msgstr ""
+
+msgid "Add an attachment to the record"
+msgstr ""
+
+msgid "Add a note to the record"
+msgstr ""
+
+msgid "E-Mail..."
+msgstr ""
+
+msgid "Send an e-mail using the record"
+msgstr ""
+
+msgid "Export"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+
+msgid "Launch action"
+msgstr ""
+
+msgid "Open related records"
+msgstr ""
+
+msgid "Print report"
+msgstr ""
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+
+msgid "Record saved."
+msgstr ""
+
+msgid "Working now on the duplicated record(s)."
+msgstr ""
+
+msgid "Are you sure to remove this record?"
+msgstr ""
+
+msgid "Are you sure to remove those records?"
+msgstr ""
+
+msgid "Records removed."
+msgstr ""
+
+msgid "Records not removed."
+msgstr ""
+
+msgid "You have to select one record."
+msgstr ""
+
+msgid "ID:"
+msgstr ""
+
+#, fuzzy
+msgid "Created by:"
+msgstr "Crear..."
+
+#, fuzzy
+msgid "Created at:"
+msgstr "Fecha creación:"
+
+#, fuzzy
+msgid "Edited by:"
+msgstr "Crear..."
+
+#, fuzzy
+msgid "Edited at:"
+msgstr "Última fecha de modificación:"
+
+msgid "Model: "
+msgstr ""
+
+msgid "Add..."
+msgstr ""
+
+msgid "Preview"
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+#, fuzzy
+msgid "Attachment (%1)"
+msgstr "Adjuntos (%1)"
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr ""
+
+msgid "Filters"
+msgstr ""
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr ""
+
+msgid "Remove this bookmark"
+msgstr ""
+
+msgid "Bookmark this filter"
+msgstr ""
+
+msgid "Bookmark Name:"
+msgstr ""
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr ""
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+#, fuzzy
+msgid "Created by"
+msgstr "Crear..."
+
+#, fuzzy
+msgid "Created at"
+msgstr "Fecha creación:"
+
+msgid "Modified by"
+msgstr ""
+
+#, fuzzy
+msgid "Modified at"
+msgstr "Última fecha de modificación:"
+
+msgid "\"%1\" is required."
+msgstr ""
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr ""
+
+msgid "The values of \"%1\" are not valid."
+msgstr ""
+
+msgid "Pre-validation"
+msgstr ""
+
+msgid ":"
+msgstr ""
+
+msgid "Translate"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Fuzzy"
+msgstr "Revisión"
+
+msgid "You need to save the record before adding translations."
+msgstr ""
+
+msgid "No other language available."
+msgstr ""
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+#, fuzzy
+msgid "Open the record"
+msgstr "Abrir registro "
+
+msgid "Clear the field"
+msgstr ""
+
+#, fuzzy
+msgid "Search a record"
+msgstr "Buscar registro "
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Open"
+msgstr ""
+
+msgid "Undelete"
+msgstr ""
+
+msgid "Save As"
+msgstr ""
+
+msgid "Save As..."
+msgstr ""
+
+msgid "Select"
+msgstr ""
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr ""
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr ""
+
+msgid ": "
+msgstr ""
+
+msgid "More"
+msgstr ""
+
+msgid "Today"
+msgstr ""
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr ""
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr ""
+
+msgid "Select your action"
+msgstr ""
+
+msgid "No action defined."
+msgstr ""
+
+msgid "Attachments (%1)"
+msgstr ""
+
+msgid "Notes (%1)"
+msgstr ""
+
+msgid "Search %1"
+msgstr ""
+
+msgid "Revision"
+msgstr ""
+
+msgid "All Fields"
+msgstr ""
+
+msgid "Fields Selected"
+msgstr ""
+
+msgid "CSV Parameters"
+msgstr ""
+
+msgid "Delimiter:"
+msgstr ""
+
+msgid "Quote Char:"
+msgstr ""
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr ""
+
+msgid "File to Import"
+msgstr ""
+
+msgid "Encoding:"
+msgstr ""
+
+msgid "Lines to Skip:"
+msgstr ""
+
+msgid "You must select an import file first."
+msgstr ""
+
+msgid "An error occured in loading the file."
+msgstr ""
+
+msgid "Error processing the file at field %1."
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Error occured in loading the file"
+msgstr ""
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr ""
+
+msgid "URL Export"
+msgstr ""
+
+msgid "Delete Export"
+msgstr ""
+
+msgid "Predefined Exports"
+msgstr ""
+
+msgid "Selected Records"
+msgstr ""
+
+msgid "Listed Records"
+msgstr ""
+
+msgid "Export:"
+msgstr ""
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr ""
+
+msgid "%1 (string)"
+msgstr ""
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr ""
+
+msgid "Override %1 definition?"
+msgstr ""
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+msgid "Reports"
+msgstr ""
+
+#, fuzzy
+msgid "Attachments"
+msgstr "Adjuntos (%1)"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+msgid "Remove File"
+msgstr ""
+
+msgid "Wizard"
+msgstr ""
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/et.po b/sao/locale/et.po
new file mode 100644
index 0000000000..095bfcbab7
--- /dev/null
+++ b/sao/locale/et.po
@@ -0,0 +1,681 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 15 2019 16:53:42 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 01 2019 13:14:07 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Mar 01 2019 00:18:48 GMT+0100 (CET)
+# Generated by grunt-xgettext on Fri Feb 01 2019 00:07:47 GMT+0100 (CET)
+# Generated by grunt-xgettext on Tue Jan 01 2019 00:13:07 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sat Dec 01 2018 00:17:31 GMT+0100 (CET)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr "Kas soovid lahkuda?"
+
+msgid "Favorites"
+msgstr "Lemmikud"
+
+msgid "Manage..."
+msgstr "Halda..."
+
+msgid "Logout"
+msgstr "Logi välja"
+
+msgid "Action"
+msgstr "Toiming"
+
+msgid "New"
+msgstr "Uus"
+
+msgid "Save"
+msgstr "Salvesta"
+
+msgid "Switch"
+msgstr "Vaheta"
+
+msgid "Reload/Undo"
+msgstr "Laadi uuesti/Taasta"
+
+msgid "Duplicate"
+msgstr "Kopeeri"
+
+msgid "Delete"
+msgstr "Kustuta"
+
+msgid "Previous"
+msgstr "Eelmine"
+
+msgid "Next"
+msgstr "Järgmine"
+
+msgid "Search"
+msgstr "Otsi"
+
+msgid "Close Tab"
+msgstr "Sulge vaheleht"
+
+msgid "Attachment"
+msgstr "Manus"
+
+msgid "Note"
+msgstr "Märkus"
+
+msgid "Relate"
+msgstr "Seosta"
+
+msgid "Print"
+msgstr "Prindi"
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr "Eelmine vaheleht"
+
+msgid "Next tab"
+msgstr "Järgmine vaheleht"
+
+msgid "Global search"
+msgstr "Üldine otsing"
+
+msgid "Show this help"
+msgstr "Näita abiinfot"
+
+msgid "Keyboard shortcuts"
+msgstr "Kiirklahvid"
+
+msgid "Close"
+msgstr "Sulge"
+
+msgid "Global shortcuts"
+msgstr "Globaalsed otseteed"
+
+msgid "Tab shortcuts"
+msgstr "Vahelehe otseteed"
+
+msgid "Unable to reach the server."
+msgstr "Serverit ei leita."
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr "Logi sisse"
+
+msgid "User name"
+msgstr "Kasutaja nimi"
+
+msgid "Database"
+msgstr "Andmebaas"
+
+msgid "Your selection:"
+msgstr "Valik:"
+
+msgid "Cancel"
+msgstr "Tühista"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Y"
+msgstr "A"
+
+msgid "M"
+msgstr "K"
+
+msgid "w"
+msgstr "n"
+
+msgid "d"
+msgstr "p"
+
+msgid "h"
+msgstr "t"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr ""
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr ""
+
+msgid "Yes"
+msgstr "Jah"
+
+msgid "True"
+msgstr "Tõene"
+
+msgid "t"
+msgstr ""
+
+msgid "False"
+msgstr "Väär"
+
+msgid "Message: "
+msgstr "Teade: "
+
+msgid "Warning: "
+msgstr "Hoiatus: "
+
+msgid "Always ignore this warning."
+msgstr "Eira alati seda hoiatust."
+
+msgid "Do you want to proceed?"
+msgstr "Kas soovid jätkata?"
+
+msgid "No"
+msgstr "Ei"
+
+msgid "Confirmation: "
+msgstr "Kinnitus: "
+
+msgid "Concurrency Exception"
+msgstr ""
+
+msgid "Write Concurrency Warning: "
+msgstr ""
+
+msgid "This record has been modified while you were editing it."
+msgstr "Kirje on muutunud viimasest salvestamisest alates."
+
+msgid "Choose:"
+msgstr "Vali:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"Tühista\", et katkestada salvestamine;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"Võrdle\", et vaadata muudetud versiooni;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"Salvesta ikkagi\", et salvestada viimased muudatused."
+
+msgid "Compare"
+msgstr "Võrdle"
+
+#, fuzzy
+msgid "Compare: %1"
+msgstr "Võrdle"
+
+msgid "Write Anyway"
+msgstr "Salvesta ikkagi"
+
+msgid "Application Error"
+msgstr "Rakenduse viga"
+
+msgid "Report Bug"
+msgstr "Vearaport"
+
+#, fuzzy
+msgid "Processing"
+msgstr "Töötlemine..."
+
+msgid "Search..."
+msgstr "Otsi..."
+
+msgid "Create..."
+msgstr "Loo..."
+
+msgid "Download"
+msgstr "Allalaadimine"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Šrift"
+
+msgid "Size"
+msgstr "Suurus"
+
+msgid "Switch view"
+msgstr "Vaheta vaadet"
+
+msgid "Previous Record"
+msgstr "Eelmine kirje"
+
+msgid "Next Record"
+msgstr "Järgmine kirje"
+
+msgid "Create a new record"
+msgstr "Loo uus kirje"
+
+msgid "Save this record"
+msgstr "Salvesta kirje"
+
+msgid "Reload"
+msgstr "Taaslae"
+
+msgid "View Logs..."
+msgstr "Vaata logisid..."
+
+msgid "Show revisions..."
+msgstr "Näita muudatusi..."
+
+msgid "Add an attachment to the record"
+msgstr "Lisa manus"
+
+msgid "Add a note to the record"
+msgstr "Lisa märkus"
+
+msgid "E-Mail..."
+msgstr ""
+
+#, fuzzy
+msgid "Send an e-mail using the record"
+msgstr "Lisa märkus"
+
+msgid "Export"
+msgstr "Eksport"
+
+msgid "Import"
+msgstr "Import"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"Järgmine toiming sulgeb kõik vahelehed.\n"
+"Kas soovid jätkata?"
+
+msgid "Launch action"
+msgstr "Käivita toiming"
+
+msgid "Open related records"
+msgstr "Ava seotud kirjed"
+
+msgid "Print report"
+msgstr "Prindi aruanne"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Seda kirjet on muudetud,\n"
+"kas soovid salvestada?"
+
+msgid "Record saved."
+msgstr "Kirje salvestatud."
+
+msgid "Working now on the duplicated record(s)."
+msgstr ""
+
+msgid "Are you sure to remove this record?"
+msgstr "Kas soovid selle kirje eemaldada?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Kas soovid need kirjed eemaldada?"
+
+msgid "Records removed."
+msgstr "Kirjed eemaldatud."
+
+msgid "Records not removed."
+msgstr "Kirjeid ei eemaldatud."
+
+msgid "You have to select one record."
+msgstr "Aktiveeri üks kirje."
+
+msgid "ID:"
+msgstr "ID"
+
+#, fuzzy
+msgid "Created by:"
+msgstr "Loo..."
+
+#, fuzzy
+msgid "Created at:"
+msgstr "Loomise kuupäev"
+
+#, fuzzy
+msgid "Edited by:"
+msgstr "Loo..."
+
+#, fuzzy
+msgid "Edited at:"
+msgstr "Muutmise kuupäev"
+
+msgid "Model: "
+msgstr "Mudel: "
+
+msgid "Add..."
+msgstr "Lisa..."
+
+#, fuzzy
+msgid "Preview"
+msgstr "Eelmine"
+
+#, fuzzy
+msgid "Template"
+msgstr "Seosta"
+
+msgid "Attachment (%1)"
+msgstr "Manus (%1)"
+
+msgid "Note (%1/%2)"
+msgstr "Märkus (%1/%2)"
+
+msgid " of "
+msgstr ""
+
+msgid "Filters"
+msgstr "Filtrid"
+
+msgid "Clear Search"
+msgstr "Tühjenda otsing"
+
+msgid "Bookmarks"
+msgstr "Järjehoidjad"
+
+msgid "Remove this bookmark"
+msgstr "Eemalda järjehoidja"
+
+msgid "Bookmark this filter"
+msgstr "Lisa filter järjehoidjatesse"
+
+msgid "Bookmark Name:"
+msgstr "Järjehoidja nimi:"
+
+msgid "Show active records"
+msgstr "Näita aktiivseid kirjeid"
+
+msgid "Show inactive records"
+msgstr "Näita mitteaktiivseid kirjeid"
+
+msgid "Find"
+msgstr "Leia"
+
+msgid "From"
+msgstr "Saatja"
+
+msgid "To"
+msgstr "Saaja"
+
+msgid "Open the calendar"
+msgstr "Ava kalender"
+
+msgid "ID"
+msgstr "ID"
+
+#, fuzzy
+msgid "Created by"
+msgstr "Loo..."
+
+#, fuzzy
+msgid "Created at"
+msgstr "Loomise kuupäev"
+
+msgid "Modified by"
+msgstr ""
+
+#, fuzzy
+msgid "Modified at"
+msgstr "Muutmise kuupäev"
+
+#, fuzzy
+msgid "\"%1\" is required."
+msgstr "\"%1\" on nõutud"
+
+#, fuzzy
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" ei ole kehtiv selle domeeni jaoks"
+
+#, fuzzy
+msgid "The values of \"%1\" are not valid."
+msgstr "Väärtused \"%1\" ei ole kehtivad"
+
+msgid "Pre-validation"
+msgstr "Eelkontroll"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Tõlgi"
+
+msgid "Edit"
+msgstr "Muuda"
+
+msgid "Fuzzy"
+msgstr "Hägune"
+
+msgid "You need to save the record before adding translations."
+msgstr "Kirje tuleb salvestada enne tõlke lisamist."
+
+msgid "No other language available."
+msgstr "Teisi keeli pole saadaval."
+
+msgid "Show"
+msgstr "Näita"
+
+msgid "Hide"
+msgstr "Peida"
+
+msgid "Open the record"
+msgstr "Ava kirje"
+
+msgid "Clear the field"
+msgstr "Tühjenda väli"
+
+msgid "Search a record"
+msgstr "Otsi kirjet"
+
+msgid "Add"
+msgstr "Lisa"
+
+msgid "Remove"
+msgstr "Eemalda"
+
+msgid "Open"
+msgstr "Ava"
+
+msgid "Undelete"
+msgstr "Taasta"
+
+msgid "Save As"
+msgstr "Salvesta nimega"
+
+msgid "Save As..."
+msgstr "Salvesta nimega..."
+
+msgid "Select"
+msgstr "Vali"
+
+msgid "Select..."
+msgstr "Vali..."
+
+msgid "Clear"
+msgstr "Tühjenda"
+
+msgid "Choose a language"
+msgstr "Vali keel"
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "Lisaks"
+
+msgid "Today"
+msgstr "Täna"
+
+msgid "Month"
+msgstr "Kuu"
+
+msgid "Week"
+msgstr "Nädal"
+
+msgid "Day"
+msgstr "Päev"
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Vali toiming"
+
+msgid "No action defined."
+msgstr "Toiming kirjeldamata."
+
+msgid "Attachments (%1)"
+msgstr "Manused (%1)"
+
+msgid "Notes (%1)"
+msgstr "Märkused (%1)"
+
+msgid "Search %1"
+msgstr "Otsi %1"
+
+msgid "Revision"
+msgstr "Läbivaatus"
+
+msgid "All Fields"
+msgstr "Kõik väljad"
+
+msgid "Fields Selected"
+msgstr "Valitud väljad"
+
+msgid "CSV Parameters"
+msgstr "CSV parameetrid"
+
+msgid "Delimiter:"
+msgstr "Eraldaja:"
+
+msgid "Quote Char:"
+msgstr "Teksti eraldaja:"
+
+msgid "CSV Import: %1"
+msgstr "CSV import: %1"
+
+msgid "Auto-Detect"
+msgstr "Automaattuvastus"
+
+msgid "File to Import"
+msgstr "Impordi fail"
+
+msgid "Encoding:"
+msgstr "Kodeering:"
+
+msgid "Lines to Skip:"
+msgstr "Jäta vahele read:"
+
+#, fuzzy
+msgid "You must select an import file first."
+msgstr "Vali imporditav fail"
+
+#, fuzzy
+msgid "An error occured in loading the file."
+msgstr "Faili laadimisel tekkis viga"
+
+msgid "Error processing the file at field %1."
+msgstr "Faili töötlemisel tekkis väljal %1 viga."
+
+msgid "Error"
+msgstr "Viga"
+
+msgid "Error occured in loading the file"
+msgstr "Faili laadimisel tekkis viga"
+
+msgid "CSV Export: %1"
+msgstr "CSV eksport: %1"
+
+msgid "Save Export"
+msgstr "Salvesta eksport"
+
+#, fuzzy
+msgid "URL Export"
+msgstr "Eksport"
+
+msgid "Delete Export"
+msgstr "Kustuta eksport"
+
+msgid "Predefined Exports"
+msgstr "Salvestatud ekspordid"
+
+#, fuzzy
+msgid "Selected Records"
+msgstr "Järgmine kirje"
+
+#, fuzzy
+msgid "Listed Records"
+msgstr "Järgmine kirje"
+
+#, fuzzy
+msgid "Export:"
+msgstr "Eksport"
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr "Kasuta piirkonna formaati"
+
+msgid "Add Field Names"
+msgstr "Lisa välja nimed"
+
+msgid "%1 (string)"
+msgstr "%1 (tekst)"
+
+msgid "%1 (model name)"
+msgstr "%1 (mudeli nimi)"
+
+msgid "%1 (record name)"
+msgstr "%1 (kirje nimi)"
+
+msgid "What is the name of this export?"
+msgstr "Ekspordi nimi?"
+
+msgid "Override %1 definition?"
+msgstr "Kirjutada üle 1% kirjeldus?"
+
+msgid "E-mail %1"
+msgstr ""
+
+#, fuzzy
+msgid "To:"
+msgstr "Saaja"
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+#, fuzzy
+msgid "Reports"
+msgstr "Vearaport"
+
+#, fuzzy
+msgid "Attachments"
+msgstr "Manus"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+#, fuzzy
+msgid "Remove File"
+msgstr "Eemalda"
+
+msgid "Wizard"
+msgstr "Nõustaja"
+
+msgid "Translate view"
+msgstr "Tõlgi vaade"
diff --git a/sao/locale/fa.po b/sao/locale/fa.po
new file mode 100644
index 0000000000..3398382a15
--- /dev/null
+++ b/sao/locale/fa.po
@@ -0,0 +1,691 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 15 2019 16:53:42 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 01 2019 13:14:07 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Mar 01 2019 00:18:48 GMT+0100 (CET)
+# Generated by grunt-xgettext on Fri Feb 01 2019 00:07:47 GMT+0100 (CET)
+# Generated by grunt-xgettext on Tue Jan 01 2019 00:13:07 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sat Dec 01 2018 00:17:31 GMT+0100 (CET)
+# Generated by grunt-xgettext on Thu Nov 01 2018 00:08:43 GMT+0100 (CET)
+# Generated by grunt-xgettext on Mon Oct 01 2018 00:07:22 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Sep 14 2018 22:59:37 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sun Sep 09 2018 10:24:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Sep 04 2018 13:54:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 14 2018 17:56:54 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Oct 09 2017 19:35:04 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr "برای ترک برنامه، آیا مطمئن هستید؟"
+
+msgid "Favorites"
+msgstr "علاقه مندی ها"
+
+msgid "Manage..."
+msgstr "مدیریت..."
+
+msgid "Logout"
+msgstr "خروج"
+
+msgid "Action"
+msgstr "اقدام"
+
+msgid "New"
+msgstr "جدید"
+
+msgid "Save"
+msgstr "ذخیره"
+
+msgid "Switch"
+msgstr "سوئیچ"
+
+msgid "Reload/Undo"
+msgstr "بارگیری مجدد / واگرد"
+
+msgid "Duplicate"
+msgstr "تکثیر"
+
+msgid "Delete"
+msgstr "حذف"
+
+msgid "Previous"
+msgstr "قبلی"
+
+msgid "Next"
+msgstr "بعدی"
+
+msgid "Search"
+msgstr "جستجو"
+
+msgid "Close Tab"
+msgstr "بستن برگه"
+
+msgid "Attachment"
+msgstr "پیوست"
+
+msgid "Note"
+msgstr "توجه"
+
+msgid "Relate"
+msgstr "مربوط"
+
+msgid "Print"
+msgstr "چاپ"
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr "برگه قبلی"
+
+msgid "Next tab"
+msgstr "برگه بعدی"
+
+msgid "Global search"
+msgstr "جستجوی سراسری"
+
+msgid "Show this help"
+msgstr "نمایش این راهنما"
+
+msgid "Keyboard shortcuts"
+msgstr "میانبرهای صفحه کلید"
+
+msgid "Close"
+msgstr "بسته"
+
+msgid "Global shortcuts"
+msgstr "کلید های میانبر سراسری"
+
+msgid "Tab shortcuts"
+msgstr "کلید های میانبر برگه"
+
+msgid "Unable to reach the server."
+msgstr "امکان دسترسی به سرور وجود ندارد."
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr "ورود"
+
+msgid "User name"
+msgstr "نام کاربری"
+
+msgid "Database"
+msgstr "پایگاه داده"
+
+msgid "Your selection:"
+msgstr "انتخاب شما :"
+
+msgid "Cancel"
+msgstr "انصراف"
+
+msgid "OK"
+msgstr "قبول"
+
+msgid "Y"
+msgstr "Y"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "w"
+
+msgid "d"
+msgstr "d"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "توسط : "
+
+msgid ", "
+msgstr "، "
+
+msgid "y"
+msgstr "y"
+
+msgid "Yes"
+msgstr "بله"
+
+msgid "True"
+msgstr "درست"
+
+msgid "t"
+msgstr "t"
+
+msgid "False"
+msgstr "غلط"
+
+msgid "Message: "
+msgstr "پیام : "
+
+msgid "Warning: "
+msgstr "هشدار: "
+
+msgid "Always ignore this warning."
+msgstr "همیشه این هشدار را نادیده بگیرید."
+
+msgid "Do you want to proceed?"
+msgstr "آیا می خواهید پردازش شود؟"
+
+msgid "No"
+msgstr "خیر"
+
+msgid "Confirmation: "
+msgstr "تأییدیه : "
+
+msgid "Concurrency Exception"
+msgstr "همزمانی استثنا"
+
+msgid "Write Concurrency Warning: "
+msgstr "نوشتن همزمانی هشدار: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "این پرونده در حالی که شما در حال ویرایش آن بودید، اصلاح شد."
+
+msgid "Choose:"
+msgstr "انتخاب :"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"لغو\" برای انصراف ذخیره کردن ؛"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"مقایسه\" برای دیدن نسخه اصلاح شده ؛"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"نوشتن بهرحال\" برای ذخیره نسخه فعلی خود."
+
+msgid "Compare"
+msgstr "مقایسه"
+
+#, fuzzy
+msgid "Compare: %1"
+msgstr "مقایسه"
+
+msgid "Write Anyway"
+msgstr "نوشتن بهرحال"
+
+msgid "Application Error"
+msgstr "خطای برنامه"
+
+msgid "Report Bug"
+msgstr "گزارش باگ"
+
+#, fuzzy
+msgid "Processing"
+msgstr "در حال پردازش..."
+
+msgid "Search..."
+msgstr "جستجو..."
+
+msgid "Create..."
+msgstr "ایجاد..."
+
+msgid "Download"
+msgstr "دانلود"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "فونت"
+
+msgid "Size"
+msgstr "اندازه"
+
+msgid "Switch view"
+msgstr "تعویض نمایه"
+
+msgid "Previous Record"
+msgstr "پرونده قبلی"
+
+msgid "Next Record"
+msgstr "پرونده بعدی"
+
+msgid "Create a new record"
+msgstr "ایجاد یک پرونده جدید"
+
+msgid "Save this record"
+msgstr "ذخیره این پرونده"
+
+msgid "Reload"
+msgstr "بارگذاری مجدد"
+
+msgid "View Logs..."
+msgstr "مشاهده گزارشات..."
+
+msgid "Show revisions..."
+msgstr "مشاهده تجدیدنظر..."
+
+msgid "Add an attachment to the record"
+msgstr "پیوست را به پرونده اضافه کنید"
+
+msgid "Add a note to the record"
+msgstr "یک یادداشت به پرونده اضافه کنید"
+
+msgid "E-Mail..."
+msgstr ""
+
+#, fuzzy
+msgid "Send an e-mail using the record"
+msgstr "یک یادداشت به پرونده اضافه کنید"
+
+msgid "Export"
+msgstr "صادر کردن"
+
+msgid "Import"
+msgstr "وارد كردن"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"اقدام زیر نیاز به بستن همه برگه ها دارد.\n"
+"می خواهید ادامه دهید؟"
+
+msgid "Launch action"
+msgstr "انجام اقدام"
+
+msgid "Open related records"
+msgstr "بازکردن پرونده های مربوطه"
+
+msgid "Print report"
+msgstr "چاپ گزارش"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"این پرونده هنوز اصلاح نشده است.\n"
+"میخواهید آن را ذخیره کنید ؟"
+
+msgid "Record saved."
+msgstr "پرونده ذخیره شد."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "هم اکنون کار بر روی پرونده(ها) تکثیر شده انجام می شود."
+
+msgid "Are you sure to remove this record?"
+msgstr "برای حذف این پرونده اطمینان کامل دارید؟"
+
+msgid "Are you sure to remove those records?"
+msgstr "برای حذف این پرونده ها اطمینان کامل دارید؟"
+
+msgid "Records removed."
+msgstr "پرونده ها حذف شدند."
+
+msgid "Records not removed."
+msgstr "پرونده ها حذف نشدند."
+
+msgid "You have to select one record."
+msgstr "شما باید یک پرونده را انتخاب کنید."
+
+msgid "ID:"
+msgstr "شناسه :"
+
+#, fuzzy
+msgid "Created by:"
+msgstr "ایجاد..."
+
+#, fuzzy
+msgid "Created at:"
+msgstr "تاریخ ایجاد"
+
+#, fuzzy
+msgid "Edited by:"
+msgstr "ایجاد..."
+
+#, fuzzy
+msgid "Edited at:"
+msgstr "تاریخ اصلاح"
+
+msgid "Model: "
+msgstr "مدل : "
+
+msgid "Add..."
+msgstr "افزودن..."
+
+#, fuzzy
+msgid "Preview"
+msgstr "قبلی"
+
+#, fuzzy
+msgid "Template"
+msgstr "مربوط"
+
+#, fuzzy
+msgid "Attachment (%1)"
+msgstr "پیوست ها(1%)"
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr " از "
+
+msgid "Filters"
+msgstr "فیلترها"
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr "بوک مارک ها"
+
+msgid "Remove this bookmark"
+msgstr "حذف این بوک مارک"
+
+msgid "Bookmark this filter"
+msgstr "بوک مارک این فیلتر"
+
+msgid "Bookmark Name:"
+msgstr "نام بوک مارک :"
+
+msgid "Show active records"
+msgstr "نمایش پرونده های فعال"
+
+msgid "Show inactive records"
+msgstr "نمایش پرونده های غیرفعال"
+
+msgid "Find"
+msgstr "یافتن"
+
+msgid "From"
+msgstr "از"
+
+msgid "To"
+msgstr "به"
+
+msgid "Open the calendar"
+msgstr "بازکردن تقویم"
+
+msgid "ID"
+msgstr "شناسه"
+
+#, fuzzy
+msgid "Created by"
+msgstr "ایجاد..."
+
+#, fuzzy
+msgid "Created at"
+msgstr "تاریخ ایجاد"
+
+msgid "Modified by"
+msgstr ""
+
+#, fuzzy
+msgid "Modified at"
+msgstr "تاریخ اصلاح"
+
+#, fuzzy
+msgid "\"%1\" is required."
+msgstr "\"%1\" مورد نیاز است"
+
+#, fuzzy
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" با توجه به دامنه آن معتبر نیست"
+
+#, fuzzy
+msgid "The values of \"%1\" are not valid."
+msgstr "مقادیر \"%1\" معتبر نیستند"
+
+msgid "Pre-validation"
+msgstr "پیش-اعتبارسنجی"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "ترجمه"
+
+msgid "Edit"
+msgstr "ویرایش"
+
+msgid "Fuzzy"
+msgstr "نامانوس"
+
+msgid "You need to save the record before adding translations."
+msgstr "قبل از اضافه کردن ترجمه ها شما باید پرونده را ذخیره کنید."
+
+msgid "No other language available."
+msgstr "هیچ زبان دیگری در دسترس نیست."
+
+msgid "Show"
+msgstr "نمایش"
+
+msgid "Hide"
+msgstr "مخفی"
+
+#, fuzzy
+msgid "Open the record"
+msgstr "بازکردن پرونده "
+
+msgid "Clear the field"
+msgstr ""
+
+#, fuzzy
+msgid "Search a record"
+msgstr "جستجوی یک پرونده "
+
+msgid "Add"
+msgstr "افزودن"
+
+msgid "Remove"
+msgstr "حذف"
+
+msgid "Open"
+msgstr "باز"
+
+msgid "Undelete"
+msgstr "بازگردانی"
+
+msgid "Save As"
+msgstr "ذخیره با نام"
+
+msgid "Save As..."
+msgstr "ذخیره با نام..."
+
+msgid "Select"
+msgstr "انتخاب"
+
+msgid "Select..."
+msgstr "انتخاب..."
+
+msgid "Clear"
+msgstr "پاک کردن"
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "بیشتر"
+
+msgid "Today"
+msgstr "امروز"
+
+msgid "Month"
+msgstr "ماه"
+
+msgid "Week"
+msgstr "هفته"
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "انتخاب اقدام شما"
+
+msgid "No action defined."
+msgstr "اقدامی تعریف نشده."
+
+msgid "Attachments (%1)"
+msgstr "پیوست ها(1%)"
+
+msgid "Notes (%1)"
+msgstr "یادداشت ها(1%)"
+
+msgid "Search %1"
+msgstr "جستجو(1%)"
+
+msgid "Revision"
+msgstr "تجدید نظر"
+
+msgid "All Fields"
+msgstr "همه فیلد ها"
+
+msgid "Fields Selected"
+msgstr "فیلد های انتخاب شده"
+
+msgid "CSV Parameters"
+msgstr "مولفه های CSV"
+
+msgid "Delimiter:"
+msgstr "جدا کننده :"
+
+msgid "Quote Char:"
+msgstr "کاراکترنقل قول :"
+
+msgid "CSV Import: %1"
+msgstr "وارد کردن (CSV) : 1%"
+
+msgid "Auto-Detect"
+msgstr "شناسایی - خودکار"
+
+msgid "File to Import"
+msgstr "فایل برای واردکردن"
+
+msgid "Encoding:"
+msgstr "رمزگذاری :"
+
+msgid "Lines to Skip:"
+msgstr "چشم پوشی ازخطوط:"
+
+#, fuzzy
+msgid "You must select an import file first."
+msgstr "شما باید ابتدا فایل ورودی را انتخاب کنید"
+
+#, fuzzy
+msgid "An error occured in loading the file."
+msgstr "خطا هنگام بارگیری فایل"
+
+msgid "Error processing the file at field %1."
+msgstr "خطای پردازش فایل واقع در فیلد : \"%1\"."
+
+msgid "Error"
+msgstr "خطا"
+
+msgid "Error occured in loading the file"
+msgstr "خطا هنگام بارگیری فایل"
+
+msgid "CSV Export: %1"
+msgstr "صادرکردن (CSV) : 1%"
+
+msgid "Save Export"
+msgstr "ذخیره استخراج"
+
+#, fuzzy
+msgid "URL Export"
+msgstr "صادر کردن"
+
+msgid "Delete Export"
+msgstr "حذف استخراج"
+
+msgid "Predefined Exports"
+msgstr "استخراج از پیش تعریف شده"
+
+#, fuzzy
+msgid "Selected Records"
+msgstr "پرونده بعدی"
+
+#, fuzzy
+msgid "Listed Records"
+msgstr "پرونده بعدی"
+
+#, fuzzy
+msgid "Export:"
+msgstr "صادر کردن"
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr "اضافه کردن نام های فیلد"
+
+msgid "%1 (string)"
+msgstr "\"1%\" (متنی)"
+
+msgid "%1 (model name)"
+msgstr "\"1%\" (نام مدل)"
+
+msgid "%1 (record name)"
+msgstr "\"1%\" (نام پرونده)"
+
+msgid "What is the name of this export?"
+msgstr "نام این فایل استخراجی چیست؟"
+
+msgid "Override %1 definition?"
+msgstr "بازنویسی \"1%\" تعاریف؟"
+
+msgid "E-mail %1"
+msgstr ""
+
+#, fuzzy
+msgid "To:"
+msgstr "به"
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+#, fuzzy
+msgid "Reports"
+msgstr "گزارش باگ"
+
+#, fuzzy
+msgid "Attachments"
+msgstr "پیوست"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+#, fuzzy
+msgid "Remove File"
+msgstr "حذف"
+
+msgid "Wizard"
+msgstr "دستیار نصب"
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/fi.po b/sao/locale/fi.po
new file mode 100644
index 0000000000..e063a83b57
--- /dev/null
+++ b/sao/locale/fi.po
@@ -0,0 +1,650 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr ""
+
+msgid "Manage..."
+msgstr ""
+
+msgid "Logout"
+msgstr ""
+
+msgid "Action"
+msgstr ""
+
+msgid "New"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Switch"
+msgstr ""
+
+msgid "Reload/Undo"
+msgstr ""
+
+msgid "Duplicate"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
+msgid "Search"
+msgstr ""
+
+msgid "Close Tab"
+msgstr ""
+
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
+msgid "Relate"
+msgstr ""
+
+msgid "Print"
+msgstr ""
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr ""
+
+msgid "Next tab"
+msgstr ""
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr ""
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr ""
+
+msgid "User name"
+msgstr ""
+
+msgid "Database"
+msgstr ""
+
+msgid "Your selection:"
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Y"
+msgstr ""
+
+msgid "M"
+msgstr ""
+
+msgid "w"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "h"
+msgstr ""
+
+msgid "m"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "By: "
+msgstr ""
+
+#, fuzzy
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "True"
+msgstr ""
+
+msgid "t"
+msgstr ""
+
+msgid "False"
+msgstr ""
+
+msgid "Message: "
+msgstr ""
+
+msgid "Warning: "
+msgstr ""
+
+msgid "Always ignore this warning."
+msgstr ""
+
+msgid "Do you want to proceed?"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Confirmation: "
+msgstr ""
+
+msgid "Concurrency Exception"
+msgstr ""
+
+msgid "Write Concurrency Warning: "
+msgstr ""
+
+msgid "This record has been modified while you were editing it."
+msgstr ""
+
+msgid "Choose:"
+msgstr ""
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr ""
+
+msgid "\"Compare\" to see the modified version;"
+msgstr ""
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Compare: %1"
+msgstr ""
+
+msgid "Write Anyway"
+msgstr ""
+
+msgid "Application Error"
+msgstr ""
+
+msgid "Report Bug"
+msgstr ""
+
+msgid "Processing"
+msgstr ""
+
+msgid "Search..."
+msgstr ""
+
+msgid "Create..."
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Switch view"
+msgstr ""
+
+msgid "Previous Record"
+msgstr ""
+
+msgid "Next Record"
+msgstr ""
+
+msgid "Create a new record"
+msgstr ""
+
+msgid "Save this record"
+msgstr ""
+
+msgid "Reload"
+msgstr ""
+
+msgid "View Logs..."
+msgstr ""
+
+msgid "Show revisions..."
+msgstr ""
+
+msgid "Add an attachment to the record"
+msgstr ""
+
+msgid "Add a note to the record"
+msgstr ""
+
+msgid "E-Mail..."
+msgstr ""
+
+msgid "Send an e-mail using the record"
+msgstr ""
+
+msgid "Export"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+
+msgid "Launch action"
+msgstr ""
+
+msgid "Open related records"
+msgstr ""
+
+msgid "Print report"
+msgstr ""
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+
+msgid "Record saved."
+msgstr ""
+
+msgid "Working now on the duplicated record(s)."
+msgstr ""
+
+msgid "Are you sure to remove this record?"
+msgstr ""
+
+msgid "Are you sure to remove those records?"
+msgstr ""
+
+msgid "Records removed."
+msgstr ""
+
+msgid "Records not removed."
+msgstr ""
+
+msgid "You have to select one record."
+msgstr ""
+
+msgid "ID:"
+msgstr ""
+
+msgid "Created by:"
+msgstr ""
+
+msgid "Created at:"
+msgstr ""
+
+msgid "Edited by:"
+msgstr ""
+
+msgid "Edited at:"
+msgstr ""
+
+msgid "Model: "
+msgstr ""
+
+msgid "Add..."
+msgstr ""
+
+msgid "Preview"
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Attachment (%1)"
+msgstr ""
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr ""
+
+msgid "Filters"
+msgstr ""
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr ""
+
+msgid "Remove this bookmark"
+msgstr ""
+
+msgid "Bookmark this filter"
+msgstr ""
+
+msgid "Bookmark Name:"
+msgstr ""
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr ""
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "Created by"
+msgstr ""
+
+msgid "Created at"
+msgstr ""
+
+msgid "Modified by"
+msgstr ""
+
+msgid "Modified at"
+msgstr ""
+
+msgid "\"%1\" is required."
+msgstr ""
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr ""
+
+msgid "The values of \"%1\" are not valid."
+msgstr ""
+
+msgid "Pre-validation"
+msgstr ""
+
+#, fuzzy
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Fuzzy"
+msgstr ""
+
+msgid "You need to save the record before adding translations."
+msgstr ""
+
+msgid "No other language available."
+msgstr ""
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Open"
+msgstr ""
+
+msgid "Undelete"
+msgstr ""
+
+msgid "Save As"
+msgstr ""
+
+msgid "Save As..."
+msgstr ""
+
+msgid "Select"
+msgstr ""
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr ""
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr ""
+
+#, fuzzy
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr ""
+
+msgid "Today"
+msgstr ""
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr ""
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr ""
+
+msgid "Select your action"
+msgstr ""
+
+msgid "No action defined."
+msgstr ""
+
+msgid "Attachments (%1)"
+msgstr ""
+
+msgid "Notes (%1)"
+msgstr ""
+
+msgid "Search %1"
+msgstr ""
+
+msgid "Revision"
+msgstr ""
+
+msgid "All Fields"
+msgstr ""
+
+msgid "Fields Selected"
+msgstr ""
+
+msgid "CSV Parameters"
+msgstr ""
+
+msgid "Delimiter:"
+msgstr ""
+
+msgid "Quote Char:"
+msgstr ""
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr ""
+
+msgid "File to Import"
+msgstr ""
+
+msgid "Encoding:"
+msgstr ""
+
+msgid "Lines to Skip:"
+msgstr ""
+
+msgid "You must select an import file first."
+msgstr ""
+
+msgid "An error occured in loading the file."
+msgstr ""
+
+msgid "Error processing the file at field %1."
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Error occured in loading the file"
+msgstr ""
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr ""
+
+msgid "URL Export"
+msgstr ""
+
+msgid "Delete Export"
+msgstr ""
+
+msgid "Predefined Exports"
+msgstr ""
+
+msgid "Selected Records"
+msgstr ""
+
+msgid "Listed Records"
+msgstr ""
+
+msgid "Export:"
+msgstr ""
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr ""
+
+msgid "%1 (string)"
+msgstr ""
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr ""
+
+msgid "Override %1 definition?"
+msgstr ""
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+msgid "Reports"
+msgstr ""
+
+msgid "Attachments"
+msgstr ""
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+msgid "Remove File"
+msgstr ""
+
+msgid "Wizard"
+msgstr ""
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/fr.po b/sao/locale/fr.po
new file mode 100644
index 0000000000..1eb088266a
--- /dev/null
+++ b/sao/locale/fr.po
@@ -0,0 +1,685 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 15 2019 16:53:42 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 01 2019 13:14:07 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Mar 01 2019 00:18:48 GMT+0100 (CET)
+# Generated by grunt-xgettext on Fri Feb 01 2019 00:07:47 GMT+0100 (CET)
+# Generated by grunt-xgettext on Tue Jan 01 2019 00:13:07 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sat Dec 01 2018 00:17:31 GMT+0100 (CET)
+# Generated by grunt-xgettext on Thu Nov 01 2018 00:08:43 GMT+0100 (CET)
+# Generated by grunt-xgettext on Mon Oct 01 2018 00:07:22 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Sep 14 2018 22:59:37 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sun Sep 09 2018 10:24:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Sep 04 2018 13:54:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 14 2018 17:56:54 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Apr 06 2018 22:57:49 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Oct 09 2017 19:35:04 GMT+0200 (CEST)
+msgid "Are your sure to leave?"
+msgstr "Êtes-vous sûr de quitter ?"
+
+msgid "Favorites"
+msgstr "Favoris"
+
+msgid "Manage..."
+msgstr "Gérer..."
+
+# Generated by grunt-xgettext on Thu Mar 31 2016 17:50:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Oct 16 2015 17:37:32 GMT+0200 (CEST)
+msgid "Logout"
+msgstr "Déconnexion"
+
+msgid "Action"
+msgstr "Actions"
+
+msgid "New"
+msgstr "Nouveau"
+
+msgid "Save"
+msgstr "Sauver"
+
+msgid "Switch"
+msgstr "Basculer"
+
+msgid "Reload/Undo"
+msgstr "Recharger/Annuler"
+
+msgid "Duplicate"
+msgstr "Dupliquer"
+
+msgid "Delete"
+msgstr "Supprimer"
+
+msgid "Previous"
+msgstr "Précédent"
+
+msgid "Next"
+msgstr "Suivant"
+
+msgid "Search"
+msgstr "Rechercher"
+
+msgid "Close Tab"
+msgstr "Fermer l'onglet"
+
+msgid "Attachment"
+msgstr "Attachement"
+
+msgid "Note"
+msgstr "Note"
+
+msgid "Relate"
+msgstr "Relation"
+
+msgid "Print"
+msgstr "Imprimer"
+
+msgid "E-Mail"
+msgstr "E-mail"
+
+msgid "Previous tab"
+msgstr "Onglet précédent"
+
+msgid "Next tab"
+msgstr "Onglet suivant"
+
+msgid "Global search"
+msgstr "Recherche globale"
+
+msgid "Show this help"
+msgstr "Affiche cette aide"
+
+msgid "Keyboard shortcuts"
+msgstr "Raccourcis clavier"
+
+msgid "Close"
+msgstr "Fermer"
+
+msgid "Global shortcuts"
+msgstr "Raccourcis globaux"
+
+msgid "Tab shortcuts"
+msgstr "Raccourcis d'onglet"
+
+msgid "Unable to reach the server."
+msgstr "Impossible de joindre le serveur."
+
+msgid "Too many requests. Try again later."
+msgstr "Trop de demandes. Réessayez plus tard."
+
+msgid "Login"
+msgstr "Connexion"
+
+msgid "User name"
+msgstr "Nom d'utilisateur"
+
+msgid "Database"
+msgstr "Base de données"
+
+msgid "Your selection:"
+msgstr "Votre sélection :"
+
+msgid "Cancel"
+msgstr "Annuler"
+
+msgid "OK"
+msgstr "Valider"
+
+msgid "Y"
+msgstr "A"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "S"
+
+msgid "d"
+msgstr "j"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "Par : "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "y"
+
+msgid "Yes"
+msgstr "Oui"
+
+msgid "True"
+msgstr "Vrai"
+
+msgid "t"
+msgstr "v"
+
+msgid "False"
+msgstr "Faux"
+
+msgid "Message: "
+msgstr "Message : "
+
+msgid "Warning: "
+msgstr "Avertissement : "
+
+msgid "Always ignore this warning."
+msgstr "Toujours ignorer cet avertissement."
+
+msgid "Do you want to proceed?"
+msgstr "Souhaitez-vous continuer ?"
+
+msgid "No"
+msgstr "Non"
+
+msgid "Confirmation: "
+msgstr "Confirmation : "
+
+msgid "Concurrency Exception"
+msgstr "Erreur d'accès concurrent"
+
+msgid "Write Concurrency Warning: "
+msgstr "Attention, accès en écriture concurrents : "
+
+msgid "This record has been modified while you were editing it."
+msgstr ""
+"Cet enregistrement a été modifié pendant que vous étiez en train de "
+"l'éditer."
+
+msgid "Choose:"
+msgstr "Choisissez :"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "« Annuler » pour annuler vos modifications ;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "« Comparer » pour voir la nouvelle version ;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "« Écraser » pour sauver vos modifications."
+
+msgid "Compare"
+msgstr "Comparer"
+
+msgid "Compare: %1"
+msgstr "Comparer : %1"
+
+msgid "Write Anyway"
+msgstr "Écraser"
+
+msgid "Application Error"
+msgstr "Erreur applicative"
+
+msgid "Report Bug"
+msgstr "Rapporter un bogue"
+
+msgid "Processing"
+msgstr "Traitement en cours"
+
+msgid "Search..."
+msgstr "Recherche..."
+
+msgid "Create..."
+msgstr "Créer..."
+
+msgid "Download"
+msgstr "Télécharger"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Police"
+
+msgid "Size"
+msgstr "Taille"
+
+msgid "Switch view"
+msgstr "Basculer la vue"
+
+msgid "Previous Record"
+msgstr "Enregistrement précédent"
+
+msgid "Next Record"
+msgstr "Enregistrement suivant"
+
+msgid "Create a new record"
+msgstr "Créer un nouvel enregistrement"
+
+msgid "Save this record"
+msgstr "Sauver cet enregistrement"
+
+msgid "Reload"
+msgstr "Recharger"
+
+msgid "View Logs..."
+msgstr "Voir les Logs..."
+
+msgid "Show revisions..."
+msgstr "Afficher les révisions..."
+
+msgid "Add an attachment to the record"
+msgstr "Ajouter un attachement à l'enregistrement"
+
+msgid "Add a note to the record"
+msgstr "Ajouter une note à l'enregistrement"
+
+msgid "E-Mail..."
+msgstr "E-mail..."
+
+msgid "Send an e-mail using the record"
+msgstr "Envoyer un e-mail en utilisant l'enregistrement"
+
+msgid "Export"
+msgstr "Exporter"
+
+msgid "Import"
+msgstr "Importer"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"L'action suivante nécessite de fermer tous les onglets.\n"
+"Voulez-vous continuer ?"
+
+msgid "Launch action"
+msgstr "Lancer une action"
+
+msgid "Open related records"
+msgstr "Ouvrir les enregistrements liés"
+
+msgid "Print report"
+msgstr "Imprimer un rapport"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Cet enregistrement a été modifié\n"
+"voulez-vous le sauvegarder ?"
+
+msgid "Record saved."
+msgstr "Enregistrement sauvegardé."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Sur les enregistrement(s) dupliqué(s) maintenant."
+
+msgid "Are you sure to remove this record?"
+msgstr "Êtes-vous sûr de vouloir supprimer cet enregistrement ?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Êtes-vous sûr de vouloir supprimer ces enregistrements ?"
+
+msgid "Records removed."
+msgstr "Enregistrements supprimés."
+
+msgid "Records not removed."
+msgstr "Enregistrements non supprimés."
+
+msgid "You have to select one record."
+msgstr "Vous devez sélectionner un enregistrement."
+
+msgid "ID:"
+msgstr "ID :"
+
+msgid "Created by:"
+msgstr "Crée par :"
+
+msgid "Created at:"
+msgstr "Crée le :"
+
+msgid "Edited by:"
+msgstr "Édité par :"
+
+msgid "Edited at:"
+msgstr "Édité le :"
+
+msgid "Model: "
+msgstr "Modèle : "
+
+msgid "Add..."
+msgstr "Ajouter..."
+
+msgid "Preview"
+msgstr "Aperçu"
+
+msgid "Template"
+msgstr "Modèle"
+
+msgid "Attachment (%1)"
+msgstr "Attachement (%1)"
+
+msgid "Note (%1/%2)"
+msgstr "Note (%1/%2)"
+
+msgid " of "
+msgstr " de "
+
+msgid "Filters"
+msgstr "Filtres"
+
+msgid "Clear Search"
+msgstr "Effacer la recherche"
+
+msgid "Bookmarks"
+msgstr "Marques-pages"
+
+msgid "Remove this bookmark"
+msgstr "Supprimer ce marque-page"
+
+msgid "Bookmark this filter"
+msgstr "Sauver ce filtre"
+
+msgid "Bookmark Name:"
+msgstr "Nom du marque-page :"
+
+msgid "Show active records"
+msgstr "Montrer les enregistrements actifs"
+
+msgid "Show inactive records"
+msgstr "Montrer les enregistrements inactifs"
+
+msgid "Find"
+msgstr "Chercher"
+
+msgid "From"
+msgstr "De"
+
+msgid "To"
+msgstr "À"
+
+msgid "Open the calendar"
+msgstr "Ouvrir le calendrier"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Created by"
+msgstr "Créé par"
+
+msgid "Created at"
+msgstr "Crée le"
+
+msgid "Modified by"
+msgstr "Modifié par"
+
+msgid "Modified at"
+msgstr "Modifié le"
+
+msgid "\"%1\" is required."
+msgstr "« %1 » est requis."
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr "« %1 » n'est pas valide selon son domaine."
+
+msgid "The values of \"%1\" are not valid."
+msgstr "Les valeurs de « %1 » ne sont pas valides."
+
+msgid "Pre-validation"
+msgstr "Pré-validation"
+
+msgid ":"
+msgstr " :"
+
+msgid "Translate"
+msgstr "Traduire"
+
+msgid "Edit"
+msgstr "Éditer"
+
+msgid "Fuzzy"
+msgstr "Floue"
+
+msgid "You need to save the record before adding translations."
+msgstr ""
+"Vous devez sauvegarder l'enregistrement avant d'ajouter des traductions."
+
+msgid "No other language available."
+msgstr "Pas d'autre langue disponible."
+
+msgid "Show"
+msgstr "Afficher"
+
+msgid "Hide"
+msgstr "Masquer"
+
+msgid "Open the record"
+msgstr "Ouvrir l'enregistrement"
+
+msgid "Clear the field"
+msgstr "Effacer le champ"
+
+msgid "Search a record"
+msgstr "Chercher un enregistrement"
+
+msgid "Add"
+msgstr "Ajouter"
+
+msgid "Remove"
+msgstr "Enlever"
+
+msgid "Open"
+msgstr "Ouvrir"
+
+msgid "Undelete"
+msgstr "Restaurer"
+
+msgid "Save As"
+msgstr "Enregistrer sous"
+
+msgid "Save As..."
+msgstr "Enregistrer sous..."
+
+msgid "Select"
+msgstr "Sélectionner"
+
+msgid "Select..."
+msgstr "Sélectionner..."
+
+msgid "Clear"
+msgstr "Effacer"
+
+msgid "Choose a language"
+msgstr "Choisir une langue"
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr " : "
+
+msgid "More"
+msgstr "Plus"
+
+msgid "Today"
+msgstr "Aujourd'hui"
+
+msgid "Month"
+msgstr "Mois"
+
+msgid "Week"
+msgstr "Semaine"
+
+msgid "Day"
+msgstr "Jour"
+
+msgid ",..."
+msgstr ",..."
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Sélectionnez votre action"
+
+msgid "No action defined."
+msgstr "Pas d'action définie."
+
+msgid "Attachments (%1)"
+msgstr "Attachements (%1)"
+
+msgid "Notes (%1)"
+msgstr "Notes (%1)"
+
+msgid "Search %1"
+msgstr "Recherche %1"
+
+msgid "Revision"
+msgstr "Révision"
+
+msgid "All Fields"
+msgstr "Tous les champs"
+
+msgid "Fields Selected"
+msgstr "Champs sélectionnés"
+
+msgid "CSV Parameters"
+msgstr "Paramètres CSV"
+
+msgid "Delimiter:"
+msgstr "Délimiteur :"
+
+msgid "Quote Char:"
+msgstr "Caractère de guillemet :"
+
+msgid "CSV Import: %1"
+msgstr "Import CSV : %1"
+
+msgid "Auto-Detect"
+msgstr "Détection automatique"
+
+msgid "File to Import"
+msgstr "Fichier à importer"
+
+msgid "Encoding:"
+msgstr "Codage :"
+
+msgid "Lines to Skip:"
+msgstr "Lignes à ignorer :"
+
+msgid "You must select an import file first."
+msgstr "Vous devez d'abord sélectionner un fichier d'import."
+
+msgid "An error occured in loading the file."
+msgstr "Une erreur a eu lieu au chargement du fichier."
+
+msgid "Error processing the file at field %1."
+msgstr "Erreur lors du traitement du fichier du champ %1."
+
+msgid "Error"
+msgstr "Erreur"
+
+msgid "Error occured in loading the file"
+msgstr "Une erreur a eu lieu au chargement du fichier"
+
+msgid "CSV Export: %1"
+msgstr "Export CSV : %1"
+
+msgid "Save Export"
+msgstr "Sauver l'exportation"
+
+msgid "URL Export"
+msgstr "URL d'exportation"
+
+msgid "Delete Export"
+msgstr "Supprimer l'exportation"
+
+msgid "Predefined Exports"
+msgstr "Exportations prédéfinies"
+
+msgid "Selected Records"
+msgstr "Enregistrements sélectionnés"
+
+msgid "Listed Records"
+msgstr "Enregistrements listés"
+
+msgid "Export:"
+msgstr "Exporter :"
+
+msgid "Ignore search limit"
+msgstr "Ignorer la limite de recherche"
+
+msgid "Use locale format"
+msgstr "Utiliser le format local"
+
+msgid "Add Field Names"
+msgstr "Ajouter les noms des champs"
+
+msgid "%1 (string)"
+msgstr "%1 (string)"
+
+msgid "%1 (model name)"
+msgstr "%1 (nom de l'enregistrement)"
+
+msgid "%1 (record name)"
+msgstr "%1 (nom de l'enregistrement)"
+
+msgid "What is the name of this export?"
+msgstr "Quel est le nom de cet export ?"
+
+msgid "Override %1 definition?"
+msgstr "Surcharger la définition %1 ?"
+
+msgid "E-mail %1"
+msgstr "E-mail %1"
+
+msgid "To:"
+msgstr "À :"
+
+msgid "Cc:"
+msgstr "Cc :"
+
+msgid "Bcc:"
+msgstr "Cci :"
+
+msgid "Subject:"
+msgstr "Objet :"
+
+msgid "Reports"
+msgstr "Rapports"
+
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-04-19 21:49+0000\n"
+"PO-Revision-Date: 2021-04-19 21:49+0000\n"
+"Last-Translator: Cedric Krier \n"
+"Language-Team: LANGUAGE \n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 4.5.3\n"
+
+msgid "Attachments"
+msgstr "Pièces jointes"
+
+msgid "Files"
+msgstr "Fichiers"
+
+msgid "Send"
+msgstr "Envoyer"
+
+msgid "Remove File"
+msgstr "Supprimer le fichier"
+
+msgid "Wizard"
+msgstr "Assistant"
+
+msgid "Translate view"
+msgstr "Traduire la vue"
diff --git a/sao/locale/hu.po b/sao/locale/hu.po
new file mode 100644
index 0000000000..f4549239e7
--- /dev/null
+++ b/sao/locale/hu.po
@@ -0,0 +1,670 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr "Könyvjelzők"
+
+msgid "Manage..."
+msgstr "Módosítás..."
+
+msgid "Logout"
+msgstr "Kilépés"
+
+msgid "Action"
+msgstr "Művelet"
+
+msgid "New"
+msgstr "Új"
+
+msgid "Save"
+msgstr "Mentés"
+
+msgid "Switch"
+msgstr "Átvált"
+
+msgid "Reload/Undo"
+msgstr "Újratöltés / Visszavonás"
+
+msgid "Duplicate"
+msgstr "Duplázás"
+
+msgid "Delete"
+msgstr "Törlés"
+
+msgid "Previous"
+msgstr "Vissza"
+
+msgid "Next"
+msgstr "Tovább"
+
+msgid "Search"
+msgstr "Keresés"
+
+msgid "Close Tab"
+msgstr "Lap bezárása"
+
+msgid "Attachment"
+msgstr "Melléklet"
+
+msgid "Note"
+msgstr "Jegyzetek"
+
+msgid "Relate"
+msgstr "Kapcsolat"
+
+msgid "Print"
+msgstr "Nyomtatás"
+
+msgid "E-Mail"
+msgstr "E-mail"
+
+msgid "Previous tab"
+msgstr "Előző lap"
+
+msgid "Next tab"
+msgstr "Következő lap"
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr "Gyorsbillentyűk"
+
+msgid "Close"
+msgstr "Bezárás"
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr ""
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr "Bejelentkezés"
+
+msgid "User name"
+msgstr "Felhasználónév"
+
+msgid "Database"
+msgstr "Adatbázis"
+
+msgid "Your selection:"
+msgstr "Az ön választásai:"
+
+msgid "Cancel"
+msgstr "Mégse"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Y"
+msgstr "É"
+
+msgid "M"
+msgstr "H"
+
+msgid "w"
+msgstr "h"
+
+msgid "d"
+msgstr "t"
+
+msgid "h"
+msgstr "ó"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr ""
+
+#, fuzzy
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "J"
+
+msgid "Yes"
+msgstr "Igen"
+
+msgid "True"
+msgstr "Igaz"
+
+msgid "t"
+msgstr "w"
+
+msgid "False"
+msgstr "Hamis"
+
+msgid "Message: "
+msgstr "Üzenet: "
+
+msgid "Warning: "
+msgstr ""
+
+msgid "Always ignore this warning."
+msgstr "Ne mutassa többet ezt a figyelmeztetést"
+
+msgid "Do you want to proceed?"
+msgstr "Akarja folyatni?"
+
+msgid "No"
+msgstr "Nem"
+
+msgid "Confirmation: "
+msgstr ""
+
+msgid "Concurrency Exception"
+msgstr "Egyidejű módosítási hiba"
+
+msgid "Write Concurrency Warning: "
+msgstr ""
+
+msgid "This record has been modified while you were editing it."
+msgstr ""
+"Ezt a rekordot valaki más módosította az idő alatt, míg Ön dolgozott rajta."
+
+msgid "Choose:"
+msgstr "Válasszon:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "„Mégse”, hogy ne mentse el;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr ""
+"„Összehasonlítás”, hogy megtekintse a másik felhasználó által módosított "
+"változatot;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "„Felülírás”, hogy a másik felhasználóét az Ön verziójával felülírja."
+
+msgid "Compare"
+msgstr "Összehasonlítás"
+
+msgid "Compare: %1"
+msgstr "Összehasonlítás: %1"
+
+msgid "Write Anyway"
+msgstr "Felülírás"
+
+msgid "Application Error"
+msgstr "Alkalmazáshiba"
+
+msgid "Report Bug"
+msgstr "A hiba jelentése"
+
+msgid "Processing"
+msgstr "Folyamatban"
+
+msgid "Search..."
+msgstr "Keresés..."
+
+msgid "Create..."
+msgstr "Létrehozás..."
+
+msgid "Download"
+msgstr "Letöltés"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Betűtípus"
+
+msgid "Size"
+msgstr "Méret"
+
+msgid "Switch view"
+msgstr "Nézet váltása"
+
+msgid "Previous Record"
+msgstr "Előző rekord"
+
+msgid "Next Record"
+msgstr "Következő rekord"
+
+msgid "Create a new record"
+msgstr "Új rekord létrehozása"
+
+msgid "Save this record"
+msgstr "Rekord mentése"
+
+msgid "Reload"
+msgstr "Újratöltés"
+
+msgid "View Logs..."
+msgstr "Napló megtekintése..."
+
+msgid "Show revisions..."
+msgstr "Feldolgozások megtekintése"
+
+msgid "Add an attachment to the record"
+msgstr "Melléklet hozzáadása a rekordhoz"
+
+msgid "Add a note to the record"
+msgstr "Jegyzet hozzáadása a rekordhoz"
+
+msgid "E-Mail..."
+msgstr ""
+
+msgid "Send an e-mail using the record"
+msgstr "E-mail küldése a rekord adataival"
+
+msgid "Export"
+msgstr "Exportálás"
+
+msgid "Import"
+msgstr "Importálás"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"A továbblépéshez be kell zárnia minden nyitott lapot.\n"
+"Biztosan tovább akar lépni?"
+
+msgid "Launch action"
+msgstr "Művelet indítása"
+
+msgid "Open related records"
+msgstr "Kapcsolódó rekordok megnyitása"
+
+msgid "Print report"
+msgstr "Nyomtatás"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Módosította ezt a rekordot,\n"
+"el akarja menteni?"
+
+msgid "Record saved."
+msgstr "Rekord elmentve."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Most az új másolaton(okon) dolgozik."
+
+msgid "Are you sure to remove this record?"
+msgstr "Biztos törölni szeretné?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Biztos törölni szeretné?"
+
+msgid "Records removed."
+msgstr "Rekordok törölve."
+
+msgid "Records not removed."
+msgstr "A rekordok nem lettek törölve."
+
+msgid "You have to select one record."
+msgstr "Ki kell választania egy rekordot."
+
+msgid "ID:"
+msgstr ""
+
+msgid "Created by:"
+msgstr "Létrehozta:"
+
+msgid "Created at:"
+msgstr "Létrehozás dátuma:"
+
+msgid "Edited by:"
+msgstr "Módosította:"
+
+msgid "Edited at:"
+msgstr "Módosítás dátuma:"
+
+msgid "Model: "
+msgstr "Elem: "
+
+msgid "Add..."
+msgstr "Hozzáadás..."
+
+msgid "Preview"
+msgstr "Előnézet"
+
+msgid "Template"
+msgstr "Sablon"
+
+msgid "Attachment (%1)"
+msgstr "Melléklet (%1)"
+
+msgid "Note (%1/%2)"
+msgstr "Jegyzet (%1/%2)"
+
+msgid " of "
+msgstr " , összesen "
+
+msgid "Filters"
+msgstr "Szűrők"
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr "Elmentett szűrők"
+
+msgid "Remove this bookmark"
+msgstr "Ez az elmentett szűrő eltávolítása"
+
+msgid "Bookmark this filter"
+msgstr "Ez a szűrő elmentése"
+
+msgid "Bookmark Name:"
+msgstr "Könyvjelző neve:"
+
+msgid "Show active records"
+msgstr "Aktív rekordok megjelenítése"
+
+msgid "Show inactive records"
+msgstr "Inaktív rekordok megjelenítése"
+
+msgid "Find"
+msgstr "Keresés"
+
+msgid "From"
+msgstr "Küldő"
+
+msgid "To"
+msgstr "Címzett"
+
+msgid "Open the calendar"
+msgstr "Naptár megnyitása"
+
+msgid "ID"
+msgstr ""
+
+msgid "Created by"
+msgstr "Létrehozta"
+
+msgid "Created at"
+msgstr "Létrehozás dátuma"
+
+msgid "Modified by"
+msgstr ""
+
+msgid "Modified at"
+msgstr ""
+
+msgid "\"%1\" is required."
+msgstr ""
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr ""
+
+msgid "The values of \"%1\" are not valid."
+msgstr ""
+
+msgid "Pre-validation"
+msgstr "Adatkitöltés ellenőrzése"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Fordítás"
+
+msgid "Edit"
+msgstr "Módosítás"
+
+msgid "Fuzzy"
+msgstr "Pontatlan"
+
+msgid "You need to save the record before adding translations."
+msgstr "El kell menteni a rekordot mielőtt hozzáadja a fordítást."
+
+msgid "No other language available."
+msgstr "Másik nyelv nem elérhető."
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr "Elrejtés"
+
+msgid "Open the record"
+msgstr "Rekord megnyitása"
+
+msgid "Clear the field"
+msgstr "A mező kiürítése"
+
+msgid "Search a record"
+msgstr "Rekord keresése"
+
+msgid "Add"
+msgstr "Hozzáad"
+
+msgid "Remove"
+msgstr "Eltávolítás"
+
+msgid "Open"
+msgstr "Megnyitás"
+
+msgid "Undelete"
+msgstr ""
+
+msgid "Save As"
+msgstr "Mentés másként"
+
+msgid "Save As..."
+msgstr "Mentés másként..."
+
+msgid "Select"
+msgstr "Kiválaszt"
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr "Törlés"
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr ""
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr ""
+
+msgid "Today"
+msgstr "Ma"
+
+msgid "Month"
+msgstr "Hónap"
+
+msgid "Week"
+msgstr "Hét"
+
+msgid "Day"
+msgstr "Nap"
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr ""
+
+msgid "Select your action"
+msgstr "Válasszon műveletet"
+
+msgid "No action defined."
+msgstr ""
+
+msgid "Attachments (%1)"
+msgstr "Mellékletek (%1)"
+
+msgid "Notes (%1)"
+msgstr "Jegyzetek (%1)"
+
+msgid "Search %1"
+msgstr ""
+
+msgid "Revision"
+msgstr "Szerkesztés"
+
+msgid "All Fields"
+msgstr "Összes mező"
+
+msgid "Fields Selected"
+msgstr "Kiválasztott mezők"
+
+msgid "CSV Parameters"
+msgstr "CSV paraméterek"
+
+msgid "Delimiter:"
+msgstr "Elválasztójel:"
+
+msgid "Quote Char:"
+msgstr "Karakterlánc-elválasztó:"
+
+msgid "CSV Import: %1"
+msgstr "Importálás CSV-ből: %1"
+
+msgid "Auto-Detect"
+msgstr "Automatikus felismerés"
+
+msgid "File to Import"
+msgstr "Importadatok"
+
+msgid "Encoding:"
+msgstr "Kódolás:"
+
+msgid "Lines to Skip:"
+msgstr "Átugrandó sorok:"
+
+msgid "You must select an import file first."
+msgstr "Először adja meg a betöltendő fájlt."
+
+msgid "An error occured in loading the file."
+msgstr ""
+
+msgid "Error processing the file at field %1."
+msgstr ""
+
+msgid "Error"
+msgstr "Hiba"
+
+msgid "Error occured in loading the file"
+msgstr ""
+
+msgid "CSV Export: %1"
+msgstr "Exportálás CSV-be: %1"
+
+msgid "Save Export"
+msgstr "Oszloplista elmentése"
+
+msgid "URL Export"
+msgstr "Exportálás URL-je"
+
+msgid "Delete Export"
+msgstr "Oszloplista törlése"
+
+msgid "Predefined Exports"
+msgstr "Elmentett oszloplisták"
+
+msgid "Selected Records"
+msgstr "Csak a kiválasztott rekordokat"
+
+msgid "Listed Records"
+msgstr "A listán szereplő összes rekordot"
+
+msgid "Export:"
+msgstr "Exportálás:"
+
+msgid "Ignore search limit"
+msgstr "Keresési korlát nélkül"
+
+msgid "Use locale format"
+msgstr "A felhasználó nyelvén"
+
+msgid "Add Field Names"
+msgstr "Mezőnevek hozzáadása"
+
+msgid "%1 (string)"
+msgstr ""
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr "Mi legyen az oszloplista neve?"
+
+msgid "Override %1 definition?"
+msgstr ""
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr "Címzett:"
+
+msgid "Cc:"
+msgstr "Másolatot kap:"
+
+msgid "Bcc:"
+msgstr "Rejtett másolat:"
+
+msgid "Subject:"
+msgstr "Tárgy:"
+
+msgid "Reports"
+msgstr "Nyomtatványok"
+
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-04-10 10:06+0000\n"
+"PO-Revision-Date: 2021-04-10 10:06+0000\n"
+"Last-Translator: Dukai Gábor \n"
+"Language-Team: LANGUAGE \n"
+"Language: hu\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 4.5.2\n"
+
+msgid "Attachments"
+msgstr "Mellékletek"
+
+msgid "Files"
+msgstr "Fájlok"
+
+msgid "Send"
+msgstr "Küldés"
+
+msgid "Remove File"
+msgstr "Fájl eltávolítása"
+
+msgid "Wizard"
+msgstr ""
+
+msgid "Translate view"
+msgstr "Nézet fordítása."
diff --git a/sao/locale/id.po b/sao/locale/id.po
new file mode 100644
index 0000000000..7f117538a5
--- /dev/null
+++ b/sao/locale/id.po
@@ -0,0 +1,652 @@
+# Generated by grunt-xgettext on Sat Jun 01 2019 23:48:54 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr ""
+
+msgid "Manage..."
+msgstr ""
+
+msgid "Logout"
+msgstr ""
+
+msgid "Action"
+msgstr "Tindakan"
+
+msgid "New"
+msgstr "Baru"
+
+msgid "Save"
+msgstr "Simpan"
+
+msgid "Switch"
+msgstr ""
+
+msgid "Reload/Undo"
+msgstr ""
+
+msgid "Duplicate"
+msgstr ""
+
+msgid "Delete"
+msgstr "Hapus"
+
+msgid "Previous"
+msgstr "Sebelumnya"
+
+msgid "Next"
+msgstr "Berikutnya"
+
+msgid "Search"
+msgstr ""
+
+msgid "Close Tab"
+msgstr ""
+
+msgid "Attachment"
+msgstr "Lampiran"
+
+msgid "Note"
+msgstr "Catatan"
+
+msgid "Relate"
+msgstr ""
+
+msgid "Print"
+msgstr "Cetak"
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr ""
+
+msgid "Next tab"
+msgstr ""
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr "Tutup"
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr ""
+
+msgid "Too many requests. Try again later."
+msgstr "Terlalu banyak permintaan. Coba lagi nanti."
+
+msgid "Login"
+msgstr ""
+
+msgid "User name"
+msgstr ""
+
+msgid "Database"
+msgstr ""
+
+msgid "Your selection:"
+msgstr "Pilihan anda:"
+
+msgid "Cancel"
+msgstr "Batal"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Y"
+msgstr "Y"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "w"
+
+msgid "d"
+msgstr "d"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "Oleh: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "y"
+
+msgid "Yes"
+msgstr "Ya"
+
+msgid "True"
+msgstr "Benar"
+
+msgid "t"
+msgstr "t"
+
+msgid "False"
+msgstr "Salah"
+
+msgid "Message: "
+msgstr "Pesan: "
+
+msgid "Warning: "
+msgstr ""
+
+msgid "Always ignore this warning."
+msgstr "Selalu abaikan peringatan ini."
+
+msgid "Do you want to proceed?"
+msgstr "Apakah Anda ingin melanjutkan?"
+
+msgid "No"
+msgstr "Tidak"
+
+msgid "Confirmation: "
+msgstr ""
+
+msgid "Concurrency Exception"
+msgstr ""
+
+msgid "Write Concurrency Warning: "
+msgstr ""
+
+msgid "This record has been modified while you were editing it."
+msgstr "Rekaman ini telah diubah selagi anda menyuntingnya."
+
+msgid "Choose:"
+msgstr ""
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr ""
+
+msgid "\"Compare\" to see the modified version;"
+msgstr ""
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr ""
+
+msgid "Compare"
+msgstr "Bandingkan"
+
+msgid "Compare: %1"
+msgstr "Bandingkan: %1"
+
+msgid "Write Anyway"
+msgstr "Tetap Menulis"
+
+msgid "Application Error"
+msgstr ""
+
+msgid "Report Bug"
+msgstr "Melaporkan Kesalahan"
+
+msgid "Processing"
+msgstr ""
+
+msgid "Search..."
+msgstr ""
+
+msgid "Create..."
+msgstr ""
+
+msgid "Download"
+msgstr "Unduh"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Switch view"
+msgstr ""
+
+msgid "Previous Record"
+msgstr ""
+
+msgid "Next Record"
+msgstr ""
+
+msgid "Create a new record"
+msgstr ""
+
+msgid "Save this record"
+msgstr ""
+
+msgid "Reload"
+msgstr ""
+
+msgid "View Logs..."
+msgstr ""
+
+msgid "Show revisions..."
+msgstr ""
+
+msgid "Add an attachment to the record"
+msgstr ""
+
+msgid "Add a note to the record"
+msgstr ""
+
+msgid "E-Mail..."
+msgstr "E-Mail..."
+
+msgid "Send an e-mail using the record"
+msgstr ""
+
+msgid "Export"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"Tindakan berikut ini perlu untuk menutup semua tab.\n"
+"Apakah Anda ingin melanjutkan?"
+
+msgid "Launch action"
+msgstr ""
+
+msgid "Open related records"
+msgstr ""
+
+msgid "Print report"
+msgstr "Cetak laporan"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+
+msgid "Record saved."
+msgstr ""
+
+msgid "Working now on the duplicated record(s)."
+msgstr ""
+
+msgid "Are you sure to remove this record?"
+msgstr ""
+
+msgid "Are you sure to remove those records?"
+msgstr ""
+
+msgid "Records removed."
+msgstr ""
+
+msgid "Records not removed."
+msgstr ""
+
+msgid "You have to select one record."
+msgstr ""
+
+msgid "ID:"
+msgstr "ID:"
+
+msgid "Created by:"
+msgstr "Dibuat oleh:"
+
+msgid "Created at:"
+msgstr "Dibuat pada:"
+
+msgid "Edited by:"
+msgstr "Disunting oleh:"
+
+msgid "Edited at:"
+msgstr "Disunting pada:"
+
+msgid "Model: "
+msgstr ""
+
+msgid "Add..."
+msgstr ""
+
+#, fuzzy
+msgid "Preview"
+msgstr "Sebelumnya"
+
+msgid "Template"
+msgstr "Templat"
+
+msgid "Attachment (%1)"
+msgstr "Lampiran (%1)"
+
+msgid "Note (%1/%2)"
+msgstr "Catatan (%1/%2)"
+
+msgid " of "
+msgstr ""
+
+msgid "Filters"
+msgstr ""
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr ""
+
+msgid "Remove this bookmark"
+msgstr ""
+
+msgid "Bookmark this filter"
+msgstr ""
+
+msgid "Bookmark Name:"
+msgstr ""
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr ""
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr "Kepada"
+
+msgid "Open the calendar"
+msgstr "Buka kalender"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Created by"
+msgstr "Dibuat oleh"
+
+msgid "Created at"
+msgstr "Dibuat pada"
+
+msgid "Modified by"
+msgstr ""
+
+msgid "Modified at"
+msgstr ""
+
+msgid "\"%1\" is required."
+msgstr ""
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr ""
+
+msgid "The values of \"%1\" are not valid."
+msgstr ""
+
+msgid "Pre-validation"
+msgstr ""
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr ""
+
+msgid "Edit"
+msgstr "Sunting"
+
+msgid "Fuzzy"
+msgstr ""
+
+msgid "You need to save the record before adding translations."
+msgstr ""
+
+msgid "No other language available."
+msgstr "Tidak ada bahasa lain yang tersedia."
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr "Tambahkan"
+
+msgid "Remove"
+msgstr "Hapus"
+
+msgid "Open"
+msgstr "Buka"
+
+msgid "Undelete"
+msgstr ""
+
+msgid "Save As"
+msgstr "Simpan Sebagai"
+
+msgid "Save As..."
+msgstr "Simpan Sebagai..."
+
+msgid "Select"
+msgstr "Pilih"
+
+msgid "Select..."
+msgstr "Pilih..."
+
+msgid "Clear"
+msgstr "Bersihkan"
+
+msgid "Choose a language"
+msgstr "Pilih bahasa"
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr ""
+
+msgid "Today"
+msgstr "Hari ini"
+
+msgid "Month"
+msgstr "Bulan"
+
+msgid "Week"
+msgstr "Pekan"
+
+msgid "Day"
+msgstr "Hari"
+
+msgid ",..."
+msgstr ",..."
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Pilih tindakan Anda"
+
+msgid "No action defined."
+msgstr "Tidak ada tindakan yang ditentukan."
+
+msgid "Attachments (%1)"
+msgstr ""
+
+msgid "Notes (%1)"
+msgstr ""
+
+msgid "Search %1"
+msgstr ""
+
+msgid "Revision"
+msgstr "Revisi"
+
+msgid "All Fields"
+msgstr ""
+
+msgid "Fields Selected"
+msgstr ""
+
+msgid "CSV Parameters"
+msgstr ""
+
+msgid "Delimiter:"
+msgstr ""
+
+msgid "Quote Char:"
+msgstr ""
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr ""
+
+msgid "File to Import"
+msgstr ""
+
+msgid "Encoding:"
+msgstr ""
+
+msgid "Lines to Skip:"
+msgstr ""
+
+msgid "You must select an import file first."
+msgstr ""
+
+msgid "An error occured in loading the file."
+msgstr ""
+
+msgid "Error processing the file at field %1."
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Error occured in loading the file"
+msgstr ""
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr ""
+
+msgid "URL Export"
+msgstr ""
+
+msgid "Delete Export"
+msgstr ""
+
+msgid "Predefined Exports"
+msgstr ""
+
+msgid "Selected Records"
+msgstr ""
+
+msgid "Listed Records"
+msgstr ""
+
+msgid "Export:"
+msgstr ""
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr ""
+
+msgid "%1 (string)"
+msgstr ""
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr ""
+
+msgid "Override %1 definition?"
+msgstr ""
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr "Kepada:"
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr "Subject:"
+
+#, fuzzy
+msgid "Reports"
+msgstr "Melaporkan Kesalahan"
+
+#, fuzzy
+msgid "Attachments"
+msgstr "Lampiran"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr "Kirim"
+
+#, fuzzy
+msgid "Remove File"
+msgstr "Hapus"
+
+msgid "Wizard"
+msgstr "Wisaya"
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/it.po b/sao/locale/it.po
new file mode 100644
index 0000000000..a0aabf92a9
--- /dev/null
+++ b/sao/locale/it.po
@@ -0,0 +1,684 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid "Are your sure to leave?"
+msgstr "Sei sicuro di voler abbandonare?"
+
+msgid "Favorites"
+msgstr "Preferiti"
+
+msgid "Manage..."
+msgstr "Gestisci..."
+
+msgid "Logout"
+msgstr "Esci"
+
+msgid "Action"
+msgstr "Azione"
+
+msgid "New"
+msgstr "Nuovo"
+
+msgid "Save"
+msgstr "Salva"
+
+msgid "Switch"
+msgstr "Scambia"
+
+msgid "Reload/Undo"
+msgstr "Ricarica/Ripristina"
+
+msgid "Duplicate"
+msgstr "Duplica"
+
+msgid "Delete"
+msgstr "Elimina"
+
+msgid "Previous"
+msgstr "Precedente"
+
+msgid "Next"
+msgstr "Successivo"
+
+msgid "Search"
+msgstr "Cerca"
+
+msgid "Close Tab"
+msgstr "Chiudi la scheda"
+
+msgid "Attachment"
+msgstr "Allegato"
+
+msgid "Note"
+msgstr "nota"
+
+msgid "Relate"
+msgstr "collega"
+
+msgid "Print"
+msgstr "Stampa"
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr "Scheda precedente"
+
+msgid "Next tab"
+msgstr "Scheda successiva"
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr "Chiudi"
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr "server non raggiungibile"
+
+msgid "Too many requests. Try again later."
+msgstr "Troppe richieste. Riprovare più tardi."
+
+msgid "Login"
+msgstr "Login"
+
+msgid "User name"
+msgstr ""
+
+msgid "Database"
+msgstr "Database"
+
+msgid "Your selection:"
+msgstr "la tua selezione"
+
+msgid "Cancel"
+msgstr "Annulla"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Y"
+msgstr "Y"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "w"
+
+msgid "d"
+msgstr "d"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "per: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "y"
+
+msgid "Yes"
+msgstr "Sì"
+
+msgid "True"
+msgstr "Vero"
+
+msgid "t"
+msgstr "t"
+
+msgid "False"
+msgstr "Falso"
+
+msgid "Message: "
+msgstr "messaggio: "
+
+msgid "Warning: "
+msgstr "Attenzione: "
+
+msgid "Always ignore this warning."
+msgstr "ignorare sempre questo avviso"
+
+msgid "Do you want to proceed?"
+msgstr "Continuare?"
+
+msgid "No"
+msgstr "no"
+
+msgid "Confirmation: "
+msgstr "conferma: "
+
+msgid "Concurrency Exception"
+msgstr "eccezione di concorrenza"
+
+msgid "Write Concurrency Warning: "
+msgstr "scrivi avviso di concorrenza: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "Questo record è stato modificato mentre lo stavi compilando."
+
+msgid "Choose:"
+msgstr "Scegli:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"Annulla\" per annullare il salvataggio;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"Confronta\" per vedere la versione modificata;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"Scrivi comunque\" per salvare la versione corrente"
+
+msgid "Compare"
+msgstr "Confronta"
+
+msgid "Compare: %1"
+msgstr "Confronta: %1"
+
+msgid "Write Anyway"
+msgstr "Scrivi comunque"
+
+msgid "Application Error"
+msgstr "Errore dell'applicazione"
+
+msgid "Report Bug"
+msgstr "Segnala l'errore"
+
+msgid "Processing"
+msgstr ""
+
+msgid "Search..."
+msgstr "Cerca..."
+
+msgid "Create..."
+msgstr "Crea..."
+
+msgid "Download"
+msgstr "Scarica"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Carattere"
+
+msgid "Size"
+msgstr "Dimensione"
+
+msgid "Switch view"
+msgstr "cambia visualizzazione"
+
+msgid "Previous Record"
+msgstr "Record precedente"
+
+msgid "Next Record"
+msgstr "Record successivo"
+
+msgid "Create a new record"
+msgstr "Crea un nuovo record"
+
+msgid "Save this record"
+msgstr "salvare il record"
+
+msgid "Reload"
+msgstr "Ricarica"
+
+msgid "View Logs..."
+msgstr "vedi logs"
+
+msgid "Show revisions..."
+msgstr "mostra revisioni"
+
+msgid "Add an attachment to the record"
+msgstr "aggiungere un allegato al record"
+
+msgid "Add a note to the record"
+msgstr "Aggiungi un appunto sul record"
+
+msgid "E-Mail..."
+msgstr ""
+
+#, fuzzy
+msgid "Send an e-mail using the record"
+msgstr "Aggiungi un appunto sul record"
+
+msgid "Export"
+msgstr "Esporta"
+
+msgid "Import"
+msgstr "Importa"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"la seguente azione richiede la chiusura di tutte le finestre. Intendi "
+"continuare?"
+
+msgid "Launch action"
+msgstr "lancia applicazione"
+
+msgid "Open related records"
+msgstr "apri record collegati"
+
+msgid "Print report"
+msgstr "Stampa rapporto"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Questo record è stato modificato\n"
+"intendi salvarlo?"
+
+msgid "Record saved."
+msgstr "Record salvato."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Stai ora lavorando nel record duplicato."
+
+msgid "Are you sure to remove this record?"
+msgstr "sei sicuro di rimuovere questo record?"
+
+msgid "Are you sure to remove those records?"
+msgstr "sei sicuro di rimuovere questi record?"
+
+msgid "Records removed."
+msgstr "Record rimossi."
+
+msgid "Records not removed."
+msgstr "Record non rimossi."
+
+msgid "You have to select one record."
+msgstr "Devi selezionare un record."
+
+msgid "ID:"
+msgstr "ID:"
+
+msgid "Created by:"
+msgstr "Creato da:"
+
+msgid "Created at:"
+msgstr "Creato il:"
+
+msgid "Edited by:"
+msgstr "Modificato da:"
+
+msgid "Edited at:"
+msgstr "Modifica il:"
+
+msgid "Model: "
+msgstr "Modello: "
+
+msgid "Add..."
+msgstr "Inserisci..."
+
+#, fuzzy
+msgid "Preview"
+msgstr "Precedente"
+
+#, fuzzy
+msgid "Template"
+msgstr "collega"
+
+#, fuzzy
+msgid "Attachment (%1)"
+msgstr "allegati (%1)"
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr ""
+
+msgid "Filters"
+msgstr "Filtri"
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr "Segnalibri"
+
+msgid "Remove this bookmark"
+msgstr "rimuovere questo segnalibro"
+
+msgid "Bookmark this filter"
+msgstr "contrassegnare questo filtro"
+
+msgid "Bookmark Name:"
+msgstr "Nome segnalibro"
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr "Trova"
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr ""
+
+msgid "ID"
+msgstr "ID"
+
+#, fuzzy
+msgid "Created by"
+msgstr "Crea..."
+
+#, fuzzy
+msgid "Created at"
+msgstr "creato il "
+
+msgid "Modified by"
+msgstr ""
+
+#, fuzzy
+msgid "Modified at"
+msgstr "Data di modifica "
+
+#, fuzzy
+msgid "\"%1\" is required."
+msgstr "\"%1\" è obbligatorio"
+
+#, fuzzy
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" non è valido rispetto al dominio"
+
+#, fuzzy
+msgid "The values of \"%1\" are not valid."
+msgstr "i valori di \"%1\" non sono validi"
+
+msgid "Pre-validation"
+msgstr "pre-validazione"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Traduci"
+
+msgid "Edit"
+msgstr "Modifica"
+
+msgid "Fuzzy"
+msgstr "fuzzy"
+
+msgid "You need to save the record before adding translations."
+msgstr "devi salvare il record prima di inserire la traduzione"
+
+msgid "No other language available."
+msgstr "non sono disponibili altre lingue"
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr "Aggiungi"
+
+msgid "Remove"
+msgstr "Rimuovi"
+
+msgid "Open"
+msgstr "Apri"
+
+msgid "Undelete"
+msgstr "Annullare l'eliminazione"
+
+msgid "Save As"
+msgstr ""
+
+msgid "Save As..."
+msgstr ""
+
+msgid "Select"
+msgstr "Seleziona"
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr "Cancella"
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr "%1%"
+
+#, fuzzy
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "più"
+
+msgid "Today"
+msgstr ""
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr ""
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Seleziona l'azione"
+
+msgid "No action defined."
+msgstr "Nessuna azione definita."
+
+msgid "Attachments (%1)"
+msgstr "allegati (%1)"
+
+msgid "Notes (%1)"
+msgstr "note (%1)"
+
+msgid "Search %1"
+msgstr "Cerca %1"
+
+msgid "Revision"
+msgstr "Revisione"
+
+msgid "All Fields"
+msgstr "Ogni Campo"
+
+msgid "Fields Selected"
+msgstr "campi selezionati"
+
+msgid "CSV Parameters"
+msgstr "parametri CSV"
+
+msgid "Delimiter:"
+msgstr "Delimitatore:"
+
+msgid "Quote Char:"
+msgstr "Carattere tra virgolette:"
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr "Autorilevamento"
+
+msgid "File to Import"
+msgstr "file da importare"
+
+msgid "Encoding:"
+msgstr "Codifica:"
+
+msgid "Lines to Skip:"
+msgstr "righe da saltare"
+
+#, fuzzy
+msgid "You must select an import file first."
+msgstr "va prima selezionato un file da importare"
+
+#, fuzzy
+msgid "An error occured in loading the file."
+msgstr "si è verificato un errore nel caricamento del file"
+
+msgid "Error processing the file at field %1."
+msgstr "errore nell'elaborazione del file nel campo %1"
+
+msgid "Error"
+msgstr "Errore"
+
+msgid "Error occured in loading the file"
+msgstr "si è verificato un errore nel caricamento del file"
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr "salvare esportazione"
+
+#, fuzzy
+msgid "URL Export"
+msgstr "Esporta"
+
+msgid "Delete Export"
+msgstr "eliminare esportazione"
+
+msgid "Predefined Exports"
+msgstr "esportazioni predefinite"
+
+msgid "Selected Records"
+msgstr "Record selezionati"
+
+msgid "Listed Records"
+msgstr "Record elencati"
+
+#, fuzzy
+msgid "Export:"
+msgstr "Esporta"
+
+msgid "Ignore search limit"
+msgstr "Ignora limite di ricerca"
+
+msgid "Use locale format"
+msgstr "Usa il formato locale"
+
+msgid "Add Field Names"
+msgstr "inserire nomi campo"
+
+msgid "%1 (string)"
+msgstr "%1 (stringa)"
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr "qual è il nome di questa esportazione?"
+
+msgid "Override %1 definition?"
+msgstr "sovrascrivere definizione %1?"
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+#, fuzzy
+msgid "Reports"
+msgstr "Segnala l'errore"
+
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2020-10-16 15:42+0000\n"
+"PO-Revision-Date: 2020-10-16 15:42+0000\n"
+"Last-Translator: Luca Cristaldi \n"
+"Language-Team: LANGUAGE \n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 4.2.2\n"
+
+#, fuzzy
+msgid "Attachments"
+msgstr "Allegato"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+#, fuzzy
+msgid "Remove File"
+msgstr "Rimuovi"
+
+msgid "Wizard"
+msgstr "wizard"
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/lo.po b/sao/locale/lo.po
new file mode 100644
index 0000000000..7370aca813
--- /dev/null
+++ b/sao/locale/lo.po
@@ -0,0 +1,689 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr "ທີ່ມັກ"
+
+msgid "Manage..."
+msgstr ""
+
+# Generated by grunt-xgettext on Thu Mar 31 2016 17:50:31 GMT+0200 (CEST)
+msgid "Logout"
+msgstr "ອອກລະບົບ"
+
+msgid "Action"
+msgstr "ດຳເນີນການ"
+
+msgid "New"
+msgstr "ໃໝ່"
+
+msgid "Save"
+msgstr "ບັນທຶກ"
+
+msgid "Switch"
+msgstr "ສະຫຼັບ"
+
+msgid "Reload/Undo"
+msgstr "ໂຫຼດຄືນໃໝ່/ຍົກເລີກ"
+
+msgid "Duplicate"
+msgstr "ຊໍ້າກັນ"
+
+msgid "Delete"
+msgstr "ລຶບ"
+
+msgid "Previous"
+msgstr "ກ່ອນໜ້າ"
+
+msgid "Next"
+msgstr "ຕໍ່ໄປ"
+
+msgid "Search"
+msgstr "ຊອກຫາ"
+
+msgid "Close Tab"
+msgstr "ອັດແຖບງານ"
+
+msgid "Attachment"
+msgstr "ຄັດຕິດ"
+
+msgid "Note"
+msgstr "ບັນທຶກຂໍ້ຄວາມ"
+
+msgid "Relate"
+msgstr "ກ່ຽວພັນກັບ"
+
+msgid "Print"
+msgstr "ພິມອອກ"
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr ""
+
+msgid "Next tab"
+msgstr ""
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr "ອັດ"
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr "ບໍ່ສາມາດເຂົ້າເຖິງແມ່ຂ່າຍໄດ້"
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr "ເຂົ້າສູ່ລະບົບ"
+
+msgid "User name"
+msgstr "ຊື່ຜູ້ໃຊ້"
+
+msgid "Database"
+msgstr "ຖານຂໍ້ມູນ"
+
+msgid "Your selection:"
+msgstr "ການເລືອກຂອງທ່ານ:"
+
+msgid "Cancel"
+msgstr "ຍົກເລີກ"
+
+msgid "OK"
+msgstr "ຕົກລົງ"
+
+msgid "Y"
+msgstr "ປ"
+
+msgid "M"
+msgstr "ດ"
+
+msgid "w"
+msgstr "ອ"
+
+msgid "d"
+msgstr "ວ"
+
+msgid "h"
+msgstr "ມ"
+
+msgid "m"
+msgstr "ນ"
+
+msgid "s"
+msgstr "ວ"
+
+msgid "By: "
+msgstr "ໂດຍ: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "ມ"
+
+msgid "Yes"
+msgstr "ແມ່ນ"
+
+msgid "True"
+msgstr "ຈິງ"
+
+msgid "t"
+msgstr "ຈ"
+
+msgid "False"
+msgstr "ເທັດ"
+
+msgid "Message: "
+msgstr "ຂໍ້ຄວາມ: "
+
+msgid "Warning: "
+msgstr "ຄຳເຕືອນ: "
+
+msgid "Always ignore this warning."
+msgstr "ບໍ່ສົນກັບຄຳເຕືອນນີ້."
+
+msgid "Do you want to proceed?"
+msgstr "ທ່ານຕ້ອງການດຳເນີນບໍ່?"
+
+msgid "No"
+msgstr "ບໍ່"
+
+msgid "Confirmation: "
+msgstr "ຄຳຢັ້ງຢືນ: "
+
+msgid "Concurrency Exception"
+msgstr "ຍົກເວັ້ນສະກຸນເງິນ"
+
+msgid "Write Concurrency Warning: "
+msgstr "ຂຽນຄຳເຕືອນສະກຸນເງິນ: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "ແຖວຂໍ້ມູນນີ້ຖືກດັດແປງແລ້ວໃນຂະນະທີ່ທ່ານແກ້ໄຂມັນ."
+
+msgid "Choose:"
+msgstr "ເລືອກເອົາ:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"ຍົກເລີກ\" ເພື່ອຍົກເລີກການບັນທຶກ;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"ສົມທຽບ\" ເພື່ອເບິ່ງທຽບກັບສະບັບດັດແປງແລ້ວ;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"ຂຽນລົງເລີຍ\" ເພື່ອບັນທຶກສະບັບປັດຈຸບັນນີ້."
+
+msgid "Compare"
+msgstr "ສົມທຽບ"
+
+#, fuzzy
+msgid "Compare: %1"
+msgstr "ສົມທຽບ"
+
+msgid "Write Anyway"
+msgstr "ຂຽນລົງເລີຍ"
+
+msgid "Application Error"
+msgstr "ໂປຣແກຣມຜິດພາດ"
+
+msgid "Report Bug"
+msgstr "ລາຍງານຂໍ້ຜິດພາດ"
+
+#, fuzzy
+msgid "Processing"
+msgstr "ກຳລັງປະມວນຜົນ..."
+
+msgid "Search..."
+msgstr "ຄົ້ນຫາ..."
+
+msgid "Create..."
+msgstr "ສ້າງ..."
+
+msgid "Download"
+msgstr "ດາວໂຫຼດ"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "ໂຕໜັງສື"
+
+msgid "Size"
+msgstr "ຂະໜາດ"
+
+msgid "Switch view"
+msgstr "ສະຫຼັບໜ້າເບິ່ງ"
+
+msgid "Previous Record"
+msgstr "ແຖວຂໍ້ມູນກ່ອນ"
+
+msgid "Next Record"
+msgstr "ແຖວຂໍ້ມູນຕໍ່ໄປ"
+
+msgid "Create a new record"
+msgstr "ສ້າງແຖວຂໍ້ມູນໃໝ່"
+
+msgid "Save this record"
+msgstr "ບັນທຶກແຖວຂໍ້ມູນນີ້"
+
+msgid "Reload"
+msgstr "ໂຫຼດຄືນໃໝ່"
+
+msgid "View Logs..."
+msgstr "ເບິ່ງບັນທຶກ..."
+
+msgid "Show revisions..."
+msgstr "ສະແດງການແກ້ໄຂ"
+
+msgid "Add an attachment to the record"
+msgstr "ເອົາຂໍ້ມູນຄັດຕິດເຂົ້າໃນແຖວຂໍ້ມູນນີ້"
+
+msgid "Add a note to the record"
+msgstr "ບັນທຶກຂໍ້ຄວາມໃສ່ແຖວຂໍ້ມູນນີ້"
+
+msgid "E-Mail..."
+msgstr ""
+
+#, fuzzy
+msgid "Send an e-mail using the record"
+msgstr "ບັນທຶກຂໍ້ຄວາມໃສ່ແຖວຂໍ້ມູນນີ້"
+
+msgid "Export"
+msgstr "ສ່ົງອອກ"
+
+msgid "Import"
+msgstr "ນຳເຂົ້າ"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"ການດຳເນີນການຕໍ່ໄປນີ້ ຮຽກຮ້ອງໃຫ້ຕ້ອງອັດແຖບງານທັງໝົດລົງ\n"
+"ເຈົ້າຕ້ອງການດຳເນີນຕໍ່ບໍ່?"
+
+msgid "Launch action"
+msgstr "ປະຕິບັດການ"
+
+msgid "Open related records"
+msgstr "ໄຂແຖວຂໍ້ມູນທີ່ກ່ຽວພັນຂຶ້ນມາ"
+
+msgid "Print report"
+msgstr "ພິມລາຍງານອອກ"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"ແຖວຂໍ້ມູນນີ້ຖືກປ່ຽນແປງແລ້ວ\n"
+"ທ່ານຕ້ອງການບັນທຶກໄວ້ບໍ່?"
+
+msgid "Record saved."
+msgstr "ແຖວຂໍ້ມູນຖືກບັນທຶກໄວ້ແລ້ວ"
+
+msgid "Working now on the duplicated record(s)."
+msgstr "ປັດຈຸບັນເຮັດວຽກກັບແຖວຂໍ້ມູນທີ່ສ້າງຊໍ້າກັນໄວ້"
+
+msgid "Are you sure to remove this record?"
+msgstr "ທ່ານແນ່ໃຈບໍ່ທີ່ຈະລຶບແຖວຂໍ້ມູນນີ້?"
+
+msgid "Are you sure to remove those records?"
+msgstr "ທ່ານແນ່ໃຈບໍ່ທີ່ຈະລຶບແຖວຂໍ້ມູນເຫຼົ່ານີ້?"
+
+msgid "Records removed."
+msgstr "ແຖວຂໍ້ມູນເຫຼົ່ານີ້ຖືກລຶບອອກແລ້ວ"
+
+msgid "Records not removed."
+msgstr "ແຖວຂໍ້ມູນເຫຼົ່ານີ້ບໍ່ໄດ້ຖືກລຶບອອກ"
+
+msgid "You have to select one record."
+msgstr "ທ່ານຕ້ອງເລືອກເອົາໜຶ່ງແຖວຂໍ້ມູນ"
+
+msgid "ID:"
+msgstr "ເລກກຳກັບ:"
+
+#, fuzzy
+msgid "Created by:"
+msgstr "ສ້າງ..."
+
+#, fuzzy
+msgid "Created at:"
+msgstr "ວັນທີສ້າງ"
+
+#, fuzzy
+msgid "Edited by:"
+msgstr "ສ້າງ..."
+
+#, fuzzy
+msgid "Edited at:"
+msgstr "ວັນທີແກ້ໄຂ"
+
+msgid "Model: "
+msgstr "ແມ່ແບບ: "
+
+msgid "Add..."
+msgstr ""
+
+#, fuzzy
+msgid "Preview"
+msgstr "ກ່ອນໜ້າ"
+
+#, fuzzy
+msgid "Template"
+msgstr "ກ່ຽວພັນກັບ"
+
+#, fuzzy
+msgid "Attachment (%1)"
+msgstr "ຄັດຕິດ(%1)"
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr " ຂອງ "
+
+msgid "Filters"
+msgstr "ກັ່ນຕອງ"
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr "ໝາຍໜ້າ"
+
+msgid "Remove this bookmark"
+msgstr "ເອົາໝາຍໜ້າອອກ"
+
+msgid "Bookmark this filter"
+msgstr "ໝາຍໜ້າເອົາການກັ່ນຕອງນີ້"
+
+msgid "Bookmark Name:"
+msgstr "ຊື່ໝາຍໜ້າ:"
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr "ຄົ້ນຫາ"
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr ""
+
+msgid "ID"
+msgstr "ເລກລຳດັບ"
+
+#, fuzzy
+msgid "Created by"
+msgstr "ສ້າງ..."
+
+#, fuzzy
+msgid "Created at"
+msgstr "ວັນທີສ້າງ"
+
+msgid "Modified by"
+msgstr ""
+
+#, fuzzy
+msgid "Modified at"
+msgstr "ວັນທີແກ້ໄຂ"
+
+#, fuzzy
+msgid "\"%1\" is required."
+msgstr "ຕ້ອງໃຫ້ມີ \"%1\""
+
+#, fuzzy
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" ບໍ່ມີຄ່າທີ່ຖຶກຕ້ອງກັບ ໂດເມນຂອງມັນ"
+
+#, fuzzy
+msgid "The values of \"%1\" are not valid."
+msgstr "ຄ່າ ຂອງ \"%1\" ນີ້ ບໍ່ຖືກຕ້ອງ"
+
+msgid "Pre-validation"
+msgstr "ກ່ອນ-ການກວດສອບ"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "ແປ"
+
+msgid "Edit"
+msgstr "ແກ້ໄຂ"
+
+msgid "Fuzzy"
+msgstr "ບໍ່ຈະແຈ້ງ"
+
+msgid "You need to save the record before adding translations."
+msgstr "ທ່ານຕ້ອງໄດ້ບັນທຶກແຖວຂໍ້ມູນໄວ້ກ່ອນຈຶ່ງຈະເພີ່ມການແປເຂົ້າໄປໄດ້"
+
+msgid "No other language available."
+msgstr "ບໍ່ມີພາສາອື່ນໃຫ້ໃຊ້ໄດ້."
+
+msgid "Show"
+msgstr "ສະແດງ"
+
+msgid "Hide"
+msgstr "ເຊື່ອງ"
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr "ເອົາເຂົ້າ"
+
+msgid "Remove"
+msgstr "ເອົາອອກ"
+
+msgid "Open"
+msgstr "ໄຂ"
+
+msgid "Undelete"
+msgstr "ເອົາກັບຄືນ"
+
+msgid "Save As"
+msgstr ""
+
+msgid "Save As..."
+msgstr ""
+
+msgid "Select"
+msgstr "ເລືອກ"
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr "ລຶບອອກ"
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "ເພີ່ມຕື່ມ"
+
+msgid "Today"
+msgstr ""
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr ""
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "ເລືອກການດຳເນີນການ"
+
+msgid "No action defined."
+msgstr "ບໍ່ມີການດຳເນີນການໃດຖືກກຳນົດໄວ້!"
+
+msgid "Attachments (%1)"
+msgstr "ຄັດຕິດ(%1)"
+
+msgid "Notes (%1)"
+msgstr "ບັນທຶກຂໍ້ຄວາມ(%1)"
+
+msgid "Search %1"
+msgstr "ຊອກຫາ %1"
+
+msgid "Revision"
+msgstr "ກວດກາຄືນ"
+
+msgid "All Fields"
+msgstr "ຊ່ອງຂໍ້ມູນທັງໝົດ"
+
+msgid "Fields Selected"
+msgstr "ຊ່ອງຂໍ້ມູນທີ່ເລືອກເອົາ"
+
+msgid "CSV Parameters"
+msgstr "ປາຣາແມັດເຕີຣ໌ CSV"
+
+msgid "Delimiter:"
+msgstr "ຂັ້ນ:"
+
+msgid "Quote Char:"
+msgstr "Quote Char:"
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr "ກວດພົບອັດຕະໂນມັດ"
+
+msgid "File to Import"
+msgstr "ຟາຍລ໌ທີ່ຈະນຳເຂົ້າ"
+
+msgid "Encoding:"
+msgstr "ການເຂົ້າລະຫັດ:"
+
+msgid "Lines to Skip:"
+msgstr "ແຖວທີ່ຈະຂວ້າມ:"
+
+#, fuzzy
+msgid "You must select an import file first."
+msgstr "ທ່ານຕ້ອງໄດ້ເລືອກຟາຍລ໌ທີ່ຈະນຳເຂົ້ານັ້ນກ່ອນ"
+
+#, fuzzy
+msgid "An error occured in loading the file."
+msgstr "ມີຂໍ້ຜິດພາດເກີດຂຶ້ນໃນການດຶງເອົາຟາຍລ໌"
+
+msgid "Error processing the file at field %1."
+msgstr "ມີຂໍ້ຜິດພາດໃນການປະມວນຜົນຟາຍລ໌ ໃນຊ່ອງຂໍ້ມູນ %1."
+
+msgid "Error"
+msgstr "ຜິດພາດ"
+
+msgid "Error occured in loading the file"
+msgstr "ມີຂໍ້ຜິດພາດເກີດຂຶ້ນໃນການດຶງເອົາຟາຍລ໌"
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr "ບັນທຶກຟາຍລ໌ທີ່ສົ່ງອອກ"
+
+#, fuzzy
+msgid "URL Export"
+msgstr "ສ່ົງອອກ"
+
+msgid "Delete Export"
+msgstr "ລຶບຟາຍລ໌ທີ່ສົ່ງອອກ"
+
+msgid "Predefined Exports"
+msgstr "ການສົ່ງອອກທີ່ຈັດຕຽມໄວ້ກ່ອນ"
+
+#, fuzzy
+msgid "Selected Records"
+msgstr "ແຖວຂໍ້ມູນຕໍ່ໄປ"
+
+#, fuzzy
+msgid "Listed Records"
+msgstr "ແຖວຂໍ້ມູນຕໍ່ໄປ"
+
+#, fuzzy
+msgid "Export:"
+msgstr "ສ່ົງອອກ"
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr "ເພີ່ມຊື່ຊ່ອງຂໍ້ມູນ"
+
+msgid "%1 (string)"
+msgstr "%1 (string)"
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr "ຊື່ຂອງການສົ່ງອອກນີ້ແມ່ນຫຍັງ?"
+
+msgid "Override %1 definition?"
+msgstr "ຂຽນທັບຄຳອະທິບາຍ %1 ນີ້ບໍ?"
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+#, fuzzy
+msgid "Reports"
+msgstr "ລາຍງານຂໍ້ຜິດພາດ"
+
+msgid ""
+msgstr ""
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-05-01 15:33+0000\n"
+"PO-Revision-Date: 2019-10-31 09:05+0000\n"
+"Last-Translator: Cedric Krier \n"
+"Language: lo\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Weblate 3.8\n"
+
+#, fuzzy
+msgid "Attachments"
+msgstr "ຄັດຕິດ"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+#, fuzzy
+msgid "Remove File"
+msgstr "ເອົາອອກ"
+
+msgid "Wizard"
+msgstr "ນໍາພາສ້າງ"
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/lt.po b/sao/locale/lt.po
new file mode 100644
index 0000000000..a401085a61
--- /dev/null
+++ b/sao/locale/lt.po
@@ -0,0 +1,661 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr "Mėgstami"
+
+msgid "Manage..."
+msgstr "Valdyti..."
+
+msgid "Logout"
+msgstr ""
+
+msgid "Action"
+msgstr "Veiksmai"
+
+msgid "New"
+msgstr "Naujas"
+
+msgid "Save"
+msgstr "Išsaugoti"
+
+msgid "Switch"
+msgstr "Perjungti"
+
+msgid "Reload/Undo"
+msgstr "Perkrauti/Atšaukti"
+
+msgid "Duplicate"
+msgstr ""
+
+msgid "Delete"
+msgstr "Naikinti"
+
+msgid "Previous"
+msgstr "Buvęs"
+
+msgid "Next"
+msgstr "Kitas"
+
+msgid "Search"
+msgstr "Ieškoti"
+
+msgid "Close Tab"
+msgstr "Uždaryti kortelę"
+
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr "Pastaba"
+
+msgid "Relate"
+msgstr "Susijęs"
+
+msgid "Print"
+msgstr "Spausdinimas"
+
+msgid "E-Mail"
+msgstr ""
+
+#, fuzzy
+msgid "Previous tab"
+msgstr "_Buvusi kortelė"
+
+#, fuzzy
+msgid "Next tab"
+msgstr "Kita kortelė"
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr "Užverti"
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr ""
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr "Prisijungti"
+
+msgid "User name"
+msgstr "Naudotojo vardas"
+
+msgid "Database"
+msgstr ""
+
+msgid "Your selection:"
+msgstr "Jūsų pasirinkimas:"
+
+msgid "Cancel"
+msgstr "Atsisakyti"
+
+msgid "OK"
+msgstr "Gerai"
+
+msgid "Y"
+msgstr "m."
+
+msgid "M"
+msgstr "mėn."
+
+msgid "w"
+msgstr "sav."
+
+msgid "d"
+msgstr "d."
+
+msgid "h"
+msgstr "val."
+
+msgid "m"
+msgstr "min."
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr ""
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "t"
+
+msgid "Yes"
+msgstr "Taip"
+
+msgid "True"
+msgstr "Tiesa"
+
+msgid "t"
+msgstr "t"
+
+msgid "False"
+msgstr "Netiesa"
+
+msgid "Message: "
+msgstr ""
+
+msgid "Warning: "
+msgstr ""
+
+msgid "Always ignore this warning."
+msgstr "Daugiau nepaisyti šio pranešimo."
+
+msgid "Do you want to proceed?"
+msgstr "Ar tikrai norite vykdyti?"
+
+msgid "No"
+msgstr "Ne"
+
+msgid "Confirmation: "
+msgstr ""
+
+msgid "Concurrency Exception"
+msgstr "Lygiagretaus duomenų rašymo klaida"
+
+msgid "Write Concurrency Warning: "
+msgstr "Lygiagretaus duomenų rašymo perspėjimas: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "Kol jūs taisėte šį įrašą, jis buvo pakeistas."
+
+msgid "Choose:"
+msgstr ""
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr ""
+
+msgid "\"Compare\" to see the modified version;"
+msgstr ""
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr ""
+
+msgid "Compare"
+msgstr "Palyginti"
+
+#, fuzzy
+msgid "Compare: %1"
+msgstr "Palyginti"
+
+msgid "Write Anyway"
+msgstr "Rašyti visvien"
+
+msgid "Application Error"
+msgstr "Programos klaida"
+
+msgid "Report Bug"
+msgstr "Pranešti apie klaidą"
+
+msgid "Processing"
+msgstr ""
+
+msgid "Search..."
+msgstr ""
+
+msgid "Create..."
+msgstr ""
+
+msgid "Download"
+msgstr "Atsisiųsti"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Switch view"
+msgstr "Perjungti rodymą"
+
+msgid "Previous Record"
+msgstr "Buvęs įrašas"
+
+msgid "Next Record"
+msgstr "Kitas įrašas"
+
+msgid "Create a new record"
+msgstr "Sukurti naują įrašą"
+
+msgid "Save this record"
+msgstr "Išsaugoti šį įrašą"
+
+msgid "Reload"
+msgstr ""
+
+msgid "View Logs..."
+msgstr ""
+
+msgid "Show revisions..."
+msgstr "Rodyti pakeitimus..."
+
+msgid "Add an attachment to the record"
+msgstr "Prisegti failą prie įrašo"
+
+msgid "Add a note to the record"
+msgstr "Prisegti pastabą prie įrašo"
+
+msgid "E-Mail..."
+msgstr ""
+
+#, fuzzy
+msgid "Send an e-mail using the record"
+msgstr "Prisegti pastabą prie įrašo"
+
+msgid "Export"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"Atliekant šį veiksmą bus uždarytos visos kortelės.\n"
+"Ar norite tęsti?"
+
+msgid "Launch action"
+msgstr "Vykdyti veiksmą"
+
+msgid "Open related records"
+msgstr "Atverti susijusius įrašus"
+
+msgid "Print report"
+msgstr "Spausdinti ataskaitą"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Šis įrašas buvo pakeistas\n"
+"Ar norite jį išsaugoti?"
+
+msgid "Record saved."
+msgstr "Įrašas išsaugotas."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Dabar dirbate su įrašo(-ų) kopija(-omis)."
+
+msgid "Are you sure to remove this record?"
+msgstr "Ar tikrai norite ištrinti šį įrašą?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Ar tikrai norite ištrinti šiuos įrašus?"
+
+msgid "Records removed."
+msgstr "Įrašai ištrinti."
+
+msgid "Records not removed."
+msgstr "Įrašai nebuvo ištrinti."
+
+msgid "You have to select one record."
+msgstr "Pasirinkite bent vieną įrašą."
+
+msgid "ID:"
+msgstr "ID:"
+
+#, fuzzy
+msgid "Created by:"
+msgstr "Sukūręs naudotojas"
+
+#, fuzzy
+msgid "Created at:"
+msgstr "Sukūrimo data"
+
+msgid "Edited by:"
+msgstr "Pakeitęs naudotojas:"
+
+msgid "Edited at:"
+msgstr "Keitimo data:"
+
+msgid "Model: "
+msgstr ""
+
+msgid "Add..."
+msgstr "Sukurti naują..."
+
+#, fuzzy
+msgid "Preview"
+msgstr "Buvęs"
+
+#, fuzzy
+msgid "Template"
+msgstr "Susijęs"
+
+msgid "Attachment (%1)"
+msgstr ""
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr " iš "
+
+msgid "Filters"
+msgstr ""
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr ""
+
+msgid "Remove this bookmark"
+msgstr "Šalinti šią žymelę"
+
+msgid "Bookmark this filter"
+msgstr "Sukurti šio filtro žymelę"
+
+msgid "Bookmark Name:"
+msgstr "Žymelės pavadinimas:"
+
+msgid "Show active records"
+msgstr "Rodyti aktyvius įrašus"
+
+msgid "Show inactive records"
+msgstr "Rodyti neaktyvius įrašus"
+
+msgid "Find"
+msgstr "Rasti"
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr "Atverti kalendorių"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Created by"
+msgstr "Sukūręs naudotojas"
+
+msgid "Created at"
+msgstr "Sukūrimo data"
+
+msgid "Modified by"
+msgstr ""
+
+#, fuzzy
+msgid "Modified at"
+msgstr "Pakeitęs naudotojas"
+
+msgid "\"%1\" is required."
+msgstr ""
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr ""
+
+msgid "The values of \"%1\" are not valid."
+msgstr ""
+
+msgid "Pre-validation"
+msgstr "Išankstinis patikrinimas"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr ""
+
+msgid "Edit"
+msgstr "Keisti"
+
+msgid "Fuzzy"
+msgstr "Netikslus"
+
+msgid "You need to save the record before adding translations."
+msgstr "Išsaugokite įrašą prieš pridedant vertimą."
+
+msgid "No other language available."
+msgstr "Nėra kitų kalbų."
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr "Pridėti"
+
+msgid "Remove"
+msgstr ""
+
+msgid "Open"
+msgstr "Atvėrimas"
+
+msgid "Undelete"
+msgstr ""
+
+msgid "Save As"
+msgstr "Įrašyti kaip"
+
+msgid "Save As..."
+msgstr "Įrašyti kaip..."
+
+msgid "Select"
+msgstr "Pasirinkti"
+
+msgid "Select..."
+msgstr "Pasirinkti..."
+
+msgid "Clear"
+msgstr "Valyti"
+
+msgid "Choose a language"
+msgstr "Pasirinkti kalbą"
+
+msgid "%1%"
+msgstr ""
+
+#, fuzzy
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr ""
+
+msgid "Today"
+msgstr "Šiandien"
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr "Savaitė"
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr ""
+
+msgid "Select your action"
+msgstr "Pasirinkite veiksmą"
+
+msgid "No action defined."
+msgstr "Nėra apibrėžtų veiksmų."
+
+msgid "Attachments (%1)"
+msgstr ""
+
+msgid "Notes (%1)"
+msgstr "Pastabos (%1)"
+
+msgid "Search %1"
+msgstr ""
+
+msgid "Revision"
+msgstr "Taisymas"
+
+msgid "All Fields"
+msgstr ""
+
+msgid "Fields Selected"
+msgstr ""
+
+msgid "CSV Parameters"
+msgstr "CSV parametrai"
+
+msgid "Delimiter:"
+msgstr "Skirtukas:"
+
+msgid "Quote Char:"
+msgstr ""
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr ""
+
+msgid "File to Import"
+msgstr ""
+
+msgid "Encoding:"
+msgstr "Koduotė:"
+
+msgid "Lines to Skip:"
+msgstr "Praleisti eilutes:"
+
+msgid "You must select an import file first."
+msgstr "Jūs pirmiausiai turite pasirinkti importo failą."
+
+msgid "An error occured in loading the file."
+msgstr ""
+
+msgid "Error processing the file at field %1."
+msgstr ""
+
+msgid "Error"
+msgstr "Klaida"
+
+msgid "Error occured in loading the file"
+msgstr ""
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr ""
+
+msgid "URL Export"
+msgstr ""
+
+msgid "Delete Export"
+msgstr ""
+
+msgid "Predefined Exports"
+msgstr ""
+
+msgid "Selected Records"
+msgstr "Pasirinkti įrašai"
+
+msgid "Listed Records"
+msgstr "Rodomi įrašai"
+
+msgid "Export:"
+msgstr ""
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr "Naudoti lokalės formatą"
+
+msgid "Add Field Names"
+msgstr ""
+
+msgid "%1 (string)"
+msgstr ""
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr "Kokiu pavadinimu išsaugoti šį eksportavimo šabloną?"
+
+msgid "Override %1 definition?"
+msgstr ""
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+#, fuzzy
+msgid "Reports"
+msgstr "Pranešti apie klaidą"
+
+msgid "Attachments"
+msgstr ""
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+msgid "Remove File"
+msgstr ""
+
+msgid "Wizard"
+msgstr "Vedlys"
+
+msgid "Translate view"
+msgstr "Išversti rodinį"
diff --git a/sao/locale/messages.pot b/sao/locale/messages.pot
new file mode 100644
index 0000000000..c49d77e2af
--- /dev/null
+++ b/sao/locale/messages.pot
@@ -0,0 +1,643 @@
+# Generated by grunt-xgettext on Sat May 01 2021 02:11:54 GMT+0200 (Central European Summer Time)
+
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr ""
+
+msgid "Manage..."
+msgstr ""
+
+msgid "Logout"
+msgstr ""
+
+msgid "Action"
+msgstr ""
+
+msgid "New"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Switch"
+msgstr ""
+
+msgid "Reload/Undo"
+msgstr ""
+
+msgid "Duplicate"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
+msgid "Search"
+msgstr ""
+
+msgid "Close Tab"
+msgstr ""
+
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
+msgid "Relate"
+msgstr ""
+
+msgid "Print"
+msgstr ""
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr ""
+
+msgid "Next tab"
+msgstr ""
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr ""
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr ""
+
+msgid "User name"
+msgstr ""
+
+msgid "Database"
+msgstr ""
+
+msgid "Your selection:"
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Y"
+msgstr ""
+
+msgid "M"
+msgstr ""
+
+msgid "w"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "h"
+msgstr ""
+
+msgid "m"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "By: "
+msgstr ""
+
+msgid ", "
+msgstr ""
+
+msgid "y"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "True"
+msgstr ""
+
+msgid "t"
+msgstr ""
+
+msgid "False"
+msgstr ""
+
+msgid "Message: "
+msgstr ""
+
+msgid "Warning: "
+msgstr ""
+
+msgid "Always ignore this warning."
+msgstr ""
+
+msgid "Do you want to proceed?"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Confirmation: "
+msgstr ""
+
+msgid "Concurrency Exception"
+msgstr ""
+
+msgid "Write Concurrency Warning: "
+msgstr ""
+
+msgid "This record has been modified while you were editing it."
+msgstr ""
+
+msgid "Choose:"
+msgstr ""
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr ""
+
+msgid "\"Compare\" to see the modified version;"
+msgstr ""
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Compare: %1"
+msgstr ""
+
+msgid "Write Anyway"
+msgstr ""
+
+msgid "Application Error"
+msgstr ""
+
+msgid "Report Bug"
+msgstr ""
+
+msgid "Processing"
+msgstr ""
+
+msgid "Search..."
+msgstr ""
+
+msgid "Create..."
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid "..."
+msgstr ""
+
+msgid "Font"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Switch view"
+msgstr ""
+
+msgid "Previous Record"
+msgstr ""
+
+msgid "Next Record"
+msgstr ""
+
+msgid "Create a new record"
+msgstr ""
+
+msgid "Save this record"
+msgstr ""
+
+msgid "Reload"
+msgstr ""
+
+msgid "View Logs..."
+msgstr ""
+
+msgid "Show revisions..."
+msgstr ""
+
+msgid "Add an attachment to the record"
+msgstr ""
+
+msgid "Add a note to the record"
+msgstr ""
+
+msgid "E-Mail..."
+msgstr ""
+
+msgid "Send an e-mail using the record"
+msgstr ""
+
+msgid "Export"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid "The following action requires to close all tabs.\nDo you want to continue?"
+msgstr ""
+
+msgid "Launch action"
+msgstr ""
+
+msgid "Open related records"
+msgstr ""
+
+msgid "Print report"
+msgstr ""
+
+msgid "This record has been modified\ndo you want to save it?"
+msgstr ""
+
+msgid "Record saved."
+msgstr ""
+
+msgid "Working now on the duplicated record(s)."
+msgstr ""
+
+msgid "Are you sure to remove this record?"
+msgstr ""
+
+msgid "Are you sure to remove those records?"
+msgstr ""
+
+msgid "Records removed."
+msgstr ""
+
+msgid "Records not removed."
+msgstr ""
+
+msgid "You have to select one record."
+msgstr ""
+
+msgid "ID:"
+msgstr ""
+
+msgid "Created by:"
+msgstr ""
+
+msgid "Created at:"
+msgstr ""
+
+msgid "Edited by:"
+msgstr ""
+
+msgid "Edited at:"
+msgstr ""
+
+msgid "Model: "
+msgstr ""
+
+msgid "Add..."
+msgstr ""
+
+msgid "Preview"
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Attachment (%1)"
+msgstr ""
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr ""
+
+msgid "Filters"
+msgstr ""
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr ""
+
+msgid "Remove this bookmark"
+msgstr ""
+
+msgid "Bookmark this filter"
+msgstr ""
+
+msgid "Bookmark Name:"
+msgstr ""
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr ""
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "Created by"
+msgstr ""
+
+msgid "Created at"
+msgstr ""
+
+msgid "Modified by"
+msgstr ""
+
+msgid "Modified at"
+msgstr ""
+
+msgid "\"%1\" is required."
+msgstr ""
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr ""
+
+msgid "The values of \"%1\" are not valid."
+msgstr ""
+
+msgid "Pre-validation"
+msgstr ""
+
+msgid ":"
+msgstr ""
+
+msgid "Translate"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Fuzzy"
+msgstr ""
+
+msgid "You need to save the record before adding translations."
+msgstr ""
+
+msgid "No other language available."
+msgstr ""
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Open"
+msgstr ""
+
+msgid "Undelete"
+msgstr ""
+
+msgid "Save As"
+msgstr ""
+
+msgid "Save As..."
+msgstr ""
+
+msgid "Select"
+msgstr ""
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr ""
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr ""
+
+msgid ": "
+msgstr ""
+
+msgid "More"
+msgstr ""
+
+msgid "Today"
+msgstr ""
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr ""
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr ""
+
+msgid "Select your action"
+msgstr ""
+
+msgid "No action defined."
+msgstr ""
+
+msgid "Attachments (%1)"
+msgstr ""
+
+msgid "Notes (%1)"
+msgstr ""
+
+msgid "Search %1"
+msgstr ""
+
+msgid "Revision"
+msgstr ""
+
+msgid "All Fields"
+msgstr ""
+
+msgid "Fields Selected"
+msgstr ""
+
+msgid "CSV Parameters"
+msgstr ""
+
+msgid "Delimiter:"
+msgstr ""
+
+msgid "Quote Char:"
+msgstr ""
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr ""
+
+msgid "File to Import"
+msgstr ""
+
+msgid "Encoding:"
+msgstr ""
+
+msgid "Lines to Skip:"
+msgstr ""
+
+msgid "You must select an import file first."
+msgstr ""
+
+msgid "An error occured in loading the file."
+msgstr ""
+
+msgid "Error processing the file at field %1."
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Error occured in loading the file"
+msgstr ""
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr ""
+
+msgid "URL Export"
+msgstr ""
+
+msgid "Delete Export"
+msgstr ""
+
+msgid "Predefined Exports"
+msgstr ""
+
+msgid "Selected Records"
+msgstr ""
+
+msgid "Listed Records"
+msgstr ""
+
+msgid "Export:"
+msgstr ""
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr ""
+
+msgid "%1 (string)"
+msgstr ""
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr ""
+
+msgid "Override %1 definition?"
+msgstr ""
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+msgid "Reports"
+msgstr ""
+
+msgid ""
+msgstr ""
+
+msgid "Attachments"
+msgstr ""
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+msgid "Remove File"
+msgstr ""
+
+msgid "Wizard"
+msgstr ""
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/nl.po b/sao/locale/nl.po
new file mode 100644
index 0000000000..b8d0e7f1cd
--- /dev/null
+++ b/sao/locale/nl.po
@@ -0,0 +1,652 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr "Ben je zeker dat je weggaat?"
+
+msgid "Favorites"
+msgstr "Favorieten"
+
+msgid "Manage..."
+msgstr "Beheren..."
+
+msgid "Logout"
+msgstr "Uitloggen"
+
+msgid "Action"
+msgstr "Actie"
+
+msgid "New"
+msgstr "Nieuw"
+
+msgid "Save"
+msgstr "Opslaan"
+
+msgid "Switch"
+msgstr "Omschakelen"
+
+msgid "Reload/Undo"
+msgstr "Herladen/Annuleren"
+
+msgid "Duplicate"
+msgstr "Duplicaat"
+
+msgid "Delete"
+msgstr "Verwijderen"
+
+msgid "Previous"
+msgstr "Vorige"
+
+msgid "Next"
+msgstr "Volgende"
+
+msgid "Search"
+msgstr "Zoeken"
+
+msgid "Close Tab"
+msgstr "Tabblad sluiten"
+
+msgid "Attachment"
+msgstr "Bijlage"
+
+msgid "Note"
+msgstr "Aantekening"
+
+msgid "Relate"
+msgstr "Relatie"
+
+msgid "Print"
+msgstr "Afdrukken"
+
+msgid "E-Mail"
+msgstr "E-mail"
+
+msgid "Previous tab"
+msgstr "Vorig tabblad"
+
+msgid "Next tab"
+msgstr "Volgende tabblad"
+
+msgid "Global search"
+msgstr "Algemeen zoeken"
+
+msgid "Show this help"
+msgstr "Toon deze hulp"
+
+msgid "Keyboard shortcuts"
+msgstr "Toetsenbord sneltoetsen"
+
+msgid "Close"
+msgstr "Sluiten"
+
+msgid "Global shortcuts"
+msgstr "algemene snelkoppeling"
+
+msgid "Tab shortcuts"
+msgstr "Tab snelkoppelingen"
+
+msgid "Unable to reach the server."
+msgstr "Kan geen verbinding maken met server."
+
+msgid "Too many requests. Try again later."
+msgstr "Te veel verzoeken. Probeer het later nog eens."
+
+msgid "Login"
+msgstr "Inlognaam"
+
+msgid "User name"
+msgstr "Gebruikersnaam"
+
+msgid "Database"
+msgstr "Database"
+
+msgid "Your selection:"
+msgstr "Uw selectie:"
+
+msgid "Cancel"
+msgstr "Annuleren"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Y"
+msgstr "J"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "w"
+
+msgid "d"
+msgstr "d"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "Door: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "J"
+
+msgid "Yes"
+msgstr "Ja"
+
+msgid "True"
+msgstr "Waar"
+
+msgid "t"
+msgstr "w (t)"
+
+msgid "False"
+msgstr "Niet waar"
+
+msgid "Message: "
+msgstr "Bericht: "
+
+msgid "Warning: "
+msgstr "Waarschuwing: "
+
+msgid "Always ignore this warning."
+msgstr "Deze waarschuwing altijd negeren."
+
+msgid "Do you want to proceed?"
+msgstr "Doorgaan?"
+
+msgid "No"
+msgstr "Nee"
+
+msgid "Confirmation: "
+msgstr "Bevestiging: "
+
+msgid "Concurrency Exception"
+msgstr "Simultaan gebruik (error)"
+
+msgid "Write Concurrency Warning: "
+msgstr "Aandacht, schrijftoegang concurrenten (Write Concurrency) : "
+
+msgid "This record has been modified while you were editing it."
+msgstr "Dit veld werd gewijzigd terwijl u het aan het bewerken was."
+
+msgid "Choose:"
+msgstr "Kiezen:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"Annuleren\" om het opslaan te annuleren;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"Vergelijken\" om de gewijzigde versie te zien;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"Overschrijven\" om de huidige versie te bewaren."
+
+msgid "Compare"
+msgstr "Vergelijken"
+
+msgid "Compare: %1"
+msgstr "Vergelijk:% 1"
+
+msgid "Write Anyway"
+msgstr "Overschrijven"
+
+msgid "Application Error"
+msgstr "Applicatiefout"
+
+msgid "Report Bug"
+msgstr "Programmafout melden"
+
+msgid "Processing"
+msgstr "Verwerking"
+
+msgid "Search..."
+msgstr "Zoeken..."
+
+msgid "Create..."
+msgstr "Maak ..."
+
+msgid "Download"
+msgstr "Download"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "lettertype"
+
+msgid "Size"
+msgstr "Grootte"
+
+msgid "Switch view"
+msgstr "Wissel van weergave"
+
+msgid "Previous Record"
+msgstr "Vorig record"
+
+msgid "Next Record"
+msgstr "Volgende record"
+
+msgid "Create a new record"
+msgstr "Maak een nieuw record"
+
+msgid "Save this record"
+msgstr "Bewaar deze record"
+
+msgid "Reload"
+msgstr "Herladen"
+
+msgid "View Logs..."
+msgstr "Bekijk logregister..."
+
+msgid "Show revisions..."
+msgstr "Herzieningen tonen ..."
+
+msgid "Add an attachment to the record"
+msgstr "Voeg een bijlage toe aan het record"
+
+msgid "Add a note to the record"
+msgstr "Voeg een nota toe aan het veld"
+
+msgid "E-Mail..."
+msgstr "E-mail..."
+
+msgid "Send an e-mail using the record"
+msgstr "Stuur een e-mail met behulp van het record"
+
+msgid "Export"
+msgstr "Exporteren"
+
+msgid "Import"
+msgstr "Importeren"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"De volgende actie vereist het sluiten van alle tabbladen.\n"
+"Verder gaan?"
+
+msgid "Launch action"
+msgstr "Start actie"
+
+msgid "Open related records"
+msgstr "Open gerelateerde records"
+
+msgid "Print report"
+msgstr "Rapport afdrukken"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Dit veld is aangepast.\n"
+"Wil je de wijzigingen opslaan?"
+
+msgid "Record saved."
+msgstr "Record opgeslagen."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Nu aan het werk op het/de gecopieërde record(s)."
+
+msgid "Are you sure to remove this record?"
+msgstr "Weet je zeker dat je dit record wilt verwijderen?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Weet je zeker dat je deze records wilt verwijderen?"
+
+msgid "Records removed."
+msgstr "Records verwijderd."
+
+msgid "Records not removed."
+msgstr "Records niet verwijderd."
+
+msgid "You have to select one record."
+msgstr "U moet één record selecteren."
+
+msgid "ID:"
+msgstr "ID:"
+
+msgid "Created by:"
+msgstr "Aangemaakt door:"
+
+msgid "Created at:"
+msgstr "Aanmaakdatum:"
+
+msgid "Edited by:"
+msgstr "Aangepast door:"
+
+msgid "Edited at:"
+msgstr "Bewerkt op:"
+
+msgid "Model: "
+msgstr "Model: "
+
+msgid "Add..."
+msgstr "Toevoegen..."
+
+#, fuzzy
+msgid "Preview"
+msgstr "Vorige"
+
+msgid "Template"
+msgstr "Sjabloon"
+
+msgid "Attachment (%1)"
+msgstr "Bijlage (%1)"
+
+msgid "Note (%1/%2)"
+msgstr "Opmerking (%1/%2)"
+
+msgid " of "
+msgstr " van "
+
+msgid "Filters"
+msgstr "filters"
+
+msgid "Clear Search"
+msgstr "Wis zoeken"
+
+msgid "Bookmarks"
+msgstr "bladwijzers"
+
+msgid "Remove this bookmark"
+msgstr "Verwijder deze bladwijzer"
+
+msgid "Bookmark this filter"
+msgstr "Maak een bladwijzer van deze filter"
+
+msgid "Bookmark Name:"
+msgstr "Bladwijzernaam:"
+
+msgid "Show active records"
+msgstr "Toon actieve records"
+
+msgid "Show inactive records"
+msgstr "Toon niet actieve records"
+
+msgid "Find"
+msgstr "Zoeken"
+
+msgid "From"
+msgstr "Van"
+
+msgid "To"
+msgstr "Aan"
+
+msgid "Open the calendar"
+msgstr "Open de kalender"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Created by"
+msgstr "Aangemaakt door"
+
+msgid "Created at"
+msgstr "Aanmaakdatum"
+
+msgid "Modified by"
+msgstr "Aangepast door"
+
+msgid "Modified at"
+msgstr "Gewijzigd om"
+
+msgid "\"%1\" is required."
+msgstr "\"%1\" is vereist."
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" is niet geldig volgens zijn domein."
+
+msgid "The values of \"%1\" are not valid."
+msgstr "De waarden van \"%1\" zijn niet geldig."
+
+msgid "Pre-validation"
+msgstr "Pre-validatie"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Vertalen"
+
+msgid "Edit"
+msgstr "Bewerk"
+
+msgid "Fuzzy"
+msgstr "Flauwe"
+
+msgid "You need to save the record before adding translations."
+msgstr "U moet de record opslaan voordat u vertalingen toevoegt."
+
+msgid "No other language available."
+msgstr "Geen andere taal beschikbaar."
+
+msgid "Show"
+msgstr "Toon"
+
+msgid "Hide"
+msgstr "Verbergen"
+
+msgid "Open the record"
+msgstr "Open het record"
+
+msgid "Clear the field"
+msgstr "Wis het veld"
+
+msgid "Search a record"
+msgstr "Zoek een record"
+
+msgid "Add"
+msgstr "Toevoegen"
+
+msgid "Remove"
+msgstr "Verwijderen"
+
+msgid "Open"
+msgstr "Openen"
+
+msgid "Undelete"
+msgstr "wissen ongedaan maken"
+
+msgid "Save As"
+msgstr "Opslaan als"
+
+msgid "Save As..."
+msgstr "Opslaan als..."
+
+msgid "Select"
+msgstr "Selecteer"
+
+msgid "Select..."
+msgstr "Selecteer ..."
+
+msgid "Clear"
+msgstr "Wissen"
+
+msgid "Choose a language"
+msgstr "Kies een taal"
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "Meer"
+
+msgid "Today"
+msgstr "Vandaag"
+
+msgid "Month"
+msgstr "Maand"
+
+msgid "Week"
+msgstr "Week"
+
+msgid "Day"
+msgstr "Dag"
+
+msgid ",..."
+msgstr ",..."
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Selecteer je handeling"
+
+msgid "No action defined."
+msgstr "Geen handeling gedefinieerd."
+
+msgid "Attachments (%1)"
+msgstr "Bijlagen (%1)"
+
+msgid "Notes (%1)"
+msgstr "Notities (%1)"
+
+msgid "Search %1"
+msgstr "Zoek %1"
+
+msgid "Revision"
+msgstr "Herziening"
+
+msgid "All Fields"
+msgstr "Alle velden"
+
+msgid "Fields Selected"
+msgstr "Geselecteerde Velden"
+
+msgid "CSV Parameters"
+msgstr "CSV parameters"
+
+msgid "Delimiter:"
+msgstr "scheidingsteken:"
+
+msgid "Quote Char:"
+msgstr "aanhalingstekens :"
+
+msgid "CSV Import: %1"
+msgstr "CSV-Import: %1"
+
+msgid "Auto-Detect"
+msgstr "Automatische detectie"
+
+msgid "File to Import"
+msgstr "Bestand om te importeren"
+
+msgid "Encoding:"
+msgstr "Codering:"
+
+msgid "Lines to Skip:"
+msgstr "Regels overslaan:"
+
+msgid "You must select an import file first."
+msgstr "U moet eerst een importbestand selecteren."
+
+msgid "An error occured in loading the file."
+msgstr "Er is een fout opgetreden bij het laden van het bestand."
+
+msgid "Error processing the file at field %1."
+msgstr "Fout bij verwerken van het bestand op veld %1."
+
+msgid "Error"
+msgstr "Fout"
+
+msgid "Error occured in loading the file"
+msgstr "Er is een fout opgetreden bij het laden van het bestand"
+
+msgid "CSV Export: %1"
+msgstr "Exporteer CSV: %1"
+
+msgid "Save Export"
+msgstr "Export opslaan"
+
+msgid "URL Export"
+msgstr "URL Exporteren"
+
+msgid "Delete Export"
+msgstr "Export verwijderen"
+
+msgid "Predefined Exports"
+msgstr "Vooraf gedefinieerde exports"
+
+msgid "Selected Records"
+msgstr "Geselecteerde records"
+
+msgid "Listed Records"
+msgstr "Vermelde records"
+
+msgid "Export:"
+msgstr "Exporteer:"
+
+msgid "Ignore search limit"
+msgstr "Zoeklimiet negeren"
+
+msgid "Use locale format"
+msgstr "Gebruik lokaal formaat"
+
+msgid "Add Field Names"
+msgstr "Voeg veldnamen toe"
+
+msgid "%1 (string)"
+msgstr "%1 (string)"
+
+msgid "%1 (model name)"
+msgstr "%1 (model naam)"
+
+msgid "%1 (record name)"
+msgstr "%1 (recordnaam)"
+
+msgid "What is the name of this export?"
+msgstr "Wat is de naam voor deze export?"
+
+msgid "Override %1 definition?"
+msgstr "Definitie van %1 overschrijven?"
+
+msgid "E-mail %1"
+msgstr "E-mail %1"
+
+msgid "To:"
+msgstr "Aan:"
+
+msgid "Cc:"
+msgstr "Cc:"
+
+msgid "Bcc:"
+msgstr "Bcc:"
+
+msgid "Subject:"
+msgstr "Onderwerp:"
+
+msgid "Reports"
+msgstr "Rapporten"
+
+msgid "Attachments"
+msgstr "Bijlagen"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr "Sturen"
+
+#, fuzzy
+msgid "Remove File"
+msgstr "Verwijderen"
+
+msgid "Wizard"
+msgstr "Assistent"
+
+msgid "Translate view"
+msgstr "Vertaal aanzicht"
diff --git a/sao/locale/pl.po b/sao/locale/pl.po
new file mode 100644
index 0000000000..14d060c547
--- /dev/null
+++ b/sao/locale/pl.po
@@ -0,0 +1,666 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 15 2019 16:53:42 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 01 2019 13:14:07 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Mar 01 2019 00:18:48 GMT+0100 (CET)
+# Generated by grunt-xgettext on Fri Feb 01 2019 00:07:47 GMT+0100 (CET)
+# Generated by grunt-xgettext on Tue Jan 01 2019 00:13:07 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sat Dec 01 2018 00:17:31 GMT+0100 (CET)
+# Generated by grunt-xgettext on Thu Nov 01 2018 00:08:43 GMT+0100 (CET)
+# Generated by grunt-xgettext on Mon Oct 01 2018 00:07:22 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Sep 14 2018 22:59:37 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sun Sep 09 2018 10:24:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Sep 04 2018 13:54:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 14 2018 17:56:54 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Apr 06 2018 22:57:49 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Oct 09 2017 19:35:04 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr "Czy na pewno wyjść?"
+
+msgid "Favorites"
+msgstr "Ulubione"
+
+msgid "Manage..."
+msgstr "Zarządzaj..."
+
+msgid "Logout"
+msgstr "Wyloguj"
+
+msgid "Action"
+msgstr "Akcja"
+
+msgid "New"
+msgstr "Nowy"
+
+msgid "Save"
+msgstr "Zapisz"
+
+msgid "Switch"
+msgstr "Przełącz"
+
+msgid "Reload/Undo"
+msgstr "Odśwież/Przywróć"
+
+msgid "Duplicate"
+msgstr "Duplikuj"
+
+msgid "Delete"
+msgstr "Usuń"
+
+msgid "Previous"
+msgstr "Poprzedni"
+
+msgid "Next"
+msgstr "Następny"
+
+msgid "Search"
+msgstr "Szukaj"
+
+msgid "Close Tab"
+msgstr "Zamknij kartę"
+
+msgid "Attachment"
+msgstr "Załącznik"
+
+msgid "Note"
+msgstr "Notatka"
+
+msgid "Relate"
+msgstr "Odnośnik"
+
+msgid "Print"
+msgstr "Wydruk"
+
+msgid "E-Mail"
+msgstr "E-mail"
+
+msgid "Previous tab"
+msgstr "Poprzednia karta"
+
+msgid "Next tab"
+msgstr "Następna karta"
+
+msgid "Global search"
+msgstr "Wyszukiwanie globalne"
+
+msgid "Show this help"
+msgstr "Wyświetl tę pomoc"
+
+msgid "Keyboard shortcuts"
+msgstr "Skróty klawiszowe"
+
+msgid "Close"
+msgstr "Zamknij"
+
+msgid "Global shortcuts"
+msgstr "Skróty globalne"
+
+msgid "Tab shortcuts"
+msgstr "Skróty kart"
+
+msgid "Unable to reach the server."
+msgstr "Brak dostępu do serwera."
+
+msgid "Too many requests. Try again later."
+msgstr "Za dużo połączeń. Spróbuj później."
+
+msgid "Login"
+msgstr "Login"
+
+msgid "User name"
+msgstr "Nazwa użytkownika"
+
+msgid "Database"
+msgstr "Baza danych"
+
+msgid "Your selection:"
+msgstr "Twoje zaznaczenie:"
+
+msgid "Cancel"
+msgstr "Anuluj"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Y"
+msgstr "R"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "t"
+
+msgid "d"
+msgstr "d"
+
+msgid "h"
+msgstr "g"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "Przez: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "t"
+
+msgid "Yes"
+msgstr "Tak"
+
+msgid "True"
+msgstr "Tak"
+
+msgid "t"
+msgstr "p"
+
+msgid "False"
+msgstr "Nie"
+
+msgid "Message: "
+msgstr "Wiadomość: "
+
+msgid "Warning: "
+msgstr "Ostrzeżenie: "
+
+msgid "Always ignore this warning."
+msgstr "Zawsze ignoruj takie ostrzeżenie."
+
+msgid "Do you want to proceed?"
+msgstr "Czy chcesz kontynuować?"
+
+msgid "No"
+msgstr "Nie"
+
+msgid "Confirmation: "
+msgstr "Potwierdzenie: "
+
+msgid "Concurrency Exception"
+msgstr "Wyjątek równoczesnego zapisu danych"
+
+msgid "Write Concurrency Warning: "
+msgstr "Ostrzeżenie o równoczesnym zapisie danych: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "Ten rekord został zmodyfikowany w trakcie twojej edycji."
+
+msgid "Choose:"
+msgstr "Wybierz:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"Anuluj\" jeśli chcesz anulować zapis danych;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"Porównaj\" jeśli chcesz zobaczyć zmienioną wersję danych;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"Zapisz\" jeśli chcesz zapisać aktualną wersję danych."
+
+msgid "Compare"
+msgstr "Porównaj"
+
+msgid "Compare: %1"
+msgstr "Porównaj: %1"
+
+msgid "Write Anyway"
+msgstr "Zapisz"
+
+msgid "Application Error"
+msgstr "Błąd aplikacji"
+
+msgid "Report Bug"
+msgstr "Zgłoś błąd"
+
+msgid "Processing"
+msgstr "Przetwarzanie"
+
+msgid "Search..."
+msgstr "Szukaj..."
+
+msgid "Create..."
+msgstr "Utwórz..."
+
+msgid "Download"
+msgstr "Pobierz"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Czcionka"
+
+msgid "Size"
+msgstr "Rozmiar"
+
+msgid "Switch view"
+msgstr "Przełącz widok"
+
+msgid "Previous Record"
+msgstr "Poprzedni rekord"
+
+msgid "Next Record"
+msgstr "Następny rekord"
+
+msgid "Create a new record"
+msgstr "Utwórz nowy rekord"
+
+msgid "Save this record"
+msgstr "Zapisz rekord"
+
+msgid "Reload"
+msgstr "Odśwież"
+
+msgid "View Logs..."
+msgstr "Pokaż dziennik..."
+
+msgid "Show revisions..."
+msgstr "Pokaż rewizje..."
+
+msgid "Add an attachment to the record"
+msgstr "Dodaj załącznik do rekordu"
+
+msgid "Add a note to the record"
+msgstr "Dodaj notatkę do rekordu"
+
+msgid "E-Mail..."
+msgstr "E-mail..."
+
+msgid "Send an e-mail using the record"
+msgstr "Wyślij e-mail używając rekordu"
+
+msgid "Export"
+msgstr "Eksportuj"
+
+msgid "Import"
+msgstr "Importuj"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"Wykonanie polecenia wymaga zamknięcia wszystkich kart.\n"
+"Czy chcesz kontynuować?"
+
+msgid "Launch action"
+msgstr "Uruchom akcję"
+
+msgid "Open related records"
+msgstr "Otwórz powiązane rekordy"
+
+msgid "Print report"
+msgstr "Drukuj raport"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Rekord został zmodyfikowany.\n"
+"Czy chcesz go zapisać?"
+
+msgid "Record saved."
+msgstr "Rekord został zapisany."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Pracujesz na zduplikowanym(ch) rekordzie(ch)."
+
+msgid "Are you sure to remove this record?"
+msgstr "Czy na pewno usunąć wybrany rekord?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Czy na pewno usunąć wybrane rekordy?"
+
+msgid "Records removed."
+msgstr "Rekordy zostały usunięte."
+
+msgid "Records not removed."
+msgstr "Rekordy nie zostały usunięte."
+
+msgid "You have to select one record."
+msgstr "Musisz wybrać jeden rekord."
+
+msgid "ID:"
+msgstr "ID:"
+
+msgid "Created by:"
+msgstr "Utworzył:"
+
+msgid "Created at:"
+msgstr "Data utworzenia:"
+
+msgid "Edited by:"
+msgstr "Zmodyfikował:"
+
+msgid "Edited at:"
+msgstr "Data modyfikacji:"
+
+msgid "Model: "
+msgstr "Model: "
+
+msgid "Add..."
+msgstr "Dodaj..."
+
+#, fuzzy
+msgid "Preview"
+msgstr "Poprzedni"
+
+msgid "Template"
+msgstr "Szablon"
+
+msgid "Attachment (%1)"
+msgstr "Załącznik (%1)"
+
+msgid "Note (%1/%2)"
+msgstr "Notatka (%1/%2)"
+
+msgid " of "
+msgstr " z "
+
+msgid "Filters"
+msgstr "Filtry"
+
+msgid "Clear Search"
+msgstr "Wyczyść wyszukiwanie"
+
+msgid "Bookmarks"
+msgstr "Zakładki"
+
+msgid "Remove this bookmark"
+msgstr "Usuń zakładkę"
+
+msgid "Bookmark this filter"
+msgstr "Dodaj filtr do zakładek"
+
+msgid "Bookmark Name:"
+msgstr "Dodaj nazwę zakładek:"
+
+msgid "Show active records"
+msgstr "Pokaż aktywne rekordy"
+
+msgid "Show inactive records"
+msgstr "Pokaż nieaktywne rekordy"
+
+msgid "Find"
+msgstr "Znajdź"
+
+msgid "From"
+msgstr "Od"
+
+msgid "To"
+msgstr "Do"
+
+msgid "Open the calendar"
+msgstr "Otwórz kalendarz"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Created by"
+msgstr "Utworzył"
+
+msgid "Created at"
+msgstr "Data utworzenia"
+
+msgid "Modified by"
+msgstr "Zmodyfikował"
+
+msgid "Modified at"
+msgstr "Data modyfikacji"
+
+msgid "\"%1\" is required."
+msgstr "\"%1\" jest wymagany."
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" jest nieprawidłowy pod względem swojej domeny."
+
+msgid "The values of \"%1\" are not valid."
+msgstr "Wartości \"%1\" nie są prawidłowe."
+
+msgid "Pre-validation"
+msgstr "Wstępna walidacja"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Przetłumacz"
+
+msgid "Edit"
+msgstr "Edycja"
+
+msgid "Fuzzy"
+msgstr "Niejasne"
+
+msgid "You need to save the record before adding translations."
+msgstr "Musisz zapisać rekord przed dodaniem tłumaczeń."
+
+msgid "No other language available."
+msgstr "Brak innych języków."
+
+msgid "Show"
+msgstr "Pokaż"
+
+msgid "Hide"
+msgstr "Ukryj"
+
+msgid "Open the record"
+msgstr "Otwórz rekord"
+
+msgid "Clear the field"
+msgstr "Wyczyść pole"
+
+msgid "Search a record"
+msgstr "Szukaj rekord"
+
+msgid "Add"
+msgstr "Dodaj"
+
+msgid "Remove"
+msgstr "Usuń"
+
+msgid "Open"
+msgstr "Otwórz"
+
+msgid "Undelete"
+msgstr "Przywróć"
+
+msgid "Save As"
+msgstr "Zapisz jako"
+
+msgid "Save As..."
+msgstr "Zapisz jako..."
+
+msgid "Select"
+msgstr "Wybierz"
+
+msgid "Select..."
+msgstr "Wybierz..."
+
+msgid "Clear"
+msgstr "Wyczyść"
+
+msgid "Choose a language"
+msgstr "Wybierz język"
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "Więcej"
+
+msgid "Today"
+msgstr "Dzisiaj"
+
+msgid "Month"
+msgstr "Miesiąc"
+
+msgid "Week"
+msgstr "Tydzień"
+
+msgid "Day"
+msgstr "Dzień"
+
+msgid ",..."
+msgstr ",..."
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Wybierz akcję"
+
+msgid "No action defined."
+msgstr "Brak zdefiniowanej akcji."
+
+msgid "Attachments (%1)"
+msgstr "Załączniki (%1)"
+
+msgid "Notes (%1)"
+msgstr "Notatki (%1)"
+
+msgid "Search %1"
+msgstr "Szukaj %1"
+
+msgid "Revision"
+msgstr "Rewizja"
+
+msgid "All Fields"
+msgstr "Wszystkie pola"
+
+msgid "Fields Selected"
+msgstr "Pola wybrane"
+
+msgid "CSV Parameters"
+msgstr "Parametry CSV"
+
+msgid "Delimiter:"
+msgstr "Separator:"
+
+msgid "Quote Char:"
+msgstr "Symbol dziesiętny:"
+
+msgid "CSV Import: %1"
+msgstr "Import z CSV: %1"
+
+msgid "Auto-Detect"
+msgstr "Automatyczne rozpoznawanie"
+
+msgid "File to Import"
+msgstr "Plik do zaimportowania"
+
+msgid "Encoding:"
+msgstr "Kodowanie:"
+
+msgid "Lines to Skip:"
+msgstr "Wiersze do ominięcia:"
+
+msgid "You must select an import file first."
+msgstr "Wybierz plik do zaimportowania."
+
+msgid "An error occured in loading the file."
+msgstr "Błąd ładowania pliku."
+
+msgid "Error processing the file at field %1."
+msgstr "Błąd przetwarzania pliku w polu %1."
+
+msgid "Error"
+msgstr "Błąd"
+
+msgid "Error occured in loading the file"
+msgstr "Błąd ładowania pliku"
+
+msgid "CSV Export: %1"
+msgstr "Eksport do CSV: %1"
+
+msgid "Save Export"
+msgstr "Zapisz eksport"
+
+msgid "URL Export"
+msgstr "Eksportuj URL"
+
+msgid "Delete Export"
+msgstr "Usuń eksport"
+
+msgid "Predefined Exports"
+msgstr "Predefiniowane eksporty"
+
+msgid "Selected Records"
+msgstr "Wybrane rekordy"
+
+msgid "Listed Records"
+msgstr "Wymienione rekordy"
+
+msgid "Export:"
+msgstr "Eksport:"
+
+msgid "Ignore search limit"
+msgstr "Ignoruj limit wyszukiwań"
+
+msgid "Use locale format"
+msgstr "Użyj formatu lokalnego"
+
+msgid "Add Field Names"
+msgstr "Dodaj nazwy pól"
+
+msgid "%1 (string)"
+msgstr "%1 (string)"
+
+msgid "%1 (model name)"
+msgstr "%1 (model name)"
+
+msgid "%1 (record name)"
+msgstr "%1 (record name)"
+
+msgid "What is the name of this export?"
+msgstr "Jaka jest nazwa tego eksportu?"
+
+msgid "Override %1 definition?"
+msgstr "Czy nadpisać definicję %1?"
+
+msgid "E-mail %1"
+msgstr "E-mail %1"
+
+msgid "To:"
+msgstr "Do:"
+
+msgid "Cc:"
+msgstr "DW:"
+
+msgid "Bcc:"
+msgstr "UDW:"
+
+msgid "Subject:"
+msgstr "Temat:"
+
+msgid "Reports"
+msgstr "Raporty"
+
+msgid "Attachments"
+msgstr "Załączniki"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr "Wyślij"
+
+#, fuzzy
+msgid "Remove File"
+msgstr "Usuń"
+
+msgid "Wizard"
+msgstr "Kreator"
+
+msgid "Translate view"
+msgstr "Widok tłumaczenia"
diff --git a/sao/locale/pt.po b/sao/locale/pt.po
new file mode 100644
index 0000000000..cc2fdafe97
--- /dev/null
+++ b/sao/locale/pt.po
@@ -0,0 +1,694 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 15 2019 16:53:42 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Apr 01 2019 13:14:07 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Mar 01 2019 00:18:48 GMT+0100 (CET)
+# Generated by grunt-xgettext on Fri Feb 01 2019 00:07:47 GMT+0100 (CET)
+# Generated by grunt-xgettext on Tue Jan 01 2019 00:13:07 GMT+0100 (CET)
+# Generated by grunt-xgettext on Sat Dec 01 2018 00:17:31 GMT+0100 (CET)
+# Generated by grunt-xgettext on Thu Nov 01 2018 00:08:43 GMT+0100 (CET)
+# Generated by grunt-xgettext on Mon Oct 01 2018 00:07:22 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Sep 14 2018 22:59:37 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sun Sep 09 2018 10:24:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Tue Sep 04 2018 13:54:29 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Sat Apr 14 2018 17:56:54 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Apr 06 2018 22:57:49 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Mon Oct 09 2017 19:35:04 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr "Tem certeza que quer sair?"
+
+msgid "Favorites"
+msgstr "Favoritos"
+
+msgid "Manage..."
+msgstr "Gerenciar..."
+
+# Generated by grunt-xgettext on Thu Mar 31 2016 17:50:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Oct 16 2015 17:37:32 GMT+0200 (CEST)
+msgid "Logout"
+msgstr "Sair"
+
+msgid "Action"
+msgstr "Ação"
+
+msgid "New"
+msgstr "Novo"
+
+msgid "Save"
+msgstr "Gravar"
+
+msgid "Switch"
+msgstr "Alternar"
+
+msgid "Reload/Undo"
+msgstr "Recarregar/Desfazer"
+
+msgid "Duplicate"
+msgstr "Duplicar"
+
+msgid "Delete"
+msgstr "Apagar"
+
+msgid "Previous"
+msgstr "Anterior"
+
+msgid "Next"
+msgstr "Próximo"
+
+msgid "Search"
+msgstr "Buscar"
+
+msgid "Close Tab"
+msgstr "Fechar aba"
+
+msgid "Attachment"
+msgstr "Anexo"
+
+msgid "Note"
+msgstr "Nota"
+
+msgid "Relate"
+msgstr "Relacionar"
+
+msgid "Print"
+msgstr "Imprimir"
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr "Aba anterior"
+
+msgid "Next tab"
+msgstr "Próxima aba"
+
+msgid "Global search"
+msgstr "Pesquisa global"
+
+msgid "Show this help"
+msgstr "Mostra esta ajuda"
+
+msgid "Keyboard shortcuts"
+msgstr "Teclas de atalho"
+
+msgid "Close"
+msgstr "Fechar"
+
+msgid "Global shortcuts"
+msgstr "Atalhos Globais"
+
+msgid "Tab shortcuts"
+msgstr "Atalhos para abas"
+
+msgid "Unable to reach the server."
+msgstr "Não foi possível se conectar ao servidor."
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr "Entrar"
+
+msgid "User name"
+msgstr "Usuário"
+
+msgid "Database"
+msgstr "Banco de dados"
+
+msgid "Your selection:"
+msgstr "Sua seleção:"
+
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Y"
+msgstr "A"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "s"
+
+msgid "d"
+msgstr "d"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "Por: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "a"
+
+msgid "Yes"
+msgstr "Sim"
+
+msgid "True"
+msgstr "Verdadeiro"
+
+msgid "t"
+msgstr "v"
+
+msgid "False"
+msgstr "Falso"
+
+msgid "Message: "
+msgstr "Mensagem: "
+
+msgid "Warning: "
+msgstr "Alerta: "
+
+msgid "Always ignore this warning."
+msgstr "Sempre ignorar este alerta."
+
+msgid "Do you want to proceed?"
+msgstr "Você deseja continuar?"
+
+msgid "No"
+msgstr "Não"
+
+msgid "Confirmation: "
+msgstr "Confirmação: "
+
+msgid "Concurrency Exception"
+msgstr "Exceção de concorrência"
+
+msgid "Write Concurrency Warning: "
+msgstr "Alerta de edição concorrente: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "Este registro foi modificado enquanto você o editava."
+
+msgid "Choose:"
+msgstr "Escolha:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"Cancelar\" para cancelar a gravação;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"Comparar\" para ver a versão modificada;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"Forçar Escrita\" para gravar sua versão atual."
+
+msgid "Compare"
+msgstr "\"Escrever mesmo assim\" para gravar sua versão atual."
+
+#, fuzzy
+msgid "Compare: %1"
+msgstr "\"Escrever mesmo assim\" para gravar sua versão atual."
+
+msgid "Write Anyway"
+msgstr "Forçar Escrita"
+
+msgid "Application Error"
+msgstr "Erro no Sistema"
+
+msgid "Report Bug"
+msgstr "Relatar erro"
+
+#, fuzzy
+msgid "Processing"
+msgstr "Processando..."
+
+msgid "Search..."
+msgstr "Buscar..."
+
+msgid "Create..."
+msgstr "Criar..."
+
+msgid "Download"
+msgstr "Baixar"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Fonte"
+
+msgid "Size"
+msgstr "Tamanho"
+
+msgid "Switch view"
+msgstr "Alternar a visão"
+
+msgid "Previous Record"
+msgstr "Registro anterior"
+
+msgid "Next Record"
+msgstr "Próximo registro"
+
+msgid "Create a new record"
+msgstr "Criar um novo registro"
+
+msgid "Save this record"
+msgstr "Gravar este registro"
+
+msgid "Reload"
+msgstr "Recarregar"
+
+msgid "View Logs..."
+msgstr "Ver logs..."
+
+msgid "Show revisions..."
+msgstr "Mostrar revisões..."
+
+msgid "Add an attachment to the record"
+msgstr "Adicionar um anexo ao registro"
+
+msgid "Add a note to the record"
+msgstr "Adicionar uma nota ao registro"
+
+msgid "E-Mail..."
+msgstr ""
+
+#, fuzzy
+msgid "Send an e-mail using the record"
+msgstr "Adicionar uma nota ao registro"
+
+msgid "Export"
+msgstr "Exportar"
+
+msgid "Import"
+msgstr "Importar"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"A seguinte ação requer que todas as abas sejam fechadas.\n"
+"Você deseja continuar?"
+
+msgid "Launch action"
+msgstr "Iniciar ação"
+
+msgid "Open related records"
+msgstr "Abrir registos relacionados"
+
+msgid "Print report"
+msgstr "Imprimir relatório"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Este registo foi modificado\n"
+"você deseja gravá-lo?"
+
+msgid "Record saved."
+msgstr "Registo gravado."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Trabalhando agora no(s) registo(s) duplicado(s)"
+
+msgid "Are you sure to remove this record?"
+msgstr "Você tem certeza que deseja apagar este registro?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Você tem certeza que deseja apagar estes registros?"
+
+msgid "Records removed."
+msgstr "Registos apagados."
+
+msgid "Records not removed."
+msgstr "Registros não apagados."
+
+msgid "You have to select one record."
+msgstr "Você precisa selecionar um registo."
+
+msgid "ID:"
+msgstr "ID:"
+
+#, fuzzy
+msgid "Created by:"
+msgstr "Criar..."
+
+#, fuzzy
+msgid "Created at:"
+msgstr "Data de criação"
+
+#, fuzzy
+msgid "Edited by:"
+msgstr "Criar..."
+
+#, fuzzy
+msgid "Edited at:"
+msgstr "Data de modificação"
+
+msgid "Model: "
+msgstr "Modelo: "
+
+msgid "Add..."
+msgstr "Adicionar..."
+
+#, fuzzy
+msgid "Preview"
+msgstr "Anterior"
+
+#, fuzzy
+msgid "Template"
+msgstr "Relacionar"
+
+#, fuzzy
+msgid "Attachment (%1)"
+msgstr "Anexo (%1)"
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr " de "
+
+msgid "Filters"
+msgstr "Filtros"
+
+msgid "Clear Search"
+msgstr "Limpar Busca"
+
+msgid "Bookmarks"
+msgstr "Favoritos"
+
+msgid "Remove this bookmark"
+msgstr "Remover este favorito"
+
+msgid "Bookmark this filter"
+msgstr "Adicionar este filtro aos favoritos"
+
+msgid "Bookmark Name:"
+msgstr "Nome do favorito:"
+
+msgid "Show active records"
+msgstr "Mostrar registros ativos"
+
+msgid "Show inactive records"
+msgstr "Mostrar registros inativos"
+
+msgid "Find"
+msgstr "Localizar"
+
+msgid "From"
+msgstr "De"
+
+msgid "To"
+msgstr "Para"
+
+msgid "Open the calendar"
+msgstr "Abrir o calendário"
+
+msgid "ID"
+msgstr "ID"
+
+#, fuzzy
+msgid "Created by"
+msgstr "Criar..."
+
+#, fuzzy
+msgid "Created at"
+msgstr "Data de criação"
+
+msgid "Modified by"
+msgstr ""
+
+#, fuzzy
+msgid "Modified at"
+msgstr "Data de modificação"
+
+#, fuzzy
+msgid "\"%1\" is required."
+msgstr "\"%1\" é obrigatório"
+
+#, fuzzy
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" não é válido de acordo com seu domínio"
+
+#, fuzzy
+msgid "The values of \"%1\" are not valid."
+msgstr "Os valores para \"%1\" não são válidos"
+
+msgid "Pre-validation"
+msgstr "Pré-validação"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Traduzir"
+
+msgid "Edit"
+msgstr "Editar"
+
+msgid "Fuzzy"
+msgstr "Vago"
+
+msgid "You need to save the record before adding translations."
+msgstr "Você precisa gravar o registro antes de adicionar traduções."
+
+msgid "No other language available."
+msgstr "Não há outro idioma disponível."
+
+msgid "Show"
+msgstr "Mostrar"
+
+msgid "Hide"
+msgstr "Ocultar"
+
+#, fuzzy
+msgid "Open the record"
+msgstr "Abrir o registro "
+
+msgid "Clear the field"
+msgstr ""
+
+#, fuzzy
+msgid "Search a record"
+msgstr "Buscar um registro "
+
+msgid "Add"
+msgstr "Adicionar"
+
+msgid "Remove"
+msgstr "Remover"
+
+msgid "Open"
+msgstr "Abrir"
+
+msgid "Undelete"
+msgstr "Recuperar"
+
+msgid "Save As"
+msgstr "Salvar como"
+
+msgid "Save As..."
+msgstr "Salvar como..."
+
+msgid "Select"
+msgstr "Selecionar"
+
+msgid "Select..."
+msgstr "Selecionar..."
+
+msgid "Clear"
+msgstr "Limpar"
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "Mais"
+
+msgid "Today"
+msgstr "Hoje"
+
+msgid "Month"
+msgstr "Mês"
+
+msgid "Week"
+msgstr "Semana"
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Selecione sua ação"
+
+msgid "No action defined."
+msgstr "Nenhuma ação definida."
+
+msgid "Attachments (%1)"
+msgstr "Anexo (%1)"
+
+msgid "Notes (%1)"
+msgstr "Notas (%1)"
+
+msgid "Search %1"
+msgstr "Buscar %1"
+
+msgid "Revision"
+msgstr "Revisão"
+
+msgid "All Fields"
+msgstr "Todos os Campos"
+
+msgid "Fields Selected"
+msgstr "Campos Selecionados"
+
+msgid "CSV Parameters"
+msgstr "Parâmetros CSV"
+
+msgid "Delimiter:"
+msgstr "Separador:"
+
+msgid "Quote Char:"
+msgstr "Caractere de Citação:"
+
+msgid "CSV Import: %1"
+msgstr "Importar CSV: %1"
+
+msgid "Auto-Detect"
+msgstr "Auto-Detectar"
+
+msgid "File to Import"
+msgstr "Arquivo a importar"
+
+msgid "Encoding:"
+msgstr "Codificação:"
+
+msgid "Lines to Skip:"
+msgstr "Linhas a Ignorar:"
+
+#, fuzzy
+msgid "You must select an import file first."
+msgstr "Primeiro você deve selecionar um arquivo para importar."
+
+#, fuzzy
+msgid "An error occured in loading the file."
+msgstr "Ocorreu um erro ao carregar o arquivo"
+
+msgid "Error processing the file at field %1."
+msgstr "Erro ao processar o arquivo no campo %1."
+
+msgid "Error"
+msgstr "Erro"
+
+msgid "Error occured in loading the file"
+msgstr "Ocorreu um erro ao carregar o arquivo"
+
+msgid "CSV Export: %1"
+msgstr "Exportar CSV: %1"
+
+msgid "Save Export"
+msgstr "Gravar Exportação"
+
+#, fuzzy
+msgid "URL Export"
+msgstr "Exportar"
+
+msgid "Delete Export"
+msgstr "Apagar Exportação"
+
+msgid "Predefined Exports"
+msgstr "Exportações Pre-definidas"
+
+#, fuzzy
+msgid "Selected Records"
+msgstr "Próximo registro"
+
+#, fuzzy
+msgid "Listed Records"
+msgstr "Próximo registro"
+
+#, fuzzy
+msgid "Export:"
+msgstr "Exportar"
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr "Adicionar Campos"
+
+msgid "%1 (string)"
+msgstr "%1 (texto)"
+
+msgid "%1 (model name)"
+msgstr "%1 (nome do modelo)"
+
+msgid "%1 (record name)"
+msgstr "%1 (nome do modelo)"
+
+msgid "What is the name of this export?"
+msgstr "Qual é o nome desta Exportação?"
+
+msgid "Override %1 definition?"
+msgstr "Sobrescrever definição %1?"
+
+msgid "E-mail %1"
+msgstr ""
+
+#, fuzzy
+msgid "To:"
+msgstr "Para"
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+#, fuzzy
+msgid "Reports"
+msgstr "Relatar erro"
+
+#, fuzzy
+msgid "Attachments"
+msgstr "Anexo"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+#, fuzzy
+msgid "Remove File"
+msgstr "Remover"
+
+msgid "Wizard"
+msgstr "Assistente"
+
+msgid "Translate view"
+msgstr "Traduzir tela"
diff --git a/sao/locale/ro.po b/sao/locale/ro.po
new file mode 100644
index 0000000000..aada5833e5
--- /dev/null
+++ b/sao/locale/ro.po
@@ -0,0 +1,668 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+# Generated by grunt-xgettext on Sun Mar 01 2020 02:18:27 GMT+0100 (Central
+# European Standard Time)
+msgid "Are your sure to leave?"
+msgstr "Sigur iesiti?"
+
+msgid "Favorites"
+msgstr "Favorite"
+
+msgid "Manage..."
+msgstr "Gestionare..."
+
+msgid "Logout"
+msgstr "Deconectare"
+
+msgid "Action"
+msgstr "Acțiune"
+
+msgid "New"
+msgstr "Nou"
+
+msgid "Save"
+msgstr "Salvare"
+
+msgid "Switch"
+msgstr "Schimba"
+
+msgid "Reload/Undo"
+msgstr "Reincarcare/Desfacere"
+
+msgid "Duplicate"
+msgstr "Duplicat"
+
+msgid "Delete"
+msgstr "Ștergere"
+
+msgid "Previous"
+msgstr "Anterior"
+
+msgid "Next"
+msgstr "Următor"
+
+msgid "Search"
+msgstr "Căutare"
+
+msgid "Close Tab"
+msgstr "Închidere fila"
+
+msgid "Attachment"
+msgstr "Atașament"
+
+msgid "Note"
+msgstr "Nota"
+
+msgid "Relate"
+msgstr "Relata"
+
+msgid "Print"
+msgstr "Tiparire"
+
+msgid "E-Mail"
+msgstr "E-Mail"
+
+msgid "Previous tab"
+msgstr "Fila anterioară"
+
+msgid "Next tab"
+msgstr "Fila următoare"
+
+msgid "Global search"
+msgstr "Căutare globală"
+
+msgid "Show this help"
+msgstr "Arătați acest ajutor"
+
+msgid "Keyboard shortcuts"
+msgstr "Comenzi rapide"
+
+msgid "Close"
+msgstr "Închidere"
+
+msgid "Global shortcuts"
+msgstr "Comenzile rapide globale"
+
+msgid "Tab shortcuts"
+msgstr "Comenzile rapide pentru file"
+
+msgid "Unable to reach the server."
+msgstr "Serverul nu se poate accessa."
+
+msgid "Too many requests. Try again later."
+msgstr "Prea multe cereri. Încercați mai târziu."
+
+msgid "Login"
+msgstr "Autentificare"
+
+msgid "User name"
+msgstr "Utilizator"
+
+msgid "Database"
+msgstr "Bază de date"
+
+msgid "Your selection:"
+msgstr "Selecția dvs.:"
+
+msgid "Cancel"
+msgstr "Anulare"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Y"
+msgstr "Y"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "w"
+
+msgid "d"
+msgstr "d"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "De: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "y"
+
+msgid "Yes"
+msgstr "Da"
+
+msgid "True"
+msgstr "Adevărat"
+
+msgid "t"
+msgstr "t"
+
+msgid "False"
+msgstr "Fals"
+
+msgid "Message: "
+msgstr "Mesaj: "
+
+msgid "Warning: "
+msgstr "Avertizare: "
+
+msgid "Always ignore this warning."
+msgstr "Ignorați întotdeauna acest avertisment."
+
+msgid "Do you want to proceed?"
+msgstr "Doriți să continuați?"
+
+msgid "No"
+msgstr "Nu"
+
+msgid "Confirmation: "
+msgstr "Confirmare: "
+
+msgid "Concurrency Exception"
+msgstr "Excepție de concurgență"
+
+msgid "Write Concurrency Warning: "
+msgstr "Avertizare de scriere simultană: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "Această înregistrare a fost modificată în timp ce o editați."
+
+msgid "Choose:"
+msgstr "Alegere:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "„Anulare” pentru a anula salvarea;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"Comparație\" pentru a vedea versiunea modificată;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"Scrie Oricum\" pentru a salva versiunea curentă."
+
+msgid "Compare"
+msgstr "Comparaţie"
+
+msgid "Compare: %1"
+msgstr "Comparație:% 1"
+
+msgid "Write Anyway"
+msgstr "Scrie oricum"
+
+msgid "Application Error"
+msgstr "Eroare de aplicație"
+
+msgid "Report Bug"
+msgstr "Raporteati eroare"
+
+msgid "Processing"
+msgstr "Se prelucreaza"
+
+msgid "Search..."
+msgstr "Căutare..."
+
+msgid "Create..."
+msgstr "Creare..."
+
+msgid "Download"
+msgstr "Descarca"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Font"
+
+msgid "Size"
+msgstr "Mărime"
+
+msgid "Switch view"
+msgstr "Comutare vedere"
+
+msgid "Previous Record"
+msgstr "Înregistrare anterioară"
+
+msgid "Next Record"
+msgstr "Următoarea înregistrare"
+
+msgid "Create a new record"
+msgstr "Creați o înregistrare nouă"
+
+msgid "Save this record"
+msgstr "Salvare înregistrare"
+
+msgid "Reload"
+msgstr "Reîncare"
+
+msgid "View Logs..."
+msgstr "Vizualizare jurnalele ..."
+
+msgid "Show revisions..."
+msgstr "Afișați revizii..."
+
+msgid "Add an attachment to the record"
+msgstr "Adăugați un atașament la înregistrare"
+
+msgid "Add a note to the record"
+msgstr "Adăugați o notă la înregistrare"
+
+msgid "E-Mail..."
+msgstr "E-Mail..."
+
+msgid "Send an e-mail using the record"
+msgstr "Trimiteți un e-mail folosind înregistrarea"
+
+msgid "Export"
+msgstr "Export"
+
+msgid "Import"
+msgstr "Import"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"Următoarea acțiune necesită închiderea tuturor filelor.\n"
+"Doriți să continuați?"
+
+msgid "Launch action"
+msgstr "Lansare acțiune"
+
+msgid "Open related records"
+msgstr "Deschidere înregistrări conexe"
+
+msgid "Print report"
+msgstr "Tipărire raport"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Această înregistrare a fost modificată\n"
+"vrei sa o salvezi?"
+
+msgid "Record saved."
+msgstr "Înregistrare salvată."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Lucrează acum la înregistrările duplicate."
+
+msgid "Are you sure to remove this record?"
+msgstr "Sigur eliminați această înregistrare?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Sigur eliminați această înregistrare?"
+
+msgid "Records removed."
+msgstr "Înregistrările au fost eliminate."
+
+msgid "Records not removed."
+msgstr "Înregistrările nu au fost eliminate."
+
+msgid "You have to select one record."
+msgstr "Trebuie selectaa o singura înregistrare."
+
+msgid "ID:"
+msgstr "ID:"
+
+msgid "Created by:"
+msgstr "Creat de:"
+
+msgid "Created at:"
+msgstr "Creat la:"
+
+msgid "Edited by:"
+msgstr "Editat de:"
+
+msgid "Edited at:"
+msgstr "Editat la:"
+
+msgid "Model: "
+msgstr "Model: "
+
+msgid "Add..."
+msgstr "Adăuga..."
+
+msgid "Preview"
+msgstr "Previzualizare"
+
+msgid "Template"
+msgstr "Șablon"
+
+msgid "Attachment (%1)"
+msgstr "Atachment (%1)"
+
+msgid "Note (%1/%2)"
+msgstr "Notă (%1/%2)"
+
+msgid " of "
+msgstr " de "
+
+msgid "Filters"
+msgstr "Filtre"
+
+msgid "Clear Search"
+msgstr "Ștergeți Căutarea"
+
+msgid "Bookmarks"
+msgstr "Marcaje"
+
+msgid "Remove this bookmark"
+msgstr "Eliminare marcaj"
+
+msgid "Bookmark this filter"
+msgstr "Marcare filtru"
+
+msgid "Bookmark Name:"
+msgstr "Denumire marcaj:"
+
+msgid "Show active records"
+msgstr "Afișează înregistrări active"
+
+msgid "Show inactive records"
+msgstr "Afișează înregistrări active"
+
+msgid "Find"
+msgstr "Căutare"
+
+msgid "From"
+msgstr "De la"
+
+msgid "To"
+msgstr "La"
+
+msgid "Open the calendar"
+msgstr "Deschidere calendar"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Created by"
+msgstr "Creat de"
+
+msgid "Created at"
+msgstr "Creat la"
+
+msgid "Modified by"
+msgstr "Modificat de"
+
+msgid "Modified at"
+msgstr "Modificat la"
+
+msgid "\"%1\" is required."
+msgstr "\"%1\" este necesar."
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr "\"%1\" nu este valabil dupa domeniul sau."
+
+msgid "The values of \"%1\" are not valid."
+msgstr "Valorile lui \"%s\" nu sunt valide."
+
+msgid "Pre-validation"
+msgstr "Pre-validare"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Traducere"
+
+msgid "Edit"
+msgstr "Editare"
+
+msgid "Fuzzy"
+msgstr "Cautare aproximativa"
+
+msgid "You need to save the record before adding translations."
+msgstr "Trebuie să salvați înregistrarea înainte de a adăuga traduceri."
+
+msgid "No other language available."
+msgstr "Nu există altă limbă disponibilă."
+
+msgid "Show"
+msgstr "Afișare"
+
+msgid "Hide"
+msgstr "Ascunde"
+
+msgid "Open the record"
+msgstr "Deschidere inregistrare"
+
+msgid "Clear the field"
+msgstr "Golire câmp"
+
+msgid "Search a record"
+msgstr "Cautare in inregistrare"
+
+msgid "Add"
+msgstr "Adăuga"
+
+msgid "Remove"
+msgstr "Eliminare"
+
+msgid "Open"
+msgstr "Deschidere"
+
+msgid "Undelete"
+msgstr "Anulați ștergerea"
+
+msgid "Save As"
+msgstr "Salvează ca"
+
+msgid "Save As..."
+msgstr "Salvare că..."
+
+msgid "Select"
+msgstr "Selectați"
+
+msgid "Select..."
+msgstr "Selectare..."
+
+msgid "Clear"
+msgstr "Golire"
+
+msgid "Choose a language"
+msgstr "Alegere limbă"
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "Mai multe"
+
+msgid "Today"
+msgstr "Astăzi"
+
+msgid "Month"
+msgstr "Lună"
+
+msgid "Week"
+msgstr "Săptămână"
+
+msgid "Day"
+msgstr "Zi"
+
+msgid ",..."
+msgstr ",..."
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Selectați acțiunea"
+
+msgid "No action defined."
+msgstr "Nicio acțiune definită."
+
+msgid "Attachments (%1)"
+msgstr "Atașamente (%1)"
+
+msgid "Notes (%1)"
+msgstr "Note (%1)"
+
+msgid "Search %1"
+msgstr "Căutare %1"
+
+msgid "Revision"
+msgstr "Revizuire"
+
+msgid "All Fields"
+msgstr "Toate câmpurile"
+
+msgid "Fields Selected"
+msgstr "Câmpuri selectate"
+
+msgid "CSV Parameters"
+msgstr "Parametri CSV"
+
+msgid "Delimiter:"
+msgstr "Delimitator:"
+
+msgid "Quote Char:"
+msgstr "Caracter de cotatie:"
+
+msgid "CSV Import: %1"
+msgstr "Import CSV: %1"
+
+msgid "Auto-Detect"
+msgstr "Auto-detectare"
+
+msgid "File to Import"
+msgstr "Fișier de importat"
+
+msgid "Encoding:"
+msgstr "Codifiere:"
+
+msgid "Lines to Skip:"
+msgstr "Rânduri de sarit:"
+
+msgid "You must select an import file first."
+msgstr "Mai întâi trebuie să selectați un fișier de import."
+
+msgid "An error occured in loading the file."
+msgstr "A apărut o eroare la încărcarea fișierului."
+
+msgid "Error processing the file at field %1."
+msgstr "Eroare la procesarea fișierului la câmpul %1."
+
+msgid "Error"
+msgstr "Eroare"
+
+msgid "Error occured in loading the file"
+msgstr "A apărut o eroare la încărcarea fișierului"
+
+msgid "CSV Export: %1"
+msgstr "Export CSV: %1"
+
+msgid "Save Export"
+msgstr "Salvare Export"
+
+msgid "URL Export"
+msgstr "Export URL"
+
+msgid "Delete Export"
+msgstr "Ștergere Export"
+
+msgid "Predefined Exports"
+msgstr "Exporturi predefinite"
+
+msgid "Selected Records"
+msgstr "Înregistrări selectate"
+
+msgid "Listed Records"
+msgstr "Înregistrări enumerate"
+
+msgid "Export:"
+msgstr "Export:"
+
+msgid "Ignore search limit"
+msgstr "Ignorați limita de căutare"
+
+msgid "Use locale format"
+msgstr "Utilizați formatul local"
+
+msgid "Add Field Names"
+msgstr "Adăugare denumire de câmp"
+
+msgid "%1 (string)"
+msgstr "%1 (șir)"
+
+msgid "%1 (model name)"
+msgstr "%1 (denumire model)"
+
+msgid "%1 (record name)"
+msgstr "%1 (denmire inregistrare)"
+
+msgid "What is the name of this export?"
+msgstr "Care este numele acestui export?"
+
+#, fuzzy
+msgid "Override %1 definition?"
+msgstr "Trece peste definiția %1?"
+
+msgid "E-mail %1"
+msgstr "E-mail %1"
+
+msgid "To:"
+msgstr "Destinatar:"
+
+msgid "Cc:"
+msgstr "CC:"
+
+msgid "Bcc:"
+msgstr "Bcc:"
+
+msgid "Subject:"
+msgstr "Subiect:"
+
+msgid "Reports"
+msgstr "Raport"
+
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2020-11-16 13:23+0000\n"
+"PO-Revision-Date: 2020-11-23 09:53+0000\n"
+"Last-Translator: Dimitrios Moustos \n"
+"Language-Team: LANGUAGE \n"
+"Language: ro\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;\n"
+"X-Generator: Weblate 4.3.2\n"
+
+msgid "Attachments"
+msgstr "Atașamente"
+
+msgid "Files"
+msgstr "Fişiere"
+
+msgid "Send"
+msgstr "Trimite"
+
+msgid "Remove File"
+msgstr "Eliminare Fişier"
+
+msgid "Wizard"
+msgstr "Asistent"
+
+msgid "Translate view"
+msgstr "Traducere vedere"
diff --git a/sao/locale/ru.po b/sao/locale/ru.po
new file mode 100644
index 0000000000..c80c418437
--- /dev/null
+++ b/sao/locale/ru.po
@@ -0,0 +1,656 @@
+#
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr ""
+
+msgid "Manage..."
+msgstr ""
+
+msgid "Logout"
+msgstr ""
+
+msgid "Action"
+msgstr ""
+
+msgid "New"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Switch"
+msgstr ""
+
+msgid "Reload/Undo"
+msgstr ""
+
+msgid "Duplicate"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
+msgid "Search"
+msgstr ""
+
+msgid "Close Tab"
+msgstr ""
+
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
+msgid "Relate"
+msgstr ""
+
+msgid "Print"
+msgstr ""
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr ""
+
+msgid "Next tab"
+msgstr ""
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr ""
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr ""
+
+msgid "User name"
+msgstr ""
+
+msgid "Database"
+msgstr ""
+
+msgid "Your selection:"
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Y"
+msgstr ""
+
+msgid "M"
+msgstr ""
+
+msgid "w"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "h"
+msgstr ""
+
+msgid "m"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "By: "
+msgstr ""
+
+#, fuzzy
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "True"
+msgstr ""
+
+msgid "t"
+msgstr ""
+
+msgid "False"
+msgstr ""
+
+msgid "Message: "
+msgstr ""
+
+msgid "Warning: "
+msgstr ""
+
+msgid "Always ignore this warning."
+msgstr ""
+
+msgid "Do you want to proceed?"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Confirmation: "
+msgstr ""
+
+msgid "Concurrency Exception"
+msgstr ""
+
+msgid "Write Concurrency Warning: "
+msgstr ""
+
+msgid "This record has been modified while you were editing it."
+msgstr ""
+
+msgid "Choose:"
+msgstr ""
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr ""
+
+msgid "\"Compare\" to see the modified version;"
+msgstr ""
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Compare: %1"
+msgstr ""
+
+msgid "Write Anyway"
+msgstr ""
+
+msgid "Application Error"
+msgstr ""
+
+msgid "Report Bug"
+msgstr ""
+
+msgid "Processing"
+msgstr ""
+
+msgid "Search..."
+msgstr ""
+
+msgid "Create..."
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+#, fuzzy
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Switch view"
+msgstr ""
+
+msgid "Previous Record"
+msgstr ""
+
+msgid "Next Record"
+msgstr ""
+
+msgid "Create a new record"
+msgstr ""
+
+msgid "Save this record"
+msgstr ""
+
+msgid "Reload"
+msgstr ""
+
+msgid "View Logs..."
+msgstr ""
+
+msgid "Show revisions..."
+msgstr ""
+
+msgid "Add an attachment to the record"
+msgstr ""
+
+msgid "Add a note to the record"
+msgstr ""
+
+msgid "E-Mail..."
+msgstr ""
+
+msgid "Send an e-mail using the record"
+msgstr ""
+
+msgid "Export"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+
+msgid "Launch action"
+msgstr ""
+
+msgid "Open related records"
+msgstr ""
+
+msgid "Print report"
+msgstr ""
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+
+msgid "Record saved."
+msgstr ""
+
+msgid "Working now on the duplicated record(s)."
+msgstr ""
+
+msgid "Are you sure to remove this record?"
+msgstr ""
+
+msgid "Are you sure to remove those records?"
+msgstr ""
+
+msgid "Records removed."
+msgstr ""
+
+msgid "Records not removed."
+msgstr ""
+
+msgid "You have to select one record."
+msgstr ""
+
+msgid "ID:"
+msgstr ""
+
+msgid "Created by:"
+msgstr ""
+
+msgid "Created at:"
+msgstr ""
+
+msgid "Edited by:"
+msgstr ""
+
+msgid "Edited at:"
+msgstr ""
+
+msgid "Model: "
+msgstr ""
+
+msgid "Add..."
+msgstr ""
+
+msgid "Preview"
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Attachment (%1)"
+msgstr ""
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr " из "
+
+msgid "Filters"
+msgstr ""
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr ""
+
+msgid "Remove this bookmark"
+msgstr ""
+
+msgid "Bookmark this filter"
+msgstr ""
+
+msgid "Bookmark Name:"
+msgstr ""
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr ""
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "Created by"
+msgstr ""
+
+msgid "Created at"
+msgstr ""
+
+msgid "Modified by"
+msgstr ""
+
+msgid "Modified at"
+msgstr ""
+
+msgid "\"%1\" is required."
+msgstr ""
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr ""
+
+msgid "The values of \"%1\" are not valid."
+msgstr ""
+
+msgid "Pre-validation"
+msgstr ""
+
+msgid ":"
+msgstr ""
+
+msgid "Translate"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Fuzzy"
+msgstr ""
+
+msgid "You need to save the record before adding translations."
+msgstr ""
+
+msgid "No other language available."
+msgstr ""
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Open"
+msgstr ""
+
+msgid "Undelete"
+msgstr ""
+
+msgid "Save As"
+msgstr ""
+
+msgid "Save As..."
+msgstr ""
+
+msgid "Select"
+msgstr ""
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr ""
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr ""
+
+#, fuzzy
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr ""
+
+msgid "Today"
+msgstr ""
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr ""
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr ""
+
+msgid "Select your action"
+msgstr ""
+
+msgid "No action defined."
+msgstr ""
+
+msgid "Attachments (%1)"
+msgstr ""
+
+msgid "Notes (%1)"
+msgstr ""
+
+msgid "Search %1"
+msgstr ""
+
+msgid "Revision"
+msgstr ""
+
+msgid "All Fields"
+msgstr ""
+
+msgid "Fields Selected"
+msgstr ""
+
+msgid "CSV Parameters"
+msgstr ""
+
+msgid "Delimiter:"
+msgstr ""
+
+msgid "Quote Char:"
+msgstr ""
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr ""
+
+msgid "File to Import"
+msgstr ""
+
+msgid "Encoding:"
+msgstr ""
+
+msgid "Lines to Skip:"
+msgstr ""
+
+msgid "You must select an import file first."
+msgstr ""
+
+msgid "An error occured in loading the file."
+msgstr ""
+
+msgid "Error processing the file at field %1."
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Error occured in loading the file"
+msgstr ""
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr ""
+
+msgid "URL Export"
+msgstr ""
+
+msgid "Delete Export"
+msgstr ""
+
+msgid "Predefined Exports"
+msgstr ""
+
+msgid "Selected Records"
+msgstr ""
+
+msgid "Listed Records"
+msgstr ""
+
+msgid "Export:"
+msgstr ""
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr ""
+
+msgid "%1 (string)"
+msgstr ""
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr ""
+
+msgid "Override %1 definition?"
+msgstr ""
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+msgid "Reports"
+msgstr ""
+
+msgid ""
+msgstr ""
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2019-05-01 15:33+0000\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+
+msgid "Attachments"
+msgstr ""
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+msgid "Remove File"
+msgstr ""
+
+msgid "Wizard"
+msgstr ""
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/sl.po b/sao/locale/sl.po
new file mode 100644
index 0000000000..4145a2e89e
--- /dev/null
+++ b/sao/locale/sl.po
@@ -0,0 +1,677 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr "Zaznamki"
+
+msgid "Manage..."
+msgstr ""
+
+# Generated by grunt-xgettext on Thu Mar 31 2016 17:50:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Oct 16 2015 17:37:32 GMT+0200 (CEST)
+msgid "Logout"
+msgstr "Odjava"
+
+msgid "Action"
+msgstr "Ukrep"
+
+msgid "New"
+msgstr "Novo"
+
+msgid "Save"
+msgstr "Shrani"
+
+msgid "Switch"
+msgstr "Preklopi"
+
+msgid "Reload/Undo"
+msgstr "Ponovno naloži"
+
+msgid "Duplicate"
+msgstr "Podvoji"
+
+msgid "Delete"
+msgstr "Zbriši"
+
+msgid "Previous"
+msgstr "Prejšnji"
+
+msgid "Next"
+msgstr "Naslednji"
+
+msgid "Search"
+msgstr "Išči"
+
+msgid "Close Tab"
+msgstr "Zapri zavihek"
+
+msgid "Attachment"
+msgstr "Priponka"
+
+msgid "Note"
+msgstr "Zabeležka"
+
+msgid "Relate"
+msgstr "Veza"
+
+msgid "Print"
+msgstr "Tisk"
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr ""
+
+msgid "Next tab"
+msgstr ""
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr "Zapri"
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr "Ni se mogoče povezati s strežnikom."
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr "Prijava"
+
+msgid "User name"
+msgstr "Uporabniško ime"
+
+msgid "Database"
+msgstr "Podatkovna baza"
+
+msgid "Your selection:"
+msgstr "Vaša izbira:"
+
+msgid "Cancel"
+msgstr "Prekliči"
+
+msgid "OK"
+msgstr "V redu"
+
+msgid "Y"
+msgstr "l"
+
+msgid "M"
+msgstr "M"
+
+msgid "w"
+msgstr "t"
+
+msgid "d"
+msgstr "d"
+
+msgid "h"
+msgstr "h"
+
+msgid "m"
+msgstr "m"
+
+msgid "s"
+msgstr "s"
+
+msgid "By: "
+msgstr "Od: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "d"
+
+msgid "Yes"
+msgstr "Da"
+
+msgid "True"
+msgstr "Da"
+
+msgid "t"
+msgstr "d"
+
+msgid "False"
+msgstr "Ne"
+
+msgid "Message: "
+msgstr "Sporočilo: "
+
+msgid "Warning: "
+msgstr "Opozorilo: "
+
+msgid "Always ignore this warning."
+msgstr "Vedno prezri to opozorilo."
+
+msgid "Do you want to proceed?"
+msgstr "Ali želiš nadaljevati?"
+
+msgid "No"
+msgstr "Ne"
+
+msgid "Confirmation: "
+msgstr "Potrditev: "
+
+msgid "Concurrency Exception"
+msgstr "Napaka sočasnega izvajanja"
+
+msgid "Write Concurrency Warning: "
+msgstr "Opozorilo sočasnega zapisovanja: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "Ta zapis je bil spremenjen v času vašega popravljanja."
+
+msgid "Choose:"
+msgstr "Izberi:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"Prekliči\" - prekliči spremembe;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"Primerjaj\" - primerjaj z drugo različico;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"Vseeno shrani\" - shrani trenutno različico."
+
+msgid "Compare"
+msgstr "Primerjaj"
+
+#, fuzzy
+msgid "Compare: %1"
+msgstr "Primerjaj"
+
+msgid "Write Anyway"
+msgstr "Vseeno shrani"
+
+msgid "Application Error"
+msgstr "Programska napaka"
+
+msgid "Report Bug"
+msgstr "Prijavi programsko napako"
+
+#, fuzzy
+msgid "Processing"
+msgstr "Obdelava ..."
+
+msgid "Search..."
+msgstr "Išči ..."
+
+msgid "Create..."
+msgstr "Izdelaj ..."
+
+msgid "Download"
+msgstr "Prenesi"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "Pisava"
+
+msgid "Size"
+msgstr "Velikost"
+
+msgid "Switch view"
+msgstr "Preklopi pogled"
+
+msgid "Previous Record"
+msgstr "Prejšnji zapis"
+
+msgid "Next Record"
+msgstr "Naslednji zapis"
+
+msgid "Create a new record"
+msgstr "Ustvari nov zapis"
+
+msgid "Save this record"
+msgstr "Shrani ta zapis"
+
+msgid "Reload"
+msgstr "Ponovno naloži"
+
+msgid "View Logs..."
+msgstr "Prikaži dnevnik ..."
+
+msgid "Show revisions..."
+msgstr "Prikaži revizije ..."
+
+msgid "Add an attachment to the record"
+msgstr "Dodaj priponko zapisu"
+
+msgid "Add a note to the record"
+msgstr "Dodaj zapisu zabeležko"
+
+msgid "E-Mail..."
+msgstr ""
+
+#, fuzzy
+msgid "Send an e-mail using the record"
+msgstr "Dodaj zapisu zabeležko"
+
+msgid "Export"
+msgstr "Izvoz"
+
+msgid "Import"
+msgstr "Uvoz"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"Za slednji ukrep se bodo zaprli vsi zavihki.\n"
+"Ali želiš nadaljevati?"
+
+msgid "Launch action"
+msgstr "Zaženi ukrep"
+
+msgid "Open related records"
+msgstr "Odpri povezane zapise"
+
+msgid "Print report"
+msgstr "Izpis poročila"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"Ta zapis je bil spremenjen,\n"
+"ga želiš shraniti?"
+
+msgid "Record saved."
+msgstr "Zapis shranjen."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "Trenutno se dela na podvojenem zapisu."
+
+msgid "Are you sure to remove this record?"
+msgstr "Ali res želiš zbrisati ta zapis?"
+
+msgid "Are you sure to remove those records?"
+msgstr "Ali res želiš zbrisati te zapise?"
+
+msgid "Records removed."
+msgstr "Zapisi zbrisani."
+
+msgid "Records not removed."
+msgstr "Zapisi niso bili zbrisani."
+
+msgid "You have to select one record."
+msgstr "En zapis mora biti izbran."
+
+msgid "ID:"
+msgstr "ID:"
+
+#, fuzzy
+msgid "Created by:"
+msgstr "Izdelaj ..."
+
+#, fuzzy
+msgid "Created at:"
+msgstr "Ustvarjeno"
+
+#, fuzzy
+msgid "Edited by:"
+msgstr "Izdelaj ..."
+
+#, fuzzy
+msgid "Edited at:"
+msgstr "Popravljeno"
+
+msgid "Model: "
+msgstr "Model: "
+
+msgid "Add..."
+msgstr ""
+
+#, fuzzy
+msgid "Preview"
+msgstr "Prejšnji"
+
+#, fuzzy
+msgid "Template"
+msgstr "Veza"
+
+#, fuzzy
+msgid "Attachment (%1)"
+msgstr "Priponke (%1)"
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr ""
+
+msgid "Filters"
+msgstr "Filtri"
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr "Zaznamki"
+
+msgid "Remove this bookmark"
+msgstr "Zbriši ta zaznamek"
+
+msgid "Bookmark this filter"
+msgstr "Shrani ta filter"
+
+msgid "Bookmark Name:"
+msgstr "Ime zaznamka:"
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr "Najdi"
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr ""
+
+msgid "ID"
+msgstr "ID"
+
+#, fuzzy
+msgid "Created by"
+msgstr "Izdelaj ..."
+
+#, fuzzy
+msgid "Created at"
+msgstr "Ustvarjeno"
+
+msgid "Modified by"
+msgstr ""
+
+#, fuzzy
+msgid "Modified at"
+msgstr "Popravljeno"
+
+#, fuzzy
+msgid "\"%1\" is required."
+msgstr "Polje \"%1\" je obvezno"
+
+#, fuzzy
+msgid "\"%1\" is not valid according to its domain."
+msgstr "Polje \"%1\" ni veljavno glede na svojo domeno"
+
+#, fuzzy
+msgid "The values of \"%1\" are not valid."
+msgstr "Vrednosti polja \"%1\" niso veljavne"
+
+msgid "Pre-validation"
+msgstr "Predpreverjanje"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "Prevod"
+
+msgid "Edit"
+msgstr "Uredi"
+
+msgid "Fuzzy"
+msgstr "Nejasno"
+
+msgid "You need to save the record before adding translations."
+msgstr "Pred prevajanjem mora biti zapis shranjen."
+
+msgid "No other language available."
+msgstr "Drugega jezika ni na voljo."
+
+msgid "Show"
+msgstr "Pokaži"
+
+msgid "Hide"
+msgstr "Skrij"
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr "Dodaj"
+
+msgid "Remove"
+msgstr "Odstrani"
+
+msgid "Open"
+msgstr "Odpri"
+
+msgid "Undelete"
+msgstr "Povrni"
+
+msgid "Save As"
+msgstr ""
+
+msgid "Save As..."
+msgstr ""
+
+msgid "Select"
+msgstr "Izberi"
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr "Počisti"
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "Več"
+
+msgid "Today"
+msgstr ""
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr ""
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "Izberi ukrep"
+
+msgid "No action defined."
+msgstr "Nobenega ukrepa še ni določenega."
+
+msgid "Attachments (%1)"
+msgstr "Priponke (%1)"
+
+msgid "Notes (%1)"
+msgstr "Zabeležke (%1)"
+
+msgid "Search %1"
+msgstr "Išči %1"
+
+msgid "Revision"
+msgstr "Različica"
+
+msgid "All Fields"
+msgstr "Vsa polja"
+
+msgid "Fields Selected"
+msgstr "Izbrana polja"
+
+msgid "CSV Parameters"
+msgstr "CSV parametri"
+
+msgid "Delimiter:"
+msgstr "Ločilo:"
+
+msgid "Quote Char:"
+msgstr "Narekovaj:"
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr "Samozaznava"
+
+msgid "File to Import"
+msgstr "Datoteka za uvoz"
+
+msgid "Encoding:"
+msgstr "Kodiranje:"
+
+msgid "Lines to Skip:"
+msgstr "Izpuščene vrstice:"
+
+#, fuzzy
+msgid "You must select an import file first."
+msgstr "Najprej je potrebno izbrati datoteko za uvoz"
+
+#, fuzzy
+msgid "An error occured in loading the file."
+msgstr "Pri nalaganju datoteke je prišlo do napake"
+
+msgid "Error processing the file at field %1."
+msgstr "Napaka pri obdelavi datoteke pri polju %1."
+
+msgid "Error"
+msgstr "Napaka"
+
+msgid "Error occured in loading the file"
+msgstr "Pri nalaganju datoteke je prišlo do napake"
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr "Shrani izvoz"
+
+#, fuzzy
+msgid "URL Export"
+msgstr "Izvoz"
+
+msgid "Delete Export"
+msgstr "Zbriši izvoz"
+
+msgid "Predefined Exports"
+msgstr "Prednastavljeni izvozi"
+
+#, fuzzy
+msgid "Selected Records"
+msgstr "Naslednji zapis"
+
+#, fuzzy
+msgid "Listed Records"
+msgstr "Naslednji zapis"
+
+#, fuzzy
+msgid "Export:"
+msgstr "Izvoz"
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr "Dodaj imena polj"
+
+msgid "%1 (string)"
+msgstr "%1 (niz)"
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr "%1 (ime zapisa)"
+
+msgid "What is the name of this export?"
+msgstr "Ime izvoza?"
+
+msgid "Override %1 definition?"
+msgstr "Prepis definicije %1?"
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+#, fuzzy
+msgid "Reports"
+msgstr "Prijavi programsko napako"
+
+#, fuzzy
+msgid "Attachments"
+msgstr "Priponka"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+#, fuzzy
+msgid "Remove File"
+msgstr "Odstrani"
+
+msgid "Wizard"
+msgstr "Čarovnik"
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/tr.po b/sao/locale/tr.po
new file mode 100644
index 0000000000..15ae48e353
--- /dev/null
+++ b/sao/locale/tr.po
@@ -0,0 +1,646 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr ""
+
+msgid "Favorites"
+msgstr ""
+
+msgid "Manage..."
+msgstr ""
+
+msgid "Logout"
+msgstr ""
+
+msgid "Action"
+msgstr ""
+
+msgid "New"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Switch"
+msgstr ""
+
+msgid "Reload/Undo"
+msgstr ""
+
+msgid "Duplicate"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "Previous"
+msgstr ""
+
+msgid "Next"
+msgstr ""
+
+msgid "Search"
+msgstr ""
+
+msgid "Close Tab"
+msgstr ""
+
+msgid "Attachment"
+msgstr ""
+
+msgid "Note"
+msgstr ""
+
+msgid "Relate"
+msgstr ""
+
+msgid "Print"
+msgstr ""
+
+msgid "E-Mail"
+msgstr ""
+
+msgid "Previous tab"
+msgstr ""
+
+msgid "Next tab"
+msgstr ""
+
+msgid "Global search"
+msgstr ""
+
+msgid "Show this help"
+msgstr ""
+
+msgid "Keyboard shortcuts"
+msgstr ""
+
+msgid "Close"
+msgstr ""
+
+msgid "Global shortcuts"
+msgstr ""
+
+msgid "Tab shortcuts"
+msgstr ""
+
+msgid "Unable to reach the server."
+msgstr ""
+
+msgid "Too many requests. Try again later."
+msgstr ""
+
+msgid "Login"
+msgstr ""
+
+msgid "User name"
+msgstr ""
+
+msgid "Database"
+msgstr ""
+
+msgid "Your selection:"
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Y"
+msgstr ""
+
+msgid "M"
+msgstr ""
+
+msgid "w"
+msgstr ""
+
+msgid "d"
+msgstr ""
+
+msgid "h"
+msgstr ""
+
+msgid "m"
+msgstr ""
+
+msgid "s"
+msgstr ""
+
+msgid "By: "
+msgstr ""
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "True"
+msgstr ""
+
+msgid "t"
+msgstr ""
+
+msgid "False"
+msgstr ""
+
+msgid "Message: "
+msgstr ""
+
+msgid "Warning: "
+msgstr ""
+
+msgid "Always ignore this warning."
+msgstr ""
+
+msgid "Do you want to proceed?"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Confirmation: "
+msgstr ""
+
+msgid "Concurrency Exception"
+msgstr ""
+
+msgid "Write Concurrency Warning: "
+msgstr ""
+
+msgid "This record has been modified while you were editing it."
+msgstr ""
+
+msgid "Choose:"
+msgstr ""
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr ""
+
+msgid "\"Compare\" to see the modified version;"
+msgstr ""
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr ""
+
+msgid "Compare"
+msgstr ""
+
+msgid "Compare: %1"
+msgstr ""
+
+msgid "Write Anyway"
+msgstr ""
+
+msgid "Application Error"
+msgstr ""
+
+msgid "Report Bug"
+msgstr ""
+
+msgid "Processing"
+msgstr ""
+
+msgid "Search..."
+msgstr ""
+
+msgid "Create..."
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr ""
+
+msgid "Size"
+msgstr ""
+
+msgid "Switch view"
+msgstr ""
+
+msgid "Previous Record"
+msgstr ""
+
+msgid "Next Record"
+msgstr ""
+
+msgid "Create a new record"
+msgstr ""
+
+msgid "Save this record"
+msgstr ""
+
+msgid "Reload"
+msgstr ""
+
+msgid "View Logs..."
+msgstr ""
+
+msgid "Show revisions..."
+msgstr ""
+
+msgid "Add an attachment to the record"
+msgstr ""
+
+msgid "Add a note to the record"
+msgstr ""
+
+msgid "E-Mail..."
+msgstr ""
+
+msgid "Send an e-mail using the record"
+msgstr ""
+
+msgid "Export"
+msgstr ""
+
+msgid "Import"
+msgstr ""
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+
+msgid "Launch action"
+msgstr ""
+
+msgid "Open related records"
+msgstr ""
+
+msgid "Print report"
+msgstr ""
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+
+msgid "Record saved."
+msgstr ""
+
+msgid "Working now on the duplicated record(s)."
+msgstr ""
+
+msgid "Are you sure to remove this record?"
+msgstr ""
+
+msgid "Are you sure to remove those records?"
+msgstr ""
+
+msgid "Records removed."
+msgstr ""
+
+msgid "Records not removed."
+msgstr ""
+
+msgid "You have to select one record."
+msgstr ""
+
+msgid "ID:"
+msgstr ""
+
+msgid "Created by:"
+msgstr ""
+
+msgid "Created at:"
+msgstr ""
+
+msgid "Edited by:"
+msgstr ""
+
+msgid "Edited at:"
+msgstr ""
+
+msgid "Model: "
+msgstr ""
+
+msgid "Add..."
+msgstr ""
+
+msgid "Preview"
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Attachment (%1)"
+msgstr ""
+
+msgid "Note (%1/%2)"
+msgstr ""
+
+msgid " of "
+msgstr ""
+
+msgid "Filters"
+msgstr ""
+
+msgid "Clear Search"
+msgstr ""
+
+msgid "Bookmarks"
+msgstr ""
+
+msgid "Remove this bookmark"
+msgstr ""
+
+msgid "Bookmark this filter"
+msgstr ""
+
+msgid "Bookmark Name:"
+msgstr ""
+
+msgid "Show active records"
+msgstr ""
+
+msgid "Show inactive records"
+msgstr ""
+
+msgid "Find"
+msgstr ""
+
+msgid "From"
+msgstr ""
+
+msgid "To"
+msgstr ""
+
+msgid "Open the calendar"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "Created by"
+msgstr ""
+
+msgid "Created at"
+msgstr ""
+
+msgid "Modified by"
+msgstr ""
+
+msgid "Modified at"
+msgstr ""
+
+msgid "\"%1\" is required."
+msgstr ""
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr ""
+
+msgid "The values of \"%1\" are not valid."
+msgstr ""
+
+msgid "Pre-validation"
+msgstr ""
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Fuzzy"
+msgstr ""
+
+msgid "You need to save the record before adding translations."
+msgstr ""
+
+msgid "No other language available."
+msgstr ""
+
+msgid "Show"
+msgstr ""
+
+msgid "Hide"
+msgstr ""
+
+msgid "Open the record"
+msgstr ""
+
+msgid "Clear the field"
+msgstr ""
+
+msgid "Search a record"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Open"
+msgstr ""
+
+msgid "Undelete"
+msgstr ""
+
+msgid "Save As"
+msgstr ""
+
+msgid "Save As..."
+msgstr ""
+
+msgid "Select"
+msgstr ""
+
+msgid "Select..."
+msgstr ""
+
+msgid "Clear"
+msgstr ""
+
+msgid "Choose a language"
+msgstr ""
+
+msgid "%1%"
+msgstr ""
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr ""
+
+msgid "Today"
+msgstr ""
+
+msgid "Month"
+msgstr ""
+
+msgid "Week"
+msgstr ""
+
+msgid "Day"
+msgstr ""
+
+msgid ",..."
+msgstr ""
+
+msgid "%1 (%2)"
+msgstr ""
+
+msgid "Select your action"
+msgstr ""
+
+msgid "No action defined."
+msgstr ""
+
+msgid "Attachments (%1)"
+msgstr ""
+
+msgid "Notes (%1)"
+msgstr ""
+
+msgid "Search %1"
+msgstr ""
+
+msgid "Revision"
+msgstr ""
+
+msgid "All Fields"
+msgstr ""
+
+msgid "Fields Selected"
+msgstr ""
+
+msgid "CSV Parameters"
+msgstr ""
+
+msgid "Delimiter:"
+msgstr ""
+
+msgid "Quote Char:"
+msgstr ""
+
+msgid "CSV Import: %1"
+msgstr ""
+
+msgid "Auto-Detect"
+msgstr ""
+
+msgid "File to Import"
+msgstr ""
+
+msgid "Encoding:"
+msgstr ""
+
+msgid "Lines to Skip:"
+msgstr ""
+
+msgid "You must select an import file first."
+msgstr ""
+
+msgid "An error occured in loading the file."
+msgstr ""
+
+msgid "Error processing the file at field %1."
+msgstr ""
+
+msgid "Error"
+msgstr ""
+
+msgid "Error occured in loading the file"
+msgstr ""
+
+msgid "CSV Export: %1"
+msgstr ""
+
+msgid "Save Export"
+msgstr ""
+
+msgid "URL Export"
+msgstr ""
+
+msgid "Delete Export"
+msgstr ""
+
+msgid "Predefined Exports"
+msgstr ""
+
+msgid "Selected Records"
+msgstr ""
+
+msgid "Listed Records"
+msgstr ""
+
+msgid "Export:"
+msgstr ""
+
+msgid "Ignore search limit"
+msgstr ""
+
+msgid "Use locale format"
+msgstr ""
+
+msgid "Add Field Names"
+msgstr ""
+
+msgid "%1 (string)"
+msgstr ""
+
+msgid "%1 (model name)"
+msgstr ""
+
+msgid "%1 (record name)"
+msgstr ""
+
+msgid "What is the name of this export?"
+msgstr ""
+
+msgid "Override %1 definition?"
+msgstr ""
+
+msgid "E-mail %1"
+msgstr ""
+
+msgid "To:"
+msgstr ""
+
+msgid "Cc:"
+msgstr ""
+
+msgid "Bcc:"
+msgstr ""
+
+msgid "Subject:"
+msgstr ""
+
+msgid "Reports"
+msgstr ""
+
+msgid "Attachments"
+msgstr ""
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr ""
+
+msgid "Remove File"
+msgstr ""
+
+msgid "Wizard"
+msgstr ""
+
+msgid "Translate view"
+msgstr ""
diff --git a/sao/locale/zh_CN.po b/sao/locale/zh_CN.po
new file mode 100644
index 0000000000..4bc8ce293b
--- /dev/null
+++ b/sao/locale/zh_CN.po
@@ -0,0 +1,654 @@
+# Generated by grunt-xgettext on Wed May 01 2019 00:09:20 GMT+0200 (CEST)
+msgid ""
+msgstr "Content-Type: text/plain; charset=utf-8\n"
+
+msgid "Are your sure to leave?"
+msgstr "您确定要离开吗?"
+
+msgid "Favorites"
+msgstr "收藏(_V)"
+
+msgid "Manage..."
+msgstr "管理..."
+
+# Generated by grunt-xgettext on Thu Mar 31 2016 17:50:31 GMT+0200 (CEST)
+# Generated by grunt-xgettext on Fri Oct 16 2015 17:37:32 GMT+0200 (CEST)
+msgid "Logout"
+msgstr "注销"
+
+msgid "Action"
+msgstr "操作"
+
+msgid "New"
+msgstr "新建"
+
+msgid "Save"
+msgstr "保存"
+
+msgid "Switch"
+msgstr "切换"
+
+msgid "Reload/Undo"
+msgstr "刷新/撤销"
+
+msgid "Duplicate"
+msgstr "复制"
+
+msgid "Delete"
+msgstr "删除"
+
+msgid "Previous"
+msgstr "向前"
+
+msgid "Next"
+msgstr "向后"
+
+msgid "Search"
+msgstr "查找"
+
+msgid "Close Tab"
+msgstr "关闭标签"
+
+msgid "Attachment"
+msgstr "附件"
+
+msgid "Note"
+msgstr "备注"
+
+msgid "Relate"
+msgstr "关联"
+
+msgid "Print"
+msgstr "打印"
+
+msgid "E-Mail"
+msgstr "电子邮件"
+
+msgid "Previous tab"
+msgstr "上一标签(_P)"
+
+msgid "Next tab"
+msgstr "下一标签(_N)"
+
+msgid "Global search"
+msgstr "全局查找"
+
+msgid "Show this help"
+msgstr "显示此帮助"
+
+msgid "Keyboard shortcuts"
+msgstr "键盘快捷键"
+
+msgid "Close"
+msgstr "关闭"
+
+msgid "Global shortcuts"
+msgstr "全局快捷方式"
+
+msgid "Tab shortcuts"
+msgstr "标签快捷方式"
+
+msgid "Unable to reach the server."
+msgstr "无法连接服务器."
+
+msgid "Too many requests. Try again later."
+msgstr "请求太多,请稍后重试."
+
+msgid "Login"
+msgstr "登录"
+
+msgid "User name"
+msgstr "用户名"
+
+msgid "Database"
+msgstr "数据库"
+
+msgid "Your selection:"
+msgstr "已选择:"
+
+msgid "Cancel"
+msgstr "取消"
+
+msgid "OK"
+msgstr "确定"
+
+msgid "Y"
+msgstr "年"
+
+msgid "M"
+msgstr "月"
+
+msgid "w"
+msgstr "星期"
+
+msgid "d"
+msgstr "日"
+
+msgid "h"
+msgstr "时"
+
+msgid "m"
+msgstr "分"
+
+msgid "s"
+msgstr "秒"
+
+msgid "By: "
+msgstr "By: "
+
+msgid ", "
+msgstr ", "
+
+msgid "y"
+msgstr "y"
+
+msgid "Yes"
+msgstr "是"
+
+msgid "True"
+msgstr "True"
+
+msgid "t"
+msgstr "t"
+
+msgid "False"
+msgstr "False"
+
+msgid "Message: "
+msgstr "信息: "
+
+msgid "Warning: "
+msgstr "警告: "
+
+msgid "Always ignore this warning."
+msgstr "下次不再提示."
+
+msgid "Do you want to proceed?"
+msgstr "继续此项操作 ?"
+
+msgid "No"
+msgstr "否"
+
+msgid "Confirmation: "
+msgstr "确认: "
+
+msgid "Concurrency Exception"
+msgstr "并行操作异常"
+
+msgid "Write Concurrency Warning: "
+msgstr "同步操作警告: "
+
+msgid "This record has been modified while you were editing it."
+msgstr "在你编辑的时候,这条记录已经被更改."
+
+msgid "Choose:"
+msgstr "选择:"
+
+msgid "\"Cancel\" to cancel saving;"
+msgstr "\"取消\" 不保存;"
+
+msgid "\"Compare\" to see the modified version;"
+msgstr "\"对比\" 查看变更的数据;"
+
+msgid "\"Write Anyway\" to save your current version."
+msgstr "\"覆写\" 保存当前数据."
+
+msgid "Compare"
+msgstr "比较"
+
+msgid "Compare: %1"
+msgstr "比较: %1"
+
+msgid "Write Anyway"
+msgstr "覆写"
+
+msgid "Application Error"
+msgstr "程序错误"
+
+msgid "Report Bug"
+msgstr "报告Bug"
+
+msgid "Processing"
+msgstr "正在处理"
+
+msgid "Search..."
+msgstr "查找..."
+
+msgid "Create..."
+msgstr "新建..."
+
+msgid "Download"
+msgstr "下载"
+
+msgid "..."
+msgstr "..."
+
+msgid "Font"
+msgstr "字体"
+
+msgid "Size"
+msgstr "大小"
+
+msgid "Switch view"
+msgstr "切换视图"
+
+msgid "Previous Record"
+msgstr "前一条记录"
+
+msgid "Next Record"
+msgstr "后一条记录"
+
+msgid "Create a new record"
+msgstr "新建记录"
+
+msgid "Save this record"
+msgstr "保存当前记录"
+
+msgid "Reload"
+msgstr "重载"
+
+msgid "View Logs..."
+msgstr "查看日志..."
+
+msgid "Show revisions..."
+msgstr "显示修订版本..."
+
+msgid "Add an attachment to the record"
+msgstr "为当前记录添加附件"
+
+msgid "Add a note to the record"
+msgstr "为当前记录添加注释"
+
+msgid "E-Mail..."
+msgstr "用电子邮件发送..."
+
+msgid "Send an e-mail using the record"
+msgstr "使用当前记录发送电子邮件"
+
+msgid "Export"
+msgstr "导出"
+
+msgid "Import"
+msgstr "导入"
+
+msgid ""
+"The following action requires to close all tabs.\n"
+"Do you want to continue?"
+msgstr ""
+"该操作需要关闭所有标签.\n"
+"是否继续?"
+
+msgid "Launch action"
+msgstr "执行操作"
+
+msgid "Open related records"
+msgstr "打开关联记录"
+
+msgid "Print report"
+msgstr "打印报告"
+
+msgid ""
+"This record has been modified\n"
+"do you want to save it?"
+msgstr ""
+"记录有改动\n"
+"是否保存?"
+
+msgid "Record saved."
+msgstr "记录保存成功."
+
+msgid "Working now on the duplicated record(s)."
+msgstr "正在处理重复记录."
+
+msgid "Are you sure to remove this record?"
+msgstr "确定要删除这条记录吗?"
+
+msgid "Are you sure to remove those records?"
+msgstr "确定要删除这些记录?"
+
+msgid "Records removed."
+msgstr "记录已成功删除."
+
+msgid "Records not removed."
+msgstr "所选记录未删除成功."
+
+msgid "You have to select one record."
+msgstr "需要选择一条记录."
+
+msgid "ID:"
+msgstr "标识:"
+
+msgid "Created by:"
+msgstr "创建者:"
+
+msgid "Created at:"
+msgstr "创建日期:"
+
+msgid "Edited by:"
+msgstr "编辑者:"
+
+msgid "Edited at:"
+msgstr "编辑于:"
+
+msgid "Model: "
+msgstr "模型: "
+
+msgid "Add..."
+msgstr "添加..."
+
+#, fuzzy
+msgid "Preview"
+msgstr "向前"
+
+msgid "Template"
+msgstr "模板"
+
+msgid "Attachment (%1)"
+msgstr "附件(%1)"
+
+msgid "Note (%1/%2)"
+msgstr "备注 (%1/%2)"
+
+msgid " of "
+msgstr " of "
+
+msgid "Filters"
+msgstr "筛选"
+
+msgid "Clear Search"
+msgstr "清除搜索"
+
+msgid "Bookmarks"
+msgstr "书签"
+
+msgid "Remove this bookmark"
+msgstr "移除书签"
+
+msgid "Bookmark this filter"
+msgstr "收藏当前筛选器"
+
+msgid "Bookmark Name:"
+msgstr "书签名称:"
+
+msgid "Show active records"
+msgstr "显示已启用记录"
+
+msgid "Show inactive records"
+msgstr "显示未启用记录"
+
+msgid "Find"
+msgstr "查找"
+
+msgid "From"
+msgstr "从"
+
+msgid "To"
+msgstr "至"
+
+msgid "Open the calendar"
+msgstr "打开日历"
+
+msgid "ID"
+msgstr "标识"
+
+msgid "Created by"
+msgstr "创建者"
+
+msgid "Created at"
+msgstr "创建日期"
+
+msgid "Modified by"
+msgstr "修改者"
+
+msgid "Modified at"
+msgstr "修改于"
+
+msgid "\"%1\" is required."
+msgstr "\"%1\" 是必填项."
+
+msgid "\"%1\" is not valid according to its domain."
+msgstr "根据域设置,\"%1\" 不可用."
+
+msgid "The values of \"%1\" are not valid."
+msgstr "\"%1\" 的取值不可用."
+
+msgid "Pre-validation"
+msgstr "预校验"
+
+msgid ":"
+msgstr ":"
+
+msgid "Translate"
+msgstr "翻译"
+
+msgid "Edit"
+msgstr "编辑"
+
+msgid "Fuzzy"
+msgstr "模糊"
+
+msgid "You need to save the record before adding translations."
+msgstr "请先保存已翻译条目,然后再增加新翻译 ."
+
+msgid "No other language available."
+msgstr "没有其他可翻译语言."
+
+msgid "Show"
+msgstr "显示"
+
+msgid "Hide"
+msgstr "隐藏"
+
+msgid "Open the record"
+msgstr "打开记录"
+
+msgid "Clear the field"
+msgstr "清除字段 "
+
+msgid "Search a record"
+msgstr "搜索记录"
+
+msgid "Add"
+msgstr "添加"
+
+msgid "Remove"
+msgstr "删除"
+
+msgid "Open"
+msgstr "打开"
+
+msgid "Undelete"
+msgstr "回滚"
+
+msgid "Save As"
+msgstr "另存为"
+
+msgid "Save As..."
+msgstr "另存为..."
+
+msgid "Select"
+msgstr "选择"
+
+msgid "Select..."
+msgstr "选择..."
+
+msgid "Clear"
+msgstr "清除"
+
+msgid "Choose a language"
+msgstr "选择一种语言"
+
+msgid "%1%"
+msgstr "%1%"
+
+msgid ": "
+msgstr ": "
+
+msgid "More"
+msgstr "更多"
+
+msgid "Today"
+msgstr "今天"
+
+msgid "Month"
+msgstr "月"
+
+msgid "Week"
+msgstr "周"
+
+msgid "Day"
+msgstr "天"
+
+msgid ",..."
+msgstr ",..."
+
+msgid "%1 (%2)"
+msgstr "%1 (%2)"
+
+msgid "Select your action"
+msgstr "选择一项操作"
+
+msgid "No action defined."
+msgstr "没有定义任何操作 ."
+
+msgid "Attachments (%1)"
+msgstr "附件(%1)"
+
+msgid "Notes (%1)"
+msgstr "注释(%s)"
+
+msgid "Search %1"
+msgstr "搜索 %1"
+
+msgid "Revision"
+msgstr "修订版本"
+
+msgid "All Fields"
+msgstr "所有字段"
+
+msgid "Fields Selected"
+msgstr "所选字段"
+
+msgid "CSV Parameters"
+msgstr "CSV 参数"
+
+msgid "Delimiter:"
+msgstr "分隔符:"
+
+msgid "Quote Char:"
+msgstr "限定符:"
+
+msgid "CSV Import: %1"
+msgstr "CSV导入: %s"
+
+msgid "Auto-Detect"
+msgstr "自动侦测"
+
+msgid "File to Import"
+msgstr "导入文件"
+
+msgid "Encoding:"
+msgstr "编码:"
+
+msgid "Lines to Skip:"
+msgstr "跳过行:"
+
+msgid "You must select an import file first."
+msgstr "必须先选择要导入的文件."
+
+msgid "An error occured in loading the file."
+msgstr "加载文件时发生错误。"
+
+msgid "Error processing the file at field %1."
+msgstr "处理字段 %s 对应的文件时出错."
+
+msgid "Error"
+msgstr "错误"
+
+msgid "Error occured in loading the file"
+msgstr "加载文件时发生错误"
+
+msgid "CSV Export: %1"
+msgstr "CSV导出:%s"
+
+msgid "Save Export"
+msgstr "保存导出"
+
+msgid "URL Export"
+msgstr "URL 导出"
+
+msgid "Delete Export"
+msgstr "删除导出"
+
+msgid "Predefined Exports"
+msgstr "预定义导出"
+
+msgid "Selected Records"
+msgstr "已选记录"
+
+msgid "Listed Records"
+msgstr "已列出记录"
+
+msgid "Export:"
+msgstr "导出:"
+
+msgid "Ignore search limit"
+msgstr "忽略搜索限制"
+
+msgid "Use locale format"
+msgstr "使用 locale 格式"
+
+msgid "Add Field Names"
+msgstr "添加字段名称"
+
+msgid "%1 (string)"
+msgstr "%1 (字符串)"
+
+msgid "%1 (model name)"
+msgstr "%1 (模型名称)"
+
+msgid "%1 (record name)"
+msgstr "%1 (记录名称)"
+
+msgid "What is the name of this export?"
+msgstr "导出设置的名称是?"
+
+msgid "Override %1 definition?"
+msgstr "覆盖 %1 的定义?"
+
+msgid "E-mail %1"
+msgstr "电子邮件 %1"
+
+msgid "To:"
+msgstr "收件人:"
+
+msgid "Cc:"
+msgstr "抄送:"
+
+msgid "Bcc:"
+msgstr "私下抄送:"
+
+msgid "Subject:"
+msgstr "主题:"
+
+msgid "Reports"
+msgstr "报告(_R)"
+
+msgid "Attachments"
+msgstr "附件"
+
+msgid "Files"
+msgstr ""
+
+msgid "Send"
+msgstr "发送"
+
+#, fuzzy
+msgid "Remove File"
+msgstr "删除"
+
+msgid "Wizard"
+msgstr "向导"
+
+msgid "Translate view"
+msgstr "翻译视图"
diff --git a/sao/package.json b/sao/package.json
new file mode 100644
index 0000000000..5985e82c5c
--- /dev/null
+++ b/sao/package.json
@@ -0,0 +1,58 @@
+{
+ "name": "tryton-sao",
+ "title": "sao",
+ "description": "Tryton webclient",
+ "version": "6.0.25",
+ "homepage": "http://www.tryton.org/",
+ "author": {
+ "name": "Tryton"
+ },
+ "repository": {
+ "type": "hg",
+ "url": "http://hg.tryton.org/sao"
+ },
+ "bugs": {
+ "url": "http://bugs.tryton.org/",
+ "email": "bugs@tryton.org"
+ },
+ "license": "GPL-3.0+",
+ "files": [
+ "COPYRIGHT",
+ "CHANGELOG",
+ "Gruntfile.js",
+ "LICENSE",
+ "README.md",
+ "bower.json",
+ "dist",
+ "images",
+ "index.html",
+ "locale",
+ "package.json",
+ "src",
+ "tests"
+ ],
+ "scripts": {
+ "test": "npx grunt test",
+ "postinstall": "npx bower install"
+ },
+ "devDependencies": {
+ "grunt-contrib-nodeunit": "^2.0",
+ "grunt-contrib-qunit": "^3.1",
+ "grunt-contrib-watch": "^1.1",
+ "grunt-shell": "^3.0",
+ "grunt-xgettext": "^0.3",
+ "grunt-po2json": "^0.3"
+ },
+ "keywords": [
+ "tryton"
+ ],
+ "dependencies": {
+ "bower": "^1.8.4",
+ "grunt": "^1.0",
+ "grunt-cli": "^1.3",
+ "grunt-contrib-concat": "^1.0",
+ "grunt-contrib-jshint": "^2.1",
+ "grunt-contrib-less": "^2.0",
+ "grunt-contrib-uglify": "^4.0"
+ }
+}
diff --git a/sao/src/.jshintrc b/sao/src/.jshintrc
new file mode 100644
index 0000000000..5956712c68
--- /dev/null
+++ b/sao/src/.jshintrc
@@ -0,0 +1,5 @@
+{
+ "browser": true,
+ "devel": true,
+ "jquery": true
+}
diff --git a/sao/src/action.js b/sao/src/action.js
new file mode 100644
index 0000000000..1268e7b049
--- /dev/null
+++ b/sao/src/action.js
@@ -0,0 +1,240 @@
+/* This file is part of Tryton. The COPYRIGHT file at the top level of
+ this repository contains the full copyright notices and license terms. */
+(function() {
+ 'use strict';
+
+ Sao.Action = {
+ report_blob_url: undefined
+ };
+
+ Sao.Action.exec_action = function(action, data, context) {
+ if (!context) {
+ context = {};
+ } else {
+ context = jQuery.extend({}, context);
+ }
+ var session = Sao.Session.current_session;
+ if (data === undefined) {
+ data = {};
+ } else {
+ data = jQuery.extend({}, data);
+ }
+
+ delete context.active_id;
+ delete context.active_ids;
+ delete context.active_model;
+
+ function add_name_suffix(name, context){
+ if (!data.model || !data.ids) {
+ return jQuery.when(name);
+ }
+ var max_records = 5;
+ var ids = data.ids.filter(function(id){
+ return id >= 0;
+ }).slice(0, max_records);
+ if (!ids.length) {
+ return jQuery.when(name);
+ }
+ return Sao.rpc({
+ 'method': 'model.' + data.model + '.read',
+ 'params': [ids, ['rec_name'], context]
+ }, Sao.Session.current_session).then(function(result) {
+ var name_suffix = result.map(function(record){
+ return record.rec_name;
+ }).join(Sao.i18n.gettext(', '));
+
+ if (data.ids.length > ids.length) {
+ name_suffix += Sao.i18n.gettext(',...');
+ }
+ return Sao.i18n.gettext('%1 (%2)', name, name_suffix);
+ });
+ }
+ data.action_id = action.id;
+ var params = {};
+ var name_prm;
+ switch (action.type) {
+ case 'ir.action.act_window':
+ params.view_ids = [];
+ params.mode = null;
+ if (!jQuery.isEmptyObject(action.views)) {
+ params.view_ids = [];
+ params.mode = [];
+ action.views.forEach(function(x) {
+ params.view_ids.push(x[0]);
+ params.mode.push(x[1]);
+ });
+ } else if (!jQuery.isEmptyObject(action.view_id)) {
+ params.view_ids = [action.view_id[0]];
+ }
+
+ if (action.pyson_domain === undefined) {
+ action.pyson_domain = '[]';
+ }
+ var ctx = {
+ active_model: data.model || null,
+ active_id: data.id || null,
+ active_ids: data.ids || [],
+ };
+ ctx = jQuery.extend(ctx, session.context);
+ ctx._user = session.user_id;
+ var decoder = new Sao.PYSON.Decoder(ctx);
+ params.context = jQuery.extend(
+ {}, context,
+ decoder.decode( action.pyson_context || '{}'));
+ ctx = jQuery.extend(ctx, params.context);
+
+ ctx.context = ctx;
+ decoder = new Sao.PYSON.Decoder(ctx);
+ params.domain = decoder.decode(action.pyson_domain);
+ params.order = decoder.decode(action.pyson_order);
+ params.search_value = decoder.decode(
+ action.pyson_search_value || '[]');
+ params.tab_domain = [];
+ action.domains.forEach(function(element, index) {
+ params.tab_domain.push(
+ [element[0], decoder.decode(element[1]), element[2]]);
+ });
+ name_prm = jQuery.when(action.name);
+ params.model = action.res_model || data.res_model;
+ params.res_id = action.res_id || data.res_id;
+ params.context_model = action.context_model;
+ params.context_domain = action.context_domain;
+ if (action.limit !== null) {
+ params.limit = action.limit;
+ } else {
+ params.limit = Sao.config.limit;
+ }
+ params.icon = action['icon.rec_name'] || '';
+
+ if (action.keyword) {
+ name_prm = add_name_suffix(action.name, params.context);
+ }
+ name_prm.then(function(name) {
+ params.name = name;
+ Sao.Tab.create(params);
+ });
+ return;
+ case 'ir.action.wizard':
+ params.action = action.wiz_name;
+ params.data = data;
+ params.context = context;
+ params.window = action.window;
+ name_prm = jQuery.when(action.name);
+ if ((action.keyword || 'form_action') === 'form_action') {
+ name_prm = add_name_suffix(action.name, context);
+ }
+ name_prm.done(function(name) {
+ params.name = name;
+ Sao.Wizard.create(params);
+ });
+ return;
+ case 'ir.action.report':
+ params.name = action.report_name;
+ params.data = data;
+ params.direct_print = action.direct_print;
+ params.context = context;
+ Sao.Action.exec_report(params);
+ return;
+ case 'ir.action.url':
+ window.open(action.url, '_blank', 'noreferrer,noopener');
+ return;
+ }
+ };
+
+ Sao.Action.exec_keyword = function(keyword, data, context, warning,
+ alwaysask)
+ {
+ if (warning === undefined) {
+ warning = true;
+ }
+ if (alwaysask === undefined) {
+ alwaysask = false;
+ }
+ var actions = [];
+ var model_id = data.id;
+ var args = {
+ 'method': 'model.' + 'ir.action.keyword.get_keyword',
+ 'params': [keyword, [data.model, model_id], {}]
+ };
+ var prm = Sao.rpc(args, Sao.Session.current_session);
+ var exec_action = function(actions) {
+ var keyact = {};
+ for (var i in actions) {
+ var action = actions[i];
+ keyact[action.name.split(' / ').pop()] = action;
+ }
+ var prm = Sao.common.selection(
+ Sao.i18n.gettext('Select your action'),
+ keyact, alwaysask);
+ return prm.then(function(action) {
+ Sao.Action.exec_action(action, data, context);
+ }, function() {
+ if (jQuery.isEmptyObject(keyact) && warning) {
+ alert(Sao.i18n.gettext('No action defined.'));
+ }
+ });
+ };
+ return prm.pipe(exec_action);
+ };
+
+ Sao.Action.exec_report = function(attributes) {
+ if (!attributes.context) {
+ attributes.context = {};
+ }
+ var data = jQuery.extend({}, attributes.data);
+ var context = jQuery.extend({}, Sao.Session.current_session.context);
+ jQuery.extend(context, attributes.context);
+ context.direct_print = attributes.direct_print;
+
+ var prm = Sao.rpc({
+ 'method': 'report.' + attributes.name + '.execute',
+ 'params': [data.ids || [], data, context]
+ }, Sao.Session.current_session);
+ prm.done(function(result) {
+ var report_type = result[0];
+ var data = result[1];
+ var print = result[2];
+ var name = result[3];
+
+ // TODO direct print
+ var file_name = name + '.' + report_type;
+ Sao.common.download_file(data, file_name);
+ });
+ };
+
+ Sao.Action.execute = function(action, data, context, keyword) {
+ if (typeof action == 'number') {
+ action = Sao.rpc({
+ 'method': 'model.ir.action.get_action_value',
+ 'params': [action, context],
+ }, Sao.Session.current_session, false);
+ }
+ if (keyword) {
+ var keywords = {
+ 'ir.action.report': 'form_report',
+ 'ir.action.wizard': 'form_action',
+ 'ir.action.act_window': 'form_relate'
+ };
+ if (!action.keyword) {
+ action.keyword = keywords[action.type];
+ }
+ }
+ Sao.Action.exec_action(action, data, context);
+ };
+
+ Sao.Action.evaluate = function(action, atype, record) {
+ action = jQuery.extend({}, action);
+ var email = {};
+ if ('pyson_email' in action) {
+ email = record.expr_eval(action.pyson_email);
+ if (jQuery.isEmptyObject(email)) {
+ email = {};
+ }
+ }
+ if (!('subject' in email)) {
+ email.subject = action.name.replace(/_/g, '');
+ }
+ action.email = email;
+ return action;
+ };
+}());
diff --git a/sao/src/board.js b/sao/src/board.js
new file mode 100644
index 0000000000..02ee3414bb
--- /dev/null
+++ b/sao/src/board.js
@@ -0,0 +1,214 @@
+/* This file is part of Tryton. The COPYRIGHT file at the top level of
+ this repository contains the full copyright notices and license terms. */
+(function() {
+ 'use strict';
+
+ Sao.View.BoardXMLViewParser = Sao.class_(Sao.View.FormXMLViewParser, {
+ _parse_board: function(node, attributes) {
+ var container = new Sao.View.Form.Container(
+ Number(node.getAttribute('col') || 4));
+ this.view.el.append(container.el);
+ this.parse_child(node, container);
+ if (this._containers.length > 0) {
+ throw 'AssertionError';
+ }
+ },
+ _parse_action: function(node, attributes) {
+ var action;
+ if (attributes.yexpand === undefined) {
+ attributes.yexpand = true;
+ }
+ if (attributes.yfill === undefined) {
+ attributes.yfill = true;
+ }
+ action = new Sao.View.Board.Action(attributes, this.view.context);
+ this.view.actions.push(action);
+ this.container.add(action, attributes);
+ },
+ });
+
+ Sao.View.Board = Sao.class_(Object, {
+ xml_parser: Sao.View.BoardXMLViewParser,
+ init: function(xml, context) {
+ var attributes, attribute, node, actions_prms;
+
+ this.context = context;
+ this.actions = [];
+ this.containers = [];
+ this.state_widgets = [];
+ this.el = jQuery('', {
+ 'class': 'board'
+ });
+ new this.xml_parser(this, null, {}).parse(xml.children()[0]);
+
+ actions_prms = [];
+ for (var i = 0, len = this.actions.length; i < len; i++) {
+ actions_prms.push(this.actions[i].action_prm);
+ }
+ this.actions_prms = jQuery.when.apply(jQuery, actions_prms);
+ },
+ reload: function() {
+ var i;
+ for (i = 0; i < this.actions.length; i++) {
+ this.actions[i].display();
+ }
+ for (i = 0; i < this.state_widgets.length; i++) {
+ this.state_widgets[i].set_state(null);
+ }
+ }
+ });
+
+ Sao.View.Board.Action = Sao.class_(Object, {
+ init: function(attributes, context) {
+ if (context === undefined) {
+ context = {};
+ }
+
+ var session = Sao.Session.current_session;
+ this.name = attributes.name;
+
+ this.el = jQuery('', {
+ 'class': 'board-action panel panel-default',
+ });
+ this.title = jQuery('', {
+ 'class': 'panel-heading',
+ });
+ this.el.append(this.title);
+ this.body = jQuery('', {
+ 'class': 'panel-body',
+ });
+ this.el.append(this.body);
+
+ var act_window = new Sao.Model('ir.action.act_window');
+ this.action_prm = act_window.execute('get', [this.name], {});
+ this.action_prm.done(function(action) {
+ var params = {};
+ this.action = action;
+ params.view_ids = [];
+ params.mode = null;
+ if (!jQuery.isEmptyObject(action.views)) {
+ params.view_ids = [];
+ params.mode = [];
+ action.views.forEach(function(x) {
+ params.view_ids.push(x[0]);
+ params.mode.push(x[1]);
+ });
+ } else if (!jQuery.isEmptyObject(action.view_id)) {
+ params.view_ids = [action.view_id[0]];
+ }
+
+ if (!('pyson_domain' in this.action)) {
+ this.action.pyson_domain = '[]';
+ }
+ var ctx = {};
+ ctx = jQuery.extend(ctx, session.context);
+ ctx._user = session.user_id;
+ var decoder = new Sao.PYSON.Decoder(ctx);
+ params.context = jQuery.extend(
+ {}, context,
+ decoder.decode(action.pyson_context || '{}'));
+ ctx = jQuery.extend(ctx, params.context);
+
+ ctx.context = ctx;
+ decoder = new Sao.PYSON.Decoder(ctx);
+ params.domain = decoder.decode(action.pyson_domain);
+ params.order = decoder.decode(action.pyson_order);
+ params.search_value = decoder.decode(
+ action.pyson_search_value || '[]');
+ params.tab_domain = [];
+ action.domains.forEach(function(element, index) {
+ params.tab_domain.push(
+ [element[0], decoder.decode(element[1]), element[2]]);
+ });
+ params.context_model = action.context_model;
+ params.context_domain = action.context_domain;
+ if (action.limit !== null) {
+ params.limit = action.limit;
+ } else {
+ params.limit = Sao.config.limit;
+ }
+
+ this.context = ctx;
+ this.domain = [];
+ this.update_domain([]);
+
+ params.row_activate = this.row_activate.bind(this);
+
+ this.screen = new Sao.Screen(this.action.res_model,
+ params);
+
+ if (attributes.string) {
+ this.title.text(attributes.string);
+ } else {
+ this.title.text(this.action.name);
+ }
+ this.screen.switch_view().done(function() {
+ this.body.append(this.screen.screen_container.el);
+ this.screen.search_filter();
+ }.bind(this));
+ }.bind(this));
+ },
+ row_activate: function() {
+ var record_ids, win;
+
+ if (!this.screen.current_record) {
+ return;
+ }
+
+ if (this.screen.current_view.view_type == 'tree' &&
+ (this.screen.current_view.attributes.keyword_open == 1)) {
+ record_ids = this.screen.current_view.selected_records.map(
+ function(record) { return record.id; });
+ Sao.Action.exec_keyword('tree_open', {
+ model: this.screen.model_name,
+ id: this.screen.current_record.id,
+ ids: record_ids
+ }, jQuery.extend({}, this.screen.group._context), false);
+ } else {
+ win = new Sao.Window.Form(this.screen, function(result) {
+ if (result) {
+ this.screen.current_record.save();
+ } else {
+ this.screen.current_record.cancel();
+ }
+ }.bind(this), {
+ 'title': this.title.text(),
+ });
+ }
+ },
+ set_value: function() {
+ },
+ display: function() {
+ this.screen.search_filter(this.screen.screen_container.get_text());
+ },
+ get_active: function() {
+ if (this.screen && this.screen.current_record) {
+ return Sao.common.EvalEnvironment(this.screen.current_record);
+ }
+ },
+ update_domain: function(actions) {
+ var i, len;
+ var active, domain_ctx, decoder, new_domain;
+
+ domain_ctx = jQuery.extend({}, this.context);
+ domain_ctx.context = domain_ctx;
+ domain_ctx._user = Sao.Session.current_session.user_id;
+ for (i = 0, len = actions.length; i < len; i++) {
+ active = actions[i].get_active();
+ if (active) {
+ domain_ctx[actions[i].name] = active;
+ }
+ }
+ decoder = new Sao.PYSON.Decoder(domain_ctx);
+ new_domain = decoder.decode(this.action.pyson_domain);
+ if (Sao.common.compare(this.domain, new_domain)) {
+ return;
+ }
+ this.domain.splice(0, this.domain.length);
+ jQuery.extend(this.domain, new_domain);
+ if (this.screen) {
+ this.display();
+ }
+ }
+ });
+}());
diff --git a/sao/src/bus.js b/sao/src/bus.js
new file mode 100644
index 0000000000..20e31ce435
--- /dev/null
+++ b/sao/src/bus.js
@@ -0,0 +1,86 @@
+/* This file is part of Tryton. The COPYRIGHT file at the top level of
+ this repository contains the full copyright notices and license terms. */
+(function() {
+ 'use strict';
+
+ Sao.Bus = {};
+
+ // Bus Identifier
+ Sao.Bus.id = Sao.common.uuid4();
+ Sao.Bus.channels = ['client:' + Sao.Bus.id];
+
+ Sao.Bus.listen = function(last_message, wait) {
+ wait = wait || 1;
+ var session = Sao.Session.current_session;
+ if (!session) {
+ return;
+ }
+
+ var prm = jQuery.ajax({
+ headers: {
+ Authorization: 'Session ' + session.get_auth(),
+ },
+ contentType: 'application/json',
+ data: JSON.stringify({
+ last_message: last_message,
+ channels: Sao.Bus.channels
+ }),
+ dataType: 'json',
+ url: '/' + session.database + '/bus',
+ type: 'POST',
+ timeout: Sao.config.bus_timeout,
+ });
+
+ prm.done(function(response) {
+ if (Sao.Session.current_session != session) {
+ return;
+ }
+ if (response.message) {
+ last_message = response.message.message_id;
+ Sao.Bus.handle(response.message);
+ }
+ Sao.Bus.listen(last_message, 1);
+ });
+
+ prm.fail(function(response, status, error) {
+ if (Sao.Session.current_session != session) {
+ return;
+ }
+ if (error === "timeout") {
+ Sao.Bus.listen(last_message, 1);
+ } else if (response.status == 501) {
+ console.log("Bus not supported");
+ return;
+ } else {
+ window.setTimeout(
+ Sao.Bus.listen,
+ Math.min(wait * 1000, Sao.config.bus_timeout),
+ last_message, wait * 2);
+ }
+ });
+ };
+
+ Sao.Bus.handle = function(message) {
+ var notify = function(message) {
+ try {
+ if (Notification.permission != "granted") {
+ return;
+ }
+ } catch (e) {
+ (console.error || console.log).call(console, e, e.stack);
+ return;
+ }
+
+ new Notification(message.title, {
+ body: message.body || '',
+ });
+ };
+
+ switch (message.type) {
+ case 'notification':
+ notify(message);
+ break;
+ }
+ };
+
+}());
diff --git a/sao/src/common.js b/sao/src/common.js
new file mode 100644
index 0000000000..ef125469cf
--- /dev/null
+++ b/sao/src/common.js
@@ -0,0 +1,4115 @@
+/* This file is part of Tryton. The COPYRIGHT file at the top level of
+ this repository contains the full copyright notices and license terms. */
+(function() {
+ 'use strict';
+
+ Sao.common = {};
+
+ Sao.common.BACKSPACE_KEYCODE = 8;
+ Sao.common.TAB_KEYCODE = 9;
+ Sao.common.RETURN_KEYCODE = 13;
+ Sao.common.ESC_KEYCODE = 27;
+ Sao.common.UP_KEYCODE = 38;
+ Sao.common.DOWN_KEYCODE = 40;
+ Sao.common.DELETE_KEYCODE = 46;
+ Sao.common.F2_KEYCODE = 113;
+ Sao.common.F3_KEYCODE = 114;
+
+ Sao.common.SELECTION_NONE = 1;
+ Sao.common.SELECTION_SINGLE = 2;
+ Sao.common.SELECTION_MULTIPLE = 3;
+
+ Sao.common.BIG_IMAGE_SIZE = Math.pow(10, 6);
+
+ Sao.common.compare = function(arr1, arr2) {
+ if (arr1.length != arr2.length) {
+ return false;
+ }
+ for (var i = 0; i < arr1.length; i++) {
+ var a = arr1[i], b = arr2[i];
+ if ((a instanceof Array) && (b instanceof Array)) {
+ if (!Sao.common.compare(a, b)) {
+ return false;
+ }
+ } else if (moment.isMoment(a) && moment.isMoment(b)) {
+ if ((a.isDate != b.isDate) &&
+ (a.isDateTime != b.isDateTime) &&
+ (a.valueOf() != b.valueOf())) {
+ return false;
+ }
+ } else if ((a instanceof Number) || (b instanceof Number)) {
+ if (Number(a) !== Number(b)) {
+ return false;
+ }
+ } else if (a != b) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ Sao.common.contains = function(array1, array2) {
+ for (var i = 0; i < array1.length; i++) {
+ if (Sao.common.compare(array1[i], array2)) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ // Find the intersection of two arrays.
+ // The arrays must be sorted.
+ Sao.common.intersect = function(a, b) {
+ var ai = 0, bi = 0;
+ var result = [];
+ while (ai < a.length && bi < b.length) {
+ if (a[ai] < b[bi]) {
+ ai++;
+ } else if (a[ai] > b[bi]) {
+ bi++;
+ } else {
+ result.push(a[ai]);
+ ai++;
+ bi++;
+ }
+ }
+ return result;
+ };
+
+ Sao.common.scrollIntoViewIfNeeded = function(element) {
+ element = element[0];
+ var rect = element.getBoundingClientRect();
+ if (rect.bottom > window.innerHeight) {
+ element.scrollIntoView(false);
+ }
+ if (rect.top < 0) {
+ element.scrollIntoView();
+ }
+ };
+
+ // Handle click and Return press event
+ // If one, the handler is executed at most once for both events
+ Sao.common.click_press = function(func, one) {
+ return function handler(evt) {
+ if (evt.type != 'keypress' ||
+ evt.which == Sao.common.RETURN_KEYCODE) {
+ if (one) {
+ jQuery(this).off('click keypress', null, handler);
+ }
+ return func(evt);
+ }
+ };
+ };
+
+ // Cartesian product
+ Sao.common.product = function(array, repeat) {
+ repeat = repeat || 1;
+ var pools = [];
+ var i = 0;
+ while (i < repeat) {
+ pools = pools.concat(array);
+ i++;
+ }
+ var result = [[]];
+ pools.forEach(function(pool) {
+ var tmp = [];
+ result.forEach(function(x) {
+ pool.forEach(function(y) {
+ tmp.push(x.concat([y]));
+ });
+ });
+ result = tmp;
+ });
+ return result;
+ };
+
+ Sao.common.selection = function(title, values, alwaysask) {
+ if (alwaysask === undefined) {
+ alwaysask = false;
+ }
+ var prm = jQuery.Deferred();
+ if (jQuery.isEmptyObject(values)) {
+ prm.reject();
+ return prm;
+ }
+ var keys = Object.keys(values).sort();
+ if ((keys.length == 1) && (!alwaysask)) {
+ var key = keys[0];
+ prm.resolve(values[key]);
+ return prm;
+ }
+ var dialog = new Sao.Dialog(
+ title || Sao.i18n.gettext('Your selection:'),
+ 'selection-dialog');
+
+ keys.forEach(function(k, i) {
+ jQuery('', {
+ 'class': 'radio'
+ }).append(jQuery('')
+ .text(' ' + k)
+ .prepend(jQuery('', {
+ 'type': 'radio',
+ 'name': 'selection',
+ 'value': i
+ })))
+ .appendTo(dialog.body);
+ });
+ dialog.body.find('input').first().prop('checked', true);
+
+ jQuery('', {
+ 'class': 'btn btn-link',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('Cancel')).click(function() {
+ dialog.modal.modal('hide');
+ prm.reject();
+ }).appendTo(dialog.footer);
+ jQuery('', {
+ 'class': 'btn btn-primary',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('OK')).click(function() {
+ var i = dialog.body.find('input:checked').attr('value');
+ dialog.modal.modal('hide');
+ prm.resolve(values[keys[i]]);
+ }).appendTo(dialog.footer);
+ dialog.modal.on('hidden.bs.modal', function(e) {
+ jQuery(this).remove();
+ });
+ dialog.modal.modal('show');
+ return prm;
+ };
+
+ Sao.common.moment_format = function(format) {
+ return format
+ .replace('%a', 'ddd')
+ .replace('%A', 'dddd')
+ .replace('%w', 'd')
+ .replace('%d', 'DD')
+ .replace('%b', 'MMM')
+ .replace('%B', 'MMMM')
+ .replace('%m', 'MM')
+ .replace('%y', 'YY')
+ .replace('%Y', 'YYYY')
+ .replace('%H', 'HH')
+ .replace('%I', 'hh')
+ .replace('%p', 'A')
+ .replace('%M', 'mm')
+ .replace('%S', 'ss')
+ .replace('%f', 'SSS')
+ .replace('%z', 'ZZ')
+ .replace('%Z', 'zz')
+ .replace('%j', 'DDDD')
+ .replace('%U', 'ww')
+ .replace('%W', 'WW')
+ .replace('%c', 'llll')
+ .replace('%x', 'L')
+ .replace('%X', 'LTS')
+ .replace('%', '%%')
+ ;
+ };
+
+ Sao.common.DATE_OPERATORS = [
+ ['S', moment.duration(-1, 'seconds')],
+ ['s', moment.duration(1, 'seconds')],
+ ['I', moment.duration(-1, 'minutes')],
+ ['i', moment.duration(1, 'minutes')],
+ ['H', moment.duration(-1, 'hours')],
+ ['h', moment.duration(1, 'hours')],
+ ['D', moment.duration(-1, 'days')],
+ ['d', moment.duration(1, 'days')],
+ ['W', moment.duration(-1, 'weeks')],
+ ['w', moment.duration(1, 'weeks')],
+ ['M', moment.duration(-1, 'months')],
+ ['m', moment.duration(1, 'months')],
+ ['Y', moment.duration(-1, 'years')],
+ ['y', moment.duration(1, 'years')],
+ ];
+
+ Sao.common.date_format = function(format) {
+ if (jQuery.isEmptyObject(format)) {
+ format = '%x';
+ if (Sao.Session.current_session) {
+ var context = Sao.Session.current_session.context;
+ if (context.locale && context.locale.date) {
+ format = context.locale.date;
+ }
+ }
+ }
+ return Sao.common.moment_format(format);
+ };
+
+ Sao.common.format_time = function(format, date) {
+ if (!date) {
+ return '';
+ }
+ return date.format(Sao.common.moment_format(format));
+ };
+
+ Sao.common.parse_time = function(format, value) {
+ if (!value) {
+ return null;
+ }
+ var getNumber = function(pattern) {
+ var i = format.indexOf(pattern);
+ if (~i) {
+ var number = parseInt(value.slice(i, i + pattern.length), 10);
+ if (!isNaN(number)) {
+ return number;
+ }
+ }
+ return 0;
+ };
+ return Sao.Time(getNumber('%H'), getNumber('%M'), getNumber('%S'),
+ getNumber('%f'));
+ };
+
+ Sao.common.format_date = function(date_format, date) {
+ if (!date) {
+ return '';
+ }
+ return date.format(Sao.common.moment_format(date_format));
+ };
+
+ Sao.common.parse_date = function(date_format, value) {
+ var date = moment(value,
+ Sao.common.moment_format(date_format));
+ if (date.isValid()) {
+ date = Sao.Date(date.year(), date.month(), date.date());
+ } else {
+ date = null;
+ }
+ return date;
+ };
+
+ Sao.common.format_datetime = function(datetime_format, date) {
+ if (!date) {
+ return '';
+ }
+ return date.format(Sao.common.moment_format(datetime_format));
+ };
+
+ Sao.common.parse_datetime = function(datetime_format, value) {
+ var date = moment(value, Sao.common.moment_format(datetime_format));
+ if (date.isValid()) {
+ date = Sao.DateTime(date.year(), date.month(), date.date(),
+ date.hour(), date.minute(), date.second(),
+ date.millisecond());
+ } else {
+ date = null;
+ }
+ return date;
+ };
+
+ Sao.common.timedelta = {};
+ Sao.common.timedelta.DEFAULT_CONVERTER = {
+ 's': 1
+ };
+ Sao.common.timedelta.DEFAULT_CONVERTER.m =
+ Sao.common.timedelta.DEFAULT_CONVERTER.s * 60;
+ Sao.common.timedelta.DEFAULT_CONVERTER.h =
+ Sao.common.timedelta.DEFAULT_CONVERTER.m * 60;
+ Sao.common.timedelta.DEFAULT_CONVERTER.d =
+ Sao.common.timedelta.DEFAULT_CONVERTER.h * 24;
+ Sao.common.timedelta.DEFAULT_CONVERTER.w =
+ Sao.common.timedelta.DEFAULT_CONVERTER.d * 7;
+ Sao.common.timedelta.DEFAULT_CONVERTER.M =
+ Sao.common.timedelta.DEFAULT_CONVERTER.d * 30;
+ Sao.common.timedelta.DEFAULT_CONVERTER.Y =
+ Sao.common.timedelta.DEFAULT_CONVERTER.d * 365;
+ Sao.common.timedelta._get_separator = function() {
+ return {
+ Y: Sao.i18n.gettext('Y'),
+ M: Sao.i18n.gettext('M'),
+ w: Sao.i18n.gettext('w'),
+ d: Sao.i18n.gettext('d'),
+ h: Sao.i18n.gettext('h'),
+ m: Sao.i18n.gettext('m'),
+ s: Sao.i18n.gettext('s')
+ };
+ };
+ Sao.common.timedelta.format = function(value, converter) {
+ if (!value) {
+ return '';
+ }
+ if (!converter) {
+ converter = Sao.common.timedelta.DEFAULT_CONVERTER;
+ }
+ var text = [];
+ value = value.asSeconds();
+ var sign = '';
+ if (value < 0) {
+ sign = '-';
+ }
+ value = Math.abs(value);
+ converter = Object.keys(
+ Sao.common.timedelta._get_separator()).map(function(key) {
+ return [key, converter[key]];
+ });
+ var values = [];
+ var k, v;
+ for (var i = 0; i < converter.length; i++) {
+ k = converter[i][0];
+ v = converter[i][1];
+ if (v) {
+ var part = Math.floor(value / v);
+ value -= part * v;
+ values.push(part);
+ } else {
+ values.push(0);
+ }
+ }
+ for (i = 0; i < converter.length - 3; i++) {
+ k = converter[i][0];
+ v = values[i];
+ if (v) {
+ text.push(v + Sao.common.timedelta._get_separator()[k]);
+ }
+ }
+ if (jQuery(values.slice(-3)).is(function(i, v) { return v; }) ||
+ jQuery.isEmptyObject(text)) {
+ var time_values = values.slice(-3);
+ var time = time_values[0].toString().padStart(2, "0");
+ time += ":" + time_values[1].toString().padStart(2, "0");
+ if (time_values[2] || value) {
+ time += ':' + time_values[2].toString().padStart(2, "0");
+ }
+ text.push(time);
+ }
+ text = sign + text.reduce(function(p, c) {
+ if (p) {
+ return p + ' ' + c;
+ } else {
+ return c;
+ }
+ });
+ if (value) {
+ if (!jQuery(values.slice(-3)).is(function(i, v) { return v; })) {
+ // Add space if no time
+ text += ' ';
+ }
+ text += ('' + value.toFixed(6)).slice(1);
+ }
+ return text;
+ };
+ Sao.common.timedelta.parse = function(text, converter) {
+ if (!text) {
+ return null;
+ }
+ if (!converter) {
+ converter = Sao.common.timedelta.DEFAULT_CONVERTER;
+ }
+ var separators = Sao.common.timedelta._get_separator();
+ var separator;
+ for (var k in separators) {
+ separator = separators[k];
+ text = text.replace(separator, separator + ' ');
+ }
+
+ var seconds = 0;
+ var sec;
+ var parts = text.split(' ');
+ for (var i = 0; i < parts.length; i++) {
+ var part = parts[i];
+ if (part.contains(':')) {
+ var subparts = part.split(':');
+ var subconverter = [
+ converter.h, converter.m, converter.s];
+ for (var j = 0;
+ j < Math.min(subparts.length, subconverter.length);
+ j ++) {
+ var t = subparts[j];
+ var v = subconverter[j];
+ sec = Math.abs(parseFloat(t)) * v;
+ if (!isNaN(sec)) {
+ seconds += sec;
+ }
+ }
+ } else {
+ var found = false;
+ for (var key in separators) {
+ separator =separators[key];
+ if (part.endsWith(separator)) {
+ part = part.slice(0, -separator.length);
+ sec = Math.abs(parseFloat(part)) * converter[key];
+ if (!isNaN(sec)) {
+ seconds += sec;
+ }
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ sec = Math.abs(parseFloat(part));
+ if (!isNaN(sec)) {
+ seconds += sec;
+ }
+ }
+ }
+ }
+ if (text.contains('-')) {
+ seconds *= -1;
+ }
+ return Sao.TimeDelta(null, seconds);
+ };
+
+ Sao.common.ModelAccess = Sao.class_(Object, {
+ init: function() {
+ this.batchnum = 100;
+ this._models = [];
+ this._access = {};
+ },
+ load_models: function(refresh) {
+ if (!refresh) {
+ this._access = {};
+ }
+ this._models = Sao.rpc({
+ 'method': 'model.ir.model.list_models',
+ 'params': [{}]
+ }, Sao.Session.current_session, false);
+ },
+ get: function(model) {
+ if (this._access[model] !== undefined) {
+ return this._access[model];
+ }
+ var idx = this._models.indexOf(model);
+ if (idx < 0) {
+ this.load_models(false);
+ idx = this._models.indexOf(model);
+ }
+ var to_load = this._models.slice(
+ Math.max(0, idx - Math.floor(this.batchnum / 2)),
+ idx + Math.floor(this.batchnum / 2));
+ var access = Sao.rpc({
+ 'method': 'model.ir.model.access.get_access',
+ 'params': [to_load, {}]
+ }, Sao.Session.current_session, false);
+ this._access = jQuery.extend(this._access, access);
+ return this._access[model];
+ }
+ });
+ Sao.common.MODELACCESS = new Sao.common.ModelAccess();
+
+ Sao.common.ModelHistory = Sao.class_(Object, {
+ init: function() {
+ this._models = [];
+ },
+ load_history: function() {
+ this._models = [];
+ return Sao.rpc({
+ 'method': 'model.ir.model.list_history',
+ 'params': [{}]
+ }, Sao.Session.current_session).then(function(models) {
+ this._models = models;
+ }.bind(this));
+ },
+ contains: function(model) {
+ return ~this._models.indexOf(model);
+ }
+ });
+ Sao.common.MODELHISTORY = new Sao.common.ModelHistory();
+
+ Sao.common.ModelName = Sao.class_(Object, {
+ init: function() {
+ this._names = {};
+ },
+ load_names: function() {
+ this._names = Sao.rpc({
+ 'method':'model.ir.model.get_names',
+ 'params': [{}],
+ }, Sao.Session.current_session, false);
+ },
+ get: function(model) {
+ if (jQuery.isEmptyObject(this._names)) {
+ this.load_names();
+ }
+ return this._names[model] || '';
+ },
+ clear: function() {
+ this._names = {};
+ },
+ });
+ Sao.common.MODELNAME = new Sao.common.ModelName();
+
+ Sao.common.ViewSearch = Sao.class_(Object, {
+ init: function() {
+ this.encoder = new Sao.PYSON.Encoder();
+ },
+ load_searches: function() {
+ this.searches = {};
+ return Sao.rpc({
+ 'method': 'model.ir.ui.view_search.get_search',
+ 'params': [{}]
+ }, Sao.Session.current_session).then(function(searches) {
+ this.searches = searches;
+ }.bind(this));
+ },
+ get: function(model) {
+ return this.searches[model] || [];
+ },
+ add: function(model, name, domain) {
+ return Sao.rpc({
+ 'method': 'model.ir.ui.view_search.create',
+ 'params': [[{
+ 'model': model,
+ 'name': name,
+ 'domain': this.encoder.encode(domain)
+ }], {}]
+ }, Sao.Session.current_session).then(function(ids) {
+ var id = ids[0];
+ if (this.searches[model] === undefined) {
+ this.searches[model] = [];
+ }
+ this.searches[model].push([id, name, domain, true]);
+ }.bind(this));
+ },
+ remove: function(model, id) {
+ return Sao.rpc({
+ 'method': 'model.ir.ui.view_search.delete',
+ 'params': [[id], {}]
+ }, Sao.Session.current_session).then(function() {
+ for (var i = 0; i < this.searches[model].length; i++) {
+ var domain = this.searches[model][i];
+ if (domain[0] === id) {
+ this.searches[model].splice(i, 1);
+ break;
+ }
+ }
+ }.bind(this));
+ }
+ });
+ Sao.common.VIEW_SEARCH = new Sao.common.ViewSearch();
+
+ Sao.common.humanize = function(size) {
+ var sizes = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
+ for (var i =0, len = sizes.length; i < len; i++) {
+ if (size < 1000) {
+ return size.toPrecision(4) + ' ' + sizes[i];
+ }
+ size /= 1000;
+ }
+ };
+
+ Sao.common.EvalEnvironment = function(parent_, eval_type) {
+ if (eval_type === undefined)
+ eval_type = 'eval';
+ var environment;
+ if (eval_type == 'eval') {
+ environment = parent_.get_eval();
+ } else {
+ environment = {};
+ for (var key in parent_.model.fields) {
+ var field = parent_.model.fields[key];
+ environment[key] = field.get_on_change_value(parent_);
+ }
+ }
+ environment.id = parent_.id;
+ if (parent_.group.parent)
+ Object.defineProperty(environment, '_parent_' +
+ parent_.group.parent_name, {
+ 'enumerable': true,
+ 'get': function() {
+ return Sao.common.EvalEnvironment(parent_.group.parent,
+ eval_type);
+ }
+ });
+ environment.get = function(item, default_) {
+ if (this.hasOwnProperty(item))
+ return this[item];
+ return default_;
+ };
+
+ return environment;
+ };
+
+ Sao.common.selection_mixin = {};
+ Sao.common.selection_mixin.init = function() {
+ this.selection = null;
+ this.help = null;
+ this.inactive_selection = [];
+ this._last_domain = null;
+ this._values2selection = {};
+ this._domain_cache = {};
+ if (this.nullable_widget === undefined) {
+ this.nullable_widget = true;
+ }
+ };
+ Sao.common.selection_mixin.init_selection = function(value, callback) {
+ if (!value) {
+ value = {};
+ (this.attributes.selection_change_with || []).forEach(function(e) {
+ value[e] = null;
+ });
+ }
+ var key = JSON.stringify(value);
+ var selection = this.attributes.selection || [];
+ var help = this.attributes.help_selection || {};
+ var prm;
+ var prepare_selection = function(selection) {
+ selection = jQuery.extend([], selection);
+ if (this.attributes.sort === undefined || this.attributes.sort) {
+ selection.sort(function(a, b) {
+ return a[1].localeCompare(b[1]);
+ });
+ }
+ this.selection = jQuery.extend([], selection);
+ this.help = this.attributes.help_selection || {};
+ if (callback) callback(this.selection, this.help);
+ };
+ if (!(selection instanceof Array) &&
+ !(key in this._values2selection)) {
+ if (!jQuery.isEmptyObject(this.attributes.selection_change_with)) {
+ prm = this.model.execute(selection, [value]);
+ } else {
+ prm = this.model.execute(selection, []);
+ }
+ prm = prm.then(function(selection) {
+ this._values2selection[key] = selection;
+ return selection;
+ }.bind(this));
+ prm = prm.then(prepare_selection.bind(this));
+ } else {
+ if (key in this._values2selection) {
+ selection = this._values2selection[key];
+ }
+ prepare_selection.call(this, selection);
+ prm = jQuery.when();
+ }
+ this.inactive_selection = [];
+ this._selection_prm = prm;
+ };
+ Sao.common.selection_mixin.update_selection = function(record, field,
+ callback) {
+ var _update_selection = function() {
+ if (!field) {
+ if (callback) {
+ callback(this.selection, this.help);
+ }
+ return;
+ }
+ var domain = field.get_domain(record);
+ if (!('relation' in this.attributes)) {
+ var change_with = this.attributes.selection_change_with || [];
+ var value = record._get_on_change_args(change_with);
+ delete value.id;
+ Sao.common.selection_mixin.init_selection.call(this, value,
+ function() {
+ Sao.common.selection_mixin.filter_selection.call(
+ this, domain, record, field);
+ if (callback) {
+ callback(this.selection, this.help);
+ }
+ }.bind(this));
+ } else {
+ var context = field.get_context(record);
+ var jdomain = JSON.stringify([domain, context]);
+ if (jdomain in this._domain_cache) {
+ this.selection = this._domain_cache[jdomain];
+ this._last_domain = [domain, context];
+ }
+ if ((this._last_domain !== null) &&
+ Sao.common.compare(domain, this._last_domain[0]) &&
+ (JSON.stringify(context) ==
+ JSON.stringify(this._last_domain[1]))) {
+ if (callback) {
+ callback(this.selection, this.help);
+ }
+ return;
+ }
+ var fields = ['rec_name'];
+ var help_field = this.attributes.help_field;
+ if (help_field) {
+ fields.push(help_field);
+ }
+ var prm = Sao.rpc({
+ 'method': 'model.' + this.attributes.relation +
+ '.search_read',
+ 'params': [domain, 0, null, null, fields, context]
+ }, record.model.session);
+ prm.done(function(result) {
+ var selection = [];
+ result.forEach(function(x) {
+ selection.push([x.id, x.rec_name]);
+ });
+ if (this.nullable_widget) {
+ selection.push([null, '']);
+ }
+ var help = {};
+ if (help_field){
+ result.forEach(function(x) {
+ help[x.id] = x[help_field];
+ });
+ }
+ this._last_domain = [domain, context];
+ this._domain_cache[jdomain] = selection;
+ this.selection = jQuery.extend([], selection);
+ this.help = help;
+ if (callback) {
+ callback(this.selection, this.help);
+ }
+ }.bind(this));
+ prm.fail(function() {
+ this._last_domain = null;
+ this.selection = [];
+ if (callback) {
+ callback(this.selection, this.help);
+ }
+ }.bind(this));
+ }
+ };
+ this._selection_prm.done(_update_selection.bind(this));
+ };
+ Sao.common.selection_mixin.filter_selection = function(
+ domain, record, field) {
+ if (jQuery.isEmptyObject(domain)) {
+ return;
+ }
+
+ var inversion = new Sao.common.DomainInversion();
+ var _value_evaluator = function(value) {
+ var context = {};
+ context[this.field_name] = value[0];
+ return inversion.eval_domain(domain, context);
+ }.bind(this);
+
+ var _model_evaluator = function(allowed_models) {
+ return function(value) {
+ return ~allowed_models.indexOf(value[0]) ||
+ jQuery.isEmptyObject(allowed_models);
+ };
+ };
+
+ var evaluator;
+ var type_ = field.description.type;
+ if (type_ == 'reference') {
+ var allowed_models = field.get_models(record);
+ evaluator = _model_evaluator(allowed_models);
+ } else if (type_ == 'multiselection') {
+ return;
+ } else {
+ evaluator = _value_evaluator;
+ }
+
+ this.selection = this.selection.filter(evaluator);
+ };
+ Sao.common.selection_mixin.get_inactive_selection = function(value) {
+ if (!this.attributes.relation) {
+ return jQuery.when([]);
+ }
+ for (var i = 0, len = this.inactive_selection.length; i < len; i++) {
+ if (value == this.inactive_selection[i][0]) {
+ return jQuery.when(this.inactive_selection[i]);
+ }
+ }
+ var prm = Sao.rpc({
+ 'method': 'model.' + this.attributes.relation + '.read',
+ 'params': [[value], ['rec_name'], {}]
+ }, Sao.Session.current_session);
+ return prm.then(function(result) {
+ this.inactive_selection.push([result[0].id, result[0].rec_name]);
+ return [result[0].id, result[0].rec_name];
+ }.bind(this));
+ };
+
+ Sao.common.Button = Sao.class_(Object, {
+ init: function(attributes, el, size, style) {
+ this.attributes = attributes;
+ if (el) {
+ this.el = el;
+ } else {
+ this.el = jQuery('', {
+ title: attributes.string || '',
+ name: attributes.name || '',
+ });
+ this.el.text(attributes.string || '');
+ if (this.attributes.rule) {
+ this.el.append(' ').append(jQuery('', {
+ 'class': 'badge'
+ }));
+ }
+ }
+ this.icon = this.el.children('img');
+ if (!this.icon.length) {
+ this.icon = jQuery('', {
+ 'class': 'icon',
+ }).prependTo(this.el);
+ this.icon.hide();
+ }
+ this.el.addClass(
+ ['btn', (style || 'btn-default'), (size || '')].join(' '));
+ this.el.attr('type', 'button');
+ this.icon.attr('aria-hidden', true);
+ this.set_icon(attributes.icon);
+ },
+ set_icon: function(icon_name) {
+ if (!icon_name) {
+ this.icon.attr('src', '');
+ this.icon.hide();
+ return;
+ }
+ Sao.common.ICONFACTORY.get_icon_url(icon_name).done(function(url) {
+ this.icon.attr('src', url);
+ this.icon.show();
+ }.bind(this));
+ },
+ set_state: function(record) {
+ var states;
+ if (record) {
+ states = record.expr_eval(this.attributes.states || {});
+ } else {
+ states = {};
+ }
+ if (states.invisible) {
+ this.el.hide();
+ } else {
+ this.el.show();
+ }
+ this.el.prop('disabled', Boolean(states.readonly));
+ this.set_icon(states.icon || this.attributes.icon);
+
+ if (this.attributes.rule) {
+ var prm;
+ if (record) {
+ prm = record.get_button_clicks(this.attributes.name);
+ } else {
+ prm = jQuery.when();
+ }
+ prm.then(function(clicks) {
+ var counter = this.el.children('.badge');
+ var users = [];
+ var tip = '';
+ if (!jQuery.isEmptyObject(clicks)) {
+ for (var u in clicks) {
+ users.push(clicks[u]);
+ }
+ tip = Sao.i18n.gettext('By: ') +
+ users.join(Sao.i18n.gettext(', '));
+ }
+ counter.text(users.length || '');
+ counter.attr('title', tip);
+ }.bind(this));
+ }
+
+ if (((this.attributes.type === undefined) ||
+ (this.attributes.type === 'class')) && (record)) {
+ var parent = record.group.parent;
+ while (parent) {
+ if (parent.has_changed()) {
+ this.el.prop('disabled', true);
+ break;
+ }
+ parent = parent.group.parent;
+ }
+ }
+ }
+ });
+
+ Sao.common.udlex = Sao.class_(Object, {
+ init: function(instream) {
+
+ var Stream = Sao.class_(Object, {
+ init: function(stream) {
+ this.stream = stream.split('');
+ this.i = 0;
+ },
+ read: function(length) {
+ if (length === undefined) {
+ length = 1;
+ }
+ if (this.i >= this.stream.length) {
+ return null;
+ }
+ var value = this.stream
+ .slice(this.i, this.i + length).join();
+ this.i += length;
+ return value;
+ }
+ });
+ this.instream = new Stream(instream);
+ this.eof = null;
+ this.commenters = '';
+ this.nowordchars = [':', '>', '<', '=', '!', '"', ';', '(', ')'];
+ this.whitespace = ' \t\r\n';
+ this.whitespace_split = false;
+ this.quotes = '"';
+ this.escape = '\\';
+ this.escapedquotes = '"';
+ this.state = ' ';
+ this.pushback = [];
+ this.token = '';
+ },
+ get_token: function() {
+ if (this.pushback.length > 0) {
+ return this.pushback.shift();
+ }
+ var raw = this.read_token();
+ return raw;
+ },
+ read_token: function() {
+ var quoted = false;
+ var escapedstate = ' ';
+ while (true) {
+ var nextchar = this.instream.read(1);
+ if (this.state === null) {
+ this.token = ''; // past en of file
+ break;
+ } else if (this.state == ' ') {
+ if (!nextchar) {
+ this.state = null; // end of file
+ break;
+ } else if (this.whitespace.contains(nextchar)) {
+ if (this.token || quoted) {
+ break; // emit current token
+ } else {
+ continue;
+ }
+ } else if (this.commenters.contains(nextchar)) {
+ // TODO readline
+ } else if (this.escape.contains(nextchar)) {
+ escapedstate = 'a';
+ this.state = nextchar;
+ } else if (!~this.nowordchars.indexOf(nextchar)) {
+ this.token = nextchar;
+ this.state = 'a';
+ } else if (this.quotes.contains(nextchar)) {
+ this.state = nextchar;
+ } else if (this.whitespace_split) {
+ this.token = nextchar;
+ this.state = 'a';
+ } else {
+ this.token = nextchar;
+ if (this.token || quoted) {
+ break; // emit current token
+ } else {
+ continue;
+ }
+ }
+ } else if (this.quotes.contains(this.state)) {
+ quoted = true;
+ if (!nextchar) { // end of file
+ throw 'no closing quotation';
+ }
+ if (nextchar == this.state) {
+ this.state = 'a';
+ } else if (this.escape.contains(nextchar) &&
+ this.escapedquotes.contains(this.state)) {
+ escapedstate = this.state;
+ this.state = nextchar;
+ } else {
+ this.token = this.token + nextchar;
+ }
+ } else if (this.escape.contains(this.state)) {
+ if (!nextchar) { // end of file
+ throw 'no escaped character';
+ }
+ if (this.quotes.contains(escapedstate) &&
+ (nextchar != this.state) &&
+ (nextchar != escapedstate)) {
+ this.token = this.token + this.state;
+ }
+ this.token = this.token + nextchar;
+ this.state = escapedstate;
+ } else if (this.state == 'a') {
+ if (!nextchar) {
+ this.state = null; // end of file
+ break;
+ } else if (this.whitespace.contains(nextchar)) {
+ this.state = ' ';
+ if (this.token || quoted) {
+ break; // emit current token
+ } else {
+ continue;
+ }
+ } else if (this.commenters.contains(nextchar)) {
+ // TODO
+ } else if (this.quotes.contains(nextchar)) {
+ this.state = nextchar;
+ } else if (this.escape.contains(nextchar)) {
+ escapedstate = 'a';
+ this.state = nextchar;
+ } else if ((!~this.nowordchars.indexOf(nextchar)) ||
+ this.quotes.contains(nextchar) ||
+ this.whitespace_split) {
+ this.token = this.token + nextchar;
+ } else {
+ this.pushback.unshift(nextchar);
+ this.state = ' ';
+ if (this.token) {
+ break; // emit current token
+ } else {
+ continue;
+ }
+ }
+ }
+ }
+ var result = this.token;
+ this.token = '';
+ if (!quoted && result === '') {
+ result = null;
+ }
+ return result;
+ },
+ next: function() {
+ var token = this.get_token();
+ if (token == this.eof) {
+ return null;
+ }
+ return token;
+ }
+ });
+
+ Sao.common.DomainParser = Sao.class_(Object, {
+ OPERATORS: ['!=', '<=', '>=', '=', '!', '<', '>'],
+ init: function(fields, context) {
+ this.fields = {};
+ this.strings = {};
+ this.context = context;
+ this.update_fields(fields);
+ },
+ update_fields: function(fields, prefix, string_prefix) {
+ prefix = prefix || '';
+ string_prefix = string_prefix || '';
+ for (var name in fields) {
+ var field = fields[name];
+ if ((field.searchable || (field.searchable === undefined)) &&
+ (name !== 'rec_name')) {
+ field = jQuery.extend({}, field);
+ var fullname = prefix ? prefix + '.' + name : name;
+ var string = string_prefix ?
+ string_prefix + '.' + field.string : field.string;
+ field.string = string;
+ field.name = fullname;
+ this.fields[fullname] = field;
+ this.strings[field.string.toLowerCase()] = field;
+ var rfields = field.relation_fields;
+ if (rfields) {
+ this.update_fields(rfields, fullname, string);
+ }
+ }
+ }
+ },
+ parse: function(input) {
+ try {
+ var lex = new Sao.common.udlex(input);
+ var tokens = [];
+ while (true) {
+ var token = lex.next();
+ if (token === null) {
+ break;
+ }
+ tokens.push(token);
+ }
+ tokens = this.group_operator(tokens);
+ tokens = this.parenthesize(tokens);
+ tokens = this.group(tokens);
+ tokens = this.operatorize(tokens, 'or');
+ tokens = this.operatorize(tokens, 'and');
+ tokens = this.parse_clause(tokens);
+ return this.simplify(tokens);
+ } catch (e) {
+ if (e == 'no closing quotation') {
+ return this.parse(input + '"');
+ }
+ throw e;
+ }
+ },
+ stringable: function(domain) {
+ var stringable_ = function(clause) {
+ if (!clause) {
+ return true;
+ }
+ var is_array = function(e) {
+ return e instanceof Array;
+ };
+ if ((~['AND', 'OR'].indexOf(clause[0]) ||
+ (is_array(clause[0]))) &&
+ clause.slice(1).every(is_array)) {
+ return this.stringable(clause);
+ }
+ var name = clause[0];
+ var value = clause[2];
+ if (name.endsWith('.rec_name')) {
+ name = name.slice(0, -9);
+ }
+ if (name in this.fields) {
+ var field = this.fields[name];
+ if (~['many2one', 'one2one', 'one2many', 'many2many']
+ .indexOf(field.type)) {
+ var test = function(value) {
+ if (field.type == 'many2one') {
+ if ((typeof value != 'string') &&
+ (value !== null)) {
+ return false;
+ }
+ } else {
+ if (typeof value != 'string') {
+ return false;
+ }
+ }
+ return true;
+ };
+ if (value instanceof Array) {
+ return value.every(test);
+ } else {
+ return test(value);
+ }
+ } else if (field.type == 'multiselection') {
+ return (!value ||
+ jQuery.isEmptyObject(value) ||
+ (value instanceof Array));
+ } else {
+ return true;
+ }
+ } else if (name == 'rec_name') {
+ return true;
+ }
+ return false;
+ }.bind(this);
+ if (!domain) {
+ return true;
+ }
+ if (~['AND', 'OR'].indexOf(domain[0])) {
+ domain = domain.slice(1);
+ }
+ return domain.every(stringable_);
+ },
+ string: function(domain) {
+
+ var string = function(clause) {
+ if (jQuery.isEmptyObject(clause)) {
+ return '';
+ }
+ if ((typeof clause[0] != 'string') ||
+ ~['AND', 'OR'].indexOf(clause[0])) {
+ return '(' + this.string(clause) + ')';
+ }
+ var escaped;
+ var name = clause[0];
+ var operator = clause[1];
+ var value = clause[2];
+ if (name.endsWith('.rec_name')) {
+ name = name.slice(0, -9);
+ }
+ if (!(name in this.fields)) {
+ if (this.is_full_text(value)) {
+ value = value.slice(1, -1);
+ }
+ return this.quote(value);
+ }
+ var field = this.fields[name];
+ var target = null;
+ if (clause.length > 3) {
+ target = clause[3];
+ }
+ if (operator.contains('ilike')) {
+ if (this.is_full_text(value)) {
+ value = value.slice(1, -1);
+ } else if (!this.is_like(value)) {
+ if (operator == 'ilike') {
+ operator = '=';
+ } else {
+ operator = '!';
+ }
+ value = this.unescape(value);
+ }
+ }
+ var def_operator = this.default_operator(field);
+ if (def_operator == operator.trim()) {
+ operator = '';
+ if (~this.OPERATORS.indexOf(value)) {
+ // As the value could be interpreted as an operator
+ // the default operator must be forced
+ operator = '"" ';
+ }
+ } else if ((operator.contains(def_operator) &&
+ (operator.contains('not') ||
+ operator.contains('!')))) {
+ operator = operator.replace(def_operator, '')
+ .replace('not', '!').trim();
+ }
+ if (operator.endsWith('in')) {
+ if (operator == 'not in') {
+ operator = '!';
+ } else {
+ operator = '';
+ }
+ }
+ var formatted_value = this.format_value(field, value, target);
+ if (~this.OPERATORS.indexOf(operator) &&
+ ~['char', 'text', 'selection']
+ .indexOf(field.type) &&
+ (value === '')) {
+ formatted_value = '""';
+ }
+ return (this.quote(field.string) + ': ' +
+ operator + formatted_value);
+ };
+ string = string.bind(this);
+
+ if (jQuery.isEmptyObject(domain)) {
+ return '';
+ }
+ var nary = ' ';
+ if ((domain[0] == 'AND') || (domain[0] == 'OR')) {
+ if (domain[0] == 'OR') {
+ nary = ' or ';
+ }
+ domain = domain.slice(1);
+ }
+ return domain.map(string).join(nary);
+ },
+ completion: function(input) {
+ var results = [];
+ var domain = this.parse(input);
+ var closing = 0;
+ var i, len;
+ for (i=input.length; i>0; i--) {
+ if (input[i] == ')' || input[i] == ' ') {
+ break;
+ }
+ if (input[i] == ')') {
+ closing += 1;
+ }
+ }
+ var endings = this.ending_clause(domain);
+ var ending = endings[0];
+ var deep_ending = endings[1];
+ var deep = deep_ending - closing;
+ var string_domain = this.string(domain);
+
+ if (deep > 0) {
+ string_domain = string_domain.substring(0,
+ string_domain.length - deep);
+ }
+ if (string_domain != input) {
+ results.push(string_domain);
+ }
+
+ var pslice = function(string, depth) {
+ if (depth > 0) {
+ return string.substring(0, string.length - depth);
+ }
+ return string;
+ };
+ var complete, complete_string;
+ if (ending !== null && closing === 0) {
+ var completes = this.complete(ending);
+ for (i=0, len=completes.length; i < len; i++) {
+ complete = completes[i];
+ complete_string = this.string(
+ this.replace_ending_clause(domain, complete));
+ results.push(pslice(complete_string, deep));
+ }
+ }
+ if (input.length > 0) {
+ if (input.substr(input.length - 1, 1) != ' ') {
+ return results;
+ }
+ if (input.length >= 2 ||
+ input.substr(input.length - 2, 1) == ':') {
+ return results;
+ }
+ }
+ var field, operator, value;
+ for (var key in this.strings) {
+ field = this.strings[key];
+ operator = this.default_operator(field);
+ value = '';
+ if ((operator == 'ilike') || (operator == 'not ilike')) {
+ value = this.likify(value);
+ }
+ var new_domain = this.append_ending_clause(domain,
+ [field.name, operator, value], deep);
+ var new_domain_string = this.string(new_domain);
+ results.push(pslice(new_domain_string, deep));
+ }
+ return results;
+ },
+ complete: function(clause) {
+ var results = [];
+ var name, operator, value, target;
+ if (clause.length == 1) {
+ name = clause[0];
+ } else if (clause.length == 3) {
+ name = clause[0];
+ operator = clause[1];
+ value = clause[2];
+ } else {
+ name = clause[0];
+ operator = clause[1];
+ value = clause[2];
+ target = clause[3];
+ if (name.endsWith('.rec_name')) {
+ name = name.substring(0, name.length - 9);
+ }
+ }
+ var escaped;
+ if (name == "rec_name") {
+ if (operator == "ilike") {
+ escaped = value.replace(/%%/g, '__');
+ if (escaped.startsWith('%') || escaped.endsWith('%')) {
+ value = escaped.substring(1, escaped.length - 1);
+ } else if (~escaped.indexOf('%')) {
+ value = value.replace(/%%/g, '%');
+ }
+ operator = null;
+ }
+ name = value;
+ value = '';
+ }
+ if (name === undefined || name === null) {
+ name = '';
+ }
+ var field;
+ if (!(name.toLowerCase() in this.strings) &&
+ !(name in this.fields)) {
+ for (var key in this.strings) {
+ field = this.strings[key];
+ if (field.string.toLowerCase()
+ .startsWith(name.toLowerCase())) {
+ operator = this.default_operator(field);
+ value = '';
+ if (operator == 'ilike') {
+ value = this.likify(value);
+ }
+ results.push([field.name, operator, value]);
+ }
+ }
+ return results;
+ }
+ if (name in this.fields) {
+ field = this.fields[name];
+ } else {
+ field = this.strings[name.toLowerCase()];
+ }
+ if (!operator) {
+ operator = this.default_operator(field);
+ value = '';
+ if ((operator == 'ilike') || (operator == 'not ilike')) {
+ value = this.likify(value);
+ }
+ results.push([field.name, operator, value]);
+ } else {
+ var completes = this.complete_value(field, value);
+ for (var i=0, len=completes.length; i < len; i++) {
+ results.push([field.name, operator, completes[i]]);
+ }
+ }
+ return results;
+ },
+ is_subdomain: function(element) {
+ return (element instanceof Array) && !element.clause;
+ },
+ ending_clause: function(domain, depth) {
+ if (depth === undefined) {
+ depth = 0;
+ }
+ if (domain.length === 0) {
+ return [null, depth];
+ }
+ var last_element = domain[domain.length - 1];
+ if (this.is_subdomain(last_element)) {
+ return this.ending_clause(last_element, depth + 1);
+ }
+ return [last_element, depth];
+ },
+ replace_ending_clause: function(domain, clause) {
+ var results = [];
+ var i, len;
+ for (i = 0, len=domain.length - 1; i < len; i++) {
+ results.push(domain[i]);
+ }
+ if (this.is_subdomain(domain[i])) {
+ results.push(
+ this.replace_ending_clause(domain[i], clause));
+ } else {
+ results.push(clause);
+ }
+ return results;
+ },
+ append_ending_clause: function(domain, clause, depth) {
+ if (domain.length === 0) {
+ return [clause];
+ }
+ var results = domain.slice(0, -1);
+ var last_element = domain[domain.length - 1];
+ if (this.is_subdomain(last_element)) {
+ results.push(this.append_ending_clause(last_element, clause,
+ depth - 1));
+ } else {
+ results.push(last_element);
+ if (depth === 0) {
+ results.push(clause);
+ }
+ }
+ return results;
+ },
+ complete_value: function(field, value) {
+ var complete_boolean = function() {
+ if ((value === null) || (value === undefined)) {
+ return [true, false];
+ } else if (value) {
+ return [false];
+ } else {
+ return [true];
+ }
+ };
+
+ var complete_selection = function() {
+ var results = [];
+ var test_value = value !== null ? value : '';
+ if (value instanceof Array) {
+ test_value = value[value.length - 1] || '';
+ }
+ test_value = test_value.replace(/^%*|%*$/g, '');
+ var i, len, svalue, test;
+ for (i=0, len=field.selection.length; i=', lvalue]),
+ this._clausify([field_name, '<=', rvalue])
+ ]);
+ return;
+ }
+ }
+ if (value instanceof Array) {
+ value = value.map(function(v) {
+ return this.convert_value(field, v, this.context);
+ }.bind(this));
+ if (~['many2one', 'one2many', 'many2many', 'one2one',
+ 'many2many', 'one2one'].indexOf(field.type)) {
+ field_name += '.rec_name';
+ }
+ } else {
+ value = this.convert_value(field, value, this.context);
+ }
+ if (operator.contains('like')) {
+ value = this.likify(value);
+ }
+ if (target) {
+ result.push(this._clausify(
+ [field_name, operator, value, target]));
+ } else {
+ result.push(this._clausify(
+ [field_name, operator, value]));
+ }
+ }
+ }.bind(this));
+ return result;
+ },
+ likify: function(value, escape) {
+ escape = escape || '\\';
+ if (!value) {
+ return '%';
+ }
+ var escaped = value
+ .replace(escape + '%', '')
+ .replace(escape + '_', '');
+ if (escaped.contains('%') || escaped.contains('_')) {
+ return value;
+ } else {
+ return '%' + value + '%';
+ }
+ },
+ is_full_text: function(value, escape) {
+ escape = escape || '\\';
+ var escaped = value;
+ while (escaped.charAt(0) == '%') {
+ escaped = escaped.substring(1);
+ }
+ while (escaped.charAt(escaped.length - 1) == '%') {
+ escaped = escaped.substring(0, escaped.length - 1);
+ }
+ escaped = escaped
+ .replace(escape + '%', '')
+ .replace(escape + '_', '');
+ if (escaped.contains('%') || escaped.contains('_')) {
+ return false;
+ }
+ return value.startsWith('%') && value.endsWith('%');
+ },
+ is_like: function(value, escape) {
+ escape = escape || '\\';
+ var escaped = value
+ .replace(escape + '%', '')
+ .replace(escape + '_', '');
+ return escaped.contains('%') || escaped.contains('_');
+ },
+ unescape: function(value, escape) {
+ escape = escape || '\\';
+ return value
+ .replace(escape + '%', '%')
+ .replace(escape + '_', '_');
+ },
+ quote: function(value) {
+ if (typeof value != 'string') {
+ return value;
+ }
+ if (value.contains('\\')) {
+ value = value.replace(new RegExp('\\\\', 'g'), '\\\\');
+ }
+ if (value.contains('"')) {
+ value = value.replace(new RegExp('"', 'g'), '\\"');
+ }
+ var tests = [':', ' ', '(', ')'].concat(this.OPERATORS);
+ for (var i = 0; i < tests.length; i++) {
+ var test = tests[i];
+ if (value.contains(test)) {
+ return '"' + value + '"';
+ }
+ }
+ return value;
+ },
+ default_operator: function(field) {
+ if (~['char', 'text', 'many2one', 'many2many', 'one2many',
+ 'reference', 'one2one'].indexOf(field.type)) {
+ return 'ilike';
+ } else if (field.type == 'multiselection') {
+ return 'in';
+ } else {
+ return '=';
+ }
+ },
+ negate_operator: function(operator) {
+ switch (operator) {
+ case 'ilike':
+ return 'not ilike';
+ case '=':
+ return '!=';
+ case 'in':
+ return 'not in';
+ }
+ },
+ time_format: function(field) {
+ return new Sao.PYSON.Decoder({}).decode(field.format);
+ },
+ split_target_value: function(field, value) {
+ var target = null;
+ if (typeof value == 'string') {
+ for (var i = 0; i < field.selection.length; i++) {
+ var selection = field.selection[i];
+ var key = selection[0];
+ var text = selection[1];
+ if (value.toLowerCase().startsWith(
+ text.toLowerCase() + ',')) {
+ target = key;
+ value = value.slice(text.length + 1);
+ break;
+ }
+ }
+ }
+ return [target, value];
+ },
+ convert_value: function(field, value, context) {
+ if (!context) {
+ context = {};
+ }
+ var convert_selection = function() {
+ if (typeof value == 'string') {
+ for (var i = 0; i < field.selection.length; i++) {
+ var selection = field.selection[i];
+ var key = selection[0];
+ var text = selection[1];
+ if (value.toLowerCase() == text.toLowerCase()) {
+ return key;
+ }
+ }
+ }
+ return value;
+ };
+
+ var converts = {
+ 'boolean': function() {
+ if (typeof value == 'string') {
+ return [Sao.i18n.gettext('y'),
+ Sao.i18n.gettext('Yes'),
+ Sao.i18n.gettext('True'),
+ Sao.i18n.gettext('t'),
+ '1'].some(
+ function(test) {
+ return test.toLowerCase().startsWith(
+ value.toLowerCase());
+ });
+ }
+ return null;
+ },
+ 'float': function() {
+ var factor = Number(field.factor || 1);
+ var result = Number(value);
+ if (isNaN(result) || value === '' || value === null) {
+ return null;
+ } else {
+ return result / factor;
+ }
+ },
+ 'integer': function() {
+ var factor = Number(field.factor || 1, 10);
+ var result = parseInt(value, 10);
+ if (isNaN(result)) {
+ return null;
+ } else {
+ return result / factor;
+ }
+ },
+ 'numeric': function() {
+ var factor = Number(field.factor || 1);
+ var result = Number(value);
+ if (isNaN(result.valueOf()) ||
+ value === '' || value === null) {
+ return null;
+ } else {
+ return new Sao.Decimal(result / factor);
+ }
+ },
+ 'selection': convert_selection,
+ 'multiselection': convert_selection,
+ 'reference': convert_selection,
+ 'datetime': function() {
+ var result = Sao.common.parse_datetime(
+ Sao.common.date_format(context.date_format) + ' ' +
+ this.time_format(field), value);
+ return result;
+ }.bind(this),
+ 'date': function() {
+ return Sao.common.parse_date(
+ Sao.common.date_format(context.date_format),
+ value);
+ },
+ 'time': function() {
+ try {
+ return Sao.common.parse_time(this.time_format(field),
+ value);
+ } catch (e) {
+ return null;
+ }
+ }.bind(this),
+ 'timedelta': function() {
+ var converter = null;
+ if (field.converter) {
+ converter = this.context[field.converter];
+ }
+ return Sao.common.timedelta.parse(value, converter);
+ }.bind(this),
+ 'many2one': function() {
+ if (value === '') {
+ return null;
+ } else {
+ return value;
+ }
+ }
+ };
+ var func = converts[field.type];
+ if (func) {
+ return func();
+ } else {
+ return value;
+ }
+ },
+ format_value: function(field, value, target, context) {
+ if (target === undefined) {
+ target = null;
+ }
+ if (!context) {
+ context = {};
+ }
+ var format_float = function() {
+ if (!value && value !== 0 && value !== new Sao.Decimal(0)) {
+ return '';
+ }
+ var digit = 0;
+ var factor = Number(field.factor || 1);
+ var string = String(value * factor);
+ if (string.contains('e')) {
+ var exp = string.split('e')[1];
+ string = string.split('e')[0];
+ digit -= parseInt(exp);
+ }
+ if (string.contains('.')) {
+ digit += string.replace(/0+$/, '').split('.')[1].length;
+ }
+ return (value * factor).toFixed(digit);
+ };
+ var format_selection = function() {
+ if (field.selection instanceof Array) {
+ for (var i = 0; i < field.selection.length; i++) {
+ if (field.selection[i][0] == value) {
+ return field.selection[i][1];
+ }
+ }
+ }
+ return value || '';
+ };
+
+ var format_reference = function() {
+ if (!target) {
+ return format_selection();
+ }
+ for (var i = 0; i < field.selection.length; i++) {
+ if (field.selection[i][0] == target) {
+ target = field.selection[i][1];
+ break;
+ }
+ }
+ return target + ',' + value;
+ };
+
+ var converts = {
+ 'boolean': function() {
+ if (value === false) {
+ return Sao.i18n.gettext('False');
+ } else if (value) {
+ return Sao.i18n.gettext('True');
+ } else {
+ return '';
+ }
+ },
+ 'integer': function() {
+ var factor = Number(field.factor || 1);
+ if (value || value === 0) {
+ return '' + parseInt(parseInt(value, 10) * factor, 10);
+ } else {
+ return '';
+ }
+ },
+ 'float': format_float,
+ 'numeric': format_float,
+ 'selection': format_selection,
+ 'multiselection': format_selection,
+ 'reference': format_reference,
+ 'datetime': function() {
+ if (!value) {
+ return '';
+ }
+ if (value.isDate ||
+ !(value.hour() ||
+ value.minute() ||
+ value.second())) {
+ return Sao.common.format_date(
+ Sao.common.date_format(context.date_format),
+ value);
+ }
+ return Sao.common.format_datetime(
+ Sao.common.date_format(context.date_format) + ' ' +
+ this.time_format(field), value);
+ }.bind(this),
+ 'date': function() {
+ return Sao.common.format_date(
+ Sao.common.date_format(context.date_format),
+ value);
+ },
+ 'time': function() {
+ if (!value) {
+ return '';
+ }
+ return Sao.common.format_time(
+ this.time_format(field),
+ value);
+ }.bind(this),
+ 'timedelta': function() {
+ if (!value || !value.valueOf()) {
+ return '';
+ }
+ var converter = null;
+ if (field.converter) {
+ converter = this.context[field.converter];
+ }
+ return Sao.common.timedelta.format(value, converter);
+ }.bind(this),
+ 'many2one': function() {
+ if (value === null) {
+ return '';
+ } else {
+ return value;
+ }
+ }
+ };
+ if (value instanceof Array) {
+ return value.map(function(v) {
+ return this.format_value(field, v);
+ }.bind(this)).join(';');
+ } else {
+ var func = converts[field.type];
+ if (func) {
+ return this.quote(func(value));
+ } else if (value === null) {
+ return '';
+ } else {
+ return this.quote(value);
+ }
+ }
+ },
+ simplify: function(value) {
+ if (this.is_subdomain(value)) {
+ if ((value.length == 1) && this.is_subdomain(value[0])) {
+ return this.simplify(value[0]);
+ } else if ((value.length == 2) &&
+ ((value[0] == 'AND') || (value[0] == 'OR')) &&
+ this.is_subdomain(value[1])) {
+ return this.simplify(value[1]);
+ } else if ((value.length == 3) &&
+ ((value[0] == 'AND') || (value[0] == 'OR')) &&
+ this.is_subdomain(value[1]) &&
+ (value[0] == value[1][0])) {
+ value = this.simplify(value[1]).concat([value[2]]);
+ }
+ return value.map(this.simplify.bind(this));
+ }
+ return value;
+ }
+ });
+
+ Sao.common.DomainInversion = Sao.class_(Object, {
+ and: function(a, b) {return a && b;},
+ or: function(a, b) {return a || b;},
+ OPERATORS: {
+ '=': function(a, b) {
+ return Sao.common.DomainInversion.equals(a, b);
+ },
+ '>': function(a, b) {return (a > b);},
+ '<': function(a, b) {return (a < b);},
+ '<=': function(a, b) {return (a <= b);},
+ '>=': function(a, b) {return (a >= b);},
+ '!=': function(a, b) {
+ return !Sao.common.DomainInversion.equals(a, b);
+ },
+ 'in': function(a, b) {
+ return Sao.common.DomainInversion.in_(a, b);
+ },
+ 'not in': function(a, b) {
+ return !Sao.common.DomainInversion.in_(a, b);
+ },
+ 'like': function(a, b) {
+ return Sao.common.DomainInversion.sql_like(a, b, false);
+ },
+ 'ilike': function(a, b) {
+ return Sao.common.DomainInversion.sql_like(a, b, true);
+ },
+ 'not like': function(a, b) {
+ return !Sao.common.DomainInversion.sql_like(a, b, false);
+ },
+ 'not ilike': function(a, b) {
+ return !Sao.common.DomainInversion.sql_like(a, b, true);
+ },
+ // Those operators are not supported (yet ?)
+ 'child_of': function() {return true;},
+ 'not child_of': function() {return true;}
+ },
+ locale_part: function(expression, field_name, locale_name) {
+ if (locale_name === undefined) {
+ locale_name = 'id';
+ }
+ if (expression === field_name) {
+ return locale_name;
+ }
+ if (expression.contains('.')) {
+ return expression.split('.').slice(1).join('.');
+ }
+ return expression;
+ },
+ is_leaf: function(expression) {
+ return ((expression instanceof Array) &&
+ (expression.length > 2) &&
+ (typeof expression[1] == 'string'));
+ },
+ constrained_leaf: function(part, boolop) {
+ if (boolop === undefined) {
+ boolop = this.and;
+ }
+ var field = part[0];
+ var operand = part[1];
+ var value = part[2];
+ if ((operand === '=') & (boolop === this.and)) {
+ // We should consider that other domain inversion will set a
+ // correct value to this field
+ return true;
+ }
+ return false;
+ },
+ eval_leaf: function(part, context, boolop) {
+ if (boolop === undefined) {
+ boolop = this.and;
+ }
+ var field = part[0];
+ var operand = part[1];
+ var value = part[2];
+ if (field.contains('.')) {
+ // In the case where the leaf concerns a m2o then having a
+ // value in the evaluation context is deemed suffisant
+ return Boolean(context[field.split('.')[0]]);
+ }
+ var context_field = context[field];
+ if (!~['=', '!='].indexOf(operand) &&
+ ((context_field === null) ||
+ (context_field === undefined) ||
+ (value === null) ||
+ (value === undefined)) &&
+ !(~['in', 'not in'].indexOf(operand) &&
+ ((context_field === null) ||
+ (context_field === undefined)) &&
+ ((value instanceof Array) && ~value.indexOf(null)))) {
+ return;
+ }
+ if ((context_field && context_field._isAMomentObject) && !value) {
+ if (context_field.isDateTime) {
+ value = Sao.DateTime.min;
+ } else {
+ value = Sao.Date.min;
+ }
+ }
+ if ((value && value._isAMomentObject) && !context_field) {
+ if (value.isDateTime) {
+ context_field = Sao.DateTime.min;
+ } else {
+ context_field = Sao.Date.min;
+ }
+ }
+ if ((context_field instanceof Array) & (value === null)) {
+ value = [];
+ }
+ if ((typeof context_field == 'string') &&
+ (value instanceof Array) && value.length == 2) {
+ value = value.join(',');
+ } else if ((context_field instanceof Array) &&
+ (typeof value == 'string') && context_field.length == 2) {
+ context_field = context_field.join(',');
+ }
+ if (~['=', '!='].indexOf(operand) &&
+ context_field instanceof Array &&
+ typeof value == 'number') {
+ operand = {
+ '=': 'in',
+ '!=': 'not in'
+ }[operand];
+ }
+ if (operand in this.OPERATORS) {
+ return this.OPERATORS[operand](context_field, value);
+ } else {
+ return true;
+ }
+ },
+ inverse_leaf: function(domain) {
+ if (~['AND', 'OR'].indexOf(domain)) {
+ return domain;
+ } else if (this.is_leaf(domain)) {
+ if (domain[1].contains('child_of') && !domain[0].contains('.')) {
+ if (domain.length == 3) {
+ return domain;
+ } else {
+ return [domain[3]].concat(domain.slice(1));
+ }
+ }
+ return domain;
+ } else {
+ return domain.map(this.inverse_leaf.bind(this));
+ }
+ },
+ filter_leaf: function(domain, field, model) {
+ if (~['AND', 'OR'].indexOf(domain)) {
+ return domain;
+ } else if (this.is_leaf(domain)) {
+ if (domain[0].startsWith(field) && (domain.length > 3)) {
+ if (domain[3] !== model) {
+ return ['id', '=', null];
+ }
+ }
+ return domain;
+ } else {
+ return domain.map(function(d) {
+ return this.filter_leaf(d, field, model);
+ }.bind(this));
+ }
+ },
+ eval_domain: function(domain, context, boolop) {
+ if (boolop === undefined) {
+ boolop = this.and;
+ }
+ if (this.is_leaf(domain)) {
+ return this.eval_leaf(domain, context, boolop);
+ } else if (jQuery.isEmptyObject(domain) && boolop == this.and) {
+ return true;
+ } else if (jQuery.isEmptyObject(domain) && boolop == this.or) {
+ return false;
+ } else if (domain[0] == 'AND') {
+ return this.eval_domain(domain.slice(1), context);
+ } else if (domain[0] == 'OR') {
+ return this.eval_domain(domain.slice(1), context, this.or);
+ } else {
+ return boolop(Boolean(this.eval_domain(domain[0], context)),
+ Boolean(this.eval_domain(domain.slice(1), context, boolop))
+ );
+ }
+ },
+ localize_domain: function(domain, field_name, strip_target) {
+ if (~['AND', 'OR', true, false].indexOf(domain)) {
+ return domain;
+ } else if (this.is_leaf(domain)) {
+ if (domain[1].contains('child_of')) {
+ if (domain[0].split('.').length > 1) {
+ var target = domain[0].split('.').slice(1).join('.');
+ return [target].concat(domain.slice(1));
+ }
+ if (domain.length == 3) {
+ return domain;
+ } else {
+ return [domain[3]].concat(domain.slice(1, -1));
+ }
+ }
+ var local_name = 'id';
+ if (typeof domain[2] == 'string') {
+ local_name = 'rec_name';
+ }
+ var n = strip_target ? 3 : 4;
+ return [this.locale_part(domain[0], field_name, local_name)]
+ .concat(domain.slice(1, n)).concat(domain.slice(4));
+ } else {
+ return domain.map(function(e) {
+ return this.localize_domain(e, field_name, strip_target);
+ }.bind(this));
+ }
+ },
+ prepare_reference_domain: function(domain, reference) {
+
+ var value2reference = function(value) {
+ var model = null;
+ var ref_id = null;
+ if ((typeof(value) == 'string') && value.contains(',')) {
+ var split = value.split(',');
+ var result = split.splice(0, 1);
+ result.push(split.join(','));
+ model = result[0];
+ ref_id = result[1];
+ if (ref_id != '%') {
+ ref_id = parseInt(ref_id, 10);
+ if (isNaN(ref_id)) {
+ model = null;
+ ref_id = value;
+ }
+ }
+ } else if ((value instanceof Array) &&
+ (value.length == 2) &&
+ (typeof(value[0]) == 'string') &&
+ ((typeof(value[1]) == 'number') ||
+ (value[1] == '%'))) {
+ model = value[0];
+ ref_id = value[1];
+ } else {
+ ref_id = value;
+ }
+ return [model, ref_id];
+ };
+
+ if (~['AND', 'OR'].indexOf(domain)) {
+ return domain;
+ } else if (this.is_leaf(domain)) {
+ if (domain[0] == reference) {
+ var model, ref_id, splitted;
+ if ((domain[1] == '=') || (domain[1] == '!=')) {
+ splitted = value2reference(domain[2]);
+ model = splitted[0];
+ ref_id = splitted[1];
+ if (model) {
+ if (ref_id == '%') {
+ if (domain[1] == '=') {
+ return [
+ reference + '.id', '!=', null, model];
+ } else {
+ return [reference, 'not like', domain[2]];
+ }
+ }
+ return [
+ reference + '.id', domain[1], ref_id, model];
+ }
+ } else if ((domain[1] == 'in') || (domain[1] == 'not in')) {
+ var model_values = {};
+ var break_p = false;
+ for (var i=0; i < domain[2].length; i++) {
+ splitted = value2reference(domain[2][i]);
+ model = splitted[0];
+ ref_id = splitted[1];
+ if (!model) {
+ break_p = true;
+ break;
+ }
+ if (!(model in model_values)) {
+ model_values[model] = [];
+ }
+ model_values[model].push(ref_id);
+ }
+
+ if (!break_p) {
+ var ref_ids;
+ var new_domain;
+ if (domain[1] == 'in') {
+ new_domain = ['OR'];
+ } else {
+ new_domain = ['AND'];
+ }
+ for (model in model_values) {
+ ref_ids = model_values[model];
+ if (~ref_ids.indexOf('%')) {
+ if (domain[1] == 'in') {
+ new_domain.push(
+ [reference + '.id', '!=', null,
+ model]);
+ } else {
+ new_domain.push(
+ [reference, 'not like',
+ model + ',%']);
+ }
+ } else {
+ new_domain.push(
+ [reference + '.id', domain[1],
+ ref_ids.map(Number), model]);
+ }
+ }
+ return new_domain;
+ }
+ }
+ return [];
+ }
+ return domain;
+ } else {
+ return domain.map(function(d) {
+ return this.prepare_reference_domain(d, reference);
+ }.bind(this));
+ }
+ },
+ extract_reference_models: function(domain, field_name) {
+ if (~['AND', 'OR'].indexOf(domain)) {
+ return [];
+ } else if (this.is_leaf(domain)) {
+ var local_part = domain[0].split('.', 1)[0];
+ if ((local_part == field_name) &&
+ (domain.length > 3)) {
+ return [domain[3]];
+ }
+ return [];
+ } else {
+ var models = [];
+ domain.map(function(d) {
+ var new_models = this.extract_reference_models(
+ d, field_name);
+ for (var i=0, len=new_models.length; i < len; i++) {
+ var model = new_models[i];
+ if (!~models.indexOf(model)) {
+ models.push(model);
+ }
+ }
+ }.bind(this));
+ return models;
+ }
+ },
+ simplify: function(domain) {
+ if (this.is_leaf(domain)) {
+ return domain;
+ } else if (~['OR', 'AND'].indexOf(domain)) {
+ return domain;
+ } else if ((domain instanceof Array) && (domain.length == 1) &&
+ (~['OR', 'AND'].indexOf(domain[0]))) {
+ return [];
+ } else if ((domain instanceof Array) && (domain.length == 1) &&
+ (!this.is_leaf(domain[0]))) {
+ return this.simplify(domain[0]);
+ } else if ((domain instanceof Array) && (domain.length == 2) &&
+ ~['AND', 'OR'].indexOf(domain[0])) {
+ return [this.simplify(domain[1])];
+ } else {
+ return domain.map(this.simplify.bind(this));
+ }
+ },
+ merge: function(domain, domoperator) {
+ if (jQuery.isEmptyObject(domain) ||
+ ~['AND', 'OR'].indexOf(domain)) {
+ return [];
+ }
+ var domain_type = domain[0] == 'OR' ? 'OR' : 'AND';
+ if (this.is_leaf(domain)) {
+ return [domain];
+ } else if (domoperator === undefined) {
+ return [domain_type].concat([].concat.apply([],
+ domain.map(function(e) {
+ return this.merge(e, domain_type);
+ }.bind(this))));
+ } else if (domain_type == domoperator) {
+ return [].concat.apply([], domain.map(function(e) {
+ return this.merge(e, domain_type);
+ }.bind(this)));
+ } else {
+ // without setting the domoperator
+ return [this.merge(domain)];
+ }
+ },
+ concat: function(domains, domoperator) {
+ var result = [];
+ if (domoperator) {
+ result.push(domoperator);
+ }
+ domains.forEach(function append(domain) {
+ if (!jQuery.isEmptyObject(domain)) {
+ result.push(domain);
+ }
+ });
+ return this.simplify(this.merge(result));
+ },
+ unique_value: function(domain) {
+ if ((domain instanceof Array) &&
+ (domain.length == 1)) {
+ domain = domain[0];
+ var name = domain[0];
+ var value = domain[2];
+ var count = 0;
+ if (domain.length == 4 && name.endsWith('.id')) {
+ count = 1;
+ var model = domain[3];
+ value = [model, value];
+ }
+ if ((name.split('.').length - 1) == count &&
+ (domain[1] == '=')) {
+ return [true, domain[1], value];
+ }
+ }
+ return [false, null, null];
+ },
+ parse: function(domain) {
+ var And = Sao.common.DomainInversion.And;
+ var Or = Sao.common.DomainInversion.Or;
+ if (this.is_leaf(domain)) {
+ return domain;
+ } else if (jQuery.isEmptyObject(domain)) {
+ return new And([]);
+ } else if (domain[0] === 'OR') {
+ return new Or(domain.slice(1));
+ } else {
+ var begin = 0;
+ if (domain[0] === 'AND') {
+ begin = 1;
+ }
+ return new And(domain.slice(begin));
+ }
+ },
+ domain_inversion: function(domain, symbol, context) {
+ if (context === undefined) {
+ context = {};
+ }
+ var expression = this.parse(domain);
+ if (!~expression.variables.indexOf(symbol)) {
+ return true;
+ }
+ return expression.inverse(symbol, context);
+ }
+ });
+ Sao.common.DomainInversion.equals = function(a, b) {
+ if ((a instanceof Array) && (b instanceof Array)) {
+ return Sao.common.compare(a, b);
+ } else if (moment.isMoment(a) && moment.isMoment(b)) {
+ return ((a.isDate == b.isDate) &&
+ (a.isDateTime == b.isDateTime) &&
+ (a.valueOf() == b.valueOf()));
+ } else if ((a instanceof Number) || (b instanceof Number)) {
+ return (Number(a) === Number(b));
+ } else {
+ return (a === b);
+ }
+ };
+ Sao.common.DomainInversion.in_ = function(a, b) {
+ if (a instanceof Array) {
+ if (b instanceof Array) {
+ for (var i = 0, len = a.length; i < len; i++) {
+ if (~b.indexOf(a[i])) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ return Boolean(~a.indexOf(b));
+ }
+ } else {
+ return Boolean(~b.indexOf(a));
+ }
+ };
+ Sao.common.DomainInversion.sql_like = function(value, pattern, ignore_case)
+ {
+ var escape = false;
+ var chars = [];
+ var splitted = pattern.split(/(.|\\)/);
+ var char;
+ for (var i=1, len=splitted.length; i < len; i = i+2) {
+ char = splitted[i];
+ if (escape) {
+ if ((char == '%') || (char == '_')) {
+ chars.push(char);
+ } else {
+ chars.push('\\', char);
+ }
+ escape = false;
+ } else if (char == '\\') {
+ escape = true;
+ } else if (char == '_') {
+ chars.push('.');
+ } else if (char == '%') {
+ chars.push('.*');
+ } else {
+ chars.push(char);
+ }
+ }
+
+ if (!pattern.startsWith('%')) {
+ chars.splice(0, 0, '^');
+ }
+ if (!pattern.endsWith('%')) {
+ chars.push('$');
+ }
+
+ var flags = ignore_case ? 'i' : '';
+ var regexp = new RegExp(chars.join(''), flags);
+ return regexp.test(value);
+ };
+ Sao.common.DomainInversion.And = Sao.class_(Object, {
+ init: function(expressions) {
+ this.domain_inversion = new Sao.common.DomainInversion();
+ this.branches = expressions.map(this.domain_inversion.parse.bind(
+ this.domain_inversion));
+ this.variables = [];
+ for (var i = 0, len = this.branches.length; i < len; i++) {
+ var expression = this.branches[i];
+ if (this.domain_inversion.is_leaf(expression)) {
+ this.variables.push(this.base(expression[0]));
+ } else if (expression instanceof
+ Sao.common.DomainInversion.And) {
+ this.variables = this.variables.concat(
+ expression.variables);
+ }
+ }
+ },
+ base: function(expression) {
+ if (!expression.contains('.')) {
+ return expression;
+ } else {
+ return expression.split('.')[0];
+ }
+ },
+ inverse: function(symbol, context) {
+ var DomainInversion = Sao.common.DomainInversion;
+ var result = [];
+ for (var i = 0, len = this.branches.length; i < len; i++) {
+ var part = this.branches[i];
+ if (part instanceof DomainInversion.And) {
+ var part_inversion = part.inverse(symbol, context);
+ var evaluated = typeof part_inversion == 'boolean';
+ if (!~part.variables.indexOf(symbol)) {
+ continue;
+ }
+ if (!evaluated) {
+ result.push(part_inversion);
+ } else if (part_inversion) {
+ continue;
+ } else {
+ return false;
+ }
+ } else if (this.domain_inversion.is_leaf(part) &&
+ (this.base(part[0]) === symbol)) {
+ result.push(part);
+ } else {
+ var field = part[0];
+ if ((!(field in context)) ||
+ ((field in context) &&
+ (this.domain_inversion.eval_leaf(
+ part, context, this.domain_inversion.and) ||
+ this.domain_inversion.constrained_leaf(
+ part, this.domain_inversion.and)))) {
+ result.push(true);
+ } else {
+ return false;
+ }
+ }
+ }
+ result = result.filter(function(e) {
+ return e !== true;
+ });
+ if (jQuery.isEmptyObject(result)) {
+ return true;
+ } else {
+ return this.domain_inversion.simplify(result);
+ }
+ }
+ });
+ Sao.common.DomainInversion.Or = Sao.class_(Sao.common.DomainInversion.And, {
+ inverse: function(symbol, context) {
+ var DomainInversion = Sao.common.DomainInversion;
+ var result = [];
+ if (!jQuery.isEmptyObject(this.variables.filter(function(e) {
+ return (!(e in context)) && (e != symbol);
+ }))) {
+ // In this case we don't know enough about this OR part, we
+ // consider it to be True (because people will have the
+ // constraint on this part later).
+ return true;
+ }
+ for (var i = 0, len = this.branches.length; i < len; i++) {
+ var part = this.branches[i];
+ if (part instanceof DomainInversion.And) {
+ var part_inversion = part.inverse(symbol, context);
+ var evaluated = typeof part_inversion == 'boolean';
+ if (!~part.variables.indexOf(symbol)) {
+ if (evaluated && part_inversion) {
+ return true;
+ }
+ continue;
+ }
+ if (!evaluated) {
+ result.push(part_inversion);
+ } else if (part_inversion) {
+ return true;
+ } else {
+ continue;
+ }
+ } else if (this.domain_inversion.is_leaf(part) &&
+ (this.base(part[0]) == symbol)) {
+ result.push(part);
+ } else {
+ var field = part[0];
+ field = this.base(field);
+ if ((field in context) &&
+ (this.domain_inversion.eval_leaf(
+ part, context, this.domain_inversion.or)) ||
+ this.domain_inversion.constrained_leaf(
+ part, this.domain_inversion.or)) {
+ return true;
+ } else if ((field in context) &&
+ !this.domain_inversion.eval_leaf(part, context,
+ this.domain_inversion.or)) {
+ result.push(false);
+ }
+ }
+ }
+ result = result.filter(function(e) {
+ return e !== false;
+ });
+ if (jQuery.isEmptyObject(result)) {
+ return false;
+ } else {
+ return this.domain_inversion.simplify(['OR'].concat(result));
+ }
+ }
+ });
+
+ Sao.common.mimetypes = {
+ 'csv': 'text/csv',
+ 'doc': 'application/msword',
+ 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'gif': 'image/gif',
+ 'html': 'text/html',
+ 'jpeg': 'image/jpeg',
+ 'jpg': 'image/jpeg',
+ 'mpeg': 'video/mpeg',
+ 'mpg': 'video/mpeg',
+ 'ods': 'application/vnd.oasis.opendocument.spreadsheet',
+ 'odt': 'application/vnd.oasis.opendocument.text',
+ 'ogg': 'audio/ogg',
+ 'pdf': 'application/pdf',
+ 'png': 'image/png',
+ 'svg': 'image/svg+xml',
+ 'text': 'text/plain',
+ 'tif': 'image/tif',
+ 'tiff': 'image/tif',
+ 'txt': 'text/plain',
+ 'webp': 'image/webp',
+ 'xls': 'application/vnd.ms-excel',
+ 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'xml': 'application/xml',
+ 'xpm': 'image/x-xpixmap',
+ };
+
+ Sao.common.guess_mimetype = function(filename) {
+ for (var ext in Sao.common.mimetypes) {
+ var re = new RegExp('.*\.' + ext + '$', 'i');
+ if (re.test(filename)) {
+ return Sao.common.mimetypes[ext];
+ }
+ }
+ return 'application/octet-binary';
+ };
+
+ Sao.common.LOCAL_ICONS = [
+ 'tryton-add',
+ 'tryton-archive',
+ 'tryton-attach',
+ 'tryton-back',
+ 'tryton-bookmark-border',
+ 'tryton-bookmark',
+ 'tryton-bookmarks',
+ 'tryton-cancel',
+ 'tryton-clear',
+ 'tryton-close',
+ 'tryton-copy',
+ 'tryton-create',
+ 'tryton-date',
+ 'tryton-delete',
+ 'tryton-email',
+ 'tryton-error',
+ 'tryton-exit',
+ 'tryton-export',
+ 'tryton-filter',
+ 'tryton-format-align-center',
+ 'tryton-format-align-justify',
+ 'tryton-format-align-left',
+ 'tryton-format-align-right',
+ 'tryton-format-bold',
+ 'tryton-format-color-text',
+ 'tryton-format-italic',
+ 'tryton-format-underline',
+ 'tryton-forward',
+ 'tryton-history',
+ 'tryton-import',
+ 'tryton-info',
+ 'tryton-launch',
+ 'tryton-link',
+ 'tryton-log',
+ 'tryton-menu',
+ 'tryton-note',
+ 'tryton-ok',
+ 'tryton-open',
+ 'tryton-print',
+ 'tryton-public',
+ 'tryton-question',
+ 'tryton-refresh',
+ 'tryton-remove',
+ 'tryton-save',
+ 'tryton-search',
+ 'tryton-send',
+ 'tryton-star-border',
+ 'tryton-star',
+ 'tryton-switch',
+ 'tryton-translate',
+ 'tryton-unarchive',
+ 'tryton-undo',
+ 'tryton-warning',
+ ];
+
+ Sao.common.IconFactory = Sao.class_(Object, {
+ batchnum: 10,
+ name2id: {},
+ loaded_icons: {},
+ tryton_icons: [],
+ register_prm: jQuery.when(),
+ load_icons: function(refresh) {
+ refresh = refresh || false;
+ if (!refresh) {
+ for (var icon_name in this.load_icons) {
+ if (!this.load_icons.hasOwnProperty(icon_name)) {
+ continue;
+ }
+ window.URL.revokeObjectURL(this.load_icons[icon_name]);
+ }
+ }
+
+ var icon_model = new Sao.Model('ir.ui.icon');
+ return icon_model.execute('list_icons', [], {})
+ .then(function(icons) {
+ if (!refresh) {
+ this.name2id = {};
+ this.loaded_icons = {};
+ }
+ this.tryton_icons = [];
+
+ var icon_id, icon_name;
+ for (var i=0, len=icons.length; i < len; i++) {
+ icon_id = icons[i][0];
+ icon_name = icons[i][1];
+ if (refresh && (icon_name in this.loaded_icons)) {
+ continue;
+ }
+ this.tryton_icons.push([icon_id, icon_name]);
+ this.name2id[icon_name] = icon_id;
+ }
+ }.bind(this));
+ },
+ register_icon: function(icon_name) {
+ if (!icon_name) {
+ return jQuery.when();
+ } else if ((icon_name in this.loaded_icons) ||
+ ~Sao.common.LOCAL_ICONS.indexOf(icon_name)) {
+ return jQuery.when();
+ }
+ if (this.register_prm.state() == 'pending') {
+ return this.register_prm.then(function() {
+ return this.register_icon(icon_name);
+ }.bind(this));
+ }
+ var loaded_prm;
+ if (!(icon_name in this.name2id)) {
+ loaded_prm = this.load_icons(true);
+ } else {
+ loaded_prm = jQuery.when();
+ }
+
+ var icon_model = new Sao.Model('ir.ui.icon');
+ this.register_prm = loaded_prm.then(function () {
+ var find_array = function(array) {
+ var idx, l;
+ for (idx=0, l=this.tryton_icons.length; idx < l; idx++) {
+ var icon = this.tryton_icons[idx];
+ if (Sao.common.compare(icon, array)) {
+ break;
+ }
+ }
+ return idx;
+ }.bind(this);
+ var idx = find_array([this.name2id[icon_name], icon_name]);
+ var from = Math.round(idx - this.batchnum / 2);
+ from = (from < 0) ? 0 : from;
+ var to = Math.round(idx + this.batchnum / 2);
+ var ids = [];
+ this.tryton_icons.slice(from, to).forEach(function(e) {
+ ids.push(e[0]);
+ });
+
+ var read_prm = icon_model.execute('read',
+ [ids, ['name', 'icon']], {});
+ return read_prm.then(function(icons) {
+ icons.forEach(function(icon) {
+ var img_url = this._convert(icon.icon);
+ this.loaded_icons[icon.name] = img_url;
+ delete this.name2id[icon.name];
+ this.tryton_icons.splice(
+ find_array([icon.id, icon.name]), 1);
+ }.bind(this));
+ }.bind(this));
+ }.bind(this));
+ return this.register_prm;
+ },
+ _convert: function(data) {
+ var xml = jQuery.parseXML(data);
+ jQuery(xml).find('svg').attr('fill', Sao.config.icon_colors[0]);
+ data = new XMLSerializer().serializeToString(xml);
+ var blob = new Blob([data],
+ {type: 'image/svg+xml'});
+ return window.URL.createObjectURL(blob);
+ },
+ get_icon_url: function(icon_name) {
+ if (!icon_name) {
+ return jQuery.when('');
+ }
+ return this.register_icon(icon_name).then(function() {
+ if (icon_name in this.loaded_icons) {
+ return this.loaded_icons[icon_name];
+ } else {
+ return jQuery.get('images/' + icon_name + '.svg', null, null, 'text')
+ .then(function(icon) {
+ var img_url = this._convert(icon);
+ this.loaded_icons[icon_name] = img_url;
+ return img_url;
+ }.bind(this));
+ }
+ }.bind(this));
+ },
+ get_icon_img: function(icon_name, attrs) {
+ attrs = attrs || {};
+ if (!attrs['class']) {
+ attrs['class'] = 'icon';
+ }
+ var img = jQuery('', attrs);
+ if (icon_name) {
+ this.get_icon_url(icon_name).then(function(url) {
+ img.attr('src', url);
+ });
+ }
+ return img;
+ },
+ });
+
+ Sao.common.ICONFACTORY = new Sao.common.IconFactory();
+
+ Sao.common.UniqueDialog = Sao.class_(Object, {
+ init: function() {
+ this.running = false;
+ },
+ build_dialog: function() {
+ var dialog = new Sao.Dialog('', this.class_, undefined, false);
+ return dialog;
+ },
+ run: function() {
+ if (this.running) {
+ return jQuery.when();
+ }
+ var args = Array.prototype.slice.call(arguments);
+ var prm = jQuery.Deferred();
+ args.push(prm);
+ var dialog = this.build_dialog.apply(this, args);
+ dialog.content.submit(function(evt) {
+ dialog.footer.find('button.btn-primary').first().click();
+ evt.preventDefault();
+ }.bind(this));
+ this.running = true;
+ dialog.modal.modal('show');
+ dialog.modal.on('shown.bs.modal', function() {
+ dialog.modal.find('input,select')
+ .filter(':visible').first().focus();
+ });
+ dialog.modal.on('keydown', function(e) {
+ if (e.which == Sao.common.ESC_KEYCODE) {
+ this.close(dialog);
+ prm.reject();
+ }
+ }.bind(this));
+ return prm;
+ },
+ close: function(dialog) {
+ dialog.modal.on('hidden.bs.modal', function(event) {
+ jQuery(this).remove();
+ });
+ dialog.modal.modal('hide');
+ this.running = false;
+ }
+ });
+
+ Sao.common.MessageDialog = Sao.class_(Sao.common.UniqueDialog, {
+ class_: 'message-dialog',
+ build_dialog: function(message, icon, prm) {
+ var dialog = Sao.common.MessageDialog._super.build_dialog.call(
+ this);
+ dialog.header.remove();
+ dialog.body.append(jQuery('', {
+ 'class': 'alert alert-info',
+ role: 'alert'
+ }).append(Sao.common.ICONFACTORY.get_icon_img(icon, {
+ 'aria-hidden': true,
+ })).append(jQuery('', {
+ 'class': 'sr-only'
+ }).text(Sao.i18n.gettext('Message: '))
+ ).append(jQuery('')
+ .text(message)
+ .css('white-space', 'pre-wrap')));
+ jQuery('', {
+ 'class': 'btn btn-primary',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('OK')).click(function() {
+ this.close(dialog);
+ prm.resolve('ok');
+ }.bind(this)).appendTo(dialog.footer);
+ return dialog;
+ },
+ run: function(message, icon) {
+ return Sao.common.MessageDialog._super.run.call(
+ this, message, icon || 'tryton-info');
+ }
+ });
+ Sao.common.message = new Sao.common.MessageDialog();
+
+ Sao.common.WarningDialog = Sao.class_(Sao.common.UniqueDialog, {
+ class_: 'warning-dialog',
+ build_dialog: function(message, title, prm) {
+ var dialog = Sao.common.WarningDialog._super.build_dialog.call(
+ this);
+ var content = jQuery('', {
+ 'class': 'alert alert-warning',
+ role: 'alert'
+ }).append(Sao.common.ICONFACTORY.get_icon_img('tryton-warning', {
+ 'aria-hidden': true,
+ })).append(jQuery('', {
+ 'class': 'sr-only'
+ }).text(Sao.i18n.gettext('Warning: '))
+ ).append(jQuery('')
+ .text(title)
+ .css('white-space', 'pre-wrap'));
+ if (message) {
+ content.append(jQuery('')
+ .text(message)
+ .css('white-space', 'pre-wrap'));
+ }
+ dialog.body.append(content);
+ jQuery('', {
+ 'class': 'btn btn-primary',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('OK')).click(function() {
+ this.close(dialog);
+ prm.resolve('ok');
+ }.bind(this)).appendTo(dialog.footer);
+ return dialog;
+ }
+ });
+ Sao.common.warning = new Sao.common.WarningDialog();
+
+ Sao.common.UserWarningDialog = Sao.class_(Sao.common.WarningDialog, {
+ class_: 'user-warning-dialog',
+ build_dialog: function(message, title, prm) {
+ var dialog = Sao.common.UserWarningDialog._super.build_dialog.call(
+ this, message, title, prm);
+ var always = jQuery('', {
+ 'type': 'checkbox'
+ });
+ dialog.body.append(jQuery('', {
+ 'class': 'checkbox',
+ }).append(jQuery('')
+ .text(Sao.i18n.gettext("Always ignore this warning."))
+ .prepend(always))
+ );
+ dialog.body.append(jQuery('')
+ .text(Sao.i18n.gettext('Do you want to proceed?')));
+ dialog.footer.empty();
+ jQuery('', {
+ 'class': 'btn btn-link',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('No')).click(function() {
+ this.close(dialog);
+ prm.reject();
+ }.bind(this)).appendTo(dialog.footer);
+ jQuery('', {
+ 'class': 'btn btn-primary',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('Yes')).click(function() {
+ this.close(dialog);
+ if (always.prop('checked')) {
+ prm.resolve('always');
+ }
+ prm.resolve('ok');
+ }.bind(this)).appendTo(dialog.footer);
+ return dialog;
+ }
+ });
+ Sao.common.userwarning = new Sao.common.UserWarningDialog();
+
+ Sao.common.ConfirmationDialog = Sao.class_(Sao.common.UniqueDialog, {
+ class_: 'confirmation-dialog',
+ build_dialog: function(message) {
+ var dialog = Sao.common.ConfirmationDialog._super.build_dialog.call(
+ this);
+ dialog.header.remove();
+ dialog.body.append(jQuery('', {
+ 'class': 'alert alert-info',
+ role: 'alert'
+ }).append(Sao.common.ICONFACTORY.get_icon_img('tryton-info', {
+ 'aria-hidden': true,
+ })).append(jQuery('', {
+ 'class': 'sr-only'
+ }).text(Sao.i18n.gettext('Confirmation: '))
+ ).append(jQuery('')
+ .text(message)
+ .css('white-space', 'pre-wrap')));
+ return dialog;
+ }
+ });
+
+ Sao.common.SurDialog = Sao.class_(Sao.common.ConfirmationDialog, {
+ build_dialog: function(message, prm) {
+ var dialog = Sao.common.SurDialog._super.build_dialog.call(
+ this, message);
+ jQuery('', {
+ 'class': 'btn btn-link',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('Cancel')).click(function() {
+ this.close(dialog);
+ prm.reject();
+ }.bind(this)).appendTo(dialog.footer);
+ jQuery('', {
+ 'class': 'btn btn-primary',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('OK')).click(function() {
+ this.close(dialog);
+ prm.resolve();
+ }.bind(this)).appendTo(dialog.footer);
+ return dialog;
+ }
+ });
+ Sao.common.sur = new Sao.common.SurDialog();
+
+ Sao.common.Sur3BDialog = Sao.class_(Sao.common.ConfirmationDialog, {
+ build_dialog: function(message, prm) {
+ var dialog = Sao.common.SurDialog._super.build_dialog.call(
+ this, message);
+ jQuery('', {
+ 'class': 'btn btn-link',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('Cancel')).click(function() {
+ this.close(dialog);
+ prm.resolve('cancel');
+ }.bind(this)).appendTo(dialog.footer);
+ jQuery('', {
+ 'class': 'btn btn-default',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('No')).click(function() {
+ this.close(dialog);
+ prm.resolve('ko');
+ }.bind(this)).appendTo(dialog.footer);
+ jQuery('', {
+ 'class': 'btn btn-primary',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('Yes')).click(function() {
+ this.close(dialog);
+ prm.resolve('ok');
+ }.bind(this)).appendTo(dialog.footer);
+ return dialog;
+ }
+ });
+ Sao.common.sur_3b = new Sao.common.Sur3BDialog();
+
+ Sao.common.AskDialog = Sao.class_(Sao.common.UniqueDialog, {
+ class_: 'ask-dialog',
+ run: function() {
+ var args = Array.prototype.slice.call(arguments);
+ if (args.length == 1) {
+ args.push(true);
+ }
+ return Sao.common.AskDialog._super.run.apply(this, args);
+ },
+ build_dialog: function(question, visibility, prm) {
+ var dialog = Sao.common.AskDialog._super.build_dialog.call(this);
+ dialog.header.remove();
+ var entry = jQuery('', {
+ 'class': 'form-control',
+ 'type': visibility ? 'input' : 'password',
+ 'id': 'ask-dialog-entry'
+ });
+ dialog.body.append(jQuery('', {
+ 'class': 'form-group'
+ }).append(jQuery('', {
+ 'for': 'ask-dialog-entry'
+ }).text(question)).append(entry));
+ jQuery('', {
+ 'class': 'btn btn-link',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('Cancel')).click(function() {
+ this.close(dialog);
+ prm.reject();
+ }.bind(this)).appendTo(dialog.footer);
+ jQuery('', {
+ 'class': 'btn btn-primary',
+ 'type': 'button'
+ }).text(Sao.i18n.gettext('OK')).click(function() {
+ this.close(dialog);
+ prm.resolve(entry.val());
+ }.bind(this)).appendTo(dialog.footer);
+ return dialog;
+ }
+ });
+ Sao.common.ask = new Sao.common.AskDialog();
+
+ Sao.common.ConcurrencyDialog = Sao.class_(Sao.common.UniqueDialog, {
+ class_: 'ask-dialog',
+ build_dialog: function(model, record_id, context, prm) {
+ var dialog = Sao.common.ConcurrencyDialog._super.build_dialog.call(
+ this);
+ dialog.modal.find('.modal-dialog'
+ ).removeClass('modal-sm').addClass('modal-lg');
+ dialog.add_title(Sao.i18n.gettext('Concurrency Exception'));
+ dialog.body.append(jQuery('', {
+ 'class': 'alert alert-info',
+ role: 'alert'
+ }).append(jQuery('')
+ .append(Sao.common.ICONFACTORY.get_icon_img('tryton-info', {
+ 'aria-hidden': true,
+ })).append(jQuery('', {
+ 'class': 'sr-only'
+ }).text(Sao.i18n.gettext('Write Concurrency Warning: '))
+ ).text(Sao.i18n.gettext('This record has been modified ' +
+ 'while you were editing it.')))
+ .append(jQuery('').text(Sao.i18n.gettext('Choose:')))
+ .append(jQuery('