ServerLoadMonitorFree - Version 1.0.7

Version Notes

Test version

Download this release

Release Info

Developer Aitoc
Extension ServerLoadMonitorFree
Version 1.0.7
Comparing to
See all releases


Code changes from version 1.1.0 to 1.0.7

Files changed (64) hide show
  1. Server Load Monitor Manual.pdf +0 -0
  2. app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitlink.php +0 -22
  3. app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon.php +0 -60
  4. app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/BarGraph.php +0 -166
  5. app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/Filter.php +0 -150
  6. app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/LineGraph.php +0 -212
  7. app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Calculator.php +0 -59
  8. app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/CalculatorResult.php +0 -44
  9. app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Indicator.php +0 -38
  10. app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Manage.php +0 -133
  11. app/code/local/Aitoc/Aitloadmon/Helper/Data.php +0 -93
  12. app/code/local/Aitoc/Aitloadmon/Model/Aitloadmon.php +0 -34
  13. app/code/local/Aitoc/Aitloadmon/Model/Analytics.php +0 -32
  14. app/code/local/Aitoc/Aitloadmon/Model/Calculator.php +0 -83
  15. app/code/local/Aitoc/Aitloadmon/Model/Calculator/Abstract.php +0 -90
  16. app/code/local/Aitoc/Aitloadmon/Model/Calculator/Hardware.php +0 -69
  17. app/code/local/Aitoc/Aitloadmon/Model/Calculator/Magento.php +0 -223
  18. app/code/local/Aitoc/Aitloadmon/Model/Calculator/Software.php +0 -103
  19. app/code/local/Aitoc/Aitloadmon/Model/CompressSource.php +0 -56
  20. app/code/local/Aitoc/Aitloadmon/Model/Dblog.php +0 -16
  21. app/code/local/Aitoc/Aitloadmon/Model/LevelSource.php +0 -66
  22. app/code/local/Aitoc/Aitloadmon/Model/Manage.php +0 -31
  23. app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Aitloadmon.php +0 -170
  24. app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Aitloadmon/Collection.php +0 -67
  25. app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Calculator.php +0 -25
  26. app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Calculator/Collection.php +0 -15
  27. app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Dblog.php +0 -17
  28. app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Dblog/Collection.php +0 -15
  29. app/code/local/Aitoc/Aitloadmon/Model/Mysql4/UrlRewrite.php +0 -64
  30. app/code/local/Aitoc/Aitloadmon/Model/Observer.php +0 -48
  31. app/code/local/Aitoc/Aitloadmon/Model/Process.php +0 -381
  32. app/code/local/Aitoc/Aitloadmon/Model/Router.php +0 -162
  33. app/code/local/Aitoc/Aitloadmon/Model/SysInfo.php +0 -12
  34. app/code/local/Aitoc/Aitloadmon/Model/System.php +0 -12
  35. app/code/local/Aitoc/Aitloadmon/Model/System/Abstract.php +0 -33
  36. app/code/local/Aitoc/Aitloadmon/Model/UrlRewrite.php +0 -25
  37. app/code/local/Aitoc/Aitloadmon/controllers/Adminhtml/AitloadmonController.php +0 -108
  38. app/code/local/Aitoc/Aitloadmon/controllers/Adminhtml/CalculatorController.php +0 -33
  39. app/code/local/Aitoc/Aitloadmon/etc/adminhtml.xml +0 -58
  40. app/code/local/Aitoc/Aitloadmon/etc/config.xml +0 -112
  41. app/code/local/Aitoc/Aitloadmon/etc/system.xml +0 -77
  42. app/code/local/Aitoc/Aitloadmon/sql/aitloadmon_setup/mysql4-install-1.0.0.php +0 -49
  43. app/code/local/Aitoc/Aitloadmon/sql/aitloadmon_setup/mysql4-uninstall-1.0.0.php +0 -21
  44. app/code/local/Aitoc/Aitloadmon/sql/aitloadmon_setup/mysql4-upgrade-1.0.1-1.0.2.php +0 -28
  45. app/code/local/Aitoc/Aitsys/install/Aitoc_Aitloadmon.phtml +0 -112
  46. app/design/adminhtml/default/default/layout/aitloadmon.xml +0 -55
  47. app/design/adminhtml/default/default/template/aitloadmon/back.phtml +0 -8
  48. app/design/adminhtml/default/default/template/aitloadmon/bar.phtml +0 -30
  49. app/design/adminhtml/default/default/template/aitloadmon/graph.phtml +0 -28
  50. app/design/adminhtml/default/default/template/aitloadmon/indicator.phtml +0 -12
  51. app/design/adminhtml/default/default/template/aitloadmon/line.phtml +0 -119
  52. app/design/adminhtml/default/default/template/aitloadmon/quick.phtml +0 -28
  53. app/design/adminhtml/default/default/template/aitloadmon/sysInfo.phtml +0 -11
  54. app/design/adminhtml/default/default/template/aitloadmon/system.phtml +0 -11
  55. app/etc/modules/Aitoc_Aitloadmon.xml +0 -16
  56. js/aitoc/aitloadmon/grafico.bar.custom.js +0 -204
  57. js/aitoc/aitloadmon/grafico.line.custom.js +0 -187
  58. js/aitoc/aitloadmon/grafico.min.js +0 -80
  59. js/aitoc/aitloadmon/raphael-min.js +0 -7
  60. lib/Aitoc/Aitloadmon/Adapter/Apc.php +0 -56
  61. lib/Aitoc/Aitloadmon/Adapter/File.php +0 -116
  62. lib/Aitoc/Aitloadmon/Adapter/Memcached.php +0 -66
  63. lib/Aitoc/Aitloadmon/Collect.php +0 -297
  64. package.xml +10 -31
Server Load Monitor Manual.pdf DELETED
Binary file
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitlink.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Block_Adminhtml_Aitlink extends Mage_Adminhtml_Block_System_Config_Form_Field
7
- {
8
- protected function _getElementHtml (Varien_Data_Form_Element_Abstract $element)
9
- {
10
- $buttonBlock = $element->getForm()->getParent()->getLayout()->createBlock('adminhtml/widget_button');
11
-
12
- $data = array(
13
- 'label' => Mage::helper('adminhtml')->__('Manage'),
14
- 'onclick' => 'setLocation(\''.Mage::helper('adminhtml')->getUrl("adminhtml/aitloadmon/manage").'\' )',
15
- 'class' => '',
16
- );
17
-
18
- $html = $buttonBlock->setData($data)->toHtml();
19
-
20
- return $html;
21
- }
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon.php DELETED
@@ -1,60 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Block_Adminhtml_Aitloadmon extends Mage_Adminhtml_Block_Template
7
- {
8
-
9
- protected $_collection;
10
- protected $_compareCollection;
11
-
12
- /**
13
- * Returns a collection of data for main graphics
14
- *
15
- * @return Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection
16
- */
17
- public function getCollection()
18
- {
19
- if(!isset($this->_collection))
20
- {
21
- $this->_collection = Mage::getModel('aitloadmon/aitloadmon')->getCollectionByDates($this->getData('start_date'),$this->getData('end_date'));
22
- }
23
- return $this->_collection;
24
- }
25
-
26
- /**
27
- * Returns a collection of data for compare graphics
28
- *
29
- * @return Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection
30
- */
31
- public function getCompareCollection()
32
- {
33
- if(!isset($this->_compareCollection))
34
- {
35
- $this->_compareCollection = Mage::getModel('aitloadmon/aitloadmon')->getCollectionByDates($this->getData('start_date_compare'),$this->getData('end_date_compare'));
36
- }
37
- return $this->_compareCollection;
38
- }
39
-
40
- /**
41
- * Checks if there is enough data in collection to build graphics (more then 2 dots)
42
- *
43
- * @param Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection $collection
44
- * @return bool
45
- */
46
- public function isEnoughDataToBuildGraph($collection)
47
- {
48
- $data = array();
49
- foreach($collection as $item)
50
- {
51
- $data[$item->getMeasureTime()] = 1;
52
- if(count($data)>2)
53
- {
54
- return true;
55
- }
56
- }
57
- return false;
58
- }
59
-
60
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/BarGraph.php DELETED
@@ -1,166 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Block_Adminhtml_Aitloadmon_BarGraph extends Mage_Adminhtml_Block_Widget_Form
7
- {
8
- /**
9
- * Gets collection(s) from parent block and processes data for javascript graphics
10
- */
11
- protected function _beforeToHtml()
12
- {
13
- $collection = $this->getParentBlock()->getCollection();
14
- if($this->getCompare())
15
- {
16
- $collectionCompare = $this->getParentBlock()->getCompareCollection();
17
- }
18
-
19
- $barData = $this->_preProcessDataForBar($collection);
20
- $barDataCompare = null;
21
- if($this->getCompare())
22
- {
23
- $barDataCompare = $this->_preProcessDataForBar($collectionCompare);
24
- }
25
- $this->_processDataForBar($barData,$barDataCompare);
26
- }
27
-
28
- /**
29
- * Returns whether the compare mode is enabled
30
- *
31
- * @return bool
32
- */
33
- public function getCompare()
34
- {
35
- return $this->getParentBlock()->getCompare();
36
- }
37
-
38
- /**
39
- * Pre-processes data for further data processing
40
- *
41
- * @param Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection $collection
42
- * @param bool $dataForCompare [false]
43
- * @return array
44
- */
45
- private function _preProcessDataForBar($collection, $dataForCompare = false)
46
- {
47
- $data = array();
48
- $totalPageViews = 0;
49
- $maxLoad = 0;
50
- $maxLoadTime = 0;
51
- $totalPageViewsByGroup = array();
52
-
53
- foreach($collection as $item)
54
- {
55
- $pageGroupId = $item->getData('page_group_id');
56
- if(!isset($totalPageViewsByGroup[$pageGroupId]))
57
- {
58
- $totalPageViewsByGroup[$pageGroupId]=0;
59
- }
60
- $totalPageViewsByGroup[$pageGroupId] += $item->getPageViews();
61
- $totalPageViews +=$item->getPageViews();
62
- if($item->getLoadTimeMax()>$maxLoad)
63
- {
64
- $maxLoad = $item->getLoadTimeMax();
65
- $maxLoadTime = $item->getMeasureTime();
66
- }
67
- }
68
- if(!$dataForCompare)
69
- {
70
- $this->getParentBlock()->setTotalPageViews($totalPageViews);
71
- $this->getParentBlock()->setMaxLoad($maxLoad);
72
- $this->getParentBlock()->setMaxLoadTime($maxLoadTime);
73
- }
74
-
75
- foreach($collection as $item)
76
- {
77
- $pageGroupId = $item->getData('page_group_id');
78
- if(!isset($data[$pageGroupId]))
79
- {
80
- $data[$pageGroupId] = array('avg'=>0,'max'=>0);
81
- }
82
- if($item->getLoadTimeMax()>$data[$pageGroupId]['max'])
83
- {
84
- $data[$pageGroupId]['max'] = $item->getLoadTimeMax();
85
- }
86
- $data[$pageGroupId]['avg'] += $item->getLoadTimeAvg() * $item->getPageViews()/$totalPageViewsByGroup[$pageGroupId];
87
-
88
- }
89
- return $data;
90
- }
91
-
92
- /**
93
- * Processes data and stores it as this object property
94
- *
95
- * @param array $data
96
- * @param bool $dataCompare
97
- */
98
- private function _processDataForBar($data, $dataCompare)
99
- {
100
- $loadAvg = 'avg_load: [';
101
- $loadMax = 'max_load: [';
102
- $groups = Mage::helper('aitloadmon')->getGroupsArray();
103
- $gcnt = 0;
104
- foreach($groups as $pageGroupId)
105
- {
106
- if(!isset($data[$pageGroupId]))
107
- {
108
- $loadAvg .= '0';
109
- $loadMax .= '0';
110
- }
111
- else
112
- {
113
- $loadAvg .= $data[$pageGroupId]['avg'];
114
- $loadMax .= $data[$pageGroupId]['max'];
115
- }
116
-
117
- if($dataCompare)
118
- {
119
- if(!isset($dataCompare[$pageGroupId]))
120
- {
121
- $loadAvg .= ',0';
122
- $loadMax .= ',0';
123
- }
124
- else
125
- {
126
- $loadAvg .= ','.$dataCompare[$pageGroupId]['avg'];
127
- $loadMax .= ','.$dataCompare[$pageGroupId]['max'];
128
- }
129
- }
130
-
131
- $gcnt++;
132
- if($gcnt != count($groups))
133
- {
134
- $loadAvg .= ',';
135
- $loadMax .= ',';
136
- }
137
- }
138
- $loadAvg .= ']';
139
- $loadMax .= ']';
140
-
141
- $this->setBarGraphData($loadMax.','.$loadAvg);
142
- }
143
-
144
- /**
145
- * Returns a JS array of labels
146
- *
147
- * @param bool $compareMode
148
- * @return string
149
- */
150
- public function getBarLabels($compareMode)
151
- {
152
-
153
- $groups = array_keys(Mage::helper('aitloadmon')->getGroupsArray());
154
- if($compareMode)
155
- {
156
- $glue = '\',\'\',\'';
157
- }
158
- else
159
- {
160
- $glue = '\',\'';
161
- }
162
-
163
-
164
- return '[\''.implode($glue, $groups).($compareMode?'\',\'':'').'\']';
165
- }
166
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/Filter.php DELETED
@@ -1,150 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Block_Adminhtml_Aitloadmon_Filter extends Mage_Adminhtml_Block_Widget_Form
7
- {
8
- /**
9
- * Preparing needed data for form
10
- */
11
- private function _prepareData()
12
- {
13
- $collection = $this->getParentBlock()->getCollection();
14
-
15
- $totalPageViews = 0;
16
- $maxLoad = 0;
17
- $maxLoadTime = 0;
18
-
19
- foreach($collection as $item)
20
- {
21
- $totalPageViews +=$item->getPageViews();
22
- if($item->getLoadTimeMax()>$maxLoad)
23
- {
24
- $maxLoad = $item->getLoadTimeMax();
25
- $maxLoadTime = $item->getMeasureTime();
26
- }
27
- }
28
-
29
- $this->setTotalPageViews($totalPageViews);
30
- $this->setMaxLoad($maxLoad);
31
- $this->setMaxLoadTime($maxLoadTime);
32
- }
33
-
34
- /**
35
- * Preparing form
36
- *
37
- * @return Mage_Adminhtml_Block_Widget_Form
38
- */
39
- protected function _prepareForm()
40
- {
41
- $this->_prepareData();
42
-
43
- $form = new Varien_Data_Form(array(
44
- 'id' => 'edit_form',
45
- 'action' => $this->getUrl('*/*/index'),
46
- 'method' => 'post',
47
- )
48
- );
49
- $fieldset = $form->addFieldset('aitloadmon_form', array('legend'=>Mage::helper('aitloadmon')->__('Custom Filter Options')));
50
-
51
- $fieldset->addField('starts', 'date', array(
52
- 'name' => 'startDate',
53
- 'title' => Mage::helper('aitloadmon')->__('Start Date'),
54
- 'label' => Mage::helper('aitloadmon')->__('Start Date'),
55
- 'image' => $this->getSkinUrl('images/grid-cal.gif'),
56
- 'format' => 'yyyy-MM-dd HH:mm:ss',
57
- 'value' => $this->getParentBlock()->getStartDate(),
58
- 'time' => true,
59
- 'required' => true,
60
- ));
61
-
62
- $fieldset->addField('ends', 'date', array(
63
- 'name' => 'endDate',
64
- 'title' => Mage::helper('aitloadmon')->__('End Date'),
65
- 'label' => Mage::helper('aitloadmon')->__('End Date'),
66
- 'image' => $this->getSkinUrl('images/grid-cal.gif'),
67
- 'format' => 'yyyy-MM-dd HH:mm:ss',
68
- 'value' => $this->getParentBlock()->getEndDate(),
69
- 'time' => true,
70
- 'required' => true,
71
- ));
72
-
73
-
74
- $fieldset->addField('type','select',array(
75
- 'title' => Mage::helper('aitloadmon')->__('Graph displays:'),
76
- 'label' => Mage::helper('aitloadmon')->__('Graph displays:'),
77
- 'name' => 'type',
78
- 'options' => array(
79
- 'max' => Mage::helper('aitloadmon')->__('Maximum load'),
80
- 'avg' => Mage::helper('aitloadmon')->__('Average load'),
81
- ),
82
- 'value' => $this->getParentBlock()->getType(),
83
- ));
84
-
85
-
86
- $compare = $fieldset->addField('compare','select',array(
87
- 'title' => Mage::helper('aitloadmon')->__('Compare with the same period'),
88
- 'label' => Mage::helper('aitloadmon')->__('Compare with the same period'),
89
- 'name' => 'compare',
90
- 'options' => array(
91
- 0 => Mage::helper('aitloadmon')->__('No'),
92
- 1 => Mage::helper('aitloadmon')->__('Yes'),
93
- ),
94
- 'value' => $this->getParentBlock()->getCompare(),
95
- ));
96
-
97
- $compareDate = $fieldset->addField('starts_compare', 'date', array(
98
- 'name' => 'startDateCompare',
99
- 'title' => Mage::helper('aitloadmon')->__('From Date'),
100
- 'label' => Mage::helper('aitloadmon')->__('From Date'),
101
- 'image' => $this->getSkinUrl('images/grid-cal.gif'),
102
- 'format' => 'yyyy-MM-dd HH:mm:ss',
103
- 'value' => $this->getParentBlock()->getStartDateCompare(),
104
- 'time' => true,
105
- ));
106
-
107
-
108
- $fieldset->addField('submit1', 'submit', array(
109
- 'name' => 'submit1',
110
- 'title' => Mage::helper('aitloadmon')->__('Filter'),
111
- 'value' => Mage::helper('aitloadmon')->__('Filter'),
112
- 'class' => 'form-button',
113
- ));
114
-
115
- $fieldset = $form->addFieldset('aitloadmon_stat', array('legend'=>Mage::helper('aitloadmon')->__('Global stats for the selected period')));
116
-
117
-
118
- $fieldset->addField('page_views', 'label', array(
119
- 'label' => Mage::helper('aitloadmon')->__('Total page views'),
120
- 'title' => Mage::helper('aitloadmon')->__('Total page views'),
121
- 'value' => $this->getTotalPageViews(),
122
- ));
123
-
124
-
125
- $fieldset->addField('max_load', 'label', array(
126
- 'label' => Mage::helper('aitloadmon')->__('Max load'),
127
- 'title' => Mage::helper('aitloadmon')->__('Max load'),
128
- 'value' => number_format($this->getMaxLoad(),2).' Sec',
129
- ));
130
-
131
- $fieldset->addField('max_load_time', 'label', array(
132
- 'label' => Mage::helper('aitloadmon')->__('Max load time'),
133
- 'title' => Mage::helper('aitloadmon')->__('Max load time'),
134
- 'value' => $this->getMaxLoadTime(),
135
- ));
136
-
137
- $form->setUseContainer(true);
138
- $this->setForm($form);
139
- $this->setChild('form_after', $this->getLayout()->createBlock('adminhtml/widget_form_element_dependence')
140
- ->addFieldMap($compare->getHtmlId(), $compare->getName())
141
- ->addFieldMap($compareDate->getHtmlId(), $compareDate->getName())
142
- ->addFieldDependence(
143
- $compareDate->getName(),
144
- $compare->getName(),
145
- 1
146
- )
147
- );
148
- return parent::_prepareForm();
149
- }
150
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Aitloadmon/LineGraph.php DELETED
@@ -1,212 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Block_Adminhtml_Aitloadmon_LineGraph extends Mage_Adminhtml_Block_Widget_Form
7
- {
8
-
9
- private $_maxLabelsInGraph = 20;
10
-
11
- /**
12
- * Gets collection(s) from parent block and processes data for javascript graphics
13
- */
14
- protected function _beforeToHtml()
15
- {
16
-
17
- $collection = $this->getParentBlock()->getCollection();
18
- if($this->getCompare())
19
- {
20
- $collectionCompare = $this->getParentBlock()->getCompareCollection();
21
- }
22
-
23
- $type = $this->getType();
24
- $lineData = $this->_preProcessDataForLine($collection);
25
- $this->_processDataForLine($lineData, $type);
26
-
27
- if($this->getCompare())
28
- {
29
- $lineDataCompare = $this->_preProcessDataForLine($collectionCompare);
30
- $this->_processDataForLine($lineDataCompare, $type, true);
31
- }
32
- }
33
-
34
- /**
35
- * Getting the type of values we show in graph (average or maximum)
36
- *
37
- * @return mixed
38
- */
39
- public function getType()
40
- {
41
- return $this->getParentBlock()->getType();
42
- }
43
-
44
- /**
45
- * Returns whether the compare mode is enabled
46
- *
47
- * @return bool
48
- */
49
- public function getCompare()
50
- {
51
- return $this->getParentBlock()->getCompare();
52
- }
53
-
54
- /**
55
- * Returns html for graphics controls
56
- *
57
- * @return string
58
- */
59
- public function getCheckBoxes()
60
- {
61
- $groups = Mage::helper('aitloadmon')->getGroupsArray();
62
- $html = '';
63
- foreach($groups as $groupName => $groupValue)
64
- {
65
- $html .= '<label><input type="checkbox" checked="checked" rel="'.$groupValue.'" onclick="toggleLines(this);" class="linegraph_check"/>'.ucfirst($groupName).'</label>';
66
- }
67
- return $html;
68
- }
69
-
70
-
71
- /**
72
- * Pre-processes data for further data processing
73
- *
74
- * @param Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection $collection
75
- * @return array
76
- */
77
- private function _preProcessDataForLine($collection)
78
- {
79
- $data = array();
80
- foreach($collection as $item)
81
- {
82
- $pageGroupId = $item->getData('page_group_id');
83
- $time = $item->getData('measure_time');
84
- if(!isset($data[$time]))
85
- {
86
- $data[$time] = array();
87
- }
88
- $data[$time][$pageGroupId]['avg'] = number_format($item->getLoadTimeAvg(),2);
89
- $data[$time][$pageGroupId]['max'] = number_format($item->getLoadTimeMax(),2);
90
- $data[$time][$pageGroupId]['pgv'] = $item->getPageViews();
91
- $data[$time][$pageGroupId]['cnc'] = $item->getConcurrent();
92
- }
93
- return $data;
94
- }
95
-
96
- /**
97
- * Processes data and stores it as this object property
98
- * @param $data
99
- * @param string $type
100
- * @param bool $compare
101
- */
102
- private function _processDataForLine($data, $type = 'avg', $compare = false)
103
- {
104
- $groups = Mage::helper('aitloadmon')->getGroupsArray();
105
- $dataString = '';
106
- $dataSizeString = '';
107
- $concurrentString = '';
108
- $gcnt = 0;
109
- foreach($groups as $pageGroupCode => $pageGroupId)
110
- {
111
- $dataString .= $pageGroupCode.': [';
112
- $dataSizeString .= $pageGroupId.': [';
113
- $concurrentString .= $pageGroupId.': [';
114
- $dcnt = 0;
115
- foreach($data as $timeData)
116
- {
117
- if(!isset($timeData[$pageGroupId][$type]))
118
- {
119
- $dataString .= '0';
120
- $dataSizeString .= '0';
121
- $concurrentString .= '0';
122
- }
123
- else
124
- {
125
- $dataString .= $timeData[$pageGroupId][$type];
126
- $dataSizeString .= $timeData[$pageGroupId]['pgv'];
127
- $concurrentString .= $timeData[$pageGroupId]['cnc'];
128
- }
129
- $dcnt++;
130
- if($dcnt != count($data))
131
- {
132
- $dataString .= ',';
133
- $dataSizeString .= ',';
134
- $concurrentString .= ',';
135
- }
136
- }
137
- $dataString .= ']';
138
- $dataSizeString .= ']';
139
- $concurrentString .= ']';
140
- $gcnt++;
141
- if($gcnt != count($groups))
142
- {
143
- $dataString .= ',';
144
- $dataSizeString .= ',';
145
- $concurrentString .= ',';
146
- }
147
- }
148
-
149
- $method = 'setLineGraphData';
150
- if($compare)
151
- {
152
- $method .= 'Compared';
153
- }
154
-
155
- $times = $this->_prepareHorizontalLabels(array_keys($data));
156
- $this->$method(array('data'=>$dataString,'labels'=>'[\''.implode('\',\'',$times).'\']','dot_labels'=>'[\''.implode('\',\'',array_keys($data)).'\']','dataSize'=>$dataSizeString,'concurrents'=>$concurrentString));
157
- }
158
-
159
- /**
160
- * Preparing horizontal labels for graph
161
- *
162
- * @param array $labelArray
163
- * @return array
164
- */
165
- private function _prepareHorizontalLabels($labelArray = array())
166
- {
167
- $labelArrayCount = count($labelArray);
168
- if($labelArrayCount>$this->_maxLabelsInGraph)
169
- {
170
- $each = 2;
171
- while(($labelArrayCount/$each) > $this->_maxLabelsInGraph)
172
- {
173
- $each++;
174
- }
175
- $cnt = 0;
176
- foreach($labelArray as $key=>$value)
177
- {
178
- $cnt++;
179
- if($cnt==$each)
180
- {
181
- $cnt=0;
182
- }
183
- else
184
- {
185
- $labelArray[$key]='';
186
- }
187
- }
188
- }
189
-
190
- $currentDate = '';
191
- foreach($labelArray as $key=>$value)
192
- {
193
- if($value=='')
194
- {
195
- continue;
196
- }
197
-
198
- list($date,$time) = explode(' ',$value);
199
- if($currentDate != $date)
200
- {
201
- $currentDate = $date;
202
- $labelArray[$key]=$time.'\n\r'.$date;
203
- }
204
- else
205
- {
206
- $labelArray[$key]=$time;
207
- }
208
- }
209
-
210
- return $labelArray;
211
- }
212
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Calculator.php DELETED
@@ -1,59 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Block_Adminhtml_Calculator extends Mage_Adminhtml_Block_Widget_Form
7
- {
8
- /**
9
- * Preparing form for the block
10
- *
11
- * @return Mage_Adminhtml_Block_Widget_Form|void
12
- */
13
- protected function _prepareForm()
14
- {
15
- $form = new Varien_Data_Form(array(
16
- 'id' => 'edit_form',
17
- 'action' => $this->getUrl('*/calculator/submit'),
18
- 'method' => 'post',
19
- 'enctype' => 'multipart/form-data',
20
- )
21
- );
22
- $fieldset = $form->addFieldset('aitloadmon_form', array('legend'=>Mage::helper('aitloadmon')->__('Source selection')));
23
- $source = $fieldset->addField('source','select',array(
24
- 'title' => Mage::helper('aitloadmon')->__('Please select source for exemplary server load'),
25
- 'label' => Mage::helper('aitloadmon')->__('Please select source for exemplary server load'),
26
- 'name' => 'source',
27
- 'options' => array(
28
- 'monitor' => Mage::helper('aitloadmon')->__('Server Load Monitor'),
29
- 'log' => Mage::helper('aitloadmon')->__('Magento Logs'),
30
- 'analytics' => Mage::helper('aitloadmon')->__('Google Analytics File'),
31
- ),
32
- ));
33
- $file = $fieldset->addField('csv_file', 'file', array(
34
- 'label' => Mage::helper('aitloadmon')->__('Google Analytics File'),
35
- 'required' => true,
36
- 'name' => 'csv_file',
37
- ));
38
- $fieldset->addField('submit', 'submit', array(
39
- 'name' => 'submit',
40
- 'title' => Mage::helper('aitloadmon')->__('Submit'),
41
- 'value' => Mage::helper('aitloadmon')->__('Submit'),
42
- 'class' => 'form-button',
43
- 'onclick' => 'var validator = new Validation(\'edit_form\');if (!validator.validate()) {return false;}',
44
- ));
45
-
46
- $form->setUseContainer(true);
47
- $this->setForm($form);
48
-
49
- $this->setChild('form_after', $this->getLayout()->createBlock('adminhtml/widget_form_element_dependence')
50
- ->addFieldMap($source->getHtmlId(), $source->getName())
51
- ->addFieldMap($file->getHtmlId(), $file->getName())
52
- ->addFieldDependence(
53
- $file->getName(),
54
- $source->getName(),
55
- 'analytics'
56
- )
57
- );
58
- }
59
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/CalculatorResult.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Block_Adminhtml_CalculatorResult extends Mage_Adminhtml_Block_Widget_Form
7
- {
8
- /**
9
- * Preparing form for the block
10
- *
11
- * @return Mage_Adminhtml_Block_Widget_Form|void
12
- */
13
- protected function _prepareForm()
14
- {
15
- $form = new Varien_Data_Form(array(
16
- 'id' => 'edit_form',
17
- 'action' => $this->getUrl('*/calculator/submit'),
18
- 'method' => 'post',
19
- 'enctype' => 'multipart/form-data',
20
- )
21
- );
22
- $fieldset = $form->addFieldset('aitloadmon_form', array('legend'=>Mage::helper('aitloadmon')->__('Data to enter in server calculator')));
23
-
24
- $fieldset->addField('products', 'label', array(
25
- 'label' => Mage::helper('aitloadmon')->__('Product number'),
26
- 'title' => Mage::helper('aitloadmon')->__('Product number'),
27
- 'value' => $this->getProducts(),
28
- ));
29
-
30
- $fieldset->addField('max_load_time', 'label', array(
31
- 'label' => Mage::helper('aitloadmon')->__('Exemplary server load'),
32
- 'title' => Mage::helper('aitloadmon')->__('Exemplary server load'),
33
- 'value' => $this->getLoad(),
34
- ));
35
-
36
- #$fieldset->addField('back', 'button', array(
37
- # 'value' => Mage::helper('aitloadmon')->__('Go Back'),
38
- # 'onclick' => 'document.location.href=\''.$this->getUrl('*/calculator/index').'\'',
39
- # 'class' => 'form-button submit',
40
- #));
41
-
42
- $this->setForm($form);
43
- }
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Indicator.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Block_Adminhtml_Indicator extends Mage_Adminhtml_Block_Template
7
- {
8
- /**
9
- * Returns an array of colors to use for different load levels in indicator
10
- *
11
- * @return string
12
- */
13
- private function _getColors()
14
- {
15
- return array(
16
- Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_GREEN => '#1B7B00',
17
- Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_YELLOW => '#f5861a',
18
- Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_RED => '#a0151e',
19
- Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_BLACK => '#000000',
20
- );
21
- }
22
-
23
- /**
24
- * Returns the color of the current load level or a green color whe the load level is unavailable for some reason
25
- *
26
- * @return string
27
- */
28
- public function getColor()
29
- {
30
- $colors = $this->_getColors();
31
- $loadLevel = Mage::helper('aitloadmon')->getLoadLevel();
32
- if($loadLevel && isset($colors[$loadLevel]))
33
- {
34
- return $colors[$loadLevel];
35
- }
36
- return $colors[Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_GREEN];
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Block/Adminhtml/Manage.php DELETED
@@ -1,133 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Block_Adminhtml_Manage extends Mage_Adminhtml_Block_Widget_Form
7
- {
8
- /**
9
- * Returns the compress date types
10
- *
11
- * @return array
12
- */
13
- private function _getCompressTypes()
14
- {
15
- return Mage::getModel('aitloadmon/compressSource')->toArray();
16
- }
17
-
18
- /**
19
- * Preparing form for the block
20
- *
21
- * @return Mage_Adminhtml_Block_Widget_Form|void
22
- */
23
- protected function _prepareForm()
24
- {
25
- $settings = Mage::getModel('aitloadmon/manage')->getSettings();
26
-
27
- $form = new Varien_Data_Form(array(
28
- 'id' => 'manageData_form',
29
- 'action' => $this->getUrl('*/*/manage'),
30
- 'method' => 'post',
31
- )
32
- );
33
-
34
- $fieldset = $form->addFieldset('manage_stat', array('legend'=>Mage::helper('aitloadmon')->__('Data stats').'<span style="font-size:10px;margin-left:20px;">('.Mage::helper('aitloadmon')->__('Server Load Monitor collects data from CMS, Checkout, Catalog, Catalogsearch and Other groups of pages every single minute by cron. It stores 60*5 values per hour, 24*60*5 per 24 hours.').')</span>'));
35
-
36
- $fieldset->addField('total_records', 'label', array(
37
- 'label' => Mage::helper('aitloadmon')->__('Total records'),
38
- 'title' => Mage::helper('aitloadmon')->__('Total records'),
39
- 'value' => Mage::getModel('aitloadmon/aitloadmon')->getResource()->getRows(),
40
- ));
41
-
42
- $fieldset->addField('total_size', 'label', array(
43
- 'label' => Mage::helper('aitloadmon')->__('Total size in bytes'),
44
- 'title' => Mage::helper('aitloadmon')->__('Total size in bytes'),
45
- 'value' => Mage::getModel('aitloadmon/aitloadmon')->getResource()->getWeight(),
46
- ));
47
-
48
- $fieldset = $form->addFieldset('manage_auto', array('legend'=>Mage::helper('aitloadmon')->__('Automatic data compression').'<span style="font-size:10px;margin-left:20px;">('.Mage::helper('aitloadmon')->__('In order not to overload database Server Load Monitor compresses data automatically.').')</span>'));
49
-
50
- $fieldset->addField('auto_enable','select', array(
51
- 'label' => Mage::helper('aitloadmon')->__('Enable automatic data compression'),
52
- 'title' => Mage::helper('aitloadmon')->__('Enable automatic data compression'),
53
- 'name' => 'auto_enable',
54
- 'options' => array(
55
- 0 => Mage::helper('aitloadmon')->__('No'),
56
- 1 => Mage::helper('aitloadmon')->__('Yes'),
57
- ),
58
- 'value' => isset($settings['enabled'])?$settings['enabled']:1,
59
- ));
60
-
61
- $fieldset->addField('auto_day','select', array(
62
- 'label' => Mage::helper('aitloadmon')->__('Compress data of last day to'),
63
- 'title' => Mage::helper('aitloadmon')->__('Compress data of last day to'),
64
- 'name' => 'auto_day',
65
- 'options' => $this->_getCompressTypes(),
66
- 'value' => isset($settings['day'])?$settings['day']:1,
67
- ));
68
-
69
- $fieldset->addField('auto_month','select', array(
70
- 'label' => Mage::helper('aitloadmon')->__('Compress data of last month to'),
71
- 'title' => Mage::helper('aitloadmon')->__('Compress data of last month to'),
72
- 'name' => 'auto_month',
73
- 'options' => $this->_getCompressTypes(),
74
- 'value' => isset($settings['month'])?$settings['month']:2,
75
- ));
76
-
77
- $fieldset->addField('auto_year','select', array(
78
- 'label' => Mage::helper('aitloadmon')->__('Compress data of last year to'),
79
- 'title' => Mage::helper('aitloadmon')->__('Compress data of last year to'),
80
- 'name' => 'auto_year',
81
- 'options' => $this->_getCompressTypes(),
82
- 'value' => isset($settings['year'])?$settings['year']:3,
83
- ));
84
-
85
- $fieldset->addField('submit_auto', 'submit', array(
86
- 'name' => 'submit_auto',
87
- 'title' => Mage::helper('aitloadmon')->__('Save settings'),
88
- 'value' => Mage::helper('aitloadmon')->__('Save settings'),
89
- 'class' => 'form-button',
90
- ));
91
-
92
- $fieldset = $form->addFieldset('manage_manual', array('legend'=>Mage::helper('aitloadmon')->__('Manual data compression').'<span style="font-size:10px;margin-left:20px;">('.Mage::helper('aitloadmon')->__('Default compression settings are optimized and recommended but Admin is enabled to choose preferred compression settings as well as compress the data manually.').')</span>'));
93
-
94
- $fieldset->addField('manual_from', 'date', array(
95
- 'name' => 'manual_from',
96
- 'title' => Mage::helper('aitloadmon')->__('From date'),
97
- 'label' => Mage::helper('aitloadmon')->__('From date'),
98
- 'image' => $this->getSkinUrl('images/grid-cal.gif'),
99
- 'format' => 'yyyy-MM-dd HH:mm:ss',
100
- 'value' => date('Y-m-d H:i:s', time()-2*24*3600),
101
- 'time' => true,
102
- ));
103
-
104
- $fieldset->addField('manual_to', 'date', array(
105
- 'name' => 'manual_to',
106
- 'title' => Mage::helper('aitloadmon')->__('To date'),
107
- 'label' => Mage::helper('aitloadmon')->__('To date'),
108
- 'image' => $this->getSkinUrl('images/grid-cal.gif'),
109
- 'format' => 'yyyy-MM-dd HH:mm:ss',
110
- 'value' => date('Y-m-d H:i:s', time()-24*3600),
111
- 'time' => true,
112
- ));
113
-
114
- $fieldset->addField('manual_compress','select', array(
115
- 'label' => Mage::helper('aitloadmon')->__('Compress data to'),
116
- 'title' => Mage::helper('aitloadmon')->__('Compress data to'),
117
- 'name' => 'manual_compress',
118
- 'options' => $this->_getCompressTypes(),
119
- 'value' => 1,
120
- ));
121
-
122
- $fieldset->addField('submit_manual', 'submit', array(
123
- 'name' => 'submit_manual',
124
- 'title' => Mage::helper('aitloadmon')->__('Compress data'),
125
- 'value' => Mage::helper('aitloadmon')->__('Compress data'),
126
- 'class' => 'form-button',
127
- ));
128
-
129
- $form->setUseContainer(true);
130
- $this->setForm($form);
131
- }
132
-
133
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Helper/Data.php DELETED
@@ -1,93 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Helper_Data extends Mage_Core_Helper_Abstract
7
- {
8
- /**
9
- * Returns an array of page groups we are dividing the page views
10
- *
11
- * @return array
12
- */
13
- public function getGroupsArray()
14
- {
15
- return array(
16
- 'other' => 1,
17
- 'cms' => 2,
18
- 'checkout' => 3,
19
- 'catalogsearch' => 4,
20
- 'catalog' => 5,
21
- );
22
- }
23
-
24
- /**
25
- * Gets current load level
26
- *
27
- * @return int
28
- */
29
- public function getLoadLevel()
30
- {
31
- return Aitoc_Aitloadmon_Collect::getLoadLevel();
32
- }
33
-
34
-
35
- /**
36
- * Gets current page group
37
- *
38
- * @return int|bool
39
- */
40
- public function getGroupIdOfCurrentPage()
41
- {
42
- $module = Mage::app()->getRequest()->getModuleName();
43
- $groupIds = Mage::helper('aitloadmon')->getGroupsArray();
44
- if($module == 'admin')
45
- {
46
- return false;
47
- }
48
- elseif(isset($groupIds[$module]))
49
- {
50
- return $groupIds[$module];
51
- }
52
- else
53
- {
54
- return 1;
55
- }
56
- }
57
-
58
- /**
59
- * Sets current load level
60
- * @param int $loadLevel
61
- */
62
- public function setLoadLevel($loadLevel)
63
- {
64
- Aitoc_Aitloadmon_Collect::setLoadLevel($loadLevel);
65
- }
66
-
67
- /**
68
- * Check config exclude uri
69
- * @param string $uri
70
- */
71
- public function checkUriExclude($uri)
72
- {
73
- if (!$uri)
74
- {
75
- return false;
76
- }
77
- $excludes = Mage::getStoreConfig('system/aitloadmon/exclude_urls');
78
- $excludes = explode("\n",str_replace("\r\n","\n",$excludes));
79
- if (is_array($excludes))
80
- {
81
- foreach ($excludes as $exclude)
82
- {
83
- if ($exclude && strpos($uri,$exclude))
84
- {
85
- return true;
86
- }
87
- }
88
- }
89
- return false;
90
- }
91
-
92
-
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Aitloadmon.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Aitloadmon extends Mage_Core_Model_Abstract
7
- {
8
- const LOAD_LEVEL_GREEN = 1;
9
- const LOAD_LEVEL_YELLOW = 2;
10
- const LOAD_LEVEL_RED = 3;
11
- const LOAD_LEVEL_BLACK = 4;
12
-
13
- /**
14
- * Standard model constructor
15
- */
16
- public function _construct()
17
- {
18
- parent::_construct();
19
- $this->_init('aitloadmon/aitloadmon');
20
- }
21
-
22
- /**
23
- * Gets a data collection bounded by 2 dates
24
- *
25
- * @param $startDate
26
- * @param $endDate
27
- * @return Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection
28
- */
29
- public function getCollectionByDates($startDate, $endDate)
30
- {
31
- return $this->getCollection()->filterByDates($startDate, $endDate);
32
- }
33
-
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Analytics.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Analytics
7
- {
8
- /**
9
- * Gets the max number of visitors per minute parsing google analytics file
10
- *
11
- * @param string $filename
12
- * @return int
13
- */
14
- public function getVisitors($filename)
15
- {
16
- $f = fopen($filename,"r");
17
- $max = 0;
18
- while($line = fgetcsv($f,0,','))
19
- {
20
- if(count($line)==2 && $line[0]!='' && isset($line[1]))
21
- {
22
- if($line[1]>$max)
23
- {
24
- $max = $line[1];
25
- }
26
- }
27
- }
28
- fclose($f);
29
-
30
- return ceil($max/60);
31
- }
32
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Calculator.php DELETED
@@ -1,83 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Calculator extends Mage_Core_Model_Abstract
7
- {
8
-
9
- private $_apiUrl = 'http://www.aitoc.com/api/xmlrpc/statistic/';
10
-
11
- private $_infoClasses = array('magento','hardware','software');
12
- private $_period = '1 WEEK';
13
-
14
- /**
15
- * Standard model constructor
16
- */
17
- public function _construct()
18
- {
19
- parent::_construct();
20
- $this->_init('aitloadmon/calculator');
21
- }
22
-
23
- /**
24
- * Getter for use in calculator results
25
- *
26
- * @return int
27
- */
28
- public function getProductInfo()
29
- {
30
- return Mage::getModel('catalog/product')->getCollection()->getSize();
31
- }
32
-
33
- /**
34
- * Collects the info that will be sent to Server Calculator
35
- *
36
- * @return array
37
- */
38
- private function _collectSendingInfo()
39
- {
40
- $data = array();
41
- foreach($this->_infoClasses as $class)
42
- {
43
- $model = Mage::getModel('aitloadmon/calculator_'.$class);
44
- if($model instanceof Aitoc_Aitloadmon_Model_Calculator_Abstract)
45
- {
46
- $data += $model->toArray();
47
- }
48
- }
49
- return $data;
50
- }
51
-
52
- /**
53
- * Sends the info required for server calculator and clears the load info table
54
- */
55
- public function sendCalcInfo()
56
- {
57
- $client = new Zend_XmlRpc_Client($this->_apiUrl);
58
- try{
59
- $client->call('call', array('1234567890', 'aitcalc.addStatistic', array($this->_collectSendingInfo())));
60
- }catch(Exception $e){
61
- Mage::log('Data sending error in '.__METHOD__.': '.$e->getMessage());
62
- }
63
- }
64
-
65
- /**
66
- * Gets the maximum number of concurrent page views based on monitor
67
- *
68
- * @return int
69
- */
70
- public function getMonitorVisitors()
71
- {
72
- $collection = Mage::getModel('aitloadmon/aitloadmon')->getCollection();
73
- $collection->getSelect()
74
- ->reset(Zend_Db_Select::COLUMNS)
75
- ->columns('MAX(concurrent) AS concurrent')
76
- ->where('measure_time > DATE_SUB(NOW(), INTERVAL '.$this->_period.')');
77
-
78
- $max = $collection->getFirstItem()->getConcurrent();
79
-
80
- return $max;
81
- }
82
-
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Calculator/Abstract.php DELETED
@@ -1,90 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- abstract class Aitoc_Aitloadmon_Model_Calculator_Abstract
7
- {
8
- protected $_infoMethodPattern = '/_get\w+Info/';
9
-
10
- /**
11
- * Executes a system command and returns its output
12
- *
13
- * @param $command
14
- * @return string
15
- */
16
- protected function _exec($command)
17
- {
18
- $data = array();
19
- @exec($command, $data);
20
- if(count($data))
21
- {
22
- return implode("\r\n",$data);
23
- }
24
- else
25
- {
26
- return '';
27
- }
28
- }
29
-
30
- /**
31
- * Safely gets the contents of a file
32
- *
33
- * @param string $file
34
- * @return null|string
35
- */
36
- protected function _getFileSafe($file)
37
- {
38
- try{
39
- if($data = @file_get_contents($file))
40
- {
41
- return $data;
42
- }
43
- if($data = $this->_exec('cat '.$file.' 2>/dev/null'))
44
- {
45
- return $data;
46
- }
47
- }
48
- catch(Exception $e)
49
- {
50
- return null;
51
- }
52
- return null;
53
- }
54
-
55
- /**
56
- * Finds the methods that return required and returns them
57
- *
58
- * @return array
59
- */
60
- protected function _getInfoMethods()
61
- {
62
- $methods = get_class_methods(get_class($this));
63
- $infoMethods = array();
64
- foreach($methods as $method)
65
- {
66
- if(preg_match($this->_infoMethodPattern,$method))
67
- {
68
- $infoMethods[] = $method;
69
- }
70
- }
71
-
72
- return $infoMethods;
73
- }
74
-
75
- /**
76
- * Returns the required info as a joined array
77
- *
78
- * @return array
79
- */
80
- public function toArray()
81
- {
82
- $returnArray = array();
83
- foreach($this->_getInfoMethods() as $method)
84
- {
85
- $returnArray += $this->$method();
86
- }
87
-
88
- return $returnArray;
89
- }
90
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Calculator/Hardware.php DELETED
@@ -1,69 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Calculator_Hardware extends Aitoc_Aitloadmon_Model_Calculator_Abstract
7
- {
8
- private $_linuxCpuFile = '/proc/cpuinfo';
9
- private $_linuxMemFile = '/proc/meminfo';
10
-
11
- /**
12
- * Gets the CPU info of a server
13
- *
14
- * @return array
15
- */
16
- protected function _getCpuInfo()
17
- {
18
- $info = $this->_getFileSafe($this->_linuxCpuFile);
19
- if($info)
20
- {//^(processor\s+:\s+\d+)\s*$.*?
21
- $freqs = array();
22
- $bogomipss = array();
23
- $modelNames = array();
24
- if(preg_match_all('/^cpu\sMHz\s+:\s+([\d\.]+)\s*$/ms',$info,$matches))
25
- {
26
- $freqs = $matches[1];
27
- }
28
- if(preg_match_all('/^bogomips\s+:\s+([\d\.]+)\s*$/ms',$info,$matches))
29
- {
30
- $bogomipss = $matches[1];
31
- }
32
- if(preg_match_all('/^model\sname\s+:\s+([\w\d\s\(\)]+)\s*$/ms',$info,$matches))
33
- {
34
- $modelNames = $matches[1];
35
- }
36
- return array('cpu'=>array('cores'=>count($freqs),'freq'=>max($freqs),'bogomips'=>max($bogomipss),'model name'=>isset($modelNames[0])?$modelNames[0]:''));
37
- }
38
-
39
- return null;
40
- }
41
-
42
- /**
43
- * Gets the memory info of a server
44
- *
45
- * @return array|null
46
- */
47
- protected function _getMemInfo()
48
- {
49
- $info = $this->_getFileSafe($this->_linuxMemFile);
50
- if($info)
51
- {
52
- if(preg_match('/MemTotal:(.*?B)/si',$info,$matches))
53
- {
54
- return array('mem'=>trim($matches[1]));
55
- }
56
- }
57
- return null;
58
- }
59
-
60
- /**
61
- * Gets if the server is virual
62
- *
63
- * @return array
64
- */
65
- protected function _getVirtualInfo()
66
- {//todo think of the additional ways
67
- return array('virtual'=>file_exists('/proc/vz/veinfo')?'true':'false');
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Calculator/Magento.php DELETED
@@ -1,223 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Calculator_Magento extends Aitoc_Aitloadmon_Model_Calculator_Abstract
7
- {
8
- /**
9
- * Gets the system cache types
10
- *
11
- * @return array
12
- */
13
- protected function _getSystemcacheInfo()
14
- {
15
- return array('system_cache' => array('backend' => (string)Mage::app()->getConfig()->getNode('global/cache/backend'), 'slow_backend' => (string)Mage::app()->getConfig()->getNode('global/cache/slow_backend')));
16
- }
17
-
18
- /**
19
- * Gets the statuses of caches
20
- *
21
- * @return array
22
- */
23
- protected function _getCacheInfo()
24
- {
25
- $caches = array();
26
- foreach (Mage::app()->getCacheInstance()->getTypes() as $type) {
27
- $caches[$type->getId()] = $type->getStatus();
28
- }
29
- return array('caches' => $caches);
30
- }
31
-
32
-
33
- /**
34
- * Gets the compiler status
35
- *
36
- * @return array
37
- */
38
- protected function _getCompilerInfo()
39
- {
40
- return array('compiler' => defined('COMPILER_INCLUDE_PATH'));
41
- }
42
-
43
- /**
44
- * Gets the number of customers
45
- *
46
- * @return array
47
- */
48
- protected function _getCustomerInfo()
49
- {
50
- return array('customers'=>Mage::getModel('customer/customer')->getCollection()->getSize());
51
- }
52
-
53
- /**
54
- * Gets the number of products
55
- *
56
- * @return array
57
- */
58
- protected function _getProductInfo()
59
- {
60
- return array('products'=>Mage::getModel('catalog/product')->getCollection()->getSize());
61
- }
62
-
63
- /**
64
- * Gets the number of quotes
65
- *
66
- * @return array
67
- */
68
- protected function _getQuoteInfo()
69
- {
70
- return array('quotes'=>Mage::getModel('sales/quote')->getCollection()->getSize());
71
- }
72
-
73
- /**
74
- * Gets the number of orders
75
- *
76
- * @return array
77
- */
78
- protected function _getOrderInfo()
79
- {
80
- return array('orders'=>Mage::getModel('sales/order')->getCollection()->getSize());
81
- }
82
-
83
- /**
84
- * Gets Magento version
85
- *
86
- * @return array
87
- */
88
- protected function _getVersionInfo()
89
- {
90
- return array('version'=>Mage::getVersion());
91
- }
92
-
93
- /**
94
- * Populates an array with load data
95
- *
96
- * @param array $data
97
- */
98
- protected function _populateLoadData(&$data)
99
- {
100
- $colArray = array();
101
- for($i=1; $i<6; $i++)
102
- {
103
- $colArray['pg'.$i.'_concurrent_load'] = 'pg'.$i.'_concurrent_load';
104
- }
105
- $colArray['concurrent'] = 'concurrent';
106
-
107
-
108
- $collection = Mage::getModel('aitloadmon/calculator')->getCollection();
109
- $collection->getSelect()
110
- ->reset(Zend_Db_Select::COLUMNS)
111
- ->columns($colArray);
112
-
113
-
114
- foreach($collection as $item)
115
- {
116
- if($item->getConcurrent())
117
- {
118
- if(!isset($data[$item->getConcurrent()]))
119
- {
120
- $data[$item->getConcurrent()] = array();
121
- }
122
- for($i=1; $i<6; $i++)
123
- {
124
- if(!isset($data[$item->getConcurrent()][$i]))
125
- {
126
- $data[$item->getConcurrent()][$i] = array();
127
- }
128
- if($item->getData('pg'.$i.'_concurrent_load'))
129
- {
130
- $data[$item->getConcurrent()][$i][] = $item->getData('pg'.$i.'_concurrent_load');
131
- }
132
- }
133
- }
134
-
135
- }
136
- unset($collection);
137
-
138
- foreach($data as $concurrentGroupId => $concurrentGroupData)
139
- {
140
- foreach($concurrentGroupData as $pageGroupId => $pageGroupData)
141
- {
142
- unset($data[$concurrentGroupId][$pageGroupId]);
143
- sort($pageGroupData);
144
- $cnt = count($pageGroupData);
145
- if($cnt)
146
- {
147
- $data[$concurrentGroupId][$pageGroupId]['min'] = (string)round($pageGroupData[0],3);
148
- $data[$concurrentGroupId][$pageGroupId]['avg'] = (string)round(array_sum($pageGroupData)/$cnt,3);
149
- $data[$concurrentGroupId][$pageGroupId]['max'] = (string)round($pageGroupData[$cnt-1],3);
150
- $data[$concurrentGroupId][$pageGroupId]['med'] = (string)round($pageGroupData[ceil($cnt*0.5)-1],3);
151
- $data[$concurrentGroupId][$pageGroupId]['90l'] = (string)round($pageGroupData[ceil($cnt*0.9)-1],3);
152
- }
153
- }
154
- }
155
- }
156
-
157
- /**
158
- * Populates an array with cnc sum pages data
159
- *
160
- * @param array $data
161
- */
162
- protected function _populateCncData(&$data)
163
- {
164
- $colArray = array();
165
- for($i=1; $i<6; $i++)
166
- {
167
- $colArray['pg'.$i.'_concurrent'] = 'SUM(pg'.$i.'_concurrent)';
168
- }
169
- $colArray['concurrent'] = 'concurrent';
170
- $collection = Mage::getModel('aitloadmon/calculator')->getCollection();
171
- $collection->getSelect()
172
- ->reset(Zend_Db_Select::COLUMNS)
173
- ->columns($colArray)
174
- ->group('concurrent');
175
-
176
- foreach($collection as $item)
177
- {
178
- for($i=1; $i<6; $i++)
179
- {
180
- if($item->getData('pg'.$i.'_concurrent'))
181
- {
182
- $data[$item->getConcurrent()][$i]['cnc'] = $item->getData('pg'.$i.'_concurrent');
183
- }
184
- }
185
- }
186
- }
187
-
188
- /**
189
- * Gets the info about server load
190
- *
191
- * @return array
192
- */
193
- protected function _getLoadInfo()
194
- {
195
- $data = array();
196
- $this->_populateLoadData($data);
197
- $this->_populateCncData($data);
198
- Mage::getModel('aitloadmon/calculator')->getResource()->deleteAll();
199
- return array('load'=>$data);
200
- }
201
-
202
-
203
- protected function _getMonitorVersionInfo()
204
- {
205
- return array('monitor_version' => (string)Mage::getConfig()->getNode()->modules->Aitoc_Aitloadmon->version);
206
- }
207
-
208
- /**
209
- * Gets the info whether the booster is enabled
210
- *
211
- * @return array
212
- */
213
- protected function _getBoosterInfo()
214
- {
215
- $enabled = 'false';
216
- $config = @simplexml_load_file(Mage::getBaseDir().DS.'app'.DS.'etc'.DS.'modules'.DS.'Aitoc_Aitpagecache.xml');
217
- if ($config){
218
- $enabled = (string)$config->modules->Aitoc_Aitpagecache->active;
219
- }
220
-
221
- return array('booster'=>$enabled);
222
- }
223
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Calculator/Software.php DELETED
@@ -1,103 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Calculator_Software extends Aitoc_Aitloadmon_Model_Calculator_Abstract
7
- {
8
- protected $_acceleratorInis = array('eAccelerator'=>'eaccelerator.enable','APC'=>'apc.enabled','xCache'=>'xcache.cacher','Zend Optimizer+'=>'zend_optimizer.optimization_level','WinCache'=>'wincache.ocenabled');
9
- protected $_osInfoFiles = array('/etc/SUSE-release','/etc/redhat-release','/etc/redhat_version','/etc/fedora-release','/etc/slackware-release','/etc/slackware-version',
10
- '/etc/debian_release','/etc/debian_version','/etc/mandrake-release','/etc/yellowdog-release','/etc/sun-release','/etc/release','/etc/gentoo-release','/etc/UnitedLinux-release',
11
- '/etc/lsb-release'
12
- );
13
-
14
- /**
15
- * Gets OS info from system files
16
- *
17
- * @return null|string
18
- */
19
- protected function _readOsInfoFromFiles()
20
- {
21
- foreach($this->_osInfoFiles as $file)
22
- {
23
- if($data = $this->_getFileSafe($file))
24
- {
25
- if(strlen($data)>256)
26
- {
27
- $data = substr($data,0,256);
28
- }
29
- break;
30
- }
31
- }
32
- return $data;
33
- }
34
-
35
- /**
36
- * Gets the OS info
37
- *
38
- * @return array
39
- */
40
- protected function _getOsInfo()
41
- {
42
- if(!($os = $this->_exec('lsb_release -a 2>/dev/null')) && !($os = $this->_readOsInfoFromFiles()))
43
- {
44
- $os = php_uname();
45
- }
46
- return array('os'=>$os);
47
- }
48
-
49
-
50
- /**
51
- * Get webserver type
52
- *
53
- * @return array
54
- */
55
- protected function _getWebserverInfo()
56
- {
57
- return array('webserver' => isset($_SERVER["SERVER_SOFTWARE"])?$_SERVER["SERVER_SOFTWARE"]:'');
58
- }
59
-
60
- /**
61
- * Get MySQL version
62
- *
63
- * @return array
64
- */
65
- protected function _getMysqlInfo()
66
- {
67
- $resource = Mage::getSingleton('core/resource');
68
- $readConnection = $resource->getConnection('core_read');
69
- $query = 'SELECT VERSION()';
70
- return array('mysql' => $readConnection->fetchOne($query));
71
- }
72
-
73
- /**
74
- * Get PHP information
75
- *
76
- * @return array
77
- */
78
- protected function _getPhpInfo()
79
- {
80
-
81
- return array('php' => array('version' => phpversion(),'memory_limit' => ini_get('memory_limit'), 'server_api' => php_sapi_name()));
82
- }
83
-
84
- /**
85
- * Get PHP Accelerator information
86
- *
87
- * @return array
88
- */
89
- protected function _getPhpAccelInfo()
90
- {
91
- $accelerator = array();
92
- foreach($this->_acceleratorInis as $name => $setting)
93
- {
94
- if(ini_get($setting))
95
- {
96
- $accelerator[] = $name;
97
- }
98
- }
99
-
100
- return array('php_accel' => $accelerator);
101
- }
102
-
103
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/CompressSource.php DELETED
@@ -1,56 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_CompressSource
7
- {
8
-
9
- /**
10
- * Returns compress types as a simple array
11
- *
12
- * @return array
13
- */
14
- public function getCompressTypesArray()
15
- {
16
- return array(
17
- 1 => Mage::helper('aitloadmon')->__('hour'),
18
- 2 => Mage::helper('aitloadmon')->__('day'),
19
- 3 => Mage::helper('aitloadmon')->__('month'),
20
- );
21
- }
22
-
23
-
24
- /**
25
- * Returns compress types as an array for settings
26
- *
27
- * @return array
28
- */
29
- public function toOptionArray()
30
- {
31
- $levels = $this->getCompressTypesArray();
32
-
33
- foreach($levels as $key=>$value)
34
- {
35
- $array[] = array('value' => $key, 'label'=>Mage::helper('aitloadmon')->__(ucfirst($value)));
36
- }
37
-
38
- return $array;
39
- }
40
-
41
- /**
42
- * Returns compress types as an array for settings
43
- *
44
- * @return array
45
- */
46
- public function toArray()
47
- {
48
- $levels = $this->getCompressTypesArray();
49
-
50
- foreach($levels as $key=>$value)
51
- {
52
- $array[$key] = Mage::helper('aitloadmon')->__(ucfirst($value));
53
- }
54
- return $array;
55
- }
56
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Dblog.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Dblog extends Mage_Core_Model_Abstract
7
- {
8
- /**
9
- * Standard model constructor
10
- */
11
- public function _construct()
12
- {
13
- parent::_construct();
14
- $this->_init('aitloadmon/dblog');
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/LevelSource.php DELETED
@@ -1,66 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_LevelSource
7
- {
8
-
9
- /**
10
- * Returns load levels as a simple array
11
- *
12
- * @return array
13
- */
14
- public function getLoadArray()
15
- {
16
- return array(
17
- Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_GREEN => 'green',
18
- Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_YELLOW => 'yellow',
19
- Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_RED => 'red',
20
- Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_BLACK => 'black'
21
- );
22
- }
23
-
24
-
25
- /**
26
- * Returns load levels as an array for settings
27
- *
28
- * @return array
29
- */
30
- public function toOptionArray()
31
- {
32
- $array = array(
33
- array('value' => 0, 'label'=>Mage::helper('aitloadmon')->__('No level')),
34
- );
35
-
36
- $levels = $this->getLoadArray();
37
-
38
- foreach($levels as $key=>$value)
39
- {
40
- $array[] = array('value' => $key, 'label'=>Mage::helper('aitloadmon')->__(ucfirst($value)));
41
- }
42
-
43
- return $array;
44
- }
45
-
46
- /**
47
- * Returns load levels as an array for settings
48
- *
49
- * @return array
50
- */
51
- public function toArray()
52
- {
53
- $array = array(
54
- 0 => Mage::helper('aitloadmon')->__('No level'),
55
- );
56
-
57
- $levels = $this->getLoadArray();
58
-
59
- foreach($levels as $key=>$value)
60
- {
61
- $array[$key] = Mage::helper('aitloadmon')->__(ucfirst($value));
62
- }
63
-
64
- return $array;
65
- }
66
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Manage.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Manage extends Mage_Core_Controller_Varien_Front
7
- {
8
- private $_settingsKey = 'system/aitloadmon/manage';
9
-
10
- /**
11
- * Gets the setting of the module
12
- *
13
- * @return mixed
14
- */
15
- public function getSettings()
16
- {
17
- return unserialize(Mage::getStoreConfig($this->_settingsKey));
18
- }
19
-
20
- /**
21
- * Sets the settings of the module
22
- *
23
- * @param $settings
24
- */
25
- public function setSettings($settings)
26
- {
27
- $config = Mage::getConfig();
28
- $config->saveConfig($this->_settingsKey, serialize($settings), 'default', 0)->reinit();
29
- }
30
-
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Aitloadmon.php DELETED
@@ -1,170 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon extends Mage_Core_Model_Mysql4_Abstract
7
- {
8
-
9
- private $_sysInfo;
10
-
11
-
12
- /**
13
- * Standard model constructor
14
- */
15
- public function _construct()
16
- {
17
- $this->_init('aitloadmon/aitloadmon', 'id');
18
- }
19
-
20
- /**
21
- * Initiates the data compression based on settings
22
- */
23
- public function compress()
24
- {
25
-
26
- $settings = Mage::getModel('aitloadmon/manage')->getSettings();
27
-
28
- if(!$settings['enabled'])
29
- {
30
- return;
31
- }
32
-
33
- //last day
34
- $format = $this->_getFormatByCompressType($settings['day']);
35
- $from = 'DATE_SUB( NOW( ) , INTERVAL 2 DAY )';
36
- $to = 'DATE_SUB( NOW( ) , INTERVAL 1 DAY )';
37
- $this->_compress($from, $to, $format);
38
-
39
- //last month
40
- $format = $this->_getFormatByCompressType($settings['month']);
41
- $from = 'DATE_SUB( NOW( ) , INTERVAL 2 MONTH )';
42
- $to = 'DATE_SUB( NOW( ) , INTERVAL 1 MONTH )';
43
- $this->_compress($from, $to, $format);
44
-
45
- //last year
46
- $format = $this->_getFormatByCompressType($settings['year']);
47
- $from = 'DATE_SUB( NOW( ) , INTERVAL 2 YEAR )';
48
- $to = 'DATE_SUB( NOW( ) , INTERVAL 1 YEAR )';
49
- $this->_compress($from, $to, $format);
50
-
51
- }
52
-
53
- /**
54
- * Returns compress formats for the data compression
55
- *
56
- * @return array
57
- */
58
- private function _getCompressFormats()
59
- {
60
- return array(
61
- 1 => '%y-%m-%d-%H',
62
- 2 => '%y-%m-%d',
63
- 3 => '%y-%m',
64
- );
65
- }
66
-
67
-
68
- /**
69
- * Gets the compress format by the compress type
70
- *
71
- * @param $id
72
- * @return mixed
73
- */
74
- private function _getFormatByCompressType($id)
75
- {
76
- $formats = $this->_getCompressFormats();
77
- if(isset($formats[$id]))
78
- {
79
- return $formats[$id];
80
- }
81
- else
82
- {
83
- return $formats[1];
84
- }
85
- }
86
-
87
- /**
88
- * Initiates manual compression
89
- *
90
- * @param string $from
91
- * @param string $to
92
- * @param int $formatId
93
- */
94
- public function manualCompress($from, $to, $formatId)
95
- {
96
- $this->_compress('\''.$from.'\'', '\''.$to.'\'', $this->_getFormatByCompressType($formatId));
97
- }
98
-
99
- /**
100
- * Gets the system table info
101
- *
102
- * @return mixed
103
- */
104
- private function _getSysInfo()
105
- {
106
- if(!isset($this->_sysInfo))
107
- {
108
- $read = Mage::getSingleton('core/resource')->getConnection('core_read');
109
- $query = 'SHOW TABLE STATUS WHERE Name = \''.$this->getTable('aitloadmon/aitloadmon').'\'';
110
- $this->_sysInfo = $read->fetchRow($query);
111
- }
112
-
113
- return $this->_sysInfo;
114
- }
115
-
116
- /**
117
- * Gets the number of rows of the table
118
- *
119
- * @return int
120
- */
121
- public function getRows()
122
- {
123
- $data = $this->_getSysInfo();
124
- return isset($data['Rows'])?$data['Rows']:0;
125
- }
126
-
127
- /**
128
- * Gets the size of the table
129
- *
130
- * @return int
131
- */
132
- public function getWeight()
133
- {
134
- $data = $this->_getSysInfo();
135
- return isset($data['Data_length'])?$data['Data_length']:0;
136
- }
137
-
138
- /**
139
- * Compresses data in the database
140
- *
141
- * @param string $from
142
- * @param string $to
143
- * @param string $format
144
- */
145
- private function _compress($from, $to, $format)
146
- {
147
- $table = $this->getTable('aitloadmon');
148
-
149
- $read = Mage::getSingleton('core/resource')->getConnection('core_read');
150
- $write = $read = Mage::getSingleton('core/resource')->getConnection('core_write');
151
-
152
- $where = 'measure_time>='.$from.' AND measure_time<='.$to;
153
-
154
- $readIdsQuery = 'SELECT id FROM '.$table.' WHERE '.$where;
155
- $ids = $read->fetchCol($readIdsQuery);
156
- if(!empty($ids))
157
- {
158
- $insertQuery ='INSERT INTO '.$table.' (measure_time, load_time_avg, load_time_max, page_group_id, page_views, max_page_views_per_minute, concurrent)
159
- SELECT MAX( measure_time ) AS measure_time, AVG( load_time_avg ) AS load_time_avg, MAX( load_time_max ) AS load_time_max, page_group_id, SUM( page_views ) AS page_views, MAX( max_page_views_per_minute ) AS max_page_views_per_minute, MAX( concurrent ) AS concurrent
160
- FROM '.$table.'
161
- WHERE '.$where.'
162
- GROUP BY DATE_FORMAT( `measure_time` , \''.$format.'\' ) , page_group_id';
163
- $write->query($insertQuery);
164
-
165
- $deleteQuery = 'DELETE FROM '.$table.' WHERE id IN('.implode(',',$ids).')';
166
- $write->query($deleteQuery);
167
- }
168
- }
169
-
170
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Aitloadmon/Collection.php DELETED
@@ -1,67 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
7
- {
8
- /**
9
- * Standard constructor
10
- */
11
- public function _construct()
12
- {
13
- $this->_init('aitloadmon/aitloadmon');
14
- }
15
-
16
- /**
17
- * Returns a string for GROUP BY in SQL
18
- *
19
- * @param string $startDate
20
- * @param string $endDate
21
- * @return bool|string
22
- */
23
- private function _getGroupString($startDate, $endDate)
24
- {
25
- $diff = strtotime($endDate) - strtotime($startDate);
26
- switch($diff)
27
- {
28
- case ($diff>30*24*3600):
29
- $format = '%y-%m';
30
- break;
31
- case ($diff>24*3600):
32
- $format = '%y-%m-%d';
33
- break;
34
- case ($diff>3600):
35
- $format = '%y-%m-%d-%H';
36
- break;
37
- default:
38
- return false;
39
- //$format = '%y-%m-%d-%H-%i';
40
- break;
41
- }
42
-
43
- return 'DATE_FORMAT(`measure_time`, "'.$format.'"), page_group_id';
44
- }
45
-
46
- /**
47
- * Gets a data collection bounded by 2 dates
48
- *
49
- * @param string $startDate
50
- * @param string $endDate
51
- * @return Aitoc_Aitloadmon_Model_Mysql4_Aitloadmon_Collection
52
- */
53
- public function filterByDates($startDate, $endDate)
54
- {
55
- if($groupString = $this->_getGroupString($startDate, $endDate))
56
- {
57
- $this->getSelect()->group($groupString)
58
- ->reset(Zend_Db_Select::COLUMNS)
59
- ->columns('measure_time, page_group_id, AVG(load_time_avg) AS load_time_avg, MAX(load_time_max) AS load_time_max, SUM(page_views) AS page_views, MAX(concurrent) as concurrent');
60
- }
61
-
62
- $this->getSelect()->where('measure_time >=?',$startDate)
63
- ->where('measure_time <=?',$endDate)
64
- ->order('measure_time');
65
- return $this;
66
- }
67
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Calculator.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Mysql4_Calculator extends Mage_Core_Model_Mysql4_Abstract
7
- {
8
- /**
9
- * Standard model constructor
10
- */
11
- public function _construct()
12
- {
13
- $this->_init('aitloadmon/calculator', 'id');
14
- }
15
-
16
- /**
17
- * Deletes everything from the table
18
- */
19
- public function deleteAll()
20
- {
21
- $adapter = $this->_getWriteAdapter();
22
- $sql = 'DELETE FROM '.$this->getTable('aitloadmon/calculator');
23
- $adapter->query($sql);
24
- }
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Calculator/Collection.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Mysql4_Calculator_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
7
- {
8
- /**
9
- * Standard constructor
10
- */
11
- public function _construct()
12
- {
13
- $this->_init('aitloadmon/calculator');
14
- }
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Dblog.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Mysql4_Dblog extends Mage_Core_Model_Mysql4_Abstract
7
- {
8
-
9
- /**
10
- * Standard model constructor
11
- */
12
- public function _construct()
13
- {
14
- $this->_init('aitloadmon/dblog', 'url_id');
15
- }
16
-
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/Dblog/Collection.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Mysql4_Dblog_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
7
- {
8
- /**
9
- * Standard constructor
10
- */
11
- public function _construct()
12
- {
13
- $this->_init('aitloadmon/dblog');
14
- }
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Mysql4/UrlRewrite.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Mysql4_UrlRewrite extends Mage_Core_Model_Mysql4_Url_Rewrite
7
- {
8
- /**
9
- * Load rewrite information for request
10
- * If $path is array - we must load all possible records and choose one matching earlier record in array
11
- *
12
- * @param Mage_Core_Model_Url_Rewrite $object
13
- * @param array|string $path
14
- * @return Mage_Core_Model_Resource_Url_Rewrite
15
- */
16
- public function loadByRequestPath(Mage_Core_Model_Url_Rewrite $object, $path)
17
- {
18
- if (!is_array($path)) {
19
- $path = array($path);
20
- }
21
-
22
- $pathBind = array();
23
- foreach ($path as $key => $url) {
24
- $pathBind['path' . $key] = $url;
25
- }
26
- // Form select
27
- $adapter = $this->_getReadAdapter();
28
- $select = $adapter->select()
29
- ->from($this->getMainTable())
30
- ->where('request_path IN (:' . implode(', :', array_flip($pathBind)) . ')');
31
- //->where('store_id IN(?)', array(Mage_Core_Model_App::ADMIN_STORE_ID, (int)$object->getStoreId()));
32
-
33
- $items = $adapter->fetchAll($select, $pathBind);
34
-
35
- // Go through all found records and choose one with lowest penalty - earlier path in array, concrete store
36
- $mapPenalty = array_flip(array_values($path)); // we got mapping array(path => index), lower index - better
37
- $currentPenalty = null;
38
- $foundItem = null;
39
- foreach ($items as $item) {
40
- if (!array_key_exists($item['request_path'], $mapPenalty)) {
41
- continue;
42
- }
43
- $penalty = $mapPenalty[$item['request_path']] << 1 + ($item['store_id'] ? 0 : 1);
44
- if (!$foundItem || $currentPenalty > $penalty) {
45
- $foundItem = $item;
46
- $currentPenalty = $penalty;
47
- if (!$currentPenalty) {
48
- break; // Found best matching item with zero penalty, no reason to continue
49
- }
50
- }
51
- }
52
-
53
- // Set data and finish loading
54
- if ($foundItem) {
55
- $object->setData($foundItem);
56
- }
57
-
58
- // Finish
59
- //$this->unserializeFields($object);
60
- $this->_afterLoad($object);
61
-
62
- return $this;
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Observer.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Observer
7
- {
8
- protected $_systemKey = 'system/aitloadmon/sent_info_date';
9
- protected $_expire = 604799;
10
-
11
- /**
12
- * Initiates the data processing job
13
- */
14
- public function processData()
15
- {
16
- Mage::getModel('aitloadmon/process')->processData();
17
- }
18
-
19
- /**
20
- * Initiates the data compressing job
21
- */
22
- public function compressData()
23
- {
24
- Mage::getModel('aitloadmon/aitloadmon')->getResource()->compress();
25
- }
26
-
27
- /**
28
- * Sends the info to Server Calculator by cron
29
- */
30
- public function sendToAitoc()
31
- {
32
- $date = Mage::getStoreConfig($this->_systemKey);
33
- $expire = $this->_expire;
34
- if(!$date)
35
- {
36
- Mage::getConfig()
37
- ->saveConfig($this->_systemKey, time(), 'default', 0)
38
- ->reinit();
39
- }
40
- elseif((time() - $date) >= $expire)
41
- {
42
- Mage::getModel('aitloadmon/calculator')->sendCalcInfo();
43
- Mage::getConfig()
44
- ->saveConfig($this->_systemKey, time(), 'default', 0)
45
- ->reinit();
46
- }
47
- }
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Process.php DELETED
@@ -1,381 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Process extends Mage_Core_Controller_Varien_Front
7
- {
8
- /**
9
- * Collects Magento routes
10
- *
11
- * @return Aitoc_Aitloadmon_Model_Process
12
- */
13
- protected function _init()
14
- {
15
- $router = Mage::getModel('aitloadmon/router');
16
- $router->collectRoutes('frontend', 'standard');
17
- $this->addRouter('custom', $router);
18
-
19
- $default = new Mage_Core_Controller_Varien_Router_Default();
20
- $this->addRouter('default', $default);
21
-
22
- return $this;
23
- }
24
-
25
- /**
26
- * Pre-processes data for saving
27
- *
28
- * @param array $data
29
- * @return array
30
- */
31
- private function _prepareForSave($data)
32
- {
33
- $result = array();
34
- $concurrents = array();
35
- foreach($data as $data_item)
36
- {
37
- if(isset($data_item['request_uri']) && isset($data_item['start']) && $data_item['start'] && isset($data_item['end']) && $data_item['end'])
38
- {
39
- if($groupId = $this->_getGroupIdByUri('http://some.host'.$data_item['request_uri']))
40
- {
41
- if(!isset($result[$groupId]))
42
- {
43
- $result[$groupId] = array('sum'=>0,'max'=>0,'cnt'=>0,'concurrent'=>0,'concurrent_load'=>0);
44
- $concurrents[$groupId] = array();
45
- }
46
- $loadTime = (float)$data_item['end'] - (float)$data_item['start'];
47
- $result[$groupId]['sum'] += $loadTime;
48
- $result[$groupId]['end'] = $data_item['end'];
49
- if($loadTime > $result[$groupId]['max'])
50
- {
51
- $result[$groupId]['max'] = $loadTime;
52
- }
53
- $result[$groupId]['cnt']++;
54
- $concurrents[$groupId]['starts'][] = array('start' => $data_item['start'], 'loadTime' => $loadTime);
55
- $concurrents[$groupId]['ends'][] = array('end' => $data_item['end'], 'loadTime' => $loadTime);
56
- }
57
- }
58
-
59
- }
60
-
61
- $tmp_data = array(); $cnt = 0;
62
- foreach($concurrents as $groupId => $groupData)
63
- {
64
- $tmp_data = array_merge_recursive($tmp_data, $groupData); $cnt+=count($groupData['starts']);
65
- list($result[$groupId]['concurrent'],$result[$groupId]['concurrent_load']) = $this->_getConcurrent($groupData);
66
- }
67
- $tmp_data = $this->_getConcurrent($tmp_data);
68
- $result['concurrent'] = $tmp_data[0];
69
- return $result;
70
- }
71
-
72
- private function _sortConcurrentData($a, $b)
73
- {
74
- $key = isset($a['start'])?'start':'end';
75
- return ($a[$key] < $b[$key]) ? -1 : 1;
76
- }
77
-
78
-
79
- /**
80
- * Calculates data for concurrent scripts and load time
81
- *
82
- * @param array $data
83
- * @return array
84
- */
85
- private function _getConcurrent($data)
86
- {
87
- $tmp_conc = 0;
88
- $tmp_load = 0;
89
- $result = array(0,0);
90
- $i = 0;
91
- if(!is_array($data['starts']) || !is_array($data['ends']))
92
- {
93
- return $result;
94
- }
95
- usort($data['starts'], array($this,'_sortConcurrentData'));
96
- usort($data['ends'], array($this,'_sortConcurrentData'));
97
-
98
- foreach($data['ends'] as $end)
99
- {
100
- while(isset($data['starts'][$i]) && $data['starts'][$i]['start'] <= $end['end'])
101
- {
102
- $tmp_conc++;
103
- $tmp_load += $data['starts'][$i]['loadTime'];
104
- $i++;
105
- if($result[0] < $tmp_conc)
106
- {
107
- $result[0] = $tmp_conc;
108
- $result[1] = (float)$tmp_load/$tmp_conc;
109
- }
110
- }
111
- $tmp_conc--;
112
- $tmp_load -= $end['loadTime'];
113
- }
114
- return $result;
115
- }
116
-
117
- /**
118
- * Saves the processed data to database
119
- *
120
- * @param array $result
121
- * @return float|int
122
- */
123
- private function _saveData($result)
124
- {
125
- $model = Mage::getModel('aitloadmon/aitloadmon');
126
- $calcModel = Mage::getModel('aitloadmon/calculator');
127
- $calcModel->load(0);
128
- $maxAvgLoadTime = 0;
129
- foreach($result as $groupId => $resultItem)
130
- {
131
- if(is_integer($groupId))
132
- {
133
- $avgLoadTime = $resultItem['sum']/$resultItem['cnt'];
134
- if($avgLoadTime > $maxAvgLoadTime)
135
- {
136
- $maxAvgLoadTime = $avgLoadTime;
137
- }
138
- $model->load(0);
139
- $model->setData(array(
140
-
141
- 'measure_time' => date('Y-m-d H:i:s',ceil((int)$resultItem['end']/60)*60),
142
- 'load_time_avg' => $avgLoadTime,
143
- 'load_time_max' => $resultItem['max'],
144
- 'page_group_id' => $groupId,
145
- 'page_views' => $resultItem['cnt'],
146
- 'max_page_views_per_minute' => $resultItem['cnt'],
147
- 'concurrent' => $resultItem['concurrent'],
148
-
149
- ));
150
- $model->save();
151
-
152
- $calcModel->addData(array(
153
- 'pg'.$groupId.'_concurrent_load' => $resultItem['concurrent_load'],
154
- 'pg'.$groupId.'_concurrent' => $resultItem['concurrent'],
155
- ));
156
-
157
- }
158
- }
159
-
160
- if($result['concurrent'])
161
- {
162
- $calcModel->setConcurrent($result['concurrent']);
163
- $calcModel->save();
164
- }
165
-
166
-
167
- return $maxAvgLoadTime;
168
- }
169
-
170
- /**
171
- * Returns a load level based on load time
172
- *
173
- * @param float|int $maxAvgLoadTime
174
- * @return int
175
- */
176
- private function _getLoadLevelByLoad($maxAvgLoadTime)
177
- {
178
- $yellow = Mage::getStoreConfig('system/aitloadmon/load_yellow');
179
- $red = Mage::getStoreConfig('system/aitloadmon/load_red');
180
- $black = Mage::getStoreConfig('system/aitloadmon/load_black');
181
- if($maxAvgLoadTime > $black)
182
- {
183
- $loadLevel = Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_BLACK;
184
- }
185
- elseif($maxAvgLoadTime > $red)
186
- {
187
- $loadLevel = Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_RED;
188
- }
189
- elseif($maxAvgLoadTime > $yellow)
190
- {
191
- $loadLevel = Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_YELLOW;
192
- }
193
- else
194
- {
195
- $loadLevel = Aitoc_Aitloadmon_Model_Aitloadmon::LOAD_LEVEL_GREEN;
196
- }
197
- return $loadLevel;
198
- }
199
-
200
- /**
201
- * Splits the data by minutes
202
- *
203
- * @param $data
204
- * @return array
205
- */
206
- private function _getTimedData($data)
207
- {
208
- $return = array();
209
- foreach($data as $dataItem)
210
- {
211
- if(isset($dataItem['end']))
212
- {
213
- $minute = ceil((int)$dataItem['end']/60);
214
- if(!isset($return[$minute]))
215
- {
216
- $return[$minute] = array();
217
- }
218
- $return[$minute][] = $dataItem;
219
- }
220
- }
221
-
222
- return $return;
223
- }
224
-
225
- /**
226
- * Processes the data collected earlier
227
- *
228
- * @return array
229
- */
230
- public function processData()
231
- {
232
-
233
- $this->_init();
234
- $rawData = Aitoc_Aitloadmon_Collect::getData();
235
- $maxAvgLoadTime = 0;
236
- $timedData = $this->_getTimedData($rawData);
237
-
238
- foreach($timedData as $data)
239
- {
240
- $result = $this->_prepareForSave($data);
241
- $maxAvgLoadTimeTemp = $this->_saveData($result);
242
- $maxAvgLoadTime = ($maxAvgLoadTime<$maxAvgLoadTimeTemp)?$maxAvgLoadTimeTemp:$maxAvgLoadTime;
243
- }
244
-
245
- $currentLoadLevel = $this->_getLoadLevelByLoad($maxAvgLoadTime);
246
- $oldLoadLevel = Mage::helper('aitloadmon')->getLoadLevel();
247
- if($currentLoadLevel != $oldLoadLevel)
248
- {
249
- Mage::helper('aitloadmon')->setLoadLevel($currentLoadLevel);
250
- Mage::dispatchEvent('aitloadmon_load_level_changed',array('from'=>$oldLoadLevel,'to'=>$currentLoadLevel));
251
- }
252
- return isset($result)?$result:array();
253
- }
254
-
255
- private function _getUrlCuts()
256
- {
257
- if(!isset($this->_urlCuts))
258
- {
259
- $stores = Mage::getModel('core/store')->getCollection();
260
- $storeUrls = array();
261
- $urlCuts = array();
262
- foreach($stores as $store)
263
- {
264
- $id = $store->getId();
265
- $storeUrls[] = Mage::getStoreConfig('web/unsecure/base_url',$id);
266
- $storeUrls[] = Mage::getStoreConfig('web/secure/base_url',$id);
267
- $storeUrls[] = Mage::getStoreConfig('web/unsecure/base_link_url',$id);
268
- $storeUrls[] = Mage::getStoreConfig('web/secure/base_link_url',$id);
269
- }
270
- foreach(array_unique($storeUrls) as $url)
271
- {
272
- $parsedUrl = parse_url($url);
273
- if(isset($parsedUrl['path']))
274
- {
275
- $url = ltrim($parsedUrl['path'],'/');
276
- if($url)
277
- {
278
- $urlCuts[] = $url;
279
- }
280
- }
281
- }
282
- $this->_urlCuts = $urlCuts;
283
- }
284
- return $this->_urlCuts;
285
- }
286
-
287
-
288
- /**
289
- * Gets page view group based on its request uri
290
- *
291
- * @param string $uri
292
- * @return int|bool
293
- */
294
- private function _getGroupIdByUri($uri)
295
- {
296
- $urlCuts = $this->_getUrlCuts();
297
- foreach($urlCuts as $urlCut)
298
- {
299
- $uri = str_replace($urlCut,'',$uri);
300
- }
301
- $uri = str_replace('index.php/','',$uri);
302
-
303
- if (Mage::helper('aitloadmon')->checkUriExclude($uri))
304
- {
305
- return false;
306
- }
307
-
308
- $request = new Mage_Core_Controller_Request_Http($uri);
309
- //commented if for 1401 support
310
- //if (!$request->isStraight()) {
311
- Mage::getModel('aitloadmon/urlRewrite')->rewrite($request);
312
- //}
313
- $this->_rewriteRequest($request);
314
-
315
- foreach ($this->_routers as $router) {
316
- if ($router->match($request)) {
317
- break;
318
- }
319
- }
320
- $module = $request->getModuleName();
321
- $groupIds = Mage::helper('aitloadmon')->getGroupsArray();
322
- if($module == 'admin')
323
- {
324
- return false;
325
- }
326
- elseif(isset($groupIds[$module]))
327
- {
328
- return $groupIds[$module];
329
- }
330
- else
331
- {
332
- return 1;
333
- }
334
- }
335
-
336
- /**
337
- * Applies rewrites to the request object
338
- *
339
- * @param $request
340
- */
341
- private function _rewriteRequest($request)
342
- {
343
- $config = Mage::getConfig()->getNode('global/rewrite');
344
- if (!$config) {
345
- return;
346
- }
347
- foreach ($config->children() as $rewrite) {
348
- $from = (string)$rewrite->from;
349
- $to = (string)$rewrite->to;
350
- if (empty($from) || empty($to)) {
351
- continue;
352
- }
353
- $from = $this->_processRewriteUrl($from);
354
- $to = $this->_processRewriteUrl($to);
355
-
356
- $pathInfo = preg_replace($from, $to, $request->getPathInfo());
357
-
358
- if (isset($rewrite->complete)) {
359
- $request->setPathInfo($pathInfo);
360
- } else {
361
- $request->rewritePathInfo($pathInfo);
362
- }
363
- }
364
-
365
- }
366
-
367
- protected function _processRewriteUrl($url)
368
- {
369
- $startPos = strpos($url, '{');
370
- if ($startPos!==false) {
371
- $endPos = strpos($url, '}');
372
- $routeName = substr($url, $startPos+1, $endPos-$startPos-1);
373
- $router = Mage::getModel('aitloadmon/router');//$this->getRouterByRoute($routeName);
374
- if ($router) {
375
- $fronName = $router->getFrontNameByRoute($routeName);
376
- $url = str_replace('{'.$routeName.'}', $fronName, $url);
377
- }
378
- }
379
- return $url;
380
- }
381
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/Router.php DELETED
@@ -1,162 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_Router extends Mage_Core_Controller_Varien_Router_Standard
7
- {
8
- /**
9
- * Dispatches the request until the needed module is found and sets the module params to the request object.
10
- * Is needed to detect the requested page view group by its module name
11
- *
12
- * This is mainly a copy paste from Magento core, but it does not execute the routed action
13
- *
14
- * @param Zend_Controller_Request_Http $request
15
- * @return bool
16
- */
17
-
18
- public function match(Zend_Controller_Request_Http $request)
19
- {
20
- //checking before even try to find out that current module
21
- //should use this router
22
- #if (!$this->_beforeModuleMatch()) {
23
- # return false;
24
- #}
25
-
26
- $this->fetchDefault();
27
-
28
- $front = $this->getFront();
29
- $path = trim($request->getPathInfo(), '/');
30
-
31
- if ($path) {
32
- $p = explode('/', $path);
33
- } else {
34
- $p = explode('/', Mage::getStoreConfig('web/default/front'));
35
- }
36
-
37
- // get module name
38
- if ($request->getModuleName()) {
39
- $module = $request->getModuleName();
40
- } else {
41
- if (!empty($p[0])) {
42
- $module = $p[0];
43
- } else {
44
- $module = $this->getFront()->getDefault('module');
45
- $request->setAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS, '');
46
- }
47
- }
48
- if (!$module) {
49
- if (Mage::app()->getStore()->isAdmin()) {
50
- $module = 'admin';
51
- } else {
52
- return false;
53
- }
54
- }
55
-
56
- /**
57
- * Searching router args by module name from route using it as key
58
- */
59
- $modules = $this->getModuleByFrontName($module);
60
-
61
- if ($modules === false) {
62
- return false;
63
- }
64
-
65
- // checks after we found out that this router should be used for current module
66
- #if (!$this->_afterModuleMatch()) {
67
- # return false;
68
- #}
69
-
70
- /**
71
- * Going through modules to find appropriate controller
72
- */
73
- $found = false;
74
- foreach ($modules as $realModule) {
75
- $request->setRouteName($this->getRouteByFrontName($module));
76
-
77
- // get controller name
78
- if ($request->getControllerName()) {
79
- $controller = $request->getControllerName();
80
- } else {
81
- if (!empty($p[1])) {
82
- $controller = $p[1];
83
- } else {
84
- $controller = $front->getDefault('controller');
85
- $request->setAlias(
86
- Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
87
- ltrim($request->getOriginalPathInfo(), '/')
88
- );
89
- }
90
- }
91
-
92
- // get action name
93
- if (empty($action)) {
94
- if ($request->getActionName()) {
95
- $action = $request->getActionName();
96
- } else {
97
- $action = !empty($p[2]) ? $p[2] : $front->getDefault('action');
98
- }
99
- }
100
-
101
- //checking if this place should be secure
102
- //$this->_checkShouldBeSecure($request, '/'.$module.'/'.$controller.'/'.$action);
103
-
104
- $controllerClassName = $this->_validateControllerClassName($realModule, $controller);
105
- if (!$controllerClassName) {
106
- continue;
107
- }
108
-
109
- // instantiate controller class
110
- $controllerInstance = Mage::getControllerInstance($controllerClassName, $request, $front->getResponse());
111
-
112
- if (!$controllerInstance->hasAction($action)) {
113
- continue;
114
- }
115
-
116
- $found = true;
117
- break;
118
- }
119
-
120
- /**
121
- * if we did not found any suitable
122
- */
123
- if (!$found) {
124
- if ($this->_noRouteShouldBeApplied()) {
125
- $controller = 'index';
126
- $action = 'noroute';
127
-
128
- $controllerClassName = $this->_validateControllerClassName($realModule, $controller);
129
- if (!$controllerClassName) {
130
- return false;
131
- }
132
-
133
- // instantiate controller class
134
- $controllerInstance = Mage::getControllerInstance($controllerClassName, $request,
135
- $front->getResponse());
136
-
137
- if (!$controllerInstance->hasAction($action)) {
138
- return false;
139
- }
140
- } else {
141
- return false;
142
- }
143
- }
144
-
145
- // set values only after all the checks are done
146
- $request->setModuleName($module);
147
- $request->setControllerName($controller);
148
- $request->setActionName($action);
149
- $request->setControllerModule($realModule);
150
-
151
- // set parameters from pathinfo
152
- #for ($i = 3, $l = sizeof($p); $i < $l; $i += 2) {
153
- # $request->setParam($p[$i], isset($p[$i+1]) ? urldecode($p[$i+1]) : '');
154
- #}
155
-
156
- // dispatch action
157
- #$request->setDispatched(true);
158
- #$controllerInstance->dispatch($action);
159
-
160
- return true;
161
- }
162
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/SysInfo.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_SysInfo extends Aitoc_Aitloadmon_Model_System_Abstract
7
- {
8
- protected $_systemUrl = 'http://www.aitoc.com/configuration-calculator';
9
- protected $_systemKey = 'system/aitloadmon/system_info';
10
- protected $_systemDateKey = 'system/aitloadmon/system_info_date';
11
- protected $_expire = 86400;
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/System.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_System extends Aitoc_Aitloadmon_Model_System_Abstract
7
- {
8
- protected $_systemUrl = 'http://www.aitoc.com/monitor-module-news';
9
- protected $_systemKey = 'system/aitloadmon/system';
10
- protected $_systemDateKey = 'system/aitloadmon/system_date';
11
- protected $_expire = 86400;
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/System/Abstract.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- abstract class Aitoc_Aitloadmon_Model_System_Abstract
7
- {
8
- public function getSystem()
9
- {
10
- $system_body = Mage::getStoreConfig($this->_systemKey);
11
- $date = Mage::getStoreConfig($this->_systemDateKey);
12
- if(!$system_body || (time()-$date)>$this->_expire)
13
- {
14
- $system = @file_get_contents($this->_systemUrl);
15
- preg_match('/<body.*?>(.*)<\/body>/msi',$system,$matches);
16
- $system_body = '';
17
- if(isset($matches[1]))
18
- {
19
- $system_body = $matches[1];
20
- }
21
- Mage::getConfig()
22
- ->saveConfig($this->_systemKey, $system_body, 'default', 0)
23
- ->saveConfig($this->_systemDateKey, time(), 'default', 0)
24
- ->reinit();
25
- }
26
- return $system_body;
27
- }
28
-
29
- public function getSystemUrl()
30
- {
31
- return $this->_systemUrl;
32
- }
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/Model/UrlRewrite.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Model_UrlRewrite extends Mage_Core_Model_Url_Rewrite
7
- {
8
- /**
9
- * Standard model constructor
10
- */
11
- protected function _construct()
12
- {
13
- $this->_init('aitloadmon/urlRewrite');
14
- }
15
-
16
- public function loadByRequestPath($path)
17
- {
18
- $this->setId(null);
19
- $this->_getResource()->loadByRequestPath($this, $path);
20
- $this->_afterLoad();
21
- $this->setOrigData();
22
- $this->_hasDataChanges = false;
23
- return $this;
24
- }
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/controllers/Adminhtml/AitloadmonController.php DELETED
@@ -1,108 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Adminhtml_AitloadmonController extends Mage_Adminhtml_Controller_Action
7
- {
8
- /**
9
- * Sets active menu, breadcrumbs and title
10
- *
11
- * @return Aitoc_Aitloadmon_Adminhtml_AitloadmonController
12
- */
13
- protected function _initIndexAction()
14
- {
15
- if(!class_exists('Aitoc_Aitloadmon_Collect',false))
16
- {
17
- Mage::getSingleton('core/session')->addError(Mage::helper('aitloadmon')->__('Please add the following line to your index.php file(s):<br>include_once(dirname($_SERVER[\'SCRIPT_FILENAME\']).DIRECTORY_SEPARATOR.\'lib\'.DIRECTORY_SEPARATOR.\'Aitoc\'.DIRECTORY_SEPARATOR.\'Aitloadmon\'.DIRECTORY_SEPARATOR.\'Collect.php\');new Aitoc_Aitloadmon_Collect();'));
18
- }
19
- $this->loadLayout()
20
- ->_setActiveMenu('system/aitloadmon')
21
- ->_addBreadcrumb(Mage::helper('aitloadmon')->__('View Stats'), Mage::helper('aitloadmon')->__('View Stats'));
22
- $this->_title(Mage::helper('aitloadmon')->__('Server Load Monitor'))->_title(Mage::helper('aitloadmon')->__('View Stats'));
23
- return $this;
24
- }
25
-
26
- /**
27
- * Sets active menu, breadcrumbs and title
28
- *
29
- * @return Aitoc_Aitloadmon_Adminhtml_AitloadmonController
30
- */
31
- protected function _initManageAction()
32
- {
33
- $this->loadLayout()
34
- ->_setActiveMenu('system/aitloadmon')
35
- ->_addBreadcrumb(Mage::helper('aitloadmon')->__('Manage Data'), Mage::helper('aitloadmon')->__('Manage Data'));
36
- $this->_title(Mage::helper('aitloadmon')->__('Server Load Monitor'))->_title(Mage::helper('aitloadmon')->__('Manage Data'));
37
- return $this;
38
- }
39
-
40
- /**
41
- * Processes request and sets its data to the main block
42
- */
43
- public function indexAction() {
44
- $this->_initIndexAction();
45
-
46
- if(!$startDate = $this->getRequest()->getParam('startDate'))
47
- {
48
- $startDate = date('Y-m-d H:i:s', time()-3600+1);
49
- }
50
-
51
- if(!$endDate = $this->getRequest()->getParam('endDate'))
52
- {
53
- $endDate = date('Y-m-d H:i:s');
54
- }
55
-
56
- $type = $this->getRequest()->getParam('type');
57
- if(!$type)
58
- {
59
- $type = 'max';
60
- }
61
-
62
- $this->getLayout()->getBlock('main_bl')
63
- ->setType($type)
64
- ->setStartDate($startDate)
65
- ->setEndDate($endDate);
66
-
67
- $compare = $this->getRequest()->getParam('compare');
68
-
69
- if($compare && !$startDateCompare = $this->getRequest()->getParam('startDateCompare'))
70
- {
71
- $startDateCompare = date('Y-m-d H:i:s', time()-86400);
72
- }
73
-
74
- if($compare)
75
- {
76
- $endDateCompare = date('Y-m-d H:i:s', strtotime($startDateCompare) + (strtotime($endDate) - strtotime($startDate)));
77
- $this->getLayout()->getBlock('main_bl')->setCompare($compare)
78
- ->setStartDateCompare($startDateCompare)
79
- ->setEndDateCompare($endDateCompare);
80
- }
81
-
82
- $this->renderLayout();
83
- }
84
-
85
- /**
86
- * This action is used to display the manage data blocks and forms
87
- */
88
- public function manageAction() {
89
- if(Mage::app()->getRequest()->getParam('submit_auto'))
90
- {
91
- $data = array(
92
- 'enabled' => Mage::app()->getRequest()->getParam('auto_enable'),
93
- 'year' => Mage::app()->getRequest()->getParam('auto_year'),
94
- 'month' => Mage::app()->getRequest()->getParam('auto_month'),
95
- 'day' => Mage::app()->getRequest()->getParam('auto_day'),
96
- );
97
- Mage::getModel('aitloadmon/manage')->setSettings($data);
98
- Mage::getSingleton('core/session')->addSuccess(Mage::helper('aitloadmon')->__('The settings are successfully saved.'));
99
- }
100
- elseif(Mage::app()->getRequest()->getParam('submit_manual'))
101
- {
102
- Mage::getModel('aitloadmon/aitloadmon')->getResource()->manualCompress(Mage::app()->getRequest()->getParam('manual_from'), Mage::app()->getRequest()->getParam('manual_to'), Mage::app()->getRequest()->getParam('manual_compress'));
103
- Mage::getSingleton('core/session')->addSuccess(Mage::helper('aitloadmon')->__('The data is successfully compressed.'));
104
- }
105
- $this->_initManageAction();
106
- $this->renderLayout();
107
- }
108
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/controllers/Adminhtml/CalculatorController.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Adminhtml_CalculatorController extends Mage_Adminhtml_Controller_Action
7
- {
8
- /**
9
- * Opens the form for data source selection for Server Calculator
10
- */
11
- public function indexAction()
12
- {
13
-
14
- $this->loadLayout()
15
- ->_setActiveMenu('system/aitloadmon')
16
- ->_addBreadcrumb(Mage::helper('aitloadmon')->__('Info for Magento Server Configuration Calculator'), Mage::helper('aitloadmon')->__('Info for Magento Server Configuration Calculator'));
17
- $this->_title(Mage::helper('aitloadmon')->__('Server Load Monitor'))->_title(Mage::helper('aitloadmon')->__('Info for Magento Server Configuration Calculator'));
18
- $this->renderLayout();
19
-
20
- /*$this->loadLayout()
21
- ->_setActiveMenu('system/aitloadmon')
22
- ->_addBreadcrumb(Mage::helper('aitloadmon')->__('Info for Magento Server Configuration Calculator'), Mage::helper('aitloadmon')->__('Info for Server Calculator'));
23
- $this->_title(Mage::helper('aitloadmon')->__('Server Load Monitor'))->_title(Mage::helper('aitloadmon')->__('Info for Magento Server Configuration Calculator'));
24
-
25
- $model = Mage::getModel('aitloadmon/calculator');
26
- $method = 'getMonitorVisitors';
27
- $this->getLayout()->getBlock('aitload_calculator_result')
28
- ->setProducts($model->getProductInfo())
29
- ->setLoad($model->$method());
30
- $this->renderLayout();*/
31
-
32
- }
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/etc/adminhtml.xml DELETED
@@ -1,58 +0,0 @@
1
- <?xml version="1.0"?>
2
- <config>
3
- <menu>
4
- <system>
5
- <children>
6
- <stats module="aitloadmon">
7
- <title>Server Load Monitor</title>
8
- <sort_order>2</sort_order>
9
- <action>adminhtml/aitloadmon</action>
10
- <children>
11
- <stats translate="title" module="aitloadmon">
12
- <title>View Stats</title>
13
- <action>adminhtml/aitloadmon</action>
14
- <sort_order>10</sort_order>
15
- </stats>
16
- <calc translate="title" module="aitloadmon">
17
- <title>Info for Magento Server Configuration Calculator</title>
18
- <action>adminhtml/calculator</action>
19
- <sort_order>20</sort_order>
20
- </calc>
21
- </children>
22
- </stats>
23
- </children>
24
- </system>
25
- </menu>
26
- <acl>
27
- <resources>
28
- <admin>
29
- <children>
30
- <system>
31
- <children>
32
- <stats>
33
- <title>Server Load Monitor</title>
34
- <sort_order>2</sort_order>
35
- <children>
36
- <stats>
37
- <title>View Stats</title>
38
- <sort_order>10</sort_order>
39
- </stats>
40
- <calc>
41
- <title>Info for Magento Server Configuration Calculator</title>
42
- <sort_order>20</sort_order>
43
- </calc>
44
- </children>
45
- </stats>
46
- </children>
47
- </system>
48
- </children>
49
- </admin>
50
- </resources>
51
- </acl>
52
- </config>
53
- <!--
54
- /**
55
- * @copyright Copyright (c) 2013 AITOC, Inc.
56
- * @license License agreement could be found at the root folder of this package
57
- */
58
- -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/etc/config.xml DELETED
@@ -1,112 +0,0 @@
1
- <?xml version="1.0"?>
2
- <config>
3
- <modules>
4
- <Aitoc_Aitloadmon>
5
- <version>1.0.2</version>
6
- </Aitoc_Aitloadmon>
7
- </modules>
8
- <admin>
9
- <routers>
10
- <adminhtml>
11
- <args>
12
- <modules>
13
- <aitloadmon before="Mage_Adminhtml">Aitoc_Aitloadmon_Adminhtml</aitloadmon>
14
- </modules>
15
- </args>
16
- </adminhtml>
17
- </routers>
18
- </admin>
19
- <adminhtml>
20
- <layout>
21
- <updates>
22
- <aitloadmon>
23
- <file>aitloadmon.xml</file>
24
- </aitloadmon>
25
- </updates>
26
- </layout>
27
- </adminhtml>
28
- <global>
29
- <models>
30
- <aitloadmon>
31
- <class>Aitoc_Aitloadmon_Model</class>
32
- <resourceModel>aitloadmon_mysql4</resourceModel>
33
- </aitloadmon>
34
- <aitloadmon_mysql4>
35
- <class>Aitoc_Aitloadmon_Model_Mysql4</class>
36
- <entities>
37
- <aitloadmon>
38
- <table>aitloadmon</table>
39
- </aitloadmon>
40
- <dblog>
41
- <table>log_url</table>
42
- </dblog>
43
- <calculator>
44
- <table>aitloadmon_calculator</table>
45
- </calculator>
46
- </entities>
47
- </aitloadmon_mysql4>
48
- </models>
49
- <resources>
50
- <aitloadmon_setup>
51
- <setup>
52
- <module>Aitoc_Aitloadmon</module>
53
- </setup>
54
- <connection>
55
- <use>core_setup</use>
56
- </connection>
57
- </aitloadmon_setup>
58
- <aitloadmon_write>
59
- <connection>
60
- <use>core_write</use>
61
- </connection>
62
- </aitloadmon_write>
63
- <aitloadmon_read>
64
- <connection>
65
- <use>core_read</use>
66
- </connection>
67
- </aitloadmon_read>
68
- </resources>
69
- <blocks>
70
- <aitloadmon>
71
- <class>Aitoc_Aitloadmon_Block</class>
72
- </aitloadmon>
73
- </blocks>
74
- <helpers>
75
- <aitloadmon>
76
- <class>Aitoc_Aitloadmon_Helper</class>
77
- </aitloadmon>
78
- </helpers>
79
- </global>
80
- <crontab>
81
- <jobs>
82
- <aitloadmon_process_data>
83
- <schedule><cron_expr>*/5 * * * *</cron_expr></schedule>
84
- <run><model>aitloadmon/observer::processData</model></run>
85
- </aitloadmon_process_data>
86
- <aitloadmon_compress_data>
87
- <schedule><cron_expr>1 */1 * * *</cron_expr></schedule>
88
- <run><model>aitloadmon/observer::compressData</model></run>
89
- </aitloadmon_compress_data>
90
- <aitloadmon_calc_send>
91
- <schedule><cron_expr>1 4 * * *</cron_expr></schedule>
92
- <run><model>aitloadmon/observer::sendToAitoc</model></run>
93
- </aitloadmon_calc_send>
94
- </jobs>
95
- </crontab>
96
- <default>
97
- <system>
98
- <aitloadmon>
99
- <load_yellow>3</load_yellow>
100
- <load_red>7</load_red>
101
- <load_black>10</load_black>
102
- <manage>a:4:{s:7:"enabled";i:1;s:4:"year";i:3;s:5:"month";i:2;s:3:"day";i:1;}</manage>
103
- </aitloadmon>
104
- </system>
105
- </default>
106
- </config>
107
- <!--
108
- /**
109
- * @copyright Copyright (c) 2013 AITOC, Inc.
110
- * @license License agreement could be found at the root folder of this package
111
- */
112
- -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/etc/system.xml DELETED
@@ -1,77 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <config>
3
- <sections>
4
- <system>
5
- <groups>
6
- <aitloadmon translate="label" module="aitloadmon">
7
- <label>Server Load Monitor</label>
8
- <frontend_type>text</frontend_type>
9
- <sort_order>1010</sort_order>
10
- <show_in_default>1</show_in_default>
11
- <show_in_website>0</show_in_website>
12
- <show_in_store>0</show_in_store>
13
- <fields>
14
- <load_yellow translate="label">
15
- <label>Yellow load level after</label>
16
- <comment><![CDATA[Yellow load level means average server load (sec); default value is 3 sec (Green load level will be if the response time will be less or equal 3 sec that means minor server load)]]></comment>
17
- <frontend_type>text</frontend_type>
18
- <validate>validate-number</validate>
19
- <sort_order>500</sort_order>
20
- <show_in_default>1</show_in_default>
21
- <show_in_website>0</show_in_website>
22
- <show_in_store>0</show_in_store>
23
- </load_yellow>
24
-
25
- <load_red translate="label">
26
- <label>Red load level after</label>
27
- <comment><![CDATA[Red load level means peak server load (sec); default value is 7 sec]]></comment>
28
- <frontend_type>text</frontend_type>
29
- <validate>validate-number</validate>
30
- <sort_order>600</sort_order>
31
- <show_in_default>1</show_in_default>
32
- <show_in_website>0</show_in_website>
33
- <show_in_store>0</show_in_store>
34
- </load_red>
35
-
36
-
37
- <load_black translate="label">
38
- <label>Black load level after</label>
39
- <comment><![CDATA[Black load level means critical load or server failure (sec); default value is 10 sec]]></comment>
40
- <frontend_type>text</frontend_type>
41
- <validate>validate-number</validate>
42
- <sort_order>700</sort_order>
43
- <show_in_default>1</show_in_default>
44
- <show_in_website>0</show_in_website>
45
- <show_in_store>0</show_in_store>
46
- </load_black>
47
-
48
- <manage_link translate="label">
49
- <label>Manage data compression</label>
50
- <frontend_model>aitloadmon/adminhtml_aitlink</frontend_model>
51
- <sort_order>800</sort_order>
52
- <show_in_default>1</show_in_default>
53
- <show_in_website>0</show_in_website>
54
- <show_in_store>0</show_in_store>
55
- </manage_link>
56
-
57
- <exclude_urls translate="label">
58
- <label>Exclude urls from monitoring</label>
59
- <comment><![CDATA[Some pages might always be slow while the rest of the site is functioning properly. Such pages might lead the SLM extension to act as if the whole site (or a group of pages) is in the critical load peak zone. If you are aware of such pages, please specify the URLs to exclude them from monitoring and thus adjust SLM sensitivity. Each URL on the new line, ex.: /example or /example.html]]></comment>
60
- <frontend_type>textarea</frontend_type>
61
- <sort_order>900</sort_order>
62
- <show_in_default>1</show_in_default>
63
- <show_in_website>0</show_in_website>
64
- <show_in_store>0</show_in_store>
65
- </exclude_urls>
66
- </fields>
67
- </aitloadmon>
68
- </groups>
69
- </system>
70
- </sections>
71
- </config>
72
- <!--
73
- /**
74
- * @copyright Copyright (c) 2013 AITOC, Inc.
75
- * @license License agreement could be found at the root folder of this package
76
- */
77
- -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/sql/aitloadmon_setup/mysql4-install-1.0.0.php DELETED
@@ -1,49 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- $installer = $this;
7
-
8
- $installer->startSetup();
9
-
10
- $installer->run("
11
-
12
- -- DROP TABLE IF EXISTS {$this->getTable('aitloadmon')};
13
- CREATE TABLE {$this->getTable('aitloadmon')} (
14
- `id` int(11) NOT NULL AUTO_INCREMENT,
15
- `measure_time` datetime NOT NULL,
16
- `load_time_avg` float NOT NULL,
17
- `load_time_max` float NOT NULL,
18
- `page_group_id` int(11) NOT NULL,
19
- `page_views` int(11) NOT NULL,
20
- `max_page_views_per_minute` int(11) NOT NULL,
21
- PRIMARY KEY (`id`),
22
- KEY `measure_time` (`measure_time`)
23
- ) ENGINE=MyISAM ;
24
-
25
- ");
26
-
27
- $installer->run("
28
-
29
- -- DROP TABLE IF EXISTS {$this->getTable('aitloadmon/calculator')};
30
- CREATE TABLE {$this->getTable('aitloadmon/calculator')} (
31
- `id` int(11) NOT NULL AUTO_INCREMENT,
32
- `load_time_avg` float NOT NULL,
33
- `max_page_views_per_minute` int(11) NOT NULL,
34
- `pg1_avg_load` float NOT NULL,
35
- `pg1_views` int(11) NOT NULL,
36
- `pg2_avg_load` float NOT NULL,
37
- `pg2_views` int(11) NOT NULL,
38
- `pg3_avg_load` float NOT NULL,
39
- `pg3_views` int(11) NOT NULL,
40
- `pg4_avg_load` float NOT NULL,
41
- `pg4_views` int(11) NOT NULL,
42
- `pg5_avg_load` float NOT NULL,
43
- `pg5_views` int(11) NOT NULL,
44
- PRIMARY KEY (`id`)
45
- ) ENGINE=MyISAM ;
46
-
47
- ");
48
-
49
- $installer->endSetup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/sql/aitloadmon_setup/mysql4-uninstall-1.0.0.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- if(!Mage::registry('aitloadmon_forced_disabled'))
7
- {
8
- $moduleKey = 'Aitoc_Aitloadmon';
9
- $moduleKeyPaid = 'Aitoc_Aitloadmonpaid';
10
- $filename = Mage::getBaseDir().DS.'app'.DS.'etc'.DS.'modules'.DS.$moduleKey.'.xml';
11
- $filenamePaid = Mage::getBaseDir().DS.'app'.DS.'etc'.DS.'modules'.DS.$moduleKeyPaid.'.xml';
12
- $enable = Mage::app()->getRequest()->getParam('enable');
13
- if(file_exists($filenamePaid) && simplexml_load_file($filenamePaid)->modules->$moduleKeyPaid->active == 'true' && isset($enable[$moduleKeyPaid]) && $enable[$moduleKeyPaid])
14
- {
15
- Mage::register('aitloadmon_forced_disabled',1);
16
- Mage::getModel('aitsys/module')->loadByModuleFile($filenamePaid)->getInstall()->uninstall();
17
- Mage::getModel('aitsys/module')->loadByModuleFile($filename)->getInstall()->uninstall();
18
- header('Location: '.Mage::helper('adminhtml')->getUrl('aitsys/index/index'));
19
- die();
20
- }
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitloadmon/sql/aitloadmon_setup/mysql4-upgrade-1.0.1-1.0.2.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- $installer = $this;
7
-
8
- $installer->startSetup();
9
- $installer->run("
10
- DROP TABLE IF EXISTS {$this->getTable('aitloadmon/calculator')};
11
- CREATE TABLE {$this->getTable('aitloadmon/calculator')} (
12
- `id` int(11) NOT NULL AUTO_INCREMENT,
13
- `concurrent` int(11) NOT NULL,
14
- `pg1_concurrent_load` float NOT NULL,
15
- `pg1_concurrent` int(11) NOT NULL,
16
- `pg2_concurrent_load` float NOT NULL,
17
- `pg2_concurrent` int(11) NOT NULL,
18
- `pg3_concurrent_load` float NOT NULL,
19
- `pg3_concurrent` int(11) NOT NULL,
20
- `pg4_concurrent_load` float NOT NULL,
21
- `pg4_concurrent` int(11) NOT NULL,
22
- `pg5_concurrent_load` float NOT NULL,
23
- `pg5_concurrent` int(11) NOT NULL,
24
- PRIMARY KEY (`id`)
25
- ) ENGINE=MyISAM ;
26
- ALTER TABLE {$this->getTable('aitloadmon')} ADD `concurrent` INT NOT NULL;
27
- ");
28
- $installer->endSetup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/local/Aitoc/Aitsys/install/Aitoc_Aitloadmon.phtml DELETED
@@ -1,112 +0,0 @@
1
- <h2 style="text-align:center; color:#FF6300;">AITOC, Inc. License Agreement<br />
2
- for Server Load Monitor Extension for Magento.</h2>
3
- <h3>1. General</h3>
4
- <p>This is a legal Agreement between AITOC Inc. and Customer that covers Customer's purchase and use of Server Load Monitor Extension for Magento (the Product) developed by AITOC Inc. The extension comes in Paid and Free version.</p>
5
- <p>By purchasing the Paid version of the Product or installing the Free version of the Product Customer is asserting with the below-stated Terms and Conditions of the present Agreement. Any violation of this Agreement will automatically deprive the Customer of the right to use the Product, thus the Customer must cease using it and terminate all copies and derivatives of the Product at Customer's disposal.</p>
6
- <br />
7
- <h3>2. License</h3>
8
- <h4 style="padding-left:20px;">2.1. General Issues</h4>
9
- <p>By purchasing the Paid version of the Product or installing the Free version of the Product Customer obtains a License which will remain valid until the Customer stops using the Product or until AITOC terminates this License because of Customer's failure to comply with any of its Terms and Conditions.</p>
10
- <p>AITOC offers a Single Installation License for Magento extensions. Each license can be used only on one production Magento installation. It can also be used on unlimited number of test Magento installations, if the installation domains comply with the terms, described in the documentation that comes with the Product.</p>
11
- <p>A sold License does not include ownership of any original works, part of thereof or any documentation or derivative works of the Product.</p>
12
- <h4 style="padding-left:20px;">2.2. License Options</h4>
13
- <p>The Paid version of the Product comes with different License Options. The Product's price depends on the number of Stores on Customer's Magento; this number is specified in the License option which is selected during the purchase.</p>
14
- <p>The Product contains necessary controlling functionality which makes sure the Customer does not exceed the allowed number of stores. When reaching the stores limit, the Customer can extend the limitation by purchasing the License Upgrade.</p>
15
- <p>Downgrades are not possible via standard License Upgrade functionality. For downgrades, please refer to AITOC, Inc. for a Refund. Please note that all Refunds, including downgrades, are only possible within the 30-day period from the initial purchase date.</p>
16
- <p>Editing License file in any way other than via Administrator Control Panel User Interface will result in License revocation, Client's deprivation of right for a refund, Product update and License Upgrade, and in Product's incorrect operation. AITOC doesn't bear any responsibility for any personal or business data loss or damaging of site in case of Client's attempts to edit License functionality.</p>
17
- <br />
18
- <h3>3. Copyright</h3>
19
- <p>Any unauthorized copying, renting, leasing, sublicensing, pledging, conveying, creating any Derivative Works, or disclosing of modification source codes in any way, porting of the Product to other platforms and content management systems without prior written approval from AITOC Inc. is prohibited.</p>
20
- <p>Proofs of copyright infringement include, but are not limited to, similar code style and structures and containing similar to Product source code, layout and design. Customer is not allowed to remove the original AITOC Inc. copyright inscription from the source code of the Product. Modifications of the source code are allowed, but at own risk.</p>
21
- <p>If revealed that the Product is used in breach of the above mentioned terms of use, AITOC, Inc. is authorized to suspend the license, advising the Customer on what actions are required to resolve the matter. In cases of a severe or repetitive violation where advice has been ignored, AITOC Inc. is authorized to revoke the License.</p>
22
- <p>The source code and files are exclusively owned by AITOC Inc. and are subject to US Copyright Law and Copyright Laws of the State of Delaware, as well as international copyright treaty provisions. AITOC Inc. retains title to and ownership of the Product and all enhancements, modifications and updates of the Product.</p>
23
- <p>The exclusive forum for disputes arising out of, or relating to, this Agreement shall be an appropriate federal or state court in the county of New Castle, Delaware.</p>
24
- <br />
25
- <h3>4. Installation</h3>
26
- <p>Paid version of the Product package includes an automated Installer. The automated installation may depend on configuration of operational Magento solution. AITOC does not pledge for its installation module to operate successfully on modified as well as non-modified Magento solution.</p>
27
- <p>Free version of the Product comes without the Installer.</p>
28
- <p>The Customer may purchase installation service executed by AITOC's staff. To use the paid installation service the Customer is obliged to present correct web-site access information to AITOC support personnel, as well as valid Product License information. Installation service payments are non-refundable. AITOC will only provide paid installation services for AITOC products where the source code hasn't been modified by the Customer or any 3rd party. Failing to meet any of the above mentioned requirements deprives Customer of ability to use this service.</p>
29
- <br />
30
- <h3>5. Product Support Policy</h3>
31
- <p>Free support period for the Paid version of the Product totals 6 months starting from the purchase date of the Product. The term of free support can be prolonged when a Product update is purchased. It is described in more detail in the Product Updates section.</p>
32
- <p>License Upgrade does not prolong the terms of free support services.</p>
33
- <p>Support team shall provide to Customer, without additional charge, all reasonably necessary written consultation requested in connection with use and operation of the Product or any problems therewith, within above-stated period of time.</p>
34
- <p>Free support does not include achieving compatibility with third party solutions and is not provided if the Product has been customized. In cases when extraordinary support efforts will be required Customer will be offered paid support services.</p>
35
- <p>Under extraordinary support efforts AITOC, Inc. supposes a request which probable cost to resolve may exceed the cost of the purchased Product. Support costs are calculated in accordance with average US market rates.</p>
36
- <p>Support team preserves the right to ignore any appeals or requests, not falling under the present conditions.</p>
37
- <p>Free version of the Product does not include free support. Any support services associated with the Free version of the Product will be paid. Support costs are calculated in accordance with average US market rates.</p>
38
- <p>All information, acquired from AITOC, Inc. support team is advisory only and shall not create any warranty for AITOC Inc.</p>
39
- <br />
40
- <h3>6. Service Level Agreement</h3>
41
- <p>AITOC, Inc. will provide support services via support tickets system on the products' pages Monday – Friday, 8 am - 5 pm GMT (3 am -12 pm EST).</p>
42
- <br />
43
- <h3>7. Product Updates</h3>
44
- <p>AITOC will timely release the information about new updates in the Changelog tab on the Product pages. It is Customer's responsibility to check for updates availability. All updates can be used only as a replacement of a previously purchased Product, not as a separate copy of a Product.</p>
45
- <p>AITOC reserves the right to determine which products will be updated and when. AITOC reserves the right to discontinue product updates.</p>
46
- <p>Updates for the Paid version of the Product shall be available to the Customer free of charge for 6 months from the original purchase date. After that an update would cost 75% of the current product price. The discount is only applied to the same License option.</p>
47
- <p>If needed, License Upgrade can be performed before or after the purchase of Product Update.</p>
48
- <p>Paid update package includes: the latest version of the product, 6 extra months of free updates and support from the purchase date.</p>
49
- <p>Customer is not obliged to purchase updates every 6 months. The decision about whether to purchase an update and when is solely Customer's right. Customer can continue using the Product after 6 months from the original purchase date and can contact AITOC for paid support services.</p>
50
- <br />
51
- <h3>8. Upgrade from the Free version to Paid version of the Product.</h3>
52
- <p>There is no special mechanism for upgrading from the Free version to Paid version of the Product. The Customer who decides to switch to the Paid version of the Product may simply purchase the Paid version and install it as per the Installation Guide that comes with the product.</p>
53
- <br />
54
- <h3>9. Refunds</h3>
55
- <p>Customer may demand a refund (full refund or License Downgrade) for the Paid version of the Product within a 30-day period from the date of purchase. Any clarification of Customer's refund claim within the 30-days period is optional. AITOC staff will check the compliance of all License information before
56
- resolving money refund issue. AITOC Inc. reserves the right to deny money refund claimed within the stated period if Customer's License info is incomplete and/or incorrect.</p>
57
- <p>Refund requests submitted after the expiration of the 30 days period shall not be accepted.</p>
58
- <p>Refunds of money charged for custom installation service shall not be issued.</p>
59
- <p>AITOC Inc. considers its Product refunded when the money has been withdrawn from its account. If no notification of non-acceptance has been received from client within 10 bank days, product is treated as refunded. The Customer is obliged to uninstall the product before requesting the refund and terminate all its copies and derivatives within the 5 bank days starting from the day of initiation of money refund process.</p>
60
- <p>AITOC Inc. is not responsible for any damages neither with Magento running, nor with business profits or information occurring due to enforced manual deleting of refunded Product or its derivatives.</p>
61
- <br />
62
- <h3>10. Confidentiality</h3>
63
- <p>Each party agrees that it shall not disclose any information concerning the customers, trade secrets, methods, processes or procedures or any other confidential, financial or business information of the other party, which it learns during the course of its performance of this Agreement to any third party, without the prior written consent of such other party. This obligation shall survive the cancellation or other termination of this Agreement or License. The Product contains trade secrets and proprietary know-how that belong to AITOC Inc. and it is being made available to Licensee in strict confidence.</p>
64
- <p>AITOC, Inc. collects the information:</p>
65
- <p>
66
- <ul>
67
- <li>&bull; Server name;</li>
68
- <li>&bull; Server host name;</li>
69
- <li>&bull; Server address (IP);</li>
70
- <li>&bull; Magento installation version;</li>
71
- <li>&bull; Personal identification for the Magento installation, issued by AITOC server during purchase;</li>
72
- <li>&bull; Magento installation source code path;</li>
73
- <li>&bull; Magento default host domain name;</li>
74
- <li>&bull; Magento current host domain name;</li>
75
- <li>&bull; Magento admin area path;</li>
76
- <li>&bull; Module's key name;</li>
77
- <li>&bull; Module's version;</li>
78
- <li>&bull; Module's identification number in AITOC DB;</li>
79
- <li>&bull; License purchase identification number.</li>
80
- </ul>
81
- </p>
82
- <p>This information is collected once, upon installation, and is mandatory to ensure the Product's valid purchase and exploitation.</p>
83
- <br />
84
- <p>Paid and Free versions of Server Load Monitor extension also collect the following information periodically in order to configure and recommend you better server settings:</p>
85
- <p>
86
- <ul>
87
- <li>&bull; Number of products in your Magento installation;</li>
88
- <li>&bull; Number of orders in your Magento installation;</li>
89
- <li>&bull; Number of customers;</li>
90
- <li>&bull; Number of quotes;</li>
91
- <li>&bull; Magento version;</li>
92
- <li>&bull; Server information:
93
- <ul>
94
- <li style="padding-left:20px;">&bull; General information about server's CPU;</li>
95
- <li style="padding-left:20px;">&bull; Number of cores on your server's CPU;</li>
96
- <li style="padding-left:20px;">&bull; CPU frequency;</li>
97
- <li style="padding-left:20px;">&bull; Measurement of CPU speed made by the Linux kernel when it boots to calibrate an internal busy-loop;</li>
98
- <li style="padding-left:20px;">&bull; CPU name;</li>
99
- <li style="padding-left:20px;">&bull; Available RAM on your server;</li>
100
- <li style="padding-left:20px;">&bull; Type of your server (virtual or dedicated);</li>
101
- <li style="padding-left:20px;">&bull; Whether AITOC's Magento Booster extension is installed;</li>
102
- </ul>
103
- <li>&bull; Statistic of number of visitors and page load time.</li>
104
- </ul>
105
- </p>
106
- <p>This information will be impersonalized and will not be associated to any personal data that may allow AITOC or any 3d party to identify any particular Magento installation or host. This information will be used to analyze Magento performance under different conditions and suggest appropriate hardware that may improve Magento's performance. Paid version of the Product allows to disable sending this data to AITOC.</p>
107
- <br />
108
- <h3>11. Disclaimer of Responsibility</h3>
109
- <p>AITOC Inc. Products are not stand-alone solutions and require Magento to be installed primarily with a valid Magento License. AITOC Inc. does not guarantee for its Product to operate correctly on any Magento solution, either modified or non-modified. AITOC Inc. does not bear any responsibility for damages or incorrect running of the Magento solution, occurred due to installation or utilizing of Module. AITOC Inc. disclaims any accountability for content of a site on which the Product is installed. Complaints received from any third party may result in License suspension or revocation if the matter cannot be resolved. License suspension action is at the sole discretion of AITOC Inc. and is intended to offer both parties time for settlement or advice. License reinstatement shall remain Vendor's exclusive privilege. AITOC Inc. is not liable to Customer or any third party for any damages including, but not limited to, loss of business or business profits, loss of business information due to using AITOC Inc. Products. By accepting this License Agreement Customer acknowledges to use the Product at own risk and has clear understanding of responsibility for any damage to own computer system and data.</p>
110
- <br />
111
- <h3>12. Changes in Conditions</h3>
112
- <p>AITOC Inc. reserves the right to modify these agreement terms at any time. It is solely Customer's responsibility to inquire about any changes made to the present Agreement.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/layout/aitloadmon.xml DELETED
@@ -1,55 +0,0 @@
1
- <?xml version="1.0"?>
2
- <layout version="0.1.0">
3
- <adminhtml_aitloadmon_index>
4
- <reference name="head">
5
- <action method="addJs"><script>aitoc/aitloadmon/raphael-min.js</script></action>
6
- <action method="addJs"><script>aitoc/aitloadmon/grafico.min.js</script></action>
7
- <action method="addJs"><script>aitoc/aitloadmon/grafico.line.custom.js</script></action>
8
- <action method="addJs"><script>aitoc/aitloadmon/grafico.bar.custom.js</script></action>
9
- </reference>
10
- <reference name="content">
11
- <block type="aitloadmon/adminhtml_aitloadmon" name="main_bl" template="aitloadmon/graph.phtml">
12
- <block type="aitloadmon/adminhtml_aitloadmon_filter" name="aitload_filter" as="filter" />
13
- <block type="aitloadmon/adminhtml_aitloadmon_lineGraph" name="aitload_lineGraph" as="lineGraph" template="aitloadmon/line.phtml" />
14
- <block type="aitloadmon/adminhtml_aitloadmon_barGraph" name="aitload_barGraph" as="barGraph" template="aitloadmon/bar.phtml" />
15
- <block type="core/template" name="aitload_quickFilter" as="quickFilter" template="aitloadmon/quick.phtml" />
16
- </block>
17
- <block type="core/template" name="system" as="system_block" template="aitloadmon/system.phtml"/>
18
- </reference>
19
- </adminhtml_aitloadmon_index>
20
- <adminhtml_aitloadmon_manage>
21
- <reference name="content">
22
- <block type="core/template" name="back" as="back_button" template="aitloadmon/back.phtml"/>
23
- <block type="aitloadmon/adminhtml_manage" name="manage" as="manage_data"/>
24
- <block type="core/template" name="system" as="system_block" template="aitloadmon/system.phtml"/>
25
- </reference>
26
- </adminhtml_aitloadmon_manage>
27
- <adminhtml_calculator_index>
28
- <reference name="content">
29
- <block type="core/template" name="sysInfo" as="sysInfo_block" template="aitloadmon/sysInfo.phtml"/>
30
- <!--block type="aitloadmon/adminhtml_calculatorResult" name="aitload_calculator_result" as="calculator_result" /-->
31
- </reference>
32
- </adminhtml_calculator_index>
33
- <!--adminhtml_calculator_index>
34
- <reference name="content">
35
- <block type="core/template" name="sysInfo" as="sysInfo_block" template="aitloadmon/sysInfo.phtml"/>
36
- </reference>
37
- </adminhtml_calculator_index>
38
- <adminhtml_calculator_submit>
39
- <reference name="content">
40
- <block type="aitloadmon/adminhtml_calculatorResult" name="aitload_calculator_result" as="calculator_result" />
41
- </reference>
42
- </adminhtml_calculator_submit-->
43
- <default>
44
- <reference name="content">
45
- <block type="aitloadmon/adminhtml_indicator" name="aitloadmon_indicator" template="aitloadmon/indicator.phtml"/>
46
- </reference>
47
- </default>
48
-
49
- </layout>
50
- <!--
51
- /**
52
- * @copyright Copyright (c) 2013 AITOC, Inc.
53
- * @license License agreement could be found at the root folder of this package
54
- */
55
- -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/aitloadmon/back.phtml DELETED
@@ -1,8 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- ?>
7
- <input type="button" class="form-button submit" title="Return to System Configuration" value="Return to System Configuration" id="return" onclick="document.location.href='<?php echo Mage::helper('adminhtml')->getUrl('adminhtml/system_config/edit',array('section'=>'system')); ?>'" style="float: right; margin-bottom: 10px;">
8
- <div style="clear: both;"></div>
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/aitloadmon/bar.phtml DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- ?>
7
- <div class="entry-edit">
8
- <div class="entry-edit-head">
9
- <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('aitloadmon')->__('Avg Load / Max Load for the selected period by groups');?></h4>
10
- </div>
11
- <div class="fieldset">
12
- <div id="graph2" style="height: 200px; width: 1000px;"></div>
13
- </div>
14
- </div>
15
- <script type="text/javascript">
16
- var graph2 = new Grafico.HorizontalBarGraphCustom($('graph2'), {
17
- <?php echo $this->getBarGraphData(); ?>
18
- },
19
- {
20
- labels: <?php echo $this->getBarLabels($this->getCompare()); ?>,
21
- show_ticks: false,
22
- compare_mode: <?php echo (int)$this->getCompare();?>,
23
- vertical_label_unit : "s",
24
- colors: {
25
- max_load: '#A0151E',
26
- avg_load: ['#877D1E',"#6016CA","#1680CA","#F5861A","#1B7B00"]
27
- }
28
- }
29
- );
30
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/aitloadmon/graph.phtml DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- ?>
7
- <ul class="messages">
8
- <?php if(!Mage::getStoreConfig('system/aitloadmon/disable_calc_info_sending')):?>
9
- <li class="notice-msg">
10
- <p><?php echo Mage::helper('aitloadmon')->__('Please note that collected data of Server Load Monitor extension will be sent to AITOC’s Magento Server Configuration Calculator in order to configure and recommend you better server settings.');?></p>
11
- </li>
12
- <?php endif; ?>
13
- <li class="notice-msg">
14
- <p><?php echo Mage::helper('aitloadmon')->__('Please note that the server time is used instead of your local one.');?></p>
15
- </li>
16
- </ul>
17
- <?php echo $this->getChildHtml('quickFilter'); ?>
18
- <?php echo $this->getChildHtml('filter'); ?>
19
- <?php if(!$this->isEnoughDataToBuildGraph($this->getCollection()) || ($this->getCompare() && !$this->isEnoughDataToBuildGraph($this->getCompareCollection()))):?>
20
- <ul class="messages">
21
- <li class="error-msg">
22
- <p><?php echo Mage::helper('aitloadmon')->__('Sorry, there is not enough data for the selected period(s).');?></p>
23
- </li>
24
- </ul>
25
- <?php else: ?>
26
- <?php echo $this->getChildHtml('barGraph'); ?>
27
- <?php echo $this->getChildHtml('lineGraph'); ?>
28
- <?php endif;?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/aitloadmon/indicator.phtml DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- ?>
7
- <div style="position: fixed; top: 35px; right: 3px; background-color: #cccccc; height: 18px; margin: 0; padding: 0;" onmouseover="$('aitloadmon_notice').show();" onmouseout="$('aitloadmon_notice').hide();">
8
- <div id="aitloadmon_notice" style="display:none; float: left;">&nbsp;<?php echo Mage::helper('aitloadmon')->__('Current Server Load:');?>&nbsp;</div>
9
- <a href="<?php echo Mage::helper("adminhtml")->getUrl('adminhtml/aitloadmon/index');?>">
10
- <div style="background-color: <?php echo $this->getColor();?>; height: 16px; width: 16px; float: left; border: 1px solid #cccccc;"></div>
11
- </a>
12
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/aitloadmon/line.phtml DELETED
@@ -1,119 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- ?>
7
- <style>
8
- .linegraph_check
9
- {
10
- margin-right: 5px;
11
- margin-left: 25px;
12
- }
13
- </style>
14
- <div class="entry-edit">
15
- <div class="entry-edit-head">
16
- <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('aitloadmon')->__(($this->getType()=='max')?'MAXIMUM':'AVERAGE').Mage::helper('aitloadmon')->__(' LOAD for the selected period by groups and time');?></h4>
17
- </div>
18
- <div class="fieldset">
19
- <div><?php echo Mage::helper('aitloadmon')->__('Show graphs for:'); ?><?php echo $this->getCheckBoxes(); ?></div>
20
- <div id="graph1" style="height: 340px; width: 1000px;"></div>
21
- <?php if($this->getCompare()):?><div id="graph1compare" style="height: 340px; width: 1000px;"></div><?php endif;?>
22
- </div>
23
- </div>
24
- <script type="text/javascript">
25
- var lineGraphs = [];
26
- function toggleLines(obj)
27
- {
28
- var graphId = $(obj).getAttribute('rel');
29
- if(lineGraphs[graphId])
30
- {
31
- if(!$(obj).checked)
32
- {
33
- lineGraphs[graphId].each(function(element){element.hide()});
34
- }
35
- else
36
- {
37
- lineGraphs[graphId].each(function(element){element.show()});
38
- }
39
- }
40
- }
41
- <?php $lineGraph = $this->getLineGraphData(); ?>
42
- var graph1 = new Grafico.LineGraphCustom($('graph1'),
43
- {
44
- <?php echo $lineGraph['data']; ?>
45
- },
46
- {
47
- markers : "value",
48
- grid : true,
49
- draw_axis : true,
50
- plot_padding : 0,
51
- stroke_width : 2,
52
- show_vertical_labels : true,
53
- show_horizontal_labels : true,
54
- vertical_label_unit: 's',
55
- label_rotation : 0,
56
- labels : <?php echo $lineGraph['labels']; ?>,
57
- dot_labels : <?php echo $lineGraph['dot_labels']; ?>,
58
- label_sizes : {<?php echo $lineGraph['dataSize']; ?>},
59
- concurrents : {<?php echo $lineGraph['concurrents']; ?>},
60
- hover_color : "#000",
61
- hover_text_color : "#fff",
62
- opacity: 1,
63
- zones: [<?php echo (int)Mage::getStoreConfig('system/aitloadmon/load_yellow');?>,<?php echo (int)Mage::getStoreConfig('system/aitloadmon/load_red');?>,<?php echo (int)Mage::getStoreConfig('system/aitloadmon/load_black');?>],
64
- colors: {
65
- other: "#877D1E",
66
- cms: "#6016CA",
67
- checkout: "#1680CA",
68
- catalogsearch: "#F5861A",
69
- catalog: "#1B7B00"
70
- },
71
- datalabels : {
72
- other: "Other pages",
73
- cms: "CMS pages",
74
- checkout: "Checkout pages",
75
- catalogsearch: "Search pages",
76
- catalog: "Catalog pages"
77
- }
78
- });
79
-
80
- <?php if($this->getCompare()):?>
81
- <?php $lineGraph = $this->getLineGraphDataCompared(); ?>
82
- var graph1 = new Grafico.LineGraphCustom($('graph1compare'),
83
- {
84
- <?php echo $lineGraph['data']; ?>
85
- },
86
- {
87
- markers : "value",
88
- grid : true,
89
- draw_axis : true,
90
- plot_padding : 0,
91
- stroke_width : 2,
92
- show_vertical_labels : true,
93
- show_horizontal_labels : true,
94
- label_rotation : 0,
95
- labels : <?php echo $lineGraph['labels']; ?>,
96
- dot_labels : <?php echo $lineGraph['dot_labels']; ?>,
97
- label_sizes : {<?php echo $lineGraph['dataSize']; ?>},
98
- concurrents : {<?php echo $lineGraph['concurrents']; ?>},
99
- hover_color : "#000",
100
- hover_text_color : "#fff",
101
- opacity: 0.5,
102
- zones: [<?php echo (int)Mage::getStoreConfig('system/aitloadmon/load_yellow');?>,<?php echo (int)Mage::getStoreConfig('system/aitloadmon/load_red');?>,<?php echo (int)Mage::getStoreConfig('system/aitloadmon/load_black');?>],
103
- colors: {
104
- other: "#877D1E",
105
- cms: "#6016CA",
106
- checkout: "#1680CA",
107
- catalogsearch: "#F5861A",
108
- catalog: "#1B7B00"
109
- },
110
- datalabels : {
111
- other: "Other pages",
112
- cms: "CMS pages",
113
- checkout: "Checkout pages",
114
- catalogsearch: "Search pages",
115
- catalog: "Catalog pages"
116
- }
117
- });
118
- <?php endif;?>
119
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/aitloadmon/quick.phtml DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- ?>
7
- <div class="entry-edit">
8
- <div class="entry-edit-head">
9
- <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('aitloadmon')->__('Basic Filter Options');?></h4>
10
- </div>
11
- <div class="fieldset">
12
- <input type="button" class="form-button" title="Last Hour" value="Last Hour" id="qickfilter0" onclick="quickFilter('<?php echo date('Y-m-d H:i:s', time()-3600+1);?>','<?php echo date('Y-m-d H:i:s');?>');">
13
- <input type="button" class="form-button" title="Last 24h" value="Last 24h" id="qickfilter1" onclick="quickFilter('<?php echo date('Y-m-d H:i:s', time()-86400+1);?>','<?php echo date('Y-m-d H:i:s');?>');">
14
- <input type="button" class="form-button" title="Last Week" value="Last Week" id="qickfilter2" onclick="quickFilter('<?php echo date('Y-m-d H:i:s', time()-86400*7+1);?>','<?php echo date('Y-m-d H:i:s');?>');">
15
- <input type="button" class="form-button" title="Last Month" value="Last Month" id="qickfilter3" onclick="quickFilter('<?php echo date('Y-m-d H:i:s', time()-86400*30+1);?>','<?php echo date('Y-m-d H:i:s');?>');">
16
- <input type="button" class="form-button" title="Last Year" value="Last Year" id="qickfilter4" onclick="quickFilter('<?php echo date('Y-m-d H:i:s', time()-86400*365+1);?>','<?php echo date('Y-m-d H:i:s');?>');">
17
- </div>
18
- </div>
19
- <script type="text/javascript">
20
- function quickFilter($start,$end)
21
- {
22
- $('starts').value = $start;
23
- $('ends').value = $end;
24
- $('compare').checked = false;
25
- $('edit_form').submit();
26
-
27
- }
28
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/aitloadmon/sysInfo.phtml DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- ?>
7
- <?php if($system = Mage::getModel('aitloadmon/sysInfo')->getSystem()): ?>
8
- <div><?php echo $system;?></div>
9
- <?php else:?>
10
- <iframe src="<?php echo Mage::getModel('aitloadmon/sysInfo')->getSystemUrl();?>" style="width: 100%; border: medium none;"></iframe>
11
- <?php endif;?>
 
 
 
 
 
 
 
 
 
 
 
app/design/adminhtml/default/default/template/aitloadmon/system.phtml DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- ?>
7
- <?php if($system = Mage::getModel('aitloadmon/system')->getSystem()): ?>
8
- <div><?php echo $system;?></div>
9
- <?php else:?>
10
- <iframe src="<?php echo Mage::getModel('aitloadmon/system')->getSystemUrl();?>" style="width: 100%; border: medium none;"></iframe>
11
- <?php endif;?>
 
 
 
 
 
 
 
 
 
 
 
app/etc/modules/Aitoc_Aitloadmon.xml DELETED
@@ -1,16 +0,0 @@
1
- <?xml version="1.0"?>
2
- <config>
3
- <modules>
4
- <Aitoc_Aitloadmon>
5
- <active>false</active>
6
- <codePool>local</codePool>
7
- <self_name>Server Load Monitor Free</self_name>
8
- </Aitoc_Aitloadmon>
9
- </modules>
10
- </config>
11
- <!--
12
- /**
13
- * @copyright Copyright (c) 2013 AITOC, Inc.
14
- * @license License agreement could be found at the root folder of this package
15
- */
16
- -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/aitoc/aitloadmon/grafico.bar.custom.js DELETED
@@ -1,204 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2013 AITOC, Inc.
3
- * @license License agreement could be found at the root folder of this package
4
- */
5
- Grafico.HorizontalBarGraphCustom = Class.create(Grafico.BarGraph, {
6
- chartDefaults: function () {
7
- return {
8
- bar : true,
9
- horizontalbar : true,
10
- plot_padding : 0,
11
- horizontal_rounded : false,
12
- bargraph_lastcolor : false
13
- };
14
- },
15
-
16
- setChartSpecificOptions: function () {
17
- // Approximate the width required by the labels
18
- this.x_padding_left = 20 + this.longestLabel() * (this.options.font_size / 2);
19
- this.bar_padding = 5;
20
- this.bar_width = this.calculateBarHeight();
21
- this.step = this.calculateStep();
22
- this.graph_width = this.options.width - this.x_padding_right - this.x_padding_left;
23
- },
24
-
25
- normalise: function (value) {
26
- var range = this.makeValueLabels(this.y_label_count);
27
- range = range[range.length-1];
28
- return ((value / range) * this.graph_width);
29
- },
30
-
31
- longestLabel: function () {
32
- return $A(this.options.labels).sort(function (a, b) { return a.toString().length < b.toString().length; }).first().toString().length;
33
- },
34
-
35
- /* Height */
36
- calculateBarHeight: function () {
37
- return (this.graph_height / this.data_size) - this.bar_padding;
38
- },
39
-
40
- calculateStep: function () {
41
- return (this.graph_height - (this.options.plot_padding * 2)) / this.data_size;
42
- },
43
-
44
- drawLines: function (label, color, data, datalabel, element, graphindex) {
45
- var y = this.y_padding_top + (this.bar_padding / 2) -0.5,
46
- offset = this.zero_value * (this.graph_width / this.y_label_count),
47
- x = this.x_padding_left + offset - 0.5,
48
- lastcolor = this.options.bargraph_lastcolor,
49
- negativecolor = this.options.bargraph_negativecolor || color;
50
- this.datalabel = datalabel;
51
- $A(data).each(function (value, index) {
52
- var color2,
53
- horizontal_rounded = this.options.horizontal_rounded ? this.bar_width / 2 : 0,
54
- bargraph;
55
-
56
- if(this.options.compare_mode)
57
- {
58
- var opacity = (index%2)?0.5:1;
59
- }
60
- else
61
- {
62
- var opacity = 1;
63
- }
64
-
65
- if(color instanceof Array)
66
- {
67
- if(this.options.compare_mode)
68
- {
69
- tmp_index = Math.floor(index / 2);
70
- }
71
- else
72
- {
73
- tmp_index = index;
74
- }
75
- tmp_color = color[tmp_index];
76
- }
77
- else
78
- {
79
- tmp_color = color;
80
- }
81
-
82
- if (lastcolor && index === data.length-1) {
83
- color2 = lastcolor;
84
- } else {
85
- color2 = value < 0 ? negativecolor : tmp_color;
86
- }
87
-
88
- value = value / this.graph_width * (this.graph_width - offset);
89
- bargraph = this.paper.rect(x, y, value, this.bar_width, horizontal_rounded).attr({fill: color2, 'stroke-width': 0, stroke : color2, 'stroke-opacity' : 0, 'fill-opacity' : opacity});
90
-
91
- if (value < 0) {
92
- bargraph.attr({width: -bargraph.attrs.width}).translate(value, 0);
93
- }
94
-
95
- if (horizontal_rounded) {
96
- var bargraphset = this.paper.set(),
97
- bargraph2 = this.paper.rect(x, y, value - this.bar_width/2, this.bar_width).attr({fill: color2, 'stroke-width': 0, stroke : color2, 'stroke-opacity' : 0});
98
-
99
- bargraphset.push(bargraph2, bargraph);
100
-
101
- if (value < 0) {
102
- bargraph2.attr({width: -bargraph2.attrs.width - this.bar_width}).translate(value + this.bar_width/2, 0);
103
- }
104
- }
105
-
106
- if (this.options.datalabels) {
107
- var hover_color = this.options.hover_color || color2,
108
- hoverSet = this.paper.set(),
109
- datalabel = this.datalabel[index].toString(),
110
- text = this.paper.text(offset + value + this.x_padding_left / 2, bargraph.attrs.y - (this.options.font_size * 1.5), datalabel)
111
- .attr({'font-size': this.options.font_size, fill: this.options.hover_text_color, opacity: 1}),
112
- hoverbar = this.paper.rect(
113
- this.x_padding_left,
114
- y,
115
- this.graph_width,
116
- this.bar_width).attr({fill: color2, 'stroke-width': 0, stroke: color2, opacity: 0}
117
- ),
118
- textbox = text.getBBox();
119
-
120
- if (value < 0) { text.translate(textbox.width, 0); }
121
-
122
- var textpadding = 4,
123
- roundRect = this.drawRoundRect(text, textbox, textpadding),
124
- nib = this.drawNib(text, textbox, textpadding);
125
-
126
- hoverSet.push(roundRect,nib,text).attr({opacity: 0});
127
- this.checkHoverPos({rect: roundRect, set: hoverSet, nib: nib});
128
- this.globalHoverSet.push(hoverSet);
129
- this.globalBlockSet.push(hoverbar);
130
- if (roundRect.attrs.y < 0) {
131
- hoverSet.translate(0, 1 - roundRect.attrs.y);
132
- }
133
-
134
- hoverbar.hover(function (event) {
135
- if (horizontal_rounded) {
136
- bargraphset.animate({fill: hover_color, stroke: hover_color}, 200);
137
- } else {
138
- bargraph.animate({fill: hover_color, stroke: hover_color}, 200);
139
- }
140
- hoverSet.animate({opacity: 1}, 200);
141
- }, function (event) {
142
- if (horizontal_rounded) {
143
- bargraphset.animate({fill: color2, stroke: color2}, 200);
144
- } else {
145
- bargraph.animate({fill: color2, stroke: color2}, 200);
146
- }
147
- hoverSet.animate({opacity: 0}, 200);
148
- });
149
- }
150
- y = y + this.step;
151
- }.bind(this));
152
- },
153
-
154
- /* Horizontal version */
155
- drawFocusHint: function () {
156
- var length = 5,
157
- x = this.x_padding_left + length * 2,
158
- y = this.options.height - this.y_padding_bottom - length / 2;
159
-
160
- this.paper.path()
161
- .attr({stroke: this.options.label_color, 'stroke-width': 2})
162
- .moveTo(x, y)
163
- .lineTo(x - length, y + length)
164
- .moveTo(x - length, y)
165
- .lineTo(x - (length * 2), y + length);
166
- },
167
-
168
- drawVerticalLabels: function () {
169
- var y_start = (this.step / 2),
170
- extra_options = this.options.label_rotation ? {"text-anchor": 'end', rotation:this.options.label_rotation, translation: "0 " + this.options.font_size/2} : {"text-anchor": 'end'},
171
- labels = this.options.labels;
172
-
173
- if (this.options.label_max_size) {
174
- for (var i = 0; i < labels.length; i++) {
175
- labels[i] = labels[i].truncate(this.options.label_max_size + 1, "тАж");
176
- }
177
- }
178
-
179
- this.drawMarkers(this.options.labels.reverse(), [0, -1], this.step, y_start, [-8, -(this.options.font_size / 5)], extra_options);
180
- },
181
-
182
- drawHorizontalLabels: function () {
183
- var x_step = this.graph_width / this.y_label_count,
184
- x_labels = this.makeValueLabels(this.y_label_count);
185
-
186
- if (this.options.vertical_label_unit) {
187
- for (var i = 0; i < x_labels.length; i++) {
188
- x_labels[i] += this.options.vertical_label_unit;
189
- }
190
- }
191
- this.drawMarkers(x_labels, [1, 0], x_step, x_step, [0, (this.options.font_size + 7) * -1]);
192
- },
193
-
194
- drawMeanLine: function (data) {
195
- var offset = $A(data).inject(0, function (value, sum) { return sum + value; }) / data.length;
196
- offset = this.options.bar ? offset + (this.zero_value * (this.graph_height / this.y_label_count)) : offset;
197
-
198
- this.paper.path()
199
- .attr(this.options.meanline)
200
- .moveTo(this.x_padding_left - 1 + offset, this.y_padding_top).
201
- lineTo(this.x_padding_left - 1 + offset, this.y_padding_top + this.graph_height);
202
- }
203
- });
204
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/aitoc/aitloadmon/grafico.line.custom.js DELETED
@@ -1,187 +0,0 @@
1
- /**
2
- * @copyright Copyright (c) 2013 AITOC, Inc.
3
- * @license License agreement could be found at the root folder of this package
4
- */
5
- Grafico.LineGraphCustom = Class.create(Grafico.BaseGraph, {
6
- chartDefaults: function () {
7
- return {
8
- line: true,
9
- start_at_zero: true,
10
- stroke_width: 5,
11
- curve_amount: 10
12
- };
13
- },
14
-
15
- setChartSpecificOptions: function () {
16
- },
17
-
18
- calculateStep: function () {
19
- return (this.graph_width - (this.options.plot_padding * 2)) / (this.data_size - 1);
20
- },
21
-
22
- startPlot: function (cursor, x, y, color) {
23
- cursor.moveTo(x, y);
24
- cursor.attr({'stroke-opacity': this.options.opacity});
25
-
26
- },
27
-
28
- drawPlot: function (index, cursor, x, y, color, coords, datalabel, element, graphindex) {
29
-
30
- if(typeof lineGraphs[graphindex+1] == 'undefined')lineGraphs[graphindex+1]=[];
31
-
32
- if (this.options.markers === 'circle') {
33
- this.drawGraphMarkers(index, x, y, color, datalabel, element);
34
- } else if (this.options.markers === 'value') {
35
- this.drawGraphValueMarkers(index, x, y, color, datalabel, element, graphindex);
36
- }
37
-
38
- if (index === 0) {
39
- lineGraphs[graphindex+1].push(cursor);
40
- return this.startPlot(cursor, x - 0.5, y, color);
41
- }
42
- if (this.options.curve_amount) {
43
- ww = cursor.cplineTo(x, y, this.options.curve_amount);
44
- } else {
45
- ww = cursor.lineTo(x, y);
46
-
47
- }
48
- },
49
-
50
- drawGraphMarkers: function (index, x, y, color, datalabel, element) {
51
- var circle = this.paper.circle(x, y, this.options.marker_size),
52
- old_marker_size = this.options.marker_size,
53
- color2 = this.options.hover_color || color,
54
- new_marker_size = parseInt(1.7 * old_marker_size, 10);
55
-
56
- circle.attr({ 'stroke-width': '1px', stroke: this.options.background_color, fill: color });
57
- this.globalMarkerSet.push(circle);
58
-
59
- circle.hover(function (event) {
60
- circle.animate({r: new_marker_size, fill: color2}, 200);
61
- }, function (event) {
62
- circle.animate({r: old_marker_size, fill: color}, 200);
63
- });
64
- },
65
-
66
- drawGrid: function () {
67
- var path = this.paper.path().attr({ stroke: this.options.grid_color}),
68
- y, x, x_labels, i;
69
-
70
- if (this.options.show_horizontal_grid) {
71
- y = this.graph_height + this.y_padding_top;
72
- for (i = 0; i < this.y_label_count + 1; i++) {
73
- path.moveTo(this.x_padding_left - 0.5, parseInt(y, 10) + 0.5);
74
- path.lineTo(this.x_padding_left + this.graph_width - 0.5, parseInt(y, 10) + 0.5);
75
- y = y - (this.graph_height / this.y_label_count);
76
- }
77
- }
78
- if (this.options.show_vertical_grid) {
79
- x = this.x_padding_left + this.options.plot_padding + this.grid_start_offset;
80
- x_labels = this.options.labels.length;
81
-
82
- for (i = 0; i < x_labels; i++) {
83
- if ((this.options.hide_empty_label_grid === true && this.options.labels[i] !== "") || this.options.hide_empty_label_grid === false) {
84
- path.moveTo(parseInt(x, 10), this.y_padding_top);
85
- path.lineTo(parseInt(x, 10), this.y_padding_top + this.graph_height);
86
- }
87
- x = x + this.step;
88
- }
89
- }
90
-
91
-
92
- if (this.options.zones) {
93
- zones = this.options.zones;
94
- for (i = 0; i < zones.length; i++)
95
- {
96
- if(zones[i] > this.top_value)
97
- {
98
- zones[i] = this.top_value;
99
- }
100
- }
101
-
102
- var zone_heights = [];
103
- zone_heights[0] = (this.top_value-zones[2])/this.top_value*this.graph_height;
104
- zone_heights[1] = (zones[2]-zones[1])/this.top_value*this.graph_height;
105
- zone_heights[2] = (zones[1]-zones[0])/this.top_value*this.graph_height;
106
- zone_heights[3] = zones[0]/this.top_value*this.graph_height;
107
-
108
- this.paper.rect(this.x_padding_left,this.y_padding_top,this.graph_width, zone_heights[0]).attr({'fill': 'black', 'fill-opacity': '0.15', 'stroke-opacity':'0'});
109
- this.paper.rect(this.x_padding_left,this.y_padding_top+zone_heights[0],this.graph_width,zone_heights[1]).attr({'fill': 'red', 'fill-opacity': '0.1', 'stroke-opacity':'0'});
110
- this.paper.rect(this.x_padding_left,this.y_padding_top+zone_heights[0]+zone_heights[1],this.graph_width,zone_heights[2]).attr({'fill': 'yellow', 'fill-opacity': '0.15', 'stroke-opacity':'0'});
111
- this.paper.rect(this.x_padding_left,this.y_padding_top+zone_heights[0]+zone_heights[1]+zone_heights[2],this.graph_width,zone_heights[3]).attr({'fill': 'green', 'fill-opacity': '0.15', 'stroke-opacity':'0'});
112
- }
113
- },
114
-
115
- drawGraphValueMarkers: function (index, x, y, color, datalabel, element, graphindex) {
116
- index += this.options.odd_horizontal_offset>1 ? this.options.odd_horizontal_offset : 0;
117
- index -= this.options.stacked_fill || this.options.area ? 1 : 0;
118
-
119
- if(!this.options.label_sizes[graphindex+1][index])
120
- {
121
- tmpsize = 1;
122
- }
123
- else
124
- {
125
- tmpsize = this.options.label_sizes[graphindex+1][index];
126
- }
127
-
128
- var circle = this.paper.circle(x, y, Math.log(tmpsize));
129
-
130
- circle.attr({ 'stroke-width': '1px', stroke: this.options.background_color, fill: color, 'fill-opacity': this.options.opacity});
131
- this.globalMarkerSet.push(circle);
132
-
133
- lineGraphs[graphindex+1].push(circle);
134
-
135
- var currentset = this.options.stacked ? this.real_data : this.data_sets,
136
- currentvalue = currentset.collect(function (data_set) { return data_set[1][index]; })[graphindex];
137
-
138
- if (currentvalue) {
139
- currentvalue = "" + currentvalue.toString().split('.');
140
- if (currentvalue[1]) {
141
- currentvalue[1] = currentvalue[1].truncate(3, '');
142
- }
143
- }
144
- if (
145
- (this.options.line||this.options.stacked) || //if the option is a line graph
146
- ((this.options.stacked_fill||this.options.area) && index != -1) && //if it's stacked or an area and it's not the first
147
- typeof currentvalue != "undefined") { //if there is a current value
148
-
149
- var rectx = x-(this.step/2),
150
- recty = y-[this.options.stroke_width/2, this.options.hover_radius].max(),
151
- rectw = this.step,
152
- recth = [this.options.stroke_width, this.options.hover_radius*2].max(),
153
- circle = this.paper.circle(x, y, this.options.marker_size == 0 ? [this.options.stroke_width*1.5, this.step].min() : this.options.marker_size).attr({ 'stroke-width': '1px', stroke: this.options.background_color, fill: color,opacity:0}),
154
- block = this.paper.rect(rectx, recty, rectw, recth).attr({fill:color, 'stroke-width': 0, stroke : color,opacity:0});
155
-
156
- if (this.options.datalabels) {
157
- if(typeof(datalabel) == 'function') {
158
- datalabel = datalabel.call(this, index, currentvalue);
159
- } else {
160
- datalabel = datalabel + ": " + currentvalue + " s\r\n" + "Page views: " + this.options.label_sizes[graphindex+1][index] + " / " + "Concurrent page views: " + this.options.concurrents[graphindex+1][index] + "\r\n" + this.options.dot_labels[index];
161
- }
162
- } else {
163
- datalabel = "" + currentvalue;
164
- }
165
- datalabel += this.options.vertical_label_unit ? " " + this.options.vertical_label_unit : "";
166
-
167
- var hoverSet = this.paper.set(),
168
- textpadding = 4,
169
- text = this.paper.text(circle.attrs.cx, circle.attrs.cy - (this.options.font_size * 1.5) -2 * textpadding, datalabel).attr({'font-size': this.options.font_size, fill:this.options.hover_text_color, opacity: 1}),
170
- textbox = text.getBBox(),
171
- roundRect= this.drawRoundRect(text, textbox, textpadding),
172
- nib = this.drawNib(text, textbox, textpadding);
173
-
174
- hoverSet.push(circle,roundRect,nib,text).attr({opacity:0});
175
- lineGraphs[graphindex+1].push(circle,roundRect,nib,text);
176
- this.checkHoverPos({rect:roundRect,set:hoverSet,marker:circle,nib:nib,textpadding:textpadding});
177
- this.globalHoverSet.push(hoverSet);
178
- this.globalBlockSet.push(block);
179
-
180
- block.hover(function (event) {
181
- hoverSet.animate({opacity:1},200);
182
- }, function (event) {
183
- hoverSet.animate({opacity:0},200);
184
- });
185
- }
186
- }
187
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/aitoc/aitloadmon/grafico.min.js DELETED
@@ -1,80 +0,0 @@
1
- var Grafico={Version:"0.9.1",Base:{},BaseGraph:{},Normaliser:{},LineGraph:{},AreaGraph:{},StackGraph:{},StreamGraph:{},BarGraph:{},StackedBarGraph:{},HorizontalBarGraph:{},SparkLine:{},SparkBar:{}};
2
- Grafico.Base=Class.create({normaliseData:function(a){return $A(a).collect(function(a){return this.normalise(a)}.bind(this))},deepCopy:function(a){var b,c,d;if(Object.prototype.toString.call(a)==="[object Array]"){b=[];d=a.length;for(c=0;c<d;c++)b[c]=arguments.callee(a[c]);return b}if(typeof a==="object"){b={};for(c in a)b[c]=arguments.callee(a[c]);return b}return a}});
3
- Grafico.Normaliser=Class.create({initialize:function(a,b){this.options={start_value:void 0,number_of_tickmarks:10};Object.extend(this.options,b||{});this.min=a.min();this.max=a.max();this.step=this.range=this.zero_value=this.start_value=void 0;if(this.options.start_value!==void 0)this.zero_value=this.start_value=this.options.start_value;this.min==0&&this.min==this.max?(this.zero_value=this.start_value=0,this.step=this.range=1):this.looseLabels(this.start_value!==void 0&&this.min>=0?this.start_value:
4
- this.min,this.max)},looseLabels:function(a,b){var c=this.niceNumber((a==b?this.niceNumber(Math.abs(b),!1):this.niceNumber(b-a,!1))/(this.options.number_of_tickmarks-1),!0),d=[-Math.floor(Math.LOG10E*Math.log(c)),0].max(),e=this.floorToPrecision(a/c,d)*c,f=this.ceilToPrecision(b/c,d)*c,g=this.roundToPrecision(this.niceNumber(0.5*c,!0),d);this.step=this.roundToPrecision(c,d);this.max<=0?f=[f+g,0].min():f+=g;this.min<0?e-=g:e=[e-g,0].max();a!==b&&(e=this.roundToOrigin(e,1));this.range=this.roundToPrecision(Math.abs(this.ceilToPrecision(f,
5
- d)-this.floorToPrecision(e,d)),d);this.start_value=this.floorToPrecision(e,d);this.zero_value=this.roundToPrecision(Math.abs(e)/this.step,d)},roundToPrecision:function(a,b){var c=Math.pow(10,b);return Math.round(a*c)/c},floorToPrecision:function(a,b){var c=Math.pow(10,b);return Math.floor(a*c)/c},ceilToPrecision:function(a,b){var c=Math.pow(10,b);return Math.ceil(a*c)/c},niceNumber:function(a,b){var c=Math.floor(Math.LOG10E*Math.log(a)),d;c=c<0?parseFloat(Math.pow(10,c).toFixed(Math.abs(c))):Math.pow(10,
6
- c);d=a/c;return(b?d<1.5?1:d<3?2:d<7?5:10:d<=1?1:d<=2?2:d<=5?5:10)*c},roundToOrigin:function(a,b){var c=a;c=Math.pow(10,-(b||1));c=Math.round(a*c)/c;return c>this.min?this.roundToOrigin(a-this.step):c}});
7
- Grafico.BaseGraph=Class.create(Grafico.Base,{initialize:function(a,b,c){this.options={width:parseInt(a.getStyle("width"),10),height:parseInt(a.getStyle("height"),10),grid:!0,show_vertical_grid:!0,show_horizontal_grid:!0,plot_padding:10,font_size:10,show_horizontal_labels:!0,show_vertical_labels:!0,show_ticks:!0,vertical_label_unit:"",background_color:"#fff",label_color:"#000",grid_color:"#ccc",hover_text_color:"#fff",markers:!1,marker_size:5,meanline:!1,padding_top:20,draw_axis:!0,datalabels:"",hover_color:"",
8
- hover_radius:15,watermark:!1,watermark_location:!1,hide_empty_label_grid:!1,left_padding:!1,right_padding:!1,label_rotation:0,label_max_size:!1,focus_hint:!0,min:0,max:null,normaliser:Grafico.Normaliser};Object.extend(this.options,this.chartDefaults()||{});Object.extend(this.options,c||{});this.element=a;this.data_sets=Object.isArray(b)?new Hash({one:b}):$H(b);if(this.chartDefaults().stacked===!0)this.real_data=this.deepCopy(this.data_sets),this.data_sets=this.stackData(this.data_sets);this.flat_data=
9
- this.data_sets.collect(function(a){return a[1]}).flatten();if(this.hasBaseLine())this.flat_data.push(this.base_line),this.flat_data=this.flat_data.flatten();this.normaliser=new this.options.normaliser(this.flat_data,this.normaliserOptions());this.label_step=this.normaliser.step;this.range=this.normaliser.range;this.start_value=this.normaliser.start_value;this.zero_value=this.normaliser.zero_value;this.data_size=this.longestDataSetLength();if(c&&c.color)c.colors={},this.data_sets.keys().each(function(a){c.colors[a]=
10
- c.color});this.options.colors=this.makeRandomColors();this.options.labels=$A($R(1,this.data_size));Object.extend(this.options,this.chartDefaults()||{});Object.extend(this.options,c||{});this.x_padding_left=10+this.paddingLeftOffset();this.x_padding_left+=this.options.vertical_label_unit?6:0;this.x_padding_left=this.options.left_padding?this.options.left_padding:this.x_padding_left;this.x_padding_right=this.options.right_padding||this.paddingRightOffset();this.x_padding=this.x_padding_left+this.x_padding_right;
11
- this.y_padding_top=this.options.padding_top;this.y_padding_bottom=20+this.paddingBottomOffset();this.y_padding=this.y_padding_top+this.y_padding_bottom;this.graph_width=this.options.width-this.x_padding;this.graph_height=this.options.height-this.y_padding;this.step=this.calculateStep();this.y_label_count=(this.range/this.label_step).round();if(isNaN(this.y_label_count))this.y_label_count=1,this.options.show_vertical_labels=!1;this.normaliser.min+this.y_label_count*this.normaliser.step<this.normaliser.max&&
12
- (this.y_label_count+=1);this.value_labels=this.makeValueLabels(this.y_label_count);this.top_value=this.value_labels.last();this.grid_start_offset=-1;this.paper=new Raphael(this.element,this.options.width,this.options.height);this.background=this.paper.rect(this.x_padding_left,this.y_padding_top,this.graph_width,this.graph_height);this.background.attr({fill:this.options.background_color,stroke:"none"});this.options.meanline=this.options.meanline===!0?{"stroke-width":"2px",stroke:"#BBBBBB"}:this.options.meanline;
13
- this.globalMarkerSet=this.paper.set();this.globalHoverSet=this.paper.set();this.globalBlockSet=this.paper.set();this.globalAreaLineSet=this.paper.set();this.setChartSpecificOptions();this.draw();this.globalAreaLineSet.toFront();this.globalMarkerSet.toFront();this.globalHoverSet.toFront();this.globalBlockSet.toFront()},normaliserOptions:function(){return{graph_height:parseInt(this.element.getStyle("height"),10)}},hasBaseLine:function(){return!1},getNormalizedBaseLine:function(){if(this.normalized_base_line==
14
- void 0)this.normalized_base_line=this.normaliseData(this.base_line);return this.normalized_base_line},getNormalizedRealData:function(){if(this.normalized_real_data==void 0)this.normalized_real_data=this.real_data.collect(function(a){return this.normaliseData(a[1])}.bind(this));return this.normalized_real_data},chartDefaults:function(){},drawPlot:function(){},calculateStep:function(){},getMousePos:function(a){var b=0,c=0;if(!a)a=window.event;if(a.pageX||a.pageY)b=a.pageX,c=a.pageY;else if(a.clientX||
15
- a.clientY)b=a.clientX+document.body.scrollLeft-document.documentElement.scrollLeft,c=a.clientY+document.body.scrollTop-document.documentElement.scrollTop;return{x:b,y:c}},makeRandomColors:function(){var a={},b=1/this.data_sets.size(),c=Math.random();this.data_sets.each(function(d){a[d[0]]=Raphael.hsb2rgb(c,0.85,0.75).hex;c=(c+b)%1});return a},longestDataSetLength:function(){var a=0;this.data_sets.each(function(b){a=b[1].length>a?b[1].length:a});return a},roundValue:function(a,b){var c=Math.pow(10,
16
- b);a*=c;return a=Math.round(a)/c},roundValues:function(a,b){return $A(a).collect(function(a){return this.roundValue(a,b)}.bind(this))},paddingLeftOffset:function(){var a=0;if(this.options.show_vertical_labels)a=this.flat_data,a=this.roundValues(a,2),a=$A(a).max(function(a){return a.toString().length}),a=(a>2?a-1:a)*this.options.font_size;return a},paddingRightOffset:function(){return 20},paddingBottomOffset:function(){return this.options.font_size},normalise:function(a){var b=this.start_value===0?
17
- this.top_value:this.range;b===0&&(b=1);return a/b*this.graph_height},draw:function(){this.options.grid&&this.drawGrid();this.options.watermark&&this.drawWatermark();this.options.show_vertical_labels&&this.drawVerticalLabels();this.options.show_horizontal_labels&&this.drawHorizontalLabels();this.options.watermark||this.drawLinesInit(this);this.options.draw_axis&&this.drawAxis();this.start_value!==0&&this.options.focus_hint&&this.drawFocusHint();this.options.meanline&&this.drawMeanLine(this.normaliseData(this.flat_data))},
18
- drawLinesInit:function(a){a.data_sets.each(function(b,c){a.drawLines(b[0],a.options.colors[b[0]],a.normaliseData(b[1]),a.options.datalabels[b[0]],a.element,c)}.bind(a))},drawWatermark:function(){var a=this.options.watermark,b=new Image,c=this;b.onload=function(){var a,e;c.options.watermark_location==="middle"?(a=(c.graph_width-b.width)/2+c.x_padding_left,e=(c.graph_height-b.height)/2+c.y_padding_top):(a=c.graph_width-b.width+c.x_padding_left-2,e=c.graph_height-b.height+c.y_padding_top-2);a=c.paper.image(b.src,
19
- a,e,b.width,b.height).attr({opacity:"0.4"});c.drawLinesInit(c,c.data);(c.options.stacked_fill||c.options.area)&&a.toFront()};b.src=a.src||a},drawGrid:function(){var a=this.paper.path().attr({stroke:this.options.grid_color}),b,c,d;if(this.options.show_horizontal_grid){b=this.graph_height+this.y_padding_top;for(d=0;d<this.y_label_count+1;d++)a.moveTo(this.x_padding_left-0.5,parseInt(b,10)+0.5),a.lineTo(this.x_padding_left+this.graph_width-0.5,parseInt(b,10)+0.5),b-=this.graph_height/this.y_label_count}if(this.options.show_vertical_grid){b=
20
- this.x_padding_left+this.options.plot_padding+this.grid_start_offset;c=this.options.labels.length;for(d=0;d<c;d++){if(this.options.hide_empty_label_grid===!0&&this.options.labels[d]!==""||this.options.hide_empty_label_grid===!1)a.moveTo(parseInt(b,10),this.y_padding_top),a.lineTo(parseInt(b,10),this.y_padding_top+this.graph_height);b+=this.step}}},drawLines:function(a,b,c,d,e,f){var g=this.calculateCoords(c),h=this.graph_height+this.y_padding_top,i,j,k;if(this.options.start_at_zero===!1)k=0,$A(g).each(function(a){if(a[1]===
21
- h)k++;else throw $break;}),this.options.odd_horizontal_offset=k,this.options.odd_horizontal_offset>1&&g.splice(0,this.options.odd_horizontal_offset);this.options.stacked_fill||this.options.area?(this.options.area?(a=this.options.area_opacity?this.options.area_opacity:1.5/this.data_sets.collect(function(a){return a.length}).length,i=this.paper.path().attr({stroke:b,fill:b,"stroke-width":"0",opacity:a,"stroke-opacity":0})):i=this.paper.path().attr({stroke:b,fill:b,"stroke-width":"0"}),this.hasBaseLine()||
22
- (g.unshift([g[0][0],h]),g.push([g[g.length-1][0],h]))):i=this.paper.path().attr({stroke:b,"stroke-width":this.options.stroke_width+"px"});$A(g).each(function(a,c){var h=a[0],j=a[1];b instanceof Array?this.drawPlot(c,i,h,j,b[c%b.length],g,d,e,f):this.drawPlot(c,i,h,j,b,g,d,e,f)}.bind(this));this.options.area&&this.options.stroke_width>0&&(j=this.paper.path().attr({stroke:b,"stroke-width":this.options.stroke_width+"px"}),g.remove(0),g.remove(-1),$A(g).each(function(a,c){this.drawPlot(c,j,a[0],a[1],
23
- b,g,d,e,f,!0)}.bind(this)),this.globalAreaLineSet.push(j));this.options.datalabels&&this.options.draw_hovers&&(this.drawHover(i,d,e,b),this.globalHoverSet.toFront())},calculateCoords:function(a){var b=this.x_padding_left+this.options.plot_padding-this.step,c=this.graph_height+this.y_padding_top+this.normalise(this.start_value);a=$A(a).collect(function(a){b+=this.step;return[b,c-a]}.bind(this));if(!this.hasBaseLine())return a;b+=this.step;for(var d=this.getNormalizedBaseLine(),e=d.length-1;e>=0;e--)b-=
24
- this.step,a.push([b,c-d[e]]);return a},drawFocusHint:function(){var a=this.x_padding_left+2.5-1,b=this.options.height-this.y_padding_bottom,c=this.paper.path().attr({stroke:this.options.label_color,"stroke-width":2});c.moveTo(a,b);c.lineTo(a-5,b-5);c.moveTo(a,b-5);c.lineTo(a-5,b-10)},drawMeanLine:function(a){var b=this.paper.path().attr(this.options.meanline);a=$A(a).inject(0,function(a,b){return b+a})/a.length-0.5;a=this.options.bar?a+this.zero_value*(this.graph_height/this.y_label_count):a;b.moveTo(this.x_padding_left-
25
- 1,this.options.height-this.y_padding_bottom-a).lineTo(this.graph_width+this.x_padding_left,this.options.height-this.y_padding_bottom-a)},drawAxis:function(){var a=this.paper.path().attr({stroke:this.options.label_color});a.moveTo(parseInt(this.x_padding_left,10)-0.5,this.options.height-parseInt(this.y_padding_bottom,10)+0.5);a.lineTo(parseInt(this.graph_width+this.x_padding_left,10)-0.5,this.options.height-parseInt(this.y_padding_bottom,10)+0.5);a.moveTo(parseInt(this.x_padding_left,10)-0.5,parseInt(this.options.height-
26
- this.y_padding_bottom,10)+0.5);a.lineTo(parseInt(this.x_padding_left,10)-0.5,parseInt(this.y_padding_top,10))},makeValueLabels:function(a){for(var b=this.label_step,c=this.start_value,d=[],e=0;e<a;e++)c=this.roundValue(c+b,3),d.push(c);return d},drawMarkers:function(a,b,c,d,e,f){var g=parseInt(this.x_padding_left,10)-0.5+d*b[0],h=this.options.height-this.y_padding_bottom+d*b[1],i=this.paper.path().attr({stroke:this.options.label_color}),j={font:this.options.font_size+'px "Arial"',stroke:"none",fill:this.options.label_color};
27
- Object.extend(j,f||{});a.each(function(a){if(this.options.draw_axis&&(this.options.hide_empty_label_grid===!0&&a!==""||this.options.hide_empty_label_grid===!1)&&this.options.show_ticks)i.moveTo(parseInt(g,10),parseInt(h,10)+0.5),i.lineTo(parseInt(g,10)+5*b[1],parseInt(h,10)+0.5+5*b[0]);a!==""&&this.paper.text(g+e[0],h-2-e[1],a.toString()).attr(j);g+=c*b[0];h+=c*b[1]}.bind(this))},drawVerticalLabels:function(){for(var a=this.graph_height/this.y_label_count,b=this.options.vertical_label_unit?" "+this.options.vertical_label_unit:
28
- "",c=0;c<this.value_labels.length;c++)this.value_labels[c]+=b;this.drawMarkers(this.value_labels,[0,-1],a,a,[-8,-2],{"text-anchor":"end"})},drawHorizontalLabels:function(){var a=this.options.label_rotation?{rotation:this.options.label_rotation,translation:-this.options.font_size+" 0"}:{},b=this.options.labels;if(this.options.label_max_size)for(var c=0;c<b.length;c++)b[c]=b[c].truncate(this.options.label_max_size+1,"\u2026");this.drawMarkers(b,[1,0],this.step,this.options.plot_padding,[0,(this.options.font_size+
29
- 7)*-1],a)},drawHover:function(a,b,c,d){var e=this,f=this.options.stacked_fill||this.options.area?"fill":"stroke",g=this.options.hover_color||d,h=this.paper.set();b=this.paper.text(a.attrs.x,a.attrs.y-this.options.font_size*1.5-4,b).attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,opacity:1});var i=b.getBBox(),j=this.drawRoundRect(b,i,4);h.push(j,b).attr({opacity:0});this.checkHoverPos({rect:j,set:h});this.globalHoverSet.push(h);a.hover(function(b){f==="fill"?a.animate({fill:g,
30
- stroke:g},200):a.animate({stroke:g},200);b=e.getMousePos(b);h[0].attr({x:b.x-i.width/2-4-c.offsetLeft,y:b.y-i.height/2-e.options.font_size*1.5-4-c.offsetTop,opacity:1});h[1].attr({x:b.x-c.offsetLeft,y:b.y-e.options.font_size*1.5-c.offsetTop,opacity:1});a.mousemove(function(a){a=e.getMousePos(a);h[0].attr({x:a.x-i.width/2-4-c.offsetLeft,y:a.y-i.height/2-e.options.font_size*1.5-4-c.offsetTop,opacity:1});h[1].attr({x:a.x-c.offsetLeft,y:a.y-e.options.font_size*1.5-c.offsetTop,opacity:1});e.checkHoverPos(j,
31
- h)})},function(){f==="fill"?a.animate({fill:d,stroke:d},200):a.animate({stroke:d},200);h.attr({opacity:0})})},checkHoverPos:function(a){var b,c,d,e,f,g;if(a.rect)c=a.rect,d=c.getBBox();if(a.set)e=a.set;if(a.marker)f=a.marker;if(a.nib)g=a.nib;if(a.textpadding)b=a.textpadding;if(c&&e){if(c.attrs.y<0)g&&f?(a=e.getBBox(),e.translate(0,a.height+b*2),f.translate(0,-a.height-b*2),g.translate(0,-d.height-b+1.5).scale(1,-1)):(b=c.attrs.y,e.translate(0,1-b));c.attrs.y+d.height>this.options.height&&(b=c.attrs.y+
32
- d.height-this.options.height,e.translate(0,-b-1),f&&f.translate(0,b+1));if(c.attrs.x<0)b=c.attrs.x,e.translate(-b+1,0),g&&g.translate(b-1,0),f&&f.translate(b-1,0);c.attrs.x+d.width>this.options.width&&(b=c.attrs.x+d.width-this.options.width,e.translate(-b-1,0),g&&g.translate(b+1,0),f&&f.translate(b+1,0))}},drawNib:function(a,b,c){return this.paper.path().attr({fill:this.options.label_color,opacity:1,stroke:this.options.label_color,"stroke-width":"0px"}).moveTo(a.attrs.x-c,a.attrs.y+b.height/2+c-1).lineTo(a.attrs.x,
33
- a.attrs.y+b.height/2+c*2).lineTo(a.attrs.x+c,a.attrs.y+b.height/2+c-1).andClose()},drawRoundRect:function(a,b,c){return this.paper.rect(a.attrs.x-b.width/2-c,a.attrs.y-b.height/2-c,b.width+c*2,b.height+c*2,c*1.5).attr({fill:this.options.label_color,opacity:1,stroke:this.options.label_color,"stroke-width":"0px"})}});Array.prototype.sum=function(){for(var a=0,b=0;a<this.length;b+=this[a++]);return b};
34
- if(typeof Array.prototype.max==="undefined")Array.prototype.max=function(){return Math.max.apply({},this)};if(typeof Array.prototype.min==="undefined")Array.prototype.min=function(){return Math.min.apply({},this)};Array.prototype.mean=function(){return this.sum()/this.length};Array.prototype.variance=function(){for(var a=this.mean(),b=0,c=0;c<this.length;c++)b+=Math.pow(this[c]-a,2);return b/(this.length-1)};Array.prototype.standard_deviation=function(){return Math.sqrt(this.variance())};
35
- Array.prototype.remove=function(a,b){var c=this.slice((b||a)+1||this.length);this.length=a<0?this.length+a:a;return this.push.apply(this,c)};Raphael.el.isAbsolute=!0;Raphael.el.absolutely=function(){this.isAbsolute=1;return this};Raphael.el.relatively=function(){this.isAbsolute=0;return this};Raphael.el.moveTo=function(a,b){this._last={x:a,y:b};return this.attr({path:this.attrs.path+["m","M"][+this.isAbsolute]+parseFloat(a)+" "+parseFloat(b)})};
36
- Raphael.el.lineTo=function(a,b){this._last={x:a,y:b};return this.attr({path:this.attrs.path+["l","L"][+this.isAbsolute]+parseFloat(a)+" "+parseFloat(b)})};Raphael.el.cplineTo=function(a,b,c){a>this._last.x?this.attr({path:this.attrs.path+["C",this._last.x+c,this._last.y,a-c,b,a,b]}):a==this._last.x?this.lineTo(a,b):this.attr({path:this.attrs.path+["C",this._last.x-c,this._last.y,a+c,b,a,b]});this._last={x:a,y:b};return this};Raphael.el.andClose=function(){return this.attr({path:this.attrs.path+"z"})};
37
- Grafico.LineGraph=Class.create(Grafico.BaseGraph,{chartDefaults:function(){return{line:!0,start_at_zero:!0,stroke_width:5,curve_amount:10}},setChartSpecificOptions:function(){},calculateStep:function(){return(this.graph_width-this.options.plot_padding*2)/(this.data_size-1)},startPlot:function(a,b,c){a.moveTo(b,c)},drawPlot:function(a,b,c,d,e,f,g,h,i){if(a===0)return this.startPlot(b,c-0.5,d,e);this.options.curve_amount?b.cplineTo(c,d,this.options.curve_amount):b.lineTo(c,d);this.options.markers===
38
- "circle"?this.drawGraphMarkers(a,c,d,e,g,h):this.options.markers==="value"&&this.drawGraphValueMarkers(a,c,d,e,g,h,i)},drawGraphMarkers:function(a,b,c,d){var e=this.paper.circle(b,c,this.options.marker_size),f=this.options.marker_size,g=this.options.hover_color||d,h=parseInt(1.7*f,10);e.attr({"stroke-width":"1px",stroke:this.options.background_color,fill:d});this.globalMarkerSet.push(e);e.hover(function(){e.animate({r:h,fill:g},200)},function(){e.animate({r:f,fill:d},200)})},drawGraphValueMarkers:function(a,
39
- b,c,d,e,f,g){a+=this.options.odd_horizontal_offset>1?this.options.odd_horizontal_offset:0;a-=this.options.stacked_fill||this.options.area?1:0;if(f=(this.options.stacked?this.real_data:this.data_sets).collect(function(b){return b[1][a]})[g])f=""+f.toString().split("."),f[1]&&(f[1]=f[1].truncate(3,""));if(this.options.line||this.options.stacked||(this.options.stacked_fill||this.options.area)&&a!=-1&&typeof f!="undefined"){g=b-this.step/2;var h=c-[this.options.stroke_width/2,this.options.hover_radius].max(),
40
- i=this.step,j=[this.options.stroke_width,this.options.hover_radius*2].max();b=this.paper.circle(b,c,this.options.marker_size==0?[this.options.stroke_width*1.5,this.step].min():this.options.marker_size).attr({"stroke-width":"1px",stroke:this.options.background_color,fill:d,opacity:0});d=this.paper.rect(g,h,i,j).attr({fill:d,"stroke-width":0,stroke:d,opacity:0});e=this.options.datalabels?typeof e=="function"?e.call(this,a,f):e+": "+f:""+f;e+=this.options.vertical_label_unit?" "+this.options.vertical_label_unit:
41
- "";var k=this.paper.set();e=this.paper.text(b.attrs.cx,b.attrs.cy-this.options.font_size*1.5-8,e).attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,opacity:1});f=e.getBBox();c=this.drawRoundRect(e,f,4);f=this.drawNib(e,f,4);k.push(b,c,f,e).attr({opacity:0});this.checkHoverPos({rect:c,set:k,marker:b,nib:f,textpadding:4});this.globalHoverSet.push(k);this.globalBlockSet.push(d);d.hover(function(){k.animate({opacity:1},200)},function(){k.animate({opacity:0},200)})}}});
42
- Grafico.AreaGraph=Class.create(Grafico.LineGraph,{chartDefaults:function(){return{area:!0,area_opacity:!1,stroke_width:0,curve_amount:10}},drawPlot:function(a,b,c,d,e,f,g,h,i,j){var k=this.options.area||this.options.stacked_fill;j||(k===!0?a!==0&&a!==f.length-1&&(this.options.markers==="circle"?this.drawGraphMarkers(a,c,d,e,g,h):this.options.markers==="value"&&this.drawGraphValueMarkers(a,c,d,e,g,h,i)):this.options.markers==="circle"?this.drawGraphMarkers(a,c,d,e,g,h):this.options.markers==="value"&&
43
- this.drawGraphValueMarkers(a,c,d,e,g,h,i));c-=0.5;if(a===0)return this.startPlot(b,c,d,e);this.options.curve_amount&&a>1&&a<f.length-1?b.cplineTo(c,d,this.options.curve_amount):this.options.curve_amount&&!k?b.cplineTo(c,d,this.options.curve_amount):b.lineTo(c,d)}});
44
- Grafico.StackGraph=Class.create(Grafico.AreaGraph,{chartDefaults:function(){return{stacked:!0,stacked_fill:!0,stroke_width:0,curve_amount:10}},setChartSpecificOptions:function(){if(!this.options.stacked_fill)this.options.stroke_width=5},stackData:function(a){for(var b=a.collect(function(a){return a[1]}),c=b.length-2;c>=0;c--)for(var d=0;d<b[0].length;d++)b[c][d]+=b[c+1][d];return a}});
45
- Grafico.StreamGraph=Class.create(Grafico.StackGraph,{chartDefaults:function(){return{stacked:!0,stacked_fill:!0,stroke_width:5,grid:!1,draw_axis:!1,show_horizontal_labels:!1,show_vertical_labels:!1,stream:!0,stream_line_smoothing:!1,stream_smart_insertion:!1,curve_amount:4,stream_label_threshold:0}},hasBaseLine:function(){return!0},calcBaseLine:function(a){var b=a.collect(function(a){return a[1]});a=[];var c,d;for(d=0;d<b[0].length;d++){for(c=sum=0;c<b.length;c++)sum+=this.options.stream_line_smoothing==
46
- !1?b[c][d]:(c+1)*b[c][d];a[d]=this.options.stream_line_smoothing==!1?-sum/2:-sum/(b.length+1)}b=a.min();for(c=0;c<a.length;c++)a[c]-=b;this.base_line=a},stackData:function(a){var b,c;if(this.options.stream_smart_insertion){a=$A(a);a.each(function(a){for(b=0;b<a[1].length&&a[1][b]<=1.0E-7;)b++;a[2]=b});var d=[],e=!1;a.sortBy(function(a){return a[2]}).each(function(a){e?d.push(a):d.unshift(a);e=!e});a=$H();d.each(function(b){a.set(b[0],b[1])})}this.real_data=this.deepCopy(a);this.calcBaseLine(a);var f=
47
- a.collect(function(a){return a[1]});for(c=0;c<f[0].length;c++)f[f.length-1][c]+=this.base_line[c];for(b=f.length-2;b>=0;b--)for(c=0;c<f[0].length;c++)f[b][c]+=f[b+1][c];return a},drawPlot:function(a,b,c,d,e,f,g,h,i,j){if(this.options.datalabels&&!j){j=this.getNormalizedRealData();var k=this.bestMarkerPositions();a<f.length/2&&k[i]>=a&&k[i]<a+1&&this.drawStreamMarker(a+1,c+(k[i]-a)*this.step,d+j[i][a]/2,e,g,h)}c-=0.5;if(a===0)return this.startPlot(b,c,d,e);b.cplineTo(c,d,this.options.curve_amount)},
48
- bestMarkerPositions:function(){if(this.best_marker_positions==void 0)this.best_marker_positions=this.real_data.collect(function(a){for(var b=-1,c=0,d=0,e=0;e<a[1].length;e++){var f=a[1][e];f>c&&f>=this.options.stream_label_threshold?(c=f,b=e,d=0):f==c&&c>0&&d++}return b+d/2}.bind(this));return this.best_marker_positions},drawStreamMarker:function(a,b,c,d,e){this.options.datalabels&&(a=this.paper.set(),b=this.paper.text(b,c-8+this.options.font_size/2,e).attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,
49
- opacity:1}),c=b.getBBox(),c=this.drawRoundRect(b,c,4),a.push(c,b),this.checkHoverPos({rect:c,set:a,textpadding:4}),this.globalHoverSet.push(a))}});
50
- Grafico.BarGraph=Class.create(Grafico.BaseGraph,{chartDefaults:function(){return{bar:!0,plot_padding:0,bargraph_lastcolor:!1,bargraph_negativecolor:!1}},normaliserOptions:function(){return{start_value:0,bar:!0}},setChartSpecificOptions:function(){this.bar_padding=5;this.bar_width=this.calculateBarWidth();this.options.plot_padding=this.bar_width/2;this.step=this.calculateStep();this.grid_start_offset=this.bar_padding-1},calculateBarWidth:function(){return this.graph_width/this.data_size-this.bar_padding},
51
- calculateStep:function(){this.data_size=this.data_size==1?2:this.data_size;return(this.graph_width-this.options.plot_padding*2-this.bar_padding*2)/(this.data_size-1)},longestDataSetLength:function(){var a=0;this.data_sets.each(function(b){a=b[1].length>a?b[1].length:a});return a},drawPlot:function(a,b,c,d,e,f,g){b=this.options.height-this.y_padding_bottom-this.zero_value*(this.graph_height/this.y_label_count);var h=this.options.bargraph_lastcolor,i=this.options.bargraph_negativecolor||e;c+=this.bar_padding;
52
- d=b-d;e=h&&a===f.length-1?h:d<0?i:e;f=this.paper.rect(c-this.bar_width/2,b,this.bar_width,d).attr({fill:e,"stroke-width":this.options.stroke_width,stroke:e,"stroke-opacity":0});d<0?f.attr({height:-f.attrs.height}):f.translate(0,-d);this.options.datalabels&&this.drawGraphValueMarkers(c,a,f,g,e);this.options.count++},drawHorizontalLabels:function(){var a=this.bar_padding+this.options.plot_padding,b=this.options.label_rotation?{rotation:this.options.label_rotation,translation:-this.options.font_size+
53
- " 0"}:{},c=this.options.labels;if(this.options.label_max_size)for(var d=0;d<c.length;d++)c[d]=c[d].truncate(this.options.label_max_size+1,"\u2026");this.drawMarkers(this.options.labels,[1,0],this.step,a,[0,(this.options.font_size+7)*-1],b)},drawGrid:function(){var a=this.paper.path().attr({stroke:this.options.grid_color,"stroke-width":1}),b=this.graph_height+this.y_padding_top,c,d;if(this.options.horizontalbar)a.moveTo(this.x_padding_left-0.5,parseInt(b,10)+0.5),a.lineTo(this.x_padding_left+this.graph_width-
54
- 0.5,parseInt(b,10)+0.5),b-=this.graph_height,a.moveTo(this.x_padding_left-0.5,parseInt(b,10)+0.5),a.lineTo(this.x_padding_left+this.graph_width-0.5,parseInt(b,10)+0.5);else if(this.options.show_horizontal_grid)for(var e=0;e<this.y_label_count+1;e++)a.moveTo(this.x_padding_left-0.5,parseInt(b,10)+0.5),a.lineTo(this.x_padding_left+this.graph_width-0.5,parseInt(b,10)+0.5),b-=this.graph_height/this.y_label_count;if(this.options.horizontalbar){b=this.x_padding_left+this.options.plot_padding+this.grid_start_offset;
55
- c=this.y_label_count;d=this.options.horizontalbar?this.graph_width/this.y_label_count:this.step;for(e=0;e<c;e++){if(this.options.hide_empty_label_grid===!0&&this.options.labels[e]!==""||this.options.hide_empty_label_grid===!1)a.moveTo(parseInt(b,10)+0.5,this.y_padding_top),a.lineTo(parseInt(b,10)+0.5,this.y_padding_top+this.graph_height);b+=d}}a.moveTo(parseInt(this.x_padding_left,10)-0.5,this.y_padding_top);a.lineTo(parseInt(this.x_padding_left,10)-0.5,this.y_padding_top+this.graph_height);a.moveTo(parseInt(this.x_padding_left+
56
- this.graph_width,10)-0.5,this.y_padding_top);a.lineTo(parseInt(this.x_padding_left+this.graph_width,10)-0.5,this.y_padding_top+this.graph_height)},drawGraphValueMarkers:function(a,b,c,d,e){var f=this.options.hover_color||e,g=this.paper.set();a=this.paper.rect(a-this.bar_width/2,this.y_padding_top,this.bar_width,this.options.height).attr({fill:e,"stroke-width":0,stroke:e,opacity:0});if(d=d&&d[b]?d[b].toString():""){b=this.paper.text(c.attrs.x+this.bar_width/2,c.attrs.y-this.options.font_size*1.5,d);
57
- b.attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,opacity:1});var h=b.getBBox();d=this.drawRoundRect(b,h,4);h=this.drawNib(b,h,4);g.push(d,h,b).attr({opacity:0});this.checkHoverPos({rect:d,set:g,nib:h});this.globalHoverSet.push(g);this.globalBlockSet.push(a);d.attrs.y<0&&g.translate(0,1+d.attrs.y*-1);a.hover(function(){c.animate({fill:f,stroke:f},200);g.animate({opacity:1},200)},function(){c.animate({fill:e,stroke:e},200);g.animate({opacity:0},200)})}}});
58
- Grafico.StackedBarGraph=Class.create(Grafico.BarGraph,{chartDefaults:function(){return{opacity:100,bar:!0,plot_padding:0,stacked:!0,stacked_fill:!0}},setChartSpecificOptions:function(){this.bar_padding=5;this.bar_width=this.calculateBarWidth();this.options.plot_padding=this.bar_width/2;this.step=this.calculateStep();this.grid_start_offset=this.bar_padding-1;this.options.stroke_width=1},stackData:function(a){for(var b=a.collect(function(a){return a[1]}),c=b.length-2;c>=0;c--)for(var d=0;d<b[0].length;d++)b[c][d]+=
59
- b[c+1][d];return a},calculateCoords:function(a){var b=this.x_padding_left+this.options.plot_padding-this.step,c=this.graph_height+this.y_padding_top+this.normalise(this.start_value);a=$A(a).collect(function(a){b+=this.step;return[b,c-a]}.bind(this));b+=this.step;for(var d=this.getNormalizedBaseLine(),e=d.length-1;e>=0;e--)b-=this.step,a.push([b,c-d[e]]);return a},drawLines:function(a,b,c,d,e,f){var g=this.calculateCoords(c),h;h=this.paper.path().attr({stroke:b,"stroke-width":0});$A(g).each(function(a,
60
- c){this.drawPlot(c,h,a[0],a[1],b,g,d,e,f)}.bind(this));this.options.datalabels&&this.options.draw_hovers&&(this.drawHover(h,d,e,b),this.globalHoverSet.toFront())},drawPlot:function(a,b,c,d,e,f,g){b=this.options.height-this.y_padding_bottom-this.zero_value*(this.graph_height/this.y_label_count);c+=this.bar_padding;d=this.options.height-this.y_padding_bottom-d-this.zero_value*(this.graph_height/this.y_label_count);f={fill:e,"stroke-width":0,stroke:this.options.color2,opacity:this.options.opacity};b=
61
- this.paper.rect(c-this.bar_width/2,b,this.bar_width,d).attr(f);d<0?b.attr({height:-b.attrs.height}):b.translate(0,-d);this.options.datalabels&&this.drawGraphValueMarkers(c,a,b,g,e);this.options.count++},drawGraphValueMarkers:function(a,b,c,d,e){a-=this.bar_width/2;var f=c.attrs.y,g=this.bar_width,h=c.attrs.height,i=this.options.hover_color||e,j=this.paper.set();a=this.paper.rect(a,f,g,h);d=d&&d.length>b?d[b].toString():"";b=this.paper.text(c.attrs.x+this.bar_width/2,c.attrs.y-this.options.font_size*
62
- 1.5,d);a.attr({fill:e,"stroke-width":0,stroke:e,opacity:0});b.attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,opacity:1});f=b.getBBox();d=this.drawRoundRect(b,f,4);f=this.drawNib(b,f,4);j.push(d,f,b).attr({opacity:0});this.checkHoverPos({rect:d,set:j,nib:f});this.globalHoverSet.push(j);this.globalBlockSet.push(a);d.attrs.y<0&&j.translate(0,1+d.attrs.y*-1);a.hover(function(){c.animate({fill:i},200);j.animate({opacity:1},200)},function(){c.animate({fill:e},200);j.animate({opacity:0},
63
- 200)})}});
64
- Grafico.HorizontalBarGraph=Class.create(Grafico.BarGraph,{chartDefaults:function(){return{bar:!0,horizontalbar:!0,plot_padding:0,horizontal_rounded:!1,bargraph_lastcolor:!1}},setChartSpecificOptions:function(){this.x_padding_left=20+this.longestLabel()*(this.options.font_size/2);this.bar_padding=5;this.bar_width=this.calculateBarHeight();this.step=this.calculateStep();this.graph_width=this.options.width-this.x_padding_right-this.x_padding_left},normalise:function(a){var b=this.makeValueLabels(this.y_label_count);b=
65
- b[b.length-1];return a/b*this.graph_width},longestLabel:function(){return $A(this.options.labels).sort(function(a,b){return a.toString().length<b.toString().length}).first().toString().length},calculateBarHeight:function(){return this.graph_height/this.data_size-this.bar_padding},calculateStep:function(){return(this.graph_height-this.options.plot_padding*2)/this.data_size},drawLines:function(a,b,c,d){var e=this.y_padding_top+this.bar_padding/2-0.5,f=this.zero_value*(this.graph_width/this.y_label_count),
66
- g=this.x_padding_left+f-0.5,h=this.options.bargraph_lastcolor,i=this.options.bargraph_negativecolor||b;this.datalabel=d;$A(c).each(function(a,d){var l,q=this.options.horizontal_rounded?this.bar_width/2:0,n;l=h&&d===c.length-1?h:a<0?i:b;a=a/this.graph_width*(this.graph_width-f);n=this.paper.rect(g,e,a,this.bar_width,q).attr({fill:l,"stroke-width":0,stroke:l,"stroke-opacity":0});a<0&&n.attr({width:-n.attrs.width}).translate(a,0);if(q){var t=this.paper.set(),m=this.paper.rect(g,e,a-this.bar_width/2,
67
- this.bar_width).attr({fill:l,"stroke-width":0,stroke:l,"stroke-opacity":0});t.push(m,n);a<0&&m.attr({width:-m.attrs.width-this.bar_width}).translate(a+this.bar_width/2,0)}if(this.options.datalabels){var r=this.options.hover_color||l,o=this.paper.set();m=this.paper.text(f+a+this.x_padding_left/2,n.attrs.y-this.options.font_size*1.5,this.datalabel[d].toString()).attr({"font-size":this.options.font_size,fill:this.options.hover_text_color,opacity:1});var u=this.paper.rect(this.x_padding_left,e,this.graph_width,
68
- this.bar_width).attr({fill:l,"stroke-width":0,stroke:l,opacity:0}),p=m.getBBox();a<0&&m.translate(p.width,0);var s=this.drawRoundRect(m,p,4);p=this.drawNib(m,p,4);o.push(s,p,m).attr({opacity:0});this.checkHoverPos({rect:s,set:o,nib:p});this.globalHoverSet.push(o);this.globalBlockSet.push(u);s.attrs.y<0&&o.translate(0,1-s.attrs.y);u.hover(function(){q?t.animate({fill:r,stroke:r},200):n.animate({fill:r,stroke:r},200);o.animate({opacity:1},200)},function(){q?t.animate({fill:l,stroke:l},200):n.animate({fill:l,
69
- stroke:l},200);o.animate({opacity:0},200)})}e+=this.step}.bind(this))},drawFocusHint:function(){var a=this.x_padding_left+10,b=this.options.height-this.y_padding_bottom-2.5;this.paper.path().attr({stroke:this.options.label_color,"stroke-width":2}).moveTo(a,b).lineTo(a-5,b+5).moveTo(a-5,b).lineTo(a-10,b+5)},drawVerticalLabels:function(){var a=this.step/2,b=this.options.label_rotation?{"text-anchor":"end",rotation:this.options.label_rotation,translation:"0 "+this.options.font_size/2}:{"text-anchor":"end"},
70
- c=this.options.labels;if(this.options.label_max_size)for(var d=0;d<c.length;d++)c[d]=c[d].truncate(this.options.label_max_size+1,"\u2026");this.drawMarkers(this.options.labels.reverse(),[0,-1],this.step,a,[-8,-(this.options.font_size/5)],b)},drawHorizontalLabels:function(){var a=this.graph_width/this.y_label_count,b=this.makeValueLabels(this.y_label_count);if(this.options.vertical_label_unit)for(var c=0;c<b.length;c++)b[c]+=this.options.vertical_label_unit;this.drawMarkers(b,[1,0],a,a,[0,(this.options.font_size+
71
- 7)*-1])},drawMeanLine:function(a){a=$A(a).inject(0,function(a,c){return c+a})/a.length;a=this.options.bar?a+this.zero_value*(this.graph_height/this.y_label_count):a;this.paper.path().attr(this.options.meanline).moveTo(this.x_padding_left-1+a,this.y_padding_top).lineTo(this.x_padding_left-1+a,this.y_padding_top+this.graph_height)}});
72
- Grafico.SparkLine=Class.create(Grafico.Base,{initialize:function(a,b,c){this.element=a;this.data=b;this.options={highlight:!1,stroke_width:1,color:this.makeRandomcolor(),width:parseInt(a.getStyle("width"),10),height:parseInt(a.getStyle("height"),10),acceptable_range:!1,zeroline:!1};Object.extend(this.options,c||{});this.step=this.calculateStep();this.paper=new Raphael(this.element,this.options.width,this.options.height);this.drawBackground();this.draw()},drawBackground:function(){this.background=
73
- this.options.acceptable_range?this.paper.rect(0,this.options.height-this.normalise(this.options.acceptable_range[1]),this.options.width,this.normalise(this.options.acceptable_range[1])-this.normalise(this.options.acceptable_range[0])):this.paper.rect(0,0,this.options.width,this.options.height);this.background.attr({fill:this.options.background_color,stroke:"none"})},calculateStep:function(){return this.options.width/(this.data.length-1)},makeRandomcolor:function(){return Raphael.hsb2rgb(Math.random(),
74
- 1,0.75).hex},normalise:function(a){var b=this.data.min()<0?this.data.max()-this.data.min():this.data.max();a-=this.data.min()<0?this.data.min():0;return a/b*this.options.height},draw:function(){var a=this.normaliseData(this.data),b;if(this.options.zeroline&&this.data.min()<0)this.options.zeroline=this.options.zeroline===!0?{"stroke-width":"1px",stroke:"#BBBBBB"}:this.options.zeroline,b=parseInt(this.options.height-this.normalise(0),10),this.paper.path().attr(this.options.zeroline).moveTo(0,b).lineTo(this.options.width,
75
- b);this.drawLines(this.options.color,a);this.options.highlight&&this.showHighlight(a)},drawLines:function(a,b){var c=this.paper.path().attr({stroke:a,"stroke-width":this.options.stroke_width}).moveTo(0,this.options.height-b.first()),d=0,e=this.data.min()<0?this.options.stroke_width:0;b.slice(1).each(function(a){d+=this.step;c.lineTo(d,this.options.height-a-e)}.bind(this))},showHighlight:function(a){var b=1+this.options.stroke_width/2,c=this.options.width-b;a=a[this.options.highlight.index||a.length-
76
- 1]+(b/2).round();var d=this.options.highlight.color||"#f00";typeof this.options.highlight.index!=="undefined"&&(c=this.step*this.options.highlight.index);this.paper.circle(c,this.options.height-a+b/2,b).attr({stroke:!1,fill:d})}});
77
- Grafico.SparkBar=Class.create(Grafico.SparkLine,{calculateStep:function(){return this.options.width/this.data.length},drawLines:function(a,b){var c=this.options.bargraph_lastcolor,d=this.step>2?this.step-1:this.step,e=d/2,f=this.normalise(0);b.each(function(g,h){var i,j;i=c&&h===b.length-1?c:a;j=this.paper.path().attr({stroke:i,"stroke-width":d});j.moveTo(e,this.options.height-g);j.lineTo(e,this.options.height-f);g<f&&j.attr({stroke:this.options.bargraph_negativecolor||i});e+=this.step}.bind(this))},
78
- showHighlight:function(){}});
79
- Grafico.SparkArea=Class.create(Grafico.SparkLine,{drawLines:function(a,b){var c=a,d=a,e=0.2,f=this.normalise(0);typeof a=="object"&&(c=a[1],d=a[0],e=1);var g=this.paper.path().attr({fill:c,stroke:c,"stroke-width":0,"stroke-opacity":0,opacity:e}).moveTo(0,this.options.height-f).lineTo(0,this.options.height-b.first()),h=this.paper.path().attr({stroke:d,"stroke-width":this.options.stroke_width}).moveTo(0,this.options.height-b.first()),i=0;b.slice(1).each(function(a){i+=this.step;g.lineTo(i,this.options.height-
80
- a);h.lineTo(i,this.options.height-a)}.bind(this));g.lineTo(i,this.options.height-f)}});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/aitoc/aitloadmon/raphael-min.js DELETED
@@ -1,7 +0,0 @@
1
- /*!
2
- * Raphael 1.5.2 - JavaScript Vector Library
3
- *
4
- * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
5
- * Licensed under the MIT (http://raphaeljs.com/license.html) license.
6
- */
7
- (function(){function R(){if(R.is(arguments[0],array)){var a=arguments[0],cnv=create[apply](R,a.splice(0,3+R.is(a[0],nu))),res=cnv.set();for(var i=0,ii=a[length];i<ii;i++){var j=a[i]||{};elements[has](j.type)&&res[push](cnv[j.type]().attr(j))}return res}return create[apply](R,arguments)}R.version="1.5.2";var separator=/[, ]+/,elements={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},formatrg=/\{(\d+)\}/g,proto="prototype",has="hasOwnProperty",doc=document,win=window,oldRaphael={was:Object[proto][has].call(win,"Raphael"),is:win.Raphael},Paper=function(){this.customAttributes={}},paperproto,appendChild="appendChild",apply="apply",concat="concat",supportsTouch="createTouch" in doc,E="",S=" ",Str=String,split="split",events="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[split](S),touchMap={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},join="join",length="length",lowerCase=Str[proto].toLowerCase,math=Math,mmax=math.max,mmin=math.min,abs=math.abs,pow=math.pow,PI=math.PI,nu="number",string="string",array="array",toString="toString",fillString="fill",objectToString=Object[proto][toString],paper={},push="push",ISURL=/^url\(['"]?([^\)]+?)['"]?\)$/i,colourRegExp=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,isnan={"NaN":1,"Infinity":1,"-Infinity":1},bezierrg=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,round=math.round,setAttribute="setAttribute",toFloat=parseFloat,toInt=parseInt,ms=" progid:DXImageTransform.Microsoft",upperCase=Str[proto].toUpperCase,availableAttrs={blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,preserveAspectRatio:"none",rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},availableAnimAttrs={along:"along",blur:nu,"clip-rect":"csv",cx:nu,cy:nu,fill:"colour","fill-opacity":nu,"font-size":nu,height:nu,opacity:nu,path:"path",r:nu,rotation:"csv",rx:nu,ry:nu,scale:"csv",stroke:"colour","stroke-opacity":nu,"stroke-width":nu,translation:"csv",width:nu,x:nu,y:nu},rp="replace",animKeyFrames=/^(from|to|\d+%?)$/,commaSpaces=/\s*,\s*/,hsrg={hs:1,rg:1},p2s=/,?([achlmqrstvxz]),?/gi,pathCommand=/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,pathValues=/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,radial_gradient=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,sortByKey=function(a,b){return a.key-b.key};R.type=(win.SVGAngle||doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML");if(R.type=="VML"){var d=doc.createElement("div"),b;d.innerHTML='<v:shape adj="1"/>';b=d.firstChild;b.style.behavior="url(#default#VML)";if(!(b&&typeof b.adj=="object")){return R.type=null}d=null}R.svg=!(R.vml=R.type=="VML");Paper[proto]=R[proto];paperproto=Paper[proto];R._id=0;R._oid=0;R.fn={};R.is=function(o,type){type=lowerCase.call(type);if(type=="finite"){return !isnan[has](+o)}return(type=="null"&&o===null)||(type==typeof o)||(type=="object"&&o===Object(o))||(type=="array"&&Array.isArray&&Array.isArray(o))||objectToString.call(o).slice(8,-1).toLowerCase()==type};R.angle=function(x1,y1,x2,y2,x3,y3){if(x3==null){var x=x1-x2,y=y1-y2;if(!x&&!y){return 0}return((x<0)*180+math.atan(-y/-x)*180/PI+360)%360}else{return R.angle(x1,y1,x3,y3)-R.angle(x2,y2,x3,y3)}};R.rad=function(deg){return deg%360*PI/180};R.deg=function(rad){return rad*180/PI%360};R.snapTo=function(values,value,tolerance){tolerance=R.is(tolerance,"finite")?tolerance:10;if(R.is(values,array)){var i=values.length;while(i--){if(abs(values[i]-value)<=tolerance){return values[i]}}}else{values=+values;var rem=value%values;if(rem<tolerance){return value-rem}if(rem>values-tolerance){return value-rem+values}}return value};function createUUID(){var s=[],i=0;for(;i<32;i++){s[i]=(~~(math.random()*16))[toString](16)}s[12]=4;s[16]=((s[16]&3)|8)[toString](16);return"r-"+s[join]("")}R.setWindow=function(newwin){win=newwin;doc=win.document};var toHex=function(color){if(R.vml){var trim=/^\s+|\s+$/g;var bod;try{var docum=new ActiveXObject("htmlfile");docum.write("<body>");docum.close();bod=docum.body}catch(e){bod=createPopup().document.body}var range=bod.createTextRange();toHex=cacher(function(color){try{bod.style.color=Str(color)[rp](trim,E);var value=range.queryCommandValue("ForeColor");value=((value&255)<<16)|(value&65280)|((value&16711680)>>>16);return"#"+("000000"+value[toString](16)).slice(-6)}catch(e){return"none"}})}else{var i=doc.createElement("i");i.title="Rapha\xebl Colour Picker";i.style.display="none";doc.body[appendChild](i);toHex=cacher(function(color){i.style.color=color;return doc.defaultView.getComputedStyle(i,E).getPropertyValue("color")})}return toHex(color)},hsbtoString=function(){return"hsb("+[this.h,this.s,this.b]+")"},hsltoString=function(){return"hsl("+[this.h,this.s,this.l]+")"},rgbtoString=function(){return this.hex};R.hsb2rgb=function(h,s,b,o){if(R.is(h,"object")&&"h" in h&&"s" in h&&"b" in h){b=h.b;s=h.s;h=h.h;o=h.o}return R.hsl2rgb(h,s,b/2,o)};R.hsl2rgb=function(h,s,l,o){if(R.is(h,"object")&&"h" in h&&"s" in h&&"l" in h){l=h.l;s=h.s;h=h.h}if(h>1||s>1||l>1){h/=360;s/=100;l/=100}var rgb={},channels=["r","g","b"],t2,t1,t3,r,g,b;if(!s){rgb={r:l,g:l,b:l}}else{if(l<0.5){t2=l*(1+s)}else{t2=l+s-l*s}t1=2*l-t2;for(var i=0;i<3;i++){t3=h+1/3*-(i-1);t3<0&&t3++;t3>1&&t3--;if(t3*6<1){rgb[channels[i]]=t1+(t2-t1)*6*t3}else{if(t3*2<1){rgb[channels[i]]=t2}else{if(t3*3<2){rgb[channels[i]]=t1+(t2-t1)*(2/3-t3)*6}else{rgb[channels[i]]=t1}}}}}rgb.r*=255;rgb.g*=255;rgb.b*=255;rgb.hex="#"+(16777216|rgb.b|(rgb.g<<8)|(rgb.r<<16)).toString(16).slice(1);R.is(o,"finite")&&(rgb.opacity=o);rgb.toString=rgbtoString;return rgb};R.rgb2hsb=function(red,green,blue){if(green==null&&R.is(red,"object")&&"r" in red&&"g" in red&&"b" in red){blue=red.b;green=red.g;red=red.r}if(green==null&&R.is(red,string)){var clr=R.getRGB(red);red=clr.r;green=clr.g;blue=clr.b}if(red>1||green>1||blue>1){red/=255;green/=255;blue/=255}var max=mmax(red,green,blue),min=mmin(red,green,blue),hue,saturation,brightness=max;if(min==max){return{h:0,s:0,b:max,toString:hsbtoString}}else{var delta=(max-min);saturation=delta/max;if(red==max){hue=(green-blue)/delta}else{if(green==max){hue=2+((blue-red)/delta)}else{hue=4+((red-green)/delta)}}hue/=6;hue<0&&hue++;hue>1&&hue--}return{h:hue,s:saturation,b:brightness,toString:hsbtoString}};R.rgb2hsl=function(red,green,blue){if(green==null&&R.is(red,"object")&&"r" in red&&"g" in red&&"b" in red){blue=red.b;green=red.g;red=red.r}if(green==null&&R.is(red,string)){var clr=R.getRGB(red);red=clr.r;green=clr.g;blue=clr.b}if(red>1||green>1||blue>1){red/=255;green/=255;blue/=255}var max=mmax(red,green,blue),min=mmin(red,green,blue),h,s,l=(max+min)/2,hsl;if(min==max){hsl={h:0,s:0,l:l}}else{var delta=max-min;s=l<0.5?delta/(max+min):delta/(2-max-min);if(red==max){h=(green-blue)/delta}else{if(green==max){h=2+(blue-red)/delta}else{h=4+(red-green)/delta}}h/=6;h<0&&h++;h>1&&h--;hsl={h:h,s:s,l:l}}hsl.toString=hsltoString;return hsl};R._path2string=function(){return this.join(",")[rp](p2s,"$1")};function cacher(f,scope,postprocessor){function newf(){var arg=Array[proto].slice.call(arguments,0),args=arg[join]("\u25ba"),cache=newf.cache=newf.cache||{},count=newf.count=newf.count||[];if(cache[has](args)){return postprocessor?postprocessor(cache[args]):cache[args]}count[length]>=1000&&delete cache[count.shift()];count[push](args);cache[args]=f[apply](scope,arg);return postprocessor?postprocessor(cache[args]):cache[args]}return newf}R.getRGB=cacher(function(colour){if(!colour||!!((colour=Str(colour)).indexOf("-")+1)){return{r:-1,g:-1,b:-1,hex:"none",error:1}}if(colour=="none"){return{r:-1,g:-1,b:-1,hex:"none"}}!(hsrg[has](colour.toLowerCase().substring(0,2))||colour.charAt()=="#")&&(colour=toHex(colour));var res,red,green,blue,opacity,t,values,rgb=colour.match(colourRegExp);if(rgb){if(rgb[2]){blue=toInt(rgb[2].substring(5),16);green=toInt(rgb[2].substring(3,5),16);red=toInt(rgb[2].substring(1,3),16)}if(rgb[3]){blue=toInt((t=rgb[3].charAt(3))+t,16);green=toInt((t=rgb[3].charAt(2))+t,16);red=toInt((t=rgb[3].charAt(1))+t,16)}if(rgb[4]){values=rgb[4][split](commaSpaces);red=toFloat(values[0]);values[0].slice(-1)=="%"&&(red*=2.55);green=toFloat(values[1]);values[1].slice(-1)=="%"&&(green*=2.55);blue=toFloat(values[2]);values[2].slice(-1)=="%"&&(blue*=2.55);rgb[1].toLowerCase().slice(0,4)=="rgba"&&(opacity=toFloat(values[3]));values[3]&&values[3].slice(-1)=="%"&&(opacity/=100)}if(rgb[5]){values=rgb[5][split](commaSpaces);red=toFloat(values[0]);values[0].slice(-1)=="%"&&(red*=2.55);green=toFloat(values[1]);values[1].slice(-1)=="%"&&(green*=2.55);blue=toFloat(values[2]);values[2].slice(-1)=="%"&&(blue*=2.55);(values[0].slice(-3)=="deg"||values[0].slice(-1)=="\xb0")&&(red/=360);rgb[1].toLowerCase().slice(0,4)=="hsba"&&(opacity=toFloat(values[3]));values[3]&&values[3].slice(-1)=="%"&&(opacity/=100);return R.hsb2rgb(red,green,blue,opacity)}if(rgb[6]){values=rgb[6][split](commaSpaces);red=toFloat(values[0]);values[0].slice(-1)=="%"&&(red*=2.55);green=toFloat(values[1]);values[1].slice(-1)=="%"&&(green*=2.55);blue=toFloat(values[2]);values[2].slice(-1)=="%"&&(blue*=2.55);(values[0].slice(-3)=="deg"||values[0].slice(-1)=="\xb0")&&(red/=360);rgb[1].toLowerCase().slice(0,4)=="hsla"&&(opacity=toFloat(values[3]));values[3]&&values[3].slice(-1)=="%"&&(opacity/=100);return R.hsl2rgb(red,green,blue,opacity)}rgb={r:red,g:green,b:blue};rgb.hex="#"+(16777216|blue|(green<<8)|(red<<16)).toString(16).slice(1);R.is(opacity,"finite")&&(rgb.opacity=opacity);return rgb}return{r:-1,g:-1,b:-1,hex:"none",error:1}},R);R.getColor=function(value){var start=this.getColor.start=this.getColor.start||{h:0,s:1,b:value||0.75},rgb=this.hsb2rgb(start.h,start.s,start.b);start.h+=0.075;if(start.h>1){start.h=0;start.s-=0.2;start.s<=0&&(this.getColor.start={h:0,s:1,b:start.b})}return rgb.hex};R.getColor.reset=function(){delete this.start};R.parsePathString=cacher(function(pathString){if(!pathString){return null}var paramCounts={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},data=[];if(R.is(pathString,array)&&R.is(pathString[0],array)){data=pathClone(pathString)}if(!data[length]){Str(pathString)[rp](pathCommand,function(a,b,c){var params=[],name=lowerCase.call(b);c[rp](pathValues,function(a,b){b&&params[push](+b)});if(name=="m"&&params[length]>2){data[push]([b][concat](params.splice(0,2)));name="l";b=b=="m"?"l":"L"}while(params[length]>=paramCounts[name]){data[push]([b][concat](params.splice(0,paramCounts[name])));if(!paramCounts[name]){break}}})}data[toString]=R._path2string;return data});R.findDotsAtSegment=function(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t){var t1=1-t,x=pow(t1,3)*p1x+pow(t1,2)*3*t*c1x+t1*3*t*t*c2x+pow(t,3)*p2x,y=pow(t1,3)*p1y+pow(t1,2)*3*t*c1y+t1*3*t*t*c2y+pow(t,3)*p2y,mx=p1x+2*t*(c1x-p1x)+t*t*(c2x-2*c1x+p1x),my=p1y+2*t*(c1y-p1y)+t*t*(c2y-2*c1y+p1y),nx=c1x+2*t*(c2x-c1x)+t*t*(p2x-2*c2x+c1x),ny=c1y+2*t*(c2y-c1y)+t*t*(p2y-2*c2y+c1y),ax=(1-t)*p1x+t*c1x,ay=(1-t)*p1y+t*c1y,cx=(1-t)*c2x+t*p2x,cy=(1-t)*c2y+t*p2y,alpha=(90-math.atan((mx-nx)/(my-ny))*180/PI);(mx>nx||my<ny)&&(alpha+=180);return{x:x,y:y,m:{x:mx,y:my},n:{x:nx,y:ny},start:{x:ax,y:ay},end:{x:cx,y:cy},alpha:alpha}};var pathDimensions=cacher(function(path){if(!path){return{x:0,y:0,width:0,height:0}}path=path2curve(path);var x=0,y=0,X=[],Y=[],p;for(var i=0,ii=path[length];i<ii;i++){p=path[i];if(p[0]=="M"){x=p[1];y=p[2];X[push](x);Y[push](y)}else{var dim=curveDim(x,y,p[1],p[2],p[3],p[4],p[5],p[6]);X=X[concat](dim.min.x,dim.max.x);Y=Y[concat](dim.min.y,dim.max.y);x=p[5];y=p[6]}}var xmin=mmin[apply](0,X),ymin=mmin[apply](0,Y);return{x:xmin,y:ymin,width:mmax[apply](0,X)-xmin,height:mmax[apply](0,Y)-ymin}}),pathClone=function(pathArray){var res=[];if(!R.is(pathArray,array)||!R.is(pathArray&&pathArray[0],array)){pathArray=R.parsePathString(pathArray)}for(var i=0,ii=pathArray[length];i<ii;i++){res[i]=[];for(var j=0,jj=pathArray[i][length];j<jj;j++){res[i][j]=pathArray[i][j]}}res[toString]=R._path2string;return res},pathToRelative=cacher(function(pathArray){if(!R.is(pathArray,array)||!R.is(pathArray&&pathArray[0],array)){pathArray=R.parsePathString(pathArray)}var res=[],x=0,y=0,mx=0,my=0,start=0;if(pathArray[0][0]=="M"){x=pathArray[0][1];y=pathArray[0][2];mx=x;my=y;start++;res[push](["M",x,y])}for(var i=start,ii=pathArray[length];i<ii;i++){var r=res[i]=[],pa=pathArray[i];if(pa[0]!=lowerCase.call(pa[0])){r[0]=lowerCase.call(pa[0]);switch(r[0]){case"a":r[1]=pa[1];r[2]=pa[2];r[3]=pa[3];r[4]=pa[4];r[5]=pa[5];r[6]=+(pa[6]-x).toFixed(3);r[7]=+(pa[7]-y).toFixed(3);break;case"v":r[1]=+(pa[1]-y).toFixed(3);break;case"m":mx=pa[1];my=pa[2];default:for(var j=1,jj=pa[length];j<jj;j++){r[j]=+(pa[j]-((j%2)?x:y)).toFixed(3)}}}else{r=res[i]=[];if(pa[0]=="m"){mx=pa[1]+x;my=pa[2]+y}for(var k=0,kk=pa[length];k<kk;k++){res[i][k]=pa[k]}}var len=res[i][length];switch(res[i][0]){case"z":x=mx;y=my;break;case"h":x+=+res[i][len-1];break;case"v":y+=+res[i][len-1];break;default:x+=+res[i][len-2];y+=+res[i][len-1]}}res[toString]=R._path2string;return res},0,pathClone),pathToAbsolute=cacher(function(pathArray){if(!R.is(pathArray,array)||!R.is(pathArray&&pathArray[0],array)){pathArray=R.parsePathString(pathArray)}var res=[],x=0,y=0,mx=0,my=0,start=0;if(pathArray[0][0]=="M"){x=+pathArray[0][1];y=+pathArray[0][2];mx=x;my=y;start++;res[0]=["M",x,y]}for(var i=start,ii=pathArray[length];i<ii;i++){var r=res[i]=[],pa=pathArray[i];if(pa[0]!=upperCase.call(pa[0])){r[0]=upperCase.call(pa[0]);switch(r[0]){case"A":r[1]=pa[1];r[2]=pa[2];r[3]=pa[3];r[4]=pa[4];r[5]=pa[5];r[6]=+(pa[6]+x);r[7]=+(pa[7]+y);break;case"V":r[1]=+pa[1]+y;break;case"H":r[1]=+pa[1]+x;break;case"M":mx=+pa[1]+x;my=+pa[2]+y;default:for(var j=1,jj=pa[length];j<jj;j++){r[j]=+pa[j]+((j%2)?x:y)}}}else{for(var k=0,kk=pa[length];k<kk;k++){res[i][k]=pa[k]}}switch(r[0]){case"Z":x=mx;y=my;break;case"H":x=r[1];break;case"V":y=r[1];break;case"M":mx=res[i][res[i][length]-2];my=res[i][res[i][length]-1];default:x=res[i][res[i][length]-2];y=res[i][res[i][length]-1]}}res[toString]=R._path2string;return res},null,pathClone),l2c=function(x1,y1,x2,y2){return[x1,y1,x2,y2,x2,y2]},q2c=function(x1,y1,ax,ay,x2,y2){var _13=1/3,_23=2/3;return[_13*x1+_23*ax,_13*y1+_23*ay,_13*x2+_23*ax,_13*y2+_23*ay,x2,y2]},a2c=function(x1,y1,rx,ry,angle,large_arc_flag,sweep_flag,x2,y2,recursive){var _120=PI*120/180,rad=PI/180*(+angle||0),res=[],xy,rotate=cacher(function(x,y,rad){var X=x*math.cos(rad)-y*math.sin(rad),Y=x*math.sin(rad)+y*math.cos(rad);return{x:X,y:Y}});if(!recursive){xy=rotate(x1,y1,-rad);x1=xy.x;y1=xy.y;xy=rotate(x2,y2,-rad);x2=xy.x;y2=xy.y;var cos=math.cos(PI/180*angle),sin=math.sin(PI/180*angle),x=(x1-x2)/2,y=(y1-y2)/2;var h=(x*x)/(rx*rx)+(y*y)/(ry*ry);if(h>1){h=math.sqrt(h);rx=h*rx;ry=h*ry}var rx2=rx*rx,ry2=ry*ry,k=(large_arc_flag==sweep_flag?-1:1)*math.sqrt(abs((rx2*ry2-rx2*y*y-ry2*x*x)/(rx2*y*y+ry2*x*x))),cx=k*rx*y/ry+(x1+x2)/2,cy=k*-ry*x/rx+(y1+y2)/2,f1=math.asin(((y1-cy)/ry).toFixed(9)),f2=math.asin(((y2-cy)/ry).toFixed(9));f1=x1<cx?PI-f1:f1;f2=x2<cx?PI-f2:f2;f1<0&&(f1=PI*2+f1);f2<0&&(f2=PI*2+f2);if(sweep_flag&&f1>f2){f1=f1-PI*2}if(!sweep_flag&&f2>f1){f2=f2-PI*2}}else{f1=recursive[0];f2=recursive[1];cx=recursive[2];cy=recursive[3]}var df=f2-f1;if(abs(df)>_120){var f2old=f2,x2old=x2,y2old=y2;f2=f1+_120*(sweep_flag&&f2>f1?1:-1);x2=cx+rx*math.cos(f2);y2=cy+ry*math.sin(f2);res=a2c(x2,y2,rx,ry,angle,0,sweep_flag,x2old,y2old,[f2,f2old,cx,cy])}df=f2-f1;var c1=math.cos(f1),s1=math.sin(f1),c2=math.cos(f2),s2=math.sin(f2),t=math.tan(df/4),hx=4/3*rx*t,hy=4/3*ry*t,m1=[x1,y1],m2=[x1+hx*s1,y1-hy*c1],m3=[x2+hx*s2,y2-hy*c2],m4=[x2,y2];m2[0]=2*m1[0]-m2[0];m2[1]=2*m1[1]-m2[1];if(recursive){return[m2,m3,m4][concat](res)}else{res=[m2,m3,m4][concat](res)[join]()[split](",");var newres=[];for(var i=0,ii=res[length];i<ii;i++){newres[i]=i%2?rotate(res[i-1],res[i],rad).y:rotate(res[i],res[i+1],rad).x}return newres}},findDotAtSegment=function(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t){var t1=1-t;return{x:pow(t1,3)*p1x+pow(t1,2)*3*t*c1x+t1*3*t*t*c2x+pow(t,3)*p2x,y:pow(t1,3)*p1y+pow(t1,2)*3*t*c1y+t1*3*t*t*c2y+pow(t,3)*p2y}},curveDim=cacher(function(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y){var a=(c2x-2*c1x+p1x)-(p2x-2*c2x+c1x),b=2*(c1x-p1x)-2*(c2x-c1x),c=p1x-c1x,t1=(-b+math.sqrt(b*b-4*a*c))/2/a,t2=(-b-math.sqrt(b*b-4*a*c))/2/a,y=[p1y,p2y],x=[p1x,p2x],dot;abs(t1)>"1e12"&&(t1=0.5);abs(t2)>"1e12"&&(t2=0.5);if(t1>0&&t1<1){dot=findDotAtSegment(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t1);x[push](dot.x);y[push](dot.y)}if(t2>0&&t2<1){dot=findDotAtSegment(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t2);x[push](dot.x);y[push](dot.y)}a=(c2y-2*c1y+p1y)-(p2y-2*c2y+c1y);b=2*(c1y-p1y)-2*(c2y-c1y);c=p1y-c1y;t1=(-b+math.sqrt(b*b-4*a*c))/2/a;t2=(-b-math.sqrt(b*b-4*a*c))/2/a;abs(t1)>"1e12"&&(t1=0.5);abs(t2)>"1e12"&&(t2=0.5);if(t1>0&&t1<1){dot=findDotAtSegment(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t1);x[push](dot.x);y[push](dot.y)}if(t2>0&&t2<1){dot=findDotAtSegment(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,t2);x[push](dot.x);y[push](dot.y)}return{min:{x:mmin[apply](0,x),y:mmin[apply](0,y)},max:{x:mmax[apply](0,x),y:mmax[apply](0,y)}}}),path2curve=cacher(function(path,path2){var p=pathToAbsolute(path),p2=path2&&pathToAbsolute(path2),attrs={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},attrs2={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},processPath=function(path,d){var nx,ny;if(!path){return["C",d.x,d.y,d.x,d.y,d.x,d.y]}!(path[0] in {T:1,Q:1})&&(d.qx=d.qy=null);switch(path[0]){case"M":d.X=path[1];d.Y=path[2];break;case"A":path=["C"][concat](a2c[apply](0,[d.x,d.y][concat](path.slice(1))));break;case"S":nx=d.x+(d.x-(d.bx||d.x));ny=d.y+(d.y-(d.by||d.y));path=["C",nx,ny][concat](path.slice(1));break;case"T":d.qx=d.x+(d.x-(d.qx||d.x));d.qy=d.y+(d.y-(d.qy||d.y));path=["C"][concat](q2c(d.x,d.y,d.qx,d.qy,path[1],path[2]));break;case"Q":d.qx=path[1];d.qy=path[2];path=["C"][concat](q2c(d.x,d.y,path[1],path[2],path[3],path[4]));break;case"L":path=["C"][concat](l2c(d.x,d.y,path[1],path[2]));break;case"H":path=["C"][concat](l2c(d.x,d.y,path[1],d.y));break;case"V":path=["C"][concat](l2c(d.x,d.y,d.x,path[1]));break;case"Z":path=["C"][concat](l2c(d.x,d.y,d.X,d.Y));break}return path},fixArc=function(pp,i){if(pp[i][length]>7){pp[i].shift();var pi=pp[i];while(pi[length]){pp.splice(i++,0,["C"][concat](pi.splice(0,6)))}pp.splice(i,1);ii=mmax(p[length],p2&&p2[length]||0)}},fixM=function(path1,path2,a1,a2,i){if(path1&&path2&&path1[i][0]=="M"&&path2[i][0]!="M"){path2.splice(i,0,["M",a2.x,a2.y]);a1.bx=0;a1.by=0;a1.x=path1[i][1];a1.y=path1[i][2];ii=mmax(p[length],p2&&p2[length]||0)}};for(var i=0,ii=mmax(p[length],p2&&p2[length]||0);i<ii;i++){p[i]=processPath(p[i],attrs);fixArc(p,i);p2&&(p2[i]=processPath(p2[i],attrs2));p2&&fixArc(p2,i);fixM(p,p2,attrs,attrs2,i);fixM(p2,p,attrs2,attrs,i);var seg=p[i],seg2=p2&&p2[i],seglen=seg[length],seg2len=p2&&seg2[length];attrs.x=seg[seglen-2];attrs.y=seg[seglen-1];attrs.bx=toFloat(seg[seglen-4])||attrs.x;attrs.by=toFloat(seg[seglen-3])||attrs.y;attrs2.bx=p2&&(toFloat(seg2[seg2len-4])||attrs2.x);attrs2.by=p2&&(toFloat(seg2[seg2len-3])||attrs2.y);attrs2.x=p2&&seg2[seg2len-2];attrs2.y=p2&&seg2[seg2len-1]}return p2?[p,p2]:p},null,pathClone),parseDots=cacher(function(gradient){var dots=[];for(var i=0,ii=gradient[length];i<ii;i++){var dot={},par=gradient[i].match(/^([^:]*):?([\d\.]*)/);dot.color=R.getRGB(par[1]);if(dot.color.error){return null}dot.color=dot.color.hex;par[2]&&(dot.offset=par[2]+"%");dots[push](dot)}for(i=1,ii=dots[length]-1;i<ii;i++){if(!dots[i].offset){var start=toFloat(dots[i-1].offset||0),end=0;for(var j=i+1;j<ii;j++){if(dots[j].offset){end=dots[j].offset;break}}if(!end){end=100;j=ii}end=toFloat(end);var d=(end-start)/(j-i+1);for(;i<j;i++){start+=d;dots[i].offset=start+"%"}}}return dots}),getContainer=function(x,y,w,h){var container;if(R.is(x,string)||R.is(x,"object")){container=R.is(x,string)?doc.getElementById(x):x;if(container.tagName){if(y==null){return{container:container,width:container.style.pixelWidth||container.offsetWidth,height:container.style.pixelHeight||container.offsetHeight}}else{return{container:container,width:y,height:w}}}}else{return{container:1,x:x,y:y,width:w,height:h}}},plugins=function(con,add){var that=this;for(var prop in add){if(add[has](prop)&&!(prop in con)){switch(typeof add[prop]){case"function":(function(f){con[prop]=con===that?f:function(){return f[apply](that,arguments)}})(add[prop]);break;case"object":con[prop]=con[prop]||{};plugins.call(this,con[prop],add[prop]);break;default:con[prop]=add[prop];break}}}},tear=function(el,paper){el==paper.top&&(paper.top=el.prev);el==paper.bottom&&(paper.bottom=el.next);el.next&&(el.next.prev=el.prev);el.prev&&(el.prev.next=el.next)},tofront=function(el,paper){if(paper.top===el){return}tear(el,paper);el.next=null;el.prev=paper.top;paper.top.next=el;paper.top=el},toback=function(el,paper){if(paper.bottom===el){return}tear(el,paper);el.next=paper.bottom;el.prev=null;paper.bottom.prev=el;paper.bottom=el},insertafter=function(el,el2,paper){tear(el,paper);el2==paper.top&&(paper.top=el);el2.next&&(el2.next.prev=el);el.next=el2.next;el.prev=el2;el2.next=el},insertbefore=function(el,el2,paper){tear(el,paper);el2==paper.bottom&&(paper.bottom=el);el2.prev&&(el2.prev.next=el);el.prev=el2.prev;el2.prev=el;el.next=el2},removed=function(methodname){return function(){throw new Error("Rapha\xebl: you are calling to method \u201c"+methodname+"\u201d of removed object")}};R.pathToRelative=pathToRelative;if(R.svg){paperproto.svgns="http://www.w3.org/2000/svg";paperproto.xlink="http://www.w3.org/1999/xlink";round=function(num){return +num+(~~num===num)*0.5};var $=function(el,attr){if(attr){for(var key in attr){if(attr[has](key)){el[setAttribute](key,Str(attr[key]))}}}else{el=doc.createElementNS(paperproto.svgns,el);el.style.webkitTapHighlightColor="rgba(0,0,0,0)";return el}};R[toString]=function(){return"Your browser supports SVG.\nYou are running Rapha\xebl "+this.version};var thePath=function(pathString,SVG){var el=$("path");SVG.canvas&&SVG.canvas[appendChild](el);var p=new Element(el,SVG);p.type="path";setFillAndStroke(p,{fill:"none",stroke:"#000",path:pathString});return p};var addGradientFill=function(o,gradient,SVG){var type="linear",fx=0.5,fy=0.5,s=o.style;gradient=Str(gradient)[rp](radial_gradient,function(all,_fx,_fy){type="radial";if(_fx&&_fy){fx=toFloat(_fx);fy=toFloat(_fy);var dir=((fy>0.5)*2-1);pow(fx-0.5,2)+pow(fy-0.5,2)>0.25&&(fy=math.sqrt(0.25-pow(fx-0.5,2))*dir+0.5)&&fy!=0.5&&(fy=fy.toFixed(5)-0.00001*dir)}return E});gradient=gradient[split](/\s*\-\s*/);if(type=="linear"){var angle=gradient.shift();angle=-toFloat(angle);if(isNaN(angle)){return null}var vector=[0,0,math.cos(angle*PI/180),math.sin(angle*PI/180)],max=1/(mmax(abs(vector[2]),abs(vector[3]))||1);vector[2]*=max;vector[3]*=max;if(vector[2]<0){vector[0]=-vector[2];vector[2]=0}if(vector[3]<0){vector[1]=-vector[3];vector[3]=0}}var dots=parseDots(gradient);if(!dots){return null}var id=o.getAttribute(fillString);id=id.match(/^url\(#(.*)\)$/);id&&SVG.defs.removeChild(doc.getElementById(id[1]));var el=$(type+"Gradient");el.id=createUUID();$(el,type=="radial"?{fx:fx,fy:fy}:{x1:vector[0],y1:vector[1],x2:vector[2],y2:vector[3]});SVG.defs[appendChild](el);for(var i=0,ii=dots[length];i<ii;i++){var stop=$("stop");$(stop,{offset:dots[i].offset?dots[i].offset:!i?"0%":"100%","stop-color":dots[i].color||"#fff"});el[appendChild](stop)}$(o,{fill:"url(#"+el.id+")",opacity:1,"fill-opacity":1});s.fill=E;s.opacity=1;s.fillOpacity=1;return 1};var updatePosition=function(o){var bbox=o.getBBox();$(o.pattern,{patternTransform:R.format("translate({0},{1})",bbox.x,bbox.y)})};var setFillAndStroke=function(o,params){var dasharray={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},node=o.node,attrs=o.attrs,rot=o.rotate(),addDashes=function(o,value){value=dasharray[lowerCase.call(value)];if(value){var width=o.attrs["stroke-width"]||"1",butt={round:width,square:width,butt:0}[o.attrs["stroke-linecap"]||params["stroke-linecap"]]||0,dashes=[];var i=value[length];while(i--){dashes[i]=value[i]*width+((i%2)?1:-1)*butt}$(node,{"stroke-dasharray":dashes[join](",")})}};params[has]("rotation")&&(rot=params.rotation);var rotxy=Str(rot)[split](separator);if(!(rotxy.length-1)){rotxy=null}else{rotxy[1]=+rotxy[1];rotxy[2]=+rotxy[2]}toFloat(rot)&&o.rotate(0,true);for(var att in params){if(params[has](att)){if(!availableAttrs[has](att)){continue}var value=params[att];attrs[att]=value;switch(att){case"blur":o.blur(value);break;case"rotation":o.rotate(value,true);break;case"href":case"title":case"target":var pn=node.parentNode;if(lowerCase.call(pn.tagName)!="a"){var hl=$("a");pn.insertBefore(hl,node);hl[appendChild](node);pn=hl}if(att=="target"&&value=="blank"){pn.setAttributeNS(o.paper.xlink,"show","new")}else{pn.setAttributeNS(o.paper.xlink,att,value)}break;case"cursor":node.style.cursor=value;break;case"clip-rect":var rect=Str(value)[split](separator);if(rect[length]==4){o.clip&&o.clip.parentNode.parentNode.removeChild(o.clip.parentNode);var el=$("clipPath"),rc=$("rect");el.id=createUUID();$(rc,{x:rect[0],y:rect[1],width:rect[2],height:rect[3]});el[appendChild](rc);o.paper.defs[appendChild](el);$(node,{"clip-path":"url(#"+el.id+")"});o.clip=rc}if(!value){var clip=doc.getElementById(node.getAttribute("clip-path")[rp](/(^url\(#|\)$)/g,E));clip&&clip.parentNode.removeChild(clip);$(node,{"clip-path":E});delete o.clip}break;case"path":if(o.type=="path"){$(node,{d:value?attrs.path=pathToAbsolute(value):"M0,0"})}break;case"width":node[setAttribute](att,value);if(attrs.fx){att="x";value=attrs.x}else{break}case"x":if(attrs.fx){value=-attrs.x-(attrs.width||0)}case"rx":if(att=="rx"&&o.type=="rect"){break}case"cx":rotxy&&(att=="x"||att=="cx")&&(rotxy[1]+=value-attrs[att]);node[setAttribute](att,value);o.pattern&&updatePosition(o);break;case"height":node[setAttribute](att,value);if(attrs.fy){att="y";value=attrs.y}else{break}case"y":if(attrs.fy){value=-attrs.y-(attrs.height||0)}case"ry":if(att=="ry"&&o.type=="rect"){break}case"cy":rotxy&&(att=="y"||att=="cy")&&(rotxy[2]+=value-attrs[att]);node[setAttribute](att,value);o.pattern&&updatePosition(o);break;case"r":if(o.type=="rect"){$(node,{rx:value,ry:value})}else{node[setAttribute](att,value)}break;case"src":if(o.type=="image"){node.setAttributeNS(o.paper.xlink,"href",value)}break;case"stroke-width":node.style.strokeWidth=value;node[setAttribute](att,value);if(attrs["stroke-dasharray"]){addDashes(o,attrs["stroke-dasharray"])}break;case"stroke-dasharray":addDashes(o,value);break;case"translation":var xy=Str(value)[split](separator);xy[0]=+xy[0]||0;xy[1]=+xy[1]||0;if(rotxy){rotxy[1]+=xy[0];rotxy[2]+=xy[1]}translate.call(o,xy[0],xy[1]);break;case"scale":xy=Str(value)[split](separator);o.scale(+xy[0]||1,+xy[1]||+xy[0]||1,isNaN(toFloat(xy[2]))?null:+xy[2],isNaN(toFloat(xy[3]))?null:+xy[3]);break;case fillString:var isURL=Str(value).match(ISURL);if(isURL){el=$("pattern");var ig=$("image");el.id=createUUID();$(el,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});$(ig,{x:0,y:0});ig.setAttributeNS(o.paper.xlink,"href",isURL[1]);el[appendChild](ig);var img=doc.createElement("img");img.style.cssText="position:absolute;left:-9999em;top-9999em";img.onload=function(){$(el,{width:this.offsetWidth,height:this.offsetHeight});$(ig,{width:this.offsetWidth,height:this.offsetHeight});doc.body.removeChild(this);o.paper.safari()};doc.body[appendChild](img);img.src=isURL[1];o.paper.defs[appendChild](el);node.style.fill="url(#"+el.id+")";$(node,{fill:"url(#"+el.id+")"});o.pattern=el;o.pattern&&updatePosition(o);break}var clr=R.getRGB(value);if(!clr.error){delete params.gradient;delete attrs.gradient;!R.is(attrs.opacity,"undefined")&&R.is(params.opacity,"undefined")&&$(node,{opacity:attrs.opacity});!R.is(attrs["fill-opacity"],"undefined")&&R.is(params["fill-opacity"],"undefined")&&$(node,{"fill-opacity":attrs["fill-opacity"]})}else{if((({circle:1,ellipse:1})[has](o.type)||Str(value).charAt()!="r")&&addGradientFill(node,value,o.paper)){attrs.gradient=value;attrs.fill="none";break}}clr[has]("opacity")&&$(node,{"fill-opacity":clr.opacity>1?clr.opacity/100:clr.opacity});case"stroke":clr=R.getRGB(value);node[setAttribute](att,clr.hex);att=="stroke"&&clr[has]("opacity")&&$(node,{"stroke-opacity":clr.opacity>1?clr.opacity/100:clr.opacity});break;case"gradient":(({circle:1,ellipse:1})[has](o.type)||Str(value).charAt()!="r")&&addGradientFill(node,value,o.paper);break;case"opacity":if(attrs.gradient&&!attrs[has]("stroke-opacity")){$(node,{"stroke-opacity":value>1?value/100:value})}case"fill-opacity":if(attrs.gradient){var gradient=doc.getElementById(node.getAttribute(fillString)[rp](/^url\(#|\)$/g,E));if(gradient){var stops=gradient.getElementsByTagName("stop");stops[stops[length]-1][setAttribute]("stop-opacity",value)}break}default:att=="font-size"&&(value=toInt(value,10)+"px");var cssrule=att[rp](/(\-.)/g,function(w){return upperCase.call(w.substring(1))});node.style[cssrule]=value;node[setAttribute](att,value);break}}}tuneText(o,params);if(rotxy){o.rotate(rotxy.join(S))}else{toFloat(rot)&&o.rotate(rot,true)}};var leading=1.2,tuneText=function(el,params){if(el.type!="text"||!(params[has]("text")||params[has]("font")||params[has]("font-size")||params[has]("x")||params[has]("y"))){return}var a=el.attrs,node=el.node,fontSize=node.firstChild?toInt(doc.defaultView.getComputedStyle(node.firstChild,E).getPropertyValue("font-size"),10):10;if(params[has]("text")){a.text=params.text;while(node.firstChild){node.removeChild(node.firstChild)}var texts=Str(params.text)[split]("\n");for(var i=0,ii=texts[length];i<ii;i++){if(texts[i]){var tspan=$("tspan");i&&$(tspan,{dy:fontSize*leading,x:a.x});tspan[appendChild](doc.createTextNode(texts[i]));node[appendChild](tspan)}}}else{texts=node.getElementsByTagName("tspan");for(i=0,ii=texts[length];i<ii;i++){i&&$(texts[i],{dy:fontSize*leading,x:a.x})}}$(node,{y:a.y});var bb=el.getBBox(),dif=a.y-(bb.y+bb.height/2);dif&&R.is(dif,"finite")&&$(node,{y:a.y+dif})},Element=function(node,svg){var X=0,Y=0;this[0]=node;this.id=R._oid++;this.node=node;node.raphael=this;this.paper=svg;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!svg.bottom&&(svg.bottom=this);this.prev=svg.top;svg.top&&(svg.top.next=this);svg.top=this;this.next=null};var elproto=Element[proto];Element[proto].rotate=function(deg,cx,cy){if(this.removed){return this}if(deg==null){if(this._.rt.cx){return[this._.rt.deg,this._.rt.cx,this._.rt.cy][join](S)}return this._.rt.deg}var bbox=this.getBBox();deg=Str(deg)[split](separator);if(deg[length]-1){cx=toFloat(deg[1]);cy=toFloat(deg[2])}deg=toFloat(deg[0]);if(cx!=null&&cx!==false){this._.rt.deg=deg}else{this._.rt.deg+=deg}(cy==null)&&(cx=null);this._.rt.cx=cx;this._.rt.cy=cy;cx=cx==null?bbox.x+bbox.width/2:cx;cy=cy==null?bbox.y+bbox.height/2:cy;if(this._.rt.deg){this.transformations[0]=R.format("rotate({0} {1} {2})",this._.rt.deg,cx,cy);this.clip&&$(this.clip,{transform:R.format("rotate({0} {1} {2})",-this._.rt.deg,cx,cy)})}else{this.transformations[0]=E;this.clip&&$(this.clip,{transform:E})}$(this.node,{transform:this.transformations[join](S)});return this};Element[proto].hide=function(){!this.removed&&(this.node.style.display="none");return this};Element[proto].show=function(){!this.removed&&(this.node.style.display="");return this};Element[proto].remove=function(){if(this.removed){return}tear(this,this.paper);this.node.parentNode.removeChild(this.node);for(var i in this){delete this[i]}this.removed=true};Element[proto].getBBox=function(){if(this.removed){return this}if(this.type=="path"){return pathDimensions(this.attrs.path)}if(this.node.style.display=="none"){this.show();var hide=true}var bbox={};var Browser={Version:function(){var version=999;if(navigator.appVersion.indexOf("MSIE")!=-1){version=parseFloat(navigator.appVersion.split("MSIE")[1])}return version}};try{bbox=this.node.getBBox();var operaFix=false;if(/Opera/.test(navigator.userAgent)){operaFix=true;for(var el in bbox){if(bbox[el]!=0){operaFix=false;break}}}if(((Browser.Version()==9||navigator.userAgent.match("Chrome")||/Konqueror|Safari|KHTML/.test(navigator.userAgent))&&(this.type!="text"))||operaFix){bbox={x:this.attrs.x,y:this.attrs.y,width:this.attrs.width,height:this.attrs.height}}}catch(e){bbox={x:this.attrs.x,y:this.attrs.y,width:this.attrs.width,height:this.attrs.height}}finally{bbox=bbox||{}}if((Browser.Version()<7)&&(this.type=="text")){bbox={x:bbox.x,y:Infinity,width:0,height:0};for(var i=0,ii=this.node.getNumberOfChars();i<ii;i++){var bb=this.node.getExtentOfChar(i);(bb.y<bbox.y)&&(bbox.y=bb.y);(bb.y+bb.height-bbox.y>bbox.height)&&(bbox.height=bb.y+bb.height-bbox.y);(bb.x+bb.width-bbox.x>bbox.width)&&(bbox.width=bb.x+bb.width-bbox.x)}}hide&&this.hide();return bbox};Element[proto].attr=function(name,value){if(this.removed){return this}if(name==null){var res={};for(var i in this.attrs){if(this.attrs[has](i)){res[i]=this.attrs[i]}}this._.rt.deg&&(res.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(res.scale=this.scale());res.gradient&&res.fill=="none"&&(res.fill=res.gradient)&&delete res.gradient;return res}if(value==null&&R.is(name,string)){if(name=="translation"){return translate.call(this)}if(name=="rotation"){return this.rotate()}if(name=="scale"){return this.scale()}if(name==fillString&&this.attrs.fill=="none"&&this.attrs.gradient){return this.attrs.gradient}return this.attrs[name]}if(value==null&&R.is(name,array)){var values={};for(var j=0,jj=name.length;j<jj;j++){values[name[j]]=this.attr(name[j])}return values}if(value!=null){var params={};params[name]=value}else{if(name!=null&&R.is(name,"object")){params=name}}for(var key in this.paper.customAttributes){if(this.paper.customAttributes[has](key)&&params[has](key)&&R.is(this.paper.customAttributes[key],"function")){var par=this.paper.customAttributes[key].apply(this,[][concat](params[key]));this.attrs[key]=params[key];for(var subkey in par){if(par[has](subkey)){params[subkey]=par[subkey]}}}}setFillAndStroke(this,params);return this};Element[proto].toFront=function(){if(this.removed){return this}this.node.parentNode[appendChild](this.node);var svg=this.paper;svg.top!=this&&tofront(this,svg);return this};Element[proto].toBack=function(){if(this.removed){return this}if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);toback(this,this.paper);var svg=this.paper}return this};Element[proto].insertAfter=function(element){if(this.removed){return this}var node=element.node||element[element.length-1].node;if(node.nextSibling){node.parentNode.insertBefore(this.node,node.nextSibling)}else{node.parentNode[appendChild](this.node)}insertafter(this,element,this.paper);return this};Element[proto].insertBefore=function(element){if(this.removed){return this}var node=element.node||element[0].node;node.parentNode.insertBefore(this.node,node);insertbefore(this,element,this.paper);return this};Element[proto].blur=function(size){var t=this;if(+size!==0){var fltr=$("filter"),blur=$("feGaussianBlur");t.attrs.blur=size;fltr.id=createUUID();$(blur,{stdDeviation:+size||1.5});fltr.appendChild(blur);t.paper.defs.appendChild(fltr);t._blur=fltr;$(t.node,{filter:"url(#"+fltr.id+")"})}else{if(t._blur){t._blur.parentNode.removeChild(t._blur);delete t._blur;delete t.attrs.blur}t.node.removeAttribute("filter")}};var theCircle=function(svg,x,y,r){var el=$("circle");svg.canvas&&svg.canvas[appendChild](el);var res=new Element(el,svg);res.attrs={cx:x,cy:y,r:r,fill:"none",stroke:"#000"};res.type="circle";$(el,res.attrs);return res},theRect=function(svg,x,y,w,h,r){var el=$("rect");svg.canvas&&svg.canvas[appendChild](el);var res=new Element(el,svg);res.attrs={x:x,y:y,width:w,height:h,r:r||0,rx:r||0,ry:r||0,fill:"none",stroke:"#000"};res.type="rect";$(el,res.attrs);return res},theEllipse=function(svg,x,y,rx,ry){var el=$("ellipse");svg.canvas&&svg.canvas[appendChild](el);var res=new Element(el,svg);res.attrs={cx:x,cy:y,rx:rx,ry:ry,fill:"none",stroke:"#000"};res.type="ellipse";$(el,res.attrs);return res},theImage=function(svg,src,x,y,w,h,aspRatio){var el=$("image");aspRatio=(aspRatio==undefined||aspRatio==0||aspRatio=="")?"none":aspRatio;$(el,{x:x,y:y,width:w,height:h,preserveAspectRatio:aspRatio});el.setAttributeNS(svg.xlink,"href",src);svg.canvas&&svg.canvas[appendChild](el);var res=new Element(el,svg);res.attrs={x:x,y:y,width:w,height:h,src:src,preserveAspectRatio:aspRatio};res.type="image";return res},theText=function(svg,x,y,text){var el=$("text");$(el,{x:x,y:y,"text-anchor":"middle"});svg.canvas&&svg.canvas[appendChild](el);var res=new Element(el,svg);res.attrs={x:x,y:y,"text-anchor":"middle",text:text,font:availableAttrs.font,stroke:"none",fill:"#000"};res.type="text";setFillAndStroke(res,res.attrs);return res},setSize=function(width,height){this.width=width||this.width;this.height=height||this.height;this.canvas[setAttribute]("width",this.width);this.canvas[setAttribute]("height",this.height);return this},create=function(){var con=getContainer[apply](0,arguments),container=con&&con.container,x=con.x,y=con.y,width=con.width,height=con.height;if(!container){throw new Error("SVG container not found.")}var cnvs=$("svg");x=x||0;y=y||0;width=width||512;height=height||342;$(cnvs,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:width,height:height});if(container==1){cnvs.style.cssText="position:absolute;left:"+x+"px;top:"+y+"px";doc.body[appendChild](cnvs)}else{if(container.firstChild){container.insertBefore(cnvs,container.firstChild)}else{container[appendChild](cnvs)}}container=new Paper;container.width=width;container.height=height;container.canvas=cnvs;plugins.call(container,container,R.fn);container.clear();return container};paperproto.clear=function(){var c=this.canvas;while(c.firstChild){c.removeChild(c.firstChild)}this.bottom=this.top=null;(this.desc=$("desc"))[appendChild](doc.createTextNode("Created with Rapha\xebl"));c[appendChild](this.desc);c[appendChild](this.defs=$("defs"))};paperproto.remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var i in this){this[i]=removed(i)}}}if(R.vml){var map={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},bites=/([clmz]),?([^clmz]*)/gi,blurregexp=/ progid:\S+Blur\([^\)]+\)/g,val=/-?[^,\s-]+/g,coordsize=1000+S+1000,zoom=10,pathlike={path:1,rect:1},path2vml=function(path){var total=/[ahqstv]/ig,command=pathToAbsolute;Str(path).match(total)&&(command=path2curve);total=/[clmz]/g;if(command==pathToAbsolute&&!Str(path).match(total)){var res=Str(path)[rp](bites,function(all,command,args){var vals=[],isMove=lowerCase.call(command)=="m",res=map[command];args[rp](val,function(value){if(isMove&&vals[length]==2){res+=vals+map[command=="m"?"l":"L"];vals=[]}vals[push](round(value*zoom))});return res+vals});return res}var pa=command(path),p,r;res=[];for(var i=0,ii=pa[length];i<ii;i++){p=pa[i];r=lowerCase.call(pa[i][0]);r=="z"&&(r="x");for(var j=1,jj=p[length];j<jj;j++){r+=round(p[j]*zoom)+(j!=jj-1?",":E)}res[push](r)}return res[join](S)};R[toString]=function(){return"Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl "+this.version};thePath=function(pathString,vml){var g=createNode("group");g.style.cssText="position:absolute;left:0;top:0;width:"+vml.width+"px;height:"+vml.height+"px";g.coordsize=vml.coordsize;g.coordorigin=vml.coordorigin;var el=createNode("shape"),ol=el.style;ol.width=vml.width+"px";ol.height=vml.height+"px";el.coordsize=coordsize;el.coordorigin=vml.coordorigin;g[appendChild](el);var p=new Element(el,g,vml),attr={fill:"none",stroke:"#000"};pathString&&(attr.path=pathString);p.type="path";p.path=[];p.Path=E;setFillAndStroke(p,attr);vml.canvas[appendChild](g);return p};setFillAndStroke=function(o,params){o.attrs=o.attrs||{};var node=o.node,a=o.attrs,s=node.style,xy,newpath=(params.x!=a.x||params.y!=a.y||params.width!=a.width||params.height!=a.height||params.r!=a.r)&&o.type=="rect",res=o;for(var par in params){if(params[has](par)){a[par]=params[par]}}if(newpath){a.path=rectPath(a.x,a.y,a.width,a.height,a.r);o.X=a.x;o.Y=a.y;o.W=a.width;o.H=a.height}params.href&&(node.href=params.href);params.title&&(node.title=params.title);params.target&&(node.target=params.target);params.cursor&&(s.cursor=params.cursor);"blur" in params&&o.blur(params.blur);if(params.path&&o.type=="path"||newpath){node.path=path2vml(a.path)}if(params.rotation!=null){o.rotate(params.rotation,true)}if(params.translation){xy=Str(params.translation)[split](separator);translate.call(o,xy[0],xy[1]);if(o._.rt.cx!=null){o._.rt.cx+=+xy[0];o._.rt.cy+=+xy[1];o.setBox(o.attrs,xy[0],xy[1])}}if(params.scale){xy=Str(params.scale)[split](separator);o.scale(+xy[0]||1,+xy[1]||+xy[0]||1,+xy[2]||null,+xy[3]||null)}if("clip-rect" in params){var rect=Str(params["clip-rect"])[split](separator);if(rect[length]==4){rect[2]=+rect[2]+(+rect[0]);rect[3]=+rect[3]+(+rect[1]);var div=node.clipRect||doc.createElement("div"),dstyle=div.style,group=node.parentNode;dstyle.clip=R.format("rect({1}px {2}px {3}px {0}px)",rect);if(!node.clipRect){dstyle.position="absolute";dstyle.top=0;dstyle.left=0;dstyle.width=o.paper.width+"px";dstyle.height=o.paper.height+"px";group.parentNode.insertBefore(div,group);div[appendChild](group);node.clipRect=div}}if(!params["clip-rect"]){node.clipRect&&(node.clipRect.style.clip=E)}}if(o.type=="image"&&params.src){node.src=params.src}if(o.type=="image"&&params.opacity){node.filterOpacity=ms+".Alpha(opacity="+(params.opacity*100)+")";s.filter=(node.filterMatrix||E)+(node.filterOpacity||E)}params.font&&(s.font=params.font);params["font-family"]&&(s.fontFamily='"'+params["font-family"][split](",")[0][rp](/^['"]+|['"]+$/g,E)+'"');params["font-size"]&&(s.fontSize=params["font-size"]);params["font-weight"]&&(s.fontWeight=params["font-weight"]);params["font-style"]&&(s.fontStyle=params["font-style"]);if(params.opacity!=null||params["stroke-width"]!=null||params.fill!=null||params.stroke!=null||params["stroke-width"]!=null||params["stroke-opacity"]!=null||params["fill-opacity"]!=null||params["stroke-dasharray"]!=null||params["stroke-miterlimit"]!=null||params["stroke-linejoin"]!=null||params["stroke-linecap"]!=null){node=o.shape||node;var fill=(node.getElementsByTagName(fillString)&&node.getElementsByTagName(fillString)[0]),newfill=false;!fill&&(newfill=fill=createNode(fillString));if("fill-opacity" in params||"opacity" in params){var opacity=((+a["fill-opacity"]+1||2)-1)*((+a.opacity+1||2)-1)*((+R.getRGB(params.fill).o+1||2)-1);opacity=mmin(mmax(opacity,0),1);fill.opacity=opacity}params.fill&&(fill.on=true);if(fill.on==null||params.fill=="none"){fill.on=false}if(fill.on&&params.fill){var isURL=params.fill.match(ISURL);if(isURL){fill.src=isURL[1];fill.type="tile"}else{fill.color=R.getRGB(params.fill).hex;fill.src=E;fill.type="solid";if(R.getRGB(params.fill).error&&(res.type in {circle:1,ellipse:1}||Str(params.fill).charAt()!="r")&&addGradientFill(res,params.fill)){a.fill="none";a.gradient=params.fill}}}newfill&&node[appendChild](fill);var stroke=(node.getElementsByTagName("stroke")&&node.getElementsByTagName("stroke")[0]),newstroke=false;!stroke&&(newstroke=stroke=createNode("stroke"));if((params.stroke&&params.stroke!="none")||params["stroke-width"]||params["stroke-opacity"]!=null||params["stroke-dasharray"]||params["stroke-miterlimit"]||params["stroke-linejoin"]||params["stroke-linecap"]){stroke.on=true}(params.stroke=="none"||stroke.on==null||params.stroke==0||params["stroke-width"]==0)&&(stroke.on=false);var strokeColor=R.getRGB(params.stroke);stroke.on&&params.stroke&&(stroke.color=strokeColor.hex);opacity=((+a["stroke-opacity"]+1||2)-1)*((+a.opacity+1||2)-1)*((+strokeColor.o+1||2)-1);var width=(toFloat(params["stroke-width"])||1)*0.75;opacity=mmin(mmax(opacity,0),1);params["stroke-width"]==null&&(width=a["stroke-width"]);params["stroke-width"]&&(stroke.weight=width);width&&width<1&&(opacity*=width)&&(stroke.weight=1);stroke.opacity=opacity;params["stroke-linejoin"]&&(stroke.joinstyle=params["stroke-linejoin"]||"miter");stroke.miterlimit=params["stroke-miterlimit"]||8;params["stroke-linecap"]&&(stroke.endcap=params["stroke-linecap"]=="butt"?"flat":params["stroke-linecap"]=="square"?"square":"round");if(params["stroke-dasharray"]){var dasharray={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};stroke.dashstyle=dasharray[has](params["stroke-dasharray"])?dasharray[params["stroke-dasharray"]]:E}newstroke&&node[appendChild](stroke)}if(res.type=="text"){s=res.paper.span.style;a.font&&(s.font=a.font);a["font-family"]&&(s.fontFamily=a["font-family"]);a["font-size"]&&(s.fontSize=a["font-size"]);a["font-weight"]&&(s.fontWeight=a["font-weight"]);a["font-style"]&&(s.fontStyle=a["font-style"]);res.node.string&&(res.paper.span.innerHTML=Str(res.node.string)[rp](/</g,"&#60;")[rp](/&/g,"&#38;")[rp](/\n/g,"<br>"));res.W=a.w=res.paper.span.offsetWidth;res.H=a.h=res.paper.span.offsetHeight;res.X=a.x;res.Y=a.y+round(res.H/2);switch(a["text-anchor"]){case"start":res.node.style["v-text-align"]="left";res.bbx=round(res.W/2);break;case"end":res.node.style["v-text-align"]="right";res.bbx=-round(res.W/2);break;default:res.node.style["v-text-align"]="center";break}}};addGradientFill=function(o,gradient){o.attrs=o.attrs||{};var attrs=o.attrs,fill,type="linear",fxfy=".5 .5";o.attrs.gradient=gradient;gradient=Str(gradient)[rp](radial_gradient,function(all,fx,fy){type="radial";if(fx&&fy){fx=toFloat(fx);fy=toFloat(fy);pow(fx-0.5,2)+pow(fy-0.5,2)>0.25&&(fy=math.sqrt(0.25-pow(fx-0.5,2))*((fy>0.5)*2-1)+0.5);fxfy=fx+S+fy}return E});gradient=gradient[split](/\s*\-\s*/);if(type=="linear"){var angle=gradient.shift();angle=-toFloat(angle);if(isNaN(angle)){return null}}var dots=parseDots(gradient);if(!dots){return null}o=o.shape||o.node;fill=o.getElementsByTagName(fillString)[0]||createNode(fillString);!fill.parentNode&&o.appendChild(fill);if(dots[length]){fill.on=true;fill.method="none";fill.color=dots[0].color;fill.color2=dots[dots[length]-1].color;var clrs=[];for(var i=0,ii=dots[length];i<ii;i++){dots[i].offset&&clrs[push](dots[i].offset+S+dots[i].color)}fill.colors&&(fill.colors.value=clrs[length]?clrs[join]():"0% "+fill.color);if(type=="radial"){fill.type="gradientradial";fill.focus="100%";fill.focussize=fxfy;fill.focusposition=fxfy}else{fill.type="gradient";fill.angle=(270-angle)%360}}return 1};Element=function(node,group,vml){var Rotation=0,RotX=0,RotY=0,Scale=1;this[0]=node;this.id=R._oid++;this.node=node;node.raphael=this;this.X=0;this.Y=0;this.attrs={};this.Group=group;this.paper=vml;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!vml.bottom&&(vml.bottom=this);this.prev=vml.top;vml.top&&(vml.top.next=this);vml.top=this;this.next=null};elproto=Element[proto];elproto.rotate=function(deg,cx,cy){if(this.removed){return this}if(deg==null){if(this._.rt.cx){return[this._.rt.deg,this._.rt.cx,this._.rt.cy][join](S)}return this._.rt.deg}deg=Str(deg)[split](separator);if(deg[length]-1){cx=toFloat(deg[1]);cy=toFloat(deg[2])}deg=toFloat(deg[0]);if(cx!=null){this._.rt.deg=deg}else{this._.rt.deg+=deg}cy==null&&(cx=null);this._.rt.cx=cx;this._.rt.cy=cy;this.setBox(this.attrs,cx,cy);this.Group.style.rotation=this._.rt.deg;return this};elproto.setBox=function(params,cx,cy){if(this.removed){return this}var gs=this.Group.style,os=(this.shape&&this.shape.style)||this.node.style;params=params||{};for(var i in params){if(params[has](i)){this.attrs[i]=params[i]}}cx=cx||this._.rt.cx;cy=cy||this._.rt.cy;var attr=this.attrs,x,y,w,h;switch(this.type){case"circle":x=attr.cx-attr.r;y=attr.cy-attr.r;w=h=attr.r*2;break;case"ellipse":x=attr.cx-attr.rx;y=attr.cy-attr.ry;w=attr.rx*2;h=attr.ry*2;break;case"image":x=+attr.x;y=+attr.y;w=attr.width||0;h=attr.height||0;break;case"text":this.textpath.v=["m",round(attr.x),", ",round(attr.y-2),"l",round(attr.x)+1,", ",round(attr.y-2)][join](E);x=attr.x-round(this.W/2);y=attr.y-this.H/2;w=this.W;h=this.H;break;case"rect":case"path":if(!this.attrs.path){x=0;y=0;w=this.paper.width;h=this.paper.height}else{var dim=pathDimensions(this.attrs.path);x=dim.x;y=dim.y;w=dim.width;h=dim.height}break;default:x=0;y=0;w=this.paper.width;h=this.paper.height;break}cx=(cx==null)?x+w/2:cx;cy=(cy==null)?y+h/2:cy;var left=cx-this.paper.width/2,top=cy-this.paper.height/2,t;gs.left!=(t=left+"px")&&(gs.left=t);gs.top!=(t=top+"px")&&(gs.top=t);this.X=pathlike[has](this.type)?-left:x;this.Y=pathlike[has](this.type)?-top:y;this.W=w;this.H=h;if(pathlike[has](this.type)){os.left!=(t=-left*zoom+"px")&&(os.left=t);os.top!=(t=-top*zoom+"px")&&(os.top=t)}else{if(this.type=="text"){os.left!=(t=-left+"px")&&(os.left=t);os.top!=(t=-top+"px")&&(os.top=t)}else{gs.width!=(t=this.paper.width+"px")&&(gs.width=t);gs.height!=(t=this.paper.height+"px")&&(gs.height=t);os.left!=(t=x-left+"px")&&(os.left=t);os.top!=(t=y-top+"px")&&(os.top=t);os.width!=(t=w+"px")&&(os.width=t);os.height!=(t=h+"px")&&(os.height=t)}}};elproto.hide=function(){!this.removed&&(this.Group.style.display="none");return this};elproto.show=function(){!this.removed&&(this.Group.style.display="block");return this};elproto.getBBox=function(){if(this.removed){return this}if(pathlike[has](this.type)){return pathDimensions(this.attrs.path)}return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H}};elproto.remove=function(){if(this.removed){return}tear(this,this.paper);this.node.parentNode.removeChild(this.node);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);for(var i in this){delete this[i]}this.removed=true};elproto.attr=function(name,value){if(this.removed){return this}if(name==null){var res={};for(var i in this.attrs){if(this.attrs[has](i)){res[i]=this.attrs[i]}}this._.rt.deg&&(res.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(res.scale=this.scale());res.gradient&&res.fill=="none"&&(res.fill=res.gradient)&&delete res.gradient;return res}if(value==null&&R.is(name,"string")){if(name=="translation"){return translate.call(this)}if(name=="rotation"){return this.rotate()}if(name=="scale"){return this.scale()}if(name==fillString&&this.attrs.fill=="none"&&this.attrs.gradient){return this.attrs.gradient}return this.attrs[name]}if(this.attrs&&value==null&&R.is(name,array)){var ii,values={};for(i=0,ii=name[length];i<ii;i++){values[name[i]]=this.attr(name[i])}return values}var params;if(value!=null){params={};params[name]=value}value==null&&R.is(name,"object")&&(params=name);if(params){for(var key in this.paper.customAttributes){if(this.paper.customAttributes[has](key)&&params[has](key)&&R.is(this.paper.customAttributes[key],"function")){var par=this.paper.customAttributes[key].apply(this,[][concat](params[key]));this.attrs[key]=params[key];for(var subkey in par){if(par[has](subkey)){params[subkey]=par[subkey]}}}}if(params.text&&this.type=="text"){this.node.string=params.text}setFillAndStroke(this,params);if(params.gradient&&(({circle:1,ellipse:1})[has](this.type)||Str(params.gradient).charAt()!="r")){addGradientFill(this,params.gradient)}(!pathlike[has](this.type)||this._.rt.deg)&&this.setBox(this.attrs)}return this};elproto.toFront=function(){!this.removed&&this.Group.parentNode[appendChild](this.Group);this.paper.top!=this&&tofront(this,this.paper);return this};elproto.toBack=function(){if(this.removed){return this}if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);toback(this,this.paper)}return this};elproto.insertAfter=function(element){if(this.removed){return this}if(element.constructor==Set){element=element[element.length-1]}if(element.Group.nextSibling){element.Group.parentNode.insertBefore(this.Group,element.Group.nextSibling)}else{element.Group.parentNode[appendChild](this.Group)}insertafter(this,element,this.paper);return this};elproto.insertBefore=function(element){if(this.removed){return this}if(element.constructor==Set){element=element[0]}element.Group.parentNode.insertBefore(this.Group,element.Group);insertbefore(this,element,this.paper);return this};elproto.blur=function(size){var s=this.node.runtimeStyle,f=s.filter;f=f.replace(blurregexp,E);if(+size!==0){this.attrs.blur=size;s.filter=f+S+ms+".Blur(pixelradius="+(+size||1.5)+")";s.margin=R.format("-{0}px 0 0 -{0}px",round(+size||1.5))}else{s.filter=f;s.margin=0;delete this.attrs.blur}};theCircle=function(vml,x,y,r){var g=createNode("group"),o=createNode("oval"),ol=o.style;g.style.cssText="position:absolute;left:0;top:0;width:"+vml.width+"px;height:"+vml.height+"px";g.coordsize=coordsize;g.coordorigin=vml.coordorigin;g[appendChild](o);var res=new Element(o,g,vml);res.type="circle";setFillAndStroke(res,{stroke:"#000",fill:"none"});res.attrs.cx=x;res.attrs.cy=y;res.attrs.r=r;res.setBox({x:x-r,y:y-r,width:r*2,height:r*2});vml.canvas[appendChild](g);return res};function rectPath(x,y,w,h,r){if(r){return R.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z",x+r,y,w-r*2,r,-r,h-r*2,r*2-w,r*2-h)}else{return R.format("M{0},{1}l{2},0,0,{3},{4},0z",x,y,w,h,-w)}}theRect=function(vml,x,y,w,h,r){var path=rectPath(x,y,w,h,r),res=vml.path(path),a=res.attrs;res.X=a.x=x;res.Y=a.y=y;res.W=a.width=w;res.H=a.height=h;a.r=r;a.path=path;res.type="rect";return res};theEllipse=function(vml,x,y,rx,ry){var g=createNode("group"),o=createNode("oval"),ol=o.style;g.style.cssText="position:absolute;left:0;top:0;width:"+vml.width+"px;height:"+vml.height+"px";g.coordsize=coordsize;g.coordorigin=vml.coordorigin;g[appendChild](o);var res=new Element(o,g,vml);res.type="ellipse";setFillAndStroke(res,{stroke:"#000"});res.attrs.cx=x;res.attrs.cy=y;res.attrs.rx=rx;res.attrs.ry=ry;res.setBox({x:x-rx,y:y-ry,width:rx*2,height:ry*2});vml.canvas[appendChild](g);return res};theImage=function(vml,src,x,y,w,h,aspRatio){aspRatio=(aspRatio==undefined||aspRatio==0||aspRatio=="")?"none":aspRatio;var g=createNode("group"),o=createNode("image");g.style.cssText="position:absolute;left:0;top:0;width:"+vml.width+"px;height:"+vml.height+"px";g.coordsize=coordsize;g.coordorigin=vml.coordorigin;o.src=src;g[appendChild](o);var res=new Element(o,g,vml);res.type="image";res.attrs.src=src;res.attrs.x=x;res.attrs.y=y;res.attrs.w=w;res.attrs.h=h;res.attrs.preserveAspectRatio=aspRatio;res.setBox({x:x,y:y,width:w,height:h});vml.canvas[appendChild](g);return res};theText=function(vml,x,y,text){var g=createNode("group"),el=createNode("shape"),ol=el.style,path=createNode("path"),ps=path.style,o=createNode("textpath");g.style.cssText="position:absolute;left:0;top:0;width:"+vml.width+"px;height:"+vml.height+"px";g.coordsize=coordsize;g.coordorigin=vml.coordorigin;path.v=R.format("m{0},{1}l{2},{1}",round(x*10),round(y*10),round(x*10)+1);path.textpathok=true;ol.width=vml.width;ol.height=vml.height;o.string=Str(text);o.on=true;el[appendChild](o);el[appendChild](path);g[appendChild](el);var res=new Element(o,g,vml);res.shape=el;res.textpath=path;res.type="text";res.attrs.text=text;res.attrs.x=x;res.attrs.y=y;res.attrs.w=1;res.attrs.h=1;setFillAndStroke(res,{font:availableAttrs.font,stroke:"none",fill:"#000"});res.setBox();vml.canvas[appendChild](g);return res};setSize=function(width,height){var cs=this.canvas.style;width==+width&&(width+="px");height==+height&&(height+="px");cs.width=width;cs.height=height;cs.clip="rect(0 "+width+" "+height+" 0)";return this};var createNode;doc.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!doc.namespaces.rvml&&doc.namespaces.add("rvml","urn:schemas-microsoft-com:vml");createNode=function(tagName){return doc.createElement("<rvml:"+tagName+' class="rvml">')}}catch(e){createNode=function(tagName){return doc.createElement("<"+tagName+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}create=function(){var con=getContainer[apply](0,arguments),container=con.container,height=con.height,s,width=con.width,x=con.x,y=con.y;if(!container){throw new Error("VML container not found.")}var res=new Paper,c=res.canvas=doc.createElement("div"),cs=c.style;x=x||0;y=y||0;width=width||512;height=height||342;width==+width&&(width+="px");height==+height&&(height+="px");res.width=1000;res.height=1000;res.coordsize=zoom*1000+S+zoom*1000;res.coordorigin="0 0";res.span=doc.createElement("span");res.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";c[appendChild](res.span);cs.cssText=R.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",width,height);if(container==1){doc.body[appendChild](c);cs.left=x+"px";cs.top=y+"px";cs.position="absolute"}else{if(container.firstChild){container.insertBefore(c,container.firstChild)}else{container[appendChild](c)}}plugins.call(res,res,R.fn);return res};paperproto.clear=function(){this.canvas.innerHTML=E;this.span=doc.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[appendChild](this.span);this.bottom=this.top=null};paperproto.remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var i in this){this[i]=removed(i)}return true}}var version=navigator.userAgent.match(/Version\/(.*?)\s/);if((navigator.vendor=="Apple Computer, Inc.")&&(version&&version[1]<4||navigator.platform.slice(0,2)=="iP")){paperproto.safari=function(){var rect=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});win.setTimeout(function(){rect.remove()})}}else{paperproto.safari=function(){}}var preventDefault=function(){this.returnValue=false},preventTouch=function(){return this.originalEvent.preventDefault()},stopPropagation=function(){this.cancelBubble=true},stopTouch=function(){return this.originalEvent.stopPropagation()},addEvent=(function(){if(doc.addEventListener){return function(obj,type,fn,element){var realName=supportsTouch&&touchMap[type]?touchMap[type]:type;var f=function(e){if(supportsTouch&&touchMap[has](type)){for(var i=0,ii=e.targetTouches&&e.targetTouches.length;i<ii;i++){if(e.targetTouches[i].target==obj){var olde=e;e=e.targetTouches[i];e.originalEvent=olde;e.preventDefault=preventTouch;e.stopPropagation=stopTouch;break}}}return fn.call(element,e)};obj.addEventListener(realName,f,false);return function(){obj.removeEventListener(realName,f,false);return true}}}else{if(doc.attachEvent){return function(obj,type,fn,element){var f=function(e){e=e||win.event;e.preventDefault=e.preventDefault||preventDefault;e.stopPropagation=e.stopPropagation||stopPropagation;return fn.call(element,e)};obj.attachEvent("on"+type,f);var detacher=function(){obj.detachEvent("on"+type,f);return true};return detacher}}}})(),drag=[],dragMove=function(e){var x=e.clientX,y=e.clientY,scrollY=doc.documentElement.scrollTop||doc.body.scrollTop,scrollX=doc.documentElement.scrollLeft||doc.body.scrollLeft,dragi,j=drag.length;while(j--){dragi=drag[j];if(supportsTouch){var i=e.touches.length,touch;while(i--){touch=e.touches[i];if(touch.identifier==dragi.el._drag.id){x=touch.clientX;y=touch.clientY;(e.originalEvent?e.originalEvent:e).preventDefault();break}}}else{e.preventDefault()}x+=scrollX;y+=scrollY;dragi.move&&dragi.move.call(dragi.move_scope||dragi.el,x-dragi.el._drag.x,y-dragi.el._drag.y,x,y,e)}},dragUp=function(e){R.unmousemove(dragMove).unmouseup(dragUp);var i=drag.length,dragi;while(i--){dragi=drag[i];dragi.el._drag={};dragi.end&&dragi.end.call(dragi.end_scope||dragi.start_scope||dragi.move_scope||dragi.el,e)}drag=[]};for(var i=events[length];i--;){(function(eventName){R[eventName]=Element[proto][eventName]=function(fn,scope){if(R.is(fn,"function")){this.events=this.events||[];this.events.push({name:eventName,f:fn,unbind:addEvent(this.shape||this.node||doc,eventName,fn,scope||this)})}return this};R["un"+eventName]=Element[proto]["un"+eventName]=function(fn){var events=this.events,l=events[length];while(l--){if(events[l].name==eventName&&events[l].f==fn){events[l].unbind();events.splice(l,1);!events.length&&delete this.events;return this}}return this}})(events[i])}elproto.hover=function(f_in,f_out,scope_in,scope_out){return this.mouseover(f_in,scope_in).mouseout(f_out,scope_out||scope_in)};elproto.unhover=function(f_in,f_out){return this.unmouseover(f_in).unmouseout(f_out)};elproto.drag=function(onmove,onstart,onend,move_scope,start_scope,end_scope){this._drag={};this.mousedown(function(e){(e.originalEvent||e).preventDefault();var scrollY=doc.documentElement.scrollTop||doc.body.scrollTop,scrollX=doc.documentElement.scrollLeft||doc.body.scrollLeft;this._drag.x=e.clientX+scrollX;this._drag.y=e.clientY+scrollY;this._drag.id=e.identifier;onstart&&onstart.call(start_scope||move_scope||this,e.clientX+scrollX,e.clientY+scrollY,e);!drag.length&&R.mousemove(dragMove).mouseup(dragUp);drag.push({el:this,move:onmove,end:onend,move_scope:move_scope,start_scope:start_scope,end_scope:end_scope})});return this};elproto.undrag=function(onmove,onstart,onend){var i=drag.length;while(i--){drag[i].el==this&&(drag[i].move==onmove&&drag[i].end==onend)&&drag.splice(i++,1)}!drag.length&&R.unmousemove(dragMove).unmouseup(dragUp)};paperproto.circle=function(x,y,r){return theCircle(this,x||0,y||0,r||0)};paperproto.rect=function(x,y,w,h,r){return theRect(this,x||0,y||0,w||0,h||0,r||0)};paperproto.ellipse=function(x,y,rx,ry){return theEllipse(this,x||0,y||0,rx||0,ry||0)};paperproto.path=function(pathString){pathString&&!R.is(pathString,string)&&!R.is(pathString[0],array)&&(pathString+=E);return thePath(R.format[apply](R,arguments),this)};paperproto.image=function(src,x,y,w,h,aspRatio){return theImage(this,src||"about:blank",x||0,y||0,w||0,h||0,aspRatio||"none")};paperproto.text=function(x,y,text){return theText(this,x||0,y||0,Str(text))};paperproto.set=function(itemsArray){arguments[length]>1&&(itemsArray=Array[proto].splice.call(arguments,0,arguments[length]));return new Set(itemsArray)};paperproto.setSize=setSize;paperproto.top=paperproto.bottom=null;paperproto.raphael=R;function x_y(){return this.x+S+this.y}elproto.resetScale=function(){if(this.removed){return this}this._.sx=1;this._.sy=1;this.attrs.scale="1 1"};elproto.scale=function(x,y,cx,cy){if(this.removed){return this}if(x==null&&y==null){return{x:this._.sx,y:this._.sy,toString:x_y}}y=y||x;!+y&&(y=x);var dx,dy,dcx,dcy,a=this.attrs;if(x!=0){var bb=this.getBBox(),rcx=bb.x+bb.width/2,rcy=bb.y+bb.height/2,kx=abs(x/this._.sx),ky=abs(y/this._.sy);cx=(+cx||cx==0)?cx:rcx;cy=(+cy||cy==0)?cy:rcy;var posx=this._.sx>0,posy=this._.sy>0,dirx=~~(x/abs(x)),diry=~~(y/abs(y)),dkx=kx*dirx,dky=ky*diry,s=this.node.style,ncx=cx+abs(rcx-cx)*dkx*(rcx>cx==posx?1:-1),ncy=cy+abs(rcy-cy)*dky*(rcy>cy==posy?1:-1),fr=(x*dirx>y*diry?ky:kx);switch(this.type){case"rect":case"image":var neww=a.width*kx,newh=a.height*ky;this.attr({height:newh,r:a.r*fr,width:neww,x:ncx-neww/2,y:ncy-newh/2});break;case"circle":case"ellipse":this.attr({rx:a.rx*kx,ry:a.ry*ky,r:a.r*fr,cx:ncx,cy:ncy});break;case"text":this.attr({x:ncx,y:ncy});break;case"path":var path=pathToRelative(a.path),skip=true,fx=posx?dkx:kx,fy=posy?dky:ky;for(var i=0,ii=path[length];i<ii;i++){var p=path[i],P0=upperCase.call(p[0]);if(P0=="M"&&skip){continue}else{skip=false}if(P0=="A"){p[path[i][length]-2]*=fx;p[path[i][length]-1]*=fy;p[1]*=kx;p[2]*=ky;p[5]=+(dirx+diry?!!+p[5]:!+p[5])}else{if(P0=="H"){for(var j=1,jj=p[length];j<jj;j++){p[j]*=fx}}else{if(P0=="V"){for(j=1,jj=p[length];j<jj;j++){p[j]*=fy}}else{for(j=1,jj=p[length];j<jj;j++){p[j]*=(j%2)?fx:fy}}}}}var dim2=pathDimensions(path);dx=ncx-dim2.x-dim2.width/2;dy=ncy-dim2.y-dim2.height/2;path[0][1]+=dx;path[0][2]+=dy;this.attr({path:path});break}if(this.type in {text:1,image:1}&&(dirx!=1||diry!=1)){if(this.transformations){this.transformations[2]="scale("[concat](dirx,",",diry,")");this.node[setAttribute]("transform",this.transformations[join](S));dx=(dirx==-1)?-a.x-(neww||0):a.x;dy=(diry==-1)?-a.y-(newh||0):a.y;this.attr({x:dx,y:dy});a.fx=dirx-1;a.fy=diry-1}else{this.node.filterMatrix=ms+".Matrix(M11="[concat](dirx,", M12=0, M21=0, M22=",diry,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");s.filter=(this.node.filterMatrix||E)+(this.node.filterOpacity||E)}}else{if(this.transformations){this.transformations[2]=E;this.node[setAttribute]("transform",this.transformations[join](S));a.fx=0;a.fy=0}else{this.node.filterMatrix=E;s.filter=(this.node.filterMatrix||E)+(this.node.filterOpacity||E)}}a.scale=[x,y,cx,cy][join](S);this._.sx=x;this._.sy=y}return this};elproto.clone=function(){if(this.removed){return null}var attr=this.attr();delete attr.scale;delete attr.translation;return this.paper[this.type]().attr(attr)};var curveslengths={},getPointAtSegmentLength=function(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,length){var len=0,precision=100,name=[p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y].join(),cache=curveslengths[name],old,dot;!cache&&(curveslengths[name]=cache={data:[]});cache.timer&&clearTimeout(cache.timer);cache.timer=setTimeout(function(){delete curveslengths[name]},2000);if(length!=null){var total=getPointAtSegmentLength(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y);precision=~~total*10}for(var i=0;i<precision+1;i++){if(cache.data[length]>i){dot=cache.data[i*precision]}else{dot=R.findDotsAtSegment(p1x,p1y,c1x,c1y,c2x,c2y,p2x,p2y,i/precision);cache.data[i]=dot}i&&(len+=pow(pow(old.x-dot.x,2)+pow(old.y-dot.y,2),0.5));if(length!=null&&len>=length){return dot}old=dot}if(length==null){return len}},getLengthFactory=function(istotal,subpath){return function(path,length,onlystart){path=path2curve(path);var x,y,p,l,sp="",subpaths={},point,len=0;for(var i=0,ii=path.length;i<ii;i++){p=path[i];if(p[0]=="M"){x=+p[1];y=+p[2]}else{l=getPointAtSegmentLength(x,y,p[1],p[2],p[3],p[4],p[5],p[6]);if(len+l>length){if(subpath&&!subpaths.start){point=getPointAtSegmentLength(x,y,p[1],p[2],p[3],p[4],p[5],p[6],length-len);sp+=["C",point.start.x,point.start.y,point.m.x,point.m.y,point.x,point.y];if(onlystart){return sp}subpaths.start=sp;sp=["M",point.x,point.y+"C",point.n.x,point.n.y,point.end.x,point.end.y,p[5],p[6]][join]();len+=l;x=+p[5];y=+p[6];continue}if(!istotal&&!subpath){point=getPointAtSegmentLength(x,y,p[1],p[2],p[3],p[4],p[5],p[6],length-len);return{x:point.x,y:point.y,alpha:point.alpha}}}len+=l;x=+p[5];y=+p[6]}sp+=p}subpaths.end=sp;point=istotal?len:subpath?subpaths:R.findDotsAtSegment(x,y,p[1],p[2],p[3],p[4],p[5],p[6],1);point.alpha&&(point={x:point.x,y:point.y,alpha:point.alpha});return point}};var getTotalLength=getLengthFactory(1),getPointAtLength=getLengthFactory(),getSubpathsAtLength=getLengthFactory(0,1);elproto.getTotalLength=function(){if(this.type!="path"){return}if(this.node.getTotalLength){return this.node.getTotalLength()}return getTotalLength(this.attrs.path)};elproto.getPointAtLength=function(length){if(this.type!="path"){return}return getPointAtLength(this.attrs.path,length)};elproto.getSubpath=function(from,to){if(this.type!="path"){return}if(abs(this.getTotalLength()-to)<"1e-6"){return getSubpathsAtLength(this.attrs.path,from).end}var a=getSubpathsAtLength(this.attrs.path,to,1);return from?getSubpathsAtLength(a,from).end:a};R.easing_formulas={linear:function(n){return n},"<":function(n){return pow(n,3)},">":function(n){return pow(n-1,3)+1},"<>":function(n){n=n*2;if(n<1){return pow(n,3)/2}n-=2;return(pow(n,3)+2)/2},backIn:function(n){var s=1.70158;return n*n*((s+1)*n-s)},backOut:function(n){n=n-1;var s=1.70158;return n*n*((s+1)*n+s)+1},elastic:function(n){if(n==0||n==1){return n}var p=0.3,s=p/4;return pow(2,-10*n)*math.sin((n-s)*(2*PI)/p)+1},bounce:function(n){var s=7.5625,p=2.75,l;if(n<(1/p)){l=s*n*n}else{if(n<(2/p)){n-=(1.5/p);l=s*n*n+0.75}else{if(n<(2.5/p)){n-=(2.25/p);l=s*n*n+0.9375}else{n-=(2.625/p);l=s*n*n+0.984375}}}return l}};var animationElements=[],animation=function(){var Now=+new Date;for(var l=0;l<animationElements[length];l++){var e=animationElements[l];if(e.stop||e.el.removed){continue}var time=Now-e.start,ms=e.ms,easing=e.easing,from=e.from,diff=e.diff,to=e.to,t=e.t,that=e.el,set={},now;if(time<ms){var pos=easing(time/ms);for(var attr in from){if(from[has](attr)){switch(availableAnimAttrs[attr]){case"along":now=pos*ms*diff[attr];to.back&&(now=to.len-now);var point=getPointAtLength(to[attr],now);that.translate(diff.sx-diff.x||0,diff.sy-diff.y||0);diff.x=point.x;diff.y=point.y;that.translate(point.x-diff.sx,point.y-diff.sy);to.rot&&that.rotate(diff.r+point.alpha,point.x,point.y);break;case nu:now=+from[attr]+pos*ms*diff[attr];break;case"colour":now="rgb("+[upto255(round(from[attr].r+pos*ms*diff[attr].r)),upto255(round(from[attr].g+pos*ms*diff[attr].g)),upto255(round(from[attr].b+pos*ms*diff[attr].b))][join](",")+")";break;case"path":now=[];for(var i=0,ii=from[attr][length];i<ii;i++){now[i]=[from[attr][i][0]];for(var j=1,jj=from[attr][i][length];j<jj;j++){now[i][j]=+from[attr][i][j]+pos*ms*diff[attr][i][j]}now[i]=now[i][join](S)}now=now[join](S);break;case"csv":switch(attr){case"translation":var x=pos*ms*diff[attr][0]-t.x,y=pos*ms*diff[attr][1]-t.y;t.x+=x;t.y+=y;now=x+S+y;break;case"rotation":now=+from[attr][0]+pos*ms*diff[attr][0];from[attr][1]&&(now+=","+from[attr][1]+","+from[attr][2]);break;case"scale":now=[+from[attr][0]+pos*ms*diff[attr][0],+from[attr][1]+pos*ms*diff[attr][1],(2 in to[attr]?to[attr][2]:E),(3 in to[attr]?to[attr][3]:E)][join](S);break;case"clip-rect":now=[];i=4;while(i--){now[i]=+from[attr][i]+pos*ms*diff[attr][i]}break}break;default:var from2=[].concat(from[attr]);now=[];i=that.paper.customAttributes[attr].length;while(i--){now[i]=+from2[i]+pos*ms*diff[attr][i]}break}set[attr]=now}}that.attr(set);that._run&&that._run.call(that)}else{if(to.along){point=getPointAtLength(to.along,to.len*!to.back);that.translate(diff.sx-(diff.x||0)+point.x-diff.sx,diff.sy-(diff.y||0)+point.y-diff.sy);to.rot&&that.rotate(diff.r+point.alpha,point.x,point.y)}(t.x||t.y)&&that.translate(-t.x,-t.y);to.scale&&(to.scale+=E);that.attr(to);animationElements.splice(l--,1)}}R.svg&&that&&that.paper&&that.paper.safari();animationElements[length]&&setTimeout(animation)},keyframesRun=function(attr,element,time,prev,prevcallback){var dif=time-prev;element.timeouts.push(setTimeout(function(){R.is(prevcallback,"function")&&prevcallback.call(element);element.animate(attr,dif,attr.easing)},prev))},upto255=function(color){return mmax(mmin(color,255),0)},translate=function(x,y){if(x==null){return{x:this._.tx,y:this._.ty,toString:x_y}}this._.tx+=+x;this._.ty+=+y;switch(this.type){case"circle":case"ellipse":this.attr({cx:+x+this.attrs.cx,cy:+y+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+x+this.attrs.x,y:+y+this.attrs.y});break;case"path":var path=pathToRelative(this.attrs.path);path[0][1]+=+x;path[0][2]+=+y;this.attr({path:path});break}return this};elproto.animateWith=function(element,params,ms,easing,callback){for(var i=0,ii=animationElements.length;i<ii;i++){if(animationElements[i].el.id==element.id){params.start=animationElements[i].start}}return this.animate(params,ms,easing,callback)};elproto.animateAlong=along();elproto.animateAlongBack=along(1);function along(isBack){return function(path,ms,rotate,callback){var params={back:isBack};R.is(rotate,"function")?(callback=rotate):(params.rot=rotate);path&&path.constructor==Element&&(path=path.attrs.path);path&&(params.along=path);return this.animate(params,ms,callback)}}function CubicBezierAtTime(t,p1x,p1y,p2x,p2y,duration){var cx=3*p1x,bx=3*(p2x-p1x)-cx,ax=1-cx-bx,cy=3*p1y,by=3*(p2y-p1y)-cy,ay=1-cy-by;function sampleCurveX(t){return((ax*t+bx)*t+cx)*t}function solve(x,epsilon){var t=solveCurveX(x,epsilon);return((ay*t+by)*t+cy)*t}function solveCurveX(x,epsilon){var t0,t1,t2,x2,d2,i;for(t2=x,i=0;i<8;i++){x2=sampleCurveX(t2)-x;if(abs(x2)<epsilon){return t2}d2=(3*ax*t2+2*bx)*t2+cx;if(abs(d2)<0.000001){break}t2=t2-x2/d2}t0=0;t1=1;t2=x;if(t2<t0){return t0}if(t2>t1){return t1}while(t0<t1){x2=sampleCurveX(t2);if(abs(x2-x)<epsilon){return t2}if(x>x2){t0=t2}else{t1=t2}t2=(t1-t0)/2+t0}return t2}return solve(t,1/(200*duration))}elproto.onAnimation=function(f){this._run=f||0;return this};elproto.animate=function(params,ms,easing,callback){var element=this;element.timeouts=element.timeouts||[];if(R.is(easing,"function")||!easing){callback=easing||null}if(element.removed){callback&&callback.call(element);return element}var from={},to={},animateable=false,diff={};for(var attr in params){if(params[has](attr)){if(availableAnimAttrs[has](attr)||element.paper.customAttributes[has](attr)){animateable=true;from[attr]=element.attr(attr);(from[attr]==null)&&(from[attr]=availableAttrs[attr]);to[attr]=params[attr];switch(availableAnimAttrs[attr]){case"along":var len=getTotalLength(params[attr]);var point=getPointAtLength(params[attr],len*!!params.back);var bb=element.getBBox();diff[attr]=len/ms;diff.tx=bb.x;diff.ty=bb.y;diff.sx=point.x;diff.sy=point.y;to.rot=params.rot;to.back=params.back;to.len=len;params.rot&&(diff.r=toFloat(element.rotate())||0);break;case nu:diff[attr]=(to[attr]-from[attr])/ms;break;case"colour":from[attr]=R.getRGB(from[attr]);var toColour=R.getRGB(to[attr]);diff[attr]={r:(toColour.r-from[attr].r)/ms,g:(toColour.g-from[attr].g)/ms,b:(toColour.b-from[attr].b)/ms};break;case"path":var pathes=path2curve(from[attr],to[attr]);from[attr]=pathes[0];var toPath=pathes[1];diff[attr]=[];for(var i=0,ii=from[attr][length];i<ii;i++){diff[attr][i]=[0];for(var j=1,jj=from[attr][i][length];j<jj;j++){diff[attr][i][j]=(toPath[i][j]-from[attr][i][j])/ms}}break;case"csv":var values=Str(params[attr])[split](separator),from2=Str(from[attr])[split](separator);switch(attr){case"translation":from[attr]=[0,0];diff[attr]=[values[0]/ms,values[1]/ms];break;case"rotation":from[attr]=(from2[1]==values[1]&&from2[2]==values[2])?from2:[0,values[1],values[2]];diff[attr]=[(values[0]-from[attr][0])/ms,0,0];break;case"scale":params[attr]=values;from[attr]=Str(from[attr])[split](separator);diff[attr]=[(values[0]-from[attr][0])/ms,(values[1]-from[attr][1])/ms,0,0];break;case"clip-rect":from[attr]=Str(from[attr])[split](separator);diff[attr]=[];i=4;while(i--){diff[attr][i]=(values[i]-from[attr][i])/ms}break}to[attr]=values;break;default:values=[].concat(params[attr]);from2=[].concat(from[attr]);diff[attr]=[];i=element.paper.customAttributes[attr][length];while(i--){diff[attr][i]=((values[i]||0)-(from2[i]||0))/ms}break}}}}if(!animateable){var attrs=[],lastcall;for(var key in params){if(params[has](key)&&animKeyFrames.test(key)){attr={value:params[key]};key=="from"&&(key=0);key=="to"&&(key=100);attr.key=toInt(key,10);attrs.push(attr)}}attrs.sort(sortByKey);if(attrs[0].key){attrs.unshift({key:0,value:element.attrs})}for(i=0,ii=attrs[length];i<ii;i++){keyframesRun(attrs[i].value,element,ms/100*attrs[i].key,ms/100*(attrs[i-1]&&attrs[i-1].key||0),attrs[i-1]&&attrs[i-1].value.callback)}lastcall=attrs[attrs[length]-1].value.callback;if(lastcall){element.timeouts.push(setTimeout(function(){lastcall.call(element)},ms))}}else{var easyeasy=R.easing_formulas[easing];if(!easyeasy){easyeasy=Str(easing).match(bezierrg);if(easyeasy&&easyeasy[length]==5){var curve=easyeasy;easyeasy=function(t){return CubicBezierAtTime(t,+curve[1],+curve[2],+curve[3],+curve[4],ms)}}else{easyeasy=function(t){return t}}}animationElements.push({start:params.start||+new Date,ms:ms,easing:easyeasy,from:from,diff:diff,to:to,el:element,t:{x:0,y:0}});R.is(callback,"function")&&(element._ac=setTimeout(function(){callback.call(element)},ms));animationElements[length]==1&&setTimeout(animation)}return this};elproto.stop=function(){for(var i=0;i<animationElements.length;i++){animationElements[i].el.id==this.id&&animationElements.splice(i--,1)}for(i=0,ii=this.timeouts&&this.timeouts.length;i<ii;i++){clearTimeout(this.timeouts[i])}this.timeouts=[];clearTimeout(this._ac);delete this._ac;return this};elproto.translate=function(x,y){return this.attr({translation:x+" "+y})};elproto[toString]=function(){return"Rapha\xebl\u2019s object"};R.ae=animationElements;var Set=function(items){this.items=[];this[length]=0;this.type="set";if(items){for(var i=0,ii=items[length];i<ii;i++){if(items[i]&&(items[i].constructor==Element||items[i].constructor==Set)){this[this.items[length]]=this.items[this.items[length]]=items[i];this[length]++}}}};Set[proto][push]=function(){var item,len;for(var i=0,ii=arguments[length];i<ii;i++){item=arguments[i];if(item&&(item.constructor==Element||item.constructor==Set)){len=this.items[length];this[len]=this.items[len]=item;this[length]++}}return this};Set[proto].pop=function(){delete this[this[length]--];return this.items.pop()};for(var method in elproto){if(elproto[has](method)){Set[proto][method]=(function(methodname){return function(){for(var i=0,ii=this.items[length];i<ii;i++){this.items[i][methodname][apply](this.items[i],arguments)}return this}})(method)}}Set[proto].attr=function(name,value){if(name&&R.is(name,array)&&R.is(name[0],"object")){for(var j=0,jj=name[length];j<jj;j++){this.items[j].attr(name[j])}}else{for(var i=0,ii=this.items[length];i<ii;i++){this.items[i].attr(name,value)}}return this};Set[proto].animate=function(params,ms,easing,callback){(R.is(easing,"function")||!easing)&&(callback=easing||null);var len=this.items[length],i=len,item,set=this,collector;callback&&(collector=function(){!--len&&callback.call(set)});easing=R.is(easing,string)?easing:collector;item=this.items[--i].animate(params,ms,easing,collector);while(i--){this.items[i]&&!this.items[i].removed&&this.items[i].animateWith(item,params,ms,easing,collector)}return this};Set[proto].insertAfter=function(el){var i=this.items[length];while(i--){this.items[i].insertAfter(el)}return this};Set[proto].getBBox=function(){var x=[],y=[],w=[],h=[];for(var i=this.items[length];i--;){var box=this.items[i].getBBox();x[push](box.x);y[push](box.y);w[push](box.x+box.width);h[push](box.y+box.height)}x=mmin[apply](0,x);y=mmin[apply](0,y);return{x:x,y:y,width:mmax[apply](0,w)-x,height:mmax[apply](0,h)-y}};Set[proto].clone=function(s){s=new Set;for(var i=0,ii=this.items[length];i<ii;i++){s[push](this.items[i].clone())}return s};R.registerFont=function(font){if(!font.face){return font}this.fonts=this.fonts||{};var fontcopy={w:font.w,face:{},glyphs:{}},family=font.face["font-family"];for(var prop in font.face){if(font.face[has](prop)){fontcopy.face[prop]=font.face[prop]}}if(this.fonts[family]){this.fonts[family][push](fontcopy)}else{this.fonts[family]=[fontcopy]}if(!font.svg){fontcopy.face["units-per-em"]=toInt(font.face["units-per-em"],10);for(var glyph in font.glyphs){if(font.glyphs[has](glyph)){var path=font.glyphs[glyph];fontcopy.glyphs[glyph]={w:path.w,k:{},d:path.d&&"M"+path.d[rp](/[mlcxtrv]/g,function(command){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[command]||"M"})+"z"};if(path.k){for(var k in path.k){if(path[has](k)){fontcopy.glyphs[glyph].k[k]=path.k[k]}}}}}}return font};paperproto.getFont=function(family,weight,style,stretch){stretch=stretch||"normal";style=style||"normal";weight=+weight||{normal:400,bold:700,lighter:300,bolder:800}[weight]||400;if(!R.fonts){return}var font=R.fonts[family];if(!font){var name=new RegExp("(^|\\s)"+family[rp](/[^\w\d\s+!~.:_-]/g,E)+"(\\s|$)","i");for(var fontName in R.fonts){if(R.fonts[has](fontName)){if(name.test(fontName)){font=R.fonts[fontName];break}}}}var thefont;if(font){for(var i=0,ii=font[length];i<ii;i++){thefont=font[i];if(thefont.face["font-weight"]==weight&&(thefont.face["font-style"]==style||!thefont.face["font-style"])&&thefont.face["font-stretch"]==stretch){break}}}return thefont};paperproto.print=function(x,y,string,font,size,origin,letter_spacing){origin=origin||"middle";letter_spacing=mmax(mmin(letter_spacing||0,1),-1);var out=this.set(),letters=Str(string)[split](E),shift=0,path=E,scale;R.is(font,string)&&(font=this.getFont(font));if(font){scale=(size||16)/font.face["units-per-em"];var bb=font.face.bbox.split(separator),top=+bb[0],height=+bb[1]+(origin=="baseline"?bb[3]-bb[1]+(+font.face.descent):(bb[3]-bb[1])/2);for(var i=0,ii=letters[length];i<ii;i++){var prev=i&&font.glyphs[letters[i-1]]||{},curr=font.glyphs[letters[i]];shift+=i?(prev.w||font.w)+(prev.k&&prev.k[letters[i]]||0)+(font.w*letter_spacing):0;curr&&curr.d&&out[push](this.path(curr.d).attr({fill:"#000",stroke:"none",translation:[shift,0]}))}out.scale(scale,scale,top,height).translate(x-top,y-height)}return out};R.format=function(token,params){var args=R.is(params,array)?[0][concat](params):arguments;token&&R.is(token,string)&&args[length]-1&&(token=token[rp](formatrg,function(str,i){return args[++i]==null?E:args[i]}));return token||E};R.ninja=function(){oldRaphael.was?(win.Raphael=oldRaphael.is):delete Raphael;return R};R.el=elproto;R.st=Set[proto];oldRaphael.was?(win.Raphael=R):(Raphael=R)})();
 
 
 
 
 
 
 
lib/Aitoc/Aitloadmon/Adapter/Apc.php DELETED
@@ -1,56 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Adapter_Apc
7
- {
8
- private static $DATA_KEY = 'aitloadmon_data';
9
- private static $DATA_NUM_KEY = 'aitloadmon_data_key';
10
-
11
- /**
12
- * Saves the data into storage
13
- *
14
- * @param array $params
15
- */
16
- public function save($params)
17
- {
18
- if(!$index = apc_fetch(self::$DATA_NUM_KEY))
19
- {
20
- apc_add(self::$DATA_NUM_KEY, 1);
21
- $index = 1;
22
- }
23
-
24
- while(!apc_add(self::$DATA_KEY.$index,$params))
25
- {
26
- $index++;
27
- }
28
- apc_delete(self::$DATA_NUM_KEY);
29
- apc_add(self::$DATA_NUM_KEY, $index);
30
- }
31
-
32
-
33
- /**
34
- * Gets the data from the storage
35
- *
36
- * @return array
37
- */
38
- public function getData()
39
- {
40
- $data = array();
41
- if($index = apc_fetch(self::$DATA_NUM_KEY))
42
- {
43
- for($i=1;$i<=$index;$i++)
44
- {
45
- if($element = apc_fetch(self::$DATA_KEY.$i))
46
- {
47
- $data = array_merge_recursive($data,$element);
48
- apc_delete(self::$DATA_KEY.$i);
49
- }
50
- }
51
- apc_delete(self::$DATA_NUM_KEY);
52
- apc_add(self::$DATA_NUM_KEY, $i);
53
- }
54
- return $data;
55
- }
56
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/Aitoc/Aitloadmon/Adapter/File.php DELETED
@@ -1,116 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Adapter_File
7
- {
8
- const DS = DIRECTORY_SEPARATOR;
9
-
10
- private static $_dataDir = 'data';
11
- private static $_filename = 'data_';
12
-
13
- /**
14
- * Gets the path to the directory for the data files
15
- *
16
- * @return string
17
- */
18
- private function _getDataDir()
19
- {
20
- return Aitoc_Aitloadmon_Collect::getTempDir().self::$_dataDir.self::DS;
21
- }
22
-
23
- /**
24
- * Returns the file resource for writing
25
- *
26
- * @return resource
27
- */
28
- private function _getCurrentFileHandle()
29
- {
30
- $i = 0;
31
- $currentFileHandle = null;
32
- if(!file_exists($this->_getDataDir()))
33
- {
34
- mkdir($this->_getDataDir());
35
- }
36
- $curFilePath = $this->_getDataDir().self::$_filename;
37
- while(!$currentFileHandle)
38
- {
39
- $fileHandle = fopen($curFilePath.$i, 'a');
40
- $locked = flock($fileHandle, LOCK_EX);
41
- if($locked)
42
- {
43
- $currentFileHandle = $fileHandle;
44
- }
45
- $i++;
46
- }
47
- return $currentFileHandle;
48
- }
49
-
50
- /**
51
- * Writes a string to file
52
- *
53
- * @param string $string
54
- */
55
- private function _writeStringToFile($string)
56
- {
57
- $fileHandle = $this->_getCurrentFileHandle();
58
- fwrite($fileHandle,$string."\r\n");
59
- flock($fileHandle, LOCK_UN);
60
- fclose($fileHandle);
61
- }
62
-
63
- /**
64
- * Saves the data into storage
65
- *
66
- * @param array $params
67
- */
68
- public function save($params)
69
- {
70
- $this->_writeStringToFile(serialize($params));
71
- }
72
-
73
- /**
74
- * Gets the list of data files
75
- *
76
- * @return array
77
- */
78
- private function _getDataFileList()
79
- {
80
- return scandir($this->_getDataDir());
81
- }
82
-
83
- /**
84
- * Gets the data from the storage
85
- *
86
- * @return array
87
- */
88
- public function getData()
89
- {
90
- $dir = $this->_getDataDir();
91
- $data = array();
92
- foreach($this->_getDataFileList() as $fileName)
93
- {
94
- if($fileName != '.' && $fileName != '..')
95
- {
96
- $fileHandle = fopen($dir.$fileName, 'r');
97
- $locked = null;
98
- while(!$locked)
99
- {
100
- $locked = flock($fileHandle, LOCK_EX);
101
- }
102
-
103
- while($string = fgets($fileHandle))
104
- {
105
- $data = array_merge_recursive($data,unserialize($string));
106
- }
107
- flock($fileHandle, LOCK_UN);
108
- fclose($fileHandle);
109
- unlink($dir.$fileName);
110
- }
111
- }
112
-
113
- return $data;
114
- }
115
-
116
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/Aitoc/Aitloadmon/Adapter/Memcached.php DELETED
@@ -1,66 +0,0 @@
1
- <?php
2
- /**
3
- * @copyright Copyright (c) 2013 AITOC, Inc.
4
- * @license License agreement could be found at the root folder of this package
5
- */
6
- class Aitoc_Aitloadmon_Adapter_Memcached
7
- {
8
- private static $DATA_KEY = 'aitloadmon_data';
9
- private static $DATA_NUM_KEY = 'aitloadmon_data_key';
10
-
11
- private $_cache;
12
-
13
- /**
14
- * Initiates the connection to memcache
15
- *
16
- * @param array $settings
17
- */
18
- public function __construct($settings)
19
- {
20
- $this->_cache = new Memcache;
21
- $this->_cache->connect($settings['host'], $settings['port']);
22
- }
23
-
24
- /**
25
- * Saves the data into storage
26
- *
27
- * @param array $params
28
- */
29
- public function save($params)
30
- {
31
- if(!$index = $this->_cache->get(self::$DATA_NUM_KEY))
32
- {
33
- $this->_cache->set(self::$DATA_NUM_KEY, 1);
34
- $index = 1;
35
- }
36
-
37
- while(!$this->_cache->add(self::$DATA_KEY.$index,$params))
38
- {
39
- $index++;
40
- }
41
- $this->_cache->set(self::$DATA_NUM_KEY, $index);
42
- }
43
-
44
- /**
45
- * Gets the data from the storage
46
- *
47
- * @return array
48
- */
49
- public function getData()
50
- {
51
- $data = array();
52
- if($index = $this->_cache->get(self::$DATA_NUM_KEY))
53
- {
54
- for($i=1;$i<=$index;$i++)
55
- {
56
- if($element = $this->_cache->get(self::$DATA_KEY.$i))
57
- {
58
- $data = array_merge_recursive($data,$element);
59
- $this->_cache->delete(self::$DATA_KEY.$i);
60
- }
61
- }
62
- $this->_cache->set(self::$DATA_NUM_KEY, 1);
63
- }
64
- return $data;
65
- }
66
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/Aitoc/Aitloadmon/Collect.php DELETED
@@ -1,297 +0,0 @@
1
- <?php
2
-
3
- class Aitoc_Aitloadmon_Collect
4
- {
5
- const DS = DIRECTORY_SEPARATOR;
6
-
7
- private static $_tempDir = 'ait_loadmon';
8
- private static $_settingsFilename = 'settings.ini';
9
- private static $_loadLevelFilename = 'load_level';
10
-
11
- private static $_adapter;
12
- private static $_enabled;
13
- private static $_loadLevel;
14
- private static $_pathAddon;
15
- private static $_timeOffset = 0;
16
- private $_uniqueId;
17
- private $_startWritten;
18
-
19
- /**
20
- * Gets the root path of Magento installation
21
- *
22
- * @return string
23
- */
24
- private static function _getRootPath()
25
- {//todo think of it
26
- return dirname($_SERVER['SCRIPT_FILENAME']).self::$_pathAddon;
27
- }
28
-
29
- /**
30
- * Returns whether the module is enabled
31
- *
32
- * @return bool
33
- */
34
- public static function isModuleEnabled()
35
- {
36
- if(!isset(self::$_enabled))
37
- {
38
- self::$_enabled = false;
39
- $config = simplexml_load_file(self::_getRootPath().self::DS.'app'.self::DS.'etc'.self::DS.'modules'.self::DS.'Aitoc_Aitloadmon.xml');
40
- if ($config){
41
- self::$_enabled = (string)$config->modules->Aitoc_Aitloadmon->active;
42
- }
43
- }
44
- return self::$_enabled;
45
- }
46
-
47
-
48
- /**
49
- * Checks if module is enabled and if it is writes the start data
50
- */
51
- public function __construct($pathAddon = '')
52
- {
53
- self::$_pathAddon = $pathAddon;
54
- if (!self::isModuleEnabled())
55
- {
56
- return;
57
- }
58
- $this->_startWritten = 0;
59
- $this->_save();
60
- register_shutdown_function(array($this,'shutdown'));
61
- }
62
-
63
- /**
64
- * Gets the unique id for storing purposes
65
- *
66
- * @return string
67
- */
68
- private function _getUniqueId()
69
- {
70
- if(!isset($this->_uniqueId))
71
- {
72
- $this->_uniqueId = uniqid();
73
- }
74
- return $this->_uniqueId;
75
- }
76
-
77
- /**
78
- * Gets the VAR folder of Magento
79
- *
80
- * @return string
81
- */
82
- public static function getTempDir()
83
- {
84
- return self::_getRootPath().self::DS.'var'.self::DS.self::$_tempDir.self::DS;
85
- }
86
-
87
- /**
88
- * Gets the full path of the settings file
89
- *
90
- * @return string
91
- */
92
- private static function _getSettingsFilename()
93
- {
94
- return self::getTempDir().self::$_settingsFilename;
95
- }
96
-
97
- /**
98
- * Saves the data
99
- */
100
- private function _save()
101
- {
102
- if(!$this->_startWritten)
103
- {
104
- $saveData = array(
105
- $this->_getUniqueId() => array(
106
- 'request_uri' => $_SERVER['REQUEST_URI'],
107
- 'start' => microtime(true),
108
- )
109
- );
110
- }
111
- else
112
- {
113
- $microtime = microtime(true) + self::$_timeOffset;
114
- $saveData = array(
115
- $this->_getUniqueId() => array(
116
- 'end' => $microtime,
117
- )
118
- );
119
- }
120
- self::_getAdapter()->save($saveData);
121
- $this->_startWritten = 1;
122
- }
123
-
124
- /**
125
- * Checks if module is enabled and if it is writes the finish data
126
- */
127
- public function shutdown()/*__destruct()*/
128
- {
129
- if (!self::isModuleEnabled())
130
- {
131
- return;
132
- }
133
- $this->_save();
134
- }
135
-
136
- /**
137
- * Gets the data storage adapter
138
- *
139
- * @return Aitoc_Aitloadmon_Adapter_Memcached|Aitoc_Aitloadmon_Adapter_File|Aitoc_Aitloadmon_Adapter_Apc
140
- * @throws Exception
141
- */
142
- private static function _getAdapter()
143
- {
144
- if(!isset(self::$_adapter))
145
- {
146
- $settings = self::_getSettings();
147
-
148
- if(!isset($settings['adapter']))
149
- {
150
- throw new Exception('No adapter specified in settings');
151
- }
152
-
153
- $adapterName = ucfirst(strtolower($settings['adapter']));
154
- $adapterClassFile = self::_getRootPath().self::DS.'lib'.self::DS.'Aitoc'.self::DS.'Aitloadmon'.self::DS.'Adapter'.self::DS.$adapterName.'.php';
155
-
156
- if(!file_exists($adapterClassFile))
157
- {
158
- throw new Exception('Adapter does not exists');
159
- }
160
-
161
- include_once($adapterClassFile);
162
-
163
- $adapterClass = 'Aitoc_Aitloadmon_Adapter_'.$adapterName;
164
- self::$_adapter = new $adapterClass($settings);
165
- }
166
- return self::$_adapter;
167
- }
168
-
169
-
170
- /**
171
- * Gets the settings array
172
- *
173
- * @return array
174
- */
175
- private static function _getSettings()
176
- {
177
- if(!file_exists(self::_getSettingsFilename()))
178
- {
179
-
180
- $config = simplexml_load_file(self::_getRootPath().self::DS.'app'.self::DS.'etc'.self::DS.'local.xml');
181
- $cacheEngine = null;
182
- if ($config){
183
- $cacheEngine = (string)$config->global->cache->backend;
184
- }
185
- switch($cacheEngine)
186
- {
187
- case 'memcached':
188
- $settingsString = 'adapter = "memcached"'."\r\n".'host = "'.(string)$config->global->cache->memcached->servers->server->host.'"'."\r\n".'port = "'.(string)$config->global->cache->memcached->servers->server->port.'"';
189
- break;
190
-
191
- case 'apc':
192
- $settingsString = 'adapter = "apc"';
193
- break;
194
-
195
- default:
196
- $settingsString = 'adapter = "file"';
197
-
198
- }
199
- if(!file_exists(self::getTempDir()))
200
- {
201
- mkdir(self::getTempDir());
202
- }
203
- file_put_contents(self::_getSettingsFilename(),$settingsString);
204
-
205
- }
206
-
207
- $settings = parse_ini_file(self::_getSettingsFilename());
208
-
209
- return $settings;
210
- }
211
-
212
- /**
213
- * Gets the data that was collected and stored
214
- *
215
- * @return array
216
- */
217
- public static function getData()
218
- {
219
- $adapter = self::_getAdapter();
220
- $data = $adapter->getData();
221
- return $data;
222
- }
223
-
224
- /**
225
- * Gets the full path of a file with current load level
226
- *
227
- * @return string
228
- */
229
- private static function _getLoadLevelFilename()
230
- {
231
- return self::getTempDir().self::$_loadLevelFilename;
232
- }
233
-
234
- /**
235
- * Sets current load level
236
- *
237
- * @param int $loadLevel
238
- */
239
- public static function setLoadLevel($loadLevel)
240
- {
241
- self::$_loadLevel = $loadLevel;
242
- $filename = self::_getLoadLevelFilename();
243
- file_put_contents($filename,$loadLevel);
244
-
245
- }
246
-
247
- /**
248
- * Gets current load level
249
- *
250
- * @return null|int
251
- */
252
- public static function getLoadLevel()
253
- {
254
- if(!isset(self::$_loadLevel))
255
- {
256
- $filename = self::_getLoadLevelFilename();
257
- if(file_exists($filename))
258
- {
259
- self::$_loadLevel = file_get_contents($filename);
260
- }
261
- else
262
- {
263
- self::$_loadLevel = null;
264
- }
265
- }
266
- return self::$_loadLevel;
267
- }
268
-
269
- /**
270
- * Gets time offset
271
- *
272
- * @return int
273
- */
274
- public static function getTimeOffset()
275
- {
276
- return self::$_timeOffset;
277
- }
278
-
279
- /**
280
- * Sets time offset
281
- *
282
- */
283
- public static function setTimeOffset($offset)
284
- {
285
- self::$_timeOffset = $offset;
286
- }
287
-
288
- /**
289
- * Adds time offset
290
- *
291
- */
292
- public static function addTimeOffset($offset)
293
- {
294
- self::$_timeOffset += $offset;
295
- }
296
-
297
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
package.xml CHANGED
@@ -1,39 +1,18 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>ServerLoadMonitorFree</name>
4
- <version>1.1.0</version>
5
  <stability>stable</stability>
6
- <license uri="http://www.aitoc.com/en/aitdownloadablefiles/download/aitfile/aitfile_id/722/">License - proprietary (can be found in module package)</license>
7
  <channel>community</channel>
8
  <extends/>
9
- <summary>It&#x2019;s quite frustrating to have your server overloaded or crashed when trade is brisk and sales are booming. Neither is it a good thing to happen to a fledging e-commerce company still busy building up credibility with customers. Crash prevention is a serious issue and a valid goal. And even if your server is powerful enough and properly customized it is still useful to keep an eye on it, monitor your Magento store traffic load page by page. &#xD;
10
- &#xD;
11
- Server Load Monitor is just the right extension to serve all the above mentioned purposes. It will provide you with a comprehensive overview of load-related processes essential for trouble-free performance of your Magento server.</summary>
12
- <description>Description:&#xD;
13
- &#xD;
14
- Server Load Monitor (free) features:&#xD;
15
- &#xD;
16
- &#x2022; Allows for monitoring the following: CMS, Checkout, Catalog, Catalog Search and other pages; &#xD;
17
- &#x2022; Divides server performance into four intuitive color-coded zones; &#xD;
18
- &#x2022; Allows for tracking Average and Max page load and load time for a selected time period;&#xD;
19
- &#x2022; Displays load statistics in the form of easy and intuitive diagrams in the back-end;&#xD;
20
- &#x2022; Displays color-coded live server load info in the Admin panel;&#xD;
21
- &#x2022; Provides statistics for every minute; &#xD;
22
- &#x2022; Allows for comparing stats for different time periods;&#xD;
23
- &#x2022; Load statistics are stored in a database;&#xD;
24
- &#x2022; Compresses data automatically to avoid overloading the database. Default compression settings are optimized and recommended, but Admin is enabled to choose preferred compression settings as well as compress the data manually;&#xD;
25
- &#x2022; Sends data to AITOC&#x2019;s Server Calculator*; &#xD;
26
- &#x2022; Comes with a User Manual;&#xD;
27
- &#x2022; The extension's functionality code is 100% Open Source.&#xD;
28
- &#xD;
29
- * Please note that collected data will be sent to AITOC's Server Calculator in order to configure and recommend you better server settings. If you wish to disable sending data for Server Calculator stats, disable the ads, and get alerts about critical load peaks, please get the &lt;a href=&#x201D;http://aitoc.com/en/magentomods_ server_load_monitor_paid.htm&#x201D;&gt;paid version&lt;/a&gt; of the extension.</description>
30
- <notes>09.09.2013 &#xD;
31
- &#xD;
32
- * Fixed the issue with access to extension by admin with restricted permissions.</notes>
33
- <authors><author><name>AITOC</name><user>auto-converted</user><email>aitoc-connect@aitoc.com</email></author></authors>
34
- <date>2013-09-23</date>
35
- <time>12:31:50</time>
36
- <contents><target name="magelocal"><dir name="Aitoc"><dir name="Aitloadmon"><dir name="Block"><dir name="Adminhtml"><dir name="Aitloadmon"><file name="BarGraph.php" hash="90e16b55a20987cdd214bc6da435ea6d"/><file name="Filter.php" hash="eade4a66c1a68f1a2334138fd4c33d3a"/><file name="LineGraph.php" hash="4eee44af29cb9588268044d8fc516fd0"/></dir><file name="Aitlink.php" hash="4ea78c7a1d6f9e31aead66249a256a1d"/><file name="Aitloadmon.php" hash="5be3738e8cf84e5b85806701d6efbcd2"/><file name="Calculator.php" hash="4e08727116a1ac204bce97dab899b2e0"/><file name="CalculatorResult.php" hash="6d48c208e97c09a450302837a20b618c"/><file name="Indicator.php" hash="9d1e87229cef34dafe0d2ec435f6bb9f"/><file name="Manage.php" hash="dbfdb4f6d788fba1469ab0a61fde9d9d"/></dir></dir><dir name="Helper"><file name="Data.php" hash="876ae674bbf6cc06dcbc7839e61028e1"/></dir><dir name="Model"><dir name="Calculator"><file name="Abstract.php" hash="f525c95d18986065984dcfd7b5211942"/><file name="Hardware.php" hash="1164c19b50d86b9a71da74f9629c2e1d"/><file name="Magento.php" hash="918dac7ec4fcd4ba4393faa13c5c2417"/><file name="Software.php" hash="a523bba11e6781151ed32fac9da14246"/></dir><dir name="Mysql4"><dir name="Aitloadmon"><file name="Collection.php" hash="c5b65db67cedba6f28279ff78fd4f353"/></dir><dir name="Calculator"><file name="Collection.php" hash="15170dd43faeebdfc30e42ebd6270c28"/></dir><dir name="Dblog"><file name="Collection.php" hash="3dc0dcc5e9d3bb5951573d3d11a8e4dc"/></dir><file name="Aitloadmon.php" hash="2aa72df90f50823274a1a6b232c371d6"/><file name="Calculator.php" hash="7354931dd66342f5071f782b5de7401e"/><file name="Dblog.php" hash="4f4e76036d37c170fdf4771f2669dce8"/><file name="UrlRewrite.php" hash="08aecaea96122e801cdb2f9793e22ddf"/></dir><dir name="System"><file name="Abstract.php" hash="1cdc94c9f08d4507ef57fe766f30fe13"/></dir><file name="Aitloadmon.php" hash="8c7e29b4f586640975b8283688ab8bb7"/><file name="Analytics.php" hash="a223097ec56f7eea3329d43fe7e2956b"/><file name="Calculator.php" hash="84c46b31725072226f6f1e071e5a67b1"/><file name="CompressSource.php" hash="65b4aa585216893143d7ca28bfda6645"/><file name="Dblog.php" hash="4c134db8959a150f8031b71787ae2503"/><file name="LevelSource.php" hash="1937e32cc2b08ffbfc875d3a2f0d362b"/><file name="Manage.php" hash="6b06b0dbbb19d098b1414c6cd4a1bb8a"/><file name="Observer.php" hash="a58aa407da9971ba9cc30afb5be41248"/><file name="Process.php" hash="0ae9c0e159a108f47e920c7071882db5"/><file name="Router.php" hash="91ed3d96b51501d3852e8a2573c58674"/><file name="SysInfo.php" hash="a5c868f2ec1fa10cbbbca85c917a63f9"/><file name="System.php" hash="6eeee453abc5efd3c35a24babe613609"/><file name="UrlRewrite.php" hash="ea3849ee4bedc6422b03bdb4be2535fd"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="AitloadmonController.php" hash="0c5f48b6086679ccdb1334d3d9e1e2a4"/><file name="CalculatorController.php" hash="1b453f63fa4820c1cc2d87790bb89830"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="2a3046ce15833ca2704cb9d24737d62f"/><file name="config.xml" hash="9261658dfc9ac9d4459dbae48c89f785"/><file name="system.xml" hash="e2b9300c1ad1ea759e77f61b7d381869"/></dir><dir name="sql"><dir name="aitloadmon_setup"><file name="mysql4-install-1.0.0.php" hash="bb6d6c9aec69500be4a10d7944a82dfc"/><file name="mysql4-uninstall-1.0.0.php" hash="177151acef7c5d0c376f1d49bc5ce8c7"/><file name="mysql4-upgrade-1.0.1-1.0.2.php" hash="f2ae0c006d0180d3dc3fae7829135d52"/></dir></dir></dir><dir name="Aitsys"><dir name="install"><file name="Aitoc_Aitloadmon.phtml" hash="9a81474e26aac8b23a5b2d2cdd6ab30d"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="aitloadmon.xml" hash="5d8447f20382ed3a9aaab19cebc1e7b6"/></dir><dir name="template"><dir name="aitloadmon"><file name="back.phtml" hash="ccc9f0ff80649046eddf0faa3b1b50c5"/><file name="bar.phtml" hash="2bd5dd221588543850d3f9a4f4a9e35e"/><file name="graph.phtml" hash="097408b5b89d48df6e80953d0c6a379a"/><file name="indicator.phtml" hash="f0dce9d5c49118b7f98573a91766c563"/><file name="line.phtml" hash="b5e5eb4bc32fd6fdc161d84aed01ba42"/><file name="quick.phtml" hash="b0eecb7f8296c293d7abff2cddc5aa5c"/><file name="sysInfo.phtml" hash="674767482f77361975c90c8bc412e4a5"/><file name="system.phtml" hash="b17117164a92d0fda7c99e9cf7027938"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Aitoc_Aitloadmon.xml" hash="f9495b99199f39960003b4e6270baacf"/></dir></target><target name="magelib"><dir name="Aitoc"><dir name="Aitloadmon"><dir name="Adapter"><file name="Apc.php" hash="c67c74af65e094da996e39f0a8451d62"/><file name="File.php" hash="e440b9dc1c0792680043b8288d22f0a5"/><file name="Memcached.php" hash="b770d4016679b99e9dee9f82e28838a4"/></dir><file name="Collect.php" hash="9178d6ff1c4a5b5873652810a5f1b3b2"/></dir></dir></target><target name="mageweb"><dir name="js"><dir name="aitoc"><dir name="aitloadmon"><file name="grafico.bar.custom.js" hash="e54db4c61047afb27a56968a8eec9fc4"/><file name="grafico.line.custom.js" hash="1eee2034b47debfb9a746116979ddfa1"/><file name="grafico.min.js" hash="cde1bec6859b10e4a179aadec3c7e232"/><file name="raphael-min.js" hash="20908f0263d452ea59b1b528145c1a47"/></dir></dir></dir></target><target name="mage"><dir name="."><file name="readme.txt" hash="33729d5788f0da4048501c989079b42e"/><file name="License agreement Server Load Monitor.pdf" hash="2c37f69a12f4508aa13181f6cefd264b"/><file name="Server Load Monitor Manual.pdf" hash="21465278b287e1a35d900a92233b796a"/></dir></target></contents>
37
  <compatible/>
38
- <dependencies/>
39
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>ServerLoadMonitorFree</name>
4
+ <version>1.0.7</version>
5
  <stability>stable</stability>
6
+ <license>Free</license>
7
  <channel>community</channel>
8
  <extends/>
9
+ <summary>Server Load Monitor</summary>
10
+ <description>Server Load Monitor</description>
11
+ <notes>Test version</notes>
12
+ <authors><author><name>Aitoc</name><user>Aitoc</user><email>sales@aitoc.com</email></author></authors>
13
+ <date>2015-10-20</date>
14
+ <time>12:51:32</time>
15
+ <contents><target name="magedesign"><dir name="app"><dir name="design"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="aitcore.xml" hash=""/><file name="aitinstall.xml" hash=""/><file name="aitloadmon.xml" hash=""/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="app"><dir name="etc"><dir name="modules"><file name="Aitoc_Aitinstall.xml" hash=""/><file name="Aitoc_Aitloadmon.xml" hash=""/></dir></dir></dir></target><target name="mage"><dir name="."><file name="License agreement Server Load Monitor.pdf" hash="2c37f69a12f4508aa13181f6cefd264b"/><file name="readme.txt" hash="33729d5788f0da4048501c989079b42e"/></dir></target><target name="magelocal"><dir name="."><file name="Server Load Monitor Manual.pdf" hash=""/></dir></target><target name="mageskin"><dir name="skin"><dir name="adminhtml"><dir name="default"><dir name="default"><file name="aitoc" hash=""/></dir></dir></dir></dir></target></contents>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  <compatible/>
17
+ <dependencies><required><php><min>5.4.0</min><max>5.6.0</max></php></required></dependencies>
18
  </package>