simple-po-parser-1.1.5/0000755000175200017520000000000013632502563014154 5ustar debiandebiansimple-po-parser-1.1.5/test/0000755000175200017520000000000013632502563015133 5ustar debiandebiansimple-po-parser-1.1.5/test/benchmark.po0000644000175200017520000012077713632502563017443 0ustar debiandebian# PO benchmark file header # #, fuzzy msgid "" msgstr "" "Project-Id-Version: somehwat master\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: last t \n" "Language-Team: team\n" "Content-Type: text/plain; charset=UTF-8\n" "MIME-Version: 1.0\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: m+h+H6l+o/zMYZ3FIGrCJRLOnwEpuIB7Bv+BmU0R/Q== msgctxt "AEli7osWHSRGFtzs0IqkZaigqPyaZwuDhxXdeQ2KY5oVelVnhgzu1bJGSMM" msgid "QtkIdWTljoOSLjOfPQismPI/IulEDxDq2oOpx1A2f05x2lnX6UdzJ/61QikXluSw5UnaRmwT2PevqzbZNlqElmHemnbAGeyD7Ixd6MryovaeBIIB/60Y1lKzH8NTm/L/Ts1Y3n0FLkISXwhqHKukSSCKmLJFjXRl" msgid_plural "yrt9qstDmENB3jiezA==" msgstr[0] "/zry7XukzOFCxC5uYeFf929pTCFhAWJFWp2OB1Bm2JhSb5M7uLcshXZY1mGiE6C1n2en5tNPyHfA/8hxr0spfQ9g" msgstr[1] "/zry7XukzOFCxC5uYeFf929pTCFhAWJFWp2OB1Bm2JhSb5M7uLcshXZY1mGiE6C1n2en5tNPyHfA/8hxr0spfQ9g" #: H6gVO/bfxh5UCRDw2Xz9sIyNo5oRxwrQJvU3MgnZ msgctxt "yWjZcO+zwP80XHIOd5LY2P0lGc5XH/Nf3FJWJVJdqTWb2O6wzVY9zqkNMNveu0szMNUW5s2vtD19RQ1G" msgid "5iMGZrIjcXPPnjQCmmIk2uOgrGa5iWNmYZgCSfw9XJEV6wLRX8CzGxzlZNYn2BzYKmQLyieZnKrzRhU1brN2w26odcwCgnZKu3klOJ2yEOJtnRC/E40zC6+t3Shu0OGF+I5fwnODFcN4nZ2nVg==" msgstr "Jpr5bTW6QBjLosltbBieyObSWZnkyZ+cfLlb9VSdXHNLS6HRWA==" #: aSD+youWGbj4dN1ZQI1XTjvhgj4cwTaA8vVQljMusoemN3lU0raoQQ== msgctxt "SoPybmFEnpJ3C5frTQ==" msgid "N5V7svBB0zMhJarlCDFOpBzLXt8LOx3vHbgNwLmIB0HzC5MfuoC07Z/HdoN4g7HhuS9jCWircg==" msgstr "uOl/2r0KSBNQ5dQ/L3lzJ3q/pb0sOj6MVAjhz3YaiUz/9GazgWMpX8zo7d96MwxucYXZFIfhTtSfHZCURB2wFRgAB2bxl29GnJzHOtjudWjKKtDK0Y/PPDwmkneT/lKH+kJ7pcbq5UGoAGFcm2a3OCCuGwRqCwWpGflly54K4CCxbKfzcA==" #: JrjroYo5lA== #: h1Y4it53IhP/WZvz3iVjaE6bKumuvSjQlsdMMZr2fJpwPbxKybkJKoOgeXOb #: DfiJuPy2dDZxteKOvjj+C+gbkt5j9i1/xtOSsymhpgDC4qIB/UFARrk1b9Doivy76A== #: LCZYHOHxZSCqj5VJcUEAOgtJpctcUfMxWvkc61X4x5GXRMB330mDlKO6xYQ= #: msgctxt "86vV6CdxDgiQJOom1F8P8tMJJKz/9o54j7LEGyPDPz0ZtP9q" msgid "mw/fkjvMpIG18ZrmL4kVbZaeK5nldXaIycd+1k0aAi81aJzen/Bkq7/epV1DH09LcqT9vqR0gNAgLbi9lLH/h+MPHL5b4zo=" msgstr "JGzpNzm1QZ6Mb9bYsR+eEeLic3H0SwnWXQSyc6nbFuYsQ07NqjUvr+STtFwrWHvwkrs4U1FCJlcoG4F7trg8ZJM=" #: kZ7OVSwllBbIbmpXP+85Bhc12jj05j4= msgctxt "h65Z0/lfDC+V5EYgvG6IJJ4fTbUwGnWhBdz+q5ea6Q5THeFG1FJEuhlsAy9+Q9foGLE=" msgid "wLiriIDgX5Hd6ThjK2GCNxz7h81GYrZdA4HyYZjroa0TYjhDFUQYSXvlan3IJr7uEn9xKcvLqp0C3Zu8TTMUMOy9VtJlVVdspJEv30mnIY7OmQ9gh/SEkK/o/Tcyy+kcRF5Lgyh1coQjTsoI7HkKfA==" msgstr "xb+yJHpjQ4Yujn5iQzIAxfb/5w==" #: EnthqvkNLwUiVfYEqaoyTq60uJgdlaOTeU2qf6kF msgctxt "9ihYCwlIEg==" msgid "AloClNt81srB2Op/gEoKap7QvzlMzWBXxMEWLyjI2bQZV3praFAT2jpYhfQmgzu4Wix2tAsOeZV6lZ1TcnRmuHXht8FLfE016Q==" msgstr "i+9eqs/otjcsICeBK5MEcfQ5hJOmP++ROezIMcPEWVOEh+XAT1brUoxfqrQAMefK" #: jg4iou6yKnWxlkOF5Hw50gBFXZuUaBRTCJ7XNHeEqikz msgctxt "9dPrCWJHJu9pkv7ioE0gmE563vhWJwoO" msgid "" "ZP4A+/XWGwER2cE=\n" "llqjEdZBpEpLdx72tT0I3M38kqWVwJnnkxxL6nJslKC6es+nfci4\n" msgstr "" "sKNQ7Be/6PUKvxMOEOVGtLIRFByih6tvt47hxGW0EqLU78FZMAbx7u6RBUZvghqjG6c=\n" "BwyW73h+yBRohS0dzkg1GQ7f/oWOLKdA2lIDYjYrhWu7BNpb7yeu4ZPUlLvswTLI8mKmGqOUxQ==\n" #: MH2Nksc= #: 5M/f74zFJJTCW0A1/AZBW2EuESg3ZvnRzMkOP0kBJ+OtRTdk7w== #: 7QJjYuJkkqmim7AYvw== #: qMi3sM3C9kNHnGxUN+AznU5Gogo1JkWOnhhpW1jtG7F/UQ17 msgctxt "yllw6Az6BJFY9pFcI3Iu0S+wlkE2W+m8RKb/T/zfYT07cKB+wqrROZGKyop9ghQ=" msgid "OcX+h/Sm7Bd3dzrOE/7TMWZuFo9PuOyIMCcpeTnvp7xqnQ+nwNduH76FoTUXFbs+Bp9QWpfILppFxhKLo4NQgOrn/a7kZ4TeDDJBc5OO2x/Ruvfi4/ZOVhIGhWJNcNsgeBGbo7zrJ1dp40EDvflwQdNTyV9wA5HwQCrXXdwnAwO3ZRIWvA==" msgstr "qnGx/OS7MCSaIQafZY0ouNaGhxjSMdHIIBervBHxXr5KDSNcYMiEOtTZ9s2ubuk8s0JqRNCuxZXtfedVzMMd2f+7IIKLfu38Krun+8Wh44jgOkHF7c8Z+3dTOsP3+6eJOA==" #: er0+DIITT1z9VNOWNQ0= msgctxt "f3VqFzn9TODhG6w=" msgid "h/HRX1b5kUJPMJQ0VnoIlbqLjjRGxU9oaaXkcMxC2jrSlSmbWEJy7hCmzoxftdm/M6pRYYWE5JSCglv5SKDCaCx4Pw9PbBc3KDe9QOREEupCfcC4JlA3Bm9TFTEAGs5rPpg5HrsB7gMY0pBSltFBIJe+LQEYtKtFLiSHg8pkl9lfFD/1NJpMjQ==" msgstr "j3ntorS13hLFvoFIGPzPjBS5oz4yMW1PhcnOzu0yk8DUYaudGlgo2Ggt0M/6EwEDFtaHzyLpGHduFZybH8JamqrLjAlI6W1GmHVpxIS9CGPepsN/nlJw" #: r2+DT8AHAaoqJacYykjZZzQXct8Gmw== #: AJyA93ZRj+1V7+xyZeWLFkqdPNGfgYG6/TaHbtCf #: sGNU9rpwHacu4rjaHnCvM3+fCnVypsFZlZvoPy1PTiNY #: oRITXeQh9W112xNTSQ/cnkzGPhbBkiaLaLhSqTu0IzjWweU9GBgfBaA= #: /2QiHyb3yR6gn0ipIiNoJXFgaSv9dPEeagzvGcWUPAaYAAboFUb4ZAzdNh1e msgctxt "fIuWrJdsJ5oTwkG9tckouFrtUU9ceKe0wtY2qUpOGHyGT0qHZnI00OUM1x5H3wM8XflgEPGIqZWbAg==" msgid "kQoSwDQ76dGK6G1dqFEkE618nsPOwVCtQ5mh0m4DeNCs873riRFwCqo0K1yKFXYy1z0wJSTft7YSlJN05m+MIo98x81W3VDSZLvS44+IVUqrsIT2HbPIOtnADq8Cyq27z5G7kcfR5rPloOTCfLruJ4KyuDjuZs7hHw==" msgstr "MKDopDznYZB0I8k3DcjAjJcF4aPjEDg/utJJqAnXvjT9PBSvF6j2b+AfegrWGL5+XmQZuy4/eDv+RzzsZP/ilES4mmcK6Lx7+6InzwVjL2H2glr9R50fHmch9Jru5qtT+/s=" # FsIREQ6GmeuuEEZRnvRPUrXKnwfYqKm3 #: 4V9RQPWuJ/yQU7tUY6UNwV/Icg== #: oH1gNGhxawtCS8lStY+8HWxdr1o1FbeFGZ8N0RGLuFMzL5W91F34SEUtkn4= #: T8vFX0jPQZrnpd+i7GO6foNYfzDSBftKoRkG msgctxt "LlwD" msgid "EaDWzP75TqTaTlxllI9sUcLG35qi2yUs098RCJshJPpZX2H7Xq5B9oitC4K4WeLXnH+YjbQMBj/5xnx/A8TJt7wS00s1S5bt7tAZvsT1wlIPTcqzF3kbcZlr2KxsNLYtWlAl/kprM26/mBD7Wl8SqertBRYb9J4UxmgR7jh5AbXsr7FAHmaDRYcK2lo=" msgstr "Kc1i3RBhSUmvxFhHFiUhFzj5THt8SlfM" #: A+BM8WwEzij/Ic+s msgctxt "nA6v" msgid "3c5Rq1GsjWVJpiAdrFXuwPpPhMxezuRGufJgfy7v9Qg+qxPqxajOggUXkDpoByJfHbDcl/2o/ekpdzZcjHUq/A==" msgstr "o6CJxxELvCx0BTed28R4cQfgNrw5ZbAdHmSb0Igm6zxiBoRZ84RMsUM3U1Edl9bn+5pU+4DPOa56kMwd99M=" # ko0C8GP3GSfgkYPkqYbtO7CZ7r4h4wTQDWoBrzDP #: UBtoNWKSXrONTdtsvF1n02Iu20V+QUXb9O75cA== msgctxt "NEvWfLxim0Fnwjh6J/l0PHuZ7nnijBzBWOvqqW2lfLsTAmV79OhjKOovYKJY3T+V94cys5BeGiYw/N+nSZZz1Sy37B7z" msgid "" "d1WC+kZdA+D0jVisnx+ymnLh9LR+jjmA1ZBZpGE=\n" "Hcy5hG46Pw5LagQkiGM/L2vyOY+8OistQm4txtlEKgANKsYTIoNnG6BLeqMm4Q==\n" "ofroefaklot4zV0wFUEjfFDw8g0Qewg=\n" msgstr "" "mU7Ueamc4c/AyXVDBS+J\n" "yJ5kTojgFaI/cu+0nX75g3PJtbjN2iZwI8fOnhbMUzsQgSibY3ptjYm8USvZrA==\n" "EtOkGXeeJUcdZ0s7Ct0boV36/wkPvhixOGcKPMb9sdV47FVNouROrajL1vNAoucg\n" msgctxt "z/Q344KKdA==" msgid "oRzH51UpKW7g+XGe0lg7W6JupXCceNeKV2VxuREUhveJD+a/0GnyhfKpCdqRnxvSN71476b3f09fDfo6KHrVCRB+dxNZ29XmfFy71my8VaI6tbw=" msgstr "ywlF4ijXBLqXN6V7mzMklik/28CYOa7X0CJY62F8nhq+kreBMIAFnQLyrk0/Gke6VhN/DgvCPJKmFQdt9Nz79GOqxpmkXc/QnhGj60PpCYxMgP1rBiDKzfWRVjikPHfrdMH/RDlmGQ==" #: uoY5cWc= msgctxt "GW6HhhqPAGtGIoTFKH1x1ukHrqwY58qbQhlOyyZAb6FRcz2Eo2PsIIDPYg==" msgid "" "m2fR1pNEdWvpfAOzfrPzpHoJg6LT6oGcbicp5lxwtPhZBSf6BVv71wZL4A==\n" "9/+fq1KCrIOjEeCewc1uUGJp0hq4f4afRwNsbie/vW/Mbd+wXIpeSToA9tC7pQ/NkCTLrT86iTyv\n" "tLST7E9yOGENqTbUKwCpkttP5xTlxY44szJ81Q1YLfMJKOYp\n" "qMUOqTE0m8rMpw65q7G8jtKTOtCXinHK1YLrNKML2nLpIyPFoPqkzOShJxivKQeyqRPBFXtN1mhi+U+cfl09J9kF0TNL\n" "LJM2\n" msgstr "" "WdeY5Dg=\n" "SKZCMv0OfyEG+/fnOCanWNJQG/VlXaZ8AEP8kMwdjElKAikkeJbqHjF6AkPI+HBdn1eXU31iDoXTPYE=\n" "I7/geEX7KzOANQOg5Jbycc8/n5w8ytVVIGb0MXkAHlEPeqMUmxYManuk1NqOFscxn/ObUK8wZRXUBu8GcBM=\n" "eZncBSVvNOUWLxI99UIa2wfrwpkNBBe36auToywVpoc8jE+pVXdG6gmhYx5AGV35x0hdUg==\n" "7dWKqfpjvwoElyseHz2iVdOF07AEd+2EoaztqBdzJOzVRS5e3JhxXcPoMw==\n" #: F9DAFH+Ew8kh3bpXprtJ6HU= msgctxt "A1WDJiSQ4m8auFfuWs9AJiSK" msgid "VklPIdSp3LaCnT1k/ZZ5s8IUS8jvAIRjlliWDOWXiXZMiA==" msgid_plural "6/ddSF4GYSGJmWmrbpxuB6AnwG1WATc2UXlorB76a8Kvqs/JCN4UR2AOVEBgVdbPl1635kv5FsxewguUkMPH9sv3j+t7i3m4QmZluJTx0db2rRJcwY2QYhiPalWtR8IddSeQsVd0NV2m0NNpPCwITAyoGKY=" msgstr[0] "G2QscJ5Q3W2vAHnyHVCHy9RIFNaCLg9DTVr3Dv3CPfgEMBTuKAdZCOxP5Te1A9vW" msgstr[1] "G2QscJ5Q3W2vAHnyHVCHy9RIFNaCLg9DTVr3Dv3CPfgEMBTuKAdZCOxP5Te1A9vW" #: omc9f8DBncegJOK5zW/L+fjquVG07L3GG3HVaQ== msgid "00xLwPsVgSH8jLCn/YtqasW3PDizVciQVv6FVHq2xhbAAUK9c1U/RIlmHosVToC1b0nPpvy98rUn4X1Y0b2/fFqtZ+dKBQku7XK5O56zYiUoZgUCr5O+8U+XTsu3lPFgMjDaEpl3bw9n01KNJ3andk6XdeFBOGJ0/ADvQC+7Z0a17gSdow==" msgid_plural "hFmonbo4pdSMhtLvVZ81PHV7ztyJ3pMLLZQKRzA+4E6NRD4zSEpI7ZAm7581dIAE8D536EdUGSssF8UaJDNUM63hVT83C6sx5Yo4Xfa7LsViZjeLqGFgdMosohFqLP/qQeS6DzRhp/WwtJ6bjZ1/ZFOQJ4kQ1FVJdqgJVF24hoMjMP0z" msgstr[0] "v0xhFig0flhYswpPfXRuyfHqL4ilFrq614foWCimn84EMbrqlskW83+vdQmvoM81CpjGyXs14x7Gog/g3MbLMscqvQI43wBzdx5OrmBrtkBaBPCUhs1ivZpzuOgTF3tUQSdmhuqL1VevreadVJjUVlX2ulSy0R+Nk+gt4PDeJpq7Y7iR1v5dvIEpYHgZiOj1" msgstr[1] "v0xhFig0flhYswpPfXRuyfHqL4ilFrq614foWCimn84EMbrqlskW83+vdQmvoM81CpjGyXs14x7Gog/g3MbLMscqvQI43wBzdx5OrmBrtkBaBPCUhs1ivZpzuOgTF3tUQSdmhuqL1VevreadVJjUVlX2ulSy0R+Nk+gt4PDeJpq7Y7iR1v5dvIEpYHgZiOj1" # 4BxJN8D2d0xZNy80odgZcubVkvJx4MZgWX+Y1bnwad+IXMHeSKNYDQwwhQ== #. Yg== #: Me0L1qmKXj969EKqMfTno0boh+kYfyCEgO2qdw== msgctxt "gZ7Cz7B5Yka0rzG7SZDhGV+hVFfmGfA97r7AIrfEFOcv0E+0hub/zNezQQ==" msgid "jvVE30uDPlGrP8EO3uL4M47HfS6DIBILGhjIiaxI/kAYZ8QWWeTYpF/AyHRwcBCwrXeof+zd4AFtUOpS6mkJ2FoXnNa6hBhkM+0G3o19U/MVC06egiOoPj1Rp19YJ+Wrc5lpQtaNQRdkz5/13V6adOU=" msgstr "JcOB06OlFxP36kMvbpe5S0WKPdFHmkDeK66uyBkF8HTixJuRWcXt4raLQjISlKDFzVbOdR3OYZHUuMvmK9J+PZuJ6FyP8bYoEjsSYFnT51R3itE7+9fzCAAJoZ6vvDKwYgKjktGujBCXEPLSgkk=" #: jAOjaZJQfKa7E0MYZEusbJvs+Mbk5q7Jr5XJPlLAWzKjmQOvknjt msgid "" "xec4VRPLmWbCpouWAG4x\n" "IqtQST1aqktHTMAms3IMfOAM22RzMOrjQntng5dGF+ah9TVedNddf0ECYxpvMuphpEYE9msF+jwaMlTm3f+GsqArTBg=\n" "QCevcHTPmHeqoMSyZTlLgNd9gmQsjSEVI/iJ3mUq0Pp52xAo/d6DMR/n8wyL3NZ7wHcAAVAd\n" "//E6O4Zd6B41MeJzUtceTtJI2a6w3YOWAdBlUkO5y55ALmnkYVHEc55GPThCmA==\n" "gZykQfM=\n" msgstr "" "LYgAQPrAsh1U1gtK1IXUzxw+3/KiDPrFrZYIVUrYU5i1zhCPUjJaCxzPmuzZmEvIPp0RVrKPnB1yb7E=\n" "yYIFbVdRQhUgW4e0OC3T6sql3ZGomN71F8YtTPQ31kL71Hz44w0KcN356itqfytH5Q==\n" "K8EBUEhQiuKXhVf8SqhbqiWavhV/DL1fKPRX5HJCIOZmEb+SJ89Rou0GMdr3\n" "jGwSH+MSgbcrgZSBTS4ODCysagfY2wQW37Y=\n" "yuDTLQ8EeSADJwkYarUPtQ==\n" #: /YM0mzd+DHy7pzRp8LiFgtFOdOInm0coj2f0slhdTXahMv+9eEXuDvl3 msgid "" "u5XDqaPKqXgoDRorNSWRqXqVHmLhUlCVUq4xQljdG95xjdxjGuUH9wIIzVhKqqi8\n" "R0yYbJmaVzEj00k659iP+R/f9l7k29qC4SAKvQ0FJ+IpdH3NkT76+Yzs8uJu1cLk9n7GsZc=\n" msgstr "" "Dg==\n" "FvJ+zE5odXB2r5OSlXkKT2l8NLd5APHEE8DzYIFs4W8vimS2588dmGZV1Wt3BbhzTHQNULdtI1lFMd7smw==\n" #: YJbn5MrPiw== msgctxt "tulXYxrUOIKP28lzFVmwWyMoEJ5qtifSRJerUBxHhdSNzJGYFoUNchsPohUz7XgbG19tGM/PPuRqdwA=" msgid "9XdITszHCaQcG2V1ozY84NUHIJV1SJppnDmEmJucjp4PqO4hvK/6LfpHoXD6Ty3Vv0ul+OAgEi4X7+Y/sO1WYbzeVAh5QKqVrdJMaob0g2mTBVxJB/f8h+6u5DLRVUuLjW32K+lkTNzDty16ElXtlnIvmns4PHDjmhCj26Li" msgstr "WMuC9/EliSWHmn+0O8+moDiK/wDDk2wYuKBkNR8tyVnjRQqS+1h1qYueX4TaeNyKnyTlrH8/gJRwRqZI8mAL64LALqWc4YP/DAyPTxwqshVzVpV+d2Dr9ImuKAmqux0vAtGqa94dt0VF/QGSNSCuM9ZLxg==" #: rWp112wGWYkIRAFOkds/J/XRMqWgE8GyM6qmtFRR msgctxt "094CwanGlFvGHaWgdO++etQWWxqCpZrKSvsrJb5Y9UKt1oE3" msgid "xC8FzBjBZV0mdudhDfuzgIjRdfH5POWHxN0C8u9X6TW326t79Lf2fmhsxLUR1rNGmc/a9b1ICZhyoRsrpMVhaalk+JZtGFMPfwwdJI/vzPwL" msgstr "FwI0qOY9ntkesmN7OVn2Ls2zKJsi/uOO2oGjhg==" #. ScA2De4a/31qTRIByA== #: kfHvIyB1cKX/osgk5vX6SG+URoziPCl+tPZBgURD1ymfeh9Owt/w msgctxt "qkdpxmLbmdE8uk5026Wfk3+BGdoE25lwnp0ka3SLfHFx" msgid "r4HcYmUTiOU2h4eL0J1GFNsPqS0PdJ0=" msgstr "vTJcbHaBk6Z7G1TQcyHsDuQ=" # qEcHBMQKiT2wqzlXX1jQPaQDQgRYgGcbyJkxV3sBxRWebkYXwftcKtFyE30= msgctxt "8Gl6N+JZ9KkBiwLjOssqKsptv2nvyohNFnyn31KfMzhQXfYDH7mLNAOvd35Gp0FN0xyOdIOZsFehgTRbyA==" msgid "rVqqNBOUG5hBWM+XWckqDOyYXRNTox6M1xm5jdJQJoegg/1GnVqWltoIXurOucfnIu0Z9wH3zLNx/nB5mW/BkvbZ9PJl0rIA5KhRD5PolF449jrrorygvOeACXF3ma5tXY+prEsdmIKubc5nqXfVnIAxPsPxI9ubRX1s" msgstr "2n+iUL8mGdOmuGWaPFYEKQjs" # #: Hs3jLKTiTeHeRyCnYL7/hnzlpm9zXgtU+qi+qE6JSplkQg== msgctxt "J3FqLpkySYs=" msgid "hVatPW31M8ycJkYTD7sZviA6scSS6UqeMDgF3MS9Zx2wXSuSrriSlQEbQb9Z3TCgwpcfQYowbErMvUex3lEKvgKmpElrIBv7LHIxoEjDr18gMG63cd9ZKcGtVH/r+HbabLe6HHIgyz/u0T0jCBe5v1qzr7las/o7VTcWiSYANGy5LfEjGWC0wfSU3QPJCeC/p2k=" msgstr "oSzDbUeDJ91OmNWInA5jKvWMEsXrQHLrcFTrCILkHodAi+Z+J+9UHtvOJz8y3EUNHlTzpGO/oslPzVIBewdzD6NFTJHphhTiSJo8IMoenF+eTw5i/ZF6D1psqmFECY0i9KeFsn7PGOOYSHb0pQhIb38=" #: CDT9SNbvO1UqvK4zepP2DSZh014ida09/CzJ32mnYFKDpQ== msgctxt "5s+YJUI3oR3ks8E9J+Jw96UGVJWeTbMxYt9Pmwr88fA4VpU1" msgid "+dNPLRODNoh+bEfurnrfZyW12ztIXFTt+CMsdQDUSBVUvVbPlJyhdPDSXOQhHipeA4wCPpAOaAS0k5gxFGl10o9OapUmeaq9PjE=" msgstr "GuLEnnavKW5BGn78o8NjJX9Pqq/Uk7Yt7kcErHu4GnV5VpW/jgx+tsZHJ3uA/TURs7Gzbg8Wmhn4H1abQtg=" #: amLa7A1OJ2aEV4vBDfpWFFg9s3M7gLNkLUXglJK3KNbE msgctxt "fL3MmMTNFUaUU3hYkZaonW01njtGyL9F8bMFLaNiMUBgi190zILvO3oCM7nWSq8hvyJHZ5QaGLmyhXQ=" msgid "VxPWBFQrKc6wgrHyiQv8aDlLw6SKmQ5glBd2dHe1BXfOvc7VmKs02VqVLx/RyYFlbBflae+guM6m+GjXND+saOwDxE7A6FacOjpvXqqZAcAsr+JWbogR5v23nKNia38ZcaCW9y2YhPC8ltBvp9ug+XsenBmgUiloFf5veDPNDpsLDLUJVQ14+CzIWtr2" msgstr "QdHYGMiqjk5EfiQFSoC3ghBFVw==" #: KBcX0L2SNnFupJo0+RBPJSQHzgB3VA== msgctxt "P9JbeLjSjBM=" msgid "ZOE7+h7G+CrstUkN65eNau2oRm5HAr7oZo8eiw0CKnYv/D2+gpFy8A4RSBA=" msgstr "tUBxSbzYWm460Mjgn+p/sYT+ELiw0iL3KDgeKfVN9GCdwDfCHWAzEh9mS4cOLIBYSgxg2cYobf3jH7o=" msgctxt "ZeXhTsGFW0EC3ZATVm1FngUefyuGbqhVZMB/eNngSYVM" msgid "RvRQgTx6A5eAqmAgqG0EAVgyvxuuAeGP9zZALcKsI9jEypWkHw==" msgstr "WK+1t/zdp0MQeC+71tsqTi8YFhEIi94vyvEtqzGviEjGE57I146uoDyURhiPsH5nyJnIEcMZcHE6z0D+bqoO/pxOGRSO" #: /GlLn3327KLA0vU= #: x4qD6iMegwQJw54UmqoUi8I6lf2g #: OslaXLhogK7AI9qKfUOMmzis9Xk8/mZga9GWAliOhpiz msgctxt "uvzG6ZjjOePlKsXb4QfAZMOtHBSeFVr18xR8x+mLxLeDZicBfh+P97fijzVl6FYPvK+Aa+XNbVOG811JORyiXQ==" msgid "40UHEyi4S4HyCWQ2FKwD1+jTrfboYmvx6wvOTsOn6JTCVbF0i4GA3EI0gboMCci05R3n+d7iNjLynQX77aclXFwIBGGpYEKwj4dWgz8KwGe+ZeaK/GryXePViOpzSdoX0h0dbe39jzyEHMdgmHkS22Yl+csLe+P55wiJRcg0jRbZ/Wx1f0g=" msgstr "wXhIZOYst1SJiEW+UiTWIYY94KDBaeU38CEJrWQmFWHDi5y8EGn89taKFFzKsF84T9Ein43Nb7AbBvUJbnsDPmctner/zQl1LscjWLJ2R7hU41NxScPbgtYQyXaso2EHdryGL3tMKCu/dqY5fjbUoSxoJB8MBqaZJSk3UpQwth75gdEk9g2iZivRgzqsnFo=" #: Ldl/vbnGLrup4+Veg7D0Jw== #, fuzzy #| msgctxt "MA9kQYYzgrRH+mWbBpq2bt91RtBbPapR20xjUKQT+HKvWR+IBZ+oBiaCQ7SlmhEgcTOic5T99bndh1lqN/iTXc6J" #| msgid "P4Zczd04O+j+Ay5nMS/1QKxCOBF0Tw==" msgctxt "MA9kQYYzgrRH+mWbBpq2bt91RtBbPapR20xjUKQT+HKvWR+IBZ+oBiaCQ7SlmhEgcTOic5T99bndh1lqN/iTXc6J" msgid "P4Zczd04O+j+Ay5nMS/1QKxCOBF0Tw==" msgstr "" #: VSgljGtOKqJwDixRyF3hF3+F msgctxt "2Ro0SomI08IcYRmaR0kDO/BbyHRl0sXOKm0Y5B9Uy5i1TLvquWSf5PIP+hy/dO+p932ZWCAVTZoQuKM4hFC+" msgid "vPbr7yTqZpI3z94dj7g=" msgstr "z7xy5jOdBz5P+yTz3yfy3IV5wP4jzktRoB+lG5oKlblun/TKdl6nSaBQL6PwTJ/0CqpH83L9aTM7gVF7nx4wQFZrC+iifUlSM3FU8JAmLtiHBKtdP3zUorcU4sT7HyE=" #: lpYbZT1qrSeC6DBwqhUnmyCmVqGCZbVOvywqq1C7ZoPh4QhqSfwIn7RI1ez5gQ3x msgid "x37TxY5LT8r63WITLOcb2LsVCM1usBsVq9KSVC+aKO5pMvE0OUjbCIhtvroRUVEtVj/N83jmQb1zHwHOKtpqhaLGYIgUgtHDdkREOzRNUPe1Rdxsrqjv7votqdrc4Cnw9nVp4xkVAf4=" msgstr "EPRFFO+8hPv0C4jwApJ9sB5VbQuEpBjn3+R9KdV7toHwaxDEwUTVzvbS0wne7lXkcPPLX5ShU3FUzfB1g4sCvJ7jT4V7/EJpMP3Q1+Wf9ksg7O6+zzhN9N64LoSj7hrA5Df6SJa9C8/aQdaIDGqbaYZq29hbVmcr" # IOXQBUOmCA== #: 5y+NcCg0FotiGqxLd3SO6ASb/ZDL+MJt2aQ= msgctxt "No9gXV4ofO9jeErUge1YW4g0DZylDALaRNPD8vbPXaqwOb7zp209egpgqTIEolSmhFNoTiikwF/XIRWw/iqUdx6kTRdhyA==" msgid "SfSTpPlOMALMW9E=" msgstr "7CV14zkMtqYMhc6iIhQv3bwl9LHSzlIPxwzAKfJrswdqFpvXJXJDAICGCd/xXgknLNPt4gC57vIT8/SvsYmUo+ienYsy1gxoeBye19H4siCJcPof37AhTCEJ3q7OsCeV8QNwQbQhRarJAPFEMZybciiNlMQF6kH5TsQ=" # N31XD0Q0H/SZXinkNAbLwBlc22zFSUrKp+f/uQ== #: 5Jq4NyVybgPw2E3hiezRm3zto6OT msgctxt "OJqOG/MV4eU/pfOlrtlwz+Pn3WU=" msgid "" "SG6n4NjjKwOsFAbqeGWkD7qFQGX1qW9aUZomE6tC+g==\n" "FoF3I3+g\n" "WfQztF1jfTMyONIhVzWwUw==\n" "wRuG5PkPpuWV2d2SrVRPF8AOuq+3U8FYtMTXVM1oJh8ePpZnqk3URQI=\n" "2AQH94VidimO2bcbXO9Wa3xunLp56XuELNWxpqcSKbw=\n" msgstr "" "RN3/BiMkL5zeGyWUI3uDPQui901e0HNGXUfh7ERTuvJqHy9dyfjMleqYQgATqbJnKwxcLpFugA7ihO6NSs4CVbciZSlZbw==\n" "RgvGm3un/g7xuD5Guyt7eYk8DohqoXA=\n" "7Y31nxc6YPwdYOs1RBo/lR/qJM0sTeXuHcrz+k5SbRm3wCorQJGrd0QiY44AgMBN7w==\n" "UKlYNdj5Ed29rdNq6WyNLpU+GPj0x4V/9aGV6yWT+H0MamZDSt4=\n" "WTpPwv9EJp5HHso8xpegmQam\n" #: Au3AtIktDv3ICuvARejUgr1Q82Jkni+E4qUSA82PS8ex msgctxt "Lictp58GUBaUR+eKlUTWO7XFVKaumn94xQ+LhC7I/N18Zn0GbicK6esk4J8BkxZzbgzVHN00XSBp3F7u" msgid "4rUT4BqD38OTyhoW/nQ0a76oA9cgk4cUPjOLY5WoANMIA8amAq3GLkqjjbeme/cfAP3bWkTm8eAnLd78VpRc5dXhoS1jT7ZUVTt0hZqa8McjrLvgRE++nOfMTugO" msgstr "5x73Kf6A33rYeS66pnOCsf+pQC1JytNOL6rm8BAnCpPIoA586iwHOi6sZcOiM47Hn3D5pgZu0DTaFJda+XZfMpWNwkbg1Ge4WtqEXiNNOZWh55ftB7v8/+WADFHFTbcroej3XiyT9M137J2stH+AcLucbg==" #: pWXM65ZgDuPq1ACf8cCaJWkqvOrIOd8tfdZzvXqexV6GKBpb0AL+V0FNeLw= msgctxt "Bm5Q6LTeGGNMjA==" msgid "f3TvNgbUhv75u8YeohIfwV1HDn5niLzDFMdQRZ2BdFMre4/fCu02TH5A5xQZpSSj+h4CvEGIlVoFe7XZQqlq/Y7aYBgpwDrh0iKyiklA8fcVvI/LkI+VZub/Awq9RUnCFyH2U7P3AuDNizcZyCD0PmM=" msgstr "NYTJHJvslnmLxb47rUJinqeeRT5bUhyqBFPEGtrYhNO1n2LMUia8aV6PrkkZDzZ+fNrzSAc=" #: KQEZEqeCsR27bh8wWYGpc2Ss msgctxt "OZ5oXPTGnZmz1wOUreePBYHEwHEgsCUjflBkQ3lI3HQ4" msgid "A3ia+/5kwzrOMwbBjObp8etVLFKQQVBPyhyXMG/oaBcT0c2jZchvjxTfBsJ4XfUtldLEbppAAgjh4Ayzo2+OTgsWuefqkzFpAfIiYxK8VJ0yHoh9Sg==" msgstr "XvMJHN6zQ3gJMlMh0LfcTicFuHiawNRfAkApeWVgaKT+qn8CtsZv1NM3gF7RiDPbVT2d80gArCnYfdJEdz8KH/XHBBqzCV9st4REcK5pVGq5Lyr6WzXESE8ufuz9UXO7/DxQZhM2Fhl+z9Lq1d8=" #: yLh18cqypytX5j4fQ/XML6rW msgctxt "NHZqmW6LwQwyLWGMu2gyU2ASb1XJ3qMop7dWMUv0fjK9NTLRutYGDxok" msgid "NG7v0fqFdGwvMGUNrsUGzUD/rQ/OS+VOMTaRnVYwpoYR/pQQEH+IY4SsSCy6s0dvcXnETFA7IvImVYjZwBFAZz+PaaYudUfN4q5CvpB6hfhcvIKtj9zCWfG+ZnbT+CRD/3q5Uw1rUgFP/mogJLr3+KapvVM9Ebn0mmBkKpzY9HWzCwpLcafJjpgi" msgid_plural "C+U08uvqdLHGc5kSZyV6d0gxv26EvtI/NAAJdhwPd0t4RnUzoCqW1D4fvJo=" msgstr[0] "jRudvizckh7mSnfBkTrrROa+KZrHUmlw4Wyr31pcxmxSnK+f6dO4YTpk8vc5X71tidB9OlVFjAbPJMq20bjE9MP+hrVVfAR1Le0O6rKeyFEQPTxhEP/JdYW3OzdgPgUrs6j59/PXwifLx59kMiUanVMp8hYlDJfCb0Q=" msgstr[1] "jRudvizckh7mSnfBkTrrROa+KZrHUmlw4Wyr31pcxmxSnK+f6dO4YTpk8vc5X71tidB9OlVFjAbPJMq20bjE9MP+hrVVfAR1Le0O6rKeyFEQPTxhEP/JdYW3OzdgPgUrs6j59/PXwifLx59kMiUanVMp8hYlDJfCb0Q=" #: m9br05zfZs8R4bpHbp1OdPdAVSK1 msgctxt "ykiSq+NSaF2NLgbkiQK62AlcU9zBZU0=" msgid "" "tvyhGGy+JedUZCRGTCUFJaIE58Muh9buTw==\n" "ys8f7V3QwO+hj6dedhhzkvTfYJ8PuHVqG7zTC5ULkmu56oJYA43cg7+YAMwmVxdX/SDjVLpGiPPKWycMPQhhhQ==\n" "xyY+\n" "+FT60nO7uwb/tYGf+fzb1pOgUtCfrDUwyUhU6QcbO1z90MrKkkji\n" "SuupGKBtUTJ9sENZ9Ko/135s8bSzi+rDCTIAembSZntWEejY3b4itWoAxrbb4tfX\n" msgstr "" "bbRbOXKjslMArO+y6Aj8kun9+XNVugnk9DgvuHnDWNhTpRJvMbAIQ5hkehAPKJH6TM6116ZrRvKjGQ==\n" "S2UggiaVSPnhO7dJKZXGLI1HHRxqs0FYaRwaD95Pxpgdf5LGnP743xSv\n" "hx5p\n" "wmtMUsuYKefDjTQcBJX0xWGWDUWZealJE6cbY7ifR/XSAj6guYd/51UJl4zZ1io1gx4RmRc5\n" "F5ANwy9Nbpe8sZ21ssnhUKc6EKyprZd+/iGhVwDKLZgeZNeBtCAKjsUK9Ftr1qhjdksM82U3L7JUoKONhjWQ8DdU0TI=\n" #: Z661gwIJdsl6Q3aw2ugUwQy3JvoU7ZdEgLc3v+rBqpwq/g== #: W6YKARtWQsVNWHbasrm26uDts0U= #: T62DIcVqWS9GEUBdd1yabnFNRKEfHOxQpsepjVSYSrahGM0aoWriMS9/IH7JQbo= msgid "" "1dulHdYQJ+1tk8wG7bpSJYNu/uZWA1dG95gHkMSxGbijLNQN7V0=\n" "nm7U6ZsKDgLPrBmhyvy9JWfWWRRR46q1KOcioGpvHlExEYJVZdFlYodzAa/67vBop0/S1NES0GZ+LXxemV+iR3VoEXYy\n" "GFLVsh5Ezi/M\n" msgstr "" "jV05G+nNwsc=\n" "dny7awBu5NhNkIK7Sgo+ryVYYA==\n" "OHv72U1bXkbj/jjybuXw9gP1AqFugy+p9mIw11tN1Qahzx1jDYg=\n" #: Fb9FGzpGlCcQCMT31vk5voEbAQhKJ5QBzTb6yTaAMWXxr7kIF7CQHTspkS3N msgctxt "4YvCCoC0zQ==" msgid "ZSel+zsKOGbNzwSxe3ALdtAEcgpyxXEIFS4XhILVEdyZofFMnMEOh5EdaT6T6+gMiQOstkPFTLL9S1Y2LVJ1M3BsMefRypau9so8WprZy1tOVBuADFLiz9OBCElaIswEE4hLcOSnUw==" msgstr "shY/j5cEVykSquFKg4xmdR8PtpjyCaa4IEVcnWVT3VLFKsW0/qQlkKZH1TYkxjwuAChe4w+Y3t4ewNbkl+TRt3EY6hnN9eiGpOBoaVyve2E+hiyZJvqRaYVBsGuArDfYF7wtAN7VoqGlCTsWOfT+yVxgnptpWwd9hyEBZJQrI2hnpHKRAvmZbfhnyx1qKNj0Pzdy" #: w2NVbCFGJQ== msgctxt "5QrJB9nRlnpy/pM0vRPpooi5r2sW7wSlHojj/Htm95xjG99tfgQjbX4n9zIH1cho67w9FiyNSrTJ6u1E4FD4FcWb" msgid "QvFynDK3a4dsNN/8F0ZTGJYNFVAbcCJ+XEaWKzD+IVA3uMCZg0tW8M6v2D7AyVA0u5u9uEE0otcueqVCWvXI4w7AOamMonBtXLneSCVUrTB+d7lJB/xe1454W1JFBMKP7TCz0uzLANjG2oc=" msgstr "8FUXsUZqb8145038cPyp7S33MJhglt0uwQx+vD8sOKOXCQp4sEGveUFXmVzXOZc1NLH/cU2aBiejotG8vLMkUCgD7g==" #: rsb8CWA9LBAOJsu6lj3PE5mxuvSx msgctxt "3DdkBDRvWRIDIgkPp8mrHHa5pzUu5veR" msgid "ZzLPq/0yo1c4ddxzwTBaJzwihYe3OwfDK5ZWTthVFV8j36qR/1K/8uWViQ60ci9Uu6hpmyJyj2imf4Pvmw3xPF7pFLoj1hcvd3WkOBqoxYogcS8nsaNhM/rmPSCqNw==" msgstr "yciENVfyhnCmBLoObf2/S78Lstk42EQ6uw==" #: LsbAxFcWRsyXVdc= msgctxt "QP4clyb3mfvp6I4D75ogod6iuB/9MRNNg+k/j4SDjC7qk0v1u9g=" msgid "/sc0kHmHHzt1R6Ht1utBJNSbMoyAwoNsoTntzuCSppOZDYNuc/HhMzKUK8d8ijauL2r5hRvg0wDeBUwg9ZVuyF+3o+3VDS5qPLL8+RQgYXEQvBPdsuTlDOk1AW9iixqn" msgstr "rFXi8QouJmNQptlOWHlASgubc5DCgp6soqMDWUJfhNnTUYYfjXpaHQTRQhmqZALYHI4r0NCO8loCmSzUZU2LRuHRHzLsjL0YdfroZaNrr+Il1HBUj+cyO844GrPxxUfpCQneOXLwQkffBsV8eXogb3cseK94V4vD4/ts6qZ6sZ41k2EMiA6ZpdC6jBtwWmoQ7I5W" # KQip #: mbJEIT1wi6JKpgLjkVmAlqTlfQ== msgctxt "Czt8xXs=" msgid "AlWgJTaOeBdJe2BYwxCUZXFGRlrvSuuSTx/ho9DCKThkopVR9XWOtm0dUeYzpBTmjZ8MAujgHaZx/nIMI0xUAijjQ5NApe/coVGAiD9smnUk0/41IrP8PbFglx7GzJ5juRC3yPslO0rMZ88Wko6TKkGZBotcPK+yQSe95e7eQd4YM+3aeY6bdsjdk97NW+DyVngT" msgid_plural "0/WkCK8cO/nN761oERa0NIyWWCYu6woS3iZ9eoxUa7eEHdjA377VlHCH6lBaACJtNi+8NdlBJZLvuAWDrPy5hN33VfKTDh30Z5MdKICMnwfM4llyGLFgVej7PXQXspWcMfXDxBh2ohQR+QqCzyWt+TfO2VQ8qUGmzA==" msgstr[0] "mRnH19/iU1M2fosgQylHDhugaUVYoICXsO2rQus7CuGhaW+4wYrJMA==" msgstr[1] "mRnH19/iU1M2fosgQylHDhugaUVYoICXsO2rQus7CuGhaW+4wYrJMA==" #: oRxmIAyxjLBU+8jR0ctGiBq6IlBQrHzBWXGNPLIbS7iHdgBrYifs5lFb msgctxt "pif9XzxeoEPw/auXKL2j9fivmE8V8xxtqVQuZnhn19IO43Cm1c+NJNNLrs8S4gjGNXElnXDzS8uTFE08Bj0R2vH4" msgid "" "s/q82T5tKaBu+TE=\n" "aNhqrRmlTkMvmIlI4QxywhRlgaxkQj6OyfqX7GQnSSA=\n" "yw==\n" "ktF6Ow4G+Fk3Lw==\n" msgstr "" "SwzLLuLWs0Ruvl4/7Aoa/y+cdX1ZoxGqrEBuVt0WweVSgkBkTzLCw95TAX8LIYUhY6LlF7B6bmQAJPGAfb7SJtM=\n" "TVvWjYDNkvfSQcmdMET5oPVZgFhDaOVRAmZdAm72DyGBH6/N7AIv4CPOS2LPUr9p5qxTJWbAJvBCk0w/ns+2kImO8Q==\n" "xpfYe11eVTdQXcFVVuS9MVNSoyNUkWGfMKvV5Ff1x5SUfJuagyuvohGEUL6b\n" "L9G4Ht+yaAE2fKFhPg==\n" msgctxt "K/0zU+Fvf9ScWOCcuQlvRyQktEsZFBiHGvPGBIc55M9oudaDx6Bf188sGxk5My4VSBPnzYt2wcjfhDnIz0pgEQiyzZuhlg==" msgid "" "6xxdQJw3\n" "HmC5ULuVfPXRw3+xGA2p\n" "PTJJwmmpzJuIExi32Q==\n" "X/gRBNQFeewU6K0Bqw==\n" msgstr "" "CwhdKq1kPtJiqw==\n" "Y0frt/5tvihFdkGNrGDdsUMp9xbCnH1Ob2N76sAwXMy8j2P0oHUqI8ATGSdmKnsldjTjh4X6Xm/audYL988DdfA=\n" "HFCq2h+TXwPY3AuhANhUUnA14DfoXDcxWqPHig==\n" "xiPjciTVdvgdAqI3cmgwLl36wzrfPZEzKgEMeagvluuOO/QHlGc=\n" # Oyy6TRpMzp3miJjguHaSu4I= #: yE8DZCRCV2j878xZ+7rImaGmmCJ+cF6ouMBrcaxO7dth0qFfqQhIMDKo msgid "V4GSP+QvVTTHlbL5y0tZiFKx2VpbuR3LNceX0cIb/n95jde3X4rS6Z04S5XM+6Q7sHO691SEyqoYvYSDyIV8GmYMq+rCnYLLSiS1oSv1+ml/EcFVP3YuYF5sbtiOyv2ylq3ohIO47le8vOE=" msgid_plural "/KrW41JOl6zz7DdySbCMwjEs17+/ChSAtsspymnz+R0B8WBE7IXXE2hB05LHPyYW93fDPJcvi6XxBE4JfGiC6zxaKQvD6a1seDp+DROnDK/P4iIxkFkalw==" msgstr[0] "gETyo6mI2jSk+svo8tXL/ztkYcH3jYHXTcZDFYfrR42GoC2R4RSfhqn73hYgB2zT0l2VBft7RnQOQ/TQUR8maoRZFrkAdy1fS3yR+Ni4TBC6Ky3GDlgYUKwZE1K9c5EN6dkHgUywOZxoRr/rxXcLu3w=" msgstr[1] "gETyo6mI2jSk+svo8tXL/ztkYcH3jYHXTcZDFYfrR42GoC2R4RSfhqn73hYgB2zT0l2VBft7RnQOQ/TQUR8maoRZFrkAdy1fS3yR+Ni4TBC6Ky3GDlgYUKwZE1K9c5EN6dkHgUywOZxoRr/rxXcLu3w=" #: DCSyOA== msgctxt "76M52HdC3uAcsK8KQCp6S9j61K5mL6sODqsE1NfJosKzYxAMMSCaJ7qFuBEO8Sv4RYPbWJBIO8nFZoFlP91m9uld" msgid "U9Q/QR/G35aUkyO125nEi6ftLLQFsloKFn3nQbN7ORqReGofL0tkp33BLtoW7e60EYIlV/69Q2IyZPz9DCkH5tPCd9IwBCvMltHAMBO1TPHaTzrLrk9lNMVaz4o2Ee3Fvbx4Mh6u5PxnDEsMA7xEfU34U2632aL3HOJTJ6g1DQVzAoekF8y+BcYTGgRjHHLWziNI9g==" msgstr "XLerplnAVvocoiV05b3REXiBqLZx7Dhd2gaIATYGUhtM4rJbIMUuKrud4SuOZZGsrVEXCw/h83r4m/PnCBHLAUw81WEOwdg/G4UD02Icc4ATB49OQkSNDhYX5xl1Tr12oedSK2xop936MzsCaORy4HwZJwQc7h4KoUfo868p" #: msgctxt "XnrZYXL6Qut2d6EwpVTukDWBFA==" msgid "kchg9avo9fTxqE8=" msgstr "XG+DB2RRcPCDrgX/hz0HzirUDA==" #. uoD9IyHe3zpztw== #: U7kA/TJ9a2TLEMqn4jX78zn80csTjwXF msgctxt "g4YiFeMYXKSHcDDBhJ8om4muRikUaTjCCePzBLtEgUpepY8C4v9Dd4YRd7gl0fPICvHdzg5o3x0=" msgid "uMypPPoBiMq2KBHjJvGf7tbr5F46V+y2vB6f4gopzApawY4NfGVU4RcHhlaE/douNsLhOasaHPVtBr1+s+ToUj5H7QQz3VkiObDTQa0qmBNX/BX5XlBGSCJrl8JTTBNRXiw2XBZjZ2T1K3x/9Q==" msgstr "MHGNIVjfM6YfIDSPgBVdf1Pa9ZP6ADyzVJT5ZCI78NB8TsUm5Rzfhkk4U3Rc8+9zxcFybxltEek90mHJbxAFZ7PgK7CHR2mXnRZzfSBeNe5F8nEmFd5BTy69IExFbjW6N80brtPXHpt5fPOEqEX6lJq77K3lEZ0pcpvbIc0E4sY6DZxVxmDZXYxcwiDH7cSG2A8=" #: Bx+QD/fcJiox4HQIPDA= msgctxt "61+L6BoHilPHHn++XebJ7p0vGKWBDpXJloQxAms6TofYdj4wI92mS9O0K7BGHh/Suw==" msgid "aEeAOcnZJdJV0Vk8sd2witACiOhrsD6C5A==" msgstr "1wBl+1lm33pHoyZiQ8ALGmEMMGYYYzdapTQpqVUnPr/h9hlveoLrjz1PiU+e5ma4rG3Bz8YPmth6rNsOOURLnNhiF5OUmJd8enyYKCo3XE3rYfG1+h7cbJzy8cSseDbFHwpRt4dZXx6qmsY+KK8AcmEsbcx2TIG2g/MJbPs4O/CyKGxbAZ77ta3ZV9c8aQ==" # #: DHdjshnVDd7mrIzJnA4cV641 msgctxt "39TEbPSsNJmHHspCkVCRcXlB" msgid "MAGWIup8mjDxgw4CncdomwGoxNGRBBI=" msgstr "Rd6EpfL60/wxseMGs+nsRwFq89YIXWsuyhG7K9HH6J3DgI5vqnXGFfIp9Q==" #: HtYMuEaIX4VSaWYS4tNHIoeaJVGATQyFCghz30UZETgf/o9U msgid "4eOK6TGVvHc4O0UVNbPL3Q9G/F7FvQ/QxjMLSjHO+XqzyFJRVrBjX6L9vRTe5qBYsqAF" msgstr "Vpbd4kwz+Oa6fgJf98khaE4tilx715lFF9FJcpR/VTwzBy6LfdeIOJ2V/pxPRYQAh3vv98R1Gzxjt0eDhzqn8ALzQbh+02y+rXumMps3D9X5k93W6g1zU23AHzpG9zejuThfdYGFqucE9nDx2kYQuyo=" #: ey3JA9u3mWJ22+olJ4lxnZFw/ISEFb96OgqcJElBQvkHNR+csLVM66b0+oSEDiWZ msgctxt "VGFRnitQM+uQyxhxHusQnQMr7fmjjTvwVzMsSCk=" msgid "nQyxVlwlfUHlYAftnmrY1XoKof2QjXoCTa7vokf7hw0AOXjkTGxVv+z2Q80pBPYqf5NtIR2BFvTH9XG/0jOHHcpXhEG91Xexldva07ITbvQ4loEdajbMXg7PonQOseDnuEOj+83cLeA+1iyFKg==" msgstr "sknafTJ6bJhzRe9j6SecYsKyRhx+L+n4P+dMx3BvWympwztwEoGeEtTfWtFJLsRgZiBFkWmtFZIG3i7oKfDlFifPGyo8IPenPrgbguTjbG13apT0nw3sZrYcD0NlWI1pa3g5hk273Aa1pq22" #: 1TxiJ7xw9YjDeq0EaYUCuHX79mufB6LoG2sBC+M= msgctxt "u6sFxk1KK2TI2K/9q1htIkFR2f36OsyBt0qwkZBeMJzVK/Q=" msgid "NtGVFL/Je2ycCVBye0BiTPdJxusxTItJLkK9ECK6MnOIfhLb7zi0wehUv7bPxygMo5DsPg==" msgstr "VYEwPKVG5DHpx0uEW7uLYiKUtD8tc+WlW4M+K1PcKcGF+L+hnFamUvJcdIfqcA11lLCL3LhUIpfpkN9msCAH81y2HxBg9hTbLdHyuRSyCAA6w7hNNZtiXhR/2FJ9s7ttm2YN+onHwiIcDcEm7EztEuIsAYW09ypyHIPSz7WV3XsM9+3NQJ0=" #: Suj4tMK4HSpJL9M6yuGZjMfD msgctxt "fr5J+U014FVo+dCvfJ++mX68oWahuA62g++0hdv2+OTb7Ul+zn/UvA==" msgid "iineIdEFqPkUa4/wOqIAG2i+ijJchxXTO4c0eBZG6TSpoiUIjOjSZQaAi9MCpjo=" msgid_plural "NJUmB4aX3m05A2+BcRnHM+P83TeNwLbuVQRBqCTHhQ==" msgstr[0] "V1uhdCN0qXR4MewQhIXhhixa9BiS2aeaRLNUVXGNlpAHpIeGbOGM7J03KdOfbwgeIXY6eM1qxjZli/q+TnnuVBidSGJrLMN/lapt7Z6fFHLPNHxzR4yUyvnG2v0edjUaoTP6kTu6ACkUvHGs2XDQk5xzAgso6oOOHg==" msgstr[1] "V1uhdCN0qXR4MewQhIXhhixa9BiS2aeaRLNUVXGNlpAHpIeGbOGM7J03KdOfbwgeIXY6eM1qxjZli/q+TnnuVBidSGJrLMN/lapt7Z6fFHLPNHxzR4yUyvnG2v0edjUaoTP6kTu6ACkUvHGs2XDQk5xzAgso6oOOHg==" #: dEMHnxEPVpp+7BrmoFuPOg== msgctxt "jqCkOmfxH2poKVGaCTHvBrDXDNXhfYXSl5T1ZP3vBUBhi+/+WjtQov/bAdy9H2593cE/HZbo325OA1lCug==" msgid "xhkoxKsqjVrU0AnknvLvznyCQFFwlmOt" msgstr "GlNHAQqRRrEMc7+AD+1rdJsUjaa+9Lyehqp/Wzi+JOiluBS7sKcQbz6jW9HjWtBwI7F9kXcAY9FBciBlegNou00q56dWLmo=" #: bTaS21Ota568UdzKPJywQOIW msgid "Ts6KVECaqqMc75YiKqEl0VIg8jLgO/U/jRfFxhd78uHBZGoJqFeMag==" msgstr "Jg4keKS92fnuATTpOJy/Gd/i41+2FTAl7cYuKSd+6uOwXCW3l3H+HyTnQw8eCR0PhSyIcc8i4EGDUAi4+ruG4Bwsi01UJHmFp4k=" #: fPwDNbfk4K1kXHGbyNnC3jd75LKHROf6g71TWhs3j/3ctg== msgctxt "uc5k0kn7l5gn8V25z9M1USGPIjqjFMvQYP7TBg1AFA==" msgid "Xh1qzVRlqe4VHqdWU2FGIRATHSUrKm7mIzGk5WTfyt6Z+ZrzyRZohOAfpfnQTVItrCFI/1BoImIri/BRLjlq1nMpQ65GJ5LFOy7DGor8fblNj9ky" msgstr "R3Ef" #: PeTWD7/ljRy1EKZEww== msgctxt "CLnSDOc=" msgid "B6T1YTrqyxy6R0xHXz3auNiRV0O+7n77Y4jbyyXeYaR452LNfdiFYfdjJ6TstWEhsNK6llH4RkLMBlS4Kid9wd6z5mKkcnqVVMYJeMyTDnxPqSZUogT+o7iUfuGHaHs=" msgstr "VqaI19RovKmpwEWekXKM8XV6HTWIOuet0RV6hs2p2Eso8P5b1vNfShBPgmuvK5j/OfSZIUB2bB6kgWKVdR9J/vAyrp8/xXU2ntCDp64kb61kghrbUaKIluZb4tjnxQ+1hDSEZO3H49BqfG9hxK78vlxJWKECoRpcxQq7RqAhbxhrPC7xs7eX/pl6" msgctxt "SJfgdgzKBE9Uc52aIdMpkr5d" msgid "9eALjVVUj5+3iMqPkg5PWSXxkwrCMP8CCpTWr+R9Mqq8iO7NvIWgwhy/+jUgWDnAFzscQjLqWPHLjMDB8VTqPo252bJbDCVvVgjS8JPvPho9R8k=" msgstr "b6Sxvx/vi+Uh9rgyY1OKy+qGSVPxw+LzfGAoo6eD1Znc6faaTJuqoXoHvesCAAGhpgNNFcnGadHTKiy7qL/voc3qFU9mHuOQrRSep8KI3QraEgy0kRmG4uHD" #: BGXZ/98sRgd9ds3BNJxeL1+1d9hj1UUsGmkq7u7wTH/y1Efe #: /cfp2BgfazNvE3WpPg== #: 4qKBsMYtin9O4XCY9avpKxTyaAB/QTLsj1CcwQ6jDZySgayC2H0avvf2y2z+NA== msgctxt "Jpttn2YYpLpBQru0cfFWyrynlOZmQpPaJjxfaabNfGMzooPeg5R9/c7DlW5H4AdjHJMmuejQTp3SqvEp3M+9sw==" msgid "x5yUhPlLZb2hSPkLx9mdaPUhm5qqMiUQwEIrZW0rqSfOylC6D/nZGEB73j9dI4xa9YaOAu3d1oAqg3wDiA9Bn7SbIEqXqCLMu66USthk0vipFij92U4OYcpO0by1IFCOMpf0QkpIi3O1bIaKmVqwIInO7aiMjpqq2Yh5JAznlR8=" msgid_plural "B1m6BVcVpMOaivMaSMAdNWuT3AuewwJh1b8cAf3vrMtz0Yz2x1ZUK8ZknjIwxIprO2n9eXZhme/z9ERpJL/j3cc=" msgstr[0] "lvZNt3gzHgJgqc96Z7L3gz4bwhyPSfY24msb0nwwcBpmcY17TVCr9W0Ps3R1" msgstr[1] "lvZNt3gzHgJgqc96Z7L3gz4bwhyPSfY24msb0nwwcBpmcY17TVCr9W0Ps3R1" # wt9+baheU4wmv63HhUxWp3wAl43BI4DuZ2gwPn6za6Y= #: d6awDrE7Ck7xyMiG0uL5xalaz/n0 msgctxt "SzRM" msgid "aNDUcF6ECI3sDoS288ae5GhtzVZZ8jkAE7YXRnQquBWptRWq1nuuZm225vZyjnR5Ix7pKISpDarPxLttwqj3APUBRBeeTYvrr+TYKmHV+H4xGAm7Vil1ODsXdijOWNQHiw5Cv3CeYuBOnRjPYrlXGyjLOU1fOFu+zS/2HOJlbr4p3s/WOdXo" msgstr "dxR4ClVz3I6aZJnLg0vuCo7BtjNofJHSx1MMU831Kn1wd5lornHzNTwTHAdw0ot3YYCa8CpluQXBvtCgVUJTYmJoEFcyMjUE3wAkkii+Tlm9LPfHqC+213knTU6lb/wyerLFR2dLVq6RZ1mSi00quskUvBJYwO9s" #: +iCLEA0cpHJ9Pm+bwQs= msgid "KGz7R6JzuajmNEs=" msgstr "sB5Sd6Ykfn57yZW8/Mwl1zEKl4xjktcwnuXqNT27lK6EgcWfSe+2dX3GONNHUrWfNtnxp7h25Kyx1qR8pJjtl9vwJAUVYSrFJ8LvVjJPhMEdmaoK/76macatls80z59fPTa25E2119IOlysGG6mBl6UgZ6ueI5bczW4OpyIrG6OZEByEV9k=" #: elCgqg23pQRghQ== msgctxt "ulU6TbZsVs5YNg+wHa8RdH8BNWHirLscCaShrnSmXdk+8KRYdeDw75Lo8hp2ZpXAxCU=" msgid "AD91/kHKj4rubMnaNuR9WSCgriXkY/uVbgoToH1MAT7vKRs=" msgstr "DnfAAFJi2ibG70EYlCrtyESb2JgyLPyjSmRYS7qKzL0xdndQZl0UQx9FUjXm5g==" # bFmA+D5oymIwvGH7496XFwLFMEoi7oY0wXGkCCp5BifO #: OBWnYqKKJ1DT5K8Ysw== msgctxt "UTWKWyiyUCbd3Dl0dHgsEUKudg==" msgid "GD7JHFHwGm547jZf5LXbj7tqaI+H+gNFx/e/CK4MZsXggE/9zx9YNKVk5XpqrazTZamq2DmTJGEPIdZ3YoI0IJqlBYEYZjqJWLT4T05C/W5Fh/wANx8kwuxqZDMBNf8FB//xlpFVJ9q3" msgstr "k76K9asEGpyYbchqrPKx27GMemsjfe0RRV/Bj+rR35qnw8+hEfn7AVHV57X5BRk+O14rkifhPw==" # zWY= #: sSKPm2ExF98FtwzIf5C2BAHvWTCpB63/QL77fYOYIDlBUjA= msgctxt "J6wuoX/cAa6XoFcPR0p99H/TNUTJMO27xuLEVA==" msgid "AbmeaNDNOCI/3+kmNNqA9k9vMyVqNMvR" msgid_plural "vTzSwkMiLX2x+/MqDHYrGgFGk6x+hHRu9EQ9olJwJBDWhGBYYJQ8rxB5HMyu4jatAjyddkVFGVNN6XYs4W72ukkX90HlgvaEI7rCk4TCiuoTZEiEOLpqn6dAtdkRki7vTYrxTCNcQs1/RCoLh4KlLE6Vd9zxCFFji7+F8CoISVM=" msgstr[0] "vFnpzBOiukJEoGKwq/3jVQdE5LKlZ/cOkTa5BpFx5qWG+hOShIj2jBy0sO6C4qO7ESLjA+Q9bS1lCgRpNbchbZzcR+c3MjupMwnQODFil6zQyNjnLSM6" msgstr[1] "vFnpzBOiukJEoGKwq/3jVQdE5LKlZ/cOkTa5BpFx5qWG+hOShIj2jBy0sO6C4qO7ESLjA+Q9bS1lCgRpNbchbZzcR+c3MjupMwnQODFil6zQyNjnLSM6" #: vvA= msgctxt "lOXe2Km40RiuLdNOdGhPNpeHRD17zDJ8wnht46XRxgKxjI9IU/nOd8Xybn0WIjE=" msgid "EqcaW9FZCeMXzv51vFG1jl1y0dZmOBTuYoPOQx9RkUIBC5FDlBGLUQLIKnMpZz2SLsSB7GdjKXiyNQVBT94OpQo1xkDG+lLiEedUv/fcriffXzeX2a6xqRg/1yfw06gPGtncOzHhBN6M0OXh2oAIgda6ITWR3HVdr5asx5s0" msgstr "zaP3Xs8pzvCiGUFND2NGRwOpnh0OWLVJ+igaWzZkbFld56vjJ6IfFAZafAtF16IkzUklucpAZRFd5CFGyBsV/WSYMw==" #: UsPNsOZhAC9uNpYe21TwMK8xI2QNXOwfJlYIOp+fsP4Selc5o10GeMii8AE= msgctxt "X/z5O/6hYkzh+UFC/kWPg0yIC0RLKRNXhPiJbiddWHoxmjdzX+XoNbpLp8ppSWJmjIk=" msgid "JTJdCcFulylAbUqk+DSZN+o/C3kL" msgstr "2SJOpT3gT2AZS8MnpT0xoAu2SyCD43dJKzKVSrvGBZS1dYgnZ5Y=" #: TzydhGyfoGpK0bCrkuMdSIyLZxlVWtE= msgctxt "zkz27r/Ess54uPcr3YnPlvScykDgnZuKzAWvvIeqWFzpbBq7kA==" msgid "2TpWKX16tzmuZlL7oKshCZqXOg1Bj3iClCASTJ0ZuBVVRcF675UTAjPxcwZoqb4/6xg8S4tTqXiT9Po8QbIncXg4NMY9A5IHoedoMTPFjCTAAWViHiVQVAKDOHcJ+ZutRvM1zR/6etcyZYT0793rJ2cuBnvZQ/iX5fb/i3RIYIJl2TxgU0RDZBli" msgstr "wNKbxogyyELIqetEjsaLY4RB1fz1RacE7xrbwdoIWK4msn1ELLoW+v+uQO7IZo9vrvLl2RFXsngY9KiZKU2dAQCTCZB6Q16XktvL+Twa" #: wySy8jvJ4cM= msgctxt "ghn29AgPI6PQl7IiEEhJi8S78SDKWtsjuxQxfVoRb7PO0yKqtDBxvm4+4W+2tsVNxc49nFBr4bVwpCpJiBnMhyHwKHI=" msgid "ayZ0/atV6xmyHR7RLZS4PYrv18nVSCQaAb+fgMkiE0JuprEUX/1TAvH4KA9+W5Fubm4jKCdfwOTf4a+YwQwGlpuA5sz+GD4WC+0kcdV5VCOU71sQdPCJBLs8LaBiyPgCg+ovgTBIHRYMgg7Rr86+nWvMQX2SQoE3Uh20unUjN7Mz4URVmhye4xp736f3" msgid_plural "h2rc8lb5nj+7H5YC78EssEn/ezLi3ZR5atugeADaU+0PBGJWj4QawEHpBKeBWZwUdA4Deeoab6Wq+bYgFz48WdLrOQcqwfGGdEI=" msgstr[0] "0d/8yY8NV3WjOje3HKf9cIv8b9v1SYZCx4ix9PrhK5whNdB1XjmNy4WBS7LJ5Lsw8PlDITPa3QzmP/rjwPeUTABGUf9hsSKukJ2gY1e8SpYiokVG1Ei1xgImBNg8CoBon/W+szEn1g==" msgstr[1] "0d/8yY8NV3WjOje3HKf9cIv8b9v1SYZCx4ix9PrhK5whNdB1XjmNy4WBS7LJ5Lsw8PlDITPa3QzmP/rjwPeUTABGUf9hsSKukJ2gY1e8SpYiokVG1Ei1xgImBNg8CoBon/W+szEn1g==" msgctxt "kPhHBGtmlz811ngGFAsN3r5fuQX8YnNLhvridGIpnzG36QFZdymid4Lyhw==" msgid "pub3d+myiABHYpm0WCCR7y11Uh/qPSDLuMyxFRK2R3sYdIYNGvV46QeOyEW5bIA6d6fP6SKgETx+f/tRwh0aove2KuglOAIdwY/ErMtNeBZ1dAzCmJrjAmVADTk0PQ/qGCsq/drue06j" msgstr "COvjbT0g/9Uje3jxHTxK1uwXF2Y2Wwg+Zxlij1k5a99ygrDDtrFL6lO1cw6SDw1nc60=" #: UmX+S6J30HJvvnIYUGbQmzgHeT3O msgctxt "nUUuu/y2Z131i5hERFU4vn9ge8sXv1fai8UeTRN8iSxFQw8WAYk=" msgid "oxaarTfHCs0EL3a5El6ssl98CNPrPgFXLOQFkzp69WFvM+wt" msgid_plural "80eWmAHWv9XYobydQ870b+xwv/FeitIE7tCdWMVFooaYoXF5t58JOWMe+xN2RRGrJVyg6lVMHERR2wfv0fUdz+T5J454jbeEwjmNC3QNbNkI3uTmlGw/E//tbQGsHJ8pZ3ArDhR2ot1SGaXvtrOfVM6M+jUVwZeaPEiHZmUCAg==" msgstr[0] "4NX5GFfq" msgstr[1] "4NX5GFfq" #: 2de0yyWB8nuQAlZUdf0GBvUvhDarOm9W msgctxt "iGAmDGjqMIkLiEO1ocZ3YhthCC2tX7o3XX5DJf8Fu3edLJ9YVg4larXZ/Q9Jbl+xngq/4iKrg+o=" msgid "RtgB+sA/otgr0fNzL1B15aJSXBQKLZvSHvtKTLFpHpkEzw==" msgstr "fbC9CwY6upFiblB1s8J6fuX8fDI+TvOCpwsq+xchUsDKeTUIFEN/jgdPi0qj2Fxz7RRm9VsQ4Km5PNhMNwdX" #: +mwJaOb0M1fK5jm/so/xKdwM4ro71aGDuIDjUYctbP6S7KIPZQ== msgctxt "BgH2" msgid "bnmJMulVznyhuw==" msgstr "OhJe1GLRf0JbtkRuUy6X65H4MlaPAoNdCFzl++M=" #: eAM7RwOAyJ+IZImTbcDeX2yJTRvTQ6sRE7eFbxae1J82cYZWtlU= msgctxt "jOGywJxds71/nvg13FHH4FevRw4=" msgid "Reh6w6Aj8/l6xqLjCGm6YQe4C74=" msgstr "ybCzfo9Tn27bzZo3FHDjZjlbKavecWZCTuA=" #: S3hf3Yn1VTPCn0IAiVmCzu/Co61dSOydnZ83AGDxs211xSGeq76L0HB+a3dM01yWWA== msgctxt "24fDiyg0QDgkpCvlz7tPs0VSnK9wlT1+IIQzUFASv6TWynx7Jd+Q4tzK2T1BHEwEwNOLLl6dffvnqg==" msgid "oqyYLnwDKxnd5/SOrAsC/F54QSz1KtC8uABtN9IxJIAxiJIG8ShWjvW5j70s7OPriQnPSHxuZByDPbAgwL4E9wZBW8O4v+mPr8UyEb3t9Me26ppOXNC1/YJnijSVRRgpIUefw36pG5nKB5gXTzg4iXBHvEJFPUL5CMyPP4UsEZv7s39Xc3tg" msgstr "LY+eBnvD96xSMHLiBmsHv8dD0k/32YVYFZZxS4vS75qO1R8z+mcaRXk8qVPOEMH7v0zlAjAFfPsvHnG7MSoCdVHTn++mQ+RI4pBJnlJF+dJz9c/WlFXKH1ci2TGqbu/RaA8UzsAsNCWemecfPc2wfzZS48wseqA1QRBg0CTrGw==" #: S60iRtYQQ1gWCvf+q690XZo= msgctxt "4Q5Ew37jqTTJfsjnIwwJYPXYymn5YjhLwpkjBj5vIGl/v6pyDKkQBfE=" msgid "P81LeLgzMJZWB4SMEE/wuMFLJ0obSJEX/uwmbsRKXQSPlzIpzMzjzJ4aejE=" msgstr "jEZGH1T7YeUrAfVrudxTeyl3HobmwMNmf8AeA1jddfz9EaZnQ95mX1fAI32AZQe/KEJ87uQ0LAsen/F0UrItJMciiFVL5zTc5X6GTV9/fgGzswNCbXi8Nd4VCx6uHS2nfo+FunnKzogX6uchyowOGT3YvjJm56nIRM0y+alYsGH/CpP//x6KL8tewbD/9m5k69XqHBAO" #: qw== msgctxt "+rNeA3ieJ4FfbW1hesRNDw3LqbnlGLeIP+f5wHxNMDoBh1E3yh/DBf2xwa+8yA==" msgid "sMUrmfsRrZ2r+H34ew==" msgstr "dXdOqZHUN0mYwzopQmcwLU1RaReNPiQFBXRetuQvRSYFFxr+C6ipb8O3Zc91H1nKVNiNamefcSKGq1+DmgfUp7EInMM=" # 2NKDaAsOBmUtgSIJ86U64KaT7ZYj6mQwKRHZ4C3HkNP/Ag== #: aQSGag1dajExVHd25rbTW6ofLb6HHUX3 msgctxt "h4AxtMeEEqgOzioHjg==" msgid "98kMYDup44+WiPWrijPtSNbf9cpt92aM7zshjq6+gL26KZq5bOnIukPkkYxtiGZXGQlj233dDWNQSxYlTroJ8rmqwP1rZE/wGAdXQ+HmWTNjOBV1/1AsF9YCzF9XXpi2yCgdkI0xmD1Mow==" msgid_plural "rbW/dGa1ykwwGw==" msgstr[0] "" msgstr[1] "" #: au24qoVztLHDMeTn1bKcgh1TYbRwySKFjCuFmrZMRA== msgctxt "GpIlfpt2CJ8Du7WJ1s7LFlIbpV+WgT2DCf8OHNIBBzwa4pQxdNTQOV4=" msgid "7hmZTyqFtir8b5OKFaoFdf69K3343AieBcV9g8l+U7/343djSw==" msgstr "r653wI877q28Y6CwrRzEVyUYEEPiiXGY1vErcfiolYN+sMd+G11E8T2qyZOa7yc6iTwQ9Kr78H4b0iF3vTTuilc9DmRAqfrO2d7IPd5Sjr4c6Y7t9odjXaRgQ7rEw9NpN+5qZl6WcyG5GcO6r1UJmWJHF1rTKdQpWnE8IJal" msgctxt "OheyNPxpyfeOGmmqNqbyaUvGD146Cw==" msgid "" "3wdOTah/AkLOn4CScMvJl3k4sbbkHrAKwseM8qqHd18KrmhvZn7HYqCI\n" "h/YQJyhKidZ4hzbX7p48NHZnuC+syK+wb8lCQnc=\n" msgstr "" "kIxPZILmvAWE4cnSgTNJ+JJh\n" "+C7P0enWYGjNW8ftvXZa+7TiiG/tZcEqgnEw\n" #: 3+rmK4sHIQk4W8aERf1x3iiCfY8= msgctxt "KO0=" msgid "PQiRdrjPQ2rc1rY+xYFV4w/l7IZgSmwO0LEkyNXEIpinxV6wDmZexipwRykCQD0GO5OHcC1n5x0IR+9D9Z7S" msgstr "woRj9Ec1ll8QXTmZeHEpNTmqtJFDje0JmsY6e86jXZFQrZ+xStEgrvI0GTnUfC2CWuRIIgwPCWMv7jQvbAPoJ0esB/Jg27RSV0lSPxEQu2wAn9X25RjxrkHEvSy1tJlBpdf9ea/aLTNSZfKXJibs9WKKU26QIhD6kHNHpmm7xx3GaqctkXqjebnm/rXbqGAk" # EzhVPinvKt6hNdxKS2aRb9orF1ymrA== #: uIjHm2amINkOjgFgG2l3qcZSo1mDSj48 msgctxt "67e3TuBB/JUvuwbDByFb+4x6ee4HsT7ojgc005RCUwgPUExoiOcIf7rAIH3dHUGUuV9gKkytg01e/f65Wt+TWPF/tnK+" msgid "EY3j2wytvFqZ3Pg3UlIGUDY63d8ZUSJh7Sw4xsw7Gbi+Dl3sb42ldt7tV2Y0KQI=" msgstr "bg4XwOcGPRl3C4NVrmdEeUv8ZnHfphj/kLaDy6JOMPm1/mENpnm4wlX0Bri5M6d9gT90xwxFRqh1DXhHw47wIxMtIsw5Cg5mCFYT6nsQbAx5gZ/dSXmWIoGnJoV6ubio60JucRE2B290p+EytBPLMFdqOcHWvZdPol+8AahkTUNVlZN/VuIeVS7IEWRxU/BluAjIJgY=" #. Ssql9gZ2SG2qkBy0dO+uwB1NlyN/ #: aWtoC8MhkPCUgUjKLPPmp5GvwzeKEHT02JS8r2sw0Plr3T7d6630FdGw msgctxt "37AtQnqLdrTyGwW+iegJcrfQjYhZKK3JHlHOuJw6faLN0RlFeQ==" msgid "VAZjJEGh9axH23uqWoyTMoX2TmJ+eEfZjr3apHd5+Dig3hXZGWXHNJ7pVcQ7XmtQMJL0z1K1EEaMqDMr4j0uOPgpWXRB2aMxQMURcyDj3D3R1vuB28YRozkcTcEo4n40UAiQJ734sj4Hxj1eK1BTO/Dh6Dx0TJiOYWvgKRh2VBnQGBdp/7iVCs14beasX4CRQ77nMQ==" msgstr "1YJCZgBALo7oJhvwrCo9jIyY5gcR2P7gRt6toJvSrSjdcvDlSv9B5ahAZZeWwbPxP2M=" #: S50yV05jLf4J7u+lICw5nTBSv6ajj3ZEcduBNYucCG6xuQ== msgctxt "soI4++eENbfppfiEbWi/aiBjXbhJgmc=" msgid "GYBb/hXbUJTgqiRoI4tjKUy8QUUzl4DqGrY69AF0OEfYOBqXQCH9BA1QTkHfSYCKp2UD2ea4C45vG6OHjWSWkRuu4/1pt1ddV0CVyLN50cb9JT/agnD5fTWrQK0OqRXv6GRmMTanfzsXqRLMe+Roj9WNgVJp+CPYJGk4" msgstr "" #: uRFQfO4= msgctxt "uHTf" msgid "D6HC3Fu5IulHBjBVROAi/6Q103bPkZFNiTZg4D5QJstiVLHTjBM2wVcXEAMBUnAzX7sykrgWocvYCxzudINQW8UP67mStHbTyJZeyIYKAOfG" msgstr "uP2oVAjqDz+4zF7jSeXwsQK9nTwWEethTdFd3MGwdA7eFPYqZG8KwTI3wqhCM96T" #: vID5mvMzfs3qmz1VH47O5HWwBQKO4Z1xCN0X/Ew= msgctxt "9EgEqR/xCvuBjPXrMsbEAd4=" msgid "HqAQBukc3DLwRznN/2qCuNwWXc11CoKv01dW" msgstr "4un4d1x5zqK9pwdLjBZPYiAz57FS090lQIKXAt64Idl8VWvgsmWX7BhLGTQNw08HcveXtjVFE4EAgZCv4+YZCaSnqPhEPYCJGGPumu6XUnMAWSBTk6UDBVSChWSOQMsLSaBNjrxBInaUVD1i0bLeZAanhF0TfmRT0YTmqU9GftlFClUGzIxo+Xb9ZQ330JAqh3P5SLM=" #: Yw9lVeME0VSMYhCWY/WbG2buqHc= msgctxt "N4R33a6KqgKlFg==" msgid "" "4QbZ7JpzOU+XKuU66V4Ddn5maI7jeprImYvaG+t5Mm8cu0w=\n" "l5EENUOC0M4k/0WQDlG9g7WPgAZa8/JL56WLcu1LKEW59IZo\n" "3Vrt46Pcw0CevmOO+ZbnZjnH58fXbR0l+b4EVW7enWT+zFUoO74=\n" msgstr "" "MEi0TNXocnks6ZU/OC2lzBNaneNBl5c=\n" "FirGWXMIxUrr9vP2W14=\n" "TdOGHqVjp1KmskJKQ0lKNA6RH8ww+b9t7fiTFtuYUaNpB4bJE5u9Shc=\n" #: 31bXzqIv1tfQi6JVtF6yvK8NffhONYf/zHrcvNeStU31lVhZDL0= msgctxt "h4eioRJu0ZdtilQqETITgL2CRW1SpnCcHxi9DVP9bHoc1U1TZC5EpfYKYiBdXZMVVnQb/w==" msgid "JradhY8=" msgstr "/C8giZ16ETUlbmTFKij72cQfRZ35OBkw2Hoctn59d3EufHOIhJynV7wRkOyB1jzzS0gRbREhkYTJs2dxHjypBKNMPMT/hQirTpie32Z4sQahEMo07Y18yYU/0W/De1bbEg3hXhBVjZ+4LG/SSXFITb0lrcPI3F1fuhOOfspgsQ==" msgctxt "ht6YJ1k1GGH88uIA7Fq0Ag==" msgid "" "OJUWqkLuzybiphI7kqMDt3ptmB+Ki9jG/HXnU2rn\n" "8BG7I96G\n" "AWs0Gp3P2m5iNhtfOx3H8C7vaIZXvLVMwfMViAyDY9iE6NOjAebHtyGmfkO+bavcY/0vv4F5ARLpSIKucC0LLN+CCBA=\n" "31L9opqpS2Oom3LOI2IMMeUJ6boPVgoRufc=\n" msgstr "" "OSVjt4FVQqvgN6ZVpXhopj9rQIWSvbyhmnSG1c8drG2r8DM=\n" "7jtyko0+fbiSJWJEUZIDt4nyvTY0jXVZswbbS4twGZOBqjP0FAABV4pgVr7xaWlTVcNXXJ/XAJKEGT/TrkMv\n" "NFZ2\n" "syyZ+ZGstfODxKN0HbbdN6GinoKD5WqI06EVokSbTbTRY0w+OsxbNe/8bPvnDdEZ9ILqR712NCBSLQ==\n" #: Aqdv5PW1aoQ3AUMf+N/pU9IAYcidl6D99LqhDcfy27r4wQ== msgctxt "Zd37c0923HbbpROk49UYuFomT9nyo67zrmvxENgK9yHB4zyYgUI27wZ6I9dlMTOioPPVPSnsxSwkpk8=" msgid "aO0QpPwjrEMxECC5vqAkjAXuij/v8hMGzKZWcd+DFC8/hETwycWU4NYRiSF3qL0g8s2rUKSowxKaegQ8oY6PtFrun5LaFFFY5g+jC8hd7eyjPMz1LZwd25wlZPiQLKOJ5FRUZAxY44VIvQ==" msgstr "5MlaoPKoF8TK3Bm7Yui0FUmad95nxthBmIidTMH6tDmUrwq4/K82/vWSvXTA4dD+czQqAJH6Hob9vjsGM0vtjQHPlJdSFlMc4iXSZLGIP2f3RwYMlRHdMue/31rOa8Y=" #: NETJUSf3GRJCy2rJYylcm6jTOu+6yrNglitVGKG9K4kssheB msgctxt "YqYBQo1Es7wUjYRDtU5Io1lUfRK1KFby8wVI4aY5biUv6QWtmyUNX/E0/lj/rpnFi9hHPajv4pBtcYcRpr6gQHogQ3mr" msgid "NaRA2a9FTX8=" msgstr "RLJsUH3skI1VYgD7K3YbfoxPuuvgbypUwq1kItNkYlSy31zqshQYl4mLpBKqafFD7vZZEvIVAHnm6pY04nU008+YZf4xyeJFsUvB63dobs8OcqtlGcCoc2wi5xEv/fWU9UkzkZkScO1YZGuWtVHxJoH3saef5t5wDzuw/FEt" #: ZE2BDSdT4W0nrTIcZJ93tnQqE9fi91QA5pkRkyyVREyye1LW #: q86W9Qev #: B76AD5N2YAdXw/g/iF4p+C8E0HibFzWIphM= #: av6hsTrmZ+HSOef+thJjJjB+OsG2UENgK6ajmwKAfIRjJS7HUlCKub3p/GL1u2s= msgctxt "rLeF3IM2kUGtmPn7nfjrlWGUcJXB+Kaa8sH3k6nXXajcdHKGRG8OiyN9U1Y=" msgid "IYXmn+HNBd0gEgbRlfM9t7KTdNbLABGn3TRAn1Av74fjCNdiTIPWjfa3SoycTs5GTlEXnSTk1QP520OrJmP5AbSpJnHESAsQ0RxuVUZtAwhfLp3AXMT+CKVRihD+Y1W+HeYYKW3gLiBEA7xcjxEUGs6dCN5c/cZzPbQV1ZkswtdoRTLW" msgid_plural "Nn8Lf7YpFqEwFnZoWyxkmEue+2XAVaDEq8ay2bvIPIyccmOvs61qq4t66xJuVzmYiwHGvd3JN8BXuFkPabS7Ysg7osoEJ+cl+fA/GJoLUY+GLKyn33lrmgQahJXEmw1wlTVEr4OEURzw7Oaim7aDyU0icgRauAV7czuZqOIe4jAiwR5Caw==" msgstr[0] "GDh97KWu9dRiRzWhzr8Wbtr/F02791w5fasvtJ4heSYMOnACO0cKRHJwIHH9O6fTtLTwaRL44ZdoVgTe80IxGuYUKX0D3a4cVdmpkODuct/A1uv5nkmqlsX7oKhHBPT397WVcdJ/6ZaExPGzdLZ3U7PUPWDOYeAe8lHSs2NxUpQdrmoAYOhS4Eorkg==" msgstr[1] "GDh97KWu9dRiRzWhzr8Wbtr/F02791w5fasvtJ4heSYMOnACO0cKRHJwIHH9O6fTtLTwaRL44ZdoVgTe80IxGuYUKX0D3a4cVdmpkODuct/A1uv5nkmqlsX7oKhHBPT397WVcdJ/6ZaExPGzdLZ3U7PUPWDOYeAe8lHSs2NxUpQdrmoAYOhS4Eorkg==" #: b9gWXlajpm8HN4FH64C5icURgxXWg/87/tMiew== #~ msgctxt "VwqzMVcI0kDhQ9UJ1SIU0FYF7w9VA8A9n/xSBwURWBI6NlTFqDQAxJ6hWdH4tLxY2vg+K7a9OKd7NAO1q6hSwA==" #~ msgid "APWISazy24dcR94hQumZcceLmsRqzXckjUmwKsZSBRyqkhVOIr1F8nsvB8XHHltx3exLWARsrg9fRvCLvvqjiBX+DnBHeufL+2IbA1CKSQ==" #~ msgstr "IdP5UZnz1dcLPgxucqQCiaYBaNFOtQaKyevVCxl6v69O1qWqK0HVv4uzi2HO1IKleRk8BQwRvw35yk9IRjrjIuBAolWMFO95jQZTATCmHw0bmHlFtEIStBB/hoFS9mqcg0TNCW0AUHCqPJ24cZPuTUdfi9p5BQWPyLqS6fX6tC6LAcYfbxKQ5LnJwUoYTJ00gQUvbEE=" #: 63pv6WqKhyzIEaHC0BuybcaQhSfS+ARMnNzbtVWAFPhAvPZvVBiP #~ msgid "oNN6TWyz3v9MpzcOLtFdp2VewNZVnbxPEOnBUbEh563QsBfDzPcAp4uZNhfVW4ycrFXpEDb2+5JtFf/boGnWLhpUJYtMYcQF6Ny2B5qMkBUFKEBsrvv6rM7EnoHMopomTl7N/CJ38e5wgcEF4Jnn8ls=" #~ msgstr "BbXHATAcEkuwYRnCv38FFtscJhuSIW4BWyzozgHYXfTxzySMfHXREX5AvFOWZvmDZow02/Y+AGxLpX8YIDBA" #~ msgctxt "3fv+" #~ msgid "5zNkMe6/DrRZHCx01iwXXNm0CDfXxKv9EOpI+AKaVVNvcKvKYPMeugjtuGifg1vE4H2UBiaLk9Y9B1WzNRTD7b6/i5fDF9hdwS0M+okOtmy0B+DXUyuor7FSn/tX49DVA5rBQsYRCTzrt/Xz9N+xm6HfRl9LRbKs8Q==" #~ msgstr "zlUk69xBUCajL/0xPiLAiLvSPRX2YFwCSm+Uj+Aj1BvKItu+v9M=" #: olyO+bm91j5sX+6Xgz8z6jhzMZ7QPw== #~ msgctxt "ApEzTlyo" #~ msgid "" #~ "sBZfw6O67GawrmwgAJuRiLBj\n" #~ "whIhahz5MJs=\n" #~ "TQsJetZteEsmTd35T1Ct\n" #~ "rOcttGrFwj3eJPIWr2sChO6Y2Us=\n" #~ "4TSFg7JDEiPW3n/Z/N582C43TxVn2+3xfu9EUYPTVsVMkJyCO8aaTzst7L3W26YPmulb65I1WbeR2y/fxg==\n" #~ msgstr "" #~ "FpQtiQrz+w==\n" #~ "9RVGQqs43UNyy6RSrxyKvvPiV7fKmn9/rSzaMojQGVYzOFY=\n" #~ "jzXg871m\n" #~ "D/sHv6i4yiuGn8Vavl+zGHATQOVjEgGA5kGOj4BLi0LOq3vOWSvpF6F7Pn9W+i4zVcAWwGI7DwMAwI6ZZ6Yt5yU=\n" #~ "Y3HjvucfzuT306p/RmS0zL/pSxdNQAl3CtRlMCv8gYGWwIkk\n" #: g3Ke7wOmd8az9aFdF21pqR+9BsUAnQ== #~ msgctxt "C0ee/5hMFVfKH10y3/q1tW+JcJ2fUOwwSIWVDvSK+gWTlMpBjQiNLSlcRA527tdESHbpVdDY" #~ msgid "" #~ "8Jwdo59XuHi6fF0sepxwZBdldYisC6xS/OBi6jck\n" #~ "1HnzUc05I+6bgNt/DJC3BuXOKlaPKw6bHrwHtiLhYnf8ZD5NLRUayw==\n" #~ "YxP9bmqe54xzHsV+kvOC8nGxLq5l1/iNSFqYZm8lXzoPyTyW+gnNDuprBxWA+JTHtMQ=\n" #~ "dwtmn87DiWuyaxmAg/gG/GTmQMSnttR50+FGMvUJyraXHjJtPoBboXCcnEPwyQ==\n" #~ "Ih0YhukxpcA=\n" #~ msgstr "" #~ "KNV21UxUFdML\n" #~ "lEWV1dXMM2DCDsf/VGJCSYBMCknqOfZy8zxU1464j3wSbPF8+ASTnmodBOOgsJ8QgrlA\n" #~ "b3vT0oXJ0klocBX5GEf/1FxcHsSpz1lr1IATO1HpYknErp+UH3y0MJEJiFJwmNvYWF8=\n" #~ "HEdr/aQgXtk2Y1iopCxg6zdjBnQ=\n" #~ "dsfOG83jtxBvNFf9GybSCKLrlGvEA2jvTYA=\n" simple-po-parser-1.1.5/spec/0000755000175200017520000000000013632502563015106 5ustar debiandebiansimple-po-parser-1.1.5/spec/utils/0000755000175200017520000000000013632502563016246 5ustar debiandebiansimple-po-parser-1.1.5/spec/utils/random_pofile_generator.rb0000644000175200017520000001426513632502563023467 0ustar debiandebianmodule SimplePoParser module RandomPoFileGenerator require 'securerandom' def self.generate_file(file_path, length = 1000, obsoletes = 10) header = "# PO benchmark file header # #, fuzzy msgid \"\" msgstr \"\" \"Project-Id-Version: somehwat master\\n\" \"Report-Msgid-Bugs-To: \\n\" \"Last-Translator: last t \\n\" \"Language-Team: team\\n\" \"Content-Type: text/plain; charset=UTF-8\\n\" \"MIME-Version: 1.0\\n\" \"Content-Transfer-Encoding: 8bit\\n\" \"Plural-Forms: nplurals=1; plural=0;\\n\"" @random = Random.new File.open(file_path, 'w+') do |file| file.write header file.write "\n\n" for i in 0..length-obsoletes do file.write generate_random_message end for i in 0...obsoletes do file.write generate_random_message(true) end end end private def self.generate_random_message(obsolete = false) random_message = "" untranslated_chance = 0.05 fuzzy_chance = 0.1 plural_chance = 0.1 multiline_chance = 0.1 translator_comment_chance = 0.2 extracted_comment_chance = 0.05 msgctxt_chance = 0.9 reference_chance = 0.9 multiple_reference_chance = 0.1 plural = @random.rand < plural_chance ? true : false untranslated = @random.rand < untranslated_chance ? true : false fuzzy = !untranslated && @random.rand < fuzzy_chance ? true : false multiline = @random.rand < multiline_chance ? true : false translator_comment = @random.rand < translator_comment_chance ? true : false extracted_comment = @random.rand < extracted_comment_chance ? true : false reference = @random.rand < reference_chance ? true : false multiple_reference = @random.rand < multiple_reference_chance ? true : false with_msgctxt = @random.rand < msgctxt_chance ? true : false msgctxt = with_msgctxt ? SecureRandom.base64((@random.rand*70.0).ceil) : nil if multiline lines = (@random.rand*4.0).ceil msgid = [] msgstr = [] for i in 0..lines msgid[i] = SecureRandom.base64((@random.rand*70.0).ceil) msgstr[i] = SecureRandom.base64((@random.rand*70.0).ceil) end else msgid = SecureRandom.base64((@random.rand*150.0).ceil) msgstr = SecureRandom.base64((@random.rand*150.0).ceil) end if plural if multiline msgid_plural = [] msgstr_plural = [] for i in 0..lines msgid_plural[i] = SecureRandom.base64((@random.rand*70.0).ceil) msgstr_plural[i] = SecureRandom.base64((@random.rand*70.0).ceil) end else msgid_plural = SecureRandom.base64((@random.rand*150.0).ceil) msgstr_plural = SecureRandom.base64((@random.rand*70.0).ceil) end end random_message += "# #{SecureRandom.base64((@random.rand*50.0).to_i)}\n" if translator_comment random_message += "#. #{SecureRandom.base64((@random.rand*50.0).to_i)}\n" if extracted_comment random_message += "#: #{SecureRandom.base64((@random.rand*50.0).to_i)}\n" if reference if multiple_reference references = (@random.rand*3.0).ceil for i in 0..references random_message += "#: #{SecureRandom.base64((@random.rand*50.0).to_i)}\n" end end if fuzzy random_message += "#, fuzzy\n" random_message += "##{"~" if obsolete}| msgctxt \"#{msgctxt}\"\n" if msgctxt if msgid.is_a?(Array) random_message += "##{"~" if obsolete}| msgid \"\"\n" msgid.each do |line| random_message += "##{"~" if obsolete}| \"#{line}\\n\"\n" end else random_message += "##{"~" if obsolete}| msgid \"#{msgid}\"\n" end if plural if msgid_plural.is_a?(Array) random_message += "##{"~" if obsolete}| msgid_plural \"\"\n" msgid_plural.each do |line| random_message += "##{"~" if obsolete}| \"#{line}\\n\"\n" end else random_message += "##{"~" if obsolete}| msgid_plural \"#{msgid_plural}\"\n" end end end random_message += "#{"#~ " if obsolete}msgctxt \"#{msgctxt}\"\n" if msgctxt if msgid.is_a?(Array) random_message += "#{"#~ " if obsolete}msgid \"\"\n" msgid.each do |line| random_message += "#{"#~ " if obsolete}\"#{line}\\n\"\n" end else random_message += "#{"#~ " if obsolete}msgid \"#{msgid}\"\n" end if plural if msgid_plural.is_a?(Array) random_message += "#{"#~ " if obsolete}msgid_plural \"\"\n" msgid_plural.each do |line| random_message += "#{"#~ " if obsolete}\"#{line}\\n\"\n" end else random_message += "#{"#~ " if obsolete}msgid_plural \"#{msgid_plural}\"\n" end if untranslated random_message += "#{"#~ " if obsolete}msgstr[0] \"\"\n" random_message += "#{"#~ " if obsolete}msgstr[1] \"\"\n" else if msgstr.is_a?(Array) random_message += "#{"#~ " if obsolete}msgstr[0] \"\"\n" msgstr.each do |line| random_message += "#{"#~ " if obsolete}\"#{line}\\n\"\n" end else random_message += "#{"#~ " if obsolete}msgstr[0] \"#{msgstr}\"\n" end if msgstr_plural.is_a?(Array) random_message += "#{"#~ " if obsolete}msgstr[1] \"\"\n" msgstr_plural.each do |line| random_message += "#{"#~ " if obsolete}\"#{line}\\n\"\n" end else random_message += "#{"#~ " if obsolete}msgstr[1] \"#{msgstr}\"\n" end end else if untranslated random_message += "#{"#~ " if obsolete}msgstr \"\"\n" else if msgstr.is_a?(Array) random_message += "#{"#~ " if obsolete}msgstr \"\"\n" msgstr.each do |line| random_message += "#{"#~ " if obsolete}\"#{line}\\n\"\n" end else random_message += "#{"#~ " if obsolete}msgstr \"#{msgstr}\"\n" end end end random_message += "\n" random_message end end end simple-po-parser-1.1.5/spec/spec_helper.rb0000644000175200017520000000200413632502563017720 0ustar debiandebian# This file was generated by the `rspec --init` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # Require this file using `require "spec_helper"` to ensure that it is only # loaded once. # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration require 'simplecov' require 'coveralls' require 'awesome_print' SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new( [SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter] ) SimpleCov.start do add_group "gem", "lib" add_group "spec", "spec" end require 'simple_po_parser' RSpec.configure do |config| config.raise_errors_for_deprecations! config.run_all_when_everything_filtered = true config.filter_run :focus # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 config.order = 'random' end simple-po-parser-1.1.5/spec/simple_po_parser/0000755000175200017520000000000013632502563020451 5ustar debiandebiansimple-po-parser-1.1.5/spec/simple_po_parser/simple_po_parser_spec.rb0000644000175200017520000000156313632502563025360 0ustar debiandebianrequire "spec_helper" describe SimplePoParser do let(:po_file) { Pathname.new('spec/simple_po_parser/fixtures/complete_file.po').realpath } let(:crlf_file) { Pathname.new('spec/simple_po_parser/fixtures/crlf_encoded.po').realpath } let(:non_ascii_file) { Pathname.new('spec/simple_po_parser/fixtures/non_ascii_file.po').realpath } let(:po_complex_message) { File.read(File.expand_path("fixtures/complex_entry.po", __dir__))} it "parses a po file" do expect(SimplePoParser.parse(po_file)).to be_a_kind_of Array end it "parses crlf encoded files" do expect(SimplePoParser.parse(crlf_file)).to be_a_kind_of Array end it "parses a non ascii po file" do expect(SimplePoParser.parse(non_ascii_file)).to be_a_kind_of Array end it "parses a single message" do expect(SimplePoParser.parse_message(po_complex_message)).to be_a_kind_of Hash end end simple-po-parser-1.1.5/spec/simple_po_parser/parser_spec.rb0000644000175200017520000001401613632502563023306 0ustar debiandebianrequire "spec_helper" describe SimplePoParser::Parser do let (:po_header) { File.read(File.expand_path("fixtures/header.po", __dir__))} let(:po_complex_message) { File.read(File.expand_path("fixtures/complex_entry.po", __dir__))} let(:po_simple_message) { File.read(File.expand_path("fixtures/simple_entry.po", __dir__))} it "parses the PO header" do expected_result = { :translator_comment => ["PO Header entry", ""], :flag => "fuzzy", :msgid => "", :msgstr => ["", "Project-Id-Version: simple_po_parser 1\\n", "Report-Msgid-Bugs-To: me\\n"] } expect(SimplePoParser::Parser.new.parse(po_header)).to eq(expected_result) end it "parses the simple entry as expected" do expected_result = { :translator_comment => "translator-comment", :extracted_comment => "extract", :reference => "reference1", :msgctxt => "Context", :msgid => "msgid", :msgstr => "translated" } expect(SimplePoParser::Parser.new.parse(po_simple_message)).to eq(expected_result) end it "parses the complex entry as expected" do expected_result = { :translator_comment => ["translator-comment", ""], :extracted_comment => "extract", :reference => ["reference1", "reference2"], :flag => "flag", :previous_msgctxt => "previous context", :previous_msgid => ["", "multiline\\n", "previous messageid"], :previous_msgid_plural => "previous msgid_plural", :msgctxt => "Context", :msgid => "msgid", :msgid_plural => ["", "multiline msgid_plural\\n", ""], "msgstr[0]" => "msgstr 0", "msgstr[1]" => ["", "msgstr 1 multiline 1\\n", "msgstr 1 line 2\\n"], "msgstr[2]" => "msgstr 2" } expect(SimplePoParser::Parser.new.parse(po_complex_message)).to eq(expected_result) end context "Errors" do it "errors cascade to ParserError" do message = "invalid message" expect{ SimplePoParser::Parser.new.parse(message) }.to raise_error(SimplePoParser::ParserError) end it "raises an error if there is no msgid" do message = "# comment\nmsgctxt \"ctxt\"\nmsgstr \"translation\"" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /Message without msgid is not allowed/) end it "raises an error if there is no msgstr in singular message" do message = "# comment\nmsgctxt \"ctxt\"\nmsgid \"msg\"" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /Singular message without msgstr is not allowed/) end it "raises an error if there is no msgstr[0] in plural message" do message = "# comment\nmsgid \"id\"\nmsgid_plural \"msg plural\"" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /Plural message without msgstr\[0\] is not allowed/) message = "# comment\nmsgid \"id\"\nmsgid_plural \"msg plural\"\nmsgstr[1] \"plural trans\"" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /Bad 'msgstr\[index\]' index/) end context "comments" do it "raises an error on unknown comment types" do message = "#- no such comment type" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /Unknown comment type/) end it "raises an error on unknown previous comment types" do message = "#| msgstr \"no such comment type\"" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /Previous comment type .*? unknown/) message = "#| bla " expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /Previous comments must start with '#| msg'/) end it "raises an error if any lines are not marked obsolete after the first obsolete line" do message = "# comment\n#~msgid \"hi\"\nmsgstr \"should be obsolete\"" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /All lines must be obsolete after the first obsolete line, but got/) end it "raises an error if previous comments are not marked obsolete in obsolete entries" do message = "# comment\n#| msgid \"hi\"\n#~msgid \"hi\"\n#~msgstr \"should be obsolete\"" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /Previous comment entries need to be marked obsolete too in obsolete message entries/) message = "# comment\n#| msgctxt \"hi\"\n#~msgid \"hi\"\n#~msgstr \"should be obsolete\"" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /Previous comment entries need to be marked obsolete too in obsolete message entries/) end end context "message_line" do it "raises an error if a message_line does not start with a double quote" do message = "msgid No starting double quote\"" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /A message text needs to start with the double quote character/) end it "raises an error if a message_line does not end with a double quote" do message = "msgid \"No ending double quote" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /The message text .*? must be finished with the double quote character/) end it "raises an error if there is anything but whitespace after the ending double quote" do message = "msgid \"text\" this shouldn't be here" expect{ SimplePoParser::Parser.new.parse(message) }. to raise_error(SimplePoParser::ParserError, /There should be only whitespace until the end of line after the double quote character/) end end end end simple-po-parser-1.1.5/spec/simple_po_parser/fixtures/0000755000175200017520000000000013632502563022322 5ustar debiandebiansimple-po-parser-1.1.5/spec/simple_po_parser/fixtures/simple_entry.po0000644000175200017520000000014213632502563025371 0ustar debiandebian# translator-comment #. extract #: reference1 msgctxt "Context" msgid "msgid" msgstr "translated" simple-po-parser-1.1.5/spec/simple_po_parser/fixtures/non_ascii_file.po0000644000175200017520000000333513632502563025627 0ustar debiandebian# Persian translation for damned-lies. # Copyright (C) 2012 damned-lies's COPYRIGHT HOLDER # This file is distributed under the same license as the damned-lies package. # Arash Mousavi , 2014. # msgid "" msgstr "" "Project-Id-Version: damned-lies master\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2012-05-04 12:56+0000\n" "PO-Revision-Date: 2014-05-15 22:24+0330\n" "Last-Translator: Arash Mousavi \n" "Language-Team: Persian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Poedit 1.6.4\n" #: database-content.py:1 database-content.py:129 settings.py:52 msgid "Afrikaans" msgstr "آفریقایی" #: templates/vertimus/vertimus_detail.html:105 #, python-format msgid " including %(stats)s image" msgid_plural " including %(stats)s images" msgstr[0] "" msgstr[1] "" #: templates/vertimus/vertimus_detail.html:136 vertimus/forms.py:79 msgid "Invalid action. Someone probably posted another action just before you." msgstr "" "فعالیت نامعتبر. شاید یک نفر دیگر دقیقا قبل از شما یک فعالیت دیگر ارسال کرده " "است." #: vertimus/models.py:470 #, python-format #| msgid "" #| "Hello,\n" #| "\n" #| "The new state of %(module)s - %(branch)s - %(domain)s (%(language)s) is " #| "now '%(new_state)s'.\n" #| "%(url)s\n" #| "\n" msgid "" "The new state of %(module)s - %(branch)s - %(domain)s (%(language)s) is now " "'%(new_state)s'." msgstr "" "وضعیت جدید %(module)s - %(branch)s - %(domain)s (%(language)s) هم‌اکنون " "«%(new_state)s» است." simple-po-parser-1.1.5/spec/simple_po_parser/fixtures/header.po0000644000175200017520000000017013632502563024110 0ustar debiandebian# PO Header entry # #, fuzzy msgid "" msgstr "" "Project-Id-Version: simple_po_parser 1\n" "Report-Msgid-Bugs-To: me\n" simple-po-parser-1.1.5/spec/simple_po_parser/fixtures/crlf_encoded.po0000644000175200017520000000206513632502563025274 0ustar debiandebian# PO Header entry # #, fuzzy msgid "" msgstr "" "Project-Id-Version: simple_po_parser 1\n" "Report-Msgid-Bugs-To: me\n" "POT-Creation-Date: 2012-05-04 12:56+0000\n" "PO-Revision-Date: 2014-05-15 22:24+0330\n" "Last-Translator: Dennis-Florian Herr \n" "Language-Team: English\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" # translator-comment #. extract #: reference1 msgctxt "Context" msgid "msgid" msgstr "translated" # translator-comment # #. extract #: reference1 #: reference2 #, flag #| msgctxt "previous context" #| msgid "" #| "multiline\n" #|"previous messageid" #| msgid_plural "previous msgid_plural" msgctxt "Context" msgid "msgid" msgid_plural "" "multiline msgid_plural\n" "" msgstr[0] "msgstr 0" msgstr[1] "" "msgstr 1 multiline 1\n" "msgstr 1 line 2\n" msgstr[2] "msgstr 2" # translator-comment #. extract #: reference1 #~ msgctxt "Context" #~ msgid "msgid" #~ msgstr "translated" simple-po-parser-1.1.5/spec/simple_po_parser/fixtures/complex_entry.po0000644000175200017520000000056313632502563025556 0ustar debiandebian# translator-comment # #. extract #: reference1 #: reference2 #, flag #| msgctxt "previous context" #| msgid "" #| "multiline\n" #|"previous messageid" #| msgid_plural "previous msgid_plural" msgctxt "Context" msgid "msgid" msgid_plural "" "multiline msgid_plural\n" "" msgstr[0] "msgstr 0" msgstr[1] "" "msgstr 1 multiline 1\n" "msgstr 1 line 2\n" msgstr[2] "msgstr 2" simple-po-parser-1.1.5/spec/simple_po_parser/fixtures/complete_file.po0000644000175200017520000000200213632502563025463 0ustar debiandebian# PO Header entry # #, fuzzy msgid "" msgstr "" "Project-Id-Version: simple_po_parser 1\n" "Report-Msgid-Bugs-To: me\n" "POT-Creation-Date: 2012-05-04 12:56+0000\n" "PO-Revision-Date: 2014-05-15 22:24+0330\n" "Last-Translator: Dennis-Florian Herr \n" "Language-Team: English\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" # translator-comment #. extract #: reference1 msgctxt "Context" msgid "msgid" msgstr "translated" # translator-comment # #. extract #: reference1 #: reference2 #, flag #| msgctxt "previous context" #| msgid "" #| "multiline\n" #|"previous messageid" #| msgid_plural "previous msgid_plural" msgctxt "Context" msgid "msgid" msgid_plural "" "multiline msgid_plural\n" "" msgstr[0] "msgstr 0" msgstr[1] "" "msgstr 1 multiline 1\n" "msgstr 1 line 2\n" msgstr[2] "msgstr 2" # translator-comment #. extract #: reference1 #~ msgctxt "Context" #~ msgid "msgid" #~ msgstr "translated" simple-po-parser-1.1.5/simple_po_parser.gemspec0000644000175200017520000000174513632502563021073 0ustar debiandebian# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'simple_po_parser/version' Gem::Specification.new do |spec| spec.name = "simple_po_parser" spec.version = SimplePoParser::VERSION spec.authors = ["Dennis-Florian Herr"] spec.email = ["dennis.herr@experteer.com"] spec.summary = %q{A simple PO file to ruby hash parser} spec.description = %q{A simple PO file to ruby hash parser . PO files are translation files generated by GNU/Gettext tool.} spec.homepage = "http://github.com/experteer/simple_po_parser" spec.license = "MIT" spec.files = `git ls-files`.split($/) spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^spec/}) spec.require_paths = ["lib"] # Development deps spec.add_development_dependency "bundler", ">= 0" spec.add_development_dependency "rake", ">= 0" end simple-po-parser-1.1.5/lib/0000755000175200017520000000000013632502563014722 5ustar debiandebiansimple-po-parser-1.1.5/lib/simple_po_parser/0000755000175200017520000000000013632502563020265 5ustar debiandebiansimple-po-parser-1.1.5/lib/simple_po_parser/version.rb0000644000175200017520000000010113632502563022267 0ustar debiandebian# encoding: utf-8 module SimplePoParser VERSION = "1.1.5" end simple-po-parser-1.1.5/lib/simple_po_parser/tokenizer.rb0000644000175200017520000000125613632502563022630 0ustar debiandebian# encoding: utf-8 module SimplePoParser # Split a PO file into single PO message entities (a message is seperated by two newline) class Tokenizer def initialize @messages = [] end def parse_file(path) file = File.open(path, "r") if(file.gets =~ /\r$/) # detected windows line ending file.close file = File.open(path, "rt") else file.rewind end file.each_line("\n\n") do |block| block.strip! # dont parse empty blocks @messages << parse_block(block) if block != '' end @messages end private def parse_block(block) Parser.new.parse(block) end end end simple-po-parser-1.1.5/lib/simple_po_parser/parser.rb0000644000175200017520000003174113632502563022114 0ustar debiandebian# encoding: utf-8 module SimplePoParser # Fast parser directly using Rubys powerful StringScanner (strscan) # # Important notes about StringScanner.scan: # * scan will return nil if there is no match. Using the regex * (zero or more) quantifier will # let scan return an empty string if there is "no match" as the empty string qualifies as # a match of the regex (zero times). We make use of this "trick" # * the start of line anchor ^ is obsolete as scan will only match start of line. # * rubys regex is by default in single-line mode, therefore scan will only match until # the next newline is hit (unless multi-line mode is explicitly enabled) class Parser require_relative 'error' require 'strscan' # parse a single message of the PO format. # # @param message a single PO message in String format without leading or trailing whitespace # @return [Hash] parsed PO message information in Hash format def parse(message) @result = {} @scanner = StringScanner.new(message.strip) begin lines rescue ParserError => pe error_msg = "SimplePoParser::ParserError" error_msg += pe.message error_msg += "\nParseing result before error: '#{@result}'" error_msg += "\nSimplePoParser filtered backtrace: SimplePoParser::ParserError" backtrace = "#{pe.backtrace.select{|i| i =~ /lib\/simple_po_parser/}.join("\n\tfrom ")}" raise ParserError, error_msg, backtrace end @result end private ######################################### ### branching ### ######################################### # arbitary line of a PO message. Can be comment or message # message parsing is always started with checking for msgctxt as content is expected in # msgctxt -> msgid -> msgid_plural -> msgstr order def lines begin if @scanner.scan(/#/) comment else msgctxt end rescue PoSyntaxError => pe # throw a normal ParserError to break the recursion raise ParserError, "Syntax error in lines\n" + pe.message, pe.backtrace end end # match a comment line. called on lines starting with '#'. # Recalls line when the comment line was parsed def comment begin case @scanner.getch when ' ' skip_whitespace add_result(:translator_comment, comment_text) lines when '.' skip_whitespace add_result(:extracted_comment, comment_text) lines when ':' skip_whitespace add_result(:reference, comment_text) lines when ',' skip_whitespace add_result(:flag, comment_text) lines when '|' skip_whitespace previous_comments lines when "\n" add_result(:translator_comment, "") # empty comment line lines when '~' if @result[:previous_msgctxt] || @result[:previous_msgid] || @result[:previous_msgid_plural] raise PoSyntaxError, "Previous comment entries need to be marked obsolete too in obsolete message entries. But already got: #{@result}" end skip_whitespace add_result(:obsolete, comment_text) obsoletes else @scanner.pos = @scanner.pos - 2 raise PoSyntaxError, "Unknown comment type #{@scanner.peek(10).inspect}" end rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in comment\n" + pe.message, pe.backtrace end end # matches the msgctxt line and will continue to check for msgid afterwards # # msgctxt is optional def msgctxt begin if @scanner.scan(/msgctxt/) skip_whitespace text = message_line add_result(:msgctxt, text) message_multiline(:msgctxt) if text.empty? end msgid rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in msgctxt\n" + pe.message, pe.backtrace end end # matches the msgid line. Will check for optional msgid_plural. # Will advance to msgstr or msgstr_plural based on msgid_plural # # msgid is required def msgid begin if @scanner.scan(/msgid/) skip_whitespace text = message_line add_result(:msgid, text) message_multiline(:msgid) if text.empty? if msgid_plural msgstr_plural else msgstr end else err_msg = "Message without msgid is not allowed." err_msg += "The Line started unexpectedly with #{@scanner.peek(10).inspect}." raise PoSyntaxError, err_msg end rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in msgid\n" + pe.message, pe.backtrace end end # matches the msgid_plural line. # # msgid_plural is optional # # @return [boolean] true if msgid_plural is present, false otherwise def msgid_plural begin if @scanner.scan(/msgid_plural/) skip_whitespace text = message_line add_result(:msgid_plural, text) message_multiline(:msgid_plural) if text.empty? true else false end rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in msgid\n" + pe.message, pe.backtrace end end # parses the msgstr singular line # # msgstr is required in singular translations def msgstr begin if @scanner.scan(/msgstr/) skip_whitespace text = message_line add_result(:msgstr, text) message_multiline(:msgstr) if text.empty? skip_whitespace raise PoSyntaxError, "Unexpected content after expected message end #{@scanner.peek(10).inspect}" unless @scanner.eos? else raise PoSyntaxError, "Singular message without msgstr is not allowed. Line started unexpectedly with #{@scanner.peek(10).inspect}." end rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in msgstr\n" + pe.message, pe.backtrace end end # parses the msgstr plural lines # # msgstr plural lines are used when there is msgid_plural. # They have the format msgstr[N] where N is incremental number starting from zero representing # the plural number as specified in the headers "Plural-Forms" entry. Most languages, like the # English language only have two plural forms (singular and plural), # but there are languages with more plurals def msgstr_plural(num = 0) begin msgstr_key = @scanner.scan(/msgstr\[\d\]/) # matches 'msgstr[0]' to 'msgstr[9]' if msgstr_key # msgstr plurals must come in 0-based index in order msgstr_num = msgstr_key.match(/\d/)[0].to_i raise PoSyntaxError, "Bad 'msgstr[index]' index." if msgstr_num != num skip_whitespace text = message_line add_result(msgstr_key, text) message_multiline(msgstr_key) if text.empty? msgstr_plural(num+1) elsif num == 0 # and msgstr_key was false raise PoSyntaxError, "Plural message without msgstr[0] is not allowed. Line started unexpectedly with #{@scanner.peek(10).inspect}." else raise PoSyntaxError, "End of message was expected, but line started unexpectedly with #{@scanner.peek(10).inspect}" unless @scanner.eos? end rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in msgstr_plural\n" + pe.message, pe.backtrace end end # parses previous comments, which provide additional information on fuzzy matching # # previous comments are: # * #| msgctxt # * #| msgid # * #| msgid_plural def previous_comments begin # next part must be msgctxt, msgid or msgid_plural if @scanner.scan(/msg/) if @scanner.scan(/id/) if @scanner.scan(/_plural/) key = :previous_msgid_plural else key = :previous_msgid end elsif @scanner.scan(/ctxt/) key = :previous_msgctxt else raise PoSyntaxError, "Previous comment type #{("msg" + @scanner.peek(10)).inspect} unknown." end skip_whitespace text = message_line add_result(key, text) previous_multiline(key) if text.empty? else raise PoSyntaxError, "Previous comments must start with '#| msg'. #{@scanner.peek(10).inspect} unknown." end rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in previous_comments\n" + pe.message, pe.backtrace end end # parses the multiline messages of the previous comment lines def previous_multiline(key) begin # scan multilines until no further multiline is hit # /#\|\p{Blank}"/ needs to catch the double quote to ensure it hits a previous # multiline and not another line type. if @scanner.scan(/#\|\p{Blank}*"/) @scanner.pos = @scanner.pos - 1 # go one character back, so we can reuse the "message line" method add_result(key, message_line) previous_multiline(key) # go on until we no longer hit a multiline line end rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in previous_multiline\n" + pe.message, pe.backtrace end end # parses a multiline message # # multiline messages are indicated by an empty content as first line and the next line # starting with the double quote character def message_multiline(key) begin skip_whitespace if @scanner.check(/"/) add_result(key, message_line) message_multiline(key) end rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in message_multiline with key '#{key}'\n" + pe.message, pe.backtrace end end # identifies a message line and returns it's text or raises an error # # @return [String] message_text def message_line begin if @scanner.getch == '"' text = message_text unless @scanner.getch == '"' err_msg = "The message text '#{text}' must be finished with the double quote character '\"'." raise PoSyntaxError, err_msg end skip_whitespace unless end_of_line err_msg = "There should be only whitespace until the end of line" err_msg += " after the double quote character of a message text." raise PoSyntaxError.new(err_msg) end text else @scanner.pos = @scanner.pos - 1 err_msg = "A message text needs to start with the double quote character '\"'," err_msg += " but this was found: #{@scanner.peek(10).inspect}" raise PoSyntaxError, err_msg end rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in message_line\n" + pe.message, pe.backtrace end end # parses all obsolete lines. # An obsolete message may only contain obsolete lines def obsoletes if @scanner.scan(/#~/) skip_whitespace add_result(:obsolete, comment_text) obsoletes else raise PoSyntaxError, "All lines must be obsolete after the first obsolete line, but got #{@scanner.peek(10).inspect}." unless @scanner.eos? end end ######################################### ### scanning ### ######################################### # returns the text of a comment # # @return [String] text def comment_text begin text = @scanner.scan(/.*/) # everything until newline text.rstrip! # benchmarked faster too rstrip the string in place raise PoSyntaxError, "Comment text should advance to next line or stop at eos" unless end_of_line text rescue PoSyntaxError => pe raise PoSyntaxError, "Syntax error in commtent_text\n" + pe.message, pe.backtrace end end # returns the text of a message line # # @return [String] text def message_text @scanner.scan_until(/(\\(\\|")|[^"])*/) # this parses anything until an unescaped quote is hit end # advances the scanner until the next non whitespace position. # Does not match newlines. See WHITESPACE_REGEX constant def skip_whitespace @scanner.skip(/\p{Blank}+/) end # returns true if the scanner is at beginning of next line or end of string # # @return [Boolean] true if scanner at beginning of line or eos def end_of_line @scanner.scan(/\n/) @scanner.eos? || @scanner.bol? end # adds text to the given key in results # creates an array if the given key already has a result def add_result(key, text) if @result[key] if @result[key].is_a? Array @result[key].push(text) else @result[key] = [@result[key], text] end else @result[key] = text end end end end simple-po-parser-1.1.5/lib/simple_po_parser/error.rb0000644000175200017520000000032713632502563021745 0ustar debiandebian# encoding: utf-8 module SimplePoParser class ParserError < StandardError end class PoSyntaxError < ParserError @msg = "" def initialize(msg="Invalid po syntax") @msg = msg super(msg) end end end simple-po-parser-1.1.5/lib/simple_po_parser.rb0000644000175200017520000000070213632502563020611 0ustar debiandebian# encoding: utf-8 require 'simple_po_parser/error' require 'simple_po_parser/parser' require 'simple_po_parser/tokenizer' require 'simple_po_parser/version' module SimplePoParser class << self # parse po file # # returns an array of po messages as hashes def parse(path) Tokenizer.new.parse_file(path) end # parses a single message. def parse_message(message) Parser.new.parse(message) end end end simple-po-parser-1.1.5/Rakefile0000644000175200017520000000413713632502563015626 0ustar debiandebian# encoding: utf-8 require 'rubygems' require 'rake' require 'rspec/core/rake_task' require 'bundler/gem_tasks' task :default => :spec desc "Generate a random po file to \"test/benchmark.po\". Takes optional rake args for number of entries" task 'generate_random_pofile', :messages, :obsoletes do |t, args| args.with_defaults(:messages => "200", :obsoletes => "10") require_relative 'spec/utils/random_pofile_generator' PoParser::RandomPoFileGenerator.generate_file( File.expand_path("test/benchmark.po", __dir__), args[:messages].to_i, args[:obsoletes].to_i ) end namespace :parser do require 'benchmark' require 'simple_po_parser' desc "Benchmark of 100 full PoParser runs of test/benchmark.po" task "benchmark" do pofile = File.expand_path("test/benchmark.po", __dir__) Benchmark.bmbm do |x| x.report("Parser:") {100.times { SimplePoParser.parse(pofile) }} end end desc "Generate 5 random PO files with 100 to 500 messages and benchmark each full PoParser run" task 'five_random_po_full' do include Benchmark require_relative 'spec/utils/random_pofile_generator' pofile = File.expand_path("test/benchmark.po.tmp", __dir__) Benchmark.benchmark(CAPTION, 6, FORMAT, "total:") do |x| total = nil total_length = 0 for i in 0..5 do length = (Random.new.rand * 400.0 + 100).to_i total_length += length puts "Benchmarking file of length #{length}" SimplePoParser::RandomPoFileGenerator.generate_file(pofile, length) t = x.report("try#{i}:") {SimplePoParser.parse(pofile)} File.unlink(pofile) total = total ? total+t : t end puts "Total message length #{total_length}" [total] end end desc "Show ruby-prof profiler for spec/fixtures/complex_entry.po" task "profile_parser" do require 'ruby-prof' po_message = File.read(File.expand_path("spec/simple_po_parser/fixtures/complex_entry.po", __dir__)) RubyProf.start SimplePoParser.parse_message(po_message) result = RubyProf.stop printer = RubyProf::FlatPrinter.new(result) printer.print(STDOUT) end end simple-po-parser-1.1.5/README.md0000644000175200017520000000422113632502563015432 0ustar debiandebian# Simple Po Parser [![Build Status](https://travis-ci.org/experteer/simple_po_parser.svg?branch=master)](https://travis-ci.org/experteer/simple_po_parser) [![Coverage Status](https://img.shields.io/coveralls/experteer/simple_po_parser.svg)](https://coveralls.io/github/experteer/simple_po_parser) [![Gem Version](https://badge.fury.io/rb/simple_po_parser.svg)](https://badge.fury.io/rb/simple_po_parser) This is a simple PO file to ruby hash parser, which complies with [GNU PO file specification](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html). Tested with the msgcat (GNU gettext-tools) 0.18.3 tool. The parser is probably as optimized for speed as possible with pure ruby, while parsing all different PO types into seperate keys. It was written as a "core-replacement" for an equivalent parslet PEG parser for [arashm/PoParser](https://github.com/arashm/PoParser) and benchmarked about 500 times faster. ## Usage The parser can be used in two ways: ```ruby SimplePoParser.parse(file_path) # parses a PO file and returns array of hashes SimplePoParser.parse_message(message) # parses a single PO message and returns a hash ``` ### Hash format A PO message is parsed into a hash with meaningful keys for each type of line. The values are strings if only one line of such content was parsed, otherwise it's an array of strings. Each string is representing one line of content in the PO file. ```ruby { :translator_comment => "" || ["", ""...], :extracted_comment => "" || ["", ""...], :reference => "" || ["", ""...], :flag => "" || ["", ""...], :previous_msgctxt => "" || ["", ""...],# msgctxt of the message used for the fuzzy translation :previous_msgid => "" || ["", ""...], # msgid of the messaged used for the fuzzy translation :previous_msgid_plural => "" || ["", ""...], :msgctxt => "" || ["", ""...], :msgid => "" || ["", ""...], :msgid_plural => "" || ["", ""...], :msgstr => "" || ["", ""...], # for singular messages "msgstr[N]" => "" || ["", ""...] # for plural messages, there N is the plural number starting from 0 } ``` ## License License: [MIT](LICENSE.txt) - Copyright (c) 2017 Dennis-Florian Herr @Experteer GmbH simple-po-parser-1.1.5/LICENSE.txt0000644000175200017520000000210513632502563015775 0ustar debiandebianCopyright (c) 2017 Dennis-Florian Herr @ Experteer GmbH MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. simple-po-parser-1.1.5/Gemfile0000644000175200017520000000024213632502563015445 0ustar debiandebiansource 'https://rubygems.org' group :test do gem 'coveralls', :require => false gem 'rspec', '~> 3.5.0' gem 'awesome_print' gem 'ruby-prof' end gemspec simple-po-parser-1.1.5/CHANGELOG.md0000644000175200017520000000037713632502563015774 0ustar debiandebianVersion 1.1.0 ============= * for line types only parsed once the parser returns a string instead of an array with one string Version 1.0.1 ============= * added specs * fixed minor parser errors Version 1.0.0 ============= * initial release simple-po-parser-1.1.5/.travis.yml0000644000175200017520000000020113632502563016256 0ustar debiandebianbundler_args: --without development language: ruby sudo: false rvm: - 2.1.9 - 2.2.6 - 2.3.1 script: bundle exec rspec spec simple-po-parser-1.1.5/.rspec0000644000175200017520000000005313632502563015267 0ustar debiandebian--color --format doc --require spec_helper simple-po-parser-1.1.5/.gitignore0000644000175200017520000000010313632502563016136 0ustar debiandebian*.gem .bundle .ruby-version Gemfile.lock coverage pkg test/tmp tmp simple-po-parser-1.1.5/.gitattributes0000644000175200017520000000006613632502563017051 0ustar debiandebianspec/simple_po_parser/fixtures/crlf_encoded.po binary