diff --git a/install/openerp-intro.bmp b/install/openerp-intro.bmp new file mode 100644 index 00000000000..8d3c9340c9b Binary files /dev/null and b/install/openerp-intro.bmp differ diff --git a/install/openerp-slogan.bmp b/install/openerp-slogan.bmp new file mode 100644 index 00000000000..a3cffd104f2 Binary files /dev/null and b/install/openerp-slogan.bmp differ diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py index ab9231b129c..41edfcbe0a3 100644 --- a/openerp/addons/base/__openerp__.py +++ b/openerp/addons/base/__openerp__.py @@ -34,6 +34,7 @@ 'base_data.xml', 'security/base_security.xml', 'base_menu.xml', + 'base_module_meta.xml', 'res/res_security.xml', 'res/res_config.xml', 'data/res.country.state.csv' diff --git a/openerp/addons/base/base_module_meta.xml b/openerp/addons/base/base_module_meta.xml new file mode 100644 index 00000000000..09e28609cec --- /dev/null +++ b/openerp/addons/base/base_module_meta.xml @@ -0,0 +1,61 @@ + + + + + + 10 + + + 32 + + + 4 + + + 2 + + + 12 + + + 30 + + + 28 + + + 38 + + + 24 + + + 16 + + + 18 + + + 6 + + + 8 + + + 20 + + + 22 + + + 19 + + + 14 + + + 16 + + + + diff --git a/openerp/addons/base/module/module.py b/openerp/addons/base/module/module.py index 54685c105a0..2d11d5028bf 100644 --- a/openerp/addons/base/module/module.py +++ b/openerp/addons/base/module/module.py @@ -189,6 +189,7 @@ class module(osv.osv): 'published_version': fields.char('Published Version', size=64, readonly=True), 'url': fields.char('URL', size=128, readonly=True), + 'sequence': fields.integer('Sequence'), 'dependencies_id': fields.one2many('ir.module.module.dependency', 'module_id', 'Dependencies', readonly=True), 'state': fields.selection([ @@ -222,11 +223,12 @@ class module(osv.osv): _defaults = { 'state': 'uninstalled', + 'sequence': 100, 'demo': False, 'license': 'AGPL-3', 'complexity': 'normal', } - _order = 'name' + _order = 'sequence,name' def _name_uniq_msg(self, cr, uid, ids, context=None): return _('The name of the module must be unique !') @@ -250,10 +252,10 @@ class module(osv.osv): _('You try to remove a module that is installed or will be installed')) mod_names.append(mod['name']) #Removing the entry from ir_model_data - ids_meta = self.pool.get('ir.model.data').search(cr, uid, [('name', '=', 'module_meta_information'), ('module', 'in', mod_names)]) + #ids_meta = self.pool.get('ir.model.data').search(cr, uid, [('name', '=', 'module_meta_information'), ('module', 'in', mod_names)]) - if ids_meta: - self.pool.get('ir.model.data').unlink(cr, uid, ids_meta, context) + #if ids_meta: + # self.pool.get('ir.model.data').unlink(cr, uid, ids_meta, context) return super(module, self).unlink(cr, uid, ids, context=context) @@ -316,7 +318,20 @@ class module(osv.osv): return demo def button_install(self, cr, uid, ids, context=None): + model_obj = self.pool.get('ir.model.data') self.state_update(cr, uid, ids, 'to install', ['uninstalled'], context) + + categ = model_obj.get_object(cr, uid, 'base', 'module_category_hidden_links', context=context) + todo = [] + for mod in categ.module_ids: + if mod.state=='uninstalled': + ok = True + for dep in mod.dependencies_id: + ok = ok and (dep.state in ('to install','installed')) + if ok: + todo.append(mod.id) + if todo: + self.button_install(cr, uid, todo, context=context) return dict(ACTION_DICT, name=_('Install')) def button_immediate_install(self, cr, uid, ids, context=None): @@ -327,7 +342,7 @@ class module(osv.osv): :returns: next res.config item to execute :rtype: dict[str, object] """ - self.state_update(cr, uid, ids, 'to install', ['uninstalled'], context) + self.button_install(cr, uid, ids, context=context) cr.commit() db, pool = pooler.restart_pool(cr.dbname, update_module=True) diff --git a/openerp/addons/base/module/module_data.xml b/openerp/addons/base/module/module_data.xml index 2cee6f0fce4..5cf66064a9e 100644 --- a/openerp/addons/base/module/module_data.xml +++ b/openerp/addons/base/module/module_data.xml @@ -7,9 +7,9 @@ - + - Link + Links 0 diff --git a/openerp/addons/base/module/module_view.xml b/openerp/addons/base/module/module_view.xml index b0392fbd531..de72e7278ce 100644 --- a/openerp/addons/base/module/module_view.xml +++ b/openerp/addons/base/module/module_view.xml @@ -75,19 +75,21 @@ - - - - -
-

-

-
-
- Complex -

- - +
+ + + + +
+

+

+
+
+ Complex +

+ + +
diff --git a/openerp/addons/base/res/res_partner.py b/openerp/addons/base/res/res_partner.py index 32b5e08d7b6..d686941ab32 100644 --- a/openerp/addons/base/res/res_partner.py +++ b/openerp/addons/base/res/res_partner.py @@ -141,7 +141,6 @@ class res_partner(osv.osv): 'company_id': fields.many2one('res.company', 'Company', select=1), 'color': fields.integer('Color Index'), } - def _default_category(self, cr, uid, context=None): if context is None: context = {} @@ -235,7 +234,7 @@ class res_partner(osv.osv): address_obj = self.pool.get('res.partner.address') address_ids = address_obj.search(cr, uid, [('partner_id', 'in', ids)]) address_rec = address_obj.read(cr, uid, address_ids, ['type']) - res = list(tuple(addr.values()) for addr in address_rec) + res = list((addr['type'],addr['id']) for addr in address_rec) adr = dict(res) # get the id of the (first) default address if there is one, # otherwise get the id of the first address in the list @@ -314,7 +313,6 @@ class res_partner_address(osv.osv): 'active': lambda *a: 1, 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'res.partner.address', context=c), } - def name_get(self, cr, user, ids, context=None): if context is None: context = {} diff --git a/openerp/addons/base/res/res_partner_view.xml b/openerp/addons/base/res/res_partner_view.xml index b489a4d6e79..1f0e8f88b1c 100644 --- a/openerp/addons/base/res/res_partner_view.xml +++ b/openerp/addons/base/res/res_partner_view.xml @@ -82,7 +82,7 @@ - + @@ -214,7 +214,7 @@
- + @@ -331,7 +331,7 @@ - + @@ -345,8 +345,8 @@ - - + + diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index acd3a3c19ca..898a100a2cf 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -873,7 +873,7 @@ class users_view(osv.osv): res[name_selection_groups(map(int, gs))] = { 'type': 'selection', 'string': app and app.name or _('Other'), - 'selection': [(g.id, g.name) for g in gs], + 'selection': [(False, '')] + [(g.id, g.name) for g in gs], 'help': '\n'.join(tips), } else: diff --git a/openerp/addons/base/static/src/css/modules.css b/openerp/addons/base/static/src/css/modules.css index a1fd6b94604..4ee04e98bba 100644 --- a/openerp/addons/base/static/src/css/modules.css +++ b/openerp/addons/base/static/src/css/modules.css @@ -1,3 +1,8 @@ +.oe_module_vignette { + padding: 6px; + min-height: 100px; +} + .oe_module_icon, .oe_module_desc { display: inline-block; vertical-align: top; diff --git a/openerp/modules/db.py b/openerp/modules/db.py index 31d6ddb60eb..d9c4f76dd3b 100644 --- a/openerp/modules/db.py +++ b/openerp/modules/db.py @@ -86,7 +86,7 @@ def initialize(cr): id = cr.fetchone()[0] cr.execute('INSERT INTO ir_model_data \ (name,model,module, res_id, noupdate) VALUES (%s,%s,%s,%s,%s)', ( - 'module_meta_information', 'ir.module.module', i, id, True)) + 'module_'+i, 'ir.module.module', 'base', id, True)) dependencies = info['depends'] for d in dependencies: cr.execute('INSERT INTO ir_module_module_dependency \ diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 90a8975b27a..b35432a88ef 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -335,8 +335,8 @@ class browse_record(object): cache.setdefault(table._name, {}) self._data = cache[table._name] - if not (id and isinstance(id, (int, long,))): - raise BrowseRecordError(_('Wrong ID for the browse record, got %r, expected an integer.') % (id,)) +# if not (id and isinstance(id, (int, long,))): +# raise BrowseRecordError(_('Wrong ID for the browse record, got %r, expected an integer.') % (id,)) # if not table.exists(cr, uid, id, context): # raise BrowseRecordError(_('Object %s does not exists') % (self,)) @@ -2479,10 +2479,13 @@ class BaseModel(object): group_count = group_by = groupby if groupby: if fget.get(groupby): - if fget[groupby]['type'] in ('date', 'datetime'): - flist = "to_char(%s,'yyyy-mm') as %s " % (qualified_groupby_field, groupby) - groupby = "to_char(%s,'yyyy-mm')" % (qualified_groupby_field) - qualified_groupby_field = groupby + groupby_type = fget[groupby]['type'] + if groupby_type in ('date', 'datetime'): + qualified_groupby_field = "to_char(%s,'yyyy-mm')" % qualified_groupby_field + flist = "%s as %s " % (qualified_groupby_field, groupby) + elif groupby_type == 'boolean': + qualified_groupby_field = "coalesce(%s,false)" % qualified_groupby_field + flist = "%s as %s " % (qualified_groupby_field, groupby) else: flist = qualified_groupby_field else: diff --git a/openerp/tools/config.py b/openerp/tools/config.py index 7708ab1812d..63c08bd3760 100644 --- a/openerp/tools/config.py +++ b/openerp/tools/config.py @@ -73,7 +73,7 @@ class configmanager(object): # Not exposed in the configuration file. self.blacklist_for_save = set( ['publisher_warranty_url', 'load_language', 'root_path', - 'init', 'save', 'config', 'update']) + 'init', 'save', 'config', 'update', 'stop_after_init']) # dictionary mapping option destination (keys in self.options) to MyOptions. self.casts = {} diff --git a/setup.nsi b/setup.nsi index 0ea37b0f9e6..7979b8a872e 100644 --- a/setup.nsi +++ b/setup.nsi @@ -31,23 +31,13 @@ !define PUBLISHER 'OpenERP S.A.' -!ifndef MAJOR_VERSION - !define MAJOR_VERSION '6' -!endif -!ifndef MINOR_VERSION - !define MINOR_VERSION '0' -!endif -!ifndef REVISION_VERSION - !define REVISION_VERSION '0' -!endif -!ifndef BUILD_VERSION - !define VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${REVISION_VERSION}" -!else - !define VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${REVISION_VERSION}-${BUILD_VERSION}" +!ifndef VERSION + !define VERSION '0' !endif +#!define VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${REVISION_VERSION}" !define PRODUCT_NAME "OpenERP Server" -!define DISPLAY_NAME "${PRODUCT_NAME} ${MAJOR_VERSION}.${MINOR_VERSION}" +!define DISPLAY_NAME "${PRODUCT_NAME} ${VERSION}" !define UNINSTALL_REGISTRY_ROOT HKLM !define UNINSTALL_REGISTRY_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${DISPLAY_NAME}" @@ -68,7 +58,7 @@ ShowInstDetails show XPStyle on -InstallDir "$PROGRAMFILES\OpenERP ${MAJOR_VERSION}.${MINOR_VERSION}\Server" +InstallDir "$PROGRAMFILES\OpenERP ${VERSION}" InstallDirRegKey HKCU "${REGISTRY_KEY}" "" BrandingText '${PRODUCT_NAME} ${VERSION}' @@ -104,12 +94,12 @@ Var MUI_TEMP Var STARTMENU_FOLDER !define MUI_ABORTWARNING -!define MUI_ICON ".\pixmaps\openerp-icon.ico" +!define MUI_ICON ".\install\openerp-icon.ico" -!define MUI_WELCOMEFINISHPAGE_BITMAP ".\pixmaps\openerp-intro.bmp" -!define MUI_UNWELCOMEFINISHPAGE_BITMAP ".\pixmaps\openerp-intro.bmp" +!define MUI_WELCOMEFINISHPAGE_BITMAP ".\install\openerp-intro.bmp" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP ".\install\openerp-intro.bmp" !define MUI_HEADERIMAGE -!define MUI_HEADERIMAGE_BITMAP ".\pixmaps\openerp-slogan.bmp" +!define MUI_HEADERIMAGE_BITMAP ".\install\openerp-slogan.bmp" !define MUI_HEADERIMAGE_BITMAP_NOSTRETCH !define MUI_HEADER_TRANSPARENT_TEXT "" @@ -162,9 +152,9 @@ LangString DESC_FinishPage_Link ${LANG_FRENCH} "Contactez OpenERP pour un Parten LangString WARNING_HostNameIsEmpty ${LANG_FRENCH} "L'adresse pour la connection au serveur PostgreSQL est vide" LangString WARNING_UserNameIsEmpty ${LANG_FRENCH} "Le nom d'utilisateur pour la connection au serveur PostgreSQL est vide" LangString WARNING_PasswordIsEmpty ${LANG_FRENCH} "Le mot de passe pour la connection au serveur PostgreSQL est vide" -LangString WARNING_PortIsWrong ${LANG_FRENCH} "Le port pour la connection au serveur PostgreSQL est erroné (défaut: 5432)" +LangString WARNING_PortIsWrong ${LANG_FRENCH} "Le port pour la connection au serveur PostgreSQL est erron? (d?faut: 5432)" LangString DESC_PostgreSQLPage ${LANG_FRENCH} "Configurez les informations de connection pour le serveur PostgreSQL" -LangString DESC_PostgreSQL_Hostname ${LANG_FRENCH} "Hôte" +LangString DESC_PostgreSQL_Hostname ${LANG_FRENCH} "H?te" LangString DESC_PostgreSQL_Port ${LANG_FRENCH} "Port" LangString DESC_PostgreSQL_Username ${LANG_FRENCH} "Utilisateur" LangString DESC_PostgreSQL_Password ${LANG_FRENCH} "Mot de passe" @@ -175,7 +165,7 @@ Section -StopService SectionEnd Section OpenERP_Server SectionOpenERP_Server - SetOutPath '$INSTDIR' + SetOutPath '$INSTDIR\server' File /r "dist\*" @@ -187,14 +177,16 @@ Section OpenERP_Server SectionOpenERP_Server !insertmacro MUI_STARTMENU_WRITE_BEGIN Application ;Create shortcuts CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\OpenERP Server.lnk" "$INSTDIR\openerp-server.exe" - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Start service.lnk" "$INSTDIR\service\start.bat" - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Stop service.lnk" "$INSTDIR\service\stop.bat" - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Edit config.lnk" "notepad.exe" "$INSTDIR\openerp-server.conf" - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\View log.lnk" "notepad.exe" "$INSTDIR\openerp-server.log" - CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\uninstall.exe" - !insertmacro CreateInternetShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Forum" "http://www.openerp.com/forum" - !insertmacro CreateInternetShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Translation" "https://translations.launchpad.net/openobject" +; CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\OpenERP Server.lnk" "$INSTDIR\openerp-server.exe" +; CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Start service.lnk" "$INSTDIR\service\start.bat" +; CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Stop service.lnk" "$INSTDIR\service\stop.bat" +; CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Edit config.lnk" "notepad.exe" "$INSTDIR\openerp-server.conf" +; CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\View log.lnk" "notepad.exe" "$INSTDIR\openerp-server.log" +; CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\OpenERP.lnk" "start" "http://127.0.0.1:8069/" +; CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\uninstall.exe" +; !insertmacro CreateInternetShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Forum" "http://www.openerp.com/forum" +; !insertmacro CreateInternetShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Translation" "https://translations.launchpad.net/openobject" + !insertmacro CreateInternetShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\OpenERP" "http://127.0.0.1:8069/" !insertmacro MUI_STARTMENU_WRITE_END @@ -206,13 +198,13 @@ Section OpenERP_Server SectionOpenERP_Server FileClose $9 # If there is a previous install of the OpenERP Server, keep the login/password from the config file - WriteIniStr "$INSTDIR\openerp-server.conf" "options" "db_host" $TextPostgreSQLHostname - WriteIniStr "$INSTDIR\openerp-server.conf" "options" "db_user" $TextPostgreSQLUsername - WriteIniStr "$INSTDIR\openerp-server.conf" "options" "db_password" $TextPostgreSQLPassword - WriteIniStr "$INSTDIR\openerp-server.conf" "options" "db_port" $TextPostgreSQLPort - WriteIniStr "$INSTDIR\openerp-server.conf" "options" "pg_path" "$INSTDIR\PostgreSQL\bin" + WriteIniStr "$INSTDIR\server\openerp-server.conf" "options" "db_host" $TextPostgreSQLHostname + WriteIniStr "$INSTDIR\server\openerp-server.conf" "options" "db_user" $TextPostgreSQLUsername + WriteIniStr "$INSTDIR\server\openerp-server.conf" "options" "db_password" $TextPostgreSQLPassword + WriteIniStr "$INSTDIR\server\openerp-server.conf" "options" "db_port" $TextPostgreSQLPort + WriteIniStr "$INSTDIR\server\openerp-server.conf" "options" "pg_path" "$INSTDIR\PostgreSQL\bin" - nsExec::Exec '"$INSTDIR\openerp-server.exe" --stop-after-init --logfile "$INSTDIR\openerp-server.log" -s' + nsExec::Exec '"$INSTDIR\server\openerp-server.exe" --stop-after-init --logfile "$INSTDIR\server\openerp-server.log" -s' nsExec::Exec '"$INSTDIR\service\OpenERPServerService.exe" -auto -install' SectionEnd @@ -225,15 +217,15 @@ Section -Post WriteRegExpandStr HKLM "${UNINSTALL_REGISTRY_KEY}" "UninstallString" "$INSTDIR\Uninstall.exe" WriteRegExpandStr HKLM "${UNINSTALL_REGISTRY_KEY}" "InstallLocation" "$INSTDIR" WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "DisplayName" "${DISPLAY_NAME}" - WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "DisplayVersion" "${MAJOR_VERSION}.${MINOR_VERSION}" + WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "DisplayVersion" "${VERSION}" WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "Publisher" "${PUBLISHER}" - WriteRegDWORD HKLM "${UNINSTALL_REGISTRY_KEY}" "Version" "${VERSION}" - WriteRegDWORD HKLM "${UNINSTALL_REGISTRY_KEY}" "VersionMajor" "${MAJOR_VERSION}.${MINOR_VERSION}" - WriteRegDWORD HKLM "${UNINSTALL_REGISTRY_KEY}" "VersionMinor" "${REVISION_VERSION}" - WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "HelpLink" "support@openerp.com" - WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "HelpTelephone" "+32.81.81.37.00" - WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "URLInfoAbout" "http://www.openerp.com" - WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "Contact" "sales@openerp.com" +; WriteRegDWORD HKLM "${UNINSTALL_REGISTRY_KEY}" "Version" "${VERSION}" +; WriteRegDWORD HKLM "${UNINSTALL_REGISTRY_KEY}" "VersionMajor" "${MAJOR_VERSION}.${MINOR_VERSION}" +; WriteRegDWORD HKLM "${UNINSTALL_REGISTRY_KEY}" "VersionMinor" "${REVISION_VERSION}" +; WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "HelpLink" "support@openerp.com" +; WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "HelpTelephone" "+32.81.81.37.00" +; WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "URLInfoAbout" "http://www.openerp.com" +; WriteRegStr HKLM "${UNINSTALL_REGISTRY_KEY}" "Contact" "sales@openerp.com" WriteRegDWORD HKLM "${UNINSTALL_REGISTRY_KEY}" "NoModify" "1" WriteRegDWORD HKLM "${UNINSTALL_REGISTRY_KEY}" "NoRepair" "1" WriteUninstaller "$INSTDIR\Uninstall.exe" diff --git a/setup.py b/setup.py index 7f2d1312f2e..10c98d726f1 100755 --- a/setup.py +++ b/setup.py @@ -38,12 +38,17 @@ def data(): else: d[k]=[v] r = d.items() + if os.name == 'nt': + r.append(("Microsoft.VC90.CRT", glob.glob('C:\Microsoft.VC90.CRT\*.*'))) return r def gen_manifest(): file_list="\n".join(data()) open('MANIFEST','w').write(file_list) +if os.name == 'nt': + sys.path.append("C:\Microsoft.VC90.CRT") + def py2exe_options(): if os.name == 'nt': import py2exe @@ -54,7 +59,7 @@ def py2exe_options(): "skip_archive": 1, "optimize": 2, "dist_dir": 'dist', - "packages": [ "DAV", "HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "email", "encodings", "imaplib", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber" "vobject", "xml", "xml", "xml.dom", "xml.xpath", "yaml", ], + "packages": [ "DAV", "HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "email", "encodings", "imaplib", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber", "vobject", "xml", "xml.dom", "yaml", ], "excludes" : ["Tkconstants","Tkinter","tcl"], } }