From 6d7d53bbff975ac9421167f74c00237e35775e49 Mon Sep 17 00:00:00 2001 From: JT Smith Date: Sun, 15 Feb 2004 19:11:00 +0000 Subject: [PATCH] added drag and drop content --- docs/upgrades/upgrade_5.9.9-6.0.0.pl | 86 ++++- docs/upgrades/upgrade_5.9.9-6.0.0.sql | 16 +- lib/WebGUI/Icon.pm | 19 +- lib/WebGUI/Operation/Page.pm | 26 +- lib/WebGUI/Page.pm | 4 +- lib/WebGUI/SQL.pm | 4 +- www/extras/draggable.js | 391 ++++++++++++++++++++ www/extras/opaque.gif | Bin 0 -> 47 bytes www/extras/toolbar/charcoal/drag.gif | Bin 0 -> 1270 bytes www/extras/toolbar/classic/drag.gif | Bin 0 -> 907 bytes www/extras/toolbar/default/drag.gif | Bin 0 -> 1241 bytes www/extras/toolbar/dutch/drag.gif | Bin 0 -> 1241 bytes www/extras/toolbar/iconic/drag.gif | Bin 0 -> 187 bytes www/extras/toolbar/italiano/drag.gif | Bin 0 -> 1241 bytes www/extras/toolbar/italianoclassic/drag.gif | Bin 0 -> 907 bytes www/extras/toolbar/spanish/drag.gif | Bin 0 -> 1241 bytes 16 files changed, 527 insertions(+), 19 deletions(-) create mode 100644 www/extras/draggable.js create mode 100644 www/extras/opaque.gif create mode 100644 www/extras/toolbar/charcoal/drag.gif create mode 100644 www/extras/toolbar/classic/drag.gif create mode 100644 www/extras/toolbar/default/drag.gif create mode 100644 www/extras/toolbar/dutch/drag.gif create mode 100644 www/extras/toolbar/iconic/drag.gif create mode 100644 www/extras/toolbar/italiano/drag.gif create mode 100644 www/extras/toolbar/italianoclassic/drag.gif create mode 100644 www/extras/toolbar/spanish/drag.gif diff --git a/docs/upgrades/upgrade_5.9.9-6.0.0.pl b/docs/upgrades/upgrade_5.9.9-6.0.0.pl index 24fabc81b..9a43f1fee 100644 --- a/docs/upgrades/upgrade_5.9.9-6.0.0.pl +++ b/docs/upgrades/upgrade_5.9.9-6.0.0.pl @@ -119,13 +119,72 @@ while (my $template = $sth->hashRef) { div.wobject { border: 2px hidden; } - + .dragable{ + position: relative; +} +.dragTrigger{ + position: relative; + cursor: move; +} +.dragging{ + position: relative; + cursor: hand; + z-index: 2000; + background-image: url("^Extras;opaque.gif"); +} +.draggedOverTop{ + position: relative; + border: 1px dotted #aaaaaa; + border-top: 8px #aaaaaa dotted; +} +.draggedOverBottom { + position: relative; + border: 1px dotted #aaaaaa; + border-bottom: 8px #aaaaaa dotted; +} +.hidden{ + display: none; +} +.blank { + position: relative; + cursor: hand; + background-color: white; +} +.blankOver { + position: relative; + cursor: hand; + background-color: black; +} +.empty { + position: relative; + padding: 25px; + width: 50px; + height: 100px; + background-image: url("^Extras;opaque.gif"); +} + '.$template->{template}; $template->{template} =~ s/\/_positionFormat6x($1)/eg; + $template->{template} .= ' + + + + + + +
+ + +
+ '; WebGUI::SQL->write("update template set namespace='page', template=".quote($template->{template}) ." where templateId=".$template->{templateId}." and namespace='Page'"); } @@ -243,7 +302,7 @@ while (my $data = $a->hashRef) { my $subId = getNextId("USS_submissionId"); my $forum = WebGUI::Forum->create({}); WebGUI::SQL->write("insert into USS_submission (USS_submissionId, USS_id, title, username, userId, content, - dateUpdated, dateSubmited, forumId,contentType) values ( $subId, $ussId, ".quote($sub->{question}).", + dateUpdated, dateSubmitted, forumId,contentType) values ( $subId, $ussId, ".quote($sub->{question}).", ".quote($data->{username}).", ".$data->{ownerId}.", ".quote($sub->{answer}).", ".$data->{lastEdited}.", ".$data->{dateAdded}.", ".$forum->get("forumId").", 'html')"); } @@ -309,7 +368,7 @@ while (my $data = $a->hashRef) { my $subId = getNextId("USS_submissionId"); my $forum = WebGUI::Forum->create({}); WebGUI::SQL->write("insert into USS_submission (USS_submissionId, USS_id, title, username, userId, content, - dateUpdated, dateSubmited, forumId,contentType,userDefined1, userDefined2) values ( $subId, $ussId, ".quote($sub->{name}).", + dateUpdated, dateSubmitted, forumId,contentType,userDefined1, userDefined2) values ( $subId, $ussId, ".quote($sub->{name}).", ".quote($data->{username}).", ".$data->{ownerId}.", ".quote($sub->{description}).", ".$data->{lastEdited}.", ".$data->{dateAdded}.", ".$forum->get("forumId").", 'html', ".quote($sub->{url}).", ".quote($sub->{newWindow}).")"); } @@ -534,11 +593,23 @@ sub _positionFormat5x { #------------------------------------------------------------------- sub _positionFormat6x { my $newPositionCode = ' + + + + + + + + + + + +
+
+
+ + + @@ -546,7 +617,16 @@ sub _positionFormat6x {
+ +
+
+
'; return $newPositionCode; } diff --git a/docs/upgrades/upgrade_5.9.9-6.0.0.sql b/docs/upgrades/upgrade_5.9.9-6.0.0.sql index 40c9b59b4..497cb1694 100644 --- a/docs/upgrades/upgrade_5.9.9-6.0.0.sql +++ b/docs/upgrades/upgrade_5.9.9-6.0.0.sql @@ -348,17 +348,17 @@ INSERT INTO template VALUES (4,'Tab Form','\r\n

1; -insert into groups (groupId,groupName,description,showInForms) values (5,'Turn Admin On','These users can enable admin mode.',0); -insert into groupGroupings (groupId, inGroup) values (4,5); -insert into groupGroupings (groupId, inGroup) values (6,5); -insert into groupGroupings (groupId, inGroup) values (8,5); -insert into groupGroupings (groupId, inGroup) values (9,5); -insert into groupGroupings (groupId, inGroup) values (10,5); -insert into groupGroupings (groupId, inGroup) values (11,5); +insert into groups (groupId,groupName,description,showInForms) values (12,'Turn Admin On','These users can enable admin mode.',0); +insert into groupGroupings (groupId, inGroup) values (4,12); +insert into groupGroupings (groupId, inGroup) values (6,12); +insert into groupGroupings (groupId, inGroup) values (8,12); +insert into groupGroupings (groupId, inGroup) values (9,12); +insert into groupGroupings (groupId, inGroup) values (10,12); +insert into groupGroupings (groupId, inGroup) values (11,12); delete from groupGroupings where groupId = 3; insert into groupGroupings (groupId, inGroup) select 3, groupId from groups where groupId not in (1,3); CREATE TABLE WSClient ( diff --git a/lib/WebGUI/Icon.pm b/lib/WebGUI/Icon.pm index ff39f2a2d..d9ae701e3 100644 --- a/lib/WebGUI/Icon.pm +++ b/lib/WebGUI/Icon.pm @@ -22,7 +22,7 @@ use WebGUI::URL; our @ISA = qw(Exporter); our @EXPORT = qw(&helpIcon &becomeIcon &cutIcon ©Icon &deleteIcon &editIcon &moveBottomIcon &moveDownIcon &moveLeftIcon &moveRightIcon &moveTopIcon &moveUpIcon - &pageIcon &shortcutIcon &pasteIcon &wobjectIcon &viewIcon); + &pageIcon &dragIcon &shortcutIcon &pasteIcon &wobjectIcon &viewIcon); =head1 NAME @@ -38,6 +38,7 @@ A package for generating user interface buttons. The subroutines found herein do $html = copyIcon('op=something'); $html = cutIcon('op=something'); $html = deleteIcon('op=something'); + $html = dragIcon(); $html = editIcon('op=something'); $html = helpIcon(1,"MyNamespace"); $html = moveBottomIcon('op=something'); @@ -118,7 +119,7 @@ sub cutIcon { =head2 deleteIcon ( urlParameters [, pageURL ] ) -Generates a button with an "X" printed on it. +Generates a button that represents a delete operation. =over @@ -144,6 +145,18 @@ sub deleteIcon { #------------------------------------------------------------------- +=head2 dragIcon ( ) + +Generates an icon that can be used to drag content. + +=cut + +sub dragIcon { + return 'Drag'; +} + +#------------------------------------------------------------------- + =head2 editIcon ( urlParameters [, pageURL ] ) Generates a button with the word "Edit" printed on it. @@ -471,7 +484,7 @@ Generates an icon that looks like a wobject. It's purpose is to represent whethe =cut sub wobjectIcon { - return 'Wobject Settings'; + return 'Wobject Settings'; } diff --git a/lib/WebGUI/Operation/Page.pm b/lib/WebGUI/Operation/Page.pm index 4764ed540..4205e0379 100644 --- a/lib/WebGUI/Operation/Page.pm +++ b/lib/WebGUI/Operation/Page.pm @@ -29,7 +29,7 @@ use WebGUI::Utility; our @ISA = qw(Exporter); our @EXPORT = qw(&www_viewPageTree &www_movePageUp &www_movePageDown &www_cutPage &www_deletePage &www_deletePageConfirm &www_editPage - &www_editPageSave &www_pastePage &www_moveTreePageUp + &www_editPageSave &www_pastePage &www_moveTreePageUp &www_rearrangeWobjects &www_moveTreePageDown &www_moveTreePageLeft &www_moveTreePageRight); #------------------------------------------------------------------- @@ -608,6 +608,30 @@ sub www_pastePage { } } +#------------------------------------------------------------------- +sub www_rearrangeWobjects { + return WebGUI::Privilege::insufficient() unless (WebGUI::Privilege::canEditPage($session{page}{pageId})); + $session{page}{styleId} = 2; + my @contentAreas = split(/\./,$session{form}{map}); + my $templatePosition = 1; + foreach my $position (@contentAreas) { + my @sequence = split(",",$position); + my $sequenceNumber = 1; + foreach my $wobjectId (@sequence) { + $wobjectId =~ s/td(\d+)/$1/; + WebGUI::SQL->setRow("wobject","wobjectId",{ + wobjectId=>$wobjectId, + sequenceNumber=>$sequenceNumber, + templatePosition=>$templatePosition + }); + $sequenceNumber++; + } + $templatePosition++; + } + return $session{form}{map}; +} + + #------------------------------------------------------------------- sub www_viewPageTree { my ($output); diff --git a/lib/WebGUI/Page.pm b/lib/WebGUI/Page.pm index eba018125..ceb42fe30 100644 --- a/lib/WebGUI/Page.pm +++ b/lib/WebGUI/Page.pm @@ -278,7 +278,6 @@ sub generate { .moveUpIcon('op=movePageUp') .moveDownIcon('op=movePageDown') .cutIcon('op=cutPage'); - my @wobjectsinpage; my $sth = WebGUI::SQL->read("select * from wobject where pageId=".$session{page}{pageId}." order by sequenceNumber, wobjectId"); while (my $wobject = $sth->hashRef) { my $wobjectToolbar = wobjectIcon() @@ -325,16 +324,15 @@ sub generate { 'wobject.canView'=>WebGUI::Privilege::canViewWobject($wobject->{wobjectId}), 'wobject.canEdit'=>WebGUI::Privilege::canEditWobject($wobject->{wobjectId}), 'wobject.controls'=>$wobjectToolbar, + 'wobject.controls.drag'=>dragIcon(), 'wobject.namespace'=>$wobject->{namespace}, 'wobject.id'=>$wobject->{wobjectId}, 'wobject.isInDateRange'=>$w->inDateRange, 'wobject.content'=>eval{$w->www_view} }); WebGUI::ErrorHandler::fatalError("Wobject runtime error: ${$wobject}{namespace}. Root cause: ".$@) if($@); - push(@wobjectsinpage,{'wobject.id'=>${$wobject}{wobjectId}}); } $sth->finish; - $var{"wobjectid_list"} = \@wobjectsinpage; return WebGUI::Template::process(getTemplate(),\%var); } diff --git a/lib/WebGUI/SQL.pm b/lib/WebGUI/SQL.pm index 18a95a276..5216ec1d9 100644 --- a/lib/WebGUI/SQL.pm +++ b/lib/WebGUI/SQL.pm @@ -645,7 +645,9 @@ sub setRow { push(@pairs, $key.'='.quote($data->{$key})); } } - WebGUI::SQL->write("update $table set ".join(", ", @pairs)." where ".$keyColumn."=".quote($data->{$keyColumn}), $dbh); + if ($pairs[0] ne "") { + WebGUI::SQL->write("update $table set ".join(", ", @pairs)." where ".$keyColumn."=".quote($data->{$keyColumn}), $dbh); + } return $data->{$keyColumn}; } diff --git a/www/extras/draggable.js b/www/extras/draggable.js new file mode 100644 index 000000000..c0bed0773 --- /dev/null +++ b/www/extras/draggable.js @@ -0,0 +1,391 @@ +//Confugration +//sets the drag accruacy +//a value of 0 is most accurate. The number can be raised to improve performance. +var accuracy = 2; + +//list of the content item names. Could be searched for, but hard coded for performance +var wobjectList=new Array(); +var dragableList=new Array(); +//Internal Config (Do not Edit) + +//browser check +var dom=document.getElementById&&!document.all +var pageURL = ""; +var dragging=false; +var z,x,y +var accuracyCount =0; +var startTD = null; +var endTD = null; +var topelement=dom? "HTML" : "BODY" +var currentDiv = null; +var clipboard = null; +var contra = ""; + +//checks the key Events for copy and paste operations +//ctrlC ctrlV shiftP shiftY +function dragable_checkKeyEvent(e) { + e=dom? e : event; + + if (e.keyCode == 38 || e.keyCode == 40 || e.keyCode==37 || e.keyCode==39 || e.keyCode == 66 || e.keyCode == 65){ + contra+=e.keyCode; + if (contra.indexOf("38403840373937396665") != -1) { + alert("WebGUI was created by Plain Black LLC"); + contra=""; + } + }else { + contra = ""; + } + + if (currentDiv == null) { + return; + } + + if ((e.keyCode == 67 && e.ctrlKey) || (e.keyCode==89 && e.shiftKey)) { + clipboard=currentDiv; + return; + }else if ((e.keyCode == 86 && e.ctrlKey) || (e.keyCode==80 && e.shiftKey)) { + if (clipboard != currentDiv && !dragable_isBlank(clipboard)) { + dragable_moveContent(clipboard,currentDiv); + } + } + +} + +//goes up the parent tree until class is found. If not found, returns null +function dragable_getObjectByClass(target,clazz) { + while (target.tagName!=topelement&&target.className!=clazz){ + target=dom? target.parentNode : target.parentElement + } + + if (target.className==clazz){ + return target; + }else { + return null; + } + +} + +//initialization routine, must be called on load. Sets up event handlers +function dragable_init(url) { + pageURL = url; + //window.scroll(10,500); + //set up event handlers + document.onmouseup=dragable_dragStop; + document.onkeydown=dragable_checkKeyEvent; + document.onmousemove=dragable_move; + + //fill the wobject list + obj = document.getElementById("position1"); + contentCount=2; + while (obj != null) { + tbody = dragable_getElementChildren(obj); + children = dragable_getElementChildren(tbody[0]); + + if (children.length == 0) { + //stick in a blank + dragable_appendBlankRow(tbody[0]); + }else { + for (i = 0; i< children.length;i++) { + wobjectList[wobjectList.length] = children[i]; + dragableList[dragableList.length]=document.getElementById(children[i].id + "_div"); + } + } + obj = document.getElementById("positionArea" + contentCount); + contentCount++; + } + + for (i=0;ix1 && x < (x1 + td.offsetWidth)) { + if (y> y1 && y< (y1 + (td.offsetHeight/2))) { + returnArray[0] = td; + returnArray[1] = "top"; + return returnArray; + }else if (y> y1 && y< (y1 + td.offsetHeight)) { + returnArray[0] = td; + returnArray[1] = "bottom"; + return returnArray; + } + } + } + + return returnArray; +} + +//Called when a content item is dragged over +function dragable_dragOver(obj,position) { + + if (endTD == obj && endTDPos == position ) { + return; + } + + + if(endTD != null && endTD != obj) { + if (dragable_isBlank(endTD)) { + document.getElementById(endTD.id).className="blank"; + }else { + document.getElementById(endTD.id + "_div").className="dragable"; + } + } + + if (dragable_isBlank(obj)) { + divName = td.id; + }else { + divName = td.id + "_div"; + } + + if (dragable_isBlank(obj)) { + document.getElementById(divName).className="blankOver"; + endTDPos=null; + }else if (position == "top") { + endTDPos=position; + document.getElementById(divName).className="draggedOverTop"; + }else { + endTDPos=position; + document.getElementById(divName).className="draggedOverBottom"; + } + + endTD=obj; +} + +//called on mouse up, If an element is being dragged, this method does the right thing. +function dragable_dragStop(e) { + dragging=false; + if (z) { + + if (endTD !=null && startTD!=null) { + dragable_moveContent(startTD,endTD,endTDPos); + startTD=null; + + if (dragable_isBlank(endTD)) { + divName = endTD.id; + }else { + divName=endTD.id + "_div"; + document.getElementById(divName).className="dragable"; + } + var url = pageURL + "?op=rearrangeWobjects&map=" + dragable_getContentMap(); + //window.alert(url); + document.getElementById("dragSubmitter").src = url; + } + + for(i=0;iN{;}**ysL)bsu~6tiOIzA^_O-9?>bpu?T9DE*E&&Ue zj4UQNXEJ}-GR?Lhx1eHV(Is1Si8EWm7BdZ5ma*aP&ABh%pYVMhI&D)kdI;D9{8k1W zC^=nJrnK3q(n|HY;R%ZsH}|5!fzjQ0^#N(bU;uf3kmH6~e<<%zGf9OABH-}~TCD@a zSY?~j-_I1!(wr~y%mBB*G$<8}vydjh={(LiC~17Ps5)BLfx- z>hp<`6ayhPr=TI3Tr4hEfe=$t(S{&2?&eWU>h1<%MCi~VAjAp6h$IaejHurqwOC1w z#$qxdEE{Y;gS4s~#}vjM1Hy4(h6y1s)!pMnQO06Lg2B;1VA$&wy@Uusem5@p$N>nZ z8k+ieArcP7W@eHukadAnzmuTo5J`sgdKcynn9R_H3yZBP+h}aEQ;+I8T^t|j>_oe| zur{>~h8c>K{Ql7J(D=y6*!1*VJU&6ulGEiAg^?2{Z60rcVWMh{gCs===8a}wd%NSb z(iV**PPW)J8k?@u(PMxl@tny7cIo?vqGJ>tCVY}8MkO)oAtXtP5`+*6#u;X?`nb79 z(d*~Jem2VaUj{J9FhQ0HVs5_MK-lcK6XXRUs@G!(!cI=iA}E8REROqeob$ZY!#P3L zX!OFc-(>P0YtYe5FfthT5)wg(9UY(>=V64yFn_<3c4K}7m5D7!13uHi$ zak(fLNcTIvPABn7VdJX@8ZB1Z(a&;Rv{IqnwXd$K)_kl{SM*0(3ILP=RlrOBe*(yS z0hrR(@BXlSGm)8FQD2~1pF&Kel-Jmh1qt^e8^? zWG$t*kNWK1=Ct;b^RHX@THCvAiS0Yh^EWo1mkM-amDCRTVE?+*hIF zAEKeu2UGOs6YCdWu6{k0_uz_U3VHg~W?s{RF-vxB{CPE)eJS*avtQ;~P8x|aF zW@6BYIk92k;WkDgCW#Fbl8$zB>H3986fQc}FK@`V;fA5gv0h34GMmmzi#^)3gVRiI z1}QhpFw5+lva|51-#q*5xG#}`&pjt`7H=}CGJYAjOgEWHx2j~}mG%gEH=YAqS6^SB KaFC6K!5RQmG$@Av literal 0 HcmV?d00001 diff --git a/www/extras/toolbar/default/drag.gif b/www/extras/toolbar/default/drag.gif new file mode 100644 index 0000000000000000000000000000000000000000..9bdb2bb77b6a9efbcd22785352041df1c55578e8 GIT binary patch literal 1241 zcmWmDiBFSv9DwncLk2oa5$6HZDO1NX9Lk|pWK%~r9eB>UjF^dofWa7v2a@5W1q8HG ztCQHNC{PrXtAs-V6)K|&Ewq%D7Nn&Irz3=;Z{NOe-}m>Od;W&c^TXcnIonQrig{zi zN(}mVv^o>-y~gyWBjvgIZk|n^HrJKre47aM>!B_HjknO&I?CEWnW|``7#WHQ?QKH) z7p39j$}40~I<81}bS9(PRr@Brp>i=$vmlLzXF<>uf~*o`EJcHwA9hodUzR$cU^F31;jfsSgV1Y**CEe z$Z2Q@WQ?V_GK(~pp^;k3SO$jsQ02|2xzMtO8fyi45|YJ&rGgr1M))W+g@QE3X^}WB zwWOgOB>v9vHgc$#7%YP4n`oVY>KD)xQskII#uAv-gJcD&TWeQeL(?i|w2|t~M6VAx zlw3xe3x+~_Zys%_u_<%$?n^NKd|r`(_weTA>2{3}DUxmSi{x-6q0Ym5xTyOyD3YOt zgCu@-%}t~i%*!uP)+WaI2!_S7%PZ@homZl)Zc;kuW8d$hx|MZs&Gz^!}GkV%sN*f>1!;ctCrM*u`>x8&6lk84|87=zfXGWFgl*KV)FKCMdM(RjI z8Q@klR7mTEjH#S46fuJ$=G{G_H-}d9oTds!l}e4hL|utUp5#z*>5f=RcMGT)nCZ9c zM0VZZXsR2gyD808M7$@oH=W~BB#lAReWc=?tt%CmUqlnFj-E@jr5c%^GL{--cz_HK z!SDcA=cB46Q0;@Nm)LrE4&`OkeFmynNO1~TYZ-F|v}~X6`UBOhfN2#qRLqP%qds`k z7eZ^)TGHJG!&YKJ*oXdq0`mkc^gL&-rbwFQ>5C%NyW$F>3ld$-vV<((;GMrqo}Ba% z%aZ-Kuq)Iq{KozKg`R6}=j;5IM{WogirWYMGNu9)8nZ0_o1o(kFODhcz>Q50*O}bH zT$j5o8)-J53JXy6efI7CKWDjJ9vcpe*M*0EbjF>vKIur1D!x4^wjm-ld(LD&x_Y^Q z6S*i+>E0OdYqLsp_WJAaw#>2_Q|}wMyX+EK8sB}YU3fXZi~VHwMCZ1j+QZKM=IWNS zDeTMVinQ!%qj1SVp*AGsizqL4sIa%>w7(+QrWGj&D?C(=RQrEy5NTQdtIYr zxYHvb_N2>V*U>58oQ=CwzR^1p^UU9|GNat$1re)v%NAWti5uD4*LL>Gj+fj+Z-QM) zH@7W|OTk#{6?>XGB7+l(xE_8AF)xA)Eb;R46V9+aQeK=`AX-=7{`j6(0-KFR{0F7p B6Nvx- literal 0 HcmV?d00001 diff --git a/www/extras/toolbar/dutch/drag.gif b/www/extras/toolbar/dutch/drag.gif new file mode 100644 index 0000000000000000000000000000000000000000..9bdb2bb77b6a9efbcd22785352041df1c55578e8 GIT binary patch literal 1241 zcmWmDiBFSv9DwncLk2oa5$6HZDO1NX9Lk|pWK%~r9eB>UjF^dofWa7v2a@5W1q8HG ztCQHNC{PrXtAs-V6)K|&Ewq%D7Nn&Irz3=;Z{NOe-}m>Od;W&c^TXcnIonQrig{zi zN(}mVv^o>-y~gyWBjvgIZk|n^HrJKre47aM>!B_HjknO&I?CEWnW|``7#WHQ?QKH) z7p39j$}40~I<81}bS9(PRr@Brp>i=$vmlLzXF<>uf~*o`EJcHwA9hodUzR$cU^F31;jfsSgV1Y**CEe z$Z2Q@WQ?V_GK(~pp^;k3SO$jsQ02|2xzMtO8fyi45|YJ&rGgr1M))W+g@QE3X^}WB zwWOgOB>v9vHgc$#7%YP4n`oVY>KD)xQskII#uAv-gJcD&TWeQeL(?i|w2|t~M6VAx zlw3xe3x+~_Zys%_u_<%$?n^NKd|r`(_weTA>2{3}DUxmSi{x-6q0Ym5xTyOyD3YOt zgCu@-%}t~i%*!uP)+WaI2!_S7%PZ@homZl)Zc;kuW8d$hx|MZs&Gz^!}GkV%sN*f>1!;ctCrM*u`>x8&6lk84|87=zfXGWFgl*KV)FKCMdM(RjI z8Q@klR7mTEjH#S46fuJ$=G{G_H-}d9oTds!l}e4hL|utUp5#z*>5f=RcMGT)nCZ9c zM0VZZXsR2gyD808M7$@oH=W~BB#lAReWc=?tt%CmUqlnFj-E@jr5c%^GL{--cz_HK z!SDcA=cB46Q0;@Nm)LrE4&`OkeFmynNO1~TYZ-F|v}~X6`UBOhfN2#qRLqP%qds`k z7eZ^)TGHJG!&YKJ*oXdq0`mkc^gL&-rbwFQ>5C%NyW$F>3ld$-vV<((;GMrqo}Ba% z%aZ-Kuq)Iq{KozKg`R6}=j;5IM{WogirWYMGNu9)8nZ0_o1o(kFODhcz>Q50*O}bH zT$j5o8)-J53JXy6efI7CKWDjJ9vcpe*M*0EbjF>vKIur1D!x4^wjm-ld(LD&x_Y^Q z6S*i+>E0OdYqLsp_WJAaw#>2_Q|}wMyX+EK8sB}YU3fXZi~VHwMCZ1j+QZKM=IWNS zDeTMVinQ!%qj1SVp*AGsizqL4sIa%>w7(+QrWGj&D?C(=RQrEy5NTQdtIYr zxYHvb_N2>V*U>58oQ=CwzR^1p^UU9|GNat$1re)v%NAWti5uD4*LL>Gj+fj+Z-QM) zH@7W|OTk#{6?>XGB7+l(xE_8AF)xA)Eb;R46V9+aQeK=`AX-=7{`j6(0-KFR{0F7p B6Nvx- literal 0 HcmV?d00001 diff --git a/www/extras/toolbar/iconic/drag.gif b/www/extras/toolbar/iconic/drag.gif new file mode 100644 index 0000000000000000000000000000000000000000..a0a30d4356eb7164f8bef037629de2037659e64a GIT binary patch literal 187 zcmZ?wbhEHb6lV})IKsei=FFLU_wF4yaNz&{|4mIz|7S8htY&!L$ndU{;Z`Zb@2Lzg zn;AZIGd!td_&$;0T0X|$VbP*CVg$()yA#g+4V zpPuBIlHBVmYYu;Udwb{HfD6ARo1J4XzHnBH_f{+T`lNS>efm_UjF^dofWa7v2a@5W1q8HG ztCQHNC{PrXtAs-V6)K|&Ewq%D7Nn&Irz3=;Z{NOe-}m>Od;W&c^TXcnIonQrig{zi zN(}mVv^o>-y~gyWBjvgIZk|n^HrJKre47aM>!B_HjknO&I?CEWnW|``7#WHQ?QKH) z7p39j$}40~I<81}bS9(PRr@Brp>i=$vmlLzXF<>uf~*o`EJcHwA9hodUzR$cU^F31;jfsSgV1Y**CEe z$Z2Q@WQ?V_GK(~pp^;k3SO$jsQ02|2xzMtO8fyi45|YJ&rGgr1M))W+g@QE3X^}WB zwWOgOB>v9vHgc$#7%YP4n`oVY>KD)xQskII#uAv-gJcD&TWeQeL(?i|w2|t~M6VAx zlw3xe3x+~_Zys%_u_<%$?n^NKd|r`(_weTA>2{3}DUxmSi{x-6q0Ym5xTyOyD3YOt zgCu@-%}t~i%*!uP)+WaI2!_S7%PZ@homZl)Zc;kuW8d$hx|MZs&Gz^!}GkV%sN*f>1!;ctCrM*u`>x8&6lk84|87=zfXGWFgl*KV)FKCMdM(RjI z8Q@klR7mTEjH#S46fuJ$=G{G_H-}d9oTds!l}e4hL|utUp5#z*>5f=RcMGT)nCZ9c zM0VZZXsR2gyD808M7$@oH=W~BB#lAReWc=?tt%CmUqlnFj-E@jr5c%^GL{--cz_HK z!SDcA=cB46Q0;@Nm)LrE4&`OkeFmynNO1~TYZ-F|v}~X6`UBOhfN2#qRLqP%qds`k z7eZ^)TGHJG!&YKJ*oXdq0`mkc^gL&-rbwFQ>5C%NyW$F>3ld$-vV<((;GMrqo}Ba% z%aZ-Kuq)Iq{KozKg`R6}=j;5IM{WogirWYMGNu9)8nZ0_o1o(kFODhcz>Q50*O}bH zT$j5o8)-J53JXy6efI7CKWDjJ9vcpe*M*0EbjF>vKIur1D!x4^wjm-ld(LD&x_Y^Q z6S*i+>E0OdYqLsp_WJAaw#>2_Q|}wMyX+EK8sB}YU3fXZi~VHwMCZ1j+QZKM=IWNS zDeTMVinQ!%qj1SVp*AGsizqL4sIa%>w7(+QrWGj&D?C(=RQrEy5NTQdtIYr zxYHvb_N2>V*U>58oQ=CwzR^1p^UU9|GNat$1re)v%NAWti5uD4*LL>Gj+fj+Z-QM) zH@7W|OTk#{6?>XGB7+l(xE_8AF)xA)Eb;R46V9+aQeK=`AX-=7{`j6(0-KFR{0F7p B6Nvx- literal 0 HcmV?d00001 diff --git a/www/extras/toolbar/italianoclassic/drag.gif b/www/extras/toolbar/italianoclassic/drag.gif new file mode 100644 index 0000000000000000000000000000000000000000..15a41ae58b48799bf0f41ad27dbd3ffd2d7cfe6c GIT binary patch literal 907 zcmZ?wbhEHblwsg!_|5*avtQ;~P8x|aF zW@6BYIk92k;WkDgCW#Fbl8$zB>H3986fQc}FK@`V;fA5gv0h34GMmmzi#^)3gVRiI z1}QhpFw5+lva|51-#q*5xG#}`&pjt`7H=}CGJYAjOgEWHx2j~}mG%gEH=YAqS6^SB KaFC6K!5RQmG$@Av literal 0 HcmV?d00001 diff --git a/www/extras/toolbar/spanish/drag.gif b/www/extras/toolbar/spanish/drag.gif new file mode 100644 index 0000000000000000000000000000000000000000..9bdb2bb77b6a9efbcd22785352041df1c55578e8 GIT binary patch literal 1241 zcmWmDiBFSv9DwncLk2oa5$6HZDO1NX9Lk|pWK%~r9eB>UjF^dofWa7v2a@5W1q8HG ztCQHNC{PrXtAs-V6)K|&Ewq%D7Nn&Irz3=;Z{NOe-}m>Od;W&c^TXcnIonQrig{zi zN(}mVv^o>-y~gyWBjvgIZk|n^HrJKre47aM>!B_HjknO&I?CEWnW|``7#WHQ?QKH) z7p39j$}40~I<81}bS9(PRr@Brp>i=$vmlLzXF<>uf~*o`EJcHwA9hodUzR$cU^F31;jfsSgV1Y**CEe z$Z2Q@WQ?V_GK(~pp^;k3SO$jsQ02|2xzMtO8fyi45|YJ&rGgr1M))W+g@QE3X^}WB zwWOgOB>v9vHgc$#7%YP4n`oVY>KD)xQskII#uAv-gJcD&TWeQeL(?i|w2|t~M6VAx zlw3xe3x+~_Zys%_u_<%$?n^NKd|r`(_weTA>2{3}DUxmSi{x-6q0Ym5xTyOyD3YOt zgCu@-%}t~i%*!uP)+WaI2!_S7%PZ@homZl)Zc;kuW8d$hx|MZs&Gz^!}GkV%sN*f>1!;ctCrM*u`>x8&6lk84|87=zfXGWFgl*KV)FKCMdM(RjI z8Q@klR7mTEjH#S46fuJ$=G{G_H-}d9oTds!l}e4hL|utUp5#z*>5f=RcMGT)nCZ9c zM0VZZXsR2gyD808M7$@oH=W~BB#lAReWc=?tt%CmUqlnFj-E@jr5c%^GL{--cz_HK z!SDcA=cB46Q0;@Nm)LrE4&`OkeFmynNO1~TYZ-F|v}~X6`UBOhfN2#qRLqP%qds`k z7eZ^)TGHJG!&YKJ*oXdq0`mkc^gL&-rbwFQ>5C%NyW$F>3ld$-vV<((;GMrqo}Ba% z%aZ-Kuq)Iq{KozKg`R6}=j;5IM{WogirWYMGNu9)8nZ0_o1o(kFODhcz>Q50*O}bH zT$j5o8)-J53JXy6efI7CKWDjJ9vcpe*M*0EbjF>vKIur1D!x4^wjm-ld(LD&x_Y^Q z6S*i+>E0OdYqLsp_WJAaw#>2_Q|}wMyX+EK8sB}YU3fXZi~VHwMCZ1j+QZKM=IWNS zDeTMVinQ!%qj1SVp*AGsizqL4sIa%>w7(+QrWGj&D?C(=RQrEy5NTQdtIYr zxYHvb_N2>V*U>58oQ=CwzR^1p^UU9|GNat$1re)v%NAWti5uD4*LL>Gj+fj+Z-QM) zH@7W|OTk#{6?>XGB7+l(xE_8AF)xA)Eb;R46V9+aQeK=`AX-=7{`j6(0-KFR{0F7p B6Nvx- literal 0 HcmV?d00001