From b6cab93bd155e40fa821803a68b6930a2386c6d4 Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Sun, 8 Apr 2018 14:02:14 -0400 Subject: [PATCH 001/100] Update cron when removing a plugin To prevent any .cron files previously added from continuing to be executed --- plugins/dynamix.plugin.manager/scripts/plugin | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/dynamix.plugin.manager/scripts/plugin b/plugins/dynamix.plugin.manager/scripts/plugin index 9074e847f..b1ecbfb32 100755 --- a/plugins/dynamix.plugin.manager/scripts/plugin +++ b/plugins/dynamix.plugin.manager/scripts/plugin @@ -550,6 +550,7 @@ if ($method == "remove") { // remove the plugin file move($installed_plugin_file, "/boot/config/plugins-removed"); echo "plugin: removed\n"; + exec("/usr/local/sbin/update_cron"); exit(0); } From cfeec90c1c26ef35b70d77eb6fdb1d31916687ff Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 13 Apr 2018 16:29:46 +0200 Subject: [PATCH 002/100] CSS fixes for OS upgrade page --- plugins/dynamix/styles/default-azure.css | 2 +- plugins/dynamix/styles/default-black.css | 2 +- plugins/dynamix/styles/default-gray.css | 2 +- plugins/dynamix/styles/default-white.css | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/dynamix/styles/default-azure.css b/plugins/dynamix/styles/default-azure.css index 3ff9ddf2d..75d558769 100644 --- a/plugins/dynamix/styles/default-azure.css +++ b/plugins/dynamix/styles/default-azure.css @@ -195,7 +195,7 @@ span.heat-text{font-size:12px;color:#F0000C} span.cpu-speed{display:block;color:#3B5998} span.status{float:right;font-size:15px} span.status.vhshift{margin-top:-16px;margin-right:-20px} -span.status.hshift{margin-right:-20px} +span.status.hshift{margin-right:0} span.diskinfo{float:left;clear:both;margin-top:5px;padding-left:10px} span.bitstream{font-family:bitstream;font-size:11px} span.p0{padding-left:0} diff --git a/plugins/dynamix/styles/default-black.css b/plugins/dynamix/styles/default-black.css index 5e5d8fd1d..4f5dddcd8 100644 --- a/plugins/dynamix/styles/default-black.css +++ b/plugins/dynamix/styles/default-black.css @@ -189,7 +189,7 @@ span.heat-text{font-size:11px;color:#F0000C} span.cpu-speed{display:block;color:#3B5998} span.status{float:right;font-size:14px;margin-top:0;padding-right:8px} span.status.vhshift{margin-top:-17px;margin-right:-22px} -span.status.hshift{margin-right:-6px} +span.status.hshift{margin-top:-5px;margin-right:-6px} span.diskinfo{float:left;clear:both;margin-top:5px;padding-left:10px} span.bitstream{font-family:bitstream;font-size:11px} span.p0{padding-left:0} diff --git a/plugins/dynamix/styles/default-gray.css b/plugins/dynamix/styles/default-gray.css index 21bcb6c7d..96f5de4dd 100644 --- a/plugins/dynamix/styles/default-gray.css +++ b/plugins/dynamix/styles/default-gray.css @@ -195,7 +195,7 @@ span.heat-text{font-size:12px;color:#F0000C} span.cpu-speed{display:block;color:#3B5998} span.status{float:right;font-size:15px} span.status.vhshift{margin-top:-16px;margin-right:-20px} -span.status.hshift{margin-right:-20px} +span.status.hshift{margin-right:0} span.diskinfo{float:left;clear:both;margin-top:5px;padding-left:10px} span.bitstream{font-family:bitstream;font-size:11px} span.p0{padding-left:0} diff --git a/plugins/dynamix/styles/default-white.css b/plugins/dynamix/styles/default-white.css index c4df0144f..e132a3253 100644 --- a/plugins/dynamix/styles/default-white.css +++ b/plugins/dynamix/styles/default-white.css @@ -189,7 +189,7 @@ span.heat-text{font-size:11px;color:#F0000C} span.cpu-speed{display:block;color:#3B5998} span.status{float:right;font-size:14px;margin-top:0;padding-right:8px} span.status.vhshift{margin-top:-17px;margin-right:-22px} -span.status.hshift{margin-right:-6px} +span.status.hshift{margin-top:-5px;margin-right:-6px} span.diskinfo{float:left;clear:both;margin-top:5px;padding-left:10px} span.bitstream{font-family:bitstream;font-size:11px} span.p0{padding-left:0} From a66bc1f06722f746a4d69ccb81d1ad4d37902d55 Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 13 Apr 2018 16:46:53 +0200 Subject: [PATCH 003/100] Added selection of all available OS versions to upgrade or downgrade --- plugins/dynamix.plugin.manager/Update.page | 70 ++++--- .../include/PluginHelpers.php | 7 +- .../include/ShowPlugins.php | 179 ++++++++++++------ 3 files changed, 169 insertions(+), 87 deletions(-) diff --git a/plugins/dynamix.plugin.manager/Update.page b/plugins/dynamix.plugin.manager/Update.page index d41bab513..bb4e31486 100644 --- a/plugins/dynamix.plugin.manager/Update.page +++ b/plugins/dynamix.plugin.manager/Update.page @@ -15,7 +15,6 @@ Tag="thumbs-up" */ ?>
"; $version = $date = 'unknown'; $bzroot = file_exists('/boot/previous/bzroot'); $check = $notify['unraidos'] ? 0 : 1; @@ -31,26 +30,46 @@ if (file_exists('/boot/previous/changes.txt')) { } } ?> + - - - - - + +
ComponentAuthorVersionStatusBranch
ComponentAuthorInstalledAvailableStatusBranch
diff --git a/plugins/dynamix.plugin.manager/include/PluginHelpers.php b/plugins/dynamix.plugin.manager/include/PluginHelpers.php index 6f0ed7174..002cb981d 100644 --- a/plugins/dynamix.plugin.manager/include/PluginHelpers.php +++ b/plugins/dynamix.plugin.manager/include/PluginHelpers.php @@ -25,11 +25,11 @@ function check_plugin($arg, $dns='8.8.8.8') { return exec("ping -qnl2 -c2 -W3 $dns 2>/dev/null|awk '/received/{print $4}'") ? plugin('check',$arg) : false; } -function make_link($method, $arg, $extra='') { +function make_link($method, $arg, $extra=null, $title=null) { $plg = basename($arg,'.plg').':'.$method; $id = str_replace(['.',' ','_'],'',$plg); $check = $method=='remove' ? "" : ""; - $disabled = $check ? ' disabled' : ''; + $disabled = ($check || $extra=='disabled') ? ' disabled' : ''; if ($method == 'delete') { $cmd = "/plugins/dynamix.plugin.manager/scripts/plugin_rm&arg1=$arg"; $exec = $plg = ""; @@ -37,7 +37,8 @@ function make_link($method, $arg, $extra='') { $cmd = "/plugins/dynamix.plugin.manager/scripts/plugin&arg1=$method&arg2=$arg".($extra?"&arg3=$extra":""); $exec = "loadlist"; } - return "$check"; + $title = $title ?: $method; + return "$check"; } // trying our best to find an icon diff --git a/plugins/dynamix.plugin.manager/include/ShowPlugins.php b/plugins/dynamix.plugin.manager/include/ShowPlugins.php index 5c7c8726c..988970a0d 100644 --- a/plugins/dynamix.plugin.manager/include/ShowPlugins.php +++ b/plugins/dynamix.plugin.manager/include/ShowPlugins.php @@ -15,14 +15,18 @@ $docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'; require_once "$docroot/webGui/include/Markdown.php"; require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php"; -$system = $_GET['system'] ?? false; -$branch = $_GET['branch'] ?? false; -$audit = $_GET['audit'] ?? false; -$check = $_GET['check'] ?? false; -$empty = true; -$updates = 0; -$builtin = ['unRAIDServer']; -$plugins = "/var/log/plugins/*.plg"; +$system = $_GET['system'] ?? false; +$branch = $_GET['branch'] ?? false; +$source = $_GET['source'] ?? false; +$audit = $_GET['audit'] ?? false; +$check = $_GET['check'] ?? false; +$release = $_GET['release'] ?? false; +$empty = true; +$updates = 0; +$missing = "None"; +$builtin = "unRAIDServer"; +$plugins = $system ? "/var/log/plugins/$builtin.plg" : "/var/log/plugins/*.plg"; +$limetech = "https://s3.amazonaws.com/dnld.lime-technology.com"; if ($audit) { list($plg,$action) = explode(':',$audit); @@ -34,33 +38,66 @@ if ($audit) { } } +function strip($name) { + return str_replace('unRAID ','',$name); +} + +function file_date($file, $version) { + //file is considered outdated when older than 1 day + return ($version < 0 || !file_exists($file)) ? 'unknown' : (filectime($file) > (time()-86400) ? 'up-to-date' : 'outdated'); +} + foreach (glob($plugins,GLOB_NOSORT) as $plugin_link) { //only consider symlinks $plugin_file = @readlink($plugin_link); if ($plugin_file === false) continue; //plugin name $name = plugin('name',$plugin_file) ?: basename($plugin_file,".plg"); - $custom = in_array($name,$builtin); -//switch between system and custom plugins - if (($system && !$custom) || (!$system && $custom)) continue; -//forced plugin check? - $checked = (!$audit && !$check) ? check_plugin(basename($plugin_file)) : true; -//OS update? - $os = $system && $name==$builtin[0]; - $toggle = false; -//toggle stable/next release? - if ($os && $branch) { - $toggle = plugin('version',$plugin_file); - $tmp_plg = "$name-.plg"; +//upgrade or downgrade selected release + if ($release) { + extract(parse_ini_file('/etc/unraid-version')); $tmp_file = "/var/tmp/$name.plg"; - copy($plugin_file,$tmp_file); - exec("sed -ri 's|^(|' $tmp_file"); - symlink($tmp_file,"/var/log/plugins/$tmp_plg"); - if (check_plugin($tmp_plg)) { - copy("/tmp/plugins/$tmp_plg",$tmp_file); - $plugin_file = $tmp_file; + if ($release != $version) { + exec("sed -ri 's|^(|' $tmp_file"); + echo "$plugin_file\0$tmp_file"; + } else { + echo "$tmp_file\0$plugin_file"; } + return; } +//skip system when doing user plugins + if (!$system && strpos($name,$builtin)===0) continue; +//forced plugin check? + $forced = !$audit && !$check; + $checked = $forced ? check_plugin(basename($plugin_file)) : true; +//switch stable/next/test release? + if ($system) { + //current version + extract(parse_ini_file('/etc/unraid-version')); + //category + $category = $branch ?: plugin('category',$plugin_file) ?: (strpos($version,'-')===false ? 'stable' : 'next'); + if (!$branch && !$source) $source = $category; + $releases = []; + exec("curl -m 15 $limetech/$category/releases.json 2>/dev/null", $releases); + if ($releases) $releases = json_decode(implode("\n",$releases),true); else $releases[] = ['name' => $missing]; + $release = strip($releases[0]['name']); + if ($release != $missing) { + $tmp_plg = "$name-.plg"; + $tmp_file = "/var/tmp/$name.plg"; + copy($plugin_file,$tmp_file); + if ($branch) exec("sed -ri 's|^(|' $tmp_file"); + symlink($tmp_file,"/var/log/plugins/$tmp_plg"); + if ($release != $version && $branch) { + if (check_plugin($tmp_plg)) copy("/tmp/plugins/$tmp_plg", $tmp_file); + exec("sed -ri 's|^(|' $tmp_file"); + $plugin_file = $tmp_file; + } + } + } else { + //plugin version + $version = plugin('version',$plugin_file) ?: 'unknown'; + } + $save = $version; //link/icon $icon = icon($name); if ($launch = plugin('launch',$plugin_file)) @@ -74,45 +111,50 @@ foreach (glob($plugins,GLOB_NOSORT) as $plugin_link) { else $desc = Markdown("**{$name}**"); //author - $author = plugin('author',$plugin_file) ?: "anonymous"; -//version - $version = plugin('version',$plugin_file) ?: "unknown"; - $date = str_replace('.','',$version); -//category - $category = plugin('category',$plugin_file) ?: (strpos($version,'-')!==false ? 'next' : 'stable'); + $author = plugin('author',$plugin_file) ?: 'anonymous'; //status - $status = 'unknown'; $changes_file = $plugin_file; $url = plugin('pluginURL',$plugin_file); if ($url !== false) { - $filename = "/tmp/plugins/".(($os && $branch) ? $tmp_plg : basename($url)); - if ($checked && file_exists($filename)) { - if ($toggle && $toggle != $version) { - $status = make_link('install',$plugin_file,'forced'); + $extra = $branch && $branch != $source; + $filename = "/tmp/plugins/".(($system && $extra) ? $tmp_plg : basename($url)); + $latest = ($checked && file_exists($filename)) ? plugin('version',$filename) : 0; + if ($system) { + $release = strip($releases[0]['name']); + $other = ($release != $missing); + if ($extra) { + if ($other) $version .= "
$release"; + $status = "".make_link('install', $plugin_file,$other?'forced':'disabled').""; } else { - $latest = plugin('version',$filename); - if ($os ? version_compare($latest,$version,'>') : strcmp($latest,$version) > 0) { - $version .= "
$latest"; - $status = make_link("update",basename($plugin_file)); + $style1 = $style2 = ""; + if ($forced && $other && $latest===0) $latest = $release; + if (version_compare($latest,$version,'>')) { + $style1 = "style='display:none'"; + $version .= "
$latest"; $changes_file = $filename; - if (!$os) $updates++; } else { - //status is considered outdated when older than 1 day - $status = filectime($filename) > (time()-86400) ? 'up-to-date' : 'need check'; + $style2 = "style='display:none'"; } + $status = "".file_date($filename,$latest).""; + $status .= "".make_link('update', $plugin_file, null, 'upgrade').""; + $status .= ""; + } + } else { + if (strcmp($latest,$version) > 0) { + $version .= "
$latest"; + $status = make_link('update', basename($plugin_file), null, 'upgrade'); + $changes_file = $filename; + $updates++; + } else { + $status = file_date($filename,$latest); } } } - if (strpos($status,'update')!==false) $rank = '0'; - elseif (strpos($status,'install')!==false) $rank = '1'; - elseif ($status=='need check') $rank = '2'; - elseif ($status=='up-to-date') $rank = '3'; - else $rank = '4'; - $changes = plugin('changes',$changes_file); + $changes = strpos($version,$missing)===false ? plugin('changes',$changes_file) : false; if ($changes !== false) { $txtfile = "/tmp/plugins/".basename($plugin_file,'.plg').".txt"; file_put_contents($txtfile,$changes); - $version .= " "; + $version .= ""; } //write plugin information $empty = false; @@ -120,24 +162,39 @@ foreach (glob($plugins,GLOB_NOSORT) as $plugin_link) { echo "

$link

"; echo "$desc"; echo "$author"; - echo "$version"; + echo "$version"; + if ($system) { + // available releases + $branch = $branch ?: $source; + echo ""; + $rank = 0; + } else { + if (strpos($status,'upgrade')!==false) $rank = 0; + elseif ($status=='outdated') $rank = 1; + elseif ($status=='up-to-date') $rank = 2; + else $rank = 3; + } echo "$status"; echo ""; if ($system) { - if ($os) { - echo ""; - } + echo ""; } else { - echo make_link('remove',basename($plugin_file)); + echo make_link('remove', basename($plugin_file)); } echo ""; echo ""; //remove temporary symlink - @unlink("/var/log/plugins/$tmp_plg"); + if ($tmp_plg) unlink("/var/log/plugins/$tmp_plg"); } -if ($empty) echo " No plugins installed"; +if ($empty) echo " No plugins installed"; echo "\0".$updates; ?> From 6f83789c89ce63e57828d81e82624a92ae1a1c55 Mon Sep 17 00:00:00 2001 From: Eric Schultz Date: Fri, 13 Apr 2018 09:51:30 -0500 Subject: [PATCH 004/100] Nchan/Nginx: Use long polling for Safari and websockets for all other browsers --- plugins/dynamix/DashStats.page | 2 +- plugins/dynamix/Eth0.page | 2 +- plugins/dynamix/include/DefaultPageLayout.php | 2 +- plugins/dynamix/javascript/dynamix.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/dynamix/DashStats.page b/plugins/dynamix/DashStats.page index 978b5f5e8..03bb316ab 100644 --- a/plugins/dynamix/DashStats.page +++ b/plugins/dynamix/DashStats.page @@ -522,7 +522,7 @@ function toggle_CPU(init) { } $.cookie('cpu')===undefined ? $('.cpu_open').show() : $('.cpu_open').hide(); } -var cpuload = new NchanSubscriber('/sub/cpuload'); +var cpuload = new NchanSubscriber('/sub/cpuload', /^((?!chrome|android).)*safari/i.test(navigator.userAgent) ? {subscriber:'longpoll'} : {}); cpuload.on('message',function(data) { /* message should be something like: {"cpuload": {"cpu":[0,0],"cpu0":[0,0],"cpu1":[0,0],"cpu2":[0,0],"cpu3":[0,0]}} diff --git a/plugins/dynamix/Eth0.page b/plugins/dynamix/Eth0.page index 372219530..4b16e4932 100644 --- a/plugins/dynamix/Eth0.page +++ b/plugins/dynamix/Eth0.page @@ -365,7 +365,7 @@ function portcheck_eth0() { function portToggle(port,cmd) { $.post('/webGui/include/PortToggle.php',{port:port,cmd:cmd},function(){refresh();}); } -var watchDHCP = new NchanSubscriber('/sub/dhcp'); +var watchDHCP = new NchanSubscriber('/sub/dhcp', /^((?!chrome|android).)*safari/i.test(navigator.userAgent) ? {subscriber:'longpoll'} : {}); watchDHCP.on('message', function(data) { data = data.split(' '); for (var i=0,row; row=data[i]; i++) { diff --git a/plugins/dynamix/include/DefaultPageLayout.php b/plugins/dynamix/include/DefaultPageLayout.php index 5c0781d78..f4224776d 100644 --- a/plugins/dynamix/include/DefaultPageLayout.php +++ b/plugins/dynamix/include/DefaultPageLayout.php @@ -435,7 +435,7 @@ function parseINI(data){ }); return value; } -var watchdog = new NchanSubscriber('/sub/var'); +var watchdog = new NchanSubscriber('/sub/var', /^((?!chrome|android).)*safari/i.test(navigator.userAgent) ? {subscriber:'longpoll'} : {}); watchdog.on('message', function(data) { var ini = parseINI(data); var state = ini['fsState']; diff --git a/plugins/dynamix/javascript/dynamix.js b/plugins/dynamix/javascript/dynamix.js index 01bd53859..423aac544 100644 --- a/plugins/dynamix/javascript/dynamix.js +++ b/plugins/dynamix/javascript/dynamix.js @@ -31,4 +31,4 @@ var context=context||function(){function b(b){a=$.extend({},a,b),$(document).on( /* tooltipster v4.2.3, Copyright (c) 2012,2016 Caleb Jacob and Louis Ameline */ !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(a){return b(a)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){function b(a){this.$container,this.constraints=null,this.__$tooltip,this.__init(a)}function c(b,c){var d=!0;return a.each(b,function(a,e){return void 0===c[a]||b[a]!==c[a]?(d=!1,!1):void 0}),d}function d(b){var c=b.attr("id"),d=c?h.window.document.getElementById(c):null;return d?d===b[0]:a.contains(h.window.document.body,b[0])}function e(){if(!g)return!1;var a=g.document.body||g.document.documentElement,b=a.style,c="transition",d=["Moz","Webkit","Khtml","O","ms"];if("string"==typeof b[c])return!0;c=c.charAt(0).toUpperCase()+c.substr(1);for(var e=0;e0?e=c.__plugins[d]:a.each(c.__plugins,function(a,b){return b.name.substring(b.name.length-d.length-1)=="."+d?(e=b,!1):void 0}),e}if(b.name.indexOf(".")<0)throw new Error("Plugins must be namespaced");return c.__plugins[b.name]=b,b.core&&c.__bridge(b.core,c,b.name),this},_trigger:function(){var a=Array.prototype.slice.apply(arguments);return"string"==typeof a[0]&&(a[0]={type:a[0]}),this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate,a),this.__$emitterPublic.trigger.apply(this.__$emitterPublic,a),this},instances:function(b){var c=[],d=b||".tooltipstered";return a(d).each(function(){var b=a(this),d=b.data("tooltipster-ns");d&&a.each(d,function(a,d){c.push(b.data(d))})}),c},instancesLatest:function(){return this.__instancesLatestArr},off:function(){return this.__$emitterPublic.off.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},on:function(){return this.__$emitterPublic.on.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},one:function(){return this.__$emitterPublic.one.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},origins:function(b){var c=b?b+" ":"";return a(c+".tooltipstered").toArray()},setDefaults:function(b){return a.extend(f,b),this},triggerHandler:function(){return this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this}},a.tooltipster=new i,a.Tooltipster=function(b,c){this.__callbacks={close:[],open:[]},this.__closingTime,this.__Content,this.__contentBcr,this.__destroyed=!1,this.__$emitterPrivate=a({}),this.__$emitterPublic=a({}),this.__enabled=!0,this.__garbageCollector,this.__Geometry,this.__lastPosition,this.__namespace="tooltipster-"+Math.round(1e6*Math.random()),this.__options,this.__$originParents,this.__pointerIsOverOrigin=!1,this.__previousThemes=[],this.__state="closed",this.__timeouts={close:[],open:null},this.__touchEvents=[],this.__tracker=null,this._$origin,this._$tooltip,this.__init(b,c)},a.Tooltipster.prototype={__init:function(b,c){var d=this;if(d._$origin=a(b),d.__options=a.extend(!0,{},f,c),d.__optionsFormat(),!h.IE||h.IE>=d.__options.IEmin){var e=null;if(void 0===d._$origin.data("tooltipster-initialTitle")&&(e=d._$origin.attr("title"),void 0===e&&(e=null),d._$origin.data("tooltipster-initialTitle",e)),null!==d.__options.content)d.__contentSet(d.__options.content);else{var g,i=d._$origin.attr("data-tooltip-content");i&&(g=a(i)),g&&g[0]?d.__contentSet(g.first()):d.__contentSet(e)}d._$origin.removeAttr("title").addClass("tooltipstered"),d.__prepareOrigin(),d.__prepareGC(),a.each(d.__options.plugins,function(a,b){d._plug(b)}),h.hasTouchCapability&&a(h.window.document.body).on("touchmove."+d.__namespace+"-triggerOpen",function(a){d._touchRecordEvent(a)}),d._on("created",function(){d.__prepareTooltip()})._on("repositioned",function(a){d.__lastPosition=a.position})}else d.__options.disabled=!0},__contentInsert:function(){var a=this,b=a._$tooltip.find(".tooltipster-content"),c=a.__Content,d=function(a){c=a};return a._trigger({type:"format",content:a.__Content,format:d}),a.__options.functionFormat&&(c=a.__options.functionFormat.call(a,a,{origin:a._$origin[0]},a.__Content)),"string"!=typeof c||a.__options.contentAsHTML?b.empty().append(c):b.text(c),a},__contentSet:function(b){return b instanceof a&&this.__options.contentCloning&&(b=b.clone(!0)),this.__Content=b,this._trigger({type:"updated",content:b}),this},__destroyError:function(){throw new Error("This tooltip has been destroyed and cannot execute your method call.")},__geometry:function(){var b=this,c=b._$origin,d=b._$origin.is("area");if(d){var e=b._$origin.parent().attr("name");c=a('img[usemap="#'+e+'"]')}var f=c[0].getBoundingClientRect(),g=a(h.window.document),i=a(h.window),j=c,k={available:{document:null,window:null},document:{size:{height:g.height(),width:g.width()}},window:{scroll:{left:h.window.scrollX||h.window.document.documentElement.scrollLeft,top:h.window.scrollY||h.window.document.documentElement.scrollTop},size:{height:i.height(),width:i.width()}},origin:{fixedLineage:!1,offset:{},size:{height:f.bottom-f.top,width:f.right-f.left},usemapImage:d?c[0]:null,windowOffset:{bottom:f.bottom,left:f.left,right:f.right,top:f.top}}};if(d){var l=b._$origin.attr("shape"),m=b._$origin.attr("coords");if(m&&(m=m.split(","),a.map(m,function(a,b){m[b]=parseInt(a)})),"default"!=l)switch(l){case"circle":var n=m[0],o=m[1],p=m[2],q=o-p,r=n-p;k.origin.size.height=2*p,k.origin.size.width=k.origin.size.height,k.origin.windowOffset.left+=r,k.origin.windowOffset.top+=q;break;case"rect":var s=m[0],t=m[1],u=m[2],v=m[3];k.origin.size.height=v-t,k.origin.size.width=u-s,k.origin.windowOffset.left+=s,k.origin.windowOffset.top+=t;break;case"poly":for(var w=0,x=0,y=0,z=0,A="even",B=0;By&&(y=C,0===B&&(w=y)),w>C&&(w=C),A="odd"):(C>z&&(z=C,1==B&&(x=z)),x>C&&(x=C),A="even")}k.origin.size.height=z-x,k.origin.size.width=y-w,k.origin.windowOffset.left+=w,k.origin.windowOffset.top+=x}}var D=function(a){k.origin.size.height=a.height,k.origin.windowOffset.left=a.left,k.origin.windowOffset.top=a.top,k.origin.size.width=a.width};for(b._trigger({type:"geometry",edit:D,geometry:{height:k.origin.size.height,left:k.origin.windowOffset.left,top:k.origin.windowOffset.top,width:k.origin.size.width}}),k.origin.windowOffset.right=k.origin.windowOffset.left+k.origin.size.width,k.origin.windowOffset.bottom=k.origin.windowOffset.top+k.origin.size.height,k.origin.offset.left=k.origin.windowOffset.left+k.window.scroll.left,k.origin.offset.top=k.origin.windowOffset.top+k.window.scroll.top,k.origin.offset.bottom=k.origin.offset.top+k.origin.size.height,k.origin.offset.right=k.origin.offset.left+k.origin.size.width,k.available.document={bottom:{height:k.document.size.height-k.origin.offset.bottom,width:k.document.size.width},left:{height:k.document.size.height,width:k.origin.offset.left},right:{height:k.document.size.height,width:k.document.size.width-k.origin.offset.right},top:{height:k.origin.offset.top,width:k.document.size.width}},k.available.window={bottom:{height:Math.max(k.window.size.height-Math.max(k.origin.windowOffset.bottom,0),0),width:k.window.size.width},left:{height:k.window.size.height,width:Math.max(k.origin.windowOffset.left,0)},right:{height:k.window.size.height,width:Math.max(k.window.size.width-Math.max(k.origin.windowOffset.right,0),0)},top:{height:Math.max(k.origin.windowOffset.top,0),width:k.window.size.width}};"html"!=j[0].tagName.toLowerCase();){if("fixed"==j.css("position")){k.origin.fixedLineage=!0;break}j=j.parent()}return k},__optionsFormat:function(){return"number"==typeof this.__options.animationDuration&&(this.__options.animationDuration=[this.__options.animationDuration,this.__options.animationDuration]),"number"==typeof this.__options.delay&&(this.__options.delay=[this.__options.delay,this.__options.delay]),"number"==typeof this.__options.delayTouch&&(this.__options.delayTouch=[this.__options.delayTouch,this.__options.delayTouch]),"string"==typeof this.__options.theme&&(this.__options.theme=[this.__options.theme]),null===this.__options.parent?this.__options.parent=a(h.window.document.body):"string"==typeof this.__options.parent&&(this.__options.parent=a(this.__options.parent)),"hover"==this.__options.trigger?(this.__options.triggerOpen={mouseenter:!0,touchstart:!0},this.__options.triggerClose={mouseleave:!0,originClick:!0,touchleave:!0}):"click"==this.__options.trigger&&(this.__options.triggerOpen={click:!0,tap:!0},this.__options.triggerClose={click:!0,tap:!0}),this._trigger("options"),this},__prepareGC:function(){var b=this;return b.__options.selfDestruction?b.__garbageCollector=setInterval(function(){var c=(new Date).getTime();b.__touchEvents=a.grep(b.__touchEvents,function(a,b){return c-a.time>6e4}),d(b._$origin)||b.close(function(){b.destroy()})},2e4):clearInterval(b.__garbageCollector),b},__prepareOrigin:function(){var a=this;if(a._$origin.off("."+a.__namespace+"-triggerOpen"),h.hasTouchCapability&&a._$origin.on("touchstart."+a.__namespace+"-triggerOpen touchend."+a.__namespace+"-triggerOpen touchcancel."+a.__namespace+"-triggerOpen",function(b){a._touchRecordEvent(b)}),a.__options.triggerOpen.click||a.__options.triggerOpen.tap&&h.hasTouchCapability){var b="";a.__options.triggerOpen.click&&(b+="click."+a.__namespace+"-triggerOpen "),a.__options.triggerOpen.tap&&h.hasTouchCapability&&(b+="touchend."+a.__namespace+"-triggerOpen"),a._$origin.on(b,function(b){a._touchIsMeaningfulEvent(b)&&a._open(b)})}if(a.__options.triggerOpen.mouseenter||a.__options.triggerOpen.touchstart&&h.hasTouchCapability){var b="";a.__options.triggerOpen.mouseenter&&(b+="mouseenter."+a.__namespace+"-triggerOpen "),a.__options.triggerOpen.touchstart&&h.hasTouchCapability&&(b+="touchstart."+a.__namespace+"-triggerOpen"),a._$origin.on(b,function(b){!a._touchIsTouchEvent(b)&&a._touchIsEmulatedEvent(b)||(a.__pointerIsOverOrigin=!0,a._openShortly(b))})}if(a.__options.triggerClose.mouseleave||a.__options.triggerClose.touchleave&&h.hasTouchCapability){var b="";a.__options.triggerClose.mouseleave&&(b+="mouseleave."+a.__namespace+"-triggerOpen "),a.__options.triggerClose.touchleave&&h.hasTouchCapability&&(b+="touchend."+a.__namespace+"-triggerOpen touchcancel."+a.__namespace+"-triggerOpen"),a._$origin.on(b,function(b){a._touchIsMeaningfulEvent(b)&&(a.__pointerIsOverOrigin=!1)})}return a},__prepareTooltip:function(){var b=this,c=b.__options.interactive?"auto":"";return b._$tooltip.attr("id",b.__namespace).css({"pointer-events":c,zIndex:b.__options.zIndex}),a.each(b.__previousThemes,function(a,c){b._$tooltip.removeClass(c)}),a.each(b.__options.theme,function(a,c){b._$tooltip.addClass(c)}),b.__previousThemes=a.merge([],b.__options.theme),b},__scrollHandler:function(b){var c=this;if(c.__options.triggerClose.scroll)c._close(b);else if(d(c._$origin)&&d(c._$tooltip)){if(b.target===h.window.document)c.__Geometry.origin.fixedLineage||c.__options.repositionOnScroll&&c.reposition(b);else{var e=c.__geometry(),f=!1;if("fixed"!=c._$origin.css("position")&&c.__$originParents.each(function(b,c){var d=a(c),g=d.css("overflow-x"),h=d.css("overflow-y");if("visible"!=g||"visible"!=h){var i=c.getBoundingClientRect();if("visible"!=g&&(e.origin.windowOffset.lefti.right))return f=!0,!1;if("visible"!=h&&(e.origin.windowOffset.topi.bottom))return f=!0,!1}return"fixed"==d.css("position")?!1:void 0}),f)c._$tooltip.css("visibility","hidden");else if(c._$tooltip.css("visibility","visible"),c.__options.repositionOnScroll)c.reposition(b);else{var g=e.origin.offset.left-c.__Geometry.origin.offset.left,i=e.origin.offset.top-c.__Geometry.origin.offset.top;c._$tooltip.css({left:c.__lastPosition.coord.left+g,top:c.__lastPosition.coord.top+i})}}c._trigger({type:"scroll",event:b})}return c},__stateSet:function(a){return this.__state=a,this._trigger({type:"state",state:a}),this},__timeoutsClear:function(){return clearTimeout(this.__timeouts.open),this.__timeouts.open=null,a.each(this.__timeouts.close,function(a,b){clearTimeout(b)}),this.__timeouts.close=[],this},__trackerStart:function(){var a=this,b=a._$tooltip.find(".tooltipster-content");return a.__options.trackTooltip&&(a.__contentBcr=b[0].getBoundingClientRect()),a.__tracker=setInterval(function(){if(d(a._$origin)&&d(a._$tooltip)){if(a.__options.trackOrigin){var e=a.__geometry(),f=!1;c(e.origin.size,a.__Geometry.origin.size)&&(a.__Geometry.origin.fixedLineage?c(e.origin.windowOffset,a.__Geometry.origin.windowOffset)&&(f=!0):c(e.origin.offset,a.__Geometry.origin.offset)&&(f=!0)),f||(a.__options.triggerClose.mouseleave?a._close():a.reposition())}if(a.__options.trackTooltip){var g=b[0].getBoundingClientRect();g.height===a.__contentBcr.height&&g.width===a.__contentBcr.width||(a.reposition(),a.__contentBcr=g)}}else a._close()},a.__options.trackerInterval),a},_close:function(b,c,d){var e=this,f=!0;if(e._trigger({type:"close",event:b,stop:function(){f=!1}}),f||d){c&&e.__callbacks.close.push(c),e.__callbacks.open=[],e.__timeoutsClear();var g=function(){a.each(e.__callbacks.close,function(a,c){c.call(e,e,{event:b,origin:e._$origin[0]})}),e.__callbacks.close=[]};if("closed"!=e.__state){var i=!0,j=new Date,k=j.getTime(),l=k+e.__options.animationDuration[1];if("disappearing"==e.__state&&l>e.__closingTime&&(i=!1),i){e.__closingTime=l,"disappearing"!=e.__state&&e.__stateSet("disappearing");var m=function(){clearInterval(e.__tracker),e._trigger({type:"closing",event:b}),e._$tooltip.off("."+e.__namespace+"-triggerClose").removeClass("tooltipster-dying"),a(h.window).off("."+e.__namespace+"-triggerClose"),e.__$originParents.each(function(b,c){a(c).off("scroll."+e.__namespace+"-triggerClose")}),e.__$originParents=null,a(h.window.document.body).off("."+e.__namespace+"-triggerClose"),e._$origin.off("."+e.__namespace+"-triggerClose"),e._off("dismissable"),e.__stateSet("closed"),e._trigger({type:"after",event:b}),e.__options.functionAfter&&e.__options.functionAfter.call(e,e,{event:b,origin:e._$origin[0]}),g()};h.hasTransitions?(e._$tooltip.css({"-moz-animation-duration":e.__options.animationDuration[1]+"ms","-ms-animation-duration":e.__options.animationDuration[1]+"ms","-o-animation-duration":e.__options.animationDuration[1]+"ms","-webkit-animation-duration":e.__options.animationDuration[1]+"ms","animation-duration":e.__options.animationDuration[1]+"ms","transition-duration":e.__options.animationDuration[1]+"ms"}),e._$tooltip.clearQueue().removeClass("tooltipster-show").addClass("tooltipster-dying"),e.__options.animationDuration[1]>0&&e._$tooltip.delay(e.__options.animationDuration[1]),e._$tooltip.queue(m)):e._$tooltip.stop().fadeOut(e.__options.animationDuration[1],m)}}else g()}return e},_off:function(){return this.__$emitterPrivate.off.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments)),this},_on:function(){return this.__$emitterPrivate.on.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments)),this},_one:function(){return this.__$emitterPrivate.one.apply(this.__$emitterPrivate,Array.prototype.slice.apply(arguments)),this},_open:function(b,c){var e=this;if(!e.__destroying&&d(e._$origin)&&e.__enabled){var f=!0;if("closed"==e.__state&&(e._trigger({type:"before",event:b,stop:function(){f=!1}}),f&&e.__options.functionBefore&&(f=e.__options.functionBefore.call(e,e,{event:b,origin:e._$origin[0]}))),f!==!1&&null!==e.__Content){c&&e.__callbacks.open.push(c),e.__callbacks.close=[],e.__timeoutsClear();var g,i=function(){"stable"!=e.__state&&e.__stateSet("stable"),a.each(e.__callbacks.open,function(a,b){b.call(e,e,{origin:e._$origin[0],tooltip:e._$tooltip[0]})}),e.__callbacks.open=[]};if("closed"!==e.__state)g=0,"disappearing"===e.__state?(e.__stateSet("appearing"),h.hasTransitions?(e._$tooltip.clearQueue().removeClass("tooltipster-dying").addClass("tooltipster-show"),e.__options.animationDuration[0]>0&&e._$tooltip.delay(e.__options.animationDuration[0]),e._$tooltip.queue(i)):e._$tooltip.stop().fadeIn(i)):"stable"==e.__state&&i();else{if(e.__stateSet("appearing"),g=e.__options.animationDuration[0],e.__contentInsert(),e.reposition(b,!0),h.hasTransitions?(e._$tooltip.addClass("tooltipster-"+e.__options.animation).addClass("tooltipster-initial").css({"-moz-animation-duration":e.__options.animationDuration[0]+"ms","-ms-animation-duration":e.__options.animationDuration[0]+"ms","-o-animation-duration":e.__options.animationDuration[0]+"ms","-webkit-animation-duration":e.__options.animationDuration[0]+"ms","animation-duration":e.__options.animationDuration[0]+"ms","transition-duration":e.__options.animationDuration[0]+"ms"}),setTimeout(function(){"closed"!=e.__state&&(e._$tooltip.addClass("tooltipster-show").removeClass("tooltipster-initial"),e.__options.animationDuration[0]>0&&e._$tooltip.delay(e.__options.animationDuration[0]),e._$tooltip.queue(i))},0)):e._$tooltip.css("display","none").fadeIn(e.__options.animationDuration[0],i),e.__trackerStart(),a(h.window).on("resize."+e.__namespace+"-triggerClose",function(b){var c=a(document.activeElement);(c.is("input")||c.is("textarea"))&&a.contains(e._$tooltip[0],c[0])||e.reposition(b)}).on("scroll."+e.__namespace+"-triggerClose",function(a){e.__scrollHandler(a)}),e.__$originParents=e._$origin.parents(),e.__$originParents.each(function(b,c){a(c).on("scroll."+e.__namespace+"-triggerClose",function(a){e.__scrollHandler(a)})}),e.__options.triggerClose.mouseleave||e.__options.triggerClose.touchleave&&h.hasTouchCapability){e._on("dismissable",function(a){a.dismissable?a.delay?(m=setTimeout(function(){e._close(a.event)},a.delay),e.__timeouts.close.push(m)):e._close(a):clearTimeout(m)});var j=e._$origin,k="",l="",m=null;e.__options.interactive&&(j=j.add(e._$tooltip)),e.__options.triggerClose.mouseleave&&(k+="mouseenter."+e.__namespace+"-triggerClose ",l+="mouseleave."+e.__namespace+"-triggerClose "),e.__options.triggerClose.touchleave&&h.hasTouchCapability&&(k+="touchstart."+e.__namespace+"-triggerClose",l+="touchend."+e.__namespace+"-triggerClose touchcancel."+e.__namespace+"-triggerClose"),j.on(l,function(a){if(e._touchIsTouchEvent(a)||!e._touchIsEmulatedEvent(a)){var b="mouseleave"==a.type?e.__options.delay:e.__options.delayTouch;e._trigger({delay:b[1],dismissable:!0,event:a,type:"dismissable"})}}).on(k,function(a){!e._touchIsTouchEvent(a)&&e._touchIsEmulatedEvent(a)||e._trigger({dismissable:!1,event:a,type:"dismissable"})})}e.__options.triggerClose.originClick&&e._$origin.on("click."+e.__namespace+"-triggerClose",function(a){e._touchIsTouchEvent(a)||e._touchIsEmulatedEvent(a)||e._close(a)}),(e.__options.triggerClose.click||e.__options.triggerClose.tap&&h.hasTouchCapability)&&setTimeout(function(){if("closed"!=e.__state){var b="",c=a(h.window.document.body);e.__options.triggerClose.click&&(b+="click."+e.__namespace+"-triggerClose "),e.__options.triggerClose.tap&&h.hasTouchCapability&&(b+="touchend."+e.__namespace+"-triggerClose"),c.on(b,function(b){e._touchIsMeaningfulEvent(b)&&(e._touchRecordEvent(b),e.__options.interactive&&a.contains(e._$tooltip[0],b.target)||e._close(b))}),e.__options.triggerClose.tap&&h.hasTouchCapability&&c.on("touchstart."+e.__namespace+"-triggerClose",function(a){e._touchRecordEvent(a)})}},0),e._trigger("ready"),e.__options.functionReady&&e.__options.functionReady.call(e,e,{origin:e._$origin[0],tooltip:e._$tooltip[0]})}if(e.__options.timer>0){var m=setTimeout(function(){e._close()},e.__options.timer+g);e.__timeouts.close.push(m)}}}return e},_openShortly:function(a){var b=this,c=!0;if("stable"!=b.__state&&"appearing"!=b.__state&&!b.__timeouts.open&&(b._trigger({type:"start",event:a,stop:function(){c=!1}}),c)){var d=0==a.type.indexOf("touch")?b.__options.delayTouch:b.__options.delay;d[0]?b.__timeouts.open=setTimeout(function(){b.__timeouts.open=null,b.__pointerIsOverOrigin&&b._touchIsMeaningfulEvent(a)?(b._trigger("startend"),b._open(a)):b._trigger("startcancel")},d[0]):(b._trigger("startend"),b._open(a))}return b},_optionsExtract:function(b,c){var d=this,e=a.extend(!0,{},c),f=d.__options[b];return f||(f={},a.each(c,function(a,b){var c=d.__options[a];void 0!==c&&(f[a]=c)})),a.each(e,function(b,c){void 0!==f[b]&&("object"!=typeof c||c instanceof Array||null==c||"object"!=typeof f[b]||f[b]instanceof Array||null==f[b]?e[b]=f[b]:a.extend(e[b],f[b]))}),e},_plug:function(b){var c=a.tooltipster._plugin(b);if(!c)throw new Error('The "'+b+'" plugin is not defined');return c.instance&&a.tooltipster.__bridge(c.instance,this,c.name),this},_touchIsEmulatedEvent:function(a){for(var b=!1,c=(new Date).getTime(),d=this.__touchEvents.length-1;d>=0;d--){var e=this.__touchEvents[d];if(!(c-e.time<500))break;e.target===a.target&&(b=!0)}return b},_touchIsMeaningfulEvent:function(a){return this._touchIsTouchEvent(a)&&!this._touchSwiped(a.target)||!this._touchIsTouchEvent(a)&&!this._touchIsEmulatedEvent(a)},_touchIsTouchEvent:function(a){return 0==a.type.indexOf("touch")},_touchRecordEvent:function(a){return this._touchIsTouchEvent(a)&&(a.time=(new Date).getTime(),this.__touchEvents.push(a)),this},_touchSwiped:function(a){for(var b=!1,c=this.__touchEvents.length-1;c>=0;c--){var d=this.__touchEvents[c];if("touchmove"==d.type){b=!0;break}if("touchstart"==d.type&&a===d.target)break}return b},_trigger:function(){var b=Array.prototype.slice.apply(arguments);return"string"==typeof b[0]&&(b[0]={type:b[0]}),b[0].instance=this,b[0].origin=this._$origin?this._$origin[0]:null,b[0].tooltip=this._$tooltip?this._$tooltip[0]:null,this.__$emitterPrivate.trigger.apply(this.__$emitterPrivate,b),a.tooltipster._trigger.apply(a.tooltipster,b),this.__$emitterPublic.trigger.apply(this.__$emitterPublic,b),this},_unplug:function(b){var c=this;if(c[b]){var d=a.tooltipster._plugin(b);d.instance&&a.each(d.instance,function(a,d){c[a]&&c[a].bridged===c[b]&&delete c[a]}),c[b].__destroy&&c[b].__destroy(),delete c[b]}return c},close:function(a){return this.__destroyed?this.__destroyError():this._close(null,a),this},content:function(a){var b=this;if(void 0===a)return b.__Content;if(b.__destroyed)b.__destroyError();else if(b.__contentSet(a),null!==b.__Content){if("closed"!==b.__state&&(b.__contentInsert(),b.reposition(),b.__options.updateAnimation))if(h.hasTransitions){var c=b.__options.updateAnimation;b._$tooltip.addClass("tooltipster-update-"+c),setTimeout(function(){"closed"!=b.__state&&b._$tooltip.removeClass("tooltipster-update-"+c)},1e3)}else b._$tooltip.fadeTo(200,.5,function(){"closed"!=b.__state&&b._$tooltip.fadeTo(200,1)})}else b._close();return b},destroy:function(){var b=this;if(b.__destroyed)b.__destroyError();else{"closed"!=b.__state&&b.option("animationDuration",0)._close(null,null,!0),b._trigger("destroy"),b.__destroyed=!0,b._$origin.removeData(b.__namespace).off("."+b.__namespace+"-triggerOpen"),a(h.window.document.body).off("."+b.__namespace+"-triggerOpen");var c=b._$origin.data("tooltipster-ns");if(c)if(1===c.length){var d=null;"previous"==b.__options.restoration?d=b._$origin.data("tooltipster-initialTitle"):"current"==b.__options.restoration&&(d="string"==typeof b.__Content?b.__Content:a("
").append(b.__Content).html()),d&&b._$origin.attr("title",d),b._$origin.removeClass("tooltipstered"),b._$origin.removeData("tooltipster-ns").removeData("tooltipster-initialTitle")}else c=a.grep(c,function(a,c){return a!==b.__namespace}),b._$origin.data("tooltipster-ns",c);b._trigger("destroyed"),b._off(),b.off(),b.__Content=null,b.__$emitterPrivate=null,b.__$emitterPublic=null,b.__options.parent=null,b._$origin=null,b._$tooltip=null,a.tooltipster.__instancesLatestArr=a.grep(a.tooltipster.__instancesLatestArr,function(a,c){return b!==a}),clearInterval(b.__garbageCollector)}return b},disable:function(){return this.__destroyed?(this.__destroyError(),this):(this._close(),this.__enabled=!1,this)},elementOrigin:function(){return this.__destroyed?void this.__destroyError():this._$origin[0]},elementTooltip:function(){return this._$tooltip?this._$tooltip[0]:null},enable:function(){return this.__enabled=!0,this},hide:function(a){return this.close(a)},instance:function(){return this},off:function(){return this.__destroyed||this.__$emitterPublic.off.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},on:function(){return this.__destroyed?this.__destroyError():this.__$emitterPublic.on.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},one:function(){return this.__destroyed?this.__destroyError():this.__$emitterPublic.one.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this},open:function(a){return this.__destroyed?this.__destroyError():this._open(null,a),this},option:function(b,c){return void 0===c?this.__options[b]:(this.__destroyed?this.__destroyError():(this.__options[b]=c,this.__optionsFormat(),a.inArray(b,["trigger","triggerClose","triggerOpen"])>=0&&this.__prepareOrigin(),"selfDestruction"===b&&this.__prepareGC()),this)},reposition:function(a,b){var c=this;return c.__destroyed?c.__destroyError():"closed"!=c.__state&&d(c._$origin)&&(b||d(c._$tooltip))&&(b||c._$tooltip.detach(),c.__Geometry=c.__geometry(),c._trigger({type:"reposition",event:a,helper:{geo:c.__Geometry}})),c},show:function(a){return this.open(a)},status:function(){return{destroyed:this.__destroyed,enabled:this.__enabled,open:"closed"!==this.__state,state:this.__state}},triggerHandler:function(){return this.__destroyed?this.__destroyError():this.__$emitterPublic.triggerHandler.apply(this.__$emitterPublic,Array.prototype.slice.apply(arguments)),this}},a.fn.tooltipster=function(){var b=Array.prototype.slice.apply(arguments),c="You are using a single HTML element as content for several tooltips. You probably want to set the contentCloning option to TRUE.";if(0===this.length)return this;if("string"==typeof b[0]){var d="#*$~&";return this.each(function(){var e=a(this).data("tooltipster-ns"),f=e?a(this).data(e[0]):null;if(!f)throw new Error("You called Tooltipster's \""+b[0]+'" method on an uninitialized element');if("function"!=typeof f[b[0]])throw new Error('Unknown method "'+b[0]+'"');this.length>1&&"content"==b[0]&&(b[1]instanceof a||"object"==typeof b[1]&&null!=b[1]&&b[1].tagName)&&!f.__options.contentCloning&&f.__options.debug&&console.log(c);var g=f[b[0]](b[1],b[2]);return g!==f||"instance"===b[0]?(d=g,!1):void 0}),"#*$~&"!==d?d:this}a.tooltipster.__instancesLatestArr=[];var e=b[0]&&void 0!==b[0].multiple,g=e&&b[0].multiple||!e&&f.multiple,h=b[0]&&void 0!==b[0].content,i=h&&b[0].content||!h&&f.content,j=b[0]&&void 0!==b[0].contentCloning,k=j&&b[0].contentCloning||!j&&f.contentCloning,l=b[0]&&void 0!==b[0].debug,m=l&&b[0].debug||!l&&f.debug;return this.length>1&&(i instanceof a||"object"==typeof i&&null!=i&&i.tagName)&&!k&&m&&console.log(c),this.each(function(){var c=!1,d=a(this),e=d.data("tooltipster-ns"),f=null;e?g?c=!0:m&&(console.log("Tooltipster: one or more tooltips are already attached to the element below. Ignoring."),console.log(this)):c=!0,c&&(f=new a.Tooltipster(this,b[0]),e||(e=[]),e.push(f.__namespace),d.data("tooltipster-ns",e),d.data(f.__namespace,f),f.__options.functionInit&&f.__options.functionInit.call(f,f,{origin:this}),f._trigger("init")),a.tooltipster.__instancesLatestArr.push(f)}),this},b.prototype={__init:function(b){this.__$tooltip=b,this.__$tooltip.css({left:0,overflow:"hidden",position:"absolute",top:0}).find(".tooltipster-content").css("overflow","auto"),this.$container=a('
').append(this.__$tooltip).appendTo(h.window.document.body)},__forceRedraw:function(){var a=this.__$tooltip.parent();this.__$tooltip.detach(),this.__$tooltip.appendTo(a)},constrain:function(a,b){return this.constraints={width:a,height:b},this.__$tooltip.css({display:"block",height:"",overflow:"auto",width:a}),this},destroy:function(){this.__$tooltip.detach().find(".tooltipster-content").css({display:"",overflow:""}),this.$container.remove()},free:function(){return this.constraints=null,this.__$tooltip.css({display:"",height:"",overflow:"visible",width:""}),this},measure:function(){this.__forceRedraw();var a=this.__$tooltip[0].getBoundingClientRect(),b={size:{height:a.height||a.bottom-a.top,width:a.width||a.right-a.left}};if(this.constraints){var c=this.__$tooltip.find(".tooltipster-content"),d=this.__$tooltip.outerHeight(),e=c[0].getBoundingClientRect(),f={height:d<=this.constraints.height,width:a.width<=this.constraints.width&&e.width>=c[0].scrollWidth-1};b.fits=f.height&&f.width}return h.IE&&h.IE<=11&&b.size.width!==h.window.document.documentElement.clientWidth&&(b.size.width=Math.ceil(b.size.width)+1),b}};var j=navigator.userAgent.toLowerCase();-1!=j.indexOf("msie")?h.IE=parseInt(j.split("msie")[1]):-1!==j.toLowerCase().indexOf("trident")&&-1!==j.indexOf(" rv:11")?h.IE=11:-1!=j.toLowerCase().indexOf("edge/")&&(h.IE=parseInt(j.toLowerCase().split("edge/")[1]));var k="tooltipster.sideTip";return a.tooltipster._plugin({name:k,instance:{__defaults:function(){return{arrow:!0,distance:6,functionPosition:null,maxWidth:null,minIntersection:16,minWidth:0,position:null,side:"top",viewportAware:!0}},__init:function(a){var b=this;b.__instance=a,b.__namespace="tooltipster-sideTip-"+Math.round(1e6*Math.random()),b.__previousState="closed",b.__options,b.__optionsFormat(),b.__instance._on("state."+b.__namespace,function(a){"closed"==a.state?b.__close():"appearing"==a.state&&"closed"==b.__previousState&&b.__create(),b.__previousState=a.state}),b.__instance._on("options."+b.__namespace,function(){b.__optionsFormat()}),b.__instance._on("reposition."+b.__namespace,function(a){b.__reposition(a.event,a.helper)})},__close:function(){this.__instance.content()instanceof a&&this.__instance.content().detach(),this.__instance._$tooltip.remove(),this.__instance._$tooltip=null},__create:function(){var b=a('
');this.__options.arrow||b.find(".tooltipster-box").css("margin",0).end().find(".tooltipster-arrow").hide(),this.__options.minWidth&&b.css("min-width",this.__options.minWidth+"px"),this.__options.maxWidth&&b.css("max-width",this.__options.maxWidth+"px"),this.__instance._$tooltip=b,this.__instance._trigger("created");},__destroy:function(){this.__instance._off("."+self.__namespace)},__optionsFormat:function(){var b=this;if(b.__options=b.__instance._optionsExtract(k,b.__defaults()),b.__options.position&&(b.__options.side=b.__options.position),"object"!=typeof b.__options.distance&&(b.__options.distance=[b.__options.distance]),b.__options.distance.length<4&&(void 0===b.__options.distance[1]&&(b.__options.distance[1]=b.__options.distance[0]),void 0===b.__options.distance[2]&&(b.__options.distance[2]=b.__options.distance[0]),void 0===b.__options.distance[3]&&(b.__options.distance[3]=b.__options.distance[1]),b.__options.distance={top:b.__options.distance[0],right:b.__options.distance[1],bottom:b.__options.distance[2],left:b.__options.distance[3]}),"string"==typeof b.__options.side){var c={top:"bottom",right:"left",bottom:"top",left:"right"};b.__options.side=[b.__options.side,c[b.__options.side]],"left"==b.__options.side[0]||"right"==b.__options.side[0]?b.__options.side.push("top","bottom"):b.__options.side.push("right","left")}6===a.tooltipster._env.IE&&b.__options.arrow!==!0&&(b.__options.arrow=!1)},__reposition:function(b,c){var d,e=this,f=e.__targetFind(c),g=[];e.__instance._$tooltip.detach();var h=e.__instance._$tooltip.clone(),i=a.tooltipster._getRuler(h),j=!1,k=e.__instance.option("animation");switch(k&&h.removeClass("tooltipster-"+k),a.each(["window","document"],function(d,k){var l=null;if(e.__instance._trigger({container:k,helper:c,satisfied:j,takeTest:function(a){l=a},results:g,type:"positionTest"}),1==l||0!=l&&0==j&&("window"!=k||e.__options.viewportAware))for(var d=0;d=h.outerSize.width&&c.geo.available[k][n].height>=h.outerSize.height?h.fits=!0:h.fits=!1:h.fits=p.fits,"window"==k&&(h.fits?"top"==n||"bottom"==n?h.whole=c.geo.origin.windowOffset.right>=e.__options.minIntersection&&c.geo.window.size.width-c.geo.origin.windowOffset.left>=e.__options.minIntersection:h.whole=c.geo.origin.windowOffset.bottom>=e.__options.minIntersection&&c.geo.window.size.height-c.geo.origin.windowOffset.top>=e.__options.minIntersection:h.whole=!1),g.push(h),h.whole)j=!0;else if("natural"==h.mode&&(h.fits||h.size.width<=c.geo.available[k][n].width))return!1}})}}),e.__instance._trigger({edit:function(a){g=a},event:b,helper:c,results:g,type:"positionTested"}),g.sort(function(a,b){if(a.whole&&!b.whole)return-1;if(!a.whole&&b.whole)return 1;if(a.whole&&b.whole){var c=e.__options.side.indexOf(a.side),d=e.__options.side.indexOf(b.side);return d>c?-1:c>d?1:"natural"==a.mode?-1:1}if(a.fits&&!b.fits)return-1;if(!a.fits&&b.fits)return 1;if(a.fits&&b.fits){var c=e.__options.side.indexOf(a.side),d=e.__options.side.indexOf(b.side);return d>c?-1:c>d?1:"natural"==a.mode?-1:1}return"document"==a.container&&"bottom"==a.side&&"natural"==a.mode?-1:1}),d=g[0],d.coord={},d.side){case"left":case"right":d.coord.top=Math.floor(d.target-d.size.height/2);break;case"bottom":case"top":d.coord.left=Math.floor(d.target-d.size.width/2)}switch(d.side){case"left":d.coord.left=c.geo.origin.windowOffset.left-d.outerSize.width;break;case"right":d.coord.left=c.geo.origin.windowOffset.right+d.distance.horizontal;break;case"top":d.coord.top=c.geo.origin.windowOffset.top-d.outerSize.height;break;case"bottom":d.coord.top=c.geo.origin.windowOffset.bottom+d.distance.vertical}"window"==d.container?"top"==d.side||"bottom"==d.side?d.coord.left<0?c.geo.origin.windowOffset.right-this.__options.minIntersection>=0?d.coord.left=0:d.coord.left=c.geo.origin.windowOffset.right-this.__options.minIntersection-1:d.coord.left>c.geo.window.size.width-d.size.width&&(c.geo.origin.windowOffset.left+this.__options.minIntersection<=c.geo.window.size.width?d.coord.left=c.geo.window.size.width-d.size.width:d.coord.left=c.geo.origin.windowOffset.left+this.__options.minIntersection+1-d.size.width):d.coord.top<0?c.geo.origin.windowOffset.bottom-this.__options.minIntersection>=0?d.coord.top=0:d.coord.top=c.geo.origin.windowOffset.bottom-this.__options.minIntersection-1:d.coord.top>c.geo.window.size.height-d.size.height&&(c.geo.origin.windowOffset.top+this.__options.minIntersection<=c.geo.window.size.height?d.coord.top=c.geo.window.size.height-d.size.height:d.coord.top=c.geo.origin.windowOffset.top+this.__options.minIntersection+1-d.size.height):(d.coord.left>c.geo.window.size.width-d.size.width&&(d.coord.left=c.geo.window.size.width-d.size.width),d.coord.left<0&&(d.coord.left=0)),e.__sideChange(h,d.side),c.tooltipClone=h[0],c.tooltipParent=e.__instance.option("parent").parent[0],c.mode=d.mode,c.whole=d.whole,c.origin=e.__instance._$origin[0],c.tooltip=e.__instance._$tooltip[0],delete d.container,delete d.fits,delete d.mode,delete d.outerSize,delete d.whole,d.distance=d.distance.horizontal||d.distance.vertical;var l=a.extend(!0,{},d);if(e.__instance._trigger({edit:function(a){d=a},event:b,helper:c,position:l,type:"position"}),e.__options.functionPosition){var m=e.__options.functionPosition.call(e,e.__instance,c,l);m&&(d=m)}i.destroy();var n,o;"top"==d.side||"bottom"==d.side?(n={prop:"left",val:d.target-d.coord.left},o=d.size.width-this.__options.minIntersection):(n={prop:"top",val:d.target-d.coord.top},o=d.size.height-this.__options.minIntersection),n.valo&&(n.val=o);var p;p=c.geo.origin.fixedLineage?c.geo.origin.windowOffset:{left:c.geo.origin.windowOffset.left+c.geo.window.scroll.left,top:c.geo.origin.windowOffset.top+c.geo.window.scroll.top},d.coord={left:p.left+(d.coord.left-c.geo.origin.windowOffset.left),top:p.top+(d.coord.top-c.geo.origin.windowOffset.top)},e.__sideChange(e.__instance._$tooltip,d.side),c.geo.origin.fixedLineage?e.__instance._$tooltip.css("position","fixed"):e.__instance._$tooltip.css("position",""),e.__instance._$tooltip.css({left:d.coord.left,top:d.coord.top,height:d.size.height,width:d.size.width}).find(".tooltipster-arrow").css({left:"",top:""}).css(n.prop,n.val),e.__instance._$tooltip.appendTo(e.__instance.option("parent")),e.__instance._trigger({type:"repositioned",event:b,position:d})},__sideChange:function(a,b){a.removeClass("tooltipster-bottom").removeClass("tooltipster-left").removeClass("tooltipster-right").removeClass("tooltipster-top").addClass("tooltipster-"+b)},__targetFind:function(a){var b={},c=this.__instance._$origin[0].getClientRects();if(c.length>1){var d=this.__instance._$origin.css("opacity");1==d&&(this.__instance._$origin.css("opacity",.99),c=this.__instance._$origin[0].getClientRects(),this.__instance._$origin.css("opacity",1))}if(c.length<2)b.top=Math.floor(a.geo.origin.windowOffset.left+a.geo.origin.size.width/2),b.bottom=b.top,b.left=Math.floor(a.geo.origin.windowOffset.top+a.geo.origin.size.height/2),b.right=b.left;else{var e=c[0];b.top=Math.floor(e.left+(e.right-e.left)/2),e=c.length>2?c[Math.ceil(c.length/2)-1]:c[0],b.right=Math.floor(e.top+(e.bottom-e.top)/2),e=c[c.length-1],b.bottom=Math.floor(e.left+(e.right-e.left)/2),e=c.length>2?c[Math.ceil((c.length+1)/2)-1]:c[c.length-1],b.left=Math.floor(e.top+(e.bottom-e.top)/2)}return b}}}),a}); /* NchanSubscriber */ -!function(t,e,s){"use strict";var i=function(t,e){var s={};function i(t){return t?function(t){for(var e in i.prototype)t[e]=i.prototype[e];return t}(t):void 0}(function(){var i=["responseType","withCredentials","timeout","onprogress"];function r(t,e,s){t[e]=t[e]||s}s.ajax=function(s,n){var a=s.headers||{},o=s.body,h=s.method||(o?"POST":"GET"),c=!1,l=function(e){if(e&&t.XDomainRequest&&!/MSIE 1/.test(navigator.userAgent))return new XDomainRequest;if(t.XMLHttpRequest)return new XMLHttpRequest}(s.cors);function d(t,s){return function(){c||(n(l.status===e?t:l.status,0===l.status?"Error":l.response||l.responseText||s,l),c=!0)}}l.open(h,s.url,!0);var u=l.onload=d(200);l.onreadystatechange=function(){4===l.readyState&&u()},l.onerror=d(null,"Error"),l.ontimeout=d(null,"Timeout"),l.onabort=d(null,"Abort"),o&&(r(a,"X-Requested-With","XMLHttpRequest"),t.FormData&&o instanceof t.FormData||r(a,"Content-Type","application/x-www-form-urlencoded"));for(var p=0,m=i.length;pi;++i)s[i].apply(this,e)}return this},i.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks["$"+t]||[]},i.prototype.hasListeners=function(t){return!!this.listeners(t).length};var r,n=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){return function(){t.apply(e,arguments)}},a={};function o(e,s){if("undefined"!=typeof window&&this===window)throw"use 'new NchanSubscriber(...)' to initialize";if(this.url=e,"string"==typeof(s=s||{})&&(s={subscriber:s}),s.transport&&!s.subscriber&&(s.subscriber=s.transport),"string"==typeof s.subscriber&&(s.subscriber=[s.subscriber]),this.desiredTransport=s.subscriber,s.shared){if(!("localStorage"in t))throw"localStorage unavailable for use in shared NchanSubscriber";var i="NchanSubscriber:"+this.url+":shared:",r=function(t){return i+t},a=t.localStorage;this.shared={id:""+Math.random()+Math.random(),key:r,get:function(t){return a.getItem(r(t))},set:function(t,e){return a.setItem(r(t),e)},setWithId:n(function(t,e){return this.shared.set(t,"##"+this.shared.id+":"+e)},this),getWithId:n(function(t){return this.shared.stripIdFromVal(this.shared.get(t))},this),stripIdFromVal:function(t){if(!t)return t;var e=t.indexOf(":");return t[0]==t[1]&&"#"==t[0]&&e?t.substring(e+1,t.length):t},remove:function(t){return a.removeItem(r(t))},matchEventKey:n(function(t,e){return(!t.storageArea||t.storageArea==a)&&t.key==r(e)},this),matchEventKeyWithId:n(function(t,e){if(this.shared.matchEventKey(t,e)){var s=t.newValue,i=s.indexOf(":");if(s[0]!=s[1]||"#"!=s[0]||!i)return!0;var r=s.substring(2,i);return r!=this.shared.id}return!1},this),setRole:n(function(t){if("master"==t&&"master"!=this.shared.role){var e=(new Date).getTime()/1e3;this.shared.setWithId("master:created",e),this.shared.setWithId("master:lastSeen",e)}return"slave"!=t||this.lastMessageId||(this.lastMessageId=this.shared.get("msg:id")),this.shared.role=t,this},this),demoteToSlave:n(function(){if("master"!=this.shared.role)throw"can't demote non-master to slave";this.running?(this.stop(),this.shared.setRole("slave"),this.initializeTransport(),this.start()):this.initializeTransport()},this),maybePromoteToMaster:n(function(){if(!this.running&&!this.starting)return this;if(!this.shared.maybePromotingToMaster){var e;this.shared.maybePromotingToMaster=!0;var s,i=0,r=Math.random(),a=r,o=n(function(t){var s=parseFloat(this.shared.getWithId("lotteryTime")),i=parseFloat(this.shared.getWithId("lottery")),r=!s||s>(new Date).getTime()-4e3;r&&i&&(!a||i>a)&&(a=i),t||e()},this);o(!0),this.shared.setWithId("lottery",r),this.shared.setWithId("lotteryTime",(new Date).getTime()/1e3);var h=n(function(t){if(this.shared.matchEventKeyWithId(t,"lottery")&&t.newValue){i+=1;var e=parseFloat(this.shared.stripIdFromVal(t.newValue)),s=parseFloat(this.shared.stripIdFromVal(t.oldValue));s>e&&this.shared.setWithId("lottery",s),(!a||e>=a)&&(a=e)}},this);t.addEventListener("storage",h);var c=n(function(){this.shared.maybePromotingToMaster=!1,t.removeEventListener("storage",h),s&&clearInterval(s),this.shared&&"master"==this.shared.role&&(this.shared.remove("lottery"),this.shared.remove("lotteryTime")),this.running?(this.stop(),this.initializeTransport(),this.start()):(this.initializeTransport(),this.starting&&this.start())},this);e=n(function(){r=a&&(0==i?(this.shared.setRole("master"),c()):i=0)},this),s=t.setInterval(o,2e3)}},this),masterCheckInterval:1e4}}var o;if(this.lastMessageId=s.id||s.msgId,this.reconnect=void 0===s.reconnect||s.reconnect,this.reconnectTimeout=s.reconnectTimeout||1e3,s.reconnect){var h,c="NchanSubscriber:"+e+":lastMessageId";if("persist"==s.reconnect){if(!(h="localStorage"in t&&t.localStorage))throw"can't use reconnect: 'persist' option: localStorage not available"}else{if("session"!=s.reconnect)throw"invalid 'reconnect' option value "+s.reconnect;if(!(h="sessionStorage"in t&&t.sessionStorage))throw"can't use reconnect: 'session' option: sessionStorage not available"}o=n(function(t){this.shared&&"slave"==this.shared.role||h.setItem(c,t)},this),this.lastMessageId=h.getItem(c)}else o=function(){};var l,d,u=n(function(){this.running&&this.stop(),this.shared&&"master"==this.shared.role&&this.shared.setWithId("status","disconnected")},this);t.addEventListener("beforeunload",u,!1),t.addEventListener("DOMContentLoaded",function(){t.removeEventListener("beforeunload",u,!1),t.addEventListener("unload",u,!1)},!1),l=this.shared?n(function(t,e){"master"==this.shared.role&&("message"==t?(this.shared.set("msg:id",e[1]&&e[1].id||""),this.shared.set("msg:content-type",e[1]&&e[1]["content-type"]||""),this.shared.set("msg",e[0])):"error"==t||("connecting"==t?this.shared.setWithId("status","connecting"):"connect"==t?this.shared.setWithId("status","connected"):"reconnect"==t?this.shared.setWithId("status","reconnecting"):"disconnect"==t&&this.shared.setWithId("status","disconnected")))},this):function(){};var p=n(function(){d||!this.running||!this.reconnect||this.transport.reconnecting||this.transport.doNotReconnect?l("disconnect"):(l("reconnect"),d=t.setTimeout(n(function(){d=null,this.stop(),this.start()},this),this.reconnectTimeout))},this);this.on("message",function(t,e){this.lastMessageId=e.id,e.id&&o(e.id),l("message",[t,e])}),this.on("error",function(t,e){p(t,e),l("error",[t,e])}),this.on("connect",function(){this.connected=!0,l("connect")}),this.on("__disconnect",function(t,e){this.connected=!1,this.emit("disconnect",t,e),p(t,e)})}function h(t,e){if(e){var s=t.match(/(\?.*)$/);t+=(s?"&":"?")+"last_event_id="+encodeURIComponent(e)}return t}return i(o.prototype),o.prototype.initializeTransport=function(t){if(t&&(this.desiredTransport=t),this.shared&&"slave"==this.shared.role)this.transport=new this.SubscriberClass.__slave(n(this.emit,this));else{var e,s=n(function(t){if(!this.SubscriberClass[t])throw"unknown subscriber type "+t;try{return this.transport=new this.SubscriberClass[t](n(this.emit,this)),this.transport}catch(t){}},this);if(this.desiredTransport)for(e=0;e=200&&t<=210){var a=n.getResponseHeader("Content-Type");this.parseMultipartMixedMessage(a,e,n)||this.emit("message",e||"",{"content-type":a,id:this.msgIdFromResponseHeaders(n)}),this.reqStartTime=(new Date).getTime(),this.req=s.ajax({url:this.url,headers:this.headers},i)}else 0==t&&"Error"==e&&4==n.readyState||null===t&&"Abort"!=e?(this.emit("__disconnect",t||0,e),delete this.req):null!==t?(this.emit("error",t,e),delete this.req):(delete this.req,this.emit("__disconnect"))},this),this.reqStartTime=(new Date).getTime(),this.req=s.ajax({url:this.url,headers:this.headers},i),this.emit("connect"),this},t.prototype.parseMultipartMixedMessage=function(t,e,s){var i=t&&t.match(/^multipart\/mixed;\s+boundary=(.*)$/);if(!i)return!1;var r=i[1],n=e.split("--"+r);if(""!=n[0]||!n[n.length-1].match(/--\r?\n/))throw"weird multipart/mixed split";for(var a in n=n.slice(1,-1)){var o=(i=n[a].match(/^(.*)\r?\n\r?\n([\s\S]*)\r?\n$/m))[1].split("\n"),h={};for(var c in o){var l=o[c].match(/^([^:]+):\s+(.*)/);l&&"Content-Type"==l[1]&&(h["content-type"]=l[2])}a==n.length-1&&(h.id=this.msgIdFromResponseHeaders(s)),this.emit("message",i[2],h)}return!0},t.prototype.msgIdFromResponseHeaders=function(t){var e,s;return e=t.getResponseHeader("Last-Modified"),s=t.getResponseHeader("Etag"),e?Date.parse(e)/1e3+":"+(s||"0"):s||null},t.prototype.cancel=function(){return this.req&&(this.req.abort(),delete this.req),this},t}(),__slave:function(){function s(t){this.emit=t,this.doNotReconnect=!0}return s.prototype.listen=function(s,i){this.shared=i,this.statusChangeChecker=n(function(t){if(this.shared.matchEventKey(t,"msg")){var s=this.shared.get("msg:id"),i=this.shared.get("msg:content-type"),r=this.shared.get("msg");this.emit("message",r,{id:""==s?e:s,"content-type":""==i?e:i})}},this),t.addEventListener("storage",this.statusChangeChecker)},s.prototype.cancel=function(){t.removeEventListener("storage",this.statusChangeChecker)},s}()},o}(t);"object"==typeof module&&null!=module&&module.exports?module.exports=i:"function"==typeof define&&define.amd?define(function(){return i}):t.NchanSubscriber=i}("undefined"!=typeof window?window:this); \ No newline at end of file +!function(t,e,s){"use strict";var i=function(t,e){var s={};function i(t){return t?function(t){for(var e in i.prototype)t[e]=i.prototype[e];return t}(t):void 0}(function(){var i=["responseType","withCredentials","timeout","onprogress"];function r(t,e,s){t[e]=t[e]||s}s.ajax=function(s,n){var o=s.headers||{},a=s.body,h=s.method||(a?"POST":"GET"),c=!1,l=function(e){if(e&&t.XDomainRequest&&!/MSIE 1/.test(navigator.userAgent))return new XDomainRequest;if(t.XMLHttpRequest)return new XMLHttpRequest}(s.cors);function d(t,s){return function(){c||(n(l.status===e?t:l.status,0===l.status?"Error":l.response||l.responseText||s,l),c=!0)}}l.open(h,s.url,!0);var u=l.onload=d(200);l.onreadystatechange=function(){4===l.readyState&&u()},l.onerror=d(null,"Error"),l.ontimeout=d(null,"Timeout"),l.onabort=d(null,"Abort"),a&&(r(o,"X-Requested-With","XMLHttpRequest"),t.FormData&&a instanceof t.FormData||r(o,"Content-Type","application/x-www-form-urlencoded"));for(var p=0,m=i.length;pi;++i)s[i].apply(this,e);return this},i.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks["$"+t]||[]},i.prototype.hasListeners=function(t){return!!this.listeners(t).length};var r,n=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){return function(){t.apply(e,arguments)}},o={};function a(e,s){if("undefined"!=typeof window&&this===window)throw"use 'new NchanSubscriber(...)' to initialize";if(this.url=e,"string"==typeof(s=s||{})&&(s={subscriber:s}),s.transport&&!s.subscriber&&(s.subscriber=s.transport),"string"==typeof s.subscriber&&(s.subscriber=[s.subscriber]),this.desiredTransport=s.subscriber,s.shared){if(!("localStorage"in t))throw"localStorage unavailable for use in shared NchanSubscriber";var i="NchanSubscriber:"+this.url+":shared:",r=function(t){return i+t},o=t.localStorage;this.shared={id:""+Math.random()+Math.random(),key:r,get:function(t){return o.getItem(r(t))},set:function(t,e){return o.setItem(r(t),e)},setWithId:n(function(t,e){return this.shared.set(t,"##"+this.shared.id+":"+e)},this),getWithId:n(function(t){return this.shared.stripIdFromVal(this.shared.get(t))},this),stripIdFromVal:function(t){if(!t)return t;var e=t.indexOf(":");return t[0]==t[1]&&"#"==t[0]&&e?t.substring(e+1,t.length):t},remove:function(t){return o.removeItem(r(t))},matchEventKey:n(function(t,e){return(!t.storageArea||t.storageArea==o)&&t.key==r(e)},this),matchEventKeyWithId:n(function(t,e){if(this.shared.matchEventKey(t,e)){var s=t.newValue,i=s.indexOf(":");if(s[0]!=s[1]||"#"!=s[0]||!i)return!0;var r=s.substring(2,i);return r!=this.shared.id}return!1},this),setRole:n(function(t){if("master"==t&&"master"!=this.shared.role){var e=(new Date).getTime()/1e3;this.shared.setWithId("master:created",e),this.shared.setWithId("master:lastSeen",e)}return"slave"!=t||this.lastMessageId||(this.lastMessageId=this.shared.get("msg:id")),this.shared.role=t,this},this),demoteToSlave:n(function(){if("master"!=this.shared.role)throw"can't demote non-master to slave";this.running?(this.stop(),this.shared.setRole("slave"),this.initializeTransport(),this.start()):this.initializeTransport()},this),maybePromoteToMaster:n(function(){if(!this.running&&!this.starting)return this;if(!this.shared.maybePromotingToMaster){var e;this.shared.maybePromotingToMaster=!0;var s,i=0,r=Math.random(),o=r,a=n(function(t){var s=parseFloat(this.shared.getWithId("lotteryTime")),i=parseFloat(this.shared.getWithId("lottery")),r=!s||s>(new Date).getTime()-4e3;r&&i&&(!o||i>o)&&(o=i),t||e()},this);a(!0),this.shared.setWithId("lottery",r),this.shared.setWithId("lotteryTime",(new Date).getTime()/1e3);var h=n(function(t){if(this.shared.matchEventKeyWithId(t,"lottery")&&t.newValue){i+=1;var e=parseFloat(this.shared.stripIdFromVal(t.newValue)),s=parseFloat(this.shared.stripIdFromVal(t.oldValue));s>e&&this.shared.setWithId("lottery",s),(!o||e>=o)&&(o=e)}},this);t.addEventListener("storage",h);var c=n(function(){this.shared.maybePromotingToMaster=!1,t.removeEventListener("storage",h),s&&clearInterval(s),this.shared&&"master"==this.shared.role&&(this.shared.remove("lottery"),this.shared.remove("lotteryTime")),this.running?(this.stop(),this.initializeTransport(),this.start()):(this.initializeTransport(),this.starting&&this.start())},this);e=n(function(){r=o&&(0==i?(this.shared.setRole("master"),c()):i=0)},this),s=t.setInterval(a,2e3)}},this),masterCheckInterval:1e4}}var a;if(this.lastMessageId=s.id||s.msgId,this.reconnect=void 0===s.reconnect||s.reconnect,this.reconnectTimeout=s.reconnectTimeout||1e3,s.reconnect){var h,c="NchanSubscriber:"+e+":lastMessageId";if("persist"==s.reconnect){if(!(h="localStorage"in t&&t.localStorage))throw"can't use reconnect: 'persist' option: localStorage not available"}else{if("session"!=s.reconnect)throw"invalid 'reconnect' option value "+s.reconnect;if(!(h="sessionStorage"in t&&t.sessionStorage))throw"can't use reconnect: 'session' option: sessionStorage not available"}a=n(function(t){this.shared&&"slave"==this.shared.role||h.setItem(c,t)},this),this.lastMessageId=h.getItem(c)}else a=function(){};var l,d,u=n(function(){this.running&&this.stop(),this.shared&&"master"==this.shared.role&&this.shared.setWithId("status","disconnected")},this);t.addEventListener("beforeunload",u,!1),t.addEventListener("DOMContentLoaded",function(){t.removeEventListener("beforeunload",u,!1),t.addEventListener("unload",u,!1)},!1),l=this.shared?n(function(t,e){"master"==this.shared.role&&("message"==t?(this.shared.set("msg:id",e[1]&&e[1].id||""),this.shared.set("msg:content-type",e[1]&&e[1]["content-type"]||""),this.shared.set("msg",e[0])):"error"==t||("connecting"==t?this.shared.setWithId("status","connecting"):"connect"==t?this.shared.setWithId("status","connected"):"reconnect"==t?this.shared.setWithId("status","reconnecting"):"disconnect"==t&&this.shared.setWithId("status","disconnected")))},this):function(){};var p=n(function(){d||!this.running||!this.reconnect||this.transport.reconnecting||this.transport.doNotReconnect?l("disconnect"):(l("reconnect"),d=t.setTimeout(n(function(){d=null,this.stop(),this.start()},this),this.reconnectTimeout))},this);this.on("message",function(t,e){this.lastMessageId=e.id,e.id&&a(e.id),l("message",[t,e])}),this.on("error",function(t,e){p(t,e),l("error",[t,e])}),this.on("connect",function(){this.connected=!0,l("connect")}),this.on("__disconnect",function(t,e){this.connected=!1,this.emit("disconnect",t,e),p(t,e)})}function h(t,e){if(e){var s=t.match(/(\?.*)$/);t+=(s?"&":"?")+"last_event_id="+encodeURIComponent(e)}return t}return i(a.prototype),a.prototype.initializeTransport=function(t){if(t&&(this.desiredTransport=t),this.shared&&"slave"==this.shared.role)this.transport=new this.SubscriberClass.__slave(n(this.emit,this));else{var e,s=n(function(t){if(!this.SubscriberClass[t])throw"unknown subscriber type "+t;try{return this.transport=new this.SubscriberClass[t](n(this.emit,this)),this.transport}catch(t){}},this);if(this.desiredTransport)for(e=0;e=200&&t<=210){var i=s.getResponseHeader("Content-Type");this.parseMultipartMixedMessage(i,e,s)||this.emit("message",e||"",{"content-type":i,id:this.msgIdFromResponseHeaders(s)}),this.req&&this.pollingRequest()}else 0==t&&"Error"==e&&4==s.readyState||null===t&&"Abort"!=e?(this.emit("__disconnect",t||0,e),delete this.req):null!==t?(this.emit("error",t,e),delete this.req):(delete this.req,this.emit("__disconnect"))},this),this.pollingRequest(),this.emit("connect"),this},t.prototype.parseMultipartMixedMessage=function(t,e,s){var i=t&&t.match(/^multipart\/mixed;\s+boundary=(.*)$/);if(!i)return!1;var r=i[1],n=e.split("--"+r);if(""!=n[0]||!n[n.length-1].match(/--\r?\n/))throw"weird multipart/mixed split";n=n.slice(1,-1);for(var o in n){var a=(i=n[o].match(/^(.*)\r?\n\r?\n([\s\S]*)\r?\n$/m))[1].split("\n"),h={};for(var c in a){var l=a[c].match(/^([^:]+):\s+(.*)/);l&&"Content-Type"==l[1]&&(h["content-type"]=l[2])}o==n.length-1&&(h.id=this.msgIdFromResponseHeaders(s)),this.emit("message",i[2],h)}return!0},t.prototype.msgIdFromResponseHeaders=function(t){var e,s;return e=t.getResponseHeader("Last-Modified"),s=t.getResponseHeader("Etag"),e?Date.parse(e)/1e3+":"+(s||"0"):s||null},t.prototype.cancel=function(){return this.req&&(this.emit("transportNativeBeforeDestroy",this.req,this.name),this.req.abort(),delete this.req),this},t}(),__slave:function(){function s(t){this.emit=t,this.doNotReconnect=!0,this.shared=null,this.name="__slave",this.opt={url:null,msgid:null,headers:{}}}return s.prototype.setup=function(){this.emit("transportSetup",this.opt,this.name);var t,e=0;for(t in this.opt.headers)e++;if(0!=e)throw"__slave does not support headers"},s.prototype.listen=function(s,i){this.shared=i,this.opt.url=s,this.setup(),this.statusChangeChecker=n(function(t){if(this.shared.matchEventKey(t,"msg")){var s=this.shared.get("msg:id"),i=this.shared.get("msg:content-type"),r=this.shared.get("msg");this.emit("message",r,{id:""==s?e:s,"content-type":""==i?e:i})}},this),t.addEventListener("storage",this.statusChangeChecker)},s.prototype.cancel=function(){t.removeEventListener("storage",this.statusChangeChecker)},s}()},a}(t);"object"==typeof module&&null!=module&&module.exports?module.exports=i:"function"==typeof define&&define.amd?define(function(){return i}):t.NchanSubscriber=i}("undefined"!=typeof window?window:this); From 8a12ae2f25cee3a9ae3a6a0a0f231320a9416768 Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 13 Apr 2018 16:54:30 +0200 Subject: [PATCH 005/100] Added selection of all available OS versions to upgrade or downgrade --- plugins/dynamix.plugin.manager/Update.page | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/dynamix.plugin.manager/Update.page b/plugins/dynamix.plugin.manager/Update.page index bb4e31486..cc78fa414 100644 --- a/plugins/dynamix.plugin.manager/Update.page +++ b/plugins/dynamix.plugin.manager/Update.page @@ -110,5 +110,5 @@ $(function() { - +
ComponentAuthorInstalledAvailableStatusBranch
From a5abbde0325409ead3d14eff11adc1104221ee74 Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 13 Apr 2018 18:39:13 +0200 Subject: [PATCH 006/100] CSS correction for plugins page --- plugins/dynamix/styles/dynamix-azure.css | 2 +- plugins/dynamix/styles/dynamix-black.css | 2 +- plugins/dynamix/styles/dynamix-gray.css | 2 +- plugins/dynamix/styles/dynamix-white.css | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/dynamix/styles/dynamix-azure.css b/plugins/dynamix/styles/dynamix-azure.css index 32306a5fb..1556cbb63 100644 --- a/plugins/dynamix/styles/dynamix-azure.css +++ b/plugins/dynamix/styles/dynamix-azure.css @@ -69,7 +69,7 @@ table.tablesorter.left th,table.tablesorter.left td{text-align:left;width:20%} table.tablesorter.left th:first-child,table.tablesorter.left td:first-child{width:8%} table.tablesorter.left th:nth-last-child(2),table.tablesorter.left td:nth-last-child(2){width:8%} table.tablesorter.left th:last-child,table.tablesorter.left td:last-child{text-align:right;width:4%} -table.tablesorter.shift{margin-top:10px} +table.tablesorter.shift{margin-top:-21px} table.tablesorter.kvm{display:block;padding-top:24px} table.tablesorter thead.fixed{display:table;width:100%} table.tablesorter tbody.fixed{display:block;overflow:auto} diff --git a/plugins/dynamix/styles/dynamix-black.css b/plugins/dynamix/styles/dynamix-black.css index 9c716af33..626d447c7 100644 --- a/plugins/dynamix/styles/dynamix-black.css +++ b/plugins/dynamix/styles/dynamix-black.css @@ -64,7 +64,7 @@ table.tablesorter.left th,table.tablesorter.left td{text-align:left;width:20%} table.tablesorter.left th:first-child,table.tablesorter.left td:first-child{width:8%} table.tablesorter.left th:nth-last-child(2),table.tablesorter.left td:nth-last-child(2){width:8%} table.tablesorter.left th:last-child,table.tablesorter.left td:last-child{text-align:right;width:4%} -table.tablesorter.shift{margin-top:-21px} +table.tablesorter.shift{margin-top:-33px} table.tablesorter thead.fixed{display:table;width:100%} table.tablesorter tbody.fixed{display:block;overflow:auto} table.tablesorter.indexer thead th:first-child{width:4%} diff --git a/plugins/dynamix/styles/dynamix-gray.css b/plugins/dynamix/styles/dynamix-gray.css index ce3a9f8f9..28991b3cb 100644 --- a/plugins/dynamix/styles/dynamix-gray.css +++ b/plugins/dynamix/styles/dynamix-gray.css @@ -69,7 +69,7 @@ table.tablesorter.left th,table.tablesorter.left td{text-align:left;width:20%} table.tablesorter.left th:first-child,table.tablesorter.left td:first-child{width:8%} table.tablesorter.left th:nth-last-child(2),table.tablesorter.left td:nth-last-child(2){width:8%} table.tablesorter.left th:last-child,table.tablesorter.left td:last-child{text-align:right;width:4%} -table.tablesorter.shift{margin-top:10px} +table.tablesorter.shift{margin-top:-21px} table.tablesorter.kvm{display:block;padding-top:24px} table.tablesorter thead.fixed{display:table;width:100%} table.tablesorter tbody.fixed{display:block;overflow:auto} diff --git a/plugins/dynamix/styles/dynamix-white.css b/plugins/dynamix/styles/dynamix-white.css index 493b83356..b9e6125b5 100644 --- a/plugins/dynamix/styles/dynamix-white.css +++ b/plugins/dynamix/styles/dynamix-white.css @@ -64,7 +64,7 @@ table.tablesorter.left th,table.tablesorter.left td{text-align:left;width:20%} table.tablesorter.left th:first-child,table.tablesorter.left td:first-child{width:8%} table.tablesorter.left th:nth-last-child(2),table.tablesorter.left td:nth-last-child(2){width:8%} table.tablesorter.left th:last-child,table.tablesorter.left td:last-child{text-align:right;width:4%} -table.tablesorter.shift{margin-top:-21px} +table.tablesorter.shift{margin-top:-33px} table.tablesorter thead.fixed{display:table;width:100%} table.tablesorter tbody.fixed{display:block;overflow:auto} table.tablesorter.indexer thead th:first-child{width:4%} From 3f1ff330c6c8f59ff516d129786cad34270c555a Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 13 Apr 2018 18:41:00 +0200 Subject: [PATCH 007/100] Revert "CSS correction for plugins page" This reverts commit a5abbde0325409ead3d14eff11adc1104221ee74. --- plugins/dynamix/styles/dynamix-azure.css | 2 +- plugins/dynamix/styles/dynamix-black.css | 2 +- plugins/dynamix/styles/dynamix-gray.css | 2 +- plugins/dynamix/styles/dynamix-white.css | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/dynamix/styles/dynamix-azure.css b/plugins/dynamix/styles/dynamix-azure.css index 1556cbb63..32306a5fb 100644 --- a/plugins/dynamix/styles/dynamix-azure.css +++ b/plugins/dynamix/styles/dynamix-azure.css @@ -69,7 +69,7 @@ table.tablesorter.left th,table.tablesorter.left td{text-align:left;width:20%} table.tablesorter.left th:first-child,table.tablesorter.left td:first-child{width:8%} table.tablesorter.left th:nth-last-child(2),table.tablesorter.left td:nth-last-child(2){width:8%} table.tablesorter.left th:last-child,table.tablesorter.left td:last-child{text-align:right;width:4%} -table.tablesorter.shift{margin-top:-21px} +table.tablesorter.shift{margin-top:10px} table.tablesorter.kvm{display:block;padding-top:24px} table.tablesorter thead.fixed{display:table;width:100%} table.tablesorter tbody.fixed{display:block;overflow:auto} diff --git a/plugins/dynamix/styles/dynamix-black.css b/plugins/dynamix/styles/dynamix-black.css index 626d447c7..9c716af33 100644 --- a/plugins/dynamix/styles/dynamix-black.css +++ b/plugins/dynamix/styles/dynamix-black.css @@ -64,7 +64,7 @@ table.tablesorter.left th,table.tablesorter.left td{text-align:left;width:20%} table.tablesorter.left th:first-child,table.tablesorter.left td:first-child{width:8%} table.tablesorter.left th:nth-last-child(2),table.tablesorter.left td:nth-last-child(2){width:8%} table.tablesorter.left th:last-child,table.tablesorter.left td:last-child{text-align:right;width:4%} -table.tablesorter.shift{margin-top:-33px} +table.tablesorter.shift{margin-top:-21px} table.tablesorter thead.fixed{display:table;width:100%} table.tablesorter tbody.fixed{display:block;overflow:auto} table.tablesorter.indexer thead th:first-child{width:4%} diff --git a/plugins/dynamix/styles/dynamix-gray.css b/plugins/dynamix/styles/dynamix-gray.css index 28991b3cb..ce3a9f8f9 100644 --- a/plugins/dynamix/styles/dynamix-gray.css +++ b/plugins/dynamix/styles/dynamix-gray.css @@ -69,7 +69,7 @@ table.tablesorter.left th,table.tablesorter.left td{text-align:left;width:20%} table.tablesorter.left th:first-child,table.tablesorter.left td:first-child{width:8%} table.tablesorter.left th:nth-last-child(2),table.tablesorter.left td:nth-last-child(2){width:8%} table.tablesorter.left th:last-child,table.tablesorter.left td:last-child{text-align:right;width:4%} -table.tablesorter.shift{margin-top:-21px} +table.tablesorter.shift{margin-top:10px} table.tablesorter.kvm{display:block;padding-top:24px} table.tablesorter thead.fixed{display:table;width:100%} table.tablesorter tbody.fixed{display:block;overflow:auto} diff --git a/plugins/dynamix/styles/dynamix-white.css b/plugins/dynamix/styles/dynamix-white.css index b9e6125b5..493b83356 100644 --- a/plugins/dynamix/styles/dynamix-white.css +++ b/plugins/dynamix/styles/dynamix-white.css @@ -64,7 +64,7 @@ table.tablesorter.left th,table.tablesorter.left td{text-align:left;width:20%} table.tablesorter.left th:first-child,table.tablesorter.left td:first-child{width:8%} table.tablesorter.left th:nth-last-child(2),table.tablesorter.left td:nth-last-child(2){width:8%} table.tablesorter.left th:last-child,table.tablesorter.left td:last-child{text-align:right;width:4%} -table.tablesorter.shift{margin-top:-33px} +table.tablesorter.shift{margin-top:-21px} table.tablesorter thead.fixed{display:table;width:100%} table.tablesorter tbody.fixed{display:block;overflow:auto} table.tablesorter.indexer thead th:first-child{width:4%} From 82a6484dcea4094915991d572731959c9fb2c90f Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 13 Apr 2018 18:50:46 +0200 Subject: [PATCH 008/100] Markdown correction for plugins page --- plugins/dynamix.plugin.manager/Plugins.page | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/dynamix.plugin.manager/Plugins.page b/plugins/dynamix.plugin.manager/Plugins.page index adccdb1b0..b8e28e5c2 100644 --- a/plugins/dynamix.plugin.manager/Plugins.page +++ b/plugins/dynamix.plugin.manager/Plugins.page @@ -17,14 +17,16 @@ Code="f1e6" * all copies or substantial portions of the Software. */ ?> + - - + diff --git a/plugins/dynamix/include/DashUpdate.php b/plugins/dynamix/include/DashUpdate.php index 61a05e7dc..4548a76cb 100644 --- a/plugins/dynamix/include/DashUpdate.php +++ b/plugins/dynamix/include/DashUpdate.php @@ -379,7 +379,7 @@ case 'parity': echo my_clock(floor($t/60)); echo ""; } else { - echo " Please start a Parity-sync immediately"; + echo " Please start a Parity-Sync immediately"; } break; case 'shares': From b680e4248b89f0f13784b97d8cf9fe261f7f7806 Mon Sep 17 00:00:00 2001 From: bergware Date: Sun, 15 Apr 2018 22:07:15 +0200 Subject: [PATCH 028/100] Added selection of all available OS versions to upgrade or downgrade --- plugins/dynamix.plugin.manager/Update.page | 2 +- plugins/dynamix.plugin.manager/include/ShowPlugins.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/dynamix.plugin.manager/Update.page b/plugins/dynamix.plugin.manager/Update.page index aaa2ec9db..c187fccbf 100644 --- a/plugins/dynamix.plugin.manager/Update.page +++ b/plugins/dynamix.plugin.manager/Update.page @@ -30,7 +30,7 @@ if (file_exists('/boot/previous/changes.txt')) { } } ?> - + - - + + + + +
ComponentAuthorInstalledAvailableStatusBranch
ComponentAuthorVersionStatusBranch
diff --git a/plugins/dynamix.plugin.manager/include/PluginHelpers.php b/plugins/dynamix.plugin.manager/include/PluginHelpers.php index 0b886fdb2..3d998d8f6 100644 --- a/plugins/dynamix.plugin.manager/include/PluginHelpers.php +++ b/plugins/dynamix.plugin.manager/include/PluginHelpers.php @@ -25,11 +25,11 @@ function check_plugin($arg, $dns='8.8.8.8') { return exec("ping -qnl2 -c2 -W3 $dns 2>/dev/null|awk '/received/{print $4}'") ? plugin('check',$arg) : false; } -function make_link($method, $arg, $extra=null, $title=null) { +function make_link($method, $arg, $extra='') { $plg = basename($arg,'.plg').':'.$method; $id = str_replace(['.',' ','_'],'',$plg); $check = $method=='remove' ? "" : ""; - $disabled = ($check || $extra=='disabled') ? ' disabled' : ''; + $disabled = $check ? ' disabled' : ''; if ($method == 'delete') { $cmd = "/plugins/dynamix.plugin.manager/scripts/plugin_rm&arg1=$arg"; $exec = $plg = ""; @@ -37,8 +37,7 @@ function make_link($method, $arg, $extra=null, $title=null) { $cmd = "/plugins/dynamix.plugin.manager/scripts/plugin&arg1=$method&arg2=$arg".($extra?"&arg3=$extra":""); $exec = "loadlist"; } - $title = $title ?: $method; - return "$check"; + return "$check"; } // trying our best to find an icon diff --git a/plugins/dynamix.plugin.manager/include/ShowPlugins.php b/plugins/dynamix.plugin.manager/include/ShowPlugins.php index 49d7dcbde..5c7c8726c 100644 --- a/plugins/dynamix.plugin.manager/include/ShowPlugins.php +++ b/plugins/dynamix.plugin.manager/include/ShowPlugins.php @@ -15,18 +15,14 @@ $docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp'; require_once "$docroot/webGui/include/Markdown.php"; require_once "$docroot/plugins/dynamix.plugin.manager/include/PluginHelpers.php"; -$system = $_GET['system'] ?? false; -$branch = $_GET['branch'] ?? false; -$source = $_GET['source'] ?? false; -$audit = $_GET['audit'] ?? false; -$check = $_GET['check'] ?? false; -$release = $_GET['release'] ?? false; -$empty = true; -$updates = 0; -$missing = "None"; -$builtin = "unRAIDServer"; -$plugins = $system ? "/var/log/plugins/$builtin.plg" : "/var/log/plugins/*.plg"; -$limetech = "https://s3.amazonaws.com/dnld.lime-technology.com"; +$system = $_GET['system'] ?? false; +$branch = $_GET['branch'] ?? false; +$audit = $_GET['audit'] ?? false; +$check = $_GET['check'] ?? false; +$empty = true; +$updates = 0; +$builtin = ['unRAIDServer']; +$plugins = "/var/log/plugins/*.plg"; if ($audit) { list($plg,$action) = explode(':',$audit); @@ -38,66 +34,33 @@ if ($audit) { } } -function strip($name) { - return str_replace('unRAID ','',$name); -} - -function file_date($file) { - //file is considered outdated when older than 1 day - return file_exists($file) ? (filectime($file) > (time()-86400) ? 'up-to-date' : 'outdated') : 'unknown'; -} - foreach (glob($plugins,GLOB_NOSORT) as $plugin_link) { //only consider symlinks $plugin_file = @readlink($plugin_link); if ($plugin_file === false) continue; //plugin name $name = plugin('name',$plugin_file) ?: basename($plugin_file,".plg"); -//upgrade or downgrade selected release - if ($release) { - extract(parse_ini_file('/etc/unraid-version')); - $tmp_file = "/var/tmp/$name.plg"; - if ($release != $version) { - exec("sed -ri 's|^(|' $tmp_file"); - echo "$plugin_file\0$tmp_file"; - } else { - echo "$tmp_file\0$plugin_file"; - } - return; - } -//skip system when doing user plugins - if (!$system && strpos($name,$builtin)===0) continue; + $custom = in_array($name,$builtin); +//switch between system and custom plugins + if (($system && !$custom) || (!$system && $custom)) continue; //forced plugin check? - $forced = !$audit && !$check; - $checked = $forced ? check_plugin(basename($plugin_file)) : true; -//switch stable/next/test release? - if ($system) { - //current version - extract(parse_ini_file('/etc/unraid-version')); - //category - $category = $branch ?: plugin('category',$plugin_file) ?: (strpos($version,'-')===false ? 'stable' : 'next'); - if (!$branch && !$source) $source = $category; - $releases = []; - exec("curl -m 15 $limetech/$category/releases.json 2>/dev/null", $releases); - if ($releases) $releases = json_decode(implode("\n",$releases),true); else $releases[] = ['name' => $missing]; - $release = strip($releases[0]['name']); - if ($release != $missing) { - $tmp_plg = "$name-.plg"; - $tmp_file = "/var/tmp/$name.plg"; - copy($plugin_file,$tmp_file); - if ($branch) exec("sed -ri 's|^(|' $tmp_file"); - symlink($tmp_file,"/var/log/plugins/$tmp_plg"); - if ($release != $version && $branch) { - if (check_plugin($tmp_plg)) copy("/tmp/plugins/$tmp_plg", $tmp_file); - exec("sed -ri 's|^(|' $tmp_file"); - $plugin_file = $tmp_file; - } + $checked = (!$audit && !$check) ? check_plugin(basename($plugin_file)) : true; +//OS update? + $os = $system && $name==$builtin[0]; + $toggle = false; +//toggle stable/next release? + if ($os && $branch) { + $toggle = plugin('version',$plugin_file); + $tmp_plg = "$name-.plg"; + $tmp_file = "/var/tmp/$name.plg"; + copy($plugin_file,$tmp_file); + exec("sed -ri 's|^(|' $tmp_file"); + symlink($tmp_file,"/var/log/plugins/$tmp_plg"); + if (check_plugin($tmp_plg)) { + copy("/tmp/plugins/$tmp_plg",$tmp_file); + $plugin_file = $tmp_file; } - } else { - //plugin version - $version = plugin('version',$plugin_file) ?: 'unknown'; } - $save = $version; //link/icon $icon = icon($name); if ($launch = plugin('launch',$plugin_file)) @@ -111,51 +74,45 @@ foreach (glob($plugins,GLOB_NOSORT) as $plugin_link) { else $desc = Markdown("**{$name}**"); //author - $author = plugin('author',$plugin_file) ?: 'anonymous'; + $author = plugin('author',$plugin_file) ?: "anonymous"; +//version + $version = plugin('version',$plugin_file) ?: "unknown"; + $date = str_replace('.','',$version); +//category + $category = plugin('category',$plugin_file) ?: (strpos($version,'-')!==false ? 'next' : 'stable'); //status + $status = 'unknown'; $changes_file = $plugin_file; $url = plugin('pluginURL',$plugin_file); if ($url !== false) { - $extra = $branch && $branch != $source; - $filename = "/tmp/plugins/".(($system && $extra) ? $tmp_plg : basename($url)); - $latest = ($checked && file_exists($filename)) ? plugin('version',$filename) : 0; - if ($system) { - $release = strip($releases[0]['name']); - $other = ($release != $missing); - if ($extra) { - if ($other) $version .= "
$release"; - $status = "".make_link('install', $plugin_file,$other?'forced':'disabled').""; + $filename = "/tmp/plugins/".(($os && $branch) ? $tmp_plg : basename($url)); + if ($checked && file_exists($filename)) { + if ($toggle && $toggle != $version) { + $status = make_link('install',$plugin_file,'forced'); } else { - $style1 = $style2 = ""; - if ($forced && $other && $latest===0) $latest = $release; - if (version_compare($latest,$version,'>')) { - $style1 = "style='display:none'"; - $version .= "
$latest"; + $latest = plugin('version',$filename); + if ($os ? version_compare($latest,$version,'>') : strcmp($latest,$version) > 0) { + $version .= "
$latest"; + $status = make_link("update",basename($plugin_file)); $changes_file = $filename; + if (!$os) $updates++; } else { - $style2 = "style='display:none'"; + //status is considered outdated when older than 1 day + $status = filectime($filename) > (time()-86400) ? 'up-to-date' : 'need check'; } - $status = "".file_date($filename).""; - $status .= "".make_link('update', basename($plugin_file)).""; - $status .= ""; - } - } else { - if (strcmp($latest,$version) > 0) { - $version .= "
$latest"; - $status = make_link('update', basename($plugin_file)); - $changes_file = $filename; - $updates++; - } else { - $status = file_date($filename); } } } - $changes = strpos($version,$missing)===false ? plugin('changes',$changes_file) : false; + if (strpos($status,'update')!==false) $rank = '0'; + elseif (strpos($status,'install')!==false) $rank = '1'; + elseif ($status=='need check') $rank = '2'; + elseif ($status=='up-to-date') $rank = '3'; + else $rank = '4'; + $changes = plugin('changes',$changes_file); if ($changes !== false) { $txtfile = "/tmp/plugins/".basename($plugin_file,'.plg').".txt"; file_put_contents($txtfile,$changes); - $version .= ""; + $version .= " "; } //write plugin information $empty = false; @@ -163,36 +120,24 @@ foreach (glob($plugins,GLOB_NOSORT) as $plugin_link) { echo "

$link

"; echo "$desc"; echo "$author"; - echo "$version"; + echo "$version"; + echo "$status"; + echo ""; if ($system) { - // available releases - $branch = $branch ?: $source; - echo ""; - echo "$status"; - echo ""; + if ($os) { + echo ""; + } } else { - if (strpos($status,'upgrade')!==false) $rank = 0; - elseif ($status=='outdated') $rank = 1; - elseif ($status=='up-to-date') $rank = 2; - else $rank = 3; - echo "$status"; - echo ""; - echo make_link('remove', basename($plugin_file)); - echo ""; + echo make_link('remove',basename($plugin_file)); } + echo ""; echo ""; //remove temporary symlink - if ($tmp_plg) unlink("/var/log/plugins/$tmp_plg"); + @unlink("/var/log/plugins/$tmp_plg"); } -if ($empty) echo " No plugins installed"; +if ($empty) echo " No plugins installed"; echo "\0".$updates; ?> From 666fe0b7120150918b561a8efef0493b41508087 Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 20 Apr 2018 08:17:31 +0200 Subject: [PATCH 040/100] Fixed calculation of next custom parity schedule --- plugins/dynamix/include/DashUpdate.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/dynamix/include/DashUpdate.php b/plugins/dynamix/include/DashUpdate.php index 04ff3e4c5..2475776eb 100644 --- a/plugins/dynamix/include/DashUpdate.php +++ b/plugins/dynamix/include/DashUpdate.php @@ -123,24 +123,24 @@ function stage($i) { } } else { $d = $i ? ($now ? $D : today($i)) : today(last_day()-6); - $i = $i ?: last_day()-6; - $D = mkdate($d, $i); + $x = $i ?: last_day()-6; + $D = mkdate($d, $x); $t = mktime($h,$m,0,$M,$D,$Y)-$time; // first day if ($t < 0) { - $D = mkdate(next_day($d), $i); + $D = mkdate(next_day($d), $x); $t = mktime($h,$m,0,$M,$D,$Y)-$time; // next day } if ($t < 0) { $M = find_month($M+1); - $i = $i ?: last_day()-6; - $D = mkdate(today($i), $i); + $x = $i ?: last_day()-6; + $D = mkdate(today($x), $x); $t = mktime($h,$m,0,$M,$D,$Y)-$time; // next month } if ($t < 0) { $Y++; $M = find_month(1); - $i = $i ?: last_day()-6; - $D = mkdate(today($i), $i); + $x = $i ?: last_day()-6; + $D = mkdate(today($x), $x); $t = mktime($h,$m,0,$M,$D,$Y)-$time; // next year } } From 75ee98a201f3de5bec30e63388f4d1c446b62219 Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Mon, 23 Apr 2018 20:08:30 -0400 Subject: [PATCH 041/100] Suppress Docker PHP error if container has no ports exposed or utilized --- plugins/dynamix.docker.manager/include/DockerClient.php | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/dynamix.docker.manager/include/DockerClient.php b/plugins/dynamix.docker.manager/include/DockerClient.php index acd86b27a..037022edb 100644 --- a/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/plugins/dynamix.docker.manager/include/DockerClient.php @@ -710,6 +710,7 @@ class DockerClient { $nat = false; } $ip = $ct['NetworkSettings']['Networks'][$c['NetworkMode']]['IPAddress']; + $ports = is_array($ports) ? $ports : array(); foreach ($ports as $port => $value) { list($PrivatePort, $Type) = explode('/', $port); $c['Ports'][] = ['IP' => $ip, 'PrivatePort' => $PrivatePort, 'PublicPort' => $nat ? $value[0]['HostPort']:$PrivatePort, 'NAT' => $nat, 'Type' => $Type ]; From 1b9997f86f07ae413cc2e96d6a46ab61f4e03cc0 Mon Sep 17 00:00:00 2001 From: Squidly271 Date: Mon, 23 Apr 2018 20:39:37 -0400 Subject: [PATCH 042/100] Docker skip hidden files when listing directories Solves the problem with dockerMan pumping out tons of simpleXML errors when a Mac creates its ._ files See https://lime-technology.com/forums/topic/70636-beta-diskspeed-hard-drive-benchmarking-unraid-6/?page=5&tab=comments#comment-653133 (Hasn't really appeared prior because this template was originally published as a .xml the user had to copy manually onto the flash drive) --- plugins/dynamix.docker.manager/include/DockerClient.php | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/dynamix.docker.manager/include/DockerClient.php b/plugins/dynamix.docker.manager/include/DockerClient.php index acd86b27a..dcb8e9a1d 100644 --- a/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/plugins/dynamix.docker.manager/include/DockerClient.php @@ -72,6 +72,7 @@ class DockerTemplates { foreach ($iter as $path => $fileinfo) { $fext = $fileinfo->getExtension(); if ($ext && $ext != $fext) continue; + if (substr(basename($path),0,1) == ".") continue; if ($fileinfo->isFile()) $paths[] = ['path' => $path, 'prefix' => basename(dirname($path)), 'name' => $fileinfo->getBasename(".$fext")]; } return $paths; From 4e810dedf0d44b5725281bf81bf38ae9c2495766 Mon Sep 17 00:00:00 2001 From: bergware Date: Thu, 26 Apr 2018 11:39:39 +0200 Subject: [PATCH 043/100] Adjusted TAB color styling for all themes --- plugins/dynamix/styles/default-azure.css | 6 +++--- plugins/dynamix/styles/default-black.css | 6 +++--- plugins/dynamix/styles/default-gray.css | 6 +++--- plugins/dynamix/styles/default-white.css | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/plugins/dynamix/styles/default-azure.css b/plugins/dynamix/styles/default-azure.css index 3ff9ddf2d..2cf3ba993 100644 --- a/plugins/dynamix/styles/default-azure.css +++ b/plugins/dynamix/styles/default-azure.css @@ -219,11 +219,11 @@ label+.content{margin-top:64px} div.tabs{position:relative;margin:110px 30px 30px 100px;background-color:#E4E2E4} div.tab{float:left;margin-top:23px} div.tab input[id^='tab']{display:none} -div.tab [type=radio]+label:hover{background:#606E7F;color:#B0B0B0;cursor:pointer;border-color:#0072C6} -div.tab [type=radio]:checked+label{cursor:default;background:#606E7F;color:#B0B0B0} +div.tab [type=radio]+label:hover{cursor:pointer;border-color:#004E86;opacity:1} +div.tab [type=radio]:checked+label{cursor:default;background:transparent;color:#606E7F;border-color:#004E86;opacity:1} div.tab [type=radio]+label~.content{display:none} div.tab [type=radio]:checked+label~.content{display:inline} -div.tab [type=radio]+label{position:relative;padding:10px 10px;margin-right:2px;border-top-left-radius:12px;border-top-right-radius:12px;border:#004E86 1px solid;border-bottom:none} +div.tab [type=radio]+label{position:relative;padding:10px 10px;margin-right:2px;border-top-left-radius:12px;border-top-right-radius:12px;background:#606E7F;color:#B0B0B0;border:#8B98A7 1px solid;border-bottom:none;opacity:0.5} div.tab [type=radio]+label img{display:none} div.Panel{width:25%;height:auto;float:left;margin:0;padding:5px;border-right:#F3F0F4 1px solid;border-bottom:#F3F0F4 1px solid;box-sizing:border-box} div.Panel:hover{background-color:#EDEAEF} diff --git a/plugins/dynamix/styles/default-black.css b/plugins/dynamix/styles/default-black.css index 5e5d8fd1d..5757e5a69 100644 --- a/plugins/dynamix/styles/default-black.css +++ b/plugins/dynamix/styles/default-black.css @@ -211,11 +211,11 @@ div.content.shift{margin-top:-70px} div.tabs{position:relative;margin:24px 0 0 0} div.tab{float:left;margin:0 0 12px 0} div.tab input[id^="tab"]{display:none} -div.tab [type=radio]+label:hover{background:#000000;color:#478406;cursor:pointer} -div.tab [type=radio]:checked+label{cursor:default;background:-webkit-radial-gradient(#303030,#505050);background:linear-gradient(#303030,#505050);color:#808080} +div.tab [type=radio]+label:hover{background:transparent;color:#478406;cursor:pointer;opacity:1} +div.tab [type=radio]:checked+label{cursor:default;background:transparent;color:#808080;opacity:1} div.tab [type=radio]+label~.content{display:none} div.tab [type=radio]:checked+label~.content{display:inline} -div.tab [type=radio]+label{position:relative;font-size:14px;padding:4px 10px;margin-right:2px;border-top-left-radius:5px;border-top-right-radius:5px;border:1px solid #303030;border-bottom:1px solid #606060;background:-webkit-radial-gradient(#101010,#202020);background:linear-gradient(#101010,#202020)} +div.tab [type=radio]+label{position:relative;font-size:14px;padding:4px 10px;margin-right:2px;border-top-left-radius:5px;border-top-right-radius:5px;border:1px solid #303030;border-bottom:none;background:-webkit-radial-gradient(#101010,#202020);background:linear-gradient(#101010,#202020);opacity:0.6} div.tab [type=radio]+label img{padding-right:4px} div.Panel{text-align:center;float:left;margin:0 30px 30px 12px;height:80px} div.Panel .PanelText{padding-top:10px} diff --git a/plugins/dynamix/styles/default-gray.css b/plugins/dynamix/styles/default-gray.css index 21bcb6c7d..4c8947c2b 100644 --- a/plugins/dynamix/styles/default-gray.css +++ b/plugins/dynamix/styles/default-gray.css @@ -219,11 +219,11 @@ label+.content{margin-top:64px} div.tabs{position:relative;margin:110px 30px 30px 100px;background-color:#1B1D1B} div.tab{float:left;margin-top:23px} div.tab input[id^='tab']{display:none} -div.tab [type=radio]+label:hover{background:#606E7F;color:#B0B0B0;cursor:pointer;border-color:#0072C6} -div.tab [type=radio]:checked+label{cursor:default;background:#606E7F;color:#B0B0B0} +div.tab [type=radio]+label:hover{cursor:pointer;border-color:#0072C6;opacity:1} +div.tab [type=radio]:checked+label{cursor:default;background:transparent;color:#606E7F;border-color:#004E86;opacity:1} div.tab [type=radio]+label~.content{display:none} div.tab [type=radio]:checked+label~.content{display:inline} -div.tab [type=radio]+label{position:relative;padding:10px 10px;margin-right:2px;border-top-left-radius:12px;border-top-right-radius:12px;border:#004E86 1px solid;border-bottom:none} +div.tab [type=radio]+label{position:relative;padding:10px 10px;margin-right:2px;border-top-left-radius:12px;border-top-right-radius:12px;background:#606E7F;color:#B0B0B0;border:#8B98A7 1px solid;border-bottom:none;opacity:0.5} div.tab [type=radio]+label img{display:none} div.Panel{width:25%;height:auto;float:left;margin:0;padding:5px;border-right:#0C0F0B 1px solid;border-bottom:#0C0F0B 1px solid;box-sizing:border-box} div.Panel:hover{background-color:#121510} diff --git a/plugins/dynamix/styles/default-white.css b/plugins/dynamix/styles/default-white.css index c4df0144f..5c8b9f7b9 100644 --- a/plugins/dynamix/styles/default-white.css +++ b/plugins/dynamix/styles/default-white.css @@ -211,11 +211,11 @@ div.content.shift{margin-top:-70px} div.tabs{position:relative;margin:24px 0 0 0} div.tab{float:left;margin:0 0 12px 0} div.tab input[id^="tab"]{display:none} -div.tab [type=radio]+label:hover{background:#FFFFFF;color:#478406;cursor:pointer} -div.tab [type=radio]:checked+label{cursor:default;background:-webkit-radial-gradient(#F8F8F8,#E8E8E8);background:linear-gradient(#F8F8F8,#E8E8E8);color:#303030} +div.tab [type=radio]+label:hover{background:transparent;color:#478406;cursor:pointer;opacity:1} +div.tab [type=radio]:checked+label{cursor:default;background:transparent;color:#303030;opacity:1} div.tab [type=radio]+label~.content{display:none} div.tab [type=radio]:checked+label~.content{display:inline} -div.tab [type=radio]+label{position:relative;font-size:14px;padding:4px 10px;margin-right:2px;border-top-left-radius:5px;border-top-right-radius:5px;border:1px solid #E8E8E8;border-bottom-color:#D8D8D8;background:-webkit-radial-gradient(#D8D8D8,#B8B8B8);background:linear-gradient(#D8D8D8,#B8B8B8)} +div.tab [type=radio]+label{position:relative;font-size:14px;padding:4px 10px;margin-right:2px;border-top-left-radius:5px;border-top-right-radius:5px;border:1px solid #E8E8E8;border-bottom:none;background:-webkit-radial-gradient(#D8D8D8,#B8B8B8);background:linear-gradient(#D8D8D8,#B8B8B8);opacity:0.6} div.tab [type=radio]+label img{padding-right:4px} div.Panel{text-align:center;float:left;margin:0 30px 30px 12px;height:80px} div.Panel .PanelText{padding-top:10px} From e1bbfc7f90450c056f8ddb5b1e9761d7e304f1d8 Mon Sep 17 00:00:00 2001 From: bergware Date: Thu, 26 Apr 2018 11:40:29 +0200 Subject: [PATCH 044/100] Added branch type to previous version --- plugins/dynamix.plugin.manager/Update.page | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/dynamix.plugin.manager/Update.page b/plugins/dynamix.plugin.manager/Update.page index a88f39c4c..2c4eb3740 100644 --- a/plugins/dynamix.plugin.manager/Update.page +++ b/plugins/dynamix.plugin.manager/Update.page @@ -16,7 +16,7 @@ Tag="thumbs-up" ?>
"; -$version = $date = 'unknown'; +$version = $branch = $date = 'unknown'; $bzroot = file_exists('/boot/previous/bzroot'); $check = $notify['unraidos'] ? 0 : 1; @@ -29,6 +29,7 @@ if (file_exists('/boot/previous/changes.txt')) { break; } } + $branch = strpos($version,'rc')===false ? 'Stable' : 'Next'; } ?> @@ -86,6 +87,6 @@ $(function() { ComponentAuthorVersionStatusBranch -unRAID Server OS (previous)LimeTech +unRAID Server OS (previous)LimeTech From 0160c8c01ce8dbfaf7ab5bcee9430b638bb6d735 Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 27 Apr 2018 08:11:10 +0200 Subject: [PATCH 045/100] Minor code changes --- plugins/dynamix/include/DashUpdate.php | 14 +++++++------- plugins/dynamix/include/DeviceList.php | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/dynamix/include/DashUpdate.php b/plugins/dynamix/include/DashUpdate.php index 2475776eb..fd801c707 100644 --- a/plugins/dynamix/include/DashUpdate.php +++ b/plugins/dynamix/include/DashUpdate.php @@ -123,24 +123,24 @@ function stage($i) { } } else { $d = $i ? ($now ? $D : today($i)) : today(last_day()-6); - $x = $i ?: last_day()-6; - $D = mkdate($d, $x); + $s = $i ?: last_day()-6; + $D = mkdate($d, $s); $t = mktime($h,$m,0,$M,$D,$Y)-$time; // first day if ($t < 0) { - $D = mkdate(next_day($d), $x); + $D = mkdate(next_day($d), $s); $t = mktime($h,$m,0,$M,$D,$Y)-$time; // next day } if ($t < 0) { $M = find_month($M+1); - $x = $i ?: last_day()-6; - $D = mkdate(today($x), $x); + $s = $i ?: last_day()-6; + $D = mkdate(today($s), $s); $t = mktime($h,$m,0,$M,$D,$Y)-$time; // next month } if ($t < 0) { $Y++; $M = find_month(1); - $x = $i ?: last_day()-6; - $D = mkdate(today($x), $x); + $s = $i ?: last_day()-6; + $D = mkdate(today($s), $s); $t = mktime($h,$m,0,$M,$D,$Y)-$time; // next year } } diff --git a/plugins/dynamix/include/DeviceList.php b/plugins/dynamix/include/DeviceList.php index c97dcc4c1..3cb8f24d2 100644 --- a/plugins/dynamix/include/DeviceList.php +++ b/plugins/dynamix/include/DeviceList.php @@ -1,6 +1,6 @@ 0) { $data[] = my_scale($var['mdResync']*1024,$unit,-1)." $unit"; $data[] = my_clock(floor((time()-$var['sbUpdated'])/60)); - $data[] = my_scale($var['mdResyncPos']*1024,$unit)." $unit (".number_format(($var['mdResyncPos']/($var['mdResync']/100+1)),1,substr($display['number'],0,1),'')." %)"; + $data[] = my_scale($var['mdResyncPos']*1024,$unit)." $unit (".number_format(($var['mdResyncPos']/($var['mdResync']/100+1)),1,$display['number'][0],'')." %)"; $data[] = my_scale($var['mdResyncDb']*1024/$var['mdResyncDt'],$unit, 1)." $unit/sec"; $data[] = my_clock(round(((($var['mdResyncDt']*(($var['mdResync']-$var['mdResyncPos'])/($var['mdResyncDb']/100+1)))/100)/60),0)); $data[] = $var['sbSyncErrs']; From be36a08c242710ee7ddd80fe3c1b61ebb43d9cb9 Mon Sep 17 00:00:00 2001 From: bergware Date: Fri, 27 Apr 2018 08:41:56 +0200 Subject: [PATCH 046/100] Minor code changes --- plugins/dynamix.docker.manager/include/DockerClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/dynamix.docker.manager/include/DockerClient.php b/plugins/dynamix.docker.manager/include/DockerClient.php index a04323318..b4a896b2e 100644 --- a/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/plugins/dynamix.docker.manager/include/DockerClient.php @@ -28,7 +28,7 @@ $dockerManPaths = [ ]; // load network variables if needed. -if (!isset($eth0) && is_file("$docroot/state/network.ini")) extract(parse_ini_file("$docroot/state/network.ini",true)); +if (!isset($eth0)) extract(parse_ini_file("$docroot/state/network.ini",true)); $host = $eth0['IPADDR:0'] ?? '0.0.0.0'; // Docker configuration file - guaranteed to exist From 2c8b3a617517d67509f0db4589134c0ac1dba0a7 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 28 Apr 2018 13:01:59 +0200 Subject: [PATCH 047/100] Suppress auto generated hyperlinks by MS Edge --- plugins/dynamix/include/DefaultPageLayout.php | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/dynamix/include/DefaultPageLayout.php b/plugins/dynamix/include/DefaultPageLayout.php index c73f2457d..043ff25a8 100644 --- a/plugins/dynamix/include/DefaultPageLayout.php +++ b/plugins/dynamix/include/DefaultPageLayout.php @@ -16,6 +16,7 @@ <?=$var['NAME']?>/<?=$myPage['name']?> + "> From a67787cadea0ac73ab45caec28d197616ea4f0be Mon Sep 17 00:00:00 2001 From: bergware Date: Tue, 1 May 2018 09:37:31 +0200 Subject: [PATCH 048/100] Docker: added pause/resume commands & container console window --- .../DockerContainers.page | 1 + .../include/DockerClient.php | 14 ++++++++++ .../include/DockerContainers.php | 15 ++++++----- .../dynamix.docker.manager/include/Events.php | 13 +++++++++- .../javascript/docker.js | 26 ++++++++++++++----- plugins/dynamix/DashboardApps.page | 10 +++---- plugins/dynamix/include/DashboardApps.php | 13 +++++----- plugins/dynamix/styles/default-azure.css | 1 - plugins/dynamix/styles/default-gray.css | 1 - 9 files changed, 67 insertions(+), 27 deletions(-) diff --git a/plugins/dynamix.docker.manager/DockerContainers.page b/plugins/dynamix.docker.manager/DockerContainers.page index 85320fdf5..0900162d9 100644 --- a/plugins/dynamix.docker.manager/DockerContainers.page +++ b/plugins/dynamix.docker.manager/DockerContainers.page @@ -33,6 +33,7 @@ img.stopped{opacity:0.3} .iconstatus.stopped{font-size:1.2em} .started{color:#009900} .stopped{color:#EF3D47} +.paused{color:#F0DD33} .switch-button-label.off{color:inherit} th.five{width:5%} th.eight{width:8%} diff --git a/plugins/dynamix.docker.manager/include/DockerClient.php b/plugins/dynamix.docker.manager/include/DockerClient.php index b4a896b2e..df0496652 100644 --- a/plugins/dynamix.docker.manager/include/DockerClient.php +++ b/plugins/dynamix.docker.manager/include/DockerClient.php @@ -260,6 +260,7 @@ class DockerTemplates { $image = $ct['Image']; $tmp = &$info[$name] ?? []; $tmp['running'] = $ct['Running']; + $tmp['paused'] = $ct['Paused']; $tmp['autostart'] = in_array($name, $autoStart); if (!is_file($tmp['icon']) || $reload) $tmp['icon'] = $this->getIcon($image); if ($ct['Running']) { @@ -628,12 +629,24 @@ class DockerClient { return $code; } + public function pauseContainer($id) { + $this->getDockerJSON("/containers/$id/pause", 'POST', $code); + $this->flushCache($this::$containersCache); + return $code; + } + public function stopContainer($id) { $this->getDockerJSON("/containers/$id/stop", 'POST', $code); $this->flushCache($this::$containersCache); return $code; } + public function resumeContainer($id) { + $this->getDockerJSON("/containers/$id/unpause", 'POST', $code); + $this->flushCache($this::$containersCache); + return $code; + } + public function restartContainer($id) { $this->getDockerJSON("/containers/$id/restart", 'POST', $code); $this->flushCache($this::$containersCache); @@ -696,6 +709,7 @@ class DockerClient { $c['Name'] = substr($info['Name'], 1); $c['Status'] = $ct['Status'] ?: 'None'; $c['Running'] = $info['State']['Running']; + $c['Paused'] = $info['State']['Paused']; $c['Cmd'] = $ct['Command']; $c['Id'] = $this->extractID($ct['Id']); $c['Volumes'] = $info['HostConfig']['Binds']; diff --git a/plugins/dynamix.docker.manager/include/DockerContainers.php b/plugins/dynamix.docker.manager/include/DockerContainers.php index 039326397..6618985ad 100644 --- a/plugins/dynamix.docker.manager/include/DockerContainers.php +++ b/plugins/dynamix.docker.manager/include/DockerContainers.php @@ -43,18 +43,19 @@ $n = 0; foreach ($containers as $ct) { $name = $ct['Name']; $id = $ct['Id']; - $running = $ct['Running'] ? 1 : 0; $info = &$allInfo[$name]; + $running = $info['running'] ? 1 : 0; + $paused = $info['paused'] ? 1 : 0; $is_autostart = $info['autostart'] ? 'true':'false'; $updateStatus = $info['updated']=='true'||$info['updated']=='undef' ? 'true':'false'; $template = $info['template']; $webGui = html_entity_decode($info['url']); $support = html_entity_decode($info['Support']); $project = html_entity_decode($info['Project']); - $menu[] = sprintf("addDockerContainerContext('%s','%s','%s',%s,%s,%s,'%s','%s','%s','%s');", addslashes($name), addslashes($ct['ImageId']), addslashes($template), $running, $updateStatus, $is_autostart, addslashes($webGui), $id, addslashes($support), addslashes($project)); + $menu[] = sprintf("addDockerContainerContext('%s','%s','%s',%s,%s,%s,%s,'%s','%s','%s','%s');", addslashes($name), addslashes($ct['ImageId']), addslashes($template), $running, $paused, $updateStatus, $is_autostart, addslashes($webGui), $id, addslashes($support), addslashes($project)); $docker[] = "docker.push({name:'$name',id:'$id',state:$running,update:'$updateStatus'});"; - $shape = $running ? 'play':'square'; - $status = $running ? 'started':'stopped'; + $shape = $running ? ($paused ? 'pause' : 'play') : 'square'; + $status = $running ? ($paused ? 'paused' : 'started') : 'stopped'; $icon = $info['icon'] ?: '/plugins/dynamix.docker.manager/images/question.png'; $ports = []; foreach ($ct['Ports'] as $port) { @@ -69,15 +70,15 @@ foreach ($containers as $ct) { } echo ""; echo "
"; - echo ""; - echo "
"; + echo ""; + echo ""; echo ""; if ($template) { echo "".htmlspecialchars($name).""; } else { echo htmlspecialchars($name); } - echo "
Container ID: ".htmlspecialchars($id)."
"; + echo "
Container ID: $id
"; if ($ct['BaseImage']) echo "
".htmlspecialchars(${ct['BaseImage']})."
"; echo "
By:"; $registry = $info['registry']; diff --git a/plugins/dynamix.docker.manager/include/Events.php b/plugins/dynamix.docker.manager/include/Events.php index cb0030dc6..845741a17 100644 --- a/plugins/dynamix.docker.manager/include/Events.php +++ b/plugins/dynamix.docker.manager/include/Events.php @@ -27,9 +27,15 @@ switch ($action) { case 'start': if ($container) $arrResponse = ['success' => $DockerClient->startContainer($container)]; break; + case 'pause': + if ($container) $arrResponse = ['success' => $DockerClient->pauseContainer($container)]; + break; case 'stop': if ($container) $arrResponse = ['success' => $DockerClient->stopContainer($container)]; break; + case 'resume': + if ($container) $arrResponse = ['success' => $DockerClient->resumeContainer($container)]; + break; case 'restart': if ($container) $arrResponse = ['success' => $DockerClient->restartContainer($container)]; break; @@ -85,8 +91,13 @@ switch ($action) { exit; } break; + case 'terminal': + exec("kill \$(pgrep -a ttyd|awk '/\/$name\.sock/{print \$1}') 2>/dev/null"); + @unlink("/var/tmp/$name.sock"); + exec("exec ttyd -d 0 -i '/var/tmp/$name.sock' docker exec -it '$name' sh &>/dev/null &"); + break; default: - $arrResponse = ['error' => 'Unknown action \'' . $action . '\'']; + $arrResponse = ['error' => "Unknown action '$action'"]; break; } diff --git a/plugins/dynamix.docker.manager/javascript/docker.js b/plugins/dynamix.docker.manager/javascript/docker.js index 913b3f90b..00a002b61 100644 --- a/plugins/dynamix.docker.manager/javascript/docker.js +++ b/plugins/dynamix.docker.manager/javascript/docker.js @@ -1,9 +1,10 @@ var eventURL = '/plugins/dynamix.docker.manager/include/Events.php'; -function addDockerContainerContext(container, image, template, started, update, autostart, webui, id, Support, Project) { +function addDockerContainerContext(container, image, template, started, paused, update, autostart, webui, id, Support, Project) { var opts = [{header:container, image:'/plugins/dynamix.docker.manager/images/dynamix.docker.manager.png'}]; - if (started && (webui !== '' && webui != '#')) { - opts.push({text:'WebUI', icon:'fa-globe', href:webui, target:'_blank'}); + if (started && !paused) { + if (webui !== '' && webui != '#') opts.push({text:'WebUI', icon:'fa-globe', href:webui, target:'_blank'}); + opts.push({text:'Console', icon:'fa-terminal', action:function(e){e.preventDefault(); dockerTerminal(container);}}); opts.push({divider:true}); } if (!update) { @@ -11,7 +12,12 @@ function addDockerContainerContext(container, image, template, started, update, opts.push({divider:true}); } if (started) { - opts.push({text:'Stop', icon:'fa-stop', action:function(e){e.preventDefault(); eventControl({action:'stop', container:id}, 'loadlist');}}); + if (paused) { + opts.push({text:'Resume', icon:'fa-play', action:function(e){e.preventDefault(); eventControl({action:'resume', container:id}, 'loadlist');}}); + } else { + opts.push({text:'Pause', icon:'fa-pause', action:function(e){e.preventDefault(); eventControl({action:'pause', container:id}, 'loadlist');}}); + opts.push({text:'Stop', icon:'fa-stop', action:function(e){e.preventDefault(); eventControl({action:'stop', container:id}, 'loadlist');}}); + } opts.push({text:'Restart', icon:'fa-refresh', action:function(e){e.preventDefault(); eventControl({action:'restart', container:id}, 'loadlist');}}); } else { opts.push({text:'Start', icon:'fa-play', action:function(e){e.preventDefault(); eventControl({action:'start', container:id}, 'loadlist');}}); @@ -39,6 +45,14 @@ function addDockerImageContext(image, imageTag) { opts.push({text:'Remove', icon:'fa-trash', action:function(e){e.preventDefault(); rmImage(image, imageTag);}}); context.attach('#'+image, opts); } +function dockerTerminal(container) { + var height = 600; + var width = 900; + var top = (screen.height-height)/2; + var left = (screen.width-width)/2; + $.get(eventURL,{action:'terminal',name:container}); + setTimeout(function(){window.open('/dockerterminal/'+container+'/', container, 'resizeable=yes,scrollbars=yes,height='+height+',width='+width+',top='+top+',left='+left).focus();},180); +} function execUpContainer(container) { var title = 'Updating the container: '+container; var address = '/plugins/dynamix.docker.manager/include/CreateDocker.php?updateContainer=true&ct[]='+encodeURIComponent(container); @@ -135,7 +149,7 @@ function rmImage(image, imageName) { }); } function eventControl(params, spin) { - if (spin) $('#'+params['container']).find('i').removeClass('fa-play fa-square').addClass('fa-refresh fa-spin'); + if (spin) $('#'+params['container']).find('i').removeClass('fa-play fa-square fa-pause').addClass('fa-refresh fa-spin'); $.post(eventURL, params, function(data) { if (data.success === true) { if (spin) setTimeout(spin+'()',500); else location=window.location.href; @@ -156,7 +170,7 @@ function startAll() { } function stopAll() { $('input[type=button]').prop('disabled',true); - for (var i=0,ct; ct=docker[i]; i++) if (ct.state==1) $('#'+ct.id).find('i').removeClass('fa-play').addClass('fa-refresh fa-spin'); + for (var i=0,ct; ct=docker[i]; i++) if (ct.state==1) $('#'+ct.id).find('i').removeClass('fa-play fa-pause').addClass('fa-refresh fa-spin'); $.post('/plugins/dynamix.docker.manager/include/ContainerManager.php',{action:'stop'},function(){loadlist();}); } function checkAll() { diff --git a/plugins/dynamix/DashboardApps.page b/plugins/dynamix/DashboardApps.page index 8d38da738..8ab8f6043 100644 --- a/plugins/dynamix/DashboardApps.page +++ b/plugins/dynamix/DashboardApps.page @@ -38,7 +38,7 @@ div.Panel:hover{overflow:visible;z-index:10;background-color:unset} - +
No apps available to show
@@ -51,8 +51,8 @@ function loadlist() { $('#apps_icons').html(data[0]); $('head').append(' -
+ + Syslinux configuration: - -: +: + title="Set default boot menu" onchange="changeMenu(this.form,this.id)"> + + Server boot mode: : -Permit UEFI boot mode > +Permit UEFI boot mode > : *Boot system in UEFI mode. Please check your system settings to support UEFI boot mode.* -: +: -> Click the **Apply** button to commit the current edits. Click **Reset** to -> undo any changes you make (before Saving). Click **Done** to exit this page. -> > Click the **Default** button to initialize the edit box with the > factory-default contents. You still need to click **Apply** in order to >commit the change. +> +> Click the **Apply** button to commit the current edits. Click **Reset** to +> undo any changes you make (before Saving). Click **Done** to exit this page.
From 7fb84c978191daa262e35291fa97b2d9cf47663a Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 5 May 2018 14:45:45 +0200 Subject: [PATCH 061/100] Syslinux config: basic and advanced mode --- plugins/dynamix/Syslinux.page | 86 +++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/plugins/dynamix/Syslinux.page b/plugins/dynamix/Syslinux.page index 0e94ced38..70b9ae426 100644 --- a/plugins/dynamix/Syslinux.page +++ b/plugins/dynamix/Syslinux.page @@ -24,61 +24,71 @@ function strip($area) { $file = '/boot/syslinux/syslinux.cfg'; $menu = file_get_contents($file); $default = @file_get_contents("$file-") ?: $menu; +$text = preg_replace(["/\r\n/","/\r/"],"\n",$menu); +$text2 = preg_replace(["/\r\n/","/\r/"],"\n",$default); $menu = array_map('strip',explode('label ',$menu)); $default = array_map('strip',explode('label ',$default)); $global = 'Global Configuration'; $boot = 'menu default'; ?> + + + +
+
+Syslinux configuration: +: + +
+ Server boot mode: : From 8e7a47d6c364df9002b13d69d7ada92ca6b39ba4 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 5 May 2018 17:10:56 +0200 Subject: [PATCH 062/100] Syslinux config: basic and advanced mode --- plugins/dynamix/Syslinux.page | 49 ++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/plugins/dynamix/Syslinux.page b/plugins/dynamix/Syslinux.page index 70b9ae426..afff89f5a 100644 --- a/plugins/dynamix/Syslinux.page +++ b/plugins/dynamix/Syslinux.page @@ -60,10 +60,10 @@ const boot = ''; const global = ''; function prepareMenu(form) { - if ($.cookie('syslinux_view_mode')!='advanced') { + $('input[name="#arg[1]"]').val(form.boot.checked?1:0); + if ($.cookie('syslinux_viewmode')!='advanced') { form.text.value = form.text2.value; } else { - $('input[name="#arg[1]"]').val(form.boot.checked?1:0); var header = [], area = []; $(form).find('span[id^=header]').each(function(){ header.push($(this).text()); @@ -72,24 +72,24 @@ function prepareMenu(form) { var start = $('#checkbox-'+i).prop('checked') ? boot+'\n' : ''; area.push(start+$(this).val()); }); - var menu = ''; + var text = ''; for (var i=0; i < header.length; i++) { if (i==0) { - menu += area[i]+'\n'; + text += area[i]+'\n'; } else { - menu += 'label '+header[i]+'\n'; - menu += area[i].replace(/^/,' ').replace(/\n/g,'\n ')+'\n'; + text += 'label '+header[i]+'\n'; + text += area[i].replace(/^/,' ').replace(/\n/g,'\n ')+'\n'; } } - form.text.value = menu; + form.text.value = text; } form.text2.disabled = true; } function setDefault(form) { - var menu = []; + var text = []; $(form).find('textarea.menu').each(function(i){ - if (i < menu.length) { - var field = menu[i].split('|'); + if (i < text.length) { + var field = text[i].split('|'); var title = (i) ? field.shift():global; var start = (field[0]==boot); var checked = start ? ' checked':''; @@ -106,7 +106,7 @@ function setDefault(form) { $(form).find('textarea.text').trigger('change'); } function changeMenu(form,id) { - $(form).find('input[type=checkbox]').each(function(){ + $(form).find('input.menu').each(function(){ var i = $(this).prop('id'); var header = $('#'+i.replace('checkbox','header')); if (i == id) { @@ -117,12 +117,31 @@ function changeMenu(form,id) { $(this).prop('checked',false); } }); + if ($.cookie('syslinux_viewmode')=='advanced') { + var n = 0, o = 0, x = id.split('-')[1]; + var text = form.text2.value.split('\n'); + for (var i=0; i < text.length; i++) { + if (text[i].indexOf('label ') >= 0) if (++n == x) o = i + 1; + if (text[i].indexOf(boot) >= 0) text.splice(i,1); + } + if (o) text.splice(o,0,' '+boot); + form.text2.value = text.join('\n'); + } } $(function(){ $('form').find('textarea').each(function(){$(this).on('input change',function(){ $(this).attr('rows',($(this).val().match(/\n/g)||[]).length+1); + if ($(this).attr('class')=='text') { + var n = 0, id = null; + var text = $(this).val().split('\n'); + for (var i=0; i < text.length; i++) { + if (text[i].indexOf('label ') >= 0) n++; + if (text[i].indexOf(boot) >= 0) {id = 'checkbox-'+n; break;} + } + if (id) changeMenu($(this).closest('form'),id); + } });}); - if ($.cookie('syslinux_view_mode')=='advanced') { + if ($.cookie('syslinux_viewmode')=='advanced') { $('.advanced').show(); $('.basic').hide(); } @@ -130,12 +149,12 @@ $(function(){ labels_placement: 'left', on_label: 'Advanced View', off_label: 'Basic View', - checked: $.cookie('syslinux_view_mode')=='advanced' + checked: $.cookie('syslinux_viewmode')=='advanced' }); $('.advancedview').change(function() { $('.advanced').toggle('slow'); $('.basic').toggle('slow'); - $.cookie('syslinux_view_mode', $('.advancedview').is(':checked') ? 'advanced':'basic', {expires:3650}); + $.cookie('syslinux_viewmode', $('.advancedview').is(':checked') ? 'advanced':'basic', {expires:3650}); }); }); @@ -161,7 +180,7 @@ Syslinux configuration: $start = in_array($boot,$field); if ($start) unset($field[array_search($boot,$field)]); ?> - title="Set default boot menu" onchange="changeMenu(this.form,this.id)"> + title="Set default boot menu" onchange="changeMenu(this.form,this.id)"> From b24708eb8c5866c3567de7379ff34053ded323f7 Mon Sep 17 00:00:00 2001 From: bergware Date: Sat, 5 May 2018 17:21:59 +0200 Subject: [PATCH 063/100] Syslinux config: basic and advanced mode --- plugins/dynamix/Syslinux.page | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/dynamix/Syslinux.page b/plugins/dynamix/Syslinux.page index afff89f5a..7d91545e5 100644 --- a/plugins/dynamix/Syslinux.page +++ b/plugins/dynamix/Syslinux.page @@ -34,8 +34,8 @@ $boot = 'menu default'; ?> Samba extra configuration: -: +:   : From 32067e89b41db0c8a407ad7625975c920b49d37f Mon Sep 17 00:00:00 2001 From: Shayne Sweeney Date: Sun, 6 May 2018 21:55:51 -0700 Subject: [PATCH 081/100] Add support for Docker Labels to Docker plugin Docker object labels: https://docs.docker.com/config/labels-custom-metadata/ More and more containers are taking advantage of container metadata where environment variables are not necessary. Traefik is a good example: https://docs.traefik.io/configuration/backends/docker/#on-containers --- .../include/CreateDocker.php | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/plugins/dynamix.docker.manager/include/CreateDocker.php b/plugins/dynamix.docker.manager/include/CreateDocker.php index ebe910932..0d205ad82 100644 --- a/plugins/dynamix.docker.manager/include/CreateDocker.php +++ b/plugins/dynamix.docker.manager/include/CreateDocker.php @@ -192,6 +192,7 @@ function postToXML($post, $setOwnership=false) { $xml->Networking->addChild("Publish"); $xml->addChild("Data"); $xml->addChild("Environment"); + $xml->addChild("Labels"); $size = is_array($post['confName']) ? count($post['confName']) : 0; for ($i = 0; $i < $size; $i++) { @@ -222,6 +223,11 @@ function postToXML($post, $setOwnership=false) { $variable->Value = $post['confValue'][$i]; $variable->Name = $post['confTarget'][$i]; $variable->Mode = $post['confMode'][$i]; + } elseif ($Type == 'Label') { + $label = $xml->Labels->addChild("Label"); + $label->Value = $post['confValue'][$i]; + $label->Name = $post['confTarget'][$i]; + $label->Mode = $post['confMode'][$i]; } } $dom = new DOMDocument('1.0'); @@ -346,6 +352,25 @@ function xmlToVar($xml) { ]; } } + if (isset($xml->Labels->Variable)) { + $varNum = 0; + foreach ($xml->Labels->Variable as $varitem) { + if (empty(xml_decode($varitem->Name))) continue; + $varNum += 1; + $out['Config'][] = [ + 'Name' => "Label ${varNum}", + 'Target' => xml_decode($varitem->Name), + 'Default' => xml_decode($varitem->Value), + 'Value' => xml_decode($varitem->Value), + 'Mode' => '', + 'Description' => 'Container Label: '.xml_decode($varitem->Name), + 'Type' => 'Label', + 'Display' => 'always', + 'Required' => 'false', + 'Mask' => 'false' + ]; + } + } } xmlSecurity($out); return $out; @@ -378,6 +403,7 @@ function xmlToCommand($xml, $create_paths=false) { $Volumes = ['']; $Ports = ['']; $Variables = ['']; + $Labels = ['']; $Devices = ['']; // Bind Time $Variables[] = 'TZ="' . $var['timeZone'] . '"'; @@ -411,6 +437,8 @@ function xmlToCommand($xml, $create_paths=false) { case 'none': // No export of ports if network is set to none } + } elseif ($confType == "label") { + $Labels[] = escapeshellarg($containerConfig).'='.escapeshellarg($hostConfig); } elseif ($confType == "variable") { $Variables[] = escapeshellarg($containerConfig).'='.escapeshellarg($hostConfig); } elseif ($confType == "device") { @@ -419,7 +447,7 @@ function xmlToCommand($xml, $create_paths=false) { } $postArgs = explode(";",$xml['PostArgs']); $cmd = sprintf($docroot.'/plugins/dynamix.docker.manager/scripts/docker create %s %s %s %s %s %s %s %s %s %s %s', - $cmdName, $cmdNetwork, $cmdMyIP, $cmdPrivileged, implode(' -e ', $Variables), implode(' -p ', $Ports), implode(' -v ', $Volumes), implode(' --device=', $Devices), $xml['ExtraParams'], escapeshellarg($xml['Repository']), $postArgs[0]); + $cmdName, $cmdNetwork, $cmdMyIP, $cmdPrivileged, implode(' -e ', $Variables), implode(' -l ', $Labels), implode(' -p ', $Ports), implode(' -v ', $Volumes), implode(' --device=', $Devices), $xml['ExtraParams'], escapeshellarg($xml['Repository']), $postArgs[0]); return [preg_replace('/\s+/', ' ', $cmd), $xml['Name'], $xml['Repository']]; } @@ -1033,7 +1061,11 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t targetDiv.find('#dt1').text('Key:'); valueDiv.find('#dt2').text('Value:'); break; - case 3: // Device + case 3: // Label + targetDiv.find('#dt1').text('Key:'); + valueDiv.find('#dt2').text('Value:'); + break; + case 4: // Device targetDiv.hide(); defaultDiv.hide(); valueDiv.find('#dt2').text('Value:'); @@ -1450,7 +1482,7 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t - +
Add another Path, Port, Variable or Device Add another Path, Port, Variable, Label or Device

@@ -1483,6 +1515,7 @@ optgroup.title{background-color:#625D5D;color:#FFFFFF;text-align:center;margin-t + From 788e40f74d3335f5414631aa9b7096e1ac216dff Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 7 May 2018 08:08:35 +0200 Subject: [PATCH 082/100] Make SMB extra auto sizeable --- plugins/dynamix/SMBExtras.page | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/dynamix/SMBExtras.page b/plugins/dynamix/SMBExtras.page index 69a176c77..ea1829463 100644 --- a/plugins/dynamix/SMBExtras.page +++ b/plugins/dynamix/SMBExtras.page @@ -25,9 +25,8 @@ $text = preg_replace(["/\r\n/","/\r/"],"\n",$text); ?> From 74a47e4087dc3c0e7d590c35079a6d27a480fd4b Mon Sep 17 00:00:00 2001 From: bergware Date: Mon, 7 May 2018 08:15:58 +0200 Subject: [PATCH 083/100] Make SMB extra auto sizeable --- plugins/dynamix/SMBExtras.page | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/dynamix/SMBExtras.page b/plugins/dynamix/SMBExtras.page index ea1829463..5d25c5c45 100644 --- a/plugins/dynamix/SMBExtras.page +++ b/plugins/dynamix/SMBExtras.page @@ -20,7 +20,7 @@ Tag="share-alt-square"