diff options
author | Simon Rettberg | 2016-05-18 18:04:56 +0200 |
---|---|---|
committer | Simon Rettberg | 2016-05-18 18:04:56 +0200 |
commit | 2e18b36a287ad9b25619f9e2a073dcedf6d620ee (patch) | |
tree | 96d802fdc1c21ee9aa9b4d89a6611db7d8502433 /modules-available | |
parent | Modularized baseconfig fetching (api) (diff) | |
download | slx-admin-2e18b36a287ad9b25619f9e2a073dcedf6d620ee.tar.gz slx-admin-2e18b36a287ad9b25619f9e2a073dcedf6d620ee.tar.xz slx-admin-2e18b36a287ad9b25619f9e2a073dcedf6d620ee.zip |
MORE WMORK
Diffstat (limited to 'modules-available')
62 files changed, 505 insertions, 409 deletions
diff --git a/modules-available/backup/page.inc.php b/modules-available/backup/page.inc.php index 9d253a1e..3f2388a5 100644 --- a/modules-available/backup/page.inc.php +++ b/modules-available/backup/page.inc.php @@ -27,7 +27,6 @@ class Page_Backup extends Page if ($this->action === 'restore') { Render::addTemplate('restore', $this->templateData); } else { - Render::addScriptBottom('fileselect'); Render::addTemplate('_page'); } } diff --git a/modules-available/baseconfig/config.json b/modules-available/baseconfig/config.json index b72e9c23..9ce17b0d 100644 --- a/modules-available/baseconfig/config.json +++ b/modules-available/baseconfig/config.json @@ -1,4 +1,3 @@ { - "category": "main.settings", - "enabled": true + "category": "main.settings" } diff --git a/modules-available/baseconfig/templates/_page.html b/modules-available/baseconfig/templates/_page.html index e8b85dd3..093cb10f 100644 --- a/modules-available/baseconfig/templates/_page.html +++ b/modules-available/baseconfig/templates/_page.html @@ -63,5 +63,5 @@ </div> <button class="btn btn-primary" type="submit">{{lang_save}}</button> <button class="btn btn-default" type="reset">{{lang_reset}}</button> - <a class="btn btn-default" href="api.php?do=getconfig">Download</a> + <a class="btn btn-default" href="api.php?do=baseconfig">Download</a> </form> diff --git a/modules-available/baseconfig_partitions_cdn/config.json b/modules-available/baseconfig_partitions_cdn/config.json new file mode 100644 index 00000000..a3036a56 --- /dev/null +++ b/modules-available/baseconfig_partitions_cdn/config.json @@ -0,0 +1,4 @@ +{ + "category": "main.settings", + "dependencies": [ "baseconfig" ] +}
\ No newline at end of file diff --git a/modules-available/baseconfig_partitions_cdn/page.inc.php b/modules-available/baseconfig_partitions_cdn/page.inc.php new file mode 100644 index 00000000..b6ea869a --- /dev/null +++ b/modules-available/baseconfig_partitions_cdn/page.inc.php @@ -0,0 +1,133 @@ +<?php + +class Page_BaseConfig_Partitions_CDN extends Page +{ + + protected function doPreprocess() + { + User::load(); + + $action = Request::post('action'); + + if($action == 'new_partition') { + $this->addPartition(); + } + if($action == 'reset') { + $this->resetConfig(); + } + + $deletePartition = Request::get('deletePartition'); + if($deletePartition !== false) { // TODO: CSRF: Actions that change/update/delete anything should be POST + $this->deletePartition($deletePartition); + } + + $this->updatePartitions(); + } + + protected function doRender() + { + if (!User::hasPermission('baseconfig_local')) { + Message::addError('main.no-permission'); + Util::redirect('?do=Main'); + } + + //loads partition settings + $partitions = array(); + $res = Database::simpleQuery('SELECT id, partition_id, size, mount_point, options FROM setting_partition WHERE user=:user', + array( 'user' => User::getId() )); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $partition = array( + 'id' => $row['id'], + 'partition_id' => $row['partition_id'], + 'size' => $row['size'], + 'mount_point' => $row['mount_point'], + 'options' => $row['options'] + ); + $partitions[] = $partition; + } + + Render::addTemplate('_page', array( + 'partitions' => $partitions, + 'user' => User::getId() + )); + } + + private function addPartition() { + $partId = Request::post('new-partition-id'); + $partSize = Request::post('new-partition-size'); + $partMountPoint = Request::post('new-partition-mount-point'); + $partOptions = Request::post('new-partition-options'); + + if(strlen($partId) < 1 || strlen($partSize) < 1){ + Message::addError('main.empty-field'); + }else{ + $data = array( + 'partition_id' => $partId, + 'size' => $partSize, + 'mount_point' => $partMountPoint, + 'options' => $partOptions, + 'user' => User::getId() + ); + if (Database::exec('INSERT INTO setting_partition SET partition_id = :partition_id, size = :size, + mount_point = :mount_point, options = :options, user = :user ', $data) != 1) { + Util::traceError('Could not create new partition in DB'); + } + } + Util::redirect('?do=BaseConfig'); + } + + private function deletePartition($id){ + if(is_numeric($id)){ + $data = array( + 'id' => $id, + 'user' => User::getId() + ); + if (Database::exec('DELETE FROM setting_partition WHERE id = :id AND user = :user', $data) != 1) { + Util::traceError('Could not delete partition in DB'); + } + } + Util::redirect('?do=BaseConfig'); + } + + private function updatePartitions(){ + $partitions = array(); + foreach($_POST as $key => $value){ + if(substr($key,0,9) == 'partition'){ + $id = substr($key,10,1); + $type = substr($key,12); + $partitions[$id][$type] = $value; + } + } + + foreach($partitions as $key => $data){ + $data = array( + 'id' => $key, + 'partition_id' => $data['partition_id'], + 'size' => $data['size'], + 'mount_point' => $data['mount_point'], + 'options' => $data['options'], + 'user' => User::getId() + ); + Database::exec('UPDATE setting_partition SET partition_id=:partition_id, size=:size, mount_point=:mount_point, + options=:options WHERE id=:id AND user=:user;', $data); + } + if (!empty($partitions)) { + Message::addSuccess('partitions-updated'); + Util::redirect('?do=BaseConfig'); + } + } + + private function resetConfig(){ + $data = array( + 'user' => User::getId() + ); + //Delete all config values + Database::exec('DELETE FROM setting_partition WHERE user = :user', $data); + //Create default partition values + Database::exec ( "INSERT INTO setting_partition SET partition_id = '44', size = '5G', mount_point = '/tmp', user = :user", $data ); + Database::exec ( "INSERT INTO setting_partition SET partition_id = '43', size = '20G', mount_point = '/boot', options = 'bootable', user = :user", $data ); + Database::exec ( "INSERT INTO setting_partition SET partition_id = '40', size = '20G', mount_point = '/cache/export/dnbd3', user = :user", $data ); + Database::exec ( "INSERT INTO setting_partition SET partition_id = '41', size = '5G', mount_point = '/home', user = :user", $data ); + Database::exec ( "INSERT INTO setting_partition SET partition_id = '82', size = '1G', user = :user", $data ); + } +}
\ No newline at end of file diff --git a/modules-available/baseconfig_partitions_cdn/templates/_page.html b/modules-available/baseconfig_partitions_cdn/templates/_page.html new file mode 100644 index 00000000..ee764e37 --- /dev/null +++ b/modules-available/baseconfig_partitions_cdn/templates/_page.html @@ -0,0 +1,74 @@ +<h1>{{lang_partitioningManagement}}</h1> + +<form action="?do=BaseConfig_Partitions_CDN" method="post"> + <input type="hidden" name="token" value="{{token}}"> + <button class="btn btn-lg btn-primary" type="submit">{{lang_save}}</button> + <button class="btn btn-lg btn-primary" type="reset">{{lang_reset}}</button> + <a class="btn btn-lg btn-primary" href="#" onclick="saveConfig()">Download</a> +</form> +<div> +<form method="post" action="?do=BaseConfig_Partitions_CDN"> + <input type="hidden" name="token" value="{{token}}"> + <input type="hidden" name="action" value="reset"> + <button class="btn btn-default" type="submit" onclick="return confirm('{{lang_resetConfirm}}');">{{lang_resetDefault}}</button> +</form> +</div> + +<!-- Create Partition Window --> +<form action="?do=BaseConfig_Partitions_CDN" method="post"> + <div class="modal fade" id="add-partition" tabindex="-1" role="dialog"> + <div class="modal-dialog"> + + <div class="modal-content"> + <div class="modal-header">{{lang_newPartition}}</div> + <div class="modal-body"> + + <div class="input-group"> + <span class="input-group-addon">{{lang_partitionId}}</span> + <input name="new-partition-id" class="form-control" type="text"> + </div> + <p class="help-block">{{lang_helpId}}</p> + <div class="input-group"> + <span class="input-group-addon">{{lang_partitionSize}}</span> + <input name="new-partition-size" class="form-control" type="text"> + </div> + <p class="help-block">{{lang_helpSize}}</p> + <div class="input-group"> + <span class="input-group-addon">{{lang_partitionMountPoint}}</span> + <input name="new-partition-mount-point" class="form-control" type="text"> + </div> + <p class="help-block">{{lang_helpMountPoint}}</p> + <div class="input-group"> + <span class="input-group-addon">{{lang_partitionOptions}}</span> + <input name="new-partition-options" class="form-control" type="text"> + </div> + <p class="help-block">{{lang_helpOptions}}</p> + <input type="submit" class="btn btn-primary" value="{{lang_create}}"> + </div> + <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div> + </div> + </div> + </div> + <input type="hidden" name="action" value="new_partition"> + <input type="hidden" name="token" value="{{token}}"> +</form> +<script type="text/javascript"> + document.getElementById("cat-extra-6").innerHTML = "<div class='list-group'> <div class='list-group-item' style='background-color:#f5f5f5;color:#428bca;'> " + + "{{lang_catPartition}} <span style='display:inline-block; float: right; margin-top: -7px;'> <a class='btn btn-default ' data-toggle='modal' " + + "data-target='#add-partition'> <span class='glyphicon glyphicon-plus'></span> </a> </span> </div> {{#partitions}} <div class='list-group-item'> " + + "<div class='row'> <div class='col-md-1'> <input name='partition-{{id}}-partition_id' type='text' class='form-control' size='30' value='{{partition_id}}'" + + " placeholder='{{lang_partitionId}}' /> </div> <div class='col-md-1'> <input name='partition-{{id}}-size' type='text' class='form-control' size='30' " + + "value='{{size}}' placeholder='{{lang_partitionSize}}'/> </div> <div class='col-md-4'> <input name='partition-{{id}}-mount_point' type='text' " + + "class='form-control' size='30' value='{{mount_point}}' placeholder='{{lang_partitionMountPoint}}'/> </div> <div class='col-md-4'> <input " + + "name='partition-{{id}}-options' type='text' class='form-control' size='30' value='{{options}}' placeholder='{{lang_partitionOptions}}'/> </div> " + + "<div class='col-md-2'> <a class='btn btn-danger' href='?do=BaseConfig&deletePartition={{id}}&token={{token}}' ><span class='glyphicon glyphicon-trash'>" + + "</span> {{lang_delete}}</a> </div> </div> </div> {{/partitions}} </div> </div>"; + + function saveConfig(){ + if(confirm('{{lang_confirm}}')) + window.location = 'api.php?do=baseconfig&user={{user}}&save=true'; + else + window.location = 'api.php?do=baseconfig&user={{user}}'; + } + +</script>
\ No newline at end of file diff --git a/modules-available/dozmod/hooks/main-warning.inc.php b/modules-available/dozmod/hooks/main-warning.inc.php new file mode 100644 index 00000000..ffa87692 --- /dev/null +++ b/modules-available/dozmod/hooks/main-warning.inc.php @@ -0,0 +1,11 @@ +<?php + +/* + * Show notification in main window if there are images that should be deleted and are waiting for confirmation + */ + +$res = Database::queryFirst("SELECT Count(*) AS cnt FROM sat.imageversion WHERE deletestate = 'SHOULD_DELETE'", array(), true); +if (isset($res['cnt']) && $res['cnt'] > 0) { + Message::addInfo('dozmod.images-pending-delete-exist', true, $res['cnt']); +} +unset($res); diff --git a/modules-available/dozmod/lang/de/messages.json b/modules-available/dozmod/lang/de/messages.json index d6e39cbf..7944ffae 100644 --- a/modules-available/dozmod/lang/de/messages.json +++ b/modules-available/dozmod/lang/de/messages.json @@ -1,4 +1,5 @@ { "delete-images": "L\u00f6schung: {{0}}", + "images-pending-delete-exist": "Zur L\u00f6schung markierte Abbilder: {{0}}", "mail-config-saved": "Mail-Konfiguration gespeichert" }
\ No newline at end of file diff --git a/modules-available/dozmod/lang/en/messages.json b/modules-available/dozmod/lang/en/messages.json index a3c94a56..6651e32e 100644 --- a/modules-available/dozmod/lang/en/messages.json +++ b/modules-available/dozmod/lang/en/messages.json @@ -1,4 +1,5 @@ { "delete-images": "Delete: {{0}}", + "images-pending-delete-exist": "Images marked for deletion: {{0}}", "mail-config-saved": "Mail config saved" }
\ No newline at end of file diff --git a/modules-available/js_chart/clientscript.js b/modules-available/js_chart/clientscript.js new file mode 100644 index 00000000..3a0a2c87 --- /dev/null +++ b/modules-available/js_chart/clientscript.js @@ -0,0 +1,11 @@ +/*! + * Chart.js + * http://chartjs.org/ + * Version: 1.0.2 + * + * Copyright 2015 Nick Downie + * Released under the MIT license + * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md + */ +(function(){"use strict";var t=this,i=t.Chart,e=function(t){this.canvas=t.canvas,this.ctx=t;var i=function(t,i){return t["offset"+i]?t["offset"+i]:document.defaultView.getComputedStyle(t).getPropertyValue(i)},e=this.width=i(t.canvas,"Width"),n=this.height=i(t.canvas,"Height");t.canvas.width=e,t.canvas.height=n;var e=this.width=t.canvas.width,n=this.height=t.canvas.height;return this.aspectRatio=this.width/this.height,s.retinaScale(this),this};e.defaults={global:{animation:!0,animationSteps:60,animationEasing:"easeOutQuart",showScale:!0,scaleOverride:!1,scaleSteps:null,scaleStepWidth:null,scaleStartValue:null,scaleLineColor:"rgba(0,0,0,.1)",scaleLineWidth:1,scaleShowLabels:!0,scaleLabel:"<%=value%>",scaleIntegersOnly:!0,scaleBeginAtZero:!1,scaleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",scaleFontSize:12,scaleFontStyle:"normal",scaleFontColor:"#666",responsive:!1,maintainAspectRatio:!0,showTooltips:!0,customTooltips:!1,tooltipEvents:["mousemove","touchstart","touchmove","mouseout"],tooltipFillColor:"rgba(0,0,0,0.8)",tooltipFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipFontSize:14,tooltipFontStyle:"normal",tooltipFontColor:"#fff",tooltipTitleFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",tooltipTitleFontSize:14,tooltipTitleFontStyle:"bold",tooltipTitleFontColor:"#fff",tooltipYPadding:6,tooltipXPadding:6,tooltipCaretSize:8,tooltipCornerRadius:6,tooltipXOffset:10,tooltipTemplate:"<%if (label){%><%=label%>: <%}%><%= value %>",multiTooltipTemplate:"<%= value %>",multiTooltipKeyBackground:"#fff",onAnimationProgress:function(){},onAnimationComplete:function(){}}},e.types={};var s=e.helpers={},n=s.each=function(t,i,e){var s=Array.prototype.slice.call(arguments,3);if(t)if(t.length===+t.length){var n;for(n=0;n<t.length;n++)i.apply(e,[t[n],n].concat(s))}else for(var o in t)i.apply(e,[t[o],o].concat(s))},o=s.clone=function(t){var i={};return n(t,function(e,s){t.hasOwnProperty(s)&&(i[s]=e)}),i},a=s.extend=function(t){return n(Array.prototype.slice.call(arguments,1),function(i){n(i,function(e,s){i.hasOwnProperty(s)&&(t[s]=e)})}),t},h=s.merge=function(){var t=Array.prototype.slice.call(arguments,0);return t.unshift({}),a.apply(null,t)},l=s.indexOf=function(t,i){if(Array.prototype.indexOf)return t.indexOf(i);for(var e=0;e<t.length;e++)if(t[e]===i)return e;return-1},r=(s.where=function(t,i){var e=[];return s.each(t,function(t){i(t)&&e.push(t)}),e},s.findNextWhere=function(t,i,e){e||(e=-1);for(var s=e+1;s<t.length;s++){var n=t[s];if(i(n))return n}},s.findPreviousWhere=function(t,i,e){e||(e=t.length);for(var s=e-1;s>=0;s--){var n=t[s];if(i(n))return n}},s.inherits=function(t){var i=this,e=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return i.apply(this,arguments)},s=function(){this.constructor=e};return s.prototype=i.prototype,e.prototype=new s,e.extend=r,t&&a(e.prototype,t),e.__super__=i.prototype,e}),c=s.noop=function(){},u=s.uid=function(){var t=0;return function(){return"chart-"+t++}}(),d=s.warn=function(t){window.console&&"function"==typeof window.console.warn&&console.warn(t)},p=s.amd="function"==typeof define&&define.amd,f=s.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},g=s.max=function(t){return Math.max.apply(Math,t)},m=s.min=function(t){return Math.min.apply(Math,t)},v=(s.cap=function(t,i,e){if(f(i)){if(t>i)return i}else if(f(e)&&e>t)return e;return t},s.getDecimalPlaces=function(t){return t%1!==0&&f(t)?t.toString().split(".")[1].length:0}),S=s.radians=function(t){return t*(Math.PI/180)},x=(s.getAngleFromPoint=function(t,i){var e=i.x-t.x,s=i.y-t.y,n=Math.sqrt(e*e+s*s),o=2*Math.PI+Math.atan2(s,e);return 0>e&&0>s&&(o+=2*Math.PI),{angle:o,distance:n}},s.aliasPixel=function(t){return t%2===0?0:.5}),y=(s.splineCurve=function(t,i,e,s){var n=Math.sqrt(Math.pow(i.x-t.x,2)+Math.pow(i.y-t.y,2)),o=Math.sqrt(Math.pow(e.x-i.x,2)+Math.pow(e.y-i.y,2)),a=s*n/(n+o),h=s*o/(n+o);return{inner:{x:i.x-a*(e.x-t.x),y:i.y-a*(e.y-t.y)},outer:{x:i.x+h*(e.x-t.x),y:i.y+h*(e.y-t.y)}}},s.calculateOrderOfMagnitude=function(t){return Math.floor(Math.log(t)/Math.LN10)}),C=(s.calculateScaleRange=function(t,i,e,s,n){var o=2,a=Math.floor(i/(1.5*e)),h=o>=a,l=g(t),r=m(t);l===r&&(l+=.5,r>=.5&&!s?r-=.5:l+=.5);for(var c=Math.abs(l-r),u=y(c),d=Math.ceil(l/(1*Math.pow(10,u)))*Math.pow(10,u),p=s?0:Math.floor(r/(1*Math.pow(10,u)))*Math.pow(10,u),f=d-p,v=Math.pow(10,u),S=Math.round(f/v);(S>a||a>2*S)&&!h;)if(S>a)v*=2,S=Math.round(f/v),S%1!==0&&(h=!0);else if(n&&u>=0){if(v/2%1!==0)break;v/=2,S=Math.round(f/v)}else v/=2,S=Math.round(f/v);return h&&(S=o,v=f/S),{steps:S,stepValue:v,min:p,max:p+S*v}},s.template=function(t,i){function e(t,i){var e=/\W/.test(t)?new Function("obj","var p=[],print=function(){p.push.apply(p,arguments);};with(obj){p.push('"+t.replace(/[\r\t\n]/g," ").split("<%").join(" ").replace(/((^|%>)[^\t]*)'/g,"$1\r").replace(/\t=(.*?)%>/g,"',$1,'").split(" ").join("');").split("%>").join("p.push('").split("\r").join("\\'")+"');}return p.join('');"):s[t]=s[t];return i?e(i):e}if(t instanceof Function)return t(i);var s={};return e(t,i)}),w=(s.generateLabels=function(t,i,e,s){var o=new Array(i);return labelTemplateString&&n(o,function(i,n){o[n]=C(t,{value:e+s*(n+1)})}),o},s.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-0.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-0.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-0.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-0.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:1==(t/=1)?1:(e||(e=.3),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),-(s*Math.pow(2,10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e)))},easeOutElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:1==(t/=1)?1:(e||(e=.3),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),s*Math.pow(2,-10*t)*Math.sin(2*(1*t-i)*Math.PI/e)+1)},easeInOutElastic:function(t){var i=1.70158,e=0,s=1;return 0===t?0:2==(t/=.5)?1:(e||(e=.3*1.5),s<Math.abs(1)?(s=1,i=e/4):i=e/(2*Math.PI)*Math.asin(1/s),1>t?-.5*s*Math.pow(2,10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e):s*Math.pow(2,-10*(t-=1))*Math.sin(2*(1*t-i)*Math.PI/e)*.5+1)},easeInBack:function(t){var i=1.70158;return 1*(t/=1)*t*((i+1)*t-i)},easeOutBack:function(t){var i=1.70158;return 1*((t=t/1-1)*t*((i+1)*t+i)+1)},easeInOutBack:function(t){var i=1.70158;return(t/=.5)<1?.5*t*t*(((i*=1.525)+1)*t-i):.5*((t-=2)*t*(((i*=1.525)+1)*t+i)+2)},easeInBounce:function(t){return 1-w.easeOutBounce(1-t)},easeOutBounce:function(t){return(t/=1)<1/2.75?7.5625*t*t:2/2.75>t?1*(7.5625*(t-=1.5/2.75)*t+.75):2.5/2.75>t?1*(7.5625*(t-=2.25/2.75)*t+.9375):1*(7.5625*(t-=2.625/2.75)*t+.984375)},easeInOutBounce:function(t){return.5>t?.5*w.easeInBounce(2*t):.5*w.easeOutBounce(2*t-1)+.5}}),b=s.requestAnimFrame=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}}(),P=s.cancelAnimFrame=function(){return window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t,1e3/60)}}(),L=(s.animationLoop=function(t,i,e,s,n,o){var a=0,h=w[e]||w.linear,l=function(){a++;var e=a/i,r=h(e);t.call(o,r,e,a),s.call(o,r,e),i>a?o.animationFrame=b(l):n.apply(o)};b(l)},s.getRelativePosition=function(t){var i,e,s=t.originalEvent||t,n=t.currentTarget||t.srcElement,o=n.getBoundingClientRect();return s.touches?(i=s.touches[0].clientX-o.left,e=s.touches[0].clientY-o.top):(i=s.clientX-o.left,e=s.clientY-o.top),{x:i,y:e}},s.addEvent=function(t,i,e){t.addEventListener?t.addEventListener(i,e):t.attachEvent?t.attachEvent("on"+i,e):t["on"+i]=e}),k=s.removeEvent=function(t,i,e){t.removeEventListener?t.removeEventListener(i,e,!1):t.detachEvent?t.detachEvent("on"+i,e):t["on"+i]=c},F=(s.bindEvents=function(t,i,e){t.events||(t.events={}),n(i,function(i){t.events[i]=function(){e.apply(t,arguments)},L(t.chart.canvas,i,t.events[i])})},s.unbindEvents=function(t,i){n(i,function(i,e){k(t.chart.canvas,e,i)})}),R=s.getMaximumWidth=function(t){var i=t.parentNode;return i.clientWidth},T=s.getMaximumHeight=function(t){var i=t.parentNode;return i.clientHeight},A=(s.getMaximumSize=s.getMaximumWidth,s.retinaScale=function(t){var i=t.ctx,e=t.canvas.width,s=t.canvas.height;window.devicePixelRatio&&(i.canvas.style.width=e+"px",i.canvas.style.height=s+"px",i.canvas.height=s*window.devicePixelRatio,i.canvas.width=e*window.devicePixelRatio,i.scale(window.devicePixelRatio,window.devicePixelRatio))}),M=s.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},W=s.fontString=function(t,i,e){return i+" "+t+"px "+e},z=s.longestText=function(t,i,e){t.font=i;var s=0;return n(e,function(i){var e=t.measureText(i).width;s=e>s?e:s}),s},B=s.drawRoundedRectangle=function(t,i,e,s,n,o){t.beginPath(),t.moveTo(i+o,e),t.lineTo(i+s-o,e),t.quadraticCurveTo(i+s,e,i+s,e+o),t.lineTo(i+s,e+n-o),t.quadraticCurveTo(i+s,e+n,i+s-o,e+n),t.lineTo(i+o,e+n),t.quadraticCurveTo(i,e+n,i,e+n-o),t.lineTo(i,e+o),t.quadraticCurveTo(i,e,i+o,e),t.closePath()};e.instances={},e.Type=function(t,i,s){this.options=i,this.chart=s,this.id=u(),e.instances[this.id]=this,i.responsive&&this.resize(),this.initialize.call(this,t)},a(e.Type.prototype,{initialize:function(){return this},clear:function(){return M(this.chart),this},stop:function(){return P(this.animationFrame),this},resize:function(t){this.stop();var i=this.chart.canvas,e=R(this.chart.canvas),s=this.options.maintainAspectRatio?e/this.chart.aspectRatio:T(this.chart.canvas);return i.width=this.chart.width=e,i.height=this.chart.height=s,A(this.chart),"function"==typeof t&&t.apply(this,Array.prototype.slice.call(arguments,1)),this},reflow:c,render:function(t){return t&&this.reflow(),this.options.animation&&!t?s.animationLoop(this.draw,this.options.animationSteps,this.options.animationEasing,this.options.onAnimationProgress,this.options.onAnimationComplete,this):(this.draw(),this.options.onAnimationComplete.call(this)),this},generateLegend:function(){return C(this.options.legendTemplate,this)},destroy:function(){this.clear(),F(this,this.events);var t=this.chart.canvas;t.width=this.chart.width,t.height=this.chart.height,t.style.removeProperty?(t.style.removeProperty("width"),t.style.removeProperty("height")):(t.style.removeAttribute("width"),t.style.removeAttribute("height")),delete e.instances[this.id]},showTooltip:function(t,i){"undefined"==typeof this.activeElements&&(this.activeElements=[]);var o=function(t){var i=!1;return t.length!==this.activeElements.length?i=!0:(n(t,function(t,e){t!==this.activeElements[e]&&(i=!0)},this),i)}.call(this,t);if(o||i){if(this.activeElements=t,this.draw(),this.options.customTooltips&&this.options.customTooltips(!1),t.length>0)if(this.datasets&&this.datasets.length>1){for(var a,h,r=this.datasets.length-1;r>=0&&(a=this.datasets[r].points||this.datasets[r].bars||this.datasets[r].segments,h=l(a,t[0]),-1===h);r--);var c=[],u=[],d=function(){var t,i,e,n,o,a=[],l=[],r=[];return s.each(this.datasets,function(i){t=i.points||i.bars||i.segments,t[h]&&t[h].hasValue()&&a.push(t[h])}),s.each(a,function(t){l.push(t.x),r.push(t.y),c.push(s.template(this.options.multiTooltipTemplate,t)),u.push({fill:t._saved.fillColor||t.fillColor,stroke:t._saved.strokeColor||t.strokeColor})},this),o=m(r),e=g(r),n=m(l),i=g(l),{x:n>this.chart.width/2?n:i,y:(o+e)/2}}.call(this,h);new e.MultiTooltip({x:d.x,y:d.y,xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,xOffset:this.options.tooltipXOffset,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,titleTextColor:this.options.tooltipTitleFontColor,titleFontFamily:this.options.tooltipTitleFontFamily,titleFontStyle:this.options.tooltipTitleFontStyle,titleFontSize:this.options.tooltipTitleFontSize,cornerRadius:this.options.tooltipCornerRadius,labels:c,legendColors:u,legendColorBackground:this.options.multiTooltipKeyBackground,title:t[0].label,chart:this.chart,ctx:this.chart.ctx,custom:this.options.customTooltips}).draw()}else n(t,function(t){var i=t.tooltipPosition();new e.Tooltip({x:Math.round(i.x),y:Math.round(i.y),xPadding:this.options.tooltipXPadding,yPadding:this.options.tooltipYPadding,fillColor:this.options.tooltipFillColor,textColor:this.options.tooltipFontColor,fontFamily:this.options.tooltipFontFamily,fontStyle:this.options.tooltipFontStyle,fontSize:this.options.tooltipFontSize,caretHeight:this.options.tooltipCaretSize,cornerRadius:this.options.tooltipCornerRadius,text:C(this.options.tooltipTemplate,t),chart:this.chart,custom:this.options.customTooltips}).draw()},this);return this}},toBase64Image:function(){return this.chart.canvas.toDataURL.apply(this.chart.canvas,arguments)}}),e.Type.extend=function(t){var i=this,s=function(){return i.apply(this,arguments)};if(s.prototype=o(i.prototype),a(s.prototype,t),s.extend=e.Type.extend,t.name||i.prototype.name){var n=t.name||i.prototype.name,l=e.defaults[i.prototype.name]?o(e.defaults[i.prototype.name]):{};e.defaults[n]=a(l,t.defaults),e.types[n]=s,e.prototype[n]=function(t,i){var o=h(e.defaults.global,e.defaults[n],i||{});return new s(t,o,this)}}else d("Name not provided for this chart, so it hasn't been registered");return i},e.Element=function(t){a(this,t),this.initialize.apply(this,arguments),this.save()},a(e.Element.prototype,{initialize:function(){},restore:function(t){return t?n(t,function(t){this[t]=this._saved[t]},this):a(this,this._saved),this},save:function(){return this._saved=o(this),delete this._saved._saved,this},update:function(t){return n(t,function(t,i){this._saved[i]=this[i],this[i]=t},this),this},transition:function(t,i){return n(t,function(t,e){this[e]=(t-this._saved[e])*i+this._saved[e]},this),this},tooltipPosition:function(){return{x:this.x,y:this.y}},hasValue:function(){return f(this.value)}}),e.Element.extend=r,e.Point=e.Element.extend({display:!0,inRange:function(t,i){var e=this.hitDetectionRadius+this.radius;return Math.pow(t-this.x,2)+Math.pow(i-this.y,2)<Math.pow(e,2)},draw:function(){if(this.display){var t=this.ctx;t.beginPath(),t.arc(this.x,this.y,this.radius,0,2*Math.PI),t.closePath(),t.strokeStyle=this.strokeColor,t.lineWidth=this.strokeWidth,t.fillStyle=this.fillColor,t.fill(),t.stroke()}}}),e.Arc=e.Element.extend({inRange:function(t,i){var e=s.getAngleFromPoint(this,{x:t,y:i}),n=e.angle>=this.startAngle&&e.angle<=this.endAngle,o=e.distance>=this.innerRadius&&e.distance<=this.outerRadius;return n&&o},tooltipPosition:function(){var t=this.startAngle+(this.endAngle-this.startAngle)/2,i=(this.outerRadius-this.innerRadius)/2+this.innerRadius;return{x:this.x+Math.cos(t)*i,y:this.y+Math.sin(t)*i}},draw:function(t){var i=this.ctx;i.beginPath(),i.arc(this.x,this.y,this.outerRadius,this.startAngle,this.endAngle),i.arc(this.x,this.y,this.innerRadius,this.endAngle,this.startAngle,!0),i.closePath(),i.strokeStyle=this.strokeColor,i.lineWidth=this.strokeWidth,i.fillStyle=this.fillColor,i.fill(),i.lineJoin="bevel",this.showStroke&&i.stroke()}}),e.Rectangle=e.Element.extend({draw:function(){var t=this.ctx,i=this.width/2,e=this.x-i,s=this.x+i,n=this.base-(this.base-this.y),o=this.strokeWidth/2;this.showStroke&&(e+=o,s-=o,n+=o),t.beginPath(),t.fillStyle=this.fillColor,t.strokeStyle=this.strokeColor,t.lineWidth=this.strokeWidth,t.moveTo(e,this.base),t.lineTo(e,n),t.lineTo(s,n),t.lineTo(s,this.base),t.fill(),this.showStroke&&t.stroke()},height:function(){return this.base-this.y},inRange:function(t,i){return t>=this.x-this.width/2&&t<=this.x+this.width/2&&i>=this.y&&i<=this.base}}),e.Tooltip=e.Element.extend({draw:function(){var t=this.chart.ctx;t.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.xAlign="center",this.yAlign="above";var i=this.caretPadding=2,e=t.measureText(this.text).width+2*this.xPadding,s=this.fontSize+2*this.yPadding,n=s+this.caretHeight+i;this.x+e/2>this.chart.width?this.xAlign="left":this.x-e/2<0&&(this.xAlign="right"),this.y-n<0&&(this.yAlign="below");var o=this.x-e/2,a=this.y-n;if(t.fillStyle=this.fillColor,this.custom)this.custom(this);else{switch(this.yAlign){case"above":t.beginPath(),t.moveTo(this.x,this.y-i),t.lineTo(this.x+this.caretHeight,this.y-(i+this.caretHeight)),t.lineTo(this.x-this.caretHeight,this.y-(i+this.caretHeight)),t.closePath(),t.fill();break;case"below":a=this.y+i+this.caretHeight,t.beginPath(),t.moveTo(this.x,this.y+i),t.lineTo(this.x+this.caretHeight,this.y+i+this.caretHeight),t.lineTo(this.x-this.caretHeight,this.y+i+this.caretHeight),t.closePath(),t.fill()}switch(this.xAlign){case"left":o=this.x-e+(this.cornerRadius+this.caretHeight);break;case"right":o=this.x-(this.cornerRadius+this.caretHeight)}B(t,o,a,e,s,this.cornerRadius),t.fill(),t.fillStyle=this.textColor,t.textAlign="center",t.textBaseline="middle",t.fillText(this.text,o+e/2,a+s/2)}}}),e.MultiTooltip=e.Element.extend({initialize:function(){this.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.titleFont=W(this.titleFontSize,this.titleFontStyle,this.titleFontFamily),this.height=this.labels.length*this.fontSize+(this.labels.length-1)*(this.fontSize/2)+2*this.yPadding+1.5*this.titleFontSize,this.ctx.font=this.titleFont;var t=this.ctx.measureText(this.title).width,i=z(this.ctx,this.font,this.labels)+this.fontSize+3,e=g([i,t]);this.width=e+2*this.xPadding;var s=this.height/2;this.y-s<0?this.y=s:this.y+s>this.chart.height&&(this.y=this.chart.height-s),this.x>this.chart.width/2?this.x-=this.xOffset+this.width:this.x+=this.xOffset},getLineHeight:function(t){var i=this.y-this.height/2+this.yPadding,e=t-1;return 0===t?i+this.titleFontSize/2:i+(1.5*this.fontSize*e+this.fontSize/2)+1.5*this.titleFontSize},draw:function(){if(this.custom)this.custom(this);else{B(this.ctx,this.x,this.y-this.height/2,this.width,this.height,this.cornerRadius);var t=this.ctx;t.fillStyle=this.fillColor,t.fill(),t.closePath(),t.textAlign="left",t.textBaseline="middle",t.fillStyle=this.titleTextColor,t.font=this.titleFont,t.fillText(this.title,this.x+this.xPadding,this.getLineHeight(0)),t.font=this.font,s.each(this.labels,function(i,e){t.fillStyle=this.textColor,t.fillText(i,this.x+this.xPadding+this.fontSize+3,this.getLineHeight(e+1)),t.fillStyle=this.legendColorBackground,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize),t.fillStyle=this.legendColors[e].fill,t.fillRect(this.x+this.xPadding,this.getLineHeight(e+1)-this.fontSize/2,this.fontSize,this.fontSize)},this)}}}),e.Scale=e.Element.extend({initialize:function(){this.fit()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}));this.yLabelWidth=this.display&&this.showLabels?z(this.ctx,this.font,this.yLabels):0},addXLabel:function(t){this.xLabels.push(t),this.valuesCount++,this.fit()},removeXLabel:function(){this.xLabels.shift(),this.valuesCount--,this.fit()},fit:function(){this.startPoint=this.display?this.fontSize:0,this.endPoint=this.display?this.height-1.5*this.fontSize-5:this.height,this.startPoint+=this.padding,this.endPoint-=this.padding;var t,i=this.endPoint-this.startPoint;for(this.calculateYRange(i),this.buildYLabels(),this.calculateXLabelRotation();i>this.endPoint-this.startPoint;)i=this.endPoint-this.startPoint,t=this.yLabelWidth,this.calculateYRange(i),this.buildYLabels(),t<this.yLabelWidth&&this.calculateXLabelRotation()},calculateXLabelRotation:function(){this.ctx.font=this.font;var t,i,e=this.ctx.measureText(this.xLabels[0]).width,s=this.ctx.measureText(this.xLabels[this.xLabels.length-1]).width;if(this.xScalePaddingRight=s/2+3,this.xScalePaddingLeft=e/2>this.yLabelWidth+10?e/2:this.yLabelWidth+10,this.xLabelRotation=0,this.display){var n,o=z(this.ctx,this.font,this.xLabels);this.xLabelWidth=o;for(var a=Math.floor(this.calculateX(1)-this.calculateX(0))-6;this.xLabelWidth>a&&0===this.xLabelRotation||this.xLabelWidth>a&&this.xLabelRotation<=90&&this.xLabelRotation>0;)n=Math.cos(S(this.xLabelRotation)),t=n*e,i=n*s,t+this.fontSize/2>this.yLabelWidth+8&&(this.xScalePaddingLeft=t+this.fontSize/2),this.xScalePaddingRight=this.fontSize/2,this.xLabelRotation++,this.xLabelWidth=n*o;this.xLabelRotation>0&&(this.endPoint-=Math.sin(S(this.xLabelRotation))*o+3)}else this.xLabelWidth=0,this.xScalePaddingRight=this.padding,this.xScalePaddingLeft=this.padding},calculateYRange:c,drawingArea:function(){return this.startPoint-this.endPoint},calculateY:function(t){var i=this.drawingArea()/(this.min-this.max);return this.endPoint-i*(t-this.min)},calculateX:function(t){var i=(this.xLabelRotation>0,this.width-(this.xScalePaddingLeft+this.xScalePaddingRight)),e=i/Math.max(this.valuesCount-(this.offsetGridLines?0:1),1),s=e*t+this.xScalePaddingLeft;return this.offsetGridLines&&(s+=e/2),Math.round(s)},update:function(t){s.extend(this,t),this.fit()},draw:function(){var t=this.ctx,i=(this.endPoint-this.startPoint)/this.steps,e=Math.round(this.xScalePaddingLeft);this.display&&(t.fillStyle=this.textColor,t.font=this.font,n(this.yLabels,function(n,o){var a=this.endPoint-i*o,h=Math.round(a),l=this.showHorizontalLines;t.textAlign="right",t.textBaseline="middle",this.showLabels&&t.fillText(n,e-10,a),0!==o||l||(l=!0),l&&t.beginPath(),o>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),h+=s.aliasPixel(t.lineWidth),l&&(t.moveTo(e,h),t.lineTo(this.width,h),t.stroke(),t.closePath()),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(e-5,h),t.lineTo(e,h),t.stroke(),t.closePath()},this),n(this.xLabels,function(i,e){var s=this.calculateX(e)+x(this.lineWidth),n=this.calculateX(e-(this.offsetGridLines?.5:0))+x(this.lineWidth),o=this.xLabelRotation>0,a=this.showVerticalLines;0!==e||a||(a=!0),a&&t.beginPath(),e>0?(t.lineWidth=this.gridLineWidth,t.strokeStyle=this.gridLineColor):(t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor),a&&(t.moveTo(n,this.endPoint),t.lineTo(n,this.startPoint-3),t.stroke(),t.closePath()),t.lineWidth=this.lineWidth,t.strokeStyle=this.lineColor,t.beginPath(),t.moveTo(n,this.endPoint),t.lineTo(n,this.endPoint+5),t.stroke(),t.closePath(),t.save(),t.translate(s,o?this.endPoint+12:this.endPoint+8),t.rotate(-1*S(this.xLabelRotation)),t.font=this.font,t.textAlign=o?"right":"center",t.textBaseline=o?"middle":"top",t.fillText(i,0,0),t.restore()},this))}}),e.RadialScale=e.Element.extend({initialize:function(){this.size=m([this.height,this.width]),this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2},calculateCenterOffset:function(t){var i=this.drawingArea/(this.max-this.min);return(t-this.min)*i},update:function(){this.lineArc?this.drawingArea=this.display?this.size/2-(this.fontSize/2+this.backdropPaddingY):this.size/2:this.setScaleSize(),this.buildYLabels()},buildYLabels:function(){this.yLabels=[];for(var t=v(this.stepValue),i=0;i<=this.steps;i++)this.yLabels.push(C(this.templateString,{value:(this.min+i*this.stepValue).toFixed(t)}))},getCircumference:function(){return 2*Math.PI/this.valuesCount},setScaleSize:function(){var t,i,e,s,n,o,a,h,l,r,c,u,d=m([this.height/2-this.pointLabelFontSize-5,this.width/2]),p=this.width,g=0;for(this.ctx.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),i=0;i<this.valuesCount;i++)t=this.getPointPosition(i,d),e=this.ctx.measureText(C(this.templateString,{value:this.labels[i]})).width+5,0===i||i===this.valuesCount/2?(s=e/2,t.x+s>p&&(p=t.x+s,n=i),t.x-s<g&&(g=t.x-s,a=i)):i<this.valuesCount/2?t.x+e>p&&(p=t.x+e,n=i):i>this.valuesCount/2&&t.x-e<g&&(g=t.x-e,a=i);l=g,r=Math.ceil(p-this.width),o=this.getIndexAngle(n),h=this.getIndexAngle(a),c=r/Math.sin(o+Math.PI/2),u=l/Math.sin(h+Math.PI/2),c=f(c)?c:0,u=f(u)?u:0,this.drawingArea=d-(u+c)/2,this.setCenterPoint(u,c)},setCenterPoint:function(t,i){var e=this.width-i-this.drawingArea,s=t+this.drawingArea;this.xCenter=(s+e)/2,this.yCenter=this.height/2},getIndexAngle:function(t){var i=2*Math.PI/this.valuesCount;return t*i-Math.PI/2},getPointPosition:function(t,i){var e=this.getIndexAngle(t);return{x:Math.cos(e)*i+this.xCenter,y:Math.sin(e)*i+this.yCenter}},draw:function(){if(this.display){var t=this.ctx;if(n(this.yLabels,function(i,e){if(e>0){var s,n=e*(this.drawingArea/this.steps),o=this.yCenter-n;if(this.lineWidth>0)if(t.strokeStyle=this.lineColor,t.lineWidth=this.lineWidth,this.lineArc)t.beginPath(),t.arc(this.xCenter,this.yCenter,n,0,2*Math.PI),t.closePath(),t.stroke();else{t.beginPath();for(var a=0;a<this.valuesCount;a++)s=this.getPointPosition(a,this.calculateCenterOffset(this.min+e*this.stepValue)),0===a?t.moveTo(s.x,s.y):t.lineTo(s.x,s.y);t.closePath(),t.stroke()}if(this.showLabels){if(t.font=W(this.fontSize,this.fontStyle,this.fontFamily),this.showLabelBackdrop){var h=t.measureText(i).width;t.fillStyle=this.backdropColor,t.fillRect(this.xCenter-h/2-this.backdropPaddingX,o-this.fontSize/2-this.backdropPaddingY,h+2*this.backdropPaddingX,this.fontSize+2*this.backdropPaddingY)}t.textAlign="center",t.textBaseline="middle",t.fillStyle=this.fontColor,t.fillText(i,this.xCenter,o)}}},this),!this.lineArc){t.lineWidth=this.angleLineWidth,t.strokeStyle=this.angleLineColor;for(var i=this.valuesCount-1;i>=0;i--){if(this.angleLineWidth>0){var e=this.getPointPosition(i,this.calculateCenterOffset(this.max));t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(e.x,e.y),t.stroke(),t.closePath()}var s=this.getPointPosition(i,this.calculateCenterOffset(this.max)+5);t.font=W(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily),t.fillStyle=this.pointLabelFontColor;var o=this.labels.length,a=this.labels.length/2,h=a/2,l=h>i||i>o-h,r=i===h||i===o-h;t.textAlign=0===i?"center":i===a?"center":a>i?"left":"right",t.textBaseline=r?"middle":l?"bottom":"top",t.fillText(this.labels[i],s.x,s.y)}}}}}),s.addEvent(window,"resize",function(){var t;return function(){clearTimeout(t),t=setTimeout(function(){n(e.instances,function(t){t.options.responsive&&t.resize(t.render,!0)})},50)}}()),p?define(function(){return e}):"object"==typeof module&&module.exports&&(module.exports=e),t.Chart=e,e.noConflict=function(){return t.Chart=i,e}}).call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleBeginAtZero:!0,scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,scaleShowHorizontalLines:!0,scaleShowVerticalLines:!0,barShowStroke:!0,barStrokeWidth:2,barValueSpacing:5,barDatasetSpacing:1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].fillColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"Bar",defaults:s,initialize:function(t){var s=this.options;this.ScaleClass=i.Scale.extend({offsetGridLines:!0,calculateBarX:function(t,i,e){var n=this.calculateBaseWidth(),o=this.calculateX(e)-n/2,a=this.calculateBarWidth(t);return o+a*i+i*s.barDatasetSpacing+a/2},calculateBaseWidth:function(){return this.calculateX(1)-this.calculateX(0)-2*s.barValueSpacing},calculateBarWidth:function(t){var i=this.calculateBaseWidth()-(t-1)*s.barDatasetSpacing;return i/t}}),this.datasets=[],this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getBarsAtEvent(t):[];this.eachBars(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),this.BarClass=i.Rectangle.extend({strokeWidth:this.options.barStrokeWidth,showStroke:this.options.barShowStroke,ctx:this.chart.ctx}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,bars:[]};this.datasets.push(s),e.each(i.data,function(e,n){s.bars.push(new this.BarClass({value:e,label:t.labels[n],datasetLabel:i.label,strokeColor:i.strokeColor,fillColor:i.fillColor,highlightFill:i.highlightFill||i.fillColor,highlightStroke:i.highlightStroke||i.strokeColor}))},this)},this),this.buildScale(t.labels),this.BarClass.prototype.base=this.scale.endPoint,this.eachBars(function(t,i,s){e.extend(t,{width:this.scale.calculateBarWidth(this.datasets.length),x:this.scale.calculateBarX(this.datasets.length,s,i),y:this.scale.endPoint}),t.save()},this),this.render()},update:function(){this.scale.update(),e.each(this.activeElements,function(t){t.restore(["fillColor","strokeColor"])}),this.eachBars(function(t){t.save()}),this.render()},eachBars:function(t){e.each(this.datasets,function(i,s){e.each(i.bars,t,this,s)},this)},getBarsAtEvent:function(t){for(var i,s=[],n=e.getRelativePosition(t),o=function(t){s.push(t.bars[i])},a=0;a<this.datasets.length;a++)for(i=0;i<this.datasets[a].bars.length;i++)if(this.datasets[a].bars[i].inRange(n.x,n.y))return e.each(this.datasets,o),s;return s},buildScale:function(t){var i=this,s=function(){var t=[];return i.eachBars(function(i){t.push(i.value)}),t},n={templateString:this.options.scaleLabel,height:this.chart.height,width:this.chart.width,ctx:this.chart.ctx,textColor:this.options.scaleFontColor,fontSize:this.options.scaleFontSize,fontStyle:this.options.scaleFontStyle,fontFamily:this.options.scaleFontFamily,valuesCount:t.length,beginAtZero:this.options.scaleBeginAtZero,integersOnly:this.options.scaleIntegersOnly,calculateYRange:function(t){var i=e.calculateScaleRange(s(),t,this.fontSize,this.beginAtZero,this.integersOnly);e.extend(this,i)},xLabels:t,font:e.fontString(this.options.scaleFontSize,this.options.scaleFontStyle,this.options.scaleFontFamily),lineWidth:this.options.scaleLineWidth,lineColor:this.options.scaleLineColor,showHorizontalLines:this.options.scaleShowHorizontalLines,showVerticalLines:this.options.scaleShowVerticalLines,gridLineWidth:this.options.scaleShowGridLines?this.options.scaleGridLineWidth:0,gridLineColor:this.options.scaleShowGridLines?this.options.scaleGridLineColor:"rgba(0,0,0,0)",padding:this.options.showScale?0:this.options.barShowStroke?this.options.barStrokeWidth:0,showLabels:this.options.scaleShowLabels,display:this.options.showScale};this.options.scaleOverride&&e.extend(n,{calculateYRange:e.noop,steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}),this.scale=new this.ScaleClass(n)},addData:function(t,i){e.each(t,function(t,e){this.datasets[e].bars.push(new this.BarClass({value:t,label:i,x:this.scale.calculateBarX(this.datasets.length,e,this.scale.valuesCount+1),y:this.scale.endPoint,width:this.scale.calculateBarWidth(this.datasets.length),base:this.scale.endPoint,strokeColor:this.datasets[e].strokeColor,fillColor:this.datasets[e].fillColor})) +},this),this.scale.addXLabel(i),this.update()},removeData:function(){this.scale.removeXLabel(),e.each(this.datasets,function(t){t.bars.shift()},this),this.update()},reflow:function(){e.extend(this.BarClass.prototype,{y:this.scale.endPoint,base:this.scale.endPoint});var t=e.extend({height:this.chart.height,width:this.chart.width});this.scale.update(t)},draw:function(t){var i=t||1;this.clear();this.chart.ctx;this.scale.draw(i),e.each(this.datasets,function(t,s){e.each(t.bars,function(t,e){t.hasValue()&&(t.base=this.scale.endPoint,t.transition({x:this.scale.calculateBarX(this.datasets.length,s,e),y:this.scale.calculateY(t.value),width:this.scale.calculateBarWidth(this.datasets.length)},i).draw())},this)},this)}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,percentageInnerCutout:50,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"Doughnut",defaults:s,initialize:function(t){this.segments=[],this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,this.SegmentArc=i.Arc.extend({ctx:this.chart.ctx,x:this.chart.width/2,y:this.chart.height/2}),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.calculateTotal(t),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({value:t.value,outerRadius:this.options.animateScale?0:this.outerRadius,innerRadius:this.options.animateScale?0:this.outerRadius/100*this.options.percentageInnerCutout,fillColor:t.color,highlightColor:t.highlight||t.color,showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,startAngle:1.5*Math.PI,circumference:this.options.animateRotate?0:this.calculateCircumference(t.value),label:t.label})),e||(this.reflow(),this.update())},calculateCircumference:function(t){return 2*Math.PI*(Math.abs(t)/this.total)},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=Math.abs(t.value)},this)},update:function(){this.calculateTotal(this.segments),e.each(this.activeElements,function(t){t.restore(["fillColor"])}),e.each(this.segments,function(t){t.save()}),this.render()},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.outerRadius=(e.min([this.chart.width,this.chart.height])-this.options.segmentStrokeWidth/2)/2,e.each(this.segments,function(t){t.update({outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout})},this)},draw:function(t){var i=t?t:1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.calculateCircumference(t.value),outerRadius:this.outerRadius,innerRadius:this.outerRadius/100*this.options.percentageInnerCutout},i),t.endAngle=t.startAngle+t.circumference,t.draw(),0===e&&(t.startAngle=1.5*Math.PI),e<this.segments.length-1&&(this.segments[e+1].startAngle=t.endAngle)},this)}}),i.types.Doughnut.extend({name:"Pie",defaults:e.merge(s,{percentageInnerCutout:0})})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowGridLines:!0,scaleGridLineColor:"rgba(0,0,0,.05)",scaleGridLineWidth:1,scaleShowHorizontalLines:!0,scaleShowVerticalLines:!0,bezierCurve:!0,bezierCurveTension:.4,pointDot:!0,pointDotRadius:4,pointDotStrokeWidth:1,pointHitDetectionRadius:20,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].strokeColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"Line",defaults:s,initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx,inRange:function(t){return Math.pow(t-this.x,2)<Math.pow(this.radius+this.hitDetectionRadius,2)}}),this.datasets=[],this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this),this.buildScale(t.labels),this.eachPoints(function(t,i){e.extend(t,{x:this.scale.calculateX(i),y:this.scale.endPoint}),t.save()},this)},this),this.render()},update:function(){this.scale.update(),e.each(this.activeElements,function(t){t.restore(["fillColor","strokeColor"])}),this.eachPoints(function(t){t.save()}),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.datasets,function(t){e.each(t.points,function(t){t.inRange(s.x,s.y)&&i.push(t)})},this),i},buildScale:function(t){var s=this,n=function(){var t=[];return s.eachPoints(function(i){t.push(i.value)}),t},o={templateString:this.options.scaleLabel,height:this.chart.height,width:this.chart.width,ctx:this.chart.ctx,textColor:this.options.scaleFontColor,fontSize:this.options.scaleFontSize,fontStyle:this.options.scaleFontStyle,fontFamily:this.options.scaleFontFamily,valuesCount:t.length,beginAtZero:this.options.scaleBeginAtZero,integersOnly:this.options.scaleIntegersOnly,calculateYRange:function(t){var i=e.calculateScaleRange(n(),t,this.fontSize,this.beginAtZero,this.integersOnly);e.extend(this,i)},xLabels:t,font:e.fontString(this.options.scaleFontSize,this.options.scaleFontStyle,this.options.scaleFontFamily),lineWidth:this.options.scaleLineWidth,lineColor:this.options.scaleLineColor,showHorizontalLines:this.options.scaleShowHorizontalLines,showVerticalLines:this.options.scaleShowVerticalLines,gridLineWidth:this.options.scaleShowGridLines?this.options.scaleGridLineWidth:0,gridLineColor:this.options.scaleShowGridLines?this.options.scaleGridLineColor:"rgba(0,0,0,0)",padding:this.options.showScale?0:this.options.pointDotRadius+this.options.pointDotStrokeWidth,showLabels:this.options.scaleShowLabels,display:this.options.showScale};this.options.scaleOverride&&e.extend(o,{calculateYRange:e.noop,steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}),this.scale=new i.Scale(o)},addData:function(t,i){e.each(t,function(t,e){this.datasets[e].points.push(new this.PointClass({value:t,label:i,x:this.scale.calculateX(this.scale.valuesCount+1),y:this.scale.endPoint,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.addXLabel(i),this.update()},removeData:function(){this.scale.removeXLabel(),e.each(this.datasets,function(t){t.points.shift()},this),this.update()},reflow:function(){var t=e.extend({height:this.chart.height,width:this.chart.width});this.scale.update(t)},draw:function(t){var i=t||1;this.clear();var s=this.chart.ctx,n=function(t){return null!==t.value},o=function(t,i,s){return e.findNextWhere(i,n,s)||t},a=function(t,i,s){return e.findPreviousWhere(i,n,s)||t};this.scale.draw(i),e.each(this.datasets,function(t){var h=e.where(t.points,n);e.each(t.points,function(t,e){t.hasValue()&&t.transition({y:this.scale.calculateY(t.value),x:this.scale.calculateX(e)},i)},this),this.options.bezierCurve&&e.each(h,function(t,i){var s=i>0&&i<h.length-1?this.options.bezierCurveTension:0;t.controlPoints=e.splineCurve(a(t,h,i),t,o(t,h,i),s),t.controlPoints.outer.y>this.scale.endPoint?t.controlPoints.outer.y=this.scale.endPoint:t.controlPoints.outer.y<this.scale.startPoint&&(t.controlPoints.outer.y=this.scale.startPoint),t.controlPoints.inner.y>this.scale.endPoint?t.controlPoints.inner.y=this.scale.endPoint:t.controlPoints.inner.y<this.scale.startPoint&&(t.controlPoints.inner.y=this.scale.startPoint)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(h,function(t,i){if(0===i)s.moveTo(t.x,t.y);else if(this.options.bezierCurve){var e=a(t,h,i);s.bezierCurveTo(e.controlPoints.outer.x,e.controlPoints.outer.y,t.controlPoints.inner.x,t.controlPoints.inner.y,t.x,t.y)}else s.lineTo(t.x,t.y)},this),s.stroke(),this.options.datasetFill&&h.length>0&&(s.lineTo(h[h.length-1].x,this.scale.endPoint),s.lineTo(h[0].x,this.scale.endPoint),s.fillStyle=t.fillColor,s.closePath(),s.fill()),e.each(h,function(t){t.draw()})},this)}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers,s={scaleShowLabelBackdrop:!0,scaleBackdropColor:"rgba(255,255,255,0.75)",scaleBeginAtZero:!0,scaleBackdropPaddingY:2,scaleBackdropPaddingX:2,scaleShowLine:!0,segmentShowStroke:!0,segmentStrokeColor:"#fff",segmentStrokeWidth:2,animationSteps:100,animationEasing:"easeOutBounce",animateRotate:!0,animateScale:!1,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'};i.Type.extend({name:"PolarArea",defaults:s,initialize:function(t){this.segments=[],this.SegmentArc=i.Arc.extend({showStroke:this.options.segmentShowStroke,strokeWidth:this.options.segmentStrokeWidth,strokeColor:this.options.segmentStrokeColor,ctx:this.chart.ctx,innerRadius:0,x:this.chart.width/2,y:this.chart.height/2}),this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,lineArc:!0,width:this.chart.width,height:this.chart.height,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,valuesCount:t.length}),this.updateScaleRange(t),this.scale.update(),e.each(t,function(t,i){this.addData(t,i,!0)},this),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getSegmentsAtEvent(t):[];e.each(this.segments,function(t){t.restore(["fillColor"])}),e.each(i,function(t){t.fillColor=t.highlightColor}),this.showTooltip(i)}),this.render()},getSegmentsAtEvent:function(t){var i=[],s=e.getRelativePosition(t);return e.each(this.segments,function(t){t.inRange(s.x,s.y)&&i.push(t)},this),i},addData:function(t,i,e){var s=i||this.segments.length;this.segments.splice(s,0,new this.SegmentArc({fillColor:t.color,highlightColor:t.highlight||t.color,label:t.label,value:t.value,outerRadius:this.options.animateScale?0:this.scale.calculateCenterOffset(t.value),circumference:this.options.animateRotate?0:this.scale.getCircumference(),startAngle:1.5*Math.PI})),e||(this.reflow(),this.update())},removeData:function(t){var i=e.isNumber(t)?t:this.segments.length-1;this.segments.splice(i,1),this.reflow(),this.update()},calculateTotal:function(t){this.total=0,e.each(t,function(t){this.total+=t.value},this),this.scale.valuesCount=this.segments.length},updateScaleRange:function(t){var i=[];e.each(t,function(t){i.push(t.value)});var s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s,{size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2})},update:function(){this.calculateTotal(this.segments),e.each(this.segments,function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.SegmentArc.prototype,{x:this.chart.width/2,y:this.chart.height/2}),this.updateScaleRange(this.segments),this.scale.update(),e.extend(this.scale,{xCenter:this.chart.width/2,yCenter:this.chart.height/2}),e.each(this.segments,function(t){t.update({outerRadius:this.scale.calculateCenterOffset(t.value)})},this)},draw:function(t){var i=t||1;this.clear(),e.each(this.segments,function(t,e){t.transition({circumference:this.scale.getCircumference(),outerRadius:this.scale.calculateCenterOffset(t.value)},i),t.endAngle=t.startAngle+t.circumference,0===e&&(t.startAngle=1.5*Math.PI),e<this.segments.length-1&&(this.segments[e+1].startAngle=t.endAngle),t.draw()},this),this.scale.draw()}})}.call(this),function(){"use strict";var t=this,i=t.Chart,e=i.helpers;i.Type.extend({name:"Radar",defaults:{scaleShowLine:!0,angleShowLineOut:!0,scaleShowLabels:!1,scaleBeginAtZero:!0,angleLineColor:"rgba(0,0,0,.1)",angleLineWidth:1,pointLabelFontFamily:"'Arial'",pointLabelFontStyle:"normal",pointLabelFontSize:10,pointLabelFontColor:"#666",pointDot:!0,pointDotRadius:3,pointDotStrokeWidth:1,pointHitDetectionRadius:20,datasetStroke:!0,datasetStrokeWidth:2,datasetFill:!0,legendTemplate:'<ul class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<datasets.length; i++){%><li><span style="background-color:<%=datasets[i].strokeColor%>"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>'},initialize:function(t){this.PointClass=i.Point.extend({strokeWidth:this.options.pointDotStrokeWidth,radius:this.options.pointDotRadius,display:this.options.pointDot,hitDetectionRadius:this.options.pointHitDetectionRadius,ctx:this.chart.ctx}),this.datasets=[],this.buildScale(t),this.options.showTooltips&&e.bindEvents(this,this.options.tooltipEvents,function(t){var i="mouseout"!==t.type?this.getPointsAtEvent(t):[];this.eachPoints(function(t){t.restore(["fillColor","strokeColor"])}),e.each(i,function(t){t.fillColor=t.highlightFill,t.strokeColor=t.highlightStroke}),this.showTooltip(i)}),e.each(t.datasets,function(i){var s={label:i.label||null,fillColor:i.fillColor,strokeColor:i.strokeColor,pointColor:i.pointColor,pointStrokeColor:i.pointStrokeColor,points:[]};this.datasets.push(s),e.each(i.data,function(e,n){var o;this.scale.animation||(o=this.scale.getPointPosition(n,this.scale.calculateCenterOffset(e))),s.points.push(new this.PointClass({value:e,label:t.labels[n],datasetLabel:i.label,x:this.options.animation?this.scale.xCenter:o.x,y:this.options.animation?this.scale.yCenter:o.y,strokeColor:i.pointStrokeColor,fillColor:i.pointColor,highlightFill:i.pointHighlightFill||i.pointColor,highlightStroke:i.pointHighlightStroke||i.pointStrokeColor}))},this)},this),this.render()},eachPoints:function(t){e.each(this.datasets,function(i){e.each(i.points,t,this)},this)},getPointsAtEvent:function(t){var i=e.getRelativePosition(t),s=e.getAngleFromPoint({x:this.scale.xCenter,y:this.scale.yCenter},i),n=2*Math.PI/this.scale.valuesCount,o=Math.round((s.angle-1.5*Math.PI)/n),a=[];return(o>=this.scale.valuesCount||0>o)&&(o=0),s.distance<=this.scale.drawingArea&&e.each(this.datasets,function(t){a.push(t.points[o])}),a},buildScale:function(t){this.scale=new i.RadialScale({display:this.options.showScale,fontStyle:this.options.scaleFontStyle,fontSize:this.options.scaleFontSize,fontFamily:this.options.scaleFontFamily,fontColor:this.options.scaleFontColor,showLabels:this.options.scaleShowLabels,showLabelBackdrop:this.options.scaleShowLabelBackdrop,backdropColor:this.options.scaleBackdropColor,backdropPaddingY:this.options.scaleBackdropPaddingY,backdropPaddingX:this.options.scaleBackdropPaddingX,lineWidth:this.options.scaleShowLine?this.options.scaleLineWidth:0,lineColor:this.options.scaleLineColor,angleLineColor:this.options.angleLineColor,angleLineWidth:this.options.angleShowLineOut?this.options.angleLineWidth:0,pointLabelFontColor:this.options.pointLabelFontColor,pointLabelFontSize:this.options.pointLabelFontSize,pointLabelFontFamily:this.options.pointLabelFontFamily,pointLabelFontStyle:this.options.pointLabelFontStyle,height:this.chart.height,width:this.chart.width,xCenter:this.chart.width/2,yCenter:this.chart.height/2,ctx:this.chart.ctx,templateString:this.options.scaleLabel,labels:t.labels,valuesCount:t.datasets[0].data.length}),this.scale.setScaleSize(),this.updateScaleRange(t.datasets),this.scale.buildYLabels()},updateScaleRange:function(t){var i=function(){var i=[];return e.each(t,function(t){t.data?i=i.concat(t.data):e.each(t.points,function(t){i.push(t.value)})}),i}(),s=this.options.scaleOverride?{steps:this.options.scaleSteps,stepValue:this.options.scaleStepWidth,min:this.options.scaleStartValue,max:this.options.scaleStartValue+this.options.scaleSteps*this.options.scaleStepWidth}:e.calculateScaleRange(i,e.min([this.chart.width,this.chart.height])/2,this.options.scaleFontSize,this.options.scaleBeginAtZero,this.options.scaleIntegersOnly);e.extend(this.scale,s)},addData:function(t,i){this.scale.valuesCount++,e.each(t,function(t,e){var s=this.scale.getPointPosition(this.scale.valuesCount,this.scale.calculateCenterOffset(t));this.datasets[e].points.push(new this.PointClass({value:t,label:i,x:s.x,y:s.y,strokeColor:this.datasets[e].pointStrokeColor,fillColor:this.datasets[e].pointColor}))},this),this.scale.labels.push(i),this.reflow(),this.update()},removeData:function(){this.scale.valuesCount--,this.scale.labels.shift(),e.each(this.datasets,function(t){t.points.shift()},this),this.reflow(),this.update()},update:function(){this.eachPoints(function(t){t.save()}),this.reflow(),this.render()},reflow:function(){e.extend(this.scale,{width:this.chart.width,height:this.chart.height,size:e.min([this.chart.width,this.chart.height]),xCenter:this.chart.width/2,yCenter:this.chart.height/2}),this.updateScaleRange(this.datasets),this.scale.setScaleSize(),this.scale.buildYLabels()},draw:function(t){var i=t||1,s=this.chart.ctx;this.clear(),this.scale.draw(),e.each(this.datasets,function(t){e.each(t.points,function(t,e){t.hasValue()&&t.transition(this.scale.getPointPosition(e,this.scale.calculateCenterOffset(t.value)),i)},this),s.lineWidth=this.options.datasetStrokeWidth,s.strokeStyle=t.strokeColor,s.beginPath(),e.each(t.points,function(t,i){0===i?s.moveTo(t.x,t.y):s.lineTo(t.x,t.y)},this),s.closePath(),s.stroke(),s.fillStyle=t.fillColor,s.fill(),e.each(t.points,function(t){t.hasValue()&&t.draw()})},this)}})}.call(this);
\ No newline at end of file diff --git a/modules-available/js_chart/config.json b/modules-available/js_chart/config.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/modules-available/js_chart/config.json @@ -0,0 +1 @@ +{}
\ No newline at end of file diff --git a/modules-available/js_circles/clientscript.js b/modules-available/js_circles/clientscript.js new file mode 100644 index 00000000..0fc701eb --- /dev/null +++ b/modules-available/js_circles/clientscript.js @@ -0,0 +1,7 @@ +/** + * circles - v0.0.6 - 2015-05-27 + * + * Copyright (c) 2015 lugolabs + * Licensed + */ +!function(){"use strict";var a=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,1e3/60)},b=window.Circles=function(a){var b=a.id;if(this._el=document.getElementById(b),null!==this._el){this._radius=a.radius||10,this._duration=void 0===a.duration?500:a.duration,this._value=0,this._maxValue=a.maxValue||100,this._text=void 0===a.text?function(a){return this.htmlifyNumber(a)}:a.text,this._strokeWidth=a.width||10,this._colors=a.colors||["#EEE","#F00"],this._svg=null,this._movingPath=null,this._wrapContainer=null,this._textContainer=null,this._wrpClass=a.wrpClass||"circles-wrp",this._textClass=a.textClass||"circles-text",this._valClass=a.valueStrokeClass||"circles-valueStroke",this._maxValClass=a.maxValueStrokeClass||"circles-maxValueStroke",this._styleWrapper=a.styleWrapper===!1?!1:!0,this._styleText=a.styleText===!1?!1:!0;var c=Math.PI/180*270;this._start=-Math.PI/180*90,this._startPrecise=this._precise(this._start),this._circ=c-this._start,this._generate().update(a.value||0)}};b.prototype={VERSION:"0.0.6",_generate:function(){return this._svgSize=2*this._radius,this._radiusAdjusted=this._radius-this._strokeWidth/2,this._generateSvg()._generateText()._generateWrapper(),this._el.innerHTML="",this._el.appendChild(this._wrapContainer),this},_setPercentage:function(a){this._movingPath.setAttribute("d",this._calculatePath(a,!0)),this._textContainer.innerHTML=this._getText(this.getValueFromPercent(a))},_generateWrapper:function(){return this._wrapContainer=document.createElement("div"),this._wrapContainer.className=this._wrpClass,this._styleWrapper&&(this._wrapContainer.style.position="relative",this._wrapContainer.style.display="inline-block"),this._wrapContainer.appendChild(this._svg),this._wrapContainer.appendChild(this._textContainer),this},_generateText:function(){if(this._textContainer=document.createElement("div"),this._textContainer.className=this._textClass,this._styleText){var a={position:"absolute",top:0,left:0,textAlign:"center",width:"100%",fontSize:.7*this._radius+"px",height:this._svgSize+"px",lineHeight:this._svgSize+"px"};for(var b in a)this._textContainer.style[b]=a[b]}return this._textContainer.innerHTML=this._getText(0),this},_getText:function(a){return this._text?(void 0===a&&(a=this._value),a=parseFloat(a.toFixed(2)),"function"==typeof this._text?this._text.call(this,a):this._text):""},_generateSvg:function(){return this._svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this._svg.setAttribute("xmlns","http://www.w3.org/2000/svg"),this._svg.setAttribute("width",this._svgSize),this._svg.setAttribute("height",this._svgSize),this._generatePath(100,!1,this._colors[0],this._maxValClass)._generatePath(1,!0,this._colors[1],this._valClass),this._movingPath=this._svg.getElementsByTagName("path")[1],this},_generatePath:function(a,b,c,d){var e=document.createElementNS("http://www.w3.org/2000/svg","path");return e.setAttribute("fill","transparent"),e.setAttribute("stroke",c),e.setAttribute("stroke-width",this._strokeWidth),e.setAttribute("d",this._calculatePath(a,b)),e.setAttribute("class",d),this._svg.appendChild(e),this},_calculatePath:function(a,b){var c=this._start+a/100*this._circ,d=this._precise(c);return this._arc(d,b)},_arc:function(a,b){var c=a-.001,d=a-this._startPrecise<Math.PI?0:1;return["M",this._radius+this._radiusAdjusted*Math.cos(this._startPrecise),this._radius+this._radiusAdjusted*Math.sin(this._startPrecise),"A",this._radiusAdjusted,this._radiusAdjusted,0,d,1,this._radius+this._radiusAdjusted*Math.cos(c),this._radius+this._radiusAdjusted*Math.sin(c),b?"":"Z"].join(" ")},_precise:function(a){return Math.round(1e3*a)/1e3},htmlifyNumber:function(a,b,c){b=b||"circles-integer",c=c||"circles-decimals";var d=(a+"").split("."),e='<span class="'+b+'">'+d[0]+"</span>";return d.length>1&&(e+='.<span class="'+c+'">'+d[1].substring(0,2)+"</span>"),e},updateRadius:function(a){return this._radius=a,this._generate().update(!0)},updateWidth:function(a){return this._strokeWidth=a,this._generate().update(!0)},updateColors:function(a){this._colors=a;var b=this._svg.getElementsByTagName("path");return b[0].setAttribute("stroke",a[0]),b[1].setAttribute("stroke",a[1]),this},getPercent:function(){return 100*this._value/this._maxValue},getValueFromPercent:function(a){return this._maxValue*a/100},getValue:function(){return this._value},getMaxValue:function(){return this._maxValue},update:function(b,c){if(b===!0)return this._setPercentage(this.getPercent()),this;if(this._value==b||isNaN(b))return this;void 0===c&&(c=this._duration);var d,e,f,g,h=this,i=h.getPercent(),j=1;return this._value=Math.min(this._maxValue,Math.max(0,b)),c?(d=h.getPercent(),e=d>i,j+=d%1,f=Math.floor(Math.abs(d-i)/j),g=c/f,function k(b){if(e?i+=j:i-=j,e&&i>=d||!e&&d>=i)return void a(function(){h._setPercentage(d)});a(function(){h._setPercentage(i)});var c=Date.now(),f=c-b;f>=g?k(c):setTimeout(function(){k(Date.now())},g-f)}(Date.now()),this):(this._setPercentage(this.getPercent()),this)}},b.create=function(a){return new b(a)}}();
\ No newline at end of file diff --git a/modules-available/js_circles/config.json b/modules-available/js_circles/config.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/modules-available/js_circles/config.json @@ -0,0 +1 @@ +{}
\ No newline at end of file diff --git a/modules-available/main/lang/de/global-tags.json b/modules-available/main/lang/de/global-tags.json index 39236fd4..a8fa0034 100644 --- a/modules-available/main/lang/de/global-tags.json +++ b/modules-available/main/lang/de/global-tags.json @@ -2,8 +2,10 @@ "lang_back": "Zur\u00fcck", "lang_cancel": "Abbrechen", "lang_close": "Schlie\u00dfen", + "lang_days": "Tag(e)", "lang_delete": "L\u00f6schen", "lang_hint": "Hinweis", + "lang_hours": "Stunde(n)", "lang_next": "Weiter", "lang_save": "Speichern", "lang_today": "Heute", diff --git a/modules-available/main/lang/de/template-tags.json b/modules-available/main/lang/de/template-tags.json index b299cbad..c11843a0 100644 --- a/modules-available/main/lang/de/template-tags.json +++ b/modules-available/main/lang/de/template-tags.json @@ -1,6 +1,5 @@ { - "lang_bootMenuWarning": "Das Bootmen\u00fc ist veraltet oder wurde noch nicht generiert.", - "lang_configure": "Konfigurieren", + "lang_goTo": "Gehe zu", "lang_intro": "Dies ist die bwLehrpool Konfigurationsoberfl\u00e4che.", "lang_introGuest": "Dies ist das Administrations-Interface der lokalen bwLehrpool-Installation. Bitte authentifizieren Sie sich, um Einstellungen vorzunehmen.", "lang_language": "Sprachen", @@ -8,16 +7,11 @@ "lang_loggedInSuffix": " ", "lang_login": "Anmelden", "lang_logout": "Abmelden", - "lang_minilinuxMissing": "Wichtige Dateien der MiniLinux-Installation fehlen.", "lang_needsSetup": "Einrichtung unvollst\u00e4ndig", "lang_noExistingAccount": "Es existiert noch kein Administrator-Zugang f\u00fcr diesen Satelliten-Server.", - "lang_numerOfImagesMarkedForDeletion": "Zur L\u00f6schung markierte Abbilder", "lang_register": "Registrieren", - "lang_systemConfiguration": "Systemkonfiguration", - "lang_systemConfigurationNotChosen": "Es wurde noch keine Systemkonfiguration ausgew\u00e4hlt.", "lang_toggleNavigation": "Navigation ein\/ausblenden", "lang_translations": "\u00dcbersetzungen", - "lang_vmLocationNotSet": "Es ist noch kein Speicherort f\u00fcr die Virtuellen Maschinen festgelegt.", "lang_warning": "Warnung", "lang_warningDebug": "Debugmodus aktiv!", "lang_welcome": "Willkommen" diff --git a/modules-available/main/lang/en/global-tags.json b/modules-available/main/lang/en/global-tags.json index 10581ae2..181f600a 100644 --- a/modules-available/main/lang/en/global-tags.json +++ b/modules-available/main/lang/en/global-tags.json @@ -2,8 +2,10 @@ "lang_back": "Back", "lang_cancel": "Cancel", "lang_close": "Close", + "lang_days": "day(s)", "lang_delete": "Delete", "lang_hint": "Hint", + "lang_hours": "hour(s)", "lang_next": "Next", "lang_save": "Save", "lang_today": "Today", diff --git a/modules-available/main/lang/en/template-tags.json b/modules-available/main/lang/en/template-tags.json index be03e53e..fcb34031 100644 --- a/modules-available/main/lang/en/template-tags.json +++ b/modules-available/main/lang/en/template-tags.json @@ -1,6 +1,5 @@ { - "lang_bootMenuWarning": "The boot menu is outdated or has not been generated.", - "lang_configure": "Configure", + "lang_goTo": "Gehe zu", "lang_intro": "This is the bwLehrpool configuration interface.", "lang_introGuest": "This is the administration interface of the local bwLehrpool intallation. Please authenticate yourself to adjust settings.", "lang_language": "Language", @@ -8,16 +7,11 @@ "lang_loggedInSuffix": " ", "lang_login": "Login", "lang_logout": "Logout", - "lang_minilinuxMissing": "Important files from the mini Linux installation are missing.", "lang_needsSetup": "Setup incomplete", "lang_noExistingAccount": "No account has been created yet. Sign up to become the administrator.", - "lang_numerOfImagesMarkedForDeletion": "Images marked for deletion", "lang_register": "Register", - "lang_systemConfiguration": "System Configuration", - "lang_systemConfigurationNotChosen": "A system configuration has not been chosen yet.", "lang_toggleNavigation": "toggle navigation", "lang_translations": "Translations", - "lang_vmLocationNotSet": "A location for the virtual machine is not set yet.", "lang_warning": "Warning", "lang_warningDebug": "Debug mode active!", "lang_welcome": "Welcome" diff --git a/modules-available/main/page.inc.php b/modules-available/main/page.inc.php index 0a9acd81..bd50a5d1 100644 --- a/modules-available/main/page.inc.php +++ b/modules-available/main/page.inc.php @@ -3,24 +3,9 @@ class Page_Main extends Page { - private $sysconfig; - private $minilinux; - private $vmstore; - private $ipxe; - private $delPending; - protected function doPreprocess() { User::load(); - if (User::isLoggedIn()) { - $this->sysconfig = !file_exists(CONFIG_HTTP_DIR . '/default/config.tgz'); - $this->minilinux = !file_exists(CONFIG_HTTP_DIR . '/default/kernel') || !file_exists(CONFIG_HTTP_DIR . '/default/initramfs-stage31') || !file_exists(CONFIG_HTTP_DIR . '/default/stage32.sqfs'); - $this->vmstore = !is_array(Property::getVmStoreConfig()); - $this->ipxe = !preg_match('/^\d+\.\d+\.\d+\.\d+$/', Property::getServerIp()); - Property::setNeedsSetup(($this->sysconfig || $this->minilinux || $this->vmstore || $this->ipxe) ? 1 : 0); - $res = Database::queryFirst("SELECT Count(*) AS cnt FROM sat.imageversion WHERE deletestate = 'SHOULD_DELETE'", array(), true); - $this->delPending = isset($res['cnt']) ? $res['cnt'] : 0; - } } protected function doRender() @@ -33,24 +18,21 @@ class Page_Main extends Page } // Logged in here - // Load news - $lines = array(); - $paginate = new Paginate("SELECT newsid, dateline, title, content FROM news ORDER BY dateline DESC", 10); - $res = $paginate->exec(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if(count($lines) >= 3) break; - $lines[] = $row; - } - Render::addTemplate('page-main', array( - 'user' => User::getName(), - 'sysconfig' => $this->sysconfig, - 'minilinux' => $this->minilinux, - 'vmstore' => $this->vmstore, - 'ipxe' => $this->ipxe, - 'delpending' => $this->delPending, - 'news' => $lines + 'user' => User::getName() )); + + // Warnings + $needSetup = false; + foreach (glob('modules/*/hooks/main-warning.inc.php') as $file) { + preg_match('#^modules/([^/]+)/#', $file, $out); + if (!Module::isAvailable($out[1])) + continue; + include $file; + } + + // Update warning state + Property::setNeedsSetup($needSetup ? 1 : 0); } protected function doAjax() diff --git a/modules-available/main/templates/messagebox-error.html b/modules-available/main/templates/messagebox-error.html deleted file mode 100644 index 873716c9..00000000 --- a/modules-available/main/templates/messagebox-error.html +++ /dev/null @@ -1 +0,0 @@ -<div class="alert alert-danger"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> {{{message}}}</div> diff --git a/modules-available/main/templates/messagebox-info.html b/modules-available/main/templates/messagebox-info.html deleted file mode 100644 index eb9d518a..00000000 --- a/modules-available/main/templates/messagebox-info.html +++ /dev/null @@ -1 +0,0 @@ -<div class="alert alert-info"><span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> {{{message}}}</div> diff --git a/modules-available/main/templates/messagebox-success.html b/modules-available/main/templates/messagebox-success.html deleted file mode 100644 index 93674d69..00000000 --- a/modules-available/main/templates/messagebox-success.html +++ /dev/null @@ -1 +0,0 @@ -<div class="alert alert-success"><span class="glyphicon glyphicon-ok" aria-hidden="true"></span> {{{message}}}</div> diff --git a/modules-available/main/templates/messagebox-warning.html b/modules-available/main/templates/messagebox-warning.html deleted file mode 100644 index b02e2e8a..00000000 --- a/modules-available/main/templates/messagebox-warning.html +++ /dev/null @@ -1 +0,0 @@ -<div class="alert alert-warning"><span class="glyphicon glyphicon-warning" aria-hidden="true"></span> {{{message}}}</div> diff --git a/modules-available/main/templates/messagebox.html b/modules-available/main/templates/messagebox.html new file mode 100644 index 00000000..45d5d8f6 --- /dev/null +++ b/modules-available/main/templates/messagebox.html @@ -0,0 +1,7 @@ +<div class="alert alert-{{type}}"> + <span class="glyphicon glyphicon-{{icon}}" aria-hidden="true"></span> + {{#link}} + <a class="pull-right" href="?do={{link}}">{{lang_goTo}} »</a> + {{/link}} + {{{message}}} +</div> diff --git a/modules-available/main/templates/page-main.html b/modules-available/main/templates/page-main.html index 39e4e74e..a0b2d3b0 100644 --- a/modules-available/main/templates/page-main.html +++ b/modules-available/main/templates/page-main.html @@ -3,34 +3,3 @@ <p>{{lang_intro}}</p> </div> -<ul class="list-group"> -{{#vmstore}} - <li class="list-group-item list-group-item-text"> - {{lang_vmLocationNotSet}} - <a class="btn btn-sm btn-primary" href="?do=VmStore">{{lang_configure}} »</a> - </li> -{{/vmstore}} -{{#ipxe}} - <li class="list-group-item list-group-item-text"> - {{lang_bootMenuWarning}} - <a class="btn btn-sm btn-primary" href="?do=ServerSetup">{{lang_configure}} »</a> - </li> -{{/ipxe}} -{{#minilinux}} - <li class="list-group-item list-group-item-text"> - {{lang_minilinuxMissing}} - <a class="btn btn-sm btn-primary" href="?do=MiniLinux">MiniLinux »</a> - </li> -{{/minilinux}} -{{#sysconfig}} - <li class="list-group-item list-group-item-text"> - {{lang_systemConfigurationNotChosen}} - <a class="btn btn-sm btn-primary" href="?do=SysConfig">{{lang_systemConfiguration}} »</a> - </li> -{{/sysconfig}} -{{#delpending}} - <li class="list-group-item list-group-item-text"> - <a href="?do=DozMod">{{lang_numerOfImagesMarkedForDeletion}}: {{delpending}}</a> - </li> -{{/delpending}} -</ul> diff --git a/modules-available/minilinux/hooks/main-warning.inc.php b/modules-available/minilinux/hooks/main-warning.inc.php new file mode 100644 index 00000000..2056bbbf --- /dev/null +++ b/modules-available/minilinux/hooks/main-warning.inc.php @@ -0,0 +1,6 @@ +<?php + +if (!file_exists(CONFIG_HTTP_DIR . '/default/kernel') || !file_exists(CONFIG_HTTP_DIR . '/default/initramfs-stage31') || !file_exists(CONFIG_HTTP_DIR . '/default/stage32.sqfs')) { + Message::addError('minilinux.please-download-minilinux'); + $needSetup = true; +}
\ No newline at end of file diff --git a/modules-available/minilinux/lang/de/messages.json b/modules-available/minilinux/lang/de/messages.json new file mode 100644 index 00000000..c91772c7 --- /dev/null +++ b/modules-available/minilinux/lang/de/messages.json @@ -0,0 +1,3 @@ +{ + "please-download-minilinux": "Wichtige Dateien der MiniLinux-Installation fehlen." +}
\ No newline at end of file diff --git a/modules-available/minilinux/lang/en/messages.json b/modules-available/minilinux/lang/en/messages.json new file mode 100644 index 00000000..8d7fa76d --- /dev/null +++ b/modules-available/minilinux/lang/en/messages.json @@ -0,0 +1,3 @@ +{ + "please-download-minilinux": "Important files from the mini Linux installation are missing." +}
\ No newline at end of file diff --git a/modules-available/serversetup/config.json b/modules-available/serversetup-bwlp/config.json index f2abe27c..f2abe27c 100644 --- a/modules-available/serversetup/config.json +++ b/modules-available/serversetup-bwlp/config.json diff --git a/modules-available/serversetup/lang/de/messages.json b/modules-available/serversetup-bwlp/lang/de/messages.json index cb0b229d..cb0b229d 100644 --- a/modules-available/serversetup/lang/de/messages.json +++ b/modules-available/serversetup-bwlp/lang/de/messages.json diff --git a/modules-available/serversetup/lang/de/module.json b/modules-available/serversetup-bwlp/lang/de/module.json index eb777343..eb777343 100644 --- a/modules-available/serversetup/lang/de/module.json +++ b/modules-available/serversetup-bwlp/lang/de/module.json diff --git a/modules-available/serversetup/lang/de/template-tags.json b/modules-available/serversetup-bwlp/lang/de/template-tags.json index bdbcb1ec..bdbcb1ec 100644 --- a/modules-available/serversetup/lang/de/template-tags.json +++ b/modules-available/serversetup-bwlp/lang/de/template-tags.json diff --git a/modules-available/serversetup/lang/en/messages.json b/modules-available/serversetup-bwlp/lang/en/messages.json index d96be232..d96be232 100644 --- a/modules-available/serversetup/lang/en/messages.json +++ b/modules-available/serversetup-bwlp/lang/en/messages.json diff --git a/modules-available/serversetup/lang/en/module.json b/modules-available/serversetup-bwlp/lang/en/module.json index aeea610c..aeea610c 100644 --- a/modules-available/serversetup/lang/en/module.json +++ b/modules-available/serversetup-bwlp/lang/en/module.json diff --git a/modules-available/serversetup/lang/en/template-tags.json b/modules-available/serversetup-bwlp/lang/en/template-tags.json index af22081a..af22081a 100644 --- a/modules-available/serversetup/lang/en/template-tags.json +++ b/modules-available/serversetup-bwlp/lang/en/template-tags.json diff --git a/modules-available/serversetup/lang/pt/messages.json b/modules-available/serversetup-bwlp/lang/pt/messages.json index 65745768..65745768 100644 --- a/modules-available/serversetup/lang/pt/messages.json +++ b/modules-available/serversetup-bwlp/lang/pt/messages.json diff --git a/modules-available/serversetup/lang/pt/module.json b/modules-available/serversetup-bwlp/lang/pt/module.json index aeea610c..aeea610c 100644 --- a/modules-available/serversetup/lang/pt/module.json +++ b/modules-available/serversetup-bwlp/lang/pt/module.json diff --git a/modules-available/serversetup/lang/pt/template-tags.json b/modules-available/serversetup-bwlp/lang/pt/template-tags.json index 3120c58c..3120c58c 100644 --- a/modules-available/serversetup/lang/pt/template-tags.json +++ b/modules-available/serversetup-bwlp/lang/pt/template-tags.json diff --git a/modules-available/serversetup/page.inc.php b/modules-available/serversetup-bwlp/page.inc.php index c48ccd3d..9a040178 100644 --- a/modules-available/serversetup/page.inc.php +++ b/modules-available/serversetup-bwlp/page.inc.php @@ -3,10 +3,10 @@ class Page_ServerSetup extends Page { - private $mountIpxeTask; private $taskStatus; private $currentAddress; private $currentMenu; + private $hasIpSet = false; protected function doPreprocess() { @@ -19,14 +19,6 @@ class Page_ServerSetup extends Page $this->currentMenu = Property::getBootMenu(); - if(Request::get('download') !== false){ - $this->downloadIpxe(Request::get('download')); - } - - if(Request::get('defaultIpxe') !== false){ - $this->defaultIpxe(Request::get('defaultIpxe')); - } - $action = Request::post('action'); if ($action === false) { @@ -44,48 +36,30 @@ class Page_ServerSetup extends Page // iPXE stuff changes $this->updatePxeMenu(); } - - if($action === 'save-script') { - // Save new iPXE script - $this->updateIpxeScript(); - } - - if($action === 'default-script') { - // Restore iPXE script to default - $this->defaultIpxe(); - } } protected function doRender() { - Render::setTitle(Dictionary::translate('lang_serverConfiguration')); $taskid = Request::any('taskid'); if ($taskid !== false && Taskmanager::isTask($taskid)) { Render::addTemplate('ipxe_update', array('taskid' => $taskid)); } - if (Request::get('advanced', 'false', 'string') === 'false') { - Render::addTemplate('ipxe-smp'); - } else { - Render::addTemplate('ipaddress', array( - 'ips' => $this->taskStatus['data']['addresses'] - )); - $data = $this->currentMenu; - if (!isset($data['defaultentry'])) - $data['defaultentry'] = 'net'; - if ($data['defaultentry'] === 'net') - $data['active-net'] = 'checked'; - if ($data['defaultentry'] === 'hdd') - $data['active-hdd'] = 'checked'; - if ($data['defaultentry'] === 'custom') - $data['active-custom'] = 'checked'; - //There is no $this->username and no pxe.embed, why do we need this? - //Page won't load with lines below uncommented - //$data['username'] = $this->username; - //$data['script'] = file_get_contents("/opt/taskmanager/data/pxe.embed"); - Render::addTemplate('ipxe-adv', $data); - } + Render::addTemplate('ipaddress', array( + 'ips' => $this->taskStatus['data']['addresses'], + 'chooseHintClass' => $this->hasIpSet ? '' : 'alert alert-danger' + )); + $data = $this->currentMenu; + if (!isset($data['defaultentry'])) + $data['defaultentry'] = 'net'; + if ($data['defaultentry'] === 'net') + $data['active-net'] = 'checked'; + if ($data['defaultentry'] === 'hdd') + $data['active-hdd'] = 'checked'; + if ($data['defaultentry'] === 'custom') + $data['active-custom'] = 'checked'; + Render::addTemplate('ipxe', $data); } // ----------------------------------------------------------------------------------------------- @@ -112,6 +86,7 @@ class Page_ServerSetup extends Page } if ($this->currentAddress === $item['ip']) { $item['default'] = true; + $this->hasIpSet = true; } $sortIp[] = $item['ip']; } @@ -162,33 +137,4 @@ class Page_ServerSetup extends Page Util::redirect('?do=ServerSetup&taskid=' . $id); } - private function downloadIpxe($ipxe){ - $file = '/opt/taskmanager/data/ipxe/src/bin/ipxe.' . $ipxe; - if (file_exists($file)) { - header('Content-Description: File Transfer'); - header('Content-Type: application/octet-stream'); - header('Content-Disposition: attachment; filename='.basename($file)); - header('Expires: 0'); - header('Cache-Control: must-revalidate'); - header('Pragma: public'); - header('Content-Length: ' . filesize($file)); - ob_clean(); - flush(); - readfile($file); - exit(); - } - } - - private function updateIpxeScript(){ - $newScript = Request::post('custom-script'); - file_put_contents("/opt/taskmanager/data/pxe.embed",$newScript); - Util::redirect('?do=ServerSetup'); - } - - private function defaultIpxe(){ - $default = file_get_contents("/opt/taskmanager/data/pxe_default.embed"); - $default = str_replace("{{ip}}", "http://" . Property::getServerIp(), $default); - file_put_contents("/opt/taskmanager/data/pxe.embed",$default); - Util::redirect('?do=ServerSetup'); - } } diff --git a/modules-available/serversetup/templates/ipaddress.html b/modules-available/serversetup-bwlp/templates/ipaddress.html index e4c1fba9..0b3b2ed7 100644 --- a/modules-available/serversetup/templates/ipaddress.html +++ b/modules-available/serversetup-bwlp/templates/ipaddress.html @@ -1,12 +1,11 @@ -<a class="btn btn-default" href="?do=Serversetup&advanced=false" role="button"><strong>{{lang_ipxeSmp}}</strong></a></br></br> <div class="panel panel-default"> <div class="panel-heading"> {{lang_bootAddress}} </div> <div class="panel-body"> - <p> + <div class="{{chooseHintClass}}"> {{lang_chooseIP}} - </p> + </div> <form method="post" action="?do=ServerSetup"> <input type="hidden" name="action" value="ip"> <input type="hidden" name="token" value="{{token}}"> @@ -32,4 +31,4 @@ </p> </form> </div> -</div> +</div>
\ No newline at end of file diff --git a/modules-available/serversetup-bwlp/templates/ipxe.html b/modules-available/serversetup-bwlp/templates/ipxe.html new file mode 100644 index 00000000..4539624b --- /dev/null +++ b/modules-available/serversetup-bwlp/templates/ipxe.html @@ -0,0 +1,70 @@ +<form method="post" action="?do=ServerSetup"> + <input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="display:none;"> + <input type="password" name="password_fake" id="password_fake" value="" style="display:none;"> + <input type="hidden" name="action" value="ipxe"> + <input type="hidden" name="token" value="{{token}}"> + <div class="panel panel-default"> + <div class="panel-heading"> + {{lang_bootMenu}} + </div> + <div class="panel-body"> + <p> + {{lang_bootInfo}} + </p> + <br> + + <div class="form-group"> + <strong>{{lang_bootBehavior}}</strong> + <div><label class="radio-inline"><input type="radio" name="defaultentry" value="net" {{active-net}}> bwLehrpool</label></div> + <div><label class="radio-inline"><input type="radio" name="defaultentry" value="hdd" {{active-hdd}}> {{lang_localHDD}}</label></div> + <div><label class="radio-inline"><input type="radio" name="defaultentry" value="custom" {{active-custom}}> {{lang_customEntry}} ("custom")</label></div> + </div> + + <div class="form-group"> + <strong>{{lang_menuDisplayTime}}</strong> + <div class="input-group form-narrow"> + <input type="text" class="form-control" name="timeout" value="{{timeout}}" pattern="\d+"> + <span class="input-group-addon">{{lang_seconds}}</span> + </div> + </div> + + <div class="form-group"> + <strong>{{lang_masterPassword}}</strong> + <div class="form-narrow"> + <input type="{{password_type}}" class="form-control" name="masterpassword" value="{{masterpasswordclear}}"> + </div> + <i>{{lang_masterPasswordHelp}}</i> + </div> + + <div class="form-group"> + <strong>{{lang_menuCustom}}</strong> <a class="btn btn-default btn-xs" data-toggle="modal" data-target="#help-custom"><span class="glyphicon glyphicon-question-sign"></span></a> + <textarea class="form-control" name="custom" rows="8">{{custom}}</textarea> + </div> + </div> + + <div class="panel-footer"> + <button class="btn btn-primary" name="action" value="ipxe">{{lang_bootMenuCreate}}</button> + </div> + </div> +</form> + +<div class="modal fade" id="help-custom" tabindex="-1" role="dialog"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header">{{lang_menuCustom}}</div> + <div class="modal-body"> + {{lang_menuCustomHint1}} + <br>{{lang_example}}: + <pre>LABEL custom + MENU LABEL ^My Boot Entry + KERNEL http://1.2.3.4/kernel + INITRD http://1.2.3.4/initramfs-stage31 + APPEND custom=option + IPAPPEND 3</pre> + {{lang_menuCustomHint2}} LABEL <strong>custom</strong> + {{lang_menuCustomHint3}} + </div> + <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div> + </div> + </div> +</div> diff --git a/modules-available/serversetup/templates/ipxe_update.html b/modules-available/serversetup-bwlp/templates/ipxe_update.html index 9c598667..9c598667 100644 --- a/modules-available/serversetup/templates/ipxe_update.html +++ b/modules-available/serversetup-bwlp/templates/ipxe_update.html diff --git a/modules-available/serversetup/templates/ipxe-adv.html b/modules-available/serversetup/templates/ipxe-adv.html deleted file mode 100644 index 00e9fd3a..00000000 --- a/modules-available/serversetup/templates/ipxe-adv.html +++ /dev/null @@ -1,149 +0,0 @@ -<div class="panel panel-default"> - <div class="panel-heading"> - {{lang_mountIpxe}} - </div> - <div class="panel-body"> - <p>{{lang_ipxeInfo}}</p> - <label for="ext">{{lang_extension}}:</label> - <select name="ext" class="form-control"> - <option value="kkpxe">.kkpxe</option> - <option value="usb">.usb</option> - <option value="iso">.iso</option> - </select> - <br> - <form method="post" action="?do=ServerSetup" style="display:inline;"> - <input type="hidden" name="action" value="save-script"> - <input type="hidden" name="token" value="{{token}}"> - - <label for="custom-script">{{lang_customScript}}</label> - <textarea class="form-control" name="custom-script" rows="9" style="resize:none">{{script}}</textarea> - <br> - <input class="btn btn-default btn-sm" type="submit" value="{{lang_saveScript}}" /> - </form> - <form method="post" action="?do=ServerSetup" style="display:inline;"> - <input type="hidden" name="action" value="default-script"> - <input type="hidden" name="token" value="{{token}}"> - <input class="btn btn-default btn-sm" type="submit" value="{{lang_restoreDefault}}" /> - </form> - </div> - <div class="panel-footer"> - <button id="mount-button" onclick="mountIpxe();" class="btn btn-primary" type="button" data-toggle="modal" data-target="#ipxe-modal" data-backdrop="static"> {{lang_compile}} - </button> - </div> -</div> - -<form method="post" action="?do=ServerSetup"> - <input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="display:none;"> - <input type="password" name="password_fake" id="password_fake" value="" style="display:none;"> - <input type="hidden" name="action" value="ipxe"> - <input type="hidden" name="token" value="{{token}}"> - <div class="panel panel-default"> - <div class="panel-heading"> - {{lang_bootMenu}} - </div> - <div class="panel-body"> - <p> - {{lang_bootInfo}} - </p> - <br> - - <div class="form-group"> - <strong>{{lang_bootBehavior}}</strong> - <div><label class="radio-inline"><input type="radio" name="defaultentry" value="net" {{active-net}}> bwLehrpool</label></div> - <div><label class="radio-inline"><input type="radio" name="defaultentry" value="hdd" {{active-hdd}}> {{lang_localHDD}}</label></div> - <div><label class="radio-inline"><input type="radio" name="defaultentry" value="custom" {{active-custom}}> {{lang_customEntry}} ("custom")</label></div> - </div> - - <div class="form-group"> - <strong>{{lang_menuDisplayTime}}</strong> - <div class="input-group form-narrow"> - <input type="text" class="form-control" name="timeout" value="{{timeout}}" pattern="\d+"> - <span class="input-group-addon">{{lang_seconds}}</span> - </div> - </div> - - <div class="form-group"> - <strong>{{lang_masterPassword}}</strong> - <div class="form-narrow"> - <input type="{{password_type}}" class="form-control" name="masterpassword" value="{{masterpasswordclear}}"> - </div> - <i>{{lang_masterPasswordHelp}}</i> - </div> - - <div class="form-group"> - <strong>{{lang_menuCustom}}</strong> <a class="btn btn-default btn-xs" data-toggle="modal" data-target="#help-custom"><span class="glyphicon glyphicon-question-sign"></span></a> - <textarea class="form-control" name="custom" rows="8">{{custom}}</textarea> - </div> - </div> - - <div class="panel-footer"> - <button class="btn btn-primary" name="action" value="ipxe">{{lang_bootMenuCreate}}</button> - </div> - </div> -</form> - -<div class="modal fade" id="help-custom" tabindex="-1" role="dialog"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header">{{lang_menuCustom}}</div> - <div class="modal-body"> - {{lang_menuCustomHint1}} - <br>{{lang_example}}: - <pre>LABEL custom - MENU LABEL ^My Boot Entry - KERNEL http://1.2.3.4/kernel - INITRD http://1.2.3.4/initramfs-stage31 - APPEND custom=option - IPAPPEND 3</pre> - {{lang_menuCustomHint2}} LABEL <strong>custom</strong> - {{lang_menuCustomHint3}} - </div> - <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div> - </div> - </div> -</div> - -<div class="modal fade" id="ipxe-modal" tabindex="-1" role="dialog" aria-labelledby="ipxe-modal-label" aria-hidden="true"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header"> - <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h4 class="modal-title" id="ipxe-modal-label">{{lang_compilingIpxe}}</h4> - </div> - <div class="modal-body" id="ipxe-modal-body"> - - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button> - <button id="download-btn" type="button" class="btn btn-primary" disabled="disabled" onclick="downloadIpxe()">{{lang_download}}</button> - </div> - </div> - </div> -</div> - -<script> - function mountIpxe() { - document.getElementById('ipxe-modal-body').innerHTML = "<div class='alert alert-info' role='alert'>{{lang_ipxeWarning}}</div>" - + "{{lang_loading}} <img src='fonts/loader.gif'/>"; - $("#download-btn").prop("disabled",true); - var xmlhttp = new XMLHttpRequest(); - var extension = $("select[name=ext]").val(); - xmlhttp.open("GET","?do=ServerSetup&async=true&submitTask=true&extension=" + extension,true); - xmlhttp.onreadystatechange= function() { - if (xmlhttp.readyState==4 && xmlhttp.status==200) { - var initResponse = xmlhttp.responseText; - if(initResponse != "success") - document.getElementById('ipxe-modal-body').innerHTML = initResponse; - else { - document.getElementById('ipxe-modal-body').innerHTML = "{{lang_success}}: ipxe." + extension; - $("#download-btn").prop("disabled",false); - } - } - } - xmlhttp.send(); - } - - function downloadIpxe() { - window.location = "?do=ServerSetup&download=" + $("select[name=ext]").val(); - } -</script> diff --git a/modules-available/serversetup/templates/ipxe-smp.html b/modules-available/serversetup/templates/ipxe-smp.html deleted file mode 100644 index d126710c..00000000 --- a/modules-available/serversetup/templates/ipxe-smp.html +++ /dev/null @@ -1,62 +0,0 @@ -<a class="btn btn-default" href="?do=Serversetup&advanced=true" role="button"><strong>{{lang_ipxeAdv}}</strong></a></br></br> -<div class="panel panel-default"> - <div class="panel-heading"> - {{lang_mountIpxe}} - </div> - <div class="panel-body"> - <p>{{lang_ipxeSmpInfo}}</p> - <button id="mount-button" onclick="mountIpxe('iso');" class="btn btn-primary" type="button" data-toggle="modal" data-target="#ipxe-modal" data-backdrop="static"> {{lang_compileIso}} - </button> - <button id="mount-button" onclick="mountIpxe('usb');" class="btn btn-primary" type="button" data-toggle="modal" data-target="#ipxe-modal" data-backdrop="static"> {{lang_compileUsb}} - </button> - <br> - </div> -</div> - - -<div class="modal fade" id="ipxe-modal" tabindex="-1" role="dialog" aria-labelledby="ipxe-modal-label" aria-hidden="true"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header"> - <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h4 class="modal-title" id="ipxe-modal-label">{{lang_compilingIpxe}}</h4> - </div> - <div class="modal-body" id="ipxe-modal-body"> - - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button> - <button id="download-btn" type="button" class="btn btn-primary" disabled="disabled" onclick="downloadIpxe()">{{lang_download}}</button> - </div> - </div> - </div> -</div> - -<script> - function mountIpxe(extension) { - document.getElementById('ipxe-modal-body').innerHTML = "<div class='alert alert-info' role='alert'>{{lang_ipxeWarning}}</div>" - + "{{lang_loading}} <img src='fonts/loader.gif'/>"; - $("#download-btn").prop("disabled",true); - var xmlhttp = new XMLHttpRequest(); - xmlhttp.open("GET","?do=ServerSetup&async=true&submitTask=true&extension=" + extension,true); - xmlhttp.onreadystatechange= function() { - if (xmlhttp.readyState==4 && xmlhttp.status==200) { - var initResponse = xmlhttp.responseText; - if(initResponse != "success") - document.getElementById('ipxe-modal-body').innerHTML = initResponse; - else { - document.getElementById('ipxe-modal-body').innerHTML = "{{lang_success}}: ipxe." + extension; - document.getElementById('download-btn').setAttribute('onclick','downloadIpxe(\''+extension+'\')'); - $("#download-btn").prop("disabled",false); - } - } - } - xmlhttp.send(); - } - - function downloadIpxe(extension) { - console.log("TESTE"); - console.log(extension); - window.location = "?do=ServerSetup&download=" + extension; - } -</script> diff --git a/modules-available/statistics/config.json b/modules-available/statistics/config.json index b0123727..ab71ddbd 100644 --- a/modules-available/statistics/config.json +++ b/modules-available/statistics/config.json @@ -1,5 +1,5 @@ { "category":"main.status", - "enabled":"true", + "dependencies": [ "js_chart" ], "permission":"0" } diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php index f21f0db9..a896b7a6 100644 --- a/modules-available/statistics/page.inc.php +++ b/modules-available/statistics/page.inc.php @@ -49,7 +49,6 @@ class Page_Statistics extends Page $this->showMachineList($filter, $argument); return; } - Render::addScriptBottom('chart.min'); Render::openTag('div', array('class' => 'row')); $this->showSummary(); $this->showMemory(); @@ -548,7 +547,6 @@ class Page_Statistics extends Page Render::addTemplate('machine-usage', $spans); // Any hdds? if (!empty($hdds['hdds'])) { - Render::addScriptBottom('chart.min'); Render::addTemplate('machine-hdds', $hdds); } // Client log diff --git a/modules-available/sysconfig/addmodule_branding.inc.php b/modules-available/sysconfig/addmodule_branding.inc.php index cb5609e6..84602614 100644 --- a/modules-available/sysconfig/addmodule_branding.inc.php +++ b/modules-available/sysconfig/addmodule_branding.inc.php @@ -9,7 +9,6 @@ class Branding_Start extends AddModule_Base protected function renderInternal() { - Render::addScriptBottom('fileselect'); Render::addDialog(Dictionary::translate('config-module', 'branding_title'), false, 'branding-start', array( 'step' => 'Branding_ProcessFile', 'edit' => $this->edit ? $this->edit->id() : false diff --git a/modules-available/sysconfig/addmodule_custommodule.inc.php b/modules-available/sysconfig/addmodule_custommodule.inc.php index d08cc5fb..3f112c95 100644 --- a/modules-available/sysconfig/addmodule_custommodule.inc.php +++ b/modules-available/sysconfig/addmodule_custommodule.inc.php @@ -12,7 +12,6 @@ class CustomModule_Start extends AddModule_Base protected function renderInternal() { Session::set('mod_temp', false); - Render::addScriptBottom('fileselect'); Render::addDialog(Dictionary::translate('config-module', 'custom_title'), false, 'custom-upload', array( 'step' => 'CustomModule_ProcessUpload', 'edit' => $this->edit ? $this->edit->id() : false diff --git a/modules-available/sysconfig/clientscript.js b/modules-available/sysconfig/clientscript.js new file mode 100644 index 00000000..2a133353 --- /dev/null +++ b/modules-available/sysconfig/clientscript.js @@ -0,0 +1,21 @@ + +function forceTable(t) +{ + var pwidth = t.parent().innerWidth(); + var rows = t.find('tr'); + var row = rows.first(); + pwidth = Math.round(pwidth); + t.width(pwidth); + var sum = 0; + row.find('td').each(function() { + if (!$(this).hasClass('slx-width-ignore')) + sum += $(this).outerWidth(true); + }); + var w = Math.round(pwidth - sum); + do { + rows.find('.slx-dyn-ellipsis').each(function() { + $(this).width(w).css('width', w + 'px').css('max-width', w + 'px'); + }); + w -= 3; + } while (t.width() > pwidth); +} diff --git a/modules-available/sysconfig/hooks/main-warning.inc.php b/modules-available/sysconfig/hooks/main-warning.inc.php new file mode 100644 index 00000000..e5bc592f --- /dev/null +++ b/modules-available/sysconfig/hooks/main-warning.inc.php @@ -0,0 +1,6 @@ +<?php + +if (!file_exists(CONFIG_HTTP_DIR . '/default/config.tgz')) { + Message::addError('sysconfig.no-noconfig-active', true); + $needSetup = true; +}
\ No newline at end of file diff --git a/modules-available/sysconfig/inc/configmodule.inc.php b/modules-available/sysconfig/inc/configmodule.inc.php index 7b92ff89..9fc3db21 100644 --- a/modules-available/sysconfig/inc/configmodule.inc.php +++ b/modules-available/sysconfig/inc/configmodule.inc.php @@ -118,7 +118,7 @@ abstract class ConfigModule * Get module instances from module type. * * @param int $moduleType module type to get - * @return array The requested modules from DB, or false on error + * @return \ConfigModule[] The requested modules from DB, or false on error */ public static function getAll($moduleType = false) { diff --git a/modules-available/sysconfig/lang/de/messages.json b/modules-available/sysconfig/lang/de/messages.json index 7993babd..e6203d3d 100644 --- a/modules-available/sysconfig/lang/de/messages.json +++ b/modules-available/sysconfig/lang/de/messages.json @@ -1,20 +1,21 @@ { + "config-activated": "Konfiguration {{0}} wurde aktiviert", + "config-invalid": "Konfiguration mit ID {{0}} existiert nicht", "invalid-action": "Ung\u00fcltige Aktion: {{0}}", + "missing-file": "Es wurde keine Datei ausgew\u00e4hlt!", "missing-title": "Kein Titel eingegeben", - "module-edited": "Modul wurde aktualisiert", "module-added": "Modul erfolgreich hinzugef\u00fcgt", - "replacing-config": "Ersetzen von Konfiguration {{0}}", - "missing-file": "Es wurde keine Datei ausgew\u00e4hlt!", - "unsuccessful-action": "Nicht erfolgreich", - "upload-failed": "Upload schlug fehl: {{0}}", - "remote-timeout": "Konnte Ressource {{0}} nicht herunterladen ({{1}})", - "no-image": "Unter der angegebenen URL konnte kein SVG-Bild gefunden werden", - "replacing-module": "Ersetzen von Modul {{0}}", - "config-invalid": "Konfiguration mit ID {{0}} existiert nicht", - "config-activated": "Konfiguration {{0}} wurde aktiviert", - "module-rebuilt": "Modul wurde neu generiert", + "module-deleted": "Modul {{0}} wurde gel\u00f6scht", + "module-edited": "Modul wurde aktualisiert", + "module-in-use": "Modul {{0}} wird noch durch Konfiguration {{1}} verwendet", "module-rebuild-failed": "Neubau des Moduls fehlgeschlagen", "module-rebuilding": "Modul wird neu generiert", - "module-in-use": "Modul {{0}} wird noch durch Konfiguration {{1}} verwendet", - "module-deleted": "Modul {{0}} wurde gel\u00f6scht" + "module-rebuilt": "Modul wurde neu generiert", + "no-image": "Unter der angegebenen URL konnte kein SVG-Bild gefunden werden", + "no-noconfig-active": "Es wurde noch keine Systemkonfiguration ausgew\u00e4hlt.", + "remote-timeout": "Konnte Ressource {{0}} nicht herunterladen ({{1}})", + "replacing-config": "Ersetzen von Konfiguration {{0}}", + "replacing-module": "Ersetzen von Modul {{0}}", + "unsuccessful-action": "Nicht erfolgreich", + "upload-failed": "Upload schlug fehl: {{0}}" }
\ No newline at end of file diff --git a/modules-available/sysconfig/lang/en/messages.json b/modules-available/sysconfig/lang/en/messages.json index fc3c1160..a4aa8dc1 100644 --- a/modules-available/sysconfig/lang/en/messages.json +++ b/modules-available/sysconfig/lang/en/messages.json @@ -1,20 +1,21 @@ { + "config-activated": "Configuration {{0}} has been activated", + "config-invalid": "Configuration with id {{0}} does not exist", "invalid-action": "Invalid action: {{0}}", + "missing-file": "There was no file selected!", "missing-title": "No title given", - "module-edited": "Module has been edited", "module-added": "Module successfully added", - "replacing-config": "Replace config {{0}}", - "missing-file": "There was no file selected!", - "unsuccessful-action": "Not successful", - "upload-failed": "Upload failed: {{0}}", - "remote-timeout": "Could not download resource {{0}} ({{1}})", - "no-image": "Could not find an SVG-image at the given URL", - "replacing-module": "Replace module {{0}}", - "config-invalid": "Configuration with id {{0}} does not exist", - "config-activated": "Configuration {{0}} has been activated", - "module-rebuilt": "Module was rebuilt", + "module-deleted": "Module {{0}} was deleted", + "module-edited": "Module has been edited", + "module-in-use": "Module {{0}} is still used by Configuration {{1}}", "module-rebuild-failed": "Rebuilding module failed", "module-rebuilding": "Module is rebuilding...", - "module-in-use": "Module {{0}} is still used by Configuration {{1}}", - "module-deleted": "Module {{0}} was deleted" + "module-rebuilt": "Module was rebuilt", + "no-image": "Could not find an SVG-image at the given URL", + "no-noconfig-active": "No system configuration created\/selected yet.", + "remote-timeout": "Could not download resource {{0}} ({{1}})", + "replacing-config": "Replace config {{0}}", + "replacing-module": "Replace module {{0}}", + "unsuccessful-action": "Not successful", + "upload-failed": "Upload failed: {{0}}" }
\ No newline at end of file diff --git a/modules-available/sysconfig/page.inc.php b/modules-available/sysconfig/page.inc.php index 3f14a95d..efe34136 100644 --- a/modules-available/sysconfig/page.inc.php +++ b/modules-available/sysconfig/page.inc.php @@ -175,7 +175,6 @@ class Page_SysConfig extends Page 'modules' => $modules, 'havemodules' => (count($modules) > 0) )); - Render::addScriptTop('custom'); Render::addFooter('<script> $(window).load(function (e) { forceTable($("#modtable")); forceTable($("#conftable")); diff --git a/modules-available/syslog/clientscript.js b/modules-available/syslog/clientscript.js new file mode 100644 index 00000000..3d652628 --- /dev/null +++ b/modules-available/syslog/clientscript.js @@ -0,0 +1,8 @@ +/* + * bootstrap-tagsinput v0.3.9 by Tim Schlechter + * + */ +!function(a){"use strict";function b(b,c){this.itemsArray=[],this.$element=a(b),this.$element.hide(),this.isSelect="SELECT"===b.tagName,this.multiple=this.isSelect&&b.hasAttribute("multiple"),this.objectItems=c&&c.itemValue,this.placeholderText=b.hasAttribute("placeholder")?this.$element.attr("placeholder"):"",this.inputSize=Math.max(1,this.placeholderText.length),this.$container=a('<div class="bootstrap-tagsinput"></div>'),this.$input=a('<input size="'+this.inputSize+'" type="text" placeholder="'+this.placeholderText+'"/>').appendTo(this.$container),this.$element.after(this.$container),this.build(c)}function c(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(a){return a[c]}}}function d(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(){return c}}}function e(a){return a?h.text(a).html():""}function f(a){var b=0;if(document.selection){a.focus();var c=document.selection.createRange();c.moveStart("character",-a.value.length),b=c.text.length}else(a.selectionStart||"0"==a.selectionStart)&&(b=a.selectionStart);return b}var g={tagClass:function(){return"label label-info"},itemValue:function(a){return a?a.toString():a},itemText:function(a){return this.itemValue(a)},freeInput:!0,maxTags:void 0,confirmKeys:[13],onTagExists:function(a,b){b.hide().fadeIn()}};b.prototype={constructor:b,add:function(b,c){var d=this;if(!(d.options.maxTags&&d.itemsArray.length>=d.options.maxTags||b!==!1&&!b)){if("object"==typeof b&&!d.objectItems)throw"Can't add objects when itemValue option is not set";if(!b.toString().match(/^\s*$/)){if(d.isSelect&&!d.multiple&&d.itemsArray.length>0&&d.remove(d.itemsArray[0]),"string"==typeof b&&"INPUT"===this.$element[0].tagName){var f=b.split(",");if(f.length>1){for(var g=0;g<f.length;g++)this.add(f[g],!0);return c||d.pushVal(),void 0}}var h=d.options.itemValue(b),i=d.options.itemText(b),j=d.options.tagClass(b),k=a.grep(d.itemsArray,function(a){return d.options.itemValue(a)===h})[0];if(k){if(d.options.onTagExists){var l=a(".tag",d.$container).filter(function(){return a(this).data("item")===k});d.options.onTagExists(b,l)}}else{d.itemsArray.push(b);var m=a('<span class="tag '+e(j)+'">'+e(i)+'<span data-role="remove"></span></span>');if(m.data("item",b),d.findInputWrapper().before(m),m.after(" "),d.isSelect&&!a('option[value="'+escape(h)+'"]',d.$element)[0]){var n=a("<option selected>"+e(i)+"</option>");n.data("item",b),n.attr("value",h),d.$element.append(n)}c||d.pushVal(),d.options.maxTags===d.itemsArray.length&&d.$container.addClass("bootstrap-tagsinput-max"),d.$element.trigger(a.Event("itemAdded",{item:b}))}}}},remove:function(b,c){var d=this;d.objectItems&&(b="object"==typeof b?a.grep(d.itemsArray,function(a){return d.options.itemValue(a)==d.options.itemValue(b)})[0]:a.grep(d.itemsArray,function(a){return d.options.itemValue(a)==b})[0]),b&&(a(".tag",d.$container).filter(function(){return a(this).data("item")===b}).remove(),a("option",d.$element).filter(function(){return a(this).data("item")===b}).remove(),d.itemsArray.splice(a.inArray(b,d.itemsArray),1)),c||d.pushVal(),d.options.maxTags>d.itemsArray.length&&d.$container.removeClass("bootstrap-tagsinput-max"),d.$element.trigger(a.Event("itemRemoved",{item:b}))},removeAll:function(){var b=this;for(a(".tag",b.$container).remove(),a("option",b.$element).remove();b.itemsArray.length>0;)b.itemsArray.pop();b.pushVal(),b.options.maxTags&&!this.isEnabled()&&this.enable()},refresh:function(){var b=this;a(".tag",b.$container).each(function(){var c=a(this),d=c.data("item"),f=b.options.itemValue(d),g=b.options.itemText(d),h=b.options.tagClass(d);if(c.attr("class",null),c.addClass("tag "+e(h)),c.contents().filter(function(){return 3==this.nodeType})[0].nodeValue=e(g),b.isSelect){var i=a("option",b.$element).filter(function(){return a(this).data("item")===d});i.attr("value",f)}})},items:function(){return this.itemsArray},pushVal:function(){var b=this,c=a.map(b.items(),function(a){return b.options.itemValue(a).toString()});b.$element.val(c,!0).trigger("change")},build:function(b){var e=this;e.options=a.extend({},g,b);var h=e.options.typeahead||{};e.objectItems&&(e.options.freeInput=!1),c(e.options,"itemValue"),c(e.options,"itemText"),c(e.options,"tagClass"),e.options.source&&(h.source=e.options.source),h.source&&a.fn.typeahead&&(d(h,"source"),e.$input.typeahead({source:function(b,c){function d(a){for(var b=[],d=0;d<a.length;d++){var g=e.options.itemText(a[d]);f[g]=a[d],b.push(g)}c(b)}this.map={};var f=this.map,g=h.source(b);a.isFunction(g.success)?g.success(d):a.when(g).then(d)},updater:function(a){e.add(this.map[a])},matcher:function(a){return-1!==a.toLowerCase().indexOf(this.query.trim().toLowerCase())},sorter:function(a){return a.sort()},highlighter:function(a){var b=new RegExp("("+this.query+")","gi");return a.replace(b,"<strong>$1</strong>")}})),e.$container.on("click",a.proxy(function(){e.$input.focus()},e)),e.$container.on("keydown","input",a.proxy(function(b){var c=a(b.target),d=e.findInputWrapper();switch(b.which){case 8:if(0===f(c[0])){var g=d.prev();g&&e.remove(g.data("item"))}break;case 46:if(0===f(c[0])){var h=d.next();h&&e.remove(h.data("item"))}break;case 37:var i=d.prev();0===c.val().length&&i[0]&&(i.before(d),c.focus());break;case 39:var j=d.next();0===c.val().length&&j[0]&&(j.after(d),c.focus());break;default:e.options.freeInput&&a.inArray(b.which,e.options.confirmKeys)>=0&&(e.add(c.val()),c.val(""),b.preventDefault())}c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("click","[data-role=remove]",a.proxy(function(b){e.remove(a(b.target).closest(".tag").data("item"))},e)),e.options.itemValue===g.itemValue&&("INPUT"===e.$element[0].tagName?e.add(e.$element.val()):a("option",e.$element).each(function(){e.add(a(this).attr("value"),!0)}))},destroy:function(){var a=this;a.$container.off("keypress","input"),a.$container.off("click","[role=remove]"),a.$container.remove(),a.$element.removeData("tagsinput"),a.$element.show()},focus:function(){this.$input.focus()},input:function(){return this.$input},findInputWrapper:function(){for(var b=this.$input[0],c=this.$container[0];b&&b.parentNode!==c;)b=b.parentNode;return a(b)}},a.fn.tagsinput=function(c,d){var e=[];return this.each(function(){var f=a(this).data("tagsinput");if(f){var g=f[c](d);void 0!==g&&e.push(g)}else f=new b(this,c),a(this).data("tagsinput",f),e.push(f),"SELECT"===this.tagName&&a("option",a(this)).attr("selected","selected"),a(this).val(a(this).val())}),"string"==typeof c?e.length>1?e:e[0]:e},a.fn.tagsinput.Constructor=b;var h=a("<div />");a(function(){a("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput()})}(window.jQuery); +/* +//@ sourceMappingURL=bootstrap-tagsinput.min.js.map +*/
\ No newline at end of file diff --git a/modules-available/syslog/page.inc.php b/modules-available/syslog/page.inc.php index ea73d1b9..486e0248 100644 --- a/modules-available/syslog/page.inc.php +++ b/modules-available/syslog/page.inc.php @@ -15,9 +15,6 @@ class Page_SysLog extends Page protected function doRender() { - Render::setTitle('Client Log'); - Render::addScriptBottom('bootstrap-tagsinput.min'); - if (isset($_GET['filter'])) { $filter = $_GET['filter']; $not = isset($_GET['not']) ? 'NOT' : ''; diff --git a/modules-available/syslog/style.css b/modules-available/syslog/style.css new file mode 100644 index 00000000..98cfa7f3 --- /dev/null +++ b/modules-available/syslog/style.css @@ -0,0 +1,45 @@ +.bootstrap-tagsinput { + background-color: #fff; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + display: inline-block; + padding: 4px 6px; + margin-bottom: 10px; + color: #555; + vertical-align: middle; + border-radius: 4px; + max-width: 100%; + line-height: 22px; +} +.bootstrap-tagsinput input { + border: none; + box-shadow: none; + outline: none; + background-color: transparent; + padding: 0; + margin: 0; + width: auto !important; + max-width: inherit; +} +.bootstrap-tagsinput input:focus { + border: none; + box-shadow: none; +} +.bootstrap-tagsinput .tag { + margin-right: 2px; + color: white; +} +.bootstrap-tagsinput .tag [data-role="remove"] { + margin-left: 8px; + cursor: pointer; +} +.bootstrap-tagsinput .tag [data-role="remove"]:after { + content: "x"; + padding: 0px 2px; +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover { + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover:active { + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} diff --git a/modules-available/systemstatus/config.json b/modules-available/systemstatus/config.json index 650ab2fe..e78484d8 100644 --- a/modules-available/systemstatus/config.json +++ b/modules-available/systemstatus/config.json @@ -1,4 +1,5 @@ { "category":"main.status", - "enabled":"true" + "enabled":"true", + "dependencies": [ "js_circles" ] } diff --git a/modules-available/systemstatus/page.inc.php b/modules-available/systemstatus/page.inc.php index 9f892957..cf80d1cc 100644 --- a/modules-available/systemstatus/page.inc.php +++ b/modules-available/systemstatus/page.inc.php @@ -29,8 +29,6 @@ class Page_SystemStatus extends Page if (is_array($this->rebootTask) && isset($this->rebootTask['id'])) { $data['rebootTask'] = $this->rebootTask['id']; } - Render::addScriptTop('custom'); - Render::addScriptBottom('circles.min'); Render::addTemplate('_page', $data); } @@ -184,7 +182,7 @@ class Page_SystemStatus extends Page 'uptime' => '???' ); if (preg_match('/^(\d+)\D/', $uptime, $out)) { - $data['uptime'] = floor($out[1] / 86400) . ' ' . Dictionary::translate('lang_days') . ', ' . floor(($out[1] % 86400) / 3600) . ' ' . Dictionary::translate('lang_hours'); // TODO: i18n + $data['uptime'] = floor($out[1] / 86400) . ' ' . Dictionary::translate('lang_days') . ', ' . floor(($out[1] % 86400) / 3600) . ' ' . Dictionary::translate('lang_hours'); } $info = $this->sysInfo(); if (isset($info['MemTotal']) && isset($info['MemFree']) && isset($info['SwapTotal'])) { diff --git a/modules-available/translation/page.inc.php b/modules-available/translation/page.inc.php index 1fc3a0fe..5b2d24e1 100644 --- a/modules-available/translation/page.inc.php +++ b/modules-available/translation/page.inc.php @@ -721,6 +721,9 @@ class Page_Translation extends Page $depth--; } } + // QnD special case for Message::add* using true as second param to add "go to" link. + if (preg_match('/^\s*,\s*true\b/i', $str)) + return $count - 1; return $count; } diff --git a/modules-available/vmstore/hooks/main-warning.inc.php b/modules-available/vmstore/hooks/main-warning.inc.php new file mode 100644 index 00000000..ca2d1382 --- /dev/null +++ b/modules-available/vmstore/hooks/main-warning.inc.php @@ -0,0 +1,10 @@ +<?php + +/* + * Hook for main page: Show warning if vmstore not configured yet; set "warning" flag if so + */ + +if (!is_array(Property::getVmStoreConfig())) { + Message::addError('vmstore.vmstore-not-configured', true); // Always specify module prefix since this is running in main + $needSetup = true; // Set $needSetup to true if you want a warning badge to appear in the menu +} diff --git a/modules-available/vmstore/lang/de/messages.json b/modules-available/vmstore/lang/de/messages.json new file mode 100644 index 00000000..993d355d --- /dev/null +++ b/modules-available/vmstore/lang/de/messages.json @@ -0,0 +1,3 @@ +{ + "vmstore-not-configured": "Es ist noch kein Speicherort f\u00fcr die Virtuellen Maschinen festgelegt." +}
\ No newline at end of file diff --git a/modules-available/vmstore/lang/en/messages.json b/modules-available/vmstore/lang/en/messages.json new file mode 100644 index 00000000..9ac360eb --- /dev/null +++ b/modules-available/vmstore/lang/en/messages.json @@ -0,0 +1,3 @@ +{ + "vmstore-not-configured": "A location for the virtual machine is not set yet." +}
\ No newline at end of file |