You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
(4) |
May
(38) |
Jun
(3) |
Jul
(12) |
Aug
(4) |
Sep
(12) |
Oct
(15) |
Nov
(26) |
Dec
(8) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(14) |
Feb
(34) |
Mar
(105) |
Apr
(64) |
May
(56) |
Jun
(97) |
Jul
(180) |
Aug
(103) |
Sep
(54) |
Oct
(21) |
Nov
(44) |
Dec
(27) |
2002 |
Jan
(7) |
Feb
(10) |
Mar
(88) |
Apr
(57) |
May
(29) |
Jun
(12) |
Jul
(13) |
Aug
(35) |
Sep
(12) |
Oct
(16) |
Nov
(48) |
Dec
(94) |
2003 |
Jan
(36) |
Feb
(43) |
Mar
(124) |
Apr
(63) |
May
(77) |
Jun
(12) |
Jul
(7) |
Aug
(40) |
Sep
(41) |
Oct
(19) |
Nov
(22) |
Dec
(46) |
2004 |
Jan
(51) |
Feb
(129) |
Mar
(82) |
Apr
(96) |
May
(34) |
Jun
(28) |
Jul
(107) |
Aug
(87) |
Sep
(21) |
Oct
(50) |
Nov
(202) |
Dec
(110) |
2005 |
Jan
(174) |
Feb
(159) |
Mar
(250) |
Apr
(287) |
May
(159) |
Jun
(139) |
Jul
(305) |
Aug
(291) |
Sep
(558) |
Oct
(628) |
Nov
(539) |
Dec
(396) |
2006 |
Jan
(828) |
Feb
(470) |
Mar
(888) |
Apr
(524) |
May
(518) |
Jun
(424) |
Jul
(527) |
Aug
(208) |
Sep
(257) |
Oct
(276) |
Nov
(308) |
Dec
(342) |
2007 |
Jan
(366) |
Feb
(350) |
Mar
(265) |
Apr
(406) |
May
(481) |
Jun
(354) |
Jul
(195) |
Aug
(219) |
Sep
(506) |
Oct
(434) |
Nov
(467) |
Dec
(399) |
2008 |
Jan
(339) |
Feb
(185) |
Mar
(172) |
Apr
(191) |
May
(126) |
Jun
(149) |
Jul
(424) |
Aug
(317) |
Sep
(164) |
Oct
(246) |
Nov
(110) |
Dec
(123) |
2009 |
Jan
(82) |
Feb
(74) |
Mar
(125) |
Apr
(133) |
May
(51) |
Jun
(52) |
Jul
(37) |
Aug
(48) |
Sep
(60) |
Oct
(69) |
Nov
(52) |
Dec
(60) |
2010 |
Jan
(55) |
Feb
(69) |
Mar
(55) |
Apr
(144) |
May
(309) |
Jun
(318) |
Jul
(114) |
Aug
(128) |
Sep
(122) |
Oct
(96) |
Nov
(274) |
Dec
(219) |
2011 |
Jan
(223) |
Feb
(241) |
Mar
(266) |
Apr
(286) |
May
(251) |
Jun
(214) |
Jul
(308) |
Aug
(312) |
Sep
(192) |
Oct
(61) |
Nov
(20) |
Dec
(35) |
2012 |
Jan
(165) |
Feb
(70) |
Mar
(102) |
Apr
(96) |
May
(101) |
Jun
(125) |
Jul
(59) |
Aug
(108) |
Sep
(246) |
Oct
(372) |
Nov
(456) |
Dec
(374) |
2013 |
Jan
(215) |
Feb
(402) |
Mar
(386) |
Apr
(274) |
May
(117) |
Jun
(52) |
Jul
(125) |
Aug
(106) |
Sep
(188) |
Oct
(139) |
Nov
(74) |
Dec
(52) |
2014 |
Jan
(301) |
Feb
(62) |
Mar
(229) |
Apr
(85) |
May
(275) |
Jun
(138) |
Jul
(143) |
Aug
(121) |
Sep
(147) |
Oct
(278) |
Nov
(86) |
Dec
(100) |
2015 |
Jan
(113) |
Feb
(92) |
Mar
(96) |
Apr
(273) |
May
(122) |
Jun
(128) |
Jul
(41) |
Aug
(33) |
Sep
(161) |
Oct
(21) |
Nov
(71) |
Dec
(18) |
2016 |
Jan
(243) |
Feb
(35) |
Mar
(98) |
Apr
(102) |
May
(29) |
Jun
(7) |
Jul
(25) |
Aug
(25) |
Sep
(10) |
Oct
(10) |
Nov
(19) |
Dec
(8) |
2017 |
Jan
(18) |
Feb
(8) |
Mar
(4) |
Apr
(18) |
May
(22) |
Jun
(13) |
Jul
(12) |
Aug
(4) |
Sep
(3) |
Oct
(6) |
Nov
(5) |
Dec
(2) |
2018 |
Jan
(6) |
Feb
(2) |
Mar
(1) |
Apr
(4) |
May
(3) |
Jun
(2) |
Jul
(5) |
Aug
(2) |
Sep
(4) |
Oct
(2) |
Nov
|
Dec
|
2019 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2020 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
(3) |
Nov
(2) |
Dec
|
2021 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2023 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(2) |
Jul
(3) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2024 |
Jan
|
Feb
|
Mar
(1) |
Apr
(4) |
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <de...@de...> - 2017-02-12 00:37:31
|
Author: PeterThoeny Date: 2017-02-12 00:35:49 +0000 (Sun, 12 Feb 2017) New Revision: 30307 Trac url: http://develop.twiki.org/trac/changeset/30307 Modified: twiki/trunk/core/data/TWiki/TWikiPreferences.txt Log: Item7774: PARENTBC setting: Omit double-angle separator if no parent Modified: twiki/trunk/core/data/TWiki/TWikiPreferences.txt =================================================================== --- twiki/trunk/core/data/TWiki/TWikiPreferences.txt 2017-01-27 13:42:31 UTC (rev 30306) +++ twiki/trunk/core/data/TWiki/TWikiPreferences.txt 2017-02-12 00:35:49 UTC (rev 30307) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1456811560" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1486858790" format="1.1" version="$Rev$"}% ---+!! <nop>%WIKITOOLNAME% Site-Level Preferences This topic defines __site-level__ settings that apply to all users and webs on this TWikiSite. @@ -315,7 +315,7 @@ * Add =%<nop>PARENTBC%= to a heading of a topic to show the breadcrumb of its parents. Parent topics are linked, topic names are shown spaced out in a smaller font, and are separated by =»= quotes. In addition, a =parentlist= SetGetPlugin variable is set to the parent list, and a =parent= variable is set to the immediate parent. This can be retrieved later in the topic using =%<nop>GET{parentlist}%= and =%<nop>GET{parent}%=, respectively. * Example raw text:%BR% =---+ %<nop>PARENTBC% Myself and me= * Expands to: <h1> <span style="font-size: 58%"> [[%TOPIC%][Grandma And Granpa]] » [[%TOPIC%][Mother And Father]] » </span> Myself and me</h1> - * Set PARENTBC = <span style="font-size: 58%"> %SET{ "parentlist" value="%META{ "parent" nowebhome="on" format="$topic" separator=", " }%" }%%SET{ "parent" value="%CALCULATE{$LISTITEM(-1, %GET{parentlist}%)}%" }%%CALCULATE{$LISTJOIN($sp»$sp, $LISTMAP([[$item][$PROPERSPACE($item)]], %GET{parentlist}%))}% » </span> + * Set PARENTBC = <span style="font-size: 58%"> %SET{ "parentlist" value="%META{ "parent" nowebhome="on" format="$topic" separator=", " }%" }%%SET{ "parent" value="%CALCULATE{$LISTITEM(-1, %GET{parentlist}%)}%" }%%CALCULATE{$LISTJOIN($sp»$sp, $LISTMAP([[$item][$PROPERSPACE($item)]], %GET{parentlist}%)) $IF($LENGTH(%GET{parentlist}%)>0, »)}% </span> * [[VarREG][Registered trademark symbol]]: * Set REG = ® |
From: Peter T. <pe...@th...> - 2017-02-01 19:03:15
|
All: Please join our TWiki Kampala Release Meeting, http://twiki.org/cgi-bin/view/Codev/KampalaReleaseMeeting2017x02x02 scheduled for 2017-02-02 23:00 GMT [1] on IRC channel #twiki_release on the irc.freenode.net IRC network [2] - in about 28 hours from now. Proposed agenda: 1. Feature Requests for Kampala Release 2. Review Urgent and Not So Urgent Bugs 3. Extensions 4. TWiki Release Discussion 5. Miscellaneous The meeting is on Thursday or Friday, depending on your time zone. Meeting time in different time zones, tomorrow: * USA Pacific Time Zone: 03:00pm on Thu * USA Eastern Time Zone: 06:00pm on Thu * Central Europe: 24:00 on Thu/Fri night * Japan: 08:00 on Fri Please show up in time to save everybody's time. And remember that the release meeting is where decisions are made. We invite all TWiki.org contributors to join, as well as people with interest in the TWiki project in general. Cheers, Peter [1]: http://www.timeanddate.com/worldclock/converter.html?iso=20170202T230000&p1=tz_gmt&p2=248&p3=268&p4=224&p5=179 [2]: http://twiki.org/cgi-bin/view/Codev/TWikiIRC -- > Peter Thoeny - Peter09[at]Thoeny.org > http://TWiki.org/Mr.TWiki - consulting on enterprise collaboration > http://TWiki.org - is your team already TWiki enabled? > http://qualityHDR.com - Quality HDR Photography > Knowledge cannot be managed, it can be discovered and shared > This e-mail is: (_) private (_) ask first (x) public |
From: <de...@de...> - 2017-01-27 13:44:08
|
Author: AaronLWalker Date: 2017-01-27 13:42:31 +0000 (Fri, 27 Jan 2017) New Revision: 30306 Trac url: http://develop.twiki.org/trac/changeset/30306 Added: twiki/trunk/CytoscapePlugin/data/ twiki/trunk/CytoscapePlugin/data/TWiki/ twiki/trunk/CytoscapePlugin/data/TWiki/CytoscapePlugin.txt twiki/trunk/CytoscapePlugin/lib/ twiki/trunk/CytoscapePlugin/lib/TWiki/ twiki/trunk/CytoscapePlugin/lib/TWiki/Plugins/ twiki/trunk/CytoscapePlugin/lib/TWiki/Plugins/CytoscapePlugin.pm twiki/trunk/CytoscapePlugin/pub/ twiki/trunk/CytoscapePlugin/pub/TWiki/ twiki/trunk/CytoscapePlugin/pub/TWiki/CytoscapePlugin/ twiki/trunk/CytoscapePlugin/pub/TWiki/CytoscapePlugin/cytoscape.min.js Log: Item7773: Initial population of CytoscapePlugin Added: twiki/trunk/CytoscapePlugin/data/TWiki/CytoscapePlugin.txt =================================================================== --- twiki/trunk/CytoscapePlugin/data/TWiki/CytoscapePlugin.txt (rev 0) +++ twiki/trunk/CytoscapePlugin/data/TWiki/CytoscapePlugin.txt 2017-01-27 13:42:31 UTC (rev 30306) @@ -0,0 +1,80 @@ +%META:TOPICINFO{author="AaronWalker" date="1435086146" format="1.1" version="1.2"}% +---+!! !CytoscapePlugin +<!-- + Contributions to this plugin are appreciated. Please update the plugin page at + http://twiki.org/cgi-bin/view/Plugins/CytoscapePlugin or provide feedback at + http://twiki.org/cgi-bin/view/Plugins/CytoscapePluginDev. + If you are a TWiki contributor please update the plugin in the SVN repository. +--> +<sticky><div style="float:right; background-color:#EBEEF0; margin:0 0 20px 20px; padding: 0 10px 0 10px;"> +%TOC{title="Page contents"}% +</div></sticky> +%SHORTDESCRIPTION% + +---++ Introduction + +Describe the plugin here + +---++ Syntax Rules + +=%<nop>EXAMPLEVAR{"..."}%= + +| *Parameter* | *Explanation* | *Default* | +| ="..."= | Default parameter. | (none) | +| =format="..."= | Format: ... | ="$name"= | + +---++ Examples + + * =%<nop>EXAMPLEVAR{}%= expands to: %EXAMPLEVAR{}% + * + +---++ Plugin Installation & Configuration + +You do not need to install anything on the browser to use this plugin. These instructions are for the administrator who installs the plugin on the TWiki server. +%TWISTY{ + mode="div" + showlink="Show details %ICONURL{toggleopen}% " + hidelink="Hide details %ICONURL{toggleclose}% " +}% + + * For an __automated installation__, run the [[%SCRIPTURL{configure}%][configure]] script and follow "Find More Extensions" in the in the __Extensions__ section. + * See the [[http://twiki.org/cgi-bin/view/Plugins/BuildContribInstallationSupplement][installation supplement]] on TWiki.org for more information. + + * Or, follow these __manual installation__ steps: + * Download the ZIP file from the Plugins home (see below). + * Unzip ==%TOPIC%.zip== in your twiki installation directory. Content: + | *File:* | *Description:* | + | ==data/TWiki/%TOPIC%.txt== | Plugin topic | + | ==lib/TWiki/Plugins/%TOPIC%.pm== | Plugin Perl module | + * Set the ownership of the extracted directories and files to the webserver user. + * Install the dependencies (if any). + + * Plugin __configuration and testing__: + * Run the [[%SCRIPTURL{configure}%][configure]] script and enable the plugin in the __Plugins__ section. + * Configure additional plugin settings in the __Extensions__ section if needed. + * Test if the installation was successful using the example above. + +%ENDTWISTY% + +---++ Plugin Info + + * One line description, is shown in the %SYSTEMWEB%.TextFormattingRules topic: + * Set SHORTDESCRIPTION = one line description here +%TABLE{ tablewidth="100%" columnwidths="170," }% +| Plugin Author: | TWiki:Main.AaronLWalker | +| Copyright: | © 2015 TWiki:Main.AaronLWalker <br /> © 2015 TWiki:TWiki.TWikiContributor | +| License: | GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]]) | +| Plugin Version: | 2015-06-23 (V1.000) | +| Change History: | <!-- versions below in reverse order --> | +| 2015-06-23: | Initial version | +| TWiki Dependency: | $TWiki::Plugins::VERSION 1.1 | +| CPAN Dependencies: | none | +| Other Dependencies: | none | +| Perl Version: | 5.005 | +| [[TWiki:Plugins.Benchmark][Plugin Benchmark]]: | %SYSTEMWEB%.GoodStyle nn%, %SYSTEMWEB%.FormattedSearch nn%, %TOPIC% nn% | +| Plugin Home: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC% | +| Feedback: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC%Dev | +| Appraisal: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC%Appraisal | + +__Related Topics:__ %SYSTEMWEB%.TWikiPlugins, %SYSTEMWEB%.DeveloperDocumentationCategory, %SYSTEMWEB%.AdminDocumentationCategory, %SYSTEMWEB%.TWikiPreferences + Added: twiki/trunk/CytoscapePlugin/lib/TWiki/Plugins/CytoscapePlugin.pm =================================================================== --- twiki/trunk/CytoscapePlugin/lib/TWiki/Plugins/CytoscapePlugin.pm (rev 0) +++ twiki/trunk/CytoscapePlugin/lib/TWiki/Plugins/CytoscapePlugin.pm 2017-01-27 13:42:31 UTC (rev 30306) @@ -0,0 +1,63 @@ +# Plugin for TWiki Enterprise Collaboration Platform, http://TWiki.org/ +# +# Copyright (c) 2007-2008 Michael Daum, http://michaeldaumconsulting.com +# Copyright (c) 2007-2011 TWiki Contributors. All Rights Reserved. +# TWiki Contributors are listed in the AUTHORS file in the root of +# this distribution. +# NOTE: Please extend that file, not this notice. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. For +# more details read LICENSE in the root of this distribution. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# For licensing info read LICENSE file in the TWiki root. + +package TWiki::Plugins::CytoscapePlugin; +use strict; +use vars qw( + $VERSION $RELEASE $SHORTDESCRIPTION + $NO_PREFS_IN_TOPIC + $doneInit $doneHeader + $dtPubUrlPath $header +); + +$VERSION = '$Rev: 20836 (2011-05-03) $'; +$RELEASE = '2016-10-05'; +$SHORTDESCRIPTION = '<nop>Cytoscape jQuery library for TWiki'; +$NO_PREFS_IN_TOPIC = 1; + +$dtPubUrlPath = '%PUBURLPATH%/%SYSTEMWEB%/CytoscapePlugin'; +$header = "<script type=\"text/javascript\" src=\"$dtPubUrlPath/cytoscape.min.js\"></script>\n"; + +############################################################################### +sub initPlugin { + my( $topic, $web, $user, $installWeb ) = @_; + + $doneInit = 0; + $doneHeader = 0; + + TWiki::Func::registerTagHandler('CYTOSCAPE', \&handleCytoscapeBase ); + + return 1; +} + +############################################################################### +sub handleCytoscapeBase { + my ($session, $params, $theTopic, $theWeb) = @_; + + return if $doneHeader; + $doneHeader = 1 if ($_[0] =~ s/<head>(.*?[\r\n]+)/<head>$1$header/o); + + TWiki::Func::addToHEAD( + "cytoscape", + $header + ); +} + +1; Property changes on: twiki/trunk/CytoscapePlugin/lib/TWiki/Plugins/CytoscapePlugin.pm ___________________________________________________________________ Added: svn:executable + * Added: twiki/trunk/CytoscapePlugin/pub/TWiki/CytoscapePlugin/cytoscape.min.js =================================================================== --- twiki/trunk/CytoscapePlugin/pub/TWiki/CytoscapePlugin/cytoscape.min.js (rev 0) +++ twiki/trunk/CytoscapePlugin/pub/TWiki/CytoscapePlugin/cytoscape.min.js 2017-01-27 13:42:31 UTC (rev 30306) @@ -0,0 +1,63 @@ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.cytoscape=e()}}(function(){var define,module,exports;return function e(t,r,n){function i(o,s){if(!r[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[o]={exports:{}};t[o][0].call(c.exports,function(e){var r=t[o][1][e];return i(r?r:e)},c,c.exports,e,t,r,n)}return r[o].exports}for(var a="function"==typeof require&&require,o=0;o<n.length;o++)i(n[o]);return i}({1:[function(e,t,r){/*! + +Cytoscape.js 2.7.10 (MIT licensed) + +Copyright (c) The Cytoscape Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the “Software”), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +*/ +"use strict"},{}],2:[function(e,t,r){"use strict";var n=e("./util"),i=e("./is"),a=e("./promise"),o=function(e,t,r){if(!(this instanceof o))return new o(e,t,r);var a=this._private=n.extend({duration:1e3},t,r);a.target=e,a.style=a.style||a.css,a.started=!1,a.playing=!1,a.hooked=!1,a.applying=!1,a.progress=0,a.completes=[],a.frames=[],a.complete&&i.fn(a.complete)&&a.completes.push(a.complete),this.length=1,this[0]=this},s=o.prototype;n.extend(s,{instanceString:function(){return"animation"},hook:function(){var e=this._private;if(!e.hooked){var t,r=e.target._private.animation;t=e.queue?r.queue:r.current,t.push(this),i.elementOrCollection(e.target)&&e.target.cy().addToAnimationPool(e.target),e.hooked=!0}return this},play:function(){var e=this._private;return 1===e.progress&&(e.progress=0),e.playing=!0,e.started=!1,e.stopped=!1,this.hook(),this},playing:function(){return this._private.playing},apply:function(){var e=this._private;return e.applying=!0,e.started=!1,e.stopped=!1,this! .hook(),this},applying:function(){return this._private.applying},pause:function(){var e=this._private;return e.playing=!1,e.started=!1,this},stop:function(){var e=this._private;return e.playing=!1,e.started=!1,e.stopped=!0,this},rewind:function(){return this.progress(0)},fastforward:function(){return this.progress(1)},time:function(e){var t=this._private;return void 0===e?t.progress*t.duration:this.progress(e/t.duration)},progress:function(e){var t=this._private,r=t.playing;return void 0===e?t.progress:(r&&this.pause(),t.progress=e,t.started=!1,r&&this.play(),this)},completed:function(){return 1===this._private.progress},reverse:function(){var e=this._private,t=e.playing;t&&this.pause(),e.progress=1-e.progress,e.started=!1;var r=function(t,r){var n=e[t];e[t]=e[r],e[r]=n};r("zoom","startZoom"),r("pan","startPan"),r("position","startPosition");for(var n=0;n<e.style.length;n++){var i=e.style[n],a=i.name,o=e.startStyle[a];e.startStyle[a]=i,e.style[n]=o}return t&&this.play(),thi! s},promise:function(e){var t,r=this._private;switch(e){case"fr! ame":t=r .frames;break;default:case"complete":case"completed":t=r.completes}return new a(function(e,r){t.push(function(){e()})})}}),s.complete=s.completed,t.exports=o},{"./is":83,"./promise":86,"./util":100}],3:[function(e,t,r){"use strict";var n=e("../../is"),i={aStar:function(e){var t=this;e=e||{};var r=function(e,t,n,i){if(e==t)return i.push(a.getElementById(t)),i;if(t in n){var o=n[t],s=f[t];return i.push(a.getElementById(t)),i.push(a.getElementById(s)),r(e,o,n,i)}},i=function(e,t){if(0!==e.length){for(var r=0,n=t[e[0]],i=1;i<e.length;i++){var a=t[e[i]];n>a&&(n=a,r=i)}return r}},a=this._private.cy;if(null!=e&&null!=e.root){var o=n.string(e.root)?this.filter(e.root)[0]:e.root[0];if(null!=e.goal){var s=n.string(e.goal)?this.filter(e.goal)[0]:e.goal[0];if(null!=e.heuristic&&n.fn(e.heuristic))var l=e.heuristic;else var l=function(){return 0};if(null!=e.weight&&n.fn(e.weight))var u=e.weight;else var u=function(e){return 1};if(null!=e.directed)var c=e.directed;else var c=!1;var d=[],h=! [o.id()],p={},f={},v={},g={};v[o.id()]=0,g[o.id()]=l(o);for(var y=this.edges().stdFilter(function(e){return!e.isLoop()}),m=this.nodes(),b=0;h.length>0;){var x=i(h,g),w=a.getElementById(h[x]);if(b++,w.id()==s.id()){var E=r(o.id(),s.id(),p,[]);return E.reverse(),{found:!0,distance:v[w.id()],path:t.spawn(E),steps:b}}d.push(w.id()),h.splice(x,1);var _=w.connectedEdges();c&&(_=_.stdFilter(function(e){return e.data("source")===w.id()})),_=_.intersect(y);for(var P=0;P<_.length;P++){var S=_[P],k=S.connectedNodes().stdFilter(function(e){return e.id()!==w.id()}).intersect(m);if(-1==d.indexOf(k.id())){var T=v[w.id()]+u.apply(S,[S]);-1!=h.indexOf(k.id())?T<v[k.id()]&&(v[k.id()]=T,g[k.id()]=T+l(k),p[k.id()]=w.id()):(v[k.id()]=T,g[k.id()]=T+l(k),h.push(k.id()),p[k.id()]=w.id(),f[k.id()]=S.id())}}}return{found:!1,distance:void 0,path:void 0,steps:b}}}}};t.exports=i},{"../../is":83}],4:[function(e,t,r){"use strict";var n=e("../../is"),i=e("../../util"),a={bellmanFord:function(e){var t=this! ;if(e=e||{},null!=e.weight&&n.fn(e.weight))var r=e.weight;else! var r=f unction(e){return 1};if(null!=e.directed)var a=e.directed;else var a=!1;if(null!=e.root){if(n.string(e.root))var o=this.filter(e.root)[0];else var o=e.root[0];for(var s=this._private.cy,l=this.edges().stdFilter(function(e){return!e.isLoop()}),u=this.nodes(),c=u.length,d={},h=0;c>h;h++)d[u[h].id()]=h;for(var p=[],f=[],v=[],h=0;c>h;h++)u[h].id()===o.id()?p[h]=0:p[h]=1/0,f[h]=void 0;for(var g=!1,h=1;c>h;h++){g=!1;for(var y=0;y<l.length;y++){var m=d[l[y].source().id()],b=d[l[y].target().id()],x=r.apply(l[y],[l[y]]),w=p[m]+x;if(w<p[b]&&(p[b]=w,f[b]=m,v[b]=l[y],g=!0),!a){var w=p[b]+x;w<p[m]&&(p[m]=w,f[m]=b,v[m]=l[y],g=!0)}}if(!g)break}if(g)for(var y=0;y<l.length;y++){var m=d[l[y].source().id()],b=d[l[y].target().id()],x=r.apply(l[y],[l[y]]);if(p[m]+x<p[b])return i.error("Graph contains a negative weight cycle for Bellman-Ford"),{pathTo:void 0,distanceTo:void 0,hasNegativeWeightCycle:!0}}for(var E=[],h=0;c>h;h++)E.push(u[h].id());var _={distanceTo:function(e){if(n.string(e))var t=s! .filter(e)[0].id();else var t=e.id();return p[d[t]]},pathTo:function(e){var r=function(e,t,r,n,i,a){for(;;){if(i.push(s.getElementById(n[r])),i.push(a[r]),t===r)return i;var o=e[r];if("undefined"==typeof o)return;r=o}};if(n.string(e))var i=s.filter(e)[0].id();else var i=e.id();var a=[],l=r(f,d[o.id()],d[i],E,a,v);return null!=l&&l.reverse(),t.spawn(l)},hasNegativeWeightCycle:!1};return _}}};t.exports=a},{"../../is":83,"../../util":100}],5:[function(e,t,r){"use strict";var n=e("../../is"),i=e("../../heap"),a={betweennessCentrality:function(e){e=e||{};var t,r;n.fn(e.weight)?(r=e.weight,t=!0):t=!1;for(var a,o=null!=e.directed?e.directed:!1,s=this._private.cy,l=this.nodes(),u={},c={},d={set:function(e,t){c[e]=t,t>a&&(a=t)},get:function(e){return c[e]}},h=0;h<l.length;h++){var p=l[h],f=p.id();o?u[f]=p.outgoers().nodes():u[f]=p.openNeighborhood().nodes(),d.set(f,0)}for(var v=0;v<l.length;v++){for(var g=l[v].id(),y=[],m={},b={},x={},w=new i(function(e,t){return x[e]-x[t]}),h=0;h<l! .length;h++){var f=l[h].id();m[f]=[],b[f]=0,x[f]=1/0}for(b[g]=! 1,x[g]=0 ,w.push(g);!w.empty();){var p=w.pop();if(y.push(p),t)for(var E=0;E<u[p].length;E++){var _,P=u[p][E],S=s.getElementById(p);_=S.edgesTo(P).length>0?S.edgesTo(P)[0]:P.edgesTo(S)[0];var k=r.apply(_,[_]);P=P.id(),x[P]>x[p]+k&&(x[P]=x[p]+k,w.nodes.indexOf(P)<0?w.push(P):w.updateItem(P),b[P]=0,m[P]=[]),x[P]==x[p]+k&&(b[P]=b[P]+b[p],m[P].push(p))}else for(var E=0;E<u[p].length;E++){var P=u[p][E].id();x[P]==1/0&&(w.push(P),x[P]=x[p]+1),x[P]==x[p]+1&&(b[P]=b[P]+b[p],m[P].push(p))}}for(var T={},h=0;h<l.length;h++)T[l[h].id()]=0;for(;y.length>0;)for(var P=y.pop(),E=0;E<m[P].length;E++){var p=m[P][E];T[p]=T[p]+b[p]/b[P]*(1+T[P]),P!=l[v].id()&&d.set(P,d.get(P)+T[P])}}var D={betweenness:function(e){if(n.string(e))var e=s.filter(e).id();else var e=e.id();return d.get(e)},betweennessNormalized:function(e){if(n.string(e))var e=s.filter(e).id();else var e=e.id();return d.get(e)/a}};return D.betweennessNormalised=D.betweennessNormalized,D}};a.bc=a.betweennessCentrality,t.exports=a},{"../../heap! ":81,"../../is":83}],6:[function(e,t,r){"use strict";var n=e("../../is"),i=function(e){return e={bfs:e.bfs||!e.dfs,dfs:e.dfs||!e.bfs},function(t,r,i){var a,o,s;n.plainObject(t)&&!n.elementOrCollection(t)&&(a=t,t=a.roots||a.root,r=a.visit,i=a.directed,o=a.std,s=a.thisArg),i=2!==arguments.length||n.fn(r)?i:r,r=n.fn(r)?r:function(){};for(var l,u=this._private.cy,c=t=n.string(t)?this.filter(t):t,d=[],h=[],p={},f={},v={},g=0,y=this.nodes(),m=this.edges(),b=0;b<c.length;b++)c[b].isNode()&&(d.unshift(c[b]),e.bfs&&(v[c[b].id()]=!0,h.push(c[b])),f[c[b].id()]=0);for(;0!==d.length;){var c=e.bfs?d.shift():d.pop();if(e.dfs){if(v[c.id()])continue;v[c.id()]=!0,h.push(c)}var x,w=f[c.id()],E=p[c.id()],_=null==E?void 0:E.connectedNodes().not(c)[0];if(x=o?r.call(s,c,E,_,g++,w):r.call(c,g++,w,c,E,_),x===!0){l=c;break}if(x===!1)break;for(var P=c.connectedEdges(i?function(){return this.data("source")===c.id()}:void 0).intersect(m),b=0;b<P.length;b++){var S=P[b],k=S.connectedNodes(function(){retu! rn this.id()!==c.id()}).intersect(y);0===k.length||v[k.id()]||! (k=k[0], d.push(k),e.bfs&&(v[k.id()]=!0,h.push(k)),p[k.id()]=S,f[k.id()]=f[c.id()]+1)}}for(var T=[],b=0;b<h.length;b++){var D=h[b],C=p[D.id()];C&&T.push(C),T.push(D)}return{path:u.collection(T,{unique:!0}),found:u.collection(l)}}},a={breadthFirstSearch:i({bfs:!0}),depthFirstSearch:i({dfs:!0})};a.bfs=a.breadthFirstSearch,a.dfs=a.depthFirstSearch,t.exports=a},{"../../is":83}],7:[function(e,t,r){"use strict";var n=e("../../is"),i={closenessCentralityNormalized:function(e){e=e||{};var t=this.cy(),r=e.harmonic;void 0===r&&(r=!0);for(var i={},a=0,o=this.nodes(),s=this.floydWarshall({weight:e.weight,directed:e.directed}),l=0;l<o.length;l++){for(var u=0,c=0;c<o.length;c++)if(l!=c){var d=s.distance(o[l],o[c]);u+=r?1/d:d}r||(u=1/u),u>a&&(a=u),i[o[l].id()]=u}return{closeness:function(e){if(n.string(e))var e=t.filter(e)[0].id();else var e=e.id();return i[e]/a}}},closenessCentrality:function(e){if(e=e||{},null!=e.root){if(n.string(e.root))var t=this.filter(e.root)[0];else var t=e.root[0];if(null!! =e.weight&&n.fn(e.weight))var r=e.weight;else var r=function(){return 1};if(null!=e.directed&&n.bool(e.directed))var i=e.directed;else var i=!1;var a=e.harmonic;void 0===a&&(a=!0);for(var o=this.dijkstra({root:t,weight:r,directed:i}),s=0,l=this.nodes(),u=0;u<l.length;u++)if(l[u].id()!=t.id()){var c=o.distanceTo(l[u]);s+=a?1/c:c}return a?s:1/s}}};i.cc=i.closenessCentrality,i.ccn=i.closenessCentralityNormalised=i.closenessCentralityNormalized,t.exports=i},{"../../is":83}],8:[function(e,t,r){"use strict";var n=e("../../is"),i=e("../../util"),a={degreeCentralityNormalized:function(e){e=e||{};var t=this.cy();if(null!=e.directed)var r=e.directed;else var r=!1;var a=this.nodes(),o=a.length;if(r){for(var s={},l={},u=0,c=0,d=0;o>d;d++){var h=a[d],p=this.degreeCentrality(i.extend({},e,{root:h}));u<p.indegree&&(u=p.indegree),c<p.outdegree&&(c=p.outdegree),s[h.id()]=p.indegree,l[h.id()]=p.outdegree}return{indegree:function(e){if(n.string(e))var e=t.filter(e)[0].id();else var e=e.id();r! eturn s[e]/u},outdegree:function(e){if(n.string(e))var e=t.fil! ter(e)[0 ].id();else var e=e.id();return l[e]/c}}}for(var f={},v=0,d=0;o>d;d++){var h=a[d],p=this.degreeCentrality(i.extend({},e,{root:h}));v<p.degree&&(v=p.degree),f[h.id()]=p.degree}return{degree:function(e){if(n.string(e))var e=t.filter(e)[0].id();else var e=e.id();return f[e]/v}}},degreeCentrality:function(e){e=e||{};var t=this;if(null!=e&&null!=e.root){var r=n.string(e.root)?this.filter(e.root)[0]:e.root[0];if(null!=e.weight&&n.fn(e.weight))var i=e.weight;else var i=function(e){return 1};if(null!=e.directed)var a=e.directed;else var a=!1;if(null!=e.alpha&&n.number(e.alpha))var o=e.alpha;else o=0;if(a){for(var s=r.connectedEdges('edge[target = "'+r.id()+'"]').intersection(t),l=r.connectedEdges('edge[source = "'+r.id()+'"]').intersection(t),u=s.length,c=l.length,d=0,h=0,p=0;p<s.length;p++){var f=s[p];d+=i.apply(f,[f])}for(var p=0;p<l.length;p++){var f=l[p];h+=i.apply(f,[f])}return{indegree:Math.pow(u,1-o)*Math.pow(d,o),outdegree:Math.pow(c,1-o)*Math.pow(h,o)}}for(var v=r.connected! Edges().intersection(t),g=v.length,y=0,p=0;p<v.length;p++){var f=v[p];y+=i.apply(f,[f])}return{degree:Math.pow(g,1-o)*Math.pow(y,o)}}}};a.dc=a.degreeCentrality,a.dcn=a.degreeCentralityNormalised=a.degreeCentralityNormalized,t.exports=a},{"../../is":83,"../../util":100}],9:[function(e,t,r){"use strict";var n=e("../../is"),i=e("../../heap"),a={dijkstra:function(e,t,r){var a;n.plainObject(e)&&!n.elementOrCollection(e)&&(a=e,e=a.root,t=a.weight,r=a.directed);var o=this._private.cy;t=n.fn(t)?t:function(){return 1};for(var s=n.string(e)?this.filter(e)[0]:e[0],l={},u={},c={},d=this.edges().filter(function(){return!this.isLoop()}),h=this.nodes(),p=function(e){return l[e.id()]},f=function(e,t){l[e.id()]=t,v.updateItem(e)},v=new i(function(e,t){return p(e)-p(t)}),g=0;g<h.length;g++){var y=h[g];l[y.id()]=y.same(s)?0:1/0,v.push(y)}for(var m=function(e,n){for(var i,a=(r?e.edgesTo(n):e.edgesWith(n)).intersect(d),o=1/0,s=0;s<a.length;s++){var l=a[s],u=t.apply(l,[l]);(o>u||!i)&&(o=u,i=l)}r! eturn{edge:i,dist:o}};v.size()>0;){var b=v.pop(),x=p(b),w=b.id! ();if(c[ w]=x,x===Math.Infinite)break;for(var E=b.neighborhood().intersect(h),g=0;g<E.length;g++){var _=E[g],P=_.id(),S=m(b,_),k=x+S.dist;k<p(_)&&(f(_,k),u[P]={node:b,edge:S.edge})}}return{distanceTo:function(e){var t=n.string(e)?h.filter(e)[0]:e[0];return c[t.id()]},pathTo:function(e){var t=n.string(e)?h.filter(e)[0]:e[0],r=[],i=t;if(t.length>0)for(r.unshift(t);u[i.id()];){var a=u[i.id()];r.unshift(a.edge),r.unshift(a.node),i=a.node}return o.collection(r)}}}};t.exports=a},{"../../heap":81,"../../is":83}],10:[function(e,t,r){"use strict";var n=e("../../is"),i={floydWarshall:function(e){e=e||{};var t=this.cy();if(null!=e.weight&&n.fn(e.weight))var r=e.weight;else var r=function(e){return 1};if(null!=e.directed)var i=e.directed;else var i=!1;for(var a=this.edges().stdFilter(function(e){return!e.isLoop()}),o=this.nodes(),s=o.length,l={},u=0;s>u;u++)l[o[u].id()]=u;for(var c=[],u=0;s>u;u++){for(var d=new Array(s),h=0;s>h;h++)u==h?d[h]=0:d[h]=1/0;c.push(d)}var p=[],f=[],v=function(e){for(v! ar t=0;s>t;t++){for(var r=new Array(s),n=0;s>n;n++)r[n]=void 0;e.push(r)}};v(p),v(f);for(var u=0;u<a.length;u++){var g=l[a[u].source().id()],y=l[a[u].target().id()],m=r.apply(a[u],[a[u]]);c[g][y]>m&&(c[g][y]=m,p[g][y]=y,f[g][y]=a[u])}if(!i)for(var u=0;u<a.length;u++){var g=l[a[u].target().id()],y=l[a[u].source().id()],m=r.apply(a[u],[a[u]]);c[g][y]>m&&(c[g][y]=m,p[g][y]=y,f[g][y]=a[u])}for(var b=0;s>b;b++)for(var u=0;s>u;u++)for(var h=0;s>h;h++)c[u][b]+c[b][h]<c[u][h]&&(c[u][h]=c[u][b]+c[b][h],p[u][h]=p[u][b]);for(var x=[],u=0;s>u;u++)x.push(o[u].id());var w={distance:function(e,r){if(n.string(e))var i=t.filter(e)[0].id();else var i=e.id();if(n.string(r))var a=t.filter(r)[0].id();else var a=r.id();return c[l[i]][l[a]]},path:function(e,r){var i=function(e,r,n,i,a){if(e===r)return t.getElementById(i[e]);if(void 0!==n[e][r]){for(var o=[t.getElementById(i[e])],s=e;e!==r;){s=e,e=n[e][r];var l=a[s][e];o.push(l),o.push(t.getElementById(i[e]))}return o}};if(n.string(e))var a=t.filt! er(e)[0].id();else var a=e.id();if(n.string(r))var o=t.filter(! r)[0].id ();else var o=r.id();var s=i(l[a],l[o],p,x,f);return t.collection(s)}};return w}};t.exports=i},{"../../is":83}],11:[function(e,t,r){"use strict";var n=e("../../util"),i={};[e("./bfs-dfs"),e("./dijkstra"),e("./kruskal"),e("./a-star"),e("./floyd-warshall"),e("./bellman-ford"),e("./kerger-stein"),e("./page-rank"),e("./degree-centrality"),e("./closeness-centrality"),e("./betweenness-centrality")].forEach(function(e){n.extend(i,e)}),t.exports=i},{"../../util":100,"./a-star":3,"./bellman-ford":4,"./betweenness-centrality":5,"./bfs-dfs":6,"./closeness-centrality":7,"./degree-centrality":8,"./dijkstra":9,"./floyd-warshall":10,"./kerger-stein":12,"./kruskal":13,"./page-rank":14}],12:[function(e,t,r){"use strict";var n=e("../../util"),i={kargerStein:function(e){var t=this;e=e||{};var r=function(e,t,r){for(var n=r[e],i=n[1],a=n[2],o=t[i],s=t[a],l=r.filter(function(e){return t[e[1]]===o&&t[e[2]]===s?!1:t[e[1]]!==s||t[e[2]]!==o}),u=0;u<l.length;u++){var c=l[u];c[1]===s?(l[u]=c.slice(0),l! [u][1]=o):c[2]===s&&(l[u]=c.slice(0),l[u][2]=o)}for(var u=0;u<t.length;u++)t[u]===s&&(t[u]=o);return l},i=function(e,t,n,a){if(a>=n)return t;var o=Math.floor(Math.random()*t.length),s=r(o,e,t);return i(e,s,n-1,a)},a=this._private.cy,o=this.edges().stdFilter(function(e){return!e.isLoop()}),s=this.nodes(),l=s.length,u=o.length,c=Math.ceil(Math.pow(Math.log(l)/Math.LN2,2)),d=Math.floor(l/Math.sqrt(2));if(2>l)return void n.error("At least 2 nodes are required for Karger-Stein algorithm");for(var h={},p=0;l>p;p++)h[s[p].id()]=p;for(var f=[],p=0;u>p;p++){var v=o[p];f.push([p,h[v.source().id()],h[v.target().id()]])}for(var g,y=1/0,m=[],p=0;l>p;p++)m.push(p);for(var b=0;c>=b;b++){var x=m.slice(0),w=i(x,f,l,d),E=x.slice(0),_=i(x,w,d,2),P=i(E,w,d,2);_.length<=P.length&&_.length<y?(y=_.length,g=[_,x]):P.length<=_.length&&P.length<y&&(y=P.length,g=[P,E])}for(var S=g[0].map(function(e){return o[e[0]]}),k=[],T=[],D=g[1][0],p=0;p<g[1].length;p++){var C=g[1][p];C===D?k.push(s[p]):T.push(s[! p])}var M={cut:t.spawn(a,S),partition1:t.spawn(k),partition2:t! .spawn(T )};return M}};t.exports=i},{"../../util":100}],13:[function(e,t,r){"use strict";var n=e("../../is"),i={kruskal:function(e){function t(e){for(var t=0;t<a.length;t++){var r=a[t];if(r.anySame(e))return{eles:r,index:t}}}var r=this.cy();e=n.fn(e)?e:function(){return 1};for(var i=r.collection(r,[]),a=[],o=this.nodes(),s=0;s<o.length;s++)a.push(o[s].collection());for(var l=this.edges(),u=l.toArray().sort(function(t,r){var n=e.call(t,t),i=e.call(r,r);return n-i}),s=0;s<u.length;s++){var c=u[s],d=c.source()[0],h=c.target()[0],p=t(d),f=t(h);p.index!==f.index&&(i=i.add(c),a[p.index]=p.eles.add(f.eles),a.splice(f.index,1))}return o.add(i)}};t.exports=i},{"../../is":83}],14:[function(e,t,r){"use strict";var n=e("../../is"),i={pageRank:function(e){e=e||{};var t=function(e){for(var t=e.length,r=0,n=0;t>n;n++)r+=e[n];for(var n=0;t>n;n++)e[n]=e[n]/r};if(null!=e&&null!=e.dampingFactor)var r=e.dampingFactor;else var r=.8;if(null!=e&&null!=e.precision)var i=e.precision;else var i=1e-6;if(null!=! e&&null!=e.iterations)var a=e.iterations;else var a=200;if(null!=e&&null!=e.weight&&n.fn(e.weight))var o=e.weight;else var o=function(e){return 1};for(var s=this._private.cy,l=this.edges().stdFilter(function(e){return!e.isLoop()}),u=this.nodes(),c=u.length,d=l.length,h={},p=0;c>p;p++)h[u[p].id()]=p;for(var f=[],v=[],g=(1-r)/c,p=0;c>p;p++){for(var y=[],m=0;c>m;m++)y.push(0);f.push(y),v.push(0)}for(var p=0;d>p;p++){var b=l[p],x=h[b.source().id()],w=h[b.target().id()],E=o.apply(b,[b]);f[w][x]+=E,v[x]+=E}for(var _=1/c+g,m=0;c>m;m++)if(0===v[m])for(var p=0;c>p;p++)f[p][m]=_;else for(var p=0;c>p;p++)f[p][m]=f[p][m]/v[m]+g;for(var P,S=[],k=[],p=0;c>p;p++)S.push(1),k.push(0);for(var T=0;a>T;T++){for(var D=k.slice(0),p=0;c>p;p++)for(var m=0;c>m;m++)D[p]+=f[p][m]*S[m];t(D),P=S,S=D;for(var C=0,p=0;c>p;p++)C+=Math.pow(P[p]-S[p],2);if(i>C)break}var M={rank:function(e){if(n.string(e))var t=s.filter(e)[0].id();else var t=e.id();return S[h[t]]}};return M}};t.exports=i},{"../../is":83}],15:! [function(e,t,r){"use strict";var n=e("../define"),i={animate:! n.animat e(),animation:n.animation(),animated:n.animated(),clearQueue:n.clearQueue(),delay:n.delay(),delayAnimation:n.delayAnimation(),stop:n.stop()};t.exports=i},{"../define":44}],16:[function(e,t,r){"use strict";var n=e("../util"),i={classes:function(e){e=e.match(/\S+/g)||[];for(var t=this,r=[],i={},a=0;a<e.length;a++){var o=e[a];i[o]=!0}for(var s=0;s<t.length;s++){for(var l=t[s],u=l._private,c=u.classes,d=!1,a=0;a<e.length;a++){var o=e[a],h=c[o];if(!h){d=!0;break}}if(!d)for(var e=Object.keys(c),a=0;a<e.length;a++){var p=e[a],h=c[p],f=i[p];if(h&&!f){d=!0;break}}d&&(u.classes=n.copy(i),r.push(l))}return r.length>0&&this.spawn(r).updateStyle().trigger("class"),t},addClass:function(e){return this.toggleClass(e,!0)},hasClass:function(e){var t=this[0];return!(null==t||!t._private.classes[e])},toggleClass:function(e,t){for(var r=e.match(/\S+/g)||[],n=this,i=[],a=0,o=n.length;o>a;a++)for(var s=n[a],l=!1,u=0;u<r.length;u++){var c=r[u],d=s._private.classes,h=d[c],p=t||void 0===t&&!h;p?(d[c]! =!0,h||l||(i.push(s),l=!0)):(d[c]=!1,h&&!l&&(i.push(s),l=!0))}return i.length>0&&this.spawn(i).updateStyle().trigger("class"),n},removeClass:function(e){return this.toggleClass(e,!1)},flashClass:function(e,t){var r=this;if(null==t)t=250;else if(0===t)return r;return r.addClass(e),setTimeout(function(){r.removeClass(e)},t),r}};t.exports=i},{"../util":100}],17:[function(e,t,r){"use strict";var n={allAre:function(e){return this.filter(e).length===this.length},is:function(e){return this.filter(e).length>0},some:function(e,t){for(var r=0;r<this.length;r++){var n=t?e.apply(t,[this[r],r,this]):e(this[r],r,this);if(n)return!0}return!1},every:function(e,t){for(var r=0;r<this.length;r++){var n=t?e.apply(t,[this[r],r,this]):e(this[r],r,this);if(!n)return!1}return!0},same:function(e){return e=this.cy().collection(e),this.length!==e.length?!1:this.intersect(e).length===this.length},anySame:function(e){return e=this.cy().collection(e),this.intersect(e).length>0},allAreNeighbors:function(! e){return e=this.cy().collection(e),this.neighborhood().inters! ect(e).l ength===e.length}};n.allAreNeighbours=n.allAreNeighbors,t.exports=n},{}],18:[function(e,t,r){"use strict";var n={parent:function(e){for(var t=[],r=this._private.cy,n=0;n<this.length;n++){var i=this[n],a=r.getElementById(i._private.data.parent);a.size()>0&&t.push(a)}return this.spawn(t,{unique:!0}).filter(e)},parents:function(e){for(var t=[],r=this.parent();r.nonempty();){for(var n=0;n<r.length;n++){var i=r[n];t.push(i)}r=r.parent()}return this.spawn(t,{unique:!0}).filter(e)},commonAncestors:function(e){for(var t,r=0;r<this.length;r++){var n=this[r],i=n.parents();t=t||i,t=t.intersect(i)}return t.filter(e)},orphans:function(e){return this.stdFilter(function(e){return e.isNode()&&e.parent().empty()}).filter(e)},nonorphans:function(e){return this.stdFilter(function(e){return e.isNode()&&e.parent().nonempty()}).filter(e)},children:function(e){for(var t=[],r=0;r<this.length;r++){var n=this[r];t=t.concat(n._private.children)}return this.spawn(t,{unique:!0}).filter(e)},siblings:func! tion(e){return this.parent().children().not(this).filter(e)},isParent:function(){var e=this[0];return e?0!==e._private.children.length:void 0},isChild:function(){var e=this[0];return e?void 0!==e._private.data.parent&&0!==e.parent().length:void 0},descendants:function(e){function t(e){for(var n=0;n<e.length;n++){var i=e[n];r.push(i),i.children().nonempty()&&t(i.children())}}var r=[];return t(this.children()),this.spawn(r,{unique:!0}).filter(e)}};n.ancestors=n.parents,t.exports=n},{}],19:[function(e,t,r){"use strict";var n,i,a=e("../define");n=i={data:a.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:a.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:a.data({field:"scratch",bindingEvent:! "scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratc! h",setti ngTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:a.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:a.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:a.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var e=this[0];return e?e._private.data.id:void 0}},n.attr=n.data,n.removeAttr=n.removeData,t.exports=i},{"../define":44}],20:[function(e,t,r){"use strict";function n(e){return function(t){var r=this;if(void 0===t&&(t=!0),0!==r.length&&r.isNode()&&!r.removed()){for(var n=0,i=r[0],a=i._private.edges,o=0;o<a.length;o++){var s=a[o];!t&&s.isLoop()||(n+=e(i,s))}return n}}}function i(e,t){return function(r){for(var n,i=this.nodes(),a=0;a<i.length;a++){var o=i[a],s=o[e](r);void 0===s||void 0!==n&&!t(s,n)||(n=s)}return n}}var a=e("../util"),o={};a.extend(o,{degree:n(function(e,t){return t.source().same(t.target(! ))?2:1}),indegree:n(function(e,t){return t.target().same(e)?1:0}),outdegree:n(function(e,t){return t.source().same(e)?1:0})}),a.extend(o,{minDegree:i("degree",function(e,t){return t>e}),maxDegree:i("degree",function(e,t){return e>t}),minIndegree:i("indegree",function(e,t){return t>e}),maxIndegree:i("indegree",function(e,t){return e>t}),minOutdegree:i("outdegree",function(e,t){return t>e}),maxOutdegree:i("outdegree",function(e,t){return e>t})}),a.extend(o,{totalDegree:function(e){for(var t=0,r=this.nodes(),n=0;n<r.length;n++)t+=r[n].degree(e);return t}}),t.exports=o},{"../util":100}],21:[function(e,t,r){"use strict";var n,i,a=e("../define"),o=e("../is"),s=e("../util"),l=e("../math");n=i={position:a.data({field:"position",bindingEvent:"position",allowBinding:!0,allowSetting:!0,settingEvent:"position",settingTriggersEvent:!0,triggerFnName:"rtrigger",allowGetting:!0,validKeys:["x","y"],onSet:function(e){var t=e.updateCompoundBounds();t.rtrigger("position")},canSet:function(e){r! eturn!e.locked()&&!e.isParent()}}),silentPosition:a.data({fiel! d:"posit ion",bindingEvent:"position",allowBinding:!1,allowSetting:!0,settingEvent:"position",settingTriggersEvent:!1,triggerFnName:"trigger",allowGetting:!0,validKeys:["x","y"],onSet:function(e){e.updateCompoundBounds()},canSet:function(e){return!e.locked()&&!e.isParent()}}),positions:function(e,t){if(o.plainObject(e))this.position(e);else if(o.fn(e)){for(var r=e,n=0;n<this.length;n++){var i=this[n],e=r.apply(i,[n,i]);if(e&&!i.locked()&&!i.isParent()){var a=i._private.position;a.x=e.x,a.y=e.y}}var s=this.updateCompoundBounds(),l=s.length>0?this.add(s):this;t?l.trigger("position"):l.rtrigger("position")}return this},silentPositions:function(e){return this.positions(e,!0)},renderedPosition:function(e,t){var r=this[0],n=this.cy(),i=n.zoom(),a=n.pan(),s=o.plainObject(e)?e:void 0,l=void 0!==s||void 0!==t&&o.string(e);if(r&&r.isNode()){if(!l){var u=r._private.position;return s={x:u.x*i+a.x,y:u.y*i+a.y},void 0===e?s:s[e]}for(var c=0;c<this.length;c++){var r=this[c];void 0!==t?r._private.po! sition[e]=(t-a[e])/i:void 0!==s&&(r._private.position={x:(s.x-a.x)/i,y:(s.y-a.y)/i})}this.rtrigger("position")}else if(!l)return;return this},relativePosition:function(e,t){var r=this[0],n=this.cy(),i=o.plainObject(e)?e:void 0,a=void 0!==i||void 0!==t&&o.string(e),s=n.hasCompoundNodes();if(r&&r.isNode()){if(!a){var l=r._private.position,u=s?r.parent():null,c=u&&u.length>0,d=c;c&&(u=u[0]);var h=d?u._private.position:{x:0,y:0};return i={x:l.x-h.x,y:l.y-h.y},void 0===e?i:i[e]}for(var p=0;p<this.length;p++){var r=this[p],u=s?r.parent():null,c=u&&u.length>0,d=c;c&&(u=u[0]);var h=d?u._private.position:{x:0,y:0};void 0!==t?r._private.position[e]=t+h[e]:void 0!==i&&(r._private.position={x:i.x+h.x,y:i.y+h.y})}this.rtrigger("position")}else if(!a)return;return this},renderedBoundingBox:function(e){var t=this.boundingBox(e),r=this.cy(),n=r.zoom(),i=r.pan(),a=t.x1*n+i.x,o=t.x2*n+i.x,s=t.y1*n+i.y,l=t.y2*n+i.y;return{x1:a,x2:o,y1:s,y2:l,w:o-a,h:l-s}},updateCompoundBounds:function(){funct! ion e(e){if(e.isParent()){var t=e._private,n=e.children(),i="i! nclude"= ==e.pstyle("compound-sizing-wrt-labels").value,a=n.boundingBox({includeLabels:i,includeShadows:!1,includeOverlays:!1,useCache:!1}),o={top:e.pstyle("padding-top").pfValue,bottom:e.pstyle("padding-bottom").pfValue,left:e.pstyle("padding-left").pfValue,right:e.pstyle("padding-right").pfValue},s=t.position;t.autoWidth=a.w,s.x=(a.x1+a.x2-o.left+o.right)/2,t.autoHeight=a.h,s.y=(a.y1+a.y2-o.top+o.bottom)/2,r.push(e)}}var t=this.cy();if(!t.styleEnabled()||!t.hasCompoundNodes())return t.collection();for(var r=[],n=this;n.nonempty();){for(var i=0;i<n.length;i++){var a=n[i];e(a)}n=n.parent()}return this.spawn(r)}};var u=function(e){return e===1/0||e===-(1/0)?0:e},c=function(e,t,r,n,i){n-t!==0&&i-r!==0&&(e.x1=t<e.x1?t:e.x1,e.x2=n>e.x2?n:e.x2,e.y1=r<e.y1?r:e.y1,e.y2=i>e.y2?i:e.y2)},d=function(e,t){return c(e,t.x1,t.y1,t.x2,t.y2)},h=function(e,t,r){return s.getPrefixedProperty(e,t,r)},p=function(e,t,r,n){var i,a,o=t._private,s=o.rstyle,l=s.arrowWidth/2,u=t.pstyle(r+"-arrow-shape").value;"! none"!==u&&("source"===r?(i=s.srcX,a=s.srcY):"target"===r?(i=s.tgtX,a=s.tgtY):(i=s.midX,a=s.midY),c(e,i-l,a-l,i+l,a+l))},f=function(e,t,r,n){var i;i=r?r+"-":"";var a=t._private,o=a.rstyle,s=t.pstyle(i+"label").strValue;if(s){var l,u,d,p,f=t.pstyle("text-halign"),v=t.pstyle("text-valign"),g=h(o,"labelWidth",r),y=h(o,"labelHeight",r),m=h(o,"labelX",r),b=h(o,"labelY",r),x=t.pstyle(i+"text-margin-x").pfValue,w=t.pstyle(i+"text-margin-y").pfValue,E=t.isEdge(),_=t.pstyle(i+"text-rotation"),P=t.pstyle("text-shadow-blur").pfValue/2,S=t.pstyle("text-shadow-offset-x").pfValue,k=t.pstyle("text-shadow-offset-y").pfValue,T=t.pstyle("text-shadow-opacity").value,D=t.pstyle("text-outline-width").pfValue,C=t.pstyle("text-border-width").pfValue,M=C/2,N=y,B=g,z=B/2,I=N/2;if(E)l=m-z,u=m+z,d=b-I,p=b+I;else{switch(f.value){case"left":l=m-B,u=m;break;case"center":l=m-z,u=m+z;break;case"right":l=m,u=m+B}switch(v.value){case"top":d=b-N,p=b;break;case"center":d=b-I,p=b+I;break;case"bottom":d=b,p=b+N! }}var L=E&&"autorotate"===_.strValue,O=null!=_.pfValue&&0!==_.! pfValue; if(L||O){var A=L?h(a.rstyle,"labelAngle",r):_.pfValue,R=Math.cos(A),q=Math.sin(A),V=function(e,t){return e-=m,t-=b,{x:e*R-t*q+m,y:e*q+t*R+b}},F=V(l,d),j=V(l,p),X=V(u,d),Y=V(u,p);l=Math.min(F.x,j.x,X.x,Y.x),u=Math.max(F.x,j.x,X.x,Y.x),d=Math.min(F.y,j.y,X.y,Y.y),p=Math.max(F.y,j.y,X.y,Y.y)}l+=x-Math.max(D,M),u+=x+Math.max(D,M),d+=w-Math.max(D,M),p+=w+Math.max(D,M),c(e,l,d,u,p),n.includeShadows&&T>0&&(l+=-P+S,u+=+P+S,d+=-P+k,p+=+P+k,c(e,l,d,u,p))}return e},v=function(e,t){var r,n,i,a,o,s,d=e._private.cy,h=d._private,v=h.styleEnabled,g={x1:1/0,y1:1/0,x2:-(1/0),y2:-(1/0)},y=e._private,m=v?e.pstyle("display").value:"element",b=e.isNode(),x=e.isEdge(),w="none"!==m;if(w){var E=0,_=0;v&&t.includeOverlays&&(E=e.pstyle("overlay-opacity").value,0!==E&&(_=e.pstyle("overlay-padding").value));var P=0,S=0;if(v&&(P=e.pstyle("width").pfValue,S=P/2),b&&t.includeNodes){var k=y.position;o=k.x,s=k.y;var P=e.outerWidth(),T=P/2,D=e.outerHeight(),C=D/2;r=o-T-_,n=o+T+_,i=s-C-_,a=s+C+_,c(g,r,i,n,a)}e! lse if(x&&t.includeEdges){var M=y.rstyle||{};if(v&&(r=Math.min(M.srcX,M.midX,M.tgtX),n=Math.max(M.srcX,M.midX,M.tgtX),i=Math.min(M.srcY,M.midY,M.tgtY),a=Math.max(M.srcY,M.midY,M.tgtY),r-=S,n+=S,i-=S,a+=S,c(g,r,i,n,a)),v&&"haystack"===e.pstyle("curve-style").strValue){var N=M.haystackPts;if(r=N[0].x,i=N[0].y,n=N[1].x,a=N[1].y,r>n){var B=r;r=n,n=B}if(i>a){var B=i;i=a,a=B}c(g,r-S,i-S,n+S,a+S)}else{for(var z=M.bezierPts||M.linePts||[],I=0;I<z.length;I++){var L=z[I];r=L.x-S,n=L.x+S,i=L.y-S,a=L.y+S,c(g,r,i,n,a)}if(0===z.length){var O=y.source,A=O._private,R=A.position,q=y.target,V=q._private,F=V.position;if(r=R.x,n=F.x,i=R.y,a=F.y,r>n){var B=r;r=n,n=B}if(i>a){var B=i;i=a,a=B}r-=S,n+=S,i-=S,a+=S,c(g,r,i,n,a)}}}if(v){if(r=g.x1,n=g.x2,i=g.y1,a=g.y2,t.includeShadows&&e.pstyle("shadow-opacity").value>0){var j=e.pstyle("shadow-blur").pfValue/2,X=e.pstyle("shadow-offset-x").pfValue,Y=e.pstyle("shadow-offset-y").pfValue;c(g,r-j+X,i-j+Y,n+j+X,a+j+Y)}c(g,r-_,i-_,n+_,a+_)}v&&t.includeEdges&! &x&&(p(g,e,"mid-source",t),p(g,e,"mid-target",t),p(g,e,"source! ",t),p(g ,e,"target",t)),v&&t.includeLabels&&(f(g,e,null,t),x&&(f(g,e,"source",t),f(g,e,"target",t)))}return g.x1=u(g.x1),g.y1=u(g.y1),g.x2=u(g.x2),g.y2=u(g.y2),g.w=u(g.x2-g.x1),g.h=u(g.y2-g.y1),g.w>0&&g.h>0&&w&&l.expandBoundingBox(g,1),g},g=function(e){return e?"t":"f"},y=function(e){var t="";return t+=g(e.incudeNodes),t+=g(e.includeEdges),t+=g(e.includeLabels),t+=g(e.includeShadows),t+=g(e.includeOverlays)},m=function(e,t){var r,n=e._private,i=e.cy().headless(),a=t===b?x:y(t);return t.useCache&&!i&&n.bbCache&&n.bbCache[a]?r=n.bbCache[a]:(r=v(e,t),i||(n.bbCache=n.bbCache||{},n.bbCache[a]=r)),r},b={includeNodes:!0,includeEdges:!0,includeLabels:!0,includeShadows:!0,includeOverlays:!0,useCache:!0},x=y(b);i.recalculateRenderedStyle=function(e){var t=this.cy(),r=t.renderer(),n=t.styleEnabled();return r&&n&&r.recalculateRenderedStyle(this,e),this},i.boundingBox=function(e){if(1===this.length&&this[0]._private.bbCache&&(void 0===e||void 0===e.useCache||e.useCache===!0))return void 0===e&&(! e=b),m(this[0],e);var t={x1:1/0,y1:1/0,x2:-(1/0),y2:-(1/0)};e=e||s.staticEmptyObject();var r={includeNodes:s["default"](e.includeNodes,b.includeNodes),includeEdges:s["default"](e.includeEdges,b.includeEdges),includeLabels:s["default"](e.includeLabels,b.includeLabels),includeShadows:s["default"](e.includeShadows,b.includeShadows), +includeOverlays:s["default"](e.includeOverlays,b.includeOverlays),useCache:s["default"](e.useCache,b.useCache)},n=this,i=n.cy(),a=i.styleEnabled();a&&this.recalculateRenderedStyle(r.useCache);for(var o=0;o<n.length;o++){var l=n[o];a&&l.isEdge()&&"bezier"===l.pstyle("curve-style").strValue&&l.parallelEdges().recalculateRenderedStyle(r.useCache),d(t,m(l,r))}return t.x1=u(t.x1),t.y1=u(t.y1),t.x2=u(t.x2),t.y2=u(t.y2),t.w=u(t.x2-t.x1),t.h=u(t.y2-t.y1),t};var w=function(e){e.uppercaseName=s.capitalize(e.name),e.autoName="auto"+e.uppercaseName,e.labelName="label"+e.uppercaseName,e.outerName="outer"+e.uppercaseName,e.uppercaseOuterName=s.capitalize(e.outerName),n[e.name]=function(){var t=this[0],r=t._private,n=r.cy,i=n._private.styleEnabled;if(t){if(!i)return 1;if(t.isParent())return r[e.autoName]||0;var a=t.pstyle(e.name);switch(a.strValue){case"label":return r.rstyle[e.labelName]||0;default:return a.pfValue}}},n["outer"+e.uppercaseName]=function(){var t=this[0],r=t._private,n=r.c! y,i=n._private.styleEnabled;if(t){if(i){var a=t[e.name](),o=t.pstyle("border-width").pfValue,s=t.pstyle(e.paddings[0]).pfValue+t.pstyle(e.paddings[1]).pfValue;return a+o+s}return 1}},n["rendered"+e.uppercaseName]=function(){var t=this[0];if(t){var r=t[e.name]();return r*this.cy().zoom()}},n["rendered"+e.uppercaseOuterName]=function(){var t=this[0];if(t){var r=t[e.outerName]();return r*this.cy().zoom()}}};w({name:"width",paddings:["padding-left","padding-right"]}),w({name:"height",paddings:["padding-top","padding-bottom"]}),n.modelPosition=n.point=n.position,n.modelPositions=n.points=n.positions,n.renderedPoint=n.renderedPosition,n.relativePoint=n.relativePosition,n.boundingbox=n.boundingBox,n.renderedBoundingbox=n.renderedBoundingBox,t.exports=i},{"../define":44,"../is":83,"../math":85,"../util":100}],22:[function(e,t,r){"use strict";var n=e("../util"),i=e("../is"),a=function(e,t,r){var a=this;if(r=!(void 0!==r&&!r),void 0===e||void 0===t||!i.core(e))return void n.error("An! element must have a core reference and parameters set");var o! =t.group ;if(null==o&&(o=t.data&&null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"!==o&&"edges"!==o)return void n.error("An element must be of type `nodes` or `edges`; you specified `"+o+"`");if(this.length=1,this[0]=this,this._private={cy:e,single:!0,data:t.data||{},position:t.position||{},autoWidth:void 0,autoHeight:void 0,listeners:[],group:o,style:{},rstyle:{},styleCxts:[],removed:!0,selected:!!t.selected,selectable:void 0===t.selectable?!0:!!t.selectable,locked:!!t.locked,grabbed:!1,grabbable:void 0===t.grabbable?!0:!!t.grabbable,active:!1,classes:{},animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[],traversalCache:{}},t.renderedPosition){var s=t.renderedPosition,l=e.pan(),u=e.zoom();this._private.position={x:(s.x-l.x)/u,y:(s.y-l.y)/u}}if(i.string(t.classes))for(var c=t.classes.split(/\s+/),d=0,h=c.length;h>d;d++){var p=c[d];p&&""!==p&&(a._private.classes[p]=!0)}(t.style||t.css)&&e.style().applyBypass(this,t.style||t.css),(void! 0===r||r)&&this.restore()};t.exports=a},{"../is":83,"../util":100}],23:[function(e,t,r){"use strict";var n=e("../define"),i={on:n.on(),one:n.on({unbindSelfOnTrigger:!0}),once:n.on({unbindAllBindersOnTrigger:!0}),off:n.off(),trigger:n.trigger(),rtrigger:function(e,t){return 0!==this.length?(this.cy().notify({type:e,eles:this}),this.trigger(e,t),this):void 0}};n.eventAliasesOn(i),t.exports=i},{"../define":44}],24:[function(e,t,r){"use strict";var n=e("../is"),i=e("../selector"),a={nodes:function(e){return this.filter(function(e,t){return t.isNode()}).filter(e)},edges:function(e){return this.filter(function(e,t){return t.isEdge()}).filter(e)},filter:function(e){if(void 0===e)return this;if(n.string(e)||n.elementOrCollection(e))return i(e).filter(this);if(n.fn(e)){for(var t=[],r=0;r<this.length;r++){var a=this[r];e.apply(a,[r,a])&&t.push(a)}return this.spawn(t)}return this.spawn()},not:function(e){if(e){n.string(e)&&(e=this.filter(e));for(var t=[],r=0;r<this.length;r++){var i=! this[r],a=e._private.ids[i.id()];a||t.push(i)}return this.spaw! n(t)}ret urn this},absoluteComplement:function(){var e=this._private.cy;return e.mutableElements().not(this)},intersect:function(e){if(n.string(e)){var t=e;return this.filter(t)}for(var r=[],i=this,a=e,o=this.length<e.length,s=o?a._private.ids:i._private.ids,l=o?i:a,u=0;u<l.length;u++){var c=l[u]._private.data.id,d=s[c];d&&r.push(d)}return this.spawn(r)},xor:function(e){var t=this._private.cy;n.string(e)&&(e=t.$(e));var r=[],i=this,a=e,o=function(e,t){for(var n=0;n<e.length;n++){var i=e[n],a=i._private.data.id,o=t._private.ids[a];o||r.push(i)}};return o(i,a),o(a,i),this.spawn(r)},diff:function(e){var t=this._private.cy;n.string(e)&&(e=t.$(e));var r=[],i=[],a=[],o=this,s=e,l=function(e,t,r){for(var n=0;n<e.length;n++){var i=e[n],o=i._private.data.id,s=t._private.ids[o];s?a.push(i):r.push(i)}};return l(o,s,r),l(s,o,i),{left:this.spawn(r,{unique:!0}),right:this.spawn(i,{unique:!0}),both:this.spawn(a,{unique:!0})}},add:function(e){var t=this._private.cy;if(!e)return this;if(n.string(e)){! var r=e;e=t.mutableElements().filter(r)}for(var i=[],a=0;a<this.length;a++)i.push(this[a]);for(var a=0;a<e.length;a++){var o=!this._private.ids[e[a].id()];o&&i.push(e[a])}return this.spawn(i)},merge:function(e){var t=this._private,r=t.cy;if(!e)return this;if(e&&n.string(e)){var i=e;e=r.mutableElements().filter(i)}for(var a=0;a<e.length;a++){var o=e[a],s=o._private.data.id,l=!t.ids[s];if(l){var u=this.length++;this[u]=o,t.ids[s]=o,t.indexes[s]=u}else{var u=t.indexes[s];this[u]=o,t.ids[s]=o}}return this},unmergeOne:function(e){e=e[0];var t=this._private,r=e._private.data.id,n=t.indexes[r];if(null==n)return this;this[n]=void 0,t.ids[r]=void 0,t.indexes[r]=void 0;var i=n===this.length-1;if(this.length>1&&!i){var a=this.length-1,o=this[a],s=o._private.data.id;this[a]=void 0,this[n]=o,t.indexes[s]=n}return this.length--,this},unmerge:function(e){var t=this._private.cy;if(!e)return this;if(e&&n.string(e)){var r=e;e=t.mutableElements().filter(r)}for(var i=0;i<e.length;i++)this.unme! rgeOne(e[i]);return this},map:function(e,t){for(var r=[],n=thi! s,i=0;i< n.length;i++){var a=n[i],o=t?e.apply(t,[a,i,n]):e(a,i,n);r.push(o)}return r},stdFilter:function(e,t){for(var r=[],n=this,i=0;i<n.length;i++){var a=n[i],o=t?e.apply(t,[a,i,n]):e(a,i,n);o&&r.push(a)}return this.spawn(r)},max:function(e,t){for(var r,n=-(1/0),i=this,a=0;a<i.length;a++){var o=i[a],s=t?e.apply(t,[o,a,i]):e(o,a,i);s>n&&(n=s,r=o)}return{value:n,ele:r}},min:function(e,t){for(var r,n=1/0,i=this,a=0;a<i.length;a++){var o=i[a],s=t?e.apply(t,[o,a,i]):e(o,a,i);n>s&&(n=s,r=o)}return{value:n,ele:r}}},o=a;o.u=o["|"]=o["+"]=o.union=o.or=o.add,o["\\"]=o["!"]=o["-"]=o.difference=o.relativeComplement=o.subtract=o.not,o.n=o["&"]=o["."]=o.and=o.intersection=o.intersect,o["^"]=o["(+)"]=o["(-)"]=o.symmetricDifference=o.symdiff=o.xor,o.fnFilter=o.filterFn=o.stdFilter,o.complement=o.abscomp=o.absoluteComplement,t.exports=a},{"../is":83,"../selector":87}],25:[function(e,t,r){"use strict";var n={isNode:function(){return"nodes"===this.group()},isEdge:function(){return"edges"===this.group! ()},isLoop:function(){return this.isEdge()&&this.source().id()===this.target().id()},isSimple:function(){return this.isEdge()&&this.source().id()!==this.target().id()},group:function(){var e=this[0];return e?e._private.group:void 0}};t.exports=n},{}],26:[function(e,t,r){"use strict";var n=e("../util"),i=e("../is"),a=e("./element"),o={generate:function(e,t,r){for(var i=null!=r?r:n.uuid();e.hasElementWithId(i);)i=n.uuid();return i}},s=function(e,t,r){if(void 0===e||!i.core(e))return void n.error("A collection must have a reference to the core");var s={},l={},u=!1;if(t){if(t.length>0&&i.plainObject(t[0])&&!i.element(t[0])){u=!0;for(var c=[],d={},h=0,p=t.length;p>h;h++){var f=t[h];null==f.data&&(f.data={});var v=f.data;if(null==v.id)v.id=o.generate(e,f);else if(e.hasElementWithId(v.id)||d[v.id])continue;var g=new a(e,f,!1);c.push(g),d[v.id]=!0}t=c}}else t=[];this.length=0;for(var h=0,p=t.length;p>h;h++){var y=t[h];if(y){var m=y._private.data.id;(!r||r.unique&&!s[m])&&(s[m]=y,l[! m]=this.length,this[this.length]=y,this.length++)}}this._priva! te={cy:e ,ids:s,indexes:l},u&&this.restore()},l=a.prototype=s.prototype;l.instanceString=function(){return"collection"},l.spawn=function(e,t,r){return i.core(e)||(r=t,t=e,e=this.cy()),new s(e,t,r)},l.spawnSelf=function(){return this.spawn(this)},l.cy=function(){return this._private.cy},l.element=function(){return this[0]},l.collection=function(){return i.collection(this)?this:new s(this._private.cy,[this])},l.unique=function(){return new s(this._private.cy,this,{unique:!0})},l.hasElementWithId=function(e){return!!this._private.ids[e]},l.getElementById=function(e){var t=this._private.cy,r=this._private.ids[e];return r?r:new s(t)},l.poolIndex=function(){var e=this._private.cy,t=e._private.elements,r=this._private.data.id;return t._private.indexes[r]},l.json=function(e){var t=this.element(),r=this.cy();if(null==t&&e)return this;if(null!=t){var a=t._private;if(i.plainObject(e)){r.startBatch(),e.data&&t.data(e.data),e.position&&t.position(e.position);var o=function(r,n,i){var o=e[r];null!! =o&&o!==a[r]&&(o?t[n]():t[i]())};return o("removed","remove","restore"),o("selected","select","unselect"),o("selectable","selectify","unselectify"),o("locked","lock","unlock"),o("grabbable","grabify","ungrabify"),null!=e.classes&&t.classes(e.classes),r.endBatch(),this}if(void 0===e){var s={data:n.copy(a.data),position:n.copy(a.position),group:a.group,removed:a.removed,selected:a.selected,selectable:a.selectable,locked:a.locked,grabbable:a.grabbable,classes:null};return s.classes=Object.keys(a.classes).filter(function(e){return a.classes[e]}).join(" "),s}}},l.jsons=function(){for(var e=[],t=0;t<this.length;t++){var r=this[t],n=r.json();e.push(n)}return e},l.clone=function(){for(var e=this.cy(),t=[],r=0;r<this.length;r++){var n=this[r],i=n.json(),o=new a(e,i,!1);t.push(o)}return new s(e,t)},l.copy=l.clone,l.restore=function(e){var t=this,r=t.cy(),a=r._private;void 0===e&&(e=!0);for(var l,u=[],c=[],d=0,h=t.length;h>d;d++){var p=t[d];p.removed()&&(p.isNode()?u.push(p):c.push(p)! )}l=u.concat(c);var d,f=function(){l.splice(d,1),d--};for(d=0;! d<l.leng th;d++){var p=l[d],v=p._private,g=v.data;if(v.traversalCache=null,void 0===g.id)g.id=o.generate(r,p);else if(i.number(g.id))g.id=""+g.id;else{if(i.emptyString(g.id)||!i.string(g.id)){n.error("Can not create element with invalid string ID `"+g.id+"`"),f();continue}if(r.hasElementWithId(g.id)){n.error("Can not create second element with ID `"+g.id+"`"),f();continue}}var y=g.id;if(p.isNode()){var m=p,b=v.position;null==b.x&&(b.x=0),null==b.y&&(b.y=0)}if(p.isEdge()){for(var x=p,w=["source","target"],E=w.length,_=!1,P=0;E>P;P++){var S=w[P],k=g[S];i.number(k)&&(k=g[S]=""+g[S]),null==k||""===k?(n.error("Can not create edge `"+y+"` with unspecified "+S),_=!0):r.hasElementWithId(k)||(n.error("Can not create edge `"+y+"` with nonexistant "+S+" `"+k+"`"),_=!0)}if(_){f();continue}var T=r.getElementById(g.source),D=r.getElementById(g.target);T._private.edges.push(x),D._private.edges.push(x),x._private.source=T,x._private.target=D}v.ids={},v.ids[y]=p,v.indexes={},v.indexes[y]=p,v.removed=! !1,r.addToPool(p)}for(var d=0;d<u.length;d++){var m=u[d],g=m._private.data;i.number(g.parent)&&(g.parent=""+g.parent);var C=g.parent,M=null!=C;if(M){var N=r.getElementById(C);if(N.empty())g.parent=void 0;else{for(var B=!1,z=N;!z.empty();){if(m.same(z)){B=!0,g.parent=void 0;break}z=z.parent()}B||(N[0]._private.children.push(m),m._private.parent=N[0],a.hasCompoundNodes=!0)}}}if(l.length>0){for(var I=new s(r,l),d=0;d<I.length;d++){var p=I[d];if(!p.isNode()){for(var L=p.parallelEdges(),P=0;P<L.length;P++)L[P]._private.traversalCache=null;p.source()[0]._private.traversalCache=null,p.target()[0]._private.traversalCache=null}}var O;O=a.hasCompoundNodes?I.add(I.connectedNodes()).add(I.parent()):I,O.updateStyle(e),e?I.rtrigger("add"):I.trigger("add")}return t},l.removed=function(){var e=this[0];return e&&e._private.removed},l.inside=function(){var e=this[0];return e&&!e._private.removed},l.remove=function(e){function t(e){for(var t=e._private.edges,r=0;r<t.length;r++)i(t[r])}functio! n r(e){for(var t=e._private.children,r=0;r<t.length;r++)i(t[r]! )}functi on i(e){var n=h[e.id()];n||(h[e.id()]=!0,e.isNode()?(d.push(e),t(e),r(e)):d.unshift(e))}function a(e,t){var r=e._private.edges;n.removeFromArray(r,t),e._private.traversalCache=null}function o(e){for(var t=e.parallelEdges(),r=0;r<t.length;r++)t[r]._private.traversalCache=null}function l(e,t){t=t[0],e=e[0];var r=e._private.children,i=e.id();n.removeFromArray(r,t),y.ids[i]||(y.ids[i]=!0,y.push(e))}var u=this,c=[],d=[],h={},p=u._private.cy;void 0===e&&(e=!0);for(var f=0,v=u.length;v>f;f++){var g=u[f];i(g)}var y=[];y.ids={},p.removeFromPool(d);for(var f=0;f<d.length;f++){var g=d[f];if(g._private.removed=!0,c.push(g),g.isEdge()){var m=g.source()[0],b=g.target()[0];a(m,g),a(b,g),o(g)}else{var x=g.parent();0!==x.length&&l(x,g)}}var w=p._private.elements;p._private.hasCompoundNodes=!1;for(var f=0;f<w.length;f++){var g=w[f];if(g.isParent()){p._private.hasCompoundNodes=!0;break}}var E=new s(this.cy(),c);E.size()>0&&(e&&this.cy().notify({type:"remove",eles:E}),E.trigger("remove"));for(v! ar f=0;f<y.length;f++){var g=y[f];g.removed()||g.updateStyle()}return new s(p,c)},l.move=function(e){var t=this._private.cy;if(void 0!==e.source||void 0!==e.target){var r=e.source,n=e.target,i=t.hasElementWithId(r),a=t.hasElementWithId(n);if(i||a){var o=this.jsons();this.remove();for(var s=0;s<o.length;s++){var l=o[s],u=this[s];"edges"===l.group&&(i&&(l.data.source=r),a&&(l.data.target=n),l.scratch=u._private.scratch)}return t.add(o)}}else if(void 0!==e.parent){var c=e.parent,d=null===c||t.hasElementWithId(c);if(d){var o=this.jsons(),h=this.descendants(),p=h.union(h.union(this).connectedEdges());this.remove();for(var s=0;s<this.length;s++){var l=o[s],u=this[s];"nodes"===l.group&&(l.data.parent=null===c?void 0:c,l.scratch=u._private.scratch)}return t.add(o).union(p.restore())}}return this},[e("./algorithms"),e("./animation"),e("./class"),e("./comparators"),e("./compounds"),e("./data"),e("./degree"),e("./dimensions"),e("./events"),e("./filter"),e("./group"),e("./index"),e("./! iteration"),e("./layout"),e("./style"),e("./switch-functions")! ,e("./tr aversing")].forEach(function(e){n.extend(l,e)}),t.exports=s},{"../is":83,"../util":100,"./algorithms":11,"./animation":15,"./class":16,"./comparators":17,"./compounds":18,"./data":19,"./degree":20,"./dimensions":21,"./element":22,"./events":23,"./filter":24,"./group":25,"./index":26,"./iteration":27,"./layout":28,"./style":29,"./switch-functions":30,"./traversing":31}],27:[function(e,t,r){"use strict";var n=e("../is"),i=e("./zsort"),a={each:function(e){if(n.fn(e))for(var t=0;t<this.length;t++){var r=this[t],i=e.apply(r,[t,r]);if(i===!1)break}return this},forEach:function(e,t){if(n.fn(e))for(var r=0;r<this.length;r++){var i=this[r],a=t?e.apply(t,[i,r,this]):e(i,r,this);if(a===!1)break}return this},toArray:function(){for(var e=[],t=0;t<this.length;t++)e.push(this[t]);return e},slice:function(e,t){var r=[],n=this.length;null==t&&(t=n),null==e&&(e=0),0>e&&(e=n+e),0>t&&(t=n+t);for(var i=e;i>=0&&t>i&&n>i;i++)r.push(this[i]);return this.spawn(r)},size:function(){return this.length}! ,eq:function(e){return this[e]||this.spawn()},first:function(){return this[0]||this.spawn()},last:function(){return this[this.length-1]||this.spawn()},empty:function(){return 0===this.length},nonempty:function(){return!this.empty()},sort:function(e){if(!n.fn(e))return this;var t=this.toArray().sort(e);return this.spawn(t)},sortByZIndex:function(){return this.sort(i)},zDepth:function(){var e=this[0];if(e){var t=e._private,r=t.group;if("nodes"===r){var n=t.data.parent?e.parents().size():0;return e.isParent()?n:Number.MAX_VALUE}var i=t.source,a=t.target,o=i.zDepth(),s=a.zDepth();return Math.max(o,s,0)}}};t.exports=a},{"../is":83,"./zsort":32}],28:[function(e,t,r){"use strict";var n=e("../is"),i=e("../util"),a=e("../promise"),o={layoutPositions:function(e,t,r){var i=this.nodes(),o=this.cy();if(e.trigger({type:"layoutstart",layout:e}),e.animations=[],t.animate){for(var s=0;s<i.length;s++){var l=i[s],u=r.call(l,s,l),c=l.position();n.number(c.x)&&n.number(c.y)||l.silentPosition({x! :0,y:0});var d=l.animation({position:u,duration:t.animationDur! ation,ea sing:t.animationEasing});e.animations.push(d),d.play()}var h;o.on("step.*",h=function(){t.fit&&o.fit(t.eles,t.padding)}),e.one("layoutstop",function(){o.off("step.*",h)}),e.one("layoutready",t.ready),e.trigger({type:"layoutready",layout:e}),a.all(e.animations.map(function(e){return e.promise()})).then(function(){o.off("step.*",h),null!=t.zoom&&o.zoom(t.zoom),t.pan&&o.pan(t.pan),t.fit&&o.fit(t.eles,t.padding),e.one("layoutstop",t.stop),e.trigger({type:"layoutstop",layout:e})})}else i.positions(r),t.fit&&o.fit(t.eles,t.padding),null!=t.zoom&&o.zoom(t.zoom),t.pan&&o.pan(t.pan),e.one("layoutready",t.ready),e.trigger({type:"layoutready",layout:e}),e.one("layoutstop",t.stop),e.trigger({type:"layoutstop",layout:e});return this},layout:function(e){var t=this.cy();return t.layout(i.extend({},e,{eles:this})),this},makeLayout:function(e){var t=this.cy();return t.makeLayout(i.extend({},e,{eles:this}))}};o.createLayout=o.makeLayout,t.exports=o},{"../is":83,"../promise":86,"../util":100}]! ,29:[function(e,t,r){"use strict";var n=e("../is"),i={updateStyle:function(e){var t=this._private.cy;if(!t.styleEnabled())return this;if(t._private.batchingStyle){var r=t._private.batchStyleEles;return r.merge(this),this}var n=t.style();e=!(!e&&void 0!==e),n.apply(this);var i=this.updateCompoundBounds(),a=i.length>0?this.add(i):this;return e?a.rtrigger("style"):a.trigger("style"),this},updateMappers:function(e){var t=this._private.cy,r=t.style();if(e=!(!e&&void 0!==e),!t.styleEnabled())return this;r.updateMappers(this);var n=this.updateCompoundBounds(),i=n.length>0?this.add(n):this;return e?i.rtrigger("style"):i.trigger("style"),this},parsedStyle:function(e){var t=this[0];if(t.cy().styleEnabled())return t?t._private.style[e]||t.cy().style().getDefaultProperty(e):void 0},renderedStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var r=this[0];if(r){var n=r.cy().style().getRenderedStyle(r);return void 0===e?n:n[e]}},style:function(e,t){var r=this.cy();if(!r.st! yleEnabled())return this;var i=!1,a=r.style();if(n.plainObject! (e)){var o=e;a.applyBypass(this,o,i);var s=this.updateCompoundBounds(),l=s.length>0?this.add(s):this;l.rtrigger("style")}else if(n.string(e)){if(void 0===t){var u=this[0];return u?a.getStylePropertyValue(u,e):void 0}a.applyBypass(this,e,t,i);var s=this.updateCompoundBounds(),l=s.length>0?this.add(s):this;l.rtrigger("style")}else if(void 0===e){var u=t... [truncated message content] |
From: <de...@de...> - 2017-01-27 13:40:11
|
Author: AaronLWalker Date: 2017-01-27 13:38:50 +0000 (Fri, 27 Jan 2017) New Revision: 30305 Trac url: http://develop.twiki.org/trac/changeset/30305 Added: twiki/trunk/CytoscapePlugin/ Log: Item7773: Creation of initial directory for CytoscapePlugin |
From: <de...@de...> - 2017-01-27 13:25:00
|
Author: AaronLWalker Date: 2017-01-27 13:23:24 +0000 (Fri, 27 Jan 2017) New Revision: 30304 Trac url: http://develop.twiki.org/trac/changeset/30304 Added: twiki/trunk/FlotPlugin/data/ twiki/trunk/FlotPlugin/data/TWiki/ twiki/trunk/FlotPlugin/data/TWiki/FlotPlugin.txt twiki/trunk/FlotPlugin/lib/ twiki/trunk/FlotPlugin/lib/TWiki/ twiki/trunk/FlotPlugin/lib/TWiki/Plugins/ twiki/trunk/FlotPlugin/lib/TWiki/Plugins/FlotPlugin.pm twiki/trunk/FlotPlugin/pub/ twiki/trunk/FlotPlugin/pub/TWiki/ twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/ twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.crosshair.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.crosshair.min.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.fillbetween.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.fillbetween.min.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.image.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.image.min.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.min.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.navigate.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.navigate.min.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.pie.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.pie.min.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.resize.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.resize.min.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.selection.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.selection.min.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.stack.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.stack.min.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.symbol.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.symbol.min.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.threshold.js twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.threshold.min.js Log: Item7772: Initial population of FlotPlugin Added: twiki/trunk/FlotPlugin/data/TWiki/FlotPlugin.txt =================================================================== --- twiki/trunk/FlotPlugin/data/TWiki/FlotPlugin.txt (rev 0) +++ twiki/trunk/FlotPlugin/data/TWiki/FlotPlugin.txt 2017-01-27 13:23:24 UTC (rev 30304) @@ -0,0 +1,80 @@ +%META:TOPICINFO{author="AaronWalker" date="1435086146" format="1.1" version="1.2"}% +---+!! !FlotPlugin +<!-- + Contributions to this plugin are appreciated. Please update the plugin page at + http://twiki.org/cgi-bin/view/Plugins/FlotPlugin or provide feedback at + http://twiki.org/cgi-bin/view/Plugins/FlotPluginDev. + If you are a TWiki contributor please update the plugin in the SVN repository. +--> +<sticky><div style="float:right; background-color:#EBEEF0; margin:0 0 20px 20px; padding: 0 10px 0 10px;"> +%TOC{title="Page contents"}% +</div></sticky> +%SHORTDESCRIPTION% + +---++ Introduction + +Describe the plugin here + +---++ Syntax Rules + +=%<nop>EXAMPLEVAR{"..."}%= + +| *Parameter* | *Explanation* | *Default* | +| ="..."= | Default parameter. | (none) | +| =format="..."= | Format: ... | ="$name"= | + +---++ Examples + + * =%<nop>EXAMPLEVAR{}%= expands to: %EXAMPLEVAR{}% + * + +---++ Plugin Installation & Configuration + +You do not need to install anything on the browser to use this plugin. These instructions are for the administrator who installs the plugin on the TWiki server. +%TWISTY{ + mode="div" + showlink="Show details %ICONURL{toggleopen}% " + hidelink="Hide details %ICONURL{toggleclose}% " +}% + + * For an __automated installation__, run the [[%SCRIPTURL{configure}%][configure]] script and follow "Find More Extensions" in the in the __Extensions__ section. + * See the [[http://twiki.org/cgi-bin/view/Plugins/BuildContribInstallationSupplement][installation supplement]] on TWiki.org for more information. + + * Or, follow these __manual installation__ steps: + * Download the ZIP file from the Plugins home (see below). + * Unzip ==%TOPIC%.zip== in your twiki installation directory. Content: + | *File:* | *Description:* | + | ==data/TWiki/%TOPIC%.txt== | Plugin topic | + | ==lib/TWiki/Plugins/%TOPIC%.pm== | Plugin Perl module | + * Set the ownership of the extracted directories and files to the webserver user. + * Install the dependencies (if any). + + * Plugin __configuration and testing__: + * Run the [[%SCRIPTURL{configure}%][configure]] script and enable the plugin in the __Plugins__ section. + * Configure additional plugin settings in the __Extensions__ section if needed. + * Test if the installation was successful using the example above. + +%ENDTWISTY% + +---++ Plugin Info + + * One line description, is shown in the %SYSTEMWEB%.TextFormattingRules topic: + * Set SHORTDESCRIPTION = one line description here +%TABLE{ tablewidth="100%" columnwidths="170," }% +| Plugin Author: | TWiki:Main.AaronLWalker | +| Copyright: | © 2015 TWiki:Main.AaronLWalker <br /> © 2015 TWiki:TWiki.TWikiContributor | +| License: | GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]]) | +| Plugin Version: | 2017-01-23 (V1.000) | +| Change History: | <!-- versions below in reverse order --> | +| 2017-01-23: | Initial version | +| TWiki Dependency: | $TWiki::Plugins::VERSION 1.1 | +| CPAN Dependencies: | none | +| Other Dependencies: | none | +| Perl Version: | 5.005 | +| [[TWiki:Plugins.Benchmark][Plugin Benchmark]]: | %SYSTEMWEB%.GoodStyle nn%, %SYSTEMWEB%.FormattedSearch nn%, %TOPIC% nn% | +| Plugin Home: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC% | +| Feedback: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC%Dev | +| Appraisal: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC%Appraisal | + +__Related Topics:__ %SYSTEMWEB%.TWikiPlugins, %SYSTEMWEB%.DeveloperDocumentationCategory, %SYSTEMWEB%.AdminDocumentationCategory, %SYSTEMWEB%.TWikiPreferences + Added: twiki/trunk/FlotPlugin/lib/TWiki/Plugins/FlotPlugin.pm =================================================================== --- twiki/trunk/FlotPlugin/lib/TWiki/Plugins/FlotPlugin.pm (rev 0) +++ twiki/trunk/FlotPlugin/lib/TWiki/Plugins/FlotPlugin.pm 2017-01-27 13:23:24 UTC (rev 30304) @@ -0,0 +1,63 @@ +# Plugin for TWiki Enterprise Collaboration Platform, http://TWiki.org/ +# +# Copyright (c) 2007-2008 Michael Daum, http://michaeldaumconsulting.com +# Copyright (c) 2007-2011 TWiki Contributors. All Rights Reserved. +# TWiki Contributors are listed in the AUTHORS file in the root of +# this distribution. +# NOTE: Please extend that file, not this notice. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. For +# more details read LICENSE in the root of this distribution. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# For licensing info read LICENSE file in the TWiki root. + +package TWiki::Plugins::FlotPlugin; +use strict; +use vars qw( + $VERSION $RELEASE $SHORTDESCRIPTION + $NO_PREFS_IN_TOPIC + $doneInit $doneHeader + $dtPubUrlPath $header +); + +$VERSION = '$Rev: 20836 (2017-01-23) $'; +$RELEASE = '2017-01-23'; +$SHORTDESCRIPTION = '<nop>Flot jQuery library for TWiki'; +$NO_PREFS_IN_TOPIC = 1; + +$dtPubUrlPath = '%PUBURLPATH%/%SYSTEMWEB%/FlotPlugin'; +$header = "<script type=\"text/javascript\" src=\"$dtPubUrlPath/jquery.flot.min.js\"></script> \n"; + +############################################################################### +sub initPlugin { + my( $topic, $web, $user, $installWeb ) = @_; + + $doneInit = 0; + $doneHeader = 0; + + TWiki::Func::registerTagHandler('FLOT', \&handleFlotBase ); + + return 1; +} + +############################################################################### +sub handleFlotBase { + my ($session, $params, $theTopic, $theWeb) = @_; + + return if $doneHeader; + $doneHeader = 1 if ($_[0] =~ s/<head>(.*?[\r\n]+)/<head>$1$header/o); + + TWiki::Func::addToHEAD( + "flot", + $header + ); +} + +1; Property changes on: twiki/trunk/FlotPlugin/lib/TWiki/Plugins/FlotPlugin.pm ___________________________________________________________________ Added: svn:executable + * Added: twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.crosshair.js =================================================================== --- twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.crosshair.js (rev 0) +++ twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.crosshair.js 2017-01-27 13:23:24 UTC (rev 30304) @@ -0,0 +1,167 @@ +/* +Flot plugin for showing crosshairs, thin lines, when the mouse hovers +over the plot. + + crosshair: { + mode: null or "x" or "y" or "xy" + color: color + lineWidth: number + } + +Set the mode to one of "x", "y" or "xy". The "x" mode enables a +vertical crosshair that lets you trace the values on the x axis, "y" +enables a horizontal crosshair and "xy" enables them both. "color" is +the color of the crosshair (default is "rgba(170, 0, 0, 0.80)"), +"lineWidth" is the width of the drawn lines (default is 1). + +The plugin also adds four public methods: + + - setCrosshair(pos) + + Set the position of the crosshair. Note that this is cleared if + the user moves the mouse. "pos" is in coordinates of the plot and + should be on the form { x: xpos, y: ypos } (you can use x2/x3/... + if you're using multiple axes), which is coincidentally the same + format as what you get from a "plothover" event. If "pos" is null, + the crosshair is cleared. + + - clearCrosshair() + + Clear the crosshair. + + - lockCrosshair(pos) + + Cause the crosshair to lock to the current location, no longer + updating if the user moves the mouse. Optionally supply a position + (passed on to setCrosshair()) to move it to. + + Example usage: + var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } }; + $("#graph").bind("plothover", function (evt, position, item) { + if (item) { + // Lock the crosshair to the data point being hovered + myFlot.lockCrosshair({ x: item.datapoint[0], y: item.datapoint[1] }); + } + else { + // Return normal crosshair operation + myFlot.unlockCrosshair(); + } + }); + + - unlockCrosshair() + + Free the crosshair to move again after locking it. +*/ + +(function ($) { + var options = { + crosshair: { + mode: null, // one of null, "x", "y" or "xy", + color: "rgba(170, 0, 0, 0.80)", + lineWidth: 1 + } + }; + + function init(plot) { + // position of crosshair in pixels + var crosshair = { x: -1, y: -1, locked: false }; + + plot.setCrosshair = function setCrosshair(pos) { + if (!pos) + crosshair.x = -1; + else { + var o = plot.p2c(pos); + crosshair.x = Math.max(0, Math.min(o.left, plot.width())); + crosshair.y = Math.max(0, Math.min(o.top, plot.height())); + } + + plot.triggerRedrawOverlay(); + }; + + plot.clearCrosshair = plot.setCrosshair; // passes null for pos + + plot.lockCrosshair = function lockCrosshair(pos) { + if (pos) + plot.setCrosshair(pos); + crosshair.locked = true; + } + + plot.unlockCrosshair = function unlockCrosshair() { + crosshair.locked = false; + } + + function onMouseOut(e) { + if (crosshair.locked) + return; + + if (crosshair.x != -1) { + crosshair.x = -1; + plot.triggerRedrawOverlay(); + } + } + + function onMouseMove(e) { + if (crosshair.locked) + return; + + if (plot.getSelection && plot.getSelection()) { + crosshair.x = -1; // hide the crosshair while selecting + return; + } + + var offset = plot.offset(); + crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width())); + crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height())); + plot.triggerRedrawOverlay(); + } + + plot.hooks.bindEvents.push(function (plot, eventHolder) { + if (!plot.getOptions().crosshair.mode) + return; + + eventHolder.mouseout(onMouseOut); + eventHolder.mousemove(onMouseMove); + }); + + plot.hooks.drawOverlay.push(function (plot, ctx) { + var c = plot.getOptions().crosshair; + if (!c.mode) + return; + + var plotOffset = plot.getPlotOffset(); + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + if (crosshair.x != -1) { + ctx.strokeStyle = c.color; + ctx.lineWidth = c.lineWidth; + ctx.lineJoin = "round"; + + ctx.beginPath(); + if (c.mode.indexOf("x") != -1) { + ctx.moveTo(crosshair.x, 0); + ctx.lineTo(crosshair.x, plot.height()); + } + if (c.mode.indexOf("y") != -1) { + ctx.moveTo(0, crosshair.y); + ctx.lineTo(plot.width(), crosshair.y); + } + ctx.stroke(); + } + ctx.restore(); + }); + + plot.hooks.shutdown.push(function (plot, eventHolder) { + eventHolder.unbind("mouseout", onMouseOut); + eventHolder.unbind("mousemove", onMouseMove); + }); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'crosshair', + version: '1.0' + }); +})(jQuery); Added: twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.crosshair.min.js =================================================================== --- twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.crosshair.min.js (rev 0) +++ twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.crosshair.min.js 2017-01-27 13:23:24 UTC (rev 30304) @@ -0,0 +1 @@ +(function(b){var a={crosshair:{mode:null,color:"rgba(170, 0, 0, 0.80)",lineWidth:1}};function c(h){var j={x:-1,y:-1,locked:false};h.setCrosshair=function e(l){if(!l){j.x=-1}else{var k=h.p2c(l);j.x=Math.max(0,Math.min(k.left,h.width()));j.y=Math.max(0,Math.min(k.top,h.height()))}h.triggerRedrawOverlay()};h.clearCrosshair=h.setCrosshair;h.lockCrosshair=function f(k){if(k){h.setCrosshair(k)}j.locked=true};h.unlockCrosshair=function g(){j.locked=false};function d(k){if(j.locked){return}if(j.x!=-1){j.x=-1;h.triggerRedrawOverlay()}}function i(k){if(j.locked){return}if(h.getSelection&&h.getSelection()){j.x=-1;return}var l=h.offset();j.x=Math.max(0,Math.min(k.pageX-l.left,h.width()));j.y=Math.max(0,Math.min(k.pageY-l.top,h.height()));h.triggerRedrawOverlay()}h.hooks.bindEvents.push(function(l,k){if(!l.getOptions().crosshair.mode){return}k.mouseout(d);k.mousemove(i)});h.hooks.drawOverlay.push(function(m,k){var n=m.getOptions().crosshair;if(!n.mode){return}var l=m.getPlotOffset();k.s! ave();k.translate(l.left,l.top);if(j.x!=-1){k.strokeStyle=n.color;k.lineWidth=n.lineWidth;k.lineJoin="round";k.beginPath();if(n.mode.indexOf("x")!=-1){k.moveTo(j.x,0);k.lineTo(j.x,m.height())}if(n.mode.indexOf("y")!=-1){k.moveTo(0,j.y);k.lineTo(m.width(),j.y)}k.stroke()}k.restore()});h.hooks.shutdown.push(function(l,k){k.unbind("mouseout",d);k.unbind("mousemove",i)})}b.plot.plugins.push({init:c,options:a,name:"crosshair",version:"1.0"})})(jQuery); \ No newline at end of file Added: twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.fillbetween.js =================================================================== --- twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.fillbetween.js (rev 0) +++ twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.fillbetween.js 2017-01-27 13:23:24 UTC (rev 30304) @@ -0,0 +1,183 @@ +/* +Flot plugin for computing bottoms for filled line and bar charts. + +The case: you've got two series that you want to fill the area +between. In Flot terms, you need to use one as the fill bottom of the +other. You can specify the bottom of each data point as the third +coordinate manually, or you can use this plugin to compute it for you. + +In order to name the other series, you need to give it an id, like this + + var dataset = [ + { data: [ ... ], id: "foo" } , // use default bottom + { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom + ]; + + $.plot($("#placeholder"), dataset, { line: { show: true, fill: true }}); + +As a convenience, if the id given is a number that doesn't appear as +an id in the series, it is interpreted as the index in the array +instead (so fillBetween: 0 can also mean the first series). + +Internally, the plugin modifies the datapoints in each series. For +line series, extra data points might be inserted through +interpolation. Note that at points where the bottom line is not +defined (due to a null point or start/end of line), the current line +will show a gap too. The algorithm comes from the jquery.flot.stack.js +plugin, possibly some code could be shared. +*/ + +(function ($) { + var options = { + series: { fillBetween: null } // or number + }; + + function init(plot) { + function findBottomSeries(s, allseries) { + var i; + for (i = 0; i < allseries.length; ++i) { + if (allseries[i].id == s.fillBetween) + return allseries[i]; + } + + if (typeof s.fillBetween == "number") { + i = s.fillBetween; + + if (i < 0 || i >= allseries.length) + return null; + + return allseries[i]; + } + + return null; + } + + function computeFillBottoms(plot, s, datapoints) { + if (s.fillBetween == null) + return; + + var other = findBottomSeries(s, plot.getData()); + if (!other) + return; + + var ps = datapoints.pointsize, + points = datapoints.points, + otherps = other.datapoints.pointsize, + otherpoints = other.datapoints.points, + newpoints = [], + px, py, intery, qx, qy, bottom, + withlines = s.lines.show, + withbottom = ps > 2 && datapoints.format[2].y, + withsteps = withlines && s.lines.steps, + fromgap = true, + i = 0, j = 0, l; + + while (true) { + if (i >= points.length) + break; + + l = newpoints.length; + + if (points[i] == null) { + // copy gaps + for (m = 0; m < ps; ++m) + newpoints.push(points[i + m]); + i += ps; + } + else if (j >= otherpoints.length) { + // for lines, we can't use the rest of the points + if (!withlines) { + for (m = 0; m < ps; ++m) + newpoints.push(points[i + m]); + } + i += ps; + } + else if (otherpoints[j] == null) { + // oops, got a gap + for (m = 0; m < ps; ++m) + newpoints.push(null); + fromgap = true; + j += otherps; + } + else { + // cases where we actually got two points + px = points[i]; + py = points[i + 1]; + qx = otherpoints[j]; + qy = otherpoints[j + 1]; + bottom = 0; + + if (px == qx) { + for (m = 0; m < ps; ++m) + newpoints.push(points[i + m]); + + //newpoints[l + 1] += qy; + bottom = qy; + + i += ps; + j += otherps; + } + else if (px > qx) { + // we got past point below, might need to + // insert interpolated extra point + if (withlines && i > 0 && points[i - ps] != null) { + intery = py + (points[i - ps + 1] - py) * (qx - px) / (points[i - ps] - px); + newpoints.push(qx); + newpoints.push(intery) + for (m = 2; m < ps; ++m) + newpoints.push(points[i + m]); + bottom = qy; + } + + j += otherps; + } + else { // px < qx + if (fromgap && withlines) { + // if we come from a gap, we just skip this point + i += ps; + continue; + } + + for (m = 0; m < ps; ++m) + newpoints.push(points[i + m]); + + // we might be able to interpolate a point below, + // this can give us a better y + if (withlines && j > 0 && otherpoints[j - otherps] != null) + bottom = qy + (otherpoints[j - otherps + 1] - qy) * (px - qx) / (otherpoints[j - otherps] - qx); + + //newpoints[l + 1] += bottom; + + i += ps; + } + + fromgap = false; + + if (l != newpoints.length && withbottom) + newpoints[l + 2] = bottom; + } + + // maintain the line steps invariant + if (withsteps && l != newpoints.length && l > 0 + && newpoints[l] != null + && newpoints[l] != newpoints[l - ps] + && newpoints[l + 1] != newpoints[l - ps + 1]) { + for (m = 0; m < ps; ++m) + newpoints[l + ps + m] = newpoints[l + m]; + newpoints[l + 1] = newpoints[l - ps + 1]; + } + } + + datapoints.points = newpoints; + } + + plot.hooks.processDatapoints.push(computeFillBottoms); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'fillbetween', + version: '1.0' + }); +})(jQuery); Added: twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.fillbetween.min.js =================================================================== --- twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.fillbetween.min.js (rev 0) +++ twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.fillbetween.min.js 2017-01-27 13:23:24 UTC (rev 30304) @@ -0,0 +1 @@ +(function(b){var a={series:{fillBetween:null}};function c(f){function d(j,h){var g;for(g=0;g<h.length;++g){if(h[g].id==j.fillBetween){return h[g]}}if(typeof j.fillBetween=="number"){g=j.fillBetween;if(g<0||g>=h.length){return null}return h[g]}return null}function e(B,u,g){if(u.fillBetween==null){return}var p=d(u,B.getData());if(!p){return}var y=g.pointsize,E=g.points,h=p.datapoints.pointsize,x=p.datapoints.points,r=[],w,v,k,G,F,q,t=u.lines.show,o=y>2&&g.format[2].y,n=t&&u.lines.steps,D=true,C=0,A=0,z;while(true){if(C>=E.length){break}z=r.length;if(E[C]==null){for(m=0;m<y;++m){r.push(E[C+m])}C+=y}else{if(A>=x.length){if(!t){for(m=0;m<y;++m){r.push(E[C+m])}}C+=y}else{if(x[A]==null){for(m=0;m<y;++m){r.push(null)}D=true;A+=h}else{w=E[C];v=E[C+1];G=x[A];F=x[A+1];q=0;if(w==G){for(m=0;m<y;++m){r.push(E[C+m])}q=F;C+=y;A+=h}else{if(w>G){if(t&&C>0&&E[C-y]!=null){k=v+(E[C-y+1]-v)*(G-w)/(E[C-y]-w);r.push(G);r.push(k);for(m=2;m<y;++m){r.push(E[C+m])}q=F}A+=h}else{if(D&&t){C+=y;continue}! for(m=0;m<y;++m){r.push(E[C+m])}if(t&&A>0&&x[A-h]!=null){q=F+(x[A-h+1]-F)*(w-G)/(x[A-h]-G)}C+=y}}D=false;if(z!=r.length&&o){r[z+2]=q}}}}if(n&&z!=r.length&&z>0&&r[z]!=null&&r[z]!=r[z-y]&&r[z+1]!=r[z-y+1]){for(m=0;m<y;++m){r[z+y+m]=r[z+m]}r[z+1]=r[z-y+1]}}g.points=r}f.hooks.processDatapoints.push(e)}b.plot.plugins.push({init:c,options:a,name:"fillbetween",version:"1.0"})})(jQuery); \ No newline at end of file Added: twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.image.js =================================================================== --- twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.image.js (rev 0) +++ twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.image.js 2017-01-27 13:23:24 UTC (rev 30304) @@ -0,0 +1,238 @@ +/* +Flot plugin for plotting images, e.g. useful for putting ticks on a +prerendered complex visualization. + +The data syntax is [[image, x1, y1, x2, y2], ...] where (x1, y1) and +(x2, y2) are where you intend the two opposite corners of the image to +end up in the plot. Image must be a fully loaded Javascript image (you +can make one with new Image()). If the image is not complete, it's +skipped when plotting. + +There are two helpers included for retrieving images. The easiest work +the way that you put in URLs instead of images in the data (like +["myimage.png", 0, 0, 10, 10]), then call $.plot.image.loadData(data, +options, callback) where data and options are the same as you pass in +to $.plot. This loads the images, replaces the URLs in the data with +the corresponding images and calls "callback" when all images are +loaded (or failed loading). In the callback, you can then call $.plot +with the data set. See the included example. + +A more low-level helper, $.plot.image.load(urls, callback) is also +included. Given a list of URLs, it calls callback with an object +mapping from URL to Image object when all images are loaded or have +failed loading. + +Options for the plugin are + + series: { + images: { + show: boolean + anchor: "corner" or "center" + alpha: [0,1] + } + } + +which can be specified for a specific series + + $.plot($("#placeholder"), [{ data: [ ... ], images: { ... } ]) + +Note that because the data format is different from usual data points, +you can't use images with anything else in a specific data series. + +Setting "anchor" to "center" causes the pixels in the image to be +anchored at the corner pixel centers inside of at the pixel corners, +effectively letting half a pixel stick out to each side in the plot. + + +A possible future direction could be support for tiling for large +images (like Google Maps). + +*/ + +(function ($) { + var options = { + series: { + images: { + show: false, + alpha: 1, + anchor: "corner" // or "center" + } + } + }; + + $.plot.image = {}; + + $.plot.image.loadDataImages = function (series, options, callback) { + var urls = [], points = []; + + var defaultShow = options.series.images.show; + + $.each(series, function (i, s) { + if (!(defaultShow || s.images.show)) + return; + + if (s.data) + s = s.data; + + $.each(s, function (i, p) { + if (typeof p[0] == "string") { + urls.push(p[0]); + points.push(p); + } + }); + }); + + $.plot.image.load(urls, function (loadedImages) { + $.each(points, function (i, p) { + var url = p[0]; + if (loadedImages[url]) + p[0] = loadedImages[url]; + }); + + callback(); + }); + } + + $.plot.image.load = function (urls, callback) { + var missing = urls.length, loaded = {}; + if (missing == 0) + callback({}); + + $.each(urls, function (i, url) { + var handler = function () { + --missing; + + loaded[url] = this; + + if (missing == 0) + callback(loaded); + }; + + $('<img />').load(handler).error(handler).attr('src', url); + }); + } + + function drawSeries(plot, ctx, series) { + var plotOffset = plot.getPlotOffset(); + + if (!series.images || !series.images.show) + return; + + var points = series.datapoints.points, + ps = series.datapoints.pointsize; + + for (var i = 0; i < points.length; i += ps) { + var img = points[i], + x1 = points[i + 1], y1 = points[i + 2], + x2 = points[i + 3], y2 = points[i + 4], + xaxis = series.xaxis, yaxis = series.yaxis, + tmp; + + // actually we should check img.complete, but it + // appears to be a somewhat unreliable indicator in + // IE6 (false even after load event) + if (!img || img.width <= 0 || img.height <= 0) + continue; + + if (x1 > x2) { + tmp = x2; + x2 = x1; + x1 = tmp; + } + if (y1 > y2) { + tmp = y2; + y2 = y1; + y1 = tmp; + } + + // if the anchor is at the center of the pixel, expand the + // image by 1/2 pixel in each direction + if (series.images.anchor == "center") { + tmp = 0.5 * (x2-x1) / (img.width - 1); + x1 -= tmp; + x2 += tmp; + tmp = 0.5 * (y2-y1) / (img.height - 1); + y1 -= tmp; + y2 += tmp; + } + + // clip + if (x1 == x2 || y1 == y2 || + x1 >= xaxis.max || x2 <= xaxis.min || + y1 >= yaxis.max || y2 <= yaxis.min) + continue; + + var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height; + if (x1 < xaxis.min) { + sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1); + x1 = xaxis.min; + } + + if (x2 > xaxis.max) { + sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1); + x2 = xaxis.max; + } + + if (y1 < yaxis.min) { + sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1); + y1 = yaxis.min; + } + + if (y2 > yaxis.max) { + sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1); + y2 = yaxis.max; + } + + x1 = xaxis.p2c(x1); + x2 = xaxis.p2c(x2); + y1 = yaxis.p2c(y1); + y2 = yaxis.p2c(y2); + + // the transformation may have swapped us + if (x1 > x2) { + tmp = x2; + x2 = x1; + x1 = tmp; + } + if (y1 > y2) { + tmp = y2; + y2 = y1; + y1 = tmp; + } + + tmp = ctx.globalAlpha; + ctx.globalAlpha *= series.images.alpha; + ctx.drawImage(img, + sx1, sy1, sx2 - sx1, sy2 - sy1, + x1 + plotOffset.left, y1 + plotOffset.top, + x2 - x1, y2 - y1); + ctx.globalAlpha = tmp; + } + } + + function processRawData(plot, series, data, datapoints) { + if (!series.images.show) + return; + + // format is Image, x1, y1, x2, y2 (opposite corners) + datapoints.format = [ + { required: true }, + { x: true, number: true, required: true }, + { y: true, number: true, required: true }, + { x: true, number: true, required: true }, + { y: true, number: true, required: true } + ]; + } + + function init(plot) { + plot.hooks.processRawData.push(processRawData); + plot.hooks.drawSeries.push(drawSeries); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'image', + version: '1.1' + }); +})(jQuery); Added: twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.image.min.js =================================================================== --- twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.image.min.js (rev 0) +++ twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.image.min.js 2017-01-27 13:23:24 UTC (rev 30304) @@ -0,0 +1 @@ +(function(c){var a={series:{images:{show:false,alpha:1,anchor:"corner"}}};c.plot.image={};c.plot.image.loadDataImages=function(g,f,k){var j=[],h=[];var i=f.series.images.show;c.each(g,function(l,m){if(!(i||m.images.show)){return}if(m.data){m=m.data}c.each(m,function(n,o){if(typeof o[0]=="string"){j.push(o[0]);h.push(o)}})});c.plot.image.load(j,function(l){c.each(h,function(n,o){var m=o[0];if(l[m]){o[0]=l[m]}});k()})};c.plot.image.load=function(h,i){var g=h.length,f={};if(g==0){i({})}c.each(h,function(k,j){var l=function(){--g;f[j]=this;if(g==0){i(f)}};c("<img />").load(l).error(l).attr("src",j)})};function d(q,o,l){var m=q.getPlotOffset();if(!l.images||!l.images.show){return}var r=l.datapoints.points,n=l.datapoints.pointsize;for(var t=0;t<r.length;t+=n){var y=r[t],w=r[t+1],g=r[t+2],v=r[t+3],f=r[t+4],h=l.xaxis,u=l.yaxis,x;if(!y||y.width<=0||y.height<=0){continue}if(w>v){x=v;v=w;w=x}if(g>f){x=f;f=g;g=x}if(l.images.anchor=="center"){x=0.5*(v-w)/(y.width-1);w-=x;v+=x;x=0.5*(f-g! )/(y.height-1);g-=x;f+=x}if(w==v||g==f||w>=h.max||v<=h.min||g>=u.max||f<=u.min){continue}var k=0,s=0,j=y.width,p=y.height;if(w<h.min){k+=(j-k)*(h.min-w)/(v-w);w=h.min}if(v>h.max){j+=(j-k)*(h.max-v)/(v-w);v=h.max}if(g<u.min){p+=(s-p)*(u.min-g)/(f-g);g=u.min}if(f>u.max){s+=(s-p)*(u.max-f)/(f-g);f=u.max}w=h.p2c(w);v=h.p2c(v);g=u.p2c(g);f=u.p2c(f);if(w>v){x=v;v=w;w=x}if(g>f){x=f;f=g;g=x}x=o.globalAlpha;o.globalAlpha*=l.images.alpha;o.drawImage(y,k,s,j-k,p-s,w+m.left,g+m.top,v-w,f-g);o.globalAlpha=x}}function b(i,f,g,h){if(!f.images.show){return}h.format=[{required:true},{x:true,number:true,required:true},{y:true,number:true,required:true},{x:true,number:true,required:true},{y:true,number:true,required:true}]}function e(f){f.hooks.processRawData.push(b);f.hooks.drawSeries.push(d)}c.plot.plugins.push({init:e,options:a,name:"image",version:"1.1"})})(jQuery); \ No newline at end of file Added: twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.js =================================================================== --- twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.js (rev 0) +++ twiki/trunk/FlotPlugin/pub/TWiki/FlotPlugin/jquery.flot.js 2017-01-27 13:23:24 UTC (rev 30304) @@ -0,0 +1,2599 @@ +/*! Javascript plotting library for jQuery, v. 0.7. + * + * Released under the MIT license by IOLA, December 2007. + * + */ + +// first an inline dependency, jquery.colorhelpers.js, we inline it here +// for convenience + +/* Plugin for jQuery for working with colors. + * + * Version 1.1. + * + * Inspiration from jQuery color animation plugin by John Resig. + * + * Released under the MIT license by Ole Laursen, October 2009. + * + * Examples: + * + * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() + * var c = $.color.extract($("#mydiv"), 'background-color'); + * console.log(c.r, c.g, c.b, c.a); + * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" + * + * Note that .scale() and .add() return the same modified object + * instead of making a new one. + * + * V. 1.1: Fix error handling so e.g. parsing an empty string does + * produce a color rather than just crashing. + */ +(function(B){B.color={};B.color.make=function(F,E,C,D){var G={};G.r=F||0;G.g=E||0;G.b=C||0;G.a=D!=null?D:1;G.add=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]+=I}return G.normalize()};G.scale=function(J,I){for(var H=0;H<J.length;++H){G[J.charAt(H)]*=I}return G.normalize()};G.toString=function(){if(G.a>=1){return"rgb("+[G.r,G.g,G.b].join(",")+")"}else{return"rgba("+[G.r,G.g,G.b,G.a].join(",")+")"}};G.normalize=function(){function H(J,K,I){return K<J?J:(K>I?I:K)}G.r=H(0,parseInt(G.r),255);G.g=H(0,parseInt(G.g),255);G.b=H(0,parseInt(G.b),255);G.a=H(0,G.a,1);return G};G.clone=function(){return B.color.make(G.r,G.b,G.g,G.a)};return G.normalize()};B.color.extract=function(D,C){var E;do{E=D.css(C).toLowerCase();if(E!=""&&E!="transparent"){break}D=D.parent()}while(!B.nodeName(D.get(0),"body"));if(E=="rgba(0, 0, 0, 0)"){E="transparent"}return B.color.parse(E)};B.color.parse=function(F){var E,C=B.color.make;if(E=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s! *\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10))}if(E=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10),parseFloat(E[4]))}if(E=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55)}if(E=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(F)){return C(parseFloat(E[1])*2.55,parseFloat(E[2])*2.55,parseFloat(E[3])*2.55,parseFloat(E[4]))}if(E=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(F)){return C(parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16))}if(E=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(F)){return C(parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16))}var D=B.trim(F).toLowerCase();! if(D=="transparent"){return C(255,255,255,0)}else{E=A[D]||[0,0! ,0];retu rn C(E[0],E[1],E[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery); + +// the actual Flot code +(function($) { + function Plot(placeholder, data_, options_, plugins) { + // data is on the form: + // [ series1, series2 ... ] + // where series is either just the data as [ [x1, y1], [x2, y2], ... ] + // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } + + var series = [], + options = { + // the color theme used for graphs + colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], + legend: { + show: true, + noColumns: 1, // number of colums in legend table + labelFormatter: null, // fn: string -> string + labelBoxBorderColor: "#ccc", // border color for the little label boxes + container: null, // container (as jQuery object) to put legend in, null means default on top of graph + position: "ne", // position of default legend container within plot + margin: 5, // distance from grid edge to default legend container within plot + backgroundColor: null, // null means auto-detect + backgroundOpacity: 0.85 // set to 0 to avoid background + }, + xaxis: { + show: null, // null = auto-detect, true = always, false = never + position: "bottom", // or "top" + mode: null, // null or "time" + color: null, // base color, labels, ticks + tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)" + transform: null, // null or f: number -> number to transform axis + inverseTransform: null, // if transform is set, this should be the inverse function + min: null, // min. value to show, null means set automatically + max: null, // max. value to show, null means set automatically + autoscaleMargin: null, // margin in % to add if auto-setting min/max + ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks + tickFormatter: null, // fn: number -> string + labelWidth: null, // size of tick labels in pixels + labelHeight: null, + reserveSpace: null, // whether to reserve space even if axis isn't shown + tickLength: null, // size in pixels of ticks, or "full" for whole line + alignTicksWithAxis: null, // axis number or null for no sync + + // mode specific options + tickDecimals: null, // no. of decimals, null means auto + tickSize: null, // number or [number, "unit"] + minTickSize: null, // number or [number, "unit"] + monthNames: null, // list of names of months + timeformat: null, // format string to use + twelveHourClock: false // 12 or 24 time in time mode + }, + yaxis: { + autoscaleMargin: 0.02, + position: "left" // or "right" + }, + xaxes: [], + yaxes: [], + series: { + points: { + show: false, + radius: 3, + lineWidth: 2, // in pixels + fill: true, + fillColor: "#ffffff", + symbol: "circle" // or callback + }, + lines: { + // we don't put in show: false so we can see + // whether lines were actively disabled + lineWidth: 2, // in pixels + fill: false, + fillColor: null, + steps: false + }, + bars: { + show: false, + lineWidth: 2, // in pixels + barWidth: 1, // in units of the x axis + fill: true, + fillColor: null, + align: "left", // or "center" + horizontal: false + }, + shadowSize: 3 + }, + grid: { + show: true, + aboveData: false, + color: "#545454", // primary color used for outline and labels + backgroundColor: null, // null for transparent, else color + borderColor: null, // set if different from the grid color + tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)" + labelMargin: 5, // in pixels + axisMargin: 8, // in pixels + borderWidth: 2, // in pixels + minBorderMargin: null, // in pixels, null means taken from points radius + markings: null, // array of ranges or fn: axes -> array of ranges + markingsColor: "#f4f4f4", + markingsLineWidth: 2, + // interactive stuff + clickable: false, + hoverable: false, + autoHighlight: true, // highlight in case mouse is near + mouseActiveRadius: 10 // how far the mouse can be away to activate an item + }, + hooks: {} + }, + canvas = null, // the canvas for the plot itself + overlay = null, // canvas for interactive stuff on top of plot + eventHolder = null, // jQuery object that events should be bound to + ctx = null, octx = null, + xaxes = [], yaxes = [], + plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, + canvasWidth = 0, canvasHeight = 0, + plotWidth = 0, plotHeight = 0, + hooks = { + processOptions: [], + processRawData: [], + processDatapoints: [], + drawSeries: [], + draw: [], + bindEvents: [], + drawOverlay: [], + shutdown: [] + }, + plot = this; + + // public functions + plot.setData = setData; + plot.setupGrid = setupGrid; + plot.draw = draw; + plot.getPlaceholder = function() { return placeholder; }; + plot.getCanvas = function() { return canvas; }; + plot.getPlotOffset = function() { return plotOffset; }; + plot.width = function () { return plotWidth; }; + plot.height = function () { return plotHeight; }; + plot.offset = function () { + var o = eventHolder.offset(); + o.left += plotOffset.left; + o.top += plotOffset.top; + return o; + }; + plot.getData = function () { return series; }; + plot.getAxes = function () { + var res = {}, i; + $.each(xaxes.concat(yaxes), function (_, axis) { + if (axis) + res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis; + }); + return res; + }; + plot.getXAxes = function () { return xaxes; }; + plot.getYAxes = function () { return yaxes; }; + plot.c2p = canvasToAxisCoords; + plot.p2c = axisToCanvasCoords; + plot.getOptions = function () { return options; }; + plot.highlight = highlight; + plot.unhighlight = unhighlight; + plot.triggerRedrawOverlay = triggerRedrawOverlay; + plot.pointOffset = function(point) { + return { + left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left), + top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top) + }; + }; + plot.shutdown = shutdown; + plot.resize = function () { + getCanvasDimensions(); + resizeCanvas(canvas); + resizeCanvas(overlay); + }; + + // public attributes + plot.hooks = hooks; + + // initialize + initPlugins(plot); + parseOptions(options_); + setupCanvases(); + setData(data_); + setupGrid(); + draw(); + bindEvents(); + + + function executeHooks(hook, args) { + args = [plot].concat(args); + for (var i = 0; i < hook.length; ++i) + hook[i].apply(this, args); + } + + function initPlugins() { + for (var i = 0; i < plugins.length; ++i) { + var p = plugins[i]; + p.init(plot); + if (p.options) + $.extend(true, options, p.options); + } + } + + function parseOptions(opts) { + var i; + + $.extend(true, options, opts); + + if (options.xaxis.color == null) + options.xaxis.color = options.grid.color; + if (options.yaxis.color == null) + options.yaxis.color = options.grid.color; + + if (options.xaxis.tickColor == null) // backwards-compatibility + options.xaxis.tickColor = options.grid.tickColor; + if (options.yaxis.tickColor == null) // backwards-compatibility + options.yaxis.tickColor = options.grid.tickColor; + + if (options.grid.borderColor == null) + options.grid.borderColor = options.grid.color; + if (options.grid.tickColor == null) + options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString(); + + // fill in defaults in axes, copy at least always the + // first as the rest of the code assumes it'll be there + for (i = 0; i < Math.max(1, options.xaxes.length); ++i) + options.xaxes[i] = $.extend(true, {}, options.xaxis, options.xaxes[i]); + for (i = 0; i < Math.max(1, options.yaxes.length); ++i) + options.yaxes[i] = $.extend(true, {}, options.yaxis, options.yaxes[i]); + + // backwards compatibility, to be removed in future + if (options.xaxis.noTicks && options.xaxis.ticks == null) + options.xaxis.ticks = options.xaxis.noTicks; + if (options.yaxis.noTicks && options.yaxis.ticks == null) + options.yaxis.ticks = options.yaxis.noTicks; + if (options.x2axis) { + options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis); + options.xaxes[1].position = "top"; + } + if (options.y2axis) { + options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis); + options.yaxes[1].position = "right"; + } + if (options.grid.coloredAreas) + options.grid.markings = options.grid.coloredAreas; + if (options.grid.coloredAreasColor) + options.grid.markingsColor = options.grid.coloredAreasColor; + if (options.lines) + $.extend(true, options.series.lines, options.lines); + if (options.points) + $.extend(true, options.series.points, options.points); + if (options.bars) + $.extend(true, options.series.bars, options.bars); + if (options.shadowSize != null) + options.series.shadowSize = options.shadowSize; + + // save options on axes for future reference + for (i = 0; i < options.xaxes.length; ++i) + getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i]; + for (i = 0; i < options.yaxes.length; ++i) + getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i]; + + // add hooks from options + for (var n in hooks) + if (options.hooks[n] && options.hooks[n].length) + hooks[n] = hooks[n].concat(options.hooks[n]); + + executeHooks(hooks.processOptions, [options]); + } + + function setData(d) { + series = parseData(d); + fillInSeriesOptions(); + processData(); + } + + function parseData(d) { + var res = []; + for (var i = 0; i < d.length; ++i) { + var s = $.extend(true, {}, options.series); + + if (d[i].data != null) { + s.data = d[i].data; // move the data instead of deep-copy + delete d[i].data; + + $.extend(true, s, d[i]); + + d[i].data = s.data; + } + else + s.data = d[i]; + res.push(s); + } + + return res; + } + + function axisNumber(obj, coord) { + var a = obj[coord + "axis"]; + if (typeof a == "object") // if we got a real axis, extract number + a = a.n; + if (typeof a != "number") + a = 1; // default to first axis + return a; + } + + function allAxes() { + // return flat array without annoying null entries + return $.grep(xaxes.concat(yaxes), function (a) { return a; }); + } + + function canvasToAxisCoords(pos) { + // return an object with x/y corresponding to all used axes + var res = {}, i, axis; + for (i = 0; i < xaxes.length; ++i) { + axis = xaxes[i]; + if (axis && axis.used) + res["x" + axis.n] = axis.c2p(pos.left); + } + + for (i = 0; i < yaxes.length; ++i) { + axis = yaxes[i]; + if (axis && axis.used) + res["y" + axis.n] = axis.c2p(pos.top); + } + + if (res.x1 !== undefined) + res.x = res.x1; + if (res.y1 !== undefined) + res.y = res.y1; + + return res; + } + + function axisToCanvasCoords(pos) { + // get canvas coords from the first pair of x/y found in pos + var res = {}, i, axis, key; + + for (i = 0; i < xaxes.length; ++i) { + axis = xaxes[i]; + if (axis && axis.used) { + key = "x" + axis.n; + if (pos[key] == null && axis.n == 1) + key = "x"; + + if (pos[key] != null) { + res.left = axis.p2c(pos[key]); + break; + } + } + } + + for (i = 0; i < yaxes.length; ++i) { + axis = yaxes[i]; + if (axis && axis.used) { + key = "y" + axis.n; + if (pos[key] == null && axis.n == 1) + key = "y"; + + if (pos[key] != null) { + res.top = axis.p2c(pos[key]); + break; + } + } + } + + return res; + } + + function getOrCreateAxis(axes, number) { + if (!axes[number - 1]) + axes[number - 1] = { + n: number, // save the number for future reference + direction: axes == xaxes ? "x" : "y", + options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis) + }; + + return axes[number - 1]; + } + + function fillInSeriesOptions() { + var i; + + // collect what we already got of colors + var neededColors = series.length, + usedColors = [], + assignedColors = []; + for (i = 0; i < series.length; ++i) { + var sc = series[i].color; + if (sc != null) { + --neededColors; + if (typeof sc == "number") + assignedColors.push(sc); + else + usedColors.push($.color.parse(series[i].color)); + } + } + + // we might need to generate more colors if higher indices + // are assigned + for (i = 0; i < assignedColors.length; ++i) { + neededColors = Math.max(neededColors, assignedColors[i] + 1); + } + + // produce colors as needed + var colors = [], variation = 0; + i = 0; + while (colors.length < neededColors) { + var c; + if (options.colors.length == i) // check degenerate case + c = $.color.make(100, 100, 100); + else + c = $.color.parse(options.colors[i]); + + // vary color if needed + var sign = variation % 2 == 1 ? -1 : 1; + c.scale('rgb', 1 + sign * Math.ceil(variation / 2) * 0.2) + + // FIXME: if we're getting to close to something else, + // we should probably skip this one + colors.push(c); + + ++i; + if (i >= options.colors.length) { + i = 0; + ++variation; + } + } + + // fill in the options + var colori = 0, s; + for (i = 0; i < series.length; ++i) { + s = series[i]; + + // assign colors + if (s.color == null) { + s.color = colors[colori].toString(); + ++colori; + } + else if (typeof s.color == "number") + s.color = colors[s.color].toString(); + + // turn on lines automatically in case nothing is set + if (s.lines.show == null) { + var v, show = true; + for (v in s) + if (s[v] && s[v].show) { + show = false; + break; + } + if (show) + s.lines.show = true; + } + + // setup axes + s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x")); + s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y")); + } + } + + function processData() { + var topSentry = Number.POSITIVE_INFINITY, + bottomSentry = Number.NEGATIVE_INFINITY, + fakeInfinity = Number.MAX_VALUE, + i, j, k, m, length, + s, points, ps, x, y, axis, val, f, p; + + function updateAxis(axis, min, max) { + if (min < axis.datamin && min != -fakeInfinity) + axis.datamin = min; + if (max > axis.datamax && max != fakeInfinity) + axis.datamax = max; + } + + $.each(allAxes(), function (_, axis) { + // init axis + axis.datamin = topSentry; + axis.datamax = bottomSentry; + axis.used = false; + }); + + for (i = 0; i < series.length; ++i) { + s = series[i]; + s.datapoints = { points: [] }; + + executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]); + } + + // first pass: clean and copy data + for (i = 0; i < series.length; ++i) { + s = series[i]; + + var data = s.data, format = s.datapoints.format; + + if (!format) { + format = []; + // find out how to copy + format.push({ x: true, number: true, required: true }); + format.push({ y: true, number: true, required: true }); + + if (s.bars.show || (s.lines.show && s.lines.fill)) { + format.push({ y: true, number: true, required: false, defaultValue: 0 }); + if (s.bars.horizontal) { + delete format[format.length - 1].y; + f... [truncated message content] |
Author: AaronLWalker Date: 2017-01-27 13:22:20 +0000 (Fri, 27 Jan 2017) New Revision: 30303 Trac url: http://develop.twiki.org/trac/changeset/30303 Added: twiki/trunk/EPAgentPlugin/data/ twiki/trunk/EPAgentPlugin/data/TWiki/ twiki/trunk/EPAgentPlugin/data/TWiki/EPAgentPlugin.txt twiki/trunk/EPAgentPlugin/lib/ twiki/trunk/EPAgentPlugin/lib/TWiki/ twiki/trunk/EPAgentPlugin/lib/TWiki/Plugins/ twiki/trunk/EPAgentPlugin/lib/TWiki/Plugins/EPAgentPlugin.pm twiki/trunk/EPAgentPlugin/working/ twiki/trunk/EPAgentPlugin/working/work_areas/ twiki/trunk/EPAgentPlugin/working/work_areas/EPAgentPlugin/ twiki/trunk/EPAgentPlugin/working/work_areas/EPAgentPlugin/epagent.db Log: Item7770: Initial population of EPAgentPlugin Added: twiki/trunk/EPAgentPlugin/data/TWiki/EPAgentPlugin.txt =================================================================== --- twiki/trunk/EPAgentPlugin/data/TWiki/EPAgentPlugin.txt (rev 0) +++ twiki/trunk/EPAgentPlugin/data/TWiki/EPAgentPlugin.txt 2017-01-27 13:22:20 UTC (rev 30303) @@ -0,0 +1,136 @@ +%META:TOPICINFO{author="AaronWalker" date="1472053624" format="1.1" reprev="1.9" version="1.9"}% +---+!! !DataTablesPlugin +<!-- + Contributions to this plugin are appreciated. Please update the plugin page at + http://twiki.org/cgi-bin/view/Plugins/DataTablesPlugin or provide feedback at + http://twiki.org/cgi-bin/view/Plugins/DataTablesPluginDev. + If you are a TWiki contributor please update the plugin in the SVN repository. +--> +<sticky><div style="float:right; background-color:#EBEEF0; margin:0 0 20px 20px; padding: 0 10px 0 10px;"> +%TOC{title="Page contents"}% +</div></sticky> +%SHORTDESCRIPTION% + +---++ Introduction + +Describe the plugin here + +---++ Syntax Rules + +=%<nop>EXAMPLEVAR{"..."}%= + +| *Parameter* | *Explanation* | *Default* | +| ="..."= | Default parameter. | (none) | +| =format="..."= | Format: ... | ="$name"= | + +---++ REST interfaces +<noautolink> + * updateUserPref + + * updateMS + * _Used by:_ UpdateMilestoneExample + * _Used by:_ WorkflowViewer + + * updateTC + * _Used by:_ AppViewer + + * createWF + * _Used by:_ CreateWorkflow + + * modifyWF + + * leftBar + * _Used by:_ TrackerLeftBar + + * workflowData + * _Used by:_ WorkflowViewer + + * workflowListing + * _Used by:_ WorkflowListing + + * testCaseListing + * _Used by:_ TestCases + + * testCaseData + * _Used by:_ TestCaseViewer + + * appListing + * _Used by:_ Apps + + * appData + * _Used by:_ AppViewer + + * allAppsData + + * readyAppList + * _Used by:_ ReadyAppList + + * viewWFNotes + * _Used by:_ NotesPopup + + * viewAllNotes + + * milestoneData + * _Used by:_ MilestoneViewer + + * manageWFMSInfo + +</noautolink> +---++ Examples + + * =%<nop>EXAMPLEVAR{}%= expands to: %EXAMPLEVAR{}% + * + +---++ Plugin Installation & Configuration + +You do not need to install anything on the browser to use this plugin. These instructions are for the administrator who installs the plugin on the TWiki server. +%TWISTY{ + mode="div" + showlink="Show details %ICONURL{toggleopen}% " + hidelink="Hide details %ICONURL{toggleclose}% " +}% + + * For an __automated installation__, run the [[%SCRIPTURL{configure}%][configure]] script and follow "Find More Extensions" in the in the __Extensions__ section. + * See the [[http://twiki.org/cgi-bin/view/Plugins/BuildContribInstallationSupplement][installation supplement]] on TWiki.org for more information. + + * Or, follow these __manual installation__ steps: + * Download the ZIP file from the Plugins home (see below). + * Unzip ==%TOPIC%.zip== in your twiki installation directory. Content: + | *File:* | *Description:* | + | ==data/TWiki/%TOPIC%.txt== | Plugin topic | + | ==lib/TWiki/Plugins/%TOPIC%.pm== | Plugin Perl module | + * Set the ownership of the extracted directories and files to the webserver user. + * Install the dependencies (if any). + + * Plugin __configuration and testing__: + * Run the [[%SCRIPTURL{configure}%][configure]] script and enable the plugin in the __Plugins__ section. + * Configure additional plugin settings in the __Extensions__ section if needed. + * Test if the installation was successful using the example above. + +%ENDTWISTY% + + * Set DBID = epagent + * #Set DBID = trkoracle + +---++ Plugin Info + + * One line description, is shown in the %SYSTEMWEB%.TextFormattingRules topic: + * Set SHORTDESCRIPTION = one line description here +%TABLE{ tablewidth="100%" columnwidths="170," }% +| Plugin Author: | TWiki:Main.AaronLWalker | +| Copyright: | © 2015 TWiki:Main.AaronLWalker <br /> © 2015 TWiki:TWiki.TWikiContributor | +| License: | GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]]) | +| Plugin Version: | 2015-06-23 (V1.000) | +| Change History: | <!-- versions below in reverse order --> | +| 2015-06-23: | Initial version | +| TWiki Dependency: | $TWiki::Plugins::VERSION 1.1 | +| CPAN Dependencies: | none | +| Other Dependencies: | none | +| Perl Version: | 5.005 | +| [[TWiki:Plugins.Benchmark][Plugin Benchmark]]: | %SYSTEMWEB%.GoodStyle nn%, %SYSTEMWEB%.FormattedSearch nn%, %TOPIC% nn% | +| Plugin Home: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC% | +| Feedback: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC%Dev | +| Appraisal: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC%Appraisal | + +__Related Topics:__ %SYSTEMWEB%.TWikiPlugins, %SYSTEMWEB%.DeveloperDocumentationCategory, %SYSTEMWEB%.AdminDocumentationCategory, %SYSTEMWEB%.TWikiPreferences + Added: twiki/trunk/EPAgentPlugin/lib/TWiki/Plugins/EPAgentPlugin.pm =================================================================== --- twiki/trunk/EPAgentPlugin/lib/TWiki/Plugins/EPAgentPlugin.pm (rev 0) +++ twiki/trunk/EPAgentPlugin/lib/TWiki/Plugins/EPAgentPlugin.pm 2017-01-27 13:22:20 UTC (rev 30303) @@ -0,0 +1,1151 @@ +# Module of TWiki Enterprise Collaboration Platform, http://TWiki.org/ +# +# Copyright (C) 2010-2013 Peter Thoeny, peter[at]thoeny.org +# Copyright (C) 2010-2013 TWiki Contributors. All Rights Reserved. +# TWiki Contributors are listed in the AUTHORS file in the root of +# this distribution. NOTE: Please extend that file, not this notice. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. For +# more details read LICENSE in the root of this distribution. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# As per the GPL, removal of this notice is prohibited. + +=begin twiki + +This package includes a small Perl module to make it easier to use the +color picker from other TWiki plugins. This module includes the functions: + +=cut + +package TWiki::Plugins::EPAgentPlugin; + +use DBI; +use Data::Dumper; # for debugging +use strict; +use Error qw( :try ); + +require TWiki::Func; # The plugins API + +# ========================================================================== +our $VERSION = '$Rev: 25074 (2013-10-14) $'; +our $RELEASE = '2015-09-03'; +our $SHORTDESCRIPTION = "Introscope EPAgent-like Plugin"; +#our $NO_PREFS_IN_TOPIC = 1; +our $doneHeader; +our $pluginName = 'EPAgentPlugin'; # Name of this Plugin +our $debug = $TWiki::cfg{Plugins}{EPAgentPlugin}{Debug} || 0; + +# ========================================================================== +sub initPlugin { + my( $topic, $web, $user, $installWeb ) = @_; + + $doneHeader = 0; + + TWiki::Func::registerTagHandler('EPAGENTPLUGININFO', \&handlePluginInfo ); + TWiki::Func::registerTagHandler('ORACLEINFO', \&handleOracleInfo ); + TWiki::Func::registerTagHandler('TRACKERENV', \&handleListEnv ); + + TWiki::Func::registerTagHandler('TRACKERERRORCODES', \&handleShowErrorCodes ); + + # Allow a sub to be called from the REST interface + # using the provided alias + TWiki::Func::registerRESTHandler('insertVal', \&restInsertVal ); + TWiki::Func::registerRESTHandler('getEntries', \&restGetEntries ); + TWiki::Func::registerRESTHandler('getMenu', \&restGetMenu ); + + return 1; +} + +# ========================================================================== + +=begin twiki + +---+++ _getConnection + +=cut + +sub _getConnectionNoAutoCommit +{ + my $this_subs_name = (caller(0))[3]; + my $defDB = TWiki::Func::getPreferencesValue("EPAGENTPLUGIN_DBID"); + + unless (exists $TWiki::cfg{Plugins}{EPAgentPlugin}) { + die "$TWiki::cfg{Plugins}{EPAgentPlugin} not defined"; + } + unless (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}) { + die "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases} not defined"; + } + my $rawDb = ""; + my $driverDb = ""; + my $userDb = ""; + my $pwdDb = ""; + my $cString = ""; + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}) { + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{driver}) { + my $rawDriver = $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{driver}; + if ($rawDriver =~/oracle/i) { + $driverDb = "Oracle"; + } elsif ($rawDriver =~/sqlite/i) { + $driverDb = "SQLite"; + } else { + $driverDb = "unknown"; + } + } else { + $driverDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{database}) { + $rawDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{database}"; + $rawDb =~ s/\$workarea/TWiki::Func::getWorkArea( $pluginName )/geo; + } else { + $rawDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{username}) { + $userDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{username}"; + } else { + $userDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{password}) { + $pwdDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{password}"; + } else { + $pwdDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{connstring}) { + $cString = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{connstring}"; + } else { + $cString = "unknown"; + } + } else { + die "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB} not defined"; + } + + my $connString = ""; + if ($driverDb eq "Oracle") { + my $db = DBI->connect('dbi:Oracle:', "$cString", ""); + return $db; + } elsif ($driverDb eq "SQLite") { + $connString = "dbi:SQLite:${rawDb}"; + my $db = DBI->connect($connString, $userDb, $pwdDb, {sqlite_use_immediate_transaction => 1, RaiseError => 1, AutoCommit => 1}); + return $db; + } else { + die "$this_subs_name = no viable database defined"; + } +} + +sub _getConnection +{ + my $this_subs_name = (caller(0))[3]; + my $defDB = TWiki::Func::getPreferencesValue("EPAGENTPLUGIN_DBID"); + + unless (exists $TWiki::cfg{Plugins}{EPAgentPlugin}) { + die "$TWiki::cfg{Plugins}{EPAgentPlugin} not defined"; + } + unless (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}) { + die "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases} not defined"; + } + my $rawDb = ""; + my $driverDb = ""; + my $userDb = ""; + my $pwdDb = ""; + my $cString = ""; + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}) { + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{driver}) { + my $rawDriver = $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{driver}; + if ($rawDriver =~/oracle/i) { + $driverDb = "Oracle"; + } elsif ($rawDriver =~/sqlite/i) { + $driverDb = "SQLite"; + } else { + $driverDb = "unknown"; + } + } else { + $driverDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{database}) { + $rawDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{database}"; + $rawDb =~ s/\$workarea/TWiki::Func::getWorkArea( $pluginName )/geo; + } else { + $rawDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{username}) { + $userDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{username}"; + } else { + $userDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{password}) { + $pwdDb = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{password}"; + } else { + $pwdDb = "unknown"; + } + if (exists $TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{connstring}) { + $cString = "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB}{connstring}"; + } else { + $cString = "unknown"; + } + } else { + die "$TWiki::cfg{Plugins}{EPAgentPlugin}{Databases}{$defDB} not defined"; + } + + my $connString = ""; + if ($driverDb eq "Oracle") { + my $db = DBI->connect('dbi:Oracle:', "$cString", ""); + return $db; + } elsif ($driverDb eq "SQLite") { + $connString = "dbi:SQLite:${rawDb}"; + my $db = DBI->connect($connString, $userDb, $pwdDb, {sqlite_use_immediate_transaction => 1, RaiseError => 1, AutoCommit => 1}); + return $db; + } else { + die "$this_subs_name = no viable database defined"; + } +} + +# ========================================================================== + +=begin twiki + +---+++ _readTopicText + +=cut + +sub _readTopic +{ + my( $theWeb, $theTopic ) = @_; + my ($mdata, $text) = &TWiki::Func::readTopic( $theWeb, $theTopic ); + # return raw topic text, including meta data + return $text; +} + +sub restGetMenu { +# https://www.jstree.com/ +# $('#using_json_2').jstree({ 'core' : { +# 'data' : [ +# { "id" : "ajson1", "parent" : "#", "text" : "Simple root node" }, +# { "id" : "ajson2", "parent" : "#", "text" : "Root node 2" }, +# { "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" }, +# { "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" }, +# ] +# } }); + + my($session, $params, $theTopic, $theWeb) = @_; + + my $query = TWiki::Func::getCgiQuery(); + my $returntext = ""; + my @errorArray = (); + my @outArray = (); + my $success = 1; + my $this_subs_name = (caller(0))[3]; + + # Get database connection + my $db = &_getConnection; + my $numRows = 0; + + # CREATE TABLE nodes ( id INTEGER PRIMARY KEY, parent INTEGER, internal INTEGER, name TEXT) + my $getSelStmt = $db->prepare_cached("SELECT id, parent, internal, name FROM nodes"); + $success &&= $getSelStmt->execute(); + my $all = $getSelStmt->fetchall_arrayref; + #if ($getSelStmt03->rows == 0) { + + my $text = "{\"core\":{\"data\":["; + my $commactr = 0; + foreach my $row (@$all) { + my ($aa, $bb, $cc, $dd) = @$row; + if ($commactr > 0) { + $text .= ","; + } + $commactr++; + if ($bb == 0) { + $bb = "#"; + } + $text .= "{\"id\":\"$aa\",\"parent\":\"$bb\",\"text\":\"$dd\",\"int\":\"$cc\"}"; + } + $text .= "]}}"; + + return $text; +} + + +sub restGetEntries { + my($session, $params, $theTopic, $theWeb) = @_; + + my $query = TWiki::Func::getCgiQuery(); + my $returntext = ""; + my @errorArray = (); + my @outArray = (); + my $success = 1; + my $this_subs_name = (caller(0))[3]; + + # metricType=IntCounter&metricName=RTBI|ActivationSpecs|ODMSTGA_C1M1|wberuntimeear:EventReceiver&metricValue=1 + + my %inhash = (); + my @requiredInput = ('metricName'); + foreach my $parmin (@requiredInput) { + $inhash{$parmin} = $query->param($parmin); + unless( $inhash{$parmin} ) { + push(@errorArray, "$this_subs_name - no $parmin"); + $session->writeWarning("$this_subs_name - no $parmin") if $debug; + } + } + + if (@errorArray) { + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # Do first split + my @argArray = split(/:/, $inhash{'metricName'}); + if (@argArray != 2) { + push(@errorArray, "$this_subs_name - invalid metricName"); + $session->writeWarning("$this_subs_name - invalid metricName") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # clean up name + (my $invlName = $argArray[1]) =~ s/[^a-zA-Z0-9_-]//g; + # remove spaces + $invlName =~ s/^\s+|\s+$//g; + if (length($invlName) == 0) { + push(@errorArray, "$this_subs_name - illegal interval name"); + $session->writeWarning("$this_subs_name - illegal interval name") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # Do second split + my @pathArray = split(/\|/, $argArray[0]); + # Push interval on end of array + push @pathArray, $invlName; + my $parentID = 1; + my $isIntervalEntry = 1; + my @paCopy = @pathArray; + + # Get database connection + my $db = &_getConnection; + my $numRows = 0; + + foreach my $tpathLvl (@pathArray) { + (my $pathLvl = $tpathLvl) =~ s/[^a-zA-Z0-9_-]//g; + if (@paCopy == 1) { + $isIntervalEntry = 0; + } + my $newPID = &_handleDirectoryQuery(\$db, $parentID, $pathLvl, $isIntervalEntry); + if ($newPID =~/x/i) { + # !!!! NOTHING FOUND, SO SHOULD START CREATING + push(@errorArray, "$this_subs_name - entry not found"); + $session->writeWarning("$this_subs_name - entry not found") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } elsif ($newPID =~/f/i) { + # "f" means a mismatch, so fail + push(@errorArray, "$this_subs_name - mismatch type found"); + $session->writeWarning("$this_subs_name - mismatch type found") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } else { + $parentID = $newPID; + shift @paCopy; + } + } +# + #my $db = &_getConnection; + + my $getSelStmt = $db->prepare_cached("SELECT intval, ts FROM entries WHERE loc_id = ?"); + $success &&= $getSelStmt->execute($parentID); + my $all = $getSelStmt->fetchall_arrayref; + #if ($getSelStmt03->rows == 0) { + + my $text = "{\"notes\":["; + my $commactr = 0; + foreach my $row (@$all) { + my ($val, $date) = @$row; + if ($commactr > 0) { + $text .= ","; + } + $commactr++; + $text .= "{\"val\":\"$val\",\"ts\":\"$date\"}"; + } + + $text .= "]}"; + + return $text; +} + +=begin twiki + +---+++ handlePluginInfo + +=cut + +sub handlePluginInfo { + my ( $session, $params ) = @_; + my %options = %$params; + + my $text .= ""; + + my $db = &_getConnection; + + # Create a new statement handle to fetch table information + my $tabsth = $db->table_info(); + + my $ver = $db->{sqlite_version}; + #my $sth = $db->prepare("SELECT SQLITE_VERSION()"); + #$sth->execute(); + + #my $ver = $sth->fetch(); + + ### Print the header + $text .= " * DBI VERSION: $DBI::VERSION\n"; + $text .= " * DBD::SQLite VERSION: $DBD::SQLite::VERSION\n"; + $text .= "\n"; + $text .= "| *DB Version* | "; + #$text .= @$ver; + $text .= $ver; + $text .= " |\n\n"; + $text .= "| *Qualifier* | *Owner* | *Table Name* | *Type* | *Remarks* |\n"; + + ### Iterate through all the tables... + while ( my ( $qual, $owner, $name, $type, $remarks ) = + $tabsth->fetchrow_array() ) { + ### Tidy up NULL fields + foreach ($qual, $owner, $name, $type, $remarks) { + $_ = "N/A" unless defined $_; + } + ### Print out the table metadata... + $text .= "| $qual| $owner| $name | $type | $remarks |\n"; + } + + return $text; +} + +sub handleOracleInfo { + #use DBD::Oracle; + my ( $session, $params ) = @_; + my %options = %$params; + + my $text .= ""; + + #my $sth = $db->prepare("SELECT SQLITE_VERSION()"); + #$sth->execute(); + + #my $ver = $sth->fetch(); + + ### Print the header + $text .= " * DBI VERSION: $DBI::VERSION\n"; + #$text .= " * DBD::SQLite VERSION: $DBD::SQLite::VERSION\n"; + $text .= " * DBD::Oracle VERSION: $DBD::Oracle::VERSION\n"; + $text .= "\n"; + $text .= "| *DB Version* | "; + return $text; +} + +# ========================================================================== + +=begin twiki + +---+++ restTrackerReset + +=cut + +sub restTrackerReset { + my($session, $params, $theTopic, $theWeb) = @_; + + my $query = TWiki::Func::getCgiQuery(); + my $returntext = ""; + my $grouplist = $TWiki::cfg{Plugins}{EPAgentPlugin}{TrackerResetGroups} || ""; + my @groups = split(',', $grouplist ); + my $haveaccess = 0; + my @errorArray = (); + my @outArray = (); + my $user = $session->{user}; + my $this_subs_name = (caller(0))[3]; + + foreach my $group (@groups) { + if( TWiki::Func::isGroupMember($group)) { + $haveaccess = 1; + last; + } + } + + unless ($haveaccess) { + push(@errorArray, "$this_subs_name - must be member of one of groups in {Plugins}{EPAgentPlugin}{TrackerResetGroups}"); + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + my %inhash = (); + my @requiredInput = ('type'); + foreach my $parmin (@requiredInput) { + $inhash{$parmin} = $query->param($parmin); + unless( $inhash{$parmin} ) { + push(@errorArray, "$this_subs_name - no $parmin"); + $session->writeWarning("$this_subs_name - no $parmin") if $debug; + } + } + + if (@errorArray) { + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + if (($inhash{'type'} ne "sim") && ($inhash{'type'} ne "real")) { + push(@errorArray, "$this_subs_name - no valid value for 'type' passed"); + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + my $db = &_getConnection; + + my $numRows = 0; + + if ($inhash{'type'} eq "sim") { + # FOR SIMULATION + # DO TESTCASES TOO? + $numRows = $db->do("UPDATE milestones SET state = initstate"); + push(@outArray, "$this_subs_name - UPDATE milestones SET state = initstate: $numRows updated"); + $numRows = $db->do("UPDATE workflow SET state = initstate"); + push(@outArray, "$this_subs_name - UPDATE workflow SET state = initstate: $numRows updated"); + $numRows = $db->do("UPDATE apps SET state = initstate"); + push(@outArray, "$this_subs_name - UPDATE apps SET state = initstate: $numRows updated"); + $numRows = $db->do("UPDATE testcase SET state = initstate"); + push(@outArray, "$this_subs_name - UPDATE testcase SET state = initstate: $numRows updated"); + } else { + # FOR REAL DR + $numRows = $db->do("UPDATE milestones SET state = 'WAITING'"); + push(@outArray, "$this_subs_name - UPDATE milestones SET state = 'WAITING' $numRows updated"); + $numRows = $db->do("UPDATE workflow SET state = 'WAITING'"); + push(@outArray, "$this_subs_name - UPDATE workflow SET state = 'WAITING' $numRows updated"); + $numRows = $db->do("UPDATE apps SET state = 'WAITING'"); + push(@outArray, "$this_subs_name - UPDATE apps SET state = 'WAITING' $numRows updated"); + $numRows = $db->do("UPDATE testcase SET state = 'WAITING'"); + push(@outArray, "$this_subs_name - UPDATE testcase SET state = 'WAITING' $numRows updated"); + } + + # FOR ANY + $numRows = $db->do("UPDATE apps SET notifydate = NULL"); + push(@outArray, "$this_subs_name - UPDATE apps SET notifydate = NULL: $numRows updated"); + $numRows = $db->do("UPDATE milestones SET time = eta"); + push(@outArray, "$this_subs_name - UPDATE milestones SET time = eta: $numRows updated"); + #$db->do("UPDATE milestones SET duetime = strftime('%s','now')"); + + $numRows = $db->do("UPDATE milestones SET comptime = NULL, duetime = NULL"); + push(@outArray, "$this_subs_name - UPDATE milestones SET comptime = NULL, duetime = NULL: $numRows updated"); + $numRows = $db->do("UPDATE testcase SET comptime = NULL"); + push(@outArray, "$this_subs_name - UPDATE testcase SET comptime = NULL: $numRows updated"); + + $numRows = $db->do("UPDATE workflow SET currowner=(SELECT milestones.owner FROM milestones + LEFT JOIN wfms ON milestones.topic=wfms.milestone + LEFT JOIN workflow ON workflow.topic=wfms.workflow + WHERE + wfms.ord=(SELECT min(wfms.ord) FROM wfms WHERE wfms.workflow=workflow.topic AND wfms.hold = 0) + AND + wfms.workflow=workflow.topic)"); + push(@outArray, "$this_subs_name - UPDATE workflow SET currowner...: $numRows updated"); + + # Clear notes table + $numRows = $db->do("DELETE FROM notes"); + push(@outArray, "$this_subs_name - DELETE FROM notes: $numRows updated"); + $numRows = $db->do("DELETE FROM prnote"); + push(@outArray, "$this_subs_name - DELETE FROM prnote: $numRows updated"); + $numRows = $db->do("DELETE FROM problemregister"); + push(@outArray, "$this_subs_name - DELETE FROM problemregister $numRows updated"); + + $returntext = "{ \"resetData\": "; + + my $reaSize = @outArray; + my $firstTimeThru = 1; + if ($reaSize > 0) { + $returntext .= " { \"messages\": ["; + foreach my $inval (@outArray) { + if ($firstTimeThru) { + $firstTimeThru = 0; + } else { + $returntext .= ","; + } + $returntext .= "{ \"msg\": \"$inval\" }"; + } + $returntext .= " ] }"; + my $message = "Reset performed - type $inhash{'type'}"; + _writeAudit( $session, $user, 'r', 'Reset', $message ); + } + $returntext .= "}"; + + return $returntext; +} + +# ========================================================================== + +=begin twiki + +---+++ restInsertVal + +=cut + +sub restInsertVal { + use Time::Piece; + my($session, $params, $theTopic, $theWeb) = @_; + + my $query = TWiki::Func::getCgiQuery(); + my $returntext = ""; + my @errorArray = (); + my @outArray = (); + my $this_subs_name = (caller(0))[3]; + + # metricType=IntCounter&metricName=RTBI|ActivationSpecs|ODMSTGA_C1M1|wberuntimeear:EventReceiver&metricValue=1 + + my %inhash = (); + my @requiredInput = ('metricType','metricName','metricValue'); + foreach my $parmin (@requiredInput) { + $inhash{$parmin} = $query->param($parmin); + unless( $inhash{$parmin} ) { + push(@errorArray, "$this_subs_name - no $parmin"); + $session->writeWarning("$this_subs_name - no $parmin") if $debug; + } + } + + if (@errorArray) { + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # Do first split + my @argArray = split(/:/, $inhash{'metricName'}); + if (@argArray != 2) { + push(@errorArray, "$this_subs_name - invalid metricName"); + $session->writeWarning("$this_subs_name - invalid metricName") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # clean up name + (my $invlName = $argArray[1]) =~ s/[^a-zA-Z0-9_-]//g; + # remove spaces + $invlName =~ s/^\s+|\s+$//g; + if (length($invlName) == 0) { + push(@errorArray, "$this_subs_name - illegal interval name"); + $session->writeWarning("$this_subs_name - illegal interval name") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } + + # Do second split + my @pathArray = split(/\|/, $argArray[0]); + # Push interval on end of array + push @pathArray, $invlName; + my $parentID = 1; + my $isIntervalEntry = 1; + my @paCopy = @pathArray; + + # Get database connection + my $db = &_getConnection; + my $numRows = 0; + + foreach my $tpathLvl (@pathArray) { + (my $pathLvl = $tpathLvl) =~ s/[^a-zA-Z0-9_-]//g; + #print "found path level: $pathLvl \n"; + if (@paCopy == 1) { + #print "Size of array is 1\n"; + $isIntervalEntry = 0; + } + my $newPID = &_handleDirectoryQuery(\$db, $parentID, $pathLvl, $isIntervalEntry); + if ($newPID =~/x/i) { + # !!!! NOTHING FOUND, SO SHOULD START CREATING + # Send $parentID & @paCopy to routine to create new path(s) + $parentID = _createPathFromArray(\$db, $parentID, \@paCopy); + last; + } elsif ($newPID =~/f/i) { + # "f" means a mismatch, so fail + push(@errorArray, "$this_subs_name - mismatch type found"); + $session->writeWarning("$this_subs_name - mismatch type found") if $debug; + $returntext .= _returnJSONerror("1011", \@errorArray); + return $returntext; + } else { + $parentID = $newPID; + shift @paCopy; + } + } + my $rowsUpdated = _insertValue(\$db, $parentID, $inhash{'metricValue'}); + push(@outArray, "$inhash{'metricName'}: $rowsUpdated row(s) updated"); + + $returntext = "{ \"epagent\": "; + + my $reaSize = @outArray; + my $firstTimeThru = 1; + if ($reaSize > 0) { + $returntext .= " { \"messages\": ["; + foreach my $inval (@outArray) { + if ($firstTimeThru) { + $firstTimeThru = 0; + } else { + $returntext .= ","; + } + $returntext .= "{ \"msg\": \"$inval\" }"; + } + $returntext .= " ] }"; + } + $returntext .= "}"; + + return $returntext; +} + +sub _handleDirectoryQuery +{ + my $this_subs_name = (caller(0))[3]; + my $inDb = $_[0]; + my $inPid = $_[1]; + my $inMatch = $_[2]; + my $isIntNode = $_[3]; + my $db = $$inDb; + my $success = 1; + my $retVal = 'x'; + my $getSelStmt03 = $db->prepare_cached("SELECT closure.child, nodes.name, nodes.internal FROM closure JOIN nodes ON(closure.child = nodes.id) WHERE closure.parent = ? and depth = 1"); + $success &&= $getSelStmt03->execute($inPid); + my $allx = $getSelStmt03->fetchall_arrayref; + if ($getSelStmt03->rows == 0) { + # NO Children + return $retVal; + } else { + foreach my $rowx (@$allx) { + my ($ci, $ln, $ntype) = @$rowx; + if ($ln =~/$inMatch/i) { + #print "SUCCESS: match found! $ci:$ln:$ntype \n"; + if ($isIntNode != $ntype) { + # found match, but different type, so fail + #print "TYPE: Different type found \n"; + $retVal = 'f'; + last; + } + $retVal = $ci; + last; + } + } + } + return $retVal; +} + +sub _createPathFromArray +{ + my $this_subs_name = (caller(0))[3]; + my $inDb = $_[0]; + my $inPid = $_[1]; + my @inMatch = @{$_[2]}; + my $db = $$inDb; + my $success = 1; + my $retVal = 'x'; + my $iType = 1; + my @inCopy = @inMatch; + foreach my $spathLvl (@inMatch) { + if (@inCopy == 1) { + $iType = 0; + } + (my $xpathLvl = $spathLvl) =~ s/[^a-zA-Z0-9_-]//g; + #print "!! Will want to create: $xpathLvl \n"; + ## ADD NEW NODE + #print "Generating new num\n"; + my $newNode = $db->selectrow_array("SELECT max(id)+1 FROM nodes"); + #print "Inserting location\n"; + my $updateL_handle = $db->prepare_cached('INSERT INTO nodes (id, parent, name, internal) VALUES (?, ?, ?, ?)'); + $success &&= $updateL_handle->execute($newNode,$inPid,$xpathLvl,$iType); + #print "Inserting base LH\n"; + my $updateLH1_handle = $db->prepare_cached('INSERT INTO closure (parent, child, depth) VALUES (?, ?, ?)'); + $success &&= $updateLH1_handle->execute($newNode,$newNode,0); + #print "Inserting full LH\n"; + my $updateLH2_handle = $db->prepare_cached('INSERT INTO closure(parent, child, depth) SELECT p.parent, c.child, p.depth+c.depth+1 FROM closure p, closure c WHERE p.child = ? AND c.parent = ?'); + $success &&= $updateLH2_handle->execute($inPid,$newNode); + $inPid = $newNode; + shift @inCopy; + } + return $inPid; +} + +sub _insertValue +{ + my $this_subs_name = (caller(0))[3]; + my $inDb = $_[0]; + my $inPid = $_[1]; + my $inVal = $_[2]; + my $db = $$inDb; + my $retVal = 'x'; + my $updateTS_handle = $db->prepare_cached('INSERT INTO entries (loc_id, intval) VALUES (?, ?)'); + my $numRows = $updateTS_handle->execute($inPid,$inVal); + return $numRows; +} + +# ========================================================================== + +=begin twiki + +---+++ handleShowErrorCodes + +=cut + +sub handleShowErrorCodes { + my ( $session, $params ) = @_; + my %options = %$params; + + my $text .= ""; + my $inECref = &_getErrorCodeHash(); + my %errorCodes = %{$inECref}; + + $text .= "| *Code* | *Name* | *Desc & Help* |\n"; + for my $hkey ( keys %errorCodes ) { + $text .= "| $hkey| $errorCodes{$hkey}[0] | $errorCodes{$hkey}[1] |\n"; + } + + return $text; +} + + +sub handleListEnv { + my ( $session, $params ) = @_; + + my $text = ''; + + $text .= "<table>\n"; + $text .= "<tr><th> *Key* </th><th> *Value* </th></tr>\n"; + foreach (sort keys %ENV) { + $text .= "<tr><td> $_ </td><td> $ENV{$_} </td></tr>\n"; + } + $text .= "</table>\n"; + + return $text; +} + +sub _trim($) +{ + my $string = shift; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; +} + +sub _returnJSONerror { + #my ( $code, $msg, $desc ) = @_; + my ( $code, $extraInfo ) = @_; + + my $text = "{"; + + my $inECref = &_getErrorCodeHash(); + my %errorCodes = %{$inECref}; + my @receivedErrors = @{$extraInfo}; + my $reaSize = @receivedErrors; + + if (exists $errorCodes{$code}) { + $text .= " \"errors\": {"; + $text .= " \"code\" : \"$code\","; + $text .= " \"message\" : \"$errorCodes{$code}[0]\","; + $text .= " \"description\" : \"$errorCodes{$code}[1]\""; + my $firstTimeThru = 1; + if ($reaSize > 0) { + $text .= ","; + $text .= " \"errors\" : ["; + foreach my $inval (@receivedErrors) { + if ($firstTimeThru) { + $firstTimeThru = 0; + } else { + $text .= ","; + } + $text .= "{ \"error\": \"$inval\" }"; + } + $text .= " ]"; + } + $text .= " }"; + } else { + $text .= " \"errors\": {"; + $text .= " \"code\" : \"$code\","; + $text .= " \"message\" : \"Bad error code\","; + $text .= " \"description\" : \"Why did you pass this undefined error code?\""; + $text .= " }"; + } + + $text .= "}"; + + return $text; +} + +# ========================================================================== + +=begin twiki + +---+++ _returnJSONoutput + +=cut + +sub _returnJSONoutput { + my ( $extraInfo ) = @_; + + my $text = "{"; + + my @receivedInput = @{$extraInfo}; + my $reaSize = @receivedInput; + + $text .= " \"outdata\": {"; + my $firstTimeThru = 1; + if ($reaSize > 0) { + # $text .= ","; + $text .= " \"info\" : ["; + foreach my $inval (@receivedInput) { + if ($firstTimeThru) { + $firstTimeThru = 0; + } else { + $text .= ","; + } + $text .= "{ \"msg\": \"$inval\" }"; + } + $text .= " ]"; + } + $text .= " }"; + + $text .= "}"; + + return $text; +} + +# ========================================================================== + +=begin twiki + +---+++ _getErrorCodeHash + * Definition of error codes + * Returns hash reference + +=cut + +sub _getErrorCodeHash { + # error codes, with array of [ 'base message', 'extended message & help' ] + my $errorCodes; + $errorCodes->{'1001'} = [ 'No parameter passed' , 'You must pass a parameter' ]; + $errorCodes->{'1002'} = [ 'Required parameter not passed: Xparmin' , 'You must provide the parameter' ]; + $errorCodes->{'1003'} = [ 'No data' , 'No data was returned from the database' ]; + $errorCodes->{'1004'} = [ 'No rows updated' , 'No data was updated in the database' ]; + $errorCodes->{'1010'} = [ 'Request must be POST' , 'Set the POST' ]; + $errorCodes->{'1011'} = [ 'Errors!' , 'Fix your errors' ]; + $errorCodes->{'1100'} = [ 'Delete failed' , 'Delete failed' ]; + $errorCodes->{'1101'} = [ 'Prepare failed' , 'Prepare failed' ]; + $errorCodes->{'1102'} = [ 'Update failed' , 'Update failed' ]; + $errorCodes->{'1103'} = [ 'TNX failed' , 'Transaction failed' ]; + return $errorCodes; +} + +# ========================================================================== + +=begin twiki + +---+++ _returnSQLHash + * SQL! + * Returns hash reference + +=cut + +sub _returnSQLHash { + my $trackerSql; + $trackerSql->{'allAppsNotOOS'} = "SELECT apps.topic, apps.name, apps.type, apps.pri, apps.rto, apps.description, apps.auto, apps.notifydate, apps.state FROM apps where apps.state <> 'OUTOFSCOPE'"; + $trackerSql->{'allApps'} = "SELECT apps.topic, apps.name, apps.type, apps.pri, apps.rto, apps.description, apps.auto, apps.state, apps.initstate FROM apps"; + $trackerSql->{'testCaseInfo'} = "SELECT apptc.app, apptc.testcase, testcase.state, testcase.name FROM apptc LEFT JOIN testcase ON apptc.testcase=testcase.topic"; + $trackerSql->{'milestoneGoodies'} = "SELECT appms.app, appms.milestone, milestones.state, milestones.duetime, milestones.comptime FROM appms LEFT JOIN milestones ON appms.milestone=milestones.topic"; + $trackerSql->{'appList'} = "SELECT apps.topic, apps.name, apps.type, apps.pri, apps.rto, apps.description, apps.state FROM apps"; + $trackerSql->{'testCaseList'} = "SELECT testcase.topic, testcase.name, testcase.description, testcase.importance FROM testcase"; + + # milestones(id INTEGER PRIMARY KEY, topic TEXT, name TEXT, owner TEXT, eta INTEGER, time INTEGER, description TEXT, initstate TEXT, cmems TEXT, state TEXT, basetime INTEGER, duetime INTEGER, comptime INTEGER, runnernote TEXT, forhotfail INTEGER, ack INTEGER) + # + #$trackerSql->{'milestoneList'} = "SELECT milestones.topic, milestones.name, milestones.owner, milestones.eta, milestones.time, milestones.description, milestones.initstate, milestones.state FROM milestones"; + $trackerSql->{'milestoneList'} = "SELECT milestones.topic, milestones.name, milestones.owner, milestones.eta, milestones.time, milestones.description, + milestones.initstate, milestones.state, milestones.basetime, milestones.duetime, milestones.comptime, + CASE WHEN EXISTS (SELECT wfms.workflow FROM wfms WHERE wfms.milestone = milestones.topic AND wfms.hold = 0) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT wfms.workflow FROM wfms WHERE wfms.milestone = milestones.topic AND wfms.hold = 1) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT mscl.parent FROM mscl WHERE mscl.parent = milestones.topic) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT mscl.child FROM mscl WHERE mscl.child = milestones.topic) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT appms.app FROM appms WHERE appms.milestone = milestones.topic) THEN '1' ELSE '0' END + FROM milestones"; + + $trackerSql->{'milestoneListNOOOS'} = "SELECT DISTINCT milestones.topic, milestones.name, milestones.owner, milestones.eta, milestones.time, milestones.description, + milestones.initstate, milestones.state, milestones.basetime, milestones.duetime, milestones.comptime, milestones.runnernote, + CASE WHEN EXISTS (SELECT wfms.workflow FROM wfms WHERE wfms.milestone = milestones.topic AND wfms.hold = 0) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT wfms.workflow FROM wfms WHERE wfms.milestone = milestones.topic AND wfms.hold = 1) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT mscl.parent FROM mscl WHERE mscl.parent = milestones.topic) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT mscl.child FROM mscl WHERE mscl.child = milestones.topic) THEN '1' ELSE '0' END, + CASE WHEN EXISTS (SELECT appms.app FROM appms WHERE appms.milestone = milestones.topic) THEN '1' ELSE '0' END + FROM wfms LEFT JOIN milestones ON milestones.topic=wfms.milestone WHERE milestones.state <> 'OUTOFSCOPE' AND milestones.state <> 'COMPLETE'"; + #FROM milestones LEFT JOIN wfms ON milestones.topic=wfms.milestone WHERE milestones.state <> 'OUTOFSCOPE' AND milestones.state <> 'COMPLETE'"; + #FROM milestones WHERE milestones.state <> 'OUTOFSCOPE' AND milestones.state <> 'COMPLETE'"; + #FROM milestones INNER JOIN wfms ON wfms.milestone=milestones.topic WHERE milestones.state <> 'OUTOFSCOPE' AND milestones.state <> 'COMPLETE'"; + #my $availmsinfo = $db->selectall_arrayref("SELECT milestones.topic, milestones.name FROM milestones LEFT JOIN wfms ON milestones.topic=wfms.milestone WHERE wfms.milestone IS NULL"); + + return $trackerSql; +} + +# ========================================================================== + +=begin twiki + +---+++ _getSQL + +=cut + +sub _getSQL { + my ( $code ) = @_; + + my $inHashRef = &_returnSQLHash(); + my %sqlHash = %{$inHashRef}; + + if (exists $sqlHash{$code}) { + return $sqlHash{$code}; + } else { + my $rtnGarbage = "garbage"; + return $rtnGarbage; + } +} + +sub _pushInMatrix +{ + # http://www.troubleshooters.com/codecorn/littperl/perlsub.htm#Dereferencing_in_Place + my $incoming = $_[0]; + foreach my $row (@$incoming) { + push @{$_[1]}, \@$row; + } + +} + +# ========================================================================== + +=begin twiki + +---+++ _pushInHash + +=cut + +sub _pushInHash +{ + # return 1 for new hit found, zero for no hits + my $incoming = $_[0]; + my @newarray = @{$incoming}; + my $paramhash = $_[1]; + my $inSession = $_[2]; + my $session = $$inSession; + $session->writeWarning(" ==> inside _pushInHash"); + my $foundNewHit = 0; + foreach my $row (@newarray) { + my ($a, $b, $c) = @$row; + my $newkey = "${a}${b}${c}"; + unless (exists $paramhash->{$newkey}) { + $paramhash->{$newkey} = 'x'; + $foundNewHit = 1; + $session->writeWarning(" ==> _pushInHash: $newkey <=="); + } + } + return $foundNewHit; + +} + +# ========================================================================== + +=begin twiki + +---+++ _pushRowInMatrix + +=cut + +sub _pushRowInMatrix +{ + my @newarray = @{$_[0]}; + my $incoming = $_[0]; + push @{$_[1]}, \@newarray; +} + +# ========================================================================== + +=begin twiki + +---+++ _pushRowInHash + +=cut + +sub _pushRowInHash +{ + # return 1 for new hit found, zero for no hits + my @newarray = @{$_[0]}; + my $paramhash = $_[1]; + my $inSession = $_[2]; + my $session = $$inSession; + my $foundNewHit = 0; + my ($a, $b, $c, $d) = @newarray; + my $newkey = "${a}${b}${c}"; + unless (exists $paramhash->{$newkey}) { + $paramhash->{$newkey} = 'x'; + $foundNewHit = 1; + $session->writeWarning(" ==> _pushRowInHash key: $newkey") if $debug; + } + return $foundNewHit; + +} + +# ========================================================================== + +=begin twiki + +---+++ _pushStringInHash + +=cut + +sub _pushStringInHash +{ + # return 1 for new hit found, zero for no hits + my $newstring = $_[0]; + my $paramhash = $_[1]; + my $inSession = $_[2]; + my $session = $$inSession; + my $foundNewHit = 0; + unless (exists $paramhash->{$newstring}) { + $paramhash->{$newstring} = 'x'; + $foundNewHit = 1; + $session->writeWarning(" ==> _pushStringInHash key: $newstring") if $debug; + } + return $foundNewHit; + +} + +# ========================================================================== + +=begin twiki + +---+++ _bindAndExecute + +=cut + +sub _bindAndExecute +{ + my $localStatement = $_[0]; + my $parms = $_[1]; + foreach my $val (@{$parms}) { + $localStatement->bind_param( $val->[0], $val->[1] ); + } + $localStatement->execute(); +} + +# ========================================================================== + +=begin twiki + +---+++ _printHash + +=cut + +sub _printHash +{ + my $hashname = $_[0]; + my $hash_ref = $_[1]; + my $inSession = $_[2]; + my $session = $$inSession; + + while( my ($k, $v) = each %$hash_ref ) { + $session->writeWarning(" ==> _printHash \"$hashname\" key:$k value:$v "); + } +} + +1; + Added: twiki/trunk/EPAgentPlugin/working/work_areas/EPAgentPlugin/epagent.db =================================================================== (Binary files differ) Property changes on: twiki/trunk/EPAgentPlugin/working/work_areas/EPAgentPlugin/epagent.db ___________________________________________________________________ Added: svn:mime-type + application/octet-stream |
From: <de...@de...> - 2017-01-27 13:21:19
|
Author: AaronLWalker Date: 2017-01-27 13:19:55 +0000 (Fri, 27 Jan 2017) New Revision: 30302 Trac url: http://develop.twiki.org/trac/changeset/30302 Added: twiki/trunk/DateJSPlugin/data/ twiki/trunk/DateJSPlugin/data/TWiki/ twiki/trunk/DateJSPlugin/data/TWiki/DateJSPlugin.txt twiki/trunk/DateJSPlugin/lib/ twiki/trunk/DateJSPlugin/lib/TWiki/ twiki/trunk/DateJSPlugin/lib/TWiki/Plugins/ twiki/trunk/DateJSPlugin/lib/TWiki/Plugins/DateJSPlugin.pm twiki/trunk/DateJSPlugin/pub/ twiki/trunk/DateJSPlugin/pub/TWiki/ twiki/trunk/DateJSPlugin/pub/TWiki/DateJSPlugin/ twiki/trunk/DateJSPlugin/pub/TWiki/DateJSPlugin/date.js Log: Item7771: Initial population of DateJSPlugin Added: twiki/trunk/DateJSPlugin/data/TWiki/DateJSPlugin.txt =================================================================== --- twiki/trunk/DateJSPlugin/data/TWiki/DateJSPlugin.txt (rev 0) +++ twiki/trunk/DateJSPlugin/data/TWiki/DateJSPlugin.txt 2017-01-27 13:19:55 UTC (rev 30302) @@ -0,0 +1,80 @@ +%META:TOPICINFO{author="AaronWalker" date="1435086146" format="1.1" version="1.2"}% +---+!! !DateJSPlugin +<!-- + Contributions to this plugin are appreciated. Please update the plugin page at + http://twiki.org/cgi-bin/view/Plugins/DateJSPlugin or provide feedback at + http://twiki.org/cgi-bin/view/Plugins/DateJSPluginDev. + If you are a TWiki contributor please update the plugin in the SVN repository. +--> +<sticky><div style="float:right; background-color:#EBEEF0; margin:0 0 20px 20px; padding: 0 10px 0 10px;"> +%TOC{title="Page contents"}% +</div></sticky> +%SHORTDESCRIPTION% + +---++ Introduction + +Describe the plugin here + +---++ Syntax Rules + +=%<nop>EXAMPLEVAR{"..."}%= + +| *Parameter* | *Explanation* | *Default* | +| ="..."= | Default parameter. | (none) | +| =format="..."= | Format: ... | ="$name"= | + +---++ Examples + + * =%<nop>EXAMPLEVAR{}%= expands to: %EXAMPLEVAR{}% + * + +---++ Plugin Installation & Configuration + +You do not need to install anything on the browser to use this plugin. These instructions are for the administrator who installs the plugin on the TWiki server. +%TWISTY{ + mode="div" + showlink="Show details %ICONURL{toggleopen}% " + hidelink="Hide details %ICONURL{toggleclose}% " +}% + + * For an __automated installation__, run the [[%SCRIPTURL{configure}%][configure]] script and follow "Find More Extensions" in the in the __Extensions__ section. + * See the [[http://twiki.org/cgi-bin/view/Plugins/BuildContribInstallationSupplement][installation supplement]] on TWiki.org for more information. + + * Or, follow these __manual installation__ steps: + * Download the ZIP file from the Plugins home (see below). + * Unzip ==%TOPIC%.zip== in your twiki installation directory. Content: + | *File:* | *Description:* | + | ==data/TWiki/%TOPIC%.txt== | Plugin topic | + | ==lib/TWiki/Plugins/%TOPIC%.pm== | Plugin Perl module | + * Set the ownership of the extracted directories and files to the webserver user. + * Install the dependencies (if any). + + * Plugin __configuration and testing__: + * Run the [[%SCRIPTURL{configure}%][configure]] script and enable the plugin in the __Plugins__ section. + * Configure additional plugin settings in the __Extensions__ section if needed. + * Test if the installation was successful using the example above. + +%ENDTWISTY% + +---++ Plugin Info + + * One line description, is shown in the %SYSTEMWEB%.TextFormattingRules topic: + * Set SHORTDESCRIPTION = one line description here +%TABLE{ tablewidth="100%" columnwidths="170," }% +| Plugin Author: | TWiki:Main.AaronLWalker | +| Copyright: | © 2015 TWiki:Main.AaronLWalker <br /> © 2015 TWiki:TWiki.TWikiContributor | +| License: | GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]]) | +| Plugin Version: | 2017-01-23 (V1.000) | +| Change History: | <!-- versions below in reverse order --> | +| 2017-01-23: | Initial version | +| TWiki Dependency: | $TWiki::Plugins::VERSION 1.1 | +| CPAN Dependencies: | none | +| Other Dependencies: | none | +| Perl Version: | 5.005 | +| [[TWiki:Plugins.Benchmark][Plugin Benchmark]]: | %SYSTEMWEB%.GoodStyle nn%, %SYSTEMWEB%.FormattedSearch nn%, %TOPIC% nn% | +| Plugin Home: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC% | +| Feedback: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC%Dev | +| Appraisal: | http://TWiki.org/cgi-bin/view/Plugins/%TOPIC%Appraisal | + +__Related Topics:__ %SYSTEMWEB%.TWikiPlugins, %SYSTEMWEB%.DeveloperDocumentationCategory, %SYSTEMWEB%.AdminDocumentationCategory, %SYSTEMWEB%.TWikiPreferences + Added: twiki/trunk/DateJSPlugin/lib/TWiki/Plugins/DateJSPlugin.pm =================================================================== --- twiki/trunk/DateJSPlugin/lib/TWiki/Plugins/DateJSPlugin.pm (rev 0) +++ twiki/trunk/DateJSPlugin/lib/TWiki/Plugins/DateJSPlugin.pm 2017-01-27 13:19:55 UTC (rev 30302) @@ -0,0 +1,63 @@ +# Plugin for TWiki Enterprise Collaboration Platform, http://TWiki.org/ +# +# Copyright (c) 2007-2008 Michael Daum, http://michaeldaumconsulting.com +# Copyright (c) 2007-2011 TWiki Contributors. All Rights Reserved. +# TWiki Contributors are listed in the AUTHORS file in the root of +# this distribution. +# NOTE: Please extend that file, not this notice. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. For +# more details read LICENSE in the root of this distribution. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# For licensing info read LICENSE file in the TWiki root. + +package TWiki::Plugins::DateJSPlugin; +use strict; +use vars qw( + $VERSION $RELEASE $SHORTDESCRIPTION + $NO_PREFS_IN_TOPIC + $doneInit $doneHeader + $dtPubUrlPath $header +); + +$VERSION = '$Rev: 20836 (2017-01-23) $'; +$RELEASE = '2017-01-23'; +$SHORTDESCRIPTION = '<nop>DateJS library for TWiki'; +$NO_PREFS_IN_TOPIC = 1; + +$dtPubUrlPath = '%PUBURLPATH%/%SYSTEMWEB%/DateJSPlugin'; +$header = "<script type=\"text/javascript\" src=\"$dtPubUrlPath/date.js\"></script> \n"; + +############################################################################### +sub initPlugin { + my( $topic, $web, $user, $installWeb ) = @_; + + $doneInit = 0; + $doneHeader = 0; + + TWiki::Func::registerTagHandler('DATEJS', \&handleDateJSBase ); + + return 1; +} + +############################################################################### +sub handleDateJSBase { + my ($session, $params, $theTopic, $theWeb) = @_; + + return if $doneHeader; + $doneHeader = 1 if ($_[0] =~ s/<head>(.*?[\r\n]+)/<head>$1$header/o); + + TWiki::Func::addToHEAD( + "datejs", + $header + ); +} + +1; Property changes on: twiki/trunk/DateJSPlugin/lib/TWiki/Plugins/DateJSPlugin.pm ___________________________________________________________________ Added: svn:executable + * Added: twiki/trunk/DateJSPlugin/pub/TWiki/DateJSPlugin/date.js =================================================================== --- twiki/trunk/DateJSPlugin/pub/TWiki/DateJSPlugin/date.js (rev 0) +++ twiki/trunk/DateJSPlugin/pub/TWiki/DateJSPlugin/date.js 2017-01-27 13:19:55 UTC (rev 30302) @@ -0,0 +1,104 @@ +/** + * Version: 1.0 Alpha-1 + * Build Date: 13-Nov-2007 + * Copyright (c) 2006-2007, Coolite Inc. (http://www.coolite.com/). All rights reserved. + * License: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/. + * Website: http://www.datejs.com/ or http://www.coolite.com/datejs/ + */ +Date.CultureInfo={name:"en-US",englishName:"English (United States)",nativeName:"English (United States)",dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbreviatedDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],shortestDayNames:["Su","Mo","Tu","We","Th","Fr","Sa"],firstLetterDayNames:["S","M","T","W","T","F","S"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbreviatedMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],amDesignator:"AM",pmDesignator:"PM",firstDayOfWeek:0,twoDigitYearMax:2029,dateElementOrder:"mdy",formatPatterns:{shortDate:"M/d/yyyy",longDate:"dddd, MMMM dd, yyyy",shortTime:"h:mm tt",longTime:"h:mm:ss tt",fullDateTime:"dddd, MMMM dd, yyyy h:mm:ss tt",sortableDateTime:"yyyy-MM-ddTHH:mm:ss",universalSortableDateTime:"yyyy-MM-dd HH:mm:ssZ",rfc1123:"ddd, dd MMM yyyy HH:mm:ss GMT",monthDay:"MMMM dd",yearMonth:"MM! MM, yyyy"},regexPatterns:{jan:/^jan(uary)?/i,feb:/^feb(ruary)?/i,mar:/^mar(ch)?/i,apr:/^apr(il)?/i,may:/^may/i,jun:/^jun(e)?/i,jul:/^jul(y)?/i,aug:/^aug(ust)?/i,sep:/^sep(t(ember)?)?/i,oct:/^oct(ober)?/i,nov:/^nov(ember)?/i,dec:/^dec(ember)?/i,sun:/^su(n(day)?)?/i,mon:/^mo(n(day)?)?/i,tue:/^tu(e(s(day)?)?)?/i,wed:/^we(d(nesday)?)?/i,thu:/^th(u(r(s(day)?)?)?)?/i,fri:/^fr(i(day)?)?/i,sat:/^sa(t(urday)?)?/i,future:/^next/i,past:/^last|past|prev(ious)?/i,add:/^(\+|after|from)/i,subtract:/^(\-|before|ago)/i,yesterday:/^yesterday/i,today:/^t(oday)?/i,tomorrow:/^tomorrow/i,now:/^n(ow)?/i,millisecond:/^ms|milli(second)?s?/i,second:/^sec(ond)?s?/i,minute:/^min(ute)?s?/i,hour:/^h(ou)?rs?/i,week:/^w(ee)?k/i,month:/^m(o(nth)?s?)?/i,day:/^d(ays?)?/i,year:/^y((ea)?rs?)?/i,shortMeridian:/^(a|p)/i,longMeridian:/^(a\.?m?\.?|p\.?m?\.?)/i,timezone:/^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt)/i,ordinalSuffix:/^\s*(st|nd|rd|th)/i,timeContext:/^\s*(\:|a|p)/i},abbrevia! tedTimeZoneStandard:{GMT:"-000",EST:"-0400",CST:"-0500",MST:"-! 0600",PS T:"-0700"},abbreviatedTimeZoneDST:{GMT:"-000",EDT:"-0500",CDT:"-0600",MDT:"-0700",PDT:"-0800"}}; +Date.getMonthNumberFromName=function(name){var n=Date.CultureInfo.monthNames,m=Date.CultureInfo.abbreviatedMonthNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}} +return-1;};Date.getDayNumberFromName=function(name){var n=Date.CultureInfo.dayNames,m=Date.CultureInfo.abbreviatedDayNames,o=Date.CultureInfo.shortestDayNames,s=name.toLowerCase();for(var i=0;i<n.length;i++){if(n[i].toLowerCase()==s||m[i].toLowerCase()==s){return i;}} +return-1;};Date.isLeapYear=function(year){return(((year%4===0)&&(year%100!==0))||(year%400===0));};Date.getDaysInMonth=function(year,month){return[31,(Date.isLeapYear(year)?29:28),31,30,31,30,31,31,30,31,30,31][month];};Date.getTimezoneOffset=function(s,dst){return(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST[s.toUpperCase()]:Date.CultureInfo.abbreviatedTimeZoneStandard[s.toUpperCase()];};Date.getTimezoneAbbreviation=function(offset,dst){var n=(dst||false)?Date.CultureInfo.abbreviatedTimeZoneDST:Date.CultureInfo.abbreviatedTimeZoneStandard,p;for(p in n){if(n[p]===offset){return p;}} +return null;};Date.prototype.clone=function(){return new Date(this.getTime());};Date.prototype.compareTo=function(date){if(isNaN(this)){throw new Error(this);} +if(date instanceof Date&&!isNaN(date)){return(this>date)?1:(this<date)?-1:0;}else{throw new TypeError(date);}};Date.prototype.equals=function(date){return(this.compareTo(date)===0);};Date.prototype.between=function(start,end){var t=this.getTime();return t>=start.getTime()&&t<=end.getTime();};Date.prototype.addMilliseconds=function(value){this.setMilliseconds(this.getMilliseconds()+value);return this;};Date.prototype.addSeconds=function(value){return this.addMilliseconds(value*1000);};Date.prototype.addMinutes=function(value){return this.addMilliseconds(value*60000);};Date.prototype.addHours=function(value){return this.addMilliseconds(value*3600000);};Date.prototype.addDays=function(value){return this.addMilliseconds(value*86400000);};Date.prototype.addWeeks=function(value){return this.addMilliseconds(value*604800000);};Date.prototype.addMonths=function(value){var n=this.getDate();this.setDate(1);this.setMonth(this.getMonth()+value);this.setDate(Math.min(n,this.getDaysInMont! h()));return this;};Date.prototype.addYears=function(value){return this.addMonths(value*12);};Date.prototype.add=function(config){if(typeof config=="number"){this._orient=config;return this;} +var x=config;if(x.millisecond||x.milliseconds){this.addMilliseconds(x.millisecond||x.milliseconds);} +if(x.second||x.seconds){this.addSeconds(x.second||x.seconds);} +if(x.minute||x.minutes){this.addMinutes(x.minute||x.minutes);} +if(x.hour||x.hours){this.addHours(x.hour||x.hours);} +if(x.month||x.months){this.addMonths(x.month||x.months);} +if(x.year||x.years){this.addYears(x.year||x.years);} +if(x.day||x.days){this.addDays(x.day||x.days);} +return this;};Date._validate=function(value,min,max,name){if(typeof value!="number"){throw new TypeError(value+" is not a Number.");}else if(value<min||value>max){throw new RangeError(value+" is not a valid value for "+name+".");} +return true;};Date.validateMillisecond=function(n){return Date._validate(n,0,999,"milliseconds");};Date.validateSecond=function(n){return Date._validate(n,0,59,"seconds");};Date.validateMinute=function(n){return Date._validate(n,0,59,"minutes");};Date.validateHour=function(n){return Date._validate(n,0,23,"hours");};Date.validateDay=function(n,year,month){return Date._validate(n,1,Date.getDaysInMonth(year,month),"days");};Date.validateMonth=function(n){return Date._validate(n,0,11,"months");};Date.validateYear=function(n){return Date._validate(n,1,9999,"seconds");};Date.prototype.set=function(config){var x=config;if(!x.millisecond&&x.millisecond!==0){x.millisecond=-1;} +if(!x.second&&x.second!==0){x.second=-1;} +if(!x.minute&&x.minute!==0){x.minute=-1;} +if(!x.hour&&x.hour!==0){x.hour=-1;} +if(!x.day&&x.day!==0){x.day=-1;} +if(!x.month&&x.month!==0){x.month=-1;} +if(!x.year&&x.year!==0){x.year=-1;} +if(x.millisecond!=-1&&Date.validateMillisecond(x.millisecond)){this.addMilliseconds(x.millisecond-this.getMilliseconds());} +if(x.second!=-1&&Date.validateSecond(x.second)){this.addSeconds(x.second-this.getSeconds());} +if(x.minute!=-1&&Date.validateMinute(x.minute)){this.addMinutes(x.minute-this.getMinutes());} +if(x.hour!=-1&&Date.validateHour(x.hour)){this.addHours(x.hour-this.getHours());} +if(x.month!==-1&&Date.validateMonth(x.month)){this.addMonths(x.month-this.getMonth());} +if(x.year!=-1&&Date.validateYear(x.year)){this.addYears(x.year-this.getFullYear());} +if(x.day!=-1&&Date.validateDay(x.day,this.getFullYear(),this.getMonth())){this.addDays(x.day-this.getDate());} +if(x.timezone){this.setTimezone(x.timezone);} +if(x.timezoneOffset){this.setTimezoneOffset(x.timezoneOffset);} +return this;};Date.prototype.clearTime=function(){this.setHours(0);this.setMinutes(0);this.setSeconds(0);this.setMilliseconds(0);return this;};Date.prototype.isLeapYear=function(){var y=this.getFullYear();return(((y%4===0)&&(y%100!==0))||(y%400===0));};Date.prototype.isWeekday=function(){return!(this.is().sat()||this.is().sun());};Date.prototype.getDaysInMonth=function(){return Date.getDaysInMonth(this.getFullYear(),this.getMonth());};Date.prototype.moveToFirstDayOfMonth=function(){return this.set({day:1});};Date.prototype.moveToLastDayOfMonth=function(){return this.set({day:this.getDaysInMonth()});};Date.prototype.moveToDayOfWeek=function(day,orient){var diff=(day-this.getDay()+7*(orient||+1))%7;return this.addDays((diff===0)?diff+=7*(orient||+1):diff);};Date.prototype.moveToMonth=function(month,orient){var diff=(month-this.getMonth()+12*(orient||+1))%12;return this.addMonths((diff===0)?diff+=12*(orient||+1):diff);};Date.prototype.getDayOfYear=function(){return Math.floor(! (this-new Date(this.getFullYear(),0,1))/86400000);};Date.prototype.getWeekOfYear=function(firstDayOfWeek){var y=this.getFullYear(),m=this.getMonth(),d=this.getDate();var dow=firstDayOfWeek||Date.CultureInfo.firstDayOfWeek;var offset=7+1-new Date(y,0,1).getDay();if(offset==8){offset=1;} +var daynum=((Date.UTC(y,m,d,0,0,0)-Date.UTC(y,0,1,0,0,0))/86400000)+1;var w=Math.floor((daynum-offset+7)/7);if(w===dow){y--;var prevOffset=7+1-new Date(y,0,1).getDay();if(prevOffset==2||prevOffset==8){w=53;}else{w=52;}} +return w;};Date.prototype.isDST=function(){console.log('isDST');return this.toString().match(/(E|C|M|P)(S|D)T/)[2]=="D";};Date.prototype.getTimezone=function(){return Date.getTimezoneAbbreviation(this.getUTCOffset,this.isDST());};Date.prototype.setTimezoneOffset=function(s){var here=this.getTimezoneOffset(),there=Number(s)*-6/10;this.addMinutes(there-here);return this;};Date.prototype.setTimezone=function(s){return this.setTimezoneOffset(Date.getTimezoneOffset(s));};Date.prototype.getUTCOffset=function(){var n=this.getTimezoneOffset()*-10/6,r;if(n<0){r=(n-10000).toString();return r[0]+r.substr(2);}else{r=(n+10000).toString();return"+"+r.substr(1);}};Date.prototype.getDayName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedDayNames[this.getDay()]:Date.CultureInfo.dayNames[this.getDay()];};Date.prototype.getMonthName=function(abbrev){return abbrev?Date.CultureInfo.abbreviatedMonthNames[this.getMonth()]:Date.CultureInfo.monthNames[this.getMonth()];};Date.prototype._! toString=Date.prototype.toString;Date.prototype.toString=function(format){var self=this;var p=function p(s){return(s.toString().length==1)?"0"+s:s;};return format?format.replace(/dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?/g,function(format){switch(format){case"hh":return p(self.getHours()<13?self.getHours():(self.getHours()-12));case"h":return self.getHours()<13?self.getHours():(self.getHours()-12);case"HH":return p(self.getHours());case"H":return self.getHours();case"mm":return p(self.getMinutes());case"m":return self.getMinutes();case"ss":return p(self.getSeconds());case"s":return self.getSeconds();case"yyyy":return self.getFullYear();case"yy":return self.getFullYear().toString().substring(2,4);case"dddd":return self.getDayName();case"ddd":return self.getDayName(true);case"dd":return p(self.getDate());case"d":return self.getDate().toString();case"MMMM":return self.getMonthName();case"MMM":return self.getMonthName(true);case"MM":return p((self.getMonth()+1));case"M"! :return self.getMonth()+1;case"t":return self.getHours()<12?Da! te.Cultu reInfo.amDesignator.substring(0,1):Date.CultureInfo.pmDesignator.substring(0,1);case"tt":return self.getHours()<12?Date.CultureInfo.amDesignator:Date.CultureInfo.pmDesignator;case"zzz":case"zz":case"z":return"";}}):this._toString();}; +Date.now=function(){return new Date();};Date.today=function(){return Date.now().clearTime();};Date.prototype._orient=+1;Date.prototype.next=function(){this._orient=+1;return this;};Date.prototype.last=Date.prototype.prev=Date.prototype.previous=function(){this._orient=-1;return this;};Date.prototype._is=false;Date.prototype.is=function(){this._is=true;return this;};Number.prototype._dateElement="day";Number.prototype.fromNow=function(){var c={};c[this._dateElement]=this;return Date.now().add(c);};Number.prototype.ago=function(){var c={};c[this._dateElement]=this*-1;return Date.now().add(c);};(function(){var $D=Date.prototype,$N=Number.prototype;var dx=("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),mx=("january february march april may june july august september october november december").split(/\s/),px=("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),de;var df=function(n){return function(){if(this._is){this._is=false;return this.! getDay()==n;} +return this.moveToDayOfWeek(n,this._orient);};};for(var i=0;i<dx.length;i++){$D[dx[i]]=$D[dx[i].substring(0,3)]=df(i);} +var mf=function(n){return function(){if(this._is){this._is=false;return this.getMonth()===n;} +return this.moveToMonth(n,this._orient);};};for(var j=0;j<mx.length;j++){$D[mx[j]]=$D[mx[j].substring(0,3)]=mf(j);} +var ef=function(j){return function(){if(j.substring(j.length-1)!="s"){j+="s";} +return this["add"+j](this._orient);};};var nf=function(n){return function(){this._dateElement=n;return this;};};for(var k=0;k<px.length;k++){de=px[k].toLowerCase();$D[de]=$D[de+"s"]=ef(px[k]);$N[de]=$N[de+"s"]=nf(de);}}());Date.prototype.toJSONString=function(){return this.toString("yyyy-MM-ddThh:mm:ssZ");};Date.prototype.toShortDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortDatePattern);};Date.prototype.toLongDateString=function(){return this.toString(Date.CultureInfo.formatPatterns.longDatePattern);};Date.prototype.toShortTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.shortTimePattern);};Date.prototype.toLongTimeString=function(){return this.toString(Date.CultureInfo.formatPatterns.longTimePattern);};Date.prototype.getOrdinal=function(){switch(this.getDate()){case 1:case 21:case 31:return"st";case 2:case 22:return"nd";case 3:case 23:return"rd";default:return"th";}}; +(function(){Date.Parsing={Exception:function(s){this.message="Parse error at '"+s.substring(0,10)+" ...'";}};var $P=Date.Parsing;var _=$P.Operators={rtoken:function(r){return function(s){var mx=s.match(r);if(mx){return([mx[0],s.substring(mx[0].length)]);}else{throw new $P.Exception(s);}};},token:function(s){return function(s){return _.rtoken(new RegExp("^\s*"+s+"\s*"))(s);};},stoken:function(s){return _.rtoken(new RegExp("^"+s));},until:function(p){return function(s){var qx=[],rx=null;while(s.length){try{rx=p.call(this,s);}catch(e){qx.push(rx[0]);s=rx[1];continue;} +break;} +return[qx,s];};},many:function(p){return function(s){var rx=[],r=null;while(s.length){try{r=p.call(this,s);}catch(e){return[rx,s];} +rx.push(r[0]);s=r[1];} +return[rx,s];};},optional:function(p){return function(s){var r=null;try{r=p.call(this,s);}catch(e){return[null,s];} +return[r[0],r[1]];};},not:function(p){return function(s){try{p.call(this,s);}catch(e){return[null,s];} +throw new $P.Exception(s);};},ignore:function(p){return p?function(s){var r=null;r=p.call(this,s);return[null,r[1]];}:null;},product:function(){var px=arguments[0],qx=Array.prototype.slice.call(arguments,1),rx=[];for(var i=0;i<px.length;i++){rx.push(_.each(px[i],qx));} +return rx;},cache:function(rule){var cache={},r=null;return function(s){try{r=cache[s]=(cache[s]||rule.call(this,s));}catch(e){r=cache[s]=e;} +if(r instanceof $P.Exception){throw r;}else{return r;}};},any:function(){var px=arguments;return function(s){var r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;} +try{r=(px[i].call(this,s));}catch(e){r=null;} +if(r){return r;}} +throw new $P.Exception(s);};},each:function(){var px=arguments;return function(s){var rx=[],r=null;for(var i=0;i<px.length;i++){if(px[i]==null){continue;} +try{r=(px[i].call(this,s));}catch(e){throw new $P.Exception(s);} +rx.push(r[0]);s=r[1];} +return[rx,s];};},all:function(){var px=arguments,_=_;return _.each(_.optional(px));},sequence:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;if(px.length==1){return px[0];} +return function(s){var r=null,q=null;var rx=[];for(var i=0;i<px.length;i++){try{r=px[i].call(this,s);}catch(e){break;} +rx.push(r[0]);try{q=d.call(this,r[1]);}catch(ex){q=null;break;} +s=q[1];} +if(!r){throw new $P.Exception(s);} +if(q){throw new $P.Exception(q[1]);} +if(c){try{r=c.call(this,r[1]);}catch(ey){throw new $P.Exception(r[1]);}} +return[rx,(r?r[1]:s)];};},between:function(d1,p,d2){d2=d2||d1;var _fn=_.each(_.ignore(d1),p,_.ignore(d2));return function(s){var rx=_fn.call(this,s);return[[rx[0][0],r[0][2]],rx[1]];};},list:function(p,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return(p instanceof Array?_.each(_.product(p.slice(0,-1),_.ignore(d)),p.slice(-1),_.ignore(c)):_.each(_.many(_.each(p,_.ignore(d))),px,_.ignore(c)));},set:function(px,d,c){d=d||_.rtoken(/^\s*/);c=c||null;return function(s){var r=null,p=null,q=null,rx=null,best=[[],s],last=false;for(var i=0;i<px.length;i++){q=null;p=null;r=null;last=(px.length==1);try{r=px[i].call(this,s);}catch(e){continue;} +rx=[[r[0]],r[1]];if(r[1].length>0&&!last){try{q=d.call(this,r[1]);}catch(ex){last=true;}}else{last=true;} +if(!last&&q[1].length===0){last=true;} +if(!last){var qx=[];for(var j=0;j<px.length;j++){if(i!=j){qx.push(px[j]);}} +p=_.set(qx,d).call(this,q[1]);if(p[0].length>0){rx[0]=rx[0].concat(p[0]);rx[1]=p[1];}} +if(rx[1].length<best[1].length){best=rx;} +if(best[1].length===0){break;}} +if(best[0].length===0){return best;} +if(c){try{q=c.call(this,best[1]);}catch(ey){throw new $P.Exception(best[1]);} +best[1]=q[1];} +return best;};},forward:function(gr,fname){return function(s){return gr[fname].call(this,s);};},replace:function(rule,repl){return function(s){var r=rule.call(this,s);return[repl,r[1]];};},process:function(rule,fn){return function(s){var r=rule.call(this,s);return[fn.call(this,r[0]),r[1]];};},min:function(min,rule){return function(s){var rx=rule.call(this,s);if(rx[0].length<min){throw new $P.Exception(s);} +return rx;};}};var _generator=function(op){return function(){var args=null,rx=[];if(arguments.length>1){args=Array.prototype.slice.call(arguments);}else if(arguments[0]instanceof Array){args=arguments[0];} +if(args){for(var i=0,px=args.shift();i<px.length;i++){args.unshift(px[i]);rx.push(op.apply(null,args));args.shift();return rx;}}else{return op.apply(null,arguments);}};};var gx="optional not ignore cache".split(/\s/);for(var i=0;i<gx.length;i++){_[gx[i]]=_generator(_[gx[i]]);} +var _vector=function(op){return function(){if(arguments[0]instanceof Array){return op.apply(null,arguments[0]);}else{return op.apply(null,arguments);}};};var vx="each any all".split(/\s/);for(var j=0;j<vx.length;j++){_[vx[j]]=_vector(_[vx[j]]);}}());(function(){var flattenAndCompact=function(ax){var rx=[];for(var i=0;i<ax.length;i++){if(ax[i]instanceof Array){rx=rx.concat(flattenAndCompact(ax[i]));}else{if(ax[i]){rx.push(ax[i]);}}} +return rx;};Date.Grammar={};Date.Translator={hour:function(s){return function(){this.hour=Number(s);};},minute:function(s){return function(){this.minute=Number(s);};},second:function(s){return function(){this.second=Number(s);};},meridian:function(s){return function(){this.meridian=s.slice(0,1).toLowerCase();};},timezone:function(s){return function(){var n=s.replace(/[^\d\+\-]/g,"");if(n.length){this.timezoneOffset=Number(n);}else{this.timezone=s.toLowerCase();}};},day:function(x){var s=x[0];return function(){this.day=Number(s.match(/\d+/)[0]);};},month:function(s){return function(){this.month=((s.length==3)?Date.getMonthNumberFromName(s):(Number(s)-1));};},year:function(s){return function(){var n=Number(s);this.year=((s.length>2)?n:(n+(((n+2000)<Date.CultureInfo.twoDigitYearMax)?2000:1900)));};},rday:function(s){return function(){switch(s){case"yesterday":this.days=-1;break;case"tomorrow":this.days=1;break;case"today":this.days=0;break;case"now":this.days=0;this.now=true;b! reak;}};},finishExact:function(x){x=(x instanceof Array)?x:[x];var now=new Date();this.year=now.getFullYear();this.month=now.getMonth();this.day=1;this.hour=0;this.minute=0;this.second=0;for(var i=0;i<x.length;i++){if(x[i]){x[i].call(this);}} +this.hour=(this.meridian=="p"&&this.hour<13)?this.hour+12:this.hour;if(this.day>Date.getDaysInMonth(this.year,this.month)){throw new RangeError(this.day+" is not a valid value for days.");} +var r=new Date(this.year,this.month,this.day,this.hour,this.minute,this.second);if(this.timezone){r.set({timezone:this.timezone});}else if(this.timezoneOffset){r.set({timezoneOffset:this.timezoneOffset});} +return r;},finish:function(x){x=(x instanceof Array)?flattenAndCompact(x):[x];if(x.length===0){return null;} +for(var i=0;i<x.length;i++){if(typeof x[i]=="function"){x[i].call(this);}} +if(this.now){return new Date();} +var today=Date.today();var method=null;var expression=!!(this.days!=null||this.orient||this.operator);if(expression){var gap,mod,orient;orient=((this.orient=="past"||this.operator=="subtract")?-1:1);if(this.weekday){this.unit="day";gap=(Date.getDayNumberFromName(this.weekday)-today.getDay());mod=7;this.days=gap?((gap+(orient*mod))%mod):(orient*mod);} +if(this.month){this.unit="month";gap=(this.month-today.getMonth());mod=12;this.months=gap?((gap+(orient*mod))%mod):(orient*mod);this.month=null;} +if(!this.unit){this.unit="day";} +if(this[this.unit+"s"]==null||this.operator!=null){if(!this.value){this.value=1;} +if(this.unit=="week"){this.unit="day";this.value=this.value*7;} +this[this.unit+"s"]=this.value*orient;} +return today.add(this);}else{if(this.meridian&&this.hour){this.hour=(this.hour<13&&this.meridian=="p")?this.hour+12:this.hour;} +if(this.weekday&&!this.day){this.day=(today.addDays((Date.getDayNumberFromName(this.weekday)-today.getDay()))).getDate();} +if(this.month&&!this.day){this.day=1;} +return today.set(this);}}};var _=Date.Parsing.Operators,g=Date.Grammar,t=Date.Translator,_fn;g.datePartDelimiter=_.rtoken(/^([\s\-\.\,\/\x27]+)/);g.timePartDelimiter=_.stoken(":");g.whiteSpace=_.rtoken(/^\s*/);g.generalDelimiter=_.rtoken(/^(([\s\,]|at|on)+)/);var _C={};g.ctoken=function(keys){var fn=_C[keys];if(!fn){var c=Date.CultureInfo.regexPatterns;var kx=keys.split(/\s+/),px=[];for(var i=0;i<kx.length;i++){px.push(_.replace(_.rtoken(c[kx[i]]),kx[i]));} +fn=_C[keys]=_.any.apply(null,px);} +return fn;};g.ctoken2=function(key){return _.rtoken(Date.CultureInfo.regexPatterns[key]);};g.h=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/),t.hour));g.hh=_.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/),t.hour));g.H=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/),t.hour));g.HH=_.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/),t.hour));g.m=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.minute));g.mm=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.minute));g.s=_.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/),t.second));g.ss=_.cache(_.process(_.rtoken(/^[0-5][0-9]/),t.second));g.hms=_.cache(_.sequence([g.H,g.mm,g.ss],g.timePartDelimiter));g.t=_.cache(_.process(g.ctoken2("shortMeridian"),t.meridian));g.tt=_.cache(_.process(g.ctoken2("longMeridian"),t.meridian));g.z=_.cache(_.process(_.rtoken(/^(\+|\-)?\s*\d\d\d\d?/),t.timezone));g.zz=_.cache(_.process(_.rtoken(/^(\+|\-)\s*\d\d\d\d/),t.timezone));g.zzz=_.cache(_.process(g.ctoken2("timezone"),t.timezone));g.time! Suffix=_.each(_.ignore(g.whiteSpace),_.set([g.tt,g.zzz]));g.time=_.each(_.optional(_.ignore(_.stoken("T"))),g.hms,g.timeSuffix);g.d=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.dd=_.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/),_.optional(g.ctoken2("ordinalSuffix"))),t.day));g.ddd=g.dddd=_.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"),function(s){return function(){this.weekday=s;};}));g.M=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/),t.month));g.MM=_.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/),t.month));g.MMM=g.MMMM=_.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"),t.month));g.y=_.cache(_.process(_.rtoken(/^(\d\d?)/),t.year));g.yy=_.cache(_.process(_.rtoken(/^(\d\d)/),t.year));g.yyy=_.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/),t.year));g.yyyy=_.cache(_.process(_.rtoken(/^(\d\d\d\d)/),t.year));_fn=function(){return _.each(_.any.apply(null,arguments),_.not(g.ctoken2("tim! eContext")));};g.day=_fn(g.d,g.dd);g.month=_fn(g.M,g.MMM);g.ye! ar=_fn(g .yyyy,g.yy);g.orientation=_.process(g.ctoken("past future"),function(s){return function(){this.orient=s;};});g.operator=_.process(g.ctoken("add subtract"),function(s){return function(){this.operator=s;};});g.rday=_.process(g.ctoken("yesterday tomorrow today now"),t.rday);g.unit=_.process(g.ctoken("minute hour day week month year"),function(s){return function(){this.unit=s;};});g.value=_.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/),function(s){return function(){this.value=s.replace(/\D/g,"");};});g.expression=_.set([g.rday,g.operator,g.value,g.unit,g.orientation,g.ddd,g.MMM]);_fn=function(){return _.set(arguments,g.datePartDelimiter);};g.mdy=_fn(g.ddd,g.month,g.day,g.year);g.ymd=_fn(g.ddd,g.year,g.month,g.day);g.dmy=_fn(g.ddd,g.day,g.month,g.year);g.date=function(s){return((g[Date.CultureInfo.dateElementOrder]||g.mdy).call(this,s));};g.format=_.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/),function(fmt){if(g[fmt]){return g[fmt];}e! lse{throw Date.Parsing.Exception(fmt);}}),_.process(_.rtoken(/^[^dMyhHmstz]+/),function(s){return _.ignore(_.stoken(s));}))),function(rules){return _.process(_.each.apply(null,rules),t.finishExact);});var _F={};var _get=function(f){return _F[f]=(_F[f]||g.format(f)[0]);};g.formats=function(fx){if(fx instanceof Array){var rx=[];for(var i=0;i<fx.length;i++){rx.push(_get(fx[i]));} +return _.any.apply(null,rx);}else{return _get(fx);}};g._formats=g.formats(["yyyy-MM-ddTHH:mm:ss","ddd, MMM dd, yyyy H:mm:ss tt","ddd MMM d yyyy HH:mm:ss zzz","d"]);g._start=_.process(_.set([g.date,g.time,g.expression],g.generalDelimiter,g.whiteSpace),t.finish);g.start=function(s){try{var r=g._formats.call({},s);if(r[1].length===0){return r;}}catch(e){} +return g._start.call({},s);};}());Date._parse=Date.parse;Date.parse=function(s){var r=null;if(!s){return null;} +try{r=Date.Grammar.start.call({},s);}catch(e){return null;} +return((r[1].length===0)?r[0]:null);};Date.getParseFunction=function(fx){var fn=Date.Grammar.formats(fx);return function(s){var r=null;try{r=fn.call({},s);}catch(e){return null;} +return((r[1].length===0)?r[0]:null);};};Date.parseExact=function(s,fx){return Date.getParseFunction(fx)(s);}; |
From: <de...@de...> - 2017-01-27 12:54:10
|
Author: AaronLWalker Date: 2017-01-27 12:52:48 +0000 (Fri, 27 Jan 2017) New Revision: 30300 Trac url: http://develop.twiki.org/trac/changeset/30300 Added: twiki/trunk/DateJSPlugin/ twiki/trunk/EPAgentPlugin/ twiki/trunk/FlotPlugin/ twiki/trunk/JSTreePlugin/ Log: Item7769: Creation of initial directory for JSTreePlugin |
From: <de...@de...> - 2017-01-25 04:18:44
|
Author: HideyoImazu Date: 2017-01-25 04:17:56 +0000 (Wed, 25 Jan 2017) New Revision: 30299 Trac url: http://develop.twiki.org/trac/changeset/30299 Modified: twiki/branches/TWikiRelease06x00/core/data/TWiki/AllowWebCreateByUserMappingManager.txt twiki/branches/TWikiRelease06x00/core/data/TWiki/LargeSite.txt twiki/branches/TWikiRelease06x00/core/data/TWiki/TWikiAccessControl.txt twiki/branches/TWikiRelease06x00/core/data/TWiki/UserSubwebs.txt twiki/branches/TWikiRelease06x00/core/lib/TWiki/UI/Manage.pm twiki/branches/TWikiRelease06x00/core/lib/TWiki/Users.pm Log: Item7768: TWiki::Users::canRenameWeb() for symmetry with TWiki::Users::canCreateWeb() Modified: twiki/branches/TWikiRelease06x00/core/data/TWiki/AllowWebCreateByUserMappingManager.txt =================================================================== --- twiki/branches/TWikiRelease06x00/core/data/TWiki/AllowWebCreateByUserMappingManager.txt 2017-01-25 03:28:55 UTC (rev 30298) +++ twiki/branches/TWikiRelease06x00/core/data/TWiki/AllowWebCreateByUserMappingManager.txt 2017-01-25 04:17:56 UTC (rev 30299) @@ -1,44 +1,29 @@ -%META:TOPICINFO{author="TWikiContributor" date="1350633267" format="1.1" version="$Rev$"}% ----+!! Allowing Web Creation by the User Mapping Manager +%META:TOPICINFO{author="TWikiContributor" date="1485159724" format="1.1" version="$Rev$"}% +---+!! Allowing Web Creation, Deletion, & Rename by the User Mapping Manager ---++ Motivation -There are cases where DENYROOTCHANGE, ALLOWROOTCHANGE, DENYWEBCHANGE, and ALLOWWEBCHANGE are not capable enough to implement web creation permission you want. -For example, you may want to allow a user to create a certain subweb of the web Foo while you don't want to allow to create topics on the web Foo. -To cope with such cases, a method in the user mapping manager is called to check the web creation is allowed before checking the access control variables. +There are cases where DENYROOTCHANGE, ALLOWROOTCHANGE, DENYWEBCHANGE, and ALLOWWEBCHANGE are not capable enough to implement web creation/deletion/rename permission you want. +Here are some of those situations. ----+++ A large TWiki site in a large organization employing UserSubwebs +---+++ Making top level web creation and deletion self-service -Let's assume: - * It's about a large organization having 50,000 users in its LDAP. User IDs, real names, email addresses, etc. are in the LDAP - * It has an intranet single sign-on mechanism leveraging the LDAP data - * Everybody in the organization may edit topics on a TWiki site having 5,000 webs - * The TWiki site authenticate users with the intranet single sign-on mechanism - * UserSubwebs is in use -Implication: - * Requiring user registration on the TWiki site for editing doesn't make a lot of sense. Because all user account data is already in LDAP, which is supposed to be referred to if needed. - * Users need to be forbidden to create topics on the Main web. Otherwise, it accumulates a lot of clutters in the long run. - * Users need to be able to create/delete their personal web on their own - * *Here needs the capability* +Usually, to create and delete a top level web, you need to be allowed by ALLOWROOTCHANGE and DENYROOTCHANGE. +On a large TWiki site, it's desirable to make top level web creation and deletion self-service. ----+++ UsingMultipleDisks and /pub/... rewritten to /cgi-bin/viewfiles/... +---+++ Allowing users to create and delete their own UserSubwebs -Let's assume: - * There is a TWiki site employing UsingMultipleDisks - * The HTTP server housing TWiki needs to rewrite /pub/... to /cgi-bin/viewfile/... so that all attachments are obtainable by /pub/... path without symbolic links -Implication: - * The rewriting rule doesn't rewrite /pub/TWiki/... and /pub/Public/... so that files there can be retrieved directly (=quickly) from the HTTP server without going through TWiki. - * For every top level web W, there can be Public/W subweb. The owner of the web W can create Public/W if they like. - Web owners must not be able to create topics in the Public web or a subweb different from the unrelated to web names the user owns - * *Here needs the capability* +In a large orgnization having thousands or more users, the Main web needs to restrict topic creation to prevent random topics to accumulate. +Instead, UserSubwebs are desirable for content accountability. +This means that, on the Main web, users are not allowed to create topics but are allowed to create and delete the subweb of their wiki name. ---++ How it works When a new web is created, the =canCreateWeb($cUID, $web)= method of the user mapping manager is called if the method exists. -If the method returns true, TWiki goes ahead and create the web without checking DENYROOTCHANGE and ALLOWROOTCHANGE (for a top level web) or DENYWEBCHANGE and ALLOWWEBCHANGE (of the parent of a subweb). -If the method does not exist or the method returns false, web creation is permitted as usual based on ROOTCHANGE or ALLOWWEBCHANGE. +If the method returns true, the web is created without checking DENYROOTCHANGE and ALLOWROOTCHANGE (for a top level web) or DENYWEBCHANGE and ALLOWWEBCHANGE (of the parent of a subweb). +If the method does not exist or the method returns false, web creation is permitted as usual based on *ROOTCHANGE or *WEBCHANGE. -Maybe needless to say, the method would be written as follows. +The method would be written as follows. <verbatim> sub canCreateWeb { my( $this, $cUID, $web ) = @_; @@ -46,4 +31,9 @@ } </verbatim> -__Related Topics:__ AdminDocumentationCategory, TWikiAccessControl, UserSubwebs +Similarly, when a web is renamed, the =canRenameWeb($cUID, $oldWeb, $newWeb)= method of the user mapping manager is called if the method exist. +If it returns true, permission check on the parent web is omitted. +If the method does not exist or the method returns false, permission check on the parent web is conducted as usual. +Then, permission check on the rename destination takes place. + +__Related Topics:__ AdminDocumentationCategory, TWikiAccessControl, LargeSite, UserSubwebs Modified: twiki/branches/TWikiRelease06x00/core/data/TWiki/LargeSite.txt =================================================================== --- twiki/branches/TWikiRelease06x00/core/data/TWiki/LargeSite.txt 2017-01-25 03:28:55 UTC (rev 30298) +++ twiki/branches/TWikiRelease06x00/core/data/TWiki/LargeSite.txt 2017-01-25 04:17:56 UTC (rev 30299) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1424854881" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1485159244" format="1.1" version="$Rev$"}% ---+!! Managing a Large Site There is no limitation with the number of webs and users a TWiki site can have. @@ -39,10 +39,10 @@ To minimize TWiki admins intervention, you can make webs autonomous following the instruction on AutonomousWebs. This does not decrease the number of questions from web owners, but TWiki admins can hand off web administrative responsibility to the web owner that way. ----+++ Self-service web creation +---+++ Self-service web creation/deletion/rename -Usually, only Main.TWikiAdminGroup members can create new webs, which may generate a good amount of TWiki admin work. -By properly implementing =canCreateWeb()= of the user mapping handler your TWiki installation use, you can make web creation self-service. +Usually, only Main.TWikiAdminGroup members can create/delete/rename top level webs, which may generate a good amount of TWiki admin work. +By properly implementing =canCreateWeb($cUID, $web)= and =canRenameWeb($cUID, $oldWeb, $newWeb)= of the user mapping handler your TWiki installation use, you can make top level web creation/deletion/rename self-service. Assuming your TWiki configuration requires web metadata when a new web is created, if you make web creation self-service, you need to make it possible to create metadata of a new web in MetadataRepository. Modified: twiki/branches/TWikiRelease06x00/core/data/TWiki/TWikiAccessControl.txt =================================================================== --- twiki/branches/TWikiRelease06x00/core/data/TWiki/TWikiAccessControl.txt 2017-01-25 03:28:55 UTC (rev 30298) +++ twiki/branches/TWikiRelease06x00/core/data/TWiki/TWikiAccessControl.txt 2017-01-25 04:17:56 UTC (rev 30299) @@ -223,11 +223,12 @@ * everyone else will be *DENIED* 1 If you got this far, access is *PERMITTED* ----+++ Allowing web creation by user mapping manager +---+++ Allowing web creation/deletion/rename by user mapping manager -There are cases where DENYROOTCHANGE, ALLOWROOTCHANGE, DENYWEBCHANGE, and ALLOWWEBCHANGE, and DENYWEBCHANGE are not capable enough to implement web creation permission you want. -To cope with such cases, when a new web is created, the =canCreateWeb($cUID, $web)= method of the user mapping manager is called if the method exists. +There are cases where DENYROOTCHANGE, ALLOWROOTCHANGE, DENYWEBCHANGE, and ALLOWWEBCHANGE, and DENYWEBCHANGE are not capable enough to implement web creation and rename permissions you want. +To cope with such cases, when a new web is created, the =canCreateWeb($cUID, $web)= method of the user mapping manager is called if it exists. If it returns true, TWiki goes ahead and create the web without checking access control variables. +Similarly, when a web is renamed (deletion is a form of rename), the =canRenameWeb($cUID, $oldWeb, $newWeb)= method of the user mapping manager is called if it exists. Please read AllowWebCreateByUserMappingManager for more details. ---++ Forbid certain users to do certain actions by configuration Modified: twiki/branches/TWikiRelease06x00/core/data/TWiki/UserSubwebs.txt =================================================================== --- twiki/branches/TWikiRelease06x00/core/data/TWiki/UserSubwebs.txt 2017-01-25 03:28:55 UTC (rev 30298) +++ twiki/branches/TWikiRelease06x00/core/data/TWiki/UserSubwebs.txt 2017-01-25 04:17:56 UTC (rev 30299) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1424756282" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1485158914" format="1.1" version="$Rev$"}% ---+!! User Subwebs TWiki provides each user with their own topic having their information and configuration. You may want to provide each user with a subweb Main/FirstLast having a topic having the user's information and configuration. @@ -46,10 +46,12 @@ You can specify the topic name containing user preferences by =$TWiki::cfg{UserSubwebs}{UserPrefsTopicName}=, which is !WebHome by default. ----+++ Customize web creation permission -If all of the following are true, you need to have an appropriate canCreateWeb object method in the user mapping manager class. +---+++ Customize web creation/deletion/rename permission +If all of the following are true, you need to have an appropriate =canCreateWeb($cUID, $web)= object method in the user mapping manager class. * Your TWiki doesn't have user registration * You lock down the %USERSWEB% web for tidyness * You want to have users create their subwebs on their own +At the same time, you should have an appropriate =canRenameWeb($cUID, $oldWeb, $newWeb)= object method in the user mapping manager class to have users delete/rename their subwebs on their own. + __Related Topics:__ AdminDocumentationCategory, SubwebAndTopicNames, AllowWebCreateByUserMappingManager, LargeSite Modified: twiki/branches/TWikiRelease06x00/core/lib/TWiki/UI/Manage.pm =================================================================== --- twiki/branches/TWikiRelease06x00/core/lib/TWiki/UI/Manage.pm 2017-01-25 03:28:55 UTC (rev 30298) +++ twiki/branches/TWikiRelease06x00/core/lib/TWiki/UI/Manage.pm 2017-01-25 04:17:56 UTC (rev 30299) @@ -625,13 +625,16 @@ # If the user is not allowed to rename anything in the parent web - stop here # This also ensures we check root webs for ALLOWROOTRENAME and DENYROOTRENAME - TWiki::UI::checkAccess( $session, $oldParentWeb || undef, undef, - 'RENAME', $session->{user} ); + unless ( $session->{users}->canRenameWeb($oldWeb, $newWeb) ) { + TWiki::UI::checkAccess( $session, $oldParentWeb || undef, undef, + 'RENAME', $session->{user} ); - # If old web is a root web then also stop if ALLOW/DENYROOTCHANGE prevents access - if ( !$oldParentWeb ) { - TWiki::UI::checkAccess( $session, $oldParentWeb || undef, undef, - 'CHANGE', $session->{user} ); + # If old web is a root web then also stop if ALLOW/DENYROOTCHANGE + # prevents access + if ( !$oldParentWeb ) { + TWiki::UI::checkAccess( $session, $oldParentWeb || undef, undef, + 'CHANGE', $session->{user} ); + } } my $newTopic; Modified: twiki/branches/TWikiRelease06x00/core/lib/TWiki/Users.pm =================================================================== --- twiki/branches/TWikiRelease06x00/core/lib/TWiki/Users.pm 2017-01-25 03:28:55 UTC (rev 30298) +++ twiki/branches/TWikiRelease06x00/core/lib/TWiki/Users.pm 2017-01-25 04:17:56 UTC (rev 30299) @@ -1281,6 +1281,22 @@ =pod +---++ ObjectMethod canRenameWeb($oldWeb, $newWeb) -> $boolean + +=cut + +sub canRenameWeb { + my( $this, $oldWeb, $newWeb ) = @_; + my $cUID = $this->{session}{user}; + my $mapping = $this->_getMapping( $cUID ); + if ( $mapping && $mapping->can( 'canRenameWeb' ) ) { + return $mapping->canRenameWeb($cUID, $oldWeb, $newWeb); + } + return 0; +} + +=pod + ---++ ObjectMethod getAffiliation($cUID) -> $affiliation =cut |
From: <de...@de...> - 2017-01-25 03:29:43
|
Author: HideyoImazu Date: 2017-01-25 03:28:55 +0000 (Wed, 25 Jan 2017) New Revision: 30298 Trac url: http://develop.twiki.org/trac/changeset/30298 Modified: twiki/trunk/core/data/TWiki/AllowWebCreateByUserMappingManager.txt twiki/trunk/core/data/TWiki/LargeSite.txt twiki/trunk/core/data/TWiki/TWikiAccessControl.txt twiki/trunk/core/data/TWiki/UserSubwebs.txt twiki/trunk/core/lib/TWiki/UI/Manage.pm twiki/trunk/core/lib/TWiki/Users.pm Log: Item7768: TWiki::Users::canRenameWeb() for symmetry with TWiki::Users::canCreateWeb() Modified: twiki/trunk/core/data/TWiki/AllowWebCreateByUserMappingManager.txt =================================================================== --- twiki/trunk/core/data/TWiki/AllowWebCreateByUserMappingManager.txt 2017-01-13 00:51:51 UTC (rev 30297) +++ twiki/trunk/core/data/TWiki/AllowWebCreateByUserMappingManager.txt 2017-01-25 03:28:55 UTC (rev 30298) @@ -1,44 +1,29 @@ -%META:TOPICINFO{author="TWikiContributor" date="1350633267" format="1.1" version="$Rev$"}% ----+!! Allowing Web Creation by the User Mapping Manager +%META:TOPICINFO{author="TWikiContributor" date="1485159724" format="1.1" version="$Rev$"}% +---+!! Allowing Web Creation, Deletion, & Rename by the User Mapping Manager ---++ Motivation -There are cases where DENYROOTCHANGE, ALLOWROOTCHANGE, DENYWEBCHANGE, and ALLOWWEBCHANGE are not capable enough to implement web creation permission you want. -For example, you may want to allow a user to create a certain subweb of the web Foo while you don't want to allow to create topics on the web Foo. -To cope with such cases, a method in the user mapping manager is called to check the web creation is allowed before checking the access control variables. +There are cases where DENYROOTCHANGE, ALLOWROOTCHANGE, DENYWEBCHANGE, and ALLOWWEBCHANGE are not capable enough to implement web creation/deletion/rename permission you want. +Here are some of those situations. ----+++ A large TWiki site in a large organization employing UserSubwebs +---+++ Making top level web creation and deletion self-service -Let's assume: - * It's about a large organization having 50,000 users in its LDAP. User IDs, real names, email addresses, etc. are in the LDAP - * It has an intranet single sign-on mechanism leveraging the LDAP data - * Everybody in the organization may edit topics on a TWiki site having 5,000 webs - * The TWiki site authenticate users with the intranet single sign-on mechanism - * UserSubwebs is in use -Implication: - * Requiring user registration on the TWiki site for editing doesn't make a lot of sense. Because all user account data is already in LDAP, which is supposed to be referred to if needed. - * Users need to be forbidden to create topics on the Main web. Otherwise, it accumulates a lot of clutters in the long run. - * Users need to be able to create/delete their personal web on their own - * *Here needs the capability* +Usually, to create and delete a top level web, you need to be allowed by ALLOWROOTCHANGE and DENYROOTCHANGE. +On a large TWiki site, it's desirable to make top level web creation and deletion self-service. ----+++ UsingMultipleDisks and /pub/... rewritten to /cgi-bin/viewfiles/... +---+++ Allowing users to create and delete their own UserSubwebs -Let's assume: - * There is a TWiki site employing UsingMultipleDisks - * The HTTP server housing TWiki needs to rewrite /pub/... to /cgi-bin/viewfile/... so that all attachments are obtainable by /pub/... path without symbolic links -Implication: - * The rewriting rule doesn't rewrite /pub/TWiki/... and /pub/Public/... so that files there can be retrieved directly (=quickly) from the HTTP server without going through TWiki. - * For every top level web W, there can be Public/W subweb. The owner of the web W can create Public/W if they like. - Web owners must not be able to create topics in the Public web or a subweb different from the unrelated to web names the user owns - * *Here needs the capability* +In a large orgnization having thousands or more users, the Main web needs to restrict topic creation to prevent random topics to accumulate. +Instead, UserSubwebs are desirable for content accountability. +This means that, on the Main web, users are not allowed to create topics but are allowed to create and delete the subweb of their wiki name. ---++ How it works When a new web is created, the =canCreateWeb($cUID, $web)= method of the user mapping manager is called if the method exists. -If the method returns true, TWiki goes ahead and create the web without checking DENYROOTCHANGE and ALLOWROOTCHANGE (for a top level web) or DENYWEBCHANGE and ALLOWWEBCHANGE (of the parent of a subweb). -If the method does not exist or the method returns false, web creation is permitted as usual based on ROOTCHANGE or ALLOWWEBCHANGE. +If the method returns true, the web is created without checking DENYROOTCHANGE and ALLOWROOTCHANGE (for a top level web) or DENYWEBCHANGE and ALLOWWEBCHANGE (of the parent of a subweb). +If the method does not exist or the method returns false, web creation is permitted as usual based on *ROOTCHANGE or *WEBCHANGE. -Maybe needless to say, the method would be written as follows. +The method would be written as follows. <verbatim> sub canCreateWeb { my( $this, $cUID, $web ) = @_; @@ -46,4 +31,9 @@ } </verbatim> -__Related Topics:__ AdminDocumentationCategory, TWikiAccessControl, UserSubwebs +Similarly, when a web is renamed, the =canRenameWeb($cUID, $oldWeb, $newWeb)= method of the user mapping manager is called if the method exist. +If it returns true, permission check on the parent web is omitted. +If the method does not exist or the method returns false, permission check on the parent web is conducted as usual. +Then, permission check on the rename destination takes place. + +__Related Topics:__ AdminDocumentationCategory, TWikiAccessControl, LargeSite, UserSubwebs Modified: twiki/trunk/core/data/TWiki/LargeSite.txt =================================================================== --- twiki/trunk/core/data/TWiki/LargeSite.txt 2017-01-13 00:51:51 UTC (rev 30297) +++ twiki/trunk/core/data/TWiki/LargeSite.txt 2017-01-25 03:28:55 UTC (rev 30298) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1424854881" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1485159244" format="1.1" version="$Rev$"}% ---+!! Managing a Large Site There is no limitation with the number of webs and users a TWiki site can have. @@ -39,10 +39,10 @@ To minimize TWiki admins intervention, you can make webs autonomous following the instruction on AutonomousWebs. This does not decrease the number of questions from web owners, but TWiki admins can hand off web administrative responsibility to the web owner that way. ----+++ Self-service web creation +---+++ Self-service web creation/deletion/rename -Usually, only Main.TWikiAdminGroup members can create new webs, which may generate a good amount of TWiki admin work. -By properly implementing =canCreateWeb()= of the user mapping handler your TWiki installation use, you can make web creation self-service. +Usually, only Main.TWikiAdminGroup members can create/delete/rename top level webs, which may generate a good amount of TWiki admin work. +By properly implementing =canCreateWeb($cUID, $web)= and =canRenameWeb($cUID, $oldWeb, $newWeb)= of the user mapping handler your TWiki installation use, you can make top level web creation/deletion/rename self-service. Assuming your TWiki configuration requires web metadata when a new web is created, if you make web creation self-service, you need to make it possible to create metadata of a new web in MetadataRepository. Modified: twiki/trunk/core/data/TWiki/TWikiAccessControl.txt =================================================================== --- twiki/trunk/core/data/TWiki/TWikiAccessControl.txt 2017-01-13 00:51:51 UTC (rev 30297) +++ twiki/trunk/core/data/TWiki/TWikiAccessControl.txt 2017-01-25 03:28:55 UTC (rev 30298) @@ -223,11 +223,12 @@ * everyone else will be *DENIED* 1 If you got this far, access is *PERMITTED* ----+++ Allowing web creation by user mapping manager +---+++ Allowing web creation/deletion/rename by user mapping manager -There are cases where DENYROOTCHANGE, ALLOWROOTCHANGE, DENYWEBCHANGE, and ALLOWWEBCHANGE, and DENYWEBCHANGE are not capable enough to implement web creation permission you want. -To cope with such cases, when a new web is created, the =canCreateWeb($cUID, $web)= method of the user mapping manager is called if the method exists. +There are cases where DENYROOTCHANGE, ALLOWROOTCHANGE, DENYWEBCHANGE, and ALLOWWEBCHANGE, and DENYWEBCHANGE are not capable enough to implement web creation and rename permissions you want. +To cope with such cases, when a new web is created, the =canCreateWeb($cUID, $web)= method of the user mapping manager is called if it exists. If it returns true, TWiki goes ahead and create the web without checking access control variables. +Similarly, when a web is renamed (deletion is a form of rename), the =canRenameWeb($cUID, $oldWeb, $newWeb)= method of the user mapping manager is called if it exists. Please read AllowWebCreateByUserMappingManager for more details. ---++ Forbid certain users to do certain actions by configuration Modified: twiki/trunk/core/data/TWiki/UserSubwebs.txt =================================================================== --- twiki/trunk/core/data/TWiki/UserSubwebs.txt 2017-01-13 00:51:51 UTC (rev 30297) +++ twiki/trunk/core/data/TWiki/UserSubwebs.txt 2017-01-25 03:28:55 UTC (rev 30298) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1424756282" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1485158914" format="1.1" version="$Rev$"}% ---+!! User Subwebs TWiki provides each user with their own topic having their information and configuration. You may want to provide each user with a subweb Main/FirstLast having a topic having the user's information and configuration. @@ -46,10 +46,12 @@ You can specify the topic name containing user preferences by =$TWiki::cfg{UserSubwebs}{UserPrefsTopicName}=, which is !WebHome by default. ----+++ Customize web creation permission -If all of the following are true, you need to have an appropriate canCreateWeb object method in the user mapping manager class. +---+++ Customize web creation/deletion/rename permission +If all of the following are true, you need to have an appropriate =canCreateWeb($cUID, $web)= object method in the user mapping manager class. * Your TWiki doesn't have user registration * You lock down the %USERSWEB% web for tidyness * You want to have users create their subwebs on their own +At the same time, you should have an appropriate =canRenameWeb($cUID, $oldWeb, $newWeb)= object method in the user mapping manager class to have users delete/rename their subwebs on their own. + __Related Topics:__ AdminDocumentationCategory, SubwebAndTopicNames, AllowWebCreateByUserMappingManager, LargeSite Modified: twiki/trunk/core/lib/TWiki/UI/Manage.pm =================================================================== --- twiki/trunk/core/lib/TWiki/UI/Manage.pm 2017-01-13 00:51:51 UTC (rev 30297) +++ twiki/trunk/core/lib/TWiki/UI/Manage.pm 2017-01-25 03:28:55 UTC (rev 30298) @@ -625,13 +625,16 @@ # If the user is not allowed to rename anything in the parent web - stop here # This also ensures we check root webs for ALLOWROOTRENAME and DENYROOTRENAME - TWiki::UI::checkAccess( $session, $oldParentWeb || undef, undef, - 'RENAME', $session->{user} ); + unless ( $session->{users}->canRenameWeb($oldWeb, $newWeb) ) { + TWiki::UI::checkAccess( $session, $oldParentWeb || undef, undef, + 'RENAME', $session->{user} ); - # If old web is a root web then also stop if ALLOW/DENYROOTCHANGE prevents access - if ( !$oldParentWeb ) { - TWiki::UI::checkAccess( $session, $oldParentWeb || undef, undef, - 'CHANGE', $session->{user} ); + # If old web is a root web then also stop if ALLOW/DENYROOTCHANGE + # prevents access + if ( !$oldParentWeb ) { + TWiki::UI::checkAccess( $session, $oldParentWeb || undef, undef, + 'CHANGE', $session->{user} ); + } } my $newTopic; Modified: twiki/trunk/core/lib/TWiki/Users.pm =================================================================== --- twiki/trunk/core/lib/TWiki/Users.pm 2017-01-13 00:51:51 UTC (rev 30297) +++ twiki/trunk/core/lib/TWiki/Users.pm 2017-01-25 03:28:55 UTC (rev 30298) @@ -1281,6 +1281,22 @@ =pod +---++ ObjectMethod canRenameWeb($oldWeb, $newWeb) -> $boolean + +=cut + +sub canRenameWeb { + my( $this, $oldWeb, $newWeb ) = @_; + my $cUID = $this->{session}{user}; + my $mapping = $this->_getMapping( $cUID ); + if ( $mapping && $mapping->can( 'canRenameWeb' ) ) { + return $mapping->canRenameWeb($cUID, $oldWeb, $newWeb); + } + return 0; +} + +=pod + ---++ ObjectMethod getAffiliation($cUID) -> $affiliation =cut |
From: Peter T. <pe...@th...> - 2017-01-19 07:29:06
|
All: Please join our TWiki Kampala Release Meeting, http://twiki.org/cgi-bin/view/Codev/KampalaReleaseMeeting2017x01x19 scheduled for 2017-01-19 23:00 GMT [1] on IRC channel #twiki_release on the irc.freenode.net IRC network [2] - in about 15.5 hours from now. Proposed agenda: 1. Feature Requests for Kampala Release 2. Review Urgent and Not So Urgent Bugs 3. Extensions 4. TWiki Release Discussion 5. Miscellaneous The meeting is on Thursday or Friday, depending on your time zone. Meeting time in different time zones, tomorrow: * USA Pacific Time Zone: 03:00pm on Thu * USA Eastern Time Zone: 06:00pm on Thu * Central Europe: 24:00 on Thu/Fri night * Japan: 08:00 on Fri Please show up in time to save everybody's time. And remember that the release meeting is where decisions are made. We invite all TWiki.org contributors to join, as well as people with interest in the TWiki project in general. Cheers, Peter [1]: http://www.timeanddate.com/worldclock/converter.html?iso=20170119T230000&p1=tz_gmt&p2=248&p3=268&p4=224&p5=179 [2]: http://twiki.org/cgi-bin/view/Codev/TWikiIRC -- > Peter Thoeny - Peter09[at]Thoeny.org > http://TWiki.org/Mr.TWiki - consulting on enterprise collaboration > http://TWiki.org - is your team already TWiki enabled? > http://qualityHDR.com - Quality HDR Photography > Knowledge cannot be managed, it can be discovered and shared > This e-mail is: (_) private (_) ask first (x) public |
From: <de...@de...> - 2017-01-13 00:53:04
|
Author: HideyoImazu Date: 2017-01-13 00:51:51 +0000 (Fri, 13 Jan 2017) New Revision: 30297 Trac url: http://develop.twiki.org/trac/changeset/30297 Modified: twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt Log: Item7703: minor document update for VarCachePlugin Modified: twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt =================================================================== --- twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2017-01-13 00:51:10 UTC (rev 30296) +++ twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2017-01-13 00:51:51 UTC (rev 30297) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1484203439" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1484268621" format="1.1" version="$Rev$"}% ---+!! Variable Cache Plugin <!-- Contributions to this plugin are appreciated. Please update the plugin page at @@ -55,7 +55,10 @@ ---++ Plugin Settings -This plugin can be configured with preferences settings in [[%LOCALSITEPREFS%]] (site level), a WebPreferences (web level) or in a topic (page level). Do not change the settings here, they are here only to illustrate the default values. To overload, copy the settings to one of the aforementioned topics. On a large site having many webs, it's recommended to set VARCACHEPLUGIN_INVALIDATEONUPDATE =none= at the site level to prevent save slowness to happen unexpectedly. +This plugin can be configured with preferences settings in [[%LOCALSITEPREFS%]] (site level), a WebPreferences (web level) or in a topic (page level). Do not change the settings here, they are here only to illustrate the default values. To overload, copy the settings to one of the aforementioned topics. On a large site having many webs, it's recommended to set VARCACHEPLUGIN_INVALIDATEONUPDATE =none= at the site level to prevent save slowness from happening unknowingly. The current site level setting is %IF{"'%VAR{VARCACHEPLUGIN_INVALIDATEONUPDATE}%' != ''" + then="=%VARCACHEPLUGIN_INVALIDATEONUPDATE%=" + else="undefined, which is the same as =include=" +}%. * Debug plugin: (See output in =data/debug.txt=) * Set VARCACHEPLUGIN_DEBUG = 0 @@ -65,7 +68,7 @@ * On topic creation and topic update, invalidate cache of affected topics: =parent= (its parent topic), =parent(32)= (its parent topics on parent path up to 32 levels), =backlinks= (its backlink topics in current web), =include= (its including topics in current web), =none= (no invalidation), or a comma-list thereof. %BR% __Note:__ Invalidating affected topics can slow down topic save in very large webs; it is recommended to set this to =none= for webs that have 10K+ topics. * Set VARCACHEPLUGIN_INVALIDATEONCREATE = parent - * Set VARCACHEPLUGIN_INVALIDATEONUPDATE = include, parent + * <nop>Set VARCACHEPLUGIN_INVALIDATEONUPDATE = include, parent * Cache help messages. Use =$age= to indicate age of cache, =$link= to indicate the refresh URL: * Set VARCACHEPLUGIN_CACHEMSG = This topic was cached $age ago ([<nop>[$link][refresh]]) |
From: <de...@de...> - 2017-01-13 00:52:25
|
Author: HideyoImazu Date: 2017-01-13 00:51:10 +0000 (Fri, 13 Jan 2017) New Revision: 30296 Trac url: http://develop.twiki.org/trac/changeset/30296 Modified: twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt Log: Item7703: minor document update for VarCachePlugin Modified: twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt =================================================================== --- twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2017-01-12 06:46:52 UTC (rev 30295) +++ twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2017-01-13 00:51:10 UTC (rev 30296) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1484203439" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1484268621" format="1.1" version="$Rev$"}% ---+!! Variable Cache Plugin <!-- Contributions to this plugin are appreciated. Please update the plugin page at @@ -55,7 +55,10 @@ ---++ Plugin Settings -This plugin can be configured with preferences settings in [[%LOCALSITEPREFS%]] (site level), a WebPreferences (web level) or in a topic (page level). Do not change the settings here, they are here only to illustrate the default values. To overload, copy the settings to one of the aforementioned topics. On a large site having many webs, it's recommended to set VARCACHEPLUGIN_INVALIDATEONUPDATE =none= at the site level to prevent save slowness to happen unexpectedly. +This plugin can be configured with preferences settings in [[%LOCALSITEPREFS%]] (site level), a WebPreferences (web level) or in a topic (page level). Do not change the settings here, they are here only to illustrate the default values. To overload, copy the settings to one of the aforementioned topics. On a large site having many webs, it's recommended to set VARCACHEPLUGIN_INVALIDATEONUPDATE =none= at the site level to prevent save slowness from happening unknowingly. The current site level setting is %IF{"'%VAR{VARCACHEPLUGIN_INVALIDATEONUPDATE}%' != ''" + then="=%VARCACHEPLUGIN_INVALIDATEONUPDATE%=" + else="undefined, which is the same as =include=" +}%. * Debug plugin: (See output in =data/debug.txt=) * Set VARCACHEPLUGIN_DEBUG = 0 @@ -65,7 +68,7 @@ * On topic creation and topic update, invalidate cache of affected topics: =parent= (its parent topic), =parent(32)= (its parent topics on parent path up to 32 levels), =backlinks= (its backlink topics in current web), =include= (its including topics in current web), =none= (no invalidation), or a comma-list thereof. %BR% __Note:__ Invalidating affected topics can slow down topic save in very large webs; it is recommended to set this to =none= for webs that have 10K+ topics. * Set VARCACHEPLUGIN_INVALIDATEONCREATE = parent - * Set VARCACHEPLUGIN_INVALIDATEONUPDATE = include, parent + * <nop>Set VARCACHEPLUGIN_INVALIDATEONUPDATE = include, parent * Cache help messages. Use =$age= to indicate age of cache, =$link= to indicate the refresh URL: * Set VARCACHEPLUGIN_CACHEMSG = This topic was cached $age ago ([<nop>[$link][refresh]]) |
From: <de...@de...> - 2017-01-12 06:47:55
|
Author: HideyoImazu Date: 2017-01-12 06:46:52 +0000 (Thu, 12 Jan 2017) New Revision: 30295 Trac url: http://develop.twiki.org/trac/changeset/30295 Modified: twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt Log: Item7703: minor document update for VarCachePlugin Modified: twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt =================================================================== --- twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2017-01-12 06:45:50 UTC (rev 30294) +++ twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2017-01-12 06:46:52 UTC (rev 30295) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1481688327" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1484203439" format="1.1" version="$Rev$"}% ---+!! Variable Cache Plugin <!-- Contributions to this plugin are appreciated. Please update the plugin page at @@ -55,7 +55,7 @@ ---++ Plugin Settings -This plugin can be configured with preferences settings in [[%LOCALSITEPREFS%]] (site level), a WebPreferences (web level) or in a topic (page level). Do not change the settings here, they are here only to illustrate the default values. To overload, copy the settings to one of the aforementioned topics. +This plugin can be configured with preferences settings in [[%LOCALSITEPREFS%]] (site level), a WebPreferences (web level) or in a topic (page level). Do not change the settings here, they are here only to illustrate the default values. To overload, copy the settings to one of the aforementioned topics. On a large site having many webs, it's recommended to set VARCACHEPLUGIN_INVALIDATEONUPDATE =none= at the site level to prevent save slowness to happen unexpectedly. * Debug plugin: (See output in =data/debug.txt=) * Set VARCACHEPLUGIN_DEBUG = 0 |
From: <de...@de...> - 2017-01-12 06:46:53
|
Author: HideyoImazu Date: 2017-01-12 06:45:50 +0000 (Thu, 12 Jan 2017) New Revision: 30294 Trac url: http://develop.twiki.org/trac/changeset/30294 Modified: twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt Log: Item7703: minor document update for VarCachePlugin Modified: twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt =================================================================== --- twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2017-01-10 05:38:09 UTC (rev 30293) +++ twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2017-01-12 06:45:50 UTC (rev 30294) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1481688327" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1484203439" format="1.1" version="$Rev$"}% ---+!! Variable Cache Plugin <!-- Contributions to this plugin are appreciated. Please update the plugin page at @@ -55,7 +55,7 @@ ---++ Plugin Settings -This plugin can be configured with preferences settings in [[%LOCALSITEPREFS%]] (site level), a WebPreferences (web level) or in a topic (page level). Do not change the settings here, they are here only to illustrate the default values. To overload, copy the settings to one of the aforementioned topics. +This plugin can be configured with preferences settings in [[%LOCALSITEPREFS%]] (site level), a WebPreferences (web level) or in a topic (page level). Do not change the settings here, they are here only to illustrate the default values. To overload, copy the settings to one of the aforementioned topics. On a large site having many webs, it's recommended to set VARCACHEPLUGIN_INVALIDATEONUPDATE =none= at the site level to prevent save slowness to happen unexpectedly. * Debug plugin: (See output in =data/debug.txt=) * Set VARCACHEPLUGIN_DEBUG = 0 |
From: <de...@de...> - 2017-01-10 05:38:43
|
Author: HideyoImazu Date: 2017-01-10 05:38:09 +0000 (Tue, 10 Jan 2017) New Revision: 30293 Trac url: http://develop.twiki.org/trac/changeset/30293 Modified: twiki/branches/TWikiRelease06x00/core/data/TWiki/TWikiAccessControl.txt twiki/branches/TWikiRelease06x00/core/lib/TWiki/Access.pm Log: Item7766: Allow or deny access to topic in addition to allowed or denied at the web level Modified: twiki/branches/TWikiRelease06x00/core/data/TWiki/TWikiAccessControl.txt =================================================================== --- twiki/branches/TWikiRelease06x00/core/data/TWiki/TWikiAccessControl.txt 2017-01-10 05:37:18 UTC (rev 30292) +++ twiki/branches/TWikiRelease06x00/core/data/TWiki/TWikiAccessControl.txt 2017-01-10 05:38:09 UTC (rev 30293) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1427699188" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1484026158" format="1.1" version="$Rev$"}% ---+ TWiki Access Control %VAR{"TWIKI_ACCESS_CONTROL_TOP" default="<nop>" ignorenull="on"}% @@ -136,6 +136,10 @@ For example, set this to restrict a topic to be viewable only by the !MarketingExecGroup: * ==Set <nop>ALLOWTOPICVIEW = <nop>%USERSWEB%.MarketingExecGroup== +You may want to allow or deny access to a topic in addition to the ALLOWEB* or DENYWEB* specifies. In that case having + as the first non-space character of ALLOWTOPIC* or DENYTOPIC* has that effect. +For example, the following setting allows view by !MarketingExecGroup in addition to the people ALLOWWEBVIEW allows. + * ==Set <nop>ALLOWTOPICVIEW = + <nop>%USERSWEB%.MarketingExecGroup== + See "How TWiki evaluates ALLOW/DENY settings" below for more on how ALLOW and DENY interacts. %X% If the same setting is defined multiple times the last one overrides the previous. They are not OR'ed together. Modified: twiki/branches/TWikiRelease06x00/core/lib/TWiki/Access.pm =================================================================== --- twiki/branches/TWikiRelease06x00/core/lib/TWiki/Access.pm 2017-01-10 05:37:18 UTC (rev 30292) +++ twiki/branches/TWikiRelease06x00/core/lib/TWiki/Access.pm 2017-01-10 05:38:09 UTC (rev 30293) @@ -413,6 +413,8 @@ my $allowText; my $denyText; + my $denyWeb = $prefs->getWebPreferencesValue( 'DENYWEB'.$mode, $web ); + my $allowWeb = $prefs->getWebPreferencesValue( 'ALLOWWEB'.$mode, $web ); # retrieve $TWiki::cfg{Access}{Topic}{TOPIC} my $cfgAccessTopic; @@ -464,6 +466,7 @@ 'DENYTOPIC'.$mode, $web, $topic ); } if( defined( $denyText ) && $denyText =~ /\S/ ) { + $denyText =~ s/^\s*\+/$denyWeb, /; my $foreignWebDenyDynamic = 0; if( $isDynamic && $denyText =~ /%/ ) { if( $session->{webName} ne $web ) { @@ -504,6 +507,7 @@ } if( defined( $allowText ) && $allowText =~ /\S/ ) { my $foreignWebAllowDynamic = 0; + $allowText =~ s/^\s*\+/$allowWeb, /; if ( $isDynamic && $allowText =~ /%/ ) { if ( $session->{webName} ne $web ) { $foreignWebAllowDynamic = 1; @@ -540,7 +544,7 @@ # or is null, and DENYTOPIC is not set or is null my $cacheWebLevel = 1; unless( defined( $denyText ) && $denyText =~ /\S/ ) { - $denyText = $prefs->getWebPreferencesValue( 'DENYWEB'.$mode, $web ); + $denyText = $denyWeb; if( defined( $denyText ) ) { my $foreignWebDenyDynamic = 0; if ( $isDynamic && $denyText =~ /%/ ) { @@ -572,7 +576,7 @@ # Check ALLOWWEB. If this is defined and not overridden by # ALLOWTOPIC, the user _must_ be in it. - $allowText = $prefs->getWebPreferencesValue( 'ALLOWWEB'.$mode, $web ); + $allowText = $allowWeb; if( defined( $allowText ) && $allowText =~ /\S/ ) { my $foreignWebAllowDynamic = 0; |
From: <de...@de...> - 2017-01-10 05:37:52
|
Author: HideyoImazu Date: 2017-01-10 05:37:18 +0000 (Tue, 10 Jan 2017) New Revision: 30292 Trac url: http://develop.twiki.org/trac/changeset/30292 Modified: twiki/trunk/core/data/TWiki/TWikiAccessControl.txt twiki/trunk/core/lib/TWiki/Access.pm Log: Item7766: Allow or deny access to topic in addition to allowed or denied at the web level Modified: twiki/trunk/core/data/TWiki/TWikiAccessControl.txt =================================================================== --- twiki/trunk/core/data/TWiki/TWikiAccessControl.txt 2017-01-10 04:18:06 UTC (rev 30291) +++ twiki/trunk/core/data/TWiki/TWikiAccessControl.txt 2017-01-10 05:37:18 UTC (rev 30292) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1427699188" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1484026158" format="1.1" version="$Rev$"}% ---+ TWiki Access Control %VAR{"TWIKI_ACCESS_CONTROL_TOP" default="<nop>" ignorenull="on"}% @@ -136,6 +136,10 @@ For example, set this to restrict a topic to be viewable only by the !MarketingExecGroup: * ==Set <nop>ALLOWTOPICVIEW = <nop>%USERSWEB%.MarketingExecGroup== +You may want to allow or deny access to a topic in addition to the ALLOWEB* or DENYWEB* specifies. In that case having + as the first non-space character of ALLOWTOPIC* or DENYTOPIC* has that effect. +For example, the following setting allows view by !MarketingExecGroup in addition to the people ALLOWWEBVIEW allows. + * ==Set <nop>ALLOWTOPICVIEW = + <nop>%USERSWEB%.MarketingExecGroup== + See "How TWiki evaluates ALLOW/DENY settings" below for more on how ALLOW and DENY interacts. %X% If the same setting is defined multiple times the last one overrides the previous. They are not OR'ed together. Modified: twiki/trunk/core/lib/TWiki/Access.pm =================================================================== --- twiki/trunk/core/lib/TWiki/Access.pm 2017-01-10 04:18:06 UTC (rev 30291) +++ twiki/trunk/core/lib/TWiki/Access.pm 2017-01-10 05:37:18 UTC (rev 30292) @@ -413,6 +413,8 @@ my $allowText; my $denyText; + my $denyWeb = $prefs->getWebPreferencesValue( 'DENYWEB'.$mode, $web ); + my $allowWeb = $prefs->getWebPreferencesValue( 'ALLOWWEB'.$mode, $web ); # retrieve $TWiki::cfg{Access}{Topic}{TOPIC} my $cfgAccessTopic; @@ -464,6 +466,7 @@ 'DENYTOPIC'.$mode, $web, $topic ); } if( defined( $denyText ) && $denyText =~ /\S/ ) { + $denyText =~ s/^\s*\+/$denyWeb, /; my $foreignWebDenyDynamic = 0; if( $isDynamic && $denyText =~ /%/ ) { if( $session->{webName} ne $web ) { @@ -504,6 +507,7 @@ } if( defined( $allowText ) && $allowText =~ /\S/ ) { my $foreignWebAllowDynamic = 0; + $allowText =~ s/^\s*\+/$allowWeb, /; if ( $isDynamic && $allowText =~ /%/ ) { if ( $session->{webName} ne $web ) { $foreignWebAllowDynamic = 1; @@ -540,7 +544,7 @@ # or is null, and DENYTOPIC is not set or is null my $cacheWebLevel = 1; unless( defined( $denyText ) && $denyText =~ /\S/ ) { - $denyText = $prefs->getWebPreferencesValue( 'DENYWEB'.$mode, $web ); + $denyText = $denyWeb; if( defined( $denyText ) ) { my $foreignWebDenyDynamic = 0; if ( $isDynamic && $denyText =~ /%/ ) { @@ -572,7 +576,7 @@ # Check ALLOWWEB. If this is defined and not overridden by # ALLOWTOPIC, the user _must_ be in it. - $allowText = $prefs->getWebPreferencesValue( 'ALLOWWEB'.$mode, $web ); + $allowText = $allowWeb; if( defined( $allowText ) && $allowText =~ /\S/ ) { my $foreignWebAllowDynamic = 0; |
From: <de...@de...> - 2017-01-10 04:18:39
|
Author: HideyoImazu Date: 2017-01-10 04:18:06 +0000 (Tue, 10 Jan 2017) New Revision: 30291 Trac url: http://develop.twiki.org/trac/changeset/30291 Modified: twiki/branches/TWikiRelease06x00/core/lib/TWiki/Store/RcsWrap.pm Log: Item7765: Dangling RCS semaphore file causes topic/attachment save to fail Modified: twiki/branches/TWikiRelease06x00/core/lib/TWiki/Store/RcsWrap.pm =================================================================== --- twiki/branches/TWikiRelease06x00/core/lib/TWiki/Store/RcsWrap.pm 2017-01-10 04:16:52 UTC (rev 30290) +++ twiki/branches/TWikiRelease06x00/core/lib/TWiki/Store/RcsWrap.pm 2017-01-10 04:18:06 UTC (rev 30291) @@ -408,6 +408,11 @@ $comment = 'none' unless $comment; + # Item7765 + my $semaphoreFile = $this->{file}; + $semaphoreFile =~ s:^(.*/)(.*):$1,$2,:; + unlink $semaphoreFile; + my( $cmd, $rcsOutput, $exit ); if( defined( $date )) { require TWiki::Time; @@ -442,6 +447,11 @@ return unless -e $this->{rcsFile}; + # Item7765 + my $semaphoreFile = $this->{file}; + $semaphoreFile =~ s:^(.*/)(.*):$1,$2,:; + unlink $semaphoreFile; + # Try and get a lock on the file my ($rcsOutput, $exit) = $TWiki::sandbox->sysCommand( $TWiki::cfg{RCS}{lockCmd}, FILENAME => $this->{file} ); |
From: <de...@de...> - 2017-01-10 04:17:25
|
Author: HideyoImazu Date: 2017-01-10 04:16:52 +0000 (Tue, 10 Jan 2017) New Revision: 30290 Trac url: http://develop.twiki.org/trac/changeset/30290 Modified: twiki/trunk/core/lib/TWiki/Store/RcsWrap.pm Log: Item7765: Dangling RCS semaphore file causes topic/attachment save to fail Modified: twiki/trunk/core/lib/TWiki/Store/RcsWrap.pm =================================================================== --- twiki/trunk/core/lib/TWiki/Store/RcsWrap.pm 2016-12-15 05:11:04 UTC (rev 30289) +++ twiki/trunk/core/lib/TWiki/Store/RcsWrap.pm 2017-01-10 04:16:52 UTC (rev 30290) @@ -408,6 +408,11 @@ $comment = 'none' unless $comment; + # Item7765 + my $semaphoreFile = $this->{file}; + $semaphoreFile =~ s:^(.*/)(.*):$1,$2,:; + unlink $semaphoreFile; + my( $cmd, $rcsOutput, $exit ); if( defined( $date )) { require TWiki::Time; @@ -442,6 +447,11 @@ return unless -e $this->{rcsFile}; + # Item7765 + my $semaphoreFile = $this->{file}; + $semaphoreFile =~ s:^(.*/)(.*):$1,$2,:; + unlink $semaphoreFile; + # Try and get a lock on the file my ($rcsOutput, $exit) = $TWiki::sandbox->sysCommand( $TWiki::cfg{RCS}{lockCmd}, FILENAME => $this->{file} ); |
From: Peter T. <pe...@th...> - 2017-01-04 19:39:19
|
I wish you all a Häppy New Year! Please join our TWiki Kampala Release Meeting, http://twiki.org/cgi-bin/view/Codev/KampalaReleaseMeeting2017x01x05 scheduled for 2017-01-05 23:00 GMT [1] on IRC channel #twiki_release on the irc.freenode.net IRC network [2] - in about 28 hours from now. Proposed agenda: 1. Feature Requests for Kampala Release 2. Review Urgent and Not So Urgent Bugs 3. Extensions 4. Miscellaneous The meeting is on Thursday or Friday, depending on your time zone. Meeting time in different time zones, tomorrow: * USA Pacific Time Zone: 03:00pm on Thu * USA Eastern Time Zone: 06:00pm on Thu * Central Europe: 24:00 on Thu/Fri night * Japan: 08:00 on Fri Please show up in time to save everybody's time. And remember that the release meeting is where decisions are made. We invite all TWiki.org contributors to join, as well as people with interest in the TWiki project in general. Cheers, Peter [1]: http://www.timeanddate.com/worldclock/converter.html?iso=20170105T230000&p1=tz_gmt&p2=248&p3=268&p4=224&p5=179 [2]: http://twiki.org/cgi-bin/view/Codev/TWikiIRC -- > Peter Thoeny - Peter09[at]Thoeny.org > http://bit.ly/MrTWiki - consulting on enterprise collaboration > http://TWiki.org - is your team already TWiki enabled? > http://qualityHDR.com - Quality HDR Photography > Knowledge cannot be managed, it can be discovered and shared > This e-mail is: (_) private (_) ask first (x) public |
From: <de...@de...> - 2016-12-15 05:12:08
|
Author: HideyoImazu Date: 2016-12-15 05:11:04 +0000 (Thu, 15 Dec 2016) New Revision: 30289 Trac url: http://develop.twiki.org/trac/changeset/30289 Modified: twiki/trunk/LdapNgPlugin/data/TWiki/VarLDAP.txt Log: Item7700: TWiki.VarLDAP minor fix Modified: twiki/trunk/LdapNgPlugin/data/TWiki/VarLDAP.txt =================================================================== --- twiki/trunk/LdapNgPlugin/data/TWiki/VarLDAP.txt 2016-12-14 04:14:48 UTC (rev 30288) +++ twiki/trunk/LdapNgPlugin/data/TWiki/VarLDAP.txt 2016-12-15 05:11:04 UTC (rev 30289) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1356669011" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1481778565" format="1.1" version="$Rev$"}% %META:TOPICPARENT{name="TWikiVariables"}% #VarLDAP ---+++ LDAP{"filter" format="format"} -- LDAP directory query @@ -25,7 +25,7 @@ | =limit="100"= | maximum number of records to return | no limit | | =skip="10"= | number of records in the hit set to skip before displaying them | 0 (nothing is skipped) | | =required="..."= | a comma separated list of LDAP record attributes. If specified, the LDAP query results not having all of the specified attributes are eliminated | nothing is required | - | =hidenull="on"= | wether to hide any output on an empty hit set; possible values: =on=, =off= | =off= | + | =hidenull="on"= | wether to hide any output on an empty hit set; possible values: =on=, =off= | =off= | | =default="..."= | when the LDAP query yields no results, the value of this parameter is returned as the search result instead of null. Naturally, if =hidenull= is on, =default= doesn't have any effect | =""= (null string) | %IF{"{Plugins}{LdapNgPlugin}{AutoClear}" else=" | =clear=\"...\"= | comma separated list of attributes to be removed from the output if they are not resolved | nothing is cleared | |
From: Imazu, H. <Hid...@mo...> - 2016-12-15 02:06:51
|
Hi Peter, While we're on winter hiatus, can you please take a look at http://twiki.org/cgi-bin/view/Codev/AllowOrDenyTopicInAdditionToWebLevel? Any comments? Regards, Imazu -----Original Message----- From: Peter Thoeny [mailto:pe...@th...] Sent: Tuesday, December 13, 2016 21:48 To: TWiki-Dev list for developers Subject: Re: [TWiki-Dev] Postpone this week's TWiki release meeting? All: OK, let's skip the second December meeting. See you next year! Cheers, Peter On Dec 12, 2016, at 11:24 PM, "Imazu, Hideyo" <Hid...@mo...> wrote: > How about skipping the third week of Dec meeting? If we postpone the meeting by one week, it's in the holiday season. > > -----Original Message----- > From: Peter Thoeny [mailto:pe...@th...] > Sent: Monday, December 12, 2016 21:26 > To: TWiki-Dev list for developers > Subject: [TWiki-Dev] Postpone this week's TWiki release meeting? > > All: > > I am in vacation in the mountains with limited internet access. Shall we postpone the meeting by one week? Alternatively you could go head with me if you like. In that case I'll send the invite as usual. > > Cheers, > Peter > > > -- >> Peter Thoeny - Peter09[at]Thoeny.org >> http://bit.ly/MrTWiki - consulting on enterprise collaboration >> http://TWiki.org - is your team already TWiki enabled? >> http://qualityHDR.com - Quality HDR Photography Knowledge cannot be >> managed, it can be discovered and shared >> This e-mail is: (_) private (_) ask first (x) public > > > ---------------------------------------------------------------------- > -------- Developer Access Program for Intel Xeon Phi Processors Access > to Intel Xeon Phi processor-based developer platforms. > With one year of Intel Parallel Studio XE. > Training and support from Colfax. > Order your platform today.http://sdm.link/xeonphi > _______________________________________________ > TWiki-Dev mailing list > TWi...@li... > https://lists.sourceforge.net/lists/listinfo/twiki-dev > > > ---------------------------------------------------------------------- > ---------- > > NOTICE: Morgan Stanley is not acting as a municipal advisor and the opinions or views contained herein are not intended to be, and do not constitute, advice within the meaning of Section 975 of the Dodd-Frank Wall Street Reform and Consumer Protection Act. If you have received this communication in error, please destroy all electronic and paper copies and notify the sender immediately. Mistransmission is not intended to waive confidentiality or privilege. Morgan Stanley reserves the right, to the extent permitted under applicable law, to monitor electronic communications. This message is subject to terms available at the following link: http://www.morganstanley.com/disclaimers If you cannot access these links, please notify us by reply message and we will send the contents to you. By communicating with Morgan Stanley you consent to the foregoing and to the voice recording of conversations with personnel of Morgan Stanley. > ---------------------------------------------------------------------- > -------- Developer Access Program for Intel Xeon Phi Processors Access > to Intel Xeon Phi processor-based developer platforms. > With one year of Intel Parallel Studio XE. > Training and support from Colfax. > Order your platform today.http://sdm.link/xeonphi > _______________________________________________ > TWiki-Dev mailing list > TWi...@li... > https://lists.sourceforge.net/lists/listinfo/twiki-dev -- > Peter Thoeny - Peter[at]Thoeny.org - M: +1-408-505-5108 > http://bit.ly/MrTWiki - consulting on enterprise collaboration > http://TWiki.org - is your team already TWiki enabled? > http://qualityHDR.com - Quality HDR Photography Knowledge cannot be > managed, it can be discovered and shared > This e-mail is: (_) private (x) ask first (_) public ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/slashdot _______________________________________________ TWiki-Dev mailing list TWi...@li... https://lists.sourceforge.net/lists/listinfo/twiki-dev -------------------------------------------------------------------------------- NOTICE: Morgan Stanley is not acting as a municipal advisor and the opinions or views contained herein are not intended to be, and do not constitute, advice within the meaning of Section 975 of the Dodd-Frank Wall Street Reform and Consumer Protection Act. If you have received this communication in error, please destroy all electronic and paper copies and notify the sender immediately. Mistransmission is not intended to waive confidentiality or privilege. Morgan Stanley reserves the right, to the extent permitted under applicable law, to monitor electronic communications. This message is subject to terms available at the following link: http://www.morganstanley.com/disclaimers If you cannot access these links, please notify us by reply message and we will send the contents to you. By communicating with Morgan Stanley you consent to the foregoing and to the voice recording of conversations with personnel of Morgan Stanley. |
From: <de...@de...> - 2016-12-14 04:15:37
|
Author: HideyoImazu Date: 2016-12-14 04:14:48 +0000 (Wed, 14 Dec 2016) New Revision: 30288 Trac url: http://develop.twiki.org/trac/changeset/30288 Modified: twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt twiki/branches/TWikiRelease06x00/VarCachePlugin/lib/TWiki/Plugins/VarCachePlugin.pm Log: Item7764: VarCachePlugin may cause an error on a subweb Modified: twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt =================================================================== --- twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2016-12-14 04:12:45 UTC (rev 30287) +++ twiki/branches/TWikiRelease06x00/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2016-12-14 04:14:48 UTC (rev 30288) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1452759587" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1481688327" format="1.1" version="$Rev$"}% ---+!! Variable Cache Plugin <!-- Contributions to this plugin are appreciated. Please update the plugin page at @@ -125,13 +125,14 @@ | Copyright: | © 2013-2015 Wave Systems Corp. %BR% © 2004-2016 Peter Thoeny, [[http://twiki.org/][TWiki.org]] %BR% © 2008-2016 TWiki:TWiki.TWikiContributor | | Sponsor: | [[http://www.wave.com/][Wave Systems Corp.]] for VARCACHE_EXCLUDE_ variable prefix and cache invalidation logic | | License: | GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]]) | -| Plugin Version: | 2016-01-14 | +| Plugin Version: | 2016-12-14 | %TWISTY{ mode="div" showlink="Show Change History %ICONURL{toggleopen}%" hidelink="Hide Change History %ICONURL{toggleclose}% " }% %TABLE{ tablewidth="100%" columnwidths="170," }% +| 2016-12-14: | TWikibug:Item7764: May cause an error on a subweb | | 2016-01-14: | TWikibug:Item7708: Copyright update to 2016 | | 2015-03-16: | TWikibug:Item7625: Invalidate parent topics on parent path up to indicated level | | 2015-01-09: | TWikibug:Item7568: Document limitation of slow topic saves in very large webs; remove VARCACHE if found in an INCLUDE | Modified: twiki/branches/TWikiRelease06x00/VarCachePlugin/lib/TWiki/Plugins/VarCachePlugin.pm =================================================================== --- twiki/branches/TWikiRelease06x00/VarCachePlugin/lib/TWiki/Plugins/VarCachePlugin.pm 2016-12-14 04:12:45 UTC (rev 30287) +++ twiki/branches/TWikiRelease06x00/VarCachePlugin/lib/TWiki/Plugins/VarCachePlugin.pm 2016-12-14 04:14:48 UTC (rev 30288) @@ -367,7 +367,7 @@ my $dir = TWiki::Func::getWorkArea($pluginName) . "/$web"; if( ( $mkDir ) && ( ! -e "$dir" ) ) { my $sumsk = umask( 002 ); - mkdir( $dir, $TWiki::cfg{RCS}{dirPermission} ); + File::Path::mkpath( $dir, 0, $TWiki::cfg{RCS}{dirPermission} ); umask( $sumsk ); } |
From: <de...@de...> - 2016-12-14 04:13:33
|
Author: HideyoImazu Date: 2016-12-14 04:12:45 +0000 (Wed, 14 Dec 2016) New Revision: 30287 Trac url: http://develop.twiki.org/trac/changeset/30287 Modified: twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt twiki/trunk/VarCachePlugin/lib/TWiki/Plugins/VarCachePlugin.pm Log: Item7764: VarCachePlugin may cause an error on a subweb Modified: twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt =================================================================== --- twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2016-12-12 23:57:03 UTC (rev 30286) +++ twiki/trunk/VarCachePlugin/data/TWiki/VarCachePlugin.txt 2016-12-14 04:12:45 UTC (rev 30287) @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="TWikiContributor" date="1452759587" format="1.1" version="$Rev$"}% +%META:TOPICINFO{author="TWikiContributor" date="1481688327" format="1.1" version="$Rev$"}% ---+!! Variable Cache Plugin <!-- Contributions to this plugin are appreciated. Please update the plugin page at @@ -125,13 +125,14 @@ | Copyright: | © 2013-2015 Wave Systems Corp. %BR% © 2004-2016 Peter Thoeny, [[http://twiki.org/][TWiki.org]] %BR% © 2008-2016 TWiki:TWiki.TWikiContributor | | Sponsor: | [[http://www.wave.com/][Wave Systems Corp.]] for VARCACHE_EXCLUDE_ variable prefix and cache invalidation logic | | License: | GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]]) | -| Plugin Version: | 2016-01-14 | +| Plugin Version: | 2016-12-14 | %TWISTY{ mode="div" showlink="Show Change History %ICONURL{toggleopen}%" hidelink="Hide Change History %ICONURL{toggleclose}% " }% %TABLE{ tablewidth="100%" columnwidths="170," }% +| 2016-12-14: | TWikibug:Item7764: May cause an error on a subweb | | 2016-01-14: | TWikibug:Item7708: Copyright update to 2016 | | 2015-03-16: | TWikibug:Item7625: Invalidate parent topics on parent path up to indicated level | | 2015-01-09: | TWikibug:Item7568: Document limitation of slow topic saves in very large webs; remove VARCACHE if found in an INCLUDE | Modified: twiki/trunk/VarCachePlugin/lib/TWiki/Plugins/VarCachePlugin.pm =================================================================== --- twiki/trunk/VarCachePlugin/lib/TWiki/Plugins/VarCachePlugin.pm 2016-12-12 23:57:03 UTC (rev 30286) +++ twiki/trunk/VarCachePlugin/lib/TWiki/Plugins/VarCachePlugin.pm 2016-12-14 04:12:45 UTC (rev 30287) @@ -367,7 +367,7 @@ my $dir = TWiki::Func::getWorkArea($pluginName) . "/$web"; if( ( $mkDir ) && ( ! -e "$dir" ) ) { my $sumsk = umask( 002 ); - mkdir( $dir, $TWiki::cfg{RCS}{dirPermission} ); + File::Path::mkpath( $dir, 0, $TWiki::cfg{RCS}{dirPermission} ); umask( $sumsk ); } |
From: Peter T. <pe...@th...> - 2016-12-13 13:00:26
|
All: OK, let's skip the second December meeting. See you next year! Cheers, Peter On Dec 12, 2016, at 11:24 PM, "Imazu, Hideyo" <Hid...@mo...> wrote: > How about skipping the third week of Dec meeting? If we postpone the meeting by one week, it's in the holiday season. > > -----Original Message----- > From: Peter Thoeny [mailto:pe...@th...] > Sent: Monday, December 12, 2016 21:26 > To: TWiki-Dev list for developers > Subject: [TWiki-Dev] Postpone this week's TWiki release meeting? > > All: > > I am in vacation in the mountains with limited internet access. Shall we postpone the meeting by one week? Alternatively you could go head with me if you like. In that case I'll send the invite as usual. > > Cheers, > Peter > > > -- >> Peter Thoeny - Peter09[at]Thoeny.org >> http://bit.ly/MrTWiki - consulting on enterprise collaboration >> http://TWiki.org - is your team already TWiki enabled? >> http://qualityHDR.com - Quality HDR Photography Knowledge cannot be >> managed, it can be discovered and shared >> This e-mail is: (_) private (_) ask first (x) public > > > ------------------------------------------------------------------------------ > Developer Access Program for Intel Xeon Phi Processors Access to Intel Xeon Phi processor-based developer platforms. > With one year of Intel Parallel Studio XE. > Training and support from Colfax. > Order your platform today.http://sdm.link/xeonphi _______________________________________________ > TWiki-Dev mailing list > TWi...@li... > https://lists.sourceforge.net/lists/listinfo/twiki-dev > > > -------------------------------------------------------------------------------- > > NOTICE: Morgan Stanley is not acting as a municipal advisor and the opinions or views contained herein are not intended to be, and do not constitute, advice within the meaning of Section 975 of the Dodd-Frank Wall Street Reform and Consumer Protection Act. If you have received this communication in error, please destroy all electronic and paper copies and notify the sender immediately. Mistransmission is not intended to waive confidentiality or privilege. Morgan Stanley reserves the right, to the extent permitted under applicable law, to monitor electronic communications. This message is subject to terms available at the following link: http://www.morganstanley.com/disclaimers If you cannot access these links, please notify us by reply message and we will send the contents to you. By communicating with Morgan Stanley you consent to the foregoing and to the voice recording of conversations with personnel of Morgan Stanley. > ------------------------------------------------------------------------------ > Developer Access Program for Intel Xeon Phi Processors > Access to Intel Xeon Phi processor-based developer platforms. > With one year of Intel Parallel Studio XE. > Training and support from Colfax. > Order your platform today.http://sdm.link/xeonphi > _______________________________________________ > TWiki-Dev mailing list > TWi...@li... > https://lists.sourceforge.net/lists/listinfo/twiki-dev -- > Peter Thoeny - Peter[at]Thoeny.org - M: +1-408-505-5108 > http://bit.ly/MrTWiki - consulting on enterprise collaboration > http://TWiki.org - is your team already TWiki enabled? > http://qualityHDR.com - Quality HDR Photography > Knowledge cannot be managed, it can be discovered and shared > This e-mail is: (_) private (x) ask first (_) public |