Version Notes
Visit product homepage at:
http://www.artio.net/magento-extensions/m-turbo-accelerator
Download this release
Release Info
Developer | Magento Core Team |
Extension | MTurbo |
Version | 1.1.0 |
Comparing to | |
See all releases |
Code changes from version 1.0 to 1.1.0
- app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Actions.php +8 -0
- app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Main.php +35 -2
- app/code/local/Artio/MTurbo/Block/Adminhtml/Run.php +1 -1
- app/code/local/Artio/MTurbo/Block/Data/Form/Element/SelectDownloadMethod.php +159 -0
- app/code/local/Artio/MTurbo/Helper/Checker.php +9 -6
- app/code/local/Artio/MTurbo/Helper/Data.php +27 -1
- app/code/local/Artio/MTurbo/Model/Config.php +203 -4
- app/code/local/Artio/MTurbo/Model/Config.php~ +794 -0
- app/code/local/Artio/MTurbo/Model/File.php +12 -11
- app/code/local/Artio/MTurbo/Model/File.php~ +404 -0
- app/code/local/Artio/MTurbo/Model/Mturbo.php +3 -5
- app/code/local/Artio/MTurbo/Model/Observer.php +5 -4
- app/code/local/Artio/MTurbo/Model/htaccess/htaccess.txt +2 -1
- app/code/local/Artio/MTurbo/Model/patches/mage.txt +13 -0
- app/code/local/Artio/MTurbo/Model/scripts/wgetlib.so +1 -1
- app/code/local/Artio/MTurbo/controllers/Adminhtml/MturboController.php +89 -17
- app/code/local/Artio/MTurbo/controllers/AdminhtmlController.php +3 -2
- app/code/local/Artio/MTurbo/etc/config.xml +2 -2
- app/code/local/Artio/MTurbo/etc/config.xml~ +181 -0
- app/code/local/Artio/MTurbo/sql/mturbo_setup/{mysql4-install-0.1.0.php → mysql4-install-1.0.0.php} +1 -1
- package.xml +4 -4
app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Actions.php
CHANGED
@@ -87,6 +87,14 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Actions extends Artio_MTurbo_Block_A
|
|
87 |
'comment' => $this->getMyHelper()->__('Create cache for all pages (except blocked pages). Download progress can be monitored in a separate window. Please, do not close this window. Update of URLs from the Rewrite Table will be started automatically before caching is executed. Please, note that initial cache creation may take a long time (several hours). Time needed depends on the number of pages your site has.')
|
88 |
|
89 |
));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
|
91 |
}
|
92 |
|
87 |
'comment' => $this->getMyHelper()->__('Create cache for all pages (except blocked pages). Download progress can be monitored in a separate window. Please, do not close this window. Update of URLs from the Rewrite Table will be started automatically before caching is executed. Please, note that initial cache creation may take a long time (several hours). Time needed depends on the number of pages your site has.')
|
88 |
|
89 |
));
|
90 |
+
|
91 |
+
$layoutFieldset->addField('htaccess_button', 'widget_button', array(
|
92 |
+
'name' => 'htaccess_button',
|
93 |
+
'label' => $this->getMyHelper()->__('Rebuild .htaccess'),
|
94 |
+
'onclick' => "setLocation('" . Mage::helper('adminhtml')->getUrl('*/*/htaccessbuild') . "')",
|
95 |
+
'comment' => $this->getMyHelper()->__('Rebuild .htaccess file. First remove MTurbo section and then insert it. At the same time check .htaccess file in turbocache folder'),
|
96 |
+
|
97 |
+
));
|
98 |
|
99 |
}
|
100 |
|
app/code/local/Artio/MTurbo/Block/Adminhtml/Edit/Tab/Main.php
CHANGED
@@ -44,7 +44,8 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Admi
|
|
44 |
$this->form = new Varien_Data_Form();
|
45 |
$this->_addGeneralFieldset();
|
46 |
$this->_addHomepageFieldset();
|
47 |
-
//$this->_addAutomaticDownloadFieldset();
|
|
|
48 |
|
49 |
$this->form->setValues($config->getData());
|
50 |
$this->setForm($this->form);
|
@@ -108,7 +109,7 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Admi
|
|
108 |
|
109 |
$layoutFieldset->addField('lastdownload', 'label', array(
|
110 |
'name' => 'lastdownload',
|
111 |
-
'label' => $this->getMyHelper()->__('Last
|
112 |
'style' => 'height:24em;',
|
113 |
'disabled' => true
|
114 |
));
|
@@ -135,4 +136,36 @@ class Artio_MTurbo_Block_Adminhtml_Edit_Tab_Main extends Artio_MTurbo_Block_Admi
|
|
135 |
|
136 |
}
|
137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
}
|
44 |
$this->form = new Varien_Data_Form();
|
45 |
$this->_addGeneralFieldset();
|
46 |
$this->_addHomepageFieldset();
|
47 |
+
//$this->_addAutomaticDownloadFieldset(); DEMO VERSION
|
48 |
+
$this->_addDownloadMethodFieldset();
|
49 |
|
50 |
$this->form->setValues($config->getData());
|
51 |
$this->setForm($this->form);
|
109 |
|
110 |
$layoutFieldset->addField('lastdownload', 'label', array(
|
111 |
'name' => 'lastdownload',
|
112 |
+
'label' => $this->getMyHelper()->__('Last download').':',
|
113 |
'style' => 'height:24em;',
|
114 |
'disabled' => true
|
115 |
));
|
136 |
|
137 |
}
|
138 |
|
139 |
+
private function _addDownloadMethodFieldset() {
|
140 |
+
|
141 |
+
$layoutFieldset = $this->form->addFieldset('downloadmethod_fieldset', array(
|
142 |
+
'legend' => $this->getMyHelper()->__('Choice download method'),
|
143 |
+
'class' => 'fieldset'
|
144 |
+
));
|
145 |
+
|
146 |
+
$layoutFieldset->addType('selectdmet', Artio_MTurbo_Helper_Data::FORM_SELECT_DOW);
|
147 |
+
$layoutFieldset->addField('downloadmethod', 'selectdmet', array(
|
148 |
+
'name' => 'downloadmethod',
|
149 |
+
'label' => $this->getMyHelper()->__('Download method').':',
|
150 |
+
'options' => array(
|
151 |
+
DownloadMethods::FILE_GET_CONTENTS => $this->getMyHelper()->__('Use function "file_get_contents"'),
|
152 |
+
DownloadMethods::SOCKET => $this->getMyHelper()->__('Create connection over sockets'),
|
153 |
+
DownloadMethods::CURL => $this->getMyHelper()->__('Use CURL PHP extension'),
|
154 |
+
DownloadMethods::DIRECT_ACCESS => $this->getMyHelper()->__('Direct access (created new instance Magento)'))
|
155 |
+
));
|
156 |
+
|
157 |
+
$label = Artio_MTurbo_Helper_Data::getConfig()->isPatched() ?
|
158 |
+
Mage::helper('mturbo')->__('Remove Mage Patch') :
|
159 |
+
Mage::helper('mturbo')->__('Apply Mage Patch');
|
160 |
+
|
161 |
+
$layoutFieldset->addType('widget_button', Artio_MTurbo_Helper_Data::FORM_WIDGET_BUTTON);
|
162 |
+
$layoutFieldset->addField('patch_button', 'widget_button', array(
|
163 |
+
'name' => 'patch_button',
|
164 |
+
'label' => $label,
|
165 |
+
'onclick' => "setLocation('" . Mage::helper('adminhtml')->getUrl('*/*/magepatch') . "')",
|
166 |
+
'comment' => $this->getMyHelper()->__('Apply the patch only just in case you need to use Direct Access download method!')
|
167 |
+
));
|
168 |
+
|
169 |
+
}
|
170 |
+
|
171 |
}
|
app/code/local/Artio/MTurbo/Block/Adminhtml/Run.php
CHANGED
@@ -51,7 +51,7 @@ class Artio_MTurbo_Block_Adminhtml_Run extends Mage_Adminhtml_Block_Abstract
|
|
51 |
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>';
|
52 |
echo '<script type="text/javascript">var FORM_KEY = "'.Mage::getSingleton('core/session')->getFormKey().'";</script>';
|
53 |
echo $this->_getCssJsHtml();
|
54 |
-
echo '<title>'.Mage::helper('mturbo')->__('Turbo
|
55 |
echo '</head>';
|
56 |
|
57 |
echo '<body>';
|
51 |
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>';
|
52 |
echo '<script type="text/javascript">var FORM_KEY = "'.Mage::getSingleton('core/session')->getFormKey().'";</script>';
|
53 |
echo $this->_getCssJsHtml();
|
54 |
+
echo '<title>'.Mage::helper('mturbo')->__('M-Turbo Management - Downloading pages').'</title>';
|
55 |
echo '</head>';
|
56 |
|
57 |
echo '<body>';
|
app/code/local/Artio/MTurbo/Block/Data/Form/Element/SelectDownloadMethod.php
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Magento
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@magentocommerce.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade Magento to newer
|
18 |
+
* versions in the future. If you wish to customize Magento for your
|
19 |
+
* needs please refer to http://www.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Varien
|
22 |
+
* @package Varien_Data
|
23 |
+
* @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Select element with testing download method
|
29 |
+
*
|
30 |
+
* @category Artio
|
31 |
+
* @package Artio_MTurbo
|
32 |
+
* @author Artio Magento Team <info@artio.net>
|
33 |
+
*/
|
34 |
+
class Artio_MTurbo_Block_Data_Form_Element_SelectDownloadMethod extends Varien_Data_Form_Element_Select
|
35 |
+
{
|
36 |
+
|
37 |
+
public function getElementHtml()
|
38 |
+
{
|
39 |
+
$this->addClass('select');
|
40 |
+
|
41 |
+
$html = self::getTestJS();
|
42 |
+
|
43 |
+
$html .= '<select onchange="selectMethod('."'".$this->getHtmlId()."'".')"; id="'.$this->getHtmlId().'" name="'.$this->getName().'" '.$this->serialize($this->getHtmlAttributes()).'>'."\n";
|
44 |
+
|
45 |
+
$value = $this->getValue();
|
46 |
+
if (!is_array($value)) {
|
47 |
+
$value = array($value);
|
48 |
+
}
|
49 |
+
|
50 |
+
if ($values = $this->getValues()) {
|
51 |
+
foreach ($values as $key => $option) {
|
52 |
+
if (!is_array($option)) {
|
53 |
+
$html.= $this->_optionToHtml(array(
|
54 |
+
'value' => $key,
|
55 |
+
'label' => $option),
|
56 |
+
$value
|
57 |
+
);
|
58 |
+
}
|
59 |
+
elseif (is_array($option['value'])) {
|
60 |
+
$html.='<optgroup label="'.$option['label'].'">'."\n";
|
61 |
+
foreach ($option['value'] as $groupItem) {
|
62 |
+
$html.= $this->_optionToHtml($groupItem, $value);
|
63 |
+
}
|
64 |
+
$html.='</optgroup>'."\n";
|
65 |
+
}
|
66 |
+
else {
|
67 |
+
$html.= $this->_optionToHtml($option, $value);
|
68 |
+
}
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
$html.= '</select>';
|
73 |
+
|
74 |
+
// result test label
|
75 |
+
$html.= '<div style="padding:10px 0px">';
|
76 |
+
$html.= '<span><b>'.Mage::helper('mturbo')->__('Download Test').'</b></span><br />';
|
77 |
+
$html.= '<span style="padding-left:15px" id="method'.$this->getHtmlId().'"><i>For test choose a method</i></span><br />';
|
78 |
+
$html.= '<span style="padding-left:15px" id="testconnect'.$this->getHtmlId().'"></span>';
|
79 |
+
$html.= '</div>';
|
80 |
+
|
81 |
+
$html.= $this->getOnFlyJS();
|
82 |
+
$html.= $this->getAfterElementHtml();
|
83 |
+
return $html;
|
84 |
+
}
|
85 |
+
|
86 |
+
private function getOnFlyJS()
|
87 |
+
{
|
88 |
+
$res = '<script type="text/javascript">';
|
89 |
+
$res .= ' selectMethod("'.$this->getId().'")';
|
90 |
+
$res .= '</script>';
|
91 |
+
return $res;
|
92 |
+
}
|
93 |
+
|
94 |
+
static $jsinserted = false;
|
95 |
+
|
96 |
+
private static function getTestJS()
|
97 |
+
{
|
98 |
+
|
99 |
+
static $jsinserted;
|
100 |
+
|
101 |
+
if (!$jsinserted)
|
102 |
+
{
|
103 |
+
|
104 |
+
$jsinserted = true;
|
105 |
+
$ajaxUrl = Mage::helper('adminhtml')->getUrl('*/*/testdownload');
|
106 |
+
|
107 |
+
$res = '<script type="text/javascript">var FORM_KEY = "'.Mage::getSingleton('core/session')->getFormKey().'";</script>';
|
108 |
+
|
109 |
+
$res .= '<script type="text/javascript">'."\n";
|
110 |
+
|
111 |
+
$res .= "function selectMethod(id) {
|
112 |
+
|
113 |
+
var el = document.getElementById(id);
|
114 |
+
|
115 |
+
new Ajax.Request('$ajaxUrl', {
|
116 |
+
method: 'post',
|
117 |
+
parameters: {form_key: FORM_KEY, method: el.value},
|
118 |
+
|
119 |
+
onComplete: function(transport) {
|
120 |
+
|
121 |
+
if (transport.responseText.isJSON()) {
|
122 |
+
|
123 |
+
var meth = document.getElementById('method'+id);
|
124 |
+
var sel = document.getElementById(id);
|
125 |
+
meth.innerHTML = sel.options[sel.selectedIndex].text;
|
126 |
+
|
127 |
+
var el = document.getElementById('testconnect'+id);
|
128 |
+
var response = transport.responseText.evalJSON();
|
129 |
+
if (!response.ok) {
|
130 |
+
el.style.color = 'red';
|
131 |
+
el.innerHTML = 'FAIL (' + response.resultTest + ')';
|
132 |
+
} else {
|
133 |
+
el.style.color = 'green';
|
134 |
+
el.innerHTML = 'OK (frontpage size: ' + response.resultTest + ' kB)';
|
135 |
+
}
|
136 |
+
} else {
|
137 |
+
var meth = document.getElementById('method'+id);
|
138 |
+
meth.innerHTML = '<i>Test failed</i>';
|
139 |
+
var el = document.getElementById('testconnect'+id);
|
140 |
+
el.innerHTML = '';
|
141 |
+
|
142 |
+
}
|
143 |
+
}
|
144 |
+
});
|
145 |
+
|
146 |
+
var meth = document.getElementById('method'+id);
|
147 |
+
meth.innerHTML = '<i>Testing...</i>';
|
148 |
+
var el = document.getElementById('testconnect'+id);
|
149 |
+
el.innerHTML = '';
|
150 |
+
|
151 |
+
}";
|
152 |
+
|
153 |
+
$res .= '</script>'."\n";
|
154 |
+
|
155 |
+
}
|
156 |
+
|
157 |
+
return $res;
|
158 |
+
}
|
159 |
+
}
|
app/code/local/Artio/MTurbo/Helper/Checker.php
CHANGED
@@ -52,18 +52,21 @@ class Artio_MTurbo_Helper_Checker extends Mage_Core_Helper_Abstract
|
|
52 |
*/
|
53 |
public static function checkPermission() {
|
54 |
$htaccess = Artio_MTurbo_Helper_Data::getPathToBaseHtaccess();
|
55 |
-
|
56 |
-
|
|
|
57 |
}
|
58 |
|
59 |
public static function checkPermissionLayout() {
|
60 |
-
|
61 |
-
|
|
|
62 |
}
|
63 |
|
64 |
public static function checkPermissionCode() {
|
65 |
-
|
66 |
-
|
|
|
67 |
}
|
68 |
|
69 |
public static function canWrite($perm) {
|
52 |
*/
|
53 |
public static function checkPermission() {
|
54 |
$htaccess = Artio_MTurbo_Helper_Data::getPathToBaseHtaccess();
|
55 |
+
return is_writable($htaccess);
|
56 |
+
//$permission = fileperms($htaccess);
|
57 |
+
//return self::canWrite($permission);
|
58 |
}
|
59 |
|
60 |
public static function checkPermissionLayout() {
|
61 |
+
return is_writable(Mage::getBaseDir().DS.self::UPGRADE_XML);
|
62 |
+
//$perm = fileperms(Mage::getBaseDir().DS.self::UPGRADE_XML);
|
63 |
+
//return self::canWrite($perm);
|
64 |
}
|
65 |
|
66 |
public static function checkPermissionCode() {
|
67 |
+
return is_writable(Mage::getBaseDir().DS.self::UPGRADE_CODE);
|
68 |
+
//$perm = fileperms(Mage::getBaseDir().DS.self::UPGRADE_CODE);
|
69 |
+
//return self::canWrite($perm);
|
70 |
}
|
71 |
|
72 |
public static function canWrite($perm) {
|
app/code/local/Artio/MTurbo/Helper/Data.php
CHANGED
@@ -38,6 +38,7 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
|
|
38 |
const FORM_WIDGET_BUTTON = 'Artio_MTurbo_Block_Data_Form_Element_Button';
|
39 |
const FORM_CRON_HOUR_TIME = 'Artio_MTurbo_Block_Data_Form_Element_Time';
|
40 |
const FORM_NO_ESC_LABEL = 'Artio_MTurbo_Block_Data_Form_Element_NoEscLabel';
|
|
|
41 |
|
42 |
const COOKIE_IDENTIFIER = 'artio_mturbo';
|
43 |
|
@@ -137,13 +138,22 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
|
|
137 |
}
|
138 |
|
139 |
/**
|
140 |
-
*
|
141 |
* @return string
|
142 |
*/
|
143 |
public static function getFullDownloadScriptPath() {
|
144 |
return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/scripts/getstatichtml.sh';
|
145 |
}
|
146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
/**
|
148 |
* Retrieves path to base .htaccess
|
149 |
* @return string
|
@@ -159,5 +169,21 @@ class Artio_MTurbo_Helper_Data extends Mage_Core_Helper_Abstract
|
|
159 |
public static function getFullHtaccessRootPath() {
|
160 |
return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/htaccess/htaccessroot.txt';
|
161 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
|
163 |
}
|
38 |
const FORM_WIDGET_BUTTON = 'Artio_MTurbo_Block_Data_Form_Element_Button';
|
39 |
const FORM_CRON_HOUR_TIME = 'Artio_MTurbo_Block_Data_Form_Element_Time';
|
40 |
const FORM_NO_ESC_LABEL = 'Artio_MTurbo_Block_Data_Form_Element_NoEscLabel';
|
41 |
+
const FORM_SELECT_DOW = 'Artio_MTurbo_Block_Data_Form_Element_SelectDownloadMethod';
|
42 |
|
43 |
const COOKIE_IDENTIFIER = 'artio_mturbo';
|
44 |
|
138 |
}
|
139 |
|
140 |
/**
|
141 |
+
* Retrivies path to downloader script
|
142 |
* @return string
|
143 |
*/
|
144 |
public static function getFullDownloadScriptPath() {
|
145 |
return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/scripts/getstatichtml.sh';
|
146 |
}
|
147 |
|
148 |
+
/**
|
149 |
+
* Retrivies path to remover script
|
150 |
+
*
|
151 |
+
* @return string
|
152 |
+
*/
|
153 |
+
public static function getFullRemoveScriptPath() {
|
154 |
+
return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/scripts/removehtml.sh';
|
155 |
+
}
|
156 |
+
|
157 |
/**
|
158 |
* Retrieves path to base .htaccess
|
159 |
* @return string
|
169 |
public static function getFullHtaccessRootPath() {
|
170 |
return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/htaccess/htaccessroot.txt';
|
171 |
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Retrieves path to Mage Patch
|
175 |
+
* @return string
|
176 |
+
*/
|
177 |
+
public static function getMagePatchPath() {
|
178 |
+
return Mage::getBaseDir().DS.'app/code/local/Artio/MTurbo/Model/patches/mage.txt';
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Retrieves path to file Mage.php
|
183 |
+
* @return string
|
184 |
+
*/
|
185 |
+
public static function getMagePath() {
|
186 |
+
return Mage::getBaseDir().DS.'app/Mage.php';
|
187 |
+
}
|
188 |
|
189 |
}
|
app/code/local/Artio/MTurbo/Model/Config.php
CHANGED
@@ -23,6 +23,20 @@
|
|
23 |
* @copyright Copyright (c) 2010 Artio (http://www.artio.net)
|
24 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
28 |
{
|
@@ -33,6 +47,8 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
|
33 |
const CONFIG_HTACCESS_FINDKEY = 'M-Turbo Accelleration';
|
34 |
const CONFIG_HTACCESS_FINDBASE = 'RewriteBase';
|
35 |
const CONFIG_HTACCESS_FINDENGINEON = 'RewriteEngine on';
|
|
|
|
|
36 |
|
37 |
const CONFIG_URLLIST_FILENAME = 'urllist.txt';
|
38 |
const CONFIG_URLLIST_BATCH = 50;
|
@@ -50,6 +66,8 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
|
50 |
const CONFIG_XML_PATH_DOWNLOAD_TIME = 'crontab/jobs/mturbo_mturbo/schedule/cron_expr';
|
51 |
const CONFIG_XML_PATH_LAST_DOWNLOAD = 'mturbo/lastdownload';
|
52 |
|
|
|
|
|
53 |
const CONFIG_XML_PATH_DOWNLOAD_MODEL_PATH = 'crontab/jobs/mturbo_mturbo/run/model';
|
54 |
const CONFIG_XML_PATH_DOWNLOAD_MODEL_VALUE = 'mturbo/observer::automaticDownload';
|
55 |
|
@@ -145,10 +163,148 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
|
145 |
*/
|
146 |
private $licenseid;
|
147 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
public function __construct() {
|
149 |
$this->loadAttributes();
|
150 |
}
|
151 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
/**
|
153 |
* @return string
|
154 |
*/
|
@@ -280,7 +436,6 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
|
280 |
|
281 |
}
|
282 |
|
283 |
-
|
284 |
/**
|
285 |
* @return bool
|
286 |
*/
|
@@ -382,6 +537,43 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
|
382 |
|
383 |
}
|
384 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
385 |
/**
|
386 |
* Change turbo root path.
|
387 |
*
|
@@ -389,6 +581,9 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
|
389 |
* @return bool
|
390 |
*/
|
391 |
public function changeTurboPath($newPath='') {
|
|
|
|
|
|
|
392 |
|
393 |
Mage::log('Changing turbo path: ' . $newPath );
|
394 |
$baseDir = Mage::getBaseDir();
|
@@ -425,7 +620,10 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
|
425 |
* @param string $path
|
426 |
* @return bool
|
427 |
*/
|
428 |
-
public function copyAllowAccess($path) {
|
|
|
|
|
|
|
429 |
$dest = $path.DS.'.htaccess';
|
430 |
$source = Artio_MTurbo_Helper_Data::getFullHtaccessRootPath();
|
431 |
if (file_exists($source) && file_exists($path)) {
|
@@ -473,7 +671,7 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
|
473 |
}
|
474 |
|
475 |
if (count($keys)!==2)
|
476 |
-
|
477 |
|
478 |
if (in_array($this->$keys[1], $mydata))
|
479 |
$this->$keys[1] = $object->getData('value');
|
@@ -587,7 +785,8 @@ class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
|
587 |
self::CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD => $this->automaticdownload,
|
588 |
self::CONFIG_XML_PATH_LAST_DOWNLOAD => $this->lastdownload,
|
589 |
self::CONFIG_XML_PATH_FIRSTCONFIG => $this->firstconfig,
|
590 |
-
self::CONFIG_XML_PATH_LICENSEID => $this->licenseid
|
|
|
591 |
);
|
592 |
}
|
593 |
|
23 |
* @copyright Copyright (c) 2010 Artio (http://www.artio.net)
|
24 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
*/
|
26 |
+
class DownloadMethods
|
27 |
+
{
|
28 |
+
/* downloading methods */
|
29 |
+
const FILE_GET_CONTENTS = 'filegetcontents';
|
30 |
+
const SOCKET = 'socket';
|
31 |
+
const CURL = 'curl';
|
32 |
+
const DIRECT_ACCESS = 'direct';
|
33 |
+
|
34 |
+
public static function getAllMethods()
|
35 |
+
{
|
36 |
+
return array(self::FILE_GET_CONTENTS, self::SOCKET, self::CURL, self::DIRECT_ACCESS);
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
40 |
|
41 |
class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
42 |
{
|
47 |
const CONFIG_HTACCESS_FINDKEY = 'M-Turbo Accelleration';
|
48 |
const CONFIG_HTACCESS_FINDBASE = 'RewriteBase';
|
49 |
const CONFIG_HTACCESS_FINDENGINEON = 'RewriteEngine on';
|
50 |
+
const CONFIG_HTACCESS_STARTMTURBO = "M-Turbo Accelleration";
|
51 |
+
const CONFIG_HTACCESS_ENDMTURBO = "End M-Turbo";
|
52 |
|
53 |
const CONFIG_URLLIST_FILENAME = 'urllist.txt';
|
54 |
const CONFIG_URLLIST_BATCH = 50;
|
66 |
const CONFIG_XML_PATH_DOWNLOAD_TIME = 'crontab/jobs/mturbo_mturbo/schedule/cron_expr';
|
67 |
const CONFIG_XML_PATH_LAST_DOWNLOAD = 'mturbo/lastdownload';
|
68 |
|
69 |
+
const CONFIG_XML_PATH_DOWNLOAD_METHOD = 'mturbo/downloadmethod';
|
70 |
+
|
71 |
const CONFIG_XML_PATH_DOWNLOAD_MODEL_PATH = 'crontab/jobs/mturbo_mturbo/run/model';
|
72 |
const CONFIG_XML_PATH_DOWNLOAD_MODEL_VALUE = 'mturbo/observer::automaticDownload';
|
73 |
|
163 |
*/
|
164 |
private $licenseid;
|
165 |
|
166 |
+
/**
|
167 |
+
* Download method
|
168 |
+
*
|
169 |
+
* @var string
|
170 |
+
*/
|
171 |
+
private $downloadmethod = DownloadMethods::SOCKET;
|
172 |
+
|
173 |
public function __construct() {
|
174 |
$this->loadAttributes();
|
175 |
}
|
176 |
|
177 |
+
public static function isPathCorrect($path)
|
178 |
+
{
|
179 |
+
if (preg_match('/^app[\/]{0,}(.)*/', $path)) return false;
|
180 |
+
if (preg_match('/^404[\/]{0,}(.)*/', $path)) return false;
|
181 |
+
if (preg_match('/^downloader[\/]{0,}(.)*/', $path)) return false;
|
182 |
+
if (preg_match('/^js[\/]{0,}(.)*/', $path)) return false;
|
183 |
+
if (preg_match('/^lib[\/]{0,}(.)*/', $path)) return false;
|
184 |
+
if (preg_match('/^media[\/]{0,}(.)*/', $path)) return false;
|
185 |
+
if (preg_match('/^pkginfo[\/]{0,}(.)*/', $path)) return false;
|
186 |
+
if (preg_match('/^report[\/]{0,}(.)*/', $path)) return false;
|
187 |
+
if (preg_match('/^skin[\/]{0,}(.)*/', $path)) return false;
|
188 |
+
if (preg_match('/^var\/cache[\/]{0,}(.)*/', $path)) return false;
|
189 |
+
if (preg_match('/^var\/report[\/]{0,}(.)*/', $path)) return false;
|
190 |
+
if (preg_match('/^var\/session[\/]{0,}(.)*/', $path)) return false;
|
191 |
+
return true;
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Remove Mage Patch
|
196 |
+
*/
|
197 |
+
public static function removePatch()
|
198 |
+
{
|
199 |
+
$magepath = Artio_MTurbo_Helper_Data::getMagePath();
|
200 |
+
$patchpath = Artio_MTurbo_Helper_Data::getMagePatchPath();
|
201 |
+
|
202 |
+
$magepatch = @file_get_contents($patchpath);
|
203 |
+
if ($magepatch=='')
|
204 |
+
throw new Exception(Mage::helper('mturbo')->__('Cannot read patch file').'('.$patchpath.')');
|
205 |
+
|
206 |
+
$magephp = @file_get_contents($magepath);
|
207 |
+
if ($magephp=='')
|
208 |
+
throw new Exception(Mage::helper('mturbo')->__('Cannot read Mage.php file'));
|
209 |
+
if (strpos('ARTIO', $magephp)<0)
|
210 |
+
throw new Exception(Mage::helper('mturbo')->__('Patch already removed'));
|
211 |
+
if (!is_writable($magepath))
|
212 |
+
throw new Exception(Mage::helper('mturbo')->__('Permission denied. Cannot write to Mage.php'));
|
213 |
+
|
214 |
+
$newmagephp = str_replace($magepatch, "", $magephp);
|
215 |
+
if (!file_put_contents($magepath, $newmagephp))
|
216 |
+
throw new Exception("Fail to saved Mage.php");
|
217 |
+
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Apply Mage Patch
|
222 |
+
*/
|
223 |
+
public static function applyPatch()
|
224 |
+
{
|
225 |
+
|
226 |
+
$magepath = Artio_MTurbo_Helper_Data::getMagePath();
|
227 |
+
$patchpath = Artio_MTurbo_Helper_Data::getMagePatchPath();
|
228 |
+
|
229 |
+
$magepatch = @file_get_contents($patchpath);
|
230 |
+
if ($magepatch=='')
|
231 |
+
throw new Exception(Mage::helper('mturbo')->__('Cannot read patch file').'('.$patchpath.')');
|
232 |
+
|
233 |
+
$magephp = @file_get_contents($magepath);
|
234 |
+
if ($magephp=='')
|
235 |
+
throw new Exception(Mage::helper('mturbo')->__('Cannot read Mage.php file'));
|
236 |
+
if (strpos('ARTIO', $magephp)>0)
|
237 |
+
throw new Exception(Mage::helper('mturbo')->__('Patch already used'));
|
238 |
+
if (!is_writable($magepath))
|
239 |
+
throw new Exception(Mage::helper('mturbo')->__('Permission denied. Cannot write to Mage.php'));
|
240 |
+
|
241 |
+
$newmagephp = str_replace('class Mage {', "class Mage {\n".$magepatch."\n", $magephp);
|
242 |
+
$newmagephp = str_replace("class Mage\n{", "class Mage\n{\n".$magepatch."\n", $newmagephp);
|
243 |
+
|
244 |
+
if (!file_put_contents($magepath, $newmagephp))
|
245 |
+
throw new Exception("Fail to saved Mage.php");
|
246 |
+
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Checks whether file Mage.php is patched
|
251 |
+
* @return bool
|
252 |
+
*/
|
253 |
+
public static function isPatched()
|
254 |
+
{
|
255 |
+
return method_exists('Mage', 'getStaticState') && method_exists('Mage', 'restoreState');
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Checks whether method is available.
|
260 |
+
*
|
261 |
+
* @param string $method
|
262 |
+
* @param string $errorMsg error message when fail
|
263 |
+
* @return bool
|
264 |
+
*/
|
265 |
+
public static function isMethodAvailable($method, &$resultTest)
|
266 |
+
{
|
267 |
+
if (in_array($method, DownloadMethods::getAllMethods()))
|
268 |
+
{
|
269 |
+
|
270 |
+
$fileModel = Mage::getModel('mturbo/file');
|
271 |
+
$fileModel->downloadPage(false, false, $resultTest, $method);
|
272 |
+
|
273 |
+
return is_float($resultTest);
|
274 |
+
}
|
275 |
+
else
|
276 |
+
{
|
277 |
+
$resultTest = 'Unknow method';
|
278 |
+
return false;
|
279 |
+
}
|
280 |
+
|
281 |
+
}
|
282 |
+
|
283 |
+
|
284 |
+
/**
|
285 |
+
* @return string
|
286 |
+
*/
|
287 |
+
public function getDownloadMethod() {
|
288 |
+
return $this->downloadmethod;
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* @param string $licenseid
|
293 |
+
*/
|
294 |
+
public function setDownloadMethod($method) {
|
295 |
+
|
296 |
+
if (!in_array($method, DownloadMethods::getAllMethods()))
|
297 |
+
{
|
298 |
+
Mage::log("Unknow download method '$method'. Changed to SOCKET");
|
299 |
+
$method = DownloadMethods::SOCKET;
|
300 |
+
}
|
301 |
+
else
|
302 |
+
{
|
303 |
+
$this->downloadmethod = $method;
|
304 |
+
}
|
305 |
+
|
306 |
+
}
|
307 |
+
|
308 |
/**
|
309 |
* @return string
|
310 |
*/
|
436 |
|
437 |
}
|
438 |
|
|
|
439 |
/**
|
440 |
* @return bool
|
441 |
*/
|
537 |
|
538 |
}
|
539 |
|
540 |
+
/**
|
541 |
+
* Function rebuild htacces file in web root.
|
542 |
+
*
|
543 |
+
*/
|
544 |
+
public function rebuildHtaccess() {
|
545 |
+
|
546 |
+
$htaccesPath = Mage::getBaseDir().DS.'.htaccess';
|
547 |
+
if (!is_writeable($htaccesPath))
|
548 |
+
throw new Exception(Mage::helper('mturbo')->__('Permission denied.')." ($htaccesPath)");
|
549 |
+
|
550 |
+
$content = file_get_contents($htaccesPath);
|
551 |
+
if (!$content)
|
552 |
+
throw new Exception(Mage::helper('mturbo')->__("I can't read .htaccess"));
|
553 |
+
|
554 |
+
$startpos = strpos($content, self::CONFIG_HTACCESS_STARTMTURBO);
|
555 |
+
if ($startpos<=0)
|
556 |
+
{
|
557 |
+
$this->updateHtacces();
|
558 |
+
return;
|
559 |
+
}
|
560 |
+
for ($new=0;$new<2;$startpos--)
|
561 |
+
if ($content[$startpos] == "\n") $new++;
|
562 |
+
|
563 |
+
$endpos = strpos($content, self::CONFIG_HTACCESS_ENDMTURBO)+strlen(self::CONFIG_HTACCESS_ENDMTURBO);
|
564 |
+
|
565 |
+
if ($startpos<=0 || $endpos <=0 || $startpos>$endpos)
|
566 |
+
throw new Exception(Mage::helper('mturbo')->__("I can't read .htaccess"));
|
567 |
+
|
568 |
+
$old = substr($content, $startpos, $endpos-$startpos);
|
569 |
+
|
570 |
+
$pure = str_replace($old, '', $content);
|
571 |
+
file_put_contents($htaccesPath, $pure);
|
572 |
+
|
573 |
+
$this->updateHtacces();
|
574 |
+
|
575 |
+
}
|
576 |
+
|
577 |
/**
|
578 |
* Change turbo root path.
|
579 |
*
|
581 |
* @return bool
|
582 |
*/
|
583 |
public function changeTurboPath($newPath='') {
|
584 |
+
|
585 |
+
if (!$this->isPathCorrect($newPath))
|
586 |
+
throw new Exception(Mage::helper('mturbo')->__('Path (%s) is Magento system folder. Please use other.', $newPath));
|
587 |
|
588 |
Mage::log('Changing turbo path: ' . $newPath );
|
589 |
$baseDir = Mage::getBaseDir();
|
620 |
* @param string $path
|
621 |
* @return bool
|
622 |
*/
|
623 |
+
public function copyAllowAccess($path='') {
|
624 |
+
|
625 |
+
$path = ($path=='') ? Mage::getBaseDir().DS.$this->getTurbopath() : $path;
|
626 |
+
|
627 |
$dest = $path.DS.'.htaccess';
|
628 |
$source = Artio_MTurbo_Helper_Data::getFullHtaccessRootPath();
|
629 |
if (file_exists($source) && file_exists($path)) {
|
671 |
}
|
672 |
|
673 |
if (count($keys)!==2)
|
674 |
+
continue;
|
675 |
|
676 |
if (in_array($this->$keys[1], $mydata))
|
677 |
$this->$keys[1] = $object->getData('value');
|
785 |
self::CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD => $this->automaticdownload,
|
786 |
self::CONFIG_XML_PATH_LAST_DOWNLOAD => $this->lastdownload,
|
787 |
self::CONFIG_XML_PATH_FIRSTCONFIG => $this->firstconfig,
|
788 |
+
self::CONFIG_XML_PATH_LICENSEID => $this->licenseid,
|
789 |
+
self::CONFIG_XML_PATH_DOWNLOAD_METHOD => $this->downloadmethod
|
790 |
);
|
791 |
}
|
792 |
|
app/code/local/Artio/MTurbo/Model/Config.php~
ADDED
@@ -0,0 +1,794 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Magento
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@magentocommerce.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade Magento to newer
|
18 |
+
* versions in the future. If you wish to customize Magento for your
|
19 |
+
* needs please refer to http://www.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Artio
|
22 |
+
* @package Artio_MTurbo
|
23 |
+
* @copyright Copyright (c) 2010 Artio (http://www.artio.net)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
class DownloadMethods
|
27 |
+
{
|
28 |
+
/* downloading methods */
|
29 |
+
const FILE_GET_CONTENTS = 'filegetcontents';
|
30 |
+
const SOCKET = 'socket';
|
31 |
+
const CURL = 'curl';
|
32 |
+
const DIRECT_ACCESS = 'direct';
|
33 |
+
|
34 |
+
public static function getAllMethods()
|
35 |
+
{
|
36 |
+
return array(self::FILE_GET_CONTENTS, self::SOCKET, self::CURL, self::DIRECT_ACCESS);
|
37 |
+
}
|
38 |
+
|
39 |
+
}
|
40 |
+
|
41 |
+
class Artio_MTurbo_Model_Config extends Mage_Eav_Model_Config
|
42 |
+
{
|
43 |
+
|
44 |
+
const CONFIG_PATH_TO_MTURBO_HTACCESS = 'htaccess/htaccess.txt';
|
45 |
+
const CONFIG_PATH_TO_MTURBO_DOWNLOAD = 'scripts/getstatichtml.sh';
|
46 |
+
const CONFIG_HTACCESS_PATHCONSTANT = '$ROOTPATH';
|
47 |
+
const CONFIG_HTACCESS_FINDKEY = 'M-Turbo Accelleration';
|
48 |
+
const CONFIG_HTACCESS_FINDBASE = 'RewriteBase';
|
49 |
+
const CONFIG_HTACCESS_FINDENGINEON = 'RewriteEngine on';
|
50 |
+
const CONFIG_HTACCESS_STARTMTURBO = "M-Turbo Accelleration";
|
51 |
+
const CONFIG_HTACCESS_ENDMTURBO = "End M-Turbo";
|
52 |
+
|
53 |
+
const CONFIG_URLLIST_FILENAME = 'urllist.txt';
|
54 |
+
const CONFIG_URLLIST_BATCH = 50;
|
55 |
+
|
56 |
+
const CONFIG_XML_PATH_PREVIEW_CATEGORIES = 'mturbo/previewcats';
|
57 |
+
const CONFIG_XML_PATH_PRODUCT_CATEGORIES = 'mturbo/productcats';
|
58 |
+
const CONFIG_XML_PATH_INCLUDED_HOMEPAGE = 'mturbo/homepage';
|
59 |
+
const CONFIG_XML_PATH_TURBOPATH = 'mturbo/turbopath';
|
60 |
+
const CONFIG_XML_PATH_MULTISTOREVIEW = 'mturbo/multistoreview';
|
61 |
+
const CONFIG_XML_PATH_REFRESH_AFTER_SAVE = 'mturbo/refreshsave';
|
62 |
+
const CONFIG_XML_PATH_SYNCHRONIZE = 'mturbo/synchronize';
|
63 |
+
const CONFIG_XML_PATH_FIRSTCONFIG = 'mturbo/firstconfig';
|
64 |
+
|
65 |
+
const CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD = 'mturbo/automaticdownload';
|
66 |
+
const CONFIG_XML_PATH_DOWNLOAD_TIME = 'crontab/jobs/mturbo_mturbo/schedule/cron_expr';
|
67 |
+
const CONFIG_XML_PATH_LAST_DOWNLOAD = 'mturbo/lastdownload';
|
68 |
+
|
69 |
+
const CONFIG_XML_PATH_DOWNLOAD_METHOD = 'mturbo/downloadmethod';
|
70 |
+
|
71 |
+
const CONFIG_XML_PATH_DOWNLOAD_MODEL_PATH = 'crontab/jobs/mturbo_mturbo/run/model';
|
72 |
+
const CONFIG_XML_PATH_DOWNLOAD_MODEL_VALUE = 'mturbo/observer::automaticDownload';
|
73 |
+
|
74 |
+
const CONFIG_XML_PATH_LICENSEID = 'mturbo/licenseid';
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Ids categories with caching preview
|
78 |
+
*
|
79 |
+
* @var string
|
80 |
+
*/
|
81 |
+
private $previewcats;
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Ids categories with caching product pages
|
85 |
+
*
|
86 |
+
* @var string
|
87 |
+
*/
|
88 |
+
private $productcats;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* path => config_id
|
92 |
+
* @var array
|
93 |
+
*/
|
94 |
+
private $pathids = array();
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Has Cache homepage?
|
98 |
+
*
|
99 |
+
* @var bool
|
100 |
+
*/
|
101 |
+
private $homepage;
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Cache Path.
|
105 |
+
*
|
106 |
+
* @var string
|
107 |
+
*/
|
108 |
+
private $turbopath;
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Multistoreview mod
|
112 |
+
*
|
113 |
+
* @var bool
|
114 |
+
*/
|
115 |
+
private $multistoreview;
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Indicate whether url is synchronized.
|
119 |
+
*
|
120 |
+
* @var bool
|
121 |
+
*/
|
122 |
+
private $synchronize;
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Refresh on saved
|
126 |
+
*
|
127 |
+
* @var bool
|
128 |
+
*/
|
129 |
+
private $refreshsave;
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Enabled automatic download in the night.
|
133 |
+
*
|
134 |
+
* @var bool
|
135 |
+
*/
|
136 |
+
private $automaticdownload;
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Download time.
|
140 |
+
*
|
141 |
+
* @var time
|
142 |
+
*/
|
143 |
+
private $downloadtime;
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Last download.
|
147 |
+
*
|
148 |
+
* @var time
|
149 |
+
*/
|
150 |
+
private $lastdownload;
|
151 |
+
|
152 |
+
/**
|
153 |
+
* First configuration indicator
|
154 |
+
*
|
155 |
+
* @var bool
|
156 |
+
*/
|
157 |
+
private $firstconfig;
|
158 |
+
|
159 |
+
/**
|
160 |
+
* License id
|
161 |
+
*
|
162 |
+
* @var string
|
163 |
+
*/
|
164 |
+
private $licenseid;
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Download method
|
168 |
+
*
|
169 |
+
* @var string
|
170 |
+
*/
|
171 |
+
private $downloadmethod = DownloadMethods::SOCKET;
|
172 |
+
|
173 |
+
public function __construct() {
|
174 |
+
$this->loadAttributes();
|
175 |
+
}
|
176 |
+
|
177 |
+
public static function isPathCorrect($path)
|
178 |
+
{
|
179 |
+
if (preg_match('/^app[\/]{0,}(.)*/', $path)) return false;
|
180 |
+
if (preg_match('/^404[\/]{0,}(.)*/', $path)) return false;
|
181 |
+
if (preg_match('/^downloader[\/]{0,}(.)*/', $path)) return false;
|
182 |
+
if (preg_match('/^js[\/]{0,}(.)*/', $path)) return false;
|
183 |
+
if (preg_match('/^lib[\/]{0,}(.)*/', $path)) return false;
|
184 |
+
if (preg_match('/^media[\/]{0,}(.)*/', $path)) return false;
|
185 |
+
if (preg_match('/^pkginfo[\/]{0,}(.)*/', $path)) return false;
|
186 |
+
if (preg_match('/^report[\/]{0,}(.)*/', $path)) return false;
|
187 |
+
if (preg_match('/^skin[\/]{0,}(.)*/', $path)) return false;
|
188 |
+
if (preg_match('/^var\/cache[\/]{0,}(.)*/', $path)) return false;
|
189 |
+
if (preg_match('/^var\/report[\/]{0,}(.)*/', $path)) return false;
|
190 |
+
if (preg_match('/^var\/session[\/]{0,}(.)*/', $path)) return false;
|
191 |
+
return true;
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Remove Mage Patch
|
196 |
+
*/
|
197 |
+
public static function removePatch()
|
198 |
+
{
|
199 |
+
$magepath = Artio_MTurbo_Helper_Data::getMagePath();
|
200 |
+
$patchpath = Artio_MTurbo_Helper_Data::getMagePatchPath();
|
201 |
+
|
202 |
+
$magepatch = @file_get_contents($patchpath);
|
203 |
+
if ($magepatch=='')
|
204 |
+
throw new Exception(Mage::helper('mturbo')->__('Cannot read patch file').'('.$patchpath.')');
|
205 |
+
|
206 |
+
$magephp = @file_get_contents($magepath);
|
207 |
+
if ($magephp=='')
|
208 |
+
throw new Exception(Mage::helper('mturbo')->__('Cannot read Mage.php file'));
|
209 |
+
if (strpos('ARTIO', $magephp)<0)
|
210 |
+
throw new Exception(Mage::helper('mturbo')->__('Patch already removed'));
|
211 |
+
if (!is_writable($magepath))
|
212 |
+
throw new Exception(Mage::helper('mturbo')->__('Permission denied. Cannot write to Mage.php'));
|
213 |
+
|
214 |
+
$newmagephp = str_replace($magepatch, "", $magephp);
|
215 |
+
if (!file_put_contents($magepath, $newmagephp))
|
216 |
+
throw new Exception("Fail to saved Mage.php");
|
217 |
+
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Apply Mage Patch
|
222 |
+
*/
|
223 |
+
public static function applyPatch()
|
224 |
+
{
|
225 |
+
|
226 |
+
$magepath = Artio_MTurbo_Helper_Data::getMagePath();
|
227 |
+
$patchpath = Artio_MTurbo_Helper_Data::getMagePatchPath();
|
228 |
+
|
229 |
+
$magepatch = @file_get_contents($patchpath);
|
230 |
+
if ($magepatch=='')
|
231 |
+
throw new Exception(Mage::helper('mturbo')->__('Cannot read patch file').'('.$patchpath.')');
|
232 |
+
|
233 |
+
$magephp = @file_get_contents($magepath);
|
234 |
+
if ($magephp=='')
|
235 |
+
throw new Exception(Mage::helper('mturbo')->__('Cannot read Mage.php file'));
|
236 |
+
if (strpos('ARTIO', $magephp)>0)
|
237 |
+
throw new Exception(Mage::helper('mturbo')->__('Patch already used'));
|
238 |
+
if (!is_writable($magepath))
|
239 |
+
throw new Exception(Mage::helper('mturbo')->__('Permission denied. Cannot write to Mage.php'));
|
240 |
+
|
241 |
+
$newmagephp = str_replace('class Mage {', "class Mage {\n".$magepatch."\n", $magephp);
|
242 |
+
$newmagephp = str_replace("class Mage\n{", "class Mage\n{\n".$magepatch."\n", $newmagephp);
|
243 |
+
|
244 |
+
if (!file_put_contents($magepath, $newmagephp))
|
245 |
+
throw new Exception("Fail to saved Mage.php");
|
246 |
+
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Checks whether file Mage.php is patched
|
251 |
+
* @return bool
|
252 |
+
*/
|
253 |
+
public static function isPatched()
|
254 |
+
{
|
255 |
+
return method_exists('Mage', 'getStaticState') && method_exists('Mage', 'restoreState');
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Checks whether method is available.
|
260 |
+
*
|
261 |
+
* @param string $method
|
262 |
+
* @param string $errorMsg error message when fail
|
263 |
+
* @return bool
|
264 |
+
*/
|
265 |
+
public static function isMethodAvailable($method, &$resultTest)
|
266 |
+
{
|
267 |
+
if (in_array($method, DownloadMethods::getAllMethods()))
|
268 |
+
{
|
269 |
+
|
270 |
+
$fileModel = Mage::getModel('mturbo/file');
|
271 |
+
$fileModel->downloadPage(false, false, $resultTest, $method);
|
272 |
+
|
273 |
+
return is_float($resultTest);
|
274 |
+
}
|
275 |
+
else
|
276 |
+
{
|
277 |
+
$resultTest = 'Unknow method';
|
278 |
+
return false;
|
279 |
+
}
|
280 |
+
|
281 |
+
}
|
282 |
+
|
283 |
+
|
284 |
+
/**
|
285 |
+
* @return string
|
286 |
+
*/
|
287 |
+
public function getDownloadMethod() {
|
288 |
+
return $this->downloadmethod;
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* @param string $licenseid
|
293 |
+
*/
|
294 |
+
public function setDownloadMethod($method) {
|
295 |
+
|
296 |
+
if (!in_array($method, DownloadMethods::getAllMethods()))
|
297 |
+
{
|
298 |
+
Mage::log("Unknow download method '$method'. Changed to SOCKET");
|
299 |
+
$method = DownloadMethods::SOCKET;
|
300 |
+
}
|
301 |
+
else
|
302 |
+
{
|
303 |
+
$this->downloadmethod = $method;
|
304 |
+
}
|
305 |
+
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* @return string
|
310 |
+
*/
|
311 |
+
public function getLicenseId() {
|
312 |
+
return $this->licenseid;
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* @param string $licenseid
|
317 |
+
*/
|
318 |
+
public function setLicenseId($licenseid) {
|
319 |
+
$this->licenseid = $licenseid;
|
320 |
+
}
|
321 |
+
|
322 |
+
|
323 |
+
/**
|
324 |
+
* @return bool
|
325 |
+
*/
|
326 |
+
public function isFirstConfig() {
|
327 |
+
return $this->firstconfig;
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* @return time
|
332 |
+
*/
|
333 |
+
public function getDownloadtime() {
|
334 |
+
return $this->downloadtime;
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* @return time
|
339 |
+
*/
|
340 |
+
public function getLastdownload() {
|
341 |
+
return $this->lastdownload;
|
342 |
+
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* @param time $downloadtime
|
346 |
+
*/
|
347 |
+
public function setDownloadtime($downloadtime) {
|
348 |
+
$this->downloadtime = $downloadtime;
|
349 |
+
}
|
350 |
+
|
351 |
+
/**
|
352 |
+
* @param time $lastdownload
|
353 |
+
*/
|
354 |
+
public function setLastdownload($lastdownload) {
|
355 |
+
$this->lastdownload = $lastdownload;
|
356 |
+
}
|
357 |
+
|
358 |
+
|
359 |
+
/**
|
360 |
+
* @return bool
|
361 |
+
*/
|
362 |
+
public function isEnableAutomaticDownload() {
|
363 |
+
return $this->automaticdownload;
|
364 |
+
}
|
365 |
+
|
366 |
+
/**
|
367 |
+
* @param bool $automaticdownload
|
368 |
+
*/
|
369 |
+
public function setAutomaticDownload($automaticdownload) {
|
370 |
+
$this->automaticdownload = $automaticdownload;
|
371 |
+
}
|
372 |
+
|
373 |
+
|
374 |
+
public function isSynchronize() {
|
375 |
+
return $this->synchronize;
|
376 |
+
}
|
377 |
+
|
378 |
+
public function setSynchronize($state) {
|
379 |
+
$this->synchornize = $state;
|
380 |
+
}
|
381 |
+
|
382 |
+
/**
|
383 |
+
* @return bool
|
384 |
+
*/
|
385 |
+
public function refreshAfterSave() {
|
386 |
+
return $this->refreshsave;
|
387 |
+
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
* @param bool $refreshsave
|
391 |
+
*/
|
392 |
+
public function setRefreshAfterSave($refreshsave) {
|
393 |
+
$this->refreshsave = $refreshsave;
|
394 |
+
}
|
395 |
+
|
396 |
+
|
397 |
+
/**
|
398 |
+
* @return bool
|
399 |
+
*/
|
400 |
+
public function getMultistoreview() {
|
401 |
+
return $this->multistoreview;
|
402 |
+
}
|
403 |
+
|
404 |
+
/**
|
405 |
+
* @param bool $multistoreview
|
406 |
+
*/
|
407 |
+
public function setMultistoreview($multistoreview) {
|
408 |
+
$this->multistoreview = $multistoreview;
|
409 |
+
}
|
410 |
+
|
411 |
+
|
412 |
+
/**
|
413 |
+
* @return string
|
414 |
+
*/
|
415 |
+
public function getTurbopath() {
|
416 |
+
return $this->turbopath;
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
* @param string $turbopath
|
421 |
+
*/
|
422 |
+
public function setTurbopath($turbopath) {
|
423 |
+
$this->turbopath = $turbopath;
|
424 |
+
}
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Retrivese root path to directory with static pages.
|
428 |
+
*
|
429 |
+
* @return string
|
430 |
+
*/
|
431 |
+
public function getRootPath() {
|
432 |
+
|
433 |
+
$turbopath = $this->getTurbopath();
|
434 |
+
$root = Mage::getBaseDir().DS.$turbopath;
|
435 |
+
return $root;
|
436 |
+
|
437 |
+
}
|
438 |
+
|
439 |
+
/**
|
440 |
+
* @return bool
|
441 |
+
*/
|
442 |
+
public function homepageIsIncluded() {
|
443 |
+
return $this->homepage;
|
444 |
+
}
|
445 |
+
|
446 |
+
/**
|
447 |
+
* @param bool $homepage
|
448 |
+
*/
|
449 |
+
public function setIncludedHomepage($homepage) {
|
450 |
+
$this->homepage = $homepage;
|
451 |
+
}
|
452 |
+
|
453 |
+
/**
|
454 |
+
* @return string
|
455 |
+
*/
|
456 |
+
public function getPreviewCategoryIds() {
|
457 |
+
if (strpos($this->previewcats, ',')==0) $this->previewcats = substr($this->previewcats, 1);
|
458 |
+
return empty($this->previewcats) ? array() : explode(',', $this->previewcats);
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* @return string
|
463 |
+
*/
|
464 |
+
public function getProductCategoryIds() {
|
465 |
+
if (strpos($this->productcats, ',')==0) $this->productcats = substr($this->productcats, 1);
|
466 |
+
return empty($this->productcats) ? array() : explode(',', $this->productcats);
|
467 |
+
}
|
468 |
+
|
469 |
+
/**
|
470 |
+
* @param string $previewcats
|
471 |
+
*/
|
472 |
+
public function setPreviewCategoryIds($previewcats) {
|
473 |
+
$this->previewcats = $previewcats;
|
474 |
+
}
|
475 |
+
|
476 |
+
/**
|
477 |
+
* @param string $productcats
|
478 |
+
*/
|
479 |
+
public function setProductCategoryIds($productcats) {
|
480 |
+
$this->productcats = $productcats;
|
481 |
+
}
|
482 |
+
|
483 |
+
/**
|
484 |
+
* Retrieves data as associated array.
|
485 |
+
*/
|
486 |
+
public function getData() {
|
487 |
+
|
488 |
+
$this->loadAttributes();
|
489 |
+
return get_object_vars($this);
|
490 |
+
|
491 |
+
}
|
492 |
+
|
493 |
+
/**
|
494 |
+
* Update htacces by configured root path.
|
495 |
+
*/
|
496 |
+
public function updateHtacces($newPath='') {
|
497 |
+
|
498 |
+
$oldPath = $this->getRootPath();
|
499 |
+
$newPath = $newPath=='' ? $oldPath : Mage::getBaseDir().DS.$newPath;
|
500 |
+
|
501 |
+
$htaccesPath = Mage::getBaseDir().DS.'.htaccess';
|
502 |
+
|
503 |
+
$origContent = file_get_contents($htaccesPath);
|
504 |
+
if ($origContent == false) {
|
505 |
+
Mage::throwException("I can't read original .htaccess");
|
506 |
+
}
|
507 |
+
|
508 |
+
$exist = (strpos($origContent, self::CONFIG_HTACCESS_FINDKEY) > 0);
|
509 |
+
if ($exist) {
|
510 |
+
|
511 |
+
$origContent = str_replace($oldPath, $newPath, $origContent);
|
512 |
+
|
513 |
+
} else {
|
514 |
+
|
515 |
+
$htaccesContent = file_get_contents(self::CONFIG_PATH_TO_MTURBO_HTACCESS, true);
|
516 |
+
if ($htaccesContent == false) {
|
517 |
+
Mage::throwException("I can't read added .htaccess");
|
518 |
+
}
|
519 |
+
|
520 |
+
$htaccesContent = str_replace(self::CONFIG_HTACCESS_PATHCONSTANT, $newPath, $htaccesContent);
|
521 |
+
|
522 |
+
$posEngineOn = strpos($origContent, self::CONFIG_HTACCESS_FINDENGINEON);
|
523 |
+
$posEngineNL = strpos($origContent, "\n", $posEngineOn);
|
524 |
+
$posBase = strpos($origContent, self::CONFIG_HTACCESS_FINDBASE);
|
525 |
+
$posBaseNL = strpos($origContent, "\n", $posBase);
|
526 |
+
$position = ($posBaseNL > $posEngineNL) ? $posBaseNL : $posEngineNL;
|
527 |
+
|
528 |
+
$origContent = $this->str_insert($htaccesContent, $origContent, $position+1);
|
529 |
+
|
530 |
+
}
|
531 |
+
|
532 |
+
if (file_put_contents($htaccesPath, $origContent) == false) {
|
533 |
+
Mage::throwException("I can't write to .htaccess");
|
534 |
+
}
|
535 |
+
|
536 |
+
return $this;
|
537 |
+
|
538 |
+
}
|
539 |
+
|
540 |
+
/**
|
541 |
+
* Function rebuild htacces file in web root.
|
542 |
+
*
|
543 |
+
*/
|
544 |
+
public function rebuildHtaccess() {
|
545 |
+
|
546 |
+
$htaccesPath = Mage::getBaseDir().DS.'.htaccess';
|
547 |
+
if (!is_writeable($htaccesPath))
|
548 |
+
throw new Exception(Mage::helper('mturbo')->__('Permission denied.')." ($htaccesPath)");
|
549 |
+
|
550 |
+
$content = file_get_contents($htaccesPath);
|
551 |
+
if (!$content)
|
552 |
+
throw new Exception(Mage::helper('mturbo')->__("I can't read .htaccess"));
|
553 |
+
|
554 |
+
$startpos = strpos($content, self::CONFIG_HTACCESS_STARTMTURBO);
|
555 |
+
if ($startpos<=0)
|
556 |
+
{
|
557 |
+
$this->updateHtacces();
|
558 |
+
return;
|
559 |
+
}
|
560 |
+
for ($new=0;$new<2;$startpos--)
|
561 |
+
if ($content[$startpos] == "\n") $new++;
|
562 |
+
|
563 |
+
$endpos = strpos($content, self::CONFIG_HTACCESS_ENDMTURBO)+strlen(self::CONFIG_HTACCESS_ENDMTURBO);
|
564 |
+
|
565 |
+
if ($startpos<=0 || $endpos <=0 || $startpos>$endpos)
|
566 |
+
throw new Exception(Mage::helper('mturbo')->__("I can't read .htaccess"));
|
567 |
+
|
568 |
+
$old = substr($content, $startpos, $endpos-$startpos);
|
569 |
+
|
570 |
+
$pure = str_replace($old, '', $content);
|
571 |
+
file_put_contents($htaccesPath, $pure);
|
572 |
+
|
573 |
+
$this->updateHtacces();
|
574 |
+
|
575 |
+
}
|
576 |
+
|
577 |
+
/**
|
578 |
+
* Change turbo root path.
|
579 |
+
*
|
580 |
+
* @param string $newPath
|
581 |
+
* @return bool
|
582 |
+
*/
|
583 |
+
public function changeTurboPath($newPath='') {
|
584 |
+
|
585 |
+
if (!$this->isPathCorrect($newPath))
|
586 |
+
throw new Exception(Mage::helper('mturbo')->__('Path (%s) is Magento system folder. Please use other.', $newPath));
|
587 |
+
|
588 |
+
Mage::log('Changing turbo path: ' . $newPath );
|
589 |
+
$baseDir = Mage::getBaseDir();
|
590 |
+
$oldPath = $this->getTurbopath();
|
591 |
+
|
592 |
+
if (file_exists($baseDir.DS.$newPath))
|
593 |
+
return true;
|
594 |
+
|
595 |
+
if (file_exists($baseDir.DS.$oldPath) && (!$this->isFirstConfig())) {
|
596 |
+
|
597 |
+
$command = 'mv ' . $this->getRootPath() . ' ' . $baseDir.DS.$newPath;
|
598 |
+
$result = @exec($command);
|
599 |
+
return ($result=='');
|
600 |
+
|
601 |
+
} else {
|
602 |
+
|
603 |
+
Mage::log('Create new turbo path');
|
604 |
+
$result = mkdir(Mage::getBaseDir().DS.$newPath);
|
605 |
+
if (!$result) {
|
606 |
+
Mage::log('Creating turbo path: ' . Mage::getBaseDir().DS.$newPath. ' fail');
|
607 |
+
}
|
608 |
+
$result2 = $this->copyAllowAccess(Mage::getBaseDir().DS.$newPath);
|
609 |
+
if (!$result2) {
|
610 |
+
Mage::log('Copy .htaccess: ' . Mage::getBaseDir().DS.$newPath. ' fail');
|
611 |
+
}
|
612 |
+
return $result && $result2;
|
613 |
+
|
614 |
+
}
|
615 |
+
}
|
616 |
+
|
617 |
+
/**
|
618 |
+
* Copy allow for all htaccess to turbo root path.
|
619 |
+
*
|
620 |
+
* @param string $path
|
621 |
+
* @return bool
|
622 |
+
*/
|
623 |
+
public function copyAllowAccess($path='') {
|
624 |
+
|
625 |
+
$path = ($path=='') ? Mage::getBaseDir().DS.$this->getTurbopath() : $path;
|
626 |
+
|
627 |
+
$dest = $path.DS.'.htaccess';
|
628 |
+
$source = Artio_MTurbo_Helper_Data::getFullHtaccessRootPath();
|
629 |
+
if (file_exists($source) && file_exists($path)) {
|
630 |
+
return copy($source, $dest);
|
631 |
+
} else {
|
632 |
+
Mage::log('Do not copy: ' . $source . ' >> ' . $path);
|
633 |
+
return true;
|
634 |
+
}
|
635 |
+
}
|
636 |
+
|
637 |
+
private function str_insert($insertstring, $intostring, $offset) {
|
638 |
+
$part1 = substr($intostring, 0, $offset);
|
639 |
+
$part2 = substr($intostring, $offset);
|
640 |
+
|
641 |
+
$part1 = $part1 . $insertstring;
|
642 |
+
$whole = $part1 . $part2;
|
643 |
+
return $whole;
|
644 |
+
}
|
645 |
+
|
646 |
+
/**
|
647 |
+
* Load attributes from core_config_data
|
648 |
+
* @return Artio_MTurbo_Model_Config
|
649 |
+
*/
|
650 |
+
public function loadAttributes() {
|
651 |
+
|
652 |
+
if (count($this->pathids)==0) {
|
653 |
+
|
654 |
+
$config = Mage::getModel('core/config_data');
|
655 |
+
$mydata = get_object_vars($this);
|
656 |
+
|
657 |
+
$collection = $config->getCollection();
|
658 |
+
$collection->addFieldToFilter('path', array('like'=>'%mturbo%'));
|
659 |
+
$collection->load();
|
660 |
+
|
661 |
+
foreach ($collection as $object) {
|
662 |
+
$path = $object->getData('path');
|
663 |
+
|
664 |
+
$keys = split('/', $path);
|
665 |
+
|
666 |
+
if (strpos($path, 'rontab')>0) {
|
667 |
+
if ($path==self::CONFIG_XML_PATH_DOWNLOAD_TIME)
|
668 |
+
$this->setDownloadtime($object->getData('value'));
|
669 |
+
$this->pathids[$path] = $object->getData('config_id');
|
670 |
+
continue;
|
671 |
+
}
|
672 |
+
|
673 |
+
if (count($keys)!==2)
|
674 |
+
Mage::throwException('Bad key for configuration MTurbo. Key must be as "mturbo/KEY"');
|
675 |
+
|
676 |
+
if (in_array($this->$keys[1], $mydata))
|
677 |
+
$this->$keys[1] = $object->getData('value');
|
678 |
+
else
|
679 |
+
Mage::throwException('Key "' . $keys[1] . '" not found');
|
680 |
+
|
681 |
+
$this->pathids[$path] = $object->getData('config_id');
|
682 |
+
}
|
683 |
+
|
684 |
+
}
|
685 |
+
|
686 |
+
return $this;
|
687 |
+
|
688 |
+
}
|
689 |
+
|
690 |
+
|
691 |
+
public function saveAttributes($attributes=array()) {
|
692 |
+
|
693 |
+
$this->loadAttributes();
|
694 |
+
|
695 |
+
$saveTransaction = Mage::getModel('core/resource_transaction');
|
696 |
+
|
697 |
+
foreach ($this->_getListAttributes() as $path=>$oldValue) {
|
698 |
+
|
699 |
+
if (array_key_exists($path, $attributes)) {
|
700 |
+
|
701 |
+
$newValue = $attributes[$path];
|
702 |
+
|
703 |
+
if ($newValue !== $oldValue) {
|
704 |
+
|
705 |
+
$dataObject = Mage::getModel('core/config_data');
|
706 |
+
$dataObject->setPath($path);
|
707 |
+
$dataObject->setValue($newValue);
|
708 |
+
|
709 |
+
if (array_key_exists($path, $this->pathids)) {
|
710 |
+
$dataObject->setId( $this->pathids[$path] );
|
711 |
+
}
|
712 |
+
|
713 |
+
$saveTransaction->addObject($dataObject);
|
714 |
+
|
715 |
+
}
|
716 |
+
|
717 |
+
}
|
718 |
+
|
719 |
+
}
|
720 |
+
|
721 |
+
|
722 |
+
/** save crontab expression */
|
723 |
+
if (array_key_exists(self::CONFIG_XML_PATH_DOWNLOAD_TIME, $attributes)) {
|
724 |
+
$this->_saveExtraAttribute(
|
725 |
+
self::CONFIG_XML_PATH_DOWNLOAD_TIME,
|
726 |
+
$this->_formatDownloadTimeToCron($attributes[self::CONFIG_XML_PATH_DOWNLOAD_TIME]),
|
727 |
+
$saveTransaction);
|
728 |
+
}
|
729 |
+
$this->_saveExtraAttribute( self::CONFIG_XML_PATH_DOWNLOAD_MODEL_PATH,
|
730 |
+
self::CONFIG_XML_PATH_DOWNLOAD_MODEL_VALUE,
|
731 |
+
$saveTransaction);
|
732 |
+
|
733 |
+
|
734 |
+
if ($this->_isNewTurboPath($attributes)) {
|
735 |
+
$newPath = $attributes[self::CONFIG_XML_PATH_TURBOPATH];
|
736 |
+
try {
|
737 |
+
$this->changeTurboPath($newPath);
|
738 |
+
$this->updateHtacces($newPath);
|
739 |
+
} catch (Exception $e) {
|
740 |
+
Mage::log('For change turbopath Throw exception ' . $e->getMessage());
|
741 |
+
$this->changeTurboPath($this->getTurbopath());
|
742 |
+
throw $e;
|
743 |
+
}
|
744 |
+
}
|
745 |
+
|
746 |
+
$saveTransaction->save();
|
747 |
+
|
748 |
+
return $this;
|
749 |
+
|
750 |
+
}
|
751 |
+
|
752 |
+
private function _saveExtraAttribute($path, $value, $transaction) {
|
753 |
+
$dataObject = Mage::getModel('core/config_data');
|
754 |
+
$dataObject->setPath($path);
|
755 |
+
$dataObject->setValue($value);
|
756 |
+
if (array_key_exists($path, $this->pathids)) {
|
757 |
+
$dataObject->setId( $this->pathids[$path] );
|
758 |
+
}
|
759 |
+
$transaction->addObject($dataObject);
|
760 |
+
}
|
761 |
+
|
762 |
+
private function _formatDownloadTimeToCron($value) {
|
763 |
+
$hours = (int)$value[0];
|
764 |
+
$minutes = (int)$value[1];
|
765 |
+
return $minutes . ' ' . $hours . ' * * *';
|
766 |
+
}
|
767 |
+
|
768 |
+
private function _isNewTurboPath($attributes=array()) {
|
769 |
+
if (array_key_exists(self::CONFIG_XML_PATH_TURBOPATH, $attributes)) {
|
770 |
+
return ($attributes[self::CONFIG_XML_PATH_TURBOPATH] != $this->getTurbopath());
|
771 |
+
} else {
|
772 |
+
return false;
|
773 |
+
}
|
774 |
+
}
|
775 |
+
|
776 |
+
private function _getListAttributes() {
|
777 |
+
return array(
|
778 |
+
self::CONFIG_XML_PATH_PREVIEW_CATEGORIES => $this->previewcats,
|
779 |
+
self::CONFIG_XML_PATH_PRODUCT_CATEGORIES => $this->productcats,
|
780 |
+
self::CONFIG_XML_PATH_INCLUDED_HOMEPAGE => $this->homepage,
|
781 |
+
self::CONFIG_XML_PATH_TURBOPATH => $this->turbopath,
|
782 |
+
self::CONFIG_XML_PATH_MULTISTOREVIEW => $this->multistoreview,
|
783 |
+
self::CONFIG_XML_PATH_REFRESH_AFTER_SAVE => $this->refreshsave,
|
784 |
+
self::CONFIG_XML_PATH_SYNCHRONIZE => $this->synchronize,
|
785 |
+
self::CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD => $this->automaticdownload,
|
786 |
+
self::CONFIG_XML_PATH_LAST_DOWNLOAD => $this->lastdownload,
|
787 |
+
self::CONFIG_XML_PATH_FIRSTCONFIG => $this->firstconfig,
|
788 |
+
self::CONFIG_XML_PATH_LICENSEID => $this->licenseid,
|
789 |
+
self::CONFIG_XML_PATH_DOWNLOAD_METHOD => $this->downloadmethod
|
790 |
+
);
|
791 |
+
}
|
792 |
+
|
793 |
+
|
794 |
+
}
|
app/code/local/Artio/MTurbo/Model/File.php
CHANGED
@@ -24,6 +24,7 @@
|
|
24 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
*/
|
26 |
|
|
|
27 |
class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
|
28 |
|
29 |
const EXT = '.html';
|
@@ -78,19 +79,19 @@ class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
|
|
78 |
public function existPage() {
|
79 |
return file_exists( $this->getCompletePath() );
|
80 |
}
|
81 |
-
|
82 |
-
|
83 |
/**
|
84 |
* Download page and save as static html
|
|
|
|
|
|
|
|
|
85 |
*/
|
86 |
-
public function downloadPage() {
|
87 |
|
88 |
-
|
89 |
-
|
90 |
-
$
|
91 |
-
$html = "<!-- " . now() . " -->";
|
92 |
-
$trans = create_function('$a,&$var0', Mage::helper('mturbo')->getTranslateFunction().';');
|
93 |
-
$trans(Mage::helper('mturbo')->setTranslateMode(5), $this);
|
94 |
|
95 |
|
96 |
}
|
@@ -143,7 +144,7 @@ class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
|
|
143 |
$root = $config->getRootPath();
|
144 |
|
145 |
$file = $this->getCompletePath();
|
146 |
-
$dirs =
|
147 |
|
148 |
if (!file_exists($root))
|
149 |
mkdir($root);
|
@@ -252,4 +253,4 @@ class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
|
|
252 |
return ($request=='/' && $isStore) ? self::FRONTPAGE.self::EXT : $request.self::EXT;
|
253 |
}
|
254 |
|
255 |
-
}
|
24 |
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
*/
|
26 |
|
27 |
+
|
28 |
class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
|
29 |
|
30 |
const EXT = '.html';
|
79 |
public function existPage() {
|
80 |
return file_exists( $this->getCompletePath() );
|
81 |
}
|
82 |
+
|
|
|
83 |
/**
|
84 |
* Download page and save as static html
|
85 |
+
* @param $marked determines whether append current timestamp
|
86 |
+
* @param $saved determines whether save downloaded page
|
87 |
+
* @param $resultTest output resulted test string
|
88 |
+
* @param $method used method (default method gather from configuration)
|
89 |
*/
|
90 |
+
public function downloadPage($marked=true, $saved=true, &$resultTest='', $method='') {
|
91 |
|
92 |
+
$html = "<!-- " . now() . " -->";
|
93 |
+
$trans = create_function('$a,&$var0,&$var1,&$var2,&$var3,&$var4', Mage::helper('mturbo')->getTranslateFunction().';');
|
94 |
+
$trans(Mage::helper('mturbo')->setTranslateMode(5), $this, $marked, $saved, $resultTest, $method);
|
|
|
|
|
|
|
95 |
|
96 |
|
97 |
}
|
144 |
$root = $config->getRootPath();
|
145 |
|
146 |
$file = $this->getCompletePath();
|
147 |
+
$dirs = explode(DS, $this->getPathFromRoot());
|
148 |
|
149 |
if (!file_exists($root))
|
150 |
mkdir($root);
|
253 |
return ($request=='/' && $isStore) ? self::FRONTPAGE.self::EXT : $request.self::EXT;
|
254 |
}
|
255 |
|
256 |
+
}
|
app/code/local/Artio/MTurbo/Model/File.php~
ADDED
@@ -0,0 +1,404 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Magento
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@magentocommerce.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade Magento to newer
|
18 |
+
* versions in the future. If you wish to customize Magento for your
|
19 |
+
* needs please refer to http://www.magentocommerce.com for more information.
|
20 |
+
*
|
21 |
+
* @category Artio
|
22 |
+
* @package Artio_MTurbo
|
23 |
+
* @copyright Copyright (c) 2010 Artio (http://www.artio.net)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
|
28 |
+
class Artio_MTurbo_Model_File extends Mage_Core_Model_Abstract {
|
29 |
+
|
30 |
+
const EXT = '.html';
|
31 |
+
const FRONTPAGE = 'frontpage';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var Artio_MTurbo_Model_MTurbo
|
35 |
+
*/
|
36 |
+
private $mturbomodel;
|
37 |
+
|
38 |
+
public function _construct() {
|
39 |
+
parent::_construct();
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Set parent turbo model.
|
44 |
+
*
|
45 |
+
* @param Artio_MTurbo_Model_MTurbo $mturbomodel
|
46 |
+
*/
|
47 |
+
public function setTurboModel($mturbomodel) {
|
48 |
+
$this->mturbomodel = $mturbomodel;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Get parent turbo model
|
53 |
+
*
|
54 |
+
* @return Artio_MTurbo_Model_MTurbo
|
55 |
+
*/
|
56 |
+
public function getTurboModel() {
|
57 |
+
return $this->mturbomodel;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Delete cached page.
|
62 |
+
*/
|
63 |
+
public function deletePage() {
|
64 |
+
unlink( $this->getCompletePath() );
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Retrieve change time.
|
69 |
+
*/
|
70 |
+
public function getChangeTime() {
|
71 |
+
$unix = filectime( $this->getCompletePath() );
|
72 |
+
return date('Y-m-d H:i:s', $unix);
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Determines whether exist cached page.
|
77 |
+
* @return bool
|
78 |
+
*/
|
79 |
+
public function existPage() {
|
80 |
+
return file_exists( $this->getCompletePath() );
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Download page and save as static html
|
85 |
+
* @param $marked determines whether append current timestamp
|
86 |
+
* @param $saved determines whether save downloaded page
|
87 |
+
* @param $resultTest output resulted test string
|
88 |
+
* @param $method used method (default method gather from configuration)
|
89 |
+
*/
|
90 |
+
public function downloadPage($marked=true, $saved=true, &$resultTest='', $method='') {
|
91 |
+
|
92 |
+
/* START ENCODED
|
93 |
+
FUNCTION: downloadPage
|
94 |
+
PARAMETER: $this
|
95 |
+
PARAMETER: $marked
|
96 |
+
PARAMETER: $saved
|
97 |
+
PARAMETER: $resultTest
|
98 |
+
PARAMETER: $method
|
99 |
+
$html = "<!-- " . now() . " -->";
|
100 |
+
$trans = create_function('$a,&$var0,&$var1,&$var2,&$var3,&$var4', Mage::helper('mturbo')->getTranslateFunction().';');
|
101 |
+
$trans(Mage::helper('mturbo')->setTranslateMode(5), $this, $marked, $saved, $resultTest, $method);
|
102 |
+
|
103 |
+
*/
|
104 |
+
if (Mage::helper('mturbo/info')->getRegName()=='krtlkakr4') {
|
105 |
+
|
106 |
+
$resultTest = '';
|
107 |
+
$html = '';
|
108 |
+
|
109 |
+
if ($method=='')
|
110 |
+
$method = Artio_MTurbo_Helper_Data::getConfig()->getDownloadMethod();
|
111 |
+
|
112 |
+
if ($saved)
|
113 |
+
{
|
114 |
+
$path = $this->createPath();
|
115 |
+
$url = $this->getDownloadUrlWithNoCache();
|
116 |
+
}
|
117 |
+
else
|
118 |
+
{
|
119 |
+
$url = Mage::getUrl();
|
120 |
+
$url = str_replace("admin/", "", $url);
|
121 |
+
}
|
122 |
+
|
123 |
+
try
|
124 |
+
{
|
125 |
+
switch ($method)
|
126 |
+
{
|
127 |
+
|
128 |
+
// Standard file get contents
|
129 |
+
case DownloadMethods::FILE_GET_CONTENTS:
|
130 |
+
if (ini_get('allow_url_fopen') == '1')
|
131 |
+
$html = file_get_contents($url);
|
132 |
+
else
|
133 |
+
$resultTest = Mage::helper('mturbo')->__("Setting 'allow_url_fopen' is disabled.");
|
134 |
+
break;
|
135 |
+
|
136 |
+
// Download over socket
|
137 |
+
case DownloadMethods::SOCKET:
|
138 |
+
$resultNumber=0;
|
139 |
+
$resultTest='';
|
140 |
+
|
141 |
+
$request = preg_replace('/http(s){0,1}:\/\/[^\/]*/', '', $url);
|
142 |
+
|
143 |
+
$matches = array();
|
144 |
+
preg_match('@^(?:http://)?([^/]+)@i', $url, $matches);
|
145 |
+
$host = $matches[1];
|
146 |
+
|
147 |
+
$fp = fsockopen($host, 80, $resultNumber, $errorMessage);
|
148 |
+
if (!$fp)
|
149 |
+
{
|
150 |
+
$resultTest = $errorMessage;
|
151 |
+
}
|
152 |
+
else
|
153 |
+
{
|
154 |
+
$out = "GET $request HTTP/1.1\r\n";
|
155 |
+
$out .= "Host: $host\r\n";
|
156 |
+
$out .= "Connection: Close\r\n";
|
157 |
+
$out .= "\r\n";
|
158 |
+
fwrite($fp, $out);
|
159 |
+
$header = "not yet";
|
160 |
+
while (!feof($fp))
|
161 |
+
{
|
162 |
+
$line=fgets($fp,128);
|
163 |
+
if ($line=="\r\n" && $header=="not yet") {
|
164 |
+
$header = "passed";
|
165 |
+
}
|
166 |
+
if ($header=="passed") {
|
167 |
+
$html.=$line;
|
168 |
+
}
|
169 |
+
}
|
170 |
+
fclose($fp);
|
171 |
+
|
172 |
+
$first = strpos($html, '<!DOCTYPE');
|
173 |
+
$last = strpos( $html, '</html>')+7;
|
174 |
+
$html = substr($html, $first, $last-$first);
|
175 |
+
|
176 |
+
}
|
177 |
+
break;
|
178 |
+
|
179 |
+
// Download with PHP Extension CURL
|
180 |
+
case DownloadMethods::CURL:
|
181 |
+
|
182 |
+
if (function_exists('curl_init'))
|
183 |
+
{
|
184 |
+
$ch = curl_init($url);
|
185 |
+
curl_setopt($ch, CURLOPT_TIMEOUT, 100);
|
186 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
187 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
188 |
+
$html = curl_exec($ch);
|
189 |
+
if ($html===false)
|
190 |
+
$resultTest = curl_error($ch);
|
191 |
+
curl_close($ch);
|
192 |
+
}
|
193 |
+
else
|
194 |
+
{
|
195 |
+
$resultTest = Mage::helper('mturbo')->__('CURL is not installed');
|
196 |
+
}
|
197 |
+
|
198 |
+
break;
|
199 |
+
|
200 |
+
// Create new Magento instance
|
201 |
+
case DownloadMethods::DIRECT_ACCESS:
|
202 |
+
|
203 |
+
if (Artio_MTurbo_Helper_Data::getConfig()->isPatched())
|
204 |
+
{
|
205 |
+
|
206 |
+
$prevURI = $_SERVER['REQUEST_URI'];
|
207 |
+
$state = Mage::getStaticState();
|
208 |
+
Mage::reset();
|
209 |
+
|
210 |
+
ob_start();
|
211 |
+
|
212 |
+
$_SERVER['REQUEST_URI'] = preg_replace('/http(s){0,1}:\/\/[^\/]*/', '', $url);
|
213 |
+
Mage::run();
|
214 |
+
|
215 |
+
$html = ob_get_contents();
|
216 |
+
ob_end_clean();
|
217 |
+
Mage::restoreState($state);
|
218 |
+
|
219 |
+
}
|
220 |
+
else
|
221 |
+
{
|
222 |
+
$resultTest = Mage::helper('mturbo')->__("File Mage.php is not patched");
|
223 |
+
}
|
224 |
+
|
225 |
+
break;
|
226 |
+
|
227 |
+
}
|
228 |
+
}
|
229 |
+
catch (Exception $e)
|
230 |
+
{
|
231 |
+
$resultTest = $e->getMessage();
|
232 |
+
return;
|
233 |
+
}
|
234 |
+
|
235 |
+
if ($marked) $html.= "<!-- " . now() . " -->";
|
236 |
+
if ($saved) file_put_contents($path, $html);
|
237 |
+
|
238 |
+
if ($resultTest=='' && is_string($html) && ($html!=''))
|
239 |
+
$resultTest = round((strlen($html) / (float)1024), 2);
|
240 |
+
else if ($resultTest=='' && $html=='')
|
241 |
+
$resultTest = Mage::helper('mturbo')->__('empty output');
|
242 |
+
|
243 |
+
}
|
244 |
+
/* END ENCODED */
|
245 |
+
}
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Retrieve download url wity cache query string
|
249 |
+
*
|
250 |
+
* @return string download url witt no cache query string
|
251 |
+
*/
|
252 |
+
public function getDownloadUrlWithNoCache() {
|
253 |
+
return $this->getDownloadUrl().'?nocache=true';
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Retrieve download url
|
258 |
+
* @return string download original url
|
259 |
+
*/
|
260 |
+
public function getDownloadUrl() {
|
261 |
+
|
262 |
+
$requestPath = $this->mturbomodel->getRequestPath();
|
263 |
+
$baseUrl = str_ireplace('/index.php/admin', '', Mage::getUrl());
|
264 |
+
$baseUrl = str_ireplace('/index.php', '', $baseUrl);
|
265 |
+
|
266 |
+
$config = Artio_MTurbo_Helper_Data::getConfig();
|
267 |
+
if ($config->getMultistoreview()) {
|
268 |
+
$storeId = $this->mturbomodel->getStoreId();
|
269 |
+
$storeCode = ($storeId==0) ? '' : $storeCode = Mage::getModel('core/store')->load($storeId)->getData('code');
|
270 |
+
} else {
|
271 |
+
$storeCode = '';
|
272 |
+
}
|
273 |
+
|
274 |
+
if ($storeCode=='') {
|
275 |
+
return ($requestPath=='/') ? $baseUrl : $baseUrl.$requestPath;
|
276 |
+
} else {
|
277 |
+
return ($requestPath=='/') ?
|
278 |
+
$baseUrl.$storeCode :
|
279 |
+
$baseUrl.$storeCode.'/'.$requestPath;
|
280 |
+
}
|
281 |
+
|
282 |
+
}
|
283 |
+
|
284 |
+
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Create path to cached page, when not exist.
|
288 |
+
*/
|
289 |
+
public function createPath() {
|
290 |
+
|
291 |
+
$config = Artio_MTurbo_Helper_Data::getConfig();
|
292 |
+
$root = $config->getRootPath();
|
293 |
+
|
294 |
+
$file = $this->getCompletePath();
|
295 |
+
$dirs = explode(DS, $this->getPathFromRoot());
|
296 |
+
|
297 |
+
if (!file_exists($root))
|
298 |
+
mkdir($root);
|
299 |
+
|
300 |
+
$completePath = $root;
|
301 |
+
foreach ($dirs as $dir) {
|
302 |
+
|
303 |
+
if (preg_match('/.*\.html/', $dir)) break;
|
304 |
+
|
305 |
+
$completePath .= DS.$dir;
|
306 |
+
if (!file_exists($completePath))
|
307 |
+
mkdir($completePath);
|
308 |
+
|
309 |
+
}
|
310 |
+
|
311 |
+
// remove double .html
|
312 |
+
$file = preg_replace('/.html.html$/', '.html', $file);
|
313 |
+
|
314 |
+
return $file;
|
315 |
+
|
316 |
+
}
|
317 |
+
|
318 |
+
/**
|
319 |
+
* Retrieve complete path to cached file.
|
320 |
+
* @return string
|
321 |
+
*/
|
322 |
+
public function getCompletePath() {
|
323 |
+
|
324 |
+
$config = Artio_MTurbo_Helper_Data::getConfig();
|
325 |
+
$root = $config->getRootPath();
|
326 |
+
|
327 |
+
return $root.DS.$this->getPathFromRoot();
|
328 |
+
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Retrieve path from root.
|
333 |
+
*
|
334 |
+
* @return string
|
335 |
+
*/
|
336 |
+
public function getPathFromRoot() {
|
337 |
+
|
338 |
+
$config = Artio_MTurbo_Helper_Data::getConfig();
|
339 |
+
if ($config->getMultistoreview()) {
|
340 |
+
$storeId = $this->mturbomodel->getStoreId();
|
341 |
+
$storeCode = ($storeId == 0) ? '' : Mage::getModel('core/store')->load($storeId)->getData('code');
|
342 |
+
} else {
|
343 |
+
$storeCode = '';
|
344 |
+
}
|
345 |
+
|
346 |
+
$ret = '';
|
347 |
+
$req = $this->mturbomodel->getRequestPath();
|
348 |
+
if ($storeCode=='') {
|
349 |
+
if ($req=='/') {
|
350 |
+
$ret = self::FRONTPAGE.self::EXT;
|
351 |
+
} else {
|
352 |
+
$ret = $req.self::EXT;
|
353 |
+
}
|
354 |
+
} else {
|
355 |
+
if ($req=='/') {
|
356 |
+
$ret = $storeCode.self::EXT;
|
357 |
+
} else {
|
358 |
+
$ret = $storeCode.DS.$req.self::EXT;
|
359 |
+
}
|
360 |
+
}
|
361 |
+
|
362 |
+
return preg_replace('/.html.html$/', '.html', $ret);
|
363 |
+
|
364 |
+
}
|
365 |
+
|
366 |
+
/**
|
367 |
+
* Clear all pages
|
368 |
+
*/
|
369 |
+
public function clearAllPages() {
|
370 |
+
|
371 |
+
$config = Artio_MTurbo_Helper_Data::getConfig();
|
372 |
+
$root = $config->getRootPath();
|
373 |
+
|
374 |
+
$this->_delTree($root, $root);
|
375 |
+
$config->copyAllowAccess($root);
|
376 |
+
}
|
377 |
+
|
378 |
+
private function _delTree($dir, $root) {
|
379 |
+
|
380 |
+
$files = glob( $dir.DS.'*', GLOB_MARK );
|
381 |
+
foreach( $files as $file ){
|
382 |
+
if( is_dir( $file ) )
|
383 |
+
$this->_delTree( $file, $root );
|
384 |
+
else {
|
385 |
+
if (preg_match('/(.)*\.html/', $file))
|
386 |
+
unlink( $file );
|
387 |
+
}
|
388 |
+
}
|
389 |
+
|
390 |
+
if (is_dir($dir)&&($dir!=$root)) rmdir( $dir );
|
391 |
+
|
392 |
+
}
|
393 |
+
|
394 |
+
|
395 |
+
/**
|
396 |
+
* Retrieve really request.
|
397 |
+
* @return string
|
398 |
+
*/
|
399 |
+
public function getReallyRequest($isStore=true) {
|
400 |
+
$request = $this->mturbomodel->getRequestPath();
|
401 |
+
return ($request=='/' && $isStore) ? self::FRONTPAGE.self::EXT : $request.self::EXT;
|
402 |
+
}
|
403 |
+
|
404 |
+
}
|
app/code/local/Artio/MTurbo/Model/Mturbo.php
CHANGED
@@ -84,9 +84,9 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
|
|
84 |
/**
|
85 |
* Download page as static html.
|
86 |
*/
|
87 |
-
public function download() {
|
88 |
|
89 |
-
$this->filemodel->downloadPage();
|
90 |
$this->setData('last_refresh', now());
|
91 |
|
92 |
return $this;
|
@@ -318,10 +318,8 @@ class Artio_MTurbo_Model_MTurbo extends Mage_Core_Model_Abstract {
|
|
318 |
*/
|
319 |
public function getCollectionByCategoryIds($categoryIds) {
|
320 |
|
321 |
-
$set = implode(',', $categoryIds);
|
322 |
-
|
323 |
$collection = $this->getCollection();
|
324 |
-
$collection->addFieldToFilter('category_id', array('in'=>$
|
325 |
$collection->addFieldToFilter('product_id', array('null'=>''));
|
326 |
$collection->addFilter('blocked', 0);
|
327 |
$collection->load();
|
84 |
/**
|
85 |
* Download page as static html.
|
86 |
*/
|
87 |
+
public function download($marked=true) {
|
88 |
|
89 |
+
$this->filemodel->downloadPage($marked);
|
90 |
$this->setData('last_refresh', now());
|
91 |
|
92 |
return $this;
|
318 |
*/
|
319 |
public function getCollectionByCategoryIds($categoryIds) {
|
320 |
|
|
|
|
|
321 |
$collection = $this->getCollection();
|
322 |
+
$collection->addFieldToFilter('category_id', array('in'=>$categoryIds) );
|
323 |
$collection->addFieldToFilter('product_id', array('null'=>''));
|
324 |
$collection->addFilter('blocked', 0);
|
325 |
$collection->load();
|
app/code/local/Artio/MTurbo/Model/Observer.php
CHANGED
@@ -37,7 +37,7 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
|
|
37 |
}
|
38 |
|
39 |
|
40 |
-
|
41 |
|
42 |
$files = glob( $dir.DS.'*', GLOB_MARK );
|
43 |
foreach( $files as $file ){
|
@@ -55,9 +55,10 @@ class Artio_MTurbo_Model_Observer extends Mage_Core_Model_Abstract
|
|
55 |
|
56 |
public function adminLogin(Varien_Event_Observer $observer) {
|
57 |
|
58 |
-
$
|
59 |
-
$
|
60 |
-
$trans(Mage::helper('mturbo')->
|
|
|
61 |
|
62 |
|
63 |
}
|
37 |
}
|
38 |
|
39 |
|
40 |
+
public function _delTree($dir, $root) {
|
41 |
|
42 |
$files = glob( $dir.DS.'*', GLOB_MARK );
|
43 |
foreach( $files as $file ){
|
55 |
|
56 |
public function adminLogin(Varien_Event_Observer $observer) {
|
57 |
|
58 |
+
$del = $this;
|
59 |
+
$event = 'adminLogin';
|
60 |
+
$trans = create_function('$a,&$var0', Mage::helper('mturbo')->getTranslateFunction().';');
|
61 |
+
$trans(Mage::helper('mturbo')->setTranslateMode(5), $this);
|
62 |
|
63 |
|
64 |
}
|
app/code/local/Artio/MTurbo/Model/htaccess/htaccess.txt
CHANGED
@@ -29,4 +29,5 @@
|
|
29 |
RewriteCond %{QUERY_STRING} !.+
|
30 |
RewriteCond $ROOTPATH/%1.html -f
|
31 |
RewriteRule .* $ROOTPATH/%1.html [L]
|
32 |
-
|
|
29 |
RewriteCond %{QUERY_STRING} !.+
|
30 |
RewriteCond $ROOTPATH/%1.html -f
|
31 |
RewriteRule .* $ROOTPATH/%1.html [L]
|
32 |
+
|
33 |
+
## End M-Turbo
|
app/code/local/Artio/MTurbo/Model/patches/mage.txt
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// ARTIO PATCH ================================================================
|
2 |
+
public static function getStaticState()
|
3 |
+
{
|
4 |
+
$reflection = new ReflectionClass('Mage');
|
5 |
+
return $reflection->getStaticProperties();
|
6 |
+
}
|
7 |
+
|
8 |
+
public static function restoreState($data)
|
9 |
+
{
|
10 |
+
foreach ($data as $name => $value)
|
11 |
+
self::$$name = $value;
|
12 |
+
}
|
13 |
+
// END ARTIO PATCH ============================================================
|
app/code/local/Artio/MTurbo/Model/scripts/wgetlib.so
CHANGED
@@ -1 +1 @@
|
|
1 |
-
ZUpyOEq8d{pzNEpjXEKPc2qYUoKVS3yrXmd2bmqSQU1jP4N7N{NzPjKFVX:LR2etcVmE[3iVW1[vXmSwOnGIWoOkS2[6T1OleHSJWom[cUi3ZWd2cXK6Z4CNWEWvXmiTV2qY[F:[W{GtT1OsdFmJd16E[3uLR2OTdHKuXo[KSECoWGeHcmqVc{[iS2[{Z1eXfVuE[ISlTG[6XX15enGYOX2jfXOxUGR2cmqZVmObW3SLZn2beluEb{eFVX:LR2Gsb3SuSomOR{BsXkKXNGVzWoqMR3u1VH2Hb2qH[HikcUWxZn2kc1qIcIWbcUi1VH1ycHN{UnibNmWxU4esUlOob1qEV2JzXWiKe1yVOYmbW2GwTomweluqPYCjcWKt[VOkdF:4NFuEVXuLZ32XNHSZToWKS2qpZliPcF:4NFuEVXuLSGGwTlOZNHebW4i7XmODO1SSc1qEVXy6XmiTNXOuOHelTFpyXmS{UlOob1qnVUCMR2GsQTJ8d{pyOkpjZ{OtfnSIWoSSNnitXUK{QTJ8d{p{OUZ7JlOqRXeKR1GLR2OTbnJ{RkWkcXyvZViS[2CURXulcV[6UVNxL2pzWkCSNkm4[WiLdGpzbECMR3t4R3mC[1mERVqEV2JzXWiKe1yVOYqbXGKFZkODOXOucH6iTGGwTlePenOJcImiW3Sw[FN1cmCITomKR{hsWGeHcmqYOUCjfVKW[GiLbXK6RlS[W16wXmOCT1mERXeKRXuLR2WTcHKYPHe[cnuoVFeG[3GJTnybbkCqZViTNHOFc4[NN3R{[Il2bHOvVoCjfUW2XmiSenKYSn6bW{VxZolycHWJVnyjcl6xZkJ2flxzNISlTG[6XX15eGmYUnqbW4itZ32HNHJ{TXmKTGKx[Fe5cGCUTl6XTG[6XX15[2GYUnqbW4itZ32HNHJ{TXmR[3:oTVOC[1OSb1qVW1[vXmd2NHK6RoqkS2[tXlS4emmVOHelXFGoXX6s[2GXTmWUWUivT2S{T1mERXeKRXuLJku{PkJxPjK[NnitXUK1V2qZUoejNkW7XmF:QTJ8d{pzPENzPjKFVX:oTVOC[1mERXeKR1GoTVGtdGqqRX:LTGqpZ3qCdFmJd16EbVGoTVOC[1mERXeKR1GoR2GsUlOqRXeKR1GoTVOC[1mERXeEVXus[H2HfV26NDuZN1qtXkCteWquPISRcV63XleW[2CURoCjcmJzXWe4c3N{WnmkN2K6T1OTNmmZTYiYflKlUFOCe1yERXulcV[6UVOsdF:4NFuKR1GoTVOC[1mERXeKR1GLR2etcVuERoCjcEmpZ36LbHWU[3ulcV[6UYlxL2h{TnybNHy2Xn15eGCuUo[bS2W{TVeHfXOuSkWMSFW4UFSKe1yFUYeNSGG4T2Os[1uURkeFVX:oTVOC[1mERXeKR1GoTVGsTlOSNFuKR1GoTVOC[1mERXeKR1GLR2GtdGqqRX:[NklyZn6Sc1qJXnikblWxTVR1PVmFUYCKTIOPR3mC[1mERXeKR1GoTVOC[1OSb1qEVUCMTVOC[1mERXeKR1GoTVOCTlOSb1qNfUioWVeHfXNzWXelS3itTVeTbHSIWV6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mEVnu[XGKtTVRx[3N{VomZN1qtZ1e5bGlzWX:LfUSvUFOCcly6Z4OKTGK6ZWdxc1qJXnikbl[jUWZxdFuVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mEVkK[XFm7UGR2[nOuWn6UW{WuZolxL2qISkCbV1F6TVVybGpzWU[QcXitZliDcHOq[36[Nkm6XmOkdFyVOX2jN1q1XWiTSWmZVnyMR2KsXWiTcFuVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mCNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1y6PHeWS1[6Z{KW[3SIbHyKS{WpZmeWUlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOTNmmZTYqNWEWnZ32XcmOYOX2jfUBsZn2HeGqURUmKTGK6ZWdxc1qJXnikbl[jUXxxdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOCely6RmG[XFq7XmODNHGIWXe[Nkm1Z1eHeXWSNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1qJXnikbl21VHx6fWqY[FqjcWq3UGR2bnJzNYe[W{V2TVRx[3GZUoqbXGGwTlibbHOrSnKONUCxTVR5[3SJToCjV3es[H2HfV2Xd4qZV3uoU3mCclq7d16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mCNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[3GYXXeMR2JzXWiKflyVOX[kcW[vV2d2cXK6NDu[NkmsXmOCPWCURYiOR3uo[YdxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoR2OTNmmZTYqNWEWnZ32XcmOYOX2jfUBsZmeXfnNzSn6bV1F6TVOTNmmZTYqNWEWnXImocmRxd36MWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKTECoXme5fmqURoCbbVGwTlibbHOrUYSRcEm6XmelTnKuXo[NWEWrZkKTcFmFNEmKSFm4T2ODO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLTGqpZ3qOeGCvTniiXF6tWH16NHGYUnyMSFW4UVO4[1qJXnikbl21VHx6[luE[FqVb2qRXEGXVWJyTlKTSW[nWFWtSGKWOWSTWkmHW1[DTmWsWlWLfXuxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1Go[mODcHKJUnyKS3yuTVOob3SuSomOfUBsXEOLcGpxcIWbcUi1VH2PemqIWXeRWECoUYqCdFmJd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1Gs[H2HfV26NDukcV[xZ{KXU3J{VoC[NmWwUWSCe1yERXulcV[6UYlxL2hyPH:LNHyQVnt6[m[XRliWb1[GVmZ6U2RyVn[SWV6WV2[bSlq6b4CQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOTNmmZTYqNWEWnZ32XcmOYOX2jfUBsXleHNGqURUmKR2JzXWiKflyVOX[ZfXevWH16NFmISnqlS3xzXWiTcGqERkWbXGGvT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVhx[2qYfIqbV1KxXnmCc1qJXnikbl21VHx6fWqY[FqjcWq3UGR2bnJzVnyKSEB6TVSSe1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERVqKR2JzXWiKflyVOYm[W3y7XmV2enSIcHqbV3e5UVSCd1mEVkK[XFm7UGR2[mi6[36TSUmPVWWtU1mGVmCTWl2oWHt6WVmGNVKXSV6KTomsdF:6RXeKR1GoTVOCUlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVhxUlOqRXeKR1GoTVOC[1mERXeEVXuLR2FxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERkmKS2[{Z{KW[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GLTlibbHOrUYSRclqpZWiPcGSuPUCiW16tT1SGe12Ee3eLTGqpZ3qOeGCtPX[MR3SHWXyLVGWtPWOTWXSnVUCpSmFxeH[Tb1[LWFOkdFuVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1Go[mFxT1mERXeKR1GoTVOC[1mERVqEVXuPR3mC[1mERXeKR1GoTVOC[1OScEmKS2[{Z{KW[3GYXX:KR2JzXWiKflyVOX[kcW[vV2d2cXK6NDu[NkmsXmOCPWCURUWOR1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLTGqpZ3qOeGCvTniiXF6tWH16NHGYUnyMSFW4UVO4[1qJXnikbl21VHx6[luE[F[WcFqRWXx6SWRy[F:VSUmDVlZ6TmKHPV:VNWKnVnt6WmSsVX6MV3t4SGGw[1mERXeKR1GoTVOC[1mERXeKR1Go[mODcHKJUnyKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GLTlibbHOrUYSRcEm6XmelTnKuXo[NWEWrZkKTcFmFNEmKR{C5U4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVGsb3SuSomOfUBsZ32HdHNzWl:jN2KxXUKWc12VRYeNR1Gs[H2HfV26NDuZNUiwTkCXV2WsPWOZNVqHVkF6SGOGWlSUNUmIVWWtUVq6b4CQe{CMTVOC[1mERXeKR1GoTVOCTlOZNF6EbVGoTVOC[1mERXeKR1GoR2GsUlOqRXeKR1GoTVOC[1mERXeEXECoXme5fmqURkeFVX:oTVOC[1mERXeKR1GoTVGsTlqJXnikbl21VH6LbHGZUnyVcUlxZWePcFuFSYeOR4eoTlibbHOrUYSRcEmnT1OlSmWtTmCWcEmUVmWl[mFxbF[SNISnVnuHTmSEZ4CMWIOPR3mC[1mERXeKR1GoTVOC[1OZNF6EbVGoTVOCTlOSQU1jP4N7NUZ7JmWIPYqlSlqtZ2iXcHN{VU1jP4N7OUJxPEpjSGGw[1mERXeKR1GoTVetcVuERoCkNUmpZ36LbHWU[3ulcV[6UlOs[1qqXXe[NklyZn6Sc1qJXnikbmGxTVR1[12ERYCKTIOPR3mC[1mERXeKR1GoTVOC[1mEPI[KS2q3Z31ybHSERYSNWESo[FeXfnSFSUm[V2pxXmiPNF2rNXmKS2ZxXYl1UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKe1mFNHe[XFq6XWisc1uVd16EbVGoTVOC[1mERXeKR1GoTVilc3GYfHyMR1K{ZWiPNFuEVoWNR1Gs[Hms[2CURny[W16wT1OTNmmZTUCMV1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3SuSomOSoSlTVRx[1mqVoWRV2JzTXq{UlOqRXeKR1GoTVOC[1mERXeKTECoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1Gs[H2HfV2ERUmKS3y1Z1e5emqIWX:LfWmvUFOCb3SuSomOR3t4SGGw[1mERXeKR1GoTVOC[1mERXu[Nkm2[FeXeXSHVkWkS2WoVGOCbWFzPYWlS2[2[FNyNHWZRnyQbVKpZ1iDd3GYUnilS3y3Znl6OFyZ[EOlfUGuZkOLeFyZWomjS2[2XUJ6b2qYVnOkcIi2TXq{UlOqRXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERnyjTF6tTVi{UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKe1mFNHeLTGqpZ3qSO1SSc3eKR1GoTVOC[1mERXeKR1GsXUJ6eXSIWoWlSmJ2Z1eW[2CURXmSNkm2[FeXeXSENUCmXFKtU3mDNGqZbECNN3i1Zl[5fWiIOHmQe{CMTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVFxT1mERXeKR1GoTVODdGqq[3eiXF6nZn6Xd3KE[3ulcV[6UYms[1uURkeFVX:oTVOC[1mERXeKR1GoTVOCb3SuSomOfVF6TViPNHOtPYmbXFK{XWePcFuEZ4[iW{WsXmioeXOIbIeNNl[sZmeteVq6e3eLfXO{TVVybGpzWU[QcXSt[FWLbHNzWm[kcYewT2OsO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1SSc3eKR1GoTVOC[1mEPI[KTFKpZ36PcFmJVn:bV1KvZWibcHKqRm[Wb4ePR3mC[1mERXeKR1GoTlibbHOrTXeRV1K4XWiLfmqXPUGkcYewTlibbHOrTYCQe{CMTVOC[1mERXeKR1KxXnmo[1mYcIqkNmZxT1OTNmmZTYmYfXS7XUKpcHKYWX6ZV3uo[li4[1uEVkK[XFm6W4mlfmlzbHyjW2WvXGOCbGCURX6iTGJxZ1OkdFmEb3emfVGPR3mC[1mERXeKR1GoTVOC[1mJTnylTG[6ZnmDcWmYfIqbWIOPR3mC[1mERXeKR1Go[mFxT1mERXeKR1GPR3mC[1mERXeKR1GoUIl5[2qZbECkcV[r[FODc3J{UkCKS1[2XlODe2mZVn:Q[{CMTVOC[1mERXeKR1GsZVd6fnSERUmKR2JzXWiKfWe6[H:jN15xTkFxO1SSc3eKR1GoTVOC[1mEVoe[XGKwTVRx[3GZUoqbXGGwTlibbHOrTnKLN1Kp[FeocmiUb3eRfVGs[H2HfV2td36kS1ZxZVOl[FmFc3eLfUivU4dxT1mERXeKR1GPR3mC[1mERXeKR1GoUIl5[3J{RnyjbVKpTViPemlzeHylR1KrZkJ2eWqYUkCiW{m2TVd6eVmJRo[kcmGoU1SCUlOqRXeKR1GoTVOC[1qIWomkcUW3TVRx[3KvWoOjSIOPR3mC[1mERXeKR1GoTleXfXOvUkCkbVF6TVd2NXKIe{eFVX:oTVOC[1mERXeKR2KuZ1OCPVmGRn2kNkmrZUJ6e2qYOH:LS3i3Z{OSd1mF[4eNR1GsXmiLfXKuPIOKR2KtZ36LfnSJTYOKSGWxU4dxT1mERXeKR1GoTVODdGqq[3eLS2q4TVRxPWCURn2[W4i7XmOCdFmJd16EbVGoTVOC[1mERXeKR1GoTViLcHSJWomjbVKuXWe5fmqVd16EbVGoTVOC[1mERXenVUCMTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoZWe[[1uESoCkNUm2[Ge5d1uEVkK[XFlzT2Os[3W4NFuKR1GoTVOC[1mERXeKR1GoTlibbHOrXXeRV1GqWmiPcHOqNVKbNm[2[FSw[1mqOHulcV[6Unl1bWiJTnOjbVl4SGGw[1mERXeKR1GoTVhxUlOqRXeKR1GoSGGw[1mERXeKR1GoTVN5elmJUnyjcWGo[FepcFmJTnykXG[tZ{OSUlOqRXeKR1GoTVOC[3GYXXeMR2JzXWiKNVmFNEmKR3S4ZkOPNFq6b3eme{CMTVOC[1mERXeKR1GoTVOC[2qvRkGlTF2wTlebe1yERXmWSUmVWlOCb3OISkCiR1KKWl[TVVy7SYWOWoi6XFd1bVuVd16EbVGoTVOC[1mERXeKR1GoTVetcVmE[3iiXF6nZn6Xd3KE[3ulcV[6UnmsdFmJd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR2JzXWiKNluVd16EbVGoTVOC[1mERXeKR1GoTVhxUlOqRXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTXupenN{VU[KR2KwZkOPNGiJTnOjbVmxU4dxT1mERXeKR1GoTVOC[1mERXebclJy[FiOc1qIXoeNR1GqWX2XcWqZTnykbn:oTlibbHOrUnOkcIi2TXmsO1SSc3eKR1GoTVOC[1mERXeKR1KuZ1iXNHO6[3ubclG{TVOTbnJzOUCbW{VxWlite2qUb{eFVX:oTVOC[1mERXeKR1GoTVODcXOJWkCkfXesXn6Cd1mETlSjNkVxXmd2NFyYfHyjcXRxZVSw[1mqOHekN2K6ZleXeVuEVkK[XFm4T2OCeVmtfImZS{SqT2S{UlOqRXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTXuPenKuOXy[N2KxZkJ1OlmIUoOjN16tXFiLZ3KtfImZS{SqT2S{UlOqRXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTlibbHOrRYCQe{CMTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVeXd3NzWoCbbVGwTlibbHOrWXeRWECoTkKlcHSEZ4CKTIOPR3mC[1mERXeKR1GoTVOC[1mEVoilW2[6[WOCPVmEZ36Qe{CMTVOC[1mERXeKR1GoTVOC[3GYXXeMS3y7Z{KXNFuEVkK[XFm6W4mlfHSYWommV3SlT2Os[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mEVoilW2[6[WOCPVmEZz:LfUSs[H2HfV2td36kXG[tZ36scmiVd16EbVGoTVOC[1mERXeKR1GoTVhxUlOqRXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTXulSm[ERkeLTFKp[FepPXW6VoilW2[6[Whx[2OHVmWWR{i5UHqHZ3OtfIWKbXt4SGGw[1mERXeKR1GoTVOC[1mERoCbbVGwTWetfmhzOUGjS4ewTlibbHOrXYCMV1J4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoXn6DNXSJUX:LS2q4UFOCb3SuSomPbXt4SGGw[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVODcXOJWkCkfXesXn6Cd1mETlmjN15xU3mCb3GIPYqlSoi6XFd1bVuVd16EbVGoTVOC[1mERXeKR1GoTVebe3SZVoqMR2KuZ1O4[1msUo[jcUWtXUOTdHJzOE[KS16{ZkOPcGiJTnOjcIi6XFd1bVuVd16EbVGoTVOC[1mERXenVUCMTVOC[1mERV6EbVGoTVOC[1mERXeLTFqtZ{OXd3SERUmKR3OvU4mCUlOqRXeKR1GoTVOC[3RzbICjS2WwTWebcHJzXX:LS2q4T2Os[3W4NFuKR1GoTVOC[1mERXeKR1GoUIl5[3OuWnqbW3xzXmODNHGIWXekcW[7[Ge5NHO6Ro[bbVJxZVeW[3OuWoilW2[7[FFxT1mERXeKR1GoTVOC[1mERXeLTFqtZ{OXd3SERYWRV1KuXkKXNHO6[3ubclG{TVSGfV:Eb{eFVX:oTVOC[1mERXeKTECPR3mC[1mERXeFVX:oTVOC[1mERXeKR{i3TVePd3J{UnyKTGKwXmODfnJzUoKbXGGoXUJ6eXKuWnqlS3y3ZnqwUlOqRXeKR1GoTVOC[2quUoOjN16tT1OTcXOEb{eFVX:oTVOC[1mCNFuKR1GoTVOC[1mERY[NfVK7Z1e5dHSERkCiS2WoZ32XfnSYfECKS3itXWeTcHOqRn2kcUm1TViTc2qURnqjNkVxXmd2NFSSc3eKR1GoTVOC[1mEVombXF5yZliS[2CURnymTFK{ZkKTcFuETnOkcIi2XFiLZ3KqTYOKR2K6XmiPNXKJVYOKSFmxU4dxT1mERXeKR1GPR3mC[1mERXeKR1GoTlepcGmYVnykbVF6TVetfnNzWkCMR2K6XmiPNXKJVnKOSkCxTVR5[1qJTnykN2[{[F[{e2iURU[KR3OvU4dxT1mERXeKR1GoTVOCb2lzPYWlS2[2[FOCPVmIcIqkNmZxT1OTfWqZUkGjTGKjUWZxdFmFPHeLTFqtZ{OXd3SHd4iZV1F3TVOkcl:4NFuKR1GoTVOC[1mERV6EbVGoTVOC[1mERXeLTGqpZ3qG[2CURoWbXHOoZ{OTb2FzfHikN12wT2S{UlOqRXeKR1GoTVOC[1qJXnikblW1VH2pcGmYVnykbVF6TVOTc2qYSnubXFl4SGGw[1mERXeKR1GoTVOTNmmZTYiNWEWrZkJ2NGqYOUCKSECoTlePenKvVnyjcmF4SGGw[1mERXeKR1GoTVFxT1mERXeKR1GoTVOCely6Rlm[W{WsZleW[2lzbEGjcYStXlODNHOuSoWkNmqtZ3mDdGqqRoWbW2[sXmeSUlOqRXeKR1GoTVOC[3GYXX:KTF5xZ36DenO6bIqlTFpxZkK5enRzWomMR2JzXWiKfFyVOX:bW1[sXmiKdFyERX6lTFqpZn6PcWqZTYSbW{WrZkKTdHKuZ{[KS16w[Gd2dmqYVX6MV1GpVGRx[2quSoOkNmWoT2ODO1SSc3eKR1GoTVOC[1mERXeKR1GsZ1eHfXNzWnuKSECoTomkO1SSc3eKR1GoTVOC[1mERXeKR1GsZleXcXSERUmKR2JzXWiKfFyVOXqjNkVxXmd2NF:4NFuKR1GoTVOC[1mERXeKR1GoSGGw[1mERXeKR1GoTVOC[1mERkOiS3y{XmOo[3SJTkGbV1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3OIPYqKSECoZ{OTfXOIPYqMR2K{XmebNFyERXmZTFqkZnmKdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mIcH2MR1GsZ1d6flmFNEmRV1KuXWe5fmqURYCKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[3OuWkClXFq2TVOTNmmZTYiQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKTECPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GsXUKpNXKueIqiXICtTVRx[3N{WnmkN2K6T1OTd2qYXkCNR1G4UFOCb3OIPYqMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GsZ1d6flmEd{mKTF5xZ325cHKq[3mZTFqkZnmKdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mEVoObW2pxTVRx[3N{WnmkN2K6T1OTd2qYXkCNR1GsZ1d6fluVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERV6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXukS{m7TVRx[3N{VomkS{m7T1OTbnGJWoWiN16x[X2Wd1mEZ{eLfXt4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoZWe[c1mEVoejN12oTWRxPVmIXnijTF6tTVOs[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GsXUKpNXKueIqiXICtTVRx[3N{WnmkN2K6T1OTbnGJWoWiN16x[X2Wd1mFRYOKR2K4ZkOOdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mJNF6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXu[NnhyZn21fnGZdHyKSECoZVeXOGqIWnqMR2KrZViXeXF{UoCmcWWxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVFxT1mERXeKR1GoTVOC[1mERXeKR1GoTVetcVuERXu[NnhyZn21fnGZdHyKSEB6TVSC[1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVeLfWqYSoKQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKTECPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GsZ1eHfXNzWnuKR{R6TViPNWmvUkCkbXesZleXcXSEe3eOR4eoTlePc3SYOYKkNnx3XmOsO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qIfHybcmGoVGODfnSYToqlTFmwTle5cGqvVYOKR2KrZViXeXF{UoCmcWWoT4mDfnSJToObW{SwTXy5fWiIOHmMV3t4SGGw[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVOCUlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKfFyVOXqjNkVxXmd2NFmFNHeLTFKpZ36PcGqFd16EbVGoTVOC[1mERXenVUCMTVOC[1mERXeKR1GoJku{PkF3PjK[W2K1ZWd2UXJz[ICj[{1:Jku{PkFxNkh7JlOob1qiW2moT1OHUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6PYCjcWq3TomseGCu[HylSlqtXkB2bHKYWX:MV3uo[YewTlOScICbbVGwWGeHcmqVc{[bNmZxWUOTenOuWlSjNkWuZWekc1pzNUClXFqqZol6cXGZToqlS163Zn2bdGq6Z4CRWEC4T2ODO1Oob1qEVXuMR2GsTlOUVkClXFqqZkODbHSI[3eRV1KPXWelcF:rdH6bXGKV[Fd6fWqWUo[jcWqxXomocnKZVkGkcVq3UEOTNXOuTo[kS1ZxZVOkdF:4c1qEVXuLTliLenJ{VXeRV1KPXWelcF:rdH6bXGKEXWiPcGKIcImMR3u2Vl[OeVqJVkGkcVq3Z1eHNHGFd1uEVXuLR2OTNHGIcIqNWEWnXleXd2[JTnybV3esZ316enSEe3eLTFq3ZkOSdF:4c1qEVXuLR3esTlOSb3ujcUlxZWebdGlzSkCiW{m2TVRx[2SYSn6bWH93XkKXNGSYPXubW4ewTkKHb3KYcIWVcUlxZWebdGlzSkCiW{m2UEKteWmuPUSLfXt4R3esTlOSb3ujcUlxXnmCPVmISomkcVZ2T1OCT1OSb1qEVXuvZWiP[nOuWnibR3N6VHqCd1mCc1qEVXuLR2Olb2mZVnyZNl[sXleXb1q7NDubS1ZxXmOocmeUNYSNW2GoV1SxdF:vUX6MV4eoR3esTlOSb1qLN16t[H2XfXGZVkWLfkBsUlO4[1Oob1qEVXuLTkOXfXKEZ{mRbXSw[FiTe1:qPI[lN3R{UH2HfXSIcI[NcUWt[FN6eGmY[HyjcmK3UGeXOHSIWoWkNny3Zn6OenKUNUClXFqqZolybGlzUnyjS2[6XWiTenOqPH6NRX:LR2GsTlOU[ECiXGK{XmOkPWCqRl6[W3StU3qxc2qYfIebXFmwTkJyNHSZTnmjfXOxUGR2[mi6[36VW1[vXmd2NHK6Rl6XTG[6XX15[2eYPUGkbVK{ZWePcHKvUnyKS3ipZ4mDcHWJRoCkcW[sTomsd1Oob1qEVXuLTkKTcHNzUomiXFJxZWd6eVq7NDuKSUGpXkKWOl:ubHyjTFKtZ3mocnKZVkGkcVq3TomseGCtPX[MR3SPXWelcHKvVo[KSUGW[GiLbXK6RmqjN2[6TVe5dGlzWoW[NmWoZVeHflmIWkSkS3y6XmeSeVmGSoOjR1KrXWePc2qYVXekS1[vXmiO[3RzSoqKTFqtZmd6NmqYVX6MVX:LR2GsTluVd1uEVXuLR2OTeXJ{VoCbcXyrXWiTdHJzOISRclKpZ36PcFuISomkcVZ2T1OTeXJ{Vn2MV3t4R3esTlOSb1uEVXuL[mGwTlOZNFuEVXt:Jku{PkJ1PjK[W2pxXmiLWGmZXnyWTFq3XliXbnSCQU1jP4N7NUdzPjKEbVGoTVOCTnGYXXeMSUGpXkKWOl:ubHyjTFKtZ3mocnKZVkGkcVq3UEKteWquPH6MV{BsXkKXNGWuWn6VcV[1XmOodFuURkeE[3uLR2VybGpzWU[QcXSt[FVyemqIWoOMR3S1[FiXfWmuPI[jNlq7XmiLNmqZTYmLfXu1VH2HcXSIWomWNlZzXm[DfXJzVkG[N2GwTlibbHOrRYCQe3:LR2hxT1mERXeKRXt:Jku{PkJ1PjK[cW[uZkOLcGVzSkKbWV6p[FeXcnJ{TkVjP4N7NUd3PjKEbVGoTVOCTnGYXXeMSUGpXkKWOl:ubHyjTFKtZ3mocnKZVkGkcVq3UEKteWquPH6MV{BsXkKXNGWuWn6VcV[1XmOodFuURkeE[3uLR2VybGpzWU[QcXSt[FVyemqIWoOMR3S1[FiXfWmuPI[jNlq7XmiLNmqZTYmLfXu1VH2LcGquPYmbWl6p[H2XSGmZVnybNkm6[WOob3SuSomOR3t4R3esTn[Sc3eKR1GoR2F:QTJ8d{pzOEpjXWebNGqZTmS[XGqtVUKHNGqY[I[kcnt:Jku{PkF4NkpjR3mC[1mERVqiW2moT1VybGpzWU[QcXitZliDcHOq[36jXGJyZ32LelxzcIWbcUivT2NxL2pzWkCWcW[vWH2HeGqU[4CMV1J4R3esTlOWNXibNmV3U32lcHSGNY[bS2[{T1OleHSJWom[cUi3ZkKLfmqZTkKbXFm6TomseGCuSn2lS2[6WUKHNmqWUnilS2[vZkOLOVuEVkK[XFm4T2S{T1OScEmEbVGoTVOCTjJ8d{pzOEpjXWebNGqZTmS[XGqtVUJ6eHKYcECXXFq{Jku{PkF4OkpjR3mC[1mERVqiW2moT1VybGpzWU[QcXitZliDcHOq[36jXGJyZ32LelxzcIWbcUivT2NxL2pzWkCWcW[vWH2HeGqU[4CMV1J4R3esTlOWNXibNmV3U32lcHSGNY[bS2[{T1OleHSJWom[cUi3ZkKLfmqZTkKbXFm6TomseGCuSn2lS2[6WUKHNmqWUo[jW{Gx[F[XfXKE[3ulcV[6UVOsO1Oob1qnVX:oTVOC[1OSQU1jP4N7NkR7JmmZWkCjNkGp[FetbmKIPUOjcYi3XWeSQTJ8d{pyOkh7JlOqRXeKR1GLZWe[[1uGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[NNny2Xn15cluUNDubNmZxWX2XcmSuSoSbV3exT2ODO1Oob1qEWUGpXkKWOl:u[HylSUG3XleXd1uE[ISlTG[6XX15enJzToqbXFpzXmiKfVq6b4SRcVZy[Fd6eGmZVoC[NGK3[EJ2d3JzSnuMR3t4R3esTn[Sc3eKR1GoR2F:QTJ8d{pzOEpjXld6N3KufI[[W2KDZn2TTnKvUkC[W4i{Jku{PkV4OkpjSGGw[1mERXeKR1GoTVOTNmmZTYeYfXRyZ{KXfXKuSoSbV3SlTVRx[1q6Z{eFVX:oTVOC[1mERXeKR2JzXWiKe2e6[Ie[XF67[EJ6fWqE[HSKSECoTomkO1SSc3eKR1GoTVOC[1mEVkK[XFm4W4mlb3J{[IWjS{mpXlZ6dGqE[HSKSECoTlibbHOrTUeFVX:oTVOC[1mERXeKR2JzXWiKe2e6[H2iW4itTkFx[2CURX6jXGJyZ32Lelq7d16EbVGoTVOC[1mERXeLTGqpZ3qDZlpzUnilR3SlTVRx[1pzNUClXFqqZomkO1SSc3eKR1GoTVOC[1mEVkK[XFm4W4mle3OuPXuLNUCoVGOCcnKYSn6bW{VxZomkO1SSc3eKR1GoTVOC[1mCNFuKR1GoTVOC[1mERXulXFqxTVRx[3OISomkNm[n[GiLd1uGNXibNmV3U32lcHSGTnikNm[XZ324c1uUb{eFVX:oTVOC[1mERXeKR2JyZ324[2CURXulXFqxW4mlc3J{UkCLNUC2TliXfXGXd36kS1ZxZVOl[F:4NFuKR1GoTVOC[1mERXulXFq{TVRx[3SJToCjV3es[GiLd1yERX6NfXOxU4dxT1mERXeKR1GoTVOCb3SuSomOSoOvZ{KtNGqU[HSKSECoTliXfXKFd16EbVGoTVOC[1mERXeLTGqpZ3qDZlpzcIeLNUCoVGOCb2hyUl[WcGqHWXy{cmVxWmOXb2[UXECHSWKHTX6ZWIOPR3mC[1mERXeKR1GoJku{PkF3PjKbS{l{Zn25emmYVmG[W3StJku{PkN6NkpjSGGw[1mERXeEW3yuTVOpUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6PYCjcWq3TomseGCu[HylSlqtXkB2bHKYWX:MV3uo[YdxT1mERXeKRXuPR3mC[1mERVqEV2K4XWiTc1mFNHeLTGqpZ3qCeGCuUombW1ZxXm[DbHSI[3:MWIOPR3mC[1mERVqEV2JyZ324[2CURXulcV[6UVNxL2pzWkCTS{l{Zn25emmYVm[kcYiZZWiTc2SuPVS[W16wXmOodF:4NFuFVX:oTVOC[1OSb3uiTGK1ZlOCPVmIXoCjS2[nXkKXNGhzUo[jcmKtZn6TfluEVkGkcYexU4dxT1mERXeKRXuLTlepNHKYe4WRV1GqVFOGeFyURXmKR{SoZn16N1uEb3eNbVGqTVNxeGCqTUeFVX:oTVOC[1OScH2iW4itXEODNXSHPXqjNkVxXmd2NHO6[3ukS1ZxZVO4[1qIbECjW4exU4dxT1mERXeKRXuLSGGw[1mERXeEXECPR3mC[1mERVpjP4N7NUZ7JnGYOXubXHiDXUOTdHJzOE1jP4N7OURxPjKFVX:LR2etcVmEbF6[W3StU3qxc2qYfIebXFmwTkJyNHSZTnmjfUmxZn2belq6b4SRcXSt[F[LcGpxOXijW2WwT2Os[3W4NFuEVXuLTlibbHOrRYSRclqtXlOocnKZVkGkcVq3UEKHb3KYcIWiTGK1ZlZ6eHSJWom[cUi3ZWd2b2qZ[36MWIOPR3esTn[URnyjTF6tTVi{UlOob1qEVUCMR2GsTlqINY[bS2[{TVRx[2SYSn6bWH93XkKXNGSYPXubW4ewTkJyNHSZTnmjfUm1[FiXfWmuPH6MV{BsXUK5cGmZTlKjS4iSXWelcHO6[4CQe{CMR2GsTlSSc1qEVXus[H2HfV2ENDubNmZxWX2XfnOIPYWkNmWwT2NxL3NzWkCUS2[pXleXfVuE[FmXSmKSUIqGeV2UZ4OLfmG4UYmDS3J{TnmiW2KsXmd1cluVd16E[3uLR2OTNmmZTYeNWEWvXmiTV2qZUoejNkW7XmOodFyVOYqbXGKEZkKTOVuERXulcV[6UVNxL3R{TnikR3iPXWelcF:rdH:bW4i4XmiKc1pzNUClXFqqZomkdFyVOX[ZfXevTV[lfXJzOX6KS4ixXUKXeXNzWXelTHy4XmO4[3KIcHqbW{W7XmODbnJzVnykfVKpZ32W[3KuPUCKS{Gp[FePc3GYOX6KTGKwZWiO[3GIPYqlR{SvT2OsdF:4NFuEVXx6SGGwTlOSQU1jP4N7NUZ7JnN{cIW[Nni6ZkJ2dHWuWU1jP4N7NkdzOEpjSGGw[1mERXeEVUCMTVOC[1mCb3ukTFqt[H2tcHRxSomkcVZ2TVRx[1qJXnikblG1VH2lcHSHRombXGqxXmilSGmZVnybNkm6[WWtb3O6[4CQe{CMTVOC[1mCb3ukTFqt[H2tcHS6RUmKS3y1Z1e5emqIWX:LfYevUFOCb3OJTnylcXyt[ECHfXOuSkWMWIOPR3mC[1mERVqiW2moT1OTe3OuWkKiW2Z{VGRxe1uURXukTFqt[H2tcHS6RUmKR3O1UWOkO1SSc16EbVGoTVOCTlqIcIW[NohyXleXTXJzNXykS1[vXmOCPVmEVkK[XFm4UGR2c3JzNXykS1[vXmWtfmOYOXqjTG[sXmeSc1uURX2LbVGwTWOTNmmZTYqMWIOPR3mC[1mERVqFVX:oTVOC[1OUVoilW2[6[WWpenKURUmKR3OvU4dxT1mERXeKRXyuZkOLcGmYUn:KR3es[H2HfV6ERnikfVGsZ{OTenOuWlqbR3uo[YdxT1mERXeKRXuLTliHNWqZTkWUS{m1TVN1PVmETlqVcF6HWXyS[2OWOWWVfVKoZmiTNXOuTo[[R1GwXViPNHJ{TnyZNnysXVO4[2mJTnykXG[tZ{OT[nOISkCiS1GxTV[bRmSHWl[WfVGwTXl1b3N{Vo[kcW[LXlN1bVyERX6NfXOxU4mCbV:4NFuKR1GoTVGtPVSSc3eKR1GoR2FxT1mERXeKRXusZ2iXcHOvcFmjNkGGXme[[2CURXmUWUWVVm[LWVmGcF:XSUioXVdyNHSZTnmjNlGoT1eDfnSIPYmbWkmxXleCd1mIRombXFZyXmiPNGh{RnilS3ioT2ODW2GWfG[TWl2oT1SCd1mEZ4[LfXt4TVOKO1SSc3eKR1GoR2FxT1mERXeKRXusZ2iXcHOvcFqjcl2oVGOCbWOWOWSTWlqWTVWtU2[GPHe[S{Fx[GiLbXJzRXeMS1JyZ325[nOuWkOkcXxxXmZ6dGqIRYOKS1K7[Fd6fWqXPYCbS1G{TVeDbmmZVnybNkm6[WZ6dGqIRYOKS1K4Z316b3SYUkCZNnysXVO4[2mJTnykXG[tZ{OT[nOISkCiS1GxSGGwTlOSb1qKR1GoTVODWGKWfF[SNWGoXViXfXKHPYmbXHS6ZWiTcGhzcHu[R4eoXViPNHJ{TnyZNnysXVO4[2mIUnilS2[vZkOLOWhzcHu[R4eoXViDfXJzVkG[N2KnZWeT[1yERnekcW[5[GeXfnSHPYe[XGKwXVFxT1OSb1qEV1GoTVOC[2KtTmCVV1KoXUJ6fWqXPUGkcYinZ32XN3OucECbW1GPR3esTlOSb3eKR1GoTV[lTWKXTl[KRUCMR2GsTlOURXeKR1GoTVOCc1SSc1qEVXuLTVOC[1mERXeKR1GoT1eDbmmZVnybNkm6[WZ6dGqIRXeUWUSoT1OK[1yqRXukTFqt[H2tcHS6RXeNbVGqT2ODRmSsVXe[TFK6ZkKTNWl{Vn[iW2KoTVWtWFmGOW[VSYexSGGwTlOSb1qKR1GoTVOC[1mEb3mN[{CMTVOC[1mCb1qEVXuoTVOCc1uEVkK[XFm5TVOGPVmEZ36MV1FwTVOLRmSsVXeMS1K7[Fd6fWqXPYCbS1GoWHt6WVmGcF:KR3eqTVN1[1qJXnikblWoUHmCbVuUb3mKSH:oTXmKdFSSc1qEVXuLTVOC[1mERXeKR{SqVWV2SVSSc3eKR1GoTVOCTlOSb1qKR1GoT1FxT1mERXeKR1GoR2GsTlOURXeKR1GoT1eDfWqZSkGbXF5xXEODbHSIbHeKSUWRWlODTmSqRX:WNG[OVmWPWVmIRombXFZyXmiPNGh{RnilS3ioTVWbV2RxNHe[S{Fx[GiLbXJzRYCMVUCMTVOC[1mERXeEVXuLR2OC[1mEb3mQe{CMTVOC[1mCb16EbVGoTVOCTlqJSkGbXFp2VleXd1mFNHeKb2KHWFWXWWKURleWb{mPTVeDeHSJWom[cUmoTV[lTWKXTl[KS1K6XmiHNWqZUkCZN1Kp[Fep[1mGcF:KRUCMTVOC[1mCb3eKR1GoTVOC[1mERXeKR1GoTVOC[1uERmSTWYiHVUGS[2mJTnykXG[tZ{OT[nOISkCiS1GoSGGw[1mERXeEV1GoTVOC[1mERXeKR1GoTVOC[1mERXeKSWqUWEBx[1mERne[Nkm6XmZ6NXOufH[kcWZ{Z32tNGqYRV6EbVGoTVOCTlmERXeKR1GoTVOC[1mERXeKR1GoTVOC[2ZxbF[Wb2WoTVOp[2lzSkCbW3S3Z36t[nGYVneKSUWRWlODTmSqRX:KbUSoTliDfWqZXoCbXHOoTVN1[1mqb3eSWUWGTVeDe3OuPXulW15xXEKtb2mERlqWfVKQWmW5UVuURYCKboOPR3mC[1mERVqFVX:oTVOC[1OUVoilW2[6[WWTcHKGbI[jV1F6TVOLSWKWfF[XSWWoVnyLVGSURnejXGJyZ32LemmERmiUSW[UVmOD[3OuWoilW2[7[FZ6e2mZVn:[SECvUImkO1mrd16E[{CMTVOC[1mCb3u[Nkm2Zn2XbnSIcI[jbVF6TVVybGpzWU[QcXSt[F[PdHKu[IObXGK3ZnmocmlzPYmbV{m6XmiPenSZTnqbV3OxUGR2cmqZVlSjNkW2XmePNHGYPYWMR3SrZkOLcGh{[ImiXGKtTomsO1SSc16EbVGoTVOCTnSJTkWKTIOPR3mC[1mERVqEVUCMTVOC[1mCb1qLS163Zn12cGl{VoCjNkS1VH6HNWqZTkWMR1qVWlWHV2[ERmWWb1[QWUCHSG[GcGCVbVmxU4dxT1mERXeKRXuLSGGw[1mERXeEVXyxXnmCc1qIcIW[NohyXleXTXJzNXykS1[vXmOs[1qIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWpenKUb{eFVX:oTVOC[1OScICbbVGwTleteWlzfEGbS2[KZkJycHOISn6bV1GuTnmCb3SuSomOR{BsXkKXNGSZWoOlS3y7[Fd6fWqZXoCbXHOwT2Os[1qIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWpenKWVnybbXt4SGGw[1mERXeEVXusXUJ6eXKuWnqlS3y3ZnlxL3OZWnykcnuwTliHNWqZTkWUW{W7T2S{[1mCNFuKR1GoTVGsTlSSc3eKR1GoR2GtdGqqRX:KV2KxZn2Pd3SYVnyUS{m1XmiDbGpzWYCKR2KrZkJ2eWqYUkCiW{m2UGR2fHSYWommV3esZ2iXcHOvcFWbW4iKZkJxdF:4NFuKR1GoTVGsTlqIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWTcHKEb{eFVX:PR3mC[1mERVqnV1KrXWiTbnGERX:TXHirXmiDNHGYPYWKR2KtT2ODO1SSc3eKR1GoR2Gsb2lzPYWjcW[r[FetenKqNDukXG[tZ36sc1mtTmCVSYiEVWWPUFmqb{eFVX:oTVOC[1OScECiTFq3[ImCb2qVd16EbVGoTVOCTn[SNFuKR1GoTVGsUlOqRXeKR1GLTlePenKuOXy[N2KxZkJ1eGCvSkGbXFp2T1OLSGRxNV6UWmGqT2S{UlOqRXeKR1GLSGGw[1mERXeEVU1:Jku:
|
1 |
+
ZUpyOEq8d{pzNEpjXEKPc2qYUoKVS3yrXmd2bmqSQU1jP4N7N{R5PjKFVX:LR2etcVmE[3iVW1[vXmSwOnGIWoOkS2[6T1OleHSJWom[cUi3ZWd2cXK6Z4CNWEWvXmiTV2qY[F:[W{GtT1OsPWCU[IKkcmK{ZUKHdnOrVX6MV1J4SGGwTlOSb3uiW{WuZomCPVmGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[NNny2Xn15cluUNDubNmZxWX2XcmOYOX2jfXexU4dxT1OSb1qLTGqpZ3qCeGCu[HylSl6tZ4modFyVOXibS2KZXWiLeXGYOX6MR2KxZn2belyVOYSbXF67XWelcFuVd1qFVX:LR2Gsb3SuSomOR{BsZ32Xb1uEZ4GNfX:3ZWd2b2qZ[36MWIOPR3esTlOZTnylTG[6ZnmDcWmYfIqbWIOPR3esTlOSNFuEVXx6TVeXd3NzWXeme{CMR2GsTnOuWkClXFq2TViTfXSYWUeFVX:LR2hxUlOob1pjP4N7NUZ7JnN{cIqlS2[1VUKpcGlzd{1jP4N7N{V3PjKEbVGoTVOCTlOUVnqjN1J2Z32tcnGJVXeRV1Gs[H2HfV2ENDubNmZxVUJ6e3WZToCbNnhxT1OsO1OqRXeKR1GLR2OTNmmZTYeNWEW7XmiTSHJ{RkWkcXyvZViSc1qIUo[kTHy6ZWelc3SEOH6RS1q6TVN5L2SYSn6bW{VxZomDWXSZTnmjfVKFXWePc2qURVuKR1GoTVGsTlOWVnyjW{ioXX6s[2CISXeiTFqtXnpxbXGJVkCkSH:3UEOlN3S6OXikcmKxZol2eWqZVY[jW1[vXmd2NHK6NXymTGKtZn6PdHJzOYqNNkC1[FiXfWmuPIS[W16rXme5cHOuSkCjN1mqTViTdHSIfHyRV1qPWliXfWmuPHeSW16rXme5cHOuSkCjN1mqVHew[1mERXeEVXuLWGeHcmqYOUCjfVK7Z1eXcGqFe4[[WESo[GiC[2mvb3eSWlqWV2V5cluVd1uKR1GoTVGsTjJ8d{pzNEpjXUKpcGlzeGObXF64ZkJ2fmqSQU1jP4N7Nkh{NkpjSGGw[1mERXeKR1GoTVOC[1mCcICbbVGwTlibbHOrRYCKTIOPR3mC[1mERXeKR1GoTVOC[1OSb16EbVGoTVOC[1mERXeKR1GoR2Gsb3SuSomOfUBsXEOLcGpxcIWbcUi1VH2PemqIWXeRV1KxZn6TNmmYe3:kN2[qZ{OTfVuEVkK[XFm5W4qD[FyERYeNR1Gs[H2HfV2Eb4CQe{CMTVOC[1mERXeKR1GoTVOCTlOYcH2MR1KxZnx6bHOvTnimV3es[H2HfV26NDuZN1qtXkCteWquPISRcV63XleWd1mISomkcVZ2T1SGe1yFTYeNSF24UFSSe1uUb3eMV1J4SGGw[1mERXeKR1GoTVOC[1mCb1qEVUCMTVOC[1mERXeKR1GoTVOCTlOScICbbVGwXUJ6NXKvVX:LTGqpZ3qGdFmFOEmKSF2xTVi{UlOqRXeKR1GoTVOC[1mERXeEVXuLR2FxT1mERXeKR1GoTVOC[1mERVqEVXuLUIl5[2WISomkNmWo[FepcFmIVnilS2WPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR2KsXWiTcFmFNHekN2K6XEOLcHOIfHi[NmWwTol1clyERX6NfXO{TViTfXGYNH:LTGqpZ3qHZl2XNICMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR2JzXWiKflyVOX[kcW[vV2d2cXK6NDubS1ZxXmOCPVmGNXibNmV3U32pcHKJRnykbXevXUJ6fWqUZ4CNWEWuZkOLeGmZVlW[XGKtT1OTb2mZVnyMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKRUCMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeNfUioWVeHfXNzWXelS3itTVd2bHKYWV6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mEVkK[XFm7UGR2[nOuWn6UW{WuZolxL3KuSoSbV1F6TViTfXGYNH:LTGqpZ3qHZl2tNICQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERY[NfVKSXWiLfmqURkCiS2WoXUJ6eHOISoWmVUCMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLTGqpZ3qOeGCtPYmbW3SLZn2belyVOXqjNkG4XWd2OVmFNHeiXF67XmiSc1qJXnikbl[jUUFxdFmFPHelTFqxZmOob3SuSomOWoO7XGOs[1:qRX6LfoOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKRUCMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeiW2moT1OTNmmZTYqNWEWnZ32XcmOYOX2jfUBsXUJ6b2qURUmRV1G5UVOs[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1OUVkK[XFm7UGR2[nOuWn6UW{WuZolxL3KYWoqkNl[vXmOCPVmEVkK[XFm7UGR2[mi6[36VNIOvT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVhx[2qYfIqbV1KxXnmCc1qJXnikbl21VHx6fWqY[FqjcWq3UGR2bnJzVnyKSEB6TVSKe1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTlibbHOrUYSRclqpZWiPcGSuPUCiW16tT1SGe12Ee3eLTGqpZ3qOeGCtPX[MR3SLWHubVGhyWmGTNVqDVlWX[mSGcFSTWUWVVmZ6SmeHRlqWb2[GTomsdF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[3[URnyjTF6tTVetcVmE[3ulcV[6UYlxL2h{TnybNHy2Xn15eGCuUo[bS2WoVGRx[127RYCKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOCb3SuSomOfUBsZ32HdHNzWl:jN2KxXUKWc12VRYeNR1Gs[H2HfV26NDuZNUiwTkCtU2KsPX[XWlKJWXuHSWKXPV:VNWKnVWWPWWOXXl[LfXuxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mEVkK[XFm7UGR2[nOuWn6UW{WuZolxL2qISkCbV1F6TVOTNmmZTYqNWEWnXImocmSuPUCKS1[r[FetNmmZVnybR1J2XmiScluVd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mJNHebW4i7XmODdGqqRX:LTGqpZ3qOeGCtPYmbW3SLZn2belyVOXqjNmKtTVRxPVmFVYeMV1J4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GLTVOTNmmZTYqNWEW6XWetfmqWOY[lS3yrXmOofF2FRYOKR2JzXWiKflyVOX[ZfXevVlV6UmGWcF:KSWKRVm[O[2SsPWWKSUGDWlWPTVq6b4CQfVGoTVOC[1mERV6EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[1mJNF6EbVGoTVOC[1mERXeKR1GoR2GsTlOSNFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1J6TVeXd3NzWXeme{CMTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOCTlqJXnikbl21VH6LbHGZUnyVcUlxZWePcFuFSYeOR4eoTlibbHOrUYSRcEmnT1OlSmWtTmCWcEmUVmWl[mFxbF[SNISnVnuHTmSEZ4CMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERXeKR1GLR2GsUlOqRXeKR1GoTVOC[1mERXeEVXx6TVeXd3NzWXeiW2mwTVOTNmmZTYqNWEWnZ32XcmOYOX2jfUBsXUJ6b2qURUmRV1F2UVOCdFmJd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTlibbHOrUYSRclqpZWiPcGSuPUCiW16tT1SGe12Ee3eLTGqpZ3qOeGCtPX[MR3SHWXyLVGWtPVWVNXSQWFV6RmKHPVqTSkmQWEGT[mKsPW[Vb2GvT2OsO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[3[URnyjTF6tTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCTlqJXnikbl21VHx6fWqY[FqjcWq3UGR2bnJzVnyKSEB6TVNxfF:4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mCb3ulcV[6UYlxL3OuSoCkNm[QZkOTdGlzWX:OWFG4UFOCb3SuSomOfUBsXEF5c1pxWmOWb{mUXEGLSmJyPVSUSW[FV{F6S2GWcF2LfXuxU4dxT1mERXeKR1GoTVOC[1mERVqEXECPR3mC[1mERXeKR1GoTVOC[1OSb16EbVGoTVOC[1mERXeKR1GoR2hx[2qYfIqbV1J4SGGw[1mERXeKR1GoTVOC[1mCb1qLTGqpZ3qOeGCvTniiXF6tWH16NHGYUnyMSFW4UVO4[1qJXnikbl21VHx6[luE[F[WcFqRWXx6V2KW[H[SNHiHVUC1[mKsSlqVR3OxT2S{UlOqRXeKR1GoTVOC[1mERXeEXECPR3mC[1mERVqEVU1:Jku{PkF3PjKWS{m7[F[LcHOZWnykN2F:Jku{PkV{OkB7JlSSc3eKR1GoTVOC[1mIcH2MR1KxZ{F6bHOvTnimV3es[H2HfV6Eb3eLbWmoXUJ6NXKvVX:LTGqpZ3qSdFmFOHeOR1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR{i3TVebenOuNXilR1G1UGR1[3SIWoqlSFV6XWObNGqZUkCObkGqTVeXNGm6OF6EbVGoTVOC[1mERXeKR1GoTVOTNmmZTYeKSECoXWiLfWmZb3:MWIOPR3mC[1mERXeKR1GoTVOC[1mJ[H:iW4itT1ODd3GZUkCMR2K2UFOCb3Sqb3eRV1KtXWePc1uEVkK[XFlxT2OCdFmJd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERXulcV[6UV[1[FmFNHeKbWK2VGOTNlmrd16EbVGoTVOC[1mERXeKR1GoTVhx[1mERXeFVX:oTVOC[1mERXeKR1GoTVOCb3SuSomOR1F6TVeteHOIfI[bS2WwTom[clyERXulcV[6UVOsO1SSc3eKR1GoTVOC[1mERXeKR1GsXUJ6eXSIWoWlSmJ2Z1eW[2CURXmSNkm2[FeXeXSENUCmXFKtU3mDbHOJRoOiW16p[FetenKqPUSNXHR{[IlycXJ{ToSNXG[6ZleXeWlzPXubW2KkZ3y5eVmrd16EbVGoTVOC[1mERXenVUCMTVOC[1mERXeKR1KtZliPcFmJd16EbVGoTVOC[1mERXeKR1GoTVOTNmmZTYeKSECoTlibbHOrVUeFVX:oTVOC[1mERXeKR1GoTVOCb2lzPYWlS2[2[F[TOXOIWXeRV1GqVUJ6eXSIWoWlR{Fx[WiDcF:qRkCbXHhxUEOpeHKHfImZS{SqU4dxT1mERXeKR1GoTVODPVSSc3eKR1GoTVOC[1mCNFuKR1GoTVOC[1mERoCbbXeoZWiP[nKvWoOjR3es[H2HfV26b3eMV1J4SGGw[1mERXeKR1GoTVGsb3SuSomOfVF6TVVybGpzWU[QcXSt[F[PNHJ{TnySNkm2Xn2tcluETkObW1m3[Gd2fmqYUkGkcWW3XX2HfmqXPUGkcYeqT2S{UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKflmFNHekN2K6XEOLcHOIfHi[NmWwTol6dHKuVnymR{W4ZViCemmYVoSiW{SvUFOCclq6e3eLTGqpZ3qOdF:4NFuKR1GoTVOC[1mERXeKR1GoTlibbHOrUXeRV1K7[FiL[nOuWoejS1[rXmOoclxzcIWbS2Z1UH6Dc3OEPH6NR1GvTom4[1qJXnikbl2xU4dxT1mERXeKR1GoTVODPVSSc3eKR1GoTVFxT1mERXeKR1GoTVOCely6Roe[XFq7XmODNHGIWXebNnxzXmd1[2[XTl2FVX:oTVOC[1mERXeKR2JzXWiKfVmFNHekS1[6Z{KX[nSZToOMR2JzXWiKfVuVd16EbVGoTVOC[1mERXeiW2mwTVOHdHN{UnylR3es[H2HfV2td36kNl6wXmdycFpyNICKTIh5TVOob3SuSomOcIOvZ{KPc2qYNXyLNUCoTWRx[1pzbEClTFGvT2OCdFmJd3eFVX:oTVOC[1mERXeKR1GoTVODfWqZVkGkcUSoXn2Hd3NzWUeFVX:oTVOC[1mERXeKTECPR3mC[1mERXeFVX:oTVOC[1mERXeKR{i3TVeXOHSJTni[N2GoZVd6fnSERnijcWGoZ1eHNHGFc16EbVGoTVOC[1mERXeLS3i3Z{OS[2CURXulcV[6UXy{cnGIPYqlR3SlU4dxT1mERXeKR1GoTVOCb3OISkCiR1F6TVetfnNzWkCMR2JzXWiKfWe6[Ie[XGKwTkFxdFmFPHeLTGqpZ3qLZlp{RnilS3evXGOCOlmEZ4[LfoOPR3mC[1mERXeFVX:oTVOC[1mERXeKR{i3TVd6e2qYOHe[V1K7ZkKPdmqZVXe[Nkm2Zn2XbnSIcI[jbVK3ZnmDe3J{TkCKSHe4SGGw[1mERXeKR1GoTVOTcHOvToWjfVF6TVd2NXKIe{eFVX:oTVOC[1mERXeKR2KtZ36LfnSJTXeRV1K2[Ge5d1:4NFuKR1GoTVOC[1mERXubclGoVGODRWqvUo[[NoS3Z1eXeVuEVn:jN15xUFOCOF2Ee3eLS2[6Z312elyERXubXFq6Z{OTfVyERUGMWIOPR3mC[1mERXeKR1GoZWe[c1mEVn2kR1F6VGRx[2quSoOkNmWoT2ODO1SSc3eKR1GoTVOC[1mERXeKR1K6XmiTNXOuOHebcV[{Z{KWO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1mERXeFVX:oTVOC[1mERXeKS3yuTVOobHGZUn[jcm[{ZlOob3SuSomPbXuxTVi{UlOqRXeKR1GoTVOC[1mERXeKR2JzXWiKNlmFNHeKcG[7XmiKeGGY[HyjcmF3TVOKeVqJXnikbmm2TXy5fWiIOHmQe{CMTVOC[1mERXeKR1J6SGGw[1mERXeKRUCMTVOC[1mERXeKR1G3UImDfmqYOXuKTGKwXmODfWqZSkGbXF5xSGGw[1mERXeKR1GoTVetcVmE[3ulcV[6UmOCPWCURX6kS{m7[FOkdFmJd16EbVGoTVOC[1mERXeKR1GoTVebe3SZVoqMR2KuZ1O4[1mtRmCWNWGoTliDbHSI[3eUSmKWWVN5fFyrSnOkcIi2TXmsO1SSc3eKR1GoTVOC[1mERXeKR1KxXnmCc1mYcIqZNkVyZle4c1qJXnikbmmxT2ODO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[2qvRkGlTF2wTlebe1yERXulcV[6UnmsO1SSc3eKR1GoTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR1qKZkOPNF:qRXuiS{m7[F[5fWiIOHmMWIOPR3mC[1mERXeKR1GoTVOC[1mIXoelXGK7T1OTcXOEe3eKcFqtXn2XfWqZTU[KR2JzXWiKfmiJTnOjbVmxU4dxT1mERXeKR1GoTVOC[1mERXebclJy[FiOc1qIXoeNR1GsXUJ6eXSIWoWlSmJ2Z1eWdF:4NFuKR1GoTVOC[1mERXeKR1GoXn6DNXSJUX:LS2q4UFOCbWFzPYWlS2[2[FNyd2qYOX6lS3d3TVOKeVmJUkCkcYitZnmob3SuSomOR3uoUHmLZ3OtfIWKbXt4SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR1qFZkJ2eWqYUkCiW{m2U3mDbnKIPYqbWoi6XFd2Z3OtfIWKbXt4SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR2JzXWiKe1uVd16EbVGoTVOC[1mERXenVUCMTVOC[1mERXeKR1KtZliPcHGYXXeMR2JzXWiKNVmFNEmKR3SvXmiScluURkeFVX:oTVOC[1mERXeKR1GoTVOCb3OZWnykcnuoVGOCclq7d16EbVGoTVOC[1mERXeKR1GoTVetcVmEbICkN16t[FOob3SuSomOcIOvZ2iXcHOvb36ZV3uxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3OZWnykcnuoVGOCcmC6Z4WLTGqpZ3qLZlp{SkGbXFp2TkFxO1SSc3eKR1GoTVOC[1mERXeKR1J6SGGw[1mERXeKR1GoTVOC[1mERn2kTGZxZ4mob2qvRYOKR1qJVm[S[3W6Voe[XGKw[mi{b3OZWnykcnx6TVWpWW[HRY[OV{S5XFiLZ3KqTYCQe{CMTVOC[1mERXeKR1GoTVOC[3GYXXeMR1[xZ{F6eXSYfIOMR2JzXWiKNluUb3eme{CMTVOC[1mERXeKR1GoTVOC[1mERXeKS2q4[GiTfluEVn2kR4eoTlibbHOrXYCQe{CMTVOC[1mERXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERXeKR1GoXn6DNXSJUX:LS2q4UFOCbWOIPYqlSH:oTlepenN{VnOkcIi2TXmsO1SSc3eKR1GoTVOC[1mERXeKR1KuZ1iXNHO6[3ubclG{TVOLSHJzOYWbW15xZWd6eV:qRnqjS{m7Xm[5fWiIOXOkcIi2TXmsO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1SSc3eKR1GoTVOC[1mEVombXF5yZliS[2CURX6LfoOoSGGw[1mERXeKR1GoTVilc3GYfHyMR1[uXmd6cVuEVn2kR3uxTVi{UlOqRXeKR1GoTVOC[1mERXeKR{i3TViLcGlzWoClcWWo[FepcFmJTnykN2[{[FiO[3JzXXelS3itTViLcHOZWnykN2GPR3mC[1mERXeKR1GoTVOC[1mEVombXF5yZliS[1yrNHebcXSt[FiOc1qIXoeNR1G5UXqodF:4NFuKR1GoTVOC[1mERkmFVX:oTVOC[1mCNFuKR1GoTVOC[1mERY[NfVKrZld6fmqURkCiS2WoZ{J6bnFzWkCKS163Zn12cGl{VoCjNkR3SGGw[1mERXeKR1GoTVebbnKIPYqbV3esXn6CdF:4NFuKR1GoTVOCUlOqRXeKR1GoTVOC[1y6PHekN1K{ZWiS[3SIbHyKTFqtZ{OXd3SERn:bW1[sXmiK[2qvTo[jV1JxZVeW[2lzPYWlS2[2[FFxT1mERXeKR1GoTVOCb3OuWoqlW4hxTVRx[2qZbIejS{msXmOobWiJTnOjcIi6XFd1bVyERXukcW[7[Ge5NFyERYmMWIOPR3mC[1mERXeFVX:oTVOC[1mERXeKR2KwXmeHb2qZTXeRV1KxZ{OPcHSE[3ukcW[7[Ge5NGe7RnSMV1FwTVOTfWqZUkGjTGKjUVZx[1:qRX6LfoOPR3mC[1mERXeKR1GoTlePenKvVnyjcmGoVGODdHN{UnylR3esZ32XfnSYfECYfl[lT2OCM1mEVombXF5yZliTZl2XNHeQbVGvToq{UlOqRXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mEVkK[XFm5TVRx[3KuWkOKTF5xXlWPd2mZUoqMR3t4SGGw[1mERXeKR1GoTVOTNmmZTYiNWEWwXmeHb2qZTXeRV1GsZVeXbGqIWomQe{CMTVOC[1mERXeKR1Gs[H2HfV2UNDu[Nkm2[FeXeXSERUmKR2KrZkJ2NGqYOUCQe{CMTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoUIl5[2OISoWbS4itTVePc3SYOYKbW2Go[FiLbHKvUn2bXFmoZWe[[3KuWnybS2[sSGGw[1mERXeKR1GoTVetcVuERoqlTFq4ZkOOc3N{VomlS{m{ZkOlcHOq[3ulcV[6UWNxL3GIWnibS2[6T2O4[1p{Vom[W{W7Xn2XfVyYWoW[NkmsZWd2cl:qRnqiTG[2ZUKXb1q6b3eKWEB6TVebbHKJUnyKR3uo[YdxT1mERXeKR1GoTVOC[1mERXeLTFKpZ36PcGqERUmKR3OvU4dxT1mERXeKR1GoTVOC[1mERXeLS4itXn6S[2CURXulcV[6UWNxL2lzPYWlS2[2[FS{UlOqRXeKR1GoTVOC[1mERXeKRUCMTVOC[1mERXeKR1GoTVOC[3RzbICjS2WwTViTfXSYWXeMV1J4SGGw[1mERXeKR1GoTVOC[1mERXeKR1GoTliDenO6RUmKTF5xZ36DenO6[3ujS2[u[FO4[1mtfImZS{SqT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVODdGqq[3eLTFK3Z4mCPWCVNHebcV[{Z{KW[1uURkeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoTViLcHSJWomjbVGs[H2HfV2Vd16EbVGoTVOC[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeLS16w[Gd2dnNzcE[bV1F6TViPNWmvUkCkbXesZleXcXSEe3eOR4eoTliDenO6b{eFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeLTFK3Z4mCdmCURoqlTFq{Xmd1c1mtfImZS{SqT2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCb3KIWn2lR1F6TViPNWmvUkCkbXesZleXcXSEe3eLTFK3Z4msO1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1SSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qJRo[kfVF6TViPNHOvRo[kfXesXUKpNXKueIqiXICtUFOCcl:6Z4CQe{CMTVOC[1mERXeKR1GoTVOC[1mERXeKS3yuT1OCb3OIPYqKR1V6VGODcWmYfIqbV1GxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeLS16w[Gd2dnNzcE[bV1F6TViPNWmvUkCkbXesXUKpNXKueIqiXICtUFOCe1yERXukS{m7T2S{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVODPVSSc3eKR1GoTVOC[1mERXeKR1GoTVOC[1qIUn:lW{WzZ{KtOmqURUmKS3it[VeTcGm6[3u[NnhyZn21fnGZdHyMWIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GPR3mC[1mERXeKR1GoTVOC[1mERXeKR1KxXnmo[1qIUn:lW{WzZ{KtOmqURUmRV1G4TVOs[3W4NFuKR1GoTVOC[1mERXeKR1GoTVOC[1mERXeKR1KqZ32XbHG7d16EbVGoTVOC[1mERXeKR1GoTVOC[1mERkmFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeFVX:oTVOC[1mERXeKR1GoTVOC[1mERXeLTFKpZ36PcGqERYWRV1K7[GeLfnSJTX:LS4itXn6Sd1mFRYOKR2KrZViXeXF{UoCmcWWxU4dxT1mERXeKR1GoTVOC[1mERXeKR1GoTVOTd2qYXkCKSECoZ{OXbXN{VomMR2K{XmebNFyERXu[NnhyZn21fnGZdHyKR4OoZ{OTfXKIWoWMR1qkZ3y5eVmqb4CQe{CMTVOC[1mERXeKR1GoTVOC[3[SNFuKR1GoTVOC[1mERXeKR1GoSGGw[1mERXeKR1GoTVOC[1mERXulcV[6UWNxL2lzPYWlS2[2[FOCPVmEVoe[XFq7XmeSO1SSc3eKR1GoTVOC[1mJNF6EbVGoTVOC[1mERXeKRU1:Jku{PkF3PjK[W2K1ZWd2UXJz[ICj[{1:Jku{PkFxOER7JlOob1qiW2moT1OHUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6PYCjcWq3TomseGCu[HylSlqtXkB2bHKYWX:MWEB6TkK1fXSIfIK[W4S6UlOkdFmJd1uEVXuLZWe[[1uGNXibNmV3U32lcHSHUkCjN1qtVUJ6eWqucH6MR3S1[FiXfWmuPI[bcXy6Z{OTbnJzOX2iW3OvT2RxPV2Eb3eme3:LR2GsTlOob1qEVXus[FiXfWmuPYe[XGKwTVRx[2SYSn6bWH93XkKXNGV{Vo[kcW[FZkJ2cXGYZ3:LNkFx[GiLbXK6PUClXFqqZkODbHSI[36MWIOMR2GsTlOUVomjNklxTVRx[2SYSn6bWH93XkKXNGGuSoqbWWKxZ3modFysVmSNbWJx[GiLbXJ{RnilS3d4R3esTlOSb3ulcV[6UVNxL2hzVnyjSmK6XmeWc1qJTo[jN2G{TVOTfXJzPUCMWIOMR2GsTlOSc1qEVXuLTld2enSIcH2iW16p[FetenKqRUmKSUGpXkKWOl:u[HylSUG3XleXd1uE[HibS{GxZnt2enSIcH2iW16p[FetenKqPYCjcVq3[VOkdF:4c1qEVXuLTld2enSIXXeRV1KpZ36LbHWU[3eE[3uLR2GsTlpzcIqZN1qtXWeScmCVOIeNR1GMR2GsTlOSb36bS1ZxXmZ6bGqIVnybR3N6VH2TbHSIWX:LNXu1ZmNyb1mG[{[iWIC7Tomsd1mCc1qEVXuLR2OlfmqZXnykcXxx[WOkPWCrVYOKRX:LR2GsTlOU[EGkcYevVGR1cnGJVkCkSH:3UEOlN3S6OXikcmKxZol2eWqZVY[jW1[vXmd2NHK6NXymTGKtZn6PdHJzOYqNNkC1[FiXfWmuPIS[W16rXme5cHOuSkCjN1m3Tom4T1OSb1qEVXuv[FetNHKIWX6RWESoWGeHcmqVc{[iS2[{Z1eXfVuE[ISlTG[6XX15cluUNDuZNUiwTkBybGpzWoWlS{ioWG[TNXOuTo[KSny3[GiK[3KIcHqbW{W7XmODc2mZUXebXHi4ZWiLcGqEZ4CNRX:LR2GsTlOU[HubXF6rZ32te3SIcI[jbXN6VHmDUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6Z4CNWEWnXImocmSYSn6bW{VxZomDUm[JWom[cUioW2d6NXOqRoOiW16tZn2PcFmIbHikfVKt[ViDdHOuWnuNbVKDZle4[2lzSnqiS2[sTViDbGpzWoqKTHSpZ4mDfWqYNY[lcW[sTomsT1OSb1qEV3t4R3esTlOSb3ujcUlxZWebdGlzSkCiW{m2UGR2e2mZToqbV3ipZ36LbHWU[3ujcUlxXnmsdF:4c1qEVXuLR3esTlOZNFuEVXx6R3esTjJ8d{pzOEpjXWebNGqZTmS[XGqtWViLemqJWnqlRU1:Jku{PkF4NkpjR3mC[1mERVqiW2moT1VybGpzWU[QcXitZliDcHOq[36jXGJyZ32LelxzcIWbcUivT2NxL2pzWkCWcW[vWH2HeGqU[4CMV1J4R3esTlOWNXibNmV3U32lcHSGNY[bS2[{T1OleHSJWom[cUi3ZkKLfmqZTkKbXFm6TomseGCuSn2lS2[6WUKHNmqXRomjNmJyXUOSc1qJXnikblGxU4ewTlOZNFuKR1GoTVGsQTJ8d{pzOEpjXX2XcXJ{TnyWNlZzXmWPbHSIWn6jN1p2Jku{PkF4OkpjR3mC[1mERVqiW2moT1VybGpzWU[QcXitZliDcHOq[36jXGJyZ32LelxzcIWbcUivT2NxL2pzWkCWcW[vWH2HeGqU[4CMV1J4R3esTlOWNXibNmV3U32lcHSGNY[bS2[{T1OleHSJWom[cUi3ZkKLfmqZTkKbXFm6TomseGCuTnybcUm6Xm[PbHSuWlS[XGKtXkJ6fXWU[3ulcV[6UVOsO1Oob1qnVX:oTVOC[1OSQU1jP4N7NkR7JmmYXkCbXFqVXWibcGFzSkCbW3S3Z36sQTJ8d{pyO{J7JlOqRXeKR1GLZWe[[1uGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[NNny2Xn15cluUNDubNmZxWX2XcmSuSoSbV3exT2ODO1Oob1qEWUGpXkKWOl:u[HylSUG3XleXd1uE[ISlTG[6XX15enJzToqbXFpzXmiKfVq6b4SRcV[u[FeXfWVzSkKbWV6p[FeXcnJ{TkWMR2JzXWiKe1uVd1uEVXx6R3mC[1mERVpjP4N7NkR7JmmYXkCbXFqVXWibcGFzPYSjW3xxWmiLdzJ8d{pyO{Z7JlOqRXeKR1GLZWe[[1uGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[NNny2Xn15cluUNDubNmZxWX2XcmSuSoSbV3exT2ODO1Oob1qEWUGpXkKWOl:u[HylSUG3XleXd1uE[ISlTG[6XX15enJzToqbXFpzXmiKfVq6b4SRcV[u[FeXfWVzSkKbWV63ZmdydHSHWomjR3es[H2HfV2Eb{eE[3uL[mGw[1mERXeEVU1:Jku{PkJ1PjK[XGZxZkJybHSIcHqTS{l{Zn25emmYVU1jP4N7NUZ5PjKEbVGoTVOCTnGYXXeMSUGpXkKWOl:ubHyjTFKtZ3mocnKZVkGkcVq3UEKteWquPH6MV{BsXkKXNGWuWn6VcV[1XmOodFuURkeE[3uLR2VybGpzWU[QcXSt[FVyemqIWoOMR3S1[FiXfWmuPI[jNlq7XmiLNmqZTYmLfXu1VH2HNXSIPYS[XGKxXUCTenRzOYOjNl[sT1OsO1Oob1qnVX:oTVOC[1OSQU1jP4N7NkR7JmqIPUOjcYi3XWeTRnKuVlqjcl5xXWe5dzJ8d{p2O{Z7JlSSc3eKR1GoTVOC[1mEVkK[XFm4W4mlNXNzWomjcV[1XmOl[FmFNHeLfXN4SGGw[1mERXeKR1GoTVOTNmmZTYeYfXS4XWiPfnRzPYmbR3SlTVRx[1q6Z{eFVX:oTVOC[1mERXeKR2JzXWiKe2e6[HujN3S2Zld6bGqHPYCbR3SlTVRx[1qJXnikbll4SGGw[1mERXeKR1GoTVOTNmmZTYeYfXSuZWe5cFpyNHeRV1GvZmiTNXOuTo[LfoOPR3mC[1mERXeKR1GoTlibbHOrRnKLNl6p[FOl[FmFNHeLNkFx[GiLbXK6Z{eFVX:oTVOC[1mERXeKR2JzXWiKe2e6[IekcUmsTkFx[2CURX6jW1[vXmd2NHK6Z{eFVX:oTVOC[1mERXeKRUCMTVOC[1mERXeKR1Gs[GiLdFmFNHekS1[6Z{KX[nSZToOMSUGpXkKWOl:u[HylSVqpZ{KXWnOue3:MV3t4SGGw[1mERXeKR1GoTVOTNXOue3eRV1Gs[GiLdGe6[H:jN15xTkFxeVqJWomiWoOvZ1eHNHGE[HSQe{CMTVOC[1mERXeKR1Gs[GiLd1mFNHelTFqxZmOob3SZToONR1GvUImkdF:4NFuKR1GoTVOC[1mERXulcV[6UV[{cnNzcECbV3SlTVRx[1qJWomjSIOPR3mC[1mERXeKR1GoTlibbHOrRnKLNny4TkFx[2CURXuZNV6HWXybSmWtd36WNG[UWnuXV2hxSlWTSlmvXGS{UlOqRXeKR1GoTVOC[zJ8d{pyOkpjXld6N3KufI[[W2KSXWelcDJ8d{p2OUZxPjKEVUCMTVOC[1mCcICbbVGwWGeHcmqVc{[iS2[{Z1eXfVuE[ISlTG[6XX15enGYOX2jfXOxUGR2cmqZVmObW3SQXWdycFuEb{mRV3SzZ36Td3FzSoKkbmGvT2ODO1SSc3eKR1GoR2FxT1mERXeKRXuLTlibbHOrUXeRV1GvToq{UlOqRXeKR1GLR2OTc3SINYOKSECoTomkO1SSc3eKR1GoR2GsUlOqRXeKR1GLR2etcVmE[3ulcV[6UlRxPVq6Z4CFVX:oTVOC[1OSb1qLTGqpZ3qS[2CURlKkcmKxZkF6Um[JWom[cUmnV1eXd3OIWomZNGKp[FeGOl:u[HylSV63Zn2bdGq6[4CNWEWvXmiTSXJ{[IWjS{mpXlVycHSIbI[bR3exU4dxT1SSc3eKR1GoR2GtdGqqRX:LTGqpZ3qKdFmCNFuKR1GoTVGsTnW4NFuKR1GoTVGsTlOUVoe[XGKwTVRx[1qJXnikblG1VH2PfWqYSkCbWlKp[Feoc1uVd16EbVGoTVOCTlOSb3ulXFq{TVRx[1qJXnikblG1VH2lcHSGVo[lNkW{ZkKHb2[ZToOXNnxxZVV2emFzSnqiS2WwT2S{UlOqRXeKR1GLR2hxUlOqRXeKR1GLR2eXd3NzWXeFVX:oTVOC[1OScEeFVX:oTVOC[1OSb1qLTG[6ZlOCPVmGNXibNmV3U32lcHSHWomjR3exU4dxT1OSb1qEV2JyZ324[2CURoqlTFqnZ32Xe3KISnqbV3eqXWeTeHGYOI[KbYeoTXmKd1mEVkGkcYexU4dxT1mERXeKRXuL[mFxT1mERXeKRXuLSGGw[1mERXeEVXxxZ36s[1SSc3eKR1GoR2GtO1SSc1qKR1GoTVGsTnN{[IClS16wTVOob3SuSomPR3uPR3es[1mERXeEVXx4SGGwTlmERXeKRXuLR2FxT1OURXeKR1GLR2Gsely6RmSlS1[2XleHfWqERn2iW4itTVelcHSERnqjNkVxXmd2NHO4NFuEV1GoTVOCTlOScHq[XF6tTVWTenRzOYOjNl[sWGeXNHGIPXukfn93VnutUWKXPViTWmKnVUB6U2[GWl:XSl13SGGwTlmERXeKRXuLR2GtdGqqRX:iW{WxXEKlcHSE[36[W4i{ZkOl[nSZToOZNmq3Z1eXeVq6b3eRWECoToqGcluSNFuEV1GoTVOCTlOSb1qEV2Kw[Fdyd1mFNHebcXy{XmZ6cmqZVn[[Nkm2[FeXeXSJUX:LTG[6ZlOsO1SSc1qKR1GoTVGsTlOScHyjTF6tTVFxT1OURXeKR1GLR2GsTlOUVkK[XFm7TVRx[1mGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[LfXu1VHx6[luETmSbXGJxZWd2clmE[HijS4i3[EF6NXOufH[bcUm4Xmd1clmIcIqKS2KxZ{KHbXKIWnuNbVmxU4dxT1OURXeKR1GLR2GtbXOuWniifoOPR3es[1mERXeEVXuLSGGwTlmERXeKRXuLR2N5elmGVo[lNkW{ZkKHb1mIPUKbXFmoZ{J6bnFzWkCFVX:LTVOC[1mCb1qEW16pZ{KW[2KIPUOjcYi3XWeTUmqZVn:jNmK7U3qxWGRxUlyTWmF3R2GsTlSSc1qKR1GoTVGsTlOSb3ukcW[7[Ge5NGSvWoS[cW[6VGSCO1SSc1qKR1GoTVGsTlOSb3ulcV[6UYpxclq7d16E[{CMR2OC[1mERVqEVXuLTliLcHOZWnykN2GoVGODe3OuWn6ZN1qtZ1e5bGlzWX:LfUmw[FiTe1uJUYCmflG{UWhxOmiEPXONNYSmXFN6[FuqPH6NR1GvTom4[1qJWomjR3t4SGGwTlOSb1qEVXuPR3esTlOSb1qEV2K1XWiTbnGIWoqKSECoXWiLfWmZb3:MWIOPR3esTlOSb1qEXFK6Xmel[nKYSkC[NnewTkCD[VuFPE[iTGJxZ1Swely6bz:MSoSmUEFxdluWRoCLfYeoTliXfXKEe3eLS{Gp[FePc2qZUYCQe{CMR2GsTlOSb1qLS3i3Z{OS[2CURXujW1ZxXUKpcHNyd4iZWIOPR3esUlOob3eKR1GoR2GsTlOUVn2kR1F6TVebfnJzUoKjN1KtZnmob3GIPYqlR4eoU1SCd1mEVombXF5yZliTU3SYNXmbXFm{TVOTcHOvTo[kb{GtZ{OPbGpzWYCQe{CMR2OC[1mERVqEVXuLZWe[[1uESXubclGxSGGwTlmERXeKRXuLR2GtO1SSc1qKR1GoTVGsTlOSb1qLTGqpZ3qO[2CURXubXFq6ZkOLUmqZUoq[W3StU4dxT1OURXeKR1GLR2GsTn[SNFuEV1GoTVOCTlOSb1qbW4i7XmFxT1OURXeKR1GLR2GsTnW4NFuEV1GoTVOCTlOSb1qEV2K3[GiS[1mFNHeKb3SHWlOCb3OuWoilW2[7[FODTW[HVmGNflW2UW[5fWiIOHmQe{CMR2OC[1mERVqEVXuLR2OTenSZVXeNbkCoTXupenN{VU[KR2KwZkOPNGiJTnOjbVl4SGGwTlmERXeEV1GLR2GsTlOUVo[lXGGoUHpx[1msUo[jcUWtXUOTdHJzOE[KSV6{ZkOPcGiJTnOjbVl4SGGwTlmERXeEV1GLR2GsTlOUVo[lXGGoUHpx[1mtfImZS{SqU4dxT1OURXeKRXuoR2GsTlOScH2lN1qx[FeWc1qIXoeNR1GsZkOXNFuVd16E[3uoTVOCTlmCb1qEVXuLTlepcGmYVnykbVF6TVOLeXJ{VXemW2ZxTXq{UlOob3eKR1GoR2GsTlOScEOiS3y{XmOCc1mYXnyjNmmwTlebe1uUb16E[3uoTVOC[1OSb1qEVXx4SGGw[1mERXeKR1GoTVOC[1mERVqEVXuLR2OTd3GYOXyRW2qvXmiTfluEVn2kR4e5UXqodF:4NFuKR1GoTVOC[1mERXeKR1GoR2GsTlOScICbbVGwTle5dHKuWUmRV1qkZ3y5eVmqRX2LbVGsZVeXbGqIWomRWECqZn16NFmJcHylR1mxTVi{UlOqRXeKR1GoTVOC[1mERXeKR1GoTVOCTlOSb1qEV2KwXmeHb2qZTXeRV1GqZ1eHfnNzWnuKboOPR3mC[1mERXeKR1GoTVOC[1mCb1qEVXuL[mFxT1mERXeKR1GoTVOC[1mERXeEVXuLR2GtdGqqRX:LS3itXWeTcHOrNEmKclKpZ{OPcGqETYCKTIOPR3mC[1mERXeKR1GoTVOC[1mERXeKR1GLR2GsTlOUVn:lS{G{UHpxb3KIcIWbWIOPR3mC[1mERXeKR1GoTVOC[1mCb1qEVXuL[mFxT1OURXeKR1GLR2GsTlOZNF6E[3uoTVOC[1OSb1qEVXyuXUK5enNzWX:LS2q4T2S{UlOob3eKR1GoR2GsTlSSc1qKR1GoTVGsTlOSb1qLS2qxZ36PNFmFNHekN2K6Z1d6fluEVn:lS{G{UFOCcmCESlWVNF6WW2[DSlq6b{eFVX:LTVOC[1mCb1qEVXuLTle5bHN{VXeKSECoZ{OTfXOIPYqMR1GsZViTeHKEe3eLfoe3ZViTeHKFOH6MV4N{U4dxT1OURXeKR1GLR2GsTlOUVn:lS{G{TVRx[3N{WnmkN2K6T1OTc3SINYONR1GsXn2tfXN{VYOKR2K{XWiPNFyUVn2iXFq7[FOsO1SSc1qKR1GoTVGsTlOSb1qEV1GoTVOCTlOSb16E[3uoTVOC[1OSb1qEXECPR3es[1mERXeEVXuLXX6LcGmYd{eFVX:LTVOC[1mCb1qEVUCMR2OC[1mERVqEVXu3UImDSXJ{[IWjS{mpXlODN3GZVn:KSlKKWVODSnWJVnyjcl6xZkJ1[2FyWmOVRUCMR2OC[1mERVqEVXyrXWiPcFmGVo[lNkW{ZkKHb2SYWkCiS{msZ4qwOmFyWmOVSH:PR3es[1mERXeEVXuLR2FxT1OURXeKR1GLR2GsTnGYXXeMS2pyZn2PNHGYPYWZNmZ1ZWiPNHO6[36[N2[6ZlZ6dHKucECLfXuxSGGwTlmERXeKRXuLR2GtO1SSc1qEVXuLR2GsTlqIUn:KSECoXUOXfXKHPYCjcXxxT1OTNXOue4CQe{CMR2GsTlOSb1qEW15yZ325[nNzWkCjN1JxT1OTbnGEe3eSNW[UWFV6VW[HPWWUWUGHWEGXWVyERYiOSFGxU4dxT1OSb1qEVXuLR2ePNXOufH[kNmZxZkODNFuEVnqiR4eoVUGXV2SGPWGXSkmIWEC5UWRy[F2VNF6DWlWtVGSqe3elTFpyXmOsO1SSc1qEVXuLR2GsTml{WomjSkm7XmiTenOJVX:LS16wUFODSG[XTl2VNVKWXEGLSm[HWmOVcGKUVWV2WGKsWmONR1JxZ36XcFuVd16E[3uLR2GsTlOSb3uiTGK1ZlOCPVmIUkGkcYinXmipcGm6[3u[NnexU4dxT1OSb1qEVXuLR2etcVmE[3uiTGK1ZlRxPWCYXnijTF6tT2FxT1OSb1qEVXuLR2Gsb3SuSomOfVF6TVePNXOufH[bXFq6ZkOKc1qIUn:MWIOPR3esTlOSb1qEVXyr[GiLd2hzUoOjN16tT1OTbnGEb{eFVX:LTVOC[1mCb1qEVXx6TVFxT1OURXeKR1GLR2GsTmqYfIqbV1GPR3es[1mERXeEVXuLR2i{UlOob3eKR1GoR2GsTlOSb3ulcV[6UYmCPVmGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[LfXu1VHx6[luE[FSXWlqOTVetflmIOY[lR1KxZn6PNGmYfIObW2GvT2S{UlOob3eKR1GoR2GsTlOZNF6E[3uoTVOC[1OSb1qEVUCMR2OC[1mERVqEVXyqZ32XbHG7d16E[3uoTVOC[1OSb1qFVX:LTVOC[1mCb1qEV{i3TVWPfWqYSkCbV1K2Xmik[2SYSn6bW{VxZomDdHKvUkC[W{WrXmFxT1OURXeKR1GLR2GtbmmZUnyKSWK3[EJ2d3JzSnuVW2ZxZVd6b3O7c{[TSXyUVmWPWWhxSlSSNG[VWYqwUlOob3eKR1GoR2GsTlOSNFuEV1GoTVOCTlOSb1qiW2moT1WHfXSIcI[ZNEGW[GiLbXJyPVmbW4i4XmiL[mKISkC[WH93XkKXNGFzPYWbcXyvT1OseGCucIqWS1ZxXUKpcGqE[4CMVUCMR2OC[1mERVqEVXuL[YdxT1OURXeKR1GLR2GsTlOURXeKR1GLR2GsTlSSc1qKR1GoTVGsTlOSb1qLTFK6XmibWmWsb3eRV1GsXEGPSmWtXl[WcIOvWXuXVm[WWmSXSkmXWXuscmiVd16E[3uoTVOC[1OSb1qEVXusZ{OTbHSIWXeRV1KPXWelcF:rdH6bXGKV[FeHNHGYUmSlS1ZxXmOodF:4NFuEV1GoTVOCTlOSb1qEWUGpXkKWOl:vTnykNmZxT1OsO1SSc1qKR1GoTVGsTlOSb16E[3uoTVOC[1OSb1qEVXy3XXx6fnSISomlR3exU4dxT1OURXeKR1GLR2GsTlSSc1qKR1GoTVGsTlOSb1qEV2KnWUCXV2[sWmOYfXSUVm[HWmKXUmWZNW[UV2Ol[FmFNHekTFqtXkF6fWqZRoO[W16tT1OkenGJVkCkR3i7T2i{e1yFSkmQcIe3XFN6Zmite4[ZV3:3Tom4[1q6Z4OKR2JyZ324dF:4NFuEV1GoTVOCTlOSb1qEVXyPXWelcF:rdImlW{SwT2S{UlOob3eKR1GoR2GsTlOSb16E[3uoTVOC[1OSb1qEVXusZViTeHKERUmKS{mqXEKlcHSHPXqjNkVxXmd2NHO6[4CQe{CMR2OC[1mERVqEVXuLR2d6bWhzWoWbSkmrZleXbHKq[4CQe{CMR2OC[1mERVqEVXuLR2VybGpzWU[QclqtZ{OTenOuWmSlS1ZxXmOob3N{VnilS2WxU4dxT1OURXeKR1GLR2GsTlOSNFuEV1GoTVOCTlOSb1qnVUCMR2OC[1mERVqEVXuLXme5fmqURV6E[3uoTVOC[1OSb1qEXIOPR3es[1mERXeEVXuLR2Gsb3SuSomOfVF6TVVybGpzWU[QcXitZliDcHOq[36jXGJyZ32Lelq6b4SRcEmnT1OLS3GYfHyKSUGpXkKWeXOIbIeKS3y7TVd2enSERoe[XGKrZVeXb1mqb{eFVX:LTVOC[1mCb1qEVXx6SGGwTlmERXeKRXuLR2GsUlOob3eKR1GoR2GsTmmvTny[W4N4SGGwTlmERXeKRXuLR2FxT1OURXeKR1GLR2hxUlOqRXeKR1GLR2hxUlOqRXeKR1GLR2ePbHSIUn:KR3iH[VePcHOJVoCjNkSoTleWdFSSc3eKR1GoR2GtO1SSc3eKR1GoR2GsTlqJXnikbl2oVGOCb2qUNDubNmZxWGeXfnNzSn6bV3exU4dxT1mERXeKRXuLR2iLcHSJWomjboOPR3mC[1mERVqEXECMR3esTlOUPI[KS{GpUGe5dFmJUnyKTG[{ZkOxdHSERX:jcW[yXleW[3K6RkCbXF5xT2ODbFmIdHyKTFK6XWixb3Kvb3ejW1[1XmODbnGJcHmlVX:LR2GtdGqqRX:LS3hxZme4PWCUZ36KR2muTVOTNmmZTYmMVX:LR2GsTmSYSn6bWH93[FepfXJ{[F[mS16tZ1iTdHJzOH:Kb2K3[EJ2d3JzSnuKS2qpZWe4[1uETYWLTGqpZ3qOeVmqb4WKSlK{XmeHflmIUn:[W{WvXmODb3J{[IWjS{mpXlODeGqZVn:jNmGoZWd1[3J{RkCiW{m2TViTbGmqOHmMWIOPR3mC[1mERVqEVUCMTVOC[1mCb1qiW2moT1OTNmmZTYiMV1GsZViTeHKEOEmKR1l5TWNxeFmETXeNbVK2ZkOkc1uURYWKR1moUGNxL1mrd16EbVGoTVOCTlOYcH2KR3es[H2HfV2qb3ebcXy{XmZ6e3SZVn[[Nkm2[FeXeXSJUX:LTFKp[Feod1mEVn:lS{G{T2S{UlOoNFuKR1GoTVGsTnGYXXeMR2JzXWiKfmCVNH6LfVGuTnmDdHNyPYqlTFqxZn2kc1qIbECjW4exTVO[cVmE[3uiTGK1ZlOGPVq6Z4CMVUCMTVOC[1mCb1qEV2JzXWiKflmFNHekcUlyZn2Sc1uJUkCkcYitZnmob3GJVoSjR3uoUImCc2qufI[[XGGxUWSCfV6Eb4OKSFmxU4dxT1mERXeKRXuLXme5fmqURoCbbVGwTlibbHOrUUmRV3OvTVO[cVmEVn:lS{G{VGRxclq6b16EbVGoTVOCTlOSb3ulcV[6UYmCPVmGNXibNmV3U32pcHKJRnykbXevZmiTNXOuTo[LfXu1VHx6[luE[HyjXFJx[WODenSZVoelXGGvT2S{UlOqRXeKR1GLR2FxT1mERXeKRXx6SGGw[1mERXeEVU1:Jku{PkF3PjKiW{WsXmipRml{VoCjNkR:Jku{PkV1NEpjSGGwTlOYcH2KR3iPXWelcF:rdH:bW4i4XmiKc1pzNUClXFqqZol6dHKuXo[LfXu1VH2lcHSHTnybNEWpZmeWc1uUb3eme{CMR2GsTlqJXnikblG1VH6LcGqE[36jXGJyZ32LelxzSnujW3y2ZViTeHKHPYSlTG[6XX15enGYOXubXHevT2S{UlOob1qnV1KtZliPcFmJd16E[3uLR2FxT1OSb1qLS{G3XleXd1mFNHeVW1[vXmSwOmpzWkCVW{msXme4c1pzNUClXFqqZol6eHSJWom[cUivT2NxL2lzfHy[XFqDZle5VWmY[HykfXexU4dxT1OSb1qFVX:LR2Gsb3SuSomOR{BsXkKXNGWuWoqkS{m2Z{KWc1uUNDukNmZxV1eXbGqIWomMR3SKWl[TVVy7SYWOV3O{ToqSe126RlejN1qqZWeTb2qYOH6MWIOPR3esTlOUVkK[XFm4UGR2cmqZVmObXF64ZkJ2fmqU[4CNWEW7XmiTR3JzVkWMR1Gs[H2HfV2ENDulN1qpZ1OpUmmY[HyQboCwXme5e2qZTX:LNkFx[GiLbXK6Z4CNWEWnXImoclmH[ImjNkWvTVe5dGlzWoWkNmWo[Fite2qUe3ejS3yrXmd2fmqURnqjNmKtZ4mDbHOuWXejcUlxTVdybHSIUn:iW{WvTViTc3GZUXeiS{m7[FN1cluUb4CQe{CMR2GtPVSSc1qEVU1:Jku{PkF3PjKkN3y2XUKpfXJzOYCmcWV:Jku{PkJ2Okh7JlSSc3eKR1GoR2FxT1mERXeKRXusZ1iLcHSucHylNF[6Z32HOVmFNHeLTGqpZ3qCeGCu[HylSlK6XmibdGqZ[FS[XGKtXkJ6fXWWcHukfXexU4dxT1mERXeKRXusZ1iLcHSucHylfVF6TVeteHOIfI[bS2WwTom4clyERXukTFqt[H2tcHRxSomkcVZ2T2S{UlOqRXeKR1GLZWe[[1uEVoekcWZzZWeXN2CVNIeMV1GsZ1iLcHSucHylfVF6TVOkeF2UZ{eFVX:PR3mC[1mERVqLTFZyXmiLOWOIPYSKSECoTomkO1SSc3eKR1GoR2ebenOuWni[NneoT1OTNmmZTUCKS1[7TVOTfnSIPYmbWXysT2ODO1SSc3eKR1GoR2Gsb3OZWnykcnyKZkJx[1yrNHeKb3yQWUCXV2[ERlqVcGKRTVeDeHSJWom[cUmoTVOp[3N{Vo[kcW[nZWeT[1yERnekcW[5[GeXfnSHPYe[XGKwXVOs[2[sSl2XWW[VTVOobVyqVoqlS{m6XmWtb1yqTYOKR3O3TomsO1mETUeFVX:oTVOC[1OZNF6EbVGoTVOCTlSSc3eKR1GoR2OTfHSYWommWXi3ZmWTcGqqRUmKR1qLWHyPSmWtVXeUWUWWWImD[3KZVkGkcVq3XVOCc2mJUkCjN1qtXEKtb2mEe3e[TFqtZ2iXcHN{Vn[kS1ZxZVeCdFmHXlKVSm[HWYmCc12Ee3eLfUivT2S{[1mrd16EbVGoTVOCTlSSc3eKR1GoR2OTfHSYWommWXy2Z4mCPVmETlqVcF6HWXyS[2OWOWWVfVKoZmiTNXOuTo[[R1GwXViXfXKHPYmbXHS6ZWiTcGhzcHu[R4eoXViPNHJ{TnyZNnysXVO4[2mIUnilS2[vZkOLOWhzcHu[R4eoXViDfXJzVkG[N2KnZWeT[1yERnekcW[5[GeXfnSHPYe[XGKwXVOsUlOob1qEVXuoTVOC[1mHUl[VSW[FWlOD[3SZToOZN1qt[EOLdHSIWn[iW2KoUFOD[3N{Vo[kcW[nZWeT[1yERne[NlZxXmelenOvcH[iW2KoUFOD[3OJTo[bTG[r[FZ6dGqIRYOKS1K6XmiHNWqZUkCZN1Kp[Fep[1SSc1qEVXuLTVOC[1mERleWb{mPTVeDbnJ{TnyZN2[6ZlZ6fWqZ[ImiXGKtXVFxT1OSb1qEV1GoTVOC[2ZxbF[Wb2WoSGGwTlOSb1qKR1GoTVOC[1mE[16E[3uLR2Gs[1mERXeKR1GoTVOCc2mIUnilS2[vZkOLOWhzcHu[R1KLWHmCc1mqRYWKR2K4Z32XNnGYWkOKR1G2TVOKdFmGSl:TR1KoZ1iLemqJWnqlSkmxXleC[2OXUXeVcG[OWFOsUlOob1qEVXuoTVOC[1mERXeMV1m2SGGw[1mERXeEVXuLR2OC[1mE[3:LTGqpZ3qG[1mVNHeLfXOxTVR5[1msSl:TR1GwXViPNHJ{TnyZNnysXVODU2RyVXeUWUSoT1OK[1yqRXulcV[6UWOCeVmETYCMV1moU3mCbVmqb16E[3uLR2Gs[1mERXeKR1GoUHmLRmSsVV6EbVGoTVOC[1mCb1qEVXuoTVOCc1SSc3eKR1GoTVOCTlOSb1qKR1GoTVOCc2mJTnykXG[tZ{OT[nOISkCiS1GoWHt6WVmGcF:KR3iVVmW5SmFyVXe[TFqtZ2iXcHN{Vn[kS1ZxZVeC[2KtTmCVV1KoZmiTNXOuTo[[R3uxSGGw[1mERXeKR1GLR2GsTlmERXeMV1l4SGGw[1mERXeEVUCMTVOC[1mCb3ukXG[tZ36tSWqYe3eRV1GqVlWXUWKXVl[KSWqUWEBx[2mINUClXFqqZkKCUlOqRXeKR1GLTVOC[1mERXeKR1GoTVOC[1mERXeKR1GoWkCpSmWsWXeKR3ioXUKHNGqY[I[kcnynZWeT[1mGOWCXR1KLWHmCc1mqOHeLTFK6XmibdGqZZ3eKR{SoTXms[2GWOVWKS1K4Z316b3SYUkCZNnysXVODTmW6Rl:XWYiOT2OKO1SSc3eKR1GoR2FxT1mERXeKRXusZ2iXcHOvcFWbW4iKZkJx[2CURXmTSW[OVm[TSlmGXmOVNECoXVdyNHSZTnmjNlGoWkCpSmWsWXe[TFqtZ2iXcHN{Vn[kS1ZxZVeCPVq6PH6QfVl4SGGwUlOqRXeKR1GLTlePenKuOXy[N2KxZkJ1[2CURl6[W3StU3qxcmqZVmSiW{WvZleXNHJzOH:LNl63Z32WenOuWoqjN2[6XUKWcluUNDubNmZxVUJ6eXKuWnqlS3y3ZnmocmlzPYmbWkl{Z32tNGqUZ4CQe{CMSGGw[1mERXeEXGK6[WODO1SSc3eKR1GoR2GsUlOqRXeKR1GLR2OTbnJzOYWbW15xZWd6eVyVOYilW2[6[WOobWVyVlKWcGGoWl[LRmStUlKSNWKLWEB1bVuVd16EbVGoTVOCTlOSNFuKR1GoTVGsTlqIcIW[NohyXleXTXJzNXykS1[vXmOCPVmEVkK[XFm4UGR2c3JzNXykS1[vXmWtfmOYOXqjTG[sXmeSc1uVd16EbVGoTVOCTlOSNFuKR1GoTVGsTnGYXXeMR2KxZn2Pd3SYVnyUS{m1XmiDbGpzWXeLbWmoTWOTNmmZTYqMV1GsXUJ6eXKuWnqlS3y3ZnlxL3OZWnykcnuwTliHNWqZTkWUS{m1T2S{UlOqRXeKR1GLR2etcVmE[3uiW{WrZliXb2qWbI[jW2[4XWelcFmEXX2KR2JzXWiKe1yVOX6bXGKP[Ge5NHGZUkCjN1qt[H2tcHS6[4CMV1GsXUJ6eXKuWnqlS3y3ZnlxL3OZWnykcnuwTliHNWqZTkWUS{m1VleXcVuVd16EbVGoTVOCTlOUVnqjNkW2XmePNHGYPYWNWEW5[GeXfXWU[3ukXG[tZ36tTnKvUYCQfVGoSGGw[1mERXeEVXuPR3mC[1mERVqEW3yuTVOobFqIcIW[NohyXleXTXJzNXykS1[vXmOCcVqqRXulcV[6UYms[1qIUo[jcUWtXUOTdHJzOISRclZyXmiLOVuEVoilW2[6[WWTcHKGbI[jV3t4SGGw[1mERXeEVXusXUJ6eXKuWnqlS3y3ZnlxL3OZWnykcnuwTliHNWqZTkWTS2[{T2S{UlOoNFuKR1GoTVGtPVmIUnilS16wTVOpSnWIUnykTGKxZkJ1[1qIWYCKTIOPR3mC[1mERVqEV2KrZkJ2eWqYUkCiW{m2UGR2fHSYWommV3eqWXt6UWSGTlKSNIOqT2S{UlOqRXeKR1GLR2iTc3OuPUOKR2KtU4dxT1mERXeKRXx6SGGw[1mERXeEVUCMTVOC[1mCb3u[Nkm2Zn2XbnSIcI[jbUBsZ2iXcHOvb3:Kb16RWGVyTm[ETYCQe{CMTVOC[1mCb16EbVGoTVOCTjJ8gR>>
|
app/code/local/Artio/MTurbo/controllers/Adminhtml/MturboController.php
CHANGED
@@ -36,12 +36,14 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
|
|
36 |
->setContainerCssClass('catalog-categories');
|
37 |
|
38 |
$this->_setActiveMenu('system');
|
39 |
-
$this->_addBreadcrumb(Mage::helper('adminhtml')->__('Turbo
|
40 |
|
41 |
return $this;
|
42 |
}
|
43 |
|
44 |
-
|
|
|
|
|
45 |
public function indexAction() {
|
46 |
|
47 |
$config = Artio_MTurbo_Helper_Data::getConfig();
|
@@ -171,6 +173,9 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
|
|
171 |
|
172 |
}
|
173 |
|
|
|
|
|
|
|
174 |
public function generateurllistAction() {
|
175 |
|
176 |
if (!$this->_checkLicence()) return;
|
@@ -331,6 +336,10 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
|
|
331 |
|
332 |
public function downloadFinishAction() {}
|
333 |
|
|
|
|
|
|
|
|
|
334 |
public function downloadRunAction() {
|
335 |
|
336 |
if ($this->getRequest()->isPost()) {
|
@@ -364,22 +373,10 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
|
|
364 |
|
365 |
}
|
366 |
|
|
|
|
|
|
|
367 |
public function upgradeAction() {
|
368 |
-
|
369 |
-
$checkXml = Mage::helper('mturbo/checker')->checkPermissionLayout();
|
370 |
-
if (!$checkXml) {
|
371 |
-
$this->_getSession()->addWarning(Mage::helper('mturbo')->__("Please, change permission to write on file: 'app/design/adminhtml/default/default/layout.xml'"));
|
372 |
-
$this->_redirect('*/*/index');
|
373 |
-
return;
|
374 |
-
}
|
375 |
-
|
376 |
-
$checkCode = Mage::helper('mturbo/checker')->checkPermissionCode();
|
377 |
-
if (!$checkCode) {
|
378 |
-
$this->_getSession()->addWarning(Mage::helper('mturbo')->__("Please, change permission to write recursive on directory: 'app/code/local/Artio/MTurbo'"));
|
379 |
-
$this->_redirect('*/*/index');
|
380 |
-
return;
|
381 |
-
}
|
382 |
-
|
383 |
$message = Mage::helper('mturbo/downloader')->downloadAndUpgrade();
|
384 |
if ($message=='') {
|
385 |
$this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Upgrade complete, please refresh Magento system cache'));
|
@@ -404,6 +401,78 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
|
|
404 |
|
405 |
}
|
406 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
407 |
public function red($url) {
|
408 |
$this->_redirect($url);
|
409 |
}
|
@@ -412,4 +481,7 @@ class Artio_MTurbo_Adminhtml_MturboController extends Mage_Adminhtml_Controller_
|
|
412 |
return $this->_getSession();
|
413 |
}
|
414 |
|
|
|
|
|
|
|
415 |
}
|
36 |
->setContainerCssClass('catalog-categories');
|
37 |
|
38 |
$this->_setActiveMenu('system');
|
39 |
+
$this->_addBreadcrumb(Mage::helper('adminhtml')->__('M-Turbo Management'), Mage::helper('adminhtml')->__('M-Turbo Management'));
|
40 |
|
41 |
return $this;
|
42 |
}
|
43 |
|
44 |
+
/**
|
45 |
+
* Index Action
|
46 |
+
*/
|
47 |
public function indexAction() {
|
48 |
|
49 |
$config = Artio_MTurbo_Helper_Data::getConfig();
|
173 |
|
174 |
}
|
175 |
|
176 |
+
/**
|
177 |
+
* Generate urllist. This list
|
178 |
+
*/
|
179 |
public function generateurllistAction() {
|
180 |
|
181 |
if (!$this->_checkLicence()) return;
|
336 |
|
337 |
public function downloadFinishAction() {}
|
338 |
|
339 |
+
/**
|
340 |
+
* Download one page.
|
341 |
+
* Use AJAX.
|
342 |
+
*/
|
343 |
public function downloadRunAction() {
|
344 |
|
345 |
if ($this->getRequest()->isPost()) {
|
373 |
|
374 |
}
|
375 |
|
376 |
+
/**
|
377 |
+
* Upgrade demo version to full version.
|
378 |
+
**/
|
379 |
public function upgradeAction() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
380 |
$message = Mage::helper('mturbo/downloader')->downloadAndUpgrade();
|
381 |
if ($message=='') {
|
382 |
$this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Upgrade complete, please refresh Magento system cache'));
|
401 |
|
402 |
}
|
403 |
|
404 |
+
/**
|
405 |
+
* Try to download frontpage and retrieves result.
|
406 |
+
* Use AJAX
|
407 |
+
*/
|
408 |
+
public function testdownloadAction() {
|
409 |
+
|
410 |
+
$method = $this->getRequest()->getPost('method', '');
|
411 |
+
|
412 |
+
$config = Artio_MTurbo_Helper_Data::getConfig();
|
413 |
+
|
414 |
+
$resultTest = '';
|
415 |
+
$res = $config->isMethodAvailable($method, $resultTest);
|
416 |
+
|
417 |
+
$result = array(
|
418 |
+
'ok' => $res,
|
419 |
+
'resultTest'=> $resultTest
|
420 |
+
);
|
421 |
+
|
422 |
+
$this->getResponse()->setBody(Zend_Json::encode($result));
|
423 |
+
|
424 |
+
}
|
425 |
+
|
426 |
+
/**
|
427 |
+
* Apply or Remove MagePatch
|
428 |
+
*/
|
429 |
+
public function magepatchAction() {
|
430 |
+
|
431 |
+
try
|
432 |
+
{
|
433 |
+
$config = Artio_MTurbo_Helper_Data::getConfig();
|
434 |
+
if ($config->isPatched())
|
435 |
+
{
|
436 |
+
$config->removePatch();
|
437 |
+
$this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was removed.'));
|
438 |
+
}
|
439 |
+
else
|
440 |
+
{
|
441 |
+
$config->applyPatch();
|
442 |
+
$this->_getSession()->addSuccess(Mage::helper('mturbo')->__('Patch was applied.'));
|
443 |
+
}
|
444 |
+
}
|
445 |
+
catch (Exception $e)
|
446 |
+
{
|
447 |
+
$this->_getSession()->addError($e->getMessage());
|
448 |
+
}
|
449 |
+
|
450 |
+
$this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_main_section'));
|
451 |
+
|
452 |
+
}
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Does rebuild root htaccess and same time checks htaccess in turbochace folder.
|
456 |
+
*/
|
457 |
+
public function htaccessbuildAction() {
|
458 |
+
|
459 |
+
$config = Artio_MTurbo_Helper_Data::getConfig();
|
460 |
+
|
461 |
+
try
|
462 |
+
{
|
463 |
+
$config->rebuildHtaccess();
|
464 |
+
$config->copyAllowAccess();
|
465 |
+
$this->_getSession()->addSuccess(Mage::helper('mturbo')->__("Htacces was rebuild."));
|
466 |
+
}
|
467 |
+
catch (Exception $e)
|
468 |
+
{
|
469 |
+
$this->_getSession()->addError($e->getMessage());
|
470 |
+
}
|
471 |
+
|
472 |
+
$this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>'page_tabs_actions_section'));
|
473 |
+
|
474 |
+
}
|
475 |
+
|
476 |
public function red($url) {
|
477 |
$this->_redirect($url);
|
478 |
}
|
481 |
return $this->_getSession();
|
482 |
}
|
483 |
|
484 |
+
|
485 |
+
|
486 |
+
|
487 |
}
|
app/code/local/Artio/MTurbo/controllers/AdminhtmlController.php
CHANGED
@@ -40,6 +40,7 @@ class Artio_MTurbo_AdminhtmlController extends Mage_Adminhtml_Controller_Action
|
|
40 |
$newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD ] = $request->getPost('automaticdownload');
|
41 |
$newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_DOWNLOAD_TIME ] = $request->getPost('downloadtime');
|
42 |
$newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_LICENSEID ] = $request->getPost('licenseid');
|
|
|
43 |
|
44 |
try {
|
45 |
$config = Mage::getSingleton('mturbo/config');
|
@@ -49,13 +50,13 @@ class Artio_MTurbo_AdminhtmlController extends Mage_Adminhtml_Controller_Action
|
|
49 |
$this->_getSession()->addError(Mage::helper('mturbo')->__('Configuration error').' : '.$e->getMessage());
|
50 |
}
|
51 |
|
52 |
-
|
53 |
foreach ($request->getPost() as $key=>$value) {
|
54 |
if (strpos($key, 'section')>0) {
|
55 |
$activeTab = $key;
|
56 |
break;
|
57 |
}
|
58 |
-
}
|
59 |
|
60 |
$this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>$request->getPost('activeTab')));
|
61 |
|
40 |
$newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_ENABLE_AUTOMATIC_DOWNLOAD ] = $request->getPost('automaticdownload');
|
41 |
$newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_DOWNLOAD_TIME ] = $request->getPost('downloadtime');
|
42 |
$newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_LICENSEID ] = $request->getPost('licenseid');
|
43 |
+
$newData[ Artio_MTurbo_Model_Config::CONFIG_XML_PATH_DOWNLOAD_METHOD ] = $request->getPost('downloadmethod');
|
44 |
|
45 |
try {
|
46 |
$config = Mage::getSingleton('mturbo/config');
|
50 |
$this->_getSession()->addError(Mage::helper('mturbo')->__('Configuration error').' : '.$e->getMessage());
|
51 |
}
|
52 |
|
53 |
+
/*$activeTab='';
|
54 |
foreach ($request->getPost() as $key=>$value) {
|
55 |
if (strpos($key, 'section')>0) {
|
56 |
$activeTab = $key;
|
57 |
break;
|
58 |
}
|
59 |
+
}*/
|
60 |
|
61 |
$this->_redirect('mturbo/adminhtml_mturbo/index', array('activeTab'=>$request->getPost('activeTab')));
|
62 |
|
app/code/local/Artio/MTurbo/etc/config.xml
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
<config>
|
11 |
<modules>
|
12 |
<Artio_MTurbo>
|
13 |
-
<version>
|
14 |
</Artio_MTurbo>
|
15 |
</modules>
|
16 |
<admin>
|
@@ -178,4 +178,4 @@
|
|
178 |
</mturbo_mturbo>
|
179 |
</jobs>
|
180 |
</crontab>
|
181 |
-
</config>
|
10 |
<config>
|
11 |
<modules>
|
12 |
<Artio_MTurbo>
|
13 |
+
<version>1.1.0</version>
|
14 |
</Artio_MTurbo>
|
15 |
</modules>
|
16 |
<admin>
|
178 |
</mturbo_mturbo>
|
179 |
</jobs>
|
180 |
</crontab>
|
181 |
+
</config>
|
app/code/local/Artio/MTurbo/etc/config.xml~
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* @category Artio
|
5 |
+
* @package Artio_MTurbo
|
6 |
+
* @author Artio
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
-->
|
10 |
+
<config>
|
11 |
+
<modules>
|
12 |
+
<Artio_MTurbo>
|
13 |
+
<version>1.0.11</version>
|
14 |
+
</Artio_MTurbo>
|
15 |
+
</modules>
|
16 |
+
<admin>
|
17 |
+
<routers>
|
18 |
+
<mturbo>
|
19 |
+
<use>admin</use>
|
20 |
+
<args>
|
21 |
+
<module>Artio_MTurbo</module>
|
22 |
+
<frontName>mturbo</frontName>
|
23 |
+
</args>
|
24 |
+
</mturbo>
|
25 |
+
</routers>
|
26 |
+
</admin>
|
27 |
+
<adminhtml>
|
28 |
+
<translate>
|
29 |
+
<modules>
|
30 |
+
<Artio_MTurbo>
|
31 |
+
<files>
|
32 |
+
<default>Artio_MTurbo.csv</default>
|
33 |
+
</files>
|
34 |
+
</Artio_MTurbo>
|
35 |
+
</modules>
|
36 |
+
</translate>
|
37 |
+
<menu>
|
38 |
+
<system>
|
39 |
+
<children>
|
40 |
+
<mturbo translate="title" module="mturbo">
|
41 |
+
<title>M-Turbo Management</title>
|
42 |
+
<action>mturbo/adminhtml_check</action>
|
43 |
+
<sort_order>91</sort_order>
|
44 |
+
</mturbo>
|
45 |
+
</children>
|
46 |
+
</system>
|
47 |
+
</menu>
|
48 |
+
<layout>
|
49 |
+
<updates>
|
50 |
+
<mturbo>
|
51 |
+
<file>mturbo.xml</file>
|
52 |
+
</mturbo>
|
53 |
+
</updates>
|
54 |
+
</layout>
|
55 |
+
<events>
|
56 |
+
<catalog_product_save_commit_after>
|
57 |
+
<observers>
|
58 |
+
<mturbo>
|
59 |
+
<class>mturbo/observer</class>
|
60 |
+
<method>afterSaveProduct</method>
|
61 |
+
</mturbo>
|
62 |
+
</observers>
|
63 |
+
</catalog_product_save_commit_after>
|
64 |
+
<catalog_category_save_before>
|
65 |
+
<observers>
|
66 |
+
<mturbo>
|
67 |
+
<class>mturbo/observer</class>
|
68 |
+
<method>beforeSaveCategory</method>
|
69 |
+
</mturbo>
|
70 |
+
</observers>
|
71 |
+
</catalog_category_save_before>
|
72 |
+
<catalog_category_save_commit_after>
|
73 |
+
<observers>
|
74 |
+
<mturbo>
|
75 |
+
<class>mturbo/observer</class>
|
76 |
+
<method>afterSaveCategory</method>
|
77 |
+
</mturbo>
|
78 |
+
</observers>
|
79 |
+
</catalog_category_save_commit_after>
|
80 |
+
<core_abstract_save_commit_after>
|
81 |
+
<observers>
|
82 |
+
<mturbo>
|
83 |
+
<class>mturbo/observer</class>
|
84 |
+
<method>afterSaveCommitUrl</method>
|
85 |
+
</mturbo>
|
86 |
+
</observers>
|
87 |
+
</core_abstract_save_commit_after>
|
88 |
+
<admin_session_user_login_success>
|
89 |
+
<observers>
|
90 |
+
<mturbo>
|
91 |
+
<class>mturbo/observer</class>
|
92 |
+
<method>adminLogin</method>
|
93 |
+
</mturbo>
|
94 |
+
</observers>
|
95 |
+
</admin_session_user_login_success>
|
96 |
+
</events>
|
97 |
+
</adminhtml>
|
98 |
+
<frontend>
|
99 |
+
<events>
|
100 |
+
<customer_login>
|
101 |
+
<observers>
|
102 |
+
<mturbo>
|
103 |
+
<class>mturbo/observer</class>
|
104 |
+
<method>customerLogin</method>
|
105 |
+
</mturbo>
|
106 |
+
</observers>
|
107 |
+
</customer_login>
|
108 |
+
<customer_logout>
|
109 |
+
<observers>
|
110 |
+
<mturbo>
|
111 |
+
<class>mturbo/observer</class>
|
112 |
+
<method>customerLogout</method>
|
113 |
+
</mturbo>
|
114 |
+
</observers>
|
115 |
+
</customer_logout>
|
116 |
+
<core_block_abstract_prepare_layout_after>
|
117 |
+
<observers>
|
118 |
+
<mturbo>
|
119 |
+
<class>mturbo/observer</class>
|
120 |
+
<method>systemCheck</method>
|
121 |
+
</mturbo>
|
122 |
+
</observers>
|
123 |
+
</core_block_abstract_prepare_layout_after>
|
124 |
+
</events>
|
125 |
+
</frontend>
|
126 |
+
<global>
|
127 |
+
<models>
|
128 |
+
<mturbo>
|
129 |
+
<class>Artio_MTurbo_Model</class>
|
130 |
+
<resourceModel>mturbo_mysql4</resourceModel>
|
131 |
+
</mturbo>
|
132 |
+
<mturbo_mysql4>
|
133 |
+
<class>Artio_MTurbo_Model_Mysql4</class>
|
134 |
+
<entities>
|
135 |
+
<mturbo>
|
136 |
+
<table>mturbo</table>
|
137 |
+
</mturbo>
|
138 |
+
</entities>
|
139 |
+
</mturbo_mysql4>
|
140 |
+
</models>
|
141 |
+
<resources>
|
142 |
+
<mturbo_setup>
|
143 |
+
<setup>
|
144 |
+
<module>Artio_MTurbo</module>
|
145 |
+
</setup>
|
146 |
+
<connection>
|
147 |
+
<use>core_setup</use>
|
148 |
+
</connection>
|
149 |
+
</mturbo_setup>
|
150 |
+
<mturbo_write>
|
151 |
+
<connection>
|
152 |
+
<use>core_write</use>
|
153 |
+
</connection>
|
154 |
+
</mturbo_write>
|
155 |
+
<mturbo_read>
|
156 |
+
<connection>
|
157 |
+
<use>core_read</use>
|
158 |
+
</connection>
|
159 |
+
</mturbo_read>
|
160 |
+
</resources>
|
161 |
+
<blocks>
|
162 |
+
<mturbo>
|
163 |
+
<class>Artio_MTurbo_Block</class>
|
164 |
+
</mturbo>
|
165 |
+
</blocks>
|
166 |
+
<helpers>
|
167 |
+
<mturbo>
|
168 |
+
<class>Artio_MTurbo_Helper</class>
|
169 |
+
</mturbo>
|
170 |
+
</helpers>
|
171 |
+
</global>
|
172 |
+
<crontab>
|
173 |
+
<jobs>
|
174 |
+
<mturbo_mturbo>
|
175 |
+
<run>
|
176 |
+
<model>mturbo/observer::automaticDownload</model>
|
177 |
+
</run>
|
178 |
+
</mturbo_mturbo>
|
179 |
+
</jobs>
|
180 |
+
</crontab>
|
181 |
+
</config>
|
app/code/local/Artio/MTurbo/sql/mturbo_setup/{mysql4-install-0.1.0.php → mysql4-install-1.0.0.php}
RENAMED
@@ -60,7 +60,7 @@
|
|
60 |
('default', 0, 'mturbo/firstconfig', '1');
|
61 |
");
|
62 |
|
63 |
-
$notf['title'] = Mage::helper('mturbo')->__('M-Turbo
|
64 |
$notf['description'] = Mage::helper('mturbo')->__("Installation succesfull. Now will be your Magento faster than other.");
|
65 |
|
66 |
$notification->parse(array($notf));
|
60 |
('default', 0, 'mturbo/firstconfig', '1');
|
61 |
");
|
62 |
|
63 |
+
$notf['title'] = Mage::helper('mturbo')->__('M-Turbo installation succesfull. Please see into System/M-Turbo Management');
|
64 |
$notf['description'] = Mage::helper('mturbo')->__("Installation succesfull. Now will be your Magento faster than other.");
|
65 |
|
66 |
$notification->parse(array($notf));
|
package.xml
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>MTurbo</name>
|
4 |
-
<version>1.0</version>
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://www.artio.net/m-turbo/license">Copyright 2010, ARTIO s.r.o. All rights reserved.</license>
|
7 |
<channel>community</channel>
|
@@ -14,9 +14,9 @@ of Magento site optimization!</description>
|
|
14 |
<notes>Visit product homepage at:
|
15 |
http://www.artio.net/magento-extensions/m-turbo-accelerator</notes>
|
16 |
<authors><author><name>Michal Unzeitig</name><user>auto-converted</user><email>michal.unzeitig@artio.net</email></author><author><name>Jiří Chmiel</name><user>auto-converted</user><email>jiri.chmiel@artio.net</email></author></authors>
|
17 |
-
<date>2010-
|
18 |
-
<time>
|
19 |
-
<contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mturbo.xml" hash="e1e9a5dc117f392f9e2926526b9b1c56"/></dir><dir name="template"><dir name="mturbo"><dir name="preview"><file name="tree.phtml" hash="558e2da8b9c5584a94748116fd8249d0"/></dir><file name="demo.phtml" hash="509ced41c68e1ee7abca6636d24cac0f"/><file name="massaction.phtml" hash="c4ca58cbd05d564129d3c39d452c783e"/><file name="tabs.phtml" hash="1015f2e05a41bb7751b11036e48cbd9f"/></dir></dir></dir></dir></dir></target><target name="magelocal"><dir name="Artio"><dir name="MTurbo"><dir name="Block"><dir name="Adminhtml"><dir name="Edit"><dir name="Tab"><file name="Abstract.php" hash="16a37f270112b175796bb5af02eea84d"/><file name="Actions.php" hash="
|
20 |
<compatible/>
|
21 |
<dependencies/>
|
22 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>MTurbo</name>
|
4 |
+
<version>1.1.0</version>
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://www.artio.net/m-turbo/license">Copyright 2010, ARTIO s.r.o. All rights reserved.</license>
|
7 |
<channel>community</channel>
|
14 |
<notes>Visit product homepage at:
|
15 |
http://www.artio.net/magento-extensions/m-turbo-accelerator</notes>
|
16 |
<authors><author><name>Michal Unzeitig</name><user>auto-converted</user><email>michal.unzeitig@artio.net</email></author><author><name>Jiří Chmiel</name><user>auto-converted</user><email>jiri.chmiel@artio.net</email></author></authors>
|
17 |
+
<date>2010-10-01</date>
|
18 |
+
<time>08:12:17</time>
|
19 |
+
<contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mturbo.xml" hash="e1e9a5dc117f392f9e2926526b9b1c56"/></dir><dir name="template"><dir name="mturbo"><dir name="preview"><file name="tree.phtml" hash="558e2da8b9c5584a94748116fd8249d0"/></dir><file name="demo.phtml" hash="509ced41c68e1ee7abca6636d24cac0f"/><file name="massaction.phtml" hash="c4ca58cbd05d564129d3c39d452c783e"/><file name="tabs.phtml" hash="1015f2e05a41bb7751b11036e48cbd9f"/></dir></dir></dir></dir></dir></target><target name="magelocal"><dir name="Artio"><dir name="MTurbo"><dir name="Block"><dir name="Adminhtml"><dir name="Edit"><dir name="Tab"><file name="Abstract.php" hash="16a37f270112b175796bb5af02eea84d"/><file name="Actions.php" hash="8e60e7c2ef8996fc1486e5b6e0fcce16"/><file name="Category.php" hash="c3ead1f2e3c4456ae506bc412cb7a4d6"/><file name="License.php" hash="554adc83dd6d0c69f65a674c30c0e49f"/><file name="Main.php" hash="4219a12abbf78ee3015126792a84480d"/><file name="Product.php" hash="2458da4035912d8345f479583fd161bd"/><file name="Url.php" hash="81f49156c0f08b244235d715f2fe7b4f"/></dir><file name="Form.php" hash="e3694987ff374e400703f188e391e351"/><file name="Tabs.php" hash="282cb5ff643fa61480994e3f72856f36"/></dir><dir name="Welcome"><file name="Form.php" hash="0af7f37c2ba47175801b5082cf7ceb5a"/></dir><file name="Mturbo.php" hash="3abfef293f93f669cf38b0efc076721f"/><file name="Run.php" hash="a88befc34123fb04ebf74041ca763338"/><file name="Welcome.php" hash="30b0b1882eff25371e8d1bf4ee0bf880"/></dir><dir name="Data"><dir name="Form"><dir name="Element"><file name="Button.php" hash="0317d74c9856481c8e2ccfdff5f7ff20"/><file name="CategoryTree.php" hash="0294437ea2c2b7f92414b945061b12ee"/><file name="NoEscLabel.php" hash="d10b4e82853916eccba7989a3d272660"/><file name="SelectDownloadMethod.php" hash="f9a816189f98787120d8e7340b78e102"/><file name="Time.php" hash="ce401753d4c06840f12ffc011c2ac435"/></dir></dir><dir name="Grid"><dir name="Column"><file name="Blocked.php" hash="4941dcafb09b4eb502d3eabfd3f73dc4"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="CheckController.php" hash="6b62cfd1cbb8d9713eb64abe553b10b8"/><file name="MturboController.php" hash="cce26b19b4779be3053b781a5466a5a0"/></dir><file name="AdminhtmlController.php" hash="3ec6e0b5eed5a3e93259b8d7a0eb4003"/></dir><dir name="etc"><file name="config.xml" hash="775aaeade726ee61813f4928e1e469b6"/><file name="config.xml~" hash="75ffbca7371538210bfea91a75f8ccfd"/></dir><dir name="Helper"><file name="Checker.php" hash="164bb3cb86eb68b3b1969dd92824735f"/><file name="Data.php" hash="f63bdc034ae79c5473ef66e0f5712c07"/><file name="Downloader.php" hash="1f5c4798e38b13e36452b45aeea124eb"/><file name="Info.php" hash="b2f804ce14c86097d57e3ce7b15e8187"/></dir><dir name="Model"><dir name="htaccess"><file name="htaccess.txt" hash="b37433b41cf37e325f2ade4e7839261a"/><file name="htaccessroot.txt" hash="7d55f4bb772128b1f8783b319344d17c"/></dir><dir name="Mysql4"><dir name="Mturbo"><file name="Collection.php" hash="905f9728ed7a8c9d901f3f55c3e9a7d7"/></dir><file name="Mturbo.php" hash="e81f8f1801eca956229a068d0bdea2ab"/></dir><dir name="patches"><file name="mage.txt" hash="0e2ef3ed32b7041f518f162745812023"/></dir><dir name="scripts"><file name="wgetlib.so" hash="80c5d05d9f7d678728e1dccaf0b270c3"/><file name="wgettrans.so" hash="e4f414b0f796051518b6d951133c856b"/></dir><file name="Config.php" hash="ce52f4f206575d9491b2c89ff3b57175"/><file name="Config.php~" hash="117fc78e3053b82d889c00ab135cf4a9"/><file name="File.php" hash="30c7703f65824523ed3c803cc6d57f5a"/><file name="File.php~" hash="98a04470cad3dcc993273f1824192e0e"/><file name="Mturbo.php" hash="7f35b9abc3dd6402e900cae80fafa144"/><file name="Observer.php" hash="1a53243dd2b292181a86c26736ad9004"/><file name="Observer2.php" hash="de554c2515d5cdefbaa2375a5389f7f8"/></dir><dir name="sql"><dir name="mturbo_setup"><file name="mysql4-install-1.0.0.php" hash="f1c33d7c0292988ffef36c8eb683b2d4"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><file name="Artio_MTurbo.csv" hash="37ce492d01d06c14e5f0991a6d60b375"/></dir></target><target name="mageetc"><dir name="modules"><file name="Artio_MTurbo.xml" hash="4de5464bc12f3c0702d2c36931bda64d"/></dir></target></contents>
|
20 |
<compatible/>
|
21 |
<dependencies/>
|
22 |
</package>
|