diff --git a/odoo-debrand/README.rst b/odoo-debrand/README.rst new file mode 100644 index 000000000..c077468eb --- /dev/null +++ b/odoo-debrand/README.rst @@ -0,0 +1,56 @@ +.. image:: https://img.shields.io/badge/licence-GPL--3-blue.svg + :target: http://www.gnu.org/licenses/gpl-3.0-standalone.html + :alt: License: GPL-3 + +=============== +Odoo Debranding +=============== + +Debranding of odoo with the given configurations under Website Admin -> Debranding Configurations. +Will replace: + - Page Title + - Odoo from Popups + - Settings Odoo branding Items + - User Drop down Odoo links + - Website Title, footer + - Powered By Odoo on Backend by your company name + - Odoo label from Dialogues + - Odoo Database Selector Logo, Labels + - Copyright @odoo with your company on website page + + + + +Installation +============ + +To install this module from odoo apps after updating the app list. + + +Usage +===== + +Fill the configuration under Website Admin. Clear Browser Image caches after installing the module. + +Known issues / Roadmap +====================== + +* ... + +Bug Tracker +=========== + +Contact odoo@cybrosys.com + + +Contributors +------------ + +* Tintuk Tomin + +Maintainer +---------- + +This module is maintained by Cybrosys Technologies. + +For support and more information, please visit https://www.cybrosys.com. diff --git a/odoo-debrand/__init__.py b/odoo-debrand/__init__.py new file mode 100644 index 000000000..64261465b --- /dev/null +++ b/odoo-debrand/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Tintuk Tomin() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +from . import controllers +from . import models diff --git a/odoo-debrand/__manifest__.py b/odoo-debrand/__manifest__.py new file mode 100644 index 000000000..01c258748 --- /dev/null +++ b/odoo-debrand/__manifest__.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Cybrosys Technologies Pvt. Ltd. +# Copyright (C) 2017-TODAY Cybrosys Technologies(). +# Author: Tintuk Tomin() +# you can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. +# +# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE +# GENERAL PUBLIC LICENSE (LGPL v3) along with this program. +# If not, see . +# +############################################################################## +{ + 'name': "Odoo Debranding", + 'version': "11.0.1.0.0", + 'summary': """Debrand Odoo""", + 'description': """Debrand Odoo""", + 'author': "Cybrosys Techno Solutions", + 'company': "Cybrosys Techno Solutions", + 'website': "https://www.cybrosys.com/", + 'category': 'Tools', + 'depends': ['base', 'im_livechat', 'website'], + 'data': [ + 'views/views.xml'], + 'demo': [], + 'qweb': ["static/src/xml/base.xml"], + 'images': ['static/description/banner.jpg'], + 'license': "LGPL-3", + 'installable': True, + 'application': False +} diff --git a/odoo-debrand/controllers/__init__.py b/odoo-debrand/controllers/__init__.py new file mode 100644 index 000000000..457bae27e --- /dev/null +++ b/odoo-debrand/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import controllers \ No newline at end of file diff --git a/odoo-debrand/controllers/controllers.py b/odoo-debrand/controllers/controllers.py new file mode 100644 index 000000000..2bfed6aad --- /dev/null +++ b/odoo-debrand/controllers/controllers.py @@ -0,0 +1,99 @@ +# -*- coding: utf-8 -*- +import imghdr +import json +import functools +from odoo import http, tools +import odoo, os, sys, jinja2 +from odoo.addons.web.controllers.main import Database +from odoo.addons.web.controllers import main +from odoo.addons.web.controllers.main import Binary +from odoo.modules import get_resource_path +from io import StringIO +from odoo.http import request + +if hasattr(sys, 'frozen'): + # When running on compiled windows binary, we don't have access to package loader. + path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'views')) + loader = jinja2.FileSystemLoader(path) +else: + loader = jinja2.PackageLoader('odoo.addons.odoo-debrand', "views") +env = main.jinja2.Environment(loader=loader, autoescape=True) +env.filters["json"] = json.dumps +db_monodb = http.db_monodb + + +class BinaryCustom(Binary): + @http.route([ + '/web/binary/company_logo', + '/logo', + '/logo.png', + ], type='http', auth="none") + def company_logo(self, dbname=None, **kw): + imgname = 'logo' + imgext = '.png' + company_logo = request.env['website'].sudo().search([])[0].company_logo + custom_logo = tools.image_resize_image(company_logo, (150, None)) + placeholder = functools.partial(get_resource_path, 'web', 'static', 'src', 'img') + uid = None + if request.session.db: + dbname = request.session.db + uid = request.session.uid + elif dbname is None: + dbname = db_monodb() + + if not uid: + uid = odoo.SUPERUSER_ID + + if not dbname: + response = http.send_file(placeholder(imgname + imgext)) + else: + try: + # create an empty registry + registry = odoo.modules.registry.Registry(dbname) + if custom_logo: + image_base64 = custom_logo.decode('base64') + image_data = StringIO(image_base64) + imgext = '.' + (imghdr.what(None, h=image_base64) or 'png') + response = http.send_file(image_data, filename=imgname + imgext, mtime=None) + else: + with registry.cursor() as cr: + cr.execute("""SELECT c.logo_web, c.write_date + FROM res_users u + LEFT JOIN res_company c + ON c.id = u.company_id + WHERE u.id = %s + """, (uid,)) + row = cr.fetchone() + if row and row[0]: + image_base64 = str(row[0]).decode('base64') + image_data = StringIO(image_base64) + imgext = '.' + (imghdr.what(None, h=image_base64) or 'png') + response = http.send_file(image_data, filename=imgname + imgext, mtime=row[1]) + else: + response = http.send_file(placeholder('nologo.png')) + except Exception: + response = http.send_file(placeholder(imgname + imgext)) + return response + + +class OdooDebrand(Database): + def _render_template(self, **d): + d.setdefault('manage', True) + d['insecure'] = odoo.tools.config['admin_passwd'] == 'admin' + d['list_db'] = odoo.tools.config['list_db'] + d['langs'] = odoo.service.db.exp_list_lang() + d['countries'] = odoo.service.db.exp_list_countries() + website_id = request.env['website'].sudo().search([]) + d['company_name'] = website_id and website_id[0].company_name + d['favicon_url'] = website_id and website_id[0].favicon_url or '' + d['company_logo_url'] = website_id and website_id[0].company_logo_url or '' + + # databases list + d['databases'] = [] + try: + d['databases'] = http.db_list() + except odoo.exceptions.AccessDenied: + monodb = db_monodb() + if monodb: + d['databases'] = [monodb] + return env.get_template("database_manager_extend.html").render(d) diff --git a/odoo-debrand/doc/changelog.rst b/odoo-debrand/doc/changelog.rst new file mode 100644 index 000000000..5651afe3c --- /dev/null +++ b/odoo-debrand/doc/changelog.rst @@ -0,0 +1,9 @@ +Changelog +========= + +`11.0.1.0.0` +------------ +- Initial Commit + + + diff --git a/odoo-debrand/models/__init__.py b/odoo-debrand/models/__init__.py new file mode 100644 index 000000000..77bbdbd39 --- /dev/null +++ b/odoo-debrand/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import models + diff --git a/odoo-debrand/models/models.py b/odoo-debrand/models/models.py new file mode 100644 index 000000000..05894dfeb --- /dev/null +++ b/odoo-debrand/models/models.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + + +from odoo import models, fields, api + + +class OdooDebrand(models.Model): + _inherit = "website" + + @api.one + @api.depends('company_favicon') + def get_favicon(self): + self.favicon_url = 'data:image/png;base64,' + str(self.company_favicon.decode('UTF-8')) + + @api.one + @api.depends('company_logo') + def get_company_logo(self): + self.company_logo_url = 'data:image/png;base64,' + str(self.company_logo.decode('UTF-8')) + + company_logo = fields.Binary("Logo", attachment=True, + help="This field holds the image used for the Company Logo") + company_name = fields.Char("Company Name", help="Branding Name") + company_favicon = fields.Binary("Favicon", attachment=True, + help="This field holds the image used for as favicon") + company_website = fields.Char("Company URL") + favicon_url = fields.Char("Url", compute='get_favicon') + company_logo_url = fields.Char("Url", compute='get_company_logo') + + +class WebsiteConfig(models.TransientModel): + _inherit = "res.config.settings" + + company_logo = fields.Binary(related='website_id.company_logo', string="Company Logo", + help="This field holds the image used for the Company Logo") + company_name = fields.Char(related='website_id.company_name', string="Company Name") + company_favicon = fields.Binary(related='website_id.company_favicon', string="Company Favicon", + help="This field holds the image used for as favicon") + company_website = fields.Char(related='website_id.company_website') diff --git a/odoo-debrand/security/ir.model.access.csv b/odoo-debrand/security/ir.model.access.csv new file mode 100644 index 000000000..c42b07654 --- /dev/null +++ b/odoo-debrand/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_odoo-debrand_odoo-debrand,odoo-debrand.odoo-debrand,model_odoo-debrand_odoo-debrand,,1,0,0,0 \ No newline at end of file diff --git a/odoo-debrand/static/description/about.png b/odoo-debrand/static/description/about.png new file mode 100644 index 000000000..62e0c21e9 Binary files /dev/null and b/odoo-debrand/static/description/about.png differ diff --git a/odoo-debrand/static/description/banner.jpg b/odoo-debrand/static/description/banner.jpg new file mode 100644 index 000000000..0db7eaadd Binary files /dev/null and b/odoo-debrand/static/description/banner.jpg differ diff --git a/odoo-debrand/static/description/cybro_logo.png b/odoo-debrand/static/description/cybro_logo.png new file mode 100644 index 000000000..bb309114c Binary files /dev/null and b/odoo-debrand/static/description/cybro_logo.png differ diff --git a/odoo-debrand/static/description/cybrosys-odoo-debranding-1.jpg b/odoo-debrand/static/description/cybrosys-odoo-debranding-1.jpg new file mode 100644 index 000000000..8298b6791 Binary files /dev/null and b/odoo-debrand/static/description/cybrosys-odoo-debranding-1.jpg differ diff --git a/odoo-debrand/static/description/cybrosys-odoo-debranding-2.jpg b/odoo-debrand/static/description/cybrosys-odoo-debranding-2.jpg new file mode 100644 index 000000000..43face9b0 Binary files /dev/null and b/odoo-debrand/static/description/cybrosys-odoo-debranding-2.jpg differ diff --git a/odoo-debrand/static/description/cybrosys-odoo-debranding-3.jpg b/odoo-debrand/static/description/cybrosys-odoo-debranding-3.jpg new file mode 100644 index 000000000..0b9327e1a Binary files /dev/null and b/odoo-debrand/static/description/cybrosys-odoo-debranding-3.jpg differ diff --git a/odoo-debrand/static/description/cybrosys-odoo-debranding-4.jpg b/odoo-debrand/static/description/cybrosys-odoo-debranding-4.jpg new file mode 100644 index 000000000..20e3124cc Binary files /dev/null and b/odoo-debrand/static/description/cybrosys-odoo-debranding-4.jpg differ diff --git a/odoo-debrand/static/description/cybrosys-odoo-debranding-5.jpg b/odoo-debrand/static/description/cybrosys-odoo-debranding-5.jpg new file mode 100644 index 000000000..46c87bbcc Binary files /dev/null and b/odoo-debrand/static/description/cybrosys-odoo-debranding-5.jpg differ diff --git a/odoo-debrand/static/description/cybrosys-odoo-debranding-6.jpg b/odoo-debrand/static/description/cybrosys-odoo-debranding-6.jpg new file mode 100644 index 000000000..86b2c97c8 Binary files /dev/null and b/odoo-debrand/static/description/cybrosys-odoo-debranding-6.jpg differ diff --git a/odoo-debrand/static/description/cybrosys-odoo-debranding-7.jpg b/odoo-debrand/static/description/cybrosys-odoo-debranding-7.jpg new file mode 100644 index 000000000..59fd35685 Binary files /dev/null and b/odoo-debrand/static/description/cybrosys-odoo-debranding-7.jpg differ diff --git a/odoo-debrand/static/description/icon.png b/odoo-debrand/static/description/icon.png new file mode 100644 index 000000000..ca93c09ef Binary files /dev/null and b/odoo-debrand/static/description/icon.png differ diff --git a/odoo-debrand/static/description/index.html b/odoo-debrand/static/description/index.html new file mode 100644 index 000000000..8761f0032 --- /dev/null +++ b/odoo-debrand/static/description/index.html @@ -0,0 +1,385 @@ + +
+
+

+ Odoo Debranding +

+

+ Debrand Odoo Back-end + Front-End +

+
+ Cybrosys Technologies +
+ +
+ cybrosys technologies
+
+
+
+ +
+
+

+ Overview +

+

+ Want to debrand your company website? Odoo Debranding module developed by Cybrosys Technologies + helps you to change the aesthetic look of Odoo software via customizing them + with Logo and other branding changes. The module helps you to change almost every area of Odoo visuals, + delivering a brand new customized website. +

+

+ Configuration +

+

+ After installation you need to enter the Company name,url,image and favicon. +

+
+
+ +
+
+

+ Features +

+

+ + Debranding configuration page +

+

+ + Modify database selector page +

+

+ + Modify login page +

+

+ + Updates website footer +

+

+ + Remove Odoo's default favicon +

+

+ + Updated "About" list +

+

+ + Removed advertisements from the settings page +

+

+ + Updated warning messages +

+

+ + Page title modification +

+ +
+
+ +
+
+

+ Screenshots +

+

+ + From the settings page, you can view the Debrand tab and there you can enter the company logo, favicon, company name, and website. +

+
+ +
+

+
+ The title is changed with the company name and favicon.
+
+ Default company logo is changed.
+
+ Odoo accounts and documentation is removed from the dropdown list.
+

+
+ +
+

+
+ Company logo in login page.
+
+ Powered by in the front-end and in the footer is changed to company name
+
+ Copyright in the front-end is changed to company name
+

+
+ +
+

+ + Company logo in the database selector page is changed. +

+
+ +
+

+
+ Odoo promotional banners in the settings dashboard page is changed.
+
+ Powered by in the back-end footer is changed to company name
+

+
+ +
+

+ + Updated the Odoo title in the error message +

+
+ +
+

+ + Updated the Odoo title in the warning message +

+
+ +
+
+
+
+
+ cybrosys technologies +
+
+ +
+ +
+
+ +
+ +
+ +
+ diff --git a/odoo-debrand/static/src/js/title.js b/odoo-debrand/static/src/js/title.js new file mode 100644 index 000000000..3ff0288f7 --- /dev/null +++ b/odoo-debrand/static/src/js/title.js @@ -0,0 +1,220 @@ +odoo.define('odoo-debrand-11.title', function(require) { +"use strict"; + +var core = require('web.core'); +var utils = require('web.utils'); +var ajax = require('web.ajax'); +var Dialog = require('web.Dialog'); +var WebClient = require('web.AbstractWebClient'); +var CrashManager = require('web.CrashManager'); // We can import crash_manager also +var concurrency = require('web.concurrency'); +var mixins = require('web.mixins'); +var session = require('web.session'); +var weclient = require('web.WebClient'); + +var QWeb = core.qweb; +var _t = core._t; +var _lt = core._lt; + + +var map_title ={ + user_error: _lt('Warning'), + warning: _lt('Warning'), + access_error: _lt('Access Error'), + missing_error: _lt('Missing Record'), + validation_error: _lt('Validation Error'), + except_orm: _lt('Global Business Error'), + access_denied: _lt('Access Denied'), +}; + +WebClient.include({ +init: function (parent) { + this.client_options = {}; + mixins.ServiceProvider.init.call(this); + this._super(parent); + this.origin = undefined; + this._current_state = null; + this.menu_dm = new concurrency.DropMisordered(); + this.action_mutex = new concurrency.Mutex(); + var self = this; + // Rpc call to fetch the compant name from model + this._rpc({ + fields: ['company_name',], + domain: [], + model: 'website', + method: 'search_read', + limit: 1, + context: session.user_context, + }).done(function(result){ + self.set('title_part', {"zopenerp": result && result[0] && result[0].company_name || ''}); + }); + }, +}); +CrashManager.include({ + rpc_error: function(error) { + var self = this; + if (!this.active) { + return; + } + if (this.connection_lost) { + return; + } + if (error.code === -32098) { + core.bus.trigger('connection_lost'); + this.connection_lost = true; + var timeinterval = setInterval(function() { + ajax.jsonRpc('/web/webclient/version_info').then(function() { + clearInterval(timeinterval); + core.bus.trigger('connection_restored'); + self.connection_lost = false; + }); + }, 2000); + return; + } + var handler = core.crash_registry.get(error.data.name, true); + if (handler) { + new (handler)(this, error).display(); + return; + } + if (error.data.name === "odoo.http.SessionExpiredException" || error.data.name === "werkzeug.exceptions.Forbidden") { + this.show_warning({type: _t("Session Expired"), data: {message: _t("Your session expired. Please refresh the current web page.")}}); + return; + } + if (_.has(map_title, error.data.exception_type)) { + if(error.data.exception_type === 'except_orm'){ + if(error.data.arguments[1]) { + error = _.extend({}, error, + { + data: _.extend({}, error.data, + { + message: error.data.arguments[1], + title: error.data.arguments[0] !== 'Warning' ? (" - " + error.data.arguments[0]) : '', + }) + }); + } + else { + error = _.extend({}, error, + { + data: _.extend({}, error.data, + { + message: error.data.arguments[0], + title: '', + }) + }); + } + } + else { + error = _.extend({}, error, + { + data: _.extend({}, error.data, + { + message: error.data.arguments[0], + title: map_title[error.data.exception_type] !== 'Warning' ? (" - " + map_title[error.data.exception_type]) : '', + }) + }); + } + + this.show_warning(error); + //InternalError + + } else { + this.show_error(error); + } + }, + show_warning: function(error) { + if (!this.active) { + return; + } + // Error message contains odoo title. Replace it + error.message = error.message && error.message.replace("Odoo", "") + new Dialog(this, { + size: 'medium', + title: _.str.capitalize(error.type || error.message) || _t("Warning"), + subtitle: error.data.title, + $content: $(QWeb.render('CrashManager.warning', {error: error})) + }).open(); + }, + show_error: function(error) { + if (!this.active) { + return; + } + error.message = error.message && error.message.replace("Odoo", "") + var dialog = new Dialog(this, { + title: _.str.capitalize(error.type || error.message) || _t("Warning"), + $content: $(QWeb.render('CrashManager.error', {error: error})) + }); + console.log(error) + // When the dialog opens, initialize the copy feature and destroy it when the dialog is closed + var $clipboardBtn; + var clipboard; + dialog.opened(function () { + // When the full traceback is shown, scroll it to the end (useful for better python error reporting) + dialog.$(".o_error_detail").on("shown.bs.collapse", function (e) { + e.target.scrollTop = e.target.scrollHeight; + }); + + $clipboardBtn = dialog.$(".o_clipboard_button"); + $clipboardBtn.tooltip({title: _t("Copied !"), trigger: "manual", placement: "left"}); + clipboard = new window.Clipboard($clipboardBtn[0], { + text: function () { + return (_t("Error") + ":\n" + error.message + "\n\n" + error.data.debug).trim(); + } + }); + clipboard.on("success", function (e) { + _.defer(function () { + $clipboardBtn.tooltip("show"); + _.delay(function () { + $clipboardBtn.tooltip("hide"); + }, 800); + }); + }); + }); + dialog.on("closed", this, function () { + $clipboardBtn.tooltip("destroy"); + clipboard.destroy(); + }); + + dialog.open(); + }, + show_message: function(exception) { + this.show_error({ + type: _t("Client Error"), + message: exception, + data: {debug: ""} + }); + }, +}); +Dialog.include({ + init: function (parent, options) { + this._super(parent); + this._opened = $.Deferred(); + // Normal Odoo dialogues have title Odoo followed by subtitle, Replace it + options = _.defaults(options || {}, { + title: _t(''), subtitle: '', + size: 'large', + dialogClass: '', + $content: false, + buttons: [{text: _t("Ok"), close: true}], + technical: true, + }); + + this.$content = options.$content; + this.title = options.title; + this.subtitle = options.subtitle; + this.dialogClass = options.dialogClass; + this.size = options.size; + this.buttons = options.buttons; + this.technical = options.technical; + }, +}); + +weclient.include({ + update_logo: function(reload) { + // This function change the debranding logo to default company logo + var company = session.company_id; + var img = session.url('/web/binary/company_logo' + '?db=' + session.db + (company ? '&company=' + company : '')); +// this.$('.o_sub_menu_logo img').attr('src', '').attr('src', img + (reload ? "&t=" + Date.now() : '')); + this.$('.oe_logo_edit').toggleClass('oe_logo_edit_admin', session.is_superuser); + }, +}); +}); diff --git a/odoo-debrand/static/src/xml/base.xml b/odoo-debrand/static/src/xml/base.xml new file mode 100644 index 000000000..c72f1d30d --- /dev/null +++ b/odoo-debrand/static/src/xml/base.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + +
+ + + + + + Your permission is required to enable desktop notifications. + + + \ No newline at end of file diff --git a/odoo-debrand/views/database_manager_extend.html b/odoo-debrand/views/database_manager_extend.html new file mode 100644 index 000000000..a91669949 --- /dev/null +++ b/odoo-debrand/views/database_manager_extend.html @@ -0,0 +1,352 @@ + + + + + {{ company_name }} + + + + + + + + + + +{% macro master_input() -%} +
+ {% if insecure %} + + {% else %} + + + {% endif %} +
+{%- endmacro %} + +{% macro create_form() -%} +

Odoo is up and running!
+ Create a new database by filling out the form, + you'll be able to install your first app in a minute.

+ {{ master_input() }} +
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+ + + +
+
+
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+{%- endmacro %} + + + +
+
+
+ +
+ {% if insecure and databases %} +
+ + Warning, {{ company_name }} database manager is not protected. + Please set a master password + to secure it. +
+ {% endif %} + {% if error %} +
{{ error }}
+ {% endif %} + {% if databases %} + + {% if manage %} +
+ + + +
+ {% else %} + + {% endif %} + {% else %} +
+ {{ create_form() }} + +
+ + or restore a database + + {% endif %} +
+
+ + + + + + + + + + + + + + + + + + + + + + + diff --git a/odoo-debrand/views/views.xml b/odoo-debrand/views/views.xml new file mode 100644 index 000000000..0d963e271 --- /dev/null +++ b/odoo-debrand/views/views.xml @@ -0,0 +1,167 @@ + + + Debranding Configuration + res.config.settings + + + +
+ +

Debranding Configurations

+
+
+
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + +