Continued porting the web browser. QtWebEngine

Sun, 13 Mar 2016 20:54:42 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 13 Mar 2016 20:54:42 +0100
branch
QtWebEngine
changeset 4858
19dff9c9cf26
parent 4857
8dba5fb92f12
child 4859
36c4b21c9f7b

Continued porting the web browser.

- continued porting the AdBlock code

WebBrowser/AdBlock/AdBlockDialog.py file | annotate | diff | comparison | revisions
WebBrowser/AdBlock/AdBlockDialog.ui file | annotate | diff | comparison | revisions
WebBrowser/AdBlock/AdBlockExceptionsDialog.py file | annotate | diff | comparison | revisions
WebBrowser/AdBlock/AdBlockExceptionsDialog.ui file | annotate | diff | comparison | revisions
WebBrowser/AdBlock/AdBlockIcon.py file | annotate | diff | comparison | revisions
WebBrowser/AdBlock/AdBlockManager.py file | annotate | diff | comparison | revisions
WebBrowser/AdBlock/AdBlockRule.py file | annotate | diff | comparison | revisions
WebBrowser/AdBlock/AdBlockSubscription.py file | annotate | diff | comparison | revisions
WebBrowser/AdBlock/AdBlockTreeWidget.py file | annotate | diff | comparison | revisions
WebBrowser/AdBlock/AdBlockUrlInterceptor.py file | annotate | diff | comparison | revisions
WebBrowser/GreaseMonkey/GreaseMonkeyUrlInterceptor.py file | annotate | diff | comparison | revisions
WebBrowser/Network/EricSchemeHandler.py file | annotate | diff | comparison | revisions
WebBrowser/Network/NetworkManager.py file | annotate | diff | comparison | revisions
WebBrowser/WebBrowserLanguagesDialog.py file | annotate | diff | comparison | revisions
WebBrowser/WebBrowserWindow.py file | annotate | diff | comparison | revisions
WebBrowser/data/html.qrc file | annotate | diff | comparison | revisions
WebBrowser/data/html/adblockPage.html file | annotate | diff | comparison | revisions
WebBrowser/data/html_rc.py file | annotate | diff | comparison | revisions
WebBrowser/data/icons.qrc file | annotate | diff | comparison | revisions
WebBrowser/data/icons/adBlockPlus16.png file | annotate | diff | comparison | revisions
WebBrowser/data/icons/adBlockPlus64.png file | annotate | diff | comparison | revisions
WebBrowser/data/icons_rc.py file | annotate | diff | comparison | revisions
eric6.e4p file | annotate | diff | comparison | revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/AdBlock/AdBlockDialog.py	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,325 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2009 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the AdBlock configuration dialog.
+"""
+
+from __future__ import unicode_literals
+
+from PyQt5.QtCore import pyqtSlot, Qt, QTimer, QCoreApplication
+from PyQt5.QtWidgets import QDialog, QMenu, QToolButton
+
+from E5Gui import E5MessageBox
+
+from .Ui_AdBlockDialog import Ui_AdBlockDialog
+
+import UI.PixmapCache
+import Preferences
+
+
+class AdBlockDialog(QDialog, Ui_AdBlockDialog):
+    """
+    Class implementing the AdBlock configuration dialog.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent object (QWidget)
+        """
+        super(AdBlockDialog, self).__init__(parent)
+        self.setupUi(self)
+        self.setWindowFlags(Qt.Window)
+        
+        self.iconLabel.setPixmap(UI.PixmapCache.getPixmap("adBlockPlus48.png"))
+        
+        self.updateSpinBox.setValue(Preferences.getHelp("AdBlockUpdatePeriod"))
+        
+        self.searchEdit.setInactiveText(self.tr("Search..."))
+        
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        self.__manager = WebBrowserWindow.adBlockManager()
+        self.adBlockGroup.setChecked(self.__manager.isEnabled())
+        self.__manager.requiredSubscriptionLoaded.connect(self.addSubscription)
+        
+        self.__currentTreeWidget = None
+        self.__currentSubscription = None
+        self.__loaded = False
+        
+        menu = QMenu(self)
+        menu.aboutToShow.connect(self.__aboutToShowActionMenu)
+        self.actionButton.setMenu(menu)
+        self.actionButton.setIcon(UI.PixmapCache.getIcon("adBlockAction.png"))
+        self.actionButton.setPopupMode(QToolButton.InstantPopup)
+        
+        self.__load()
+        
+        self.buttonBox.setFocus()
+    
+    def __loadSubscriptions(self):
+        """
+        Private slot to load the AdBlock subscription rules.
+        """
+        for index in range(self.subscriptionsTabWidget.count()):
+            tree = self.subscriptionsTabWidget.widget(index)
+            tree.refresh()
+    
+    def __load(self):
+        """
+        Private slot to populate the tab widget with subscriptions.
+        """
+        if self.__loaded or not self.adBlockGroup.isChecked():
+            return
+        
+        from .AdBlockTreeWidget import AdBlockTreeWidget
+        for subscription in self.__manager.subscriptions():
+            tree = AdBlockTreeWidget(subscription, self.subscriptionsTabWidget)
+            if subscription.isEnabled():
+                icon = UI.PixmapCache.getIcon("adBlockPlus.png")
+            else:
+                icon = UI.PixmapCache.getIcon("adBlockPlusDisabled.png")
+            self.subscriptionsTabWidget.addTab(
+                tree, icon, subscription.title())
+        
+        self.__loaded = True
+        QCoreApplication.processEvents()
+        
+        QTimer.singleShot(50, self.__loadSubscriptions)
+    
+    def addSubscription(self, subscription, refresh=True):
+        """
+        Public slot adding a subscription to the list.
+        
+        @param subscription reference to the subscription to be
+            added (AdBlockSubscription)
+        @param refresh flag indicating to refresh the tree (boolean)
+        """
+        from .AdBlockTreeWidget import AdBlockTreeWidget
+        tree = AdBlockTreeWidget(subscription, self.subscriptionsTabWidget)
+        index = self.subscriptionsTabWidget.insertTab(
+            self.subscriptionsTabWidget.count() - 1, tree,
+            subscription.title())
+        self.subscriptionsTabWidget.setCurrentIndex(index)
+        QCoreApplication.processEvents()
+        if refresh:
+            tree.refresh()
+        self.__setSubscriptionEnabled(subscription, True)
+    
+    def __aboutToShowActionMenu(self):
+        """
+        Private slot to show the actions menu.
+        """
+        subscriptionEditable = self.__currentSubscription and \
+            self.__currentSubscription.canEditRules()
+        subscriptionRemovable = self.__currentSubscription and \
+            self.__currentSubscription.canBeRemoved()
+        subscriptionEnabled = self.__currentSubscription and \
+            self.__currentSubscription.isEnabled()
+        
+        menu = self.actionButton.menu()
+        menu.clear()
+        
+        menu.addAction(self.tr("Add Rule"), self.__addCustomRule)\
+            .setEnabled(subscriptionEditable)
+        menu.addAction(self.tr("Remove Rule"), self.__removeCustomRule)\
+            .setEnabled(subscriptionEditable)
+        menu.addSeparator()
+        menu.addAction(
+            self.tr("Browse Subscriptions..."), self.__browseSubscriptions)
+        menu.addAction(
+            self.tr("Remove Subscription"), self.__removeSubscription)\
+            .setEnabled(subscriptionRemovable)
+        if self.__currentSubscription:
+            menu.addSeparator()
+            if subscriptionEnabled:
+                txt = self.tr("Disable Subscription")
+            else:
+                txt = self.tr("Enable Subscription")
+            menu.addAction(txt, self.__switchSubscriptionEnabled)
+        menu.addSeparator()
+        menu.addAction(
+            self.tr("Update Subscription"), self.__updateSubscription)\
+            .setEnabled(not subscriptionEditable)
+        menu.addAction(
+            self.tr("Update All Subscriptions"),
+            self.__updateAllSubscriptions)
+        menu.addSeparator()
+        menu.addAction(self.tr("Learn more about writing rules..."),
+                       self.__learnAboutWritingFilters)
+    
+    def addCustomRule(self, filter):
+        """
+        Public slot to add a custom AdBlock rule.
+        
+        @param filter filter to be added (string)
+        """
+        self.subscriptionsTabWidget.setCurrentIndex(
+            self.subscriptionsTabWidget.count() - 1)
+        self.__currentTreeWidget.addRule(filter)
+    
+    def __addCustomRule(self):
+        """
+        Private slot to add a custom AdBlock rule.
+        """
+        self.__currentTreeWidget.addRule()
+    
+    def __removeCustomRule(self):
+        """
+        Private slot to remove a custom AdBlock rule.
+        """
+        self.__currentTreeWidget.removeRule()
+    
+    def __updateSubscription(self):
+        """
+        Private slot to update the selected subscription.
+        """
+        self.__currentSubscription.updateNow()
+    
+    def __updateAllSubscriptions(self):
+        """
+        Private slot to update all subscriptions.
+        """
+        self.__manager.updateAllSubscriptions()
+    
+    def __browseSubscriptions(self):
+        """
+        Private slot to browse the list of available AdBlock subscriptions.
+        """
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        mw = WebBrowserWindow.mainWindow()
+        mw.newTab("http://adblockplus.org/en/subscriptions")
+        mw.raise_()
+    
+    def __learnAboutWritingFilters(self):
+        """
+        Private slot to show the web page about how to write filters.
+        """
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        mw = WebBrowserWindow.mainWindow()
+        mw.newTab("http://adblockplus.org/en/filters")
+        mw.raise_()
+    
+    def __removeSubscription(self):
+        """
+        Private slot to remove the selected subscription.
+        """
+        requiresTitles = []
+        requiresSubscriptions = \
+            self.__manager.getRequiresSubscriptions(self.__currentSubscription)
+        for subscription in requiresSubscriptions:
+            requiresTitles.append(subscription.title())
+        if requiresTitles:
+            message = self.tr(
+                "<p>Do you really want to remove subscription"
+                " <b>{0}</b> and all subscriptions requiring it?</p>"
+                "<ul><li>{1}</li></ul>").format(
+                self.__currentSubscription.title(),
+                "</li><li>".join(requiresTitles))
+        else:
+            message = self.tr(
+                "<p>Do you really want to remove subscription"
+                " <b>{0}</b>?</p>").format(self.__currentSubscription.title())
+        res = E5MessageBox.yesNo(
+            self,
+            self.tr("Remove Subscription"),
+            message)
+        
+        if res:
+            removeSubscription = self.__currentSubscription
+            removeTrees = [self.__currentTreeWidget]
+            for index in range(self.subscriptionsTabWidget.count()):
+                tree = self.subscriptionsTabWidget.widget(index)
+                if tree.subscription() in requiresSubscriptions:
+                    removeTrees.append(tree)
+            for tree in removeTrees:
+                self.subscriptionsTabWidget.removeTab(
+                    self.subscriptionsTabWidget.indexOf(tree))
+            self.__manager.removeSubscription(removeSubscription)
+    
+    def __switchSubscriptionEnabled(self):
+        """
+        Private slot to switch the enabled state of the selected subscription.
+        """
+        newState = not self.__currentSubscription.isEnabled()
+        self.__setSubscriptionEnabled(self.__currentSubscription, newState)
+    
+    def __setSubscriptionEnabled(self, subscription, enable):
+        """
+        Private slot to set the enabled state of a subscription.
+        
+        @param subscription subscription to set the state for
+            (AdBlockSubscription)
+        @param enable state to set to (boolean)
+        """
+        if enable:
+            # enable required one as well
+            sub = self.__manager.subscription(subscription.requiresLocation())
+            requiresSubscriptions = [] if sub is None else [sub]
+            icon = UI.PixmapCache.getIcon("adBlockPlus.png")
+        else:
+            # disable dependent ones as well
+            requiresSubscriptions = \
+                self.__manager.getRequiresSubscriptions(subscription)
+            icon = UI.PixmapCache.getIcon("adBlockPlusDisabled.png")
+        requiresSubscriptions.append(subscription)
+        for sub in requiresSubscriptions:
+            sub.setEnabled(enable)
+        
+        for index in range(self.subscriptionsTabWidget.count()):
+            tree = self.subscriptionsTabWidget.widget(index)
+            if tree.subscription() in requiresSubscriptions:
+                self.subscriptionsTabWidget.setTabIcon(
+                    self.subscriptionsTabWidget.indexOf(tree), icon)
+    
+    @pyqtSlot(int)
+    def on_updateSpinBox_valueChanged(self, value):
+        """
+        Private slot to handle changes of the update period.
+        
+        @param value update period (integer)
+        """
+        if value != Preferences.getWebBrowser("AdBlockUpdatePeriod"):
+            Preferences.setWebBrowser("AdBlockUpdatePeriod", value)
+            
+            from WebBrowser.WebBrowserWindow import WebBrowserWindow
+            manager = WebBrowserWindow.adBlockManager()
+            for subscription in manager.subscriptions():
+                subscription.checkForUpdate()
+    
+    @pyqtSlot(int)
+    def on_subscriptionsTabWidget_currentChanged(self, index):
+        """
+        Private slot handling the selection of another tab.
+        
+        @param index index of the new current tab (integer)
+        """
+        if index != -1:
+            self.__currentTreeWidget = \
+                self.subscriptionsTabWidget.widget(index)
+            self.__currentSubscription = \
+                self.__currentTreeWidget.subscription()
+    
+    @pyqtSlot(str)
+    def on_searchEdit_textChanged(self, filter):
+        """
+        Private slot to set a new filter on the current widget.
+        
+        @param filter filter to be set (string)
+        """
+        if self.__currentTreeWidget and self.adBlockGroup.isChecked():
+            self.__currentTreeWidget.filterString(filter)
+    
+    @pyqtSlot(bool)
+    def on_adBlockGroup_toggled(self, state):
+        """
+        Private slot handling the enabling/disabling of AdBlock.
+        
+        @param state state of the toggle (boolean)
+        """
+        self.__manager.setEnabled(state)
+        
+        if state:
+            self.__load()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/AdBlock/AdBlockDialog.ui	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AdBlockDialog</class>
+ <widget class="QDialog" name="AdBlockDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>650</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>AdBlock Configuration</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <widget class="QGroupBox" name="adBlockGroup">
+     <property name="title">
+      <string>Enable AdBlock</string>
+     </property>
+     <property name="checkable">
+      <bool>true</bool>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <item>
+       <layout class="QGridLayout" name="gridLayout">
+        <property name="horizontalSpacing">
+         <number>20</number>
+        </property>
+        <item row="0" column="0" rowspan="2">
+         <widget class="QLabel" name="iconLabel">
+          <property name="minimumSize">
+           <size>
+            <width>48</width>
+            <height>48</height>
+           </size>
+          </property>
+          <property name="text">
+           <string notr="true">Icon</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <spacer name="horizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item row="1" column="1">
+         <widget class="E5ClearableLineEdit" name="searchEdit">
+          <property name="toolTip">
+           <string>Enter search term for subscriptions and rules</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QTabWidget" name="subscriptionsTabWidget">
+        <property name="documentMode">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout">
+        <item>
+         <widget class="QToolButton" name="actionButton">
+          <property name="text">
+           <string>Actions</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QLabel" name="label">
+          <property name="text">
+           <string>Default Update Period (days):</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QSpinBox" name="updateSpinBox">
+          <property name="toolTip">
+           <string>Enter the update period (1 to 14 days)</string>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+          </property>
+          <property name="suffix">
+           <string/>
+          </property>
+          <property name="minimum">
+           <number>1</number>
+          </property>
+          <property name="maximum">
+           <number>14</number>
+          </property>
+          <property name="value">
+           <number>7</number>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Close</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>E5ClearableLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header>E5Gui/E5LineEdit.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>adBlockGroup</tabstop>
+  <tabstop>searchEdit</tabstop>
+  <tabstop>subscriptionsTabWidget</tabstop>
+  <tabstop>actionButton</tabstop>
+  <tabstop>updateSpinBox</tabstop>
+  <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>AdBlockDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>252</x>
+     <y>445</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>AdBlockDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>320</x>
+     <y>445</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/AdBlock/AdBlockExceptionsDialog.py	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to configure the AdBlock exceptions.
+"""
+
+from __future__ import unicode_literals
+
+from PyQt5.QtCore import pyqtSlot, Qt
+from PyQt5.QtWidgets import QDialog
+
+from .Ui_AdBlockExceptionsDialog import Ui_AdBlockExceptionsDialog
+
+import UI.PixmapCache
+
+
+class AdBlockExceptionsDialog(QDialog, Ui_AdBlockExceptionsDialog):
+    """
+    Class implementing a dialog to configure the AdBlock exceptions.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget (QWidget)
+        """
+        super(AdBlockExceptionsDialog, self).__init__(parent)
+        self.setupUi(self)
+        self.setWindowFlags(Qt.Window)
+        
+        self.iconLabel.setPixmap(
+            UI.PixmapCache.getPixmap("adBlockPlusGreen48.png"))
+        
+        self.hostEdit.setInactiveText(self.tr("Enter host to be added..."))
+        
+        self.buttonBox.setFocus()
+    
+    def load(self, hosts):
+        """
+        Public slot to load the list of excepted hosts.
+        
+        @param hosts list of excepted hosts
+        """
+        self.hostList.clear()
+        self.hostList.addItems(hosts)
+    
+    @pyqtSlot(str)
+    def on_hostEdit_textChanged(self, txt):
+        """
+        Private slot to handle changes of the host edit.
+        
+        @param txt text of the edit (string)
+        """
+        self.addButton.setEnabled(bool(txt))
+    
+    @pyqtSlot()
+    def on_addButton_clicked(self):
+        """
+        Private slot to handle a click of the add button.
+        """
+        self.hostList.addItem(self.hostEdit.text())
+        self.hostEdit.clear()
+    
+    @pyqtSlot()
+    def on_hostList_itemSelectionChanged(self):
+        """
+        Private slot handling a change of the number of selected items.
+        """
+        self.deleteButton.setEnabled(len(self.hostList.selectedItems()) > 0)
+    
+    @pyqtSlot()
+    def on_deleteButton_clicked(self):
+        """
+        Private slot handling a click of the delete button.
+        """
+        for itm in self.hostList.selectedItems():
+            row = self.hostList.row(itm)
+            removedItem = self.hostList.takeItem(row)
+            del removedItem
+    
+    def accept(self):
+        """
+        Public slot handling the acceptance of the dialog.
+        """
+        hosts = []
+        for row in range(self.hostList.count()):
+            hosts.append(self.hostList.item(row).text())
+        
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        WebBrowserWindow.adBlockManager().setExceptions(hosts)
+        
+        super(AdBlockExceptionsDialog, self).accept()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/AdBlock/AdBlockExceptionsDialog.ui	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AdBlockExceptionsDialog</class>
+ <widget class="QDialog" name="AdBlockExceptionsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>550</width>
+    <height>450</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>AdBlock Exceptions</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0" rowspan="2">
+      <widget class="QLabel" name="iconLabel">
+       <property name="minimumSize">
+        <size>
+         <width>48</width>
+         <height>48</height>
+        </size>
+       </property>
+       <property name="text">
+        <string notr="true">Icon</string>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>188</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item row="1" column="1">
+      <widget class="E5ClearableLineEdit" name="hostEdit">
+       <property name="toolTip">
+        <string>Enter a host to block AdBlock for</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="2">
+      <widget class="QPushButton" name="addButton">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+       <property name="toolTip">
+        <string>Press to add the host</string>
+       </property>
+       <property name="text">
+        <string>&amp;Add</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0" rowspan="2" colspan="2">
+      <widget class="QListWidget" name="hostList">
+       <property name="alternatingRowColors">
+        <bool>true</bool>
+       </property>
+       <property name="sortingEnabled">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="2">
+      <widget class="QPushButton" name="deleteButton">
+       <property name="enabled">
+        <bool>false</bool>
+       </property>
+       <property name="toolTip">
+        <string>Press to delete the selected hosts</string>
+       </property>
+       <property name="text">
+        <string>&amp;Delete</string>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="2">
+      <spacer name="verticalSpacer">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>148</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>E5ClearableLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header>E5Gui/E5LineEdit.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>hostEdit</tabstop>
+  <tabstop>addButton</tabstop>
+  <tabstop>hostList</tabstop>
+  <tabstop>deleteButton</tabstop>
+  <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>AdBlockExceptionsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>AdBlockExceptionsDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/AdBlock/AdBlockIcon.py	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,188 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the AdBlock icon for the main window status bar.
+"""
+
+from __future__ import unicode_literals
+
+from PyQt5.QtCore import Qt
+from PyQt5.QtWidgets import QAction, QMenu
+
+from E5Gui.E5ClickableLabel import E5ClickableLabel
+
+import UI.PixmapCache
+
+
+class AdBlockIcon(E5ClickableLabel):
+    """
+    Class implementing the AdBlock icon for the main window status bar.
+    """
+    def __init__(self, parent):
+        """
+        Constructor
+        
+        @param parent reference to the parent widget (HelpWindow)
+        """
+        super(AdBlockIcon, self).__init__(parent)
+        
+        self.__mw = parent
+        self.__menuAction = None
+        self.__enabled = False
+        
+        self.setMaximumHeight(16)
+        self.setCursor(Qt.PointingHandCursor)
+        self.setToolTip(self.tr(
+            "AdBlock lets you block unwanted content on web pages."))
+        
+        self.clicked.connect(self.__showMenu)
+    
+    def setEnabled(self, enabled):
+        """
+        Public slot to set the enabled state.
+        
+        @param enabled enabled state (boolean)
+        """
+        self.__enabled = enabled
+        if enabled:
+            self.currentChanged()
+        else:
+            self.setPixmap(
+                UI.PixmapCache.getPixmap("adBlockPlusDisabled16.png"))
+    
+    def __createMenu(self, menu=None):
+        """
+        Private slot to create the context menu.
+        
+        @param menu parent menu (QMenu)
+        """
+        if menu is None:
+            menu = self.sender()
+            if menu is None:
+                return
+        
+        menu.clear()
+        
+        manager = self.__mw.adBlockManager()
+        
+        if manager.isEnabled():
+            menu.addAction(
+                UI.PixmapCache.getIcon("adBlockPlusDisabled.png"),
+                self.tr("Disable AdBlock"),
+                self.__enableAdBlock).setData(False)
+        else:
+            menu.addAction(
+                UI.PixmapCache.getIcon("adBlockPlus.png"),
+                self.tr("Enable AdBlock"),
+                self.__enableAdBlock).setData(True)
+        menu.addSeparator()
+        if manager.isEnabled() and self.__mw.currentBrowser().url().host():
+            if self.__isCurrentHostExcepted():
+                menu.addAction(
+                    UI.PixmapCache.getIcon("adBlockPlus.png"),
+                    self.tr("Remove AdBlock Exception"),
+                    self.__setException).setData(False)
+            else:
+                menu.addAction(
+                    UI.PixmapCache.getIcon("adBlockPlusGreen.png"),
+                    self.tr("Add AdBlock Exception"),
+                    self.__setException).setData(True)
+        menu.addAction(
+            UI.PixmapCache.getIcon("adBlockPlusGreen.png"),
+            self.tr("AdBlock Exceptions..."), manager.showExceptionsDialog)
+        menu.addSeparator()
+        menu.addAction(
+            UI.PixmapCache.getIcon("adBlockPlus.png"),
+            self.tr("AdBlock Configuration..."), manager.showDialog)
+    
+    def menuAction(self):
+        """
+        Public method to get a reference to the menu action.
+        
+        @return reference to the menu action (QAction)
+        """
+        if not self.__menuAction:
+            self.__menuAction = QAction(self.tr("AdBlock"))
+            self.__menuAction.setMenu(QMenu())
+            self.__menuAction.menu().aboutToShow.connect(self.__createMenu)
+        
+        if self.__enabled:
+            self.__menuAction.setIcon(
+                UI.PixmapCache.getIcon("adBlockPlus.png"))
+        else:
+            self.__menuAction.setIcon(
+                UI.PixmapCache.getIcon("adBlockPlusDisabled.png"))
+        
+        return self.__menuAction
+    
+    def __showMenu(self, pos):
+        """
+        Private slot to show the context menu.
+        
+        @param pos position the context menu should be shown (QPoint)
+        """
+        menu = QMenu()
+        self.__createMenu(menu)
+        menu.exec_(pos)
+    
+    def __enableAdBlock(self):
+        """
+        Private slot to enable or disable AdBlock.
+        """
+        act = self.sender()
+        if act is not None:
+            self.__mw.adBlockManager().setEnabled(act.data())
+    
+    def __isCurrentHostExcepted(self):
+        """
+        Private method to check, if the host of the current browser is
+        excepted.
+        
+        @return flag indicating an exception (boolean)
+        """
+        browser = self.__mw.currentBrowser()
+        if browser is None:
+            return False
+        
+        urlHost = browser.page().url().host()
+        
+        return urlHost and \
+            self.__mw.adBlockManager().isHostExcepted(urlHost)
+    
+    def currentChanged(self):
+        """
+        Public slot to handle a change of the current browser tab.
+        """
+        if self.__enabled:
+            if self.__isCurrentHostExcepted():
+                self.setPixmap(
+                    UI.PixmapCache.getPixmap("adBlockPlusGreen16.png"))
+            else:
+                self.setPixmap(UI.PixmapCache.getPixmap("adBlockPlus16.png"))
+    
+    def __setException(self):
+        """
+        Private slot to add or remove the current host from the list of
+        exceptions.
+        """
+        act = self.sender()
+        if act is not None:
+            urlHost = self.__mw.currentBrowser().url().host()
+            if act.data():
+                self.__mw.adBlockManager().addException(urlHost)
+            else:
+                self.__mw.adBlockManager().removeException(urlHost)
+            self.currentChanged()
+    
+    def sourceChanged(self, browser, url):
+        """
+        Public slot to handle URL changes.
+        
+        @param browser reference to the browser (HelpBrowser)
+        @param url new URL (QUrl)
+        """
+        if browser == self.__mw.currentBrowser():
+            self.currentChanged()
--- a/WebBrowser/AdBlock/AdBlockManager.py	Sun Mar 13 14:56:13 2016 +0100
+++ b/WebBrowser/AdBlock/AdBlockManager.py	Sun Mar 13 20:54:42 2016 +0100
@@ -11,9 +11,14 @@
 
 import os
 
-from PyQt5.QtCore import pyqtSignal, QObject, QUrl, QFile
+from PyQt5.QtCore import pyqtSignal, QObject, QUrl, QUrlQuery, QFile, \
+    QByteArray
+from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInfo
+
+from E5Gui import E5MessageBox
 
 from .AdBlockSubscription import AdBlockSubscription
+from .AdBlockUrlInterceptor import AdBlockUrlInterceptor
 
 from Utilities.AutoSaver import AutoSaver
 import Utilities
@@ -56,6 +61,20 @@
             bytes(self.__customSubscriptionUrl().toEncoded()).decode()
         
         self.rulesChanged.connect(self.__saveTimer.changeOccurred)
+        self.rulesChanged.connect(self.__rulesChanged)
+        
+        self.__interceptor = AdBlockUrlInterceptor(self)
+        
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        WebBrowserWindow.networkManager().installUrlInterceptor(
+            self.__interceptor)
+    
+    def __rulesChanged(self):
+        """
+        Private slot handling a change of the AdBlock rules.
+        """
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        WebBrowserWindow.mainWindow().reloadUserStyleSheet()
     
     def close(self):
         """
@@ -94,17 +113,61 @@
         if enabled:
             self.__loadSubscriptions()
         self.rulesChanged.emit()
-##    
-##    def network(self):
-##        """
-##        Public method to get a reference to the network block object.
-##        
-##        @return reference to the network block object (AdBlockNetwork)
-##        """
-##        if self.__adBlockNetwork is None:
-##            from .AdBlockNetwork import AdBlockNetwork
-##            self.__adBlockNetwork = AdBlockNetwork(self)
-##        return self.__adBlockNetwork
+    
+    def block(self, info):
+        """
+        Public method to check, if a request should be blocked.
+        
+        @param info request info aobject
+        @type QWebEngineUrlRequestInfo
+        @return flag indicating to block the request
+        @rtype bool
+        """
+        urlString = bytes(info.requestUrl().toEncoded()).decode().lower()
+        urlDomain = info.requestUrl().host().lower()
+        urlScheme = info.requestUrl().scheme().lower()
+        refererHost = info.firstPartyUrl().host().lower()
+        
+        if not self.isEnabled() or not self.__canRunOnScheme(urlScheme):
+            return False
+        
+        if self.isHostExcepted(urlDomain) or self.isHostExcepted(refererHost):
+            return False
+            
+        res = False
+        
+        for subscription in self.subscriptions():
+            if subscription.isEnabled():
+                if subscription.adBlockDisabledForUrl(info.requestUrl()):
+                    continue
+                
+                blockedRule = subscription.match(info, urlDomain, urlString)
+                if blockedRule:
+                    res = True
+                    if info.resourceType() == \
+                            QWebEngineUrlRequestInfo.ResourceTypeMainFrame:
+                        url = QUrl("eric:adblock")
+                        query = QUrlQuery()
+                        query.addQueryItem("rule", blockedRule.filter())
+                        query.addQueryItem(
+                            "subscription", blockedRule.subscription().title())
+                        url.setQuery(query)
+                        info.redirect(url)
+                        res = False
+                    else:
+                        info.block(True)
+                    break
+        
+        return res
+    
+    def __canRunOnScheme(self, scheme):
+        """
+        Private method to check, if AdBlock can be performed on the scheme.
+        
+        @param scheme scheme to check (string)
+        @return flag indicating, that AdBlock can be performed (boolean)
+        """
+        return scheme not in ["data", "eric", "qthelp", "qrc", "file", "abp"]
     
     def page(self):
         """
@@ -218,6 +281,42 @@
         except ValueError:
             pass
     
+    def addSubscriptionFromUrl(self, url):
+        """
+        Public method to ad an AdBlock subscription given the abp URL:
+        
+        @param url URL to subscribe an AdBlock subscription
+        @type QUrl
+        @return flag indicating success
+        @rtype bool
+        """
+        if url.path() != "subscribe":
+            return False
+        
+        title = QUrl.fromPercentEncoding(
+            QByteArray(QUrlQuery(url).queryItemValue("title").encode()))
+        if not title:
+            return False
+        
+        res = E5MessageBox.yesNo(
+            None,
+            self.tr("Subscribe?"),
+            self.tr(
+                """<p>Subscribe to this AdBlock subscription?</p>"""
+                """<p>{0}</p>""").format(title))
+        if res:
+            from .AdBlockSubscription import AdBlockSubscription
+            from WebBrowser.WebBrowserWindow import WebBrowserWindow
+            
+            dlg = WebBrowserWindow.adBlockManager().showDialog()
+            subscription = AdBlockSubscription(
+                url, False,
+                WebBrowserWindow.adBlockManager())
+            WebBrowserWindow.adBlockManager().addSubscription(subscription)
+            dlg.addSubscription(subscription, False)
+            dlg.setFocus()
+            dlg.raise_()
+    
     def addSubscription(self, subscription):
         """
         Public method to add an AdBlock subscription.
@@ -271,8 +370,13 @@
         self.__loaded = True
         
         self.__enabled = Preferences.getWebBrowser("AdBlockEnabled")
+##    if (!m_enabled) {
+##        mApp->networkManager()->removeUrlInterceptor(m_interceptor);
+##        return;
+##    }
         if self.__enabled:
             self.__loadSubscriptions()
+##    mApp->networkManager()->installUrlInterceptor(m_interceptor);
     
     def __loadSubscriptions(self):
         """
@@ -362,23 +466,13 @@
         self.__adBlockDialog.show()
         return self.__adBlockDialog
     
-    def showRule(self):
-        """
-        Public slot to show an AdBlock rule.
-        """
-        act = self.sender()
-        if act is not None:
-            rule = act.data()
-            if rule:
-                self.showDialog().showRule(rule)
-    
     def elementHidingRules(self):
         """
         Public method to get the element hiding rules.
         
         @return element hiding rules (string)
         """
-        if not self.__enabled:
+        if not self.isEnabled():
             return ""
         
         rules = ""
@@ -399,7 +493,7 @@
         @param url URL to get hiding rules for (QUrl)
         @return element hiding rules (string)
         """
-        if not self.__enabled:
+        if not self.isEnabled():
             return ""
         
         rules = ""
@@ -432,7 +526,7 @@
         
         @param hosts list of excepted hosts (list of string)
         """
-        self.__exceptedHosts = hosts[:]
+        self.__exceptedHosts = [host.lower() for host in hosts]
         Preferences.setWebBrowser("AdBlockExceptions", self.__exceptedHosts)
     
     def addException(self, host):
@@ -441,6 +535,7 @@
         
         @param host to be excepted (string)
         """
+        host = host.lower()
         if host and host not in self.__exceptedHosts:
             self.__exceptedHosts.append(host)
             Preferences.setWebBrowser(
@@ -452,6 +547,7 @@
         
         @param host to be removed from the list of exceptions (string)
         """
+        host = host.lower()
         if host in self.__exceptedHosts:
             self.__exceptedHosts.remove(host)
             Preferences.setWebBrowser(
@@ -464,6 +560,7 @@
         @param host host to check (string)
         @return flag indicating an exception (boolean)
         """
+        host = host.lower()
         return host in self.__exceptedHosts
     
     def showExceptionsDialog(self):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/AdBlock/AdBlockRule.py	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,662 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2009 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the AdBlock rule class.
+"""
+
+from __future__ import unicode_literals
+
+import re
+
+from PyQt5.QtCore import Qt, QRegExp, QUrl
+from PyQt5.QtNetwork import QNetworkRequest
+from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInfo
+
+
+def toSecondLevelDomain(url):
+    """
+    Module function to get a second level domain from the given URL.
+    
+    @param url URL to extract domain from (QUrl)
+    @return name of second level domain (string)
+    """
+    topLevelDomain = url.topLevelDomain()
+    urlHost = url.host()
+    
+    if not topLevelDomain or not urlHost:
+        return ""
+    
+    domain = urlHost[:len(urlHost) - len(topLevelDomain)]
+    if domain.count(".") == 0:
+        return urlHost
+    
+    while domain.count(".") != 0:
+        domain = domain[domain.find(".") + 1:]
+    
+    return domain + topLevelDomain
+
+
+class AdBlockRule(object):
+    """
+    Class implementing the AdBlock rule.
+    """
+    def __init__(self, filter="", subscription=None):
+        """
+        Constructor
+        
+        @param filter filter string of the rule (string)
+        @param subscription reference to the subscription object
+            (AdBlockSubscription)
+        """
+        self.__subscription = subscription
+        
+        self.__regExp = QRegExp()
+        self.__options = []
+        self.__blockedDomains = []
+        self.__allowedDomains = []
+        
+        self.__enabled = True
+        self.__cssRule = False
+        self.__exception = False
+        self.__internalDisabled = False
+        self.__domainRestricted = False
+        self.__useRegExp = False
+        self.__useDomainMatch = False
+        self.__useEndsMatch = False
+        self.__thirdParty = False
+        self.__thirdPartyException = False
+        self.__object = False
+        self.__objectException = False
+        self.__subdocument = False
+        self.__subdocumentException = False
+        self.__xmlhttprequest = False
+        self.__xmlhttprequestException = False
+        self.__document = False
+        self.__elemhide = False
+        self.__caseSensitivity = Qt.CaseInsensitive
+        self.__image = False
+        self.__imageException = False
+        self.__script = False
+        self.__scriptException = False
+        self.__stylesheet = False
+        self.__stylesheetException = False
+        self.__objectSubrequest = False
+        self.__objectSubrequestException = False
+        
+        self.setFilter(filter)
+    
+    def subscription(self):
+        """
+        Public method to get the subscription this rule belongs to.
+        
+        @return subscription of the rule (AdBlockSubscription)
+        """
+        return self.__subscription
+    
+    def filter(self):
+        """
+        Public method to get the rule filter string.
+        
+        @return rule filter string (string)
+        """
+        return self.__filter
+    
+    def setFilter(self, filter):
+        """
+        Public method to set the rule filter string.
+        
+        @param filter rule filter string (string)
+        """
+        self.__filter = filter
+        self.__parseFilter()
+    
+    def __parseFilter(self):
+        """
+        Private method to parse the filter pattern.
+        """
+        parsedLine = self.__filter
+        
+        # empty rule or just a comment
+        if not parsedLine.strip() or parsedLine.startswith(("!", "[Adblock")):
+            self.__enabled = False
+            return
+        
+        # CSS element hiding rule
+        if "##" in parsedLine or "#@#" in parsedLine:
+            self.__cssRule = True
+            pos = parsedLine.find("#")
+            
+            # domain restricted rule
+            if not parsedLine.startswith("##"):
+                domains = parsedLine[:pos]
+                self.__parseDomains(domains, ",")
+            
+            self.__exception = parsedLine[pos + 1] == "@"
+            
+            if self.__exception:
+                self.__cssSelector = parsedLine[pos + 3:]
+            else:
+                self.__cssSelector = parsedLine[pos + 2:]
+            # CSS rule cannot have more options -> stop parsing
+            return
+        
+        # Exception always starts with @@
+        if parsedLine.startswith("@@"):
+            self.__exception = True
+            parsedLine = parsedLine[2:]
+        
+        # Parse all options following '$' character
+        optionsIndex = parsedLine.find("$")
+        if optionsIndex >= 0:
+            options = parsedLine[optionsIndex + 1:].split(",")
+            
+            handledOptions = 0
+            for option in options:
+                if option.startswith("domain="):
+                    self.__parseDomains(option[7:], "|")
+                    handledOptions += 1
+                elif option == "match-case":
+                    self.__caseSensitivity = Qt.CaseSensitive
+                    handledOptions += 1
+                elif option.endswith("third-party"):
+                    self.__thirdParty = True
+                    self.__thirdPartyException = option.startswith("~")
+                    handledOptions += 1
+                elif option.endswith("object"):
+                    self.__object = True
+                    self.__objectException = option.startswith("~")
+                    handledOptions += 1
+                elif option.endswith("subdocument"):
+                    self.__subdocument = True
+                    self.__subdocumentException = option.startswith("~")
+                    handledOptions += 1
+                elif option.endswith("xmlhttprequest"):
+                    self.__xmlhttprequest = True
+                    self.__xmlhttprequestException = option.startswith("~")
+                    handledOptions += 1
+                elif option.endswith("image"):
+                    self.__image = True
+                    self.__imageException = option.startswith("~")
+                elif option.endswith("script"):
+                    self.__script = True
+                    self.__scriptException = option.startswith("~")
+                elif option.endswith("stylesheet"):
+                    self.__stylesheet = True
+                    self.__stylesheetException = option.startswith("~")
+                elif option.endswith("object-subrequest"):
+                    self.__objectSubrequest = True
+                    self.__objectSubrequestException = option.startswith("~")
+                elif option == "document" and self.__exception:
+                    self.__document = True
+                    handledOptions += 1
+                elif option == "elemhide" and self.__exception:
+                    self.__elemhide = True
+                    handledOptions += 1
+                elif option == "collapse":
+                    # Hiding placeholders of blocked elements
+                    handledOptions += 1
+            
+            # If we don't handle all options, it's safer to just disable
+            # this rule
+            if handledOptions != len(options):
+                self.__internalDisabled = True
+                return
+            
+            parsedLine = parsedLine[:optionsIndex]
+        
+        # Rule is classic regexp
+        if parsedLine.startswith("/") and parsedLine.endswith("/"):
+            parsedLine = parsedLine[1:-1]
+            self.__useRegExp = True
+            self.__regExp = QRegExp(parsedLine, self.__caseSensitivity,
+                                    QRegExp.RegExp)
+            return
+        
+        # Remove starting / ending wildcards
+        if parsedLine.startswith("*"):
+            parsedLine = parsedLine[1:]
+        if parsedLine.endswith("*"):
+            parsedLine = parsedLine[:-1]
+        
+        # Fast string matching for domain can be used
+        if parsedLine.startswith("||") and \
+           parsedLine.endswith("^") and \
+           QRegExp("[/:?=&\\*]").indexIn(parsedLine) == -1:
+            parsedLine = parsedLine[2:-1]
+            self.__useDomainMatch = True
+            self.__matchString = parsedLine
+            return
+        
+        # If rule contains '|' only at the end, string matching can be used
+        if parsedLine.endswith("|") and \
+           QRegExp("[\\^\\*]").indexIn(parsedLine) == -1 and \
+           parsedLine.count("|") == 1:
+            parsedLine = parsedLine[:-1]
+            self.__useEndsMatch = True
+            self.__matchString = parsedLine
+            return
+        
+        # If there is still a wildcard (*) or separator (^) or (|),
+        # the rule must be modified to comply with QRegExp.
+        if "*" in parsedLine or "^" in parsedLine or "|" in parsedLine:
+            pattern = self.__convertPatternToRegExp(parsedLine)
+            self.__useRegExp = True
+            self.__regExp = QRegExp(pattern, self.__caseSensitivity,
+                                    QRegExp.RegExp)
+            return
+        
+        # no regexp required
+        self.__useRegExp = False
+        self.__matchString = parsedLine
+    
+    def __parseDomains(self, domains, separator):
+        """
+        Private method to parse a string with a domain list.
+        
+        @param domains list of domains (string)
+        @param separator separator character used by the list (string)
+        """
+        domainsList = domains.split(separator)
+        
+        for domain in domainsList:
+            if not domain:
+                continue
+            if domain.startswith("~"):
+                self.__blockedDomains.append(domain[1:])
+            else:
+                self.__allowedDomains.append(domain)
+        
+        self.__domainRestricted = \
+            bool(self.__blockedDomains) or bool(self.__allowedDomains)
+    
+    def networkMatch(self, request, domain, encodedUrl):
+        """
+        Public method to check the rule for a match.
+        
+        @param request reference to the network request
+        @type QWebEngineUrlRequestInfo
+        @param domain domain name
+        @type str
+        @param encodedUrl string encoded URL to be checked
+        @type str
+        @return flag indicating a match
+        @rtype bool
+        """
+        if self.__cssRule or not self.__enabled or self.__internalDisabled:
+            return False
+        
+        matched = False
+        
+        if self.__useRegExp:
+            matched = self.__regExp.indexIn(encodedUrl) != -1
+        elif self.__useDomainMatch:
+            matched = domain.endswith(self.__matchString)
+        elif self.__useEndsMatch:
+            if self.__caseSensitivity == Qt.CaseInsensitive:
+                matched = encodedUrl.lower().endswith(
+                    self.__matchString.lower())
+            else:
+                matched = encodedUrl.endswith(self.__matchString)
+        else:
+            if self.__caseSensitivity == Qt.CaseInsensitive:
+                matched = self.__matchString.lower() in encodedUrl.lower()
+            else:
+                matched = self.__matchString in encodedUrl
+        
+        if matched:
+            # check domain restrictions
+            if self.__domainRestricted and \
+                    not self.matchDomain(request.firstPartyUrl().host()):
+                return False
+            
+            # check third-party restrictions
+            if self.__thirdParty and not self.matchThirdParty(request):
+                return False
+            
+            # check object restrictions
+            if self.__object and not self.matchObject(request):
+                return False
+            
+            # check subdocument restrictions
+            if self.__subdocument and not self.matchSubdocument(request):
+                return False
+            
+            # check xmlhttprequest restriction
+            if self.__xmlhttprequest and not self.matchXmlHttpRequest(request):
+                return False
+            
+            # check image restriction
+            if self.__image and not self.matchImage(request):
+                return False
+            
+            # check script restriction
+            if self.__script and not self.matchScript(request):
+                return False
+            
+            # check stylesheet restriction
+            if self.__stylesheet and not self.matchStyleSheet(request):
+                return False
+            
+            # check object-subrequest restriction
+            if self.__objectSubrequest and \
+                    not self.matchObjectSubrequest(request):
+                return False
+        
+        return matched
+    
+    def urlMatch(self, url):
+        """
+        Public method to check an URL against the rule.
+        
+        @param url URL to check (QUrl)
+        @return flag indicating a match (boolean)
+        """
+        if not self.__document and not self.__elemhide:
+            return False
+        
+        encodedUrl = bytes(url.toEncoded()).decode()
+        domain = url.host()
+        return self.networkMatch(QNetworkRequest(url), domain, encodedUrl)
+    
+    def matchDomain(self, domain):
+        """
+        Public method to match a domain.
+        
+        @param domain domain name to check (string)
+        @return flag indicating a match (boolean)
+        """
+        if not self.__enabled:
+            return False
+        
+        if not self.__domainRestricted:
+            return True
+        
+        if len(self.__blockedDomains) == 0:
+            for dom in self.__allowedDomains:
+                if domain.endswith(dom):
+                    return True
+        elif len(self.__allowedDomains) == 0:
+            for dom in self.__blockedDomains:
+                if domain.endswith(dom):
+                    return False
+            return True
+        else:
+            for dom in self.__blockedDomains:
+                if domain.endswith(dom):
+                    return False
+            for dom in self.__allowedDomains:
+                if domain.endswith(dom):
+                    return True
+        
+        return False
+    
+    def matchThirdParty(self, req):
+        """
+        Public slot to match a third-party rule.
+        
+        @param req request object to check (QWebEngineUrlRequestInfo)
+        @return flag indicating a match (boolean)
+        """
+        # Third-party matching should be performed on second-level domains
+        firstPartyHost = toSecondLevelDomain(req.firstPartyUrl())
+        host = toSecondLevelDomain(req.requestUrl())
+        
+        match = firstPartyHost != host
+        
+        if self.__thirdPartyException:
+            return not match
+        else:
+            return match
+    
+    def matchObject(self, req):
+        """
+        Public slot to match an object rule.
+        
+        @param req request object to check (QWebEngineUrlRequestInfo)
+        @return flag indicating a match (boolean)
+        """
+        match = (
+            req.resourceType() == QWebEngineUrlRequestInfo.ResourceTypeObject)
+        
+        if self.__objectException:
+            return not match
+        else:
+            return match
+    
+    def matchSubdocument(self, req):
+        """
+        Public slot to match a sub-document rule.
+        
+        @param req request object to check (QWebEngineUrlRequestInfo)
+        @return flag indicating a match (boolean)
+        """
+        match = (
+            req.resourceType() ==
+            QWebEngineUrlRequestInfo.ResourceTypeSubFrame)
+        
+        if self.__subdocumentException:
+            return not match
+        else:
+            return match
+    
+    def matchXmlHttpRequest(self, req):
+        """
+        Public slot to match a XmlHttpRequest rule.
+        
+        @param req request object to check (QWebEngineUrlRequestInfo)
+        @return flag indicating a match (boolean)
+        """
+        match = (
+            req.resourceType() == QWebEngineUrlRequestInfo.ResourceTypeXhr)
+        
+        if self.__xmlhttprequestException:
+            return not match
+        else:
+            return match
+    
+    def matchImage(self, req):
+        """
+        Public slot to match an Image rule.
+        
+        @param req request object to check (QWebEngineUrlRequestInfo)
+        @return flag indicating a match (boolean)
+        """
+        match = (
+            req.resourceType() == QWebEngineUrlRequestInfo.ResourceTypeImage)
+        
+        if self.__imageException:
+            return not match
+        else:
+            return match
+    
+    def matchScript(self, req):
+        """
+        Public slot to match a Script rule.
+        
+        @param req request object to check (QWebEngineUrlRequestInfo)
+        @return flag indicating a match (boolean)
+        """
+        match = (
+            req.resourceType() == QWebEngineUrlRequestInfo.ResourceTypeScript)
+        
+        if self.__scriptException:
+            return not match
+        else:
+            return match
+    
+    def matchStyleSheet(self, req):
+        """
+        Public slot to match a StyleSheet rule.
+        
+        @param req request object to check (QWebEngineUrlRequestInfo)
+        @return flag indicating a match (boolean)
+        """
+        match = (
+            req.resourceType() ==
+            QWebEngineUrlRequestInfo.ResourceTypeStylesheet)
+        
+        if self.__stylesheetException:
+            return not match
+        else:
+            return match
+    
+    def matchObjectSubrequest(self, req):
+        """
+        Public slot to match an Object Subrequest rule.
+        
+        @param req request object to check (QWebEngineUrlRequestInfo)
+        @return flag indicating a match (boolean)
+        """
+        match = (
+            req.resourceType() ==
+            QWebEngineUrlRequestInfo.ResourceTypeSubResource)
+        
+        if self.__objectSubrequestException:
+            return not match
+        else:
+            return match
+    
+    def isException(self):
+        """
+        Public method to check, if the rule defines an exception.
+        
+        @return flag indicating an exception (boolean)
+        """
+        return self.__exception
+    
+    def setException(self, exception):
+        """
+        Public method to set the rule's exception flag.
+        
+        @param exception flag indicating an exception rule (boolean)
+        """
+        self.__exception = exception
+    
+    def isEnabled(self):
+        """
+        Public method to check, if the rule is enabled.
+        
+        @return flag indicating enabled state (boolean)
+        """
+        return self.__enabled
+    
+    def setEnabled(self, enabled):
+        """
+        Public method to set the rule's enabled state.
+        
+        @param enabled flag indicating the new enabled state (boolean)
+        """
+        self.__enabled = enabled
+        if not enabled:
+            self.__filter = "!" + self.__filter
+        else:
+            self.__filter = self.__filter[1:]
+    
+    def isCSSRule(self):
+        """
+        Public method to check, if the rule is a CSS rule.
+        
+        @return flag indicating a CSS rule (boolean)
+        """
+        return self.__cssRule
+    
+    def cssSelector(self):
+        """
+        Public method to get the CSS selector of the rule.
+        
+        @return CSS selector (string)
+        """
+        return self.__cssSelector
+    
+    def isDocument(self):
+        """
+        Public method to check, if this is a document rule.
+        
+        @return flag indicating a document rule (boolean)
+        """
+        return self.__document
+    
+    def isElementHiding(self):
+        """
+        Public method to check, if this is an element hiding rule.
+        
+        @return flag indicating an element hiding rule (boolean)
+        """
+        return self.__elemhide
+    
+    def isDomainRestricted(self):
+        """
+        Public method to check, if this rule is restricted by domain.
+        
+        @return flag indicating a domain restriction (boolean)
+        """
+        return self.__domainRestricted
+    
+    def isComment(self):
+        """
+        Public method to check, if this is a comment.
+        
+        @return flag indicating a comment (boolean)
+        """
+        return self.__filter.startswith("!")
+    
+    def isHeader(self):
+        """
+        Public method to check, if this is a header.
+        
+        @return flag indicating a header (boolean)
+        """
+        return self.__filter.startswith("[Adblock")
+    
+    def isSlow(self):
+        """
+        Public method to check, if this is a slow rule.
+        
+        @return flag indicating a slow rule (boolean)
+        """
+        return self.__useRegExp
+    
+    def isInternalDisabled(self):
+        """
+        Public method to check, if this rule was disabled internally.
+        
+        @return flag indicating an internally disabled rule (boolean)
+        """
+        return self.__internalDisabled
+    
+    def __convertPatternToRegExp(self, wildcardPattern):
+        """
+        Private method to convert a wildcard pattern to a regular expression.
+        
+        @param wildcardPattern string containing the wildcard pattern (string)
+        @return string containing a regular expression (string)
+        """
+        pattern = wildcardPattern
+        
+        # remove multiple wildcards
+        pattern = re.sub(r"\*+", "*", pattern)
+        # remove anchors following separator placeholder
+        pattern = re.sub(r"\^\|$", "^", pattern)
+        # remove leading wildcards
+        pattern = re.sub(r"^(\*)", "", pattern)
+        # remove trailing wildcards
+        pattern = re.sub(r"(\*)$", "", pattern)
+        # escape special symbols
+        pattern = re.sub(r"(\W)", r"\\\1", pattern)
+        # process extended anchor at expression start
+        pattern = re.sub(
+            r"^\\\|\\\|",
+            r"^[\w\-]+:\/+(?!\/)(?:[^\/]+\.)?", pattern)
+        # process separator placeholders
+        pattern = re.sub(r"\\\^", r"(?:[^\w\d\-.%]|$)", pattern)
+        # process anchor at expression start
+        pattern = re.sub(r"^\\\|", "^", pattern)
+        # process anchor at expression end
+        pattern = re.sub(r"\\\|$", "$", pattern)
+        # replace wildcards by .*
+        pattern = re.sub(r"\\\*", ".*", pattern)
+        
+        return pattern
--- a/WebBrowser/AdBlock/AdBlockSubscription.py	Sun Mar 13 14:56:13 2016 +0100
+++ b/WebBrowser/AdBlock/AdBlockSubscription.py	Sun Mar 13 20:54:42 2016 +0100
@@ -128,10 +128,9 @@
         self.__requiresTitle = QUrl.fromPercentEncoding(
             QByteArray(urlQuery.queryItemValue("requiresTitle").encode()))
         if self.__requiresLocation and self.__requiresTitle:
-            import Helpviewer.HelpWindow
-            Helpviewer.HelpWindow.HelpWindow.adBlockManager()\
-                .loadRequiredSubscription(self.__requiresLocation,
-                                          self.__requiresTitle)
+            from WebBrowser.WebBrowserWindow import WebBrowserWindow
+            WebBrowserWindow.adBlockManager().loadRequiredSubscription(
+                self.__requiresLocation, self.__requiresTitle)
         
         lastUpdateString = urlQuery.queryItemValue("lastUpdate")
         self.__lastUpdate = QDateTime.fromString(lastUpdateString,
@@ -499,7 +498,7 @@
         """
         Public method to check the subscription for a matching rule.
         
-        @param req reference to the network request (QNetworkRequest)
+        @param req reference to the network request (QWebEngineUrlRequestInfo)
         @param urlDomain domain of the URL (string)
         @param urlString URL (string)
         @return reference to the rule object or None (AdBlockRule)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/AdBlock/AdBlockTreeWidget.py	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,273 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 - 2016 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a tree widget for the AdBlock configuration dialog.
+"""
+
+from __future__ import unicode_literals
+
+from PyQt5.QtCore import Qt
+from PyQt5.QtGui import QFont, QColor
+from PyQt5.QtWidgets import QAbstractItemView, QTreeWidgetItem, QInputDialog, \
+    QLineEdit, QMenu, QApplication
+
+from E5Gui.E5TreeWidget import E5TreeWidget
+
+
+class AdBlockTreeWidget(E5TreeWidget):
+    """
+    Class implementing a tree widget for the AdBlock configuration dialog.
+    """
+    def __init__(self, subscription, parent=None):
+        """
+        Constructor
+        
+        @param subscription reference to the subscription (AdBlockSubscription)
+        @param parent reference to the parent widget (QWidget)
+        """
+        super(AdBlockTreeWidget, self).__init__(parent)
+        
+        self.__subscription = subscription
+        self.__topItem = None
+        self.__ruleToBeSelected = ""
+        self.__itemChangingBlock = False
+        
+        self.setContextMenuPolicy(Qt.CustomContextMenu)
+        self.setDefaultItemShowMode(E5TreeWidget.ItemsExpanded)
+        self.setHeaderHidden(True)
+        self.setAlternatingRowColors(True)
+        
+        self.customContextMenuRequested.connect(self.__contextMenuRequested)
+        self.itemChanged.connect(self.__itemChanged)
+        self.__subscription.changed.connect(self.__subscriptionChanged)
+        self.__subscription.rulesChanged.connect(self.__subscriptionChanged)
+    
+    def subscription(self):
+        """
+        Public method to get a reference to the subscription.
+        
+        @return reference to the subscription (AdBlockSubscription)
+        """
+        return self.__subscription
+    
+    def showRule(self, rule):
+        """
+        Public method to highlight the given rule.
+        
+        @param rule AdBlock rule to be shown (AdBlockRule)
+        """
+        if rule:
+            self.__ruleToBeSelected = rule.filter()
+        if not self.__topItem:
+            return
+        if self.__ruleToBeSelected:
+            items = self.findItems(self.__ruleToBeSelected, Qt.MatchRecursive)
+            if items:
+                item = items[0]
+                self.setCurrentItem(item)
+                self.scrollToItem(item, QAbstractItemView.PositionAtCenter)
+            
+            self.__ruleToBeSelected = ""
+    
+    def refresh(self):
+        """
+        Public method to refresh the tree.
+        """
+        QApplication.setOverrideCursor(Qt.WaitCursor)
+        self.__itemChangingBlock = True
+        self.clear()
+        
+        boldFont = QFont()
+        boldFont.setBold(True)
+        
+        self.__topItem = QTreeWidgetItem(self)
+        self.__topItem.setText(0, self.__subscription.title())
+        self.__topItem.setFont(0, boldFont)
+        self.addTopLevelItem(self.__topItem)
+        
+        allRules = self.__subscription.allRules()
+        
+        index = 0
+        for rule in allRules:
+            item = QTreeWidgetItem(self.__topItem)
+            item.setText(0, rule.filter())
+            item.setData(0, Qt.UserRole, index)
+            if self.__subscription.canEditRules():
+                item.setFlags(item.flags() | Qt.ItemIsEditable)
+            self.__adjustItemFeatures(item, rule)
+            index += 1
+        
+        self.expandAll()
+        self.showRule(None)
+        self.__itemChangingBlock = False
+        QApplication.restoreOverrideCursor()
+        QApplication.processEvents()
+    
+    def addRule(self, filter=""):
+        """
+        Public slot to add a new rule.
+        
+        @param filter filter to be added (string)
+        """
+        if not self.__subscription.canEditRules():
+            return
+        
+        if not filter:
+            filter = QInputDialog.getText(
+                self,
+                self.tr("Add Custom Rule"),
+                self.tr("Write your rule here:"),
+                QLineEdit.Normal)
+            if filter == "":
+                return
+        
+        from .AdBlockRule import AdBlockRule
+        rule = AdBlockRule(filter, self.__subscription)
+        offset = self.__subscription.addRule(rule)
+        
+        item = QTreeWidgetItem()
+        item.setText(0, filter)
+        item.setData(0, Qt.UserRole, offset)
+        item.setFlags(item.flags() | Qt.ItemIsEditable)
+        
+        self.__itemChangingBlock = True
+        self.__topItem.addChild(item)
+        self.__itemChangingBlock = False
+        
+        self.__adjustItemFeatures(item, rule)
+    
+    def removeRule(self):
+        """
+        Public slot to remove the current rule.
+        """
+        item = self.currentItem()
+        if item is None or \
+           not self.__subscription.canEditRules() or \
+           item == self.__topItem:
+            return
+        
+        offset = item.data(0, Qt.UserRole)
+        self.__subscription.removeRule(offset)
+        self.deleteItem(item)
+    
+    def __contextMenuRequested(self, pos):
+        """
+        Private slot to show the context menu.
+        
+        @param pos position for the menu (QPoint)
+        """
+        if not self.__subscription.canEditRules():
+            return
+        
+        item = self.itemAt(pos)
+        if item is None:
+            return
+        
+        menu = QMenu()
+        menu.addAction(self.tr("Add Rule"), self.addRule)
+        menu.addSeparator()
+        act = menu.addAction(self.tr("Remove Rule"), self.removeRule)
+        if item.parent() is None:
+            act.setDisabled(True)
+        
+        menu.exec_(self.viewport().mapToGlobal(pos))
+    
+    def __itemChanged(self, itm):
+        """
+        Private slot to handle the change of an item.
+        
+        @param itm changed item (QTreeWidgetItem)
+        """
+        if itm is None or self.__itemChangingBlock:
+            return
+        
+        self.__itemChangingBlock = True
+        
+        offset = itm.data(0, Qt.UserRole)
+        oldRule = self.__subscription.rule(offset)
+        
+        if itm.checkState(0) == Qt.Unchecked and oldRule.isEnabled():
+            # Disable rule
+            rule = self.__subscription.setRuleEnabled(offset, False)
+            self.__adjustItemFeatures(itm, rule)
+        elif itm.checkState(0) == Qt.Checked and not oldRule.isEnabled():
+            # Enable rule
+            rule = self.__subscription.setRuleEnabled(offset, True)
+            self.__adjustItemFeatures(itm, rule)
+        elif self.__subscription.canEditRules():
+            from .AdBlockRule import AdBlockRule
+            # Custom rule has been changed
+            rule = self.__subscription.replaceRule(
+                AdBlockRule(itm.text(0), self.__subscription), offset)
+            self.__adjustItemFeatures(itm, rule)
+        
+        self.__itemChangingBlock = False
+    
+    def __copyFilter(self):
+        """
+        Private slot to copy the current filter to the clipboard.
+        """
+        item = self.currentItem()
+        if item is not None:
+            QApplication.clipboard().setText(item.text(0))
+    
+    def __subscriptionChanged(self):
+        """
+        Private slot handling a subscription change.
+        """
+        self.refresh()
+        
+        self.__itemChangingBlock = True
+        self.__topItem.setText(
+            0, self.tr("{0} (recently updated)").format(
+                self.__subscription.title()))
+        self.__itemChangingBlock = False
+    
+    def __adjustItemFeatures(self, itm, rule):
+        """
+        Private method to adjust an item.
+        
+        @param itm item to be adjusted (QTreeWidgetItem)
+        @param rule rule for the adjustment (AdBlockRule)
+        """
+        if not rule.isEnabled():
+            font = QFont()
+            font.setItalic(True)
+            itm.setForeground(0, QColor(Qt.gray))
+            
+            if not rule.isComment() and not rule.isHeader():
+                itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable)
+                itm.setCheckState(0, Qt.Unchecked)
+                itm.setFont(0, font)
+            
+            return
+        
+        itm.setFlags(itm.flags() | Qt.ItemIsUserCheckable)
+        itm.setCheckState(0, Qt.Checked)
+        
+        if rule.isCSSRule():
+            itm.setForeground(0, QColor(Qt.darkBlue))
+            itm.setFont(0, QFont())
+        elif rule.isException():
+            itm.setForeground(0, QColor(Qt.darkGreen))
+            itm.setFont(0, QFont())
+        else:
+            itm.setForeground(0, QColor())
+            itm.setFont(0, QFont())
+    
+    def keyPressEvent(self, evt):
+        """
+        Protected method handling key presses.
+        
+        @param evt key press event (QKeyEvent)
+        """
+        if evt.key() == Qt.Key_C and \
+           evt.modifiers() & Qt.ControlModifier:
+            self.__copyFilter()
+        elif evt.key() == Qt.Key_Delete:
+            self.removeRule()
+        else:
+            super(AdBlockTreeWidget, self).keyPressEvent(evt)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/AdBlock/AdBlockUrlInterceptor.py	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2016 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing an URL interceptor base class.
+"""
+
+from __future__ import unicode_literals
+
+from ..Network.UrlInterceptor import UrlInterceptor
+
+class AdBlockUrlInterceptor(UrlInterceptor):
+    """
+    Class implementing an URL interceptor for AdBlock.
+    """
+    def __init__(self, manager, parent=None):
+        """
+        Constructor
+        
+        @param manager reference to the AdBlock manager
+        @type AdBlockManager
+        @param parent referemce to the parent object
+        @type QObject
+        """
+        super(AdBlockUrlInterceptor, self).__init__(parent)
+        
+        self.__manager = manager
+    
+    def interceptRequest(self, info):
+        """
+        Public method to intercept a request.
+        
+        @param info request info object
+        @type QWebEngineUrlRequestInfo
+        """
+        if self.__manager.block(info):
+            info.block(True)
--- a/WebBrowser/GreaseMonkey/GreaseMonkeyUrlInterceptor.py	Sun Mar 13 14:56:13 2016 +0100
+++ b/WebBrowser/GreaseMonkey/GreaseMonkeyUrlInterceptor.py	Sun Mar 13 20:54:42 2016 +0100
@@ -34,6 +34,6 @@
         @param info request info object
         @type QWebEngineUrlRequestInfo
         """
-        if info.requestUrl().toString.endswith(".user.js"):
+        if info.requestUrl().toString().endswith(".user.js"):
             self.__manager.downloadScript(info.requestUrl())
             info.block(True)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/Network/EricSchemeHandler.py	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,138 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2016 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a scheme handler for the eric: scheme.
+"""
+
+from __future__ import unicode_literals
+
+from PyQt5.QtCore import QByteArray, QBuffer, QIODevice, QTextStream, \
+    QUrlQuery
+from PyQt5.QtWebEngineCore import QWebEngineUrlSchemeHandler
+
+from ..Tools.WebBrowserTools import readAllFileContents
+
+class EricSchemeHandler(QWebEngineUrlSchemeHandler):
+    """
+    Class implementing a scheme handler for the eric: scheme.
+    """
+    SupportedPages = [
+        "adblock",          # error page for URLs blocked by AdBlock
+    ]
+    
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent object
+        @type QObject
+        """
+        super(EricSchemeHandler, self).__init__(parent)
+    
+    def requestStarted(self, job):
+        """
+        Public method handling the URL request.
+        
+        @param job URL request job
+        @type QWebEngineUrlRequestJob
+        """
+        if job.requestUrl().path() in self.SupportedPages:
+            job.reply(b"text/html", EricSchemeReply(job))
+        else:
+            job.reply(QByteArray(), QBuffer())
+            # job.fail(QWebEngineUrlRequestJob.UrlNotFound)
+
+
+class EricSchemeReply(QIODevice):
+    """
+    Class implementing a reply for a requested eric: page.
+    """
+    # TODO: SchemeHandler: debug this further
+    def __init__(self, job, parent=None):
+        """
+        Constructor
+        
+        @param job reference to the URL request
+        @type QWebEngineUrlRequestJob
+        @param parent reference to the parent object
+        @type QObject
+        """
+        super(EricSchemeReply, self).__init__(parent)
+        
+        self.__loaded = False
+        self.__job = job
+        
+        self.__pageName = self.__job.requestUrl().path()
+        self.__buffer = QBuffer()
+        
+        self.open(QIODevice.ReadOnly)
+        self.__buffer.open(QIODevice.ReadWrite)
+        self.__loadPage()
+    
+    def __loadPage(self):
+        """
+        Private method to load the requested page.
+        """
+        if self.__loaded:
+            return
+        
+        stream = QTextStream(self.__buffer)
+        stream.setCodec("utf-8")
+        
+        if self.__pageName == "adblock":
+            stream << self.__adBlockPage()
+        
+        stream.flush()
+        self.__buffer.reset()
+        self.__loaded = True
+    
+    def bytesAvailable(self):
+        """
+        Public method to get the number of available bytes.
+        
+        @return number of available bytes
+        @rtype int
+        """
+        print("bytesAvailable", self.__buffer.bytesAvailable())
+        return self.__buffer.bytesAvailable()
+    
+    def readData(self, maxlen):
+        """
+        Public method to retrieve data from the reply object.
+        
+        @param maxlen maximum number of bytes to read (integer)
+        @return string containing the data (bytes)
+        """
+        print("readData")
+        self.__loadPage()
+        return self.__buffer.read(maxlen)
+    
+    def writeData(self, data, len):
+        return 0
+    
+    def __adBlockPage(self):
+        """
+        Private method to build the AdBlock page.
+        
+        @return built AdBlock page
+        @rtype str
+        """
+        query = QUrlQuery(self.__job.requestUrl())
+        rule = query.queryItemValue("rule")
+        subscription = query.queryItemValue("subscription")
+        title = self.tr("Content blocked by AdBlock Plus")
+        message = self.tr(
+            "Blocked by rule: <i>{0} ({1})</i>").format(rule, subscription)
+        
+        page = readAllFileContents(":/html/adblockPage.html")
+        page = page.replace(
+            "@FAVICON@", "qrc:icons/adBlockPlus16.png")
+        page = page.replace(
+            "@IMAGE@", "qrc:icons/adBlockPlus64.png")
+        page = page.replace("@TITLE@", title)
+        page = page.replace("@MESSAGE@", message)
+        
+        return page
--- a/WebBrowser/Network/NetworkManager.py	Sun Mar 13 14:56:13 2016 +0100
+++ b/WebBrowser/Network/NetworkManager.py	Sun Mar 13 20:54:42 2016 +0100
@@ -11,7 +11,7 @@
 
 import json
 
-from PyQt5.QtCore import pyqtSignal
+from PyQt5.QtCore import pyqtSignal, QByteArray
 from PyQt5.QtWidgets import QDialog
 from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkProxy
 
@@ -74,6 +74,10 @@
             lambda reply, auth: self.authentication(reply.url(), auth))
         
         # TODO: install network scheme handlers
+        from .EricSchemeHandler import EricSchemeHandler
+        self.__ericSchemeHandler = EricSchemeHandler()
+        WebBrowserWindow.webProfile().installUrlSchemeHandler(
+            QByteArray(b"eric"), self.__ericSchemeHandler)
         
         self.__interceptor = NetworkUrlInterceptor(self)
         WebBrowserWindow.webProfile().setRequestInterceptor(self.__interceptor)
@@ -265,9 +269,8 @@
                 WebBrowserLanguagesDialog.defaultAcceptLanguages()))
         self.__acceptLanguage = WebBrowserLanguagesDialog.httpString(languages)
         
-        # TODO: Qt 5.6
-##        WebBrowserWindow.webProfile().setHttpAcceptLanguage(
-##            self.__acceptLanguage)
+        WebBrowserWindow.webProfile().setHttpAcceptLanguage(
+            self.__acceptLanguage)
     
     def installUrlInterceptor(self, interceptor):
         """
@@ -276,8 +279,7 @@
         @param interceptor URL interceptor to be installed
         @type UrlInterceptor
         """
-        # TODO: Qt 5.6
-##        self.__interceptor.installUrlInterceptor(interceptor)
+        self.__interceptor.installUrlInterceptor(interceptor)
     
     def removeUrlInterceptor(self, interceptor):
         """
@@ -286,12 +288,10 @@
         @param interceptor URL interceptor to be removed
         @type UrlInterceptor
         """
-        # TODO: Qt 5.6
-##        self.__interceptor.removeUrlInterceptor(interceptor)
+        self.__interceptor.removeUrlInterceptor(interceptor)
     
     def preferencesChanged(self):
         """
         Public slot to handle a change of preferences.
         """
-        # TODO: Qt 5.6
-##        self.__interceptor.preferencesChanged()
+        self.__interceptor.preferencesChanged()
--- a/WebBrowser/WebBrowserLanguagesDialog.py	Sun Mar 13 14:56:13 2016 +0100
+++ b/WebBrowser/WebBrowserLanguagesDialog.py	Sun Mar 13 20:54:42 2016 +0100
@@ -9,7 +9,7 @@
 
 from __future__ import unicode_literals
 
-from PyQt5.QtCore import pyqtSlot, QByteArray, QLocale, QStringListModel
+from PyQt5.QtCore import pyqtSlot, QLocale, QStringListModel
 from PyQt5.QtWidgets import QDialog
 
 from .Ui_WebBrowserLanguagesDialog import Ui_WebBrowserLanguagesDialog
@@ -144,7 +144,7 @@
             if qvalue > 0.1:
                 qvalue -= 0.1
         
-        return QByteArray(", ".join(processed).encode("utf-8"))
+        return ", ".join(processed)
     
     @classmethod
     def defaultAcceptLanguages(cls):
--- a/WebBrowser/WebBrowserWindow.py	Sun Mar 13 14:56:13 2016 +0100
+++ b/WebBrowser/WebBrowserWindow.py	Sun Mar 13 20:54:42 2016 +0100
@@ -53,7 +53,7 @@
 from UI.Info import Version
 ##
 ##from .data import icons_rc          # __IGNORE_WARNING__
-##from .data import html_rc           # __IGNORE_WARNING__
+from .data import html_rc           # __IGNORE_WARNING__
 from .data import javascript_rc     # __IGNORE_WARNING__
 
 
@@ -89,7 +89,7 @@
     _bookmarksManager = None
     _historyManager = None
     _passwordManager = None
-##    _adblockManager = None
+    _adblockManager = None
     _downloadManager = None
     _feedsManager = None
 ##    _userAgentsManager = None
@@ -155,8 +155,7 @@
 ##            from .HelpSearchWidget import HelpSearchWidget
             from .WebBrowserView import WebBrowserView
             from .WebBrowserTabWidget import WebBrowserTabWidget
-            # TODO: AdBlock
-##            from .AdBlock.AdBlockIcon import AdBlockIcon
+            from .AdBlock.AdBlockIcon import AdBlockIcon
             from .VirusTotal.VirusTotalApi import VirusTotalAPI
             
             # TODO: allow using Qt Help even if not called from eric6
@@ -286,16 +285,15 @@
             self.__tabWidget.newBrowser(home)
             self.__tabWidget.currentBrowser().setFocus()
             
-            # TODO: AdBlock
-##            self.__adBlockIcon = AdBlockIcon(self)
-##            self.statusBar().addPermanentWidget(self.__adBlockIcon)
-##            self.__adBlockIcon.setEnabled(
-##                Preferences.getWebBrowser("AdBlockEnabled"))
-##            self.__tabWidget.currentChanged[int].connect(
-##                self.__adBlockIcon.currentChanged)
-##            self.__tabWidget.sourceChanged.connect(
-##                self.__adBlockIcon.sourceChanged)
-##            
+            self.__adBlockIcon = AdBlockIcon(self)
+            self.statusBar().addPermanentWidget(self.__adBlockIcon)
+            self.__adBlockIcon.setEnabled(
+                Preferences.getWebBrowser("AdBlockEnabled"))
+            self.__tabWidget.currentChanged[int].connect(
+                self.__adBlockIcon.currentChanged)
+            self.__tabWidget.sourceChanged.connect(
+                self.__adBlockIcon.sourceChanged)
+            
             self.networkIcon = E5NetworkIcon(self)
             self.statusBar().addPermanentWidget(self.networkIcon)
             
@@ -2553,9 +2551,8 @@
         
         self.passwordManager().close()
         
-        # TODO: AdBlock
-##        self.adBlockManager().close()
-##        
+        self.adBlockManager().close()
+        
         # TODO: UserAgents
 ##        self.userAgentsManager().close()
 ##        
@@ -2633,7 +2630,8 @@
         """
         Private slot called to handle the reload action.
         """
-        self.currentBrowser().reloadBypassingCache()
+##        self.currentBrowser().reloadBypassingCache()
+        self.currentBrowser().reload()
     
     def __stopLoading(self):
         """
@@ -3577,28 +3575,27 @@
         
         return cls._passwordManager
     
-    # TODO: AdBlock
-##    @classmethod
-##    def adBlockManager(cls):
-##        """
-##        Class method to get a reference to the AdBlock manager.
-##        
-##        @return reference to the AdBlock manager (AdBlockManager)
-##        """
-##        if cls._adblockManager is None:
-##            from .AdBlock.AdBlockManager import AdBlockManager
-##            cls._adblockManager = AdBlockManager()
-##        
-##        return cls._adblockManager
-##    
-##    def adBlockIcon(self):
-##        """
-##        Public method to get a reference to the AdBlock icon.
-##        
-##        @return reference to the AdBlock icon (AdBlockIcon)
-##        """
-##        return self.__adBlockIcon
-##    
+    @classmethod
+    def adBlockManager(cls):
+        """
+        Class method to get a reference to the AdBlock manager.
+        
+        @return reference to the AdBlock manager (AdBlockManager)
+        """
+        if cls._adblockManager is None:
+            from .AdBlock.AdBlockManager import AdBlockManager
+            cls._adblockManager = AdBlockManager()
+        
+        return cls._adblockManager
+    
+    def adBlockIcon(self):
+        """
+        Public method to get a reference to the AdBlock icon.
+        
+        @return reference to the AdBlock icon (AdBlockIcon)
+        """
+        return self.__adBlockIcon
+    
     @classmethod
     def downloadManager(cls):
         """
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/data/html.qrc	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+<qresource>
+  <file>html/adblockPage.html</file>
+</qresource>
+</RCC>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/data/html/adblockPage.html	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"> 
+<meta http-equiv="content-type" content="text/html; charset=utf-8">
+<title>@TITLE@</title>
+<link rel="icon" href="@FAVICON@" type="image/x-icon" />
+<style>
+body {
+  padding: 3em 0em;
+  background: -webkit-gradient(linear, left top, left bottom, from(#85784A), to(#FDFDFD), color-stop(0.5, #FDFDFD));
+  background-repeat: repeat-x;
+}
+#box {
+  background: white;
+  border: 1px solid #85784A;
+  max-width: 600px;
+  height: 50%;
+  padding: 40px;
+  padding-bottom: 10px;
+  margin: auto;
+  border-radius: 0.8em;
+  text-align: center;
+  vertical-align: middle;
+  margin: auto;
+}
+h1 {
+  font-size: 130%;
+  font-weight: bold;
+  border-bottom: 1px solid #85784A;
+  margin-bottom: 0px;
+}
+</style>
+</head>
+<body>
+  <div id="box">
+    <img src="@IMAGE@" width="64" height="64"/>
+    <h1>AdBlock Plus</h1>
+    <p>@MESSAGE@</p>
+  </div>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/data/html_rc.py	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+
+# Resource object code
+#
+# Created by: The Resource Compiler for PyQt5 (Qt v5.6.0)
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore
+
+qt_resource_data = b"\
+\x00\x00\x03\x7c\
+\x3c\
+\x21\x44\x4f\x43\x54\x59\x50\x45\x20\x68\x74\x6d\x6c\x3e\x0a\x3c\
+\x68\x74\x6d\x6c\x3e\x0a\x3c\x68\x65\x61\x64\x3e\x0a\x3c\x6d\x65\
+\x74\x61\x20\x63\x68\x61\x72\x73\x65\x74\x3d\x22\x75\x74\x66\x2d\
+\x38\x22\x3e\x20\x0a\x3c\x6d\x65\x74\x61\x20\x68\x74\x74\x70\x2d\
+\x65\x71\x75\x69\x76\x3d\x22\x63\x6f\x6e\x74\x65\x6e\x74\x2d\x74\
+\x79\x70\x65\x22\x20\x63\x6f\x6e\x74\x65\x6e\x74\x3d\x22\x74\x65\
+\x78\x74\x2f\x68\x74\x6d\x6c\x3b\x20\x63\x68\x61\x72\x73\x65\x74\
+\x3d\x75\x74\x66\x2d\x38\x22\x3e\x0a\x3c\x74\x69\x74\x6c\x65\x3e\
+\x40\x54\x49\x54\x4c\x45\x40\x3c\x2f\x74\x69\x74\x6c\x65\x3e\x0a\
+\x3c\x6c\x69\x6e\x6b\x20\x72\x65\x6c\x3d\x22\x69\x63\x6f\x6e\x22\
+\x20\x68\x72\x65\x66\x3d\x22\x40\x46\x41\x56\x49\x43\x4f\x4e\x40\
+\x22\x20\x74\x79\x70\x65\x3d\x22\x69\x6d\x61\x67\x65\x2f\x78\x2d\
+\x69\x63\x6f\x6e\x22\x20\x2f\x3e\x0a\x3c\x73\x74\x79\x6c\x65\x3e\
+\x0a\x62\x6f\x64\x79\x20\x7b\x0a\x20\x20\x70\x61\x64\x64\x69\x6e\
+\x67\x3a\x20\x33\x65\x6d\x20\x30\x65\x6d\x3b\x0a\x20\x20\x62\x61\
+\x63\x6b\x67\x72\x6f\x75\x6e\x64\x3a\x20\x2d\x77\x65\x62\x6b\x69\
+\x74\x2d\x67\x72\x61\x64\x69\x65\x6e\x74\x28\x6c\x69\x6e\x65\x61\
+\x72\x2c\x20\x6c\x65\x66\x74\x20\x74\x6f\x70\x2c\x20\x6c\x65\x66\
+\x74\x20\x62\x6f\x74\x74\x6f\x6d\x2c\x20\x66\x72\x6f\x6d\x28\x23\
+\x38\x35\x37\x38\x34\x41\x29\x2c\x20\x74\x6f\x28\x23\x46\x44\x46\
+\x44\x46\x44\x29\x2c\x20\x63\x6f\x6c\x6f\x72\x2d\x73\x74\x6f\x70\
+\x28\x30\x2e\x35\x2c\x20\x23\x46\x44\x46\x44\x46\x44\x29\x29\x3b\
+\x0a\x20\x20\x62\x61\x63\x6b\x67\x72\x6f\x75\x6e\x64\x2d\x72\x65\
+\x70\x65\x61\x74\x3a\x20\x72\x65\x70\x65\x61\x74\x2d\x78\x3b\x0a\
+\x7d\x0a\x23\x62\x6f\x78\x20\x7b\x0a\x20\x20\x62\x61\x63\x6b\x67\
+\x72\x6f\x75\x6e\x64\x3a\x20\x77\x68\x69\x74\x65\x3b\x0a\x20\x20\
+\x62\x6f\x72\x64\x65\x72\x3a\x20\x31\x70\x78\x20\x73\x6f\x6c\x69\
+\x64\x20\x23\x38\x35\x37\x38\x34\x41\x3b\x0a\x20\x20\x6d\x61\x78\
+\x2d\x77\x69\x64\x74\x68\x3a\x20\x36\x30\x30\x70\x78\x3b\x0a\x20\
+\x20\x68\x65\x69\x67\x68\x74\x3a\x20\x35\x30\x25\x3b\x0a\x20\x20\
+\x70\x61\x64\x64\x69\x6e\x67\x3a\x20\x34\x30\x70\x78\x3b\x0a\x20\
+\x20\x70\x61\x64\x64\x69\x6e\x67\x2d\x62\x6f\x74\x74\x6f\x6d\x3a\
+\x20\x31\x30\x70\x78\x3b\x0a\x20\x20\x6d\x61\x72\x67\x69\x6e\x3a\
+\x20\x61\x75\x74\x6f\x3b\x0a\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\
+\x72\x61\x64\x69\x75\x73\x3a\x20\x30\x2e\x38\x65\x6d\x3b\x0a\x20\
+\x20\x74\x65\x78\x74\x2d\x61\x6c\x69\x67\x6e\x3a\x20\x63\x65\x6e\
+\x74\x65\x72\x3b\x0a\x20\x20\x76\x65\x72\x74\x69\x63\x61\x6c\x2d\
+\x61\x6c\x69\x67\x6e\x3a\x20\x6d\x69\x64\x64\x6c\x65\x3b\x0a\x20\
+\x20\x6d\x61\x72\x67\x69\x6e\x3a\x20\x61\x75\x74\x6f\x3b\x0a\x7d\
+\x0a\x68\x31\x20\x7b\x0a\x20\x20\x66\x6f\x6e\x74\x2d\x73\x69\x7a\
+\x65\x3a\x20\x31\x33\x30\x25\x3b\x0a\x20\x20\x66\x6f\x6e\x74\x2d\
+\x77\x65\x69\x67\x68\x74\x3a\x20\x62\x6f\x6c\x64\x3b\x0a\x20\x20\
+\x62\x6f\x72\x64\x65\x72\x2d\x62\x6f\x74\x74\x6f\x6d\x3a\x20\x31\
+\x70\x78\x20\x73\x6f\x6c\x69\x64\x20\x23\x38\x35\x37\x38\x34\x41\
+\x3b\x0a\x20\x20\x6d\x61\x72\x67\x69\x6e\x2d\x62\x6f\x74\x74\x6f\
+\x6d\x3a\x20\x30\x70\x78\x3b\x0a\x7d\x0a\x3c\x2f\x73\x74\x79\x6c\
+\x65\x3e\x0a\x3c\x2f\x68\x65\x61\x64\x3e\x0a\x3c\x62\x6f\x64\x79\
+\x3e\x0a\x20\x20\x3c\x64\x69\x76\x20\x69\x64\x3d\x22\x62\x6f\x78\
+\x22\x3e\x0a\x20\x20\x20\x20\x3c\x69\x6d\x67\x20\x73\x72\x63\x3d\
+\x22\x40\x49\x4d\x41\x47\x45\x40\x22\x20\x77\x69\x64\x74\x68\x3d\
+\x22\x36\x34\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x36\x34\x22\
+\x2f\x3e\x0a\x20\x20\x20\x20\x3c\x68\x31\x3e\x41\x64\x42\x6c\x6f\
+\x63\x6b\x20\x50\x6c\x75\x73\x3c\x2f\x68\x31\x3e\x0a\x20\x20\x20\
+\x20\x3c\x70\x3e\x40\x4d\x45\x53\x53\x41\x47\x45\x40\x3c\x2f\x70\
+\x3e\x0a\x20\x20\x3c\x2f\x64\x69\x76\x3e\x0a\x3c\x2f\x62\x6f\x64\
+\x79\x3e\x0a\x3c\x2f\x68\x74\x6d\x6c\x3e\x0a\
+"
+
+qt_resource_name = b"\
+\x00\x04\
+\x00\x06\xfb\x3c\
+\x00\x68\
+\x00\x74\x00\x6d\x00\x6c\
+\x00\x10\
+\x0b\xe9\x1d\x9c\
+\x00\x61\
+\x00\x64\x00\x62\x00\x6c\x00\x6f\x00\x63\x00\x6b\x00\x50\x00\x61\x00\x67\x00\x65\x00\x2e\x00\x68\x00\x74\x00\x6d\x00\x6c\
+"
+
+qt_resource_struct = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
+\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+"
+
+def qInitResources():
+    QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+    QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/data/icons.qrc	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,7 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+<qresource>
+  <file>icons/adBlockPlus16.png</file>
+  <file>icons/adBlockPlus64.png</file>
+</qresource>
+</RCC>
Binary file WebBrowser/data/icons/adBlockPlus16.png has changed
Binary file WebBrowser/data/icons/adBlockPlus64.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/data/icons_rc.py	Sun Mar 13 20:54:42 2016 +0100
@@ -0,0 +1,614 @@
+# -*- coding: utf-8 -*-
+
+# Resource object code
+#
+# Created by: The Resource Compiler for PyQt5 (Qt v5.6.0)
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore
+
+qt_resource_data = b"\
+\x00\x00\x20\x26\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\
+\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
+\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\
+\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\
+\x00\x9a\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xdc\x02\x15\
+\x0e\x23\x2f\xab\xc9\xe5\x0b\x00\x00\x00\x1d\x69\x54\x58\x74\x43\
+\x6f\x6d\x6d\x65\x6e\x74\x00\x00\x00\x00\x00\x43\x72\x65\x61\x74\
+\x65\x64\x20\x77\x69\x74\x68\x20\x47\x49\x4d\x50\x64\x2e\x65\x07\
+\x00\x00\x1f\x7d\x49\x44\x41\x54\x78\xda\xcd\x9b\x69\x90\x5d\xd7\
+\x71\xdf\x7f\x7d\xee\xfa\x96\xd9\x07\xc4\x00\x33\x18\x02\x03\xae\
+\x22\x45\x53\x0b\x25\xd2\x91\x44\x53\x8a\x2d\x89\x91\x17\xad\xa4\
+\x2c\x5b\x52\x12\xc9\xf1\x56\x72\xca\xa9\xe4\x4b\x2a\x1f\x52\x89\
+\xbf\x38\x49\x39\x72\xe2\x4d\x92\x63\x4b\xb1\x55\x12\x4d\x49\xb4\
+\xc5\x45\x24\x41\x10\xa0\x44\x09\x80\x28\x42\x22\x41\x12\xfb\x3a\
+\x33\x00\x66\x06\xb3\xbf\xed\xde\x7b\x4e\xe7\xc3\xb9\x6f\x30\x00\
+\x41\xed\x76\xe5\x56\xdd\x79\x6f\xee\xf6\x4e\xf7\xe9\xfe\x77\xf7\
+\xff\xf4\x85\x1f\x73\x7b\xf1\xc5\x17\xf9\xff\x65\xfb\x49\xc6\x12\
+\xfe\x34\x06\x70\xe0\xc0\x81\xde\x9e\x9e\x9e\x9f\x37\xc6\xbc\x4e\
+\x44\x7a\x01\xfb\x8f\x24\x6b\xa0\xaa\xcb\xce\xb9\xef\xac\xac\xac\
+\x3c\x7e\xf3\xcd\x37\x2f\xff\xa4\x0f\x94\x1f\xe7\xa6\x3d\x7b\xf6\
+\x70\xfb\xed\xb7\x03\xf0\xf5\xaf\x7f\xbd\x32\x3a\x3a\x7a\x6f\xad\
+\x56\xfb\x70\x14\x45\x37\x1b\x63\x22\x40\x45\x04\x91\x2b\x3f\xfe\
+\xf2\xe3\xaa\xfa\x8a\xbf\xa5\xaa\xeb\xcf\x8b\x73\x2e\xcf\xf3\xfc\
+\x40\xa3\xd1\xf8\xdc\xd4\xd4\xd4\x17\xde\xfc\xe6\x37\xb7\x2e\x1f\
+\xd3\x3f\xea\xf6\xe0\x83\x0f\xae\x7d\x7f\xe0\x81\x07\x92\xe3\xc7\
+\x8f\x7f\xe8\xdc\xb9\x73\xdf\x5c\x5c\x5c\x6c\xaf\x36\x1a\xda\x6c\
+\xb5\xb4\xd5\x6e\x6b\xbb\xd3\xd1\x4e\xb9\x67\x59\xe6\xf7\x3c\xd7\
+\x2c\xcf\x35\xcf\x73\x2d\x8a\x42\xf3\xa2\xf0\x9f\xeb\x8e\x67\x79\
+\xbe\x76\x7d\xa7\xd3\xd1\x76\xbb\xad\xad\x56\x4b\x5b\xad\x96\x36\
+\x5b\x2d\x5d\x5d\x5d\xd5\x85\x85\x85\xf6\xb9\x73\xe7\xbe\x79\xfc\
+\xf8\xf1\x0f\x3d\xf0\xc0\x03\xc9\x95\xc6\xf6\x8f\xb2\xed\xd9\xb3\
+\x67\xed\xfb\xfd\xf7\xdf\x9f\x1e\x3e\x7c\xf8\xdd\xd3\xd3\xd3\x7b\
+\x16\x16\x16\x8a\x46\xa3\xa1\xed\x2c\xd3\x8e\xb5\x2e\x73\x4e\x73\
+\xa7\x5a\xa8\xdf\x6d\xb9\xbb\x72\xbf\xd2\xe6\xd6\xed\xdd\xeb\x0b\
+\x55\xcd\x55\x35\x73\x4e\x33\xe7\xb4\x63\xad\x6b\x67\x99\x36\x1a\
+\x0d\x5d\x58\x58\x28\xa6\xa7\xa7\xf7\x1c\x3e\x7c\xf8\xdd\xf7\xdf\
+\x7f\x7f\x7a\xa5\x31\xfe\x54\x5d\x60\xff\xfe\xfd\xbc\xe6\x35\xaf\
+\x01\x60\xe7\xce\x9d\xb5\xcd\x9b\x37\xbf\xa5\x5e\xaf\xff\xa7\x4a\
+\xb5\x7a\x47\x9a\x24\x88\x88\xae\x9c\x3c\xc1\xe2\xb1\xe3\x92\x35\
+\x56\x41\x04\xb8\xd4\x0d\x8c\xc8\xda\x2f\x0a\x82\x5e\xb4\x73\x7f\
+\x5c\x41\xfd\x1f\x7f\x4e\xb5\xbc\x46\x41\x95\xb8\x56\xa3\x6f\xfb\
+\x76\xed\xdd\xba\x0d\x55\x95\x76\xa7\x43\xab\xd9\xfc\xd6\xea\xea\
+\xea\x7f\x39\x7b\xf6\xec\x53\x77\xdd\x75\x57\xe3\xf2\xb1\xfe\x54\
+\x14\xf0\xdd\xef\x7e\x97\x5b\x6f\xbd\xb5\xeb\xf3\xf5\x91\x91\x91\
+\xb7\x56\xab\xd5\xff\x90\x56\x2a\xff\x2c\x89\x63\x44\x55\x57\xcf\
+\x9c\x91\x43\x9f\xfe\x33\x0e\xff\xcd\xe7\x58\x99\x5d\xea\xca\xb3\
+\xf6\xd9\xfd\x31\x53\xfe\xaf\x57\x18\x88\x00\xee\xb2\xeb\xd7\x3f\
+\xa3\x77\x43\x1f\xd7\xfe\xda\x87\xb9\xfe\xe3\xbf\x45\x6d\xcb\x16\
+\x45\x44\xda\xed\x36\xed\x76\xfb\xe9\x56\xab\xf5\x87\xe7\xcf\x9f\
+\xdf\xf9\xa6\x37\xbd\x69\xf5\xf2\x31\xff\xd8\x0a\x78\xee\xb9\xe7\
+\x00\xb8\xe5\x96\x5b\xba\xc2\xf7\x8c\x8c\x8c\xdc\x5d\xad\x56\x7f\
+\x2f\x4d\xd3\x3b\x92\x24\x51\x50\x56\x4f\x9d\x92\x83\x9f\xfe\x14\
+\x8b\x0f\xfd\x3d\x3d\x4b\x33\xf4\xd7\x13\x50\xc1\xb5\x1d\x61\xcd\
+\x80\x03\x2d\x20\x88\x04\x13\x09\xae\x50\x34\x57\x4c\xc5\x5b\x84\
+\x6d\x28\x26\x11\x24\x14\x5c\xee\x70\x05\x98\x00\x54\xa0\x58\x75\
+\x04\x55\x03\xa2\x2c\xae\x76\x58\xe9\xbb\x8a\xfe\xbb\x7f\x89\xeb\
+\x3f\xf6\x1b\xd4\xc7\xb7\xaa\x0a\x74\x3a\x1d\xe9\x74\x3a\xdf\x6a\
+\x36\x9b\x9f\x3c\x77\xee\xdc\xc3\x6f\x7e\xf3\x9b\x57\xae\x34\xfe\
+\x9f\x28\x0c\x3e\xf9\xe4\x93\x7d\x23\x23\x23\xbf\x52\xad\x56\xff\
+\x4d\x9a\xa6\x77\xc4\x71\x8c\x3a\xc7\xea\x99\xd3\x1c\xfa\xf4\x9f\
+\xb3\xf2\xe8\x57\xe9\x59\x9c\xa5\x1e\x45\x68\x0e\xa2\x10\x24\x01\
+\x61\x2a\xa0\x82\x6d\x39\xd4\x2a\xd6\x2a\x88\x60\x52\x83\xa9\x88\
+\x9f\xdd\x4c\xd1\x42\xa1\xf0\xf3\x6d\x22\x21\x48\x05\x54\x71\x99\
+\x57\x1e\x02\xf5\x20\x86\xc5\x39\x56\x1e\xff\x2a\x07\x51\xae\xff\
+\xd8\x6f\x52\x1f\x1f\x27\x8e\x63\x44\xe4\x0e\x11\x61\x64\x64\x24\
+\x7d\xf2\xc9\x27\x1f\xb8\xeb\xae\xbb\x96\x7e\x22\x17\x58\x6f\x42\
+\x4f\x3d\xf5\x54\xff\xe8\xe8\xe8\xfb\x2a\x95\xca\x47\x93\x24\xb9\
+\x2d\x8a\xe3\x58\x40\x9b\x53\x53\xf2\xe2\xff\xfa\x24\xab\x3b\x1e\
+\xa6\x67\x71\x81\x6a\x28\x84\x89\xc1\x84\x02\x4e\xd0\x8e\x12\xd6\
+\x0d\x58\x50\xab\x98\x48\x30\xa1\x17\xc8\x15\x8a\x49\xbd\xe1\xdb\
+\xa6\xc3\x24\x06\x13\x94\x16\x60\x15\x29\xa7\xa6\x68\x94\x96\x62\
+\x14\x97\x2b\x79\xe6\x68\x5a\x65\xa5\x67\x80\xfa\xdb\xee\xe6\x55\
+\x9f\xf8\x04\xd5\xd1\x31\x75\xaa\x92\x67\x59\x96\x65\xd9\xb7\x5b\
+\xad\xd6\x5f\x4f\x4d\x4d\xdd\xff\x96\xb7\xbc\x65\xf1\x07\xb9\x83\
+\xb9\xd2\xc1\xbd\x7b\xf7\xae\xdd\xb0\x7b\xf7\xee\xbe\x4d\x9b\x36\
+\xbd\x2f\x49\x92\x8f\xc4\x71\xfc\xda\x30\x0c\x63\x13\x04\xb4\x67\
+\xce\xf1\xfc\x27\xff\x88\x95\x47\x1e\xa2\x6f\x79\x81\x9a\x11\xa2\
+\xc0\x10\xc6\x86\xb0\x12\x78\x45\x58\x10\x27\x88\x13\x0c\x42\x18\
+\x1b\xa2\x6a\xf7\x9c\xc1\x38\x83\x71\x10\x60\x88\x12\x43\x54\xf3\
+\x0a\x0c\xf0\xe7\xc5\x09\xc6\xf9\xfb\xc2\x34\xf0\xf7\x07\x86\x2a\
+\x42\xef\xca\x02\x2b\x8f\x3e\xc4\x81\x4f\xfe\x11\xed\xf3\xe7\x08\
+\xc2\x80\x28\x8a\xe2\x38\x8e\x5f\x9b\x24\xc9\x47\x36\x6d\xda\xf4\
+\xbe\xdd\xbb\x77\xf7\x01\xdc\x7a\xeb\xad\xec\xdd\xbb\xf7\x87\xb3\
+\x80\xf5\x09\xc5\x13\x4f\x3c\xd1\x3b\x36\x36\xf6\x9e\x5a\xad\xf6\
+\xb1\x24\x49\x5e\x1b\x45\x51\x25\xae\x56\x59\x3a\x76\x4c\x5f\xf8\
+\xe3\xff\x29\xab\x0f\xfd\x03\xfd\xed\x15\xfa\x7a\x22\x0c\x7e\xd6\
+\x25\x10\x82\x48\xbc\xdf\xe7\x4a\x54\x37\xa8\x13\xef\xf3\x81\xf7\
+\x73\xb5\x0a\x0e\x4c\xd5\xc3\x9b\x6d\x80\x09\x81\x40\xd0\x42\x51\
+\xa7\x48\xe4\xcf\x15\x2b\x8a\x24\xa0\x06\x5c\xae\xa8\x55\x34\x00\
+\xe7\x1c\xcb\xab\x39\x8b\x69\x2f\xb5\x77\xfe\x22\x37\xfd\xde\xbf\
+\xd5\xde\xed\xdb\x25\x6b\x36\x29\xf2\xbc\xd5\xe9\x74\x9e\x6d\x34\
+\x1a\x9f\x99\x9c\x9c\xfc\xf2\xdb\xde\xf6\xb6\xe5\x57\x4a\x96\xcc\
+\xe5\x49\x4e\xf7\x82\xa7\x9f\x7e\xba\x3e\x3a\x3a\x7a\x77\xb5\x5a\
+\xfd\x8d\x24\x49\x6e\x8b\xa2\xa8\x12\x55\xab\xcc\x1f\x3c\xa8\x2f\
+\xfd\xe9\x9f\xc8\xfc\xfd\x5f\x64\xa0\xb9\x44\x5f\x35\x22\x4c\x02\
+\x82\xc4\x60\x8c\x60\x1c\x48\xe1\xf7\x30\x31\x84\xa9\x21\xaa\x08\
+\x41\x28\x88\x03\x32\x10\x2b\x04\x89\x10\x56\x84\x30\xed\x9e\x13\
+\x24\x53\xc4\x79\xb0\x8c\xaa\x42\x58\x09\x30\xdd\x73\x16\xc4\x82\
+\x09\x84\xa8\x62\x88\xd2\x80\xde\x34\x62\xa0\xb9\xc4\xfc\x97\xbf\
+\xc0\x4b\x7f\xf6\x27\x32\x7f\xf0\xa0\x46\x95\x0a\x61\x14\x55\x92\
+\x24\xb9\xad\x5a\xad\xfe\xc6\xe8\xe8\xe8\xdd\x4f\x3f\xfd\x74\x1d\
+\xe0\xf6\xdb\x6f\x7f\x59\xb2\xb4\xa6\x80\x1d\x3b\x76\xf0\xae\x77\
+\xbd\xab\x3b\xf3\xb5\xc1\xc1\xc1\xb7\x56\x2a\x95\x4f\x24\x49\x72\
+\x47\x18\x86\xb1\x09\x43\x96\x8e\x1e\xd5\x43\x9f\xfe\x94\x9c\xfb\
+\xec\xa7\xd9\x12\x5b\xfa\x7b\x52\x0c\x5e\x30\xb1\x42\x60\x84\x20\
+\x36\x04\xa9\x21\x48\x0c\x62\x05\xca\x3d\x10\xf1\xca\xa8\x1b\xc2\
+\x54\x10\xdb\xdd\x0d\x81\x7a\xd3\x8f\xea\x86\x30\x11\x8c\x0a\xe4\
+\xfe\xb9\xc6\x79\x25\x45\x15\xe3\x5d\x47\x04\x0a\x4a\xb7\x32\xf4\
+\xf7\x24\x6c\x49\x95\x73\x9f\xfd\x34\x47\x3e\xfd\x29\x59\x3a\x76\
+\x4c\x4d\x10\x10\x86\x61\x9c\x24\xc9\x1d\x95\x4a\xe5\x13\x83\x83\
+\x83\x6f\x7d\xe2\x89\x27\x6a\x00\xef\x7a\xd7\xbb\xd8\xb1\x63\xc7\
+\x45\x17\xd8\xbd\x7b\x37\x00\x77\xde\x79\x27\x00\xf7\xdd\x77\x5f\
+\x7a\xe3\x8d\x37\xbe\xb5\x56\xab\xfd\xc7\x4a\xa5\xf2\xb3\x69\x9a\
+\x02\x68\x7b\x76\x96\xe7\xff\xfb\xff\x90\xa5\xaf\x7c\x81\x2d\xa9\
+\xa3\xb7\x9e\xe0\x1c\xb8\x86\x62\x62\x81\x42\x08\x13\x21\xac\x1b\
+\x4c\x22\x60\xa1\x98\x71\x04\x35\x0f\x82\x12\x42\xd8\x13\x10\x54\
+\x05\xd7\x56\x8a\x79\x87\x24\x94\xb1\x4e\x09\x07\x0c\x92\x0a\xb6\
+\xa9\x14\xcb\x16\xb5\x20\x06\x6c\x1b\x82\x61\x41\x02\xc5\x76\x94\
+\x62\xc5\x61\x33\x07\x81\x0f\xa7\xa6\x06\xc6\x08\x4b\xab\x1d\xce\
+\xb4\x84\xbe\x77\xdf\xc3\xab\x7f\xff\xdf\x69\xb2\x61\x18\x10\xe9\
+\x74\x3a\xb4\x5a\xad\x6f\x36\x1a\x8d\x3f\x78\xe9\xa5\x97\x76\x7e\
+\xe0\x03\x1f\x68\x97\xd8\xc6\x9d\x77\xde\x79\x29\x06\x7c\xe6\x33\
+\x9f\x49\xde\xf0\x86\x37\xdc\x5d\xab\xd5\xfe\x7d\xa5\x52\xf1\x71\
+\x5e\x95\xd6\xb9\x73\xf2\xd2\xff\xfe\x24\xcd\x47\x1e\x62\xb0\xb9\
+\x44\x5f\x6f\xea\xfd\x59\x3d\xa2\x87\x35\x3f\xdb\x02\x98\xd8\x5b\
+\x01\x16\xdc\xaa\x12\x0d\x1a\xb0\x3e\x22\x98\x54\xbc\x72\x3a\x8a\
+\x6b\x83\xe9\xf3\x3f\x6f\x97\x1c\xa6\x66\x90\x08\x5c\x47\xd1\xcc\
+\x63\x80\x33\x4a\x7e\xc1\x11\xf4\x79\x7c\xb0\x6d\x87\xcb\x14\x35\
+\x8a\x0a\xd8\x86\x2b\xf1\x41\xb0\x99\x63\x69\xb9\xcd\x7c\xb5\x8f\
+\xea\x3b\xfe\x05\x37\xfc\xee\x27\xa8\x6c\x1c\x51\x44\xe8\x74\x3a\
+\xd2\x6e\xb7\xbf\xd5\x68\x34\xfe\xdb\xbe\x7d\xfb\x1e\xfe\xd8\xc7\
+\x3e\xd6\xe9\x82\x7d\xd0\x15\xfe\xf3\x9f\xff\x7c\xed\x96\x5b\x6e\
+\x79\x6f\xad\x56\xfb\xfd\x34\x4d\x6f\x4f\xd2\x04\x51\xa5\x71\xe6\
+\x0c\x87\xff\xe2\x4f\xa5\xfd\xe4\xa3\x0c\x76\x96\xa9\x47\x31\x64\
+\x52\x9a\xbe\x10\x24\x86\xb0\x62\x08\x22\x83\x58\xaf\x10\x29\x40\
+\x72\x21\xac\x05\x04\x35\xe3\x7d\xdc\xfa\xe3\x74\x4a\x77\xa9\x1b\
+\x82\x9a\xf8\x90\x59\x78\xa5\xd0\xf1\x85\xb4\x89\xbb\xe7\xfc\x73\
+\x34\xf7\x80\xaa\x39\x98\x50\x08\x6a\x06\x91\x12\x4c\x73\x0f\x9c\
+\xb6\x05\x49\x12\x12\x49\x87\xd5\xe9\x29\x96\x66\xe7\xe9\xb9\xe6\
+\x5a\xe2\xde\x5e\x82\x20\x10\x60\x0b\xb0\x75\x78\x78\xb8\x71\xe7\
+\x9d\x77\x1e\xfb\xd2\x97\xbe\x94\x7f\xfc\xe3\x1f\xf7\x0a\xd8\xb5\
+\x6b\x57\xff\xf8\xf8\xf8\xfb\x6b\xb5\xda\x6f\x56\x2a\x95\x37\x24\
+\x69\x2a\xa2\xaa\xab\xa7\x4f\xc9\xd1\xbf\xfc\x8c\x34\x1f\x7f\x84\
+\xbe\xd5\x45\x6a\x12\x10\x88\x4f\x52\xc2\xd4\x20\x81\xf7\xd3\xc0\
+\x78\x7f\x36\xf8\xe3\x41\x45\x08\x02\x41\xb2\xae\x80\xa5\xcf\xa6\
+\x86\xb0\xba\xee\x98\xc1\x03\x63\x2e\x84\x55\x7f\x9f\x98\x12\x2c\
+\xd5\x2b\xcd\xb5\x14\x53\xf7\x96\x23\x94\xd1\xc5\x51\x46\x19\x90\
+\x58\x30\xb1\xf7\x24\x51\x21\x44\x30\xad\x16\xab\xa7\x27\x59\x5e\
+\x5e\x91\xda\xb6\x09\x89\xfb\xfb\x35\x8c\x22\x11\x91\xcd\xc6\x98\
+\xd1\x81\x81\x81\xce\xbd\xf7\xde\x7b\xe2\x4d\x6f\x7a\x53\xdb\x00\
+\xd4\x6a\xb5\xb7\xa7\x69\xfa\x91\x24\x49\x5e\x1b\xc5\xb1\x41\x55\
+\x57\x4f\x9f\x96\x63\x7f\xf5\x97\x34\xbf\xf6\x10\x3d\x0b\xf3\xd4\
+\xc4\xc7\x64\x29\xe3\x79\x10\x1b\x82\xa8\x1c\xac\x05\x32\x45\x80\
+\x20\x16\x6f\x11\x15\x03\xb9\x9f\x6d\x29\x04\x03\x84\xa9\x10\xf6\
+\xfa\x88\x21\x19\x98\x42\x90\x5c\x30\x85\x10\xa4\xa6\x3c\xb7\x2e\
+\x22\x14\x3e\xaa\x84\x69\x69\x65\xa9\xf1\x4a\xe8\x00\x85\x07\xc8\
+\xa0\x74\xb9\x30\xf1\x2e\x69\x0a\xf1\x79\xc2\xd2\x02\xad\xc7\x1e\
+\xe6\xf8\x67\xff\x92\xc6\xe9\xd3\x82\x53\x8d\xe2\xd8\x24\x49\xf2\
+\xda\x34\x4d\x3f\x52\xab\xd5\xde\xde\x4d\x85\x0d\xf0\xfa\x28\x8a\
+\x6e\x8a\xa2\x28\x0e\xc2\x90\xe5\x63\xc7\x38\xfe\x57\xff\x87\xd5\
+\x47\x1e\xa4\x6f\x71\x9e\x5a\x1a\x12\xc6\x81\x0f\x71\x5a\x9a\x24\
+\x3e\xdd\x35\x81\x1f\x84\x84\x7e\x76\xc8\x40\xb5\x74\x8f\x14\x82\
+\xe4\xe2\x71\xc9\xbc\xcf\x4b\xee\x05\x36\x55\x01\x2d\x5d\xa6\x34\
+\x7f\x29\x84\x20\x02\x62\x5f\x2d\x9a\x96\x81\x36\xa8\x51\xc8\x7c\
+\x2e\x61\x22\xc1\xa1\x60\x9d\x77\x0d\x29\x9f\x6f\xf0\x96\x47\x40\
+\xcd\x29\x6e\xfe\x02\xcb\x0f\x3d\xc8\x51\x07\x13\x1f\xfd\x57\xf4\
+\x4c\x6c\x27\x8a\xa2\xb8\x28\x8a\x9b\x80\xd7\x03\x7f\x17\x02\x71\
+\x51\x14\x7d\x22\x12\x19\x63\x40\x44\xdb\x27\x4f\xca\xfc\xdf\x7d\
+\x91\xe1\xa2\x45\x3d\x8e\x09\x23\x1f\x8f\x8d\x08\xb4\x0a\x74\x39\
+\x43\xe3\xd2\x4c\x43\x90\x24\xc2\x44\x31\x14\xa1\x9f\x71\x01\x71\
+\xbe\xc0\x09\x2a\x5e\x68\x2d\x1c\x34\xdb\xd0\x74\x5e\x71\xc9\xc5\
+\xf2\x58\x0a\x41\x0b\x01\xe3\x43\x1b\x49\x80\xd4\x0c\x8a\xa2\x2b\
+\xde\xc7\xc5\x78\x1c\x30\x36\x83\xb8\x40\x2d\x68\xcb\xa2\x4e\x71\
+\x01\xd8\x86\x85\x48\x90\x54\x10\x15\x02\x31\xd4\xa3\x00\x5d\x9c\
+\xe3\xc2\xdf\x7d\x91\xd6\xcf\xdd\x25\x3d\xd7\x5c\xa3\xc6\x18\x11\
+\x91\xa8\x28\x8a\x3e\x20\x0e\x81\x38\xcb\x32\x51\xf5\xc4\x93\x82\
+\x84\xed\x26\xfd\x0b\xf3\xf4\x8e\x0c\x60\xd4\x9b\x96\xcf\xe7\x0b\
+\xc2\xc1\x61\xd2\x89\x09\xa2\x81\x3a\xb8\xb2\xc4\x35\x19\x6e\x7a\
+\x1a\x37\x77\x01\x43\x41\x90\x78\xd3\x27\x2f\x77\xeb\x08\x7a\x87\
+\x08\xb6\x6c\xc1\x0c\xf4\x41\xe1\x6f\x34\xf5\xb2\x34\x9e\x2f\x50\
+\xcd\x20\x6b\xe1\x66\xe7\x71\xf3\x0b\x68\x2b\x47\x82\x32\x1d\xae\
+\x7b\x73\x93\xb4\x8a\x6c\xbc\x0e\x33\xba\x09\x57\x14\xc4\xab\x0e\
+\x35\x40\x00\x45\xcb\xe2\x6c\x81\xda\x36\xf9\xe2\x22\x3a\x3d\x8b\
+\x2e\x2e\xd0\x5b\x8d\x29\xce\xcf\x13\xb6\x5b\x94\x46\x8b\xaa\x6a\
+\x96\x65\x02\x44\x21\x10\xe4\x79\x1e\x38\xe7\xa4\xcb\xbf\xc5\x81\
+\xa1\xaf\x16\x78\x40\x52\xef\x6f\xea\x14\xbb\xda\xa6\xfe\xd6\xdb\
+\xd9\xf4\x5f\xff\x80\x78\xf3\x96\xb5\xba\xbd\x38\x7f\x96\xe5\x4f\
+\xfd\x39\xd9\xce\xbf\xc7\xb4\x67\x30\x95\x08\xb1\x06\xb7\x02\x18\
+\x41\xdb\x16\xee\xb8\x85\xe4\x77\x7e\x9f\xf8\x96\x9f\x59\x47\x84\
+\xf8\x64\x5c\x5b\x0d\x74\xf9\x02\x6e\x6e\x0a\xfb\xec\x33\xe4\x4f\
+\xee\xc2\x1e\x3e\x88\x5b\x6d\xf9\x7a\x22\x35\x38\x2d\x30\x9b\x46\
+\xa8\x7e\xe8\xb7\xa9\xbd\xf3\xfd\x5c\x89\x45\xb4\xab\xab\xe4\x67\
+\xa7\x69\xbf\x74\x80\x95\xa7\x76\xb1\xfa\xf4\x4e\xb2\xb9\x19\xfa\
+\xeb\x01\x49\x68\xd6\xf8\x45\xe7\x9c\xe4\x79\x1e\x00\x61\x57\x01\
+\x62\xad\x5d\x77\x81\xa2\x0e\xcf\xd9\xa8\xf7\xb9\x30\x16\x6c\x54\
+\x25\xdc\xb6\x95\x78\xf3\x96\x4b\x0a\x09\x73\xd5\x46\x82\x6d\x5b\
+\xa1\xa7\x17\x6d\xcc\xf8\x4a\xb0\x4c\x5b\x83\x41\xa1\xdd\x50\x5a\
+\x81\x12\xa9\x12\x5f\x46\x92\xa0\x20\x95\x1a\xa6\x52\x23\xd8\x38\
+\x4e\x78\xd3\x1d\x84\x3f\x77\x37\xd9\xfd\x7f\x41\xbe\xeb\x61\xf4\
+\x78\x03\x71\xe0\x54\xc8\x33\x25\x2a\xf4\x15\xcb\xd8\xb0\x5e\x27\
+\xbc\xf6\x3a\x2a\xd7\x5e\x47\xcf\x5b\x7f\x81\xe5\x1d\x0f\x73\xfe\
+\xcf\xff\x98\x7c\xe1\x19\x9c\x73\x6b\xf2\x59\x6b\xc9\xf3\x5c\x80\
+\xc0\x5c\x89\x95\x55\xa7\x68\x07\x5c\xc7\x97\xad\x18\x50\x57\x10\
+\x5d\x37\x41\x72\xc3\x75\x2f\xe7\xaa\xc5\x10\x6d\x1b\xc7\x0c\x6f\
+\xc4\xb5\x42\xdc\xac\x43\x97\x94\xa0\xcf\x63\x84\x8b\xa1\x48\x15\
+\x17\xac\x11\x5c\xa8\xb5\x74\x1a\xab\x74\x9a\xab\x14\xad\x16\xea\
+\xdc\x9a\x60\xc1\xe6\xad\x84\xef\xb8\x07\x19\xdb\x82\xe9\x0d\xb0\
+\xf3\x8a\x9d\x71\xe4\x8b\x0e\xdb\xd1\x4b\x18\x63\xe7\x1c\xce\x59\
+\x5c\x79\xff\x7a\x65\xf4\xbd\xfd\x5d\xf4\xbe\xfd\x97\x09\x7a\x36\
+\x78\x17\x5e\xc7\x30\x77\x3f\xc3\x4b\x14\x50\x5e\x20\x02\x12\x81\
+\x89\x7d\xfc\x56\x0b\x2e\xcb\x49\xb6\x6c\x27\xdc\x76\xed\x95\xcb\
+\xca\x8d\x63\x98\xf1\xab\xe1\xe4\x0b\x04\xd9\xaa\x0f\x57\x6d\xa0\
+\xe2\x93\x1f\xb2\x92\xef\x2a\x85\x6c\x2e\x2d\x70\xe0\xef\xef\xc7\
+\x39\x4b\xda\x3b\xc0\xc6\x57\xdd\xcc\xf0\xc4\x35\xc4\x95\x2a\x12\
+\x04\x04\x9b\xae\xc6\x8d\xbf\x0a\xf7\x9d\x93\x04\xbd\x0e\x75\x86\
+\xa2\x66\x20\x94\xf5\x9c\x39\xf3\xa7\x4f\x32\x7f\xfa\x14\xce\x39\
+\xea\xc3\x1b\xe8\xdf\x3c\x4a\xb5\x7f\x00\x63\x0c\x26\xad\x30\xf0\
+\xcb\xef\x66\xe1\xe1\x87\x20\x0a\xd7\x94\xbc\x5e\x11\x21\x50\x6a\
+\xd1\xa1\x5a\x2a\xc3\xf8\x8c\x4b\x82\x92\xd4\xb4\x8a\xd3\x80\x78\
+\x6c\x2b\xe9\xd8\x38\x00\xce\x5a\xb2\x56\x8b\xb8\x52\xc1\x04\x01\
+\xe1\xc6\x51\xc2\xf1\x71\x8a\x81\x3a\x2c\xad\x22\x2a\xb0\x02\xb4\
+\x15\x6d\xe3\x51\x7e\x9d\xa1\xe5\x8b\x0b\x5c\xf8\xca\xe7\x20\xcf\
+\x28\xf2\x80\xe5\xdb\x6f\xc3\xdc\xf3\x51\x46\x5e\xfd\x7a\x7f\x41\
+\x94\x90\x0f\x6e\x01\x35\x44\x69\xc9\x2b\x24\xc6\x87\xdb\x35\x4b\
+\x75\x4c\x7f\xeb\x29\x0e\x7f\xf9\xf3\x34\xe6\xe6\x49\x37\x6f\x63\
+\xeb\x3f\x7f\x07\xd7\xbf\xf3\x9d\xf4\x8f\x6c\x46\x44\xa8\x4c\x5c\
+\x43\xb4\x6d\x2b\x54\x52\xaf\x00\xbd\x68\x39\x6b\x0a\x58\xf3\xff\
+\x2e\x07\x6b\x3d\x45\xe5\x72\xc5\x00\x06\x87\xd9\x34\x42\xb2\x75\
+\x1b\x51\x5f\x3f\x00\x59\xb3\xc9\xd9\x03\xcf\x33\x34\x31\x41\x7d\
+\xc3\x55\x44\x3d\x75\xc2\x4d\xe3\x14\xb5\x21\xf4\xdc\x39\x1c\xea\
+\x79\x81\x58\x7c\x9c\x0f\x29\x99\x62\xaf\x87\x48\x0b\xb6\x15\x33\
+\x24\x45\x46\x73\x36\x23\x7b\x21\xc6\x4e\x4f\x52\xdc\xf4\x3a\x42\
+\xe3\x73\x80\x4e\x1c\x11\x05\xa0\x2d\x87\x16\x0e\xd7\xe3\xc0\xae\
+\x77\x57\x25\x9a\x9b\xa3\xff\xe8\x11\xa2\xc9\xb3\x74\x4e\x9c\xe2\
+\x82\x38\xe6\xc6\xc7\xe8\x1f\xd9\xbc\xce\xa5\xc6\xd0\xb4\xba\x26\
+\x63\x17\x07\x5e\xa6\x80\xf5\x2c\xb5\xb3\x0a\xae\x54\x88\x58\xc2\
+\xed\xdb\x09\xb7\x8c\x23\x71\xe4\x15\xb0\xba\xc2\xe4\x53\x4f\x42\
+\x91\x53\xe9\xeb\x27\x4a\x53\xcc\xc6\x51\x18\x1e\xc3\x1d\x3a\x84\
+\xb1\x0e\x8d\xd5\xc7\x65\x2b\x10\xc0\x3a\x92\x9b\x00\x65\xb4\x2a\
+\xd4\x9c\x21\x6f\xa5\xac\xf6\x0e\x10\x26\xd5\x35\x23\x51\x55\x5a\
+\x8b\xe7\x09\x70\xb8\x0e\x3e\xee\x77\x4a\xee\xb0\x0b\xa2\x0a\x3d\
+\x61\xc4\xd5\xd5\x1a\x59\xb5\xce\xaa\x16\x64\xe7\x4f\x53\x4c\x9d\
+\x59\x7b\x86\x88\xe0\x7a\xfa\x21\x8a\xbc\x60\xe5\xf1\x4b\x14\xd0\
+\x45\xc8\xf5\x3c\x91\x04\xa5\x0b\x38\xc1\x59\x88\xc6\x27\x08\x47\
+\x46\x51\x13\xe0\x54\xc9\x97\x16\x59\xd9\xfb\x14\x0b\x3d\x3d\x8c\
+\xdc\xf2\x33\x84\x69\x8a\x8c\x8c\x22\xdb\x26\xd0\xef\x7d\x1d\x69\
+\xb4\xd0\x1c\x5c\x53\x71\x6d\xc5\x15\x0e\x67\x1d\x0a\x38\x55\x88\
+\x12\x64\xe2\x67\xb0\x6a\x91\xb1\x0a\xb5\x5b\xdf\x88\xd9\x3a\x81\
+\x31\x82\x05\x5a\x17\xe6\x68\x1f\x3c\x44\x3d\x2b\x90\x44\x20\x14\
+\x24\x16\x54\xbc\x1a\x7d\xa4\x72\x88\x58\xc2\xc8\x4b\xd2\x53\x80\
+\x86\x29\xf5\x4a\xa5\xbc\xc6\x21\x41\x40\x3b\xeb\x90\xd8\xe2\xe2\
+\x04\x5c\xee\x02\x97\xad\xbf\x79\x0c\x08\x40\x4a\x53\xd4\xb0\x4a\
+\x3c\xba\x95\x70\x70\x08\x44\xc8\xda\x6d\x9a\x67\x27\x89\x8e\xbd\
+\x48\x3e\x36\x81\x6d\xb6\x70\x7d\xfd\x04\x57\x6d\x24\xd8\xba\x15\
+\xdb\x57\x41\x8a\x16\x7a\x41\xb1\x40\xd1\xf6\x4a\x50\xa7\x9e\xf7\
+\xb7\x05\x66\xe8\x2a\xa2\x8f\xfd\x67\x54\x14\x89\xab\x04\xbd\x7d\
+\x48\xad\x8e\x5a\xcb\xca\xec\x0c\xd3\x5f\xdf\x05\x07\x8f\x20\xb9\
+\x85\xbe\xb2\x68\x4a\x14\x0d\xfd\x33\x9c\x3a\x54\x1d\x84\x01\x54\
+\x62\x4c\x5f\x42\xa0\x75\xa2\x89\x9b\xa8\x4e\x5c\x8b\x2d\x31\xc2\
+\x04\x01\xad\xf3\xd3\x04\xad\x66\xb9\x18\xa3\x2f\x07\xc1\xae\x39\
+\xac\x73\x2d\x9c\x53\x9c\x2a\x62\x95\x60\xeb\x16\xc2\xb1\x51\x24\
+\x4d\x51\xa0\x39\x7f\x81\xd9\xfd\xcf\x30\x94\x77\x60\xf2\x0c\x8d\
+\xd9\xf3\x04\x83\x83\x04\x49\x42\xb0\x61\x33\xb2\x61\x0b\x6e\x66\
+\x1e\x50\x82\x01\xc1\x34\x58\xe3\xf1\x1c\xe0\xac\x83\x30\x46\xae\
+\xbe\xc6\x27\x42\xea\xf1\x41\x8c\xa1\xbd\xba\xca\xf4\xb3\x7b\x39\
+\xf5\xe0\xff\xe5\x3a\xbd\x80\x29\x7c\x14\xc2\xe9\x1a\x9b\xec\x95\
+\xe8\xad\x36\x1c\xd9\x0c\x37\xdd\x8a\x1b\x6f\x52\x7f\xcd\xcf\x52\
+\xb9\xeb\xe7\x89\xb7\x4d\xe0\xb2\x0c\x55\xa5\x68\xb7\x29\x26\x27\
+\xa1\xd9\xf2\x18\x54\x0a\x7e\x65\x17\xd0\x8b\x20\x68\xdb\x8a\x69\
+\x3b\x50\x25\xda\xba\x0d\xd9\xb4\x19\x17\x45\x38\xa0\x7d\xe1\x02\
+\x17\xf6\x7c\x9b\xcd\x0d\xa1\x68\x2e\xb0\x78\xe2\x08\xc9\xe8\x18\
+\x95\x38\xc1\xf6\x5f\x45\x67\xf8\x7a\xcc\xdc\xb3\xa4\x83\xa1\x1f\
+\xac\x51\x48\x1c\x4e\x1c\xb6\x34\xdd\x35\xb0\x59\xf3\x39\x1f\x59\
+\x82\xb4\xc2\xf8\xeb\xdf\xc8\x55\xed\x0f\x23\x5f\xf8\x33\x68\xcf\
+\x52\xcc\x5a\xb2\x8e\x23\x37\x8e\xb8\x65\x4b\x25\xfa\xc5\x82\x9e\
+\x9f\x7b\x27\xbc\xe5\x17\x3c\x28\x18\x03\x81\x41\xad\xc3\x8a\xa0\
+\x45\xc1\x91\x5d\x4f\xd2\x38\x72\x9c\x81\xac\xc0\x18\xb3\x86\x77\
+\x97\xb8\xc0\xe5\x18\x20\xe2\xab\x3b\x89\x05\xd4\x10\x8f\x6d\x25\
+\xda\x30\x82\x44\x31\xce\x29\xc5\xfc\x2c\xee\xe0\x77\x08\x22\x47\
+\xfb\xdc\x0c\xed\x63\x47\xb0\xaf\xb9\x0d\xed\x1b\x20\xd8\xb8\x91\
+\xe8\xd5\x37\x52\x3c\xea\x17\x43\x24\x16\x6c\xc7\x2b\xd4\x59\xb7\
+\x06\x60\x9d\x95\x65\x26\x9f\xfd\x36\xea\x2c\x51\xa5\x4e\xff\xf8\
+\x38\xd5\xa1\x61\xc2\x38\x26\xe8\x1d\xa0\xf2\xc6\xb7\xd2\x39\x7d\
+\x92\xe2\xc4\x17\xa0\xa7\x8d\xa9\x0b\x52\xf7\x96\xa4\xeb\x73\x97\
+\x20\x44\xa2\xe8\xb2\xfc\x52\xb1\x79\xce\xd2\xd4\x24\xa7\xbf\xfa\
+\x65\xc2\xe9\xd3\x04\x5d\x8e\xed\x95\x30\xe0\x12\x96\x5c\x00\xe3\
+\x57\x70\x64\x68\x98\x68\xcb\x38\xa6\x56\x03\x11\x3a\x8d\x06\xf9\
+\xf2\x12\x7d\x7d\xbd\x44\x1b\x37\x12\x65\x06\x1a\x6d\x5c\x27\xc3\
+\xda\x02\x53\xeb\x21\xbe\x7a\x2b\xf9\x55\x43\xd8\xe3\x17\x10\xe3\
+\x28\x5a\xea\xa9\x2c\xab\xde\x77\x81\xe6\xcc\x0c\x2f\x7c\xf2\x0f\
+\x21\xcf\x50\x0c\xf5\x1b\xaf\x63\xfc\x17\xee\x66\xec\xb6\x37\x51\
+\x19\x18\x42\xeb\xfd\xd8\x57\xbd\x91\x9c\xfb\x89\xa2\x32\x22\x45\
+\x0a\x81\x4f\xd5\xbb\x02\xd8\xa2\x83\x2d\x0a\xbf\x8a\x64\x1d\x45\
+\x96\xd1\x59\x5d\xe1\xc2\xb1\x63\x9c\x7a\xf4\x61\xec\xd3\xbb\xa9\
+\xb5\x57\x09\x4c\x77\x61\x56\x5e\x9e\x09\x5e\xb4\x80\x75\x28\x59\
+\x28\xce\x7a\x1f\x0b\xb6\x6c\x81\x24\xc6\x15\x05\x36\xcf\x48\xc7\
+\xc6\xd9\xfc\xaf\x7f\x97\x38\x8a\x89\x73\x07\xa3\x63\x98\x4a\x15\
+\x9b\xe7\xbe\x2c\xee\x1f\xc6\x4e\xdc\x84\x9c\xd8\x45\x18\x19\x5f\
+\x4c\x19\x8f\x29\xea\xbc\x1b\x98\xbc\xcd\xe8\x85\x63\xc4\x79\x46\
+\xb6\x6c\x69\xce\x4f\xb3\xda\xd3\x4b\x63\x6c\x82\xb4\x7f\x08\x15\
+\x41\xae\x9e\xc0\xd6\x6b\x48\x63\x99\x22\xf7\x69\xb0\x2b\xdc\xda\
+\x78\x9d\x73\x9c\x3f\x74\x88\xb9\x43\x07\xc9\x5b\x2d\x6c\x9e\x93\
+\xaf\x2c\xd1\x3a\x7f\x8e\xd6\x91\xa3\xd8\x17\x0f\xb0\xa1\xb5\x42\
+\x54\xb8\x4b\x00\xee\xfb\x24\x42\xeb\xf2\x80\x02\xac\x1a\xe2\x91\
+\x51\xc2\xcd\xa3\x10\x46\xd8\xa2\xc0\x88\x50\xdd\xb2\x15\x19\xbb\
+\x1a\x05\x12\xca\x04\x27\x08\x70\x85\xf7\x4b\x57\xef\x87\x9b\x6e\
+\xc3\xee\x7c\x82\x30\x0d\xc1\x81\x0b\x40\x71\x6b\xb3\x17\x18\xd8\
+\x36\x54\xa7\x52\x74\xc8\x8d\x63\x31\xcb\xe9\xcc\xce\xe2\x96\x97\
+\x70\x28\x2a\x42\xd0\xdf\x4f\xde\xd7\x0f\x0b\xe7\xb0\x1d\x87\x6d\
+\x2b\x36\x2f\x05\x50\xc5\x15\x05\x8b\xcf\x7d\x97\xe9\x7f\xf8\x32\
+\xed\xb9\x79\x04\x07\x59\x0b\x5d\x5a\x22\x5e\x5c\x66\xd0\x2a\xf5\
+\x28\xf4\x39\x84\xbb\x58\x80\xfe\xc0\x3c\x40\x7d\x11\x08\x95\x0a\
+\xd1\x96\x71\xc2\x81\x41\xd4\x18\x70\x0e\x09\x43\x4c\x9c\xbc\xac\
+\x1c\x53\xeb\x50\x67\xb1\x45\x8e\xd4\xea\x44\x37\xdc\x4c\x3b\x48\
+\x08\xda\x4a\xd1\x76\xe5\xcc\x95\xc5\x8b\xfa\xff\xf3\x95\x8c\xb0\
+\xc8\x71\x6d\x4b\xb5\x56\x23\x19\x1e\x24\xa9\x56\xb1\x85\x2d\x81\
+\x52\x68\x4b\x40\x50\xae\xab\xab\x28\xaa\xae\x4c\xdd\xbd\x35\x85\
+\xf3\xb3\xf4\x9f\x3c\x44\x7e\x76\x06\x11\x43\x10\x08\x91\x18\xe2\
+\x20\xc0\x04\x1e\x17\xf2\x2b\xb4\xdd\x7c\xff\x3c\x40\x14\x8d\x04\
+\x19\x1e\x24\x9a\x98\x40\x92\xc4\x87\x94\x4e\x87\x4e\xa3\x41\xd1\
+\x69\xaf\xa5\xb5\xdd\x94\x2c\x8c\x63\xa2\x6a\x95\x30\x4e\x90\x28\
+\x26\xda\xb8\x89\xc6\xa6\xab\x29\xa6\x8f\x53\x34\x2c\xb6\xe3\x13\
+\x21\xd7\x15\x40\x05\x1b\x0d\x92\x4b\x86\xf4\x0b\xe6\xc6\xed\x04\
+\xaf\x7d\x1d\x66\xc3\x46\x5c\x91\xfb\x59\x6a\xb7\x69\xcd\x5c\xa0\
+\x12\x58\xbf\x86\x10\x2b\x1a\x5c\x54\xa2\xaa\xa3\x16\x1b\x92\x9e\
+\x14\xd7\xaa\x50\xb4\xf0\x8a\x2e\x93\x2d\x4f\x9f\xfb\xda\x06\xb9\
+\x72\xdf\xd1\x95\xf3\x00\xa7\x38\x0c\x3a\x38\x4c\xb0\x6d\x3b\x1a\
+\x04\x88\x31\xcc\x1d\x3f\xc6\x81\xaf\x7c\x89\x33\xdf\xde\x43\x10\
+\x45\x65\xd7\x12\x60\x2c\xc3\x37\xdc\xc4\x0d\xef\xf8\x45\x46\x6f\
+\x7d\x0d\x61\x10\xe2\x92\x94\xe2\xf5\xb7\x11\xee\x38\xe9\x31\x40\
+\xf4\x62\xd1\x55\x14\x04\x83\x43\xa4\xbf\xf5\x7b\x04\xce\x41\x5a\
+\xc7\x8c\x8f\x23\xc3\x1b\x21\xad\xe0\xac\xc5\xda\x82\xe5\xa9\xd3\
+\x98\x95\x65\x30\x0e\xeb\xc0\xe6\x65\x1e\xe0\x1c\xea\x9c\x27\x69\
+\x0a\xbf\xe4\x6e\x33\xc5\xa9\x40\xd0\x5d\x49\x2e\x6b\x1a\x51\xac\
+\x5b\x17\x71\xbb\xe4\xc9\xf7\x77\x01\xc5\x3a\x43\x30\xb8\x91\x74\
+\xfc\x6a\x08\x02\xd4\x18\x96\x8f\x1d\x41\x9f\xfe\x06\x63\x07\x5e\
+\x24\x4a\x22\x44\xfc\xb2\x95\x09\x1c\x79\x7b\x85\xec\xba\xeb\xc9\
+\xae\xbb\x1e\x93\xa6\x90\x26\xc4\x6f\xbc\x03\xbb\xf3\x7e\x9c\x71\
+\x68\x54\x9a\xb0\x75\xa8\x75\x50\xad\x11\xfe\xec\x5d\x17\xa3\x4f\
+\x18\xfa\x38\x0e\x20\x86\xce\xf2\x32\x87\xbe\xf4\x79\x36\x6b\x93\
+\xce\xbc\xc5\x15\x96\x3c\xb5\xd8\xce\xc5\x38\xae\xce\xe1\xda\x8e\
+\x7c\xd9\xe1\x56\x1d\x92\x1a\x24\x2e\x59\x6a\x05\x9b\xf9\x88\x63\
+\xf3\x2e\xea\xcb\x95\x5d\xe0\x65\xc5\x90\x31\xc8\x60\x1f\xf1\xab\
+\x6e\x24\xac\x54\x10\x63\xc8\x0b\x8b\x9e\x3a\x4d\xcf\xd9\x29\x7a\
+\x13\x25\xaa\x94\xa1\xa9\x80\x30\x14\x16\xcf\x4e\xc1\xd4\x24\xb6\
+\xd5\xf2\x1d\x40\x71\x42\xe5\xda\xeb\x59\xee\x1d\xc0\x2e\x2c\x63\
+\x33\x8b\x77\xeb\x92\x08\x15\x83\x24\xe9\x25\x21\x49\xfd\x09\x16\
+\xcf\x4e\x73\x7a\xc7\x43\x98\x3d\xbb\x30\x2b\x6d\xcf\x1d\x5a\x45\
+\x52\xf5\x33\x2c\xdd\xe7\x08\x9a\x80\x54\xbc\x7b\x38\xa7\x90\x7b\
+\xf3\x77\xae\x24\x72\xe4\xe5\xed\x38\x3f\x44\x31\x24\xb8\x34\xa5\
+\x55\xad\x32\x73\xf2\x24\x26\x8c\x68\x2c\xcc\xb3\x7a\xf0\x30\x49\
+\xab\x45\x1c\x19\x8c\x94\x99\x65\x01\xd2\x86\xb8\xdd\x24\x3f\x7a\
+\x8c\xb9\x17\x0f\xb0\xda\x69\x21\x4e\x61\x65\x85\x4e\xcf\x26\x8a\
+\xce\x24\xed\xc5\x06\x8b\xd3\x53\xe4\x27\x8e\xe1\xda\xed\x75\xf8\
+\xe1\xf3\xfa\xac\xb9\x42\x67\x71\x81\xa5\x93\x27\x59\xdc\xbf\x1f\
+\x79\xe1\x79\xc6\x16\xe6\x30\x56\x3d\x00\x2b\x58\x2d\x58\x99\x9f\
+\xc5\x1e\x3d\x8a\xeb\xb4\x21\x2f\xe8\x2c\x2c\x80\x2d\x20\x04\xd7\
+\x71\xd8\xac\xeb\x6e\xde\xfc\xdd\xba\xe8\xe6\x09\xce\x2b\x58\x00\
+\x5d\x98\x28\x19\x91\x70\x60\x40\x64\xe3\x26\x8e\x7c\xf9\x4b\xb4\
+\x1f\x7f\x1c\x4c\x80\x74\x9a\x0c\x9c\x99\x64\x28\x2f\x70\xa1\xff\
+\x91\xf2\x79\x88\x40\x12\x05\x2c\xbc\xf0\x1c\x53\x4b\x0b\x74\x7a\
+\x7b\x11\x20\xca\x2d\xa3\x33\xa7\x49\x43\xa1\x79\xfa\x04\x67\xff\
+\xf6\xaf\x29\x1e\xec\x87\x52\xfb\xdd\x2e\x10\xcd\x14\x8a\x0e\xd2\
+\x69\x22\xf3\xf3\xc4\x73\xb3\x0c\xda\x0e\x3d\x71\x0c\x45\xd7\x94\
+\x85\xf6\xec\x3c\xb3\x0f\xfd\x03\x2b\xcf\x7c\x1b\xb5\x16\x93\x2b\
+\x23\x33\x53\xf4\x2c\x37\x90\x42\x71\xca\x25\xd5\xa2\x07\x42\xa8\
+\xde\x7c\x23\xe1\xe0\x20\x65\x25\x24\xeb\xfa\xb5\xbc\x02\xf2\x3c\
+\x6f\x34\x9b\xcd\x22\xcb\x32\xc2\x38\x96\x74\xeb\x36\xbd\xea\x97\
+\x7e\x59\x2e\x7c\xee\xaf\x59\x7d\x7a\x0f\x0a\x54\x42\x88\xd2\x18\
+\x09\x23\x0a\x27\x18\xd5\x72\x61\x04\x34\x12\x82\x28\x20\xba\x30\
+\x43\x38\x79\x86\x5c\x9d\x27\x22\x82\x80\x70\xb8\x4a\x14\x85\x54\
+\x96\x2e\xd0\x3a\x3b\x8d\x5a\xbb\x56\x6e\xfb\x16\x19\xd0\xa6\x12\
+\x8a\xef\x30\xa9\x06\x21\xbd\x69\x48\xad\xc7\x87\xda\xa2\xed\x28\
+\xda\xe5\xd2\x57\xd6\x24\x98\x79\x1e\xf3\xbd\x67\xfc\xac\xb6\x15\
+\x4d\x13\x5c\x12\x43\xee\x85\x27\xf4\x5c\x86\x53\x87\x4a\x40\x65\
+\xfb\x35\x6c\xb8\xe7\x5e\xd2\x6d\x13\x8a\x73\x92\x65\x19\xcd\x66\
+\xb3\xc8\xf3\xbc\xd1\x55\x80\xce\xcc\xcc\xbc\x34\x39\x39\x79\x32\
+\x4d\xd3\x9e\x8d\x41\x10\x56\x47\x46\xd8\xf4\xde\xf7\x91\x0a\xcc\
+\xdd\x77\x1f\xed\x93\xc7\x11\x57\x78\x9a\x1c\xc5\xaa\x2f\x35\x05\
+\xf1\x09\x46\xee\x4d\xa1\x1e\x84\xf4\xf4\x44\x7e\xcd\x4f\x7d\x4d\
+\x61\xc4\x40\xa6\xf4\x07\x01\x83\x3d\x35\x24\xe8\x22\xb2\x10\x94\
+\x3d\x9e\x36\x2a\x01\xca\x74\x13\x16\xf5\xb3\x2e\x42\xd1\x2d\xd2\
+\x14\x12\x23\x6c\xae\xa4\x8c\x06\x09\xaa\x50\xc4\xd6\x27\x6d\x65\
+\x5f\xa1\xba\x6e\x06\xeb\xd0\x20\x22\xdd\x3a\xc1\xf0\xfb\x3e\x40\
+\xff\xaf\xbc\x07\xed\x1f\xa0\xd9\x6a\x32\x3b\x3b\x5b\x4c\x4e\x4e\
+\x9e\x9c\x99\x99\x79\x09\x9f\x9f\x91\x2c\x2d\x2d\x35\x92\x24\x89\
+\xa3\x28\xda\x98\x26\xc9\x50\xa5\x52\x91\xa0\x56\xd3\xca\xb6\x09\
+\x31\x81\xa1\x3d\x39\x45\xb1\xb4\x84\x2b\xac\xaf\x0f\x42\x5f\x57\
+\x28\xfe\x07\xd5\xe1\x5b\x5b\x04\x24\x12\x4c\x59\x9b\x14\x6d\x8f\
+\xc2\x9a\x79\xbe\x91\x08\x24\x36\x28\x50\xb4\x7c\x32\x53\xe4\x3e\
+\xbb\x33\x69\x49\x78\xa8\xc3\xe5\x8a\xcd\x1d\xd6\x2a\x2e\x73\xbe\
+\x49\x2a\x2a\xc1\xab\xbc\xde\x5a\x1f\x02\x25\x04\x82\x2e\xcd\xa5\
+\xd8\xc2\x41\x10\x92\x5e\xbd\x9d\x0d\xf7\xdc\x43\xff\x7b\xde\x83\
+\xeb\xeb\xd3\x4e\xa7\x23\x67\xcf\x9e\xd5\x43\x87\x0e\x1d\x79\xe6\
+\x99\x67\x1e\x7c\xec\xb1\xc7\x1e\x9b\x9d\x9d\x9d\x0f\x80\x60\x76\
+\x76\x36\x3f\x72\xe4\xc8\x5c\xa5\x52\x21\x8a\xa2\x91\x38\x8e\x07\
+\x7b\x7a\x7b\xc5\x54\x2a\x5a\x9d\xb8\x06\x11\x95\xec\xec\x34\xf9\
+\xc2\x22\x58\x77\x91\xdb\x2b\x57\x6a\x25\x10\x14\xf1\x40\xda\xf5\
+\x41\xeb\x97\xb3\x25\x64\xcd\x27\x11\x0f\x33\x2e\x2f\x41\x28\xea\
+\xc6\x64\x5d\x2b\xd5\xbb\x35\x88\x1a\x01\x51\x6c\xc1\x9a\x65\xd8\
+\xdc\xb7\xda\x69\xd9\x57\xe1\x4d\x1d\xd4\x09\xb6\xcc\x0f\x30\x01\
+\x95\x6d\x13\x0c\xbf\xff\xfd\x0c\xbe\xf7\xfd\xea\x7a\xfb\xc8\xad\
+\x95\xd3\xa7\x4e\x71\xe0\xc0\x81\x63\xdf\xfc\xe6\x37\x1f\xb8\xef\
+\xbe\xfb\x1e\x3a\x7d\xfa\xf4\x19\xa0\x15\x74\xd7\x67\x5a\xad\x56\
+\x7e\xf4\xe8\xd1\xf3\x49\x92\xb4\xe2\x38\xde\x14\xc7\xf1\x50\x5f\
+\x7f\x3f\x52\x49\xa9\xdd\x70\xa3\x18\x55\x3a\x93\xa7\xc9\xe6\x2e\
+\xac\x09\xae\x56\x3d\x6d\x66\xc0\x18\xf5\x1d\x23\xb9\x4f\x42\x5c\
+\xee\xdb\xe2\x24\x34\xe0\xb3\x68\x5c\xae\x14\x1d\x3f\x53\x12\x97\
+\x4d\x51\x52\x0a\x97\x95\x25\x73\xb9\x0e\x21\x21\x68\xd9\x03\x50\
+\x74\x1c\x45\xae\xb8\x52\x19\x84\x5d\xc1\xfd\x33\xbb\x33\xef\xd4\
+\x51\xd9\x3e\xc1\x86\x0f\x7c\x90\xc1\x0f\x7e\x08\x5b\xaf\x53\x58\
+\xcb\x89\xe3\xc7\xe5\xb9\xe7\x9e\x3b\xf2\x8d\x6f\x7c\xe3\x8b\x5f\
+\xf9\xca\x57\xbe\xb6\xb4\xb4\x34\x89\xe7\xac\x9b\xdd\x06\x09\x07\
+\xd8\x2c\xcb\xf2\x53\xa7\x4e\xcd\x85\x61\xb8\x9c\xa6\xe9\x58\x1c\
+\xc7\x43\xbd\xfd\xfd\x22\x49\xa2\x3d\x37\xbf\x1a\x51\xa4\x79\xf4\
+\x18\xf9\xfc\x05\x4c\x14\x96\x83\xd7\xb5\x19\x52\xe7\x85\x92\xd0\
+\xcf\x9e\x2b\xd4\x77\x7f\xba\x8b\x33\x29\x51\x49\x4b\x59\x20\xf4\
+\x94\x9b\xed\xf8\xf5\x3d\xc2\x12\xa8\x9d\xef\x1d\x76\x40\xd1\xb4\
+\xde\x52\x02\x59\x8b\xef\x5d\x58\x28\x0a\x8f\xf2\x2a\x8a\xed\x74\
+\x48\xc7\xaf\x66\xe4\xd7\x3f\xca\xf0\xaf\xff\xba\x16\x69\x4a\x6e\
+\xad\x74\x85\x7f\xea\xa9\xa7\xfe\xe6\x91\x47\x1e\xd9\xb9\xb2\xb2\
+\x32\x09\x2c\x02\x2d\xc0\x76\x2d\xc0\x89\x88\x05\x6c\xa7\xd3\xc9\
+\xce\x9f\x3f\xbf\x14\xc7\xf1\x6a\x9a\xa6\x9b\x2a\x69\x3a\x54\xad\
+\xd5\x24\xa8\x56\xa5\x76\xdd\x75\x1a\x55\x2a\xd2\x38\x74\x90\x6c\
+\x61\xbe\x64\x5f\x14\xe7\x04\x6b\x3d\xe5\x2c\xeb\x92\x0f\x97\x97\
+\xa0\x54\xb6\xbe\x11\x78\x41\xbd\x39\x7b\x8e\xc0\xe6\x1e\xb4\x24\
+\xf4\x1c\x84\x73\x4a\x51\x5c\xea\xeb\x5d\xc5\x38\xf5\xee\x51\xe4\
+\xba\x66\xf2\x8a\x62\xdb\x1d\xe2\xd1\x51\xc6\x7e\xf3\xb7\x19\xba\
+\xf7\x83\x6a\x6b\x35\x69\xb7\x5a\x32\x79\xe6\x0c\xcf\x3f\xff\xfc\
+\xe1\xa7\x9f\x7e\xfa\x0b\x3b\x76\xec\xd8\xbd\xb8\xb8\x78\x1a\x58\
+\x14\x91\x06\x90\xe3\xf9\x95\x8b\x15\x40\xa9\x04\xd7\x6a\xb5\x3a\
+\x33\x33\x33\x0b\x95\x4a\x25\x8b\xa2\x68\x43\x25\x4d\xfb\xd2\x38\
+\x0e\xe2\xa1\x21\xa9\x6c\xbd\x5a\xa3\x9e\x1e\x69\x1e\x3d\x4a\xbe\
+\xb0\xe0\x99\xf3\xb2\x5f\x68\xad\xde\xee\x22\xb2\x2b\xc1\xf2\x22\
+\xc3\xee\xf9\x46\xeb\xcf\xa9\x78\xcc\x70\x76\x5d\xfc\xb6\x25\x06\
+\x94\x4f\xb2\xa5\x85\x75\x85\x2f\xd7\x36\x7c\xc1\xe3\x7c\x5a\x9d\
+\x8e\x5f\xcd\x96\xdf\xfa\x1d\x06\xde\xfb\x5e\x65\x68\x48\x56\x17\
+\x17\x99\x9a\x9a\xca\x9f\x7f\xfe\xf9\x23\x7b\xf7\xee\xfd\xf2\xe3\
+\x8f\x3f\xfe\xc4\xdc\xdc\xdc\xa9\xae\xf0\xaa\x9a\x77\xd3\xb0\xe0\
+\xb2\x2c\x71\x4d\x09\x8d\x46\x23\x9b\x99\x99\xb9\x50\xa9\x54\x5c\
+\x1c\xc7\x43\x95\x4a\xa5\x2f\x0a\x82\x20\x1d\x1a\x96\xea\xf6\x6b\
+\x34\x88\x22\x69\x9d\x3e\x43\xbe\xbc\xe4\xeb\x70\xfc\xb4\xbb\x6e\
+\x58\x2a\x0f\xad\x37\x79\xe7\x74\x4d\x40\xa4\x34\x79\xf1\xdc\x83\
+\xb3\x9e\x2c\xed\x0a\x4f\xe8\xc3\xa2\x2d\x13\x1c\x57\x86\x38\xd5\
+\x12\x14\x71\x38\x0c\x95\xad\xdb\xd9\xfc\xd1\x7f\xc9\xd0\x3d\x1f\
+\x54\x06\x87\x64\xf9\xc2\x1c\x67\xcf\x9e\xcd\x0e\x1c\x38\x70\x74\
+\xdf\xbe\x7d\x0f\x3e\xf6\xd8\x63\x8f\x9e\x3f\x7f\xfe\xf4\x95\x84\
+\xbf\x92\x02\xba\x4a\x70\x7e\xb5\x79\xb5\x33\x37\x37\x37\x97\x24\
+\x89\x89\xe3\x78\x30\x4d\xd3\xbe\x24\x0c\x83\xa8\xb7\x57\x7a\x6e\
+\x7c\x95\xaa\x75\xd2\x99\x9e\x26\x5f\x5a\x42\x0b\xeb\x05\x2f\x53\
+\x4f\x5f\x72\x7a\x25\x38\x57\xe6\xfb\xee\x22\x25\xdd\x6d\x8b\x77\
+\x0e\x4f\x94\x96\xd7\xbb\x2e\x75\x8e\x77\x07\x6b\x75\xcd\x9a\xdc\
+\xc5\xe5\x6d\x34\x88\xa8\x6c\x9b\x60\xe4\xde\x0f\xb2\xf1\xc3\x1f\
+\x51\x5b\xab\xc9\xca\xc2\x02\x53\x53\x53\xd9\x0b\x2f\xbc\x70\x74\
+\xef\xde\xbd\x5f\xdb\xb1\x63\xc7\x23\xd3\xd3\xd3\xa7\x80\x05\x11\
+\x69\x5e\x2e\xfc\x2b\x29\xa0\x9b\xa5\x5b\xc0\x2e\x2f\x2f\xb7\x66\
+\x66\x66\xe6\xa2\x28\x92\x28\x8a\x86\xd2\x34\x1d\xa8\x56\xab\xc6\
+\x24\x09\xf5\x1b\x6f\x14\xa3\x8e\xf6\xe4\x14\xd9\xe2\x92\x6f\x50\
+\x30\xbe\x27\x00\x29\x73\x83\x12\xb8\x5c\xb9\xe6\xe8\x43\xa6\x9f\
+\x59\xd5\x75\x16\x51\xce\xb8\x67\x7a\xdc\xda\x71\x67\x3d\x76\x78\
+\x32\x44\xb1\xd6\xc7\xf9\xca\xc4\x04\x9b\xee\xb9\x97\x0d\xbf\xf6\
+\x6b\xd8\x34\xa5\xd5\x6c\xca\x99\x33\x67\x8a\x03\x07\x0e\x1c\xd9\
+\xb3\x67\xcf\x23\x3b\x76\xec\x78\x78\x6a\x6a\xea\x78\x09\x78\x0d\
+\xdf\xe5\xf0\xf2\xb6\x82\xef\xa7\x00\xd7\x7d\x7f\x61\x65\x65\xa5\
+\x31\x37\x37\x37\x17\x86\xa1\x0b\x82\x60\x43\x9a\xa6\xc3\x7d\x7d\
+\x7d\x62\x92\x44\xeb\xd7\x5e\x87\xc1\x48\x6b\x72\x92\xce\xc2\xfc\
+\x1a\xf3\xeb\x5c\x59\xfa\xae\x95\x18\xac\x2d\xbe\x6a\xd7\x15\xd6\
+\x7a\x11\xbc\xc7\x3b\x55\x6c\xd7\x55\xba\xee\xd4\xcd\xe9\x9d\x17\
+\x5e\x4d\x40\x75\xfb\xb5\x6c\xbe\xf7\x57\xd9\x70\xcf\x3d\xea\x6a\
+\x35\xf2\xa2\x90\x13\x27\x4e\xf0\xbd\xef\x7d\xef\xf0\xde\xbd\x7b\
+\xbf\xba\x73\xe7\xce\x47\xa6\xa7\xa7\x8f\x77\x43\x5d\x17\xf0\xae\
+\xf8\x1a\xda\x0f\x68\xa7\xef\x2a\xc1\xae\xac\xac\xb4\x2e\x5c\xb8\
+\x30\x63\x8c\xe9\xa8\xea\xc6\x30\x0c\x87\x87\x86\x86\x90\x34\xa5\
+\xb6\x7d\xbb\x04\x41\x40\x7b\x6a\x8a\xf6\xcc\x9c\x4f\x56\xba\xb4\
+\x9a\xf1\x4d\x53\x97\x08\xee\xca\xc6\xa6\xf2\xb5\x99\xae\x95\x58\
+\xab\x17\x5d\x48\x64\xcd\x0d\x9c\xfa\x64\xc9\x39\xa8\x5f\x77\x3d\
+\xa3\xbf\xfa\x21\x36\xbc\xef\x7d\x68\x6f\x2f\x85\xb5\x1c\x3c\x78\
+\x50\x9e\x7d\xf6\xd9\x43\xfb\xf6\xed\xbb\x7f\xf7\xee\xdd\x5f\x9b\
+\x9e\x9e\x3e\x09\x2c\x95\xc2\x67\xaf\x24\xfc\x0f\xa3\x80\xcb\x95\
+\xd0\x39\x7f\xfe\xfc\x9c\x31\x66\x25\x08\x82\xd1\x20\x08\x86\x07\
+\x07\x07\x25\xa8\xd5\xb4\xb6\x7d\xbb\x04\x61\x48\xeb\xc4\x71\x1a\
+\x8b\x8b\xd8\xf2\xfd\x87\xc2\x2a\x85\xf3\xbb\x75\x17\xbf\x17\xd6\
+\xef\xd6\x2a\x79\x79\x6e\xfd\xf9\xbc\x3c\x5f\xa8\x5f\x10\xb6\x40\
+\xef\xb6\xad\x6c\xf9\xc8\x47\xd9\xf0\x81\xf7\xa3\x7d\xfd\x9a\xe5\
+\xb9\xbc\xf8\xe2\x8b\xb2\x7f\xff\xfe\xc3\x7b\xf6\xec\xf9\xdb\x5d\
+\xbb\x76\x3d\xd1\x05\xbc\x32\xce\xe7\xdf\x4f\xf8\x1f\xf6\x8d\x11\
+\x05\x0a\x11\x69\xa9\x2a\x73\x73\x73\x6e\xf7\xee\xdd\x3b\xad\xb5\
+\xd6\x39\xf7\x11\xe0\xba\xeb\x6f\xb8\x41\xaa\x03\x03\x3a\xfc\x9e\
+\xf7\x30\x74\xfb\xed\xe2\x96\x97\xaf\xdc\x8f\x2f\xeb\x8f\xe8\x2b\
+\x74\xee\xeb\x25\x2f\x0d\x5d\xb2\x64\xd9\xdb\x8b\x6c\xde\xac\x32\
+\x30\x40\xab\xd9\x92\x43\x07\x0f\xf2\xec\xb3\xcf\x1e\xde\xb3\x67\
+\xcf\x67\xbf\xf1\x8d\x6f\xec\x9e\x9f\x9f\x3f\x0d\x2c\x97\x63\x2d\
+\x7e\x90\xf0\x3f\xca\x2b\x33\x4e\x55\x73\x11\xdf\x4c\x36\x3f\x3f\
+\x7f\x6a\xe7\xce\x9d\x4f\x1a\x63\x22\x11\xf9\xd5\x30\x0c\xaf\xd9\
+\xba\x6d\x9b\xe9\xdd\xb8\x91\x78\x7c\x5c\x83\x20\x90\x4b\x49\xd3\
+\xf5\x0b\x37\x3f\x68\x4c\xf2\xf2\x37\xad\x4a\xaa\xda\x5a\xab\x59\
+\xa7\x23\xcb\x8b\x8b\x9c\x3c\x71\xc2\xed\xdf\xbf\xff\xe8\xbe\x7d\
+\xfb\x3e\xbf\x73\xe7\xce\x27\x57\x57\x57\xcf\xfc\xa8\xc2\xff\xa8\
+\xaf\xce\xaa\xaa\xae\x59\xc2\xea\xea\xea\xe4\xe3\x8f\x3f\xfe\x68\
+\x10\x04\x49\x18\x86\xef\x06\xae\x19\xdb\xb2\x25\x4c\xd3\x6e\x91\
+\xaf\xfc\x54\x37\xaf\x50\x69\xb7\xdb\x4c\x9e\x39\x53\xec\xdf\xbf\
+\xff\xe8\x33\xcf\x3c\xf3\x95\xc7\x1f\x7f\xfc\xd1\x46\xa3\x31\xf5\
+\xe3\x08\xff\xe3\xbc\x3b\xac\xa5\x25\xa0\xaa\xd2\x68\x34\xd8\xb5\
+\x6b\xd7\x83\xc6\x18\x03\xbc\x73\x69\x69\x69\x6b\x4f\x4f\x4f\xa8\
+\xfa\xd3\x96\x7e\x6d\xcd\x52\x56\x56\x56\x8a\xe3\xc7\x8f\x9f\xdc\
+\xb7\x6f\xdf\x23\xbb\x76\xed\x7a\xf0\x32\xe1\xf3\x7f\x92\x77\x87\
+\xcb\x2d\x06\x52\xa0\x77\x6c\x6c\x6c\xeb\xeb\x5e\xf7\xba\x3b\xfb\
+\xfb\xfb\x5f\x15\x04\x41\xdd\x39\xa7\x3f\xe1\xb3\xaf\xa8\x7c\x63\
+\x8c\x58\x6b\x57\x17\x17\x17\x5f\xfc\xce\x77\xbe\xb3\x7b\x72\x72\
+\xf2\x24\xb0\x8c\x6f\xc7\xca\xfe\xc9\x5e\x9e\x5e\x77\x6f\x58\xf6\
+\x81\xd5\x81\x1e\xa0\x56\x2a\x26\x58\xf7\x2e\xe4\x4f\x45\xf8\x75\
+\xc9\x59\x56\x26\x36\x2b\xc0\x6a\x89\xf6\x3f\x92\xd9\xaf\xdf\xfe\
+\x1f\xba\xc9\xa0\xf1\xd3\x43\x85\x2f\x00\x00\x00\x00\x49\x45\x4e\
+\x44\xae\x42\x60\x82\
+\x00\x00\x03\x30\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
+\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\
+\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0e\x4d\x00\x00\x0e\x9c\
+\x01\xde\xf6\x9c\x57\x00\x00\x02\xd2\x49\x44\x41\x54\x38\x8d\x6d\
+\x93\x4d\x68\x5c\x55\x14\x80\xbf\x73\xdf\x9b\xe9\xc4\x21\xcc\x4c\
+\x4c\xc6\x2a\x22\xb6\xa9\x93\x44\x0c\xa3\x62\xc1\x2c\x14\x9d\xd2\
+\x12\x35\x85\x52\x5a\x11\x6c\xa5\x1b\x71\x57\xe8\xce\xc5\x74\x37\
+\x82\x2e\xa5\x4b\x05\xcb\x20\xc6\x45\xdd\x48\x4a\xf0\x27\xf1\x07\
+\x69\xa4\x86\xc2\x98\xd0\xc4\x50\x14\x1a\x4d\x9b\x57\xf3\x63\xe0\
+\xbd\xe4\xdd\xf7\xee\xbd\x2e\x06\xa7\xb1\x7a\x56\xe7\x1c\x38\x1f\
+\x87\xc3\x77\x84\x7b\x62\x69\x69\xc9\x69\xad\xef\x6d\x03\x90\xcd\
+\x66\xa9\x54\x2a\xb2\xbb\xe7\xef\x2e\x5a\xad\x96\xdb\xba\xd0\xc0\
+\x9f\xbe\x8c\x12\xc1\xcb\x08\xce\x82\xb5\x0e\xa7\x1c\x5b\xcf\x8f\
+\xd1\x6a\xb5\x5c\xb5\x5a\xed\x40\x3a\xc9\xcc\xcc\x8c\x53\xcd\x0b\
+\xdc\xf7\xed\x57\x78\x22\x74\xed\xf5\x31\xeb\x16\x44\xf0\xef\x57\
+\x6c\xdf\x4a\x30\xc6\x12\xd5\x0e\x63\x4e\x9f\x65\x64\x64\x44\x3a\
+\x80\xe9\xe9\x69\xe7\x35\x3f\xa0\x77\x76\x8a\x6c\xc6\xc3\xf7\x05\
+\x3f\xeb\xa1\x3c\x01\x0b\x56\x1c\x26\xb5\x24\x3b\x16\x9d\x1a\xd6\
+\x0e\x1e\x22\x3d\xf5\x26\xb5\x5a\x4d\x64\x62\x62\xc2\x75\x7d\xfa\
+\x11\xe5\xab\xdf\xb3\x99\x11\x36\x8d\x63\xef\x9e\x0c\x7b\xba\x3d\
+\x82\x6d\x8b\x00\xbd\x5d\x42\x12\x59\x56\xa2\x04\x8b\xa3\x94\x3a\
+\xf4\xb3\x2f\x12\xbf\x76\x06\x15\x04\x01\x3d\x3f\x7c\x83\x38\x21\
+\x1e\x3d\xc6\xd8\x42\xc0\xce\xcb\x27\x59\x13\xc7\xa1\xd9\xdf\x79\
+\xe1\xc7\xdf\x28\xbc\x7b\x91\x2b\x5b\x09\x47\x17\x02\x8e\xce\xdf\
+\x22\x7f\xfe\x3d\xf4\x77\x5f\xb3\xba\xba\x8a\x0a\xc3\x10\x25\xa0\
+\xb2\x42\xe1\xf1\xa7\xd8\xd9\xdc\xa0\xfb\x89\x2a\x6e\xbb\x7d\x9e\
+\xcf\xde\x38\xc6\xc3\x07\x9f\x23\xdf\xdf\x0f\xc0\xf8\xe9\x93\x3c\
+\xfd\xfa\x19\x36\x4a\xbd\x84\x61\xd8\x06\x58\x0b\x6b\x91\xa1\x6f\
+\xb8\x4a\xeb\xd2\x38\xbd\x83\xc3\xfc\xa9\x0c\x69\x9a\xf2\xcc\x5b\
+\xe7\xb8\x73\x63\x91\x70\xf9\x0f\xd2\x34\x25\xd7\x53\x20\x35\x06\
+\x67\xcc\x5d\x80\x01\xee\x28\x45\x71\x7f\x85\x6b\x1f\x5f\xa4\x7b\
+\x5f\x3f\xb7\xb7\x1c\x71\x1c\xb3\x7c\x6d\x96\x5c\xdf\x83\xa8\x62\
+\x81\x38\x8e\x39\xf2\xce\xfb\xfc\xd4\xfc\x90\xe2\xe6\x3a\x51\x14\
+\xe1\x87\x61\x48\x92\x18\xa2\x47\x2b\x58\xa5\x38\xde\xbc\x84\x01\
+\x72\xfb\x0f\xa0\xb5\xe6\xe7\x4f\x9a\x0c\xbe\x7a\x0a\x3f\x5f\x44\
+\x6b\xcd\xf8\x93\xfb\x18\x44\xe8\x43\xda\x1b\x44\x51\x84\x4e\x0c\
+\xde\xc0\x10\x2b\x73\x2d\xa6\xce\xbf\xcd\xed\xeb\xf3\x94\x2a\x43\
+\x68\xad\x39\xf1\xf9\x14\x37\xaf\x5e\x61\xe3\xfa\x3c\x5a\x6b\x4a\
+\x0a\xf2\x16\x92\x24\x25\x8a\x22\xa4\x5e\xaf\xbb\x07\xa6\x26\xc9\
+\x2d\x2d\xe0\x7b\x8a\x03\x39\x9f\x65\xe7\x40\x14\x4a\xb5\x45\xe9\
+\x51\x0a\x27\x8e\x20\x4a\x29\x88\xa3\xa8\x60\xee\x91\x01\x56\x6a\
+\xa3\x6d\x91\xea\xf5\xba\x2b\x7f\x39\x49\x75\xe5\x17\x24\x01\x25\
+\x42\xae\xe0\x63\x22\x07\x80\x97\x17\xe2\xbf\x0c\xd6\x39\x5c\xc6\
+\xd1\x7a\x68\x80\xd5\xc3\x2f\xd1\x68\x34\xa4\xa3\x72\xbd\x5e\x77\
+\xe5\x2f\x2e\x33\xf8\xeb\x02\x9e\x08\xa2\xa4\x6d\xa2\x03\xac\xc3\
+\xe2\x48\x8d\x63\xb1\x7f\x88\xe0\xc8\x2b\x34\x1a\x8d\xbb\x2a\xef\
+\x86\x94\x26\x27\x78\x6c\x71\x0e\x2f\xeb\xe1\x2c\xe0\x40\x7c\x30\
+\xb1\xe1\xc6\xd0\x30\xeb\xa3\x63\x9d\xe1\xff\x00\xfe\x81\x04\x41\
+\xf0\xbf\xef\x5c\x2e\x97\xff\x35\x0c\xf0\x37\x5c\xfc\x53\xd5\x3a\
+\x96\xb0\xec\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
+"
+
+qt_resource_name = b"\
+\x00\x05\
+\x00\x6f\xa6\x53\
+\x00\x69\
+\x00\x63\x00\x6f\x00\x6e\x00\x73\
+\x00\x11\
+\x0c\x49\x94\x07\
+\x00\x61\
+\x00\x64\x00\x42\x00\x6c\x00\x6f\x00\x63\x00\x6b\x00\x50\x00\x6c\x00\x75\x00\x73\x00\x36\x00\x34\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\
+\x00\x11\
+\x0c\x97\x94\x07\
+\x00\x61\
+\x00\x64\x00\x42\x00\x6c\x00\x6f\x00\x63\x00\x6b\x00\x50\x00\x6c\x00\x75\x00\x73\x00\x31\x00\x36\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\
+"
+
+qt_resource_struct = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\
+\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x00\x38\x00\x00\x00\x00\x00\x01\x00\x00\x20\x2a\
+"
+
+def qInitResources():
+    QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+    QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
--- a/eric6.e4p	Sun Mar 13 14:56:13 2016 +0100
+++ b/eric6.e4p	Sun Mar 13 20:54:42 2016 +0100
@@ -1266,9 +1266,15 @@
     <Source>ViewManager/BookmarkedFilesDialog.py</Source>
     <Source>ViewManager/ViewManager.py</Source>
     <Source>ViewManager/__init__.py</Source>
+    <Source>WebBrowser/AdBlock/AdBlockDialog.py</Source>
+    <Source>WebBrowser/AdBlock/AdBlockExceptionsDialog.py</Source>
+    <Source>WebBrowser/AdBlock/AdBlockIcon.py</Source>
     <Source>WebBrowser/AdBlock/AdBlockManager.py</Source>
     <Source>WebBrowser/AdBlock/AdBlockPage.py</Source>
+    <Source>WebBrowser/AdBlock/AdBlockRule.py</Source>
     <Source>WebBrowser/AdBlock/AdBlockSubscription.py</Source>
+    <Source>WebBrowser/AdBlock/AdBlockTreeWidget.py</Source>
+    <Source>WebBrowser/AdBlock/AdBlockUrlInterceptor.py</Source>
     <Source>WebBrowser/AdBlock/__init__.py</Source>
     <Source>WebBrowser/Bookmarks/AddBookmarkDialog.py</Source>
     <Source>WebBrowser/Bookmarks/BookmarkNode.py</Source>
@@ -1346,6 +1352,7 @@
     <Source>WebBrowser/History/__init__.py</Source>
     <Source>WebBrowser/JavaScript/ExternalJsObject.py</Source>
     <Source>WebBrowser/JavaScript/__init__.py</Source>
+    <Source>WebBrowser/Network/EricSchemeHandler.py</Source>
     <Source>WebBrowser/Network/FollowRedirectReply.py</Source>
     <Source>WebBrowser/Network/LoadRequest.py</Source>
     <Source>WebBrowser/Network/NetworkManager.py</Source>
@@ -1427,6 +1434,8 @@
     <Source>WebBrowser/ZoomManager/ZoomValuesModel.py</Source>
     <Source>WebBrowser/ZoomManager/__init__.py</Source>
     <Source>WebBrowser/__init__.py</Source>
+    <Source>WebBrowser/data/html_rc.py</Source>
+    <Source>WebBrowser/data/icons_rc.py</Source>
     <Source>WebBrowser/data/javascript_rc.py</Source>
     <Source>__init__.py</Source>
     <Source>cleanupSource.py</Source>
@@ -1827,6 +1836,8 @@
     <Form>VCS/CommandOptionsDialog.ui</Form>
     <Form>VCS/RepositoryInfoDialog.ui</Form>
     <Form>ViewManager/BookmarkedFilesDialog.ui</Form>
+    <Form>WebBrowser/AdBlock/AdBlockDialog.ui</Form>
+    <Form>WebBrowser/AdBlock/AdBlockExceptionsDialog.ui</Form>
     <Form>WebBrowser/Bookmarks/AddBookmarkDialog.ui</Form>
     <Form>WebBrowser/Bookmarks/BookmarkPropertiesDialog.ui</Form>
     <Form>WebBrowser/Bookmarks/BookmarksDialog.ui</Form>
@@ -1904,6 +1915,8 @@
     <Resource>IconEditor/cursors/cursors.qrc</Resource>
     <Resource>WebBrowser/Bookmarks/DefaultBookmarks.qrc</Resource>
     <Resource>WebBrowser/OpenSearch/DefaultSearchEngines/DefaultSearchEngines.qrc</Resource>
+    <Resource>WebBrowser/data/html.qrc</Resource>
+    <Resource>WebBrowser/data/icons.qrc</Resource>
     <Resource>WebBrowser/data/javascript.qrc</Resource>
   </Resources>
   <Interfaces/>
@@ -2026,6 +2039,9 @@
     <Other>WebBrowser/OpenSearch/DefaultSearchEngines/Wiktionary.xml</Other>
     <Other>WebBrowser/OpenSearch/DefaultSearchEngines/Yahoo.xml</Other>
     <Other>WebBrowser/OpenSearch/DefaultSearchEngines/YouTube.xml</Other>
+    <Other>WebBrowser/data/html/adblockPage.html</Other>
+    <Other>WebBrowser/data/icons/adBlockPlus16.png</Other>
+    <Other>WebBrowser/data/icons/adBlockPlus64.png</Other>
     <Other>WebBrowser/data/javascript/jquery-ui.js</Other>
     <Other>WebBrowser/data/javascript/jquery.js</Other>
     <Other>WebBrowser/data/javascript/qwebchannel.js</Other>

eric ide

mercurial