").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var dd=a.document.documentElement;function ed(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(typeof e.getBoundingClientRect!==L&&(d=e.getBoundingClientRect()),c=ed(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||dd;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||dd})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return W(this,function(a,d,e){var f=ed(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Mb(l.pixelPosition,function(a,c){return c?(c=Kb(a,b),Ib.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return W(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var fd=a.jQuery,gd=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=gd),b&&a.jQuery===n&&(a.jQuery=fd),n},typeof b===L&&(a.jQuery=a.$=n),n});
diff --git a/applications/welcome3/static/js/modernizr.custom.js b/applications/welcome3/static/js/modernizr.custom.js
new file mode 100644
index 00000000..2a6e0e42
--- /dev/null
+++ b/applications/welcome3/static/js/modernizr.custom.js
@@ -0,0 +1,4 @@
+/* Modernizr 2.7.1 (Custom Build) | MIT & BSD
+ * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-flexboxlegacy-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-cssclasses-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load
+ */
+;window.Modernizr=function(a,b,c){function C(a){j.cssText=a}function D(a,b){return C(n.join(a+";")+(b||""))}function E(a,b){return typeof a===b}function F(a,b){return!!~(""+a).indexOf(b)}function G(a,b){for(var d in a){var e=a[d];if(!F(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function H(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:E(f,"function")?f.bind(d||b):f}return!1}function I(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return E(b,"string")||E(b,"undefined")?G(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),H(e,b,c))}function J(){e.input=function(c){for(var d=0,e=c.length;d
',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=E(e[d],"function"),E(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),A={}.hasOwnProperty,B;!E(A,"undefined")&&!E(A.call,"undefined")?B=function(a,b){return A.call(a,b)}:B=function(a,b){return b in a&&E(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return I("flexWrap")},s.flexboxlegacy=function(){return I("boxDirection")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!E(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!I("indexedDB",a)},s.hashchange=function(){return z("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return C("background-color:rgba(150,255,150,.5)"),F(j.backgroundColor,"rgba")},s.hsla=function(){return C("background-color:hsla(120,40%,100%,.5)"),F(j.backgroundColor,"rgba")||F(j.backgroundColor,"hsla")},s.multiplebgs=function(){return C("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return I("backgroundSize")},s.borderimage=function(){return I("borderImage")},s.borderradius=function(){return I("borderRadius")},s.boxshadow=function(){return I("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return D("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return I("animationName")},s.csscolumns=function(){return I("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return C((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),F(j.backgroundImage,"gradient")},s.cssreflections=function(){return I("boxReflect")},s.csstransforms=function(){return!!I("transform")},s.csstransforms3d=function(){var a=!!I("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return I("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML=" ",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var K in s)B(s,K)&&(x=K.toLowerCase(),e[x]=s[K](),v.push((e[x]?"":"no-")+x));return e.input||J(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)B(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},C(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.hasEvent=z,e.testProp=function(a){return G([a])},e.testAllProps=I,e.testStyles=y,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f #mq-test-1 { width: 42px; }',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){v(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},g=function(a){return a.replace(c.regex.minmaxwh,"").match(c.regex.other)};if(c.ajax=f,c.queue=d,c.unsupportedmq=g,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var h,i,j,k=a.document,l=k.documentElement,m=[],n=[],o=[],p={},q=30,r=k.getElementsByTagName("head")[0]||l,s=k.getElementsByTagName("base")[0],t=r.getElementsByTagName("link"),u=function(){var a,b=k.createElement("div"),c=k.body,d=l.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=k.createElement("body"),c.style.background="none"),l.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&l.insertBefore(c,l.firstChild),a=b.offsetWidth,f?l.removeChild(c):c.removeChild(b),l.style.fontSize=d,e&&(c.style.fontSize=e),a=j=parseFloat(a)},v=function(b){var c="clientWidth",d=l[c],e="CSS1Compat"===k.compatMode&&d||k.body[c]||d,f={},g=t[t.length-1],p=(new Date).getTime();if(b&&h&&q>p-h)return a.clearTimeout(i),i=a.setTimeout(v,q),void 0;h=p;for(var s in m)if(m.hasOwnProperty(s)){var w=m[s],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?j||u():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?j||u():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(n[w.rules]))}for(var C in o)o.hasOwnProperty(C)&&o[C]&&o[C].parentNode===r&&r.removeChild(o[C]);o.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=k.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,r.insertBefore(E,g.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(k.createTextNode(F)),o.push(E)}},w=function(a,b,d){var e=a.replace(c.regex.comments,"").replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},i=!f&&d;b.length&&(b+="/"),i&&(f=1);for(var j=0;f>j;j++){var k,l,o,p;i?(k=d,n.push(h(a))):(k=e[j].match(c.regex.findStyles)&&RegExp.$1,n.push(RegExp.$2&&h(RegExp.$2))),o=k.split(","),p=o.length;for(var q=0;p>q;q++)l=o[q],g(l)||m.push({media:l.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:n.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}v()},x=function(){if(d.length){var b=d.shift();f(b.href,function(c){w(c,b.href,b.media),p[b.href]=!0,a.setTimeout(function(){x()},0)})}},y=function(){for(var b=0;b
+ (MIT license)
+
+ Example:
+
+
+
+**/
+
+jQuery(function(){
+ var script_source = jQuery('script[src*="share.js"]').attr('src');
+ var params = function(name,default_value) {
+ var match = RegExp('[?&]' + name + '=([^&]*)').exec(script_source);
+ return match && decodeURIComponent(match[1].replace(/\+/g, ' '))||default_value;
+ }
+ var path = params('static','social');
+ var url = encodeURIComponent(window.location.href);
+ var host = window.location.hostname;
+ var title = escape(jQuery('title').text());
+ var twit = 'http://twitter.com/home?status='+title+'%20'+url;
+ var facebook = 'http://www.facebook.com/sharer.php?u='+url;
+ var gplus = 'https://plus.google.com/share?url='+url;
+ var tbar = '';
+ // Add the share tool bar.
+ jQuery('body').append(tbar);
+ var st = jQuery('#socialdrawer');
+ st.css({'opacity':'.7','z-index':'3000','background':'#FFF','border':'solid 1px #666','border-width':' 1px 0 0 1px','height':'20px','width':'40px','position':'fixed','bottom':'0','right':'0','padding':'2px 5px','overflow':'hidden','-webkit-border-top-left-radius':' 12px','-moz-border-radius-topleft':' 12px','border-top-left-radius':' 12px','-moz-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','-webkit-box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)','box-shadow':' -3px -3px 3px rgba(0,0,0,0.5)'});
+ jQuery('#socialdrawer a').css({'float':'left','width':'32px','margin':'3px 2px 2px 2px','padding':'0','cursor':'pointer'});
+ jQuery('#socialdrawer span').css({'float':'left','margin':'2px 3px','text-shadow':' 1px 1px 1px #FFF','color':'#444','font-size':'12px','line-height':'1em'});
+ jQuery('#socialdrawer img').hide();
+ // hover
+ st.click(function(){
+ jQuery(this).animate({height:'40px', width:'160px', opacity: 0.95}, 300);
+ jQuery('#socialdrawer img').show();
+ });
+ //leave
+ st.mouseleave(function(){
+ st.animate({height:'20px', width: '40px', opacity: .7}, 300);
+ jQuery('#socialdrawer img').hide();
+ return false;
+ } );
+ });
diff --git a/applications/welcome3/static/js/web2py-bootstrap3.js b/applications/welcome3/static/js/web2py-bootstrap3.js
new file mode 100644
index 00000000..ccf1b210
--- /dev/null
+++ b/applications/welcome3/static/js/web2py-bootstrap3.js
@@ -0,0 +1,253 @@
+/*!
+ * part of the package to convert web2py elements to bootstrap3 theme
+ * Developed by Paolo Caruccio ( paolo.caruccio66@gmail.com )
+ * Released under MIT license
+ * version 1 rev.201402261600
+ *
+ * Supported version of bootstrap framework: 3.0.2+
+
+ * The full package includes:
+ * - bootstrap3.py python module
+ * - web2py-bootstrap3.css
+ * - this js file
+ * - example of layout.html
+
+ */
+
+(function ($) {
+
+ // bootstrap3 classes for elements of horizontal form - data
+ var FH_CL_PREFIX = 'col-md-', // class prefix
+ FH_LABEL_COLW = '4', // nr. of columns of 12
+ FH_CONTROL_COLW = '8' // 12 - FH_LABEL_COLW;
+
+ // bootstrap3 classes for elements of horizontal form - calculations
+ var fh_label_class = FH_CL_PREFIX + FH_LABEL_COLW,
+ fh_offest_class = FH_CL_PREFIX+'offset-'+FH_LABEL_COLW,
+ fh_control_class = FH_CL_PREFIX + FH_CONTROL_COLW;
+
+ // functions
+ function menu_is_collapsed() {
+ return !$('.navbar-toggle').is(':hidden')
+ };
+
+ function closeSubmenu() {
+ $(".dropdown-submenu>a.active").each(function(){
+ var o = $(this);
+ o.parent().children("ul").toggleClass('open').data('phase', null);
+ o.toggleClass('active');
+ });
+ };
+
+ $.fn.center = function (options) {
+ var defaults = {'parent': false, 'mode': "both"};
+ var settings = $.extend(defaults, options);
+ var parent;
+ if (settings.parent) {
+ parent = this.parent();
+ } else {
+ parent = window;
+ }
+ if (settings.mode != "horizontally") {
+ this.css("top", Math.max(0, (($(parent).height() - $(this).outerHeight()) / 2) + $(parent).scrollTop()) + "px");}
+ if (settings.mode != "vertically") {
+ this.css("left", Math.max(0, (($(parent).width() - $(this).outerWidth()) / 2) + $(parent).scrollLeft()) + "px");}
+ return this;
+ };
+
+ function adjust_maxheight_of_collapsed_nav() {
+ var cn = $('div.navbar-collapse');
+ var sh = $(window).height();
+ if (cn.get(0)) {
+ if (sh<320) {
+ cn.addClass('short-screen');
+ }
+ else {
+ cn.removeClass('short-screen');
+ }
+ }
+ };
+
+ // alert centering
+ $('.flash.alert.centered').center({'mode': "horizontally"});
+
+ // navs
+ $(".nav ul.dropdown-menu").not("#w2p-auth-bar").each(function() {
+ var toggle = $(this).parent();
+ if (toggle.parent().hasClass("nav")) {
+ toggle.attr("data-w2pmenulevel", "l0");
+ toggle.children("a")
+ .addClass("dropdown-toggle")
+ .append(' ')
+ .attr("data-toggle", "dropdown");
+ } else {
+ toggle.addClass("dropdown-submenu").removeClass("dropdown");
+ };
+ });
+
+ $('.navbar-nav a.dropdown-toggle').click(function(e) {
+ if (menu_is_collapsed()) {
+ e.preventDefault();
+ }else{
+ window.location=$(this).attr('href');
+ };
+ });
+
+ $(".dropdown-submenu>a").click(function(event) {
+ if (menu_is_collapsed()) {
+ event.preventDefault();
+ event.stopPropagation();
+ var submenu = $(this).parent().children("ul");
+ submenu.data('phase','opening');
+ var dropdownOfThis = $(this).parent().parent();
+ var actives = dropdownOfThis.find('ul.dropdown-menu.open');
+ if (actives && actives.length) {
+ var hasData = actives.data('phase');
+ if (hasData && hasData=='opened') {
+ actives.removeClass('open');
+ actives.siblings('a.active').removeClass('active');
+ hasData || actives.data('phase', null);
+ };
+ };
+ submenu.toggleClass('open').data('phase','opened');
+ $(this).toggleClass('active');
+ }else{
+ window.location=$(this).attr('href');
+ };
+ });
+
+ $(".nav-tabs .web2py-menu-active").addClass('active');
+ $(".nav-tabs a").not(".dropdown-toggle").attr("data-toggle", "tab");
+
+ // form fixes
+ $(document).ready(function() {
+ $("form.bs3-form .w2p_list a").each(function() {
+ // the plus and minus buttons are generated by web2py.js
+ $(this).addClass('btn btn-default');
+ });
+ $("form.bs3-form p.w2p-autocomplete-widget").each(function() {
+ // not generated by formstyle
+ $(this).children('input').addClass('form-control');
+ });
+ $("form.bs3-form input[name='password_two']").each(function() {
+ // auth addition after form creation
+ var $this = $(this).addClass('form-control');
+ var groupClass = 'form-group'
+ var labelClass = 'control-label';
+ var commentClass = 'help-block';
+ var comment;
+ var mode;
+ var hasError = false;
+ if ($this.parent().hasClass('form-horizontal')) {
+ mode = 'horizontal';
+ labelClass = fh_label_class+' control-label';
+ };
+ if ($this.parent().hasClass('form-inline')) {
+ mode = 'inline';
+ labelClass = 'sr-only';
+ commentClass = 'sr-only';
+ var labelText = $this.prev('label').text();
+ $this.attr("placeholder", labelText.slice(0,-2));
+ };
+ var error = $this.next('div.error_wrapper');
+ if (error.length > 0) {
+ var hasError = true;
+ groupClass = 'form-group has-error'
+ var text = error[0].nextSibling.nodeValue;
+ if (text) {
+ comment = "";
+ error[0].parentNode.removeChild(error[0].nextSibling);
+ };
+ } else {
+ var text = $this[0].nextSibling.nodeValue;
+ if (text) {
+ comment = "";
+ $this[0].parentNode.removeChild($this[0].nextSibling);
+ };
+ };
+ $this.prev('label').addClass(labelClass).andSelf().wrapAll("
");
+ if (mode == 'horizontal') {
+ $this.wrap('
');
+ };
+ if (hasError) {
+ $this.parent().append(error);
+ };
+ $this.parent().append(comment);
+ });
+ $('form.bs3-form #auth_user_remember').each(function() {
+ // auth addition after form creation
+ var $input = $(this);
+ var $label = $input.next('label');
+ var $iParent = $input.parent();
+ $input.removeClass('checkbox');
+ $iParent.prev('label').remove();
+ $input.prependTo($label);
+ var newGroup = $label;
+ $iParent.replaceWith(newGroup);
+ if (newGroup.parent().hasClass('form-horizontal')) {
+ newGroup.wrap($(''));
+ } else {
+ newGroup.wrap($(''));
+ };
+ });
+ });
+
+ // form errors
+ $('form.bs3-form .error_wrapper').each(function() {
+ var $this = $(this)
+ var rcContainer = $this.parents('.rc_container');
+ if (rcContainer.length > 0) {
+ $this.appendTo(rcContainer);
+ }
+ });
+ $('form.bs3-form').find('div.error').addClass('text-danger').closest(".form-group").addClass('has-error');
+
+ // uploadwidget
+ $('#file-reset-btn').click(function() {
+ var el = $('div.w2p-uploaded-file')[0];
+ var whatReset = jQuery.data(el, "reset");
+ if (whatReset == "changed") {
+ $('.w2p-uploaded-file input[type="file"]')
+ .replaceWith(
+ $('.w2p-uploaded-file input[type="file"]')
+ .clone());
+ $('.w2p-file-preview, .w2p-uploaded-file input[type="file"], #edit-btn-dd, #file-reset-btn').toggle();
+ }else{
+ $('.w2p-file-preview, #no-file, #edit-btn-dd, #file-reset-btn').toggle();
+ $('div.w2p-uploaded-file').children('input[type=checkbox]').trigger('click');
+ }
+ jQuery.removeData(el, "reset");
+ });
+ $('#change-file-option').click(function(e) {
+ e.preventDefault();
+ $('.w2p-file-preview, .w2p-uploaded-file input[type="file"], #edit-btn-dd, #file-reset-btn').toggle();
+ jQuery.data($('div.w2p-uploaded-file')[0], "reset", "changed");
+ });
+ $('#delete-file-option').click(function(e) {
+ e.preventDefault();
+ var wimg = $('#image-thumb').outerWidth(),
+ himg = $('#image-thumb').outerHeight();
+ $('#no-file')
+ .width(wimg)
+ .height(himg)
+ .css({'line-height':himg+'px'});
+ $('.w2p-file-preview, #no-file, #edit-btn-dd, #file-reset-btn').toggle();
+ $('div.w2p-uploaded-file').children('input[type=checkbox]').trigger('click');
+ jQuery.data($('div.w2p-uploaded-file')[0], "reset", "deleted");
+ });
+
+ // on page load
+ adjust_maxheight_of_collapsed_nav();
+
+ // resize and orientation change events
+ $(window).on('orientationchange resize', function(event) {
+ adjust_maxheight_of_collapsed_nav();
+ $('.flash.alert').center({'mode':"horizontally"});
+ if (menu_is_collapsed() === false) {
+ closeSubmenu();
+ $('.navbar-nav .dropdown.open a.dropdown-toggle').dropdown('toggle');
+ $('#main-menu.in, #login-menu.in').collapse('hide');
+ };
+ });
+
+}(jQuery));
diff --git a/applications/welcome3/static/js/web2py.js b/applications/welcome3/static/js/web2py.js
new file mode 100644
index 00000000..b3cc12c0
--- /dev/null
+++ b/applications/welcome3/static/js/web2py.js
@@ -0,0 +1,721 @@
+(function ($, undefined) {
+ /*
+ * Unobtrusive scripting adapter for jQuery, largely taken from
+ * the wonderful https://github.com/rails/jquery-ujs
+ *
+ *
+ * Released under the MIT license
+ *
+ */
+ if($.web2py !== undefined) {
+ $.error('web2py.js has already been loaded!');
+ }
+
+
+ String.prototype.reverse = function () {
+ return this.split('').reverse().join('');
+ };
+ var web2py;
+
+ $.web2py = web2py = {
+
+ popup: function (url) {
+ /* popup a window */
+ newwindow = window.open(url, 'name', 'height=400,width=600');
+ if(window.focus) newwindow.focus();
+ return false;
+ },
+ collapse: function (id) {
+ /* toggle an element */
+ $('#' + id).slideToggle();
+ },
+ fade: function (id, value) {
+ /*fade something*/
+ if(value > 0) $('#' + id).hide().fadeIn('slow');
+ else $('#' + id).show().fadeOut('slow');
+ },
+ ajax: function (u, s, t) {
+ /*simple ajax function*/
+ query = '';
+ if(typeof s == "string") {
+ d = $(s).serialize();
+ if(d) {
+ query = d;
+ }
+ } else {
+ pcs = [];
+ if(s != null && s != undefined)
+ for(i = 0; i < s.length; i++) {
+ q = $("[name=" + s[i] + "]").serialize();
+ if(q) {
+ pcs.push(q);
+ }
+ }
+ if(pcs.length > 0) {
+ query = pcs.join("&");
+ }
+ }
+ $.ajax({
+ type: "POST",
+ url: u,
+ data: query,
+ success: function (msg) {
+ if(t) {
+ if(t == ':eval') eval(msg);
+ else if(typeof t == 'string') $("#" + t).html(msg);
+ else t(msg);
+ }
+ }
+ });
+ },
+ ajax_fields: function (target) {
+ /*
+ *this attaches something to a newly loaded fragment/page
+ * Ideally all events should be bound to the document, so we can avoid calling
+ * this over and over... all will be bound to the document
+ */
+ /*adds btn class to buttons*/
+ $('button', target).addClass('btn').addClass('btn-default');
+ $('form input[type="submit"], form input[type="button"]', target).addClass('btn').addClass('btn-default');
+ /* javascript for PasswordWidget*/
+ $('input[type=password][data-w2p_entropy]', target).each(function () {
+ web2py.validate_entropy($(this));
+ });
+ /* javascript for ListWidget*/
+ $('ul.w2p_list', target).each(function () {
+ function pe(ul, e) {
+ var new_line = ml(ul);
+ rel(ul);
+ if($(e.target).parent().is(':visible')) {
+ /* make sure we didn't delete the element before we insert after */
+ new_line.insertAfter($(e.target).parent());
+ } else {
+ /* the line we clicked on was deleted, just add to end of list */
+ new_line.appendTo(ul);
+ }
+ new_line.find(":text").focus();
+ return false;
+ }
+
+ function rl(ul, e) {
+ if($(ul).children().length > 1) {
+ /* only remove if we have more than 1 item so the list is never empty */
+ $(e.target).parent().remove();
+ }
+ }
+
+ function ml(ul) {
+ /* clone the first field */
+ var line = $(ul).find("li:first").clone(true);
+ line.find(':text').val('');
+ return line;
+ }
+
+ function rel(ul) {
+ /* keep only as many as needed*/
+ $(ul).find("li").each(function () {
+ var trimmed = $.trim($(this.firstChild).val());
+ if(trimmed == '') $(this).remove();
+ else $(this.firstChild).val(trimmed);
+ });
+ }
+ var ul = this;
+ $(ul).find(":text").after('+ - ').keypress(function (e) {
+ return(e.which == 13) ? pe(ul, e) : true;
+ }).next().click(function (e) {
+ pe(ul, e);
+ e.preventDefault();
+ }).next().click(function (e) {
+ rl(ul, e);
+ e.preventDefault();
+ });
+ });
+ },
+ ajax_init: function (target) {
+ /*called whenever a fragment gets loaded */
+ $('.hidden', target).hide();
+ web2py.manage_errors(target);
+ web2py.ajax_fields(target);
+ web2py.show_if_handler(target);
+ web2py.component_handler(target);
+ },
+ /* manage errors in forms */
+ manage_errors: function (target) {
+ $('.error', target).hide().slideDown('slow');
+ },
+ after_ajax: function (xhr) {
+ /* called whenever an ajax request completes */
+ var command = xhr.getResponseHeader('web2py-component-command');
+ var flash = xhr.getResponseHeader('web2py-component-flash');
+ if(command !== null) {
+ eval(decodeURIComponent(command));
+ }
+ if(flash) {
+ web2py.flash(decodeURIComponent(flash))
+ }
+ },
+ event_handlers: function () {
+ /*
+ * This is called once for page
+ * Ideally it should bound all the things that are needed
+ * and require no dom manipulations
+ */
+ var doc = $(document);
+ doc.on('click', '.flash', function (e) {
+ var t = $(this);
+ if(t.css('top') == '0px') t.slideUp('slow');
+ else t.fadeOut();
+ });
+ doc.on('keyup', 'input.integer', function () {
+ var nvalue = this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g, '').reverse();
+ if(this.value!=nvalue) this.value = nvalue;
+ });
+ doc.on('keyup', 'input.double, input.decimal', function () {
+ var nvalue = this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g, '').reverse();
+ if(this.value!=nvalue) this.value = nvalue;
+ });
+ var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
+ doc.on('click', "input[type='checkbox'].delete", function () {
+ if(this.checked)
+ if(!web2py.confirm(confirm_message)) this.checked = false;
+ });
+ var datetime_format = (typeof w2p_ajax_datetime_format != 'undefined') ? w2p_ajax_datetime_format : "%Y-%m-%d %H:%M:%S";
+ doc.on('click', "input.datetime", function () {
+ var tformat = $(this).data('w2p_datetime_format');
+ var active = $(this).data('w2p_datetime');
+ var format = (typeof tformat != 'undefined') ? tformat : datetime_format;
+ if(active === undefined) {
+ Calendar.setup({
+ inputField: this,
+ ifFormat: format,
+ showsTime: true,
+ timeFormat: "24"
+ });
+ $(this).attr('autocomplete', 'off');
+ $(this).data('w2p_datetime', 1);
+ $(this).trigger('click');
+ }
+ });
+ var date_format = (typeof w2p_ajax_date_format != 'undefined') ? w2p_ajax_date_format : "%Y-%m-%d";
+ doc.on('click', "input.date", function () {
+ var tformat = $(this).data('w2p_date_format');
+ var active = $(this).data('w2p_date');
+ var format = (typeof tformat != 'undefined') ? tformat : date_format;
+ if(active === undefined) {
+ Calendar.setup({
+ inputField: this,
+ ifFormat: format,
+ showsTime: false
+ });
+ $(this).data('w2p_date', 1);
+ $(this).attr('autocomplete', 'off');
+ $(this).trigger('click');
+ }
+ });
+ doc.on('focus', "input.time", function () {
+ var active = $(this).data('w2p_time');
+ if(active === undefined) {
+ $(this).timeEntry({
+ spinnerImage: ''
+ }).attr('autocomplete', 'off');
+ $(this).data('w2p_time', 1);
+ }
+ });
+ /* help preventing double form submission for normal form (not LOADed) */
+ $(doc).on('submit', 'form', function () {
+ var submit_button = $(this).find(web2py.formInputClickSelector);
+ web2py.disableElement(submit_button);
+ });
+ doc.ajaxSuccess(function (e, xhr) {
+ var redirect = xhr.getResponseHeader('web2py-redirect-location');
+ if(redirect !== null) {
+ window.location = redirect;
+ };
+ /* run this here only if this Ajax request is NOT for a web2py component. */
+ if(xhr.getResponseHeader('web2py-component-content') == null) {
+ web2py.after_ajax(xhr);
+ };
+ });
+
+ doc.ajaxError(function (e, xhr, settings, exception) {
+ /*personally I don't like it.
+ *if there's an error it it flashed and can be removed
+ *as any other message
+ *doc.off('click', '.flash')
+ */
+ switch(xhr.status) {
+ case 500:
+ web2py.flash(ajax_error_500);
+ }
+ });
+
+ },
+
+ trap_form: function (action, target) {
+ /* traps any LOADed form */
+ $('#' + target + ' form').each(function (i) {
+ var form = $(this);
+ if (form.hasClass('no_trap')) {
+ return;
+ }
+
+ form.attr('data-w2p_target', target);
+ var url = form.attr('action');
+
+ if ((url === "") || (url === "#")) {
+ /* form has no action. Use component url. */
+ url = action;
+ }
+
+ form.submit(function (e) {
+ web2py.disableElement(form.find(web2py.formInputClickSelector));
+ web2py.hide_flash();
+ web2py.ajax_page('post', url, form.serialize(), target, form);
+ e.preventDefault();
+ });
+ });
+ },
+
+
+ ajax_page: function (method, action, data, target, element) {
+ /* element is a new parameter, but should be put be put in front */
+ if(element == undefined) element = $(document);
+ /* if target is not there, fill it with something that there isn't in the page*/
+ if(target == undefined || target == '') target = 'w2p_none';
+ if(web2py.fire(element, 'ajax:before', null, target )) { /*test a usecase, should stop here if returns false */
+ $.ajax({
+ 'type': method,
+ 'url': action,
+ 'data': data,
+ 'beforeSend': function (xhr, settings) {
+ xhr.setRequestHeader('web2py-component-location', document.location);
+ xhr.setRequestHeader('web2py-component-element', target);
+ return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false
+ },
+ 'success': function (data, status, xhr) {
+ /*bummer for form submissions....the element is not there after complete
+ *because it gets replaced by the new response....
+ */
+ web2py.fire(element, 'ajax:success', [data, status, xhr], target);
+ },
+ 'error': function (xhr, status, error) {
+ /*bummer for form submissions....in addition to the element being not there after
+ *complete because it gets replaced by the new response, standard form
+ *handling just returns the same status code for good and bad
+ *form submissions (i.e. that triggered a validator error)
+ */
+ web2py.fire(element, 'ajax:error', [xhr, status, error], target);
+ },
+ 'complete': function (xhr, status) {
+ web2py.fire(element, 'ajax:complete', [xhr, status], target);
+ web2py.updatePage(xhr, target); /* Parse and load the html received */
+ web2py.trap_form(action, target);
+ web2py.ajax_init('#' + target);
+ web2py.after_ajax(xhr);
+ }
+ });
+ }
+ },
+ component: function (action, target, timeout, times, el) {
+ /* element is a new parameter, but should be put in front */
+ $(function () {
+ var jelement = $("#" + target);
+ var element = jelement.get(0);
+ var statement = "jQuery('#" + target + "').get(0).reload();";
+ element.reload = function () {
+ /* Continue if times is Infinity or
+ * the times limit is not reached
+ */
+ if(element.reload_check()) {
+ web2py.ajax_page('get', action, null, target, el);
+ }
+ };
+ /* Method to check timing limit */
+ element.reload_check = function () {
+ if(jelement.hasClass('w2p_component_stop')) {
+ clearInterval(this.timing);
+ return false;
+ }
+ if(this.reload_counter == Infinity) {
+ return true;
+ } else {
+ if(!isNaN(this.reload_counter)) {
+ this.reload_counter -= 1;
+ if(this.reload_counter < 0) {
+ if(!this.run_once) {
+ clearInterval(this.timing);
+ return false;
+ }
+ } else {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+ if(!isNaN(timeout)) {
+ element.timeout = timeout;
+ element.reload_counter = times;
+ if(times > 1) {
+ /* Multiple or infinite reload
+ * Run first iteration
+ */
+ web2py.ajax_page('get', action, null, target, el);
+ element.run_once = false;
+ element.timing = setInterval(statement, timeout);
+ element.reload_counter -= 1;
+ } else if(times == 1) {
+ /* Run once with timeout */
+ element.run_once = true;
+ element.setTimeout = setTimeout;
+ element.timing = setTimeout(statement, timeout);
+ }
+ } else {
+ /* run once (no timeout specified) */
+ element.reload_counter = Infinity;
+ web2py.ajax_page('get', action, null, target, el);
+ }
+ });
+ },
+ updatePage: function (xhr, target) {
+ var t = $('#' + target);
+ var html = $.parseHTML(xhr.responseText, document, true);
+ var title_elements = $(html).filter('title').add($(html).find('title'));
+ var title = title_elements.last().text();
+ if (title) {
+ title_elements.remove(); /* Remove any title elements from the response */
+ document.title = $.trim(title); /* Set the new document title */
+ }
+ var content = xhr.getResponseHeader('web2py-component-content');
+ if(content == 'prepend') t.prepend(xhr.responseText);
+ else if(content == 'append') t.append(xhr.responseText);
+ else if(content != 'hide') t.html(html);
+ },
+ calc_entropy: function (mystring) {
+ /* calculate a simple entropy for a given string */
+ var csets = new Array(
+ 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ '0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/',
+ '0123456789abcdefghijklmnopqrstuvwxyz');
+ var score = 0,
+ other = {}, seen = {}, lastset = null,
+ mystringlist = mystring.split('');
+ for(var i = 0; i < mystringlist.length; i++) { /* classify this character */
+ var c = mystringlist[i],
+ inset = 5;
+ for(var j = 0; j < csets.length; j++)
+ if(csets[j].indexOf(c) != -1) {
+ inset = j;
+ break;
+ }
+ /*calculate effect of character on alphabet size */
+ if(!(inset in seen)) {
+ seen[inset] = 1;
+ score += csets[inset].length;
+ } else if(!(c in other)) {
+ score += 1;
+ other[c] = 1;
+ }
+ if(inset != lastset) {
+ score += 1;
+ lastset = inset;
+ }
+ }
+ var entropy = mystring.length * Math.log(score) / 0.6931471805599453;
+ return Math.round(entropy * 100) / 100
+ },
+ validate_entropy: function (myfield, req_entropy) {
+ if(myfield.data('w2p_entropy') != undefined) req_entropy = myfield.data('w2p_entropy');
+ var validator = function () {
+ var v = (web2py.calc_entropy(myfield.val()) || 0) / req_entropy;
+ var r = 0,
+ g = 0,
+ b = 0,
+ rs = function (x) {
+ return Math.round(x * 15).toString(16)
+ };
+ if(v <= 0.5) {
+ r = 1.0;
+ g = 2.0 * v;
+ } else {
+ r = (1.0 - 2.0 * (Math.max(v, 0) - 0.5));
+ g = 1.0;
+ }
+ var color = '#' + rs(r) + rs(g) + rs(b);
+ myfield.css('background-color', color);
+ entropy_callback = myfield.data('entropy_callback');
+ if(entropy_callback) entropy_callback(v);
+ }
+ if(!myfield.hasClass('entropy_check')) myfield.on('keyup', validator).on('keydown', validator).addClass('entropy_check');
+ },
+ web2py_websocket: function (url, onmessage, onopen, onclose) {
+ if("WebSocket" in window) {
+ var ws = new WebSocket(url);
+ ws.onopen = onopen ? onopen : (function () {});
+ ws.onmessage = onmessage;
+ ws.onclose = onclose ? onclose : (function () {});
+ return true; /* supported */
+ } else return false; /* not supported */
+ },
+ /* new from here */
+ /* Form input elements bound by web2py.js */
+ formInputClickSelector: 'input[type=submit]:not([name]), input[type=image]:not([name]), button[type=submit]:not([name]), button:not([type]):not([name])',
+ /* Form input elements disabled during form submission */
+ disableSelector: 'input, button, textarea, select',
+ /* Form input elements re-enabled after form submission */
+ enableSelector: 'input:disabled, button:disabled, textarea:disabled, select:disabled',
+ /* Triggers an event on an element and returns false if the event result is false */
+ fire: function (obj, type, data, target) {
+ var event = $.Event(type, {'containerTarget': $('#' + target)[0]});
+ obj.trigger(event, data);
+ return event.result !== false;
+ },
+ /* Helper function, needed to provide consistent behavior in IE */
+ stopEverything: function (e) {
+ $(e.target).trigger('w2p:everythingStopped');
+ e.stopImmediatePropagation();
+ return false;
+ },
+ confirm: function (message) {
+ return confirm(message);
+ },
+ /* replace element's html with the 'data-disable-with' after storing original html
+ * and prevent clicking on it */
+ disableElement: function (el) {
+ el.addClass('disabled');
+ var method = el.prop('type') == 'submit' ? 'val' : 'html';
+ var disable_with_message = (typeof w2p_ajax_disable_with_message != 'undefined') ? w2p_ajax_disable_with_message : "Working...";
+ /*store enabled state if not already disabled */
+ if (el.data('w2p:enable-with') === undefined) {
+ el.data('w2p:enable-with', el[method]());
+ }
+ /*if you don't want to see "working..." on buttons, replace the following
+ * two lines with this one
+ * el.data('w2p_disable_with', el[method]());
+ */
+ if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) {
+ el.data('w2p_disable_with', disable_with_message);
+ }
+
+ /* set to disabled state*/
+ el[method](el.data('w2p_disable_with'));
+
+ el.bind('click.w2pDisable', function (e) { /* prevent further clicking*/
+ return web2py.stopEverything(e);
+ });
+ },
+
+ /* restore element to its original state which was disabled by 'disableElement' above*/
+ enableElement: function (el) {
+ var method = el.prop('type') == 'submit' ? 'val' : 'html';
+ if(el.data('w2p:enable-with') !== undefined) {
+ /* set to old enabled state */
+ el[method](el.data('w2p:enable-with'));
+ el.removeData('w2p:enable-with');
+ }
+ el.removeClass('disabled');
+ el.unbind('click.w2pDisable');
+ },
+ /*convenience wrapper, internal use only */
+ simple_component: function (action, target, element) {
+ web2py.component(action, target, 0, 1, element);
+ },
+ /*helper for flash messages*/
+ flash: function (message, status) {
+ var flash = $('.flash');
+ web2py.hide_flash();
+ flash.html(message).addClass(status);
+ if(flash.html()) flash.append(' × ').slideDown();
+ },
+ hide_flash: function () {
+ $('.flash').fadeOut(0).html('');
+ },
+ show_if_handler: function (target) {
+ var triggers = {};
+ var show_if = function () {
+ var t = $(this);
+ var id = t.attr('id');
+ t.attr('value', t.val());
+ for(var k = 0; k < triggers[id].length; k++) {
+ var dep = $('#' + triggers[id][k], target);
+ var tr = $('#' + triggers[id][k] + '__row', target);
+ if(t.is(dep.attr('data-show-if'))) tr.slideDown();
+ else tr.hide();
+ }
+ };
+ $('[data-show-trigger]', target).each(function () {
+ var name = $(this).attr('data-show-trigger');
+ if(!triggers[name]) triggers[name] = [];
+ triggers[name].push($(this).attr('id'));
+ });
+ for(var name in triggers) {
+ $('#' + name, target).change(show_if).keyup(show_if);
+ show_if.call($('#' + name, target));
+ };
+ },
+ component_handler: function (target) {
+ $('div[data-w2p_remote]', target).each(function () {
+ var remote, times, timeout, target;
+ var el = $(this);
+ remote = el.data('w2p_remote');
+ times = el.data('w2p_times');
+ timeout = el.data('w2p_timeout');
+ target = el.attr('id');
+ web2py.component(remote, target, timeout, times, $(this));
+ })
+ },
+ a_handler: function (el, e) {
+ e.preventDefault();
+ var method = el.data('w2p_method');
+ var action = el.attr('href');
+ var target = el.data('w2p_target');
+ var confirm_message = el.data('w2p_confirm');
+
+ var pre_call = el.data('w2p_pre_call');
+ if(pre_call != undefined) {
+ eval(pre_call);
+ }
+ if(confirm_message != undefined) {
+ if(confirm_message == 'default') confirm_message = w2p_ajax_confirm_message || 'Are you sure you want to delete this object?';
+ if(!web2py.confirm(confirm_message)) {
+ web2py.stopEverything(e);
+ return;
+ }
+ }
+ if(target == undefined) {
+ if(method == 'GET') {
+ web2py.ajax_page('get', action, [], '', el);
+ } else if(method == 'POST') {
+ web2py.ajax_page('post', action, [], '', el);
+ }
+ } else {
+ if(method == 'GET') {
+ web2py.ajax_page('get', action, [], target, el);
+ } else if(method == 'POST') {
+ web2py.ajax_page('post', action, [], target, el);
+ }
+ }
+ },
+ a_handlers: function () {
+ var el = $(document);
+ el.on('click', 'a[data-w2p_method]', function (e) {
+ web2py.a_handler($(this), e);
+ });
+ /* removal of element should happen only on success */
+ el.on('ajax:success', 'a[data-w2p_method][data-w2p_remove]', function (e) {
+ var el = $(this);
+ var toremove = el.data('w2p_remove');
+ if(toremove != undefined) {
+ toremove = el.closest(toremove);
+ if(!toremove.length) {
+ /*this enables removal of whatever selector if a closest is not found */
+ toremove = $(toremove);
+ }
+ toremove.remove();
+ }
+ });
+ el.on('ajax:beforeSend', 'a[data-w2p_method][data-w2p_disable_with]', function (e) {
+ web2py.disableElement($(this));
+ });
+ /*re-enable click on completion*/
+ el.on('ajax:complete', 'a[data-w2p_method][data-w2p_disable_with]', function (e) {
+ web2py.enableElement($(this));
+ });
+ },
+ /* Disables form elements:
+ - Caches element value in 'ujs:enable-with' data store
+ - Replaces element text with value of 'data-disable-with' attribute
+ - Sets disabled property to true
+ */
+ disableFormElements: function (form) {
+ form.find(web2py.disableSelector).each(function () {
+ var element = $(this),
+ method = element.is('button') ? 'html' : 'val';
+ var disable_with = element.data('w2p_disable_with');
+ if(disable_with == undefined) {
+ element.data('w2p_disable_with', element[method]())
+ }
+ if (element.data('w2p:enable-with') === undefined) {
+ element.data('w2p:enable-with', element[method]());
+ }
+ element[method](element.data('w2p_disable_with'));
+ element.prop('disabled', true);
+ });
+ },
+
+ /* Re-enables disabled form elements:
+ - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
+ - Sets disabled property to false
+ */
+ enableFormElements: function (form) {
+ form.find(web2py.enableSelector).each(function () {
+ var element = $(this),
+ method = element.is('button') ? 'html' : 'val';
+ if(element.data('w2p:enable-with')) {
+ element[method](element.data('w2p:enable-with'));
+ element.removeData('w2p:enable-with');
+ }
+ element.prop('disabled', false);
+ });
+ },
+ form_handlers: function () {
+ var el = $(document);
+ el.on('ajax:beforeSend', 'form[data-w2p_target]', function (e) {
+ web2py.disableFormElements($(this));
+ });
+ el.on('ajax:complete', 'form[data-w2p_target]', function (e) {
+ web2py.enableFormElements($(this));
+ });
+ },
+ /* Invalidate and force reload of a web2py component
+ */
+ invalidate: function(target) {
+ $('div[data-w2p_remote]', target).each(function () {
+ var el = $('#' + $(this).attr('id')).get(0);
+ if (el.timing !== undefined) { // Block triggering regular routines
+ clearInterval(el.timing);
+ }
+ });
+ $.web2py.component_handler(target);
+ },
+ }
+
+ /*end of functions */
+ /*main hook*/
+ $(function () {
+ var flash = $('.flash');
+ flash.hide();
+ if(flash.html()) web2py.flash(flash.html());
+ web2py.ajax_init(document);
+ web2py.event_handlers();
+ web2py.a_handlers();
+ web2py.form_handlers();
+ });
+
+})(jQuery);
+
+/* compatibility code - start */
+ajax = jQuery.web2py.ajax;
+web2py_component = jQuery.web2py.component;
+web2py_websocket = jQuery.web2py.web2py_websocket;
+web2py_ajax_page = jQuery.web2py.ajax_page;
+/*needed for IS_STRONG(entropy)*/
+web2py_validate_entropy = jQuery.web2py.validate_entropy;
+/*needed for crud.search and SQLFORM.grid's search*/
+web2py_ajax_fields = jQuery.web2py.ajax_fields;
+/*used for LOAD(ajax=False)*/
+web2py_trap_form = jQuery.web2py.trap_form;
+
+/*undocumented - rare*/
+popup = jQuery.web2py.popup;
+collapse = jQuery.web2py.collapse;
+fade = jQuery.web2py.fade;
+
+/* internals - shouldn't be needed
+web2py_ajax_init = jQuery.web2py.ajax_init;
+web2py_event_handlers = jQuery.web2py.event_handlers;
+web2py_trap_link = jQuery.web2py.trap_link;
+web2py_calc_entropy = jQuery.web2py.calc_entropy;
+*/
+/* compatibility code - end*/
+
diff --git a/applications/welcome3/views/__init__.py b/applications/welcome3/views/__init__.py
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/applications/welcome3/views/__init__.py
@@ -0,0 +1 @@
+
diff --git a/applications/welcome3/views/appadmin.html b/applications/welcome3/views/appadmin.html
new file mode 100644
index 00000000..054efd49
--- /dev/null
+++ b/applications/welcome3/views/appadmin.html
@@ -0,0 +1,268 @@
+{{extend 'layout.html'}}
+
+
+{{if request.function=='index':}}
+{{=T("Available Databases and Tables")}}
+ {{if not databases:}}{{=T("No databases in this application")}}{{pass}}
+
+ {{for db in sorted(databases):}}
+ {{for table in databases[db].tables:}}
+ {{qry='%s.%s.id>0'%(db,table)}}
+ {{tbl=databases[db][table]}}
+ {{if hasattr(tbl,'_primarykey'):}}
+ {{if tbl._primarykey:}}
+ {{firstkey=tbl[tbl._primarykey[0]]}}
+ {{if firstkey.type in ['string','text']:}}
+ {{qry='%s.%s.%s!=""'%(db,table,firstkey.name)}}
+ {{else:}}
+ {{qry='%s.%s.%s>0'%(db,table,firstkey.name)}}
+ {{pass}}
+ {{else:}}
+ {{qry=''}}
+ {{pass}}
+ {{pass}}
+
+
+ {{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
+
+
+ {{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn")}}
+
+
+ {{pass}}
+ {{pass}}
+
+
+{{elif request.function=='select':}}
+ {{=XML(str(T("Database %s select"))%A(request.args[0],_href=URL('index'))) }}
+
+ {{if tb:}}
+ {{=T('Traceback')}}
+
+ {{=tb}}
+
+ {{pass}}
+ {{if table:}}
+ {{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn")}}
+ {{=T("Rows in Table")}}
+ {{else:}}
+ {{=T("Rows selected")}}
+ {{pass}}
+ {{=form}}
+ {{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.')}}
+ {{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}
+ {{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}
+
+ {{=T("%s selected", nrows)}}
+ {{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn")}}{{pass}}
+ {{if stop
+ {{linkto = lambda f, t, r: URL('update', args=[request.args[0], r, f]) if f else "#"}}
+ {{upload=URL('download',args=request.args[0])}}
+ {{=SQLTABLE(rows,linkto,upload,orderby=True,_class='sortable')}}
+
+ {{pass}}
+
+
+
+
+
+
{{=T("Overview")}}
+
{{=T.M("Number of entries: **%s**", total['entries'])}}
+ {{if total['entries'] > 0:}}
+
{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses})",
+ dict(ratio=total['ratio'], hits=total['hits'], misses=total['misses']))}}
+
+
+ {{=T("Size of cache:")}}
+ {{if object_stats:}}
+ {{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict(items=total['objects'], bytes=total['bytes']))}}
+ {{if total['bytes'] > 524287:}}
+ {{=T.M("(**%.0d MB**)", total['bytes'] / 1048576)}}
+ {{pass}}
+ {{else:}}
+ {{=T.M("**not available** (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
+ {{pass}}
+
+
+ {{=T.M("Cache contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
+ dict(hours=total['oldest'][0], min=total['oldest'][1], sec=total['oldest'][2]))}}
+
+ {{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle();')}}
+
+ {{=total['keys']}}
+
+
+ {{pass}}
+
+
{{=T("RAM")}}
+
{{=T.M("Number of entries: **%s**", ram['entries'])}}
+ {{if ram['entries'] > 0:}}
+
{{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
+ dict( ratio=ram['ratio'], hits=ram['hits'], misses=ram['misses']))}}
+
+
+ {{=T("Size of cache:")}}
+ {{if object_stats:}}
+ {{=T.M("**%(items)s** items, **%(bytes)s** %%{byte(bytes)}", dict(items=ram['objects'], bytes=ram['bytes']))}}
+ {{if ram['bytes'] > 524287:}}
+ {{=T.M("(**%.0d MB**)", ram['bytes'] / 10485576)}}
+ {{pass}}
+ {{else:}}
+ {{=T.M("``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
+ {{pass}}
+
+
+ {{=T.M("RAM contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
+ dict(hours=ram['oldest'][0], min=ram['oldest'][1], sec=ram['oldest'][2]))}}
+
+ {{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle();')}}
+
+ {{=ram['keys']}}
+
+
+ {{pass}}
+
+
{{=T("DISK")}}
+
{{=T.M("Number of entries: **%s**", disk['entries'])}}
+ {{if disk['entries'] > 0:}}
+
+ {{=T.M("Hit Ratio: **%(ratio)s%%** (**%(hits)s** %%{hit(hits)} and **%(misses)s** %%{miss(misses)})",
+ dict(ratio=disk['ratio'], hits=disk['hits'], misses=disk['misses']))}}
+
+
+ {{=T("Size of cache:")}}
+ {{if object_stats:}}
+ {{=T.M("**%(items)s** %%{item(items)}, **%(bytes)s** %%{byte(bytes)}", dict( items=disk['objects'], bytes=disk['bytes']))}}
+ {{if disk['bytes'] > 524287:}}
+ {{=T.M("(**%.0d MB**)", disk['bytes'] / 1048576)}}
+ {{pass}}
+ {{else:}}
+ {{=T.M("``**not available**``:red (requires the Python [[guppy http://pypi.python.org/pypi/guppy/ popup]] library)")}}
+ {{pass}}
+
+
+ {{=T.M("DISK contains items up to **%(hours)02d** %%{hour(hours)} **%(min)02d** %%{minute(min)} **%(sec)02d** %%{second(sec)} old.",
+ dict(hours=disk['oldest'][0], min=disk['oldest'][1], sec=disk['oldest'][2]))}}
+
+ {{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
+
+ {{=disk['keys']}}
+
+
+ {{pass}}
+
+
+
+
+
+
+
+ {{for k, tablename in enumerate(tablenames):}}
+
+ {{=LOAD(f='manage.load', args=[request.args(0), k], ajax=True)}}
+
+ {{pass}}
+
+{{pass}}
diff --git a/applications/welcome3/views/default/index.html b/applications/welcome3/views/default/index.html
new file mode 100644
index 00000000..85e03922
--- /dev/null
+++ b/applications/welcome3/views/default/index.html
@@ -0,0 +1,50 @@
+{{left_sidebar_enabled,right_sidebar_enabled=False,('message' in globals())}}
+{{extend 'layout.html'}}
+
+{{block head}}
+
+{{end head}}
+
+{{if 'message' in globals():}}
+