From 5032dad17d3bf4d74fd9ac07804881df6e70dafa Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 18 Feb 2013 18:55:59 +0100 Subject: [PATCH 001/483] [FIX] module: install_from_urls: restrict to administrators. Urls must come from apps server. lp bug: https://launchpad.net/bugs/1129299 fixed bzr revid: chs@openerp.com-20130218175559-ygo0goytspg119bl --- openerp/addons/base/module/module.py | 16 ++++++++++++++-- openerp/addons/base/static/src/js/apps.js | 4 ++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index a0d1eedef2b..73c61812ee0 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -30,6 +30,7 @@ import shutil import tempfile import urllib import urllib2 +import urlparse import zipfile import zipimport @@ -39,6 +40,7 @@ except ImportError: from StringIO import StringIO # NOQA import openerp +import openerp.exceptions from openerp import modules, pooler, tools, addons from openerp.modules.db import create_categories from openerp.tools.parse_version import parse_version @@ -655,6 +657,11 @@ class module(osv.osv): return res def install_from_urls(self, cr, uid, urls, context=None): + if not self.pool['res.users'].has_group(cr, uid, 'base.group_system'): + raise openerp.exceptions.AccessDenied() + + apps_server = urlparse.urlparse(self.get_apps_server(cr, uid, context=context)) + OPENERP = 'openerp' tmp = tempfile.mkdtemp() _logger.debug('Install from url: %r', urls) @@ -663,6 +670,11 @@ class module(osv.osv): for module_name, url in urls.items(): if not url: continue # nothing to download, local version is already the last one + + up = urlparse.urlparse(url) + if up.scheme != apps_server.scheme or up.netloc != apps_server.netloc: + raise openerp.exceptions.AccessDenied() + try: _logger.info('Downloading module `%s` from OpenERP Apps', module_name) content = urllib2.urlopen(url).read() @@ -727,8 +739,8 @@ class module(osv.osv): finally: shutil.rmtree(tmp) - def install_by_names(self, cr, uid, names, context=None): - raise NotImplementedError('# TODO') + def get_apps_server(self, cr, uid, context=None): + return tools.config.get('apps_server', 'https://apps.openerp.com/apps') def _update_dependencies(self, cr, uid, mod_browse, depends=None): if depends is None: diff --git a/openerp/addons/base/static/src/js/apps.js b/openerp/addons/base/static/src/js/apps.js index a55c89a0483..7a77e827a94 100644 --- a/openerp/addons/base/static/src/js/apps.js +++ b/openerp/addons/base/static/src/js/apps.js @@ -62,8 +62,8 @@ openerp.base = function(instance) { if (instance.base.apps_client) { return check_client_available(instance.base.apps_client); } else { - var ICP = new instance.web.Model('ir.config_parameter'); - return ICP.call('get_param', ['apps.server', 'https://apps.openerp.com/apps']).then(function(u) { + var Mod = new instance.web.Model('ir.module.module'); + return Mod.call('get_apps_server').then(function(u) { var link = $(_.str.sprintf('', u))[0]; var host = _.str.sprintf('%s//%s', link.protocol, link.host); var dbname = link.pathname; From a1f11cf0cd19a9599bfe6a7e9a5e05bd0380d423 Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Mon, 11 Mar 2013 14:24:33 +0100 Subject: [PATCH 002/483] [FIX] pto in invoice template should not cover the whole document lp bug: https://launchpad.net/bugs/971713 fixed bzr revid: stefan@therp.nl-20130311132433-rfz85yz831u1o1s9 --- .../account/report/account_print_invoice.rml | 28 +++++----- addons/sale/report/sale_order.rml | 52 +++++++++---------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/addons/account/report/account_print_invoice.rml b/addons/account/report/account_print_invoice.rml index 4ffa7a33f9d..579b6f0c10a 100644 --- a/addons/account/report/account_print_invoice.rml +++ b/addons/account/report/account_print_invoice.rml @@ -138,21 +138,8 @@ - [[ repeatIn(objects,'o') ]] [[ setLang(o.partner_id.lang) ]] - - - - Description - Taxes - Quantity - Unit Price - Disc.(%) - Price - - - @@ -217,6 +204,19 @@ + + + + + Description + Taxes + Quantity + Unit Price + Disc.(%) + Price + + + @@ -264,6 +264,7 @@ + @@ -371,6 +372,5 @@ - diff --git a/addons/sale/report/sale_order.rml b/addons/sale/report/sale_order.rml index a00d2d4e3ef..43e517394e5 100644 --- a/addons/sale/report/sale_order.rml +++ b/addons/sale/report/sale_order.rml @@ -126,33 +126,8 @@ - [[repeatIn(objects,'o')]] [[ setLang(o.partner_id.lang) ]] - - - - - Description - - - Tax - - - Quantity - - - Unit Price - - - Disc.(%) - - - Price - - - - @@ -236,6 +211,31 @@ + + + + + + Description + + + VAT + + + Quantity + + + Unit Price + + + Disc.(%) + + + Price + + + + @@ -283,6 +283,7 @@ + @@ -338,6 +339,5 @@ - From b5793bc85b97e99b89875417f1212a9be471fca7 Mon Sep 17 00:00:00 2001 From: Mohammed Shekha Date: Mon, 1 Apr 2013 11:05:00 +0530 Subject: [PATCH 003/483] [FIX]Fixed the issue of file input widget which is not working in firefox and IE. bzr revid: msh@openerp.com-20130401053500-q8tsnnr59u2aqawt --- addons/web/static/src/css/base.css | 9 +++++---- addons/web/static/src/css/base.sass | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 385405e39ca..cbfa554c735 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1,4 +1,4 @@ -@charset "utf-8"; +@charset "UTF-8"; @font-face { font-family: "mnmliconsRegular"; src: url("/web/static/src/font/mnmliconsv21-webfont.eot") format("eot"); @@ -1269,7 +1269,7 @@ color: white; padding: 2px 4px; margin: 1px 6px 0 0; - border: 1px solid lightGray; + border: 1px solid lightgrey; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); -moz-border-radius: 4px; -webkit-border-radius: 4px; @@ -1301,7 +1301,7 @@ transform: scale(1.1); } .openerp .oe_secondary_submenu .oe_active { - border-top: 1px solid lightGray; + border-top: 1px solid lightgrey; border-bottom: 1px solid #dedede; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2), inset 0 -1px 3px rgba(40, 40, 40, 0.2); @@ -2284,7 +2284,7 @@ } .openerp .oe_form .oe_form_label_help[for] span, .openerp .oe_form .oe_form_label[for] span { font-size: 80%; - color: darkGreen; + color: darkgreen; vertical-align: top; position: relative; top: -4px; @@ -2475,6 +2475,7 @@ } .openerp .oe_hidden_input_file { position: relative; + overflow-x: hidden; } .openerp .oe_hidden_input_file input.oe_form_binary_file { z-index: 0; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 5fe5b1ceaf4..fcace37ec03 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -1967,6 +1967,7 @@ $sheet-padding: 16px // Position: relative is used for the hidden input[type=file] // Do not remove it anymore ! position: relative + overflow-x: hidden input.oe_form_binary_file z-index: 0 line-height: 0 From 014f1ddc2a202a3249ae501ce96d02e3a1603f9d Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 18 Jul 2013 14:35:26 +0200 Subject: [PATCH 004/483] [FIX] account: Chart Installer: new way to get apps server bzr revid: chs@openerp.com-20130718123526-4xqacoe63c9qqufp --- addons/account/installer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account/installer.py b/addons/account/installer.py index 9ad20129587..357ec11dec3 100644 --- a/addons/account/installer.py +++ b/addons/account/installer.py @@ -47,7 +47,7 @@ class account_installer(osv.osv_memory): # try get the list on apps server try: - apps_server = self.pool.get('ir.config_parameter').get_param(cr, uid, 'apps.server', 'https://apps.openerp.com') + apps_server = self.pool.get('ir.module.module').get_apps_server(cr, uid, context=context) up = urlparse.urlparse(apps_server) url = '{0.scheme}://{0.netloc}/apps/charts?serie={1}'.format(up, serie) From 65caa33162d85c154ade2bcde29a3756221d5ae5 Mon Sep 17 00:00:00 2001 From: "Amit Dodiya (OpenERP)" Date: Mon, 28 Oct 2013 18:18:22 +0530 Subject: [PATCH 005/483] [FIX] account: while refuding the invoice with payment term journal items are created wrongly with write-off account bzr revid: ado@tinyerp.com-20131028124822-we80argd26aozxg7 --- addons/account/wizard/account_invoice_refund.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/account/wizard/account_invoice_refund.py b/addons/account/wizard/account_invoice_refund.py index 37ab5f18af8..eec37490963 100644 --- a/addons/account/wizard/account_invoice_refund.py +++ b/addons/account/wizard/account_invoice_refund.py @@ -156,9 +156,11 @@ class account_invoice_refund(osv.osv_memory): if mode in ('cancel', 'modify'): movelines = inv.move_id.line_id to_reconcile_ids = {} + move_line_ids = [] for line in movelines: if line.account_id.id == inv.account_id.id: - to_reconcile_ids[line.account_id.id] = [line.id] + move_line_ids.append(line.id) + to_reconcile_ids[line.account_id.id] = move_line_ids if line.reconcile_id: line.reconcile_id.unlink() wf_service.trg_validate(uid, 'account.invoice', \ From 6a11a5b1cf813cdd6ae9ea1754bead1e2b854c82 Mon Sep 17 00:00:00 2001 From: "ajay javiya (OpenERP)" Date: Wed, 29 Jan 2014 14:57:50 +0530 Subject: [PATCH 006/483] [ADD] : customize option for blog background cover bzr revid: aja@tinyerp.com-20140129092750-p24fv06yt4ydnz75 --- .../website_blog/static/src/css/website_blog.css | 12 ++++++++++++ .../website_blog/static/src/css/website_blog.sass | 10 ++++++++++ .../website_blog/views/website_blog_templates.xml | 14 ++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/addons/website_blog/static/src/css/website_blog.css b/addons/website_blog/static/src/css/website_blog.css index 96045adb914..03791848750 100644 --- a/addons/website_blog/static/src/css/website_blog.css +++ b/addons/website_blog/static/src/css/website_blog.css @@ -21,3 +21,15 @@ p.post-meta { position: relative; top: -5px; } + +.blog_cover { + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; + background-position: center; + height: 100vh; + color: white; + padding-top: 20%; + margin-bottom: 8px; +} diff --git a/addons/website_blog/static/src/css/website_blog.sass b/addons/website_blog/static/src/css/website_blog.sass index 4691dde83c2..fa35001839f 100644 --- a/addons/website_blog/static/src/css/website_blog.sass +++ b/addons/website_blog/static/src/css/website_blog.sass @@ -20,3 +20,13 @@ p.post-meta position: relative top: -5px +.blog_cover + -webkit-background-size: cover + -moz-background-size: cover + -o-background-size: cover + background-size: cover + background-position: center + height: 100vh + color: white + padding-top: 20% + margin-bottom: 8px diff --git a/addons/website_blog/views/website_blog_templates.xml b/addons/website_blog/views/website_blog_templates.xml index 7682ec50fbc..dc5b940d822 100644 --- a/addons/website_blog/views/website_blog_templates.xml +++ b/addons/website_blog/views/website_blog_templates.xml @@ -225,6 +225,20 @@ + + + From f0a2cebb93359c227a493f5445a57b0538df441a Mon Sep 17 00:00:00 2001 From: "Mahendra Barad (OpenERP)" Date: Wed, 29 Jan 2014 17:25:30 +0530 Subject: [PATCH 008/483] [Add]demo data in website_blog bzr revid: mba@tinyerp.com-20140129115530-2dbt32c2ogy1088p --- .../website/static/src/img/OpemERP_board.jpg | Bin 0 -> 104339 bytes .../static/src/img/turnover_updated.png | Bin 0 -> 25636 bytes .../website_blog/data/website_blog_demo.xml | 184 ++++++++++++++---- 3 files changed, 149 insertions(+), 35 deletions(-) create mode 100644 addons/website/static/src/img/OpemERP_board.jpg create mode 100644 addons/website/static/src/img/turnover_updated.png diff --git a/addons/website/static/src/img/OpemERP_board.jpg b/addons/website/static/src/img/OpemERP_board.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05a854f15eb78518853bb17e1261d9b40fa79895 GIT binary patch literal 104339 zcmbTdby!@@(l0vb-~=CFaDoL0F2UX1U4uh#4ekUOoCJ4w_W;2O?(QCZ&>)9*fBW0t zJ?FW9+;e-@npM+XU8}0Qp4GkTSM$2~x(RqED=8xhfPsMlNWXmmuUkZ~5}wu;0Dyu5 zfB^siAOV0dm;l%}3SL@W3;^@)Uo`65Z&Mf|0K(f9=IwNVA^s2T4nqfk`&a#2FIb#^ z({Ehi)&Tf_^ZUJZ(|nUhF8|r`vxE6tE#RNK|4Y_?T~Q-w|J_p-0EhzsfN!nvENpBn zad7|A0QZdf%zY8a$x^k8(3%#+<$1? z9EAU-VR+u|31DMkW&6a!{fUL0oR$3(3-2dZ*8kVKH+@Xr*v;QGg87$L@T$CT0$~5G z`P<$9kp@77f%~@(h;KdqGlDP$|1*Lx7601^!u&^{2H5}TOepp*Y5&Klz5YLE^q; zo{@!>gM)*NmREp>jh~sFgY6$7Fv!TrXsBo)baW6K1(<^E|GK<(1F(<)k$^rp7)k&v z77QE~%xfQj>`hOEH~;&`1^->%rVt(h5r~A0g8IhL_~vpjaB#5ja0m$SZw>_G`_B}^ zVzZ+5}L!^6P?|FH`O*5mDj!-7YkU`50hQ30Ab;ZU*#BH@b0 z=hpThQ?aXF;F&s4q2N<|yFi_Y=!frckm*^Xje&5ejJ4u3o5y(QdQ1a)M$_BN;U2QRNdf4<>mOrVjoPpSL zxZ6oI&|$3ghS)Xpcex38>EWu3Sn!^Dzb%GAg(m0w=<%3ZT;aBTP15^Cg05;XeC8Ep}JQ z?3>+rPx+(rDs6f2wS}OEKJ&W0zka7EY_~RHPza*BND(xZSA zxTZCh55whEv{F~`5uMzmyeX+)!G|Hlsvnj$MpJ9?TSn01WyIF%PxR+@cDGEfZ3CM# z4XjgZ?V!&p8>hbj%;ObOu6Cd!T?Bp-g?aoZOW0Yp`9C`l5bGqqlD|c);dUmbfTKSxKsz#V* z+~b9mPc~kDZ}dk>PskD{^=jN>2edPtU5&Y+kF#M_mW6hpANLBFp?NV)ii}*{2Ud610uIUKkR!VgJ5(N|M3H~W8LS15JZNQLA+{bqO0c$do`%r=SkWPax>9HSAseX_-;gagM{ZKO174M5#qyT4 zOfic<3wWUUASmv-5^eyy1hG{S5rKN?pse{IYWKN9Ogb5Bfm8gTh?*-~N?9dMDnnk1 zDGv&pf^(Z&<*aT@MS`AuNnJu;E&#o#&A^CCHYv;V6@aqW02OmglwpZ6a~2tJiHDr% z4VvLMGOSt;`_&sZ_Bkn0So0??RLd?+x_y{(v2~cn7inTi_gsM-BA8G3a8^uEHvVN(a%jV@@=g+Cp+y|Bh1pJBg6KwW7CUvQ%B8My1Bwqo4Vj}}QZYGX2&04Na zbO@4-K~9Sc?<;V;N=D#^!SQhbXGt5X7C93))K)i{_3`<&!c3NxxqxNXp@S-CA%+x0 zuG=yaLC@NkT1oYJ<;V()Yn?SxlV5!sKET>?_VIJ8Gr7-o8?3{yRcD*qtqxKZh5f%n z`rd_WIDD2E96hss!KzDJ(Tv~2+8HLdkJoE~(zI5}q{)~jWs$NzI_U|bKDg<;0!{*7 z0h1|7Sz%7PnK8?#hcq$Y3+V5nb{IuAU0ys(=B+tKt+sJe0O+{^4^sMQzBUa=3%6=i zwHi3!%^Ru=zsAJp+V^c8=&1ZwvZYQfW}MZ%K}VS+oeRsFk`{(!%{Kir_9l&Ov+omV zuJ!}FADUgVlt_S7WU@iTt-IfxYoyOG`WPJn!xM^`=*+pUx7d0Hiz6i>1C*xRXfE-y znzAyo`(@|@`wC+jT39KebJAb7Ca8|Id%dVgbz9+RbNk)XjJ-e)_*K)1*Rp*kz~-O2 zot5{pqpHnvYxLT(-`UZgFINM6o`o2uIo7HyRjoTwblrm}r}NPpKRb1xhq-N)uac%x3Igp%>cd1C@gh?<2`148DJ5+lbXpHdv1XT3jTLMVVp#vzJn8Q_5<6sXl9rA(Nn6XT~ScDahjlwsN` zWttExeaqQwf}7fw+nyjE#uf8*`XDg?2-iCFZ0ptDH;&wFZn<`}fNCc~91V^?EdJSP zbP?2i8#4?aybC7l(~_`eirHJ8f6>>`0HL+6@;zQ=Ii2frExRI9HFhYAuQ-zGf*raDdt*Mx!1dpMdm| zjFD^0IGqzCxrC%F=PJNkN!<3HiuAH0260{cMTaUbX=imlEOqN-?6cqsi$**;EwC|PTLM!v~EhJ z#i+{gLxU>|X=j#be%fIt5Fe^P&@>pN?*T!I>&kaZ(sT+ihniUY~fBdin>o{ck0j>Jx4Y z+rW3msvkvSm2|6%^@vvv?HBG>fJYn9lEn5F+RtXqQ&3wywt7k&uBmI*aW>xmFMWRc z8dh5g{BZ@aKozyV3PdHm;LfoIYLn^jgN0~{!iZ@yJY&-ROIcRMmNSL8!<4b~Y$C(7 zHPBL3MrOpVahR%5Jw^X^4;!VwCuz=$eS@rZEGJii&mT+`Eud}I(?e|Q`tmZ+?T)D( z`}T#D3A|HoU4+8zPZKDt#v;b~j*nn1yzOdCoqK=9*!`tK)2omr3V2sqewZV9OvigugtMz<8PRaA+FH~}2jZWV>RKi;t9^RSiioVxN_4{IbFJoBQE7K7 z(hf~4NZQZ50!Wq4AhuVu5e2uIP>kA_(hoz~(jA`{D3Y4shMQM_kQ2jiHXH1Ic>8Uk zNo|^?)EI?C+^au$cS`mu^pD~u63Qeo}!IL>JuD{zzzmZIz0-XA#X&uJ> zKjl!V2JFs+d=B8H_BM^rb<1q4=U(6>bQ=dfv)RDlxPR#lm*I+Lp;m2)yeq!bdU?Rr z047h>c;DrHkL+41l3kH!FNH=)d^u3k^JP{B$?%&I{*DWV49(A`66NR{X#Zj%k?U5v z>33e8goijArjECV^DAT2joo&#}9`%@Y z?ZapXgS?RgBAdw3e5G7PuetL#3gVU_xTxVv`T1$172k{@wPCbg#j?JP!0w$wu7pKq zmuM8xKc3zF-hSy$WlKlywGwvKD5ANT35t?D{6yD$yYx0yD0Y@B0bU@$i~fR(S+R}K z(xgCE?!MGs)ds^}?aXu-(*BdRhm%)@_yVh!Lk)ny+K`)@hvQU{*ymo=)70t=A5Rlj zcw|K#W)QULGw&Z^-kz!x@9<+cft+d-9QWzw$+oa@;hZ@S^##JCL5PXr^kDjJQM0ut zGF1TG%@6%&P0+rY3(AifbhLEmUqP7AD#b17wm3Y%IWJr@Xa3e^v3{Vmdvq-tL8-o) z!=ao@;blh3-Ko6`Z2NDvn5*peS%0JPX8w4I2tw@T`)kVnyFsDw{{?y!NVRe`PSC| z&ecOZ{?95eBO&-ipYkFoT=MN92hzviSlwD}n z7A;yQNIB~A>Z;1wF(P#j%6gdASsFH}+W%sBL4?%fftI_Utsr_c)PI|6G4HyJ4m9)A z*1v+zjO|_lZv7upO@D;WKIOcqPgjM%SK8CvCS>ga-V}Ye0G1o%XK z_%fRMH~1u3+}W*~m~1DbnM!zbwGMGs9yUZF1nS*<=7~O-n$)FWE(M(v9FZligJ4 zLr7>KaD}qQ^`s7?Up~QE1Z?(XTQ$wGQYm35z0DFbKp1JTp~x;gYMX0|)RQ11O_E|L zM5XqiyVh3wg(c@Ef@~J0ktD3u?q_?NGq9ljr0?)|L>-tEm3$thCTIxz}wDfPny<)FSK z7-K>5am`adAGfnOo@xAVh=LNlVY{tJtC$ys#=M={Y)0RAO%1?siD|Y2q+GyU@H3`v zqFS>j^D^&TNI-Ccv;QMB?p+mD`=zE#pT5Mc*E;`!?K{kp%1%L48T)*%ir;l;TTjzM zipi-Z{a^z5Z;MwjLi26DsOn8kGZbMynB0VX1IWCz^Yvzus#cLy>uT zm1adpT$6v;^{e?)l`asQRPV&o&wDt8E^waN)hdXn7q4y*lgWf}ig_N~ zkiwr`yI(xZ<#OKlkgDHK?-XJ9r`VWn-8-b-ajQu4p;-SZRzFUTYs4u6& zJ^GfUNfbZg@0|xWoWi&vw6ti7LZ52v&Ne{}vle29r*XbzTOVueLER@RF@v-oVj24Z zlm=o3!4)aju7B5F0U|0!o)DFniPoqc1>jd^ZYtLYf3lH^4m&eyA-~|XQWx9z{S~zo z%fBmfu7JF_Fnf;dWNhzIzOKT>kHd_4e+(Z81S5mvd(hg2E!mp(g<=6!Ui`$qxH%7T zZbQGwE-F_P@Q?I~OQ*%pa=nCN01cm1@{aC4w5{(!S|~!LXv5OUsE5{nv%YYqk|sNR zYc*Y7+=_3?o-SrReng} z(ReH1d9(TZN7d1W>^)WgUfm(-)|pkaawd;@`M#Kgq^Z4qpoU zoo}c4&e0CkMgDNQ_`3XB^WRu9@-u>v;L+49E^el4uL?p3OW(UZ9TQ4ZUCiQOLVbGI z{&HUxHHV%FFH?txmkzxot3YkHGM2lfJQvkvp3AMt5%q><=7tAP`W1tjxkIaFgPIN( zcX6HiIjkQGQ^h=^gxba+(}m&MvpdQXy~DBTlm7A=hfiugpy#~`)ypSFt%v<@61QJ5OEwZ{OW|QKZkXiiO)L#Mon!TPy^AfKBncDBZur)8PKbH+jT7){p zqqEP&wQl(_aCLQ@TM5zv|FOoj{~BuYjAw{3K>A&seSmL5GJU zjl!8zi)D)#aN<-d?bEd?_d40xD?rxkP-qRWBtmsy9Uv?IF8GN)sv#nq87SaA`3kta zCj0ven4L*|c6tSTorFWF&rUKYZQ0LI`P$p}PRfw}^D97omix)ezdQUY$4s`2Sy~?} zl!R|4jO*(X045qnIr}Z}=j9()`u^|KGdh5Ij+zVf?DACFqW{znAgR}s5`&h|yaH1E z&;3KmiEA*zGh70tQsnGc7T{|+uBXZFe%|WJv`ImQ#sjfrh?5?q6frrqhTV4(q!fLe zG!G7co?$*CCi^{QA9TX;+WUyL{zR%NK#kr@XK=a4bhrs73vHwuhYw&e$xOf+^qbpI zxHEcbg*+pvt2{3Wt-bm>$n_JZGH0AIOKQvGVSA~QXfQs9{i~B{pBqR>*~+2 z(;@O?bPhR@IpoW%yAKy>1IU{(`X5wiKTDUUtVpyQOnTY*d@mdqLfh_W+cSvmu|JWd(>HgZ(a7z%ZHUHTVX0tXBG&+%5^-wp(%e}D%B6d({02@M4e4HX3y z6&(Zn9XbXU1}f@1{C8M5xOjMYXqW^bd|VJVE*|c`;1amEKJW<02nfiy=&0zp|JUVT za0x6fEcAbaOGw@@65xLjg?|8(e}g430OU8+LG?di2_ih~8|DLp{vWUekrjv|qC#on zg!C`81n&(kQSHH}e!~>D*u~U>67ntx-qUcHU8=j(^@3={gY&03%@gb2WD>mv{NJFA ze}gmsTwq`U{~$DPZ47T9#y{ns_J6+r)rbX0fz1jpf|kS;P_mGz%K!`!4%ZJv13Bcp4_`}_t%6|H;dJ~sQkEKJVydF`E>i9aDUo$4Y8?e# z^M7lO_XM68=;*;a18xeHBh(A1Y(16>l7Y+LVsVJSDm+lQ900SBdkxk;BNt8EDJm&WZ$9jMv^*Ju z)OhOYa{MVpAnu9-e|=;3(35zY0n=6(wOf5_oBk=XHFDfbP_yR>ix&x+fD>|R5i`=b zn0WxZ&Y<4(m-A|np7#2hd7)2II^75y z?JSbAtH=3}EGkuW+k)rsNog9A8jTnE73UYmM*?bSLb$a^sW+w!GDY_|^V8OUsb~J2 zO7ku`l}J_ykt-Npow!IMrefowk zRLLpf-ZLU!{Z;Tnti+qPn(0%pO54o)rXcz}EZtR(Ix-eB+AX+fjSZ4~ef+Dr8g=?F ziUT>73uy=qK~i&#&lI>$_6>OYUuPh33M6>n?B9KMk{4QMAG9n+P6sV@%uWc&)yn`=Zpm_QXQ zD-*iNn@PM6w<{1xm9}=0i#>&t8Jvyv|MbU@`bJ#1GAs3qRacfl9*tj8MlzIr&yuNw zbM*5i-#Xe+h4JH^B7MTG~hIDyTUu}Bwk@Tr061vzyr6Q_l!;gB184L z6cPN%0AG49B2Zq~jN$dDvK!D-3KT5Ra*3ayXCKgJVUj(cZD(&yu_j6GmFPvuj+-z;>p&g9jqSju3?DPSfm|xBQw84Y5 zL$PGEr-!h(uS$L_TbW^iL;!{ixB8mRe&Udx{n&upzNbOw=eo0tDg=t7&=9!Gf(WQ* zJ@eu%*rhLJ3U7U;dHse}%PdS&+sy)tMSEida=Hp<*)x0> zW`f(kZ(Rm6gkE|G2k;P)u)qT-o(K(I@*o0 zId+g9%+B`E9Lv6nHa&asL{8&VJPfty7Y^4r zZVOExeZQNVw1eWL@Mu`>Q*unM-TEm95GMO&(hUdjW2kag zmHe$ey_Uer{3kIDEx?}I7-uC4zu%6IKh{b%aDgApAT>`svb;DU=x-DTl`J{I7fbhzi`>Zo+UJMp>V^w?^$R!Wd^5c^ z=tnXY)i3F6f^zwpd=Z2`=Y^YU{S5|o)(Qd?ePi7H%9{=9nMg(kS(Rl7qq@*VQ^ zPbGMf7Ih=*El4q*g<|YBmVP>{T_lvUZYv%jviXRkTgwoc$o@BJ;ah#p9CK-_()fTP%8B=0c0zT~kFM6iXS-bfNb_%_tu3`3LvTlF~GZR9}Gs zlE)!n?Q$@-2$aLlY$V#9_dHEn`&+~;xw*h%mIR|dK6$K*1Z>IiSL4KtuO-=Gi|p^D z?+l?naWFRzOxPKTe|*_RYHdx5l$Zs!WPp<>D4%|_U!r+yiI8te!5!$Y1rHLIB>%A> z(nfgFCi`^k4s@d0wdPA%b`LO`p@sbxq=f>%;=yf~v$7EkDV>mU-c%FRUo$ zo~MmIIt1s=duBt<(~iMLVB8(YdL&}Ge!xrF8P`H?zw9K;EW;$fmZMq0zWtKGYM7_f zZ5D*BuYP8zW%x2{kJ^u8(6prPp zXe~HiXeEydWXQIzqocXS!D7BBDL6P`kgTOZb#d`x#>QoIfHf5K^iYa-Abt2KqvGRg zVhLZJvFkAS)n~>91JdwiU%&K`&cXjvSCa*l-T&?RNzj_2&|$o42|UE_NPT4COPCz# z+hHVuoUdoR0;c_<8_}q=;yWD!(4JWhNhz$jZhv|z2<$43C?d$#XiFp?8*Z%V{VJ@B ze6N0u24Wle2p=c4Bb7{?F+yIdDM<7_8G)ZH?>LT!sUJE9@n z8TUPlxPK4kD-~pWs){s&ZKRooRNp|eOND-cs5Q1?owfvLciqj~@fRT*R@bhgRp9*NkmcvXz5cqD<=#u_5oy9d?w6hCzyvE7S=0aw%u3E28CHnuci(M;mT_yoPzI;K_%X!YU?*0fBh#ZwmZ90WFT-y> zyWvbu7$VB=Lk}4c?~%vIcQ$Hy2^#t@9~YiZG`nG0H~p}spUP=Y;A0FoNga2ww0@7q z#(iYxnc&FW_`!Y}btNl@X@mPSNY(2AGF_V3p!Wz{3)U;Zl4Bwt zZ1ab8HC|QkM2+!S1Q0QSn0Qh9MKa=IM(FUPQaBmGs+v$~fq`+$;d&{!Ne=6wF3Ry@ zVf)Y*u7z?KW@2`lw3;0HMTPBh7!0|cZ+Zpvb!V^UGf{mglvYGyv&^=^RKR4u(&0Kl z@id&xTTPjk0WIs_KAo(63LqXFK*Ec>wOd&noUQZP@U+{Z$-S$9N1mXbEjLP}^A#B` ziOuQ%8s7sNlcI?m&1rWTCh3{DtsI`ju|LH4E*y$t9S5m~e+7K6;6yd^B-;{NZiYxd z84%2b7zY-ul#tyas3oLviZGC3yKg4*+;AATIU-@jv9CwQuz*-61ff*PKs*C{MB-8+ zHUQw+DlFk}2c8Z*Rg)3hZP{g|Z~^P{R9Z%%i?YGatSiy;$4MfXV#lldTq+byW@IL^ zs3j1q#6gd~Jk_iJk$FRwL8LJP&5t4rnyb9S3p^1YZA_=S^m$a7tYoMK_Z8TUC1x#h z?u*v2i~qzT&z$88=R@k|x#@Q+Tq0)W6CRwLRgXa0i3QRwM@ENyK8W@G(7UToVHLT| zXVHqhTBdEjxgRc4J&iLb^m}$s6>$!(lc3O8ucikmn3P{Ku7Ow`&s zmo%byW~_cRfxQoPW5a4#lx2OP{2Z6~IKv&miXSHEiTR@bcly9XL%#;js>u!Pa=-Wr z7)axn7+l+Y$(%O3t;EcybRSvvtQ|a;mZ3c6k2cMy!ethr<=CJRKNcQG_?+tV@f&EMWGp-k>%PpATHeUf6xQHKTsF3{~__pd4-p{2!^u-d;UKP&6 zacgeS92`iyIrl$f(grI&;t4DA)YX`pm&?hM3>5CW0#% zfz3i!cz$4~OUp&mhMmLF)Ms3&Xbk^p-T;0CdCZYAUy)Y3J3Qq@y(nq|jJ$?AW}^KmC!gOp)w(GgnOo0P5a)3UCw8cIzOt@J&nDb*3>yP)FFVEqu0lgiUp5MCE6;?tpiZ+y9DUg% z)~7#E)iHWgDu($hwGgM?J{Xw(!LVDEt-v7cOC@65#AL$hUn3q585p3+?rpNQfvBg zFI7J>**Z0RrhQAa!=&P$_iSyqXm!{;$g-93+|F&Ic~3Zzo$&K}#ULNM;qU};MEUzt z!u*!-hW2zP-og9QJpvE;T;L8oWU6<=uP zyf36TsL@l21#3W_2~stqBi8-(6>yqG%HA|`=|{>5C9&-@lFbhJj47m6AG|y&%{C6$N2YftuLmNf9goGMMudxM?fj}i`h!L z2t%gAV2qm~GT%SDVS9_au|AK}kt3(7e2LLM^A21;I>9joT$cgd&eq~i!?D7oPm^1` zv0N&UWc27joiGf{Mvyq;rj)P@72e{np{2C|Nj{a@n5nR}#A5`YHB-PKnQVO&mNs@B zD>#6xY9?S6mfU>ZC`acB;PABT-9&Rz3O)VNktrIYT+1rE)PuD45?1He zG4^D$`?qz!F$`8me%G8)@huYUI?>+v5~M`M`SrKwp=`)5+_-?%!H3=9;kPWX zg4$ZlSQfsi*cG$XEF_+?toR}hHmjXat@_uAX^A!`dt;czR}-9glO&RjiHVnF6H&=F zzlpT#xY3I{8K4MM5}qy>t`4Dz6RY{-f<@_%E&dmZ%`H2w1?K);4Le&?WQPtBiUU80>U_zy6%IX0HGmq_+&Jq`e0Jzu5tJ9$CNxaclH%eDmYTV84bfyFl0M z2zN7uN73x}GhIh`w!|~_&W8{;%0J)xW7RQ)7$R)Qa3hcgfOsE|bx3oZL65^b+ zly1OINr{{m#OXoO@V}bSx2!QJL@995x@qm_(|4f*ZJM<%+EoF}+sf;i?2)5PB(S;l z{99AP91f=$xTfqEY5x2-m$2R@%u@q+@Gf}rHYPU=`L^tV=!0+)7-qmqXYFVVfee1X za~~$#J470bmn_6-y`x=EFnm2o29ElPcDgMjI(TBFqDIb8mgQ(|j}e3`g>s5| z0TTeo84T{GY9_11gyD9HzbdF1(6sNqgy_oIg{T=0&6)!+UIBX&OW5<@LF4Cz#ML-Y zl4@B>g#?z#4aBjIGL<}NKOT#;o~ilA{ITX7(>UG<*o%Lvd zV(W6*9SYf(Df)tSrqG#LjC_>mt=F71UdY!W5$ z{6xB{B~$nnfXVrz!CFM~p1n(^8@Fl5bR(<3zMp%=axCeobh__jGEv5E8giUdtJkAI#WCXo&3*{3xv+*76MN;z(mDQ zSdh_3y}4#ieOhW~Hb-0a_xa2QzbCpr@*0-5p%0-1zXF&v2wLc*&lsjJqu-zq`y=2K z57}8%+4=Al1dQKrnQHO>r&Gw zEN9r4Mw&+@Pz4IA%o}wZZIXgMPTlIIF|yeYnj8r`$_*(Q^Qn%i!rOS_1!kfvBNI5+ z#U~3w6PCUbk1V_VhfC*$ETA3E~gAF^{_MEoHIU1fBbq*PHHPzZBB^V#Q~@)!B@dc zx#nR?yvYO3T>!xoVO)6kalw!Ab~^w!$guz=Ksc7SXAD=rTA2N}c6$DurmoxYNS%F4n0V;PW^cVqbHcSAfnQHAp&lj4=&>UnoNrJ7%ShLlgiu zb2xgToZ4a9sl228mAMElr1QmeI?)o^{0N1<5A5NcXryD1hH1q`?;z#P9Z=-moT2`} zQyZ{LDsq=s@XZPENW|x76!-QP%ZtXsCUbg~Cn1g7&K^w)ETq`8KiG+Nk}G;IBg8zL z!6wk~gQQ+gYtq(T%0B3nJjyZCUGxVbXa_fqP7<`4DC+=XsO@CmPRN5je-*2|C zY8(_(F*YLHolRL*dLfAvaJFIWD=%kbxgAMM5TiN8#-qw0I~T$F<9vZ9^|A~z;6Kak z`83^V^Q3ou?{~KGVqH;w>qqvo^nTfos#yO;n8U41&R&Ln;)?h$QKvngl6;S^Zh;$D zjb3XC3U~@{geZz-6M|aFm=KZaNGR_N;vt^ z&ugfPior;qVUu#`9`1R^p!NO&Y54xkbvOE4)%IOOK0*zUVS)jpsJ~yfqLXk6EHVflph$cLjBzHmh0U9ljC2RFFE@s6 z0%h6`5*;3d?i4-?`0an5r6pByg}?eBX&4=soA|jGd`j&zxo5$`Y8M#A_TdHNKGV0P zy;z2v5gF_~@2lc$Uz;tRBvqDk>u|%|X^N+xB`G4r5TgB#Q`jk*Q=w|y9@UJ8XK+@{ zaFX;#eg~JMH@g_q;!@5FbYY>OS=8oR;8-u(Q^!=lfGakGYf4m0w;o;iL6qr9DeI)x zlSiAp%c@snn`~aRz)(5P*7Szpk1=j5`|b(Tzx5~GLI<+TJ49|ngI{MH(rHtTrw`yi zfc+$ErI%B&Ka|ST%+kc|Y@2#M&ibez6zFG3FlR2VvhG^G0wm*)d9Kxs!v?Gkq1;dg z%m^+-9^Q%R=4`oC0p0?y5M%9?oufS_;}uf^r`;M=;R(MFK1Vh+ho4l*4r`lKm8vLI zbn2`YLUr-?biy#_I||-OTGJ7y3uZH@!D9G!mKA>ZJl@01jgvUoiOe#ZVZP7=6CWov z-r1^dqPXGBtcyUp(Xs>9N_IqMbP>^%PXJl8ALJTil6_+MvZz}#HX^;#?7dq7;^N6O zAJ`T%!xdkE0oqNu6rc!aqX7jQ2klGl2?a_&X2~IvN2l?~R<@@pYE9Y%VKV=5ndKU**kobI$+VS1rN8lzf}V=ko*Fos)> zGrF-)`DP)1`ZWF*!M6L)*skPsp3wA=@w|hX`|7BD2H6iYg-##R6CXDU=~d6C@-?A3 zUGJ0BX4Mf>8T%AmM!xvB@M}>3ZscMC|xXS6_Z&J{^y(A`kk9PdEO0`a#?Jqj>${9nPFRrz&?5ON@R)C+d! zdPCKKue+X~|t)w{i#yxoJGjGT+$nq1u`UrbVF7)LH(sv*BiGp0GP zw`zanGJsxSXw{q|_6?pxnib7B2-NnRYURl4C1P0ua;S*IZUq0zHcDoS_b|tx$C9K0 zNbyBJm+`bA6!B0CZ*G!}hwnwl^5)P;^-5xPB9S_a02{T$nu3uu?Cf#hYf$ky(($ne zuXhHv?8Zw5=IBWZp}RT-$FfSiL2`+~`l{~ER^O~RxcOs0ME}a713FeY+z7-dB*u>& z`_fT_VS=O15a4SVBn3Zyb`RK{64aGT(N(Ku#p zztHRyGv5ujA7u*+0_-P=Yw@dUKm^yj;Uv4!EUm$qy7kE{TD8iKxIw%V-ca*e>KFCz zEzDB9gmQIGVSHb~vJ>-A4+*mi$w@Vda>~EAZYsX_9p* zVaJp$d@Mm&>gLW3i2lFxSLy#Xb6ZIgfo!t@(?r?HJ8qf?74Gx=6{to@)qHaiVjPQe-?f#boBaKm>{a^u(cd}j0t;JK9lg(xabQhH((g6^-;dwJIi z5&S#xpe8$biH&GWtY?vaq%up=deAA;AwYQ2^&Q?gMsqP%XazApU5s?a*G6m0&gV() z2(6TN&Uk{~7(8o}oVufw!0nqW=-S_E!RUWYq`|r_%p_gm(%CY6{+M7bhn3;@fyjHR zwTK}!nQ3R3dZ!VbkkA1mvn|?mv{Lgpbwn%~5G3@;6_Jn%sr!pJZ1UFxK4pv1;@qAb zDO5c4gw~t^etq^he+Hr~Nr6Lbk&%Q4(r~saod`K;%&g~0VnBVfxk7I%*6XqiIMNS4`hN3_D-dmjb|vQzzP&_dUxl4C zQc1NL@-+Wzq5W~gBehOVeP?#0>$klu7bAE~hgF!o=~xoXs5rA+V!IxE{2@|jruas3 z_(^nJ>_wwW_BNXJ6+n$`g>33e|ah_i1tfrPljYs3(QWSV%kek;5&2!Bjl4E#Ig zVTg3oIm<@v%T!|iID{p2)?1nc?!+IE6&#UWMfeG%;%ismKKMp^00)?9@VD5&n%|W6 zHklFuKBUIc621cb3dc5ubT}&_mep0-C56YHNH@;a@7I6u(*9}mrpJ8zkZ*oQGlG*n zlK1S$zV$pseeK)}l!miK8Ch35Lt!?XuC6ZP{KXUx2QGtl4*P5$Liv#(Jl6HQK`cJb{q zq>WuB4OmOM4DGmjp29=WtN9YL=Ljfgj^ndVsoeQfi`HMFpA~!9VxYm^va;4QVPzP8 zk4;Va+9I1lK3zon`fe9!KQiUA7fp0rg2zWVa2kq2XXkM&JrOui0_5xx2Q(3T*9VyR zx}d(T=mc@ncSK|zqKQ@oe5B#rq#LegWBy|g_SS+_VMsrhpp!?yCHT30rm$byV0 zowoTD+O6CVitBi^D16~uodBw=h!!+BGjB~)IYoV)`Hb#SioC~kPMyfeA zH>fPksto9EKcli*K5?*)yh`b-GU-~?r*I`mM*UlAnN8@*=ZQ%bM(&dD#NuzyJEf;% zKM_UYQJ4&(V5qCH4dz*G_8EhnqR5a?SYwaXs6ab;r`T=eoGXc>Fa5fkj}}%^tXMPI z$K`y2SAdOyGDke5qZUYbz38`8A{A*wU|^Gg6)ls!l2&aNSalW^>w#^{QS=H>U>PVS zK+Co!alWHV86P_~|Izva4LTV#%(IKP#IC;o;p`&QW>%2Yo$$-28SyAoP4< zJl>59Qnb99S{pepbFm=a|fDV%6@gP)J^cP0IYyE~w@ z9QccVx1}R~KW<12z&?zpW2=lezj#0$sHqiNz?eu6q6imCW^Z%X!n*5mhKE5QSaBEu0Ou%1Qi+51$AjXxGagp-y z=9|vNW*M6#zJVfA9sdiuKt;cNM0?UA<8k>>@yV0w1}a)3i=km$0tFO8qLw2jy}O{S(Q-H~ zoE~WCi8jDCGhVM5_8b+>dX9m|`aDEP0BymeR6ZNwCq1aO8;Q#wsHG~~6nsRFYF3a` ztR^_595Ru`DS;$7!sm+e9sd9loS$k|nE?6{Dkzc4mV#rBP)6h#&%Fj~M>8(sJ*iSI zKt8`(^SAR?KK<&>1WvmXPi9oIdkV`O_JWzQPU0jNTs986&VBr*pFOPP4y0x-0deq=`y)Lj&Nl^yH>08RToI1 zZ=;Pz#KB4TI5cUR6wqMI@nwm|TpZQh{coaJh7fdCgBV`l`@R#O&u(amd~G^iyBl2# zN{TV~VusE&1L^S4X$sq`D?hWtLobSVPK=JDPnkhh&Iyq}%C#KGKI<}&Tlr)U(yFe6 z@tW_%E~=AAn@@t)I3Rh%kthU!$}#$|t2b7f?%z(in#xZm<~UkN*!IX7#Wm=veVDUZ z>3wGJTGU=02UeXL=0dF=pEH6B5<4w+-@^W}yTe=bhPx;}+Iz3}0<5e50JQ%ASc#^H z%&1YeoJhoR$I6+mKGA(=IV5U082Oxj^mJaD_4*I0Lw;^2UsToOmpl2nm?JLGEn1k8+1az_Aqe5q8BE0t0SB8k$`fzSIS z5p@{#DF{ZUrj>3zf#wrAVTepTcr|jVN~kK|IoCP+Sqmtt5v)q(kL{ z$UiCyxsEe{bBY`95pExc(AN>!;U$-lyj1DXzO4*^hLE3J(B&Zk9r7tKka^@DIn5n# z_)h#{wRqmleoM4BYj>AAZjX0+X8UJ?CXqkxjGx$5TXo|vQV3VTcU>o1zq#3CY-a@V$L&|nTv0|GZzho;x$%psNFVfUN#qteru+W@ z7`5R8H=GrK?0ZvYqthKlV7_J6mdZU!HbDB+Yg7^~tBDYy#~_NMI8PbVYz!K0A{Ik@Z94a@-tQsPp~#{WcqXS0-a5|*p3li zjWME5@@UqQO68@J+Bq1XRx8i%P>#O3xv}W0Ys)E~DU$IOi0o0BvMOn#5Hz?jzx5~w z(`OY5>+zm}iZl34${*d$X?Br`ZbfQ(qf(Z|+3sdp0|CPyd{SPa*6yLPfyB2KvNcR4}XOoxhQms6fgnFHL- zf=T}XrEmDsfZJN(&U2g!W_BCc<2f`fv6`XI(&l2}4AL^>alDiJn%*!vHM||!e5i_$ zF_Go2KfPeBFzva8h{z7S52&sDVMvfK0aa5UO`@~pwrR(t1zTiic6<8LbvXp6r7Y+G zKZ^q+G>6G{x=F;2p+*XNHBi-;U2Ib={5BE1ml7l~pc#1^X#Hv(sd&TFI&_YL>T8)7 zmPjGpkD)lIkByht+OEH0pjn0?t4AA*kThA(wlD}N` ztMT!nz8sQPk$7l+Ea)9WaTUB5Qrk@D3l-XIX8gw$FWgjcxd#W|6_9m33s=$Egs{4_ zM{{g!;~zS|JP7MH>b{ef+Ud*R>9Qh?Nmw7(N)-nXu>NM$;k(k^PnVKi-3MC;*Gi8<{m%5s= zcko3c>^kh@M%Z;egS{dj%nXm8!+=M6bCzIZU`HTxP0`36O~=xs1r(Q!Jv}Amy5GbL zHJcS>11D)CpQtq(y6U}N($){U;cXT*+)+L!IPaRbHHa5cy19;J1~(;G4#ZV?t7*eW zeY55!53ax+1vX8A@b z5l*7%Bh%7bc}e$wHF8rRmIL~ZDle*Wb&=>fr_0@L{{UCGl6&S3>U_1p#uOgZ#i;)P zHt78->U}eZmQixFfLrk%PdPN@CUzXDIU@#;S^~;A<9BLtli>rCoYjj)cd^dJ0iF_j zt2ARCK-PyYaFaPcD@Q2-ZKf+=G;7+ys|wLYoT^jKEb(#`qCC-VFLd9G@mNv-Mn z9fqZLuF>DLq9%3xK@JWN>r^w+MsebkL_6vI?+kd}F`Sy$E}6)W`s|;E$C?i(JX4jlr9cP11vR(A&N1swQDCZ` z+*Sm)XF~K2X%$rD8cn%(!gIzAA96kn_oQKdC`jaUOxZdYZbC*_@k^r!$hadk*|4*B zr7_4=Mmvf&5n~1H2+yqp;U2{N%@HiXCQeDD^IVJrj2}TtJ0ejwJh0WTR>fhT*$KTz~oXggxX-JJkhsh zqb@-7q!C^_+ct6E)|KowgAs;sS81ZJ2mpHnU5;{87E$%0?*?KV^4^uF4^5c-k4+H2 z5&&yk7QqB>0G~{eRL$>E-CIp8e{^X=u>gh{BlWA7#OXF^b{vtGAbh#1H&bHQZ_Yc` zvpVQachupPi`zWE-+D8?HLpcl0Z1X9;TMuM!)E_pC1-jlm7sC z(zICXh;P~BaPdn}Tw@w+gp=$1)c*j0tu=qmjmH=U5G<}{IJ|=2x2_$LK5B~s~ zm8LJ(7B>Kl<`c)|OlF^E6xEoWPWWR3?-F_x1cErFdXe9#UYzd#09cm<{{X(! znl&Uga4N56nD%jhA8BS?kaDIGt6ryra=OeXaZ%pVe#a3xgI zk@-=Q_YM0|HV=r`cYJ@slsGNv^rlrrXHi0*m3X$(@~(4%%>~0AM>zMW{-ilFjevuJ zNxZ^a<&06Xf?t!KI|?jdIpY9TPhm>Itbt%v@0P^|M%f#T_7%lI!@thB>BDjeE6p?g z1!m ze^z+M=h~R`E~?Ywm`awZXpQ(FMf?lxO&%uo8d{~Uld?l4!C8Y3!?jOi`Qo6L-AMXe zVrZawK?Dgl?g74isk2JyBcuNSkH^Jxk}mB^;@?t6l%pzlDhGO|d`HtPZ>_GRwNVt& zDI_=b3SVK?{aJC*8qT^btpqw>l&uIX8bHmou+C4dLhg0Bx|Y&O9w7{@31kN#erB^S z_H?|2rH-hp=LK$2lo6Boetqg?(}2%r%gUIJ3HcssBXkO1rbi&0j8wO$SX=6`p&??M z`EC!Vv8_?;^Kw;bnuAA-E|Cw#+TA~0f}ve_+3@?xV!gthP?j$3Y+;g8!YK)4V8epzA z664_u__OO>MiCG|_&~`7_n{BOc=~3!DihcWuSMR9f2{6*hIoT{a`JglEv3IDuueDR zXX{g4e zxb02qt+~{IQMml73rvg5>esTImIb|dqrrJdrB;e6OlG=Rk-cq*SGEZt*pu;AqtirCP%di_%di!FD zx-uPKP_?-mWQt~01Y>d&k;lDEd@9u==*@cHsio3l*3(XzN?6Y+jbxC5RF(knxX%NV z#a##|lZ!S>BaAG0`$70YW#OMmbk3~=xVfHYvD6?v%;kK=b@>GwPtYHFpl(z(%d(Kz z9sTP-{i!@wvGEt9`ak%4G-7M}o4cDin=;!nMk7^nI6sKs_9GRXR^Wq>eS6m2xUurl z&5Ye_aI%YT-$G3+pM+tY;P<9;sBAk=KT0L_S1q+p6!)y}8eIWBlFbhfsK@K@@;@qZ z(B)VKRq=jSJ#(o< z3I0@@ex!_({it3Pc~7t0$180j+_D44NO9Zp%@N|$G4TUg7~s#hj(r73dV5uED^|3- z2Ld+)^UmJHR!ObWIv6F!NwY@WYmi+Pg)I_U;Z7aS(r`O}&XZns!Rv8hr_ZHBr$eW~ ztz{3|rHdKgdG z=Y6JI*ePh)r68T9`;V1GF71qyG=ya12Nd(Ebqck!J~C8inrE=o+fuY=+Mt7uDX?AH z&+_LMsSdiC^Ez`&lo9ZdpPuS%~FiF#klV}^p{{63&(kMC9ogu%Rt zRC-DKZ3eYVqm>A&MS&(n&Q~Op*wdsWssM0uDV}#fc#{W=jtADBE!Fn&Ffqn!3VoaU ziQCC`Mlu07^rVoJz8*af6t3l2fglaUaY-X=NeS404r!l67B3A(N8g?(wPr1lyn9jb znFv1u;*r1M0W?VXC*t{678N6~`cZ*f1Z`e@Xd7G}0@Ph>0LBz?z#hW9xngskXgekJ zDi6xMVwe&9#mCZ{(H6nrY@jJ!eut$^wH$oKZHvIZc3Y507*cTwS9FlB=dcd{Axr zRfYymuWu7yI%RE+GR^aZPzG9d((`-{{W(z za!dvY0K91@na*-5m->s-t)5Zo+|`HR5nboT@X-TvET{=pM$?A+KOUVg2et+=`a_QLEl8L!;6MrVn2EefVp0H zJ?N)Ua6=sW{HPL0BVaO3D^xIl!nqrT0PP6*BO6aNQ|)Z6cV6uN~ZwDw0n209y)5wo=(!D6W1CF-&@+=w0qjnlEiun zghj7d=!qiS!yU{eiz=|nf_cfS2du8{?mBx}wy^&I=GMkpmjk}vi2lIUCR#02DQCoP zHxR#-XvvR7-adK4G|tK6B+yHJr&`!su9tE`h9lx5IXk^Ep44=%moYTf(5yL3;eB|) zrVGxHwp-_T?ns1=W8?Ixr%h?F>vo3T8<7!<2ulo(*#Q1km*a0{nfWconGn%@I~tyD z?^;OWBXT5N&(?|RJu!5Bv&LMZV7!bG?N+4P4ymNt5pQjAsN1T5O{o&M&k5fjl|cHJ zS+UfU?lZ$ZpmqV0=m_6A^atl!qoqeGX}4yCvIR7ttar=jXK5lF~89{ZS6kBl4^_6~Q?*3hNmR z`niwOil1rBvFYpBMoah?Zb{j990iym8YUJ)G`EgkJ^}X{LV9qb=D;^-$+m4 z2a0PXESz&yy$*-19ZTvqxEcO*cpvx0ZtLC4cR4BX2OyDHSEqg*S5NueMVxzY8Li!U zByD>>0n13o>&<7#wra+;LROrB2Ghr_1WzFZ?HTVwmm`u1phlz1hT`haQ90u}jCA z=nEuR%{F*E9&y@$(UBJnMo*xlE}@bgzG@X9kMBZVrVvI)CaG~8BfpLC8uML1PIGf?i9@t0H3 zy28&=zLIN=EngRUbPfW^4h}#B;I?o_(xJU`E3a7V=-d^*opL=ubBbej&8)5LjB+{0 z2D*4)pw|>+n{Q0g67;W2_=7v@IxkXM*=iSPUJHBn`?E+eNLL53`ceHm)9_7fx>0c& zmh&#AExbDn<6!JC3HABZi=lcR8{H$PX1HEuvA5W`?n(~-06f$S#6G>ahFk3qNJX@@ zNeprnKpn_DjQ7TWwQR_iKeIwYQlHf_E#p>=ra{%Q#iB|ivyRR&EAI@_Pm{cWI{-F{ zh1m4>-Ue7UKY9vJBsZ+m?k643prvx_F01^ko-=`1WhX9;N-7_^;({{RWaOEk|W3!^-^#6v6Tnvz;6i`i#*Xu>PIr~>9e z8p!zc&Tv0!u(xGP9x^JM@T**fbq=Z2?&er*;J1N{vVIjCoAo}J9QLMev+>_ix%1=D zkK8TD+4qM~(!b1Sg&)0MwG?J)%1nlMpsxLQtOM&iVNNrE2RziY=(t0Y_s1sC+ zUYcn4HO0KRw6=VJZNe}TG{Evp3Ob5%6@weG2MT1j4MUiTjof_c$~hE92&^e1e`xfoN)w!7 zkgERxtiZhFDdY5|lS!DLJe*Q!fj6+^;Or)&=qcEtcdXq03Q%8S0w@Jko-$5(uQ4mP z*X2l^b`%OJjGW-8_M?svZaj}_1Yj`FY*&2I+a0Ld0n){f0D)a4l}{8OHFtWGU6Mk_ zBz-B97J!4E$CE`CEW{JY_OAXOK2#Y1QODvmJ7nneWTC~JAB2BR7?wDZQNc+LmUEqK6SF`8I!a&&e>7`$3C>@ zF#iDI%N5DmRE&Of%`Akj2|rU$S0ist*cHa@xfHLf8_?nQbBs5L+T-W&>AOOYe>hf* z)-ZJ2#u-1!Cj*hkb6LOa(Jz_T`uT4E0B{G7Pv;N#RO{^x;sm`nWox0@Ge>oQ5S~|z z<7`0SFUur;f{oI$wz*1-?eeGqk;dJjmP7T*=CVAIM_N7{=9MCw zk_Le6VS`g22z97>Q?B%lV(nyWOD2(>VgR!ijHm-YGfrJ;;Z5&KXy;LyV>}yzvBxnJ z+dm`kQGG7W?q-T8$y1HQ(D@?QVEAVYiZU98wgGnM2KdSk8|3N(0pao zqtx8%vL(cBr);*#w*%X4ROaQhyK;o)Q`-WinqG{TR*~LZN(8$<02~kb)iTKxv~*$P z%52lR4y$Ra={EP)l6jC$p_PaBr*)A`VXy%C)gktO)!*+uN218Z;fh%9U|;(^*$fBE zfNJP=SfV*O=NY9|(V4C;m@Vkd*nMa&FvB2Y9F(_~dC%-h+eUY#Z&7Hr8Jaa%x$b6PjBH)Z?G+wcB$e zvBgyu8m!Pj5XfI^dY*IGiqnP>duDu+;;};1 zo@m#ch%>n0uW)f&DwQKVn|+eM3hjoq*R5wL5+iBXnFMDeXFs-UGj)cQH%9eVsio~? z7L)Bzf2ua+5B?lf*HP=uOQQ8CCDS#cnzRqTIpO$Rr>aN+tu=VA%+}GMjf_ozyaRs0Meuux{Q!&Q98-Bk+*Z$k7{x877hI`q(BY{nMOx!1UErn9IAMS?c?02~kRR5m?O z&m-<7nB?~~nod}dF^^hO4tN+KeCU}6#5ox6wvq3llOOs-`I_dIjg5x#0h8_KEpH2; zKK(ub$C$_WtS!)~=56Wnvj1O64+`0>XB=c6t+k>*MY z%<^4yb*fJx_^(^CwKJ#D7#{)oyg>O`q8sVnAl?+b3u=3g~9EN51GYar`f4fbY(8A z=`BZH@k3Ryu(g&?zv@pM4$(M^ECX`jU}Gmd`qVB`e(7?-j#VTZhbPn%^~nChv|;h9 zUFg|0OC1(#cd$m8A1RcR{DZAc;;0 zI6zK2l1Z&TCRxiRNL=`12=cRTcz2}Te*@{8sb`8<(#G8pV~=9T{GbA^d2D3!>r}ss zodUf*;(oHQxsuZ2C@!N6Fi^Z;vi$ko`qqch=7K#hr%HS_R#q126mg7~Z!JdS`HH2! z((kGN0H@j;#}fp~=x!8}ycuDV~!)DlP&A^WHl(RI^;$3gqs@a3_P zPyQZ#YWOv1<;%vJiiAG((>?a#$Zs^HC+bWs`Q+0+q>f z8UeJDe-00zt!-J)=stVLkyIFTZv{F|J$I-?@wi6^dX00xV=du_Tuk@p(2~)fnUU_xG#rPKL9J@U_$dJhuLIv{C$UkJx;MeQF`& zHnF8?Iz7Va*5gmOy|;=Lw?+6y);rjf&uzb+YaUE05pp+2JhD`5&rUGpagpmrFKP~Q zbBu%7dsl-1c^Ix*FYG=yC~`=r-kj=NuAS7a@2w^BZX@J6`uvZ$J+V=}*ltG|qtZ>S zoD2@sZFI?jDiWrtrEFuplsvd#T`6~V`G9s z`x;LJhPy%+AIt1bQ7(%Y=->l^__)t%>kKc;*EPk)?rY3(#waTGJ*0UK+->h&$j(o1 zdI&1SfWrWDLJA4no+?<88gU8Oe`78(|3g+y#4+K|m2n2WcrCU}SI!^w3{&XFg zZO4oX_BUXI+r4#(1A~$Cr(e-tx;??kG!~R87(bO3?o~a>K9oXBoRVlcq(uwZrKSYo zMhyeaP(KNv764%O_n-z+G7d+|mz!g#sGO4OMQj0q>0Y2b<2(!s^(~T#HMFNZ4hN+! zS%U$e(vn-MILh#TW{oihVS~x7Tv{qptqKFGl1ZZk`;_|Pl0B;y#^FXE z(cFiZIONb;GP9Z`E0vTV96S(fr2Gy%P}56ow0o@Mw4Bd5zwO z8s;@(a52p#(GEhu4t@B|DZL}gLz+mS?=6vneQ8bWVifP+99EwjrepFIG>CVIqZYPY z;FZn~)YS#8Tfg6BZI6OZ2#Lt=@)dveA6o0(GpSocWh7~5EFNGba>2I|kEKKJJbCJS zd0jl@ZMp0Kt!|8nrX;nMn<;N_Ufm`;tXRyAjL2$5 zan(^;Y`2=#(8{5P1_%^^b$CP>n%P*P%eWbAe5qEWs_DAz(79BRQBWu{a7H~UwykWw zGI3gExAuL|0DV`eK_zYiS;nWh0PZdO;;tKj7zHPhQ9ldx=`?PL(yinR8?-)iBKk8O z-2PapRD*a0h{>zhRE|`w$*?4F067A>2@QaFp}>F+c@$iU@sJKPO4~r_HBf~BdeKD* zZonSZ)h`+VO%~ThLC6KZbz+ihp?BFC@dEX&^rp8@#W2QxLaFU`X)W&-`rUTHI*&OA z^tc?K%+#;NKDf2hH5apKV|hHK!mDRtJ;C;>xb+RhV3~qTV<5)xd0(&mYh-m39OZ1A zX}8NfO6S|0&^n*07f0!P`<~?xqWp>Ae|n1a_N(UG7488bbDllvhr}&ihK)V9^h`j( z=dlO;s@Ez)km#lJ45M=!nH!l2$zp2A=q~^@9x73wCgTAmH(X^{ja^Z0Y!TqdRgUT9?_ksWh8cnkA0q6z%gP$0Oedy(7}} zy>p}>hSye!(#0eygLYOnZ*DR(`ev`Wb$jdUFu!_=SU|`Tuy5QNg!PrI`h|qH@*#N2 zZhzCx%*1sbP05tnl6a*_tN9ZP-o^=Rz_lp7sjs?9HsrDL?6lO^0rBe(>Ly;G}>4 zsydvG-fvuV>K^C$cL(;{RT=RQUr1R_uXag4jK3m@pRe`zjy3)>cDsM6Uj+S49&7MN z8FyvG-(_2<`}OBfu0Q_(8sH!8MUS%G$_3rmnl=t|w$kCb`g;9poc{n!_2&Fq-TQN# znMuWa{Vmp}$C<2NxzBMi6eT1|m+5-+_u2md_$Irj-M?7rw|{oHj(;I+CLU(i4S-3& z&MQF~43ZbY8`zv4agt6mSjWSDq15jB@2BnN)NUn?O+pl8l2Sn%#cZ3$F-qre#0kJ1 zhtjd;YR&jl<8~qHOV+Z{?j}+3qU2-iQ7t1=Yo%cve~q^m{`B$HcM?mX+$g|iby1&Q zL8c7?SmM&xkBG7412IVRkqU>Jd}lEc?;*iH~@Zh_p9Ap^hbx9V(GUr+}vwvGqh=S_h(lF z43WG1CS_8GZhIP|^-jOmVLx$hqSUqlhqKn<1fc%_cmbTBTpyJ`mn7;k^ltF*xW&yn zE#C*adfP|S_02*_4b9_~jyYL2{{Scsae{lX{iuOEw&F<}{vnP#^H7eL@dD#cg*5r4 zfZI-`Kh^Vq3GdG}K5aVQ;@UqZ>twPxL`P6YPd)zt_1d)jv793qE{qv)JXsr?w#b&d zt^L~eJ6Pm07Yyz3bAjto`+J;Dta79hNnzT*uoFO4p)MG zg+n#H3#fDq$$OyRHLPD5lF2;vW$%?`&Q3m6Lr(0iG>4bfG&ruEyxFyFL=D(q`Y1=! z{xrLzu7CIK)!yJlh^SZ|2>Db!tS&VeEmBpFrR**Tn6^#jEychmhk0cwpM9Xy+W!Ef zz8zXkcG}D8w;OQ{tT6yLas5GvKb2QKsw|7yX56aD8<2TDg(tU~7@=>xTt#YyvF6U< z0RI5Idm1fdCfyk4<4{07`w#fkOT-?ci$~JX8ST?Dfhx|Sl*f-_>zd}XY#LJ84A%My zb&k2#qSLP}zl2Y4^T#|=iGoBxz$4U>59>zwuhI58CxUiy#RM{3*xn&JfrKT*k;u)x z3j>|M5WqR?DKAg;ak?@^qem(dIVRLY8v)LHaw&GHt4FEnlj)kJ*}kxo9%MKO9|u2} zt(aV34A67$qI0F|n!TTex<0vbZnW5BjyrpOMi&LsYJgb4_}vlgTzb?CTJZ-_)Nk!? zuWw`5C$`-hPE?LEa53rJ{=MqV@YApQYgpBE?K7&%Txrrqws1*!+n|NN3M_*k^nJSu z=a1eAbhk)Y7wP#fMbpWdtb~fzvB&=a(#S3Be-=AnR{ZdJpt43ebp=`(9#6|*dtaLVTT>&z<5U3Mvb>D zk+&$o`w@@Mm?w=%J;BedTQ94oaq8ZH+kP{i;-=mm^s(yxsnhiK%y!#^w=xiZ7(pAq zU&F^d{HhgfxH;zsiqIcsd2KB0x{_0A_l;8M$8B#akOjOzZk5Q#ImpL69GcbRMM`Ni zK1+;E1h#rw#bsro`SC_A=7#jz!{mhprp|26;H|^`_gKc*L)0>r=6vj)QpVw;+}08btrBnc7`=7R3+4A zK^y~xG2rsb6rONBtG>>1e#39z)Gl-@N4tvN-=`Yu$%P?8)4od;3`R?Z=WiYIa&mE$ zJa^Rwqt`~kkz-vp*=^ek%Rk~I{P`cHX$yX+nh6ZDrNsJd4w5t%5;S{}au8>NJDe5f zvG-eR$EbR{Ue$;y*Vod_6_~M9EJCSc$-n?)*FVf_ibjtaJ8p&t0dtX)>s~WN5C)Ht z{Xo$#mN_PX$J4N`BYuvJFlCgUG5|DUuqa6w_B50dawurUfK%Aje!_m;AZZZV%~CL_A~EaxIGO61alj1L&^M8POGiZXW;?O9}O^g65UlNmpq z7_u=O;C$&aW#l=^fIVqPl!O7C{EbAc2N-8NKm_`V7@HUb_ZZ+%Jfji7#y&=k+mp!R zm#07iNc6@By$y~Baf%NL8!9oH@8ZB1Bz81vkS@*#$T+SNTy~+3{EXL%f!n#Di9t93 z5ICX=6$cE=T)Z0 zd*~BKjAUaYHR=!Fae&;B#%t8PNwPwh$r&Nj;`gN%_gj}B=9#9qcbpNNA6i>&4o2Q+ z{L*>?fIU~}Seb;Ib=W#x?-+vdB zFc^}1`&3R(ur!kmieVy*fz26s*;tPtW|O|2WsNZ=!?(Dl69OQ&Q}Go+$*zx&{!AWH z+994JVl>n9@R1o_eQJ}`!Sm(E;mNC)#WGXw1b>8{YLvZ^gwM}%Yg2yAiRfdyO@}@6 zPxmUrLDIuusf!|*FEhCF#Y(L7o1JS)(_ptk&SK?>;B(%he`*;v^de$cdJaIRtv^>=n=u6TDCkGy2eo0Jk0{QT&ZaLV zINY5My)o8P^nLb~t00n3x!$DGEVC{{W3H>HSX7>DRWGb0j9*2SV&VBs^{BxzG2m<_uAIo++Fx*`++r zXpPz3edZm;Y)RV{X82*yH(g0EznV50Ww_qb70SxM{uQdDR<#z+ZfzrFidG{8jE|j2 z`g5#rwCJLJHuB=mX-s2NKuB3apM-Zbg7;Pk8wv3! z&V9`T?+17QXEe*ymu3w%>S6+_p*bgjJ?cg65?vJMSN{M5wUFvBrs|hw^qH3N6-~Pm zc>t51K7Q2&y4B$<$!`~ujrfFzEBaK*#_njm_%xDrRK{nL@Px3BzjklLaDSwHg(ko7 z`0BO><|yw%w2m}`(lC{-kt10Rf|kPv(0H6`md z*E9~imq~lcp3ljK<_S@_k|_bkeuNQAwT`WZB=hWa*i1@!jToj+xuMI|!>Yx#&E=$P zaRfe0Oa@A>au+_-(QfUQPBHl0QyuMF;&Qk+01{0!Yf~$;d2R~<%AZq9t%F5qxjz$f z#QM~4SyoxhsCiy~wY|$o;I;N-YU=$X>KIj&g>*UR)|U09)R6Ri_K3jS36@YjnDPE% zquo;=k6qK}Lxq`J;r{>$2bzArkNC$+-of~!FqT#KVaOk~RtHr@LpzrB;*+ano^wYi zSwfSItO4Wc#dt)kkUMwH4HQ<6uQ|aW(Xr#xKQls&0f_NMa0vr65<%#icvPz1A#}=> z;Oa39j^ivVXx`igmQjMhF&WKb-w4b90PP>9wvEJU5gccp^|B@)T}lBsW^xJb-mzwT zIvA4>kp~uIyX%lYkBPK5P42F2>}2B>;^gH z4CI{TRU>iJ+N2}QYri%jz*~}E9QOADuU?^nH4EtjMykqo;Eq8Dy)f!J98YS=w>!Ac zu6|Xi;`t<-MbPpVIB`WwtMs0^(A{aK*lTb_3rfFwMuJf)OA_Pa3^^YW91-bLSo)q> zWP#A&KzD(kU;P?u@#|Th8_towx?J21HcL^C8w(*Mk@Lv?DhH1$3*dC)ZB;R zif6daMn@bUV^gmV{3g}9!4puqN7A}>Gr8~Q7-@z->Qwh1?H)ProK#XSu6=7r(|US! zce&HVyJUGkmSQctU|!3Pzz<>1HDud(y|=@NZ8Zy)X405g#f99)9l4L!B#u{}02QMi zI4N5|$(~LLCP?+}rLfcV_0Y5&S!vK57DJYE?#I-hQ~6YC+RD+Tx0dw`uQaO-yiWUL zG9Jh?!yjIF_3h0;G~W|+$)J@#g6g*#mPw8nRb)qRLhdj?^*kOkSEqm-H9S``^*>Xz zQtEO>VY0O_g@Vo#jO;^^xrpVv)#u;JD{0=qGSh^J;n&D!^0~J)aYK9f;iD4`-w~17=O==NjnEwDn4nqI|OLHoupaUZhibI@%k8Ju3S69`T8f;0`5XR09b*=&KFRe|9bP=5jIeKJ?(8w4$Yk-$dR$xoDO;Q%^PgE zy+$Y-G30Yzyq!176$pzVhqD4Q59n)w*=uTqeoQ(mUy5OQRa-z0)@N5tD(nnbL_8%}9mxNL&ejyHB()e4e99z6%n zh9%s*k@Td@Op*+9pGs968z3)%zdfqu%33OPgp)|c$sq0dSE9A^Zc+1q1ujU{(2cy2 z-vHo1AHU~Zw_M0T?gd*MMC2me%Y8ShCo5wg`!t2Qac&_f)oI5gQR8J0cgJmdprtgSL+(<~y1 zSSX2h@JK9uaq_C}+Hq^<+~X`Tk&m4|+Rru0g2yTsj2_3sniAvX)#J z9m!sMR_s|El~I!-pvkYKMJ@`0eMzJc-FbJBPU@@`!ND0A^`Y)bqS|rqM5IPH2*i(K z4l3m;c2J_aEJ!*(@3$go2b*I&MbHn#NyjuF5js=&9j1$^z`J6dUe;iP8)Qr}=jK%Y z)nomd`p-k@?LPH&?LJ%Pg@f3blru+@l5odvatClntv~pf6U46%dcOT43#nU6{8|W< z0K`N%+0RyMuAS8M_Hy5J zm1I%rht6^N;MDIa7i#c)=BHeVH|MUb)otmXL0_(~O>9^=^&S_VnPIg*<<8+XQDZvqM8~OTwday`4Fb+qhBGxP|wL2-TE)YBtuGtih2&Pk}2Odg{ z)2DSq!v&lY4BEs>n7a=AWAY>Ss}n`*9V);|E~Z;_RoxN6V&5T-)fMV52DLpRM>HfBxRlm9~Kb2+% z=wZN7^&`~$>BVmJp1kTi9VY8dvAeswe=F~gZl+k&DI|vDCjj6Yrc&_79BC64mHEIu zg)fd7?XDu5e38neI>?Mvf;r%h)z`s=&Ha{)d2(^m>~!%5p|vj$brbi!l3PsVLv;@b z;2r@V(!g+6<(i1csYfiQkUcr8p5Lrr#JwtgCth#8-mGA53xgu4$YK7_$ESLwdYh## z`e#rnCS|o^M00`Mdmm$2{J#s2+ABtnAIX&UF2@DZWw{&eGHvH zqEqlM#Cgv?*`;0+cz<)^CsJEz$*x-T`bdUDeW(J^KnJU1p4cB+xcdJ9!;L?~u9TNe zx4%td?klBvuhSc40ATIM^d1PT_Vo5?JgW{ zit;vi*m{I*q<+-%q6`F*-Q!V@!qNr)^r(xwAw5r~e+Jg?Y}5rrl!Q^}r{Yoi8f?ZJ zpFvY!6fFzi*=h;^S)uZ!D&er{?~jomr9yxJu0#82;9@>w$`-K^LgpZ$JSk$fR!J|%R{PiyG- zA46L5G4QC}l1FOCm0YOZ4Js?{u!HYfo!rd?C~b&CJwAB>ZEKlhjfre`cRx|- zUXNW-%HMWVUN9?bTCJmr+Tmb{ky(ZtmdONr{OY>?0Wc>CfmbJ7tTO7+tZ@jGslYwj zql>4E`+;6(%8&m5BX8N)z}F7S_~>^aWp^k(#*t2M?Bv0bvcBUvt3j+30&#)uOnR=B z9Dsl_)rXB2McW}KQ@&MZ+zA;Y;jI&6(Hbt3Z)G%g8NKo&X=RdDkZ&ppARY%k)k95S z@!TRZ;Y%pb=URH~3`VDrR1eDnv*mB2R1)l>{7lrOzv`E=XFDN`Cj+*7)yt;!{pGJr z$z{{=MFf_X`;tPVcOIGf_o@%C3)%I3?cA&InfH5~WMlhPong}d0O>7^b6ecc6il0n zLotjoRm{t^zPd8%Z$k$FaaMgl}UP=S?NpY%(fbQ z7R8R@zbLau-}`@hl~6dE*t^!I0l=qoN4y1@=5SxfIgHZ_-~s@a%3Z~ z=8pdWsv$7|sGYIvNVHros>(<7AIgJe3u@YvUVlI*0QzGzzd^Ehyt})>R8$}^`q56B zX9|C2=zhD=;nT#IjN=K0W*vtef%W{WnlDG+bu`Q(w`eU`^CYJOA1`zBsjo@+c^6bY zwy8D!!bt*!h6Ro}AVNQ>k%z@kdak#r^xnB|XeQJ3E*E-z)u00;3=ph%3Uw2P-~rI$_Abvr4c7>{M!Oojb2l4p$f z$EAB!>pf#jjzpWLiUjystZr6y`Qc91{`D5U>L%)lg_fN&!FHg@C*JL(U90pw6IyLY zqOQvyOzTUFF$R@y8*94Fyl5{BYqdm$K_*7d7X+R=)r-MY>0y z_KLGV=Zc~_X8KN@(_+&jcH0vcEI2O5l30%9`~Fp7XkB${Yb0?#`(l^v9-sU6zC(0J)kn3z!?~vG4G6?D7ba$bZts)Cqzg! z5vUKknI&DzBOk*mE_iXugX!&5mYt@{d)B(jNo1Ed3#mP_TgpI%rH>(%*pQ$M0&;K< zy;J07lp~_=8yb|7nRIIQ9XsL$gt~RQ>pHY%FDhl}_*NJI?eWUr4s%crtNSx)FKUu# zdd=3Edd-Hg*5ygEbLjDY9P!?f>K#SY!Cv1~*DP%w{I?QWUL#_wEFZx}s>+Jj8jxsSt_wUcjjDLsF=g`p`$T(4x?@GdfsBE@R6d@+k2nRnpB1Yik^Fmo3|+xL(P-Ma%jt=<)^7* zL`Nv~=ia9(>;W>XE=qvRJq-m_!6kq>9P>xI0~oVaLJG?^H&p*q&~2l6@-l z@i>K&&>UyW^!)0D)vi@;WgA$X*uYY2Q`wm>!J6#((%M8{Y<^~0zbcSRe`{%KiD@BX zcr43|{VFA>%4L}&17Kno2h-fsj3}>i6O$Z&2&y+`s5XazBW(=F@$pS}ml7$z`6oQ6>zeCIPA4Zt&E@p;Q4{bJ4)xAOBignerXSvcYwCBs+ zTdw$Aj$Z?h)ki-%V9^P+!zaX4=QT6bH72-AZ9omBaE`xUU&^n?E)uWOteb_=Qrpk4 zs3Y)!!T0|F)+$5O&|BZ!8E+khoFp`%4jsmMRX&D;)O{;D>(?K5h(~8GBv*5Qp@sZf0ePD|f>?J>FjRImSN=M04re(%9SjK{QsTOW%#t5;C!o}bWXw9;Rr zt+Xh#y|C%luM)*H4&Wei>G;`{^OD=W@+iK$`$Fr{PvtI!d2Hc->2%#7#T$>Rjz7+u z^`5!#*HILZ3fT)5+&a-3vaQt|P{ zN+iy5!JBczjya$Yh7X8kjRQ*56I#;j@6!&KQ7qwrz#)JjDr7}DI9$M*`o|Qcjve3PF`Y$-q|aj!k|7W^@7?3(=D6^VVPJSK<))=@i4sE67*-! zH3*fKlcppR+)3pk`I0jrUIHm6;U7wOx>brkNNy?-sdcEZZIA%WIOdz<>)WQ262ut~ zYL|mu@J0`6_KB-pX^z&AUC(7}I|Z63q$(VG2FGwcsa{0;>6Rt=*)+7b zm!bN)87(ejk~p6sgZwx=6mLx8uCBM%blqQ|?q`lWp{O)Tvr(VraRhBC5r+4lf$9xc=a6AOs-o1dsUaK-94s< zcV!NP_bY3a5uH%GObGgp6#i9S&u(CH52v>|9AJtKPBg5K;B z$sv#alRmlb4MMIw47`*`u(}`}vf0n)PdwT0M1(O`#(VD*w7#d32o9flZF;SQozw&% zj@$}Y7%PGS1J^Xqf8kE4)AtZvTs^WZQmgGrcNPJMrAV4FAPk^j{8-Ow%_&Y_=zcL@ z?#4aFNB62TP?boLM%Cbq)#oPUg4tXQh?hA30CZM7uV%bUMLXiwj*~M= z7ZN&T{XOar(fxIGq_Sy~OzR#_*9=AvpsO>*eXy8_IVBI}R5qoByM|O8?i_n_RY!Jc zQ{z-zce?${Mf}UDBv5-7%|rE#Mr~$AwTEyX%tZm*gy4*1vpe$vt^WWOiuMn@8CE!m$;Y7t=hM)B zbdRE1O$y{&mc{{(*b(W)I(1H+qiU)CwPkMd{{Y$q2*c>Wf-AM-OO`ulA3SPoebuk6 zbtVf7vXREZF_Z628dI#=#E_qcModS&v62pRlg2nT0lm>KEKdC+S-XoJmDpS;{{Y9x z{Ed63XO~yLHl0Cv6ok6T8bt|FI}QMRu{?VNgIBq$DWT6&)#hzp;@3-6nB=6F>Lvv{#nq<%E|r5?SRVw&UxLc=XLnmqybyt7I1OY@HNrNYjiC z*vDc0z3L=n*EL;2TMYuyArUu~bEpioaksYNg3LXa<(?_}6t+5ds#mA2qHT8O-%7S_ zA!*+-%g^*gzY$UIikfMCWV-xDD-9a%>c!BnnRe0JnN;^73C=yURhNf87Ta6A)6IIf zI-Kl2`Ks!34>w@sM;Iq6GCvCbd8;}}Ei`3YTNx5E!!I<_08i0-iqfqsWqLEei=8WV z(YlS@=AUA8+XNYb>(JflnyuPQv)aXO_;qiE@;Erb zIT_F8S-gd4yA-MPK=u36)AF*lvP$FnoM%4SsJ+KrYO=ErH6u?*(J-J>&s|>&yIAmq ze=~E)d%3{__NX~M@CJT$$8lG)cgr`cJvGBzNY3OjCnmV8qyvfqkxLVtYLX}VU6ajTUvgGBHqc62(fs}umX40b48zb0$}`_;wLy%VDJv??^a zG==uzr*pbT`jh>K6d;&r_L4IE?lkvkuC0OtFV3<#zh=~u3>gU61QY%*N>OSWJpPh&C#TDhC$3I#! zP+b%$<1~%3jN6YnrEZ2of~7`xWql~QKxp4+#%rmDTpHs@5Qs|qM{!=OHdkztBn+qm_x3aAkL!EQcOpYIG9f2v)sIp!um*ih!y6@~;-A@vM|f0bMD(g!Q( z^zN}P6z4R8OOM2J+tPt`H<>UW7EdGvJ*hX|6v)w>gX}@hDw)Po(QI5$o#$b>&N$8} zH}VcjZ07tN{UP~NEMG!fG;bQ5VjXqx%s5&N`F z{Ko^a^vyxru^p`26#ygtbs)6W)JARO0oC|yjMQS>g1+sH=AHDIk=rbwwtZ->fqJ1= zRF|Km(&8NNvXf)*bFlC~xj&sk?E1N^lnDbnVEX!spJ~#hx|XG3J_WVJYn-0Nhxr^; zPkCVWH}l#|n0TZrLG&IjTM@qYQZ56aj!e2hOJ29QQp}uce5|WwjS9=lmd* z$gDYWa*Cs;;`t6O^DJ$9T!=)HNvU--Zop!AuYA?r{?XgO`Bih)y8Aq7VI9rI#vgpo zaKMtow>a-sKTq@=nyfe0;%1ITwUM9)@jQSYF`t!Z-89Xt#E*dP{{V|{$F2=khYO3g zKb7TkTv4yS&z(^E*FdJ9a98hIM5YYmlM`i-gZ}`DYR2;h_TZ9zYK;3gXw7eFs%lE< z8I!leSn@_HZia(=Qv~kM9z6%GA$JL$Gn!gr5i7PyIPFMe z+*IQ=ONf2g+pFp^X!>R4?D-K}MAEYREg9L5P7M-Co5BBe@D0@%h$w7gr)fa~pve_C5aq^_uSZ2}2pn^5t@%$h77NUTAi) z=PgOD8X!PK1+nQ$Czkg0eAtT2nB_CtlBLu{?3O>fOWL=!%cBzg6G3qCOM~!a`qPP# zM2jOFjseH0q?b}6#!D4p*cv9f+f;%Zi8el~X&AGVvB#Zn zxD^NA2S1>u&mLvA@bg->Ei-=%)*)-FL4wSz4kV1@*pZKs`BiV>uTcL02G=1n97gBL zbDlz<_!^!4s_ou>pXezkC4)WWF|qV-Eg1glD`cNM7woI4mET77d^)DFExcgHhBDy4 zsn22gRMPP`$GdR{IO3>X9_;B_q%)zxiNVKg`~JMu=^fCzwMjtAx`IBH=iR1sqSJIa z^#1@)!((hz65*S9CzH>uGxgU?GDfrHv~s08iDwMZe0&W(~` zxd<&4{rfJ((hg9(+r+9qPW5>y0y2)vPTo?5$avNg~u@m4;E2VN~SuM{2xe zxKQ{X3BdV|_07tkBW@`vA{o+pE%e=Os@-1hTOB@NwlN?2=V80dC)ffM4|=#dR_+L| zr!x%3IC+nDVtxI9?@Zb*l($JG#of$WeS~BA*Ov{1jeSQSh~tf;CYkllx6IX>|?KIFcC{gm2tba@z6MW{F4& zM{IVaw!La%(=IgY$7{P*!^0wsv}`+b?M*iN;v~3~Gsu1-;QIPeb4*niLhW;=pH;V& zl?GH6F4YPC9*GAWk-;@$jaF@T54prX?P#F+(jV%meD>;wL_k$TkTdKkNvE<#)7c%o zP$I!2+Mu`aU)#*_!FMb+uKSuaY;#k+P#yboxOb@S>|#ba8LYA`7}HKfLeC@0bCO+& z{i{IVu^w0*_9z(i_(f2cipddGY%%P8s`b=m;xd@pB3@6>Rvg+k;&xQtE8OpVIm;2X zRCoH-HG2_RRT+oF&oyZHhjtTDbyK=*WR~<53()#r_o(%|YdBG!S>I{nkUf5!RKpg@ zKd#F=!oG(cOJi?$F)41~I|V%L9)s&zU&9WU(ohmDP>p+G0iw_m(jErVt2RnE1%&zJ9dl;iq36a_Z%L>xiU|V$wwvU(HC_ zu>@!_%gM)KkV_9*>EOr0R?OM5HneLkZu_KkYd_)lcG25LJ4YR?pAXM=&A9mvJJ`v#YdiB-^cl)>0w^TQq@fEeHLR zPDbfw_ejRo>`ADPiHof3-92}Fy)UOeoiPS{*vV^sXzR#y{+Y3l#ytrYvpy)~j*(Z7 zmBLoaORYM2^gGb;x}4yoi`cL9k&me7=TzRatm{zR%4O4DRSrNl)2kL9_&aLJ>OQ2K z_;hxxT2-@lfVuPl#@mVb9bIQW?6MKQ&wLNMue_vtai5)Y9eRlZfNV_aoMsbqyfT9$6K0-ynaTZQ}bz z1thdi{5;oY>y!6MFPy@JBG^FYF*hCLW#xza1CM&rdM`_+m7@9DwxI@}rr03LqXmW) z^aPIN{{V$@#N!o%t*#}|wJ*F`v5r;vOQ9%8`4B}c)Oy1I08*M9-dr?s9kE1ZV}@=R zsP`b?ADOG+n~JB|RH1IsrMy7#&qlJlDbku`g7P);hOKhH>rxEzsJ!_~eOTqs`!x;I zy0@>ojwce{OQKmjZjyUggi+C;tE|3axx| z>g%4R*0lIF2_p0K_!&o#4#FL?k)B846-=`xxURyH5bE2a(Lo4cV^=Z{nZ`5vRA9F~ zzdG&1D_|kq2N`cl04g}nYcu|ip3W3G&S=6iymuAD#wcn74rv!*VBlTnk;(S0GvIV% z{{UxJ50CmsoxA@4^;`UfW~g{{C!R(HY3~UwTF=9c4M-cF-KHn~`5ceffmF*;FU7eM zM8iuT#h-}rQb-eGfu7#g8H){ZAEpVZJQD9k9M?VVn`l1Zh~mftnj#5Aw~}rgZ32zE zQm_&T%_O%Z&nq5I2WpNqH=%J)jFmqK^rcZdMxZd@nn;qW$N}$+(uKGvc)%a(>P_CPzM%>M@=m z#Btx+y;e|`OYiTb)^3`6qnE}GI3J}a7Rm-g5=Z{M=#_uvuRom)WaB>7)=0^A8j;V* zN#%#rDCB4Np%`um1+T7&`ApyOqSoa6!S*yUdBEcYcc{}DHi5#o(5YDUOUTzb_+=wM z-koC9u3`(DmX)!M(yBXtWQu4PJGu1D7;aEDM{iL}x7j|ui{`$Te1|bex!_3xH~CU4 z?JgUMQh&R`j4_sqB}4lP8I%K%Fg>YUQ(;f4@x=!n1<6pw5J@1PATU-S8cBJ80mcUy zrM){CeK%1J$Tu!QKA$RYzHA(1aqm{cNTW8{#alN3yz<7!{4wUEek93dr}Q?tJU5Rd zqS=)ZqT7;A(awH!?Z1rv)nEA8deC${kgj)J+{GFH0C$!@+O3n(ohN2-xNt*)c^Oo_Eih)99`*BTcrClY=kx3VoucYs{rsA1%MPHx=T3v~ z0rjWN1FJPoo7EQgPMKD3E66@#Zc`rZ+i~rhW@}^wam_1&J(d8%q1MWb4x z%AQhR2-$*y!L~63<0l1A9@VAb=v`@(aJGc!u=C^3{{Wp?yX>DVXRWo!PRQi9(s!aD z#_Y)&lk?)V{{ZsaaoP_)wauI&rDsFrd{EghL~AgEn-^j|QG*ZI(hIJa)vTj3$){a; zL)1dVexOv2J9xRkBR<5?9Zjo$Dda$V;zLRC#$Jc!+B2uxPTt{q62?PoEOEoCMp{Nf z0NjiQb6LL5?O=xzFPRodDf6v)_M!7;@N-aN?8=&joU94YJBsJ@HIg*gBD!Xaw8Wfe zu{FO0DN-lT_d~%ZfApIz<%-#gOK~cis*zagPcQ zO~MZ=eD?{T@SYHIIW@=3)Mc})y;(hf4@AQi zlk~jedx=mP-Z>m#fr1?m;5qj1P1@$4;pUBIv0OuY6I%m|c%@)vAN@xIpQ4JcwViGa zV@JNW>HeKMDlA2zx{lICl2h0!7vz)QKDEtKm&wZXb?4*882F0gbBciY4XHz^X?NNs?b}*h*bwkXEG*8-%zVI4p$&u2y;>i_t%2iHgCFh2 z!~CnRm$Z3ImZZ?s$UF1fx1|uu6?r3?cYP&ugub;uJds7dkXdv0+eYKI^F^jA=xVb- zZd3!$%+i^obz(8t_Z%8=(mG;m+l|S0YZ|EK+Dd!4=?kV%(cRffPxSe?HOw|a~p#36=562Q`wRCAmYk8$d011d);%3GOg^W}NjNm(seL0MCV!1e0`g&JFzNr<;Niq>XQ`uZb z74%CuSJ1`?HO&gd^#$|W+D&a~CO8*zln3(wite@0-9@GnTF~7_597BRmZJ8e<_&h- zPaKx=V6T@d5Oe5x`PFIDrXKn(D0&lA((ISdpGz?};`^n@n4i#9chu`8k5WCdI?Dv` zhmKL(cw@PLN|V{>@%0s{xUju@JMg%X6yQnq6%p6;Z9$76KrZ2O>e=V=A3C~CR*Kcw z!F~vk?gU`sm~P!vmIQI$oOK;#pWvR}NTwVL?n*91!6J* z{Hrr%sEkVMJmBLh2;>i)UH8#CfCwWB1~Kv#2eI(v={J!+xhlXJfk*%=oO9gcKb2TF zceb*{y`zy+1)5H9c=xQcT%SgqZij7vN8Vv@X>!RA@d~e zI33BZ-`QH~!V9f_)Z1Dx-3FB?5;BAMX1QL)#|2@|(cQ9mu9hrS6wKLVCy-#JT zNffbb7kVC=a3H?7fV8*V{unL$$fx{mg+1~`6XDD+4~e}=Z)$E^Q<~P*A$yexag!sV z$X|pp+%t~ZH1};Tfon9^7Atpsdf>F0h4CI?&N%r2&O3c7HPU*ZPaLI#&WhSiTT7W1 z>TH1*#H_?)o_-<6KHci>G|F4_Uj0ASJw?)bg6RDXs|`-_0gH>BNfg-HIXKx8<1EMf z^H!FJ{A%Lf_gd?_UZ2t@fC%n26x5~ON&c5dB_qh^Z{qn?Q`0)UcKU3;!S4S6(SDS% zjsEe}1`xORdq`G}#xszllY=Sb4`WI6?+z@yVY*p*gHbpAEvKukrk7s5+88Pp0~#O24tX1`Sri%2B-}84+9};Ch{`27M2q zs!IO=p=Mo5eJ1ka>fNoI%#E$(+2*O^aNy*6RIA264EkfkEl$Sgr?tCHL7lmR#zQDX zAdTVs95BWK<2{F}ew^y9Kd8ESA-ubW*IKiQfRbk*%s1g9i~vis0tp_NCb_LgowH+Y zLXi=<>HEz!Lfh)?GpXS&Z6bURY_8Kxn!TpGu+MicobeC(pdK=RxT(bbOQPAp^2vJ? zj*FIvEAEf|{Ej*GJX9Z3)CW@B7F+9R;a*CK<2WBaYfEYBCSDC~kPSxS;__xl?Ui%K z!2AL0-lm=p^p2@}ad&waP2Fn49#nJN-Nh2C4qOoAXE`77qnAR4XneaJlgTH-g;;z| z>FZJ%w2L`3cx~;cMq4xkaL{>0LRviflPRCc4YejpV!u? za^%YtX$aq_bl)N5OUPI%?_iRGcKs@q>YZt|&2HxLlzeOgkM=+Se!{2TEM7xtVQXrU zqTF1!oa_c0%U%a>bBe1$-GBz-djV879)kGK9rIn;j(gV~3{FD~F!ZhmsT!(`;+~_qSc3DDP1iQB6p_0Fg8Wj~h?N*!q@LKUJbk02vO$P*l%^mZ~h1#|CQ*cExnG_r^kniJ2Ejoy>n%A!>aFfmJR z5llHG^G(XCt}~WBsai>vDK@r+GlW?)87DMuR#e^U1t*daBm+EsYk+rA!J*R^(4z7} zf;1QajQr^<48GrAS{3+E=tieAr+HA48*ule*BX;V_`%3LgH5*DgGCM=P40V< zOTZY~}oaHl?uns!B806-?9 zc1Em|L#b{%4stzd)o*YxIXqM=?{fLRP>bUSzG&EWw6jO^q#^m@n$Wb#MvXcP8;ygz zHx$*VK1n=d+J&K9`MOb&SY(oO??h@1fB@j*lTRI#WmhFaQ0mFs9qO*}-s~omrQ76! z^Sr;1Tz_*`V#q)P)9F-yk6M#|9JI6tD-Ei%=h2;sBeauzGnk0=0|)i>r<*wvIgxJ~8|3sG zh;{t?575+d8;#L%jmyE$y*_EiZAlgzSdvSD#xeo?z3L`Ny^fccQAEi#oNpXofWk>~ zxb@xt0I#JuSze@(79gt+e@Y&SrRwoVGTqpl6lE&c7ch`;2lVIr)K^#3q_DM@Ck>JT zJr>C-44>~@kMaVP!}DT_oDj7@*QKRt>p|B;@(0e{{RtE20waf(R#y0eKp|J ztgj}xEw|2$hxmS3#t*$RYPa_DG>c{DhzaBG3=95v_18t zi)_RBt&)xpf7+QNvw0O`iFe4yg&oaI;^>`kPScj@$p}FHS*o6HGy9q$f>VvevOdlF zr|^#y>}}CRYkdUvg~udZPe*)@mea@SovfoQl=UlG#^5H@DVS@3Gz+*}ti+^TGBs)NcdHzBMSM;0)BmPk654 zN1Y&o+twtA0{;M0N`HgtYRe))8H{pJjsT(Ya@je0BKG#zmow}T$Xkqp4{DcmR-1p* zv){a>R^IO3TXu||aOhP30DAIVp^as=avcu~yNnM*UDP^&Ng^U)Ml$~ZTD}p6KeGem z)gkwx6H4e!UdH$C$$s|WU|bB0;~B?ly0y<0;GP`W%t&#=jt_3tnJ#tpnT%>Ss`}=g zv`tCw+BgG^>_VcGg2&pqUTTcma64WOca3n7Zd&-4ty;%CRuaJ)$-_xFSr6n$;-UKY zRO=H;*A1wB_GKHt6D~3Aa%lKEO5^x--QCOiamN!$f$|xu?)RxIF0FA2yR!g6VYa!k z#`$d9o5@u}w@7t$$4~WSdcQ90NVv;nGBG=c_BrIte3Sagcih z^BmSTg77iH{5ZiCpu7$0W2$uJ#+c_Vr?GV7osQq+f4y{K&pnnmvd?J?f-^)Dw44q; zb<)8L2H^c@404^#AL&m+{{T$_Egv9fK9ueTfg= zE>=KrbL&yI8nElFM^)3J`@7v;h?}~k%mE)!+M!zI-1Y_X`B8FOzcR*kFu| zo_l7j``ftZhjXUnVVtj}L3)zf*hK8DkW}Dej=LdcT|)YG<-Vz=$YX}#M99nj78(Bl zjXzJ-AH}TxEh|rs_^!vjV8%vYmpBHaz877NqVU$%8BS-@-R&DEJTD_3k;mmr_9c{T z3I=1?`&Nt5R> z{l2r}5YnJfG~S$4v4mh1l33RTho%E=$EHcCmWk5vYr*I5^u4SHCr774mIb)BOTAuYCZtqb!%0u@dxJ_dX@Zsa;8V zsp)U2>QgG)={h~TZPV>-)E%nh@vsa_Z5ZB3EJaSbM_1K);^$B4?z8a!08Hv=qy=p* zt)`O3D_B4*{$fS&ZBQ8Q$EGq(S3U(trr%%Q>YCM-uX`MjL2Ydwi);6Z)TrFpJ(PU@ zqn_2I^<7h?G`^mXNY+lZ(RR1HS#*R^Hmj+`I|mDvjWg-MHLn_NTPu@ASJ&Mg(GmD} z){|&GE3VsV&}s8r=~|7&z%YI0A^78u8-kIzbHfAAHAD0Tu+pB_Q(|J&ZQJ2rFM1GH z{1un7Da7-s+!AL=t*s6=^aAPN?1%*mRIwA+{&lB5QiWE&IsopI?h9&p_;-A zduc_CNUG5pl;MszEuM4r{OgtGw~g95J|bBaGFvB6*mT@2dwr?ukEQhhBI@>AC~gvW z{3cDA5+qn%zZT)fYOH>Mv%ZBjSu~wK+fSM`Xl&OLNrHV&&;TdX)3#|&i({zxZ>rx5 ztv1_R)3rw^*Oy^Iv6aTsN|FJL_XqkL2M5+)X{uZF{jHZvH2!SXc6d__i(8^bWOBK3 z$IWKR%K$PLiq9GRb&@;%ES@(v#gN-hkI>@N=e@MGvwQUgClSCA;KAWQAaXIB{Hm_% zO)~GPZ{?Ei++T!k+oV7gXSoNA3YhqzqwCsL;_H?-4Kxe_7@R6HjD8Y8$sV5;Y7+*n zY19jwh^4lfatX-~8+zxQ5nFy(Nc-w2qoTlH#r{4RhODqcW-^uxRUY$Y~&lGy0>(d3j2_}ug@Z?4!-La>IE4{y?;vR`^qY&A3lY6Q3NiJ? zFm(KFqxANXXKgHzM{Q#SNQ%S-#A~12nwxZ#Qhx}AjIFqqZb>}uHEiOVqGA64PC_|! z%|^kt+-X-|3H5=FKWYT4c1Awoa2LLQ?*9PrshZtg#rQ6!;D6dM{{T8s{BKhMN8j#B zk3%zmY}Pl2`fgLCS2D8$-#Rha!xs(=FO z7Z@I!%>jC+RF4?Ce0vN5{iv)}+XJ46F^=U3^DSoFeUP8ly4Nij1*4KN_<2K9==#4> zMdn3vf5fAT6kTC*vIdeE9Qu41{{Si<60mY~KtA~a1U!Xb&=oxX)E~X0l^$Z?a%z6v zSv|uslG@(`@TrU%Np;j$P5_R_OC$QkmWo0D06L!%U{YibOURjy=~aD!U?}@liO&B3 zF*E)mM>Q#*Rx+K#Mbe~W!OR#Rr6+rsBq5tXu$6~=jkx+?QhW=sxyptKp;v6FA6ic* z5)87F>P1MTpH7#S>8nHUu;7oOp+{}g?7z(E`BBepmu>+44G)0>Oofk<78F0Xurq zwIWE07vz!oc|t3&z+{7YLm&Cj(rF@- zDF{4vC%rQKBMO5|^5ns9ECKj^jVg*Dl9rIMEA8uDN!iG0qbN^&4AGXC9(xU;`N`!7 z7^Y8PYgQa&SCb1F2N~Upj%qq}&B>B`I^4v>JbyNeZuVRI0Qx*8qQsNa5WCC)$X>G zGTgbt3=xh$%B19|nC{4%t_cQ1MgH?G*$LQ zWpizDkbV=zEQVh!hgK?2W>QD)C_0_6WgugZK}aoSXo*KBZ>P$GBBa_SmK{lX9?eAK?hX`Oy0r}J-+02Sa9FF;?D@iu<>N&*}{{Tpk zW~AO_%T>{1Y;}DZRfg7e+I?!Cytg*@GsH&I9ITl78nQ2C zaMNJB4=g9Ctu5%KM%f_f6js%ypUV;pNLpWuwm>GX%`aKB z*R%*EmDMDbMk8bIR98#tkXXZW1W6-LaK2e=`~e8T&(9oG<4L}?mV0EA`B7vHFZ3Yq z>0G?2-JX-hlvXl(;P#8s-8tel#m1qmh&qON%IS78ua^@kQXTj9XFPzp?agRNpj2iU zBm>(#)-&tN+e^!f1h(c&WMW(&cFLcTA1c$n7wfkAuSRL24O(qk;fu+ZTg(a4LCHn~ z&}WZQ0Ie!5K{j&oN-HCxXOd3?0D2Qf4Zs2oCRt@)jN=4t#w)U36bIoYg5&{3Ix8W* zG+YS0FY2Iq4PwLfb*y823LFkF2j^O+$L(3u!;MNJg+#bKEmRiVP7%ENaPQ5MM-$~ZdHyL@^jfou%z!GU

*A2rF?0qOajj9TYOk7IsB~Dm#QjZPoh38-B5y|l?+?MCJ;5hy9Q6-Q4S!M)a zu|hpXPka|tZn?DHH|>r_1O2U}58R4mmC(!mS#J2HcyvDwHF<*-nn;8xo-)!9ynaTr zQpTegAOXc_KeTkFE|9c<4}x3hmnYmSHD>_tKoGyhj76V_oM+Or&1|*14}p&IqZmEU zwOc*{--tTe;sDqa*-DttatLqoHB;NU+mXh8RWtCfQe88zbV&*LUgOGkJYifFC-$Q*M;JcM`c@~=MS+=S(n;LsT3lUA84W8RA<+jGYmr*xD!8Q=Gn@0 zgEtwcgBl!dV^o`?(2rDzOKeK=$?*?*g>|-?w;FtRai$qq9l&?ur<2E#fr0PyrW^ZV zEsf2qd`2<-`KDV#y=;SN7wbG;O~Y*mjE_od>U|dK-Y+mHYj*7_<8CO~p)k(Cd?z`i zI=l^a6FhPgCO#!3;Qa@sFF|VdiC=;DKXkXdgE>p7*noR(^{MUEhn;lD2--o*9>7&o z(02mIN{!Ar175PqWXtd({8j_ zHG5MucTkCB*vhRK#~2{s@-xR3&hs))96p_!yliVMsFvO7_cpfTV;<{fT%^&QtB;YS z)>4S&L%Y8K6YEfJp794+@gKzB;I>x-Owlfon6%e$V;))(U7Hy$$GbC5JGAg+z{jT5G{*;Q%q|_&PEa8^+ zWf^sWcLW~ndja*So~NK&b?;lMVbZKfrK zq%zo8qi-TM!${xakdu~guWw4}Ll-@nrzedgJVmEnLjG#$7dnKX@~smrBkE2!kEayR z)|ziobrx73Td>F*A->%B_S!b{tmsbzmHBa&vu0LkY$ z#sT?LM^yNgqIBKzX_{r7w6Mb_CIS_FC~i*T2`2#h_p9C|6-6A%bHP0;sq_sdJIHPI zZ6EH;8Yk2xdkc45aUmpS&wPA4MmaU5x?1+br6H53uR1GT)GltY*E;pB+!y2%*kd8U z`3z(pGf<6w_fxZ$(re}yuwFoA)AbXXA-spa)94Nx1$%OHP*{4-eviLRL!_^@9VX^H zi8QTUSH;ND_gzV(b)}8f?vH$RWrN|mwskShZaqB6 zh}@&F&u?Q@FH!X!-&SkaS9*j5r)O*t(kEPwM`c zne=UX0Nz@b8={ea>20R;k`@{7!3+-vu`Sm2I)_$jD{pF7QYjSC+79ep20|ZP9D(h{ zb9~7uQPA;zjj<sIh;(dZYC5T0lR(JLpP z8bvx{H@Jj}<`I*CKqZM>;C7~e5wwjG9-Y3_da%j-MkINlUB)RQkn+6nK_1_!r1!l^ z)BQ1L(#xqt>`?i3_Y%2jEewDYDCe=@WbixHIQUgrvy*!s^@!m6x7_Brit;&>fSX8@ zwodH!_N@KYIuzP=ryz#thL0pV;|@K~&;ACj9}+c9J3_kCZ#2iVmOHCvnB2g{o!GVr zlP9{6K*t#R)q7~8Th^m#B$?xBH_N@T8ldEp^1wBnYEOw?ZLO7eTy<=*tlCUP3E`)n zCpagAwQ=e1Rn(GhJ&tM5T)bUFSiZT82;!RJM~y(h*|_Z=r}w7TImjQKUD?imfnI>u zMh~d>;MAML-i&U!>YH67dqZw>E!^rq=;2fGWBsG}N7kKuX6fj9cf?&v8(4gcNzxmb zVNe31vS5M#0C`P67Ak4FAcHwMG+;O&4h4I&a4W=-$8%DKO2ZT!W{-~Du3ce8%goCX zf$q!~`1&WQXfklacW?KNStt5TPqJ6% z=Naxh*L=Wz#%Y#qO(BVnOE+LBR$7nV;sF zX!UT+s!j;?H8hDDIzz4M_kojcf(4t0=kf#F~qiG8D(0*03&m*=du)#)7 z?9oK*Jd8CcOLp14n~Y=%M$#9HU^fy@-Z5PP-H*fvy%Hw?oY0bB27T!Ev=^-gq(KSf zoX{Eeu;zf%l1IgoC=Vv*8MB;vdzv+747lJCM~MMo zWZ+=uoKTCLl_!!r;)*kE@5KSGL2eE>p~i?D#5O)GU}Lpz*i~Z!!2`A!9${8O2#`plPxmQVqw{LZd&WbNvp}nC?V{erPtDTK<+l>0D{rUEpU~ zg0w-n#XHNR4=;F&;vR#&O4p$+yxr<#W1Rm0)1U1_y6Faz5gJ_FL+kLcC+WyFIR5}i zbXRwF((PqZB0OZV$E`WRVDUs%@NfngdWv|y=mRuHGpJ9`JDN2ozi&ZCN7M7g5~E%u zil=EW7Scv2(0vfgyLrMDg{&b=( zGV97@y!)#FFs35M_0A}&_DUhL%Fy)n$`P~{46JFxOV;!ih(~dE6HZSmSa%)8F6usx zlV5=#i%^QvF3<3OG3q$&P@Qw^?bCYOteTFU72Bx5Xf-L}1J^hJgU)Km$w#u8LCCNz zo2Tw&jPDH|;8=yu2d!a#q`mv*v#89Uf=j7fW7Kar{`I0J`zrLjQOPyG@tYQn9$Z1H z?m$&bWbRCn$7;@UKxS>*TjJzoWQr1!pG3zFBYm=o?qdL8vF4qxp=KLbu;P+i*cH5q zhIr$FPZCEVOs{_Zs;b#?WNoZkX2v~eo4pV;WPyePrDDv+0|AnKaqC6RY6&A5BzpFv zNDloFOJeZOV{^5@?sx{ARDlp+L1J;mbEsfhF47cSvW%1MU9hr9lW0xHJ+nim6(VKQ zI`FoV7$kpzSaMGl2I@REw|vWjtvk5KY!k&k#Q=p4eiQN;#YQ!4-^C@tJ8}SDektIs zi7FLnx;5stdkwXXte01l9kIa>%gAxq3T@SFuB>lmg7)5PNupwp4C}Fwjxa&(SJ&Ay zrqfdD&0k%ecSok%ED@I-rIh#jg;V;~&*D#mnkR`CvOU^;(^OR37NZ!;t~&-Es()T- zoVP&XMjg}c1+0aJamL_1ML7*>;zV$YQJnrU=%cWu{cYj?sn8nCnr^2C*T(3jU-~)Y z9i0!a%z9LPao95f?hPu6Y;JN&he$lve~7kQxyEY1@WaFjx(`}eoEfbr9$mz5&ft46 z`Gb$1II7wPMI-sg^Cq1w$zY*mU({BuHN?)HJ7(L`by#(4WxBVSWVe3Ir$41QG?9q_ zB&j@SHJ!W+@eF9U@aQ-01%=#zLhf*}Ke0Z|{qb5dT`CD%d*!6<@SX)?$rl!Ci&9on zUuoSy#nU=80fGC)_VNd^C;aO+%O2$8f%U7~?NxA*>U}k0hw$4?bo}-u!jJ7#P$0$0 zt?^$}WR*9ex>2>cuRTcl!;Yu6z38ndTwKQ;+%cG4S+Gb}z(1fB zC2d06{{X~A&--GEW_K54i$h@WFznfMxRGkOzL$g7Jb*q>wzpvA({PrNNM8Thr2;wMf}4S;!=&7$08rV$$qpv_m?E z!J?e(7%JH3)}p$V&)vQi7=Fhd^=N7~iK<%1AZ@QAelKHD*6E1t(VpVP6e!7bl(0WD znzh3AFFjDh(wA#3oxoJ`)nB$dlj~0=MtgIHAdW^2GH90zE}^LG0U`K8AoRy`PZnel zM}BctH+mgYTM{Mwttc$#Ac6yPOMFJ@OO0atO4Y4naRv2?#dClOS4Lp06r7x?JP&SZ zy7nI?=aIoYWOt`q-G1T?D#lh|?*nEfW%y1z1N+r;ifW{4!!9#P7AJ&SCW+DAL2U8q zyR{juT(!}I&%KlkcIOeUPEI@Ib5`E7f1^kN)a@YLdo{`?@ISvCRx8qa?@^li_f<=o zpqX6T#UxHuoMe~n*k>Gn!kZh#Iqzh|lH5D7Co(bj$2sp*rs|HP$quAyZ9}d48>Me2 z`?im11?-1&Tt#f9iO+U(@qhNF{ZGYm`H>53$HG+e{{Y&lyDcA0mqgR`eR|^Q()^YX zTSyV3PC$Lw&U5MQK-4ebhFn@o&ujn@nFd^_;BLpQZp7X=+h-@qoN~!1qEoMUpQ+xf zM6wtYB;^=}Kc8_?%Z*J|*L&8y65}-X_D_y1QsJW_NIH?T_95{0R&#JA>f*l z%Vt#ydnIYsTEb~7q<<5-Z6#&%lEgk@NimJUdU5TKr6xMH(-KP-9_P}bQgw<;2>Y6= zKW{Pr0LW8wYIk?a!dcwp^Ug8)RvejKnq!ExG~Tm)6iUr72uAX`?nh#Ox6-6K)`NLF z*y`F`?O}fr4{Le|U^gekl6#I$M{IV@R6R9pX1OTMy}#Pe#67CX>CUNb3dZw7n`yDR z2_Tw5nIa0ow<$biejlN#)ZSG_h{NMn!}S<7PNI?SI)dse+o;qjNaNWO`fmzz$>)>l z=qdrM=$3j#tji1@W4jE<$&vImE%8gJM~Aw8gf)32w$^n-6OAcU7lO?2CzSsHNjb{L zf=JG3vs%;jSO=2JX?txd28wG}!bpSyq!t6v_WIS(@ts_Xr{pC{C3Ped!Ehyw+E`lw zl}=R$%h+?xIDZbii={Qo*foh32<)YKA%ztf@xqtJNGFO=vD|5_Quj-{Dmy#@W?X#n z%@wce+I^ow^(DQixQ=^^Qi_s7>Ngex89aK^MjT$mmPI5{vW=%0$J4iJ3aDepamk^v z!*|a=tv~cXNXyopM`xwR3dbXEo?LziN8&%H1Lj3p?8MzGF8=_t_emWeq~BSZJ+~UM z4HzSpw^Bk6&4D!^`%CEGA5UuPr!VJNN`6a;6Z^ehHumw_+C^^!YZNh{jx`;TKmY;q z$M2ei_|c+&8Sv{>3O}7>Qu;i9vT(!mQflU%Y|jVwGLAbO`qz)p_w=E%fC;Dh37c+`c{YgIot!$ zy0yMAVbsg#{pi$z`%_0nQf{cT=6ow;ANbO(26;b(#;VxCVgMb!BgG?~&N1?(I#L+) zTUKAjRPG-#N&f&klA_#9b4c2F%Vd@uidSQGHM)h70gw8RsHC>}OK=$FsUyA3z2hC* z;v;}NkF8VFFR|d?N9HyN+x;inmYc*zh_MX#$R70{BxEqbKF5kUTnMgW$Y(9dZ$V2f z^fDeUwL5m00hN=vQ%9}LcDM@6&gUexG)}1{*Pc^5Pa8<)iz#`qZb> z0QWW2Zu^!%bHT~&PAPJvs)M+Jf@%>Zn!wVSwCZn+5N`Z$A2lac=i>)wM0y!L@$m6{R=sk`mZ;66sm>$$;kus=| zsA1fXYHNaPk1Whw!7PJ?03Eb_mHotVnC?iK{{Za*?Z~OkgOA`TrDaxTQU`H?Np1DP zaX5)%eD=r`zT!lDhin48W|{;s$2N0}ALumPm?;j=F7I3s#tEQ;r<{Os-i~QwmLBBs zh1@WEd(%8Z?tAc&n8W~OgEz&Wl|L`hTz{j4jzJs)#d?#5^kK+2uT$8RT|+}gJShX; zHPNH6QUSoJ7sAAaDs$~!csK_GwN=Lb7uq84qO)iDtUi=e=+l)2XDWVU{&gx44{z3j z(JpXTkEKp6dLaj!Le&ZQFXIC}nlgXRfcj3Zzk+C(eDX6>lM?a<1rXs-l?n*=#Rp?1 zL)On$U&hGaA|FCzT@HH(i@qx^+RytXHV1W;Zc4nPKiV=a+%({5$Kc_LBj0-7;& zC1v>M!9J-^{{VL+1A)(`E8lS(^N*G(`F{kjV-Na0Xz0l=nJTa<%Fn|C!3XLp8F%(? z@Yd+D9X~C$?oZt>=0HF5AMI9wunc$v&`z9lj1l?KQ?EebWizOKlsX#aH(6e58g0-Y z1IcnOBOg^N4nBsV+Mn4oRkT^9(>j|=)b^`LVxHDZXCMMdQZfnSjN_Wp$4?3B!29Pk zQIk;i`{uwSJ#eX0cD;^kq`6+a=?C!DFlEQ9;`bOXgLc*mBW4F`gb0u8@^OzLu=#` zThLM{Nl-FCJ?YlU+?6w&C?52Gp$}DH5im;=mgn}SJ$@zrDBBbRfCwWaIH&tuNh@IT zYCWyWUi##x8&!usmd`ixLrXV4nIh&oZzbzYWtfVSwShIstQWb|mxaz34puX@RzBKT>p_-(8urm z5nKjqTb5j;>JK<0jo#zGaMlwX>MalZLM^rj4Z<{ zB$8kh{(zbie2EvL9rljZKZtmba~iOCt*s!52<$!`&5z90SaIZ!hX>Hq*T$Knlf{m* zST>7zwMk%w6Y#1g69e?kLmMGe+Z}~zN~sh%SVIk{PB^5bsek!W>DS=^XEdM73I+x< zL8=PaP(pFFarL3BY&hXYd(p-`;<`{CJJ74>GypC}arw|B4I#!k9jQ*x6aXl&pAa72 zwIr88=xw_@B~i~F^#1_RB^#`CLnhUXU%|NN7+*1S`(~K0*L}|%5$#T$GpEU^>h@NV zFBVhGhQ$3#)A-KD>ikdr12`^*2kkQ7 zz9w`JP;@508ubdt_sv0Gz&V3F}O-H?kG2%oN9iV3z^`S2ZKEC3*BO7uL ze_H5VV+S7mQjdEyN7Y~{h{>EHILWUyUH zFlbQhY+;9ES!C0Zswt?X$Jp)`HBdW|K-7qu%2f0zNuDQwF7SBnXvq+$_)hLJ2fZ_; zLtTv8Ji($6Is7MreW|Og_4wt0+1ftg+1*VTH$`(Nr#$}v!k9Jd0c!0c5V1cv9)`5t zsw(2H$nKAE_g!hD?y|1m+N64O{{S(VHZj0gP6DnPL}e zx6s@&L{n+N+TS`VTUEX3`BNp@7bm~VG>ZLv+hD-_N@?e%p!523R*}X+ZNbm4{)I~9 z>5Y6{m1JyYx`G%J%dvwea}WtQCpf76)DZ~UefdqEVq@1MBloG*ze(QN#T0`M%%xe0 z_<$hukIteOyPoS#wrfc()-fC)Oh$I8E9u+k z@90i{YKBU?h&j#&0-6v|*pkZSp*`LG)$^;%aW%x43La?-vVaZ-PIwvM3bZ;)$2*M= zr>rzPjS)2)Ye>A5o9|5&p)zo|+Cj!~^a85#6oyfM#ibH!f2W`u*w>PIS{dEEev`uSKThtqaHFe--JHk@}I zzO`g{4XX_&ub|%{OG&Kfid>&S11bLi#6NnmZIm?HqfryU1OU18q_@^l>Q>hlZH<>u z$!^*9Wh?%4mOi7?oDcP(jyv&2onFR7Egj5xQIL0bHEU%lY{gPr$!Q^iP*zy86RGYB z@PD-yM}GA$@ov^DPZD~GZTYu*ue?TAwj@|47 z_dckD8B-;+qv}?ntEfp)8g(DZDr>xX^k9Af&ZIfwPwH zibrv7;m%YQKA_Wuv1wGYt~1$aLMCm+<1sKC6Ud;+vAQ^Aj}iCC<06b^lGh68J9h@0 zE!>@{C&K=WM+T3U1Z;zb^dyYZJ@zomDGrM3oxo7xxRPf8uVI1-r)1O6fwLt1#}(Kt zQa6>j1bX6=K^gAA1A@ovNJF5Fhbr0cQbvg+TmT98G>-2|ghpJZ8~vKG?60OW$>({< z48hT{@Bxf|bful`q$tD&#(o~+ifbqHRn!oDhoySt$`G@r=Ixwzp-g6#32x@RmSSUk zE-~J{KoSx;Bp;=Ek0vD&HSs^hTL}IQUc&D^h1Q&npQ!{=t8X9r`qegE>3R*x9*Go@ z=kpDUY`ccy)!nY_?x118^I&xY_M{)gY@LtuqgEg7Ra~TKP$kg)qq>1|)AVE$d;QY= zm-cXJ#y_;pngthqC96c(%ZTnFkSP5IY6vdjIQZ9Z$k8)JZi-kC81T*i0HH_ZYfM)b zS<(HaIyj=W$MH=)o3hDb%yIPx6uu7~dKXYD{{Y01S}{1q#k8sVouq#CQNd{x!Bn8y z2O0JKXj18x#P1M*!Eu~=Q>>q(aHL-LUMBQi&KBRTG+Cs^O8w{|{{YR3d$QKFy+J(K zH5(g+Cm+kYjlZ*2TbHKnX2P3zr_ z9g(!B**X5z<8QZzh0`D6QY#y;L9LP9X{c&8Z`c?wBwy@kO?%aSI>{ZkQEG-ZJ6)Rk zLc``VX#B`LG;BOX0a7-T{v(P5#+`#>j@j>7w@vF#wbSAP9h&+2niVHpIRjuEN%VeY8{k#23a%iD2&C{${+ytIH;_UJ>=5I7$xO>iap6V z$L~@*i3qipLyYY>r*8rJXmyW_T^*!6W#XGrj#+~9{J8%Bn8*JBEm)SBTz4brWu1+^ zg@v7>$F@6bXkY;M8)E{F5JGtos2=8><qVNj`FlPbQp*!)&K_rUgzcTPZKKUZs7d_!+Lfj`&_{n_Ed* zHY(mz$Ty6SL%{s&1I(-#q9|2Ufq)0+fm@61seLAy;Xa*X48;zktVbMyPved>c`$!H zr}C^!=n38EPajIPMvO>l&+Md6$>d?H&IBl?DL$*uJ7(A zKli0$nnKCEfTOh$Ycy{ay7`Lo70WJuAbB{)?T-9X;TC-jbQ1PvX(1e{4geTxC@1Yl zOc_}1IrlVDu*cSeqAs*>k{bYibYia7C%Vv7;9wAbbTx9n4+NTvWa#sej1E3jD3rDd zUVe4reM*edi&270dUK4@HSA=_{me}FvJb*R#t)@fUIXaOt$4B0c8W8

ITs+$(M; z_NkwSUuL^+6}m1xb4%*v)34IvTYKF;`oqkM7YE_m=)thVo=1Gu$KbEo&f~(araI=O ztJ!Mz(8kf)t(-2A!dPLPm*loM_7#%*G^lL5ZtSinx@nf+tZc-U?noq>sD9Hv99;ER zhPPLi(4@EeDLRZnd$eF;WFELH@qJdV0edK(V?xRMy}X`vq?r76@@1p?;AKzEYB2WT zk&%E6I(AmmTV%h%?OGid#Ezc3ok4+bQ6hp4n2D^*2S7q)QRcJ(MXe&Ui+OS0Il5DT9RVTwZ5 z8iZDno_wdb$ogb3sUDlt@agtYK&=#y8tp6r!ykTgQhz=a88Is#r2tEBBH^u+e8nZ9 z>qKVnMVed$jU@MAaYZhNvn8WDhq3gjLtEOipMa>(qZ$I*TW9e|56IAMFfA1ZwP>1t zwJI=WL(bDpH`ejr+RGBK+k>~|Qy&s+qqWs-9zD#m#6d0Y82?Cw0DS1d)3!6v+XkA^T)1L#qXahqt9^+OMpL^z<%B7;$IT_ zdqDnLE#9Lr@8m)eKPG$=`cx|COpbR1aQOT{`qORJfXYiAKiw5-$m)_RNhVD%ylT^R z6j;WMe`-5#^JA0tDdM zaw_ViQ1-%tocF~^{65uJNb5}w?eHK=*pgt~jBeW;evMJC{r>ns%gMtsC zsTWL2(ew^)3VfL!J@Gp!!8=DZif;=XWNd+ls*hT(^xw61j<(jxdwF#Q(n5JncT#b=r6X z486Xf)nYjq?N(Qh{bOs_z9GJ`XENN{wS}}1$bf|<0|SivW~)$10|K(ky%wY$5`uRr z#yB~vqrfhny43XTe(Kt3AXw*y7HGyvJ4wO)YLTDdqO20Ov^dM5>X3i?^u%YmPfC>NsP=Zz1|^s%$v(VPntgXon0NVhrsRlR zOiU~`H*8?h$dVf!iXylZunL=f>(@oM0k|rUZ(2IrPx2peZ;`IeYNvMupGwcuH0_AQ zLPFb{01tW(@WdE7!jYWjyZ1>PV2pZg^{z^?piXe3j2dEIsBpE(jIQi1F`D+pme>h$ z>K{KrMR{IbxC+INb4J^TZ;0?e!${M*57vXsajZjTRC*jy63XFrx5Q7V7^3bjULFqu zj@*q1aG4{LGey}g0ZD|IibMw;jT;TB?gTpo&OoALm0#iO=ttOE+W_D=#(R-XI?d0O1IHTW$>7ubBe~BUcim0WS_$4kw+GYZQnP0!r)6r_FzHL6* z>>hXRj$Dt>iplz)OKG#u=1pk};G6=0a%n7GD`gn-Y~EXWM;W)7lL!9mROY>x(`KI3 zJT&Rc_9p8@vk%+<0F+Qq<^ZNiybZaDf?6Q#-279fjGs@9^~ z-}QIT!TKDEdtScrD^1Ul)$?4(=@s3yQvP`>lS|4H^aU5$WzFCwm%DYf{--y16;dfHO7Y(P(*!(Fo zFZUH9v-?8Chy8P-HE6ib>wAb~2j3v$AH7I4{{S8OM(RjnlFM1OmQny&EQ6>g-Gg8c zojS)EbS=2-tS)*JsqOwZ(b@1w%ri#$KTPJLolT%?^4rND@C{KM;D=jQApT;s(eVdJ zOI;p$qc(Q>g}k>OY^OU_WhgSBdhO4xE4S+omeiOCdW%Yw`+ez9{$a6-GV#*vizS%+ zYd5x}B-(xCWjG>hSr?yE+LYS$ObIfH81G~7i8%iCv#pvLkbThW9jhOK>S!KH>1 zwGTUqAaVH|)~&hl)1|MK#n(@1)9&Ge+kuh!VyN%6FHCfQKzMA8rs&YwYZ{f(TiO^U zkOW2erEQytBWMfHsiLv8#gz16{Fv_)vu-DY^FIFoy)JUFfXp&E!1>Uv60ma|t9FA39KuWs_pBzzr85*|sG+u}&7YzFb?FV45hD#2VzQ z4xY$AsO`;4d=}}ejaOB>zgcCqOLW+?Lgg4UcM3rSV0%Jd#xGWXjuOMqREB2k4{1~{-V|)!5Gc-hXX%6($Ur(cWEXd z>YLUd{dA68{;Qft2CTmp_^u*lI3inl5RcSRvg;P{%8JrP8@UYN5m~u5XnhhB;&)x? z@xTTgfDFq2}5q+6*&~pWr9ft z=>g{iQ#W44q968<@lN-|Z3jTMy3v!NuIT-bFet`R`TLTn8*g{i6x1~03`bW zIr&r}?qothV_H^Q*`3CRf5LeF)zENBBRu+3GIbDW$f|}>eVSYBdDN?I)ICF^O(ENR zVwX{eIn0opF&{mwe@fH>GFe# zUvF?(d;WEbQD(ILmiONiBpE^a@m?1T$Py?%oR0NaMdBTl!y;wRu{5E2_R>5Z!M#om zRl)v~vK{uT=<93FlaH!Vg5GHj91ns2080dqw{Ou|fge*@Y)ibAW#k`U{e5dvc*oY( zn%9NhOQx>YmgdkTdH(-$HX6B!#4N=rNp!B-Mcu7qB;Qu{oRN4R;4Hl7I{l(}@l2;7aB&teW~z8M)L9f-#wmaYE)-A?G$od@Dy zN_`5i@FwEL8BXD!oi(+9N5B}#sWLow@p+cudzJR4Eq3&2x^3;_;YGYJAt&D)57!k& zO7vM4Xa1v{Pp)b*C&U`&OcCr2HgERN&VwVeu`F_1;%}+%{#E2m{6O(kB}8t+KJZh& zdUDgJ-5}ui9+cRLxw21cbFwN5v0R1th{td#9-WN~i=%9KR<=XIE}zrnxrSDkLY6mJ z(2@(RgoDSsRsmJTtUl_24t+6SLA*1P=cW1+r8Mi6#I|-ZEXu$hPF#=Ci2SPzbA;AX5{&<%>d?m{%{M3rk%}G#_j_i%8Jo?eG=L}Z_?IWLjQDl0Kh((guNE#J9~s}9sb=IULi5r{R}M-3AkAT2qGQfz#s| z`4R<3e$7(FH-Vif*9|F@3z*fn9Bf(NXan;#XDo0#sw|Rah+ls6>RK#OU6?QJ1Ep!* zJ>u5ArD--$SlL+%ctkd_>`nesmmp`|s<&QyXCBo!@vBn)Gveo4-K?Hswy!#)pH)&5 z{{YdbK+Z>QYQEULF#CUwKsm>-?^nNto(fIYoegQO#jR>OZ=XEzELLiz4#vjglbrrl zMp`K{4l;5$6}TKZr zK7F$l82T}*D?yIx!$q{Wo?|`K5h}?x(hP(QZv5)hngb?7TFH*zf|=*&?LKMD*qSLD zxK=o+J1(<3L@;3HX^NTWfgZlf#lec9Gw_2B0NH&);@Fk8gGR@i`3bJ?JafgpK~Stg{s&GJD=~CZlQlLDP#4n zmSiwI>l-TWCQb+MTXF3siO6|wKpgFIO8)eU^QJW2QGeF-n=8@l_nUa%Kb|Oj5+j+9 zG>t~i;%H=wc$p7p3;-kRnsq5=m%{5{GqBiX9D*xIUU((RxCb?$E-~lm7sP zfTj&wz^@N9OBwFGi=7tTSK^Y|^^V{7Rl&*j9MJeAPH7a_+OmKda(iU{;-j5Q)Oxj+ zx1(wLPLVy#7jqB4>SZ$xv?G!;>c<%T>AzmBwuX1w zs!n;wG|AGM9QsxKT9fr~)-5k#Ed&oaQF6@KMnxy$93R8SHPOS1gV~x=a&%t(XtLT% z)0W$|tQsY_+6Q)W&cyzrp?aQ!Ykc5K5k%za29s<*548ARus?W zlTn46Ck%Uf(@80kFNoBgD`g18QTZdd*ht6AgGO0eYdT%~uAi^!mUe+MBZ~H38{fS- zeeqOjr5I>)cHbxTOwJ)zo^UXZu!v@qX=ZI^$AgC1X&C zN{sRpWaflhY#J-&ji)3Gi}*M8yr?enmnR`kvQ z`ca^!CA4##q+t8G6s@H%mR{Yl?rX1UF~QuS2co?fxB^GvMd!U52V`eol+CCV&jpYMG2^A%+Z3_%#lbKcO#rJtn+;-n(|lA1;0^G{vX(;q0~{p?#QJa zmPRUa21g^GZ_=H*TPusEeL<2&m4dN%9q?Ch$LUC}w5=}Zn~grkbJ+RTvA6dXiS2E* zjXZ&A)EdR1?mVmM6n>ef$a?R@3k{~*tu-~<_*PP~56>f-&GJX^zO2()pN8EftTLH8 ze@>A5#}>jr@R3Znegt$};fc}Yx5iFwujh~U3~G!|96U*~IJnfTufXIr#iD|Kq!CLk ze$!oHZU^49Ei&x?0I@8Q=lhDBq4-X{k>9n4hMGr*S{F@ErBA3j-(K89BsaHSa80Nf z72pt0IXv)dH)AB@Y57&V_Ji?q^TivD0voL|JtjRYOu{9U$-U&j-Opi##wwv)FFa)W zdsd}Yqa>X$jmj}Rm0{fD-m}K$ zFv);V!f*$3$7?8rD!>TWWEJv%a#pE!nNE zV{`dn=8TcA6X02ABo4vbKcF?Af@Pa9_g-qK+70czsPWGD0Va)=6y zDkDFKG07sGgJ~y>dR34wEu?LM$G1FS(Tb5XZVo+wrD+dsqNdb(A`Lv^ILfK^_onpe z$k^xN0Q!%SdX&3OGr_|9r7P`@zk~2>_oblVuh|76+?t5mWdS;Vsmamx9lfch$O;YJm znOK!1jxZR3OUyM|8+5Dti#YaBfm4T48{%EJ96#<&jpbdiJ4hDi(?vvB*A1Pt>k6K~p2K*}O;7 zi^&`jT;E85mQ&tiJ91I_kku!v?!53ygXNC-- z_$9PyWO*cvPVE*+$stKNrJV_$0hGTNFe}YmgpC zBp=Y!hGG^$f!~UZ-@8SrTQC^-#!hNWa1P>s5ET9Buic4Q`En3_4|+ZsgR>5MQftwP zBa;LpjDBHh$y-HxMU z7#o@Hp+LU>0L)q)jS4p+M6tk#?99rDj1M^>ai8z{)=&FXbmHkAA=~P40@3RB2{9yp z*2a9d{XkP%o>!VF9b$<`+H4ubJq+bl5{*1$8XXF?m{OCqC zv83$Dha~pF=8cJn0|S~2n8{*spGpX95Iu2L`ZHOtKFJ+O`lm$dnk?+)bc@B37ygxw za8AMh0DVcV1E)xl-rME=A2oeGVz38;{wQ7eYt&L*#=d=>)M6XUV%S+1JQ4oVp5Ldf zY@U$u3rFj{K3zjYy_V+M-d`d{o)(SLKm%(LNf=|TP{Y<8LmM$;9;tSO zpI_#;G{~yHov~9-8tev@;{O0yTaY&Y027i`$81Oy$NvDFY7$uX9ml0uwv6)s078Y4 zqKa2QNkuF_O8P6|+$*5?dD5C|hl#Cpt8`??W-GY<>}wMEFVP?A=ZIQfmmnt5WEVGV z2Lco!n?GI`^R4aXiP)blR59Iw>GB^+NlLmjK`ImtNGMP&D`Tl6;;80MC=xBh;1*Iob?2~{oSm)hgG88T@4Ex%Ml4e)&QI4gIfIJ= zbjReizU=os=nY{QBt5GP`wCu{1THr+nm!xI#}XDf^`=Z-w8mxAZC8T}s{2p|k7K!x z_e}ih{jM#`elC7=67WCx8|o>vF38;7J!s^4cTAs94HUgL$mOEFgoFM#i8%U({{SkI z?SSMM97q*Op1tGa)&#~atuKxg|^=&!HpGmxrxh>=|AE?Nt=80|giNBQI zqCtcE(Wykz`a5aX{cER6jSp1n4x@$>NG0Rj3=KP5c-7XnZUxQto%-&=8;d3UKRviP zrb!VAQV#Baq~uU#w;3gY?a8Uhi=tU=_LSBw8NZ5Xx>{SKg!9s8i#hGY2amo^$_sI-~^2YPd}u+w!f7y1WJywK#i>ISfaDJ1e*D?KHD8+l_GGBIGF6Tn`1s0F7|>)K&I zbLtIJ)j-?jtK?i)EDDwJrRGxe5>b7ye6j5qPyPLqhQEtIRWwnlc5#a$fnvaS+L zwLC}Fq||&w>WT0jWYp)u_X>6bK3@$tS?QOzk@<-qA1-RH)cX6VwX569$*yhfrMj8t zbhfros?NoTT=R};ESlb}aT=uBz2im(0wlXr_N4h^dM)DDWv8iH8!%eni1;Tbij;VH z;+BejaK-Q8JS3E_t1Zi$!8wJb-Cy`8MO?SB;yy78}1R zXICCtF$9GJ6z^n~m$4Vvf`GrQ?Sqy6An>K3x4!`!~&_b61c z9B>Mr2VelE19j1!k@M@w6<~N>YNuP4;m#HqbCcU7f&O)0#uR)*jB;__wO`o6<3ql( z>YX0z%R0=m!#q*RwTzG=VYXy?F(iTY^r<+?N|9VP*xe26B<&8a$I!6N7*$9u&lROE z{66W+uv%RQPnpjf<$wqMMk$i_!OokU5|#~WSY!QOW?X$a$L(3ZDODGvKhGMHGPzQF z=82LBn+yg(JXOhi_I}bBN%u`tRkmmEz0yTrpdzE4N#KmyZjFC&X|2sMg5Blv^GSvFlg6WONZ0k)0YaDI99s><5c41t)H85zf=SzS4= zy|gO}kG)0)5RTw`RdY^V7D6-|4@*R@6!G6C!jXWpT=~ah@yNxcS$c0E`TZ;-Kz3)~zz0hdm2Vk5km`t>v4^Nm~sjGqhtpzbb7it07f6 zP)G+D-Hh{2+6<9fU#yeJ(MF2dbQvQmK>f`!g~M=r3Razmq$z{He_F6SAkBD%Xl~pe?@!i!W!74F z9#2$i4!ysg>nH41tNBr5jh4i|7U@?REo&FQ;RiI`d*Ggpat7;V1KoK406K=-_`lZn zgqbhw^$ZRL#gc>itvOnKpgN%x8@`>=B}2h6Ng_5W{z$(;;?fVe`#tHoV->~Z1o|uR zDW-3;#OhDo^|@78_m&XipHuA-2y9(+#EFhS)o#Jh&*NHo(7bNxy=GAyu;1zA90$0K zN`vwskL^R0ShUC}@Jm*|zH~#>dO#m79?Qy&29Z_!;L>uA!SBldxp(Nu0GD%4g2nr z*t2_)>HbtWCMtU}EwrE})gh~m7&49t+p9y-JEcs~!ub=6YZttBl z>XwsOB$oFIBe;Z=kOQ~^JM-)LQG{vOla;C5VtC0PixjdyE?7SgHz0R4ij`>4&G(n_FwBsbQo z{{S06UZB&k2}x}H)g!RWoc{o7t%I^1GN}aP6qG*4#(DYB?XG|uWjS1AA8Im7VLEP& z^2eO~s=mqBU`&}jjy_bX%4uVeJaUMnAApYPeGlYuNbP2LBq<;SeCfgoBW5QBeuIh@ zMWat>9yfH=zK^Hd-c5N7klM!-(>z{aX9@#0dyq)azcm)|pRE|nV>L?I1ek!t zeQ}e>6a``2cLNl3u$;4%HNe@cGZ>??ho-@y>b6S9X*X?HDq#BY>0dd#KkAFVkm`*)R4k7o$gucTvEuh?tHSkF8S{KWUDhmIao0 z?(N2KLr0eV25LiN_JHWS_`&`&3_tA68=?KhON$w4mK#Fbv$qri8zdEOeMLtsyinw%7c!6lov)l$3G!Ytz#+l4aZ?c z{{Rml^BDyE={Ph_Ns;%rmuTldl@!oi_sYKOHse zc>-K%_BWXsBo~DK#E;sY*X;{u1aZl!Xm@Z1aUN~wSw>06V}o4|Q5TCRmt7U1-YYEH zO}l5+Q*ZYF0EIM9;Z}t{Hb-%6dk-dK$K*vNweh#4W_3xg=dhKD!rj{upUrbm)?IPa zx{3b)RMzZfZP+Si2*CXt6)qsARsJjZQ)#DodDQxx8l3C*Jw92?Qbeu47~?*j>lz~k zVo1h$$F~)}d}z8^JR0kwuN;}tYN&#f`BAd%jsz7**vsC+=twA7SB_YVI68C-xB8Mz;j zqgIHCj;RVJoimZZiJLz_Ycc9~UTm-PKGn3k`@<{!7o)Y!NAGs-mXgLtbkjoRnHyC&2c%Garm>0aa@H%paAwAg>@Llakn4uaY6P) zYops$gI0{&t7y{LT*(BBvQ#)ClxP~BtJAuTzN4nz$*14j zKKO26eXkpPjyrsfNIXrAlc*X}%2|+PFZBCVV%ei%l32IPn$Z?#++K}O(4T5uXHn8) zT~9~0zr2J5mUv|_nSa_T$WnWd4k~GD_K?$^LfvUs_UAl^nIuvDjb=X$$i?athC5hi zxdNr;+&dDjpI?WHsmZ6J^=%ps-^Xs2x*=q}n%tjBt(XtZhD9p7>#Yx8u(`Ce*X$#f z<_RGUBmNM`S0o&J)^3YS*xB4l6Py#sr3L|h#ib7lGftpaiWZh;3WxCXCnq<=3pc#|Na)%#KX+DM2 zJx^rB+H05oRAdxKm7HhixY9g`DGLYLH&r0*>Ptl<(Ac}<_oE{FDs>2ys%zSKkN(n2 zc@&?Z6(Q0*R_m(((_LzD-@=3bihERJ-`^Rj6}OI^S!oxYCW)foC!qdhEJx*$pRENn z6%rw3_Ego&sh?l4by5jaZ7AG6p@mr*UxF4kx>&ROwUxdOf7Ca|3HKziIiqwxv=yeH zNz`<6rkrxiDRj^Gr+a@LdO}Zz>2IvuAH^-PFp=&U8VxD-HBlaa1#FikFRtTm+g0*E zb6KCqj*o+(dgXNJ?^f%XZCD9qc3{QWR2aU(ly8A)M zId4h}ZsQ<)>q02Idktm{5d)8%CEb?Cu01JBW6C(=G(>1rliYiIRKH9jh!i$B_3iIh zuYesfEG>Dh&ZHxuwzni;u|JK!Km}5kR^YH_!Q03O*V?|4^e=>(7MIZdJz;&M+BM`_ zbOLr%^4*-S;z?X&7zZ13*vhoFw(*B_y$2$(Zta`Ed%OodZ=fa-gZ*b1DV=uTU8w^-?_KJC=^ zr=CQrvV-#Yxu<<6#!j;`IF@^9{ImFOAXA^7Mh!5eMeqRba(JV}3lSh-x2+V}UmcTJ zJag9}8?H1hGUp%mZs3!6)9W z=80+wy27o3J}eGKX`5A>GD*NHpbU<}u7$N_64N3&+34f;uNagL`(w8TvKU9I2h;Nm0O*h1KZOX%|}G;iFTVOnP%#l zEIGi%NA(;304`Va^3FdF58d+gMg{uJ?~g_3NjCe75mD9JvCp7idXSYz{NPmJ@hinBC72D;0oCu@e$`g--f z4db=Kp#K1505EC4soVHH)RualnWnA!b0XP^6Jb1nL1T(X7Wx%ZMSpW^6f!md8Rs;G zEycu~f+JJ$5!{cJIbKT)^AeE=hxkFwdM_~|V5%@j_25;|jV+Z)x6qTQbO^N1D93PR zNfbJVz+w7vOl4aGpNHC?XAf{N#IW}61tt50hk~4X05h76>}6u!m4v>anLGhjO}?8H z=nEp}-lDw+)AyIJEY`Mi+^U=t67JhpCAEyO;bga-H}w)k!~Cl>+B7ba9!(E+qIRLd zIp?)Ize}s-*??o&NB;nNUFH~NB&z~`9!E6eZz`DnHr?&(RF;f3{U;F&9u;BkNB)oR zUAO62<6;1n27eSxRliVkQu|CugK)td`%<_yoj5J9X2}4l=jTfxg%n_59Os%VeKIxZ?0zkE z_LUnuYBtw|_E)lAe=tWheV5u>TZIZeoxRP^U>p?$`*2MX*4u%}AQA0N5%kr%-U$@| zZu^Bj$pD?&{its(hA;Ye50Arba?Ov_3VPH2)LIq6+jXVtkeq%f(PRVn%~y-1MZ0rE zr2Ek0(V^Tz#JD`*aYvg4BHXk4MD%p5JpD#{O!5A+X5;lEH2(mnc+Jtb<9c;IniDtz zNf{65MNqQz^|KxA2+8?UJHCyA>6L;iu5v&@%^q?O6wOy>)mlcNfvq)tKIKpSmDFwf zXEfymo^s|qN4)s<%x{vtA9Sar3|CUxCI=uI$k2|i(}DYsR_iE0%7b*oXY8QW_OC|D; z>ASa%U-B9KX}(4H1r}-(XA$fN9=M%oi-*4mp&M+&zQf%}SK)I2EG z;{-%tx&Hw2a&14Mr{d7*rdOYGUFhtma`s|RW8RWBoUzR-n8Q4cxtQ`>_V%f*$3$y( zZHaWrh6myxF#U}&YI=3R}ZmJ}zvv5`WVEhX6s>p+(MJ$|vS%*D3@J&73^s%5y5 zfjoNi>sOauAbyy?C4f5s1Q17YRE(q}O;ymNz39c(DoJ~rxYYvAWu{975c(t~jS z023(x06O{gb~d}NF@ucOj_O@^Rln&yOHH}d=eV_+6Xr)RA-0gfe!{bT=cykSNi-!Z zV048xdyxV66f23CkgTIP;L$d&L}1`xdS;jTV*c1PWNu#IccrkVPdp&iw95{owq0Jz zJFPzAHn(pukRT_Oa6uihj{dcxZh8x*rv;KJVmQb#PC)hN9M($dd#IslV7ehd%PiZDMwlR_i2entazu7-u zibs7bUenzNXs^;pq{q|(C{UWcl~siV2x_1r~F{50@Gu5>P{({HuCI!iliCodbpsN1nz zj1W*0kU_`iQAW{a+7tf(3YAC3tfUj&O>#>DK*xWTX+_YMas1RtSHHx$%_g|$jXrr3 zcAEp1I5Rc%y;Kn4$bIrQ^1K?WmVOnoZWZv!u5AIa4% z#%U$hskdO##Vi^0mNsARC~%?T{{To$#*u4l<+Ra{ zEmu2PcK`=-$TgYudxe(%S#ovnT?8W)`g?16h!1blF&h$yTA_(T{Z7fd&msY~+IW8fK9%IC=3o7T-fJf(B z`rqv}(UK#%OoFll~9S;Zq_#%J2Oh1_?{XLf%|Jf)RBnMmSr2LPZ1eIixdq7O1MWn#QLNKc?b1r~UAztUEsudUsQ|S!}hNcZ7_q z@}Q6Vz+#?lHLE+k3w=V$?E3jPQL+7+rxa$YpCF3_kC8vWb_v{&lx|MW}-j# zYt|5q{nJjl`9pn=*?_GHBgl#ITS^C`Z8$%j7A~P&D`P#m{{VrapuGy4?9TJ_r&7eZ zo2PEv4#ozKT>SuQXuVsjZ-(a1?$D>=6F|$4&{mp~8(B_%0)2Z?Pj70RatC}9L*rv9 z8GSBoWIK$ippWZqqxYi~QbGK;S0C&g{{U*zQ|Ov?-!sDm`5X!3SIGHiwJ=`zYtok_ zv*@~dvF_0)mVaYQ!Jwx_1$`PtZ7EJoLbW6i$FayPc_4qCUOp#uR*TY|F)pQH6wy!S zq+&L>XH1ZL2G6x;%iF^=%+13$CbY%zjTK39b~WluWJbWi2emBemT$XEPov_J-^h{M zvA|+S???2^nYFlK>cfgu)q&`LQ@IHKstt^uP3n%pxFUxJPtPKXxEmx_#xQxS1YLz{ zG5yO@3^E3L{HZR#p+T#xUT5IL1@`!W6#oFKTa8CeNl*>R!N+`4WEYCoQG>$_r!`JQ zi&ON>*{fPfV|y%4n;JGMLG-~iY@jqzzZqqzcZt0pJ-(-Ps#`owYddaevxinV$j7M7 zLTzL(Y6C6`oK-%6=>R0D+rb`&lv@lo0KxhD(qr(FM|wWpj{K3uErN;XKy@AWNoxN9 ze$$GJuO;FE&^nbp!5+P;)ziFm)=mY+n`0^U!ZdmM0N52y^s@Pv@u&xB2Q@TnMM%o+ z-5@`RRWg%IztLgA<5-a9^Fd`&ar}#%;CzD*^QbpnjW5KB43^Qsp*00gl(I1GQvscj#`F0i)LzniK((-DC85vvcO1XJ|hHT5-|k-fy~-vySJ$b0sX2QW%hucJEwzF&>&)%A#CPg zasL2+BBU{R-(73+I#fuMydNcO7cys>%X2ocq{g&DuR`TH+ zJ)7bf{i){D#m<4aD6(sBV9m~Mtt3T1m;_V(uTk{2tQK27q|>B@xLF!cElK|Xy^56( zR;+hf2Yi^!5Hmh+IsVpSnW{JU9 z`Ve`eUqh1FN0^W94$=iL1iBd%T)hd@QMbilvkuvcRd4g866hMelOH!qy-t4^h_au| zX0#Et5#?}-#B;c0(XiSU11xs-2mb)K6jWIoqdEC62mLC#Gk;8oMn76QEGgZ%U<%O< zXaU11BN+IHdQRE}l&!j33waN_L=8s@7S&lonEd5d4e2q)zc?I=y$At z_iPBq{?8-)=?nNp3ob|MMGAhxq^gK`KrlG=u833uxZrx! zuH(ZkdJv)yy3W3sl&AL;-zP(LJ*Z(Wl=7VC`4S`X`Bd32@Q)>oV1hDF%-5#V(sX2C zJ}&P_rn<*LwRtaN(zU>{M-Ylza}4+DlZ6nrul4b#oQ1^(8?nKp)x2qBju4;l0^l%BlG%J;QK{NAHeRcWO(F_w^DSFhPR5Z0QE_UDWrh0i~wGgK?v7$8F$;fDbC zrFPScJ<_A(`idgSyv^Sb1Rq*1c@il;BbCo1-mCT<1Cs82R_Ea!OnBvh%2KA)&X<_)M9js;9~jYbyV7$IG57O=;p!SZT1T+iQ0-AU}fTR#A_s88p#m(OETY&W`H__^l(wPM{dg|-K~rUQG$O;ceK^@%{d$H8nx}45y6Uf$LX47kpV`Tt^VeS7kdGo+2V~$ zAUj~6YRmSXGIgerVi`3zy>LRZT*k5-1MiIXsTG&nFI|8uPo&t~!o-~6qJQs?+KR~# zIJRg32HfD~vB?})B)3;kT{jGWSkL#Wiqq{arz$7kbW4b2eif~5Ji+=9Ij8+A$Igz_ z!OhjxqYe+=EsBBpf@rx#k;S4F_QKP2>puZC+mx}ij`~}xJ80)vRb(5a$-`sRE-UA} z&HUDE9)5MXKG_~1=sNd;QCR6(t-bZc+Rd|=;Uu=y4$MeDm+M$!W;==OGf}itD)tg{ zlh1nTj3~)G*A;^EjG7Xt!Dcz6dlV!R&7Rn!;9bWazT%1_KQMbz+ZaAS_H)e&b`-7A zeEptuqi>|^T8UGMWsccg0!IUL4E6^&;;smsIRGahaxyB$`zZ9d(L4m{=awzA>atvF zY$T5dYqr?V2+!b8TC(qYOH02Py3=hZ&;6u8=7Yy(l=!MMhusqJ^ARK-126WX(#&K6ZnAg?qGdi3jSW(_fJ_ zlNGxXL7s6eWq&S36#()>e6}Hwe_lY zXDJ+@{){pD8ho?yo1=9Ycb#O~ra6-8-OvxyHA>#;uuX1KSjN&n2<#~=JvDDE5hF&S zSGP14M#I4tcZ(fcqxBa>qQ0`!w=<=? zPZ3WxMI})CkSa@|mdX>TdX(yihbIe+liHZA)HSP<-lZCcg*Whm&}*7i;$x32I+OVt zjZJ2B_+^EN-iHLQVrwRtb~mvlyL$Rk%Vom?bI+wEw}{Nc9nD!!px#7q){@8m@)1$*vq^R9nPydgEo~kdiVejS;~ae3 z6{;=mp?nr>1J2gxw-rl^Y`Gc5G}cG><6(}&9MX|!h~sjGWA9om^s5V#i6Dvos3?n` ziqdY7`Ic7M9g3$k9764x{cVv!AOJItDCU3!!3Py^-FRiBPBRp8+vonpxF_goB)$^G zjKg;_jDOYuf3-xPM6DG#wNcyjptKn~c7uwtE_^GzfR8HSCI0|-a}c zPD0EIpkti#>GbxbI<}1SK|b_fFSrBya z*taGq8X|r~slXJ-bol3CxBy3QdNSWjjs_(`0l6TWWjQ1V8zy$2Y8%K2O z*7=D40K&`ubnk2Srs-mK-D!HQvk%2G#*)YT5NfB_w0Lje^5qy_a7TJap=fd0#xOF! zgy+2ncN7*qfB36G#DhU+pBm5Su*VfvGnSO<>udOcB@t7_WLHinC2A)VP z7c2hAIIK}0MWJKImY^Mt7r>ge_r(JPJ*~+d1#@q2BccwZvqU zM^*J;3D45BMzzz{y+Nlu7k2hH7TiE)n%X5Uf5bw8$@d?q+DINnB+~r4WziWQ<~qB5XL4I~;;&5*(kOy$Iyv^R6f-KBkw7MXlPP2a|wLZ%VX& z&WyIcCtJv*g=-6t!1{awt5$%7_=gzpQVxsP?z(GPg8IT$hEW?PWQ;nMBLrals>r(R zMK4Ckn^BCWJi>qu4t`aLe$-lZw@Y}Ta%_vr+Qb7@xbpx4H<5_gm^_RoNj|kaU$h3G z`mM&FePeHRY^ZX}BShTsfLDQ3{{W3$a|d4C>89G!OChGkCAae=G8q)MN5pyKpVo|| zpF+KMKrAi{v&e<9k(w36p%`vqkF6lF)9xDR1YeOkpx?qHnm|d)oEoT)XnoOLF0Mpo zWQ;HMHx)4IE4y1BmrD&USng-IkbUA%L2ZC`QS&|iS*orwiU=&!w$A5dgKuwK4&sbo zq1Mqf(RG{MA%fXTUNk?<7$sypWc;dKA79TLd#15L?1aaDIo>C*U>t^=<1ZH||0jhB}GeeaKG zqF&#yt%>1RPjv4{XdlCRa%pa@q<=bVxk)lyNsMnN(~bg;1uBhChbTaKF6{0Zp#V@FOfR zMsewmXvB$508^iS)p<$bPKR=*%7NkM{;jFLPX?eL^cQZ5dBY6Ss1nL|$inaD7QK)FQwr%ClXF6xO*m3&Pd5J?hGf#ye)T(QFv7 zJEmyRFBuzmF+ZTHP24LIa&zfdpNL zoF*~)&_dwnu=Esswyw6&%)|LkNK^9^#e78LY4}A?{1@u0E{pLqr!}2NN{3t1t**hI z!dS$DRceC2QVudZ5PMcm z=}!}FdS1dq4ZKe?EaprO~~t zVV>sUr%h5@*gvKS)-n`*S0vMcz&l%xdp8ELeX>h#%<)`J44KC0)@wey3Dmf-j4U%i#nbI%Rn~gTw ze?z_zpW2!3d^FH5Kp(^WlkXF<06nq)06Je`)S7;wgKMf;-R|dXR|rV_vzl;Lm5$*A z&GSgfAGI!ork=_-dP{;jjlg_e|luP@Lu*4{EcSbZ*MvS8T~;bt+bIP z{6wi8!5Aa!UT_p~j2^_)s~Nf}Df}nu2m#v-waE1HXBqv#rYpXT*R=3nZ6ffm_=J1M z{#@3E5i6X5k?Y22Vm6FqF#|t{9DbC%1IWxWsfiDp6p*)UNgFTs6p%f&ByF&s!;I8Y+VVo-NhLw!ij&((G>|CXNX8Ey{8LMC3hzY^ZKO{vq-V{2=erMo z_;FGFU|YvLkxLtStHE!2pX*o9=_xcxkA<2w+I@+t!&JQc#Oz#uF!Q>(@lGSX2;{gJ z^5Xz6YysYa9HV89eT5RoVcdAnpra7)aA~$GqSEk>#0b1Sxxb!U2ftgWk}M>fN`-9a zwhn%EaajGMI&t=`-IlFjq-Q2EDvy`Kf6Ay1j<;Kgr7R8s#YtnbSCE4iRXYsQw#$<* z>kk|HKJ#z>{#!BI{c0ybe!Lu1!%FJyBU9V=EqhJ7X6zE}Gx`!MCc~pcKbS&o$?Ryu z()PoH8kT=uzw@g3S7BQ=d@@TapD2lydzi4}^%)iAy>L%;BhZS*kZE^%YX`8tp45)Q z8Cicm4N0x~*RM3ij9PU~^oT(IUC!AQAE6x6si5>~*zSuFxNbe^N1CL55=W>NnjrD7 zu55~#MxCe(@@2N#N%r_L#XQ@6rS%93{r><#hj=(CYUGd0BQ(lLi6Z@YgAA+S4%njQ zw2JaQv)jdTxy~hxU;B!yY(CPxFLubcx<0RFNFN+KB~kn2RD#3D9}nkdjkU?G2+;M=WFbC~TSNimtDyUzQt2}> z97b-H8}wo`PLUYrJ7aX5p59b}v-H8{mqb)SU&3uMi1Ov05$Uw={`B8>;SAeY#i?x` zf#S_t3l!?1UI}B{+!Z+#aSF+t7GHXf79O-x8oz~_*edpd8Nz@t8(}`?kjdfKQX+{? zknVtYR|ozEud^#fg(&+tjP8gQL;W5cRQ*rs?n_E@4 zSpq!hu6V;R2lTB(^ZA>%22p{|ct4gY9nO(ucA!aVZz7*rAwqw(E61WKS(@f$nLP;f zB7taO$s=$%_3c;f?}i;SeH$Zb&_r9i#u*9y4KqpL9)Tz(D~&?ghXc#F3_tS?a1PvWbo^(tob@+wb~v()vlL6kT^8gb))Orcp~ek zwHUxZjbif$>ZH)+>VVz!B>S-1LH#Kk+q@;XJ4a;#luN0lpBE8LY<)$}kxp`{ytsQgW=SEmETvq0J+g8~J+t14veEST zaSBBdjfa^GDa2&wwgKX!O#wX+9~QLRnED4|K)4(TQUX7%l!DjThIee#@`oo)i<;&m!e{LO63 zoh$B;2_`I$a87)f%WU>I8K$G7Sl-+@d4<%G0!&gvw;1&;>-41Iu_?&K7PcCVr0mAl zV~)f`#ZEim&@Qco+1^o=k0;^cw%O@@KJfWcKqrnTH*x^Gl78SUei zNhSEAhGrW^J5;LdoLP}H{XRM73I_ArwNLtcqqNQq)vR|;IWfO%e8pKZ{g!mdZ`j-Q z4ED-SF>;9Up!VEw#DT^s_eJm?{{Tq@+-kPBQLqmin2b^t^x%{JRG(|o3w(MZ+J1@A zP+lOo@bgN)k8i|9#PJ;dPDNOKJ*#+IrUeJW+Z#p)mqiyR=fj?9rcVxaJ2|C?22!|T zD#psVK7^6UrpD>}>vm!HS;~hhT%o}uzCK?*)XlUqm9C4wMDZKLcxDkmG|d)5J{5g6 zVIX|SQYv?*Yx*VfDYDfpCsypSPNVb36_h`RPj4}rSREg+Vx$l#tNZA5=8fjJk&K6K z0h1@^HypPmTvBIYV2j`DU#oAX?YH*GEea+RE!f>fOsAK8C zI5jKj?-sh=-Z;|ZTaw||@g&itfctVrYQ>Tu*{Ng_#_;)3hf?1eZU`UeNOG3cViar(U+N1* zXDi5DbI%oFb&p2sIv0c81+LygBed2hx@&hQ`HzFaBm6iAA6l;R&lG`j2}b9?rCa_o z_>Ma3Lg*bSb_)#yM26lt(}1&;0#^NiA5%&ctrYqV>{RhjI!%i?+=Jl*IihTA5!|*3 zz%876R>AP^?2Dq!)7pLi099)D>v44oTn#%+m10GtBxg%-3 zmg(iVZ~M$n2hamYP2i@U17sZPP-|@wFDI;0uDeXhVYZ|0i1Ek zt1|P!JIH18E${8;$i@gNX_D*1E~2((BEhZ@cQG(OwJ#Qfq7rHNwE0EFbZrD6fX`s^m8=Fjt)B=Fu=8tPubX7d0AnlZIb7feJ=`u2{=Yg|Z>#HiL@I4HOSoNq5@rAo)|MzE2gLUGVZi*EMLb#k zq53j-gUxe!X07;s@oq^!nwq0!vW=lCMt2TIDmihXi0^FzMY<^X{9V0I?}1OvrEE$y zu9@P0O6wbb>C_f3&DkWFM#u7QY5p6?uA?suvCO@Jj#Xj%8phJ}^}O;d@0yW5uk@$)PrLr zNpM^P^f{+^d~ND`QW>YWyIkO#yKqk*F^Zor=&nDE(Nf^Ad^e#!^_6^Au^MNHy8J4* zMz|7z{`!U|^(LlPA84DikG<(O?g7X0U6Vgf2&i9(eM<*fYv)yh32jV}#}tVxhdEJ< zqNkW{R@1L2$&ja1ME- zva9U^ej0NLZ7 z4L?X!_EKGQV>ONR`;>Wi63WZ5vPL8zn~{IXtw) z`^MvehEPH0)BNfqHT*Xb9ilVzaam-Ym%X8mIEL&uI5p6R%wjmD@@bMtcOspq+LhXA zEX|gI_hbRZBm5#(O1df%mJ$*`ZT`G^RGK`hWP%Aj>QUjBL2260Mp`@1ac`&wb+{@+ zDIvZSfjs{8ZOCjtF5C?8){_Dc7r?ln> z>~E9~@k~(uj6cqs-=cb&*9PN2x&Huq3`jp}PC6M<-H5hCjsb2DJW`;56&TKY8bq2c z$Y3V4xwSEqkvcFUl>xLe#~@~3LUTxh+GsW}jfw>;wDQN+iJwkKy&nL{$25FVPN<}= z;f(WKPc}r$kHx?$eJIO8Rb7D^L}keG!6fiVq}QD}3%c>!@onOr^xfsy$k_+5rNAIk zJM)rFCa9Vrw;eSB0gPy*9xyOPCR=;mK0x|?^zgAeOGM;j_o&veDuxr}aLg76AVMq?ouLP}$8oTX^&09+x2VHCVMV>Tc}O zfgdaZiWAzxS;#`8vH8#rma<2cP;faOl*zO;6CD@rGpMW%HC+HGbslgdB&u~}s3k1R#g0m;J#^dBnp zeIW|~!9YI0rukGC{{Ru^k7{p{yB5DqkzkgZnuoHvg6tl~-ei3KhLnp3kB3%`f&QRD ztYrNhko;EHGutue{awm`V@BA?)jB++>77riLF}(|%%k#bkJ^vOmtbilW$j+VOrGBf z?LlZeg5;l_Wt%@1{7BPWB5P32RCl?zM-BDjoveP+ePeGaT}P*MeMFA$2blpsJPs-& z66oq$dlP}?+U_5!)cXF3Ots!vCqj>g=Y^1GpMF86o8FY^?OQ*2(e(M4{x34sGEdh4 z{`AMC__5JC*(+z&8hLa5GqXa&{{S8ZI@{k_YLgYR)NO90QTT1{6_4l*29xM&8)fio zq%JoE(W0~s+*-=%kDm=qmwp52QZM?hqpR7T+)k2#^bEh}Qt=hsPH`NkA0tDGR&kJV zgOfvt@Ea@HdKsrwvNdaUZ5x9v+QDlx zW6PACti!MzbC7?%E4C2rxMkCpRUo5H9E~A^BMPQKd-K>+3t3!AavI)S^K_+lLtyGg zbIx)(_4e&uvSV^}CtGW$`g7_0U;=(WbDdKxbL|`AH~TW z4D(B!nQrZDwK$gI_6^Gqno90KGl3ePi2nf2oeJG_MZ9>keLtk`VVYEHgqj%ECYOAJ z^tY0&ThkYPaK-izBu&*&(JqkZDeg;=IYpu(RpQdG0L#x1GgCVtnn%M$-w8( zcB&e76xcyui+8OXZ-$UyawvyjPDsHNZK)n%IK?BNr?BP$PCa(eK?eX1am{u|A(Z#| z(M-pmokiA(d!fP;n_{Jj{OW(;VVQcq>D699ntX+dU~J1M41d|~G2b;@z(Rq~KGkIS z9eS3%TP`mlvum4To2J1MC}4Kr_c;}8G+0~^YS&WgqCdM{i*X4^uN!JYefS3@zuG>W zQB)Hqal5Bvjo(aL{jyV)PfuTLsg8k}KZK&O$iMGpV=nQOs zFg09avS-+nZlL2}i>6HUq0D=Le45SPiRQ5LfFXuim;=Z@stNV>qY!M`j_xKv0?8owT=oMwJbiF!TDP&4 z6-DoZ^XQ&TI#tA)n#tX+kCgF|^9K#vfN@O8;lEk^^4Vk4QRKOOs{%Ta0_TR5=Lw&G zO1uoSYB#dMHPk}kF&VIp!F3qUaH6Oq5uSL1K z)F!=!Ztop{`^1m5D<1y<3V;W1Uuvzvu9$48bndIxG?IeXTEDj{4oX}x2Oao7@Tp69 z?bccyvX#_VP(|d6xK+0Pn5R3h3T-X4`J-EPxwx0$jUM9;r|3QDgQfg4y|?NMsI}-k zt4QO-7Vx-}%yYor+2ae7`c;rp_QbZVg8iU8Ow_zc(z(m zTnrkCPwx1>vru*`#y8a)2> zTx7a5Md-ddcHduyF*WX~G=Q*OsJZp_6=~R{){v{*T`?H|U=y0mdQaLq^4Ju((v~+2 z2IwRscfSNxfunt+bOM0it>vTR0lcm1e=u??%U`3~qWXoG%L8!@-z3t=WCRnCa698a z=T(-I;e+^v|d{smA*cqdnbpzN2Qjn#y#?bLEl;=}pUS zS0R+==f*2a`GEXP0mosHNv?F;EBuMA;*fVB#wmFI0XOW$XnH0}IgxYMb#wnzXpK*~v$5b1#ns^GgEBJ>zaa<4$yl@A#S@+%$T@08n zVPL(3f(M(9>{6oLijK0E7-RO-ygX%DjF}!p6)%0a#j`5G) z9B?qi3MMu9xHK!bA9!!6=DP^o)B?Yv$Us)Z073Wkr+qmDGbjy_--AuDNAZk~4LMsO zwL8#;L%~B<)vXfK(Kol%dOa;8x7Y0~&Bh5bT-gZ&44iyeCyG5fKf@lO3dyJR>c+aOMny)R%QRSc~fr2tIn#(Dux@FN;i!c8G)$5@(Brcsh z1IGUV)nhB7_x}K8sDbuo=w)(0gLjM2|m=Et&q&70f%Pca8k~^(rp&j(Fr0nV#6o#9Gsp{&(fU+ zh{&IVf$5HFu(t7ks$kk>md^YS{{Rzi6#l7??N3p7_Lg9O6VXu+_j^fOAEBmli(3a4 zO&d#+Hyco&T=B&l1R0ZQMGf;5!KQfU(%Ok3q0}vVWu745kCqN;{@1NKV^wX?Yc_~| zrc)aa)PJ2Dix!2;Yv@-hdxq?PDoJ(H8b+W2xYF#V!SCcKC-WTs^zCCEwxgdS?%wT4 z!1AY7&**7%8X{TzL0la3yEqjo60HzB&j~aev6Qwphdu4wulLO`>OKP6&AIJ0YwLIR zDvm#JD&~saWdtbBIVT(ssh|{%Hy!)EuxdCafpkz;9t&&GDf_;uZ0bJ`n+pPe@SIa@ zz8UpZxaQIe(~SQBA@-B`H~ecxk~j+&JpE{iL$d(U=Zu~+nx*4GQZu*u57hSLlcUWn zB|{CM7YEw_{{U)E+D4?TR$Vgk795i#44{5yw8Sk6d`zKRzCgw)!apKp=i(m4vy=JM z_`e2HqbR++xMTqD2a$}?Fv~1khDjO6BNeP>&@}s_@!8w9d;9=XP2YxnJ9j4Irbe!N zvXUr#B>8`aZH+|8eL=55X|;;3?03kk^5elhB2oOA?k!KKTrj5Fj|2=vn|t+fjyI+V z{V8541Da(cEOEsv2HFWY;=FC~gyn(Y5ms)c;I6cTd`kt(XS%-AkItjF{v2!Cc_iug z5)R34RgY_@Zu9)>b8MMB$HhhUuJ4aEkS zbR&|%5s2>Cr2bFyG3D?$CYRnjv`irYl5h@36h*k1Wy3HdZVAV8Qs@_52qe?O+!biT z=bWt~zR}=d_&{47&!s;qyxDikGW;ZC(wlXQqYFbFy~3=ApDrZ~SbcpdRS_rK8DFI# zzP8-Cj!*W+Fn*NPKSwpG#8VU?WxS$SC**(UQu}x=8V@$$119VQL%<(Doe3<8lI&O} zctic^kl+51jUH~Nuz{Y-T-0pb5;lvc#y*FNk!k)Wc!{N3hCM|!)L>)Fx5Oj&K?hg_s9=EI}hvFFWuav1$UIImMwmZCQ* z1_z+WYV|F#trtzqmp7Va*POQVTZmfVd2s9@LXvjpBpePgOxj+v6Ij|@N2%&iX{JBr zLn3*3-Thw>+(#eWaZkj|P+P};4d$XB9$nPL+-xnJupAIG$v)I5bye2ed=~S|JW3!| zSPW38L&*4mC)bcM&wA@LWW5}dQo8>DR1(_9G=5$ZX<`NAQ|vj%(t|Fcb!|Jvr3hy% zyJhoRYN0>WK*>Iw3T?N%)Ih_*6y8(q^P+JfQ=Bm>MpxgxDY3V?k5ITRXeC<&{&PMR zB@PKy$?V&6-;YWZ3$hX7;!PJp;#gy5lJY&W+m&Tv$(13ZE=+ciYW*vTM++Z9#2q5lBvPVcxL*{@q1%0ccu z=nsxD`_Z<{zGrNoomcEMgCqrj>^&=nJ)mTBLOeb(f!@4uR4^yz4LV_8r&Qo%41DUs z@OI|<&tJK@)1roHql4n}+#;wf068G@pKfZr?VNI^tbYX~Q>|)q%O9B(R-uew{x)X- zewdztZ8(nU``R@81Jmm4s#gTDhK;_e5} zij8#TmW!cj?*w{#S|OGH0G4HDjh&9{9mM^3z^54X7_6-tNfY@JOk*3+9D$C1-Q;(x zQ=}~p<(PY-g|42AWtdpS0Y9{gi+jMJPgnd z)UuWdB#q&a6?H!kucykH)(K>m^7$`pRwqYE5e^-QAnf1}2W;mQn$a!pE+m%T_Qz3Z zvA$5M=!e)gP7nMjS_klReNqP#?ve{q6=PVCvEB&u#!nda;<*%&T)a@+ZN7p=Q*irs zjf>7O4s(Hw(`eM9k6wb@Y5IlGxM34r!?eW-J%eQD^u;W`yPDY&)(E0E@0`mvQZe-- zKHaFWv%NoY73>o<*6``|-Hh|{jG zVqkvnY>?_x5l@CA4-D!ItI-{{WaX=vT1Ey>Lq+%^a3CvrHoRC5H;0Q9ss4a-;tM zwGqBqo>^Jt3gcqPejJ`bB8{R~=-am127>)$lGf#4X~ad@ld(bUeq)+6#4at#Sz0A? zx!0ZR@;^EuZ!au$XPxf6=oK)4;zlfZ4Y+)=G3iF?H^wQZ7S>QSzF6E0nBAZ1Ba9!d z05x3-A(^1LEhtH&Xz;AhhtJH8*zcc}H%M)y)`SDhlIH{YzG(8w_xMkKJd<167WPQ&PZN8YMZ)+8bBN2 z&mP>>ZL&C~Hb)sP_)ckj3FP6_m2t=;(!9zMR|MnUms!~f$jQqd+3iZM$fHF60K1f$C4oHBZ`f^T`^;0*Pj9 zl12c>)YF5-HiI#aOQQ=Y3Pe)-j(-X7inEGiBw2EJV{IeEpLjO2&5)}zES0!>IJdx7ybCT8++e=G@G7DD=Yi{OZQ=mTQau z06I&pLJ94qU9s7H;LYUo$zVhIOGd80{|!&ep!AW5QKcJb8U(wr z$^yn0G6wf-pI@QH70D5@Nu~Xx;d_?1yV4|%QOPjPza!rV80}K+H^&~9x(F^WCb5v5 z6`tL(+x$Z{LtXe|ai-ohRvMkXz-Yk+@EB$Hz+Ok^U4DwyG^d2$B1Wy2k)n`3+-KY0 zik$xdfO1~VKc@AThpvFOTD6taAL&Vgzvysj#@g06i%6L}ySDAX{VNt~S8-UftkE-h zrxBBe$OqS)gZWTfsr7vpXa=8ob7}~{SY#k6_Z-kuPqK4O8&z#cxZamDVDe)m75v33 zAip5+eSNDQTKLoA29t2M^J=ra3xk`8<7Z*=C2D`u{{U#+U*nSdOR>9(EN+yu#Ox0P zj^EmuPAr#w8Xh=toE^k>#SBNd;f4>+sjWNhL!sQ;B=_1~^_*mtK2a0kgO5X;RKHH~ zm!!27QZ;dIU$WfB(UJaC)`li*sDp+i`zACNrxRya1qL}17V6Y$OSDe;y z$m-0XY~>HFLp)m3{O=ArgE=i6D=$2L7gPRJscyk1qa$7e<~OJIq}EIY5ihZ7`oA}2cR&IFn*%B*>9GOP}&dx zLC5zM<%r~;O6A*2ra2dO^1u{i`KVVPsG!5CTiq!!xPN_zKiaA2yR*!JM*yFl6LD^{ zLQ+Hwr_z-fV`TUnCpgEg7v?Eu9q~oe-HXsnHgQD|L`(oU#V5Pd#ma0f%B1sygH8*| zj2wI5&~i&)jDbsOdj*Ws=*AU6X(QT|Zt$@}N6!bEb&snx-kG+NYi&~aZD4ja%Mioc zoYBOB!;jL6of2k=WgF9XwM8dj{{W&zAKG`RWSDt2mfD4^QKF7!$<-V0Sh3$V&5{3jfd`qM_C)9%ule8%$-WDH~< zm*-E-r?PcMfz$rb-6?S&ohx40DvyZI5R(V~?oCQ`?-n{^SBVTAMW--+$t=E8evAcV ztustw9$6qL`NPEd!1_^AXi?8}3@W8hJ3;Jeer=6L*oNjEM{C>71;k`<(8{h4=xJO) zM8o-JHva%<5m=_rM!m9Fp5EqIC3eFwY!&?KL8t27W1}2H)R)YF@P=K${XrFC%8A7r z5*v}_^20gD27cCI?CZig6QEB>!-D9fR zU2)ngl|SB}E$?SRnIU3>yC~d0QBJ14iMj=GqeC=`?zwU54sFPu!dXFodiU8~?mmjKxf_0WuV5)e=8UZvqL!19S2w$pB6)7IkF z&QYhywT#avn$M5Lf^c)k85r;0gC3i6sA@0w&06bC)5{4~-Xs%A?eRZ5gB)>%#T#pF zExELNmb4=+tz}bWySr>g3L)IiZPiPf`kVHk7NFItWQF; zK_;tY%XY(0gg2gTp;eH!4$`Vg_4n^Y^)9QbPRl%z&2?~`n4_2=BLI9$>T%n#7^5zy zUY{tJi5K5W5|+@P<~P$M1s%P8IHsAdilE;qNkKc2(0~BWFxlkiIj9ODo-Ex*bJDhv zL2U8cTuhTRlf>}Nl`Vi!<#EsA2PUbBjzb((wc@q(_nkjz(qqU;2O=^`@O!!JDx#g& z9|_3My;kjPe?mrX2?HciwxD^qCj^QvMqezPe!N$02{IA~Va8}L(r8rlb&(U zu%Slb(=GUidJLp0^V{V@+he*^k>Q2}9uL;6UkIVNYrRT)bXh!@5V&AS#{6~_TjM!$ z!)l&eJ-)Rv@XGoteNy9e=Ps#%69pu0&o9mZ@7#NO)u{|l}jdb`et_-tA#aX2+A!5V&m~+p3k7M44 zdn}KrBx!Rem4-sjKpc7< z7Wi0+IA&KlAY+c>wMrl@KHBQR5*3}LQo9ra19$aef69?XwmD~sWVwbZPS;y$2$D<_ z-1o;nrxfKKubS?p$`GfRlLS6kKHIU$qGZw`)$9(NJSlJ`#Ej!3ZquA(bDZOfl*Ug& z8{IuWhrBNhvKW+>w2i+4o-)J$82p7NN$sA(7}C`vfePh?nDS!_kBE`qusEmtONO$M zZQ^-jIoe(o7(YM(;QQvAX4G!lCW_%Ktt7)g+^yzP#X;H`$8bm@g$kVsuD7>iaEsd)zMZFjgbM1;z719RCx1A+u+EE;XV>07Buk`wJ>p*QwPJ-GMZ7$tqGGyE& zg_<_V{6lsC{Hg2Bx@l~fL`}`aZ6Ze!d8_5{1MffDh~14b&uwy%JXWn3a$o&mjO|gD zA#=y)Ng7F`EYfK(UE8dJSWL2=jB~@V@5i+|+F$9mPjfx z=SzO)e>S2ew`g4l{UnO#->_U#J#N!dyCPX77KSslLM9pBo zC5ji>gpJNOeqGHAQ_>euSpNW;Q{fp4_(#^AXMn{tQW)ZzeSrdbXEA^|%VY5$l@^xs zNP^mHxeKm#$&jo8ImgcwL9(my8^UY8s=8Zz#gKF z)t&6Z=MLUu5Wg|UAXcl2!Z@Q5%a&~8%xo4Xzcimxu(iIohA3f6gXR!p^NIu@5=-Nd zFb^K|gHvW!KWCjx>NfC8tJ%h6S7AED?ztG_1Ch9%{{Siw`#yCFT$M|!MHu)@fs_;J z$j&lrPih)XxVH$h2qwbeL-T>$D|;G2Zf>VXYo%)hPx?5(4%i)-o@!7E0^7iDqztjk zs#w6PFnqRVbDsEI4AbU~;1#591?HzURUBf#F6SwdY~&nvPv@h!<^Pi>%MAD8Xkr5bNY z*mUiSNoQwm0-Py{BEcB!!yM%PwIUjAgefh>!A$MKft-`+M#pNi!i=)2Fks4y@nHI6 z-h&E5ZN-bhACu%DnoR8=Ztgvgtv1JHc>>$pd6CTtlNS@pf0-KRkby=B8T!-gx@?!z zN^cpAZ;)Gd4o_k++J|c#R#K!kyQH>M{5|&j=hTxxX2$i><(}OnZARkS+6D69FyXSG z{2(bK^Yy0-i<#cht=CkaafxGu#Gv_jIml9Q2|fN)qUBm!i&$nz;6Mph><7(#rRY@LWL^xx+g?)}himZlLaq zr&_$A;LRfc05t}Cdja#P-m~FdmZ9YdIJ+;u* zpUmFgR8Y$53mkiKkAI~RZDDhuLoK`5jY==P04Bb16Fcs~bW!mR#FBVCRZV^jm8vS6 ztsdzInvlrwC;*tjDx~D?{kzegbhgd5c;4OAoX0o9-!2a|cWLYVI^IKP5Vev*S>Yrw zEPoN*{aN5(aZNXmquxV2dYVGA#Gm}cj22lrBx56=nE7!M({>?(m88Wc({{XG+KreA;c^>RC+*>OgeODDJwEIpy zw)3fIQOOt>CeC(NC*-Uce)UaTX?mjD$t0FH5a5*}ROXRM7nvWH*(W&!cc)TlhLp4W zM)bV#p}Je`Em&lkBl7_Hd>N%3LE=wJ^+!l+_Lh3>oYGHWGDi!!N0GLYqiX@qK&-a+ zKX`$3LAn z>blI!D-j+*<0SHabjUiy!8|J@V3R7T=L41kolQQB)U30`(ep?gWb>L>PYdyUC)%0> zrDt%=xDAdyMt|lh!YM<>0d1+DTDd=Bw7m+{{7AqWbhEuOAB6{+y|O#gEKCpKVn9BW zru)0^NWanUBO7z@VgCSdO=`P*LWNm_Hgl3I(_4#( z*>Hf7!S7Yi8mmF<$o~Mx9^Z?IB!GL!gl3i6YZmv;f+-ciBPC98^{pc|iE$^vG*Dc` zr#NI7{PRs(hlct-sD?@OOBW>PF~TEn)Dcz2G8NJ(N4@i}9N-+BmK2)d#LmNE80_Hj zR~-HT^!3t)f%P3Z&v6aOU=PsoOqU)4-dnpZk5Dwr=$E#GAF2`ks?`_l9Ey$FP-H^I ziEd;g(wl6Y+unImt2_@TRDqBi>;C{6wXZxG>Z^0UJ6k)_zOhZTk^caCqguCzy+dfb zu5@eolpN*--nj?eX*leOq`<=gF{zLNfynvM(MF6o_v9J^Otz7#T^E6f{4*g&{lyN- z-UtgAqzuv=<9IYu9Z4}jw~3=9uf^%|pnc6Y;goa1JA2Z&&?<}^;*H2FlZ;a&M%cx7 zpxa#FI)Zz4^r9D~pp0yUY>bSub_e#S_KiU&a-YtOKtHGAJn zcdARMfOz}DhR4w3KfOw;4m^DUwj|hqnA2dH$ej+aHqTTT$4_T zwlPnMco_ZaCdp-;rv0m|SjLyy74&jB$MR)I+w;N2N;JQ;mr3db$0gP6jDX`8c5JGC zV2#y79WD*Uj3c%(1rs)l6zP(s4stl{^rq&?N$k{`SBm{Ltub3Idrh7|a8S+_htwQn z^QZBvo0Y-{-ALfZ;eq`t63@~qE`+g2VaohP23e229J($401pPMcW%J&(7%>c{zjQ) ze#CLUjj8wPAyBNFJ%R5=!K;GUb=(NF`Cm1&GIV49@NV&#Ny3rx3HDSCqC2_yiiVSHd=kCrMFnk?@WTnm;0p5 z2>hIXYLaQcX?~Z~WK_I{{{TyJI5S2H=jx~Ys?U@9GL3d#-f%pG$oIv1s<`}Y=~)mI z)~yQsq$B*R)Oo+rIE=T`Nja8m3kM;5yGLw0DCA^z7(KqUk~_w9l_b+I(HLzlJ;1^z zs7;)c-`5q*Q_r)uy@tZ&F!A|{r4N^nLc=7L`cjJ*x@AE=o3?9&Q1>?zmu!LG0YJuo z52zJ&SPx5oED&5t6zcJac1I+PSiqoQZ_n16l3J^QcnqXxD$9YN(x2DCh!*xSKBcJ12H%b$ z1aP|KXYn?8{c6M?bJeV7j`11@90yB@A^||h1b>jnwK!Sm-*~mLg3kUJ5-qVf-OrYD zh9SQn)4#Ph6a?>NC#U=#&@@+$;9T5Y%AXhh^O`vu8SFOvBn~|)OJuNV3wiexh{9$6 z0A48x3$XGRfB?n@DD7gx7?`G}ZLT9p0$a)k2aYLzpJ}pFXtsB$Ya#w* zlS?1tBjE_DF|!!%b3>rIVtpf1xDY+vm9(Kl6+tKr9kanuGm-C-Fae;y@h8553w0J| zMK3Y7hbS@XKSNIT7STg=!%vIKk`h&dk&VZW*Z^^wcZ$vnNR|HQ9mH_N%vG3#S0nn5 z*PI%ijb6z4f4$17=iA)C7-TCkR$=ME?tMirxVpNw)eJW}axcKFEtWP42eBhK2kTtY z>?VfF7Md?FxRNrVPI);1agW}VK96r~U8A^?&g8g~IIWaCgFn@^iO=>KsZ1KN4ElxD zmF2=%*e0NbRpXv1cBFpj%D@wY{Y#qlz4iP>RczV=G7mYSWeA+cmOEjVcdtqrbVq`BN^X)R04XV4mrbe(~f(70T~<0bl_NF|#M0X{;4{ zV~_Kt)AdVxd!eYTh#M^`!XwWg3Gct;KPodw>06GU(E43C+ZJaM(w0F3F~60wp7i7AKSR2jxn%y+2HCF)l^z^pb)?wYTyTPJ6o% zmd~aIM(B)gyVLF(2a?v>5-u5}S*2xGlb^(K#~ra=iq`ySuWrWUe9eI^w8JrvkUp98 zsS0S*`BL4B$Q9!m2}vG_XfK`FSohb#?wnnxiaF7(vMyBew$->vyNTky_37 zl>3Q^M0R5g$lklZ!aJN%vO@0xD`sX`4qaniz%O!f+yjpFENb>6NJ7G79!H!D$0I1i zvg09u_4E`@mveEaW6gN)gprg;6}LQG{vt=NJt;+v&5o$I8|K@06Avv03k>mqN9lo1 znmxUNxx0qy&6i{=Ih@0Y%jAL!59-hPd(#8h%$ioJhCv0qZ4&ppmTYV%zrr|fJw+L( z*+~kgm;|sx4#kx6Uk4y(-zUF%Gf~!VH0G95WjyH<2+4(al|rQCAUVL}^T)jX%8Buq}KN_-NPAWAymX$7{KJ8e)OJOSS}FV zNV3LRN+wm82h@Y>`A{zPJIhTb38aQaxe6b74I>|*9mOnzOkH9a<-59JeDN1&Lcp)l z3BWWMJ&A2}=o?MkhB0p*S&L2#hEIGSh>mEh*e!JZLUffQfp(;M7%wSdpTs{9#(4Ch zf1-95ci(x!$uv>yUok@zT>Ja_eFYnI&|6s?wD-*(10-q-DD1e;BnB;P9R$8PQvcmD$Nn<23t4t@9I5B{8xc>l2$Q`mVPFC7Qh1Jrm zkz3BtpEJmnHy|h1wh8&ybqm&?S6f*oRKlMw-XM1{$2^RTb5pTugplde-wBl+t{zDX zBgc{m#~k|i$2ILcrkhT;5zOwJP&*@$@V8eE0Q{)c1ATzhn%dgc9!=h8EHJU|A0mCfI!$$``BpY^ zTiZLX-{&&Nl7O5Mk6t+x^?ILt(uKxt<-V0fXtA6s#Gq{?9_5JUiCC;)wYRx}-J1Y0 zkOeBJqMrgRL;Z-jM6CH32!GcS+tUD-pD{CFR#%1(AX}- z;pL85RGF?78{w9B-yrqDC%+W3DW{Uu5DOHLjqk(YoUi3b<<>0iC9;57{l%G?U8F`C z0Psf#a}k~>)xEfhAQswd8>@oJJhDa=QAr;Xw(gV;LhE>~V@^vVYi6Kx;ci4*{ z#_vS~<@NmPJp$6B&_;aWwj~k7!T$i5G07AMg(Z!j$SEqG^I+#AB!lQX@k^fA{pdNF zP0B`FX~x2edCBdO=|;nGE%lWD0Lz3VN(#F+HyrwV;--gBv8`p(K}jIX$sBHRx1Hmh z57LkrZ57&C;1XOkL=-9j1JE321ar*`Ro5-__gRcBI0#SkG8M=igvWF8??uZW-0CEU(Tz`~Gxgwv>^fOQv`gox@HEIpcsm0p~nbZ4%gqsI6_}xt96ojk6b;>QRpeCxS$~$~4*G0;%Il#xo^ai5Z&x1a8 zn{hUusKk=2g@RnT+^iQRFfu_s`Sz;@-{4RT;s%NS2vl|ibB}XOokewF(-x-s@@Zp@ zn`xaR4=W60DEHtV)f6qz9?ZY0>)M8waW%S?Mph{M;|xI_+2*6KEVq(0%z5`winMy) zsd`&kj&gLXi>us`9m$u=Rp*ST9Ga}=iBOznGta~-^#u~IVV3<&6o#j!ih|eKUEl%EI0Ul~N?(gkc ze~}m8#t`v~vp-1Ty(UET`tw{{W_V=hfOoXdhGlDIX(k z%u0Lu=K`w)(KUNA1KP?)Gx!bw_cZOMT0+n?t$7UcD&=iiU09!%KnETF04m8jv{>H~ z?$SQe*LG;X#5BZZ$K!%VQhzMqRIg0?Na(js{PeuCjey4VSr7hN%d@jAYaG!sGYpVH z=Dp@eh(_Q5?au^MQnWR;jismfkJEb4iT?nM*t4r;7VC5_r{9r^ltZm0%z+_zXC!AZ zN+bv72qv)vn&cuV)mtPm2evW#cCTFP^V(c_wpUU>6oShGl>~lAwHLA{M&pNAwrj?< zHz>COcWiTmkCCO%dmIq7?7*sw{39nHO2#@DiCVqPZ*TYM5+VNpT^2mWKER(^f4A{V zsJd!Mr?%=Byg)&9y|!5k{D~OB`cO}F#``HHb5<7gawG9VzI%o<|7 z@b{+m3^dwBm@F~;xWsMyVw_u0+CXLszL_*z+_ZNQ%GZV%F@p;MwU54g)wdQxD|z6K zfpe9&lJ`$mx#_;4(wGaa2KhFQO2_5_ z`L1hEWFcS<;(5WYtn4LJScuO%@G(m9+ZyP}FRa9uB_wu&Omea*Qa@2j?QWxyGO{dy z`h!}sYioPe+jDIM>U}0a{{Y+?j^Frq(>LQSqFF_g@iZ}cc^{FbaA1F?eB6tVPwhZy z09+1DTza2@{Xce~*<5NGWQ6vPQ7U8T+|*Z6@C#OqyVz@xPQTKZa1{MYnysdp2rAqw z4WxsQTI7!I6vjRg+#gzTz3`W>bl;2kG1+BfBtG5LxX^TD8`+s{06iU}^jkW1NGG& zVJVPsG7f50v@jqX`eaZgk9s)WyF3v=#de6A_E!+w$z+~SnI=%+{64>>dZz*y_Kz_G zFdg`>RdphAMb|Zy`g~B@$t|m1Y%L|k+?ft>uod9vzsoqKP}p6>kO|}vmQyXvaRPTR zC*oFP#{_Zmqpjt$wzq+9ZjHl-+Rrigv-)H6;}nu>-{V))S`?eewmKbkJ=+rvRbv2tM&CV5GrN{|P!7@~2WTXEjGs&l&_heC!E*Li z6KPs(yi0X+0E%IO_<=m~JxwS5mUJh-(4(Hzec;Qew2iyVw4Y#BC$sVi#{`V}ijYNP zsV<*9%VJ@k&NU4ys0)*TPjj?$+mdQK6@zKhO=D#<%LUA9<? zkll_6rz=}=ufYPP#HlO|pD{>Q+x`^<5ID!7@q~xH0>6~O(Nb1G?kqBjeRMR z;?6c8IXEYrD-W4Hs5g?xb%eZ2SC;gkXoEP3Q~}6ikUN8q%9Y0Q!K)dDl9NRtGZzJR zqXEePaZ=^rNm1I zAxuPW1+YQn9zBQeLy|jbBQd_CESAn0UKE6#q>KX2dE>qX4`iW{Z_C=-iLI^=FVmRbeW5Ju>+MQ&o- z2`a6Y$Kn8zLE?&CF6#Ed?eFzvnp7o~pjC-rZ}*QbJ^1fK*%;q-sOWKCNpGm@HnC50 zl98_GcE~wWF@U4rG^a|qwy}sLFk1Odwnq??ICsV~xw$-kLXl~u7Hj)hQa?V)qgQtu zQ)BmJEPgUQK=%}C#Orq*;Z|oz%9K&I+#H^BpT+W`K~#+mig{jWl4oTq^0)eEMz#WOLexxzcVOWxkj0*EXJJ(3g&=6>*c2r-Poxg=Yn> zqEbtwh|H4)OIY&b%l?tO*PeeNKrdp8-7eaAY*OAXK@4M&0yHh@f-{_C^F`U&oj&q$ z9@(N2d2_>b-eSz-JTcEBu|F}zIJt(->KVk*Lu9H(HjHOH?qldFvsKls^jYq43eES0 z42u%(60f>rg(urIK!lfFU8mb>@!7rnb~m{=ib$Enza?NfKTZedO0D|HtP)8LwAZEw zCT9!rC?M=8c^>&Rmr3dkA@3uN<0)|2f(AXt@&Q75_)dMtZv0Z~ZAKV8y(019f>ek# zoPt2I02|=}F_VB#ekdyqv>>zAwI{o^H-b1Ljf9)fl@TdD%YTGt^{3f-fZeo^La^Lh z+mp8TJRiI<@6Ue2xi#5tKxnNbDRpx(X&g)fi5DHn>?yS_?QgAQN14n+KMF&%u?GZp z{WHfDZiQdbZk;-6P>~!qXZvLI6P8_I#nRFwT;^1S=-@o@)eXE=LGlQRQ~|7 z%N*mlGR*eNYxgOf8BD0z3PTaF5^~x8)QUxl8}(})Je%S~ODJLpLUP9=gWItb=GK$T z0eG!sSAhQjE=d>#+CB3`#%?9v(#rPMSl)nSE096kmBAUIpRfgAs<^jyX9z`crG^&ppd4m01ZQNaubD^cfi-eEV}sH2V!^3!BT$M*iPXwQ;&T zcp@=xW5C?UJR*_Xz9@1@SIbR=d6J>$IXE8u{!}i7b`aejbf}SUb(5)! zgaoC!2#g2S0UgJ0i@hzh>6Nv(SZ)N0e7)*W?qR^eJoEX}b+)B=*3S*mlG00vyvQPE z4miODkD=%Aisj!>h$7n1%+u{D9FexvX+}33^RpcBP%A>K?LSQO)?2AWlK@xDD#@RJ zhd3nr;+(B?*gUfFNQU7?#+lz6*S^v-ll7*XNM?H&E~W_(k-WgBP3+j?r6(Y zo_$D3KA$WD;_{q0+xf4|15$$e(6U>pbql2tnP&UA*(*Q9jmAMy^5X`&Z$^p*zZt6%qsmjbXrk$tS2ogKUkjmlP zdNXG`bL-fCr{1F%t%&UPMw`ku=X3c*U0r}tgUQGC_U4J!H90PAP){4d5;2knkqBwH z#{<4Hd-kPvY{6t}i)(v#k<6L5Tm)X^1K+tnr7w=v^(356B*Ej_(7da^j0|8OPg+&6 zy%8&Poo}R`c_#|T%ofcc+SnK&S3T*pi69GV9ASgcu4?L5}@7juAqyc9T znD1z3Z2~sb5(e{##^jWoA?J~_f)BSMh}Is%Pny+q)p?|oDRFY|@MLg6U+MMj?@s!} z_l%0L#GY(%l=5Y4bDn=pp55_CG+ilP_ct!~>ne#@M4*DBzsm>psK^zl-#@6O{c!KYiTKxNM=XKSitze&%=S-di_OMHW#*5_Y&grFcr!I z><4g82cgD&X_n@7xYX8bC?JM4P$VjW00Xi1=RWzS=!9@+#^&}IZLW+A(UPCIWNXJ+y_=^?p@h-ZO*_3Gx8Xxy$066OMM(R>2(*J=o^+<6aj`t`kr(7QMTG`r|_@1 zy@UcGGf5@L%E%qDoHwru20K!u$+9^vkmpd2Sne7-)$9c!D^$0RO@>$}V9Grhf(C!x z88m|D?Bmr*Y3JJg*6ML118E$aWmO!8__#a0yZoz7YL+&Z7uFheo!{NH36q$Q!V4UL z26#Eg)`V=X?h-g}tq@qU?~d*#+U?)C1LEXkoOY+T>`F45{hfN($@9*g3xcKIF?AW0 zK;-UR@rqTY_)FB9T0t^2ma8;=WM(G(OYVPq(t5s)6m!8W@Si?bSex?+xM<8xwXjrtusx{N=v_5qD|4wC zW-JPs-As|6Zaa=WaaNLATj{SCp02x_11q%d9E^O8AbCXBQh6~EB4CoqhGF0T07jL< zEssPF_rkkq@6zGKH&f3ZP|p0h9+>PYw(r3Q)a<8qTRUsD3*^CJE>M%)I3tV<;0m_% z$ddlr%2=*U7fS3}Kv!~)OnksJl1(2_it0ywM<+N@96?Fvxjw%-9~wkVqhG_UE#GYI$-&%CTa0jO?wavlX(P8} zd#6NHies=w_!$Eu4V-3@!J)OmjB2phToir2ds;?ZFK@+;c%^U(Y4&Bsv~4n0iq7ge zz&{C;`D1TBy@C0D^lg~BzlhF?(jn}*$S34|Ye^po^a<`h`Fo_;-6Jyqh?`>rJROQg z4;jxii(ByCX|7Ocl3BxLyA5QPKpnWxGAYj(^yah96YeEaO*=&qb#U5zh-Hyunl;P9 z8*tm!hKz&WdRNVR$O-A6-q%r`$Qw^*fC= zG4TN$%syEFnoED-{=H{rw~M1{aY4MHYl~fs7NS)T?}Lh$#rBrfU<%jzKA&;7 z@kwm&6A|(UBQ>3(y=#f%c;R_&Kc!c>rLvogSS3s7W-7o#%ZKkdK*c>BzGYVT4 zsTo0u(n2^pTCz2lk9}7iuuI!rGULlQCE+Lt{{VS#YFVOvr?kj19;4FY7a$Kd((JH5 zJUAcTtWHVxOS4Kvc&?;^epvUUZ1XkAW|;(MfPr$^`qe$Ac>U8Fynu^_)7UTtXG63P ze2SmxeP5vKaS!3z{+V|xbLFMtsXzBy6zXk&lq|7{1||jjcjxq_UwZQJ41m-{=5hSd z9_3?z@tw<`sIM)9$k73SfLf@Hz5xB9~iCw_LPfA5FCCRz~dy-dM+|s|%ZWZqSTvl>?95RDORAdSdJGXf|;(cX(9B z$LorGYqo^oM(jRRD0K;3kRd#G$mX5OKE_K#0{g)&1r^Ppy|rdMh-VB3~ef-Rw;*KuTpLf8lplSut^IX?&n@_j`_i zMik3&qHC6F#`8kdB46<=TgU3B{HsVU@kBU4Kd#v$g-u&SqKYm zh{l<9$UK(G@1H?aI~TNiP&^G5#w8=vnQoM9nRXCaLUPFxHDxcc$*uUD!+L_+S1k+r=}IHx;P z%U4ks!?cn)9@OQmTMHRlIHZ&>nq%e9Ac9ZSn)Q01!fip?-r5h~|?lU4bM0tPj$ZSlWxV z-88biR=1J};N6Ju8?gffkEyR$sh>q`c%CGL*a(y z`rg_Z7ZEIBV?YKFviBMF1mtHm>h&N>{^{;)H3_X+_It%`k+a=xa?9YK3M&%60kTNmb9la~n>Vy$=)$8h4n#?n*JXZI+BTzAg1+u>|an5VKTdB*Tq%hfq ziZ_@Ipqv0f?av*%*Q?ag3O(WN{JmAu`sKy=M!3^&qJr93&?6*ehF6aMz4_<8Ng=hi zx6~({EnyQW^2D1m+jn-&dc8~ShtN5!VQ;-#;FL_2C5d64{F;O&vpu%AWn&t~kxO+X zY{7mlpc8;=)#`$dqg%VS)FRm@#L{ovc_D{lDo3wHE}5j*YAJVdE%u>(ADujp@nD`n zBOG#T)#@I=`a5we>K9^Wa}hT(mRPt}!N3PO;8CLPSuWzYEr_`xN2PkbMnDl-UCDSZ zH=KD!MO~vA0FpCFZ*OiQy|98Q-Y8_;%^IFFUawF?K7;kS;<~x8jjbVBSmCZ0cJ{&J zjoU|mK~dd8HE1NZbrM_1-g8FXi)0+vtJE0~?|g|RvZ5luld%P37z^R6yMXoc-yl1UOx(z1L+1?`cJIi**fA*V~C2w7!lBV@!zR@!oN&%esOUZDFT3cuPS zj@=PsiUMvBAjik>jQ;@UG)|#m5xYsG-8YrAta33a$sV7bdc91#Am?Eag7<7+%2^Wy zPz3`Ai~-t_>ZmNWOZ!OjVJbF;B<#xP;rbDgUawR^JwB5StT$Hb^Exv}hLS?eneVio z-uzT2th&!ov(;lLAz&ghD0ue-Acf;Sz0c0QUZ}e#wmtNwwRNj>e!B#$sMj$>rgTB( zMTrI)HaXgPJc?x1kbK-XSE#)e5!-17r^5{&nj0E9?TTGg6mUyV341 zmOHtv%Lv`j1IIk$8Sm>!Ev%B}?r`lPj_AlHh`BMo)=;FW;~;TfuT)_4Os%b;ztmA@ zfg}rTsyN4H1RtoTHFIawmu((DpCa!JGsbhb>B+BGsJ?)LKJ)j!wYjmmiaVH7Eg6s; z$DR%_M;Jc2rpMB4EUx0zt>IWDKlM?KvGPdlKjU7nPzxROt0=WUGFf*iT)0@+fCxU+ zrdZY{lo93z0lqR$4t*=t>RA#862=R=_}*yNNoI6oBLG=QAOb1I`$@IF)otxwF&s}b zqj_HmYyxxjIONx>)ZU1@IcKNBG_36>WWGX6p?NN$cW9Ei3S7tVamGF95=kOR)-p=dq%NUllOAEiU}TIB+Pz+=LO~1(cqj9+ z`&g*SJ%u%YpdCBZcNbQAhLsf1JZmF`cTML6^R7kG)DUrj^2IEY@_S|yM=J(%&o%1xAq5iacX3++B*|gi_n}9sPO@8^f=_&k^?H&$ zhtVg~?ppdejG!D3K|s8*g5d`E#z5eT^?H&20HQ92CAV1Z5gk~6=c~YJFs-a}DRp9@un!gL^mKItJG-> sKUmtwC9D!{+R{X>!FU-o9kU9!MC9~V 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 G-uw@F62Eo; literal 0 HcmV?d00001 diff --git a/addons/website_blog/data/website_blog_demo.xml b/addons/website_blog/data/website_blog_demo.xml index 913c2ddc9b1..8087673443d 100644 --- a/addons/website_blog/data/website_blog_demo.xml +++ b/addons/website_blog/data/website_blog_demo.xml @@ -107,6 +107,7 @@ New Hardware Integration + @@ -232,45 +233,158 @@ ]]> - - Touchscreen Point of Sale for 6.1 + Sorry SAP Campaign - The Making Of - - Point of Sale, Hardware, Interface, Payment Terminal, Store - Point of Sale with no installation required that runs online and offline. - -The brand new OpenERP touchscreen point of sale is available with 6.1 which allows you -to manage your shop sales very easily. It's fully web based so that you don't -have to install or deploy any software and all the sales shops can be easily -consolidated. It works in connected and disconnected modes so that you can -continue to sell even if you lose your internet connection.

- -

Here's a summary of its main features and benefits:

-
    -
  • 100% WEB based
  • -
  • available for any touchscreen device (ipod, ipad, any tablet)mobile (with portable devices)
  • -
  • no installation required
  • -
  • no synchronization needed, completely integrated
  • -
  • continue working even when your connection is down or if you close your browser, data won't be lost
  • -
  • fully web based with a clean interface smart interface
  • -
-

You have different options to select your products. You can do it through the -barcode reader, just browse through the categories you have put in place (ie. -drinks, snacks, meals, etc.), or text search in case neither of the other -options work for you. For example, if you need to use the POS for your restaurant, -your employees can record multiple tickets at the same time without having to wait -to process one transaction at a time. In addition, you can facilitate payments, -the application allows multiple payment methods.

-

The POS application is so simple and accessible to use that your shop or -restaurant will never need any other tool to manage orders. Due to its smart -and user-friendly interface you don't need any training to learn how to use it. -Think of it as an out-of-the-box solution to boost your business' productivity. -

-]]> + + OpenERP, News, Sorry SAP + Sorry SAP Campaign - The Making Of + +
+

I needed to change the world. I wanted to ... You know how it + is when you are young; you have big dreams, a lot of energy + and naïve stupidity. My dream was to lead the enterprise + management market with a fully open source software. (I also + wanted to get 100 employees before 30 years old with a + self-financed company but I failed this one by a few months). +

+
+ +
+
+

To fuel my motivation, I had to pick someone to fight + against. In business, it's like a playground. When you arrive in + a new school, if you want to quickly become the leader, you must + choose the class bully, the older guy who terrorises small boys, + and kick his butt in front of everyone. That was my strategy + with SAP, the enterprise software giant.

+

So, in 2005, I started to develop the TinyERP product, the + software that (at least in my mind) would change the enterprise + world. While preparing for the "day of the fight" in 2006, I + bought the SorrySAP.com domain name. I put it on hold for 6 + years, waiting for the right moment to use it. I thought it + would take 3 years to deprecate a 77 billion dollars company + just because open source is so cool. Sometimes it's better for + your self-motivation not to face reality...

+

To make things happen, I worked hard, very hard. I worked 13 + hours a day, 7 days a week, with no vacations for 7 years.I + lost friendships and broke up with my girlfriend in the process + (fortunately, I found a more valuable wife now. I will explain + later why she is worth 1 million EUR :).

+

Three years later, I discovered you can't change the world + if you are "tiny". Especially if the United States is part of + this world, where it's better to be a BigERP, rather than a + TinyERP. Can you imagine how small you feel in front of Danone's + directors asking; "but why should we pay millions of dollars + for a tiny software?" So, we renamed TinyERP to OpenERP.

+

As we worked hard, things started to evolve. We were + developing dozens of modules for OpenERP, the open source + community was growing and I was even able to pay all employees' + salaries at the end of the month without fear (which was a + situation I struggled with for 4 years).

+

In 2010, we had a 100+ employees company selling services on + OpenERP and a powerful but ugly product. This is what happens + when delivering services to customers distracts you from + building an exceptional product.

+

It was time to do a pivot in the business model.

+

The Pivot

+

We wanted to switch from a service company to a software + publisher company. This would allow to increase our efforts in + our research and development activities. As a result, we + changed our business model and decided to stop our services to + customers and focus on building a strong partner network and + maintenance offer. This would cost money, so I had to raise a + few million euros.

+

After a few months of pitching investors, I got roughly 10 + LOI from different VCs. We chosed Sofinnova Partners, the + biggest European VC, and Xavier Niel the founder of Iliad, the + only company in France funded in the past 10 years to have + reached the 1 billion euro valuation.

+

I signed the LOI. I didn't realize that this contract could + have turned me into a homeless person. (I already had a dog, + all I needed was to lose a lot of money to become homeless). + The fund raising was based on a company valuation but there + was a financial mechanism to re-evaluate the company up by + 9.8 m€ depending on the turnover of the next 4 years. I should + have received warrants convertible into shares if we achieved + the turnover targeted in the business plan.

+

The night before receiving the warrants in front of the + notary, my wife checked the contracts. She asked me what would + be the taxation on these warrants. I rang the lawyer and guess + what? Belgium is probably the only country in the world where + you have to pay taxes on warrants when you receive them, even + if you never reach the conditions to convert them into shares. + If I had accepted these warrants, I would have had to pay a + 12.5% tax on 9.8 m€; resulting in a tax of 1.2m€ to pay in 18 + months! So, my wife is worth 1.2 million EUR. I would have + ended up a homeless person without her, as I still did not + have a salary at that time.

+

We changed the deal and I got the 3 million EUR. It allowed + me to recruit a rocking management team.

+ +

Being a mature company

+

With this money in our bank account, we boosted two + departments: R&D and Sales. We burned two million EUR in 18 months, + mostly in salaries. The company started to grow even faster. + We developed a partner network of 500 partners in 100 countries + and we started to sign contracts with 6 zeros.

+

Then, things became different. You know, tedious things like + handling human resources, board meetings, dealing with big + customer contracts, traveling to launch international + subsidiaries. We did boring stuff like budgets, career paths, + management meetings, etc.

+

2011 was a complex year. We did not meet our expectations: + we only achieved 70% of the forecasted sales budget. Our + management meetings were tense. We under performed. We were not + satisfied with ourselves. We had a constant feeling that we + missed something. It's a strange feeling to build extraordinary + things but to not be proud of ourselves.

+

But one day, someone (I don't remember who, I have a + goldfish memory) made a graph of the monthly turnover of the + past 2 years. It was like waking up from a nighmare. In fact, + it was not that bad, we had multiplied by 10 the monthly turnover + over the span of roughly two years! This is when we understood + that OpenERP is a marathon, not a sprint. Only 100% growth a + year is ok... if you can keep the rhythm for several years.

+ +

+ OpenERP Monthly Turnover

+

As usual, I should have listened to my wife. She is way more + lucid than I am. Every week I complained to her "it's not good + enough, we should grow faster, what am I missing?" and she used + to reply; "But you already are the fastest growing company in + Belgium!". (Deloitte awarded us as the fastest growing company + of Belgium with 1549% growth of the turnover between 2007 and + 2011)

+

Changing the world

+

Then, the dream started to become reality. We started to get + clues that what we did would change the world:

+
    +
  • With 1.000 installations per day, we became the most + installed management software in the world,
  • +
  • Analysts from Big 4 started to prefer OpenERP over SAP,
  • +
  • OpenERP is now a compulsory subject for the + baccalaureate in France like Word, Excel and Powerpoint
  • +
  • 60 new modules are released every month (we became the + wikipedia of the management software thanks to our strong + community)
  • +
+

Something is happening... And it's big!

+

OpenERP 7.0 is about to be released and I know you will be + astonished by it.

+

The official release is planned for the 21th of December. + As the Mayas predicted it, this is the end of an age, the old + ERP dinosaurs.

+

It's time to pull out the Ace: the SorrySAP.com domain name + that I bought 6 years ago.

+

If you want to test the v7 version online, just go the homepage.

+
+
+ ]]>
- + Announcing a New Partnership From 361c56dcc8c2e5e8dcc3b342d7cfb293020dad6f Mon Sep 17 00:00:00 2001 From: "Mahendra Barad (OpenERP)" Date: Wed, 29 Jan 2014 18:15:40 +0530 Subject: [PATCH 009/483] [Add]counter on blog bzr revid: mba@tinyerp.com-20140129124540-3uav6ns35h9y2owg --- addons/website_blog/controllers/main.py | 6 ++++++ addons/website_blog/models/website_blog.py | 4 +++- addons/website_blog/views/website_blog_templates.xml | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/addons/website_blog/controllers/main.py b/addons/website_blog/controllers/main.py index 2e1477e8f2d..a18505fb0f5 100644 --- a/addons/website_blog/controllers/main.py +++ b/addons/website_blog/controllers/main.py @@ -196,6 +196,12 @@ class WebsiteBlog(http.Controller): tag_ids = tag_obj.search(cr, uid, [], context=context) tags = tag_obj.browse(cr, uid, tag_ids, context=context) + blog_post_obj = request.registry.get('blog.post') + if not request.httprequest.session.get(blog_post.id,False): + request.httprequest.session[blog_post.id] = True + counter = blog_post.counter + 1; + blog_post_obj.write(cr, SUPERUSER_ID, [blog_post.id], {'counter':counter},context=context) + MONTHS = [None, _('January'), _('February'), _('March'), _('April'), _('May'), _('June'), _('July'), _('August'), _('September'), _('October'), _('November'), _('December')] diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index 7d8448cb268..90a1c07f617 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -146,9 +146,11 @@ class BlogPost(osv.Model): 'res.users', 'Last Contributor', select=True, readonly=True, ), + 'counter': fields.integer('No of Visitors'), } _defaults = { - 'website_published': False + 'website_published': False, + 'counter': 0 } def create_history(self, cr, uid, ids, vals, context=None): diff --git a/addons/website_blog/views/website_blog_templates.xml b/addons/website_blog/views/website_blog_templates.xml index e87caac8189..bc28b3eaf66 100644 --- a/addons/website_blog/views/website_blog_templates.xml +++ b/addons/website_blog/views/website_blog_templates.xml @@ -161,6 +161,7 @@

- -
+ +
@@ -16,7 +16,7 @@ -
Post -
- + + Log in to post comments + + +
+ +
+ + + Post +
+
+
From bcf36e6deb06a3ae9a5ee4adb3f3b7d148308bef Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 4 Apr 2014 16:15:59 +0200 Subject: [PATCH 332/483] [IMP] expression: new helper for generating unaccent aware sql queries. Adapt _auto_join tests to use it. bzr revid: chs@openerp.com-20140404141559-d2sn68lruik9hz81 --- openerp/addons/base/tests/test_expression.py | 32 +++++++++++++++---- openerp/osv/expression.py | 33 ++++++++++---------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/openerp/addons/base/tests/test_expression.py b/openerp/addons/base/tests/test_expression.py index 9c0cd01cb5a..a89ae193f5c 100644 --- a/openerp/addons/base/tests/test_expression.py +++ b/openerp/addons/base/tests/test_expression.py @@ -1,4 +1,6 @@ import unittest2 + +from openerp.osv.expression import get_unaccent_wrapper from openerp.osv.orm import BaseModel import openerp.tests.common as common @@ -123,6 +125,7 @@ class test_expression(common.TransactionCase): def test_20_auto_join(self): registry, cr, uid = self.registry, self.cr, self.uid + unaccent = get_unaccent_wrapper(cr) # Get models partner_obj = registry('res.partner') @@ -179,8 +182,11 @@ class test_expression(common.TransactionCase): sql_query = self.query_list[0].get_sql() self.assertIn('res_partner_bank', sql_query[0], "_auto_join off: ('bank_ids.name', 'like', '..') first query incorrect main table") - self.assertIn('"res_partner_bank"."name" like %s', sql_query[1], + + expected = "%s like %s" % (unaccent('"res_partner_bank"."name"'), unaccent('%s')) + self.assertIn(expected, sql_query[1], "_auto_join off: ('bank_ids.name', 'like', '..') first query incorrect where condition") + self.assertEqual(set(['%' + name_test + '%']), set(sql_query[2]), "_auto_join off: ('bank_ids.name', 'like', '..') first query incorrect parameter") sql_query = self.query_list[2].get_sql() @@ -216,8 +222,11 @@ class test_expression(common.TransactionCase): "_auto_join on: ('bank_ids.name', 'like', '..') query incorrect main table") self.assertIn('"res_partner_bank" as "res_partner__bank_ids"', sql_query[0], "_auto_join on: ('bank_ids.name', 'like', '..') query incorrect join") - self.assertIn('"res_partner__bank_ids"."name" like %s', sql_query[1], + + expected = "%s like %s" % (unaccent('"res_partner__bank_ids"."name"'), unaccent('%s')) + self.assertIn(expected, sql_query[1], "_auto_join on: ('bank_ids.name', 'like', '..') query incorrect where condition") + self.assertIn('"res_partner"."id"="res_partner__bank_ids"."partner_id"', sql_query[1], "_auto_join on: ('bank_ids.name', 'like', '..') query incorrect join condition") self.assertEqual(set(['%' + name_test + '%']), set(sql_query[2]), @@ -295,8 +304,11 @@ class test_expression(common.TransactionCase): sql_query = self.query_list[0].get_sql() self.assertIn('"res_country"', sql_query[0], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect main table") - self.assertIn('"res_country"."code" like %s', sql_query[1], + + expected = "%s like %s" % (unaccent('"res_country"."code"'), unaccent('%s')) + self.assertIn(expected, sql_query[1], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect where condition") + self.assertEqual(['%' + name_test + '%'], sql_query[2], "_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect parameter") sql_query = self.query_list[1].get_sql() @@ -326,8 +338,11 @@ class test_expression(common.TransactionCase): "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect main table") self.assertIn('"res_country" as "res_country_state__country_id"', sql_query[0], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect join") - self.assertIn('"res_country_state__country_id"."code" like %s', sql_query[1], + + expected = "%s like %s" % (unaccent('"res_country_state__country_id"."code"'), unaccent('%s')) + self.assertIn(expected, sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect where condition") + self.assertIn('"res_country_state"."country_id"="res_country_state__country_id"."id"', sql_query[1], "_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 1 incorrect join condition") self.assertEqual(['%' + name_test + '%'], sql_query[2], @@ -357,8 +372,11 @@ class test_expression(common.TransactionCase): "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join") self.assertIn('"res_country" as "res_partner__state_id__country_id"', sql_query[0], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join") - self.assertIn('"res_partner__state_id__country_id"."code" like %s', sql_query[1], + + expected = "%s like %s" % (unaccent('"res_partner__state_id__country_id"."code"'), unaccent('%s')) + self.assertIn(expected, sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect where condition") + self.assertIn('"res_partner"."state_id"="res_partner__state_id"."id"', sql_query[1], "_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join condition") self.assertIn('"res_partner__state_id"."country_id"="res_partner__state_id__country_id"."id"', sql_query[1], @@ -384,7 +402,9 @@ class test_expression(common.TransactionCase): "_auto_join on one2many with domains incorrect result") # Test produced queries that domains effectively present sql_query = self.query_list[0].get_sql() - self.assertIn('"res_partner__child_ids__bank_ids"."acc_number" like %s', sql_query[1], + + expected = "%s like %s" % (unaccent('"res_partner__child_ids__bank_ids"."acc_number"'), unaccent('%s')) + self.assertIn(expected, sql_query[1], "_auto_join on one2many with domains incorrect result") # TDE TODO: check first domain has a correct table name self.assertIn('"res_partner__child_ids"."name" = %s', sql_query[1], diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py index 93e28dcccb3..da49ae12850 100644 --- a/openerp/osv/expression.py +++ b/openerp/osv/expression.py @@ -430,6 +430,10 @@ def select_distinct_from_where_not_null(cr, select_field, from_table): cr.execute('SELECT distinct("%s") FROM "%s" where "%s" is not null' % (select_field, from_table, select_field)) return [r[0] for r in cr.fetchall()] +def get_unaccent_wrapper(cr): + if openerp.modules.registry.RegistryManager.get(cr.dbname).has_unaccent: + return lambda x: "unaccent(%s)" % (x,) + return lambda x: x # -------------------------------------------------- # ExtendedLeaf class for managing leafs and contexts @@ -631,7 +635,7 @@ class expression(object): :attr list expression: the domain expression, that will be normalized and prepared """ - self.has_unaccent = openerp.modules.registry.RegistryManager.get(cr.dbname).has_unaccent + self._unaccent = get_unaccent_wrapper(cr) self.joins = [] self.root_model = table @@ -1020,7 +1024,6 @@ class expression(object): push(create_substitution_leaf(leaf, (left, operator, right), working_model)) elif field.translate and right: - field = left need_wildcard = operator in ('like', 'ilike', 'not like', 'not ilike') sql_operator = {'=like': 'like', '=ilike': 'ilike'}.get(operator, operator) if need_wildcard: @@ -1032,16 +1035,13 @@ class expression(object): sql_operator = sql_operator[4:] if sql_operator[:3] == 'not' else '=' inselect_operator = 'not inselect' - trans_left = 'value' - left = '"%s"' % (left,) - instr = '%s' + unaccent = self._unaccent if sql_operator.endswith('like') else lambda x: x - if self.has_unaccent and sql_operator.endswith('like'): - assert isinstance(right, basestring) - trans_left = 'unaccent(value)' - left = 'unaccent(%s)' % (left,) - instr = 'unaccent(%s)' - elif sql_operator == 'in': + trans_left = unaccent('value') + quote_left = unaccent(_quote(left)) + instr = unaccent('%s') + + if sql_operator == 'in': # params will be flatten by to_sql() => expand the placeholders instr = '(%s)' % ', '.join(['%s'] * len(right)) @@ -1057,10 +1057,10 @@ class expression(object): WHERE {left} {operator} {right} ) """.format(trans_left=trans_left, operator=sql_operator, - right=instr, table=working_model._table, left=left) + right=instr, table=working_model._table, left=quote_left) params = ( - working_model._name + ',' + field, + working_model._name + ',' + left, context.get('lang') or 'en_US', 'model', right, @@ -1184,10 +1184,9 @@ class expression(object): if left in model._columns: format = need_wildcard and '%s' or model._columns[left]._symbol_set[0] - if self.has_unaccent and sql_operator.endswith('like'): - query = '(unaccent(%s."%s") %s unaccent(%s))' % (table_alias, left, sql_operator, format) - else: - query = '(%s."%s" %s %s)' % (table_alias, left, sql_operator, format) + unaccent = self._unaccent if sql_operator.endswith('like') else lambda x: x + column = '%s.%s' % (table_alias, _quote(left)) + query = '(%s %s %s)' % (unaccent(column), sql_operator, unaccent(format)) elif left in MAGIC_COLUMNS: query = "(%s.\"%s\" %s %%s)" % (table_alias, left, sql_operator) params = right From 53d8055cd8ad38e0fd135ae58afb713b7c16f48f Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 4 Apr 2014 16:16:11 +0200 Subject: [PATCH 333/483] [FIX] res.partner: name_search: respect unaccent flag bzr revid: chs@openerp.com-20140404141611-qi1yagltvkd9q8ji --- openerp/addons/base/res/res_partner.py | 36 +++++++++++++++----------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/openerp/addons/base/res/res_partner.py b/openerp/addons/base/res/res_partner.py index 5d97311c01d..d43028d68ef 100644 --- a/openerp/addons/base/res/res_partner.py +++ b/openerp/addons/base/res/res_partner.py @@ -29,6 +29,7 @@ import openerp from openerp import SUPERUSER_ID from openerp import pooler, tools from openerp.osv import osv, fields +from openerp.osv.expression import get_unaccent_wrapper from openerp.tools.translate import _ from openerp.tools.yaml_import import is_comment @@ -610,27 +611,32 @@ class res_partner(osv.osv, format_address): if operator in ('=ilike', '=like'): operator = operator[1:] + unaccent = get_unaccent_wrapper(cr) + # TODO: simplify this in trunk with `display_name`, once it is stored # Perf note: a CTE expression (WITH ...) seems to have an even higher cost # than this query with duplicated CASE expressions. The bulk of # the cost is the ORDER BY, and it is inevitable if we want # relevant results for the next step, otherwise we'd return # a random selection of `limit` results. - query = ('''SELECT res_partner.id FROM res_partner - LEFT JOIN res_partner company - ON res_partner.parent_id = company.id''' - + where_str + ''' (res_partner.email ''' + operator + ''' %s OR - CASE - WHEN company.id IS NULL OR res_partner.is_company - THEN res_partner.name - ELSE company.name || ', ' || res_partner.name - END ''' + operator + ''' %s) - ORDER BY - CASE - WHEN company.id IS NULL OR res_partner.is_company - THEN res_partner.name - ELSE company.name || ', ' || res_partner.name - END''') + + display_name = """CASE WHEN company.id IS NULL OR res_partner.is_company + THEN {partner_name} + ELSE {company_name} || ', ' || {partner_name} + END""".format(partner_name=unaccent('res_partner.name'), + company_name=unaccent('company.name')) + + query = """SELECT res_partner.id + FROM res_partner + LEFT JOIN res_partner company + ON res_partner.parent_id = company.id + {where} ({email} {operator} {percent} + OR {display_name} {operator} {percent}) + ORDER BY {display_name} + """.format(where=where_str, operator=operator, + email=unaccent('res_partner.email'), + percent=unaccent('%s'), + display_name=display_name) where_clause_params += [search_name, search_name] if limit: From 4d797222279e361bfe6db0fe45f3ff503b87c717 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Fri, 4 Apr 2014 16:30:09 +0200 Subject: [PATCH 334/483] [FIX] add missing semicolons, add a missing 'var' statement and remove trailing whitespace (addon web_graph) bzr revid: ged@openerp.com-20140404143009-6uk7607bv4acbg4b --- addons/web_graph/static/src/js/pivot_table.js | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/addons/web_graph/static/src/js/pivot_table.js b/addons/web_graph/static/src/js/pivot_table.js index 309bb103fa8..d0867ca6d1a 100644 --- a/addons/web_graph/static/src/js/pivot_table.js +++ b/addons/web_graph/static/src/js/pivot_table.js @@ -278,26 +278,26 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ if (expand && !_.find(col_headers, function (hdr) {return _.isEqual(col_value, hdr.path);})) { return; - } + } var row = self.find_or_create_header(row_headers, row_value, data_pt); var col = self.find_or_create_header(col_headers, col_value, data_pt); - var cell_value = _.map(self.measures, function (m) { + var cell_value = _.map(self.measures, function (m) { return data_pt.attributes.aggregates[m.field]; }); self.cells.push({ - x: Math.min(row.id, col.id), - y: Math.max(row.id, col.id), + x: Math.min(row.id, col.id), + y: Math.max(row.id, col.id), values: cell_value - }); + }); }); }, make_header: function (values) { return _.extend({ - children: [], - domain: this.domain, - expanded: undefined, + children: [], + domain: this.domain, + expanded: undefined, id: _.uniqueId(), path: [], root: undefined, @@ -306,7 +306,7 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ }, find_or_create_header: function (headers, path, data_pt) { - var hdr = _.find(headers, function (header) { + var hdr = _.find(headers, function (header) { return _.isEqual(path, header.path); }); if (hdr) { @@ -318,11 +318,11 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return hdr; } hdr = this.make_header({ - path:path, + path:path, domain:data_pt.model._domain, title: _t(_.last(path)) }); - parent = _.find(headers, function (header) { + var parent = _.find(headers, function (header) { return _.isEqual(header.path, _.initial(path, 1)); }); @@ -399,26 +399,27 @@ openerp.web_graph.PivotTable = openerp.web.Class.extend({ return group.attributes.length > 0; }).map(function (group) { var attrs = group.attributes, - grouped_on = attrs.grouped_on instanceof Array - ? attrs.grouped_on : [attrs.grouped_on], + grouped_on = attrs.grouped_on instanceof Array ? attrs.grouped_on : [attrs.grouped_on], raw_grouped_on = grouped_on.map(function (f) { return self.raw_field(f); }); - if (grouped_on.length === 1) { attrs.value = [attrs.value]} + if (grouped_on.length === 1) { + attrs.value = [attrs.value]; + } attrs.value = _.range(grouped_on.length).map(function (i) { - if (attrs.value[i] === false) { + if (attrs.value[i] === false) { return _t('Undefined'); } else if (attrs.value[i] instanceof Array) { return attrs.value[i][1]; } - return attrs.value[i] + return attrs.value[i]; }); attrs.aggregates.__count = group.attributes.length; attrs.grouped_on = raw_grouped_on; return group; }); }); - }, + }, // if field is a fieldname, returns field, if field is field_id:interval, retuns field_id raw_field: function (field) { From be909a2dd461ad72d4bb7ba297c3e98af1846222 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Fri, 4 Apr 2014 16:51:56 +0200 Subject: [PATCH 335/483] [FIX] sale_layout: correct api method signature bzr revid: sle@openerp.com-20140404145156-msppuq3sh7onggnn --- addons/sale_layout/models/sale_layout.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/sale_layout/models/sale_layout.py b/addons/sale_layout/models/sale_layout.py index d6e7e435b99..8d3e94cca95 100644 --- a/addons/sale_layout/models/sale_layout.py +++ b/addons/sale_layout/models/sale_layout.py @@ -79,7 +79,7 @@ class SaleLayoutCategory(osv.Model): class AccountInvoice(osv.Model): _inherit = 'account.invoice' - def sale_layout_lines(self, cr, uid, ids, context, invoice_id, *args, **kwargs): + def sale_layout_lines(self, cr, uid, ids, invoice_id=None, context=None): """ Returns invoice lines from a specified invoice ordered by sale_layout_category sequence. Used in sale_layout module. @@ -110,7 +110,7 @@ class AccountInvoiceLine(osv.Model): class SaleOrder(osv.Model): _inherit = 'sale.order' - def sale_layout_lines(self, cr, uid, ids, context, order_id, *args, **kwargs): + def sale_layout_lines(self, cr, uid, ids, order_id=None, context=None): """ Returns order lines from a specified sale ordered by sale_layout_category sequence. Used in sale_layout module. From f0fe7aa177c8f6911f5e971a24c25e17ca74f714 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Fri, 4 Apr 2014 17:11:12 +0200 Subject: [PATCH 336/483] [FIX] account invoice_print: ensure the right ids are in the context before calling get_action bzr revid: sle@openerp.com-20140404151112-bov5xziw7rst1qtc --- addons/account/account_invoice.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 5f7c2b66400..effc2b03f61 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -409,7 +409,9 @@ class account_invoice(osv.osv): ''' assert len(ids) == 1, 'This option should only be used for a single id at a time.' self.write(cr, uid, ids, {'sent': True}, context=context) - return self.pool['report'].get_action(cr, uid, ids, 'account.report_invoice', context=context) + context2 = context.copy() + context2['active_ids'] = ids + return self.pool['report'].get_action(cr, uid, [], 'account.report_invoice', context=context2) def action_invoice_sent(self, cr, uid, ids, context=None): ''' From 28f0649a7181272b528216d854c8e7438ff65aa9 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 4 Apr 2014 17:17:39 +0200 Subject: [PATCH 337/483] [FIX] skip undefined and keep formating as empty string bzr revid: mat@openerp.com-20140404151739-u61resk70xoih5he --- addons/web_graph/static/src/js/graph_widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web_graph/static/src/js/graph_widget.js b/addons/web_graph/static/src/js/graph_widget.js index bb87e172718..3d8d8fa2d98 100644 --- a/addons/web_graph/static/src/js/graph_widget.js +++ b/addons/web_graph/static/src/js/graph_widget.js @@ -436,7 +436,7 @@ openerp.web_graph.Graph = openerp.web.Widget.extend({ }, make_cell: function (row, col, value, index, raw) { - var formatted_value = raw ? value : openerp.web.format_value(value, {type:this.pivot.measures[index].type}), + var formatted_value = raw && !_.isUndefined(value) ? value : openerp.web.format_value(value, {type:this.pivot.measures[index].type}), cell = {value:formatted_value}; if (this.heatmap_mode === 'none') { return cell; } From 4335ff0712e4b7da4f78c708b348c5442aa774da Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 4 Apr 2014 17:46:58 +0200 Subject: [PATCH 338/483] [FIX] force suppression of pidfile at exit of openerp. [IMP] only write/delete pidfile in non-evented mode [FIX] check if evented mode before checking in worker mode when starting server service bzr revid: chs@openerp.com-20140404154658-6x5rxyq12guej43q --- openerp/cli/server.py | 14 ++++++++------ openerp/service/server.py | 8 ++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/openerp/cli/server.py b/openerp/cli/server.py index eec85756469..0d346f160c4 100644 --- a/openerp/cli/server.py +++ b/openerp/cli/server.py @@ -29,6 +29,7 @@ GNU Public Licence. (c) 2003-TODAY, Fabien Pinckaers - OpenERP SA """ +import atexit import logging import os import signal @@ -78,16 +79,22 @@ def report_configuration(): ('database user', config['db_user'])]: _logger.info("%s: %s", name, value) +def rm_pid_file(): + config = openerp.tools.config + if not openerp.evented and os.path.exists(config['pidfile']): + os.unlink(config['pidfile']) + def setup_pid_file(): """ Create a file with the process id written in it. This function assumes the configuration has been initialized. """ config = openerp.tools.config - if config['pidfile']: + if not openerp.evented and config['pidfile']: with open(config['pidfile'], 'w') as fd: pidtext = "%d" % (os.getpid()) fd.write(pidtext) + atexit.register(rm_pid_file) def preload_registry(dbname): """ Preload a registry, and start the cron.""" @@ -189,14 +196,9 @@ def main(args): if not config["stop_after_init"]: setup_pid_file() openerp.service.server.start() - if config['pidfile']: - os.unlink(config['pidfile']) else: sys.exit(rc) - _logger.info('OpenERP server is running, waiting for connections...') - quit_on_signals() - class Server(Command): def run(self, args): main(args) diff --git a/openerp/service/server.py b/openerp/service/server.py index 6a558a24e91..6a87c85e56b 100644 --- a/openerp/service/server.py +++ b/openerp/service/server.py @@ -429,7 +429,7 @@ class PreforkServer(CommonServer): sys.exit(0) def long_polling_spawn(self): - nargs = stripped_sys_argv('--pidfile','--workers') + nargs = stripped_sys_argv() cmd = nargs[0] cmd = os.path.join(os.path.dirname(cmd), "openerp-gevent") nargs[0] = cmd @@ -814,10 +814,10 @@ def start(): """ global server load_server_wide_modules() - if config['workers']: - server = PreforkServer(openerp.service.wsgi_server.application) - elif openerp.evented: + if openerp.evented: server = GeventServer(openerp.service.wsgi_server.application) + elif config['workers']: + server = PreforkServer(openerp.service.wsgi_server.application) else: server = ThreadedServer(openerp.service.wsgi_server.application) From 97ffe7a5b94287642b99e5ff9fdce2c37bab0c37 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Fri, 4 Apr 2014 17:51:48 +0200 Subject: [PATCH 339/483] [FIX] Keep the layout between sale order and invoice bzr revid: sle@openerp.com-20140404155148-l8btjfhp640r0gew --- addons/sale_layout/models/sale_layout.py | 9 +++++++++ addons/sale_layout/views/sale_layout_template.xml | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/addons/sale_layout/models/sale_layout.py b/addons/sale_layout/models/sale_layout.py index 8d3e94cca95..ac9d4241607 100644 --- a/addons/sale_layout/models/sale_layout.py +++ b/addons/sale_layout/models/sale_layout.py @@ -135,3 +135,12 @@ class SaleOrderLine(osv.Model): # Store is intentionally set in order to keep the "historic" order. } _order = 'order_id, categ_sequence, sequence, id' + + def _prepare_order_line_invoice_line(self, cr, uid, line, account_id=False, context=None): + """Save the layout when converting to an invoice line.""" + invoice_vals = super(SaleOrderLine, self)._prepare_order_line_invoice_line(cr, uid, line, account_id=account_id, context=context) + if line.sale_layout_cat_id: + invoice_vals['sale_layout_cat_id'] = line.sale_layout_cat_id.id + if line.categ_sequence: + invoice_vals['categ_sequence'] = line.categ_sequence + return invoice_vals diff --git a/addons/sale_layout/views/sale_layout_template.xml b/addons/sale_layout/views/sale_layout_template.xml index c8c83bf2d29..88a95ae238d 100644 --- a/addons/sale_layout/views/sale_layout_template.xml +++ b/addons/sale_layout/views/sale_layout_template.xml @@ -5,7 +5,7 @@ - > + &bull; From 1d965535b0c30cc5d53260bc4bd53a3dd77fd050 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of openerp <> Date: Sat, 5 Apr 2014 05:30:45 +0000 Subject: [PATCH 340/483] Launchpad automatic translations update. bzr revid: launchpad_translations_on_behalf_of_openerp-20140405053045-3cts3jqyeqsu0x57 --- addons/account/i18n/pl.po | 10 ++++++---- addons/account_followup/i18n/pl.po | 29 ++++++++++++++++------------- addons/auth_signup/i18n/pl.po | 14 +++++++------- addons/hr_holidays/i18n/pl.po | 8 ++++---- addons/mail/i18n/pl.po | 12 ++++++------ addons/procurement/i18n/pl.po | 20 +++++++++++--------- addons/stock/i18n/pl.po | 10 +++++----- 7 files changed, 55 insertions(+), 48 deletions(-) diff --git a/addons/account/i18n/pl.po b/addons/account/i18n/pl.po index ef2849cd444..ef779200db0 100644 --- a/addons/account/i18n/pl.po +++ b/addons/account/i18n/pl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:04+0000\n" -"PO-Revision-Date: 2012-12-22 12:46+0000\n" -"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) \n" +"PO-Revision-Date: 2014-04-04 19:18+0000\n" +"Last-Translator: Dariusz Żbikowski \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-27 06:26+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-05 05:30+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: account #: model:process.transition,name:account.process_transition_supplierreconcilepaid0 @@ -989,6 +989,8 @@ msgid "" " opening/closing fiscal " "year process." msgstr "" +"Nie możesz anulować uzgodnień pozycji dziennika jeśli zostały one " +"wygenerowane procesem zamykania/otwierania roku." #. module: account #: model:ir.actions.act_window,name:account.action_subscription_form_new diff --git a/addons/account_followup/i18n/pl.po b/addons/account_followup/i18n/pl.po index b851b85d5df..1a37b819f02 100644 --- a/addons/account_followup/i18n/pl.po +++ b/addons/account_followup/i18n/pl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-12-12 17:49+0000\n" -"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) \n" +"PO-Revision-Date: 2014-04-04 19:44+0000\n" +"Last-Translator: Dariusz Żbikowski \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-27 06:16+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-05 05:30+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: account_followup #: model:email.template,subject:account_followup.email_template_account_followup_default @@ -109,7 +109,7 @@ msgstr "Kroki monitowania płatności" #. module: account_followup #: field:account_followup.print,email_body:0 msgid "Email Body" -msgstr "" +msgstr "Treść email" #. module: account_followup #: model:ir.actions.act_window,name:account_followup.action_account_followup_print @@ -403,7 +403,7 @@ msgstr "Monity o płatność" #. module: account_followup #: field:account_followup.followup.line,delay:0 msgid "Due Days" -msgstr "" +msgstr "Dni zwłoki" #. module: account_followup #: field:account.move.line,followup_line_id:0 @@ -419,7 +419,7 @@ msgstr "Ostatni monit o płatność" #. module: account_followup #: model:ir.ui.menu,name:account_followup.menu_manual_reconcile_followup msgid "Reconcile Invoices & Payments" -msgstr "" +msgstr "Uzgadnianie Faktur i Płatności" #. module: account_followup #: model:ir.ui.menu,name:account_followup.account_followup_s @@ -429,7 +429,7 @@ msgstr "Wykonaj manualnie monit o płatność" #. module: account_followup #: report:account_followup.followup.print:0 msgid "Li." -msgstr "" +msgstr "Sp." #. module: account_followup #: field:account_followup.print,email_conf:0 @@ -499,6 +499,7 @@ msgstr "Monitowanie płatności" #, python-format msgid "Email not sent because of email address of partner not filled in" msgstr "" +"Email nie został wysłany ponieważ adres email partnera nie został wypełniony" #. module: account_followup #: model:ir.model,name:account_followup.model_account_followup_followup @@ -511,6 +512,8 @@ msgid "" "Optionally you can assign a user to this field, which will make him " "responsible for the action." msgstr "" +"Opcjonalnie możesz przypisać użytkownika do tego pola, który stanie się " +"odpowiedzialny za tę akcję." #. module: account_followup #: model:ir.model,name:account_followup.model_account_followup_sending_results @@ -528,7 +531,7 @@ msgstr "" #: code:addons/account_followup/wizard/account_followup_print.py:172 #, python-format msgid " manual action(s) assigned:" -msgstr "" +msgstr " ręczna akcja przypisana do:" #. module: account_followup #: view:res.partner:0 @@ -548,13 +551,13 @@ msgstr "Przeszukaj monity o płatność" #. module: account_followup #: view:res.partner:0 msgid "Account Move line" -msgstr "" +msgstr "Pozycja zapisu" #. module: account_followup #: code:addons/account_followup/wizard/account_followup_print.py:237 #, python-format msgid "Send Letters and Emails: Actions Summary" -msgstr "" +msgstr "Listy i Email: Podsumowanie akcji" #. module: account_followup #: view:account_followup.print:0 @@ -916,7 +919,7 @@ msgstr "" #. module: account_followup #: view:res.partner:0 msgid "Responsible" -msgstr "" +msgstr "Odpowiedzialny" #. module: account_followup #: model:ir.ui.menu,name:account_followup.menu_finance_followup @@ -945,7 +948,7 @@ msgstr "Działanie monitowania płatności" #. module: account_followup #: view:account_followup.stat:0 msgid "Including journal entries marked as a litigation" -msgstr "" +msgstr "Załącz pozycje dziennika oznaczone jako sporne" #. module: account_followup #: report:account_followup.followup.print:0 diff --git a/addons/auth_signup/i18n/pl.po b/addons/auth_signup/i18n/pl.po index ebbff79b333..a95f5b3738f 100644 --- a/addons/auth_signup/i18n/pl.po +++ b/addons/auth_signup/i18n/pl.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-12-21 17:05+0000\n" -"PO-Revision-Date: 2012-12-12 18:01+0000\n" -"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) \n" +"PO-Revision-Date: 2014-04-04 19:12+0000\n" +"Last-Translator: Dariusz Żbikowski \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-27 07:32+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-05 05:30+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: auth_signup #: field:res.partner,signup_type:0 @@ -80,7 +80,7 @@ msgstr "Wprowadź hasło o potwierdź je" #. module: auth_signup #: view:res.users:0 msgid "Send an email to the user to (re)set their password." -msgstr "" +msgstr "Wyślij email do użytkownika w celu zresetowania hasła" #. module: auth_signup #. openerp-web @@ -99,7 +99,7 @@ msgstr "Nowy" #: code:addons/auth_signup/res_users.py:258 #, python-format msgid "Mail sent to:" -msgstr "" +msgstr "Mail wysłano do:" #. module: auth_signup #: field:res.users,state:0 @@ -191,7 +191,7 @@ msgstr "Proszę wprowadź nazwę użytkownika lub adres email." #. module: auth_signup #: selection:res.users,state:0 msgid "Resetting Password" -msgstr "" +msgstr "Resetowane hasło" #. module: auth_signup #. openerp-web diff --git a/addons/hr_holidays/i18n/pl.po b/addons/hr_holidays/i18n/pl.po index 180ca272e3b..8473fa6ee49 100644 --- a/addons/hr_holidays/i18n/pl.po +++ b/addons/hr_holidays/i18n/pl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:04+0000\n" -"PO-Revision-Date: 2013-06-22 10:54+0000\n" +"PO-Revision-Date: 2014-04-04 19:21+0000\n" "Last-Translator: Dariusz Kubiak \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-27 06:53+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-05 05:30+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: hr_holidays #: selection:hr.holidays.status,color_name:0 @@ -680,7 +680,7 @@ msgstr "Podsumowanie" #. module: hr_holidays #: model:hr.holidays.status,name:hr_holidays.holiday_status_unpaid msgid "Unpaid" -msgstr "Bezpłatny" +msgstr "Urlop bezpłatny" #. module: hr_holidays #: xsl:holidays.summary:0 diff --git a/addons/mail/i18n/pl.po b/addons/mail/i18n/pl.po index e44e0a315b4..051e5bad35f 100644 --- a/addons/mail/i18n/pl.po +++ b/addons/mail/i18n/pl.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-12-21 17:04+0000\n" -"PO-Revision-Date: 2012-12-17 19:55+0000\n" -"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) \n" +"PO-Revision-Date: 2014-04-04 19:25+0000\n" +"Last-Translator: Dariusz Żbikowski \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-27 07:26+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-05 05:30+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: mail #: view:mail.followers:0 @@ -1363,7 +1363,7 @@ msgstr "Wiadomość Rich-text/HTML" #. module: mail #: view:mail.mail:0 msgid "Creation Month" -msgstr "Miesiąc tworzenia" +msgstr "Miesiąc utworzenia" #. module: mail #. openerp-web @@ -1509,7 +1509,7 @@ msgstr "" #: code:addons/mail/static/src/xml/mail.xml:213 #, python-format msgid "Please, wait while the file is uploading." -msgstr "" +msgstr "Poczekaj, aż plik zostanie załadowany." #. module: mail #: view:mail.group:0 diff --git a/addons/procurement/i18n/pl.po b/addons/procurement/i18n/pl.po index b503cce0ce3..8cb301665df 100644 --- a/addons/procurement/i18n/pl.po +++ b/addons/procurement/i18n/pl.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-12-21 17:06+0000\n" -"PO-Revision-Date: 2012-12-16 20:56+0000\n" -"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) \n" +"PO-Revision-Date: 2014-04-04 19:08+0000\n" +"Last-Translator: Dariusz Żbikowski \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-27 07:18+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-05 05:30+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: procurement #: model:ir.ui.menu,name:procurement.menu_stock_sched @@ -493,7 +493,7 @@ msgstr "Nieprzeczytane wiadomości" #. module: procurement #: selection:mrp.property,composition:0 msgid "plus" -msgstr "" +msgstr "plus" #. module: procurement #: help:procurement.order,state:0 @@ -515,6 +515,8 @@ msgid "" "If the active field is set to False, it will allow you to hide the " "orderpoint without removing it." msgstr "" +"Jeśli pole nie jest aktywne, pozwoli ci ukryć punkt zamawiania bez jego " +"kasowania." #. module: procurement #: view:product.product:0 @@ -547,8 +549,8 @@ msgid "" "You have to select a product unit of measure in the same category than the " "default unit of measure of the product" msgstr "" -"Musisz wybrać jednostkę miary z tej samej kategorii do domyślna jednostka " -"produktu." +"Musisz wybrać jednostkę miary z tej samej kategorii, co domyślna jednostka " +"produktu" #. module: procurement #: view:procurement.order:0 @@ -589,7 +591,7 @@ msgstr "Projekt" #: model:ir.ui.menu,name:procurement.menu_stock_proc_schedulers #: view:procurement.order.compute.all:0 msgid "Run Schedulers" -msgstr "uruchom planowanie" +msgstr "Uruchom planowanie" #. module: procurement #: view:procurement.order.compute:0 @@ -1027,7 +1029,7 @@ msgstr "Zapotrzbowanie uruchomione późno" #. module: procurement #: selection:mrp.property,composition:0 msgid "min" -msgstr "" +msgstr "min." #. module: procurement #: view:make.procurement:0 diff --git a/addons/stock/i18n/pl.po b/addons/stock/i18n/pl.po index 46fc140db91..66cb0cb868c 100644 --- a/addons/stock/i18n/pl.po +++ b/addons/stock/i18n/pl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:04+0000\n" -"PO-Revision-Date: 2012-12-22 15:56+0000\n" -"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) \n" +"PO-Revision-Date: 2014-04-04 19:47+0000\n" +"Last-Translator: Dariusz Żbikowski \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-27 05:52+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-05 05:30+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: stock #: field:stock.inventory.line.split,line_exist_ids:0 @@ -1420,7 +1420,7 @@ msgstr "Zapas fizyczny" #: code:addons/stock/wizard/stock_move.py:214 #, python-format msgid "Processing Error!" -msgstr "" +msgstr "Błąd przetwarzania!" #. module: stock #: help:stock.location,chained_company_id:0 From ec975900def49e06ebed8a92224147f5955912c4 Mon Sep 17 00:00:00 2001 From: Kersten Jeremy Date: Sat, 5 Apr 2014 12:42:54 +0200 Subject: [PATCH 341/483] [FIX] Typo - add missing label for checkbox speaker. bzr revid: jke@openerp.com-20140405104254-2rpf239vb6wvk8hd --- addons/event/res_partner_view.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/event/res_partner_view.xml b/addons/event/res_partner_view.xml index 7e97f80e30d..19eb2517131 100644 --- a/addons/event/res_partner_view.xml +++ b/addons/event/res_partner_view.xml @@ -10,6 +10,7 @@ + From f7ea5d00e1d1182794029ec1c9708cbc25de4634 Mon Sep 17 00:00:00 2001 From: Kersten Jeremy Date: Sat, 5 Apr 2014 14:53:20 +0200 Subject: [PATCH 342/483] [FIX] base_vat : improve log when a vat code is not valid to display which code is wrong in constraint message. bzr revid: jke@openerp.com-20140405125320-ps1atos24yyc2uwj --- addons/base_vat/base_vat.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/base_vat/base_vat.py b/addons/base_vat/base_vat.py index e9ecf70b39b..9b3862508b0 100644 --- a/addons/base_vat/base_vat.py +++ b/addons/base_vat/base_vat.py @@ -126,6 +126,7 @@ class res_partner(osv.osv): continue vat_country, vat_number = self._split_vat(partner.vat) if not check_func(cr, uid, vat_country, vat_number, context=context): + _logger.info(_("Importing VAT Number [%s] is not valid !" % vat_number)) return False return True @@ -149,7 +150,9 @@ class res_partner(osv.osv): vat_no = "'CC##' (CC=Country Code, ##=VAT Number)" if default_vat_check(vat_country, vat_number): vat_no = _ref_vat[vat_country] if vat_country in _ref_vat else vat_no - return '\n' + _('This VAT number does not seem to be valid.\nNote: the expected format is %s') % vat_no + #Retrieve the current partner for wich the VAT is not valid + error_partner = self.browse(cr, uid, ids, context=context) + return '\n' + _('The VAT number [%s] for partner [%s] does not seem to be valid. \nNote: the expected format is %s') % (error_partner[0].vat, error_partner[0].name, vat_no) _constraints = [(check_vat, _construct_constraint_msg, ["vat"])] From de380aa914588a9c81fc1ef3e083ec42d8c84fd5 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Sun, 6 Apr 2014 15:25:19 +0200 Subject: [PATCH 343/483] [IMP] button snippet bzr revid: fp@tinyerp.com-20140406132519-eookdnec20c6sg20 --- addons/website/views/snippets.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml index 0df57080b99..3e27ffb227f 100644 --- a/addons/website/views/snippets.xml +++ b/addons/website/views/snippets.xml @@ -511,13 +511,13 @@ Button -
+
-
+

50,000+ companies run Odoo to grow their businesses. -

+

Join us and make your company a better place.

From bb8560f779459dc9231f0091cf88d05b01f959cc Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of openerp <> Date: Mon, 7 Apr 2014 06:53:16 +0000 Subject: [PATCH 344/483] Launchpad automatic translations update. bzr revid: launchpad_translations_on_behalf_of_openerp-20140405061904-60l019fp9qbl890t bzr revid: launchpad_translations_on_behalf_of_openerp-20140406065319-1cr9ypow2w870fbo bzr revid: launchpad_translations_on_behalf_of_openerp-20140407065316-8z3pm4a79uff45z5 --- addons/account/i18n/de.po | 12 +- addons/account/i18n/nl.po | 8 +- addons/account/i18n/sl.po | 8 +- addons/account_budget/i18n/de.po | 26 +- addons/account_followup/i18n/de.po | 10 +- addons/account_payment/i18n/de.po | 10 +- addons/account_voucher/i18n/de.po | 12 +- .../analytic_contract_hr_expense/i18n/de.po | 8 +- addons/analytic_user_function/i18n/hr.po | 26 +- addons/email_template/i18n/de.po | 10 +- addons/hr/i18n/am.po | 8 +- addons/hr/i18n/sv.po | 2 +- addons/hr_attendance/i18n/sv.po | 2 +- addons/hr_expense/i18n/de.po | 13 +- addons/hr_expense/i18n/es.po | 10 +- addons/hr_expense/i18n/sv.po | 2 +- addons/hr_recruitment/i18n/sv.po | 88 ++++-- addons/l10n_be/i18n/nl_BE.po | 273 +++++++++--------- addons/purchase/i18n/ar.po | 10 +- 19 files changed, 303 insertions(+), 235 deletions(-) diff --git a/addons/account/i18n/de.po b/addons/account/i18n/de.po index 861b0ae2929..1af16cc0eec 100644 --- a/addons/account/i18n/de.po +++ b/addons/account/i18n/de.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-14 22:29+0000\n" -"PO-Revision-Date: 2014-01-25 11:32+0000\n" -"Last-Translator: Ralf Hilgenstock \n" +"PO-Revision-Date: 2014-04-05 20:42+0000\n" +"Last-Translator: Rudolf Schnapka \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-01-26 05:15+0000\n" -"X-Generator: Launchpad (build 16914)\n" +"X-Launchpad-Export-Date: 2014-04-06 06:52+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: account #: model:process.transition,name:account.process_transition_supplierreconcilepaid0 @@ -2165,7 +2165,7 @@ msgstr "Rechnung bestätigt" #. module: account #: field:account.config.settings,module_account_check_writing:0 msgid "Pay your suppliers by check" -msgstr "" +msgstr "Lieferantenzahlung per Scheck" #. module: account #: field:account.move.line.reconcile,credit:0 @@ -10850,7 +10850,7 @@ msgstr "" #. module: account #: field:account.bank.statement.line,name:0 msgid "OBI" -msgstr "" +msgstr "Zweck" #. module: account #: help:res.partner,property_account_payable:0 diff --git a/addons/account/i18n/nl.po b/addons/account/i18n/nl.po index ed8418b88ee..2ef093ec17e 100644 --- a/addons/account/i18n/nl.po +++ b/addons/account/i18n/nl.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-14 22:29+0000\n" -"PO-Revision-Date: 2014-03-30 11:13+0000\n" +"PO-Revision-Date: 2014-04-05 08:09+0000\n" "Last-Translator: Erwin van der Ploeg (BAS Solutions) \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-31 06:39+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-06 06:52+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: account #: model:process.transition,name:account.process_transition_supplierreconcilepaid0 @@ -5062,7 +5062,7 @@ msgstr "Rek. type" #. module: account #: selection:account.journal,type:0 msgid "Bank and Checks" -msgstr "Bank en Giro." +msgstr "Bank en Giro" #. module: account #: field:account.account.template,note:0 diff --git a/addons/account/i18n/sl.po b/addons/account/i18n/sl.po index 5aa3cf8f9c8..540bcb7c74c 100644 --- a/addons/account/i18n/sl.po +++ b/addons/account/i18n/sl.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-14 22:29+0000\n" -"PO-Revision-Date: 2013-12-07 07:36+0000\n" +"PO-Revision-Date: 2014-04-04 11:12+0000\n" "Last-Translator: Dušan Laznik (Mentis) \n" "Language-Team: Slovenian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-12-08 05:46+0000\n" -"X-Generator: Launchpad (build 16869)\n" +"X-Launchpad-Export-Date: 2014-04-05 06:18+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: account #: model:process.transition,name:account.process_transition_supplierreconcilepaid0 @@ -4884,7 +4884,7 @@ msgstr "Zaključek poslovnega leta" #. module: account #: selection:account.move.line,state:0 msgid "Balanced" -msgstr "Uklajeno" +msgstr "Usklajeno" #. module: account #: model:process.node,note:account.process_node_importinvoice0 diff --git a/addons/account_budget/i18n/de.po b/addons/account_budget/i18n/de.po index 08bf459b6e7..82f184be2d3 100644 --- a/addons/account_budget/i18n/de.po +++ b/addons/account_budget/i18n/de.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2014-01-25 15:28+0000\n" -"Last-Translator: Ralf Hilgenstock \n" +"PO-Revision-Date: 2014-04-05 21:37+0000\n" +"Last-Translator: Rudolf Schnapka \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-01-26 05:15+0000\n" -"X-Generator: Launchpad (build 16914)\n" +"X-Launchpad-Export-Date: 2014-04-06 06:52+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: account_budget #: view:account.budget.analytic:0 @@ -147,6 +147,24 @@ msgid "" "

\n" " " msgstr "" +"

\n" +" Klicken um neues Budget festzusetzen.\n" +"

\n" +" Ein Budget ist eine Vorhersage über erwartete Einnahmen und/ \n" +" oder Ausgaben des Unternehmens in einem zukünftigen \n" +" Zeitraum. Ein Budget wird für bestimmte Finanzkonten oder \n" +" Kostenstellen festgelegt.\n" +" (Kostenstellen können Projekte, Abteilungen, Warengruppen, etc. \n" +" repräsentieren.)\n" +"

\n" +" Durch das Nachverfolgen Ihres Geldes, ist eine übermäßige\n" +" Belastung unwahrscheinlicher und die Erreichung Ihrer\n" +" finanziellen Ziele wahrscheinlicher. Legen Sie Ihre Budgets \n" +" durch Abschätzung der Erlöse je Kostenstelle fest und\n" +" überwachen Sie die Entwicklung an Hand der Ist-Zahlen\n" +" der entsprechenden Periode.\n" +"

\n" +" " #. module: account_budget #: report:account.budget:0 diff --git a/addons/account_followup/i18n/de.po b/addons/account_followup/i18n/de.po index 7398a3c4334..a32ede49919 100644 --- a/addons/account_followup/i18n/de.po +++ b/addons/account_followup/i18n/de.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2014-01-25 15:54+0000\n" +"PO-Revision-Date: 2014-04-05 21:40+0000\n" "Last-Translator: Ralf Hilgenstock \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-01-26 05:15+0000\n" -"X-Generator: Launchpad (build 16914)\n" +"X-Launchpad-Export-Date: 2014-04-06 06:53+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: account_followup #: model:email.template,subject:account_followup.email_template_account_followup_default @@ -901,7 +901,7 @@ msgstr "Letzte Mahnung" #. module: account_followup #: view:account_followup.sending.results:0 msgid "Download Letters" -msgstr "Herunterladen Abschreiben" +msgstr "Schreiben herunterladen" #. module: account_followup #: field:account_followup.print,company_id:0 @@ -986,7 +986,7 @@ msgstr "E-Mail senden" #. module: account_followup #: field:account_followup.stat,credit:0 msgid "Credit" -msgstr "Punkte" +msgstr "Kredit" #. module: account_followup #: field:res.partner,payment_amount_overdue:0 diff --git a/addons/account_payment/i18n/de.po b/addons/account_payment/i18n/de.po index 79ec3aa35f2..f0261cd72b9 100644 --- a/addons/account_payment/i18n/de.po +++ b/addons/account_payment/i18n/de.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2014-01-25 16:16+0000\n" +"PO-Revision-Date: 2014-04-05 21:42+0000\n" "Last-Translator: Ralf Hilgenstock \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-01-26 05:15+0000\n" -"X-Generator: Launchpad (build 16914)\n" +"X-Launchpad-Export-Date: 2014-04-06 06:53+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: account_payment #: model:ir.actions.act_window,help:account_payment.action_payment_order_tree @@ -305,7 +305,7 @@ msgstr "Erzeugt" #. module: account_payment #: view:payment.order:0 msgid "Select Invoices to Pay" -msgstr "Wähle Rechnungen" +msgstr "Rechnungen zur Zahlung wählen" #. module: account_payment #: view:payment.line:0 @@ -320,7 +320,7 @@ msgstr "Zahlungsvorschlag verbuchen" #. module: account_payment #: field:payment.line,state:0 msgid "Communication Type" -msgstr "Betreffzeile Empfänger" +msgstr "Kommunikationsart" #. module: account_payment #: field:payment.line,partner_id:0 diff --git a/addons/account_voucher/i18n/de.po b/addons/account_voucher/i18n/de.po index a0450200c49..d95bc7ad97b 100644 --- a/addons/account_voucher/i18n/de.po +++ b/addons/account_voucher/i18n/de.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2014-01-27 06:29+0000\n" -"Last-Translator: Ralf Hilgenstock \n" +"PO-Revision-Date: 2014-04-05 21:45+0000\n" +"Last-Translator: Rudolf Schnapka \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-01-28 07:02+0000\n" -"X-Generator: Launchpad (build 16914)\n" +"X-Launchpad-Export-Date: 2014-04-06 06:53+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: account_voucher #: field:account.bank.statement.line,voucher_id:0 @@ -123,7 +123,9 @@ msgstr "Zuordnung" msgid "" "This sentence helps you to know how to specify the payment rate by giving " "you the direct effect it has" -msgstr "Dieser Satz hilft dabei, die spezifische Payment Rate festzulegen." +msgstr "" +"Dieser Satz hilft dabei, die richtige Zahlweise auszuwählen, indem die " +"Auswirkung direkt dargestellt wird." #. module: account_voucher #: view:sale.receipt.report:0 diff --git a/addons/analytic_contract_hr_expense/i18n/de.po b/addons/analytic_contract_hr_expense/i18n/de.po index f53eca6e932..b16dee1b812 100644 --- a/addons/analytic_contract_hr_expense/i18n/de.po +++ b/addons/analytic_contract_hr_expense/i18n/de.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2014-01-26 16:25+0000\n" +"PO-Revision-Date: 2014-04-05 21:49+0000\n" "Last-Translator: Ralf Hilgenstock \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-01-27 05:45+0000\n" -"X-Generator: Launchpad (build 16914)\n" +"X-Launchpad-Export-Date: 2014-04-06 06:53+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: analytic_contract_hr_expense #: view:account.analytic.account:0 @@ -63,7 +63,7 @@ msgstr "Spesen Abrechnung zu %s" #: code:addons/analytic_contract_hr_expense/analytic_contract_hr_expense.py:136 #, python-format msgid "Expenses of %s" -msgstr "Spesen zu %s" +msgstr "Spesen von %s" #. module: analytic_contract_hr_expense #: view:account.analytic.account:0 diff --git a/addons/analytic_user_function/i18n/hr.po b/addons/analytic_user_function/i18n/hr.po index e0c6936c940..a91348289fd 100644 --- a/addons/analytic_user_function/i18n/hr.po +++ b/addons/analytic_user_function/i18n/hr.po @@ -8,19 +8,19 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2012-12-21 23:00+0000\n" -"Last-Translator: FULL NAME \n" +"PO-Revision-Date: 2014-04-04 17:23+0000\n" +"Last-Translator: Davor Bojkić \n" "Language-Team: Croatian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-21 06:00+0000\n" -"X-Generator: Launchpad (build 16831)\n" +"X-Launchpad-Export-Date: 2014-04-05 06:18+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: analytic_user_function #: model:ir.model,name:analytic_user_function.model_account_analytic_line msgid "Analytic Line" -msgstr "" +msgstr "Stavka analitike" #. module: analytic_user_function #: view:account.analytic.account:0 @@ -30,7 +30,7 @@ msgstr "" #. module: analytic_user_function #: field:analytic.user.funct.grid,product_id:0 msgid "Service" -msgstr "" +msgstr "Usluga" #. module: analytic_user_function #: model:ir.model,name:analytic_user_function.model_analytic_user_funct_grid @@ -40,30 +40,30 @@ msgstr "" #. module: analytic_user_function #: field:analytic.user.funct.grid,price:0 msgid "Price" -msgstr "" +msgstr "Cijena" #. module: analytic_user_function #: help:analytic.user.funct.grid,price:0 msgid "Price per hour for this user." -msgstr "" +msgstr "Cijena po satu za ovog korisnika" #. module: analytic_user_function #: field:analytic.user.funct.grid,account_id:0 #: model:ir.model,name:analytic_user_function.model_account_analytic_account msgid "Analytic Account" -msgstr "Analitički Konto" +msgstr "Konto analitike" #. module: analytic_user_function #: code:addons/analytic_user_function/analytic_user_function.py:106 #: code:addons/analytic_user_function/analytic_user_function.py:135 #, python-format msgid "Error!" -msgstr "" +msgstr "Greška!" #. module: analytic_user_function #: view:analytic.user.funct.grid:0 msgid "Invoicing Data" -msgstr "" +msgstr "Podaci računa" #. module: analytic_user_function #: field:account.analytic.account,user_product_ids:0 @@ -83,7 +83,7 @@ msgstr "" #. module: analytic_user_function #: field:analytic.user.funct.grid,uom_id:0 msgid "Unit of Measure" -msgstr "" +msgstr "Jedinica mjere" #. module: analytic_user_function #: code:addons/analytic_user_function/analytic_user_function.py:107 @@ -95,7 +95,7 @@ msgstr "nije definiran konto troška za ovaj proizvod: \"%s\" (id:%d)" #. module: analytic_user_function #: model:ir.model,name:analytic_user_function.model_hr_analytic_timesheet msgid "Timesheet Line" -msgstr "" +msgstr "Stavka evidencije rada" #. module: analytic_user_function #: view:account.analytic.account:0 diff --git a/addons/email_template/i18n/de.po b/addons/email_template/i18n/de.po index 68a052c34b0..d774f5d0f27 100644 --- a/addons/email_template/i18n/de.po +++ b/addons/email_template/i18n/de.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:37+0000\n" -"PO-Revision-Date: 2014-01-25 17:53+0000\n" -"Last-Translator: Ralf Hilgenstock \n" +"PO-Revision-Date: 2014-04-05 22:03+0000\n" +"Last-Translator: Rudolf Schnapka \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-01-26 05:15+0000\n" -"X-Generator: Launchpad (build 16914)\n" +"X-Launchpad-Export-Date: 2014-04-06 06:53+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: email_template #: field:email.template,email_from:0 @@ -494,7 +494,7 @@ msgstr "" #. module: email_template #: view:res.partner:0 msgid "Suppliers" -msgstr "" +msgstr "Lieferanten" #. module: email_template #: field:email.template,user_signature:0 diff --git a/addons/hr/i18n/am.po b/addons/hr/i18n/am.po index eca04d8af75..ef3a8d4cd65 100644 --- a/addons/hr/i18n/am.po +++ b/addons/hr/i18n/am.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2014-04-01 09:20+0000\n" +"PO-Revision-Date: 2014-04-05 07:23+0000\n" "Last-Translator: biniyam \n" "Language-Team: Amharic \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-04-02 06:44+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-06 06:53+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: hr #: model:process.node,name:hr.process_node_openerpuser0 @@ -522,7 +522,7 @@ msgstr "ተመሳሳይ ሰራተኞች" #. module: hr #: field:hr.config.settings,module_hr_holidays:0 msgid "Manage holidays, leaves and allocation requests" -msgstr "የባእልና ያረፍት ቀኖችን መቆጣጠር" +msgstr "የባዕልና የረፍት ቀኖች መቆጣጠር" #. module: hr #: field:hr.department,child_ids:0 diff --git a/addons/hr/i18n/sv.po b/addons/hr/i18n/sv.po index baa00de4231..54fd74a5609 100644 --- a/addons/hr/i18n/sv.po +++ b/addons/hr/i18n/sv.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-04-04 07:07+0000\n" +"X-Launchpad-Export-Date: 2014-04-05 06:18+0000\n" "X-Generator: Launchpad (build 16976)\n" #. module: hr diff --git a/addons/hr_attendance/i18n/sv.po b/addons/hr_attendance/i18n/sv.po index 3d4c87f2592..0d2c92066b9 100644 --- a/addons/hr_attendance/i18n/sv.po +++ b/addons/hr_attendance/i18n/sv.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-04-04 07:07+0000\n" +"X-Launchpad-Export-Date: 2014-04-05 06:18+0000\n" "X-Generator: Launchpad (build 16976)\n" #. module: hr_attendance diff --git a/addons/hr_expense/i18n/de.po b/addons/hr_expense/i18n/de.po index c21193bdb3b..18b400da9ff 100644 --- a/addons/hr_expense/i18n/de.po +++ b/addons/hr_expense/i18n/de.po @@ -8,15 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2013-01-06 21:00+0000\n" -"Last-Translator: Thorsten Vocks (OpenBig.org) \n" +"PO-Revision-Date: 2014-04-05 22:16+0000\n" +"Last-Translator: Rudolf Schnapka \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-21 06:11+0000\n" -"X-Generator: Launchpad (build 16831)\n" +"X-Launchpad-Export-Date: 2014-04-06 06:53+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: hr_expense #: view:hr.expense.expense:0 @@ -559,7 +558,7 @@ msgstr "Entwurf" #. module: hr_expense #: selection:hr.expense.expense,state:0 msgid "Paid" -msgstr "" +msgstr "Bezahlt" #. module: hr_expense #: code:addons/hr_expense/hr_expense.py:353 @@ -695,7 +694,7 @@ msgstr "Zusammenfassung" #. module: hr_expense #: model:ir.model,name:hr_expense.model_account_move_line msgid "Journal Items" -msgstr "" +msgstr "Journalbuchungen" #. module: hr_expense #: model:product.template,name:hr_expense.car_travel_product_template diff --git a/addons/hr_expense/i18n/es.po b/addons/hr_expense/i18n/es.po index 4917edcc801..6980b0145f8 100644 --- a/addons/hr_expense/i18n/es.po +++ b/addons/hr_expense/i18n/es.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2013-06-18 07:37+0000\n" +"PO-Revision-Date: 2014-04-04 18:02+0000\n" "Last-Translator: Pedro Manuel Baeza \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-21 06:11+0000\n" -"X-Generator: Launchpad (build 16831)\n" +"X-Launchpad-Export-Date: 2014-04-05 06:18+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: hr_expense #: view:hr.expense.expense:0 @@ -201,7 +201,7 @@ msgstr "" #. module: hr_expense #: view:hr.expense.expense:0 msgid "Open Accounting Entries" -msgstr "Apuntes abiertos" +msgstr "Abrir asiento contable" #. module: hr_expense #: help:hr.expense.expense,message_unread:0 @@ -943,7 +943,7 @@ msgstr "¡Sólo puede borrar gastos en borrador!" #. module: hr_expense #: field:hr.expense.expense,account_move_id:0 msgid "Ledger Posting" -msgstr "Fijado libro contable" +msgstr "Asiento contable" #. module: hr_expense #: model:process.transition,note:hr_expense.process_transition_approveinvoice0 diff --git a/addons/hr_expense/i18n/sv.po b/addons/hr_expense/i18n/sv.po index c3647221266..92f25fb5d77 100644 --- a/addons/hr_expense/i18n/sv.po +++ b/addons/hr_expense/i18n/sv.po @@ -14,7 +14,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-04-04 07:07+0000\n" +"X-Launchpad-Export-Date: 2014-04-05 06:18+0000\n" "X-Generator: Launchpad (build 16976)\n" #. module: hr_expense diff --git a/addons/hr_recruitment/i18n/sv.po b/addons/hr_recruitment/i18n/sv.po index 29b4c002738..42e24232510 100644 --- a/addons/hr_recruitment/i18n/sv.po +++ b/addons/hr_recruitment/i18n/sv.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2014-03-31 16:41+0000\n" +"PO-Revision-Date: 2014-04-04 08:45+0000\n" "Last-Translator: Anders Wallenquist \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-04-01 06:52+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-05 06:18+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: hr_recruitment #: help:hr.applicant,active:0 @@ -35,12 +35,12 @@ msgstr "Krav" #. module: hr_recruitment #: view:hr.applicant:0 msgid "Application Summary" -msgstr "" +msgstr "Summering av ansökningar" #. module: hr_recruitment #: view:hr.applicant:0 msgid "Start Interview" -msgstr "" +msgstr "Starta intervju" #. module: hr_recruitment #: view:hr.applicant:0 @@ -53,6 +53,8 @@ msgid "" "This stage is not visible, for example in status bar or kanban view, when " "there are no records in that stage to display." msgstr "" +"Denna etapp är inte synlig, t.ex. i statusfältet eller kanbanvyn, i de fall " +"etappen saknar poster." #. module: hr_recruitment #: model:hr.recruitment.degree,name:hr_recruitment.degree_graduate @@ -95,7 +97,7 @@ msgstr "Jobb" #. module: hr_recruitment #: view:hr.applicant:0 msgid "Extra advantages..." -msgstr "" +msgstr "Extra förmåner..." #. module: hr_recruitment #: view:hr.applicant:0 @@ -159,6 +161,22 @@ msgid "" "

\n" " " msgstr "" +"

\n" +" Klicka för att lägga till en ny jobbsökande.\n" +" \n" +" OpenERP hjälper dig att spåra de sökande i " +"rekryteringsprocessen\n" +" och följa upp all verksamhet: möten, intervjuer etc.\n" +"

\n" +" Om du ställer in den e-postbrygga sökande och deras " +"bifogade\n" +" CV skapas automatiskt när en e-post skickas till\n" +" jobs@yourcompany.com. Om du installerar dokumenthantering\n" +" moduler är alla meritförteckningar automatiskt indexerade, " +"så att du kan\n" +" enkelt söka igenom deras innehåll.\n" +"

\n" +" " #. module: hr_recruitment #: model:ir.actions.act_window,name:hr_recruitment.crm_case_categ0_act_job @@ -179,7 +197,7 @@ msgstr "anställd" #. module: hr_recruitment #: field:hr.config.settings,fetchmail_applicants:0 msgid "Create applicants from an incoming email account" -msgstr "" +msgstr "Skapa en ansökan från inkommande e-post" #. module: hr_recruitment #: view:hr.recruitment.report:0 @@ -351,7 +369,7 @@ msgstr "Rekryteringsstatistik" #. module: hr_recruitment #: view:hr.applicant:0 msgid "Print interview report" -msgstr "" +msgstr "Skriv ut intervjurapport" #. module: hr_recruitment #: view:hr.recruitment.report:0 @@ -408,6 +426,16 @@ msgid "" "

\n" " " msgstr "" +"

\n" +" Klicka för att lägga till en ny fas i rekryteringsprocessen.\n" +"

\n" +" Här definierar du dina etapper i rekryteringsprocessen, till " +"exempel:\n" +" kvalificeringssamtal, första intervjun, andra intervju, " +"avslag,\n" +" anställd.\n" +"

\n" +" " #. module: hr_recruitment #: view:hr.recruitment.report:0 @@ -547,6 +575,9 @@ msgid "" "the case needs to be reviewed then the status is set " "to 'Pending'." msgstr "" +"Statusen är satt till \"Utkast\", när ett ärende skapas. Om ärendet pågår är " +"status inställd på \"Öppna\". När fallet är över, sätts status till " +"\"Klar\". Om ärendet måste granskas är status \"Väntar\"." #. module: hr_recruitment #: selection:hr.recruitment.report,month:0 @@ -578,12 +609,12 @@ msgstr "Pågående" #. module: hr_recruitment #: view:hr.applicant:0 msgid "Hire & Create Employee" -msgstr "" +msgstr "Anställ och skapa medarbetare" #. module: hr_recruitment #: model:mail.message.subtype,description:hr_recruitment.mt_applicant_hired msgid "Applicant hired" -msgstr "" +msgstr "Sökande anställd" #. module: hr_recruitment #: view:hr.applicant:0 @@ -624,12 +655,12 @@ msgstr "Etiketter" #. module: hr_recruitment #: model:ir.model,name:hr_recruitment.model_hr_applicant_category msgid "Category of applicant" -msgstr "" +msgstr "Sökandekategori" #. module: hr_recruitment #: view:hr.applicant:0 msgid "e.g. Call for interview" -msgstr "" +msgstr "eg Kalla till intervju" #. module: hr_recruitment #: view:hr.recruitment.report:0 @@ -672,7 +703,7 @@ msgstr "eller" #. module: hr_recruitment #: model:mail.message.subtype,name:hr_recruitment.mt_applicant_refused msgid "Applicant Refused" -msgstr "" +msgstr "Sökande avslagen" #. module: hr_recruitment #: view:hr.applicant:0 @@ -782,7 +813,7 @@ msgstr "" #: code:addons/hr_recruitment/hr_recruitment.py:397 #, python-format msgid "Applicant created" -msgstr "" +msgstr "Sökande skapad" #. module: hr_recruitment #: view:hr.applicant:0 @@ -812,7 +843,7 @@ msgstr "Dagar i behandling" #. module: hr_recruitment #: field:hr.applicant,message_is_follower:0 msgid "Is a Follower" -msgstr "" +msgstr "Är en följare" #. module: hr_recruitment #: field:hr.recruitment.report,user_id:0 @@ -834,7 +865,7 @@ msgstr "Aktiva" #: view:hr.recruitment.report:0 #: field:hr.recruitment.report,nbr:0 msgid "# of Applications" -msgstr "" +msgstr "# sökanden" #. module: hr_recruitment #: model:ir.actions.act_window,help:hr_recruitment.hr_recruitment_stage_act @@ -848,6 +879,13 @@ msgid "" "

\n" " " msgstr "" +"

\n" +" Klicka för att lägga till en ny etapp i rekryteringsprocessen.\n" +"

\n" +" Glöm inte att ange vilken avdelning om din rekryteringsprocess\n" +" skiljer sig beroende på befattning.\n" +"

\n" +" " #. module: hr_recruitment #: field:hr.applicant,response:0 @@ -878,7 +916,7 @@ msgstr "januari" #: code:addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py:56 #, python-format msgid "A contact is already existing with the same name." -msgstr "" +msgstr "Kontakt med samma namn finns redan" #. module: hr_recruitment #: model:ir.actions.act_window,name:hr_recruitment.hr_recruitment_stage_form_installer @@ -1025,7 +1063,7 @@ msgstr "LinkedIn" #. module: hr_recruitment #: model:mail.message.subtype,name:hr_recruitment.mt_job_new_applicant msgid "New Applicant" -msgstr "" +msgstr "Ny sökande" #. module: hr_recruitment #: model:ir.model,name:hr_recruitment.model_hr_recruitment_stage @@ -1070,7 +1108,7 @@ msgstr "Beskrivning" #. module: hr_recruitment #: model:mail.message.subtype,name:hr_recruitment.mt_stage_changed msgid "Stage Changed" -msgstr "" +msgstr "Etapp ändrad" #. module: hr_recruitment #: selection:hr.recruitment.report,month:0 @@ -1125,7 +1163,7 @@ msgstr "Hänvisad av" #. module: hr_recruitment #: view:hr.applicant:0 msgid "Departement:" -msgstr "" +msgstr "Avdelning:" #. module: hr_recruitment #: selection:hr.applicant,priority:0 @@ -1141,7 +1179,7 @@ msgstr "Första intervjuen" #. module: hr_recruitment #: field:hr.recruitment.report,salary_prop_avg:0 msgid "Avg. Proposed Salary" -msgstr "" +msgstr "Erbjuden lön i medeltal" #. module: hr_recruitment #: view:hr.applicant:0 @@ -1199,7 +1237,7 @@ msgstr "Alias" #. module: hr_recruitment #: view:hr.applicant:0 msgid "Feedback of interviews..." -msgstr "" +msgstr "Återkoppling från intervjuer..." #. module: hr_recruitment #: view:hr.recruitment.report:0 @@ -1224,7 +1262,7 @@ msgstr "Meddelande- och kommunikationshistorik" #. module: hr_recruitment #: model:mail.message.subtype,description:hr_recruitment.mt_applicant_refused msgid "Applicant refused" -msgstr "" +msgstr "Ansökan avslagen" #. module: hr_recruitment #: field:hr.recruitment.stage,department_id:0 @@ -1255,7 +1293,7 @@ msgstr "Icke tilldelade rekryteringar" #. module: hr_recruitment #: model:ir.model,name:hr_recruitment.model_hr_config_settings msgid "hr.config.settings" -msgstr "" +msgstr "hr.config.settings" #. module: hr_recruitment #: help:hr.recruitment.stage,state:0 @@ -1289,4 +1327,4 @@ msgstr "" #. module: hr_recruitment #: view:hr.applicant:0 msgid "Schedule Interview" -msgstr "" +msgstr "Planerad intervju" diff --git a/addons/l10n_be/i18n/nl_BE.po b/addons/l10n_be/i18n/nl_BE.po index f9200a32c6c..bff7c4560a6 100644 --- a/addons/l10n_be/i18n/nl_BE.po +++ b/addons/l10n_be/i18n/nl_BE.po @@ -8,34 +8,34 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-11-24 02:53+0000\n" -"PO-Revision-Date: 2012-12-21 23:00+0000\n" -"Last-Translator: FULL NAME \n" +"PO-Revision-Date: 2014-04-04 16:52+0000\n" +"Last-Translator: Els Van Vossel (Foxy) \n" "Language-Team: Dutch (Belgium) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-21 06:15+0000\n" -"X-Generator: Launchpad (build 16831)\n" +"X-Launchpad-Export-Date: 2014-04-05 06:18+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_appro_mbsd3 msgid "Approvisionnements, marchandises, services et biens divers" -msgstr "" +msgstr "Handelsgoederen, grond- en hulpstoffen, diensten en diverse goederen" #. module: l10n_be #: field:vat.listing.clients,turnover:0 msgid "Base Amount" -msgstr "" +msgstr "Grondslag" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_rmunrationschargessocialesetpensions2 msgid "Rémunérations, charges sociales et pensions" -msgstr "" +msgstr "Bezoldigingen, sociale lasten en pensioenen" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_locationfinancementetdroitssimilaires2 msgid "Location-financement et droits similaires" -msgstr "" +msgstr "Leasing en soortgelijke rechten" #. module: l10n_be #: field:l1on_be.vat.declaration,tax_code_id:0 @@ -45,12 +45,12 @@ msgstr "Btw-code" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_produitsetchargesdexploitation1 msgid "Produits et charges d'exploitation" -msgstr "" +msgstr "Bedrijfsopbrengsten en bedrijfskosten" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_chargesfinancires1 msgid "Charges financières" -msgstr "" +msgstr "Financiële kosten" #. module: l10n_be #: view:l1on_be.vat.declaration:0 @@ -60,33 +60,33 @@ msgstr "" #: view:partner.vat.list:0 #: field:partner.vat.list,comments:0 msgid "Comments" -msgstr "" +msgstr "Opmerkingen" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_primesdmission2 msgid "Primes d'émission" -msgstr "" +msgstr "Uitgiftepremies" #. module: l10n_be #: model:ir.actions.act_window,name:l10n_be.action_account_report_be_pl msgid "Comptes de Charges" -msgstr "" +msgstr "Kostenrekeningen" #. module: l10n_be #: help:l1on_be.vat.declaration,ask_payment:0 msgid "It indicates whether a payment is to make or not?" -msgstr "" +msgstr "Duidt aan of er een betaling moet worden uitgevoerd." #. module: l10n_be #: model:ir.model,name:l10n_be.model_vat_listing_clients msgid "vat.listing.clients" -msgstr "" +msgstr "Klantenlisting" #. module: l10n_be #: model:ir.model,name:l10n_be.model_partner_vat_intra #: model:ir.ui.menu,name:l10n_be.l10_be_vat_intra msgid "Partner VAT Intra" -msgstr "Intracommunautaire opgave" +msgstr "Intracommunautaire aangifte" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_ammo2 @@ -94,16 +94,18 @@ msgid "" "Amortissements et réductions de valeur sur frais d'établissement, sur " "immobilisations incorporelles et corporelles" msgstr "" +"Afschrijvingen en waardeverminderingen op oprichtingskosten, op immateriële " +"en materiële vaste activa" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_prlvementssurlesimptsdiffrs1 msgid "Prélèvements sur les impôts différés" -msgstr "" +msgstr "Onttrekking aan de uitgestelde belastingen" #. module: l10n_be #: model:ir.ui.menu,name:l10n_be.menu_account_report_be_bs msgid "Balance Sheet" -msgstr "" +msgstr "Balans" #. module: l10n_be #: view:l1on_be.vat.declaration:0 @@ -115,33 +117,33 @@ msgstr "Bedrijf" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_immobilisationsincorporelles1 msgid "Immobilisations incorporelles" -msgstr "" +msgstr "Immateriële vaste activa" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_rservesimmunises3 msgid "Réserves immunisées" -msgstr "" +msgstr "Belastingvrije reserves" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:317 #, python-format msgid "No record to print." -msgstr "" +msgstr "Geen record om af te drukken" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_rserves2 msgid "Réserves" -msgstr "" +msgstr "Reserves" #. module: l10n_be #: help:partner.vat.intra,mand_id:0 msgid "Reference given by the Representative of the sending company." -msgstr "" +msgstr "Referentie van de vertegenwoordiger van de afzender" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_installationsmachinesetoutillage2 msgid "Installations, machines et outillage" -msgstr "" +msgstr "Installaties, machines en uitrusting" #. module: l10n_be #: help:l1on_be.vat.declaration,client_nihil:0 @@ -149,6 +151,9 @@ msgid "" "Tick this case only if it concerns only the last statement on the civil or " "cessation of activity: no clients to be included in the client listing." msgstr "" +"Schakel dit vakje enkel in als het gaat om de laatste aangifte van het jaar " +"of bij staking van de activiteiten: geen klanten op te nemen in " +"klantenlisting" #. module: l10n_be #: view:partner.vat.intra:0 @@ -158,13 +163,13 @@ msgstr "XML opslaan" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_placementsdetrsorerie1 msgid "Placements de trésorerie" -msgstr "" +msgstr "Geldbeleggingen" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_autresdettes6 #: model:account.financial.report,name:l10n_be.account_financial_report_autresdettes8 msgid "Autres dettes" -msgstr "" +msgstr "Overige schulden" #. module: l10n_be #: view:partner.vat.intra:0 @@ -178,14 +183,14 @@ msgstr "_XML maken" #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:111 #, python-format msgid "insufficient data!" -msgstr "" +msgstr "Onvoldoende gegevens" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:317 #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:116 #, python-format msgid "Error!" -msgstr "" +msgstr "Fout" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_account_vat_declaration.py:112 @@ -200,12 +205,12 @@ msgstr "" #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:246 #, python-format msgid "Insufficient Data!" -msgstr "" +msgstr "Onvoldoende gegevens" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_effetspayer4 msgid "Effets à payer" -msgstr "" +msgstr "Te betalen wissels" #. module: l10n_be #: view:l1on_be.vat.declaration:0 @@ -215,22 +220,22 @@ msgstr "Laatste aangifte" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_imptsdiffrs2 msgid "Impôts différés" -msgstr "" +msgstr "Uitgestelde belastingen" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_produitsfinanciers1 msgid "Produits financiers" -msgstr "" +msgstr "Financiële opbrengsten" #. module: l10n_be #: field:vat.listing.clients,vat:0 msgid "VAT" -msgstr "" +msgstr "Btw" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_transfertauximptsdiffrs1 msgid "Transfert aux impôts différés" -msgstr "" +msgstr "Overboeking naar de uitgestelde belastingen" #. module: l10n_be #: help:partner.vat.intra,period_ids:0 @@ -241,12 +246,12 @@ msgstr "Kies hier de periode(n) voor uw intracommunautaire opgave" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_stocketcommandesencoursdexcution1 msgid "Stock et commandes en cours d'exécution" -msgstr "" +msgstr "Voorraden en bestellingen in uitvoering" #. module: l10n_be #: field:partner.vat.intra,mand_id:0 msgid "Reference" -msgstr "" +msgstr "Referentie" #. module: l10n_be #: help:partner.vat.intra,period_code:0 @@ -274,12 +279,12 @@ msgstr "" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_dettesunanauplus2 msgid "Dettes à un an au plus" -msgstr "" +msgstr "Schulden op ten hoogste één jaar" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_imptssurlersultat1 msgid "Impôts sur le résultat" -msgstr "" +msgstr "Belastingen op het resultaat" #. module: l10n_be #: field:partner.vat.intra,period_code:0 @@ -290,7 +295,7 @@ msgstr "Periodecode" #: model:account.financial.report,name:l10n_be.account_financial_report_dettescommerciales5 #: model:account.financial.report,name:l10n_be.account_financial_report_dettescommerciales7 msgid "Dettes commerciales" -msgstr "" +msgstr "Handelsschulden" #. module: l10n_be #: field:partner.vat.intra,period_ids:0 @@ -301,33 +306,33 @@ msgstr "Periode(n)" #: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:94 #, python-format msgid "No data found for the selected year." -msgstr "" +msgstr "Geen gegevens gevonden voor het geselecteerde jaar." #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_actifsimmobilises0 msgid "ACTIFS IMMOBILISES" -msgstr "" +msgstr "VASTE ACTIVA" #. module: l10n_be #: model:account.account.type,name:l10n_be.user_type_stock msgid "Stock et Encours" -msgstr "Voorraden in bestelling" +msgstr "Voorraden en bestellingen in uitvoering" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_autrescrances3 #: model:account.financial.report,name:l10n_be.account_financial_report_autrescrances5 msgid "Autres créances" -msgstr "" +msgstr "Overige vorderingen" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_fraisdtablissements1 msgid "Frais d'établissements" -msgstr "" +msgstr "Oprichtingskosten" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_immobilisationsencoursetacomptesverss2 msgid "Immobilisations en cours et acomptes versés" -msgstr "" +msgstr "Activa in aanbouw en vooruitbetalingen" #. module: l10n_be #: model:account.account.type,name:l10n_be.user_type_view @@ -345,16 +350,18 @@ msgstr "Onvoldoende gegevens" msgid "" "You can remove clients/partners which you do not want to show in xml file" msgstr "" +"Klanten/relaties die u niet in het xml-bestand wil opnemen, kunt u " +"verwijderen" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_bnficepertedelexcercice1 msgid "Bénéfice (Perte) de l'excercice" -msgstr "" +msgstr "Winst (Verlies) van het boekjaar" #. module: l10n_be #: field:l1on_be.vat.declaration,client_nihil:0 msgid "Last Declaration, no clients in client listing" -msgstr "" +msgstr "Laatste aangifte, geen klanten in klantenlisting" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:258 @@ -368,19 +375,21 @@ msgid "" "Réductions de valeur sur stocks, sur commandes en cours d'exécution et sur " "créances commerciales: dotations (reprises)" msgstr "" +"Waardeverminderingen op voorraden, op bestellingen in uitvoering en op " +"handelsvorderingen: toevoegingen (terugnemingen)" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:116 #, python-format msgid "Period code is not valid." -msgstr "" +msgstr "Periodecode is niet geldig" #. module: l10n_be #: help:partner.vat.intra,no_vat:0 msgid "" "The Partner whose VAT number is not defined and they are not included in " "XML File." -msgstr "" +msgstr "Relaties zonder btw-nummer worden niet opgenomen in het xml-bestand." #. module: l10n_be #: field:partner.vat.intra,no_vat:0 @@ -391,23 +400,23 @@ msgstr "Relatie zonder btw" #: model:account.financial.report,name:l10n_be.account_financial_report_acomptesreussurcommandes6 #: model:account.financial.report,name:l10n_be.account_financial_report_acomptesreussurcommandes8 msgid "Acomptes reçus sur commandes" -msgstr "" +msgstr "Ontvangen vooruitbetalingen op bestellingen" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:123 #, python-format msgid "No partner has a VAT number asociated with him." -msgstr "" +msgstr "Geen enkele relatie heeft een btw-nummer" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_provisionspourrisquesetcharges2 msgid "Provisions pour risques et charges" -msgstr "" +msgstr "Voorzieningen voor risico's en kosten" #. module: l10n_be #: model:ir.actions.act_window,name:l10n_be.action_account_report_be_bs msgid "Bilan" -msgstr "" +msgstr "Balans" #. module: l10n_be #: field:l1on_be.vat.declaration,file_save:0 @@ -419,12 +428,12 @@ msgstr "Bestand opslaan" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_rservesimmunises3_A msgid "Pour actions propres" -msgstr "" +msgstr "Voor eigen aandelen" #. module: l10n_be #: help:l1on_be.vat.declaration,ask_restitution:0 msgid "It indicates whether a restitution is to make or not?" -msgstr "" +msgstr "Duidt aan of er een terugbetaling moet gebeuren" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:119 @@ -446,12 +455,12 @@ msgstr "Maakt een testbestand in xml" #. module: l10n_be #: view:partner.vat.intra:0 msgid "Intracom VAT Declaration" -msgstr "" +msgstr "Intracommunautaire aangifte" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_bnficeperteencours0 msgid "Bénéfice (Perte) en cours, non affecté(e)" -msgstr "" +msgstr "Te bestemmen winst (verlies) van het boekjaar" #. module: l10n_be #: view:partner.vat.intra:0 @@ -462,22 +471,22 @@ msgstr "_Voorbeeld" #: model:account.financial.report,name:l10n_be.account_financial_report_dettesfinancires5 #: model:account.financial.report,name:l10n_be.account_financial_report_dettesfinancires7 msgid "Dettes financières" -msgstr "" +msgstr "Financiële schulden" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_bnficereporte0 msgid "Bénéfice reporté" -msgstr "" +msgstr "Overgedragen winst" #. module: l10n_be #: help:partner.vat.intra,tax_code_id:0 msgid "Keep empty to use the user's company" -msgstr "" +msgstr "Leeg laten voor het bedrijf van de gebruiker" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_actif msgid "ACTIF" -msgstr "" +msgstr "ACTIVA" #. module: l10n_be #: field:partner.vat.intra,test_xml:0 @@ -487,7 +496,7 @@ msgstr "Test XML-bestand" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_dettes1 msgid "DETTES" -msgstr "" +msgstr "SCHULDEN" #. module: l10n_be #: view:l1on_be.vat.declaration:0 @@ -500,34 +509,34 @@ msgstr "Xml opslaan" #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:149 #, python-format msgid "No phone associated with the company." -msgstr "" +msgstr "Voor uw bedrijf is geen telefoonnummer ingesteld" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_dettesplusdunan2 msgid "Dettes à plus d'un an" -msgstr "" +msgstr "Schulden op meer dan één jaar" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_account_vat_declaration.py:87 #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:111 #, python-format msgid "No VAT number associated with your company." -msgstr "" +msgstr "Uw bedrijf heeft geen btw-nummer" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_rservesimmunises3_B msgid "Autres" -msgstr "" +msgstr "Overige" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_crancesplusdunan1 msgid "Créances à plus d'un an" -msgstr "" +msgstr "Vorderingen op meer dan één jaar" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_bnficepertedelexcerciceavantimpts1 msgid "Bénéfice (Perte) de l'excercice avant impôts" -msgstr "" +msgstr "Winst (Verlies) van het boekjaar vóór belasting" #. module: l10n_be #: view:partner.vat.intra:0 @@ -541,7 +550,7 @@ msgstr "Europese landen" #: view:partner.vat.intra:0 #: view:partner.vat.list:0 msgid "or" -msgstr "" +msgstr "of" #. module: l10n_be #: view:partner.vat.intra:0 @@ -552,54 +561,55 @@ msgstr "Intracommunautaire opgave" #: model:account.financial.report,name:l10n_be.account_financial_report_comptesdergularisation1 #: model:account.financial.report,name:l10n_be.account_financial_report_comptesdergularisation2 msgid "Comptes de régularisation" -msgstr "" +msgstr "Overlopende rekeningen" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_immobilisationscorporelles1 msgid "Immobilisations corporelles" -msgstr "" +msgstr "Materiële vaste activa" #. module: l10n_be #: field:vat.listing.clients,vat_amount:0 msgid "VAT Amount" -msgstr "" +msgstr "Btw-bedrag" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:246 #, python-format msgid "No vat number defined for %s." -msgstr "" +msgstr "Geen btw-nummer ingesteld voor %s." #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_bnficepertereporte2 msgid "Bénéfice (Perte) reporté(e)" -msgstr "" +msgstr "Overgedragen winst (verlies)" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_plusvaluesdervaluation2 msgid "Plus-values de réévaluation" -msgstr "" +msgstr "Herwaarderingsmeerwaarden" #. module: l10n_be #: model:ir.model,name:l10n_be.model_partner_vat_list msgid "partner.vat.list" -msgstr "" +msgstr "Jaarlijkse klantenlisting" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_rservelgale3 msgid "Réserve légale" -msgstr "" +msgstr "Wettelijke reserve" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_capitauxpropres1 msgid "CAPITAUX PROPRES" -msgstr "" +msgstr "EIGEN VERMOGEN" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:69 #, python-format msgid "No belgian contact with a VAT number in your database." msgstr "" +"Er is geen Belgische contactpersoon met een btw-nummer in uw database." #. module: l10n_be #: field:l1on_be.vat.declaration,msg:0 @@ -615,28 +625,28 @@ msgstr "Klanten" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_chargesexceptionnelles1 msgid "Charges exceptionnelles" -msgstr "" +msgstr "Uitzonderlijke kosten" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_chiffredaffaires3 msgid "Chiffre d'affaires" -msgstr "" +msgstr "Omzet" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_autreschargesdexploitation2 msgid "Autres charges d'exploitation" -msgstr "" +msgstr "Andere bedrijfskosten" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:296 #, python-format msgid "XML File has been Created" -msgstr "" +msgstr "XML-bestand is aangemaakt." #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_belgium_bs msgid "Belgium Balance Sheet" -msgstr "" +msgstr "BALANS NA WINSTVERDELING" #. module: l10n_be #: field:l1on_be.vat.declaration,ask_restitution:0 @@ -647,59 +657,59 @@ msgstr "Teruggave" #: model:account.financial.report,name:l10n_be.account_financial_report_prov_pr_chargesetdotations2 msgid "" "Provisions pour riques et charges: dotations (utilisations et reprises)" -msgstr "" +msgstr "Voorzieningen voor risico's en kosten: toevoegingen (terugnemingen)" #. module: l10n_be #: view:l1on_be.vat.declaration:0 msgid "Advanced Options" -msgstr "" +msgstr "Geavanceerde opties" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_produitsexceptionnels1 msgid "Produits exceptionnels" -msgstr "" +msgstr "Uitzonderlijke opbrengsten" #. module: l10n_be #: view:vat.listing.clients:0 msgid "VAT listing" -msgstr "" +msgstr "Jaarlijkse klantenlisting" #. module: l10n_be #: field:partner.vat.list,partner_ids:0 msgid "Clients" -msgstr "" +msgstr "Klanten" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_margebrutedexploitation2 msgid "Marge brute d'exploitation" -msgstr "" +msgstr "Brutomarge" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:265 #, python-format msgid "No data available for the client." -msgstr "" +msgstr "Geen gegevens beschikbaar voor de klant" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_etablissementsdecrdit4 msgid "Etablissements de crédit" -msgstr "" +msgstr "Kredietinstellingen" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_terrainsetconstructions2 msgid "Terrains et constructions" -msgstr "" +msgstr "Terreinen en gebouwen" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:69 #, python-format msgid "Error" -msgstr "" +msgstr "Fout" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_capitalsouscrit3 msgid "Capital souscrit" -msgstr "" +msgstr "Geplaatst kapitaal" #. module: l10n_be #: model:ir.actions.act_window,name:l10n_be.action_vat_intra @@ -709,12 +719,12 @@ msgstr "Intracommunautaire opgave" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_stocks2 msgid "Stocks" -msgstr "" +msgstr "Voorraden" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_valeursdisponibles1 msgid "Valeurs disponibles" -msgstr "" +msgstr "Liquide middelen" #. module: l10n_be #: field:l1on_be.vat.declaration,period_id:0 @@ -731,7 +741,7 @@ msgstr "Btw-aangifte" #: model:ir.actions.act_window,name:l10n_be.action_partner_vat_listing #: view:partner.vat:0 msgid "Partner VAT Listing" -msgstr "Intracommunautaire opgave" +msgstr "Jaarlijkse klantenlisting" #. module: l10n_be #: view:partner.vat.intra:0 @@ -741,7 +751,7 @@ msgstr "Algemene informatie" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_immobilisationsfinancires1 msgid "Immobilisations financières" -msgstr "" +msgstr "Financiële vaste activa" #. module: l10n_be #: view:partner.vat.intra:0 @@ -771,7 +781,7 @@ msgstr "Annuleren" #: code:addons/l10n_be/wizard/l10n_be_vat_intra.py:147 #, python-format msgid "No email address associated with the company." -msgstr "" +msgstr "Er is geen e-mailadres ingesteld voor uw bedrijf." #. module: l10n_be #: view:l1on_be.vat.declaration:0 @@ -782,12 +792,12 @@ msgstr "XML maken" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_pertereporte0 msgid "Perte reportée" -msgstr "" +msgstr "Overgedragen verlies" #. module: l10n_be #: field:vat.listing.clients,name:0 msgid "Client Name" -msgstr "" +msgstr "Klantennaam" #. module: l10n_be #: view:partner.vat.list:0 @@ -803,17 +813,17 @@ msgstr "Klanten bekijken" #: model:account.financial.report,name:l10n_be.account_financial_report_autresemprunts6 #: model:account.financial.report,name:l10n_be.account_financial_report_autresemprunts9 msgid "Autres emprunts" -msgstr "" +msgstr "Overige leningen" #. module: l10n_be #: model:ir.ui.menu,name:l10n_be.menu_account_report_be_pl msgid "Profit And Loss" -msgstr "" +msgstr "Winst en verlies" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_passif0 msgid "PASSIF" -msgstr "" +msgstr "PASSIVA" #. module: l10n_be #: view:partner.vat.list:0 @@ -823,17 +833,17 @@ msgstr "Afdrukken" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_fournisseurs4 msgid "Fournisseurs" -msgstr "" +msgstr "Leveranciers" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_commandesencoursdexcution2 msgid "Commandes en cours d'exécution" -msgstr "" +msgstr "Bestellingen in uitvoering" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_actifscirculants0 msgid "ACTIFS CIRCULANTS" -msgstr "" +msgstr "VLOTTENDE ACTIVA" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_capital2 @@ -851,32 +861,33 @@ msgstr "Bestand opslaan met '.xml'-extensie" #: model:account.financial.report,name:l10n_be.account_financial_report_dettesfiscalessalarialesetsociales3 msgid "Dettes fiscales, salariales et sociales" msgstr "" +"Schulden met betrekking tot belastingen, bezoldigingen en sociale lasten" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_autresimmobilisationscorporelles2 msgid "Autres immobilisations corporelles" -msgstr "" +msgstr "Overige materiële vaste activa" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_crancesunanauplus1 msgid "Créances à un an au plus" -msgstr "" +msgstr "Vorderingen op ten hoogste één jaar" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_impts4 msgid "Impôts" -msgstr "" +msgstr "Belastingen" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_charges_expl_pr_restruct2 msgid "" "Charges d'exploitation portées à l'actif au titre de frais de restructuration" -msgstr "" +msgstr "Als herstructureringskosten geactiveerde bedrijfskosten" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_rmunrationsetchargessociales4 msgid "Rémunérations et charges sociales" -msgstr "" +msgstr "Bezoldigingen en sociale lasten" #. module: l10n_be #: model:ir.ui.menu,name:l10n_be.partner_vat_listing @@ -886,7 +897,7 @@ msgstr "Jaarlijke klantenlisting" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_bnficepertecouranteavantimpts1 msgid "Bénéfice (Perte) courant(e) avant impôts" -msgstr "" +msgstr "Winst (Verlies) uit de gewone bedrijfsuitoefening vóór belasting" #. module: l10n_be #: view:partner.vat.intra:0 @@ -897,7 +908,7 @@ msgstr "Opmerking: " #: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:99 #, python-format msgid "Vat Listing" -msgstr "" +msgstr "Jaarlijkse klantenlisting" #. module: l10n_be #: model:ir.ui.menu,name:l10n_be.l10_be_vat_declaration @@ -909,7 +920,7 @@ msgstr "Periodieke btw-aangifte" #: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:64 #, python-format msgid "No data for the selected year." -msgstr "" +msgstr "Geen gegevens voor het gekozen jaar." #. module: l10n_be #: field:partner.vat,limit_amount:0 @@ -919,32 +930,32 @@ msgstr "Bestedingslimiet" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_provisionsetimpotsdifferes1 msgid "PROVISIONS ET IMPOTS DIFFERES" -msgstr "" +msgstr "VOORZIENINGEN EN UITGESTELDE BELASTINGEN" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_subsidesencapital2 msgid "Subsides en capital" -msgstr "" +msgstr "Kapitaalsubsidies" #. module: l10n_be #: view:partner.vat.list:0 msgid "Customer List" -msgstr "" +msgstr "Klantenlijst" #. module: l10n_be #: view:partner.vat.list:0 msgid "Annual Listing of VAT-Subjected Customers" -msgstr "" +msgstr "Jaarlijkse listing van btw-plichtige klanten" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_mobilieretmatrielroulant2 msgid "Mobilier et matériel roulant" -msgstr "" +msgstr "Meubilair en rollend materieel" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_capitalnonappel3 msgid "Capital non appelé" -msgstr "" +msgstr "Niet-opgevraagd kapitaal" #. module: l10n_be #: model:ir.ui.menu,name:l10n_be.menu_finance_belgian_statement @@ -954,18 +965,18 @@ msgstr "Belgische aangiften" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_belgiumpl0 msgid "Belgium P&L" -msgstr "" +msgstr "RESULTATENREKENING" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_crancescommerciales3 #: model:account.financial.report,name:l10n_be.account_financial_report_crancescommerciales5 msgid "Créances commerciales" -msgstr "" +msgstr "Handelsvorderingen" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_bnficepertedexploitation1 msgid "Bénéfice (Perte) d'exploitation" -msgstr "" +msgstr "Bedrijfswinst (Bedrijfsverlies)" #. module: l10n_be #: view:l1on_be.vat.declaration:0 @@ -975,18 +986,18 @@ msgstr "Periodieke btw-aangifte" #. module: l10n_be #: model:ir.model,name:l10n_be.model_partner_vat msgid "partner.vat" -msgstr "" +msgstr "Klantenlisting" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_dettesplusdunanchantdanslanne3 msgid "Dettes à plus d'un an échéant dans l'année" -msgstr "" +msgstr "Schulden op meer dan één jaar die binnen het jaar vervallen" #. module: l10n_be #: code:addons/l10n_be/wizard/l10n_be_partner_vat_listing.py:184 #, python-format msgid "No VAT number associated with the company." -msgstr "" +msgstr "Het bedrijf heeft geen btw-nummer" #. module: l10n_be #: field:l1on_be.vat.declaration,name:0 @@ -998,7 +1009,7 @@ msgstr "Bestandsnaam" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_etablissementcredits4 msgid "Etablissements de crédit, dettes de location-financement et assimilés" -msgstr "" +msgstr "Kredietinstellingen, leasingschulden en soortgelijke schulden" #. module: l10n_be #: field:l1on_be.vat.declaration,ask_payment:0 @@ -1013,14 +1024,14 @@ msgstr "Jaar" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_rservesindisponibles3 msgid "Réserves indisponibles" -msgstr "" +msgstr "Onbeschikbare reserves" #. module: l10n_be #: view:partner.vat.list:0 msgid "Free Comments to be Added to the Declaration" -msgstr "" +msgstr "Vrije opmerkingen m.b.t. de aangifte" #. module: l10n_be #: model:account.financial.report,name:l10n_be.account_financial_report_rservesdisponibles3 msgid "Réserves disponibles" -msgstr "" +msgstr "Beschikbare reserves" diff --git a/addons/purchase/i18n/ar.po b/addons/purchase/i18n/ar.po index 51d80c0a3b1..0d4afc162a1 100644 --- a/addons/purchase/i18n/ar.po +++ b/addons/purchase/i18n/ar.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2012-12-27 19:23+0000\n" -"Last-Translator: gehad shaat \n" +"PO-Revision-Date: 2014-04-06 09:15+0000\n" +"Last-Translator: Mohamed M. Hagag \n" "Language-Team: Arabic \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-11-21 06:30+0000\n" -"X-Generator: Launchpad (build 16831)\n" +"X-Launchpad-Export-Date: 2014-04-07 06:53+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: purchase #: model:res.groups,name:purchase.group_analytic_accounting @@ -887,7 +887,7 @@ msgstr "" #: model:ir.ui.menu,name:purchase.menu_purchase_config #: view:res.partner:0 msgid "Purchases" -msgstr "المشتريات" +msgstr "مشتريات" #. module: purchase #: view:purchase.report:0 From 26d62c4e55961799733e466d628c3f75a3afb92d Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 7 Apr 2014 09:32:47 +0200 Subject: [PATCH 345/483] [IMP] website: media editor: add feedback when the user try to remove a picture bzr revid: chm@openerp.com-20140407073247-davv0udxz5n5qx35 --- addons/website/static/src/js/website.editor.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 5ef53590345..bd17584c08b 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -1590,8 +1590,12 @@ try_remove: function (e) { var $help_block = this.$('.help-block').empty(); var self = this; - var id = parseInt($(e.target).data('id'), 10); + var $a = $(e.target); + var id = parseInt($a.data('id'), 10); var attachment = _.findWhere(this.records, {id: id}); + var $both = $a.parent().children(); + + $both.css({borderWidth: "5px", borderColor: "#f00"}); return openerp.jsonRpc('/web/dataset/call_kw', 'call', { model: 'ir.attachment', @@ -1607,6 +1611,7 @@ self.display_attachments(); return; } + $both.css({borderWidth: "", borderColor: ""}); $help_block.replaceWith(openerp.qweb.render( 'website.editor.dialog.image.existing.error', { views: prevented[id] From ee4b8795361b693d209817d85004b715bdd24d52 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 7 Apr 2014 09:49:22 +0200 Subject: [PATCH 346/483] [IMP] website: media editor: insert add button for image loader and fix try_remove don't remove image bzr revid: chm@openerp.com-20140407074922-zri6j4u9sw52nkkw --- addons/website/models/website.py | 2 +- addons/website/static/src/js/website.editor.js | 3 --- addons/website/static/src/xml/website.editor.xml | 9 +++++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/addons/website/models/website.py b/addons/website/models/website.py index a516f5cb96f..a0a6d1fb28b 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -638,7 +638,7 @@ class ir_attachment(osv.osv): # in-document URLs are html-escaped, a straight search will not # find them url = werkzeug.utils.escape(attachment.website_url) - ids = Views.search(cr, uid, [('arch', 'like', url)], context=context) + ids = Views.search(cr, uid, ["|", ('arch', 'like', '"%s"' % url), ('arch', 'like', "'%s'" % url)], context=context) if ids: removal_blocked_by[attachment.id] = Views.read( diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index bd17584c08b..bb24ad0bf74 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -1429,9 +1429,6 @@ this.$('input[type=file]').click(); }, 'change input[type=file]': 'file_selection', - 'change input[type=text]': function () { - this.$('form').submit(); - }, 'submit form': 'form_submit', //'change input.url': 'preview_image', //'change select.image-style': 'preview_image', diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index ca8a264ae6f..0f57dea33fe 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -153,14 +153,15 @@
— or — -
- - + +
+ +
-
+
'+ '
'); - $iframe.attr("style", this.$(this.media.$).attr("style")); $(this.media.$).replaceWith($iframe); this._super(); }, diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 0febdb2bedd..12c8d438a15 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -1438,10 +1438,25 @@ this._super(); this.$el.find(".clear-style").click(function (event) { - self.$target.removeClass("fa-spin").attr("style", null); - self.$target.transfo({ hide: true }); + self.$target.removeClass("fa-spin").attr("style", ""); + self.resetTransfo(); }); + this.$el.find(".style").click(function (event) { + var settings = self.$target.data("transfo").settings; + self.$target.transfo({ hide: (settings.hide = !settings.hide) }); + }); + + this.$overlay.find('.oe_snippet_clone, .oe_handles').addClass('hidden'); + + this.$overlay.find('[data-toggle="dropdown"]') + .on("mousedown", function () { + self.$target.transfo({ hide: true }); + }); + }, + resetTransfo: function () { + var self = this; + this.$target.transfo("destroy"); this.$target.transfo({ hide: true, callback: function () { @@ -1459,21 +1474,9 @@ self.$target.trigger("mouseover"); }) .mouseover(); - - this.$el.find(".style").click(function (event) { - var settings = self.$target.data("transfo").settings; - self.$target.transfo({ hide: (settings.hide = !settings.hide) }); - }); - - this.$overlay.find('.oe_snippet_clone, .oe_handles').addClass('hidden'); - - this.$overlay.find('[data-toggle="dropdown"]') - .on("mousedown", function () { - self.$target.transfo({ hide: true }); - }); }, onFocus : function () { - this.$target.transfo({ hide: true }); + this.resetTransfo(); }, onBlur : function () { this.$target.transfo({ hide: true }); @@ -1487,6 +1490,10 @@ website.snippet.start_animation(true, this.$target); + this.$target.on("saved", self, function (event, item) { + self.BuildingBlock.make_active($(item)); + }); + this.$el.find(".edition").click(function (event) { event.preventDefault(); event.stopPropagation(); diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index b8d8739f28d..b3012e5aa78 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -153,7 +153,7 @@
— or — - +
@@ -301,7 +301,7 @@
(Youtube, Vimeo, Dailymotion) - + Add
- +
  • Transform
  • - +
  • Spin
  • Clear Style
  • From 5be8fc620e805adfa50935bd90fc2d1dd1d7c6dc Mon Sep 17 00:00:00 2001 From: Kersten Jeremy Date: Mon, 7 Apr 2014 12:44:02 +0200 Subject: [PATCH 356/483] [FIX] Purchase - Make type 'order' as default invoice method in 'Purchase Settings'. Purchase by default use 'order', once an user update a parameter in 'Purchase Setting' without changing the default type (which by default was set to manual and not to order) the behavior is changed bzr revid: jke@openerp.com-20140407104402-nlswdttmkmxznap2 --- addons/purchase/res_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/purchase/res_config.py b/addons/purchase/res_config.py index ae3a172ce3c..2b85e8f34c2 100644 --- a/addons/purchase/res_config.py +++ b/addons/purchase/res_config.py @@ -63,7 +63,7 @@ Example: Product: this product is deprecated, do not purchase more than 5. } _defaults = { - 'default_invoice_method': 'manual', + 'default_invoice_method': 'order', } def onchange_purchase_analytic_plans(self, cr, uid, ids, module_purchase_analytic_plans, context=None): From 618a52116ceba58a70f117670cccf7df974d5de4 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 7 Apr 2014 12:56:04 +0200 Subject: [PATCH 357/483] [FIX] website: media transform: don't move center when rotation bzr revid: chm@openerp.com-20140407105604-t43kg143vqny8l5s --- addons/website/static/src/js/jQuery.transfo.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/website/static/src/js/jQuery.transfo.js b/addons/website/static/src/js/jQuery.transfo.js index 30580d84f78..074f7a5653a 100644 --- a/addons/website/static/src/js/jQuery.transfo.js +++ b/addons/website/static/src/js/jQuery.transfo.js @@ -199,6 +199,7 @@ OTHER DEALINGS IN THE SOFTWARE. "type": type, "pageX": event.pageX, "pageY": event.pageY, + "center": transfo.$center.offset(), }; } function _mouseUp($this, div, transfo, event) { @@ -209,7 +210,7 @@ OTHER DEALINGS IN THE SOFTWARE. event.preventDefault(); if (!transfo.active) return; var settings = transfo.settings; - var center = transfo.$center.offset(); + var center = transfo.active.center; var cdx = center.left - event.pageX; var cdy = center.top - event.pageY; From 5be9e5612f14916005c54226ee83e8510f3c12e4 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Mon, 7 Apr 2014 12:57:40 +0200 Subject: [PATCH 358/483] [FIX] browse()/browse_record: use iterables instead of forcing lists when constructing browse_lists This allows iterable list_class implementations bzr revid: odo@openerp.com-20140407105740-elbz311w5u9e8eos --- openerp/osv/orm.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 0a7849896fc..ac9e67b7876 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -466,7 +466,12 @@ class browse_record(object): else: new_data[field_name] = browse_null() elif field_column._type in ('one2many', 'many2many') and len(result_line[field_name]): - new_data[field_name] = self._list_class([browse_record(self._cr, self._uid, id, self._table.pool.get(field_column._obj), self._cache, context=self._context, list_class=self._list_class, fields_process=self._fields_process) for id in result_line[field_name]], self._context) + new_data[field_name] = self._list_class( + (browse_record(self._cr, self._uid, id, self._table.pool.get(field_column._obj), + self._cache, context=self._context, list_class=self._list_class, + fields_process=self._fields_process) + for id in result_line[field_name]), + context=self._context) elif field_column._type == 'reference': if result_line[field_name]: if isinstance(result_line[field_name], browse_record): @@ -4579,7 +4584,7 @@ class BaseModel(object): if isinstance(select, (int, long)): return browse_record(cr, uid, select, self, cache, context=context, list_class=self._list_class, fields_process=fields_process) elif isinstance(select, list): - return self._list_class([browse_record(cr, uid, id, self, cache, context=context, list_class=self._list_class, fields_process=fields_process) for id in select], context=context) + return self._list_class((browse_record(cr, uid, id, self, cache, context=context, list_class=self._list_class, fields_process=fields_process) for id in select), context=context) else: return browse_null() From 2372d305203deef40f19c075a8144113d3226a19 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Mon, 7 Apr 2014 13:09:19 +0200 Subject: [PATCH 359/483] [FIX] web: pass name arg to name_search, because it seems that one module (or more) wrongly overwritten the method bzr revid: dle@openerp.com-20140407110919-e0mvvhldkfe98qlq --- addons/web/controllers/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 84fd1ae93be..3015bb9c2e5 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -1211,7 +1211,7 @@ class DataSet(http.Controller): if method == 'read': names = dict(request.session.model(model).name_get(args[0], **kwargs)) else: - names = dict(request.session.model(model).name_search(args=args[0], **kwargs)) + names = dict(request.session.model(model).name_search('', args[0], **kwargs)) args[1].remove('display_name') records = getattr(request.session.model(model), method)(*args, **kwargs) for record in records: From ad93089bc2ab73f681bbdc0a2033d83e8f38b3b2 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 7 Apr 2014 13:15:06 +0200 Subject: [PATCH 360/483] [FIX] website: snippet editor add class from li[data-value] bzr revid: chm@openerp.com-20140407111506-jemffxbanul2yqbk --- addons/website/static/src/js/jQuery.transfo.js | 14 ++++++++++---- .../static/src/js/website.snippets.editor.js | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/addons/website/static/src/js/jQuery.transfo.js b/addons/website/static/src/js/jQuery.transfo.js index 074f7a5653a..6c82bfdb285 100644 --- a/addons/website/static/src/js/jQuery.transfo.js +++ b/addons/website/static/src/js/jQuery.transfo.js @@ -197,6 +197,8 @@ OTHER DEALINGS IN THE SOFTWARE. transfo.active = { "type": type, + "scalex": transfo.settings.scalex, + "scaley": transfo.settings.scaley, "pageX": event.pageX, "pageY": event.pageY, "center": transfo.$center.offset(), @@ -257,16 +259,20 @@ OTHER DEALINGS IN THE SOFTWARE. var angle = settings.angle * rad; var dx = cdx*Math.cos(angle) - cdy*Math.sin(-angle); var dy = - cdx*Math.sin(angle) + cdy*Math.cos(-angle); - if (transfo.active.type.indexOf("t") != -1) { + if (transfo.active.type.indexOf("t") != -1 && transfo.active.scaley > 0 || + transfo.active.type.indexOf("b") != -1 && transfo.active.scaley < 0) { settings.scaley = dy / (settings.height/2); } - if (transfo.active.type.indexOf("b") != -1) { + if (transfo.active.type.indexOf("b") != -1 && transfo.active.scaley > 0 || + transfo.active.type.indexOf("t") != -1 && transfo.active.scaley < 0) { settings.scaley = - dy / (settings.height/2); } - if (transfo.active.type.indexOf("l") != -1) { + if (transfo.active.type.indexOf("l") != -1 && transfo.active.scalex > 0 || + transfo.active.type.indexOf("r") != -1 && transfo.active.scalex < 0) { settings.scalex = dx / (settings.width/2); } - if (transfo.active.type.indexOf("r") != -1) { + if (transfo.active.type.indexOf("r") != -1 && transfo.active.scalex > 0 || + transfo.active.type.indexOf("l") != -1 && transfo.active.scalex < 0) { settings.scalex = - dx / (settings.width/2); } if (settings.scaley > 0 && settings.scaley < 0.05) settings.scaley = 0.05; diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 12c8d438a15..a6c387c73a0 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -743,6 +743,7 @@ this.set_active(); this.$el.find('li[data-value] a').on('mouseenter mouseleave click', _.bind(this._mouse, this)); + this.$el.not(':not([data-value])').find("a").on('mouseenter mouseleave click', _.bind(this._mouse, this)); this.$target.on('snippet-style-reset', _.bind(this.set_active, this)); this.start(); From d65b2cff231ecc426946d576b9ee10dbbbf7f98c Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 7 Apr 2014 13:23:30 +0200 Subject: [PATCH 361/483] [IMP] website: snippet editor, move resize button bzr revid: chm@openerp.com-20140407112330-6cj02vlmcs9gwxst --- addons/website/static/src/css/editor.css | 2 +- addons/website/static/src/css/snippets.css | 11 +++++++---- addons/website/static/src/css/snippets.sass | 13 ++++++++----- addons/website/static/src/xml/website.snippets.xml | 2 +- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/addons/website/static/src/css/editor.css b/addons/website/static/src/css/editor.css index 36de51db096..eb4c5b2851c 100644 --- a/addons/website/static/src/css/editor.css +++ b/addons/website/static/src/css/editor.css @@ -216,7 +216,7 @@ ul.oe_menu_editor .disclose { .modal .font-icons-icons { font-size: 2em; - max-height: 6em; + max-height: 9em; overflow: auto; } .modal .font-icons-icons .font-icons-icon { diff --git a/addons/website/static/src/css/snippets.css b/addons/website/static/src/css/snippets.css index 5d93edce80e..cbfca8be131 100644 --- a/addons/website/static/src/css/snippets.css +++ b/addons/website/static/src/css/snippets.css @@ -329,9 +329,10 @@ margin-left: -50px; } .oe_overlay .oe_handle.size .oe_handle_button { + position: relative; z-index: 3; text-align: center; - margin-left: -32px; + margin-left: -52px; margin-top: -10px; left: 0px; } @@ -343,15 +344,17 @@ box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7); } .oe_overlay .oe_handle.size .size { + position: absolute; width: 64px; cursor: row-resize; top: 9px; + margin-left: 52px; + padding: 0 5px; } .oe_overlay .oe_handle.size .auto_size { + position: absolute; width: 100px; - padding: 0 5px; - top: 1px; - margin-left: 36px; + top: 9px; cursor: pointer; } .oe_overlay .oe_handle.readonly { diff --git a/addons/website/static/src/css/snippets.sass b/addons/website/static/src/css/snippets.sass index 3f57ca4464d..40467897e26 100644 --- a/addons/website/static/src/css/snippets.sass +++ b/addons/website/static/src/css/snippets.sass @@ -241,9 +241,10 @@ bottom: -6px margin-left: -50px .oe_handle_button + position: relative z-index: 3 text-align: center - margin-left: -32px + margin-left: -52px margin-top: -10px left: 0px &:hover @@ -251,14 +252,16 @@ color: #fff +box-shadow(0 0 5px 3px rgba(255,255,255,.7)) .size + position: absolute width: 64px cursor: row-resize top: 9px - .auto_size - width: 100px + margin-left: 52px padding: 0 5px - top: 1px - margin-left: 36px + .auto_size + position: absolute + width: 100px + top: 9px cursor: pointer &.readonly cursor: auto !important diff --git a/addons/website/static/src/xml/website.snippets.xml b/addons/website/static/src/xml/website.snippets.xml index ea4ef3751fe..b1853f366b0 100644 --- a/addons/website/static/src/xml/website.snippets.xml +++ b/addons/website/static/src/xml/website.snippets.xml @@ -39,8 +39,8 @@
    -
    Resize
    Auto Resize
    +
    Resize
    From f042113b6fcf713b1dcb2803721268fe099ea5ad Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Mon, 7 Apr 2014 14:10:15 +0200 Subject: [PATCH 362/483] [FIX] res.font: re-introduce substitution for builtin PDF fonts This substitution was removed when res.font was implemented based on the idea that it would be best to allow the use of the real Helvetica/Times/Courier font if really required. However the builtin ones are always available and crippled when it comes to Unicode supports. Combined with the fact that many RML/SXW reports had Helvetica hardcoded, this breaks unicode reports for many users. This patch re-introduces a mapping to replace the builtin fonts by a few common and free alternatives (DejaVu, Liberation and Free font families). When an actual Helvetica/Times/Courier font is installed no substitution takes place for it, in the hope that it comes with decent unicode support. bzr revid: odo@openerp.com-20140407121015-jq1qmg0hfu0dt31s --- openerp/addons/base/res/res_font.py | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/openerp/addons/base/res/res_font.py b/openerp/addons/base/res/res_font.py index 47e49bf4d39..767fc3754c1 100644 --- a/openerp/addons/base/res/res_font.py +++ b/openerp/addons/base/res/res_font.py @@ -37,6 +37,23 @@ and Ubuntu distros, we have to override the search path, too. """ _logger = logging.getLogger(__name__) +# Alternatives for the [broken] builtin PDF fonts. Default order chosen to match +# the pre-v8 mapping from openerp.report.render.rml2pdf.customfonts.CustomTTFonts. +# Format: [ (BuiltinFontFamily, mode, [AlternativeFontName, ...]), ...] +BUILTIN_ALTERNATIVES = [ + ('Helvetica', "normal", ["DejaVuSans", "LiberationSans"]), + ('Helvetica', "bold", ["DejaVuSans-Bold", "LiberationSans-Bold"]), + ('Helvetica', 'italic', ["DejaVuSans-Oblique", "LiberationSans-Italic"]), + ('Helvetica', 'bolditalic', ["DejaVuSans-BoldOblique", "LiberationSans-BoldItalic"]), + ('Times', 'normal', ["LiberationSerif", "DejaVuSerif"]), + ('Times', 'bold', ["LiberationSerif-Bold", "DejaVuSerif-Bold"]), + ('Times', 'italic', ["LiberationSerif-Italic", "DejaVuSerif-Italic"]), + ('Times', 'bolditalic', ["LiberationSerif-BoldItalic", "DejaVuSerif-BoldItalic"]), + ('Courier', 'normal', ["FreeMono", "DejaVuSansMono"]), + ('Courier', 'bold', ["FreeMonoBold", "DejaVuSansMono-Bold"]), + ('Courier', 'italic', ["FreeMonoOblique", "DejaVuSansMono-Oblique"]), + ('Courier', 'bolditalic', ["FreeMonoBoldOblique", "DejaVuSansMono-BoldOblique"]), +] class res_font(osv.Model): _name = "res.font" @@ -113,9 +130,32 @@ class res_font(osv.Model): def _sync(self, cr, uid, context=None): """Set the customfonts.CustomTTFonts list to the content of the database""" customfonts.CustomTTFonts = [] + local_family_modes = set() + local_font_paths = {} found_fonts_ids = self.search(cr, uid, [('path', '!=', '/dev/null')], context=context) for font in self.browse(cr, uid, found_fonts_ids, context=None): + local_family_modes.add((font.family, font.mode)) + local_font_paths[font.name] = font.path customfonts.CustomTTFonts.append((font.family, font.name, font.path, font.mode)) + + # Attempt to remap the builtin fonts (Helvetica, Times, Courier) to better alternatives + # if available, because they only support a very small subset of unicode + # (missing 'č' for example) + for builtin_font_family, mode, alts in BUILTIN_ALTERNATIVES: + if (builtin_font_family, mode) not in local_family_modes: + # No local font exists with that name, try alternatives + for altern_font in alts: + if local_font_paths.get(altern_font): + altern_def = (builtin_font_family, altern_font, + local_font_paths[altern_font], mode) + customfonts.CustomTTFonts.append(altern_def) + _logger.debug("Builtin remapping %r", altern_def) + break + else: + _logger.warning("No local alternative found for builtin font `%s` (%s mode)." + "Consider installing the DejaVu fonts if you have problems " + "with unicode characters in RML reports", + builtin_font_family, mode) return True def clear_caches(self): From cee85a925a9240867f96978346b011eae7c08c6f Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Mon, 7 Apr 2014 14:50:50 +0200 Subject: [PATCH 363/483] [FIX] temporary fix for concurrent commit during test until we improve test cursor to emulate multiple cursors bzr revid: al@openerp.com-20140407125050-c4fq8okuya4jxj0w --- openerp/addons/base/res/res_users.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index b85c49abf15..772f7f7290b 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -394,7 +394,8 @@ class res_users(osv.osv): # (In this way, there is no opportunity to have two transactions # interleaving their cr.execute()..cr.commit() calls and have one # of them rolled back due to a concurrent access.) - cr.autocommit(True) + if not openerp.tools.config['test_enable']: + cr.autocommit(True) # check if user exists res = self.search(cr, SUPERUSER_ID, [('login','=',login)]) if res: From 82825c4acd52c70248704c5d6f886e2a1bfee037 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 7 Apr 2014 15:02:23 +0200 Subject: [PATCH 364/483] [FIX] add context parameter to various helper methods to avoid stupid crash in read_group (orm.py) bzr revid: ged@openerp.com-20140407130223-pdzge17omntpbh23 --- openerp/osv/orm.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 52fec2675a7..10c855e4268 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -2233,7 +2233,7 @@ class BaseModel(object): self._name, order_part) return groupby_terms, orderby_terms - def _read_group_process_groupby(self, gb, fget, query): + def _read_group_process_groupby(self, gb, fget, query, context): split = gb.split(':') field_type = fget[split[0]]['type'] gb_function = split[1] if len(split) == 2 else None @@ -2270,7 +2270,7 @@ class BaseModel(object): 'qualified_field': qualified_field } - def _read_group_prepare_data(self, key, value, groupby_dict): + def _read_group_prepare_data(self, key, value, groupby_dict, context): """ Helper method to sanitize the data received by read_group. The None values are converted to False, and the date/datetime are formatted, @@ -2361,7 +2361,7 @@ class BaseModel(object): fget = self.fields_get(cr, uid, fields) groupby = [groupby] if isinstance(groupby, basestring) else groupby groupby_list = groupby[:1] if lazy else groupby - annotated_groupbys = [self._read_group_process_groupby(gb, fget, query) + annotated_groupbys = [self._read_group_process_groupby(gb, fget, query, context) for gb in groupby_list] groupby_fields = [g['field'] for g in annotated_groupbys] order = orderby or ','.join([g['groupby'] for g in annotated_groupbys]) @@ -2433,7 +2433,7 @@ class BaseModel(object): for d in fetched_data: d.update(data_dict[d['id']]) - data = map(lambda r: {k: self._read_group_prepare_data(k,v, groupby_dict) for k,v in r.iteritems()}, fetched_data) + data = map(lambda r: {k: self._read_group_prepare_data(k,v, groupby_dict, context) for k,v in r.iteritems()}, fetched_data) result = [self._read_group_format_result(d, annotated_groupbys, groupby, groupby_dict, domain, context) for d in data] if lazy and groupby_fields[0] in self._group_by_full: # Right now, read_group only fill results in lazy mode (by default). From ae2a609390fbac4e3b5784c3c21ba6c9ff43f561 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 7 Apr 2014 15:02:29 +0200 Subject: [PATCH 365/483] [IMP] website: change translate px in % for snippet transform bzr revid: chm@openerp.com-20140407130229-rcoziy0gbwzl0are --- .../website/static/src/js/jQuery.transfo.js | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/addons/website/static/src/js/jQuery.transfo.js b/addons/website/static/src/js/jQuery.transfo.js index 6c82bfdb285..d2479017be0 100644 --- a/addons/website/static/src/js/jQuery.transfo.js +++ b/addons/website/static/src/js/jQuery.transfo.js @@ -143,8 +143,8 @@ OTHER DEALINGS IN THE SOFTWARE. transfo.settings = {}; transfo.settings.angle= transform.indexOf('rotate') != -1 ? parseFloat(transform.match(/rotate\(([^)]+)deg\)/)[1]) : 0; - transfo.settings.translatex= transform.indexOf('translateX') != -1 ? parseFloat(transform.match(/translateX\(([^)]+)\)/)[1]) : 0; - transfo.settings.translatey= transform.indexOf('translateY') != -1 ? parseFloat(transform.match(/translateY\(([^)]+)\)/)[1]) : 0; + var translatex = transform.match(/translateX\(([0-9.-]+)(%|px)\)/); + var translatey = transform.match(/translateY\(([0-9.-]+)(%|px)\)/); transfo.settings.scalex= transform.indexOf('scaleX') != -1 ? parseFloat(transform.match(/scaleX\(([^)]+)\)/)[1]) : 1; transfo.settings.scaley= transform.indexOf('scaleY') != -1 ? parseFloat(transform.match(/scaleY\(([^)]+)\)/)[1]) : 1; @@ -153,6 +153,22 @@ OTHER DEALINGS IN THE SOFTWARE. transfo.settings.height = $this.innerHeight(); transfo.settings.width = $this.innerWidth(); + + transfo.settings.translate = "%"; + + if (translatex && translatex[2] === "%") { + transfo.settings.translatexp = parseFloat(translatex[1]); + transfo.settings.translatex = transfo.settings.translatexp / 100 * transfo.settings.width; + } else { + transfo.settings.translatex = translatex ? parseFloat(translatex[1]) : 0; + } + if (translatey && translatey[2] === "%") { + transfo.settings.translateyp = parseFloat(translatey[1]); + transfo.settings.translatey = transfo.settings.translateyp / 100 * transfo.settings.height; + } else { + transfo.settings.translatey = translatey ? parseFloat(translatey[1]) : 0; + } + transfo.settings.css = window.getComputedStyle($this[0], null); transfo.settings.pos = $this.offset(); @@ -182,8 +198,6 @@ OTHER DEALINGS IN THE SOFTWARE. event.preventDefault(); if (transfo.active || event.which !== 1) return; - console.log(div); - var type = "position", $e = $(div); if ($e.hasClass("transfo-rotator")) type = "rotator"; else if ($e.hasClass("transfo-scaler-tl")) type = "tl"; @@ -259,20 +273,16 @@ OTHER DEALINGS IN THE SOFTWARE. var angle = settings.angle * rad; var dx = cdx*Math.cos(angle) - cdy*Math.sin(-angle); var dy = - cdx*Math.sin(angle) + cdy*Math.cos(-angle); - if (transfo.active.type.indexOf("t") != -1 && transfo.active.scaley > 0 || - transfo.active.type.indexOf("b") != -1 && transfo.active.scaley < 0) { + if (transfo.active.type.indexOf("t") != -1) { settings.scaley = dy / (settings.height/2); } - if (transfo.active.type.indexOf("b") != -1 && transfo.active.scaley > 0 || - transfo.active.type.indexOf("t") != -1 && transfo.active.scaley < 0) { + if (transfo.active.type.indexOf("b") != -1) { settings.scaley = - dy / (settings.height/2); } - if (transfo.active.type.indexOf("l") != -1 && transfo.active.scalex > 0 || - transfo.active.type.indexOf("r") != -1 && transfo.active.scalex < 0) { + if (transfo.active.type.indexOf("l") != -1) { settings.scalex = dx / (settings.width/2); } - if (transfo.active.type.indexOf("r") != -1 && transfo.active.scalex > 0 || - transfo.active.type.indexOf("l") != -1 && transfo.active.scalex < 0) { + if (transfo.active.type.indexOf("r") != -1) { settings.scalex = - dx / (settings.width/2); } if (settings.scaley > 0 && settings.scaley < 0.05) settings.scaley = 0.05; @@ -306,11 +316,11 @@ OTHER DEALINGS IN THE SOFTWARE. } if (settings.translatex) { trans = true; - transform += " translateX("+settings.translatex+"px) "; + transform += " translateX("+(settings.translate === "%" ? settings.translatexp+"%" : settings.translatex+"px")+") "; } if (settings.translatey) { trans = true; - transform += " translateY("+settings.translatey+"px) "; + transform += " translateY("+(settings.translate === "%" ? settings.translateyp+"%" : settings.translatey+"px")+"%) "; } if (settings.scalex != 1) { trans = true; @@ -341,34 +351,24 @@ OTHER DEALINGS IN THE SOFTWARE. } function _targetCss ($this, transfo) { - _setCss($this, transfo.settings.style, transfo.settings); + var settings = transfo.settings; + var width = parseFloat(settings.css.width); + var height = parseFloat(settings.css.height); + settings.translatexp = Math.round(settings.translatex/width*1000)/10; + settings.translateyp = Math.round(settings.translatey/height*1000)/10; - var pos = $this.position(); - var settings = Object.create(transfo.settings); - var w = parseFloat(transfo.settings.css.width); - var h = parseFloat(transfo.settings.css.height); - var width = Math.abs(settings.scalex) * w; - var height = Math.abs(settings.scaley) * h; - var top = settings.pos.top + (1-Math.abs(settings.scaley)) * h / 2; - var left = settings.pos.left + (1-Math.abs(settings.scalex)) * w / 2; - - var $rot = transfo.$markup.find(".transfo-rotator"); - if (settings.scalex > 0) $rot.css({"right": "0px", "left": "auto"}); - else $rot.css({"right": "auto", "left": "0px"}); - if (settings.scaley > 0) $rot.css({"top": "0px", "bottom": "auto"}); - else $rot.css({"top": "auto", "bottom": "0px"}); - - settings.scalex = settings.scaley = 1; + _setCss($this, settings.style, settings); _setCss(transfo.$markup, "position: absolute;" + - "top:" + top + "px;" + - "left:" + left + "px;" + + "top:" + settings.pos.top + "px;" + + "left:" + settings.pos.left + "px;" + "width:" + width + "px;" + "height:" + height + "px;" + "z-index:" + (transfo.settings.hide ? "-1" : "1000") + ";" + "cursor: move;", settings); + transfo.$markup.find(">").css("transform", "scaleX("+(1/settings.scalex)+") scaleY("+(1/settings.scaley)+")"); if (transfo.settings.hide) { transfo.$markup.find(">").hide(); From 9e1f395c23cd7089c36ac68f5a6899aeae5d3422 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Mon, 7 Apr 2014 15:11:45 +0200 Subject: [PATCH 366/483] [IMP] ir_qweb: added t-esc-options to allow customization of a t-esc; added an ir.qweb.widget model to format the t-esc value depending on the 'widget' key of t-esc-options; added ir.qweb.widget.monetary bzr revid: sle@openerp.com-20140407131145-a6357u6tdbu6v2ix --- openerp/addons/base/ir/ir_qweb.py | 39 ++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/openerp/addons/base/ir/ir_qweb.py b/openerp/addons/base/ir/ir_qweb.py index 84551186f05..fd715c9ac54 100644 --- a/openerp/addons/base/ir/ir_qweb.py +++ b/openerp/addons/base/ir/ir_qweb.py @@ -332,7 +332,9 @@ class QWeb(orm.AbstractModel): return self.render_element(element, template_attributes, generated_attributes, qwebcontext, inner) def render_tag_esc(self, element, template_attributes, generated_attributes, qwebcontext): - inner = werkzeug.utils.escape(self.eval_str(template_attributes["esc"], qwebcontext)) + options = json.loads(template_attributes.get('esc-options') or '{}') + widget = self.get_widget_for(options.get('widget', '')) + inner = widget.format(template_attributes['esc'], options, qwebcontext) return self.render_element(element, template_attributes, generated_attributes, qwebcontext, inner) def render_tag_foreach(self, element, template_attributes, generated_attributes, qwebcontext): @@ -419,6 +421,9 @@ class QWeb(orm.AbstractModel): return self.pool.get('ir.qweb.field.' + field_type, self.pool['ir.qweb.field']) + def get_widget_for(self, widget): + return self.pool.get('ir.qweb.widget.' + widget, self.pool['ir.qweb.widget']) + #-------------------------------------------------------------------- # QWeb Fields converters #-------------------------------------------------------------------- @@ -840,6 +845,38 @@ class Contact(orm.AbstractModel): return HTMLSafe(html) +class QwebWidget(osv.AbstractModel): + _name = 'ir.qweb.widget' + + def _format(self, inner, options, qwebcontext): + return self.pool['ir.qweb'].eval_str(inner, qwebcontext) + + def format(self, inner, options, qwebcontext): + return werkzeug.utils.escape(self._format(inner, options, qwebcontext)) + +class QwebWidgetMonetary(osv.AbstractModel): + _name = 'ir.qweb.widget.monetary' + _inherit = 'ir.qweb.widget' + + def _format(self, inner, options, qwebcontext): + inner = self.pool['ir.qweb'].eval(inner, qwebcontext) + display = self.pool['ir.qweb'].eval_object(options['display_currency'], qwebcontext) + precision = int(round(math.log10(display.rounding))) + fmt = "%.{0}f".format(-precision if precision < 0 else 0) + lang_code = qwebcontext.context.get('lang') or 'en_US' + formatted_amount = self.pool['res.lang'].format( + qwebcontext.cr, qwebcontext.uid, [lang_code], fmt, inner, grouping=True, monetary=True + ) + pre = post = u'' + if display.position == 'before': + pre = u'{symbol} ' + else: + post = u' {symbol}' + + return u'{pre}{0}{post}'.format( + formatted_amount, pre=pre, post=post + ).format(symbol=display.symbol,) + class HTMLSafe(object): """ HTMLSafe string wrapper, Werkzeug's escape() has special handling for objects with a ``__html__`` methods but AFAIK does not provide any such From d908d26c7c3520589df2090d3eb24d24fcc7e99c Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Mon, 7 Apr 2014 15:33:13 +0200 Subject: [PATCH 367/483] [REV] revert revid9276 (no need to include formatLang as qweb has since introduced t-esc-options) bzr revid: sle@openerp.com-20140407133313-re7xwd5190hk6zqi --- addons/report/models/report.py | 11 ----------- addons/sale_layout/views/sale_layout_template.xml | 4 ++-- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/addons/report/models/report.py b/addons/report/models/report.py index 018fc0b57e2..723c098ccb2 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -23,7 +23,6 @@ from openerp.osv import osv from openerp.tools import config from openerp.tools.translate import _ from openerp.addons.web.http import request -from openerp.report.formatter import Formatter import os import time @@ -138,16 +137,6 @@ class Report(osv.Model): website = None if request and hasattr(request, 'website'): website = request.website - - # formatLang method - if not values.get('formatLang'): - formatter = Formatter(cr, uid, self.pool, lang=user.lang) - values.update({ - 'formatLang': formatter.formatLang, - 'digits_fmt': formatter.digits_fmt, - 'get_digits': formatter.get_digits, - }) - values.update({ 'time': time, 'render_doc': render_doc, diff --git a/addons/sale_layout/views/sale_layout_template.xml b/addons/sale_layout/views/sale_layout_template.xml index 88a95ae238d..016c49a0a62 100644 --- a/addons/sale_layout/views/sale_layout_template.xml +++ b/addons/sale_layout/views/sale_layout_template.xml @@ -22,7 +22,7 @@ Subtotal: - + @@ -31,7 +31,7 @@ - + *** From 26058183e1732e36291ef625e736ad1188e99dbe Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Mon, 7 Apr 2014 15:34:25 +0200 Subject: [PATCH 368/483] [FIX] sale_layout: use t-esc-options to format subtotals bzr revid: sle@openerp.com-20140407133425-gfl5bqq0x2j5tq5w --- .../views/sale_layout_template.xml | 75 ++++++++++--------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/addons/sale_layout/views/sale_layout_template.xml b/addons/sale_layout/views/sale_layout_template.xml index 016c49a0a62..73406fc9fd6 100644 --- a/addons/sale_layout/views/sale_layout_template.xml +++ b/addons/sale_layout/views/sale_layout_template.xml @@ -1,42 +1,43 @@ - - - + + + + + From 078914371c0ad1b4174c44a1aabe0427b25a0711 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 7 Apr 2014 15:37:50 +0200 Subject: [PATCH 369/483] [FIX] website: save jquery transform style bzr revid: chm@openerp.com-20140407133750-he0iaor008hvzfim --- .../website/static/src/js/jQuery.transfo.js | 53 ++++++++++++++++--- .../static/src/js/website.snippets.editor.js | 4 +- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/addons/website/static/src/js/jQuery.transfo.js b/addons/website/static/src/js/jQuery.transfo.js index d2479017be0..725e5a02216 100644 --- a/addons/website/static/src/js/jQuery.transfo.js +++ b/addons/website/static/src/js/jQuery.transfo.js @@ -59,6 +59,39 @@ OTHER DEALINGS IN THE SOFTWARE. }); }, + toggle : function() { + return this.each(function() { + var $this = $(this); + var transfo = $this.data('transfo'); + if (transfo) { + transfo.settings.hide = !transfo.settings.hide; + _showHide($this, transfo); + } + }); + }, + + hide : function() { + return this.each(function() { + var $this = $(this); + var transfo = $this.data('transfo'); + if (transfo) { + transfo.settings.hide = true; + _showHide($this, transfo); + } + }); + }, + + show : function() { + return this.each(function() { + var $this = $(this); + var transfo = $this.data('transfo'); + if (transfo) { + transfo.settings.hide = false; + _showHide($this, transfo); + } + }); + }, + settings : function() { if(this.length > 1) { this.map(function () { @@ -130,6 +163,8 @@ OTHER DEALINGS IN THE SOFTWARE. },0); _bind($this, transfo); + + _targetCss($this, transfo); } function _overwriteOptions ($this, transfo, settings) { @@ -143,8 +178,6 @@ OTHER DEALINGS IN THE SOFTWARE. transfo.settings = {}; transfo.settings.angle= transform.indexOf('rotate') != -1 ? parseFloat(transform.match(/rotate\(([^)]+)deg\)/)[1]) : 0; - var translatex = transform.match(/translateX\(([0-9.-]+)(%|px)\)/); - var translatey = transform.match(/translateY\(([0-9.-]+)(%|px)\)/); transfo.settings.scalex= transform.indexOf('scaleX') != -1 ? parseFloat(transform.match(/scaleX\(([^)]+)\)/)[1]) : 1; transfo.settings.scaley= transform.indexOf('scaleY') != -1 ? parseFloat(transform.match(/scaleY\(([^)]+)\)/)[1]) : 1; @@ -154,6 +187,8 @@ OTHER DEALINGS IN THE SOFTWARE. transfo.settings.height = $this.innerHeight(); transfo.settings.width = $this.innerWidth(); + var translatex = transform.match(/translateX\(([0-9.-]+)(%|px)\)/); + var translatey = transform.match(/translateY\(([0-9.-]+)(%|px)\)/); transfo.settings.translate = "%"; if (translatex && translatex[2] === "%") { @@ -320,7 +355,7 @@ OTHER DEALINGS IN THE SOFTWARE. } if (settings.translatey) { trans = true; - transform += " translateY("+(settings.translate === "%" ? settings.translateyp+"%" : settings.translatey+"px")+"%) "; + transform += " translateY("+(settings.translate === "%" ? settings.translateyp+"%" : settings.translatey+"px")+") "; } if (settings.scalex != 1) { trans = true; @@ -345,7 +380,7 @@ OTHER DEALINGS IN THE SOFTWARE. + "transform:" + transform + ";"; } - css = css.replace(/;+/g, ';').replace(/^;+|;+$/g, ''); + css = css.replace(/(\s*;)+/g, ';').replace(/^\s*;|;\s*$/g, ''); $this.attr("style", css); } @@ -365,19 +400,23 @@ OTHER DEALINGS IN THE SOFTWARE. "left:" + settings.pos.left + "px;" + "width:" + width + "px;" + "height:" + height + "px;" + - "z-index:" + (transfo.settings.hide ? "-1" : "1000") + ";" + "cursor: move;", settings); transfo.$markup.find(">").css("transform", "scaleX("+(1/settings.scalex)+") scaleY("+(1/settings.scaley)+")"); + _showHide($this, transfo); + + transfo.settings.callback.call($this[0], $this); + } + + function _showHide ($this, transfo) { + transfo.$markup.css("z-index", transfo.settings.hide ? -1 : 1000); if (transfo.settings.hide) { transfo.$markup.find(">").hide(); transfo.$markup.find(".transfo-scaler-mc").show(); } else { transfo.$markup.find(">").show(); } - - transfo.settings.callback.call($this[0], $this); } function _destroy ($this) { diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index a6c387c73a0..ad06f5740c8 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -1452,7 +1452,7 @@ this.$overlay.find('[data-toggle="dropdown"]') .on("mousedown", function () { - self.$target.transfo({ hide: true }); + self.$target.transfo("hide"); }); }, resetTransfo: function () { @@ -1480,7 +1480,7 @@ this.resetTransfo(); }, onBlur : function () { - this.$target.transfo({ hide: true }); + this.$target.transfo("hide"); }, }); From b683b9c614512c6b3c186a488053dfb5f7bdc021 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Mon, 7 Apr 2014 15:39:31 +0200 Subject: [PATCH 370/483] [IMP] removes useless calls to field_get and replace them by self._all_columns in read_group method (orm.py). bzr revid: ged@openerp.com-20140407133931-hrf9dmdj2fx050ww --- openerp/osv/orm.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 10c855e4268..bfa145fb4a6 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -2193,7 +2193,7 @@ class BaseModel(object): r['__fold'] = folded.get(r[groupby] and r[groupby][0], False) return result - def _read_group_prepare(self, orderby, aggregated_fields, annotated_groupbys, query, fget): + def _read_group_prepare(self, orderby, aggregated_fields, annotated_groupbys, query): """ Prepares the GROUP BY and ORDER BY terms for the read_group method. Adds the missing JOIN clause to the query if order should be computed against m2o field. @@ -2217,7 +2217,7 @@ class BaseModel(object): order_field = order_split[0] if order_field in groupby_fields: - if fget[order_field.split(':')[0]]['type'] == 'many2one': + if self._all_columns[order_field.split(':')[0]].column._type == 'many2one': order_clause = self._generate_order_by(order_part, query).replace('ORDER BY ', '') if order_clause: orderby_terms.append(order_clause) @@ -2233,9 +2233,9 @@ class BaseModel(object): self._name, order_part) return groupby_terms, orderby_terms - def _read_group_process_groupby(self, gb, fget, query, context): + def _read_group_process_groupby(self, gb, query, context): split = gb.split(':') - field_type = fget[split[0]]['type'] + field_type = self._all_columns[split[0]].column._type gb_function = split[1] if len(split) == 2 else None temporal = field_type in ('date', 'datetime') tz_convert = field_type == 'datetime' and context.get('tz') in pytz.all_timezones @@ -2358,10 +2358,10 @@ class BaseModel(object): self.check_access_rights(cr, uid, 'read') query = self._where_calc(cr, uid, domain, context=context) fields = fields or self._columns.keys() - fget = self.fields_get(cr, uid, fields) + groupby = [groupby] if isinstance(groupby, basestring) else groupby groupby_list = groupby[:1] if lazy else groupby - annotated_groupbys = [self._read_group_process_groupby(gb, fget, query, context) + annotated_groupbys = [self._read_group_process_groupby(gb, query, context) for gb in groupby_list] groupby_fields = [g['field'] for g in annotated_groupbys] order = orderby or ','.join([g['groupby'] for g in annotated_groupbys]) @@ -2372,7 +2372,7 @@ class BaseModel(object): assert gb in fields, "Fields in 'groupby' must appear in the list of fields to read (perhaps it's missing in the list view?)" groupby_def = self._columns.get(gb) or (self._inherit_fields.get(gb) and self._inherit_fields.get(gb)[2]) assert groupby_def and groupby_def._classic_write, "Fields in 'groupby' must be regular database-persisted fields (no function or related fields), or function fields with store=True" - if not (gb in fget): + if not (gb in self._all_columns): # Don't allow arbitrary values, as this would be a SQL injection vector! raise except_orm(_('Invalid group_by'), _('Invalid group_by specification: "%s".\nA group_by specification must be a list of valid fields.')%(gb,)) @@ -2381,16 +2381,16 @@ class BaseModel(object): f for f in fields if f not in ('id', 'sequence') if f not in groupby_fields - if fget[f]['type'] in ('integer', 'float') - if (f in self._all_columns and getattr(self._all_columns[f].column, '_classic_write'))] + if self._all_columns[f].column._type in ('integer', 'float') + if getattr(self._all_columns[f].column, '_classic_write')] - field_formatter = lambda f: (fget[f].get('group_operator', 'sum'), self._inherits_join_calc(f, query), f) + field_formatter = lambda f: (self._all_columns[f].column.group_operator or 'sum', self._inherits_join_calc(f, query), f) select_terms = ["%s(%s) AS %s" % field_formatter(f) for f in aggregated_fields] for gb in annotated_groupbys: select_terms.append('%s as "%s" ' % (gb['qualified_field'], gb['groupby'])) - groupby_terms, orderby_terms = self._read_group_prepare(order, aggregated_fields, annotated_groupbys, query, fget) + groupby_terms, orderby_terms = self._read_group_prepare(order, aggregated_fields, annotated_groupbys, query) from_clause, where_clause, where_clause_params = query.get_sql() if lazy and (len(groupby_fields) >= 2 or not context.get('group_by_no_leaf')): count_field = groupby_fields[0] if len(groupby_fields) >= 1 else '_' From c590c253457ae8b7ab0c5a23eddf0553925399fc Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Mon, 7 Apr 2014 16:48:20 +0200 Subject: [PATCH 371/483] [FIX] accont bank statement balance: do not crash if balance is None bzr revid: sle@openerp.com-20140407144820-21qlpvd3ik42i78d --- .../views/report_bankstatementbalance.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/account_bank_statement_extensions/views/report_bankstatementbalance.xml b/addons/account_bank_statement_extensions/views/report_bankstatementbalance.xml index a8ca5f54d3a..111912a7507 100644 --- a/addons/account_bank_statement_extensions/views/report_bankstatementbalance.xml +++ b/addons/account_bank_statement_extensions/views/report_bankstatementbalance.xml @@ -22,7 +22,7 @@ - + From 153e31d754fa254613c3da9da90b66eea9bb7aaa Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 7 Apr 2014 16:49:14 +0200 Subject: [PATCH 372/483] [FIX] website: media editor: add image with topbar bzr revid: chm@openerp.com-20140407144914-50wblp9teywr8wk2 --- .../website/static/src/js/website.editor.js | 64 +++++++++++-------- .../website/static/src/xml/website.editor.xml | 4 +- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 2c7abd040bc..6f5dc682442 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -114,7 +114,7 @@ context: 'a', }); //noinspection JSValidateTypes - editor.addCommand('image', { + editor.addCommand('cimage', { exec: function (editor) { image_dialog(editor); return true; @@ -131,7 +131,7 @@ }); editor.ui.addButton('Image', { label: 'Image', - command: 'image', + command: 'cimage', toolbar: 'insert,10', }); @@ -1338,6 +1338,7 @@ }, start: function () { var self = this; + this.imageDialog = new website.editor.RTEImageDialog(this, this.editor, this.media); this.imageDialog.appendTo(this.$("#editor-media-image")); this.iconDialog = new website.editor.FontIconsDialog(this, this.editor, this.media); @@ -1361,38 +1362,49 @@ } }); - if (this.media.$.nodeName === "IMG") { - this.$('[href="#editor-media-image"]').tab('show'); - } else if (this.media.$.className.match(/(^|\s)media_iframe_video($|\s)/)) { - this.$('[href="#editor-media-video"]').tab('show'); - } else if (this.media.$.className.match(/(^|\s)fa($|\s)/)) { - this.$('[href="#editor-media-icon"]').tab('show'); - } + if (this.media) { + if (this.media.$.nodeName === "IMG") { + this.$('[href="#editor-media-image"]').tab('show'); + } else if (this.media.$.className.match(/(^|\s)media_iframe_video($|\s)/)) { + this.$('[href="#editor-media-video"]').tab('show'); + } else if (this.media.$.className.match(/(^|\s)fa($|\s)/)) { + this.$('[href="#editor-media-icon"]').tab('show'); + } - if ($(this.media.$).parent().data("oe-field") === "image") { - this.$('[href="#editor-media-video"], [href="#editor-media-icon"]').addClass('hidden'); + if ($(this.media.$).parent().data("oe-field") === "image") { + this.$('[href="#editor-media-video"], [href="#editor-media-icon"]').addClass('hidden'); + } } return this._super(); }, save: function () { var self = this; + if (self.media) { + this.media.$.innerHTML = ""; + if (this.active !== this.imageDialog) { + this.imageDialog.clear(); + } + if (this.active !== this.iconDialog) { + this.iconDialog.clear(); + } + if (this.active !== this.videoDialog) { + this.videoDialog.clear(); + } + } else { + var selection = this.editor.getSelection(); + var range = selection.getRanges(true)[0]; + this.media = new CKEDITOR.dom.element("img"); + range.insertNode(this.media); + range.selectNodeContents(this.media); + this.active.media = this.media; + } + var $el = $(self.media.$); setTimeout(function () { $el.trigger("saved", self.media.$); },0); - this.media.$.innerHTML = ""; - if (this.active !== this.imageDialog) { - this.imageDialog.clear(); - } - if (this.active !== this.iconDialog) { - this.iconDialog.clear(); - } - if (this.active !== this.videoDialog) { - this.videoDialog.clear(); - } - this.active.save(); this.media.$.className = this.media.$.className.replace(/\s+/g, ' '); @@ -1760,7 +1772,7 @@ * which may not match the visual look of the element. */ load_data: function () { - var classes = (this.media.$.className||"").split(/\s+/); + var classes = (this.media&&this.media.$.className||"").split(/\s+/); for (var i = 0; i < classes.length; i++) { var cls = classes[i]; switch(cls) { @@ -1813,7 +1825,7 @@ .attr('data-size', size) .addClass(size) .addClass(no_sizes); - if ((size && _.contains(classes, size)) || !selected) { + if ((size && _.contains(classes, size)) || (classes[2] === "" && !selected)) { this.$preview.append($p.clone()); this.$('#fa-size').val(size); $p.addClass('font-icons-selected'); @@ -1835,7 +1847,7 @@ }), start: function () { this.$iframe = this.$("iframe"); - var $media = $(this.media.$); + var $media = $(this.media && this.media.$); if ($media.hasClass("media_iframe_video")) { var src = $media.data('src'); this.$("input#urlvideo").val(src); @@ -1868,7 +1880,7 @@ return false; }, get_video: function (event) { - event.preventDefault(); + if (event) event.preventDefault(); var needle = this.$("input#urlvideo").val(); var video_id; var video_type; diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index b3012e5aa78..f0602691515 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -301,7 +301,7 @@
    (Youtube, Vimeo, Dailymotion) - + Add
    - + Date: Mon, 7 Apr 2014 17:00:27 +0200 Subject: [PATCH 373/483] [FIX] auth_oauth: redirect to url before sign in bzr revid: dle@openerp.com-20140407150027-z46yxuh3a9uqoz26 --- addons/auth_oauth/controllers/main.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/addons/auth_oauth/controllers/main.py b/addons/auth_oauth/controllers/main.py index 6d28813507c..fddf439aa1d 100644 --- a/addons/auth_oauth/controllers/main.py +++ b/addons/auth_oauth/controllers/main.py @@ -68,7 +68,8 @@ class OAuthLogin(openerp.addons.web.controllers.main.Home): def get_state(self, provider): return dict( d=request.session.db, - p=provider['id'] + p=provider['id'], + r=request.httprequest.full_path ) @http.route() @@ -114,8 +115,11 @@ class OAuthController(http.Controller): cr.commit() action = state.get('a') menu = state.get('m') + redirect = state.get('r') url = '/web' - if action: + if redirect: + url = redirect + elif action: url = '/web#action=%s' % action elif menu: url = '/web#menu_id=%s' % menu From 9660a92a91fd2570f99406581e4c544e4f08ec46 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Mon, 7 Apr 2014 17:15:15 +0200 Subject: [PATCH 374/483] [FIX] regression when fixing specific paperformat argument on a template bzr revid: sle@openerp.com-20140407151515-dxdxjt60ld7jn2cs --- addons/report/models/report.py | 19 ++++++++++++------- addons/report/views/layouts.xml | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/addons/report/models/report.py b/addons/report/models/report.py index 723c098ccb2..f619b2db0cb 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -479,12 +479,21 @@ class Report(osv.Model): command_args.extend(['--page-width', str(paperformat.page_width) + 'mm']) command_args.extend(['--page-height', str(paperformat.page_height) + 'mm']) - if specific_paperformat_args and specific_paperformat_args['data-report-margin-top']: - command_args.extend(['--margin-top', - str(specific_paperformat_args['data-report-margin-top'])]) + if specific_paperformat_args and specific_paperformat_args.get('data-report-margin-top'): + command_args.extend(['--margin-top', str(specific_paperformat_args['data-report-margin-top'])]) elif paperformat.margin_top: command_args.extend(['--margin-top', str(paperformat.margin_top)]) + if specific_paperformat_args and specific_paperformat_args.get('data-report-dpi'): + command_args.extend(['--dpi', str(specific_paperformat_args['data-report-dpi'])]) + elif paperformat.dpi: + command_args.extend(['--dpi', str(paperformat.dpi)]) + + if specific_paperformat_args and specific_paperformat_args.get('data-report-header-spacing'): + command_args.extend(['--header-spacing', str(specific_paperformat_args['data-report-header-spacing'])]) + elif paperformat.header_spacing: + command_args.extend(['--header-spacing', str(paperformat.header_spacing)]) + if paperformat.margin_left: command_args.extend(['--margin-left', str(paperformat.margin_left)]) if paperformat.margin_bottom: @@ -493,12 +502,8 @@ class Report(osv.Model): command_args.extend(['--margin-right', str(paperformat.margin_right)]) if paperformat.orientation: command_args.extend(['--orientation', str(paperformat.orientation)]) - if paperformat.header_spacing: - command_args.extend(['--header-spacing', str(paperformat.header_spacing)]) if paperformat.header_line: command_args.extend(['--header-line']) - if paperformat.dpi: - command_args.extend(['--dpi', str(paperformat.dpi)]) return command_args diff --git a/addons/report/views/layouts.xml b/addons/report/views/layouts.xml index 21c385b71c9..4f5104c726b 100644 --- a/addons/report/views/layouts.xml +++ b/addons/report/views/layouts.xml @@ -8,7 +8,7 @@ t-att-data-view-xmlid="xmlid if editable else None" t-att-data-main-object="repr(main_object) if editable else None" t-att-data-report-margin-top="data_report_margin_top if data_report_margin_top else None" - t-att-data-report-header-spacing="data_report_header_spacing if t_att_data_report_header_spacing else None" + t-att-data-report-header-spacing="data_report_header_spacing if data_report_header_spacing else None" t-att-data-report-dpi="data_report_dpi if data_report_dpi else None"> From d62c9cea680f4f50e7a66729e1b2e1e0ef186397 Mon Sep 17 00:00:00 2001 From: Anael Closson Date: Mon, 7 Apr 2014 17:45:10 +0200 Subject: [PATCH 375/483] [FIX] OPW 606045 - view_form: add a m2m tag from search_create_popup doesn't add tag to field bzr revid: acl@openerp.com-20140407154510-5vxckvf1vpsvl96e --- addons/web/static/src/js/view_form.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index fd838686ba9..7f451d324b2 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -4306,7 +4306,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in if (data.id) { self.add_id(data.id); } else { - ignore_blur = true; + self.ignore_blur = true; data.action(); } this.trigger('setSuggestions', {result : []}); @@ -4346,7 +4346,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in if (this.get("effective_readonly")) return; var self = this; - var ignore_blur = false; + self.ignore_blur = false; self.$text = this.$("textarea"); self.$text.textext(self.initialize_texttext()).bind('getSuggestions', function(e, data) { var _this = this; @@ -4366,11 +4366,11 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in self.$text .focusin(function () { self.trigger('focused'); - ignore_blur = false; + self.ignore_blur = false; }) .focusout(function() { self.$text.trigger("setInputData", ""); - if (!ignore_blur) { + if (!self.ignore_blur) { self.trigger('blurred'); } }).keydown(function(e) { @@ -4448,6 +4448,10 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in width: width, minHeight: height }); + }, + _search_create_popup: function() { + self.ignore_blur = true; + return instance.web.form.CompletionFieldMixin._search_create_popup.apply(this, arguments); }, }); From ff768827017a4a655c1727597dc6be28e2d72db6 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Mon, 7 Apr 2014 17:59:19 +0200 Subject: [PATCH 376/483] [FIX] auth_oauth: avoid infinite loop while trying to sign in bzr revid: dle@openerp.com-20140407155919-vm32q6nvcit59026 --- addons/auth_oauth/controllers/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/auth_oauth/controllers/main.py b/addons/auth_oauth/controllers/main.py index fddf439aa1d..08319b982fd 100644 --- a/addons/auth_oauth/controllers/main.py +++ b/addons/auth_oauth/controllers/main.py @@ -2,6 +2,7 @@ import functools import logging import simplejson +import urlparse import werkzeug.utils from werkzeug.exceptions import BadRequest @@ -117,7 +118,8 @@ class OAuthController(http.Controller): menu = state.get('m') redirect = state.get('r') url = '/web' - if redirect: + if redirect and not redirect.startswith('/auth_oauth/signin') and \ + (not redirect.startswith('/web/login') or 'redirect' in urlparse.urlsplit(redirect).query): url = redirect elif action: url = '/web#action=%s' % action From a247efb0e416404a8842bd14cfc44f705f393915 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Mon, 7 Apr 2014 18:33:37 +0200 Subject: [PATCH 377/483] [FIX] website: media editor fix saved trigger bzr revid: chm@openerp.com-20140407163337-3a3d3kt5l2nmm3gn --- addons/website/static/src/js/website.editor.js | 11 +++++++---- .../website/static/src/js/website.snippets.editor.js | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 6f5dc682442..7c2ed281a04 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -1400,15 +1400,17 @@ this.active.media = this.media; } - var $el = $(self.media.$); - setTimeout(function () { - $el.trigger("saved", self.media.$); - },0); + var $el = $(self.active.media.$); this.active.save(); this.media.$.className = this.media.$.className.replace(/\s+/g, ' '); + setTimeout(function () { + $el.trigger("saved", self.active.media.$); + $(document.body).trigger("media-saved", [$el[0], self.active.media.$]); + },0); + this._super(); }, searchTimer: null, @@ -1918,6 +1920,7 @@ ''+ '
    '); $(this.media.$).replaceWith($iframe); + this.media.$ = $iframe[0]; this._super(); }, clear: function () { diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index ad06f5740c8..03016905bf2 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -1491,7 +1491,8 @@ website.snippet.start_animation(true, this.$target); - this.$target.on("saved", self, function (event, item) { + $(document.body).on("media-saved", self, function (event, prev , item) { + self.editor.onBlur(); self.BuildingBlock.make_active($(item)); }); From c1cc370d757baab30c79452516c51627f2c00701 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Mon, 7 Apr 2014 18:54:55 +0200 Subject: [PATCH 378/483] [FIX] ir_actions: add missing comma bzr revid: chs@openerp.com-20140407165455-0zbsl1omgvw9e5ta --- openerp/addons/base/ir/ir_actions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index 897c5b5db43..966489b4be2 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -944,7 +944,7 @@ class ir_actions_server(osv.osv): 'uid': uid, 'user': user, 'context': context, - 'workflow': workflow + 'workflow': workflow, 'Warning': openerp.exceptions.Warning, } From 4eec536d157cf3fc30e85001ecb857a3dea9081d Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Mon, 7 Apr 2014 19:46:21 +0200 Subject: [PATCH 379/483] [FIX] base_gengo: don't skipp terms in gengo communication because of their state may have changed in the meanwhile (so using offset+limit in a serach at each loop is not a good idea) bzr revid: qdp-launchpad@openerp.com-20140407174621-m9cv56gonoga4zh0 --- .../wizard/base_gengo_translations.py | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/addons/base_gengo/wizard/base_gengo_translations.py b/addons/base_gengo/wizard/base_gengo_translations.py index b044b929c65..8cc7206e63e 100644 --- a/addons/base_gengo/wizard/base_gengo_translations.py +++ b/addons/base_gengo/wizard/base_gengo_translations.py @@ -117,35 +117,37 @@ class base_gengo_translations(osv.osv_memory): _logger.warning("%s", gengo) else: offset = 0 + all_translation_ids = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine', 'standard', 'pro', 'ultra')), ('job_id', "!=", False)], context=context) while True: - translation_ids = translation_pool.search(cr, uid, [('state', '=', 'inprogress'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('job_id', "!=",False)], limit=limit, offset=offset, context=context) - if not translation_ids: + translation_ids = all_translation_ids[offset:offset + limit] + if translation_ids: + offset += limit + translation_terms = translation_pool.browse(cr, uid, translation_ids, context=context) + gengo_job_id = [term.job_id for term in translation_terms] + if gengo_job_id: + gengo_ids = ','.join(gengo_job_id) + job_response = gengo.getTranslationJobBatch(id=gengo_ids) + if job_response['opstat'] == 'ok': + job_response_dict = dict([(job['job_id'], job) for job in job_response['response']['jobs']]) + for term in translation_terms: + up_term = up_comment = 0 + vals = {} + if job_response_dict[term.job_id]['status'] == 'approved': + vals.update({'state': 'translated', + 'value': job_response_dict[term.job_id]['body_tgt']}) + up_term += 1 + job_comment = gengo.getTranslationJobComments(id=term.job_id) + if job_comment['opstat'] == 'ok': + gengo_comments = "" + for comment in job_comment['response']['thread']: + gengo_comments += _('%s\n-- Commented on %s by %s.\n\n') % (comment['body'], time.ctime(comment['ctime']), comment['author']) + vals.update({'gengo_comment': gengo_comments}) + up_comment += 1 + if vals: + translation_pool.write(cr, uid, term.id, vals) + _logger.info("Successfully Updated `%d` terms and %d Comments." % (up_term, up_comment)) + if not len(translation_ids) == limit: break - offset += limit - translation_terms = translation_pool.browse(cr, uid, translation_ids, context=context) - gengo_job_id = [term.job_id for term in translation_terms] - if gengo_job_id: - gengo_ids = ','.join(gengo_job_id) - job_response = gengo.getTranslationJobBatch(id=gengo_ids) - if job_response['opstat'] == 'ok': - job_response_dict = dict([(job['job_id'],job) for job in job_response['response']['jobs']]) - for term in translation_terms: - up_term = up_comment = 0 - vals={} - if job_response_dict[term.job_id]['status'] == 'approved': - vals.update({'state': 'translated', - 'value': job_response_dict[term.job_id]['body_tgt']}) - up_term += 1 - job_comment = gengo.getTranslationJobComments(id=term.job_id) - if job_comment['opstat']=='ok': - gengo_comments="" - for comment in job_comment['response']['thread']: - gengo_comments += _('%s\n-- Commented on %s by %s.\n\n') % (comment['body'], time.ctime(comment['ctime']), comment['author']) - vals.update({'gengo_comment': gengo_comments}) - up_comment += 1 - if vals: - translation_pool.write(cr, uid, term.id, vals) - _logger.info("Successfully Updated `%d` terms and %d Comments." % (up_term, up_comment )) return True def _update_terms(self, cr, uid, response, context=None): @@ -229,14 +231,15 @@ class base_gengo_translations(osv.osv_memory): lang_ids = [context.get('gengo_language')] langs = [lang.code for lang in language_pool.browse(cr, uid, lang_ids, context=context)] offset = 0 + all_term_ids = translation_pool.search(cr, uid, [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine', 'standard', 'pro', 'ultra')), ('lang', 'in', langs), ('job_id', "=", False)], context=context) while True: #search for the n first terms to translate - term_ids = translation_pool.search(cr, uid, [('state', '=', 'to_translate'), ('gengo_translation', 'in', ('machine','standard','pro','ultra')), ('lang', 'in', langs),('job_id',"=",False)], limit=limit, offset=offset, context=context) + term_ids = all_term_ids[offset:offset + limit] if term_ids: - self._send_translation_terms(cr, uid, term_ids, context=context) offset += limit + self._send_translation_terms(cr, uid, term_ids, context=context) _logger.info("%s Translation terms have been posted to Gengo successfully", len(term_ids)) - else: + if not len(term_ids) == limit: break except Exception, e: _logger.error("%s", e) From dcdf729b9fb2404ac076aa0cd178df2c27dae0fb Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of openerp <> Date: Tue, 8 Apr 2014 06:18:31 +0000 Subject: [PATCH 380/483] Launchpad automatic translations update. bzr revid: launchpad_translations_on_behalf_of_openerp-20140408061831-7wnnz72jgait29og --- addons/product/i18n/pl.po | 18 ++++++++++-------- addons/stock/i18n/pl.po | 8 ++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/addons/product/i18n/pl.po b/addons/product/i18n/pl.po index ac059f0a556..9e9b65a8545 100644 --- a/addons/product/i18n/pl.po +++ b/addons/product/i18n/pl.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev_rc3\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:06+0000\n" -"PO-Revision-Date: 2012-12-16 19:25+0000\n" -"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) \n" +"PO-Revision-Date: 2014-04-07 13:25+0000\n" +"Last-Translator: Dariusz Żbikowski (Krokus) \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-27 06:41+0000\n" -"X-Generator: Launchpad (build 16967)\n" +"X-Launchpad-Export-Date: 2014-04-08 06:18+0000\n" +"X-Generator: Launchpad (build 16976)\n" #. module: product #: field:product.packaging,rows:0 @@ -735,7 +735,7 @@ msgstr "Jeśli zaznaczone, to wiadomość wymaga twojej uwagi" #. module: product #: field:product.product,ean13:0 msgid "EAN13 Barcode" -msgstr "" +msgstr "Kod kreskowy EAN13" #. module: product #: model:ir.actions.act_window,name:product.action_product_price_list @@ -1188,7 +1188,7 @@ msgstr "Wiadomości i historia komunikacji" #. module: product #: model:product.uom,name:product.product_uom_kgm msgid "kg" -msgstr "" +msgstr "kg" #. module: product #: selection:product.template,state:0 @@ -1198,7 +1198,7 @@ msgstr "Zdezaktualizowany" #. module: product #: model:product.uom,name:product.product_uom_km msgid "km" -msgstr "" +msgstr "km" #. module: product #: field:product.template,standard_price:0 @@ -1354,6 +1354,8 @@ msgid "" "This field holds the image used as image for the product, limited to " "1024x1024px." msgstr "" +"To pole utrzymuje obraz użyty jako zdjęcie produktu, limitowany rozmiar " +"1024x1024." #. module: product #: help:product.pricelist.item,categ_id:0 @@ -1519,7 +1521,7 @@ msgstr "" #. module: product #: model:product.uom,name:product.product_uom_cm msgid "cm" -msgstr "" +msgstr "cm" #. module: product #: model:ir.model,name:product.model_product_uom diff --git a/addons/stock/i18n/pl.po b/addons/stock/i18n/pl.po index 66cb0cb868c..3f8e6b9bb9f 100644 --- a/addons/stock/i18n/pl.po +++ b/addons/stock/i18n/pl.po @@ -7,13 +7,13 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:04+0000\n" -"PO-Revision-Date: 2014-04-04 19:47+0000\n" -"Last-Translator: Dariusz Żbikowski \n" +"PO-Revision-Date: 2014-04-07 13:08+0000\n" +"Last-Translator: Dariusz Żbikowski (Krokus) \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-04-05 05:30+0000\n" +"X-Launchpad-Export-Date: 2014-04-08 06:18+0000\n" "X-Generator: Launchpad (build 16976)\n" #. module: stock @@ -2623,7 +2623,7 @@ msgstr "Ustaw na projekt" #: model:ir.actions.act_window,name:stock.action_stock_journal_form #: model:ir.ui.menu,name:stock.menu_action_stock_journal_form msgid "Stock Journals" -msgstr "Dzienniki mogazynowe" +msgstr "Dzienniki magazynowe" #. module: stock #: view:product.product:0 From 7dc732af6cc21d3e3f8f850433ffc629f4436e95 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of openerp <> Date: Tue, 8 Apr 2014 07:07:58 +0000 Subject: [PATCH 381/483] Launchpad automatic translations update. bzr revid: launchpad_translations_on_behalf_of_openerp-20140408070758-jpj1hkcbia6f8630 --- addons/hr/i18n/am.po | 20 ++++++++-------- addons/stock/i18n/zh_TW.po | 49 +++++++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/addons/hr/i18n/am.po b/addons/hr/i18n/am.po index ef3a8d4cd65..478a8bc34dd 100644 --- a/addons/hr/i18n/am.po +++ b/addons/hr/i18n/am.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2013-06-07 19:36+0000\n" -"PO-Revision-Date: 2014-04-05 07:23+0000\n" +"PO-Revision-Date: 2014-04-07 13:39+0000\n" "Last-Translator: biniyam \n" "Language-Team: Amharic \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-04-06 06:53+0000\n" +"X-Launchpad-Export-Date: 2014-04-08 07:07+0000\n" "X-Generator: Launchpad (build 16976)\n" #. module: hr @@ -534,27 +534,27 @@ msgstr "" #: view:hr.job:0 #: field:hr.job,state:0 msgid "Status" -msgstr "" +msgstr "ሁኔታው" #. module: hr #: field:hr.employee,otherid:0 msgid "Other Id" -msgstr "" +msgstr "የተለየ መለያ" #. module: hr #: model:process.process,name:hr.process_process_employeecontractprocess0 msgid "Employee Contract" -msgstr "" +msgstr "የሰራተኛው ውል" #. module: hr #: view:hr.config.settings:0 msgid "Contracts" -msgstr "" +msgstr "ውሎች" #. module: hr #: help:hr.job,message_ids:0 msgid "Messages and communication history" -msgstr "" +msgstr "የመልእክትና ግንኙነት ታሪኮች" #. module: hr #: field:hr.employee,ssnid:0 @@ -564,17 +564,17 @@ msgstr "" #. module: hr #: field:hr.job,message_is_follower:0 msgid "Is a Follower" -msgstr "" +msgstr "ተከታይ ነው" #. module: hr #: field:hr.config.settings,module_hr_recruitment:0 msgid "Manage the recruitment process" -msgstr "" +msgstr "የቅጥሩን አካሄድ መቆጣጠር" #. module: hr #: view:hr.employee:0 msgid "Active" -msgstr "" +msgstr "ግልፅ" #. module: hr #: view:hr.config.settings:0 diff --git a/addons/stock/i18n/zh_TW.po b/addons/stock/i18n/zh_TW.po index 51050def38b..cb40a5afe03 100644 --- a/addons/stock/i18n/zh_TW.po +++ b/addons/stock/i18n/zh_TW.po @@ -8,13 +8,13 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2014-02-06 15:56+0000\n" -"PO-Revision-Date: 2014-04-03 11:14+0000\n" +"PO-Revision-Date: 2014-04-08 06:46+0000\n" "Last-Translator: Andy Cheng \n" "Language-Team: Chinese (Traditional) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-04-04 07:07+0000\n" +"X-Launchpad-Export-Date: 2014-04-08 07:07+0000\n" "X-Generator: Launchpad (build 16976)\n" #. module: stock @@ -4032,7 +4032,7 @@ msgstr "本次提貨無須發票" #, python-format msgid "" "You have manually created product lines, please delete them to proceed" -msgstr "" +msgstr "您有手動建立產品細項,請先刪除以繼續處理。" #. module: stock #: model:stock.location,name:stock.stock_location_shop0 @@ -4063,6 +4063,13 @@ msgid "" "* Fixed Location: The chained location is taken from the next field: Chained " "Location if Fixed." msgstr "" +"Determines whether this location is chained to another location, i.e. any " +"incoming product in this location \n" +"決定這個倉位是否鏈結到另外一個倉位,也就是說任何在這個的倉位入庫產品下一步會被移到連鎖倉位。連\n" +"鎖倉位是根據類別決定:\n" +"* 無:無連鎖倉位。\n" +"* 客戶:連鎖倉位將設為提貨單上的業務夥伴的「客戶倉位」欄位。\n" +"* 固定庫位:連鎖倉位為下一個欄位「如果連鎖庫位為固定」的設定。" #. module: stock #: code:addons/stock/stock.py:1882 @@ -4214,6 +4221,8 @@ msgid "" "If cost price is decreased, stock variation account will be creadited and " "stock input account will be debited." msgstr "" +"如果成本價格增加,庫存變動科目為借方,出庫科目為貸方,其值等於 ( 差異金額 * 存貨數量)。\n" +"如果成本價格減少,庫存變動科目為貸方,入庫科目為借方。" #. module: stock #: code:addons/stock/stock.py:2860 @@ -4406,7 +4415,7 @@ msgstr "您不能移除 %s 狀態的提貨單" msgid "" "This stock location will be used, instead of the default one, as the " "destination location for goods you send to this partner" -msgstr "" +msgstr "此倉位將會替代預設倉位,作為當您送貨至此業務夥伴的目標倉位。" #. module: stock #: view:stock.change.product.qty:0 @@ -4419,7 +4428,7 @@ msgstr "套用(_A)" #: field:stock.picking.in,max_date:0 #: field:stock.picking.out,max_date:0 msgid "Max. Expected Date" -msgstr "" +msgstr "最大預計日期" #. module: stock #: field:stock.picking,auto_picking:0 @@ -4433,12 +4442,12 @@ msgstr "自動提貨" #: report:stock.picking.list.in:0 #: report:stock.picking.list.out:0 msgid "Customer Address :" -msgstr "" +msgstr "客戶地址:" #. module: stock #: field:stock.location,chained_auto_packing:0 msgid "Chaining Type" -msgstr "" +msgstr "倉位鏈結類型" #. module: stock #: view:report.stock.inventory:0 @@ -4464,7 +4473,7 @@ msgstr "行事曆檢視" #: model:ir.actions.report.xml,name:stock.report_stock_inventory_move #: report:stock.inventory.move:0 msgid "Stock Inventory" -msgstr "" +msgstr "庫存盤點" #. module: stock #: help:report.stock.inventory,state:0 @@ -4484,12 +4493,12 @@ msgstr "" #. module: stock #: view:stock.inventory.merge:0 msgid "Do you want to merge theses inventories?" -msgstr "" +msgstr "您想要合併這些庫存盤點?" #. module: stock #: view:stock.picking.out:0 msgid "Date of Delivery" -msgstr "" +msgstr "出貨日期" #. module: stock #: field:stock.location,posy:0 @@ -4502,18 +4511,18 @@ msgstr "貨架 (Y)" msgid "" "Please define inventory valuation account on the product category: \"%s\" " "(id: %d)" -msgstr "" +msgstr "請設定此產品分類的庫存估價科目:「%s」(id: %d)" #. module: stock #: model:ir.model,name:stock.model_stock_production_lot_revision msgid "Serial Number Revision" -msgstr "" +msgstr "序號版本" #. module: stock #: code:addons/stock/product.py:100 #, python-format msgid "Specify valuation Account for Product Category: %s." -msgstr "" +msgstr "為產品分類指定估價科目:%s" #. module: stock #: help:stock.config.settings,module_claim_from_delivery:0 @@ -4521,12 +4530,14 @@ msgid "" "Adds a Claim link to the delivery order.\n" " This installs the module claim_from_delivery." msgstr "" +"為送貨單添加一個索賠鏈接。\n" +"這將會安裝 claim_from_delivery 模組," #. module: stock #: code:addons/stock/wizard/stock_return_picking.py:212 #, python-format msgid "Please specify at least one non-zero quantity." -msgstr "" +msgstr "請指定至少一個不為零的數量" #. module: stock #: field:stock.fill.inventory,set_stock_zero:0 @@ -4536,7 +4547,7 @@ msgstr "設為零" #. module: stock #: model:res.groups,name:stock.group_stock_user msgid "User" -msgstr "" +msgstr "使用者" #. module: stock #: field:stock.config.settings,module_stock_location:0 @@ -4569,7 +4580,7 @@ msgstr "" #. module: stock #: view:stock.picking:0 msgid "Check Availability" -msgstr "" +msgstr "檢查可用數量" #. module: stock #: selection:report.stock.inventory,month:0 @@ -4580,7 +4591,7 @@ msgstr "一月" #. module: stock #: constraint:stock.move:0 msgid "You cannot move products from or to a location of the type view." -msgstr "" +msgstr "不能將類型檢視的倉位作為調動的來源或目標倉位" #. module: stock #: help:stock.config.settings,group_stock_production_lot:0 @@ -4595,7 +4606,7 @@ msgstr "" #, python-format msgid "" "No product in this location. Please select a location in the product form." -msgstr "" +msgstr "該倉位沒有產品。請由產品表單選擇倉位。" #. module: stock #: model:ir.actions.act_window,name:stock.act_product_stock_move_futur_open @@ -4682,7 +4693,7 @@ msgstr "前綴" #: view:stock.move:0 #: view:stock.move.split:0 msgid "Split in Serial Numbers" -msgstr "" +msgstr "序號分拆" #. module: stock #: help:product.template,property_stock_account_input:0 From 6aa003f1ad6585b56dc712289a6eec2d0d6e4775 Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 8 Apr 2014 09:38:13 +0200 Subject: [PATCH 382/483] [IMP] improves the helper function _read_group_format_result so that it is slightly faster (orm.py) bzr revid: ged@openerp.com-20140408073813-8z23fun5274fvqaa --- openerp/osv/orm.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index bfa145fb4a6..0c5ba3c0467 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -2311,16 +2311,16 @@ class BaseModel(object): context and by properly formatting the date/datetime values. """ domain_group = [dom for gb in annotated_groupbys for dom in self._read_group_get_domain(gb, data[gb['groupby']])] - result = { '__domain': domain_group + domain } - if len(groupby) - len(annotated_groupbys) >= 1: - result['__context'] = { 'group_by': groupby[len(annotated_groupbys):]} - result.update(data) - for k,v in result.iteritems(): + for k,v in data.iteritems(): gb = groupby_dict.get(k) if gb and gb['type'] in ('date', 'datetime') and v: - result[k] = babel.dates.format_date(v, format=gb['display_format'], locale=context.get('lang', 'en_US')) - del result['id'] - return result + data[k] = babel.dates.format_date(v, format=gb['display_format'], locale=context.get('lang', 'en_US')) + + data['__domain'] = domain_group + domain + if len(groupby) - len(annotated_groupbys) >= 1: + data['__context'] = { 'group_by': groupby[len(annotated_groupbys):]} + del data['id'] + return data def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context={}, orderby=False, lazy=True): """ From 26e710fa2aad911ac756f2d16d748da68eb064a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 8 Apr 2014 10:16:48 +0200 Subject: [PATCH 383/483] [FIX] res_partner demo data: fixed email address, using a symbol not valid for an email address. bzr revid: tde@openerp.com-20140408081648-5au34720s2m4izm6 --- openerp/addons/base/res/res_partner_demo.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/res/res_partner_demo.xml b/openerp/addons/base/res/res_partner_demo.xml index cffe87b098b..4b8a19a392e 100644 --- a/openerp/addons/base/res/res_partner_demo.xml +++ b/openerp/addons/base/res/res_partner_demo.xml @@ -438,7 +438,7 @@ 89 Dong Lu Road - míng@yourcompany.example.com + ming@yourcompany.example.com +86 215 069 5177 http://www.míng.com From 568b8c76326b3dad3c9da12aae36a327f1ab6cfa Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 8 Apr 2014 10:20:29 +0200 Subject: [PATCH 384/483] [IMP] add and fix the documentation on some helper methods in read_group. (orm.py) bzr revid: ged@openerp.com-20140408082029-pmdzkbak0zjvs8jw --- openerp/osv/orm.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 0c5ba3c0467..d1c497b55a5 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -2199,17 +2199,18 @@ class BaseModel(object): to the query if order should be computed against m2o field. :param orderby: the orderby definition in the form "%(field)s %(order)s" :param aggregated_fields: list of aggregated fields in the query - :param groupby: the current groupby field name - :param qualified_field: the fully qualified SQL name for the grouped field + :param annotated_groupbys: list of dictionaries returned by _read_group_process_groupby + These dictionaries contains the qualified name of each groupby + (fully qualified SQL name for the corresponding field), + and the (non raw) field name. :param osv.Query query: the query under construction - :param groupby_type: the type of the grouped field :return: (groupby_terms, orderby_terms) """ orderby_terms = [] groupby_terms = [gb['qualified_field'] for gb in annotated_groupbys] groupby_fields = [gb['groupby'] for gb in annotated_groupbys] if not orderby: - return groupby_terms, orderby_terms + return groupby_terms, orderby_terms self._check_qorder(orderby) for order_part in orderby.split(','): @@ -2234,6 +2235,10 @@ class BaseModel(object): return groupby_terms, orderby_terms def _read_group_process_groupby(self, gb, query, context): + """ + Helper method to collect important information about groupbys: raw + field name, type, time informations, qualified name, ... + """ split = gb.split(':') field_type = self._all_columns[split[0]].column._type gb_function = split[1] if len(split) == 2 else None @@ -2353,7 +2358,6 @@ class BaseModel(object): :rtype: [{'field_name_1': value, ...] :raise AccessError: * if user has no read rights on the requested object * if user tries to bypass access rules for read on the requested object - """ self.check_access_rights(cr, uid, 'read') query = self._where_calc(cr, uid, domain, context=context) From 781e8fbbf09867e1e9b6f29839902ded6f6ba6a8 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Tue, 8 Apr 2014 10:26:49 +0200 Subject: [PATCH 385/483] [IMP] website: add Rounded Border, Box, Circle, Shadow to transform snippet bzr revid: chm@openerp.com-20140408082649-1z79gagload02ol0 --- addons/website/views/snippets.xml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml index 28cc755d87d..c999d8011db 100644 --- a/addons/website/views/snippets.xml +++ b/addons/website/views/snippets.xml @@ -965,7 +965,16 @@ From df9225295208a30fb994f81215cf8e8fecc5c760 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Tue, 8 Apr 2014 10:42:37 +0200 Subject: [PATCH 386/483] [FIX] website media editor: next previous bzr revid: chm@openerp.com-20140408084237-y8yh8cb1gsv94gbo --- .../website/static/src/js/website.editor.js | 22 ++++++++++--------- .../website/static/src/xml/website.editor.xml | 4 ---- addons/website/views/snippets.xml | 4 ++-- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 7c2ed281a04..c09f9a6b02f 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -1457,15 +1457,6 @@ //'change input.url': 'preview_image', //'change select.image-style': 'preview_image', 'click .existing-attachments img': 'select_existing', - 'click .pager > li': function (e) { - e.preventDefault(); - var $target = $(e.currentTarget); - if ($target.hasClass('disabled')) { - return; - } - this.page += $target.hasClass('previous') ? -1 : 1; - this.display_attachments(); - }, 'click .existing-attachment-remove': 'try_remove', }), @@ -1474,6 +1465,7 @@ this._super(parent, editor, media); }, start: function () { + var self = this; var res = this._super(); var o = { url: null }; @@ -1481,6 +1473,16 @@ Object.preventExtensions(o); this.trigger('start', o); + this.parent.$(".pager > li").click(function (e) { + e.preventDefault(); + var $target = $(e.currentTarget); + if ($target.hasClass('disabled')) { + return; + } + self.page += $target.hasClass('previous') ? -1 : 1; + self.display_attachments(); + }); + this.set_image(o.url); return res; @@ -1590,7 +1592,7 @@ this.$('.existing-attachments').replaceWith( openerp.qweb.render( 'website.editor.dialog.image.existing.content', {rows: rows})); - this.$('.pager') + this.parent.$('.pager') .find('li.previous').toggleClass('disabled', (from === 0)).end() .find('li.next').toggleClass('disabled', (from + per_screen >= records.length)); }, diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index f0602691515..99ffe3f6820 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -187,10 +187,6 @@
    -
    diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml index c999d8011db..b6debf6b4ec 100644 --- a/addons/website/views/snippets.xml +++ b/addons/website/views/snippets.xml @@ -959,7 +959,7 @@ From 6d234c01bdc9f0386b04a0338408583d9313f4ad Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 8 Apr 2014 11:04:18 +0200 Subject: [PATCH 387/483] [IMP] change the regex matching orders in orm.py to accept field:interval. This simplifies the code in _check_qorder (no need to compute the raw field name) bzr revid: ged@openerp.com-20140408090418-5yjnfp6axumytmrq --- openerp/osv/orm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index d1c497b55a5..0db95e7498d 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -75,7 +75,7 @@ _schema = logging.getLogger(__name__ + '.schema') # List of etree._Element subclasses that we choose to ignore when parsing XML. from openerp.tools import SKIPPED_ELEMENT_TYPES -regex_order = re.compile('^( *([a-z0-9_]+|"[a-z0-9_]+")( *desc| *asc)?( *, *|))+$', re.I) +regex_order = re.compile('^( *([a-z0-9:_]+|"[a-z0-9:_]+")( *desc| *asc)?( *, *|))+$', re.I) regex_object_name = re.compile(r'^[a-z0-9_.]+$') AUTOINIT_RECALCULATE_STORED_FIELDS = 1000 @@ -4442,7 +4442,7 @@ class BaseModel(object): return Query(tables, where_clause, where_params) def _check_qorder(self, word): - if not regex_order.match(word.split(':')[0]): + if not regex_order.match(word): raise except_orm(_('AccessError'), _('Invalid "order" specified. A valid "order" specification is a comma-separated list of valid field names (optionally followed by asc/desc for the direction)')) return True From d15ba59a23384bcebbbcf3c369a4fb6b287e7a23 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Tue, 8 Apr 2014 11:36:48 +0200 Subject: [PATCH 388/483] [IMP] website: media editor: placeholder and preview bzr revid: chm@openerp.com-20140408093648-zcx3nj5k068ejrb4 --- .../website/static/src/js/website.editor.js | 39 ++++++++++++++++--- .../static/src/js/website.snippets.editor.js | 1 + .../website/static/src/xml/website.editor.xml | 26 ++++++------- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index c09f9a6b02f..b27fd94c091 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -1442,7 +1442,7 @@ * originally passed in) */ var IMAGES_PER_ROW = 6; - var IMAGES_ROWS = 4; + var IMAGES_ROWS = 2; website.editor.ImageDialog = website.editor.Media.extend({ template: 'website.editor.dialog.image', events: _.extend({}, website.editor.Dialog.prototype.events, { @@ -1454,7 +1454,13 @@ }, 'change input[type=file]': 'file_selection', 'submit form': 'form_submit', - //'change input.url': 'preview_image', + 'change input.url': function (e) { + if ($(e.target).val() === "") { + this.$("button").addClass("btn-default").removeClass("btn-primary"); + } else { + this.$("button").removeClass("btn-default").addClass("btn-primary"); + } + }, //'change select.image-style': 'preview_image', 'click .existing-attachments img': 'select_existing', 'click .existing-attachment-remove': 'try_remove', @@ -1488,11 +1494,14 @@ return res; }, save: function () { + if (!this.link) { + this.link = this.$(".existing-attachments img:first").attr('src'); + } this.trigger('save', { - url: this.$('input.url').val() + url: this.link }); this.media.renameNode("img"); - this.media.$.attributes.src = this.$('input.url').val(); + this.media.$.attributes.src = this.link; return this._super(); }, clear: function () { @@ -1511,7 +1520,8 @@ set_image: function (url, error) { var self = this; - this.$('input.url').val(error ? null : url || ''); + if (url) this.link = url; + this.$('input.url').val(''); this.fetch_existing().then(function () { self.selected_existing(url); }); @@ -1551,6 +1561,8 @@ $button.addClass('btn-danger'); } this.set_image(url, error); + // auto save and close popup + this.parent.save(); }, fetch_existing: function (needle) { @@ -1598,10 +1610,10 @@ }, select_existing: function (e) { var link = $(e.currentTarget).attr('src'); + this.link = link; this.selected_existing(link); }, selected_existing: function (link) { - this.$('input.url').val(link); this.$('.existing-attachment-cell.media_selected').removeClass("media_selected"); var $select = this.$('.existing-attachment-cell img').filter(function () { return $(this).attr("src") == link; @@ -1848,6 +1860,8 @@ events : _.extend({}, website.editor.Dialog.prototype.events, { 'click input#urlvideo ~ button': 'get_video', 'click input#embedvideo ~ button': 'get_embed_video', + 'change input#urlvideo': 'change_input', + 'change input#embedvideo': 'change_input' }), start: function () { this.$iframe = this.$("iframe"); @@ -1860,6 +1874,15 @@ } return this._super(); }, + change_input: function (e) { + var $input = $(e.target); + var $button = $input.parent().find("button"); + if ($input.val() === "") { + $button.addClass("btn-default").removeClass("btn-primary"); + } else { + $button.removeClass("btn-default").addClass("btn-primary"); + } + }, get_url: function () { var video_id = this.$("#video_id").val(); var video_type = this.$("#video_type").val(); @@ -1914,6 +1937,10 @@ }, save: function () { var video_id = this.$("#video_id").val(); + if (!video_id) { + this.$("button.btn-primary").click(); + video_id = this.$("#video_id").val(); + } var video_type = this.$("#video_type").val(); var style = this.media.$.attributes.style ? this.media.$.attributes.style.textContent : ''; var $iframe = $( diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 03016905bf2..fac4f9ab357 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -1493,6 +1493,7 @@ $(document.body).on("media-saved", self, function (event, prev , item) { self.editor.onBlur(); + self.BuildingBlock.make_active(false); self.BuildingBlock.make_active($(item)); }); diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index 99ffe3f6820..0fcbc585ae5 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -147,17 +147,18 @@ target="fileframe" class="form-inline">
    +
    + +
    + + +
    +
    - — or — - -
    - - -
    @@ -303,9 +304,8 @@ class="form-control url pull-left" style="width: 400px;" id="urlvideo" - placeholder="http://openerp.com" - value="//www.youtube.com/embed/yws1tbgNV7k"/> - + placeholder="//www.youtube.com/embed/yws1tbgNV7k"/> +
    @@ -315,21 +315,21 @@ style="width: 400px;" id="embedvideo" placeholder='<iframe src="//www.youtube.com/embed/yws1tbgNV7k"></iframe>'/> - +
    - - + +
    From 81b84c62b182349c1ed4e15b743f66951f15fdb9 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 8 Apr 2014 11:45:13 +0200 Subject: [PATCH 389/483] [IMP] registry: switch for a dummy lock only during the execution of http tests bzr revid: rco@openerp.com-20140408094513-ahtwod1q17ijohbg --- openerp/modules/registry.py | 43 ++++++++++++++++++++++++------------- openerp/tests/common.py | 3 +++ 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py index 78b7e5caeab..ff0d56a409c 100644 --- a/openerp/modules/registry.py +++ b/openerp/modules/registry.py @@ -193,17 +193,12 @@ class Registry(Mapping): finally: cr.close() -class TestRLock(object): - def __init__(self): - self._lock = threading.RLock() +class DummyRLock(object): + """ Dummy reentrant lock, to be used while running rpc and js tests """ def acquire(self): - if openerp.tools.config['test_enable']: - return - return self._lock.acquire() + pass def release(self): - if openerp.tools.config['test_enable']: - return - return self._lock.release() + pass def __enter__(self): self.acquire() def __exit__(self, type, value, traceback): @@ -219,12 +214,30 @@ class RegistryManager(object): # Mapping between db name and model registry. # Accessed through the methods below. registries = {} - registries_lock = TestRLock() + _lock = threading.RLock() + _saved_lock = None + + @classmethod + def lock(cls): + """ Return the current registry lock. """ + return cls._lock + + @classmethod + def enter_test_mode(cls): + """ Enter the 'test' mode, where the registry is no longer locked. """ + assert cls._saved_lock is None + cls._lock, cls._saved_lock = DummyRLock(), cls._lock + + @classmethod + def leave_test_mode(cls): + """ Leave the 'test' mode. """ + assert cls._saved_lock is not None + cls._lock, cls._saved_lock = cls._saved_lock, None @classmethod def get(cls, db_name, force_demo=False, status=None, update_module=False): """ Return a registry for a given database name.""" - with cls.registries_lock: + with cls.lock(): try: return cls.registries[db_name] except KeyError: @@ -244,7 +257,7 @@ class RegistryManager(object): """ import openerp.modules - with cls.registries_lock: + with cls.lock(): registry = Registry(db_name) # Initializing a registry will call general code which will in turn @@ -286,7 +299,7 @@ class RegistryManager(object): @classmethod def delete(cls, db_name): """Delete the registry linked to a given database. """ - with cls.registries_lock: + with cls.lock(): if db_name in cls.registries: cls.registries[db_name].clear_caches() del cls.registries[db_name] @@ -294,7 +307,7 @@ class RegistryManager(object): @classmethod def delete_all(cls): """Delete all the registries. """ - with cls.registries_lock: + with cls.lock(): for db_name in cls.registries.keys(): cls.delete(db_name) @@ -309,7 +322,7 @@ class RegistryManager(object): This method is given to spare you a ``RegistryManager.get(db_name)`` that would loads the given database if it was not already loaded. """ - with cls.registries_lock: + with cls.lock(): if db_name in cls.registries: cls.registries[db_name].clear_caches() diff --git a/openerp/tests/common.py b/openerp/tests/common.py index c1f7cf88ed1..a926726c370 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -67,6 +67,7 @@ def at_install(flag): obj.at_install = flag return obj return decorator + def post_install(flag): """ Sets the post-install state of a test. The flag is a boolean specifying whether the test should or should not run after a set of @@ -166,6 +167,7 @@ class HttpCase(TransactionCase): def setUp(self): super(HttpCase, self).setUp() + openerp.modules.registry.RegistryManager.enter_test_mode() # setup a magic session_id that will be rollbacked self.session = openerp.http.root.session_store.new() self.session_id = self.session.sid @@ -176,6 +178,7 @@ class HttpCase(TransactionCase): def tearDown(self): del HTTP_SESSION[self.session_id] + openerp.modules.registry.RegistryManager.leave_test_mode() super(HttpCase, self).tearDown() def url_open(self, url, data=None, timeout=10): From 81f2c983e5e901a7c832b7213595f1bd6443a347 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Tue, 8 Apr 2014 11:47:03 +0200 Subject: [PATCH 390/483] [IMP] website: media editor: change button on keyup bzr revid: chm@openerp.com-20140408094703-7qayghtm88qku3jz --- .../website/static/src/js/website.editor.js | 23 ++++++++++++------- .../website/static/src/xml/website.editor.xml | 15 ++++++------ 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index b27fd94c091..365b8cf46ea 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -1454,13 +1454,8 @@ }, 'change input[type=file]': 'file_selection', 'submit form': 'form_submit', - 'change input.url': function (e) { - if ($(e.target).val() === "") { - this.$("button").addClass("btn-default").removeClass("btn-primary"); - } else { - this.$("button").removeClass("btn-default").addClass("btn-primary"); - } - }, + 'change input.url': "change_input", + 'keyup input.url': "change_input", //'change select.image-style': 'preview_image', 'click .existing-attachments img': 'select_existing', 'click .existing-attachment-remove': 'try_remove', @@ -1511,6 +1506,16 @@ this.trigger('cancel'); }, + change_input: function (e) { + var $input = $(e.target); + var $button = $input.parent().find("button"); + if ($input.val() === "") { + $button.addClass("btn-default").removeClass("btn-primary"); + } else { + $button.removeClass("btn-default").addClass("btn-primary"); + } + }, + search: function (needle) { var self = this; this.fetch_existing(needle).then(function () { @@ -1861,7 +1866,9 @@ 'click input#urlvideo ~ button': 'get_video', 'click input#embedvideo ~ button': 'get_embed_video', 'change input#urlvideo': 'change_input', - 'change input#embedvideo': 'change_input' + 'keyup input#urlvideo': 'change_input', + 'change input#embedvideo': 'change_input', + 'keyup input#embedvideo': 'change_input' }), start: function () { this.$iframe = this.$("iframe"); diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index 0fcbc585ae5..879da3011f6 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -147,18 +147,19 @@ target="fileframe" class="form-inline">
    -
    - +
    + + + +
    +
    + — or — +
    -
    - - - -
    From 7a905238f299816543ea99d7881f7da5d16eec85 Mon Sep 17 00:00:00 2001 From: "chm@openerp.com" <> Date: Tue, 8 Apr 2014 11:53:43 +0200 Subject: [PATCH 391/483] [IMP] website: media editor: don't display id in error message bzr revid: chm@openerp.com-20140408095343-bg9348ieabf3ayp8 --- addons/website/static/src/xml/website.editor.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index 879da3011f6..669d5f42e2f 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -206,7 +206,7 @@
  • - (id ) +
  • From b49f536baff6fab13884f4b2b6fdee1cb407f128 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 8 Apr 2014 13:49:36 +0200 Subject: [PATCH 392/483] [IMP] tests.common: turn class methods into instance methods (this will ease some future refactoring) bzr revid: rco@openerp.com-20140408114936-jfagg4qvft8bk3ms --- openerp/addons/base/tests/test_views.py | 2 +- openerp/modules/registry.py | 4 ++++ openerp/tests/common.py | 22 ++++++++-------------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/openerp/addons/base/tests/test_views.py b/openerp/addons/base/tests/test_views.py index 06030a84792..f0967836726 100644 --- a/openerp/addons/base/tests/test_views.py +++ b/openerp/addons/base/tests/test_views.py @@ -28,7 +28,7 @@ class ViewCase(common.TransactionCase): self.assertTreesEqual(c1, c2, msg) -class TestNodeLocator(common.BaseCase): +class TestNodeLocator(common.TransactionCase): """ The node locator returns None when it can not find a node, and the first match when it finds something (no jquery-style node sets) diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py index ff0d56a409c..2db14744915 100644 --- a/openerp/modules/registry.py +++ b/openerp/modules/registry.py @@ -102,6 +102,10 @@ class Registry(Mapping): """ Return the model with the given name or raise KeyError if it doesn't exist.""" return self.models[model_name] + def __call__(self, model_name): + """ Same as ``self[model_name]``. """ + return self.models[model_name] + def do_parent_store(self, cr): for o in self._init_parent: self.get(o)._parent_store_compute(cr) diff --git a/openerp/tests/common.py b/openerp/tests/common.py index a926726c370..6c4864e46d5 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -84,18 +84,13 @@ class BaseCase(unittest2.TestCase): """ Subclass of TestCase for common OpenERP-specific code. - This class is abstract and expects self.cr and self.uid to be initialized by subclasses. + This class is abstract and expects self.registry, self.cr and self.uid to be + initialized by subclasses. """ - @classmethod def cursor(self): - return openerp.modules.registry.RegistryManager.get(DB).db.cursor() + return self.registry.db.cursor() - @classmethod - def registry(self, model): - return openerp.modules.registry.RegistryManager.get(DB)[model] - - @classmethod def ref(self, xid): """ Returns database ID corresponding to a given identifier. @@ -107,7 +102,6 @@ class BaseCase(unittest2.TestCase): _, id = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, module, xid) return id - @classmethod def browse_ref(self, xid): """ Returns a browsable record for the given identifier. @@ -126,10 +120,9 @@ class TransactionCase(BaseCase): """ def setUp(self): - # Store cr and uid in class variables, to allow ref() and browse_ref to be BaseCase @classmethods - # and still access them - TransactionCase.cr = self.cursor() - TransactionCase.uid = openerp.SUPERUSER_ID + self.registry = openerp.modules.registry.RegistryManager.get(DB) + self.cr = self.cursor() + self.uid = openerp.SUPERUSER_ID def tearDown(self): self.cr.rollback() @@ -144,7 +137,8 @@ class SingleTransactionCase(BaseCase): @classmethod def setUpClass(cls): - cls.cr = cls.cursor() + cls.registry = openerp.modules.registry.RegistryManager.get(DB) + cls.cr = cls.registry.db.cursor() cls.uid = openerp.SUPERUSER_ID @classmethod From a16b0c79079c045206f81b2d02edf729673eeb97 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Tue, 8 Apr 2014 14:01:41 +0200 Subject: [PATCH 393/483] [IMP] web: select input on add record in list editable bzr revid: dle@openerp.com-20140408120141-f1fx2e9e8vqatccx --- addons/web/static/src/js/view_list_editable.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index 53ea069cee6..c4aac5565ab 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -123,10 +123,19 @@ openerp.web.list_editable = function (instance) { * as an editable row at the top or bottom of the list) */ do_add_record: function () { + var self = this; if (this.editable()) { this.$el.find('table:first').show(); this.$el.find('.oe_view_nocontent').remove(); - this.start_edition(); + this.start_edition().then(function(){ + var fields = self.editor.form.fields; + self.editor.form.fields_order.some(function(field){ + if (fields[field].$el.is(':visible')){ + fields[field].$el.find("input").select(); + return true; + } + }); + }); } else { this._super(); } From e143250b7a199c10ce5149183c000094447d374c Mon Sep 17 00:00:00 2001 From: Gery Debongnie Date: Tue, 8 Apr 2014 14:24:17 +0200 Subject: [PATCH 394/483] [IMP] simplifies the readgroup code to select order by (orm.py) bzr revid: ged@openerp.com-20140408122417-y75wp0plyloiamuy --- openerp/osv/orm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index d5c147dac73..7b11b9a2b3a 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -2373,7 +2373,7 @@ class BaseModel(object): annotated_groupbys = [self._read_group_process_groupby(gb, query, context) for gb in groupby_list] groupby_fields = [g['field'] for g in annotated_groupbys] - order = orderby or ','.join([g['groupby'] for g in annotated_groupbys]) + order = orderby or ','.join([g for g in groupby_list]) groupby_dict = {gb['groupby']: gb for gb in annotated_groupbys} self._apply_ir_rules(cr, uid, query, 'read', context=context) From 6bc60505f4e25d5ce7181f30d33692a8e7d08fe0 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Tue, 8 Apr 2014 14:51:22 +0200 Subject: [PATCH 395/483] [IMP] registry: add method get_cursor() to simply retrieve a new cursor, and refactor code to use it bzr revid: rco@openerp.com-20140408125122-ki0zmin3m21k2itd --- openerp/addons/base/res/res_users.py | 6 +++--- openerp/addons/base/tests/test_ir_sequence.py | 2 +- openerp/addons/base/tests/test_uninstall.py | 2 +- openerp/cli/server.py | 4 ++-- openerp/http.py | 2 +- openerp/modules/registry.py | 17 +++++++++++------ openerp/service/model.py | 15 ++------------- openerp/service/report.py | 4 ++-- openerp/tests/common.py | 4 ++-- openerp/tools/mail.py | 2 +- openerpcommand/module.py | 5 +---- openerpcommand/read.py | 5 +---- openerpcommand/uninstall.py | 5 +---- 13 files changed, 29 insertions(+), 44 deletions(-) diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index 772f7f7290b..0ad1d1276f6 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -388,7 +388,7 @@ class res_users(osv.osv): if not password: return False user_id = False - cr = self.pool.db.cursor() + cr = self.pool.get_cursor() try: # autocommit: our single update request will be performed atomically. # (In this way, there is no opportunity to have two transactions @@ -440,7 +440,7 @@ class res_users(osv.osv): # Successfully logged in as admin! # Attempt to guess the web base url... if user_agent_env and user_agent_env.get('base_location'): - cr = self.pool.db.cursor() + cr = self.pool.get_cursor() try: base = user_agent_env['base_location'] ICP = self.pool['ir.config_parameter'] @@ -461,7 +461,7 @@ class res_users(osv.osv): raise openerp.exceptions.AccessDenied() if self._uid_cache.get(db, {}).get(uid) == passwd: return - cr = self.pool.db.cursor() + cr = self.pool.get_cursor() try: self.check_credentials(cr, uid, passwd) if self._uid_cache.has_key(db): diff --git a/openerp/addons/base/tests/test_ir_sequence.py b/openerp/addons/base/tests/test_ir_sequence.py index e925fffa3b1..5bb64720336 100644 --- a/openerp/addons/base/tests/test_ir_sequence.py +++ b/openerp/addons/base/tests/test_ir_sequence.py @@ -21,7 +21,7 @@ def registry(model): return openerp.modules.registry.RegistryManager.get(DB)[model] def cursor(): - return openerp.modules.registry.RegistryManager.get(DB).db.cursor() + return openerp.modules.registry.RegistryManager.get(DB).get_cursor() def drop_sequence(code): diff --git a/openerp/addons/base/tests/test_uninstall.py b/openerp/addons/base/tests/test_uninstall.py index 2425249afa4..7c88196fbf6 100644 --- a/openerp/addons/base/tests/test_uninstall.py +++ b/openerp/addons/base/tests/test_uninstall.py @@ -13,7 +13,7 @@ def registry(model): return openerp.modules.registry.RegistryManager.get(DB)[model] def cursor(): - return openerp.modules.registry.RegistryManager.get(DB).db.cursor() + return openerp.modules.registry.RegistryManager.get(DB).get_cursor() def get_module(module_name): registry = openerp.modules.registry.RegistryManager.get(DB) diff --git a/openerp/cli/server.py b/openerp/cli/server.py index e7ba695f19c..a808511ab8a 100644 --- a/openerp/cli/server.py +++ b/openerp/cli/server.py @@ -103,7 +103,7 @@ def export_translation(): fileformat = os.path.splitext(config["translate_out"])[-1][1:].lower() buf = file(config["translate_out"], "w") registry = openerp.modules.registry.RegistryManager.new(dbname) - cr = registry.db.cursor() + cr = registry.get_cursor() openerp.tools.trans_export(config["language"], config["translate_modules"] or ["all"], buf, fileformat, cr) cr.close() @@ -117,7 +117,7 @@ def import_translation(): dbname = config['db_name'] registry = openerp.modules.registry.RegistryManager.new(dbname) - cr = registry.db.cursor() + cr = registry.get_cursor() openerp.tools.trans_load( cr, config["translate_in"], config["language"], context=context) cr.commit() diff --git a/openerp/http.py b/openerp/http.py index 5f37afbc116..d346211c89b 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -238,7 +238,7 @@ class WebRequest(object): # Test cursors self._cr = openerp.tests.common.acquire_test_cursor(self.session_id) if not self._cr: - self._cr = self.registry.db.cursor() + self._cr = self.registry.get_cursor() return self._cr def __enter__(self): diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py index 2db14744915..60f56ef035c 100644 --- a/openerp/modules/registry.py +++ b/openerp/modules/registry.py @@ -75,7 +75,7 @@ class Registry(Mapping): # Useful only in a multi-process context. self._any_cache_cleared = False - cr = self.db.cursor() + cr = self.get_cursor() has_unaccent = openerp.modules.db.has_unaccent(cr) if openerp.tools.config['unaccent'] and not has_unaccent: _logger.warning("The option --unaccent was given but no unaccent() function was found in database.") @@ -187,9 +187,14 @@ class Registry(Mapping): r, c) return r, c + def get_cursor(self): + """ Return a new cursor for the database. """ + return self.db.cursor() + @contextmanager def cursor(self, auto_commit=True): - cr = self.db.cursor() + """ Manage a new cursor; commit, rollback and closing are automatic. """ + cr = self.get_cursor() try: yield cr if auto_commit: @@ -286,7 +291,7 @@ class RegistryManager(object): # Yeah, crazy. registry = cls.registries[db_name] - cr = registry.db.cursor() + cr = registry.get_cursor() try: registry.do_parent_store(cr) cr.commit() @@ -342,7 +347,7 @@ class RegistryManager(object): changed = False if openerp.multi_process and db_name in cls.registries: registry = cls.get(db_name) - cr = registry.db.cursor() + cr = registry.get_cursor() try: cr.execute(""" SELECT base_registry_signaling.last_value, @@ -388,7 +393,7 @@ class RegistryManager(object): registry = cls.get(db_name) if registry.any_cache_cleared(): _logger.info("At least one model cache has been cleared, signaling through the database.") - cr = registry.db.cursor() + cr = registry.get_cursor() r = 1 try: cr.execute("select nextval('base_cache_signaling')") @@ -403,7 +408,7 @@ class RegistryManager(object): if openerp.multi_process and db_name in cls.registries: _logger.info("Registry changed, signaling through the database") registry = cls.get(db_name) - cr = registry.db.cursor() + cr = registry.get_cursor() r = 1 try: cr.execute("select nextval('base_registry_signaling')") diff --git a/openerp/service/model.py b/openerp/service/model.py index a637e234295..a91baf8ca08 100644 --- a/openerp/service/model.py +++ b/openerp/service/model.py @@ -161,21 +161,10 @@ def execute_cr(cr, uid, obj, method, *args, **kw): def execute_kw(db, uid, obj, method, args, kw=None): return execute(db, uid, obj, method, *args, **kw or {}) -@contextmanager -def closing_cr_and_commit(cr): - try: - yield cr - cr.commit() - except Exception: - cr.rollback() - raise - finally: - cr.close() - @check def execute(db, uid, obj, method, *args, **kw): threading.currentThread().dbname = db - with closing_cr_and_commit(openerp.registry(db).db.cursor()) as cr: + with openerp.registry(db).cursor() as cr: if method.startswith('_'): raise except_orm('Access Denied', 'Private methods (such as %s) cannot be called remotely.' % (method,)) res = execute_cr(cr, uid, obj, method, *args, **kw) @@ -190,7 +179,7 @@ def exec_workflow_cr(cr, uid, obj, signal, *args): @check def exec_workflow(db, uid, obj, signal, *args): - with closing_cr_and_commit(openerp.registry(db).db.cursor()) as cr: + with openerp.registry(db).cursor() as cr: return exec_workflow_cr(cr, uid, obj, signal, *args) # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/service/report.py b/openerp/service/report.py index 370b11fc199..30e043c2977 100644 --- a/openerp/service/report.py +++ b/openerp/service/report.py @@ -49,7 +49,7 @@ def exp_render_report(db, uid, object, ids, datas=None, context=None): self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None} - cr = openerp.registry(db).db.cursor() + cr = openerp.registry(db).get_cursor() try: result, format = openerp.report.render_report(cr, uid, ids, object, datas, context) if not result: @@ -87,7 +87,7 @@ def exp_report(db, uid, object, ids, datas=None, context=None): self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None} def go(id, uid, ids, datas, context): - cr = openerp.registry(db).db.cursor() + cr = openerp.registry(db).get_cursor() try: result, format = openerp.report.render_report(cr, uid, ids, object, datas, context) if not result: diff --git a/openerp/tests/common.py b/openerp/tests/common.py index 6c4864e46d5..4b20c0bc7c4 100644 --- a/openerp/tests/common.py +++ b/openerp/tests/common.py @@ -89,7 +89,7 @@ class BaseCase(unittest2.TestCase): """ def cursor(self): - return self.registry.db.cursor() + return self.registry.get_cursor() def ref(self, xid): """ Returns database ID corresponding to a given identifier. @@ -138,7 +138,7 @@ class SingleTransactionCase(BaseCase): @classmethod def setUpClass(cls): cls.registry = openerp.modules.registry.RegistryManager.get(DB) - cls.cr = cls.registry.db.cursor() + cls.cr = cls.registry.get_cursor() cls.uid = openerp.SUPERUSER_ID @classmethod diff --git a/openerp/tools/mail.py b/openerp/tools/mail.py index 85dcfd368fe..3da075fda6e 100644 --- a/openerp/tools/mail.py +++ b/openerp/tools/mail.py @@ -625,7 +625,7 @@ def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=Non if not cr: db_name = getattr(threading.currentThread(), 'dbname', None) if db_name: - local_cr = cr = openerp.registry(db_name).db.cursor() + local_cr = cr = openerp.registry(db_name).get_cursor() else: raise Exception("No database cursor found, please pass one explicitly") diff --git a/openerpcommand/module.py b/openerpcommand/module.py index 550e0a2be28..284c0186785 100644 --- a/openerpcommand/module.py +++ b/openerpcommand/module.py @@ -33,12 +33,9 @@ def run(args): xs = [] ir_module_module = registry.get('ir.module.module') - cr = registry.db.cursor() # TODO context manager - try: + with registry.cursor() as cr: ids = ir_module_module.search(cr, openerp.SUPERUSER_ID, [], {}) xs = ir_module_module.read(cr, openerp.SUPERUSER_ID, ids, [], {}) - finally: - cr.close() if xs: print "Modules (database `%s`):" % (args.database,) diff --git a/openerpcommand/read.py b/openerpcommand/read.py index 5b68fb26ef0..61c05117875 100644 --- a/openerpcommand/read.py +++ b/openerpcommand/read.py @@ -20,15 +20,12 @@ def run(args): registry = openerp.modules.registry.RegistryManager.get( args.database, update_module=False) model = registry[args.model] - cr = registry.db.cursor() # TODO context manager field_names = [args.field] if args.field else [] if args.short: # ignore --field field_names = ['name'] - try: + with registry.cursor() as cr: xs = model.read(cr, 1, args.id, field_names, {}) - finally: - cr.close() if xs: print "Records (model `%s`, database `%s`):" % (args.model, args.database) diff --git a/openerpcommand/uninstall.py b/openerpcommand/uninstall.py index 27e4e04002a..244b0575e53 100644 --- a/openerpcommand/uninstall.py +++ b/openerpcommand/uninstall.py @@ -43,15 +43,12 @@ def run(args): args.database, update_module=False) ir_module_module = registry.get('ir.module.module') - cr = registry.db.cursor() # TODO context manager - try: + with registry.cursor() as cr: ids = ir_module_module.search(cr, openerp.SUPERUSER_ID, [('name', 'in', args.module), ('state', '=', 'installed')], {}) if len(ids) == len(args.module): ir_module_module.button_immediate_uninstall(cr, openerp.SUPERUSER_ID, ids, {}) else: print "At least one module not found (database `%s`)." % (args.database,) - finally: - cr.close() def add_parser(subparsers): parser = subparsers.add_parser('uninstall', From 5dac705c1a3f3ea24caa67e28afdcf37c903bf79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 8 Apr 2014 15:41:15 +0200 Subject: [PATCH 396/483] [IMP] website_blog: enable_editor + slugify URLs in order to be directly in edit mode when creating a new blog. bzr revid: tde@openerp.com-20140408134115-125vtpmtikdd2u26 --- addons/website_blog/controllers/main.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/addons/website_blog/controllers/main.py b/addons/website_blog/controllers/main.py index 1a0bcf9402e..ee9bdc98c57 100644 --- a/addons/website_blog/controllers/main.py +++ b/addons/website_blog/controllers/main.py @@ -297,19 +297,20 @@ class WebsiteBlog(http.Controller): user = request.registry['res.users'].browse(cr, uid, uid, context=context) id = self._blog_post_message(user, blog_post_id, **post) return self._get_discussion_detail([id], publish, **post) - + @http.route('/blogpost/new', type='http', auth="public", website=True, multilang=True) def blog_post_create(self, blog_id, **post): cr, uid, context = request.cr, request.uid, request.context create_context = dict(context, mail_create_nosubscribe=True) new_blog_post_id = request.registry['blog.post'].create(cr, uid, { - 'blog_id': blog_id, - 'name': _("Blog Post Title"), - 'sub_title': _("Subtitle"), - 'content': '', - 'website_published': False, - }, context=create_context) - return werkzeug.utils.redirect("/blog/%s/post/%s/?enable_editor=1" % (blog_id, new_blog_post_id)) + 'blog_id': blog_id, + 'name': _("Blog Post Title"), + 'subtitle': _("Subtitle"), + 'content': '', + 'website_published': False, + }, context=create_context) + new_blog_post = request.registry['blog.post'].browse(cr, uid, new_blog_post_id, context=context) + return werkzeug.utils.redirect("/blog/%s/post/%s?enable_editor=1" % (slug(new_blog_post.blog_id), slug(new_blog_post))) @http.route('/blogpost/duplicate', type='http', auth="public", website=True) def blog_post_copy(self, blog_post_id, **post): @@ -322,8 +323,9 @@ class WebsiteBlog(http.Controller): cr, uid, context = request.cr, request.uid, request.context create_context = dict(context, mail_create_nosubscribe=True) nid = request.registry['blog.post'].copy(cr, uid, blog_post_id, {}, context=create_context) + new_blog_post = request.registry['blog.post'].browse(cr, uid, nid, context=context) post = request.registry['blog.post'].browse(cr, uid, nid, context) - return werkzeug.utils.redirect("/blog/%s/post/%s/?enable_editor=1" % (post.blog_id.id, nid)) + return werkzeug.utils.redirect("/blog/%s/post/%s?enable_editor=1" % (slug(post.blog_id), slug(new_blog_post))) @http.route('/blogpost/get_discussion/', type='json', auth="public", website=True) def discussion(self, post_id=0, path=None, count=False, **post): From 6c6885d7fa97483928839c40b9114fe15db48fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 8 Apr 2014 15:47:28 +0200 Subject: [PATCH 397/483] [IMP] website_blog: always have a next_post, even a visited one, it you have at least 2 posts. bzr revid: tde@openerp.com-20140408134728-fy4mbsuetwksa76v --- addons/website_blog/controllers/main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/website_blog/controllers/main.py b/addons/website_blog/controllers/main.py index ee9bdc98c57..e2eac59678e 100644 --- a/addons/website_blog/controllers/main.py +++ b/addons/website_blog/controllers/main.py @@ -196,7 +196,7 @@ class WebsiteBlog(http.Controller): blog_url = QueryURL('', ['blog', 'tag'], blog=blog_post.blog_id, tag=tag, date_begin=date_begin, date_end=date_end) if not blog_post.blog_id.id == blog.id: - return request.redirect("/blog/%s/post/%s" % (blog_post.blog_id.id, blog_post.id)) + return request.redirect("/blog/%s/post/%s" % (slug(blog_post.blog_id), slug(blog_post))) tags = tag_obj.browse(cr, uid, tag_obj.search(cr, uid, [], context=context), context=context) @@ -209,6 +209,8 @@ class WebsiteBlog(http.Controller): next_post_id = blog_post_obj.search(cr, uid, [ ('id', 'not in', visited_ids), ], order='ranking desc', limit=1, context=context) + if not next_post_id: + next_post_id = blog_post_obj.search(cr, uid, [('id', '!=', blog.id)], order='ranking desc', limit=1, context=context) next_post = next_post_id and blog_post_obj.browse(cr, uid, next_post_id[0], context=context) or False values = { @@ -223,6 +225,7 @@ class WebsiteBlog(http.Controller): 'date': date_begin, 'post_url': post_url, 'blog_url': blog_url, + 'pager': pager, } response = request.website.render("website_blog.blog_post_complete", values) response.set_cookie('visited_blogs', ','.join(map(str, visited_ids))) From e1bf5bd97c93f05dbbff9fd2a6fb06b9cb69066b Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Tue, 8 Apr 2014 15:49:53 +0200 Subject: [PATCH 398/483] [IMP] Report: renamed 'render_doc' method as 'translate_doc' for better understanding and added it a 'lang_field' attribute to explicitely set the lang. Adapted report_invoice, report_saleorder, report_overdue and report_intrastatinvoice this way. bzr revid: sle@openerp.com-20140408134953-vql9ft8cosoanixt --- addons/account/views/report_invoice.xml | 2 +- addons/account/views/report_overdue.xml | 2 +- addons/report/models/report.py | 25 +- .../views/report_intrastatinvoice.xml | 2 +- addons/sale/views/report_saleorder.xml | 250 +++++++++--------- 5 files changed, 140 insertions(+), 141 deletions(-) diff --git a/addons/account/views/report_invoice.xml b/addons/account/views/report_invoice.xml index 437c9726bf3..6757095a7d4 100644 --- a/addons/account/views/report_invoice.xml +++ b/addons/account/views/report_invoice.xml @@ -145,7 +145,7 @@ diff --git a/addons/account/views/report_overdue.xml b/addons/account/views/report_overdue.xml index 772e7661800..bc522aa8b9d 100644 --- a/addons/account/views/report_overdue.xml +++ b/addons/account/views/report_overdue.xml @@ -110,7 +110,7 @@ diff --git a/addons/report/models/report.py b/addons/report/models/report.py index f619b2db0cb..8dd8a4dce6f 100644 --- a/addons/report/models/report.py +++ b/addons/report/models/report.py @@ -23,6 +23,7 @@ from openerp.osv import osv from openerp.tools import config from openerp.tools.translate import _ from openerp.addons.web.http import request +from openerp.tools.safe_eval import safe_eval as eval import os import time @@ -103,17 +104,17 @@ class Report(osv.Model): view_obj = self.pool['ir.ui.view'] - def render_doc(doc_id, model, template): - """Helper used when a report should be translated into the associated - partner's lang. + def translate_doc(doc_id, model, lang_field, template): + """Helper used when a report should be translated into a specific lang. - + :param doc_id: id of the record to translate :param model: model of the record to translate - :param template: name of the template to translate into the partner's lang + :param lang_field': field of the record containing the lang + :param template: name of the template to translate into the lang_field """ ctx = context.copy() doc = self.pool[model].browse(cr, uid, doc_id, context=ctx) @@ -122,15 +123,9 @@ class Report(osv.Model): if ctx.get('translatable') is True: qcontext['o'] = doc else: - # Guessing the lang we want to translate the doc into - newlang = None - if doc._model._all_columns.get('partner_id'): - newlang = doc.partner_id.lang - elif doc._model._all_columns.get('lang'): - newlang = doc.lang - if newlang: - ctx['lang'] = newlang - qcontext['o'] = self.pool[model].browse(cr, uid, doc_id, context=ctx) + # Reach the lang we want to translate the doc into + ctx['lang'] = eval('doc.%s' % lang_field, {'doc': doc}) + qcontext['o'] = self.pool[model].browse(cr, uid, doc_id, context=ctx) return view_obj.render(cr, uid, template, qcontext, context=ctx) user = self.pool['res.users'].browse(cr, uid, uid) @@ -139,7 +134,7 @@ class Report(osv.Model): website = request.website values.update({ 'time': time, - 'render_doc': render_doc, + 'translate_doc': translate_doc, 'editable': True, # Will active inherit_branding 'user': user, 'res_company': user.company_id, diff --git a/addons/report_intrastat/views/report_intrastatinvoice.xml b/addons/report_intrastat/views/report_intrastatinvoice.xml index e8bce6e952d..c534f808c95 100644 --- a/addons/report_intrastat/views/report_intrastatinvoice.xml +++ b/addons/report_intrastat/views/report_intrastatinvoice.xml @@ -141,7 +141,7 @@ diff --git a/addons/sale/views/report_saleorder.xml b/addons/sale/views/report_saleorder.xml index 40c8afa045d..c23e680e664 100644 --- a/addons/sale/views/report_saleorder.xml +++ b/addons/sale/views/report_saleorder.xml @@ -1,131 +1,135 @@ + + From 4646107e1ed89cd897823f46e7a6dfbe76e7e3a2 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Tue, 8 Apr 2014 16:14:13 +0200 Subject: [PATCH 399/483] [FIX] account_invoice: print invoice report, pto missplaced around the whole report instead of just the invoice lines bzr revid: dle@openerp.com-20140408141413-xqotylt1wlgktgpx --- .../account/report/account_print_invoice.rml | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/addons/account/report/account_print_invoice.rml b/addons/account/report/account_print_invoice.rml index 6914adfaf20..f45d40a9d6c 100644 --- a/addons/account/report/account_print_invoice.rml +++ b/addons/account/report/account_print_invoice.rml @@ -135,21 +135,9 @@ - + [[ repeatIn(objects,'o') ]] [[ setLang(o.partner_id.lang) ]] - - - - Description - Taxes - Quantity - Unit Price - Disc.(%) - Price - - - @@ -214,6 +202,19 @@ + + + + + Description + Taxes + Quantity + Unit Price + Disc.(%) + Price + + + @@ -261,6 +262,7 @@
    + @@ -368,6 +370,5 @@ - From faa4c255421a886f3eccb7c257210bafde42b696 Mon Sep 17 00:00:00 2001 From: Simon Lejeune Date: Tue, 8 Apr 2014 16:41:31 +0200 Subject: [PATCH 400/483] [FIX] sale_layout: inherit the right view bzr revid: sle@openerp.com-20140408144131-fqjb6ntspah6f1hm --- addons/sale_layout/views/report_quotation_layouted.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sale_layout/views/report_quotation_layouted.xml b/addons/sale_layout/views/report_quotation_layouted.xml index ad04e271e7d..02f56786392 100644 --- a/addons/sale_layout/views/report_quotation_layouted.xml +++ b/addons/sale_layout/views/report_quotation_layouted.xml @@ -1,7 +1,7 @@ -