" && !rtbody.test( elem ) ?
+ tmp :
+ 0;
+
+ j = elem && elem.childNodes.length;
+ while ( j-- ) {
+ if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
+ elem.removeChild( tbody );
+ }
+ }
+ }
+
+ jQuery.merge( nodes, tmp.childNodes );
+
+ // Fix #12392 for WebKit and IE > 9
+ tmp.textContent = "";
+
+ // Fix #12392 for oldIE
+ while ( tmp.firstChild ) {
+ tmp.removeChild( tmp.firstChild );
+ }
+
+ // Remember the top-level container for proper cleanup
+ tmp = safe.lastChild;
+ }
+ }
+ }
+
+ // Fix #11356: Clear elements from fragment
+ if ( tmp ) {
+ safe.removeChild( tmp );
+ }
+
+ // Reset defaultChecked for any radios and checkboxes
+ // about to be appended to the DOM in IE 6/7 (#8060)
+ if ( !jQuery.support.appendChecked ) {
+ jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+ }
+
+ i = 0;
+ while ( (elem = nodes[ i++ ]) ) {
+
+ // #4087 - If origin and destination elements are the same, and this is
+ // that element, do not do anything
+ if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
+ continue;
+ }
+
+ contains = jQuery.contains( elem.ownerDocument, elem );
+
+ // Append to fragment
+ tmp = getAll( safe.appendChild( elem ), "script" );
+
+ // Preserve script evaluation history
+ if ( contains ) {
+ setGlobalEval( tmp );
+ }
+
+ // Capture executables
+ if ( scripts ) {
+ j = 0;
+ while ( (elem = tmp[ j++ ]) ) {
+ if ( rscriptType.test( elem.type || "" ) ) {
+ scripts.push( elem );
+ }
+ }
+ }
+ }
+
+ tmp = null;
+
+ return safe;
+ },
+
+ cleanData: function( elems, /* internal */ acceptData ) {
+ var elem, type, id, data,
+ i = 0,
+ internalKey = jQuery.expando,
+ cache = jQuery.cache,
+ deleteExpando = jQuery.support.deleteExpando,
+ special = jQuery.event.special;
+
+ for ( ; (elem = elems[i]) != null; i++ ) {
+
+ if ( acceptData || jQuery.acceptData( elem ) ) {
+
+ id = elem[ internalKey ];
+ data = id && cache[ id ];
+
+ if ( data ) {
+ if ( data.events ) {
+ for ( type in data.events ) {
+ if ( special[ type ] ) {
+ jQuery.event.remove( elem, type );
+
+ // This is a shortcut to avoid jQuery.event.remove's overhead
+ } else {
+ jQuery.removeEvent( elem, type, data.handle );
+ }
+ }
+ }
+
+ // Remove cache only if it was not already removed by jQuery.event.remove
+ if ( cache[ id ] ) {
+
+ delete cache[ id ];
+
+ // IE does not allow us to delete expando properties from nodes,
+ // nor does it have a removeAttribute function on Document nodes;
+ // we must handle all of these cases
+ if ( deleteExpando ) {
+ delete elem[ internalKey ];
+
+ } else if ( typeof elem.removeAttribute !== core_strundefined ) {
+ elem.removeAttribute( internalKey );
+
+ } else {
+ elem[ internalKey ] = null;
+ }
+
+ core_deletedIds.push( id );
+ }
+ }
+ }
+ }
+ },
+
+ _evalUrl: function( url ) {
+ return jQuery.ajax({
+ url: url,
+ type: "GET",
+ dataType: "script",
+ async: false,
+ global: false,
+ "throws": true
+ });
+ }
+});
+jQuery.fn.extend({
+ wrapAll: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append( this );
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ),
+ contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ var isFunction = jQuery.isFunction( html );
+
+ return this.each(function(i) {
+ jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ }
+});
+var iframe, getStyles, curCSS,
+ ralpha = /alpha\([^)]*\)/i,
+ ropacity = /opacity\s*=\s*([^)]*)/,
+ rposition = /^(top|right|bottom|left)$/,
+ // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+ // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+ rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+ rmargin = /^margin/,
+ rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
+ rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
+ rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
+ elemdisplay = { BODY: "block" },
+
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+ cssNormalTransform = {
+ letterSpacing: 0,
+ fontWeight: 400
+ },
+
+ cssExpand = [ "Top", "Right", "Bottom", "Left" ],
+ cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
+
+// return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( style, name ) {
+
+ // shortcut for names that are not vendor prefixed
+ if ( name in style ) {
+ return name;
+ }
+
+ // check for vendor prefixed names
+ var capName = name.charAt(0).toUpperCase() + name.slice(1),
+ origName = name,
+ i = cssPrefixes.length;
+
+ while ( i-- ) {
+ name = cssPrefixes[ i ] + capName;
+ if ( name in style ) {
+ return name;
+ }
+ }
+
+ return origName;
+}
+
+function isHidden( elem, el ) {
+ // isHidden might be called from jQuery#filter function;
+ // in that case, element will be second argument
+ elem = el || elem;
+ return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+}
+
+function showHide( elements, show ) {
+ var display, elem, hidden,
+ values = [],
+ index = 0,
+ length = elements.length;
+
+ for ( ; index < length; index++ ) {
+ elem = elements[ index ];
+ if ( !elem.style ) {
+ continue;
+ }
+
+ values[ index ] = jQuery._data( elem, "olddisplay" );
+ display = elem.style.display;
+ if ( show ) {
+ // Reset the inline display of this element to learn if it is
+ // being hidden by cascaded rules or not
+ if ( !values[ index ] && display === "none" ) {
+ elem.style.display = "";
+ }
+
+ // Set elements which have been overridden with display: none
+ // in a stylesheet to whatever the default browser style is
+ // for such an element
+ if ( elem.style.display === "" && isHidden( elem ) ) {
+ values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
+ }
+ } else {
+
+ if ( !values[ index ] ) {
+ hidden = isHidden( elem );
+
+ if ( display && display !== "none" || !hidden ) {
+ jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
+ }
+ }
+ }
+ }
+
+ // Set the display of most of the elements in a second loop
+ // to avoid the constant reflow
+ for ( index = 0; index < length; index++ ) {
+ elem = elements[ index ];
+ if ( !elem.style ) {
+ continue;
+ }
+ if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
+ elem.style.display = show ? values[ index ] || "" : "none";
+ }
+ }
+
+ return elements;
+}
+
+jQuery.fn.extend({
+ css: function( name, value ) {
+ return jQuery.access( this, function( elem, name, value ) {
+ var len, styles,
+ map = {},
+ i = 0;
+
+ if ( jQuery.isArray( name ) ) {
+ styles = getStyles( elem );
+ len = name.length;
+
+ for ( ; i < len; i++ ) {
+ map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+ }
+
+ return map;
+ }
+
+ return value !== undefined ?
+ jQuery.style( elem, name, value ) :
+ jQuery.css( elem, name );
+ }, name, value, arguments.length > 1 );
+ },
+ show: function() {
+ return showHide( this, true );
+ },
+ hide: function() {
+ return showHide( this );
+ },
+ toggle: function( state ) {
+ if ( typeof state === "boolean" ) {
+ return state ? this.show() : this.hide();
+ }
+
+ return this.each(function() {
+ if ( isHidden( this ) ) {
+ jQuery( this ).show();
+ } else {
+ jQuery( this ).hide();
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ // Add in style property hooks for overriding the default
+ // behavior of getting and setting a style property
+ cssHooks: {
+ opacity: {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ // We should always get a number back from opacity
+ var ret = curCSS( elem, "opacity" );
+ return ret === "" ? "1" : ret;
+ }
+ }
+ }
+ },
+
+ // Don't automatically add "px" to these possibly-unitless properties
+ cssNumber: {
+ "columnCount": true,
+ "fillOpacity": true,
+ "fontWeight": true,
+ "lineHeight": true,
+ "opacity": true,
+ "order": true,
+ "orphans": true,
+ "widows": true,
+ "zIndex": true,
+ "zoom": true
+ },
+
+ // Add in properties whose names you wish to fix before
+ // setting or getting the value
+ cssProps: {
+ // normalize float css property
+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+ },
+
+ // Get and set the style property on a DOM Node
+ style: function( elem, name, value, extra ) {
+ // Don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+ return;
+ }
+
+ // Make sure that we're working with the right name
+ var ret, type, hooks,
+ origName = jQuery.camelCase( name ),
+ style = elem.style;
+
+ name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
+
+ // gets hook for the prefixed version
+ // followed by the unprefixed version
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+ // Check if we're setting a value
+ if ( value !== undefined ) {
+ type = typeof value;
+
+ // convert relative number strings (+= or -=) to relative numbers. #7345
+ if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+ value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
+ // Fixes bug #9237
+ type = "number";
+ }
+
+ // Make sure that NaN and null values aren't set. See: #7116
+ if ( value == null || type === "number" && isNaN( value ) ) {
+ return;
+ }
+
+ // If a number was passed in, add 'px' to the (except for certain CSS properties)
+ if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+ value += "px";
+ }
+
+ // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
+ // but it would mean to define eight (for every problematic property) identical functions
+ if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
+ style[ name ] = "inherit";
+ }
+
+ // If a hook was provided, use that value, otherwise just set the specified value
+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
+
+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+ // Fixes bug #5509
+ try {
+ style[ name ] = value;
+ } catch(e) {}
+ }
+
+ } else {
+ // If a hook was provided get the non-computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+ return ret;
+ }
+
+ // Otherwise just get the value from the style object
+ return style[ name ];
+ }
+ },
+
+ css: function( elem, name, extra, styles ) {
+ var num, val, hooks,
+ origName = jQuery.camelCase( name );
+
+ // Make sure that we're working with the right name
+ name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
+
+ // gets hook for the prefixed version
+ // followed by the unprefixed version
+ hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+ // If a hook was provided get the computed value from there
+ if ( hooks && "get" in hooks ) {
+ val = hooks.get( elem, true, extra );
+ }
+
+ // Otherwise, if a way to get the computed value exists, use that
+ if ( val === undefined ) {
+ val = curCSS( elem, name, styles );
+ }
+
+ //convert "normal" to computed value
+ if ( val === "normal" && name in cssNormalTransform ) {
+ val = cssNormalTransform[ name ];
+ }
+
+ // Return, converting to number if forced or a qualifier was provided and val looks numeric
+ if ( extra === "" || extra ) {
+ num = parseFloat( val );
+ return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
+ }
+ return val;
+ }
+});
+
+// NOTE: we've included the "window" in window.getComputedStyle
+// because jsdom on node.js will break without it.
+if ( window.getComputedStyle ) {
+ getStyles = function( elem ) {
+ return window.getComputedStyle( elem, null );
+ };
+
+ curCSS = function( elem, name, _computed ) {
+ var width, minWidth, maxWidth,
+ computed = _computed || getStyles( elem ),
+
+ // getPropertyValue is only needed for .css('filter') in IE9, see #12537
+ ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
+ style = elem.style;
+
+ if ( computed ) {
+
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+ ret = jQuery.style( elem, name );
+ }
+
+ // A tribute to the "awesome hack by Dean Edwards"
+ // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
+ // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+ // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+ if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+ // Remember the original values
+ width = style.width;
+ minWidth = style.minWidth;
+ maxWidth = style.maxWidth;
+
+ // Put in the new values to get a computed value out
+ style.minWidth = style.maxWidth = style.width = ret;
+ ret = computed.width;
+
+ // Revert the changed values
+ style.width = width;
+ style.minWidth = minWidth;
+ style.maxWidth = maxWidth;
+ }
+ }
+
+ return ret;
+ };
+} else if ( document.documentElement.currentStyle ) {
+ getStyles = function( elem ) {
+ return elem.currentStyle;
+ };
+
+ curCSS = function( elem, name, _computed ) {
+ var left, rs, rsLeft,
+ computed = _computed || getStyles( elem ),
+ ret = computed ? computed[ name ] : undefined,
+ style = elem.style;
+
+ // Avoid setting ret to empty string here
+ // so we don't default to auto
+ if ( ret == null && style && style[ name ] ) {
+ ret = style[ name ];
+ }
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ // but not position css attributes, as those are proportional to the parent element instead
+ // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
+ if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
+
+ // Remember the original values
+ left = style.left;
+ rs = elem.runtimeStyle;
+ rsLeft = rs && rs.left;
+
+ // Put in the new values to get a computed value out
+ if ( rsLeft ) {
+ rs.left = elem.currentStyle.left;
+ }
+ style.left = name === "fontSize" ? "1em" : ret;
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ if ( rsLeft ) {
+ rs.left = rsLeft;
+ }
+ }
+
+ return ret === "" ? "auto" : ret;
+ };
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+ var matches = rnumsplit.exec( value );
+ return matches ?
+ // Guard against undefined "subtract", e.g., when used as in cssHooks
+ Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
+ value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+ var i = extra === ( isBorderBox ? "border" : "content" ) ?
+ // If we already have the right measurement, avoid augmentation
+ 4 :
+ // Otherwise initialize for horizontal or vertical properties
+ name === "width" ? 1 : 0,
+
+ val = 0;
+
+ for ( ; i < 4; i += 2 ) {
+ // both box models exclude margin, so add it if we want it
+ if ( extra === "margin" ) {
+ val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+ }
+
+ if ( isBorderBox ) {
+ // border-box includes padding, so remove it if we want content
+ if ( extra === "content" ) {
+ val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+ }
+
+ // at this point, extra isn't border nor margin, so remove border
+ if ( extra !== "margin" ) {
+ val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+ }
+ } else {
+ // at this point, extra isn't content, so add padding
+ val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+ // at this point, extra isn't content nor padding, so add border
+ if ( extra !== "padding" ) {
+ val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+ }
+ }
+ }
+
+ return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+ // Start with offset property, which is equivalent to the border-box value
+ var valueIsBorderBox = true,
+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+ styles = getStyles( elem ),
+ isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+ // some non-html elements return undefined for offsetWidth, so check for null/undefined
+ // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+ // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+ if ( val <= 0 || val == null ) {
+ // Fall back to computed then uncomputed css if necessary
+ val = curCSS( elem, name, styles );
+ if ( val < 0 || val == null ) {
+ val = elem.style[ name ];
+ }
+
+ // Computed unit is not pixels. Stop here and return.
+ if ( rnumnonpx.test(val) ) {
+ return val;
+ }
+
+ // we need the check for style in case a browser which returns unreliable values
+ // for getComputedStyle silently falls back to the reliable elem.style
+ valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
+
+ // Normalize "", auto, and prepare for extra
+ val = parseFloat( val ) || 0;
+ }
+
+ // use the active box-sizing model to add/subtract irrelevant styles
+ return ( val +
+ augmentWidthOrHeight(
+ elem,
+ name,
+ extra || ( isBorderBox ? "border" : "content" ),
+ valueIsBorderBox,
+ styles
+ )
+ ) + "px";
+}
+
+// Try to determine the default display value of an element
+function css_defaultDisplay( nodeName ) {
+ var doc = document,
+ display = elemdisplay[ nodeName ];
+
+ if ( !display ) {
+ display = actualDisplay( nodeName, doc );
+
+ // If the simple way fails, read from inside an iframe
+ if ( display === "none" || !display ) {
+ // Use the already-created iframe if possible
+ iframe = ( iframe ||
+ jQuery("")
+ .css( "cssText", "display:block !important" )
+ ).appendTo( doc.documentElement );
+
+ // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+ doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
+ doc.write("");
+ doc.close();
+
+ display = actualDisplay( nodeName, doc );
+ iframe.detach();
+ }
+
+ // Store the correct default display
+ elemdisplay[ nodeName ] = display;
+ }
+
+ return display;
+}
+
+// Called ONLY from within css_defaultDisplay
+function actualDisplay( name, doc ) {
+ var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
+ display = jQuery.css( elem[0], "display" );
+ elem.remove();
+ return display;
+}
+
+jQuery.each([ "height", "width" ], function( i, name ) {
+ jQuery.cssHooks[ name ] = {
+ get: function( elem, computed, extra ) {
+ if ( computed ) {
+ // certain elements can have dimension info if we invisibly show them
+ // however, it must have a current display style that would benefit from this
+ return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
+ jQuery.swap( elem, cssShow, function() {
+ return getWidthOrHeight( elem, name, extra );
+ }) :
+ getWidthOrHeight( elem, name, extra );
+ }
+ },
+
+ set: function( elem, value, extra ) {
+ var styles = extra && getStyles( elem );
+ return setPositiveNumber( elem, value, extra ?
+ augmentWidthOrHeight(
+ elem,
+ name,
+ extra,
+ jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+ styles
+ ) : 0
+ );
+ }
+ };
+});
+
+if ( !jQuery.support.opacity ) {
+ jQuery.cssHooks.opacity = {
+ get: function( elem, computed ) {
+ // IE uses filters for opacity
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+ ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
+ computed ? "1" : "";
+ },
+
+ set: function( elem, value ) {
+ var style = elem.style,
+ currentStyle = elem.currentStyle,
+ opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+ filter = currentStyle && currentStyle.filter || style.filter || "";
+
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+ // if value === "", then remove inline opacity #12685
+ if ( ( value >= 1 || value === "" ) &&
+ jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
+ style.removeAttribute ) {
+
+ // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+ // if "filter:" is present at all, clearType is disabled, we want to avoid this
+ // style.removeAttribute is IE Only, but so apparently is this code path...
+ style.removeAttribute( "filter" );
+
+ // if there is no filter style applied in a css rule or unset inline opacity, we are done
+ if ( value === "" || currentStyle && !currentStyle.filter ) {
+ return;
+ }
+ }
+
+ // otherwise, set new filter values
+ style.filter = ralpha.test( filter ) ?
+ filter.replace( ralpha, opacity ) :
+ filter + " " + opacity;
+ }
+ };
+}
+
+// These hooks cannot be added until DOM ready because the support test
+// for it is not run until after DOM ready
+jQuery(function() {
+ if ( !jQuery.support.reliableMarginRight ) {
+ jQuery.cssHooks.marginRight = {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ // Work around by temporarily setting element display to inline-block
+ return jQuery.swap( elem, { "display": "inline-block" },
+ curCSS, [ elem, "marginRight" ] );
+ }
+ }
+ };
+ }
+
+ // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+ // getComputedStyle returns percent when specified for top/left/bottom/right
+ // rather than make the css module depend on the offset module, we just check for it here
+ if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
+ jQuery.each( [ "top", "left" ], function( i, prop ) {
+ jQuery.cssHooks[ prop ] = {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ computed = curCSS( elem, prop );
+ // if curCSS returns percentage, fallback to offset
+ return rnumnonpx.test( computed ) ?
+ jQuery( elem ).position()[ prop ] + "px" :
+ computed;
+ }
+ }
+ };
+ });
+ }
+
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ // Support: Opera <= 12.12
+ // Opera reports offsetWidths and offsetHeights less than zero on some elements
+ return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
+ (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+
+// These hooks are used by animate to expand properties
+jQuery.each({
+ margin: "",
+ padding: "",
+ border: "Width"
+}, function( prefix, suffix ) {
+ jQuery.cssHooks[ prefix + suffix ] = {
+ expand: function( value ) {
+ var i = 0,
+ expanded = {},
+
+ // assumes a single number if not a string
+ parts = typeof value === "string" ? value.split(" ") : [ value ];
+
+ for ( ; i < 4; i++ ) {
+ expanded[ prefix + cssExpand[ i ] + suffix ] =
+ parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+ }
+
+ return expanded;
+ }
+ };
+
+ if ( !rmargin.test( prefix ) ) {
+ jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+ }
+});
+var r20 = /%20/g,
+ rbracket = /\[\]$/,
+ rCRLF = /\r?\n/g,
+ rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+ rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+jQuery.fn.extend({
+ serialize: function() {
+ return jQuery.param( this.serializeArray() );
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ // Can add propHook for "elements" to filter or add form elements
+ var elements = jQuery.prop( this, "elements" );
+ return elements ? jQuery.makeArray( elements ) : this;
+ })
+ .filter(function(){
+ var type = this.type;
+ // Use .is(":disabled") so that fieldset[disabled] works
+ return this.name && !jQuery( this ).is( ":disabled" ) &&
+ rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+ ( this.checked || !manipulation_rcheckableType.test( type ) );
+ })
+ .map(function( i, elem ){
+ var val = jQuery( this ).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray( val ) ?
+ jQuery.map( val, function( val ){
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }) :
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }).get();
+ }
+});
+
+//Serialize an array of form elements or a set of
+//key/values into a query string
+jQuery.param = function( a, traditional ) {
+ var prefix,
+ s = [],
+ add = function( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+ };
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( prefix in a ) {
+ buildParams( prefix, a[ prefix ], traditional, add );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join( "&" ).replace( r20, "+" );
+};
+
+function buildParams( prefix, obj, traditional, add ) {
+ var name;
+
+ if ( jQuery.isArray( obj ) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || rbracket.test( prefix ) ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+
+ } else {
+ // Item is non-scalar (array or object), encode its numeric index.
+ buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
+ }
+ });
+
+ } else if ( !traditional && jQuery.type( obj ) === "object" ) {
+ // Serialize object item.
+ for ( name in obj ) {
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+ }
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+}
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( data, fn ) {
+ return arguments.length > 0 ?
+ this.on( name, null, data, fn ) :
+ this.trigger( name );
+ };
+});
+
+jQuery.fn.extend({
+ hover: function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ },
+
+ bind: function( types, data, fn ) {
+ return this.on( types, null, data, fn );
+ },
+ unbind: function( types, fn ) {
+ return this.off( types, null, fn );
+ },
+
+ delegate: function( selector, types, data, fn ) {
+ return this.on( types, selector, data, fn );
+ },
+ undelegate: function( selector, types, fn ) {
+ // ( namespace ) or ( selector, types [, fn] )
+ return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
+ }
+});
+var
+ // Document location
+ ajaxLocParts,
+ ajaxLocation,
+ ajax_nonce = jQuery.now(),
+
+ ajax_rquery = /\?/,
+ rhash = /#.*$/,
+ rts = /([?&])_=[^&]*/,
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+ // #7653, #8125, #8152: local protocol detection
+ rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+ rnoContent = /^(?:GET|HEAD)$/,
+ rprotocol = /^\/\//,
+ rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
+
+ // Keep a copy of the old load method
+ _load = jQuery.fn.load,
+
+ /* Prefilters
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+ * 2) These are called:
+ * - BEFORE asking for a transport
+ * - AFTER param serialization (s.data is a string if s.processData is true)
+ * 3) key is the dataType
+ * 4) the catchall symbol "*" can be used
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+ */
+ prefilters = {},
+
+ /* Transports bindings
+ * 1) key is the dataType
+ * 2) the catchall symbol "*" can be used
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
+ */
+ transports = {},
+
+ // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+ allTypes = "*/".concat("*");
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+ ajaxLocation = location.href;
+} catch( e ) {
+ // Use the href attribute of an A element
+ // since IE will modify it given document.location
+ ajaxLocation = document.createElement( "a" );
+ ajaxLocation.href = "";
+ ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+ // dataTypeExpression is optional and defaults to "*"
+ return function( dataTypeExpression, func ) {
+
+ if ( typeof dataTypeExpression !== "string" ) {
+ func = dataTypeExpression;
+ dataTypeExpression = "*";
+ }
+
+ var dataType,
+ i = 0,
+ dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
+
+ if ( jQuery.isFunction( func ) ) {
+ // For each dataType in the dataTypeExpression
+ while ( (dataType = dataTypes[i++]) ) {
+ // Prepend if requested
+ if ( dataType[0] === "+" ) {
+ dataType = dataType.slice( 1 ) || "*";
+ (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
+
+ // Otherwise append
+ } else {
+ (structure[ dataType ] = structure[ dataType ] || []).push( func );
+ }
+ }
+ }
+ };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+ var inspected = {},
+ seekingTransport = ( structure === transports );
+
+ function inspect( dataType ) {
+ var selected;
+ inspected[ dataType ] = true;
+ jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+ var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+ if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+ options.dataTypes.unshift( dataTypeOrTransport );
+ inspect( dataTypeOrTransport );
+ return false;
+ } else if ( seekingTransport ) {
+ return !( selected = dataTypeOrTransport );
+ }
+ });
+ return selected;
+ }
+
+ return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+ var deep, key,
+ flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+ for ( key in src ) {
+ if ( src[ key ] !== undefined ) {
+ ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
+ }
+ }
+ if ( deep ) {
+ jQuery.extend( true, target, deep );
+ }
+
+ return target;
+}
+
+jQuery.fn.load = function( url, params, callback ) {
+ if ( typeof url !== "string" && _load ) {
+ return _load.apply( this, arguments );
+ }
+
+ var selector, response, type,
+ self = this,
+ off = url.indexOf(" ");
+
+ if ( off >= 0 ) {
+ selector = url.slice( off, url.length );
+ url = url.slice( 0, off );
+ }
+
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+
+ // We assume that it's the callback
+ callback = params;
+ params = undefined;
+
+ // Otherwise, build a param string
+ } else if ( params && typeof params === "object" ) {
+ type = "POST";
+ }
+
+ // If we have elements to modify, make the request
+ if ( self.length > 0 ) {
+ jQuery.ajax({
+ url: url,
+
+ // if "type" variable is undefined, then "GET" method will be used
+ type: type,
+ dataType: "html",
+ data: params
+ }).done(function( responseText ) {
+
+ // Save response for use in complete callback
+ response = arguments;
+
+ self.html( selector ?
+
+ // If a selector was specified, locate the right elements in a dummy div
+ // Exclude scripts to avoid IE 'Permission Denied' errors
+ jQuery("").append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+ // Otherwise use the full result
+ responseText );
+
+ }).complete( callback && function( jqXHR, status ) {
+ self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+ });
+ }
+
+ return this;
+};
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
+ jQuery.fn[ type ] = function( fn ){
+ return this.on( type, fn );
+ };
+});
+
+jQuery.extend({
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {},
+
+ ajaxSettings: {
+ url: ajaxLocation,
+ type: "GET",
+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+ global: true,
+ processData: true,
+ async: true,
+ contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+ /*
+ timeout: 0,
+ data: null,
+ dataType: null,
+ username: null,
+ password: null,
+ cache: null,
+ throws: false,
+ traditional: false,
+ headers: {},
+ */
+
+ accepts: {
+ "*": allTypes,
+ text: "text/plain",
+ html: "text/html",
+ xml: "application/xml, text/xml",
+ json: "application/json, text/javascript"
+ },
+
+ contents: {
+ xml: /xml/,
+ html: /html/,
+ json: /json/
+ },
+
+ responseFields: {
+ xml: "responseXML",
+ text: "responseText",
+ json: "responseJSON"
+ },
+
+ // Data converters
+ // Keys separate source (or catchall "*") and destination types with a single space
+ converters: {
+
+ // Convert anything to text
+ "* text": String,
+
+ // Text to html (true = no transformation)
+ "text html": true,
+
+ // Evaluate text as a json expression
+ "text json": jQuery.parseJSON,
+
+ // Parse text as xml
+ "text xml": jQuery.parseXML
+ },
+
+ // For options that shouldn't be deep extended:
+ // you can add your own custom options here if
+ // and when you create one that shouldn't be
+ // deep extended (see ajaxExtend)
+ flatOptions: {
+ url: true,
+ context: true
+ }
+ },
+
+ // Creates a full fledged settings object into target
+ // with both ajaxSettings and settings fields.
+ // If target is omitted, writes into ajaxSettings.
+ ajaxSetup: function( target, settings ) {
+ return settings ?
+
+ // Building a settings object
+ ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+ // Extending ajaxSettings
+ ajaxExtend( jQuery.ajaxSettings, target );
+ },
+
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+ // Main method
+ ajax: function( url, options ) {
+
+ // If url is an object, simulate pre-1.5 signature
+ if ( typeof url === "object" ) {
+ options = url;
+ url = undefined;
+ }
+
+ // Force options to be an object
+ options = options || {};
+
+ var // Cross-domain detection vars
+ parts,
+ // Loop variable
+ i,
+ // URL without anti-cache param
+ cacheURL,
+ // Response headers as string
+ responseHeadersString,
+ // timeout handle
+ timeoutTimer,
+
+ // To know if global events are to be dispatched
+ fireGlobals,
+
+ transport,
+ // Response headers
+ responseHeaders,
+ // Create the final options object
+ s = jQuery.ajaxSetup( {}, options ),
+ // Callbacks context
+ callbackContext = s.context || s,
+ // Context for global events is callbackContext if it is a DOM node or jQuery collection
+ globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
+ jQuery( callbackContext ) :
+ jQuery.event,
+ // Deferreds
+ deferred = jQuery.Deferred(),
+ completeDeferred = jQuery.Callbacks("once memory"),
+ // Status-dependent callbacks
+ statusCode = s.statusCode || {},
+ // Headers (they are sent all at once)
+ requestHeaders = {},
+ requestHeadersNames = {},
+ // The jqXHR state
+ state = 0,
+ // Default abort message
+ strAbort = "canceled",
+ // Fake xhr
+ jqXHR = {
+ readyState: 0,
+
+ // Builds headers hashtable if needed
+ getResponseHeader: function( key ) {
+ var match;
+ if ( state === 2 ) {
+ if ( !responseHeaders ) {
+ responseHeaders = {};
+ while ( (match = rheaders.exec( responseHeadersString )) ) {
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+ }
+ }
+ match = responseHeaders[ key.toLowerCase() ];
+ }
+ return match == null ? null : match;
+ },
+
+ // Raw string
+ getAllResponseHeaders: function() {
+ return state === 2 ? responseHeadersString : null;
+ },
+
+ // Caches the header
+ setRequestHeader: function( name, value ) {
+ var lname = name.toLowerCase();
+ if ( !state ) {
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+ requestHeaders[ name ] = value;
+ }
+ return this;
+ },
+
+ // Overrides response content-type header
+ overrideMimeType: function( type ) {
+ if ( !state ) {
+ s.mimeType = type;
+ }
+ return this;
+ },
+
+ // Status-dependent callbacks
+ statusCode: function( map ) {
+ var code;
+ if ( map ) {
+ if ( state < 2 ) {
+ for ( code in map ) {
+ // Lazy-add the new callback in a way that preserves old ones
+ statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+ }
+ } else {
+ // Execute the appropriate callbacks
+ jqXHR.always( map[ jqXHR.status ] );
+ }
+ }
+ return this;
+ },
+
+ // Cancel the request
+ abort: function( statusText ) {
+ var finalText = statusText || strAbort;
+ if ( transport ) {
+ transport.abort( finalText );
+ }
+ done( 0, finalText );
+ return this;
+ }
+ };
+
+ // Attach deferreds
+ deferred.promise( jqXHR ).complete = completeDeferred.add;
+ jqXHR.success = jqXHR.done;
+ jqXHR.error = jqXHR.fail;
+
+ // Remove hash character (#7531: and string promotion)
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+ // Handle falsy url in the settings object (#10093: consistency with old signature)
+ // We also use the url parameter if available
+ s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+ // Alias method option to type as per ticket #12004
+ s.type = options.method || options.type || s.method || s.type;
+
+ // Extract dataTypes list
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
+
+ // A cross-domain request is in order when we have a protocol:host:port mismatch
+ if ( s.crossDomain == null ) {
+ parts = rurl.exec( s.url.toLowerCase() );
+ s.crossDomain = !!( parts &&
+ ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
+ );
+ }
+
+ // Convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Apply prefilters
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+ // If request was aborted inside a prefilter, stop there
+ if ( state === 2 ) {
+ return jqXHR;
+ }
+
+ // We can fire global events as of now if asked to
+ fireGlobals = s.global;
+
+ // Watch for a new set of requests
+ if ( fireGlobals && jQuery.active++ === 0 ) {
+ jQuery.event.trigger("ajaxStart");
+ }
+
+ // Uppercase the type
+ s.type = s.type.toUpperCase();
+
+ // Determine if request has content
+ s.hasContent = !rnoContent.test( s.type );
+
+ // Save the URL in case we're toying with the If-Modified-Since
+ // and/or If-None-Match header later on
+ cacheURL = s.url;
+
+ // More options handling for requests with no content
+ if ( !s.hasContent ) {
+
+ // If data is available, append data to url
+ if ( s.data ) {
+ cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+ // #9682: remove data so that it's not used in an eventual retry
+ delete s.data;
+ }
+
+ // Add anti-cache in url if needed
+ if ( s.cache === false ) {
+ s.url = rts.test( cacheURL ) ?
+
+ // If there is already a '_' parameter, set its value
+ cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
+
+ // Otherwise add one to the end
+ cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
+ }
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ if ( jQuery.lastModified[ cacheURL ] ) {
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+ }
+ if ( jQuery.etag[ cacheURL ] ) {
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+ }
+ }
+
+ // Set the correct header, if data is being sent
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ jqXHR.setRequestHeader(
+ "Accept",
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+ s.accepts[ "*" ]
+ );
+
+ // Check for headers option
+ for ( i in s.headers ) {
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
+ }
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+ // Abort if not done already and return
+ return jqXHR.abort();
+ }
+
+ // aborting is no longer a cancellation
+ strAbort = "abort";
+
+ // Install callbacks on deferreds
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
+ jqXHR[ i ]( s[ i ] );
+ }
+
+ // Get transport
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+ // If no transport, we auto-abort
+ if ( !transport ) {
+ done( -1, "No Transport" );
+ } else {
+ jqXHR.readyState = 1;
+
+ // Send global event
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+ }
+ // Timeout
+ if ( s.async && s.timeout > 0 ) {
+ timeoutTimer = setTimeout(function() {
+ jqXHR.abort("timeout");
+ }, s.timeout );
+ }
+
+ try {
+ state = 1;
+ transport.send( requestHeaders, done );
+ } catch ( e ) {
+ // Propagate exception as error if not done
+ if ( state < 2 ) {
+ done( -1, e );
+ // Simply rethrow otherwise
+ } else {
+ throw e;
+ }
+ }
+ }
+
+ // Callback for when everything is done
+ function done( status, nativeStatusText, responses, headers ) {
+ var isSuccess, success, error, response, modified,
+ statusText = nativeStatusText;
+
+ // Called once
+ if ( state === 2 ) {
+ return;
+ }
+
+ // State is "done" now
+ state = 2;
+
+ // Clear timeout if it exists
+ if ( timeoutTimer ) {
+ clearTimeout( timeoutTimer );
+ }
+
+ // Dereference transport for early garbage collection
+ // (no matter how long the jqXHR object will be used)
+ transport = undefined;
+
+ // Cache response headers
+ responseHeadersString = headers || "";
+
+ // Set readyState
+ jqXHR.readyState = status > 0 ? 4 : 0;
+
+ // Determine if successful
+ isSuccess = status >= 200 && status < 300 || status === 304;
+
+ // Get response data
+ if ( responses ) {
+ response = ajaxHandleResponses( s, jqXHR, responses );
+ }
+
+ // Convert no matter what (that way responseXXX fields are always set)
+ response = ajaxConvert( s, response, jqXHR, isSuccess );
+
+ // If successful, handle type chaining
+ if ( isSuccess ) {
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ modified = jqXHR.getResponseHeader("Last-Modified");
+ if ( modified ) {
+ jQuery.lastModified[ cacheURL ] = modified;
+ }
+ modified = jqXHR.getResponseHeader("etag");
+ if ( modified ) {
+ jQuery.etag[ cacheURL ] = modified;
+ }
+ }
+
+ // if no content
+ if ( status === 204 || s.type === "HEAD" ) {
+ statusText = "nocontent";
+
+ // if not modified
+ } else if ( status === 304 ) {
+ statusText = "notmodified";
+
+ // If we have data, let's convert it
+ } else {
+ statusText = response.state;
+ success = response.data;
+ error = response.error;
+ isSuccess = !error;
+ }
+ } else {
+ // We extract error from statusText
+ // then normalize statusText and status for non-aborts
+ error = statusText;
+ if ( status || !statusText ) {
+ statusText = "error";
+ if ( status < 0 ) {
+ status = 0;
+ }
+ }
+ }
+
+ // Set data for the fake xhr object
+ jqXHR.status = status;
+ jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+ // Success/Error
+ if ( isSuccess ) {
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+ } else {
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+ }
+
+ // Status-dependent callbacks
+ jqXHR.statusCode( statusCode );
+ statusCode = undefined;
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+ [ jqXHR, s, isSuccess ? success : error ] );
+ }
+
+ // Complete
+ completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+ // Handle the global AJAX counter
+ if ( !( --jQuery.active ) ) {
+ jQuery.event.trigger("ajaxStop");
+ }
+ }
+ }
+
+ return jqXHR;
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get( url, data, callback, "json" );
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get( url, undefined, callback, "script" );
+ }
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+ jQuery[ method ] = function( url, data, callback, type ) {
+ // shift arguments if data argument was omitted
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = undefined;
+ }
+
+ return jQuery.ajax({
+ url: url,
+ type: method,
+ dataType: type,
+ data: data,
+ success: callback
+ });
+ };
+});
+
+/* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+ var firstDataType, ct, finalDataType, type,
+ contents = s.contents,
+ dataTypes = s.dataTypes;
+
+ // Remove auto dataType and get content-type in the process
+ while( dataTypes[ 0 ] === "*" ) {
+ dataTypes.shift();
+ if ( ct === undefined ) {
+ ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
+ }
+ }
+
+ // Check if we're dealing with a known content-type
+ if ( ct ) {
+ for ( type in contents ) {
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
+ dataTypes.unshift( type );
+ break;
+ }
+ }
+ }
+
+ // Check to see if we have a response for the expected dataType
+ if ( dataTypes[ 0 ] in responses ) {
+ finalDataType = dataTypes[ 0 ];
+ } else {
+ // Try convertible dataTypes
+ for ( type in responses ) {
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+ finalDataType = type;
+ break;
+ }
+ if ( !firstDataType ) {
+ firstDataType = type;
+ }
+ }
+ // Or just use first one
+ finalDataType = finalDataType || firstDataType;
+ }
+
+ // If we found a dataType
+ // We add the dataType to the list if needed
+ // and return the corresponding response
+ if ( finalDataType ) {
+ if ( finalDataType !== dataTypes[ 0 ] ) {
+ dataTypes.unshift( finalDataType );
+ }
+ return responses[ finalDataType ];
+ }
+}
+
+/* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+function ajaxConvert( s, response, jqXHR, isSuccess ) {
+ var conv2, current, conv, tmp, prev,
+ converters = {},
+ // Work with a copy of dataTypes in case we need to modify it for conversion
+ dataTypes = s.dataTypes.slice();
+
+ // Create converters map with lowercased keys
+ if ( dataTypes[ 1 ] ) {
+ for ( conv in s.converters ) {
+ converters[ conv.toLowerCase() ] = s.converters[ conv ];
+ }
+ }
+
+ current = dataTypes.shift();
+
+ // Convert to each sequential dataType
+ while ( current ) {
+
+ if ( s.responseFields[ current ] ) {
+ jqXHR[ s.responseFields[ current ] ] = response;
+ }
+
+ // Apply the dataFilter if provided
+ if ( !prev && isSuccess && s.dataFilter ) {
+ response = s.dataFilter( response, s.dataType );
+ }
+
+ prev = current;
+ current = dataTypes.shift();
+
+ if ( current ) {
+
+ // There's only work to do if current dataType is non-auto
+ if ( current === "*" ) {
+
+ current = prev;
+
+ // Convert response if prev dataType is non-auto and differs from current
+ } else if ( prev !== "*" && prev !== current ) {
+
+ // Seek a direct converter
+ conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+ // If none found, seek a pair
+ if ( !conv ) {
+ for ( conv2 in converters ) {
+
+ // If conv2 outputs current
+ tmp = conv2.split( " " );
+ if ( tmp[ 1 ] === current ) {
+
+ // If prev can be converted to accepted input
+ conv = converters[ prev + " " + tmp[ 0 ] ] ||
+ converters[ "* " + tmp[ 0 ] ];
+ if ( conv ) {
+ // Condense equivalence converters
+ if ( conv === true ) {
+ conv = converters[ conv2 ];
+
+ // Otherwise, insert the intermediate dataType
+ } else if ( converters[ conv2 ] !== true ) {
+ current = tmp[ 0 ];
+ dataTypes.unshift( tmp[ 1 ] );
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ // Apply converter (if not an equivalence)
+ if ( conv !== true ) {
+
+ // Unless errors are allowed to bubble, catch and return them
+ if ( conv && s[ "throws" ] ) {
+ response = conv( response );
+ } else {
+ try {
+ response = conv( response );
+ } catch ( e ) {
+ return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return { state: "success", data: response };
+}
+// Install script dataType
+jQuery.ajaxSetup({
+ accepts: {
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+ },
+ contents: {
+ script: /(?:java|ecma)script/
+ },
+ converters: {
+ "text script": function( text ) {
+ jQuery.globalEval( text );
+ return text;
+ }
+ }
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+ if ( s.cache === undefined ) {
+ s.cache = false;
+ }
+ if ( s.crossDomain ) {
+ s.type = "GET";
+ s.global = false;
+ }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+ // This transport only deals with cross domain requests
+ if ( s.crossDomain ) {
+
+ var script,
+ head = document.head || jQuery("head")[0] || document.documentElement;
+
+ return {
+
+ send: function( _, callback ) {
+
+ script = document.createElement("script");
+
+ script.async = true;
+
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ script.src = s.url;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+
+ // Remove the script
+ if ( script.parentNode ) {
+ script.parentNode.removeChild( script );
+ }
+
+ // Dereference the script
+ script = null;
+
+ // Callback if not abort
+ if ( !isAbort ) {
+ callback( 200, "success" );
+ }
+ }
+ };
+
+ // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
+ // Use native DOM manipulation to avoid our domManip AJAX trickery
+ head.insertBefore( script, head.firstChild );
+ },
+
+ abort: function() {
+ if ( script ) {
+ script.onload( undefined, true );
+ }
+ }
+ };
+ }
+});
+var oldCallbacks = [],
+ rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+ jsonp: "callback",
+ jsonpCallback: function() {
+ var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
+ this[ callback ] = true;
+ return callback;
+ }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+ var callbackName, overwritten, responseContainer,
+ jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+ "url" :
+ typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
+ );
+
+ // Handle iff the expected data type is "jsonp" or we have a parameter to set
+ if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+ // Get callback name, remembering preexisting value associated with it
+ callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+ s.jsonpCallback() :
+ s.jsonpCallback;
+
+ // Insert callback into url or form data
+ if ( jsonProp ) {
+ s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+ } else if ( s.jsonp !== false ) {
+ s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+ }
+
+ // Use data converter to retrieve json after script execution
+ s.converters["script json"] = function() {
+ if ( !responseContainer ) {
+ jQuery.error( callbackName + " was not called" );
+ }
+ return responseContainer[ 0 ];
+ };
+
+ // force json dataType
+ s.dataTypes[ 0 ] = "json";
+
+ // Install callback
+ overwritten = window[ callbackName ];
+ window[ callbackName ] = function() {
+ responseContainer = arguments;
+ };
+
+ // Clean-up function (fires after converters)
+ jqXHR.always(function() {
+ // Restore preexisting value
+ window[ callbackName ] = overwritten;
+
+ // Save back as free
+ if ( s[ callbackName ] ) {
+ // make sure that re-using the options doesn't screw things around
+ s.jsonpCallback = originalSettings.jsonpCallback;
+
+ // save the callback name for future use
+ oldCallbacks.push( callbackName );
+ }
+
+ // Call if it was a function and we have a response
+ if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+ overwritten( responseContainer[ 0 ] );
+ }
+
+ responseContainer = overwritten = undefined;
+ });
+
+ // Delegate to script
+ return "script";
+ }
+});
+var xhrCallbacks, xhrSupported,
+ xhrId = 0,
+ // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+ xhrOnUnloadAbort = window.ActiveXObject && function() {
+ // Abort all pending requests
+ var key;
+ for ( key in xhrCallbacks ) {
+ xhrCallbacks[ key ]( undefined, true );
+ }
+ };
+
+// Functions to create xhrs
+function createStandardXHR() {
+ try {
+ return new window.XMLHttpRequest();
+ } catch( e ) {}
+}
+
+function createActiveXHR() {
+ try {
+ return new window.ActiveXObject("Microsoft.XMLHTTP");
+ } catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+ /* Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+ function() {
+ return !this.isLocal && createStandardXHR() || createActiveXHR();
+ } :
+ // For all other browsers, use the standard XMLHttpRequest object
+ createStandardXHR;
+
+// Determine support properties
+xhrSupported = jQuery.ajaxSettings.xhr();
+jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+xhrSupported = jQuery.support.ajax = !!xhrSupported;
+
+// Create transport if the browser can provide an xhr
+if ( xhrSupported ) {
+
+ jQuery.ajaxTransport(function( s ) {
+ // Cross domain only allowed if supported through XMLHttpRequest
+ if ( !s.crossDomain || jQuery.support.cors ) {
+
+ var callback;
+
+ return {
+ send: function( headers, complete ) {
+
+ // Get a new xhr
+ var handle, i,
+ xhr = s.xhr();
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open( s.type, s.url, s.async, s.username, s.password );
+ } else {
+ xhr.open( s.type, s.url, s.async );
+ }
+
+ // Apply custom fields if provided
+ if ( s.xhrFields ) {
+ for ( i in s.xhrFields ) {
+ xhr[ i ] = s.xhrFields[ i ];
+ }
+ }
+
+ // Override mime type if needed
+ if ( s.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( s.mimeType );
+ }
+
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+ headers["X-Requested-With"] = "XMLHttpRequest";
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
+ } catch( err ) {}
+
+ // Do send the request
+ // This may raise an exception which is actually
+ // handled in jQuery.ajax (so no try/catch here)
+ xhr.send( ( s.hasContent && s.data ) || null );
+
+ // Listener
+ callback = function( _, isAbort ) {
+ var status, responseHeaders, statusText, responses;
+
+ // Firefox throws exceptions when accessing properties
+ // of an xhr when a network error occurred
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+ try {
+
+ // Was never called and is aborted or complete
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+ // Only called once
+ callback = undefined;
+
+ // Do not keep as active anymore
+ if ( handle ) {
+ xhr.onreadystatechange = jQuery.noop;
+ if ( xhrOnUnloadAbort ) {
+ delete xhrCallbacks[ handle ];
+ }
+ }
+
+ // If it's an abort
+ if ( isAbort ) {
+ // Abort it manually if needed
+ if ( xhr.readyState !== 4 ) {
+ xhr.abort();
+ }
+ } else {
+ responses = {};
+ status = xhr.status;
+ responseHeaders = xhr.getAllResponseHeaders();
+
+ // When requesting binary data, IE6-9 will throw an exception
+ // on any attempt to access responseText (#11426)
+ if ( typeof xhr.responseText === "string" ) {
+ responses.text = xhr.responseText;
+ }
+
+ // Firefox throws an exception when accessing
+ // statusText for faulty cross-domain requests
+ try {
+ statusText = xhr.statusText;
+ } catch( e ) {
+ // We normalize with Webkit giving an empty statusText
+ statusText = "";
+ }
+
+ // Filter status for non standard behaviors
+
+ // If the request is local and we have data: assume a success
+ // (success with no data won't get notified, that's the best we
+ // can do given current implementations)
+ if ( !status && s.isLocal && !s.crossDomain ) {
+ status = responses.text ? 200 : 404;
+ // IE - #1450: sometimes returns 1223 when it should be 204
+ } else if ( status === 1223 ) {
+ status = 204;
+ }
+ }
+ }
+ } catch( firefoxAccessException ) {
+ if ( !isAbort ) {
+ complete( -1, firefoxAccessException );
+ }
+ }
+
+ // Call complete if needed
+ if ( responses ) {
+ complete( status, statusText, responses, responseHeaders );
+ }
+ };
+
+ if ( !s.async ) {
+ // if we're in sync mode we fire the callback
+ callback();
+ } else if ( xhr.readyState === 4 ) {
+ // (IE6 & IE7) if it's in cache and has been
+ // retrieved directly we need to fire the callback
+ setTimeout( callback );
+ } else {
+ handle = ++xhrId;
+ if ( xhrOnUnloadAbort ) {
+ // Create the active xhrs callbacks list if needed
+ // and attach the unload handler
+ if ( !xhrCallbacks ) {
+ xhrCallbacks = {};
+ jQuery( window ).unload( xhrOnUnloadAbort );
+ }
+ // Add to list of active xhrs callbacks
+ xhrCallbacks[ handle ] = callback;
+ }
+ xhr.onreadystatechange = callback;
+ }
+ },
+
+ abort: function() {
+ if ( callback ) {
+ callback( undefined, true );
+ }
+ }
+ };
+ }
+ });
+}
+var fxNow, timerId,
+ rfxtypes = /^(?:toggle|show|hide)$/,
+ rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
+ rrun = /queueHooks$/,
+ animationPrefilters = [ defaultPrefilter ],
+ tweeners = {
+ "*": [function( prop, value ) {
+ var tween = this.createTween( prop, value ),
+ target = tween.cur(),
+ parts = rfxnum.exec( value ),
+ unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+ // Starting value computation is required for potential unit mismatches
+ start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
+ rfxnum.exec( jQuery.css( tween.elem, prop ) ),
+ scale = 1,
+ maxIterations = 20;
+
+ if ( start && start[ 3 ] !== unit ) {
+ // Trust units reported by jQuery.css
+ unit = unit || start[ 3 ];
+
+ // Make sure we update the tween properties later on
+ parts = parts || [];
+
+ // Iteratively approximate from a nonzero starting point
+ start = +target || 1;
+
+ do {
+ // If previous iteration zeroed out, double until we get *something*
+ // Use a string for doubling factor so we don't accidentally see scale as unchanged below
+ scale = scale || ".5";
+
+ // Adjust and apply
+ start = start / scale;
+ jQuery.style( tween.elem, prop, start + unit );
+
+ // Update scale, tolerating zero or NaN from tween.cur()
+ // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+ } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
+ }
+
+ // Update tween properties
+ if ( parts ) {
+ start = tween.start = +start || +target || 0;
+ tween.unit = unit;
+ // If a +=/-= token was provided, we're doing a relative animation
+ tween.end = parts[ 1 ] ?
+ start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
+ +parts[ 2 ];
+ }
+
+ return tween;
+ }]
+ };
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+ setTimeout(function() {
+ fxNow = undefined;
+ });
+ return ( fxNow = jQuery.now() );
+}
+
+function createTween( value, prop, animation ) {
+ var tween,
+ collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
+ index = 0,
+ length = collection.length;
+ for ( ; index < length; index++ ) {
+ if ( (tween = collection[ index ].call( animation, prop, value )) ) {
+
+ // we're done with this property
+ return tween;
+ }
+ }
+}
+
+function Animation( elem, properties, options ) {
+ var result,
+ stopped,
+ index = 0,
+ length = animationPrefilters.length,
+ deferred = jQuery.Deferred().always( function() {
+ // don't match elem in the :animated selector
+ delete tick.elem;
+ }),
+ tick = function() {
+ if ( stopped ) {
+ return false;
+ }
+ var currentTime = fxNow || createFxNow(),
+ remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+ // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+ temp = remaining / animation.duration || 0,
+ percent = 1 - temp,
+ index = 0,
+ length = animation.tweens.length;
+
+ for ( ; index < length ; index++ ) {
+ animation.tweens[ index ].run( percent );
+ }
+
+ deferred.notifyWith( elem, [ animation, percent, remaining ]);
+
+ if ( percent < 1 && length ) {
+ return remaining;
+ } else {
+ deferred.resolveWith( elem, [ animation ] );
+ return false;
+ }
+ },
+ animation = deferred.promise({
+ elem: elem,
+ props: jQuery.extend( {}, properties ),
+ opts: jQuery.extend( true, { specialEasing: {} }, options ),
+ originalProperties: properties,
+ originalOptions: options,
+ startTime: fxNow || createFxNow(),
+ duration: options.duration,
+ tweens: [],
+ createTween: function( prop, end ) {
+ var tween = jQuery.Tween( elem, animation.opts, prop, end,
+ animation.opts.specialEasing[ prop ] || animation.opts.easing );
+ animation.tweens.push( tween );
+ return tween;
+ },
+ stop: function( gotoEnd ) {
+ var index = 0,
+ // if we are going to the end, we want to run all the tweens
+ // otherwise we skip this part
+ length = gotoEnd ? animation.tweens.length : 0;
+ if ( stopped ) {
+ return this;
+ }
+ stopped = true;
+ for ( ; index < length ; index++ ) {
+ animation.tweens[ index ].run( 1 );
+ }
+
+ // resolve when we played the last frame
+ // otherwise, reject
+ if ( gotoEnd ) {
+ deferred.resolveWith( elem, [ animation, gotoEnd ] );
+ } else {
+ deferred.rejectWith( elem, [ animation, gotoEnd ] );
+ }
+ return this;
+ }
+ }),
+ props = animation.props;
+
+ propFilter( props, animation.opts.specialEasing );
+
+ for ( ; index < length ; index++ ) {
+ result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
+ if ( result ) {
+ return result;
+ }
+ }
+
+ jQuery.map( props, createTween, animation );
+
+ if ( jQuery.isFunction( animation.opts.start ) ) {
+ animation.opts.start.call( elem, animation );
+ }
+
+ jQuery.fx.timer(
+ jQuery.extend( tick, {
+ elem: elem,
+ anim: animation,
+ queue: animation.opts.queue
+ })
+ );
+
+ // attach callbacks from options
+ return animation.progress( animation.opts.progress )
+ .done( animation.opts.done, animation.opts.complete )
+ .fail( animation.opts.fail )
+ .always( animation.opts.always );
+}
+
+function propFilter( props, specialEasing ) {
+ var index, name, easing, value, hooks;
+
+ // camelCase, specialEasing and expand cssHook pass
+ for ( index in props ) {
+ name = jQuery.camelCase( index );
+ easing = specialEasing[ name ];
+ value = props[ index ];
+ if ( jQuery.isArray( value ) ) {
+ easing = value[ 1 ];
+ value = props[ index ] = value[ 0 ];
+ }
+
+ if ( index !== name ) {
+ props[ name ] = value;
+ delete props[ index ];
+ }
+
+ hooks = jQuery.cssHooks[ name ];
+ if ( hooks && "expand" in hooks ) {
+ value = hooks.expand( value );
+ delete props[ name ];
+
+ // not quite $.extend, this wont overwrite keys already present.
+ // also - reusing 'index' from above because we have the correct "name"
+ for ( index in value ) {
+ if ( !( index in props ) ) {
+ props[ index ] = value[ index ];
+ specialEasing[ index ] = easing;
+ }
+ }
+ } else {
+ specialEasing[ name ] = easing;
+ }
+ }
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+ tweener: function( props, callback ) {
+ if ( jQuery.isFunction( props ) ) {
+ callback = props;
+ props = [ "*" ];
+ } else {
+ props = props.split(" ");
+ }
+
+ var prop,
+ index = 0,
+ length = props.length;
+
+ for ( ; index < length ; index++ ) {
+ prop = props[ index ];
+ tweeners[ prop ] = tweeners[ prop ] || [];
+ tweeners[ prop ].unshift( callback );
+ }
+ },
+
+ prefilter: function( callback, prepend ) {
+ if ( prepend ) {
+ animationPrefilters.unshift( callback );
+ } else {
+ animationPrefilters.push( callback );
+ }
+ }
+});
+
+function defaultPrefilter( elem, props, opts ) {
+ /* jshint validthis: true */
+ var prop, value, toggle, tween, hooks, oldfire,
+ anim = this,
+ orig = {},
+ style = elem.style,
+ hidden = elem.nodeType && isHidden( elem ),
+ dataShow = jQuery._data( elem, "fxshow" );
+
+ // handle queue: false promises
+ if ( !opts.queue ) {
+ hooks = jQuery._queueHooks( elem, "fx" );
+ if ( hooks.unqueued == null ) {
+ hooks.unqueued = 0;
+ oldfire = hooks.empty.fire;
+ hooks.empty.fire = function() {
+ if ( !hooks.unqueued ) {
+ oldfire();
+ }
+ };
+ }
+ hooks.unqueued++;
+
+ anim.always(function() {
+ // doing this makes sure that the complete handler will be called
+ // before this completes
+ anim.always(function() {
+ hooks.unqueued--;
+ if ( !jQuery.queue( elem, "fx" ).length ) {
+ hooks.empty.fire();
+ }
+ });
+ });
+ }
+
+ // height/width overflow pass
+ if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
+ // Make sure that nothing sneaks out
+ // Record all 3 overflow attributes because IE does not
+ // change the overflow attribute when overflowX and
+ // overflowY are set to the same value
+ opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+ // Set display property to inline-block for height/width
+ // animations on inline elements that are having width/height animated
+ if ( jQuery.css( elem, "display" ) === "inline" &&
+ jQuery.css( elem, "float" ) === "none" ) {
+
+ // inline-level elements accept inline-block;
+ // block-level elements need to be inline with layout
+ if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) {
+ style.display = "inline-block";
+
+ } else {
+ style.zoom = 1;
+ }
+ }
+ }
+
+ if ( opts.overflow ) {
+ style.overflow = "hidden";
+ if ( !jQuery.support.shrinkWrapBlocks ) {
+ anim.always(function() {
+ style.overflow = opts.overflow[ 0 ];
+ style.overflowX = opts.overflow[ 1 ];
+ style.overflowY = opts.overflow[ 2 ];
+ });
+ }
+ }
+
+
+ // show/hide pass
+ for ( prop in props ) {
+ value = props[ prop ];
+ if ( rfxtypes.exec( value ) ) {
+ delete props[ prop ];
+ toggle = toggle || value === "toggle";
+ if ( value === ( hidden ? "hide" : "show" ) ) {
+ continue;
+ }
+ orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+ }
+ }
+
+ if ( !jQuery.isEmptyObject( orig ) ) {
+ if ( dataShow ) {
+ if ( "hidden" in dataShow ) {
+ hidden = dataShow.hidden;
+ }
+ } else {
+ dataShow = jQuery._data( elem, "fxshow", {} );
+ }
+
+ // store state if its toggle - enables .stop().toggle() to "reverse"
+ if ( toggle ) {
+ dataShow.hidden = !hidden;
+ }
+ if ( hidden ) {
+ jQuery( elem ).show();
+ } else {
+ anim.done(function() {
+ jQuery( elem ).hide();
+ });
+ }
+ anim.done(function() {
+ var prop;
+ jQuery._removeData( elem, "fxshow" );
+ for ( prop in orig ) {
+ jQuery.style( elem, prop, orig[ prop ] );
+ }
+ });
+ for ( prop in orig ) {
+ tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+
+ if ( !( prop in dataShow ) ) {
+ dataShow[ prop ] = tween.start;
+ if ( hidden ) {
+ tween.end = tween.start;
+ tween.start = prop === "width" || prop === "height" ? 1 : 0;
+ }
+ }
+ }
+ }
+}
+
+function Tween( elem, options, prop, end, easing ) {
+ return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+ constructor: Tween,
+ init: function( elem, options, prop, end, easing, unit ) {
+ this.elem = elem;
+ this.prop = prop;
+ this.easing = easing || "swing";
+ this.options = options;
+ this.start = this.now = this.cur();
+ this.end = end;
+ this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+ },
+ cur: function() {
+ var hooks = Tween.propHooks[ this.prop ];
+
+ return hooks && hooks.get ?
+ hooks.get( this ) :
+ Tween.propHooks._default.get( this );
+ },
+ run: function( percent ) {
+ var eased,
+ hooks = Tween.propHooks[ this.prop ];
+
+ if ( this.options.duration ) {
+ this.pos = eased = jQuery.easing[ this.easing ](
+ percent, this.options.duration * percent, 0, 1, this.options.duration
+ );
+ } else {
+ this.pos = eased = percent;
+ }
+ this.now = ( this.end - this.start ) * eased + this.start;
+
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ if ( hooks && hooks.set ) {
+ hooks.set( this );
+ } else {
+ Tween.propHooks._default.set( this );
+ }
+ return this;
+ }
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+ _default: {
+ get: function( tween ) {
+ var result;
+
+ if ( tween.elem[ tween.prop ] != null &&
+ (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
+ return tween.elem[ tween.prop ];
+ }
+
+ // passing an empty string as a 3rd parameter to .css will automatically
+ // attempt a parseFloat and fallback to a string if the parse fails
+ // so, simple values such as "10px" are parsed to Float.
+ // complex values such as "rotate(1rad)" are returned as is.
+ result = jQuery.css( tween.elem, tween.prop, "" );
+ // Empty strings, null, undefined and "auto" are converted to 0.
+ return !result || result === "auto" ? 0 : result;
+ },
+ set: function( tween ) {
+ // use step hook for back compat - use cssHook if its there - use .style if its
+ // available and use plain properties where available
+ if ( jQuery.fx.step[ tween.prop ] ) {
+ jQuery.fx.step[ tween.prop ]( tween );
+ } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
+ jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+ } else {
+ tween.elem[ tween.prop ] = tween.now;
+ }
+ }
+ }
+};
+
+// Support: IE <=9
+// Panic based approach to setting things on disconnected nodes
+
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+ set: function( tween ) {
+ if ( tween.elem.nodeType && tween.elem.parentNode ) {
+ tween.elem[ tween.prop ] = tween.now;
+ }
+ }
+};
+
+jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
+ var cssFn = jQuery.fn[ name ];
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return speed == null || typeof speed === "boolean" ?
+ cssFn.apply( this, arguments ) :
+ this.animate( genFx( name, true ), speed, easing, callback );
+ };
+});
+
+jQuery.fn.extend({
+ fadeTo: function( speed, to, easing, callback ) {
+
+ // show any hidden elements after setting opacity to 0
+ return this.filter( isHidden ).css( "opacity", 0 ).show()
+
+ // animate to the value specified
+ .end().animate({ opacity: to }, speed, easing, callback );
+ },
+ animate: function( prop, speed, easing, callback ) {
+ var empty = jQuery.isEmptyObject( prop ),
+ optall = jQuery.speed( speed, easing, callback ),
+ doAnimation = function() {
+ // Operate on a copy of prop so per-property easing won't be lost
+ var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+ // Empty animations, or finishing resolves immediately
+ if ( empty || jQuery._data( this, "finish" ) ) {
+ anim.stop( true );
+ }
+ };
+ doAnimation.finish = doAnimation;
+
+ return empty || optall.queue === false ?
+ this.each( doAnimation ) :
+ this.queue( optall.queue, doAnimation );
+ },
+ stop: function( type, clearQueue, gotoEnd ) {
+ var stopQueue = function( hooks ) {
+ var stop = hooks.stop;
+ delete hooks.stop;
+ stop( gotoEnd );
+ };
+
+ if ( typeof type !== "string" ) {
+ gotoEnd = clearQueue;
+ clearQueue = type;
+ type = undefined;
+ }
+ if ( clearQueue && type !== false ) {
+ this.queue( type || "fx", [] );
+ }
+
+ return this.each(function() {
+ var dequeue = true,
+ index = type != null && type + "queueHooks",
+ timers = jQuery.timers,
+ data = jQuery._data( this );
+
+ if ( index ) {
+ if ( data[ index ] && data[ index ].stop ) {
+ stopQueue( data[ index ] );
+ }
+ } else {
+ for ( index in data ) {
+ if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+ stopQueue( data[ index ] );
+ }
+ }
+ }
+
+ for ( index = timers.length; index--; ) {
+ if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
+ timers[ index ].anim.stop( gotoEnd );
+ dequeue = false;
+ timers.splice( index, 1 );
+ }
+ }
+
+ // start the next in the queue if the last step wasn't forced
+ // timers currently will call their complete callbacks, which will dequeue
+ // but only if they were gotoEnd
+ if ( dequeue || !gotoEnd ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ finish: function( type ) {
+ if ( type !== false ) {
+ type = type || "fx";
+ }
+ return this.each(function() {
+ var index,
+ data = jQuery._data( this ),
+ queue = data[ type + "queue" ],
+ hooks = data[ type + "queueHooks" ],
+ timers = jQuery.timers,
+ length = queue ? queue.length : 0;
+
+ // enable finishing flag on private data
+ data.finish = true;
+
+ // empty the queue first
+ jQuery.queue( this, type, [] );
+
+ if ( hooks && hooks.stop ) {
+ hooks.stop.call( this, true );
+ }
+
+ // look for any active animations, and finish them
+ for ( index = timers.length; index--; ) {
+ if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+ timers[ index ].anim.stop( true );
+ timers.splice( index, 1 );
+ }
+ }
+
+ // look for any animations in the old queue and finish them
+ for ( index = 0; index < length; index++ ) {
+ if ( queue[ index ] && queue[ index ].finish ) {
+ queue[ index ].finish.call( this );
+ }
+ }
+
+ // turn off finishing flag
+ delete data.finish;
+ });
+ }
+});
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+ var which,
+ attrs = { height: type },
+ i = 0;
+
+ // if we include width, step value is 1 to do all cssExpand values,
+ // if we don't include width, step value is 2 to skip over Left and Right
+ includeWidth = includeWidth? 1 : 0;
+ for( ; i < 4 ; i += 2 - includeWidth ) {
+ which = cssExpand[ i ];
+ attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+ }
+
+ if ( includeWidth ) {
+ attrs.opacity = attrs.width = type;
+ }
+
+ return attrs;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show"),
+ slideUp: genFx("hide"),
+ slideToggle: genFx("toggle"),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" },
+ fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return this.animate( props, speed, easing, callback );
+ };
+});
+
+jQuery.speed = function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+
+ // normalize opt.queue - true/undefined/null -> "fx"
+ if ( opt.queue == null || opt.queue === true ) {
+ opt.queue = "fx";
+ }
+
+ // Queueing
+ opt.old = opt.complete;
+
+ opt.complete = function() {
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+
+ if ( opt.queue ) {
+ jQuery.dequeue( this, opt.queue );
+ }
+ };
+
+ return opt;
+};
+
+jQuery.easing = {
+ linear: function( p ) {
+ return p;
+ },
+ swing: function( p ) {
+ return 0.5 - Math.cos( p*Math.PI ) / 2;
+ }
+};
+
+jQuery.timers = [];
+jQuery.fx = Tween.prototype.init;
+jQuery.fx.tick = function() {
+ var timer,
+ timers = jQuery.timers,
+ i = 0;
+
+ fxNow = jQuery.now();
+
+ for ( ; i < timers.length; i++ ) {
+ timer = timers[ i ];
+ // Checks the timer has not already been removed
+ if ( !timer() && timers[ i ] === timer ) {
+ timers.splice( i--, 1 );
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+ if ( timer() && jQuery.timers.push( timer ) ) {
+ jQuery.fx.start();
+ }
+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.start = function() {
+ if ( !timerId ) {
+ timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
+ }
+};
+
+jQuery.fx.stop = function() {
+ clearInterval( timerId );
+ timerId = null;
+};
+
+jQuery.fx.speeds = {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+};
+
+// Back Compat <1.8 extension point
+jQuery.fx.step = {};
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+jQuery.fn.offset = function( options ) {
+ if ( arguments.length ) {
+ return options === undefined ?
+ this :
+ this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ var docElem, win,
+ box = { top: 0, left: 0 },
+ elem = this[ 0 ],
+ doc = elem && elem.ownerDocument;
+
+ if ( !doc ) {
+ return;
+ }
+
+ docElem = doc.documentElement;
+
+ // Make sure it's not a disconnected DOM node
+ if ( !jQuery.contains( docElem, elem ) ) {
+ return box;
+ }
+
+ // If we don't have gBCR, just use 0,0 rather than error
+ // BlackBerry 5, iOS 3 (original iPhone)
+ if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
+ box = elem.getBoundingClientRect();
+ }
+ win = getWindow( doc );
+ return {
+ top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
+ left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
+ };
+};
+
+jQuery.offset = {
+
+ setOffset: function( elem, options, i ) {
+ var position = jQuery.css( elem, "position" );
+
+ // set position first, in-case top/left are set even on static elem
+ if ( position === "static" ) {
+ elem.style.position = "relative";
+ }
+
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curCSSTop = jQuery.css( elem, "top" ),
+ curCSSLeft = jQuery.css( elem, "left" ),
+ calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+ props = {}, curPosition = {}, curTop, curLeft;
+
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+ if ( calculatePosition ) {
+ curPosition = curElem.position();
+ curTop = curPosition.top;
+ curLeft = curPosition.left;
+ } else {
+ curTop = parseFloat( curCSSTop ) || 0;
+ curLeft = parseFloat( curCSSLeft ) || 0;
+ }
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ if ( options.top != null ) {
+ props.top = ( options.top - curOffset.top ) + curTop;
+ }
+ if ( options.left != null ) {
+ props.left = ( options.left - curOffset.left ) + curLeft;
+ }
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+
+ position: function() {
+ if ( !this[ 0 ] ) {
+ return;
+ }
+
+ var offsetParent, offset,
+ parentOffset = { top: 0, left: 0 },
+ elem = this[ 0 ];
+
+ // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
+ if ( jQuery.css( elem, "position" ) === "fixed" ) {
+ // we assume that getBoundingClientRect is available when computed position is fixed
+ offset = elem.getBoundingClientRect();
+ } else {
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent();
+
+ // Get correct offsets
+ offset = this.offset();
+ if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+ parentOffset = offsetParent.offset();
+ }
+
+ // Add offsetParent borders
+ parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+ parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+ }
+
+ // Subtract parent offsets and element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ return {
+ top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+ left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || docElem;
+ while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent || docElem;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
+ var top = /Y/.test( prop );
+
+ jQuery.fn[ method ] = function( val ) {
+ return jQuery.access( this, function( elem, method, val ) {
+ var win = getWindow( elem );
+
+ if ( val === undefined ) {
+ return win ? (prop in win) ? win[ prop ] :
+ win.document.documentElement[ method ] :
+ elem[ method ];
+ }
+
+ if ( win ) {
+ win.scrollTo(
+ !top ? val : jQuery( win ).scrollLeft(),
+ top ? val : jQuery( win ).scrollTop()
+ );
+
+ } else {
+ elem[ method ] = val;
+ }
+ }, method, val, arguments.length, null );
+ };
+});
+
+function getWindow( elem ) {
+ return jQuery.isWindow( elem ) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+ jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
+ // margin is only for outerHeight, outerWidth
+ jQuery.fn[ funcName ] = function( margin, value ) {
+ var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+ extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+ return jQuery.access( this, function( elem, type, value ) {
+ var doc;
+
+ if ( jQuery.isWindow( elem ) ) {
+ // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+ // isn't a whole lot we can do. See pull request at this URL for discussion:
+ // https://github.com/jquery/jquery/pull/764
+ return elem.document.documentElement[ "client" + name ];
+ }
+
+ // Get document width or height
+ if ( elem.nodeType === 9 ) {
+ doc = elem.documentElement;
+
+ // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
+ // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
+ return Math.max(
+ elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+ elem.body[ "offset" + name ], doc[ "offset" + name ],
+ doc[ "client" + name ]
+ );
+ }
+
+ return value === undefined ?
+ // Get width or height on the element, requesting but not forcing parseFloat
+ jQuery.css( elem, type, extra ) :
+
+ // Set width or height on the element
+ jQuery.style( elem, type, value, extra );
+ }, type, chainable ? margin : undefined, chainable, null );
+ };
+ });
+});
+// Limit scope pollution from any deprecated API
+// (function() {
+
+// The number of elements contained in the matched element set
+jQuery.fn.size = function() {
+ return this.length;
+};
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+// })();
+if ( typeof module === "object" && module && typeof module.exports === "object" ) {
+ // Expose jQuery as module.exports in loaders that implement the Node
+ // module pattern (including browserify). Do not create the global, since
+ // the user will be storing it themselves locally, and globals are frowned
+ // upon in the Node module world.
+ module.exports = jQuery;
+} else {
+ // Otherwise expose jQuery to the global object as usual
+ window.jQuery = window.$ = jQuery;
+
+ // Register as a named AMD module, since jQuery can be concatenated with other
+ // files that may use define, but not via a proper concatenation script that
+ // understands anonymous AMD modules. A named AMD is safest and most robust
+ // way to register. Lowercase jquery is used because AMD module names are
+ // derived from file names, and jQuery is normally delivered in a lowercase
+ // file name. Do this after creating the global so that if an AMD module wants
+ // to call noConflict to hide this version of jQuery, it will work.
+ if ( typeof define === "function" && define.amd ) {
+ define( "jquery", [], function () { return jQuery; } );
+ }
+}
+
+})( window );
diff --git a/nano/js/libraries/jquery.timers.js b/nano/js/libraries/jquery.timers.js
new file mode 100644
index 00000000..7001e503
--- /dev/null
+++ b/nano/js/libraries/jquery.timers.js
@@ -0,0 +1,4 @@
+jQuery.fn.extend({everyTime:function(c,a,d,b){return this.each(function(){jQuery.timer.add(this,c,a,d,b)})},oneTime:function(c,a,d){return this.each(function(){jQuery.timer.add(this,c,a,d,1)})},stopTime:function(c,a){return this.each(function(){jQuery.timer.remove(this,c,a)})}});
+jQuery.extend({timer:{global:[],guid:1,dataKey:"jQuery.timer",regex:/^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,powers:{ms:1,cs:10,ds:100,s:1E3,das:1E4,hs:1E5,ks:1E6},timeParse:function(c){if(c==undefined||c==null)return null;var a=this.regex.exec(jQuery.trim(c.toString()));return a[2]?parseFloat(a[1])*(this.powers[a[2]]||1):c},add:function(c,a,d,b,e){var g=0;if(jQuery.isFunction(d)){e||(e=b);b=d;d=a}a=jQuery.timer.timeParse(a);if(!(typeof a!="number"||isNaN(a)||a<0)){if(typeof e!="number"||isNaN(e)||e<0)e=
+0;e=e||0;var f=jQuery.data(c,this.dataKey)||jQuery.data(c,this.dataKey,{});f[d]||(f[d]={});b.timerID=b.timerID||this.guid++;var h=function(){if(++g>e&&e!==0||b.call(c,g)===false)jQuery.timer.remove(c,d,b)};h.timerID=b.timerID;f[d][b.timerID]||(f[d][b.timerID]=window.setInterval(h,a));this.global.push(c)}},remove:function(c,a,d){var b=jQuery.data(c,this.dataKey),e;if(b){if(a){if(b[a]){if(d){if(d.timerID){window.clearInterval(b[a][d.timerID]);delete b[a][d.timerID]}}else for(d in b[a]){window.clearInterval(b[a][d]);
+delete b[a][d]}for(e in b[a])break;if(!e){e=null;delete b[a]}}}else for(a in b)this.remove(c,a,d);for(e in b)break;e||jQuery.removeData(c,this.dataKey)}}}});jQuery(window).bind("unload",function(){jQuery.each(jQuery.timer.global,function(c,a){jQuery.timer.remove(a)})});
\ No newline at end of file
diff --git a/nano/js/nano_base_callbacks.js b/nano/js/nano_base_callbacks.js
new file mode 100644
index 00000000..fb5a86ee
--- /dev/null
+++ b/nano/js/nano_base_callbacks.js
@@ -0,0 +1,126 @@
+// NanoBaseCallbacks is where the base callbacks (common to all templates) are stored
+NanoBaseCallbacks = function ()
+{
+ // _canClick is used to disable clicks for a short period after each click (to avoid mis-clicks)
+ var _canClick = true;
+
+ var _baseBeforeUpdateCallbacks = {}
+
+ var _baseAfterUpdateCallbacks = {
+ // this callback is triggered after new data is processed
+ // it updates the status/visibility icon and adds click event handling to buttons/links
+ status: function (updateData) {
+ var uiStatusClass;
+ if (updateData['config']['status'] == 2)
+ {
+ uiStatusClass = 'icon24 uiStatusGood';
+ $('.linkActive').removeClass('inactive');
+ }
+ else if (updateData['config']['status'] == 1)
+ {
+ uiStatusClass = 'icon24 uiStatusAverage';
+ $('.linkActive').addClass('inactive');
+ }
+ else
+ {
+ uiStatusClass = 'icon24 uiStatusBad'
+ $('.linkActive').addClass('inactive');
+ }
+ $('#uiStatusIcon').attr('class', uiStatusClass);
+
+ $('.linkActive').stopTime('linkPending');
+ $('.linkActive').removeClass('linkPending');
+
+ $('.linkActive')
+ .off('click')
+ .on('click', function (event) {
+ event.preventDefault();
+ var href = $(this).data('href');
+ if (href != null && _canClick)
+ {
+ _canClick = false;
+ $('body').oneTime(300, 'enableClick', function () {
+ _canClick = true;
+ });
+ if (updateData['config']['status'] == 2)
+ {
+ $(this).oneTime(300, 'linkPending', function () {
+ $(this).addClass('linkPending');
+ });
+ }
+ window.location.href = href;
+ }
+ });
+
+ return updateData;
+ },
+ nanomap: function (updateData) {
+ $('.mapIcon')
+ .off('mouseenter mouseleave')
+ .on('mouseenter',
+ function (event) {
+ var self = this;
+ $('#uiMapTooltip')
+ .html($(this).children('.tooltip').html())
+ .show()
+ .stopTime()
+ .oneTime(5000, 'hideTooltip', function () {
+ $(this).fadeOut(500);
+ });
+ }
+ );
+
+ $('.zoomLink')
+ .off('click')
+ .on('click', function (event) {
+ event.preventDefault();
+ var zoomLevel = $(this).data('zoomLevel');
+ var uiMapObject = $('#uiMap');
+ var uiMapWidth = uiMapObject.width() * zoomLevel;
+ var uiMapHeight = uiMapObject.height() * zoomLevel;
+
+ uiMapObject.css({
+ zoom: zoomLevel,
+ left: '50%',
+ top: '50%',
+ marginLeft: '-' + Math.floor(uiMapWidth / 2) + 'px',
+ marginTop: '-' + Math.floor(uiMapHeight / 2) + 'px'
+ });
+ });
+
+ $('#uiMapImage').attr('src', 'nanomap_z' + updateData['config']['mapZLevel'] + '.png');
+
+ return updateData;
+ }
+ };
+
+ return {
+ addCallbacks: function () {
+ NanoStateManager.addBeforeUpdateCallbacks(_baseBeforeUpdateCallbacks);
+ NanoStateManager.addAfterUpdateCallbacks(_baseAfterUpdateCallbacks);
+ },
+ removeCallbacks: function () {
+ for (var callbackKey in _baseBeforeUpdateCallbacks)
+ {
+ if (_baseBeforeUpdateCallbacks.hasOwnProperty(callbackKey))
+ {
+ NanoStateManager.removeBeforeUpdateCallback(callbackKey);
+ }
+ }
+ for (var callbackKey in _baseAfterUpdateCallbacks)
+ {
+ if (_baseAfterUpdateCallbacks.hasOwnProperty(callbackKey))
+ {
+ NanoStateManager.removeAfterUpdateCallback(callbackKey);
+ }
+ }
+ }
+ };
+} ();
+
+
+
+
+
+
+
diff --git a/nano/js/nano_base_helpers.js b/nano/js/nano_base_helpers.js
index ed3ce322..c9a19067 100644
--- a/nano/js/nano_base_helpers.js
+++ b/nano/js/nano_base_helpers.js
@@ -1,21 +1,8 @@
// NanoBaseHelpers is where the base template helpers (common to all templates) are stored
NanoBaseHelpers = function ()
{
- var _urlParameters = {}; // This is populated with the base url parameters (used by all links), which is probaby just the "src" parameter
-
- var init = function ()
- {
- var body = $('body'); // We store data in the body tag, it's as good a place as any
-
- _urlParameters = body.data('urlParameters');
-
- initHelpers();
- };
-
- var initHelpers = function ()
- {
- $.views.helpers({
-
+ var _baseHelpers = {
+ // change ui styling to "syndicate mode"
syndicateMode: function() {
$('body').css("background-color","#8f1414");
$('body').css("background-image","url('uiBackground-Syndicate.png')");
@@ -26,9 +13,8 @@ NanoBaseHelpers = function ()
$('#uiTitleFluff').css("background-position","50% 50%");
$('#uiTitleFluff').css("background-repeat", "no-repeat");
- return '';
+ return '';
},
-
// Generate a Byond link
link: function( text, icon, parameters, status, elementClass, elementId) {
@@ -42,7 +28,7 @@ NanoBaseHelpers = function ()
if (typeof elementClass == 'undefined' || !elementClass)
{
- elementClass = '';
+ elementClass = 'link';
}
var elementIdHtml = '';
@@ -56,7 +42,7 @@ NanoBaseHelpers = function ()
return '
' + iconHtml + text + '
';
}
- return '
' + iconHtml + text + '
';
+ return '
' + iconHtml + text + '
';
},
// Round a number to the nearest integer
round: function(number) {
@@ -91,12 +77,12 @@ NanoBaseHelpers = function ()
}
return '';
},
- formatNumber: function(x) {
- // From http://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
- var parts = x.toString().split(".");
- parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
- return parts.join(".");
- },
+ formatNumber: function(x) {
+ // From http://stackoverflow.com/questions/2901102/how-to-print-a-number-with-commas-as-thousands-separators-in-javascript
+ var parts = x.toString().split(".");
+ parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+ return parts.join(".");
+ },
// Display a bar. Used to show health, capacity, etc.
displayBar: function(value, rangeMin, rangeMax, styleClass, showText) {
@@ -172,7 +158,7 @@ NanoBaseHelpers = function ()
status = 'selected';
}
- html += '
' + characters[index] + '
'
+ html += '
' + characters[index] + '
'
index++;
if (index % blockSize == 0 && index < characters.length)
@@ -191,52 +177,26 @@ NanoBaseHelpers = function ()
return html;
}
- });
- };
-
- // generate a Byond href, combines _urlParameters with parameters
- var generateHref = function (parameters)
- {
- var queryString = '?';
-
- for (var key in _urlParameters)
- {
- if (_urlParameters.hasOwnProperty(key))
- {
- if (queryString !== '?')
- {
- queryString += ';';
- }
- queryString += key + '=' + _urlParameters[key];
- }
- }
-
- for (var key in parameters)
- {
- if (parameters.hasOwnProperty(key))
- {
- if (queryString !== '?')
- {
- queryString += ';';
- }
- queryString += key + '=' + parameters[key];
- }
- }
- return queryString;
- };
-
+ };
+
return {
- init: function ()
+ addHelpers: function ()
{
- init();
+ NanoTemplate.addHelpers(_baseHelpers);
+ },
+ removeHelpers: function ()
+ {
+ for (var helperKey in _baseHelpers)
+ {
+ if (_baseHelpers.hasOwnProperty(helperKey))
+ {
+ NanoTemplate.removeHelper(helperKey);
+ }
+ }
}
};
} ();
-
-$(document).ready(function()
-{
- NanoBaseHelpers.init();
-});
+
diff --git a/nano/js/nano_state.js b/nano/js/nano_state.js
new file mode 100644
index 00000000..198fa451
--- /dev/null
+++ b/nano/js/nano_state.js
@@ -0,0 +1,121 @@
+// This is the base state class, it is not to be used directly
+
+function NanoStateClass() {
+ /*if (typeof this.key != 'string' || !this.key.length)
+ {
+ alert('ERROR: Tried to create a state with an invalid state key: ' + this.key);
+ return;
+ }
+
+ this.key = this.key.toLowerCase();
+
+ NanoStateManager.addState(this);*/
+}
+
+NanoStateClass.prototype.key = null;
+NanoStateClass.prototype.layoutRendered = false;
+NanoStateClass.prototype.contentRendered = false;
+NanoStateClass.prototype.mapInitialised = false;
+
+NanoStateClass.prototype.isCurrent = function () {
+ return NanoStateManager.getCurrentState() == this;
+};
+
+NanoStateClass.prototype.onAdd = function (previousState) {
+ // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function
+
+ NanoBaseCallbacks.addCallbacks();
+ NanoBaseHelpers.addHelpers();
+};
+
+NanoStateClass.prototype.onRemove = function (nextState) {
+ // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function
+
+ NanoBaseCallbacks.removeCallbacks();
+ NanoBaseHelpers.removeHelpers();
+};
+
+NanoStateClass.prototype.onBeforeUpdate = function (data) {
+ // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function
+
+ data = NanoStateManager.executeBeforeUpdateCallbacks(data);
+
+ return data; // Return data to continue, return false to prevent onUpdate and onAfterUpdate
+};
+
+NanoStateClass.prototype.onUpdate = function (data) {
+ // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function
+
+ try
+ {
+ if (!this.layoutRendered || (data['config'].hasOwnProperty('autoUpdateLayout') && data['config']['autoUpdateLayout']))
+ {
+ $("#uiLayout").html(NanoTemplate.parse('layout', data)); // render the 'mail' template to the #mainTemplate div
+ this.layoutRendered = true;
+ }
+ if (!this.contentRendered || (data['config'].hasOwnProperty('autoUpdateContent') && data['config']['autoUpdateContent']))
+ {
+ $("#uiContent").html(NanoTemplate.parse('main', data)); // render the 'mail' template to the #mainTemplate div
+ this.contentRendered = true;
+ }
+ if (NanoTemplate.templateExists('mapContent'))
+ {
+ if (!this.mapInitialised)
+ {
+ // Add drag functionality to the map ui
+ $('#uiMap').draggable({
+ handle : '#uiMapImage'
+ });
+
+ $('#uiMapTooltip')
+ .off('click')
+ .on('click', function (event) {
+ event.preventDefault();
+ $(this).fadeOut(400);
+ });
+
+ this.mapInitialised = true;
+ }
+
+ $("#uiMapContent").html(NanoTemplate.parse('mapContent', data)); // render the 'mapContent' template to the #uiMapContent div
+
+ if (data['config'].hasOwnProperty('showMap') && data['config']['showMap'])
+ {
+ $('#uiContent').addClass('hidden');
+ $('#uiMapWrapper').removeClass('hidden');
+ }
+ else
+ {
+ $('#uiMapWrapper').addClass('hidden');
+ $('#uiContent').removeClass('hidden');
+ }
+ }
+ if (NanoTemplate.templateExists('mapHeader'))
+ {
+ $("#uiMapHeader").html(NanoTemplate.parse('mapHeader', data)); // render the 'mapHeader' template to the #uiMapHeader div
+ }
+ if (NanoTemplate.templateExists('mapFooter'))
+ {
+ $("#uiMapFooter").html(NanoTemplate.parse('mapFooter', data)); // render the 'mapFooter' template to the #uiMapFooter div
+ }
+ }
+ catch(error)
+ {
+ alert('ERROR: An error occurred while rendering the UI: ' + error.message);
+ return;
+ }
+};
+
+NanoStateClass.prototype.onAfterUpdate = function (data) {
+ // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function
+
+ NanoStateManager.executeAfterUpdateCallbacks(data);
+};
+
+NanoStateClass.prototype.alertText = function (text) {
+ // Do not add code here, add it to the 'default' state (nano_state_defaut.js) or create a new state and override this function
+
+ alert(text);
+};
+
+
diff --git a/nano/js/nano_state_default.js b/nano/js/nano_state_default.js
new file mode 100644
index 00000000..65493b8c
--- /dev/null
+++ b/nano/js/nano_state_default.js
@@ -0,0 +1,14 @@
+
+NanoStateDefaultClass.inheritsFrom(NanoStateClass);
+var NanoStateDefault = new NanoStateDefaultClass();
+
+function NanoStateDefaultClass() {
+
+ this.key = 'default';
+
+ //this.parent.constructor.call(this);
+
+ this.key = this.key.toLowerCase();
+
+ NanoStateManager.addState(this);
+}
\ No newline at end of file
diff --git a/nano/js/nano_state_manager.js b/nano/js/nano_state_manager.js
new file mode 100644
index 00000000..84de1d1c
--- /dev/null
+++ b/nano/js/nano_state_manager.js
@@ -0,0 +1,220 @@
+// NanoStateManager handles data from the server and uses it to render templates
+NanoStateManager = function ()
+{
+ // _isInitialised is set to true when all of this ui's templates have been processed/rendered
+ var _isInitialised = false;
+
+ // the data for this ui
+ var _data = null;
+
+ // this is an array of callbacks which are called when new data arrives, before it is processed
+ var _beforeUpdateCallbacks = {};
+ // this is an array of callbacks which are called when new data arrives, before it is processed
+ var _afterUpdateCallbacks = {};
+
+ // this is an array of state objects, these can be used to provide custom javascript logic
+ var _states = {};
+
+ var _currentState = null;
+
+ // the init function is called when the ui has loaded
+ // this function sets up the templates and base functionality
+ var init = function ()
+ {
+ // We store initialData and templateData in the body tag, it's as good a place as any
+ _data = $('body').data('initialData');
+
+ if (_data == null || !_data.hasOwnProperty('config') || !_data.hasOwnProperty('data'))
+ {
+ alert('Error: Initial data did not load correctly.');
+ }
+
+ var stateKey = 'default';
+ if (_data['config'].hasOwnProperty('stateKey') && _data['config']['stateKey'])
+ {
+ stateKey = _data['config']['stateKey'].toLowerCase();
+ }
+
+ NanoStateManager.setCurrentState(stateKey);
+
+ $(document).on('templatesLoaded', function () {
+ doUpdate(_data);
+
+ _isInitialised = true;
+ });
+ };
+
+ // Receive update data from the server
+ var receiveUpdateData = function (jsonString)
+ {
+ var updateData;
+ try
+ {
+ // parse the JSON string from the server into a JSON object
+ updateData = jQuery.parseJSON(jsonString);
+ }
+ catch (error)
+ {
+ alert(error.Message);
+ return;
+ }
+
+ if (!updateData.hasOwnProperty('data'))
+ {
+ if (_data && _data.hasOwnProperty('data'))
+ {
+ updateData['data'] = _data['data'];
+ }
+ else
+ {
+ updateData['data'] = {};
+ }
+ }
+
+ if (_isInitialised) // all templates have been registered, so render them
+ {
+ doUpdate(updateData);
+ }
+ else
+ {
+ _data = updateData; // all templates have not been registered. We set _data directly here which will be applied after the template is loaded with the initial data
+ }
+ };
+
+ // This function does the update by calling the methods on the current state
+ var doUpdate = function (data)
+ {
+ if (_currentState == null)
+ {
+ return;
+ }
+
+ data = _currentState.onBeforeUpdate(data);
+
+ if (data === false)
+ {
+ alert('data is false, return');
+ return; // A beforeUpdateCallback returned a false value, this prevents the render from occuring
+ }
+
+ _data = data;
+
+ _currentState.onUpdate(_data);
+
+ _currentState.onAfterUpdate(_data);
+ };
+
+ // Execute all callbacks in the callbacks array/object provided, updateData is passed to them for processing and potential modification
+ var executeCallbacks = function (callbacks, data)
+ {
+ for (var key in callbacks)
+ {
+ if (callbacks.hasOwnProperty(key) && jQuery.isFunction(callbacks[key]))
+ {
+ data = callbacks[key].call(this, data);
+ }
+ }
+
+ return data;
+ };
+
+ return {
+ init: function ()
+ {
+ init();
+ },
+ receiveUpdateData: function (jsonString)
+ {
+ receiveUpdateData(jsonString);
+ },
+ addBeforeUpdateCallback: function (key, callbackFunction)
+ {
+ _beforeUpdateCallbacks[key] = callbackFunction;
+ },
+ addBeforeUpdateCallbacks: function (callbacks) {
+ for (var callbackKey in callbacks) {
+ if (!callbacks.hasOwnProperty(callbackKey))
+ {
+ continue;
+ }
+ NanoStateManager.addBeforeUpdateCallback(callbackKey, callbacks[callbackKey]);
+ }
+ },
+ removeBeforeUpdateCallback: function (key)
+ {
+ if (_beforeUpdateCallbacks.hasOwnProperty(key))
+ {
+ delete _beforeUpdateCallbacks[key];
+ }
+ },
+ executeBeforeUpdateCallbacks: function (data) {
+ return executeCallbacks(_beforeUpdateCallbacks, data);
+ },
+ addAfterUpdateCallback: function (key, callbackFunction)
+ {
+ _afterUpdateCallbacks[key] = callbackFunction;
+ },
+ addAfterUpdateCallbacks: function (callbacks) {
+ for (var callbackKey in callbacks) {
+ if (!callbacks.hasOwnProperty(callbackKey))
+ {
+ continue;
+ }
+ NanoStateManager.addAfterUpdateCallback(callbackKey, callbacks[callbackKey]);
+ }
+ },
+ removeAfterUpdateCallback: function (key)
+ {
+ if (_afterUpdateCallbacks.hasOwnProperty(key))
+ {
+ delete _afterUpdateCallbacks[key];
+ }
+ },
+ executeAfterUpdateCallbacks: function (data) {
+ return executeCallbacks(_afterUpdateCallbacks, data);
+ },
+ addState: function (state)
+ {
+ if (!(state instanceof NanoStateClass))
+ {
+ alert('ERROR: Attempted to add a state which is not instanceof NanoStateClass');
+ return;
+ }
+ if (!state.key)
+ {
+ alert('ERROR: Attempted to add a state with an invalid stateKey');
+ return;
+ }
+ _states[state.key] = state;
+ },
+ setCurrentState: function (stateKey)
+ {
+ if (typeof stateKey == 'undefined' || !stateKey) {
+ alert('ERROR: No state key was passed!');
+ return false;
+ }
+ if (!_states.hasOwnProperty(stateKey))
+ {
+ alert('ERROR: Attempted to set a current state which does not exist: ' + stateKey);
+ return false;
+ }
+
+ var previousState = _currentState;
+
+ _currentState = _states[stateKey];
+
+ if (previousState != null) {
+ previousState.onRemove(_currentState);
+ }
+
+ _currentState.onAdd(previousState);
+
+ return true;
+ },
+ getCurrentState: function ()
+ {
+ return _currentState;
+ }
+ };
+} ();
+
\ No newline at end of file
diff --git a/nano/js/nano_template.js b/nano/js/nano_template.js
new file mode 100644
index 00000000..f8f5d265
--- /dev/null
+++ b/nano/js/nano_template.js
@@ -0,0 +1,135 @@
+
+var NanoTemplate = function () {
+
+ var _templateData = {};
+
+ var _templates = {};
+ var _compiledTemplates = {};
+
+ var _helpers = {};
+
+ var init = function () {
+ // We store templateData in the body tag, it's as good a place as any
+ _templateData = $('body').data('templateData');
+
+ if (_templateData == null)
+ {
+ alert('Error: Template data did not load correctly.');
+ }
+
+ loadNextTemplate();
+ };
+
+ var loadNextTemplate = function () {
+ // we count the number of templates for this ui so that we know when they've all been rendered
+ var templateCount = Object.size(_templateData);
+
+ if (!templateCount)
+ {
+ $(document).trigger('templatesLoaded');
+ return;
+ }
+
+ // load markup for each template and register it
+ for (var key in _templateData)
+ {
+ if (!_templateData.hasOwnProperty(key))
+ {
+ continue;
+ }
+
+ $.when($.ajax({
+ url: _templateData[key],
+ cache: false,
+ dataType: 'text'
+ }))
+ .done(function(templateMarkup) {
+
+ templateMarkup += '
';
+
+ try
+ {
+ NanoTemplate.addTemplate(key, templateMarkup);
+ }
+ catch(error)
+ {
+ alert('ERROR: An error occurred while loading the UI: ' + error.message);
+ return;
+ }
+
+ delete _templateData[key];
+
+ loadNextTemplate();
+ })
+ .fail(function () {
+ alert('ERROR: Loading template ' + key + '(' + _templateData[key] + ') failed!');
+ });
+
+ return;
+ }
+ }
+
+ var compileTemplates = function () {
+
+ for (var key in _templates) {
+ try {
+ _compiledTemplates[key] = doT.template(_templates[key], null, _templates)
+ }
+ catch (error) {
+ alert(error.message);
+ }
+ }
+ };
+
+ return {
+ init: function () {
+ init();
+ },
+ addTemplate: function (key, templateString) {
+ _templates[key] = templateString;
+ },
+ templateExists: function (key) {
+ return _templates.hasOwnProperty(key);
+ },
+ parse: function (templateKey, data) {
+ if (!_compiledTemplates.hasOwnProperty(templateKey) || !_compiledTemplates[templateKey]) {
+ if (!_templates.hasOwnProperty(templateKey)) {
+ alert('ERROR: Template "' + templateKey + '" does not exist in _compiledTemplates!');
+ return '
Template error (does not exist)
';
+ }
+ compileTemplates();
+ }
+ if (typeof _compiledTemplates[templateKey] != 'function') {
+ alert(_compiledTemplates[templateKey]);
+ alert('ERROR: Template "' + templateKey + '" failed to compile!');
+ return '
Template error (failed to compile)
';
+ }
+ return _compiledTemplates[templateKey].call(this, data['data'], data['config'], _helpers);
+ },
+ addHelper: function (helperName, helperFunction) {
+ if (!jQuery.isFunction(helperFunction)) {
+ alert('NanoTemplate.addHelper failed to add ' + helperName + ' as it is not a function.');
+ return;
+ }
+
+ _helpers[helperName] = helperFunction;
+ },
+ addHelpers: function (helpers) {
+ for (var helperName in helpers) {
+ if (!helpers.hasOwnProperty(helperName))
+ {
+ continue;
+ }
+ NanoTemplate.addHelper(helperName, helpers[helperName]);
+ }
+ },
+ removeHelper: function (helperName) {
+ if (helpers.hasOwnProperty(helperName))
+ {
+ delete _helpers[helperName];
+ }
+ }
+ }
+}();
+
+
diff --git a/nano/js/nano_utility.js b/nano/js/nano_utility.js
new file mode 100644
index 00000000..59a4b2a2
--- /dev/null
+++ b/nano/js/nano_utility.js
@@ -0,0 +1,161 @@
+// NanoUtility is the place to store utility functions
+var NanoUtility = function ()
+{
+ var _urlParameters = {}; // This is populated with the base url parameters (used by all links), which is probaby just the "src" parameter
+
+ return {
+ init: function ()
+ {
+ var body = $('body'); // We store data in the body tag, it's as good a place as any
+
+ _urlParameters = body.data('urlParameters');
+ },
+ // generate a Byond href, combines _urlParameters with parameters
+ generateHref: function (parameters)
+ {
+ var queryString = '?';
+
+ for (var key in _urlParameters)
+ {
+ if (_urlParameters.hasOwnProperty(key))
+ {
+ if (queryString !== '?')
+ {
+ queryString += ';';
+ }
+ queryString += key + '=' + _urlParameters[key];
+ }
+ }
+
+ for (var key in parameters)
+ {
+ if (parameters.hasOwnProperty(key))
+ {
+ if (queryString !== '?')
+ {
+ queryString += ';';
+ }
+ queryString += key + '=' + parameters[key];
+ }
+ }
+ return queryString;
+ }
+ }
+} ();
+
+if (typeof jQuery == 'undefined') {
+ alert('ERROR: Javascript library failed to load!');
+}
+if (typeof doT == 'undefined') {
+ alert('ERROR: Template engine failed to load!');
+}
+
+// All scripts are initialised here, this allows control of init order
+$(document).ready(function () {
+ NanoUtility.init();
+ NanoStateManager.init();
+ NanoTemplate.init();
+});
+
+if (!Array.prototype.indexOf)
+{
+ Array.prototype.indexOf = function(elt /*, from*/)
+ {
+ var len = this.length;
+
+ var from = Number(arguments[1]) || 0;
+ from = (from < 0)
+ ? Math.ceil(from)
+ : Math.floor(from);
+ if (from < 0)
+ from += len;
+
+ for (; from < len; from++)
+ {
+ if (from in this &&
+ this[from] === elt)
+ return from;
+ }
+ return -1;
+ };
+};
+
+if (!String.prototype.format)
+{
+ String.prototype.format = function (args) {
+ var str = this;
+ return str.replace(String.prototype.format.regex, function(item) {
+ var intVal = parseInt(item.substring(1, item.length - 1));
+ var replace;
+ if (intVal >= 0) {
+ replace = args[intVal];
+ } else if (intVal === -1) {
+ replace = "{";
+ } else if (intVal === -2) {
+ replace = "}";
+ } else {
+ replace = "";
+ }
+ return replace;
+ });
+ };
+ String.prototype.format.regex = new RegExp("{-?[0-9]+}", "g");
+};
+
+Object.size = function(obj) {
+ var size = 0, key;
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) size++;
+ }
+ return size;
+};
+
+if(!window.console) {
+ window.console = {
+ log : function(str) {
+ return false;
+ }
+ };
+};
+
+String.prototype.toTitleCase = function () {
+ var smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|vs?\.?|via)$/i;
+
+ return this.replace(/([^\W_]+[^\s-]*) */g, function (match, p1, index, title) {
+ if (index > 0 && index + p1.length !== title.length &&
+ p1.search(smallWords) > -1 && title.charAt(index - 2) !== ":" &&
+ title.charAt(index - 1).search(/[^\s-]/) < 0) {
+ return match.toLowerCase();
+ }
+
+ if (p1.substr(1).search(/[A-Z]|\../) > -1) {
+ return match;
+ }
+
+ return match.charAt(0).toUpperCase() + match.substr(1);
+ });
+};
+
+$.ajaxSetup({
+ cache: false
+});
+
+Function.prototype.inheritsFrom = function (parentClassOrObject) {
+ this.prototype = new parentClassOrObject;
+ this.prototype.constructor = this;
+ this.prototype.parent = parentClassOrObject.prototype;
+ return this;
+};
+
+if (!String.prototype.trim) {
+ String.prototype.trim = function () {
+ return this.replace(/^\s+|\s+$/g, '');
+ };
+}
+
+// Replicate the ckey proc from BYOND
+if (!String.prototype.ckey) {
+ String.prototype.ckey = function () {
+ return this.replace(/\W/g, '').toLowerCase();
+ };
+}
\ No newline at end of file
diff --git a/nano/mapbase1024.png b/nano/mapbase1024.png
new file mode 100644
index 00000000..a927a71b
Binary files /dev/null and b/nano/mapbase1024.png differ
diff --git a/nano/templates/advanced_airlock_console.tmpl b/nano/templates/advanced_airlock_console.tmpl
index 7f886657..1558f4a2 100644
--- a/nano/templates/advanced_airlock_console.tmpl
+++ b/nano/templates/advanced_airlock_console.tmpl
@@ -4,9 +4,9 @@
External Pressure:
- {{:~displayBar(external_pressure, 0, 200, external_pressure < 80 || external_pressure > 120 ? 'bad' : external_pressure < 95 || external_pressure > 110 ? 'average' : 'good')}}
+ {{:helper.displayBar(data.external_pressure, 0, 200, (data.external_pressure < 80 || data.external_pressure > 120) ? 'bad' : (data.external_pressure < 95 || data.external_pressure > 110) ? 'average' : 'good')}}
- {{:external_pressure}} kPa
+ {{:data.external_pressure}} kPa
@@ -15,9 +15,9 @@
Chamber Pressure:
- {{:~displayBar(chamber_pressure, 0, 200, chamber_pressure < 80 || chamber_pressure > 120 ? 'bad' : chamber_pressure < 95 || chamber_pressure > 110 ? 'average' : 'good')}}
+ {{:helper.displayBar(data.chamber_pressure, 0, 200, (data.chamber_pressure < 80 || data.chamber_pressure > 120) ? 'bad' : (data.chamber_pressure < 95 || data.chamber_pressure > 110) ? 'average' : 'good')}}
- {{:chamber_pressure}} kPa
+ {{:data.chamber_pressure}} kPa
@@ -26,9 +26,9 @@
Internal Pressure:
- {{:~displayBar(internal_pressure, 0, 200, internal_pressure < 80 || internal_pressure > 120 ? 'bad' : internal_pressure < 95 || internal_pressure > 110 ? 'average' : 'good')}}
+ {{:helper.displayBar(data.internal_pressure, 0, 200, (data.internal_pressure < 80 || data.internal_pressure > 120) ? 'bad' : (data.internal_pressure < 95 || data.internal_pressure > 110) ? 'average' : 'good')}}
- {{:internal_pressure}} kPa
+ {{:data.internal_pressure}} kPa
@@ -36,25 +36,25 @@
- {{:~link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, processing ? 'disabled' : null)}}
- {{:~link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, processing ? 'disabled' : null)}}
+ {{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, data.processing ? 'disabled' : null)}}
+ {{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, data.processing ? 'disabled' : null)}}
- {{:~link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, processing ? 'yellowBackground' : null)}}
- {{:~link('Force interior door', 'alert', {'command' : 'force_int'}, null, processing ? 'yellowBackground' : null)}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, data.processing ? null : null)}}
+ {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, data.processing ? null : null)}}
- {{:~link('Purge', 'refresh', {'command' : 'purge'}, processing ? 'disabled' : null, purge ? 'linkOn' : null)}}
+ {{:helper.link('Purge', 'refresh', {'command' : 'purge'}, data.processing ? 'disabled' : null, data.purge ? 'linkOn' : null)}}
- {{:~link('Secure', secure ? 'locked' : 'unlocked', {'command' : 'secure'}, processing ? 'disabled' : null, secure ? 'linkOn' : null)}}
+ {{:helper.link('Secure', data.secure ? 'locked' : 'unlocked', {'command' : 'secure'}, data.processing ? 'disabled' : null, data.secure ? 'linkOn' : null)}}
- {{:~link('Abort', 'cancel', {'command' : 'abort'}, processing ? null : 'disabled', processing ? 'redBackground' : null)}}
+ {{:helper.link('Abort', 'cancel', {'command' : 'abort'}, data.processing ? null : 'disabled', data.processing ? 'redBackground' : null)}}
\ No newline at end of file
diff --git a/nano/templates/apc.tmpl b/nano/templates/apc.tmpl
index 82dc2175..d635f6d6 100644
--- a/nano/templates/apc.tmpl
+++ b/nano/templates/apc.tmpl
@@ -1,17 +1,17 @@
- {{if siliconUser}}
+ {{if data.siliconUser}}
Interface Lock:
- {{:~link('Engaged', 'locked', {'toggleaccess' : 1}, locked ? 'selected' : null)}}{{:~link('Disengaged', 'unlocked', {'toggleaccess' : 1}, malfStatus >= 2 ? 'linkOff' : (locked ? null : 'selected'))}}
+ {{:helper.link('Engaged', 'locked', {'toggleaccess' : 1}, data.locked ? 'selected' : null)}}{{:helper.link('Disengaged', 'unlocked', {'toggleaccess' : 1}, data.malfStatus >= 2 ? 'linkOff' : (data.locked ? null : 'selected'))}}
{{else}}
- {{if locked}}
- Swipe an ID card to unlock this interface.
+ {{if data.locked}}
+ Swipe an ID card to unlock this interface
{{else}}
- Swipe an ID card to lock this interface.
+ Swipe an ID card to lock this interface
{{/if}}
{{/if}}
@@ -25,14 +25,14 @@
Main Breaker:
- {{if locked && !siliconUser}}
- {{if isOperating}}
+ {{if data.locked && !data.siliconUser}}
+ {{if data.isOperating}}
On
{{else}}
Off
{{/if}}
{{else}}
- {{:~link('On', 'power', {'breaker' : 1}, isOperating ? 'selected' : null)}}{{:~link('Off', 'close', {'breaker' : 1}, isOperating ? null : 'selected')}}
+ {{:helper.link('On', 'power', {'breaker' : 1}, data.isOperating ? 'selected' : null)}}{{:helper.link('Off', 'close', {'breaker' : 1}, data.isOperating ? null : 'selected')}}
{{/if}}
@@ -42,9 +42,9 @@
External Power:
- {{if externalPower == 2}}
+ {{if data.externalPower == 2}}
Good
- {{else externalPower == 1}}
+ {{else data.externalPower == 1}}
Low
{{else}}
None
@@ -56,38 +56,38 @@
Power Cell:
- {{if powerCellStatus == null}}
+ {{if data.powerCellStatus == null}}
Power cell removed.
{{else}}
- {{:~displayBar(powerCellStatus, 0, 100, powerCellStatus >= 50 ? 'good' : powerCellStatus >= 25 ? 'average' : 'bad')}}
+ {{:helper.displayBar(data.powerCellStatus, 0, 100, (data.powerCellStatus >= 50) ? 'good' : (data.powerCellStatus >= 25) ? 'average' : 'bad')}}
- {{:~round(powerCellStatus*10)/10}}%
+ {{:helper.round(data.powerCellStatus*10)/10}}%
{{/if}}
- {{if powerCellStatus != null}}
+ {{if data.powerCellStatus != null}}
Charge Mode:
- {{if locked && !siliconUser}}
- {{if chargeMode}}
+ {{if data.locked && !data.siliconUser}}
+ {{if data.chargeMode}}
Auto
{{else}}
Off
{{/if}}
{{else}}
- {{:~link('Auto', 'refresh', {'cmode' : 1}, chargeMode ? 'selected' : null)}}{{:~link('Off', 'close', {'cmode' : 1}, chargeMode ? null : 'selected')}}
+ {{:helper.link('Auto', 'refresh', {'cmode' : 1}, data.chargeMode ? 'selected' : null)}}{{:helper.link('Off', 'close', {'cmode' : 1}, data.chargeMode ? null : 'selected')}}
{{/if}}
- {{if chargingStatus > 1}}
+ {{if data.chargingStatus > 1}}
[
Fully Charged]
- {{else chargingStatus == 1}}
+ {{else data.chargingStatus == 1}}
[
Charging]
{{else}}
[
Not Charging]
@@ -99,32 +99,34 @@
Power Channels
- {{for powerChannels}}
+ {{for data.powerChannels}}
- {{:title}}:
+ {{:value.title}}:
- {{:powerLoad}} W
+ {{:value.powerLoad}} W
- {{if status <= 1}}
+ {{if value.status <= 1}}
Off
- {{else status >= 2}}
+ {{else value.status >= 2}}
On
{{/if}}
- {{if status == 1 || status == 3}}
- [Auto]
- {{else}}
- [Manual]
- {{/if}}
+ {{if data.locked}}
+ {{if value.status == 1 || value.status == 3}}
+ Auto
+ {{else}}
+ Manual
+ {{/if}}
+ {{/if}}
- {{if !~root.locked || ~root.siliconUser}}
+ {{if !data.locked || data.siliconUser}}
- {{:~link('Auto', 'refresh', topicParams.auto, (status == 1 || status == 3) ? 'selected' : null)}}
- {{:~link('On', 'power', topicParams.on, (status == 2) ? 'selected' : null)}}
- {{:~link('Off', 'close', topicParams.off, (status == 0) ? 'selected' : null)}}
+ {{:helper.link('Auto', 'refresh', value.topicParams.auto, (value.status == 1 || value.status == 3) ? 'selected' : null)}}
+ {{:helper.link('On', 'power', value.topicParams.on, (value.status == 2) ? 'selected' : null)}}
+ {{:helper.link('Off', 'close', value.topicParams.off, (value.status == 0) ? 'selected' : null)}}
{{/if}}
@@ -134,8 +136,8 @@
Total Load:
-
- {{:totalLoad}} W
+
+ {{:data.totalLoad}} W
@@ -146,26 +148,26 @@
Cover Lock:
- {{if locked && !siliconUser}}
- {{if coverLocked}}
+ {{if data.locked && !data.siliconUser}}
+ {{if data.coverLocked}}
Engaged
{{else}}
Disengaged
{{/if}}
{{else}}
- {{:~link('Engaged', 'locked', {'lock' : 1}, coverLocked ? 'selected' : null)}}{{:~link('Disengaged', 'unlocked', {'lock' : 1}, coverLocked ? null : 'selected')}}
+ {{:helper.link('Engaged', 'locked', {'lock' : 1}, data.coverLocked ? 'selected' : null)}}{{:helper.link('Disengaged', 'unlocked', {'lock' : 1}, data.coverLocked ? null : 'selected')}}
{{/if}}
- {{if siliconUser}}
+ {{if data.siliconUser}}
System Overrides
- {{:~link('Overload Lighting Circuit', 'lightbulb', {'overload' : 1})}}
- {{if malfStatus == 1}}
- {{:~link('Override Programming', 'script', {'malfhack' : 1})}}
- {{else malfStatus > 1}}
+ {{:helper.link('Overload Lighting Circuit', 'lightbulb', {'overload' : 1})}}
+ {{if data.malfStatus == 1}}
+ {{:helper.link('Override Programming', 'script', {'malfhack' : 1})}}
+ {{else data.malfStatus > 1}}
APC Hacked
{{/if}}
diff --git a/nano/templates/canister.tmpl b/nano/templates/canister.tmpl
index 3bd69a4a..e4033eb0 100644
--- a/nano/templates/canister.tmpl
+++ b/nano/templates/canister.tmpl
@@ -3,8 +3,8 @@
Tank Label:
-
-
{{:name}}
{{:~link('Relabel', 'pencil', {'relabel' : 1}, (canLabel) ? null : 'disabled')}}
+
+
{{:data.name}}
{{:helper.link('Relabel', 'pencil', {'relabel' : 1}, data.canLabel ? null : 'disabled')}}
@@ -12,8 +12,8 @@
Tank Pressure:
-
- {{:tankPressure}} kPa
+
+ {{:data.tankPressure}} kPa
@@ -21,19 +21,19 @@
Port Status:
-
- {{:portConnected ? '
Connected' : '
Disconnected'}}
+
+ {{:data.portConnected ? 'Connected' : 'Disconnected'}}
Holding Tank Status
-{{if hasHoldingTank}}
+{{if data.hasHoldingTank}}
Tank Label:
-
-
{{:holdingTank.name}}
{{:~link('Eject', 'eject', {'remove_tank' : 1})}}
+
+
{{:data.holdingTank.name}}
{{:helper.link('Eject', 'eject', {'remove_tank' : 1})}}
@@ -41,11 +41,11 @@
Tank Pressure:
-
- {{:holdingTank.tankPressure}} kPa
+
+ {{:data.holdingTank.tankPressure}} kPa
-{{else}}
+{{else}}
No holding tank inserted.
{{/if}}
@@ -57,17 +57,17 @@
Release Pressure:
- {{:~displayBar(releasePressure, minReleasePressure, maxReleasePressure)}}
+ {{:helper.displayBar(data.releasePressure, data.minReleasePressure, data.maxReleasePressure)}}
- {{:~link('-', null, {'pressure_adj' : -1000}, (releasePressure > minReleasePressure) ? null : 'disabled')}}
- {{:~link('-', null, {'pressure_adj' : -100}, (releasePressure > minReleasePressure) ? null : 'disabled')}}
- {{:~link('-', null, {'pressure_adj' : -10}, (releasePressure > minReleasePressure) ? null : 'disabled')}}
- {{:~link('-', null, {'pressure_adj' : -1}, (releasePressure > minReleasePressure) ? null : 'disabled')}}
-
{{:releasePressure}} kPa
- {{:~link('+', null, {'pressure_adj' : 1}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
- {{:~link('+', null, {'pressure_adj' : 10}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
- {{:~link('+', null, {'pressure_adj' : 100}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
- {{:~link('+', null, {'pressure_adj' : 1000}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('-', null, {'pressure_adj' : -1000}, (data.releasePressure > data.minReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('-', null, {'pressure_adj' : -100}, (data.releasePressure > data.minReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('-', null, {'pressure_adj' : -10}, (data.releasePressure > data.minReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('-', null, {'pressure_adj' : -1}, (data.releasePressure > data.minReleasePressure) ? null : 'disabled')}}
+
{{:data.releasePressure}} kPa
+ {{:helper.link('+', null, {'pressure_adj' : 1}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('+', null, {'pressure_adj' : 10}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('+', null, {'pressure_adj' : 100}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('+', null, {'pressure_adj' : 1000}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}}
@@ -77,7 +77,7 @@
Release Valve:
- {{:~link('Open', 'unlocked', {'toggle' : 1}, valveOpen ? 'selected' : null)}}{{:~link('Close', 'locked', {'toggle' : 1}, valveOpen ? null : 'selected')}}
+ {{:helper.link('Open', 'unlocked', {'toggle' : 1}, data.valveOpen ? 'selected' : null)}}{{:helper.link('Close', 'locked', {'toggle' : 1}, data.valveOpen ? null : 'selected')}}
diff --git a/nano/templates/chem_dispenser.tmpl b/nano/templates/chem_dispenser.tmpl
index c2b5e62c..c19167af 100644
--- a/nano/templates/chem_dispenser.tmpl
+++ b/nano/templates/chem_dispenser.tmpl
@@ -7,7 +7,7 @@ Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm
Energy:
- {{:~displayBar(energy, 0, maxEnergy, 'good', energy + ' Units')}}
+ {{:helper.displayBar(data.energy, 0, data.maxEnergy, 'good', data.energy + ' Units')}}
@@ -16,17 +16,17 @@ Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm
Dispense:
- {{:~link('5', 'gear', {'amount' : 5}, (amount == 5) ? 'selected' : null)}}
- {{:~link('10', 'gear', {'amount' : 10}, (amount == 10) ? 'selected' : null)}}
- {{:~link('20', 'gear', {'amount' : 20}, (amount == 20) ? 'selected' : null)}}
- {{:~link('30', 'gear', {'amount' : 30}, (amount == 30) ? 'selected' : null)}}
- {{:~link('50', 'gear', {'amount' : 50}, (amount == 50) ? 'selected' : null)}}
+ {{:helper.link('5', 'gear', {'amount' : 5}, (data.amount == 5) ? 'selected' : null)}}
+ {{:helper.link('10', 'gear', {'amount' : 10}, (data.amount == 10) ? 'selected' : null)}}
+ {{:helper.link('20', 'gear', {'amount' : 20}, (data.amount == 20) ? 'selected' : null)}}
+ {{:helper.link('30', 'gear', {'amount' : 30}, (data.amount == 30) ? 'selected' : null)}}
+ {{:helper.link('40', 'gear', {'amount' : 40}, (data.amount == 40) ? 'selected' : null)}}
- {{if glass}}
+ {{if data.glass}}
Drink Dispenser
{{else}}
Chemical Dispenser
@@ -35,8 +35,8 @@ Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm
- {{for chemicals}}
- {{:~link(title, 'circle-arrow-s', commands, null, ~root.glass ? 'fixedLeftWide' : 'fixedLeft')}}
+ {{for data.chemicals}}
+ {{:helper.link(value.title, 'circle-arrow-s', value.commands, null, data.glass ? 'fixedLeftWide' : 'fixedLeft')}}
{{/for}}
@@ -44,39 +44,43 @@ Used In File(s): \code\modules\reagents\Chemistry-Machinery.dm
- {{if glass}}
+ {{if data.glass}}
Glass
{{else}}
Beaker
{{/if}} Contents
- {{:~link(glass ? 'Eject Glass' : 'Eject Beaker', 'eject', {'ejectBeaker' : 1}, isBeakerLoaded ? null : 'disabled', 'floatRight')}}
+ {{:helper.link(data.glass ? 'Eject Glass' : 'Eject Beaker', 'eject', {'ejectBeaker' : 1}, data.isBeakerLoaded ? null : 'disabled', 'floatRight')}}
-
+
- {{if isBeakerLoaded}}
- Volume: {{:beakerCurrentVolume}} / {{:beakerMaxVolume}}
- {{for beakerContents}}
- {{:volume}} units of {{:name}}
- {{else}}
+ {{if data.isBeakerLoaded}}
+ Volume: {{:data.beakerCurrentVolume}} / {{:data.beakerMaxVolume}}
+ {{for data.beakerContents}}
+ {{:value.volume}} units of {{:value.name}}
+ {{empty}}
- {{if glass}}
- Glass
- {{else}}
- Beaker
- {{/if}}
- is empty
+ {{if data.glass}}
+ Glass
+ {{else}}
+ Beaker
+ {{/if}}
+ is empty
+
{{/for}}
{{else}}
- No
- {{if glass}}
- Glass
- {{else}}
- Beaker
- {{/if}} loaded
+
+ No
+ {{if data.glass}}
+ Glass
+ {{else}}
+ Beaker
+ {{/if}}
+ loaded
+
{{/if}}
diff --git a/nano/templates/crew_monitor.tmpl b/nano/templates/crew_monitor.tmpl
new file mode 100644
index 00000000..db3e5673
--- /dev/null
+++ b/nano/templates/crew_monitor.tmpl
@@ -0,0 +1,16 @@
+
+{{:helper.link('Show Tracker Map', 'pin-s', {'showMap' : 1})}}
+
+ {{for data.crewmembers}}
+ {{if value.sensor_type == 1}}
+ | {{:value.name}} | {{:value.dead ? "Deceased" : "Living"}} | Not Available |
+ {{else value.sensor_type == 2}}
+ | {{:value.name}} | {{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}}) | Not Available |
+ {{else value.sensor_type == 3}}
+ | {{:value.name}} | {{:value.dead ? "Deceased" : "Living"}} ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}}) | {{:value.area}}({{:value.x}}, {{:value.y}}) |
+ {{/if}}
+ {{/for}}
+
\ No newline at end of file
diff --git a/nano/templates/crew_monitor_map_content.tmpl b/nano/templates/crew_monitor_map_content.tmpl
new file mode 100644
index 00000000..6e068825
--- /dev/null
+++ b/nano/templates/crew_monitor_map_content.tmpl
@@ -0,0 +1,16 @@
+
+{{for data.crewmembers}}
+ {{if value.sensor_type == 3}}
+
+
+ {{:value.name}} ({{:value.dead ? "Deceased" : "Living"}}) ({{:value.oxy}}/{{:value.tox}}/{{:value.fire}}/{{:value.brute}}) ({{:value.area}}: {{:value.x}}, {{:value.y}})
+
+
+ {{/if}}
+{{/for}}
+
+
+
\ No newline at end of file
diff --git a/nano/templates/crew_monitor_map_header.tmpl b/nano/templates/crew_monitor_map_header.tmpl
new file mode 100644
index 00000000..f9f5e2f7
--- /dev/null
+++ b/nano/templates/crew_monitor_map_header.tmpl
@@ -0,0 +1,12 @@
+
+{{:helper.link('Show Detail List', 'script', {'showMap' : 0})}}
+
+
Zoom Level:
+
x1.0
+
x1.5
+
x2.0
+
x2.5
+
\ No newline at end of file
diff --git a/nano/templates/cryo.tmpl b/nano/templates/cryo.tmpl
index c8c5610a..e8302b07 100644
--- a/nano/templates/cryo.tmpl
+++ b/nano/templates/cryo.tmpl
@@ -5,60 +5,62 @@ Used In File(s): \code\game\machinery\cryo.dm
Cryo Cell Status
- {{if !hasOccupant}}
+ {{if !data.hasOccupant}}
Cell Unoccupied
{{else}}
- {{:occupant.name}} =>
- {{if occupant.stat == 0}}
+ {{:data.occupant.name}} =>
+ {{if data.occupant.stat == 0}}
Conscious
- {{else occupant.stat == 1}}
+ {{else data.occupant.stat == 1}}
Unconscious
{{else}}
DEAD
{{/if}}
- {{if occupant.stat < 2}}
+ {{if data.occupant.stat < 2}}
Health:
- {{if occupant.health >= 0}}
- {{:~displayBar(occupant.health, 0, occupant.maxHealth, 'good')}}
+ {{if data.occupant.health >= 0}}
+ {{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, 'good')}}
{{else}}
- {{:~displayBar(occupant.health, 0, occupant.minHealth, 'average alignRight')}}
+ {{:helper.displayBar(data.occupant.health, 0, data.occupant.minHealth, 'average alignRight')}}
{{/if}}
-
{{:~round(occupant.health)}}
+
{{:helper.round(data.occupant.health)}}
=> Brute Damage:
- {{:~displayBar(occupant.bruteLoss, 0, occupant.maxHealth, 'bad')}}
-
{{:~round(occupant.bruteLoss)}}
+ {{:helper.displayBar(data.occupant.bruteLoss, 0, data.occupant.maxHealth, 'bad')}}
+
{{:helper.round(data.occupant.bruteLoss)}}
=> Resp. Damage:
- {{:~displayBar(occupant.oxyLoss, 0, occupant.maxHealth, 'bad')}}
-
{{:~round(occupant.oxyLoss)}}
+ {{:helper.displayBar(data.occupant.oxyLoss, 0, data.occupant.maxHealth, 'bad')}}
+
{{:helper.round(data.occupant.oxyLoss)}}
=> Toxin Damage:
- {{:~displayBar(occupant.toxLoss, 0, occupant.maxHealth, 'bad')}}
-
{{:~round(occupant.toxLoss)}}
+ {{:helper.displayBar(data.occupant.toxLoss, 0, data.occupant.maxHealth, 'bad')}}
+
{{:helper.round(data.occupant.toxLoss)}}
=> Burn Severity:
- {{:~displayBar(occupant.fireLoss, 0, occupant.maxHealth, 'bad')}}
-
{{:~round(occupant.fireLoss)}}
+ {{:helper.displayBar(data.occupant.fireLoss, 0, data.occupant.maxHealth, 'bad')}}
+
{{:helper.round(data.occupant.fireLoss)}}
{{/if}}
{{/if}}
-
Cell Temperature:
- {{:~string('{1} K', cellTemperatureStatus, cellTemperature)}}
-
+
+
Cell Temperature:
+ {{:data.cellTemperature}} K
+
+
Cryo Cell Operation
@@ -67,10 +69,10 @@ Used In File(s): \code\game\machinery\cryo.dm
Cryo Cell Status:
- {{:~link('On', 'power', {'switchOn' : 1}, isOperating ? 'selected' : null)}}{{:~link('Off', 'close', {'switchOff' : 1}, isOperating ? null : 'selected')}}
+ {{:helper.link('On', 'power', {'switchOn' : 1}, data.isOperating ? 'selected' : null)}}{{:helper.link('Off', 'close', {'switchOff' : 1}, data.isOperating ? null : 'selected')}}
- {{:~link('Eject Occupant', 'arrowreturnthick-1-s', {'ejectOccupant' : 1}, hasOccupant ? null : 'disabled')}}
+ {{:helper.link('Eject Occupant', 'arrowreturnthick-1-s', {'ejectOccupant' : 1}, data.hasOccupant ? null : 'disabled')}}
@@ -79,10 +81,10 @@ Used In File(s): \code\game\machinery\cryo.dm
Beaker:
- {{if isBeakerLoaded}}
- {{:beakerLabel ? beakerLabel : 'No label'}}
- {{if beakerVolume}}
- {{:beakerVolume}} units remaining
+ {{if data.isBeakerLoaded}}
+ {{:data.beakerLabel ? data.beakerLabel : 'No label'}}
+ {{if data.beakerVolume}}
+ {{:data.beakerVolume}} units remaining
{{else}}
Beaker is empty
{{/if}}
@@ -91,6 +93,6 @@ Used In File(s): \code\game\machinery\cryo.dm
{{/if}}
- {{:~link('Eject Beaker', 'eject', {'ejectBeaker' : 1}, isBeakerLoaded ? null : 'disabled')}}
+ {{:helper.link('Eject Beaker', 'eject', {'ejectBeaker' : 1}, data.isBeakerLoaded ? null : 'disabled')}}
\ No newline at end of file
diff --git a/nano/templates/disease_splicer.tmpl b/nano/templates/disease_splicer.tmpl
index a7d76fb4..c0caafd0 100644
--- a/nano/templates/disease_splicer.tmpl
+++ b/nano/templates/disease_splicer.tmpl
@@ -1,13 +1,13 @@
- {{:~link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}}
+ {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}}
-{{if busy}}
+{{if data.busy}}
The Splicer is currently busy.
-
{{:busy}}
+ {{:data.busy}}
Thank you for your patience!
@@ -17,7 +17,7 @@
Virus Dish
- {{:~link('Eject Dish', 'eject', { 'eject' : 1 }, dish_inserted ? null : 'disabled')}}
+ {{:helper.link('Eject Dish', 'eject', { 'eject' : 1 }, data.dish_inserted ? null : 'disabled')}}
@@ -25,26 +25,26 @@
Growth Density:
- {{:~displayBar(growth, 0, 100, growth >= 50 ? 'good' : growth >= 25 ? 'average' : 'bad', growth + '%' )}}
+ {{:helper.displayBar(data.growth, 0, 100, (data.growth >= 50) ? 'good' : data.growth >= 25 ? 'average' : 'bad', data.growth + '%' )}}
- {{if !info}}
+ {{if !data.info}}
Symptoms:
{{/if}}
- {{if info}}
-
{{:info}}
+ {{if data.info}}
+
{{:data.info}}
{{else}}
- {{for effects}}
+ {{for data.effects}}
- ({{:stage}}) {{:name}}
- {{if badness > 1}}
+ ({{:value.stage}}) {{:value.name}}
+ {{if value.badness > 1}}
Dangerous
{{/if}}
@@ -53,18 +53,18 @@
{{/if}}
- {{if affected_species && !info}}
+ {{if data.affected_species && !data.info}}
Affected Species:
- {{:affected_species}}
+ {{:data.affected_species}}
{{/if}}
- {{if effects}}
+ {{if data.effects}}
CAUTION: Reverse engineering will destroy the viral sample.
@@ -73,12 +73,12 @@
Reverse Engineering:
- {{for effects}}
- {{:~link(stage, 'transferthick-e-w', { 'grab' : reference })}}
+ {{for data.effects}}
+ {{:helper.link(value.stage, 'transferthick-e-w', { 'grab' : value.reference })}}
{{/for}}
- {{:~link('Species', 'transferthick-e-w', { 'affected_species' : 1 })}}
+ {{:helper.link('Species', 'transferthick-e-w', { 'affected_species' : 1 })}}
{{/if}}
@@ -92,17 +92,17 @@
Memory Buffer:
- {{if buffer}}
- {{:buffer.name}} ({{:buffer.stage}})
+ {{if data.buffer}}
+ {{:data.buffer.name}} ({{:data.buffer.stage}})
{{else}}
- {{if species_buffer}}
- {{:species_buffer}}
+ {{if data.species_buffer}}
+ {{:data.species_buffer}}
{{else}}
Empty
{{/if}}
{{/if}}
- {{:~link('Save To Disk', 'disk', { 'disk' : 1 }, (buffer || species_buffer) ? null : 'disabled')}}
- {{:~link('Splice Onto Dish', 'pencil', { 'splice' : 1 }, (buffer || species_buffer) && !info ? null : 'disabled')}}
+ {{:helper.link('Save To Disk', 'disk', { 'disk' : 1 }, (data.buffer || data.species_buffer) ? null : 'disabled')}}
+ {{:helper.link('Splice Onto Dish', 'pencil', { 'splice' : 1 }, ((data.buffer || data.species_buffer) && !data.info) ? null : 'disabled')}}
{{/if}}
diff --git a/nano/templates/dish_incubator.tmpl b/nano/templates/dish_incubator.tmpl
index 6ebff276..ae887e69 100644
--- a/nano/templates/dish_incubator.tmpl
+++ b/nano/templates/dish_incubator.tmpl
@@ -1,6 +1,6 @@
- {{:~link('Close', 'gear', {'close' : '1'}, null, 'fixedLeft')}}
+ {{:helper.link('Close', 'gear', {'close' : '1'}, null, 'fixedLeft')}}
@@ -12,12 +12,12 @@
Power:
- {{:~link('On', 'power', { 'power' : 1 }, !dish_inserted ? 'disabled' : on ? 'selected' : null)}}{{:~link('Off', 'close', { 'power' : 1 }, on ? null : 'selected')}}
+ {{:helper.link('On', 'power', { 'power' : 1 }, !data.dish_inserted ? 'disabled' : data.on ? 'selected' : null)}}{{:helper.link('Off', 'close', { 'power' : 1 }, data.on ? null : 'selected')}}
- {{:~link('Add Radiation', 'radiation', {'rad' : 1})}}
- {{:~link('Flush System', 'trash', {'flush' : 1}, system_in_use ? null : 'disabled')}}
+ {{:helper.link('Add Radiation', 'radiation', {'rad' : 1})}}
+ {{:helper.link('Flush System', 'trash', {'flush' : 1}, data.system_in_use ? null : 'disabled')}}
@@ -26,7 +26,7 @@
Virus Food:
- {{:~displayBar(food_supply, 0, 100, 'good', food_supply)}}
+ {{:helper.displayBar(data.food_supply, 0, 100, 'good', data.food_supply)}}
@@ -34,9 +34,9 @@
Radiation Level:
- {{:~displayBar(radiation, 0, 100, radiation >= 50 ? 'bad' : growth >= 25 ? 'average' : 'good')}}
+ {{:helper.displayBar(data.radiation, 0, 100, (data.radiation >= 50) ? 'bad' : (data.growth >= 25) ? 'average' : 'good')}}
- {{:~formatNumber(radiation * 10000)}}
µSv
+ {{:helper.formatNumber(data.radiation * 10000)}}
µSv
@@ -44,7 +44,7 @@
Toxicity:
- {{:~displayBar(toxins, 0, 100, toxins >= 50 ? 'bad' : toxins >= 25 ? 'average' : 'good', toxins + '%')}}
+ {{:helper.displayBar(data.toxins, 0, 100, (data.toxins >= 50) ? 'bad' : (data.toxins >= 25) ? 'average' : 'good', data.toxins + '%')}}
@@ -53,17 +53,17 @@
Chemicals
- {{:~link('Eject Chemicals', 'eject', { 'ejectchem' : 1 }, chemicals_inserted ? null : 'disabled')}}
- {{:~link('Breed Virus', 'circle-arrow-s', { 'virus' : 1 }, can_breed_virus ? null : 'disabled')}}
+ {{:helper.link('Eject Chemicals', 'eject', { 'ejectchem' : 1 }, data.chemicals_inserted ? null : 'disabled')}}
+ {{:helper.link('Breed Virus', 'circle-arrow-s', { 'virus' : 1 }, data.can_breed_virus ? null : 'disabled')}}
-{{if chemicals_inserted}}
+{{if data.chemicals_inserted}}
Volume:
- {{:~displayBar(chemical_volume, 0, max_chemical_volume, 'good', chemical_volume + ' / ' + max_chemical_volume)}}
+ {{:helper.displayBar(data.chemical_volume, 0, data.max_chemical_volume, 'good', data.chemical_volume + ' / ' + data.max_chemical_volume)}}
@@ -71,10 +71,10 @@
Breeding Environment:
-
- {{:!dish_inserted ? 'N/A' : can_breed_virus ? 'Suitable' : 'No hemolytic samples detected'}}
+
+ {{:!data.dish_inserted ? 'N/A' : data.can_breed_virus ? 'Suitable' : 'No hemolytic samples detected'}}
- {{if blood_already_infected}}
+ {{if data.blood_already_infected}}
CAUTION: Viral infection detected in blood sample.
{{/if}}
@@ -90,17 +90,17 @@
Virus Dish
- {{:~link('Eject Dish', 'eject', {'ejectdish' : 1}, dish_inserted ? null : 'disabled')}}
+ {{:helper.link('Eject Dish', 'eject', {'ejectdish' : 1}, data.dish_inserted ? null : 'disabled')}}
-{{if dish_inserted}}
- {{if virus}}
+{{if data.dish_inserted}}
+ {{if data.virus}}
Growth Density:
- {{:~displayBar(growth, 0, 100, growth >= 50 ? 'good' : growth >= 25 ? 'average' : 'bad', growth + '%' )}}
+ {{:helper.displayBar(data.growth, 0, 100, (data.growth >= 50) ? 'good' : (data.growth >= 25) ? 'average' : 'bad', data.growth + '%' )}}
@@ -108,7 +108,7 @@
Infection Rate:
- {{:analysed ? infection_rate : "Unknown"}}
+ {{:data.analysed ? data.infection_rate : "Unknown"}}
{{else}}
diff --git a/nano/templates/dna_modifier.tmpl b/nano/templates/dna_modifier.tmpl
index b064de84..9a2804ba 100644
--- a/nano/templates/dna_modifier.tmpl
+++ b/nano/templates/dna_modifier.tmpl
@@ -5,54 +5,54 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Status
- {{if !hasOccupant}}
+ {{if !data.hasOccupant}}
Cell Unoccupied
{{else}}
- {{:occupant.name}} =>
- {{if occupant.stat == 0}}
+ {{:data.occupant.name}} =>
+ {{if data.occupant.stat == 0}}
Conscious
- {{else occupant.stat == 1}}
+ {{else data.occupant.stat == 1}}
Unconscious
{{else}}
DEAD
{{/if}}
- {{if !occupant.isViableSubject || !occupant.uniqueIdentity || !occupant.structuralEnzymes}}
+ {{if !data.occupant.isViableSubject || !data.occupant.uniqueIdentity || !data.occupant.structuralEnzymes}}
The occupant's DNA structure is ruined beyond recognition, please insert a subject with an intact DNA structure.
- {{else occupant.stat < 2}}
+ {{else data.occupant.stat < 2}}
Health:
- {{if occupant.health >= 0}}
- {{:~displayBar(occupant.health, 0, occupant.maxHealth, 'good')}}
+ {{if data.occupant.health >= 0}}
+ {{:helper.displayBar(data.occupant.health, 0, data.occupant.maxHealth, 'good')}}
{{else}}
- {{:~displayBar(occupant.health, 0, occupant.minHealth, 'average alignRight')}}
+ {{:helper.displayBar(data.occupant.health, 0, data.occupant.minHealth, 'average alignRight')}}
{{/if}}
-
{{:~round(occupant.health)}}
+
{{:helper.round(data.occupant.health)}}
Radiation:
- {{:~displayBar(occupant.radiationLevel, 0, 100, 'average')}}
-
{{:~round(occupant.radiationLevel)}}
+ {{:helper.displayBar(data.occupant.radiationLevel, 0, 100, 'average')}}
+
{{:helper.round(data.occupant.radiationLevel)}}
Unique Enzymes:
-
{{:occupant.uniqueEnzymes ? occupant.uniqueEnzymes : 'Unknown'}}
+
{{:data.occupant.uniqueEnzymes ? data.occupant.uniqueEnzymes : 'Unknown'}}
{{/if}}
{{/if}}
@@ -61,65 +61,65 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Operations
- {{:~link('Modify U.I.', 'link', {'selectMenuKey' : 'ui'}, selectedMenuKey == 'ui' ? 'selected' : null)}}
- {{:~link('Modify S.E.', 'link', {'selectMenuKey' : 'se'}, selectedMenuKey == 'se' ? 'selected' : null)}}
- {{:~link('Transfer Buffers', 'disk', {'selectMenuKey' : 'buffer'}, selectedMenuKey == 'buffer' ? 'selected' : null)}}
- {{:~link('Rejuvenators', 'plusthick', {'selectMenuKey' : 'rejuvenators'}, selectedMenuKey == 'rejuvenators' ? 'selected' : null)}}
+ {{:helper.link('Modify U.I.', 'link', {'selectMenuKey' : 'ui'}, data.selectedMenuKey == 'ui' ? 'selected' : null)}}
+ {{:helper.link('Modify S.E.', 'link', {'selectMenuKey' : 'se'}, data.selectedMenuKey == 'se' ? 'selected' : null)}}
+ {{:helper.link('Transfer Buffers', 'disk', {'selectMenuKey' : 'buffer'}, data.selectedMenuKey == 'buffer' ? 'selected' : null)}}
+ {{:helper.link('Rejuvenators', 'plusthick', {'selectMenuKey' : 'rejuvenators'}, data.selectedMenuKey == 'rejuvenators' ? 'selected' : null)}}
-{{if !selectedMenuKey || selectedMenuKey == 'ui'}}
+{{if !data.selectedMenuKey || data.selectedMenuKey == 'ui'}}
Modify Unique Identifier
- {{:~displayDNABlocks(occupant.uniqueIdentity, selectedUIBlock, selectedUISubBlock, dnaBlockSize, 'UI')}}
+ {{:helper.displayDNABlocks(data.occupant.uniqueIdentity, data.selectedUIBlock, data.selectedUISubBlock, data.dnaBlockSize, 'UI')}}
Target:
- {{:~link('-', null, {'changeUITarget' : 0}, selectedUITarget > 0 ? null : 'disabled')}}
-
{{:selectedUITargetHex}}
- {{:~link('+', null, {'changeUITarget' : 1}, selectedUITarget < 15 ? null : 'disabled')}}
+ {{:helper.link('-', null, {'changeUITarget' : 0}, (data.selectedUITarget > 0) ? null : 'disabled')}}
+
{{:data.selectedUITargetHex}}
+ {{:helper.link('+', null, {'changeUITarget' : 1}, (data.selectedUITarget < 15) ? null : 'disabled')}}
- {{:~link('Irradiate Block', 'radiation', {'pulseUIRadiation' : 1}, !occupant.isViableSubject ? 'disabled' : null)}}
+ {{:helper.link('Irradiate Block', 'radiation', {'pulseUIRadiation' : 1}, !data.occupant.isViableSubject ? 'disabled' : null)}}
-{{else selectedMenuKey == 'se'}}
+{{else data.selectedMenuKey == 'se'}}
Modify Structural Enzymes
- {{:~displayDNABlocks(occupant.structuralEnzymes, selectedSEBlock, selectedSESubBlock, dnaBlockSize, 'SE')}}
+ {{:helper.displayDNABlocks(data.occupant.structuralEnzymes, data.selectedSEBlock, data.selectedSESubBlock, data.dnaBlockSize, 'SE')}}
- {{:~link('Irradiate Block', 'radiation', {'pulseSERadiation' : 1}, !occupant.isViableSubject ? 'disabled' : null)}}
+ {{:helper.link('Irradiate Block', 'radiation', {'pulseSERadiation' : 1}, !data.occupant.isViableSubject ? 'disabled' : null)}}
-{{else selectedMenuKey == 'buffer'}}
+{{else data.selectedMenuKey == 'buffer'}}
Transfer Buffers
- {{for buffers}}
-
Buffer {{:#index + 1}}
+ {{for data.buffers}}
+
Buffer {{:(index + 1)}}
Load Data:
- {{:~link('Subject U.I.', 'link', {'bufferOption' : 'saveUI', 'bufferId' : (#index + 1)}, !~root.hasOccupant ? 'disabled' : null)}}
- {{:~link('Subject U.I. + U.E.', 'link', {'bufferOption' : 'saveUIAndUE', 'bufferId' : (#index + 1)}, !~root.hasOccupant ? 'disabled' : null)}}
- {{:~link('Subject S.E.', 'link', {'bufferOption' : 'saveSE', 'bufferId' : (#index + 1)}, !~root.hasOccupant ? 'disabled' : null)}}
- {{:~link('From Disk', 'disk', {'bufferOption' : 'loadDisk', 'bufferId' : (#index + 1)}, !~root.hasDisk || !~root.disk.data ? 'disabled' : null)}}
+ {{:helper.link('Subject U.I.', 'link', {'bufferOption' : 'saveUI', 'bufferId' : (index + 1)}, !data.hasOccupant ? 'disabled' : null)}}
+ {{:helper.link('Subject U.I. + U.E.', 'link', {'bufferOption' : 'saveUIAndUE', 'bufferId' : (index + 1)}, !data.hasOccupant ? 'disabled' : null)}}
+ {{:helper.link('Subject S.E.', 'link', {'bufferOption' : 'saveSE', 'bufferId' : (index + 1)}, !data.hasOccupant ? 'disabled' : null)}}
+ {{:helper.link('From Disk', 'disk', {'bufferOption' : 'loadDisk', 'bufferId' : (index + 1)}, (!data.hasDisk || !data.disk.data) ? 'disabled' : null)}}
- {{if data}}
+ {{if value.data}}
Label:
- {{:~link(label, 'document-b', {'bufferOption' : 'changeLabel', 'bufferId' : (#parent.index + 1)})}}
+ {{:helper.link(value.label, 'document-b', {'bufferOption' : 'changeLabel', 'bufferId' : (index + 1)})}}
@@ -127,7 +127,7 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Subject:
- {{:owner ? owner : 'Unknown'}}
+ {{:value.owner ? value.owner : 'Unknown'}}
@@ -135,8 +135,8 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Stored Data:
- {{:data == 'ui' ? 'Unique Identifiers' : 'Structural Enzymes'}}
- {{:ue ? ' + Unique Enzymes' : ''}}
+ {{:value.data == 'ui' ? 'Unique Identifiers' : 'Structural Enzymes'}}
+ {{:value.ue ? ' + Unique Enzymes' : ''}}
{{else}}
@@ -151,11 +151,11 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Options:
- {{:~link('Clear', 'trash', {'bufferOption' : 'clear', 'bufferId' : (#index + 1)}, !data ? 'disabled' : null)}}
- {{:~link('Injector', ~root.isInjectorReady ? 'pencil' : 'clock', {'bufferOption' : 'createInjector', 'bufferId' : (#index + 1)}, !~root.isInjectorReady || !data ? 'disabled' : null)}}
- {{:~link('Block Injector', ~root.isInjectorReady ? 'pencil' : 'clock', {'bufferOption' : 'createInjector', 'bufferId' : (#index + 1), 'createBlockInjector' : 1}, !~root.isInjectorReady || !data ? 'disabled' : null)}}
- {{:~link('Transfer', 'radiation', {'bufferOption' : 'transfer', 'bufferId' : (#index + 1)}, !~root.hasOccupant || !data ? 'disabled' : null)}}
- {{:~link('Save To Disk', 'disk', {'bufferOption' : 'saveDisk', 'bufferId' : (#index + 1)}, !data || !~root.hasDisk ? 'disabled' : null)}}
+ {{:helper.link('Clear', 'trash', {'bufferOption' : 'clear', 'bufferId' : (index + 1)}, !value.data ? 'disabled' : null)}}
+ {{:helper.link('Injector', data.isInjectorReady ? 'pencil' : 'clock', {'bufferOption' : 'createInjector', 'bufferId' : (index + 1)}, (!data.isInjectorReady || !value.data) ? 'disabled' : null)}}
+ {{:helper.link('Block Injector', data.isInjectorReady ? 'pencil' : 'clock', {'bufferOption' : 'createInjector', 'bufferId' : (index + 1), 'createBlockInjector' : 1}, (!data.isInjectorReady || !value.data) ? 'disabled' : null)}}
+ {{:helper.link('Transfer', 'radiation', {'bufferOption' : 'transfer', 'bufferId' : (index + 1)}, (!data.hasOccupant || !value.data) ? 'disabled' : null)}}
+ {{:helper.link('Save To Disk', 'disk', {'bufferOption' : 'saveDisk', 'bufferId' : (index + 1)}, (!value.data || !data.hasDisk) ? 'disabled' : null)}}
@@ -163,14 +163,14 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Data Disk
- {{if hasDisk}}
- {{if disk.data}}
+ {{if data.hasDisk}}
+ {{if data.disk.data}}
Label:
- {{:disk.label ? disk.label : 'No Label'}}
+ {{:data.disk.label ? data.disk.label : 'No Label'}}
@@ -178,7 +178,7 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Subject:
- {{:disk.owner ? disk.owner : 'Unknown'}}
+ {{:data.disk.owner ? data.disk.owner : 'Unknown'}}
@@ -186,8 +186,8 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Stored Data:
- {{:disk.data == 'ui' ? 'Unique Identifiers' : 'Structural Enzymes'}}
- {{:disk.ue ? ' + Unique Enzymes' : ''}}
+ {{:data.disk.data == 'ui' ? 'Unique Identifiers' : 'Structural Enzymes'}}
+ {{:data.disk.ue ? ' + Unique Enzymes' : ''}}
{{else}}
@@ -206,26 +206,26 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
{{/if}}
- Options:
+ Options:
- {{:~link('Wipe Disk', 'trash', {'bufferOption' : 'wipeDisk'}, !hasDisk || !disk.data ? 'disabled' : null)}}
- {{:~link('Eject Disk', 'eject', {'bufferOption' : 'ejectDisk'}, !hasDisk ? 'disabled' : null)}}
+ {{:helper.link('Wipe Disk', 'trash', {'bufferOption' : 'wipeDisk'}, (!data.hasDisk || !data.disk.data) ? 'disabled' : null)}}
+ {{:helper.link('Eject Disk', 'eject', {'bufferOption' : 'ejectDisk'}, !data.hasDisk ? 'disabled' : null)}}
-{{else selectedMenuKey == 'rejuvenators'}}
+{{else data.selectedMenuKey == 'rejuvenators'}}
Rejuvenators
Inject:
- {{:~link('5', 'pencil', {'injectRejuvenators' : 5}, !hasOccupant || !beakerVolume ? 'disabled' : null)}}
- {{:~link('10', 'pencil', {'injectRejuvenators' : 10}, !hasOccupant || !beakerVolume ? 'disabled' : null)}}
- {{:~link('20', 'pencil', {'injectRejuvenators' : 20}, !hasOccupant || !beakerVolume ? 'disabled' : null)}}
- {{:~link('30', 'pencil', {'injectRejuvenators' : 30}, !hasOccupant || !beakerVolume ? 'disabled' : null)}}
- {{:~link('50', 'pencil', {'injectRejuvenators' : 50}, !hasOccupant || !beakerVolume ? 'disabled' : null)}}
+ {{:helper.link('5', 'pencil', {'injectRejuvenators' : 5}, (!data.hasOccupant || !data.beakerVolume) ? 'disabled' : null)}}
+ {{:helper.link('10', 'pencil', {'injectRejuvenators' : 10}, (!data.hasOccupant || !data.beakerVolume) ? 'disabled' : null)}}
+ {{:helper.link('20', 'pencil', {'injectRejuvenators' : 20}, (!data.hasOccupant || !data.beakerVolume) ? 'disabled' : null)}}
+ {{:helper.link('30', 'pencil', {'injectRejuvenators' : 30}, (!data.hasOccupant || !data.beakerVolume) ? 'disabled' : null)}}
+ {{:helper.link('50', 'pencil', {'injectRejuvenators' : 50}, (!data.hasOccupant || !data.beakerVolume) ? 'disabled' : null)}}
@@ -234,10 +234,10 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Beaker:
- {{if isBeakerLoaded}}
- {{:beakerLabel ? beakerLabel : 'No label'}}
- {{if beakerVolume}}
- {{:beakerVolume}} units remaining
+ {{if data.isBeakerLoaded}}
+ {{:data.beakerLabel ? data.beakerLabel : 'No label'}}
+ {{if data.beakerVolume}}
+ {{:data.beakerVolume}} units remaining
{{else}}
Beaker is empty
{{/if}}
@@ -246,23 +246,23 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
{{/if}}
- {{:~link('Eject Beaker', 'eject', {'ejectBeaker' : 1}, isBeakerLoaded ? null : 'disabled')}}
+ {{:helper.link('Eject Beaker', 'eject', {'ejectBeaker' : 1}, data.isBeakerLoaded ? null : 'disabled')}}
{{/if}}
-{{if !selectedMenuKey || selectedMenuKey == 'ui' || selectedMenuKey == 'se'}}
+{{if !data.selectedMenuKey || data.selectedMenuKey == 'ui' || data.selectedMenuKey == 'se'}}
Radiation Emitter Settings
Intensity:
- {{:~link('-', null, {'radiationIntensity' : 0}, radiationIntensity > 1 ? null : 'disabled')}}
-
{{:radiationIntensity}}
- {{:~link('+', null, {'radiationIntensity' : 1}, radiationIntensity < 10 ? null : 'disabled')}}
+ {{:helper.link('-', null, {'radiationIntensity' : 0}, (data.radiationIntensity > 1) ? null : 'disabled')}}
+
{{:data.radiationIntensity}}
+ {{:helper.link('+', null, {'radiationIntensity' : 1}, (data.radiationIntensity < 10) ? null : 'disabled')}}
@@ -270,9 +270,9 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Duration:
- {{:~link('-', null, {'radiationDuration' : 0}, radiationDuration > 2 ? null : 'disabled')}}
-
{{:radiationDuration}}
- {{:~link('+', null, {'radiationDuration' : 1}, radiationDuration < 20 ? null : 'disabled')}}
+ {{:helper.link('-', null, {'radiationDuration' : 0}, (data.radiationDuration > 2) ? null : 'disabled')}}
+
{{:data.radiationDuration}}
+ {{:helper.link('+', null, {'radiationDuration' : 1}, (data.radiationDuration < 20) ? null : 'disabled')}}
@@ -280,7 +280,7 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
- {{:~link('Pulse Radiation', 'radiation', {'pulseRadiation' : 1}, !hasOccupant ? 'disabled' : null)}}
+ {{:helper.link('Pulse Radiation', 'radiation', {'pulseRadiation' : 1}, !data.hasOccupant ? 'disabled' : null)}}
{{/if}}
@@ -294,7 +294,7 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Occupant:
- {{:~link('Eject Occupant', 'eject', {'ejectOccupant' : 1}, locked || !hasOccupant || irradiating ? 'disabled' : null)}}
+ {{:helper.link('Eject Occupant', 'eject', {'ejectOccupant' : 1}, data.locked || !data.hasOccupant || data.irradiating ? 'disabled' : null)}}
@@ -302,16 +302,16 @@ Used In File(s): D:\Development\SS13-BS12\code\game\dna\dna_modifier.dm
Door Lock:
- {{:~link('Engaged', 'locked', {'toggleLock' : 1}, locked ? 'selected' : !hasOccupant ? 'disabled' : null)}}
- {{:~link('Disengaged', 'unlocked', {'toggleLock' : 1}, !locked ? 'selected' : irradiating ? 'disabled' : null)}}
+ {{:helper.link('Engaged', 'locked', {'toggleLock' : 1}, data.locked ? 'selected' : !data.hasOccupant ? 'disabled' : null)}}
+ {{:helper.link('Disengaged', 'unlocked', {'toggleLock' : 1}, !data.locked ? 'selected' : data.irradiating ? 'disabled' : null)}}
-{{if irradiating}}
+{{if data.irradiating}}
Irradiating Subject
- For {{:irradiating}} seconds.
+ For {{:data.irradiating}} seconds.
{{/if}}
diff --git a/nano/templates/dnaforensics.tmpl b/nano/templates/dnaforensics.tmpl
index 04b203e4..a1e3b25f 100644
--- a/nano/templates/dnaforensics.tmpl
+++ b/nano/templates/dnaforensics.tmpl
@@ -1,21 +1,21 @@
Machine Status
- {{:~link(scanning ? 'Halt Scan' : 'Begin Scan', 'signal-diag', {'scanItem' : 1}, null)}}
+ {{:helper.link(data.scanning ? 'Halt Scan' : 'Begin Scan', 'signal-diag', {'scanItem' : 1}, null)}}
- {{:~link('Eject item', 'eject', {'ejectItem' : 1}, (bloodsamp && !scanning) ? null : 'disabled')}}
+ {{:helper.link('Eject item', 'eject', {'ejectItem' : 1}, (data.bloodsamp && !data.scanning) ? null : 'disabled')}}
Scanner
Scan progress:
- {{:~displayBar(scan_progress, 0, 100, 'good')}}
- {{:scan_progress}} %
+ {{:helper.displayBar(data.scan_progress, 0, 100, 'good')}}
+ {{:data.scan_progress}} %
- {{if scan_progress >= 100}}
+ {{if data.scan_progress >= 100}}
Scan completed successfully.
{{/if}}
@@ -24,8 +24,8 @@
Item:
- {{if bloodsamp}}
-
{{:bloodsamp}}
+ {{if data.bloodsamp}}
+
{{:data.bloodsamp}}
{{else}}
No item inserted
{{/if}}
@@ -34,8 +34,8 @@
Heuristic analysis:
- {{if bloodsamp_desc}}
- {{:bloodsamp_desc}}
+ {{if data.bloodsamp_desc}}
+ {{:data.bloodsamp_desc}}
{{/if}}
diff --git a/nano/templates/docking_airlock_console.tmpl b/nano/templates/docking_airlock_console.tmpl
new file mode 100644
index 00000000..9dd1709c
--- /dev/null
+++ b/nano/templates/docking_airlock_console.tmpl
@@ -0,0 +1,96 @@
+
+
+
+ Docking Port Status:
+
+ {{if data.docking_status == "docked"}}
+
+ {{if !data.override_enabled}}
+ DOCKED
+ {{else}}
+ DOCKED-OVERRIDE ENABLED
+ {{/if}}
+
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? null : null)}}
+
+
+ {{else data.docking_status == "docking"}}
+
+ {{if !data.override_enabled}}
+ DOCKING
+ {{else}}
+ DOCKING-OVERRIDE ENABLED
+ {{/if}}
+
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? null : null)}}
+
+
+ {{else data.docking_status == "undocking"}}
+
+ {{if !data.override_enabled}}
+ UNDOCKING
+ {{else}}
+ UNDOCKING-OVERRIDE ENABLED
+ {{/if}}
+
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? null : null)}}
+
+
+ {{else data.docking_status == "undocked"}}
+
+ {{if !data.override_enabled}}
+ NOT IN USE
+ {{else}}
+ OVERRIDE ENABLED
+ {{/if}}
+
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? null : null)}}
+
+
+ {{else}}
+
ERROR
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? null : null)}}
+ {{/if}}
+
+
+
+
+
+ Chamber Pressure:
+
+
+ {{:helper.displayBar(data.chamber_pressure, 0, 200, (data.chamber_pressure < 80 || data.chamber_pressure > 120) ? 'bad' : (data.chamber_pressure < 95 || data.chamber_pressure > 110) ? 'average' : 'good')}}
+
+ {{:data.chamber_pressure}} kPa
+
+
+
+
+
+
+
+ {{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, (data.processing || data.airlock_disabled) ? 'disabled' : null)}}
+ {{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, (data.processing || data.airlock_disabled) ? 'disabled' : null)}}
+
+
+ {{if data.airlock_disabled}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, 'disabled', null)}}
+ {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, 'disabled', null)}}
+ {{else}}
+ {{if data.interior_status.state == "open"}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, null)}}
+ {{else}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, data.processing ? null : null)}}
+ {{/if}}
+ {{if data.exterior_status.state == "open"}}
+ {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, null)}}
+ {{else}}
+ {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, data.processing ? null : null)}}
+ {{/if}}
+ {{/if}}
+
+
+
+ {{:helper.link('Abort', 'cancel', {'command' : 'abort'}, (data.processing && !data.airlock_disabled) ? null : 'disabled', (data.processing && !data.airlock_disabled) ? null : null)}}
+
+
\ No newline at end of file
diff --git a/nano/templates/door_access_console.tmpl b/nano/templates/door_access_console.tmpl
index c755d7c8..2e5c81cb 100644
--- a/nano/templates/door_access_console.tmpl
+++ b/nano/templates/door_access_console.tmpl
@@ -4,7 +4,7 @@
Exterior Door Status:
- {{if exterior_status.state == "closed"}}
+ {{if data.exterior_status.state == "closed"}}
Locked
{{else}}
Open
@@ -16,7 +16,7 @@
Interior Door Status:
- {{if interior_status.state == "closed"}}
+ {{if data.interior_status.state == "closed"}}
Locked
{{else}}
Open
@@ -27,15 +27,15 @@
- {{if exterior_status.state == "open"}}
- {{:~link('Lock Exterior Door', 'alert', {'command' : 'force_ext'}, processing ? 'disabled' : null)}}
+ {{if data.exterior_status.state == "open"}}
+ {{:helper.link('Lock Exterior Door', 'alert', {'command' : 'force_ext'}, data.processing ? 'disabled' : null)}}
{{else}}
- {{:~link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext_door'}, processing ? 'disabled' : null)}}
+ {{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext_door'}, data.processing ? 'disabled' : null)}}
{{/if}}
- {{if interior_status.state == "open"}}
- {{:~link('Lock Interior Door', 'alert', {'command' : 'force_int'}, processing ? 'disabled' : null)}}
+ {{if data.interior_status.state == "open"}}
+ {{:helper.link('Lock Interior Door', 'alert', {'command' : 'force_int'}, data.processing ? 'disabled' : null)}}
{{else}}
- {{:~link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int_door'}, processing ? 'disabled' : null)}}
+ {{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int_door'}, data.processing ? 'disabled' : null)}}
{{/if}}
diff --git a/nano/templates/escape_pod_berth_console.tmpl b/nano/templates/escape_pod_berth_console.tmpl
new file mode 100644
index 00000000..aedb46bb
--- /dev/null
+++ b/nano/templates/escape_pod_berth_console.tmpl
@@ -0,0 +1,42 @@
+
+
+
+ Escape Pod Status:
+
+
+ {{if data.docking_status == "docked"}}
+ {{if data.armed}}
+ ARMED
+ {{else}}
+ SYSTEMS OK
+ {{/if}}
+ {{else data.docking_status == "undocking"}}
+ EJECTING-STAND CLEAR!
+ {{else data.docking_status == "undocked"}}
+ POD EJECTED
+ {{else data.docking_status == "docking"}}
+ INITIALIZING...
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+
+
+
+ {{if data.armed}}
+ {{if data.docking_status == "docked"}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', null)}}
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : null)}}
+ {{else}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redBackground' : null)}}
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : 'yellowBackground')}}
+ {{/if}}
+ {{else}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, 'disabled', null)}}
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, 'disabled', null)}}
+ {{/if}}
+
+
+
\ No newline at end of file
diff --git a/nano/templates/escape_pod_console.tmpl b/nano/templates/escape_pod_console.tmpl
new file mode 100644
index 00000000..977c95ca
--- /dev/null
+++ b/nano/templates/escape_pod_console.tmpl
@@ -0,0 +1,95 @@
+
+
+
+ Escape Pod Status:
+
+
+ {{if data.docking_status == "docked"}}
+ {{if data.is_armed}}
+ ARMED
+ {{else}}
+ SYSTEMS OK
+ {{/if}}
+ {{else data.docking_status == "undocking"}}
+ EJECTING
+ {{else data.docking_status == "undocked"}}
+ POD EJECTED
+ {{else data.docking_status == "docking"}}
+ DOCKING
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+
+
+
+ Docking Hatch:
+
+
+ {{if data.docking_status == "docked"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed"}}
+ CLOSED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else data.docking_status == "docking"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed" && data.door_lock == "locked"}}
+ SECURED
+ {{else data.door_state == "closed" && data.door_lock == "unlocked"}}
+ UNSECURED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else data.docking_status == "undocking"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed" && data.door_lock == "locked"}}
+ SECURED
+ {{else data.door_state == "closed" && data.door_lock == "unlocked"}}
+ UNSECURED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else data.docking_status == "undocked"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed" && data.door_lock == "locked"}}
+ SECURED
+ {{else data.door_state == "closed" && data.door_lock == "unlocked"}}
+ UNSECURED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+
+
+
+ {{if data.docking_status == "docked"}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', null)}}
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : null)}}
+ {{else}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redBackground' : null)}}
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : 'yellowBackground')}}
+ {{/if}}
+
+
+
+
+
+
+ {{:helper.link('ARM', 'alert', {'command' : 'manual_arm'}, data.is_armed ? 'disabled' : null, data.is_armed ? 'redBackground' : 'yellowBackground')}}
+ {{:helper.link('MANUAL EJECT', 'alert', {'command' : 'force_launch'}, data.can_force ? null : 'disabled', data.can_force ? 'yellowBackground' : null)}}
+
+
+
diff --git a/nano/templates/escape_shuttle_control_console.tmpl b/nano/templates/escape_shuttle_control_console.tmpl
new file mode 100644
index 00000000..8fdb6b4c
--- /dev/null
+++ b/nano/templates/escape_shuttle_control_console.tmpl
@@ -0,0 +1,84 @@
+
Shuttle Status
+
+
+ {{:data.shuttle_status}}
+
+
+
+
+
+ Bluespace Drive:
+
+
+ {{if data.shuttle_state == "idle"}}
+ IDLE
+ {{else data.shuttle_state == "warmup"}}
+ SPINNING UP
+ {{else data.shuttle_state == "in_transit"}}
+ ENGAGED
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+{{if data.has_docking}}
+
+
+
+ Docking Status:
+
+
+ {{if data.docking_status == "docked"}}
+ DOCKED
+ {{else data.docking_status == "docking"}}
+ {{if !data.docking_override}}
+ DOCKING
+ {{else}}
+ DOCKING-MANUAL
+ {{/if}}
+ {{else data.docking_status == "undocking"}}
+ {{if !data.docking_override}}
+ UNDOCKING
+ {{else}}
+ UNDOCKING-MANUAL
+ {{/if}}
+ {{else data.docking_status == "undocked"}}
+ UNDOCKED
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+{{/if}}
+
Shuttle Authorization
+
+
+ {{if data.has_auth}}
+ Access Granted. Shuttle controls unlocked.
+ {{else}}
+ Additional authorization required.
+ {{/if}}
+
+
+
+ {{for data.auth_list}}
+ {{if value.auth_hash}}
+ {{:helper.link(value.auth_name, 'eject', {'removeid' : value.auth_hash}, null, 'itemContentWide')}}
+ {{else}}
+ {{:helper.link("", 'eject', {'scanid' : 1}, null, 'itemContentWide')}}
+ {{/if}}
+ {{/for}}
+
+
+
Shuttle Control
+
+
+
+ {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}}
+ {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}}
+ {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redBackground' : null)}}
+
+
+
\ No newline at end of file
diff --git a/nano/templates/freezer.tmpl b/nano/templates/freezer.tmpl
index 9e1c13ed..fad41bad 100644
--- a/nano/templates/freezer.tmpl
+++ b/nano/templates/freezer.tmpl
@@ -3,7 +3,20 @@
Status:
- {{:~link('On', 'power', {'toggleStatus' : 1}, on ? 'selected' : null)}}{{:~link('Off', 'close', {'toggleStatus' : 1}, on ? null : 'selected')}}
+ {{:helper.link('On', 'power', {'toggleStatus' : 1}, data.on ? 'selected' : null)}}{{:helper.link('Off', 'close', {'toggleStatus' : 1}, data.on ? null : 'selected')}}
+
+
+
+
+
+ Power Level:
+
+
+ {{:helper.link('1', null, {'setPower' : 20}, (data.powerSetting == 20)? 'selected' : null)}}
+ {{:helper.link('2', null, {'setPower' : 40}, (data.powerSetting == 40)? 'selected' : null)}}
+ {{:helper.link('3', null, {'setPower' : 60}, (data.powerSetting == 60)? 'selected' : null)}}
+ {{:helper.link('4', null, {'setPower' : 80}, (data.powerSetting == 80)? 'selected' : null)}}
+ {{:helper.link('5', null, {'setPower' : 100}, (data.powerSetting == 100)? 'selected' : null)}}
@@ -12,7 +25,7 @@
Gas Pressure:
- {{:gasPressure}} kPa
+ {{:data.gasPressure}} kPa
@@ -22,9 +35,9 @@
Current:
- {{:~displayBar(gasTemperature, minGasTemperature, maxGasTemperature, gasTemperatureClass)}}
+ {{:helper.displayBar(data.gasTemperature, data.minGasTemperature, data.maxGasTemperature, data.gasTemperatureClass)}}
- {{:gasTemperature}} K
+ {{:data.gasTemperature}} K
@@ -34,15 +47,15 @@
Target:
- {{:~displayBar(targetGasTemperature, minGasTemperature, maxGasTemperature)}}
+ {{:helper.displayBar(data.targetGasTemperature, data.minGasTemperature, data.maxGasTemperature)}}
- {{:~link('-', null, {'temp' : -100}, (targetGasTemperature > minGasTemperature) ? null : 'disabled')}}
- {{:~link('-', null, {'temp' : -10}, (targetGasTemperature > minGasTemperature) ? null : 'disabled')}}
- {{:~link('-', null, {'temp' : -1}, (targetGasTemperature > minGasTemperature) ? null : 'disabled')}}
-
{{:targetGasTemperature}} K
- {{:~link('+', null, {'temp' : 1}, (targetGasTemperature < maxGasTemperature) ? null : 'disabled')}}
- {{:~link('+', null, {'temp' : 10}, (targetGasTemperature < maxGasTemperature) ? null : 'disabled')}}
- {{:~link('+', null, {'temp' : 100}, (targetGasTemperature < maxGasTemperature) ? null : 'disabled')}}
+ {{:helper.link('-', null, {'temp' : -100}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}}
+ {{:helper.link('-', null, {'temp' : -10}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}}
+ {{:helper.link('-', null, {'temp' : -1}, (data.targetGasTemperature > data.minGasTemperature) ? null : 'disabled')}}
+
{{:data.targetGasTemperature}} K
+ {{:helper.link('+', null, {'temp' : 1}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}}
+ {{:helper.link('+', null, {'temp' : 10}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}}
+ {{:helper.link('+', null, {'temp' : 100}, (data.targetGasTemperature < data.maxGasTemperature) ? null : 'disabled')}}
diff --git a/nano/templates/gas_pump.tmpl b/nano/templates/gas_pump.tmpl
new file mode 100644
index 00000000..a26d88a2
--- /dev/null
+++ b/nano/templates/gas_pump.tmpl
@@ -0,0 +1,44 @@
+
+
+ Power:
+
+
+ {{:helper.link(data.on? 'On' : 'Off', null, {'power' : 1})}}
+
+
+
+
+
+ Desirable output pressure:
+
+
+
+ {{:helper.link('MAX', null, {'set_press' : 'max'}, null)}}
+ {{:helper.link('SET', null, {'set_press' : 'set'}, null)}}
+
{{:(data.pressure_set/100)}} kPa
+
+
+
+
+
+
+ Load:
+
+
+ {{:helper.displayBar(data.last_power_draw, 0, data.max_power_draw, (data.last_power_draw < data.max_power_draw - 5) ? 'good' : 'average')}}
+
+ {{:data.last_power_draw}} W
+
+
+
+
+
+
+ Flow Rate:
+
+
+
+ {{:(data.last_flow_rate/10)}} L/s
+
+
+
\ No newline at end of file
diff --git a/nano/templates/geoscanner.tmpl b/nano/templates/geoscanner.tmpl
index d3205e2e..90d86b03 100644
--- a/nano/templates/geoscanner.tmpl
+++ b/nano/templates/geoscanner.tmpl
@@ -6,10 +6,10 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Machine Status
- {{:~link(scanning ? 'Halt Scan' : 'Begin Scan', 'signal-diag', {'scanItem' : 1}, null)}}
+ {{:helper.link(data.scanning ? 'Halt Scan' : 'Begin Scan', 'signal-diag', {'scanItem' : 1}, null)}}
- {{:~link('Eject item', 'eject', {'ejectItem' : 1}, (scanned_item && !scanning) ? null : 'disabled')}}
+ {{:helper.link('Eject item', 'eject', {'ejectItem' : 1}, (data.scanned_item && !data.scanning) ? null : 'disabled')}}
@@ -17,8 +17,8 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Item:
- {{if scanned_item}}
-
{{:scanned_item}}
+ {{if data.scanned_item}}
+
{{:data.scanned_item}}
{{else}}
No item inserted
{{/if}}
@@ -27,8 +27,8 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Heuristic analysis:
- {{if scanned_item_desc}}
- {{:scanned_item_desc}}
+ {{if data.scanned_item_desc}}
+ {{:data.scanned_item_desc}}
{{/if}}
@@ -38,11 +38,11 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Scan progress:
- {{:~displayBar(scan_progress, 0, 100, 'good')}}
- {{:scan_progress}} %
+ {{:helper.displayBar(data.scan_progress, 0, 100, 'good')}}
+ {{:data.scan_progress}} %
- {{if scan_progress >= 100}}
+ {{if data.scan_progress >= 100}}
Scan completed successfully.
{{/if}}
@@ -50,11 +50,11 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Vacuum seal integrity:
- {{:~displayBar(scanner_seal_integrity, 0, 100, (scanner_seal_integrity < 66 ? (scanner_seal_integrity < 33 ? 'bad' : 'average') : 'good'))}}
- {{:scanner_seal_integrity}} %
+ {{:helper.displayBar(data.scanner_seal_integrity, 0, 100, ((data.scanner_seal_integrity < 66) ? ((data.scanner_seal_integrity < 33) ? 'bad' : 'average') : 'good'))}}
+ {{:data.scanner_seal_integrity}} %
- {{if scanner_seal_integrity < 25}}
+ {{if data.scanner_seal_integrity < 25}}
Warning! Vacuum seal breach will result in scan failure!
{{/if}}
@@ -64,11 +64,11 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
MASER Efficiency:
- {{:~displayBar(maser_efficiency, 1, 100, (maser_efficiency < 66 ? (maser_efficiency < 33 ? 'bad' : 'average') : 'good'))}}
- {{:maser_efficiency}} %
+ {{:helper.displayBar(data.maser_efficiency, 1, 100, ((data.maser_efficiency < 66) ? ((data.maser_efficiency) < 33 ? 'bad' : 'average') : 'good'))}}
+ {{:data.maser_efficiency}} %
- {{if maser_efficiency < 50}}
+ {{if data.maser_efficiency < 50}}
Match wavelengths to progress the scan.
{{/if}}
@@ -76,25 +76,25 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Optimal Wavelength:
- {{:~displayBar(optimal_wavelength, 1, 10000, 'good')}}
- {{:optimal_wavelength}} MHz
+ {{:helper.displayBar(data.optimal_wavelength, 1, 10000, 'good')}}
+ {{:data.optimal_wavelength}} MHz
Current Wavelength:
- {{:~displayBar(maser_wavelength, 1, 10000, 'good')}}
- {{:maser_wavelength}} MHz
+ {{:helper.displayBar(data.maser_wavelength, 1, 10000, 'good')}}
+ {{:data.maser_wavelength}} MHz
- {{:~link('-2 KHz', null, {'maserWavelength' : -2}, null)}}
- {{:~link('-1 KHz', null, {'maserWavelength' : -1}, null)}}
- {{:~link('-0.5 KHz', null, {'maserWavelength' : -0.5}, null)}}
+ {{:helper.link('-2 GHz', null, {'maserWavelength' : -2}, null)}}
+ {{:helper.link('-1 GHz', null, {'maserWavelength' : -1}, null)}}
+ {{:helper.link('-0.5 GHz', null, {'maserWavelength' : -0.5}, null)}}
- {{:~link('+0.5 KHz', null, {'maserWavelength' : 0.5}, null)}}
- {{:~link('+1 KHz', null, {'maserWavelength' : 1}, null)}}
- {{:~link('+2 KHz', null, {'maserWavelength' : 2}, null)}}
+ {{:helper.link('+0.5 GHz', null, {'maserWavelength' : 0.5}, null)}}
+ {{:helper.link('+1 GHz', null, {'maserWavelength' : 1}, null)}}
+ {{:helper.link('+2 GHz', null, {'maserWavelength' : 2}, null)}}
@@ -102,18 +102,18 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Centrifuge speed:
- {{:~displayBar(scanner_rpm, 0, 1000, 'good')}}
- {{:scanner_rpm}} RPM
+ {{:helper.displayBar(data.scanner_rpm, 0, 1000, 'good')}}
+ {{:data.scanner_rpm}} RPM
Internal temperature:
- {{:~displayBar(scanner_temperature, 0, 1273, (scanner_temperature > 250 ? (scanner_temperature > 1000 ? 'bad' : 'average') : 'good')))}}
- {{:scanner_temperature}} K
+ {{:helper.displayBar(data.scanner_temperature, 0, 1273, (data.scanner_temperature > 250 ? (data.scanner_temperature > 1000 ? 'bad' : 'average') : 'good'))}}
+ {{:data.scanner_temperature}} K
- {{if scanner_temperature > 1000}}
+ {{if data.scanner_temperature > 1000}}
Warning! Exceeding 1200K will result in scan failure!
{{/if}}
@@ -123,12 +123,12 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Ambient radiation:
- {{:~displayBar(radiation, 0, 100, (radiation > 15 ? (radiation > 65 ? 'bad' : 'average') : 'good'))}}
- {{:radiation}} mSv
+ {{:helper.displayBar(data.radiation, 0, 100, ((data.radiation > 15) ? ((data.radiation > 65) ? 'bad' : 'average') : 'good'))}}
+ {{:data.radiation}} mSv
- {{:~link(rad_shield_on ? 'Disable Radiation Shielding' : 'Enable Radiation Shielding', 'radiation', {'toggle_rad_shield' : 1}, null)}}
- {{if rad_shield_on}}
+ {{:helper.link(data.rad_shield_on ? 'Disable Radiation Shielding' : 'Enable Radiation Shielding', 'radiation', {'toggle_rad_shield' : 1}, null)}}
+ {{if data.rad_shield_on}}
Shield blocking scanner.
{{/if}}
@@ -138,11 +138,11 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Coolant remaining:
- {{:~displayBar(unused_coolant_per, 0, 100, (unused_coolant_per < 66 ? (unused_coolant_per < 33 ? 'bad' : 'average') : 'good'))}}
- {{:unused_coolant_abs}} u
+ {{:helper.displayBar(data.unused_coolant_per, 0, 100, ((data.unused_coolant_per < 66) ? ((data.unused_coolant_per < 33) ? 'bad' : 'average') : 'good'))}}
+ {{:data.unused_coolant_abs}} u
- {{if unused_coolant_per < 20}}
+ {{if data.unused_coolant_per < 20}}
Warning! Coolant stocks low!
{{/if}}
@@ -150,28 +150,28 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Coolant flow rate:
- {{:~displayBar(coolant_usage_rate, 0, 10, 'good')}}
- {{:coolant_usage_rate}} u/s
+ {{:helper.displayBar(data.coolant_usage_rate, 0, 10, 'good')}}
+ {{:data.coolant_usage_rate}} u/s
- {{:~link('Min u/s', null, {'coolantRate' : -10}, null)}}
- {{:~link('-3 u/s', null, {'coolantRate' : -3}, null)}}
- {{:~link('-1 u/s', null, {'coolantRate' : -1}, null)}}
+ {{:helper.link('Min u/s', null, {'coolantRate' : -10}, null)}}
+ {{:helper.link('-3 u/s', null, {'coolantRate' : -3}, null)}}
+ {{:helper.link('-1 u/s', null, {'coolantRate' : -1}, null)}}
- {{:~link('+1 u/s', null, {'coolantRate' : 1}, null)}}
- {{:~link('+3 u/s', null, {'coolantRate' : 3}, null)}}
- {{:~link('Max u/s', null, {'coolantRate' : 10}, null)}}
+ {{:helper.link('+1 u/s', null, {'coolantRate' : 1}, null)}}
+ {{:helper.link('+3 u/s', null, {'coolantRate' : 3}, null)}}
+ {{:helper.link('Max u/s', null, {'coolantRate' : 10}, null)}}
Coolant purity:
- {{:~displayBar(coolant_purity, 0, 100, (coolant_purity < 66 ? (coolant_purity < 33 ? 'bad' : 'average') : 'good'))}}
- {{:coolant_purity}} %
+ {{:helper.displayBar(data.coolant_purity, 0, 100, ((data.coolant_purity < 66) ? ((data.coolant_purity < 33) ? 'bad' : 'average') : 'good'))}}
+ {{:data.coolant_purity}} %
- {{if coolant_purity < 0.5}}
+ {{if data.coolant_purity < 0.5}}
Warning! Check coolant for contaminants!
{{/if}}
@@ -180,6 +180,6 @@ Used In File(s): \code\modules\research\xenoarchaeology\machinery\geosample_scan
Latest Results
- {{:last_scan_data}}
+ {{:data.last_scan_data}}
diff --git a/nano/templates/identification_computer.tmpl b/nano/templates/identification_computer.tmpl
new file mode 100644
index 00000000..e783d9e3
--- /dev/null
+++ b/nano/templates/identification_computer.tmpl
@@ -0,0 +1,236 @@
+{{if data.printing}}
+
The computer is currently busy.
+
+
Printing...
+
+
+ Thank you for your patience!
+
+{{else}}
+ {{:helper.link('Access Modification', 'home', {'choice' : 'mode', 'mode_target' : 0}, !data.mode ? 'disabled' : null)}}
+ {{:helper.link('Crew Manifest', 'folder-open', {'choice' : 'mode', 'mode_target' : 1}, data.mode ? 'disabled' : null)}}
+ {{:helper.link('Print', 'print', {'choice' : 'print'}, (data.mode || data.has_modify) ? null : 'disabled')}}
+
+ {{if data.mode}}
+
+
Crew Manifest
+
+
+ {{:data.manifest}}
+
+ {{else}}
+
+
Access Modification
+
+
+ {{if !data.authenticated}}
+
Please insert the IDs into the terminal to proceed.
+ {{/if}}
+
+
+
+ Target Identity:
+
+
+ {{:helper.link(data.target_name, 'eject', {'choice' : 'modify'})}}
+
+
+
+
+ Authorized Identity:
+
+
+ {{:helper.link(data.scan_name, 'eject', {'choice' : 'scan'})}}
+
+
+
+
+ {{if data.authenticated}}
+
+
+ {{if data.has_modify}}
+
+
Details
+
+
+
+
+
+
+
+
+ Terminations:
+
+
+ {{:helper.link('Terminate ' + data.target_owner, 'gear', {'choice' : 'terminate'}, data.target_rank == "Terminated" ? 'disabled' : null, data.target_rank == "Terminated" ? 'disabled' : 'linkDanger')}}
+
+
+
+
+
Assignment
+
+
+
+
+
+
+
+ | Command |
+
+
+ | Special |
+
+ {{:helper.link("Captain", '', {'choice' : 'assign', 'assign_target' : 'Captain'}, data.target_rank == 'Captain' ? 'disabled' : null)}}
+ {{:helper.link("Custom", '', {'choice' : 'assign', 'assign_target' : 'Custom'})}}
+ |
+
+
+ | Engineering |
+
+ {{for data.engineering_jobs}}
+ {{:helper.link(value.display_name, '', {'choice' : 'assign', 'assign_target' : value.job}, data.target_rank == value.job ? 'disabled' : null)}}
+ {{/for}}
+ |
+
+
+ | Medical |
+
+ {{for data.medical_jobs}}
+ {{:helper.link(value.display_name, '', {'choice' : 'assign', 'assign_target' : value.job}, data.target_rank == value.job ? 'disabled' : null)}}
+ {{/for}}
+ |
+
+
+ | Science |
+
+ {{for data.science_jobs}}
+ {{:helper.link(value.display_name, '', {'choice' : 'assign', 'assign_target' : value.job}, data.target_rank == value.job ? 'disabled' : null)}}
+ {{/for}}
+ |
+
+
+ | Security |
+
+ {{for data.security_jobs}}
+ {{:helper.link(value.display_name, '', {'choice' : 'assign', 'assign_target' : value.job}, data.target_rank == value.job ? 'disabled' : null)}}
+ {{/for}}
+ |
+
+
+ | Civilian |
+
+ {{for data.civilian_jobs}}
+ {{if index && index % 6 === 0}}
+ |
|
+ {{/if}}
+ {{:helper.link(value.display_name, '', {'choice' : 'assign', 'assign_target' : value.job}, data.target_rank == value.job ? 'disabled' : null)}}
+ {{/for}}
+ |
+
+ {{if data.centcom_access}}
+
+ | CentCom |
+
+ {{for data.centcom_jobs}}
+ {{if index % 6 === 0}}
+ |
|
+ {{/if}}
+
+ {{:helper.link(value.display_name, '', {'choice' : 'assign', 'assign_target' : value.job}, data.target_rank == value.job ? 'disabled' : null)}}
+ {{/for}}
+ |
+
+ {{/if}}
+
+
+
+
+ {{if data.centcom_access}}
+
+
Central Command
+
+
+ {{for data.all_centcom_access}}
+
+ {{:helper.link(value.desc, '', {'choice' : 'access', 'access_target' : value.ref, 'allowed' : value.allowed}, null, value.allowed ? 'selected' : null)}}
+
+ {{/for}}
+
+ {{else}}
+
+
{{:data.station_name}}
+
+
+ {{for data.regions}}
+
+
{{:value.name}}
+ {{for value.accesses :accessValue:accessKey}}
+
+ {{:helper.link(accessValue.desc, '', {'choice' : 'access', 'access_target' : accessValue.ref, 'allowed' : accessValue.allowed}, null, accessValue.allowed ? 'selected' : null)}}
+
+ {{/for}}
+
+ {{/for}}
+
+ {{/if}}
+ {{/if}}
+ {{/if}}
+ {{/if}}
+{{/if}}
diff --git a/nano/templates/isolation_centrifuge.tmpl b/nano/templates/isolation_centrifuge.tmpl
index 1c201ff9..4ff0272d 100644
--- a/nano/templates/isolation_centrifuge.tmpl
+++ b/nano/templates/isolation_centrifuge.tmpl
@@ -1,45 +1,45 @@
- {{:~link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}}
- {{:~link('Print', 'print', { 'print' : 1 }, antibodies || pathogens ? null : 'disabled', 'fixedLeft')}}
+ {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}}
+ {{:helper.link('Print', 'print', { 'print' : 1 }, data.antibodies || data.pathogens ? null : 'disabled', 'fixedLeft')}}
-{{if busy}}
+{{if data.busy}}
The Centrifuge is currently busy.
-
{{:busy}}
+ {{:data.busy}}
Thank you for your patience!
{{else}}
-
{{:is_antibody_sample ? 'Antibody Sample' : 'Blood Sample'}}
+ {{:data.is_antibody_sample ? 'Antibody Sample' : 'Blood Sample'}}
- {{:~link('Eject Vial', 'eject', { 'action' : 'sample' }, sample_inserted ? null : 'disabled')}}
+ {{:helper.link('Eject Vial', 'eject', { 'action' : 'sample' }, data.sample_inserted ? null : 'disabled')}}
- {{if sample_inserted}}
- {{if antibodies || pathogens}}
+ {{if data.sample_inserted}}
+ {{if data.antibodies || data.pathogens}}
- {{if antibodies}}
+ {{if data.antibodies}}
Antibodies:
- {{:antibodies}}
+ {{:data.antibodies}}
{{/if}}
- {{if pathogens}}
+ {{if data.pathogens}}
Pathogens:
- {{for pathogens}}
+ {{for data.pathogens}}
- {{:name}} ({{:spread_type}})
+ {{:value.name}} ({{:value.spread_type}})
{{/for}}
@@ -56,24 +56,24 @@
No vial detected.
{{/if}}
- {{if antibodies && !is_antibody_sample}}
+ {{if data.antibodies && !data.is_antibody_sample}}
Isolate Antibodies:
- {{:~link(antibodies, 'pencil', { 'action' : 'antibody' })}}
+ {{:helper.link(data.antibodies, 'pencil', { 'action' : 'antibody' })}}
{{/if}}
- {{if pathogens}}
+ {{if data.pathogens}}
Isolate Strain:
- {{for pathogens}}
- {{:~link(name, 'pencil', { 'isolate' : reference })}}
+ {{for data.pathogens}}
+ {{:helper.link(value.name, 'pencil', { 'isolate' : value.reference })}}
{{/for}}
diff --git a/nano/templates/layout_basic.tmpl b/nano/templates/layout_basic.tmpl
new file mode 100644
index 00000000..67fcd51f
--- /dev/null
+++ b/nano/templates/layout_basic.tmpl
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/nano/templates/layout_default.tmpl b/nano/templates/layout_default.tmpl
new file mode 100644
index 00000000..ec3e225b
--- /dev/null
+++ b/nano/templates/layout_default.tmpl
@@ -0,0 +1,30 @@
+
+
+
+
+
+

+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nano/templates/multi_docking_console.tmpl b/nano/templates/multi_docking_console.tmpl
new file mode 100644
index 00000000..95157996
--- /dev/null
+++ b/nano/templates/multi_docking_console.tmpl
@@ -0,0 +1,37 @@
+
+
+
+ Docking Port Status:
+
+
+ {{if data.docking_status == "docked"}}
+ DOCKED
+ {{else data.docking_status == "docking"}}
+ DOCKING
+ {{else data.docking_status == "undocking"}}
+ UNDOCKING
+ {{else data.docking_status == "undocked"}}
+ NOT IN USE
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+
+{{for data.airlocks}}
+
+
+
+ {{:value.name}}
+
+
+ {{if value.override_enabled}}
+ OVERRIDE ENABLED
+ {{else}}
+ STATUS OK
+ {{/if}}
+
+
+
+{{/for}}
\ No newline at end of file
diff --git a/nano/templates/omni_filter.tmpl b/nano/templates/omni_filter.tmpl
new file mode 100644
index 00000000..731340db
--- /dev/null
+++ b/nano/templates/omni_filter.tmpl
@@ -0,0 +1,86 @@
+
+
+ {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'})}}
+
+
+ {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}}
+
+
+ {{if data.config}}
+
+
+
+
Port
+ {{for data.ports}}
+
{{:value.dir}} Port
+ {{/for}}
+
+
+
Input
+ {{for data.ports}}
+
+ {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, null, value.input ? 'selected' : null)}}
+
+ {{/for}}
+
+
+
Output
+ {{for data.ports}}
+
+ {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}}
+
+ {{/for}}
+
+
+
Filter
+ {{for data.ports}}
+
+ {{:helper.link(value.f_type ? value.f_type : 'None', null, {'command' : 'switch_filter', 'mode' : value.f_type, 'dir' : value.dir}, value.filter ? null : 'disabled', value.f_type ? 'selected' : null)}}
+
+ {{/for}}
+
+
+
+
+ Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s
+
+
+ {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}}
+
+
+ {{else}}
+
+
+
+
Port
+ {{for data.ports}}
+
{{:value.dir}} Port
+ {{/for}}
+
+
+
Mode
+ {{for data.ports}}
+
+ {{if value.input}}
+ Input
+ {{else value.output}}
+ Output
+ {{else value.f_type}}
+ {{:value.f_type}}
+ {{else}}
+ Disabled
+ {{/if}}
+
+ {{/for}}
+
+
+
+
+ Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s
+
+
+
+ Flow Rate: {{:(data.last_flow_rate/10)}} L/s
+
+ {{/if}}
+
\ No newline at end of file
diff --git a/nano/templates/omni_mixer.tmpl b/nano/templates/omni_mixer.tmpl
new file mode 100644
index 00000000..770af7fc
--- /dev/null
+++ b/nano/templates/omni_mixer.tmpl
@@ -0,0 +1,101 @@
+
+
+ {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'})}}
+
+
+ {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}}
+
+
+ {{if data.config}}
+
+
+
+
Port
+ {{for data.ports}}
+
{{:value.dir}} Port
+ {{/for}}
+
+
+
Input
+ {{for data.ports}}
+
+ {{:helper.link(' ', null, value.input ? {'command' : 'switch_mode', 'mode' : 'none', 'dir' : value.dir} : {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, value.output ? 'disabled' : null, value.input ? 'selected' : null)}}
+
+ {{/for}}
+
+
+
Output
+ {{for data.ports}}
+
+ {{:helper.link(' ', null, value.output ? null : {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}}
+
+ {{/for}}
+
+
+
Concentration
+ {{for data.ports}}
+
+ {{:helper.link( value.input ? helper.round(value.concentration*100)+' %' : '-', null, {'command' : 'switch_con', 'dir' : value.dir}, value.input ? null : 'disabled')}}
+
+ {{/for}}
+
+
+
Lock
+ {{for data.ports}}
+
+ {{:helper.link(' ', value.con_lock ? 'locked' : 'unlocked', {'command' : 'switch_conlock', 'dir' : value.dir}, value.input ? null : 'disabled', value.con_lock ? 'selected' : null)}}
+
+ {{/for}}
+
+
+
+
+ Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s
+
+
+ {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}}
+
+
+ {{else}}
+
+
+
+
Port
+ {{for data.ports}}
+
{{:value.dir}} Port
+ {{/for}}
+
+
+
Mode
+ {{for data.ports}}
+
+ {{if value.input}}
+ Input
+ {{else value.output}}
+ Output
+ {{else}}
+ Disabled
+ {{/if}}
+
+ {{/for}}
+
+
+
Concentration
+ {{for data.ports}}
+
+ {{if value.input}}
+ {{:helper.round(value.concentration*100)}} %
+ {{else}}
+ -
+ {{/if}}
+
+ {{/for}}
+
+
+
+
+ Flow Rate: {{:(data.last_flow_rate/10)}} L/s
+
+
+ {{/if}}
+
\ No newline at end of file
diff --git a/nano/templates/pathogenic_isolator.tmpl b/nano/templates/pathogenic_isolator.tmpl
index ad88151c..4c46f9b1 100644
--- a/nano/templates/pathogenic_isolator.tmpl
+++ b/nano/templates/pathogenic_isolator.tmpl
@@ -2,17 +2,17 @@
Menu
- {{if !isolating}}
- {{:~link('Home', 'home', {'home' : 1}, state == 'home' ? 'disabled' : null, 'fixedLeft')}}
- {{:~link('List', 'note', {'list' : 1}, state == 'list' ? 'disabled' : null, 'fixedLeft')}}
- {{:~link('Pathogen', 'folder-open', {'entry' : 1}, state == 'entry' ? 'disabled' : null, 'fixedLeft')}}
+ {{if !data.isolating}}
+ {{:helper.link('Home', 'home', {'home' : 1}, data.state == 'home' ? 'disabled' : null, 'fixedLeft')}}
+ {{:helper.link('List', 'note', {'list' : 1}, data.state == 'list' ? 'disabled' : null, 'fixedLeft')}}
+ {{:helper.link('Pathogen', 'folder-open', {'entry' : 1}, data.state == 'entry' ? 'disabled' : null, 'fixedLeft')}}
{{/if}}
- {{:~link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}}
- {{:~link('Print', 'print', { 'print' : 1 }, can_print ? null : 'disabled', 'fixedLeft')}}
+ {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}}
+ {{:helper.link('Print', 'print', { 'print' : 1 }, data.can_print ? null : 'disabled', 'fixedLeft')}}
-{{if isolating}}
+{{if data.isolating}}
The Isolator is currently busy.
Isolating pathogens...
@@ -21,22 +21,22 @@
Thank you for your patience!
{{else}}
- {{if state =="home"}}
+ {{if data.state =="home"}}
Blood Sample
- {{:~link('Eject Syringe', 'eject', { 'eject' : 1 }, syringe_inserted ? null : 'disabled')}}
+ {{:helper.link('Eject Syringe', 'eject', { 'eject' : 1 }, data.syringe_inserted ? null : 'disabled')}}
- {{if syringe_inserted}}
+ {{if data.syringe_inserted}}
Pathogens:
- {{if pathogen_pool}}
- {{for pathogen_pool}}
+ {{if data.pathogen_pool}}
+ {{for data.pathogen_pool}}
- {{:#index + 1}}. #{{:unique_id}} {{:is_in_database ? "(Analysed)" : ""}}
- {{:name}}: {{:dna}}
+ {{:index + 1}}. #{{:value.unique_id}} {{:value.is_in_database ? "(Analysed)" : ""}}
+ {{:value.name}}: {{:value.dna}}
{{/for}}
{{else}}
@@ -48,14 +48,14 @@
No syringe loaded.
{{/if}}
- {{if pathogen_pool}}
+ {{if data.pathogen_pool}}
Isolate Pathogens:
- {{for pathogen_pool}}
- {{:~link('#' + unique_id, 'pencil', { 'isolate' : reference }, null, 'fixedLeft')}}
+ {{for data.pathogen_pool}}
+ {{:helper.link('#' + value.unique_id, 'pencil', { 'isolate' : value.reference }, null, 'fixedLeft')}}
{{/for}}
@@ -64,25 +64,25 @@
Database Lookup:
- {{for pathogen_pool}}
- {{if is_in_database}}
- {{:~link('#' + unique_id, 'info', { 'entry' : 1, 'view' : record }, null, 'fixedLeft')}}
+ {{for data.pathogen_pool}}
+ {{if value.is_in_database}}
+ {{:helper.link('#' + value.unique_id, 'info', { 'entry' : 1, 'view' : value.record }, null, 'fixedLeft')}}
{{/if}}
{{/for}}
{{/if}}
{{else}}
- {{if state == "list"}}
+ {{if data.state == "list"}}
View Database
- {{if database}}
- {{for database}}
+ {{if data.database}}
+ {{for data.database}}
-
{{:name}}
- {{:~link('Details', 'circle-arrow-s', { 'entry' : 1, 'view' : record }, null, 'fixedLeft')}}
+
{{:data.name}}
+ {{:helper.link('Details', 'circle-arrow-s', { 'entry' : 1, 'view' : value.record }, null, 'fixedLeft')}}
{{/for}}
{{else}}
@@ -90,13 +90,13 @@
{{/if}}
{{else}}
- {{if state == "entry"}}
- {{if entry}}
+ {{if data.state == "entry"}}
+ {{if data.entry}}
-
{{:entry.name}}
+ {{:data.entry.name}}
- {{:entry.description}}
+ {{:data.entry.description}}
{{else}}
No virus selected.
diff --git a/nano/templates/pda.tmpl b/nano/templates/pda.tmpl
index 3a2dff64..5df27d9e 100644
--- a/nano/templates/pda.tmpl
+++ b/nano/templates/pda.tmpl
@@ -1,18 +1,18 @@
-
-{{if owner}}
+{{if data.owner}}
Functions:
-
- {{:~link('Close', 'gear', {'choice' : "Close"}, null, 'fixedLeft')}}
- {{if idInserted}} {{:~link('Update PDA Info', 'eject', {'choice' : "UpdateInfo"}, null, 'fixedLeftWide')}} {{/if}}
- {{if mode != 0}} {{:~link('Return', 'arrowreturn-1-w', {'choice' : "Return"}, null, 'fixedLeft')}} {{/if}}
+
+ {{:helper.link('Close', 'gear', {'choice' : "Close"}, null, 'fixedLeft')}}
+ {{if data.idInserted}} {{:helper.link('Update PDA Info', 'eject', {'choice' : "UpdateInfo"}, null, 'fixedLeftWide')}} {{/if}}
+ {{if data.mode != 0}} {{:helper.link('Return', 'arrowreturn-1-w', {'choice' : "Return"}, null, 'fixedLeft')}} {{/if}}
@@ -21,913 +21,936 @@ Used In File(s): \code\game\objects\items\devices\PDA\PDA.dm
Station Time:
- {{:stationTime}}
+ {{:data.stationTime}}
- {{if mode == 0}}
-
-
- Owner:
-
-
- {{:owner}}, {{:ownjob}}
-
-
-
-
-
- ID:
-
-
- {{:~link(idLink, 'eject', {'choice' : "Authenticate"}, idInserted ? null : 'disabled', idInserted ? 'fixedLeftWidest' : 'fixedLeft')}}
-
-
-
-
-
- Cartridge:
-
-
- {{if cart_loaded==1}}
- {{:~link(cartridge.name, 'eject', {'choice' : "Eject"},null,null)}}
- {{else}}
- {{:~link('None', 'eject', {'choice' : "Eject"},'disabled',null)}}
- {{/if}}
-
-
-
-
Functions
-
-
-
- General:
-
-
- {{:~link('Notekeeper', 'note', {'choice' : "1"}, null, 'fixedLeftWide')}}
- {{:~link('Messenger', newMessage ? 'mail-closed' : 'mail-open', {'choice' : "2"}, null, 'fixedLeftWide')}}
- {{:~link('Crew Manifest', 'contact', {'choice' : "41"}, null, 'fixedLeftWide')}}
-
-
-
- {{if cartridge}}
- {{if cartridge.access.access_clown == 1}}
+
+
+ {{if data.mode == 0}}
-
- Clown:
-
-
- {{:~link('Honk Synthesizer', 'gear', {'choice' : "Honk"}, null, 'fixedLeftWide')}}
-
-
-
- {{/if}}
- {{if cartridge.access.access_engine == 1}}
-
-
- Engineering:
-
-
- {{:~link('Power Monitor', 'alert', {'choice' : "43"}, null, 'fixedLeftWide')}}
-
-
-
- {{/if}}
- {{if cartridge.access.access_medical == 1}}
-
-
- Medical:
-
-
- {{:~link('Medical Records', 'gear', {'choice' : "44"}, null, 'fixedLeftWide')}}
- {{:~link(scanmode == 1 ? 'Disable Med Scanner' : 'Enable Med Scanner', 'gear', {'choice' : "Medical Scan"}, null , 'fixedLeftWide')}}
-
-
-
- {{/if}}
- {{if cartridge.access.access_security == 1}}
-
-
- Security:
-
-
- {{:~link('Security Records', 'gear', {'choice' : "45"}, null, 'fixedLeftWide')}}
- {{if cartridge.radio ==1}} {{:~link('Security Bot Access', 'gear', {'choice' : "46"}, null, 'fixedLeftWide')}} {{/if}}
-
-
-
-
- {{/if}}
- {{if cartridge.access.access_quartermaster == 1}}
-
-
- Quartermaster:
-
-
- {{:~link('Supply Records', 'gear', {'choice' : "47"}, null, 'fixedLeftWide')}}
- {{if cartridge.radio == 3}} {{:~link('Delivery Bot Control', 'gear', {'choice' : "48"}, null, 'fixedLeftWide')}} {{/if}}
-
-
-
-
- {{/if}}
- {{/if}}
-
-
-
- Utilities:
-
-
- {{if cartridge}}
- {{if cartridge.access.access_status_display == 1}} {{:~link('Status Display', 'gear', {'choice' : "42"}, null, 'fixedLeftWide')}}{{/if}}
- {{if cartridge.access.access_janitor==1}} {{:~link('Custodial Locator', 'gear', {'choice' : "49"}, null, 'fixedLeftWide')}} {{/if}}
- {{if cartridge.radio == 2}} {{:~link('Signaler System', 'gear', {'choice' : "40"}, null, 'fixedLeftWide')}} {{/if}}
- {{if cartridge.access.access_reagent_scanner==1}} {{:~link(scanmode == 3 ? 'Disable Reagent Scanner' : 'Enable Reagent Scanner', 'gear', {'choice' : "Reagent Scan"}, null, 'fixedLeftWider')}} {{/if}}
- {{if cartridge.access.access_engine==1}} {{:~link(scanmode == 4 ? 'Disable Halogen Counter' : 'Enable Halogen Counter', 'gear', {'choice' : "Halogen Counter"}, null, 'fixedLeftWider')}} {{/if}}
- {{if cartridge.access.access_atmos==1}} {{:~link(scanmode == 5 ? 'Disable Gas Scanner' : 'Enable Gas Scanner', 'gear', {'choice' : "Gas Scan"}, null, 'fixedLeftWide')}} {{/if}}
- {{if cartridge.access.access_remote_door==1}}{{:~link('Toggle Door', 'gear', {'choice' : "Toggle Door"}, null, 'fixedLeftWide')}} {{/if}}
- {{/if}}
- {{:~link('Atmospheric Scan', 'gear', {'choice' : "3"}, null, 'fixedLeftWide')}}
- {{:~link(fon==1 ? 'Disable Flashlight' : 'Enable Flashlight', 'lightbulb', {'choice' : "Light"}, null,'fixedLeftWide')}}
-
-
- {{if pai}}
-
-
- PAI Utilities:
-
-
- {{:~link('Configuration', 'gear', {'choice' : "pai", 'option' : "1"}, null, 'fixedLeft')}}
- {{:~link('Eject pAI', 'eject', {'choice' : "pai", 'option' : "2"}, null, 'fixedLeft')}}
-
-
- {{/if}}
- {{/if}}
- {{if mode == 1}}
-
-
-
-
- {{:~link('Edit Notes', 'gear', {'choice' : "Edit"}, null, 'fixedLeft')}}
-
-
-
-
- {{else mode == 2}}
-
SpaceMessenger V4.0.1
-
-
- Messenger Functions:
-
-
-
- {{:~link(silent==1 ? 'Ringer: Off' : 'Ringer: On', silent==1 ? 'volume-off' : 'volume-on', {'choice' : "Toggle Ringer"}, null, 'fixedLeftWide')}}
- {{:~link(toff==1 ? 'Messenger: Off' : 'Messenger: On',toff==1 ? 'close':'check', {'choice' : "Toggle Messenger"}, null, 'fixedLeftWide')}}
- {{:~link('Set Ringtone', 'comment', {'choice' : "Ringtone"}, null, 'fixedLeftWide')}}
- {{:~link('Delete all Conversations', 'trash', {'choice' : "Clear", 'option' : "All"}, null, 'fixedLeftWider')}}
-
-
- {{if toff == 0}}
-
- {{if cartridge}}
- {{if cartridge.charges}}
-
- {{:cartridge.charges}}
- {{if cartridge.type == "/obj/item/weapon/cartridge/syndicate"}} detonation charges left. {{/if}}
- {{if cartridge.type == "/obj/item/weapon/cartridge/clown" || cartridge.type == "/obj/item/weapon/cartridge/mime"}} viral files left. {{/if}}
-
-
- {{/if}}
- {{/if}}
-
- {{if pda_count == 0}}
No other PDAS located
- {{else}}
-
Current Conversations
- {{for convopdas}}
-
- {{:~link(Name, 'circle-arrow-s', {'choice' : "Select Conversation", 'convo' : Reference } , null, fixedLeftWider)}}
- {{if ~root.cartridge}}
- {{if ~root.cartridge.type == "/obj/item/weapon/cartridge/syndicate" && Detonate == 1}} {{:~link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
- {{if ~root.cartridge.type == "/obj/item/weapon/cartridge/clown"}} {{:~link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
- {{if ~root.cartridge.type == "/obj/item/weapon/cartridge/mime"}} {{:~link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
- {{/if}}
-
- {{/for}}
-
Other PDAs
- {{for pdas}}
-
- {{:~link(Name, 'circle-arrow-s', {'choice' : "Message", 'target' : Reference}, null, fixedLeftWider)}}
- {{if ~root.cartridge}}
- {{if ~root.cartridge.type == "/obj/item/weapon/cartridge/syndicate" && Detonate == 1}} {{:~link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
- {{if ~root.cartridge.type == "/obj/item/weapon/cartridge/clown"}} {{:~link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
- {{if ~root.cartridge.type == "/obj/item/weapon/cartridge/mime"}} {{:~link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : Reference}, null, 'fixedLeft')}} {{/if}}
- {{/if}}
-
- {{/for}}
- {{/if}}
- {{/if}}
-
- {{else mode == 21}}
-
SpaceMessenger V4.0.1
-
-
- Messenger Functions:
-
-
-
- {{:~link('Delete Conversation', 'trash', {'choice' : "Clear", 'option' : "Convo"}, null, 'fixedLeftWide')}}
-
-
-
-
Conversation with: {{:convo_name}} ({{:convo_job}})
-
-
-
- {{for messages}}
- {{if ~root.active_conversation == target}}
- {{if sent==0}}
- Them: {{:message}}
- {{else}}
- You: {{:message}}
- {{/if}}
- {{/if}}
- {{/for}}
-
-
-
-
- {{:~link('Reply', 'comment', {'choice' : "Message", 'target': active_conversation}, null, 'fixedLeft')}}
-
- {{else mode== 41}}
-
-
- {{if manifest.heads.length}}
- | Command |
- {{for manifest["heads"]}}
- {{if rank == "Captain"}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{else}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{/if}}
- {{/for}}
- {{/if}}
- {{if manifest.sec.length}}
- | Security |
- {{for manifest["sec"]}}
- {{if rank == "Head of Security"}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{else}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{/if}}
- {{/for}}
- {{/if}}
- {{if manifest.eng.length}}
- | Engineering |
- {{for manifest["eng"]}}
- {{if rank == "Chief Engineer"}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{else}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{/if}}
-
- {{/for}}
- {{/if}}
- {{if manifest.med.length}}
- | Medical |
- {{for manifest["med"]}}
- {{if rank == "Chief Medical Officer"}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{else}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{/if}}
- {{/for}}
- {{/if}}
- {{if manifest.sci.length}}
- | Science |
- {{for manifest["sci"]}}
- {{if rank == "Research Director"}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{else}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{/if}}
- {{/for}}
- {{/if}}
- {{if manifest.civ.length}}
- | Civilian |
- {{for manifest["civ"]}}
- {{if rank == "Head of Personnel"}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{else}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{/if}}
- {{/for}}
- {{/if}}
- {{if manifest.misc.length}}
- | Misc |
- {{for manifest["misc"]}}
- | {{:name}} | {{:rank}} | {{:active}} |
- {{/for}}
- {{/if}}
-
-
-
-
- {{else mode == 3}}
-
-
Atmospheric Scan
-
-
- {{if aircontents.reading == 1}}
-
- Pressure:
-
-
- {{:~string('{1} kPa', aircontents.pressure < 80 || aircontents.pressure > 120 ? 'bad' : aircontents.pressure < 95 || aircontents.pressure > 110 ? 'average' : 'good' , aircontents.pressure)}}
-
-
- Temperature:
-
-
- {{:~string('{1} °C', aircontents.temp < 5 || aircontents.temp > 35 ? 'bad' : aircontents.temp < 15 || aircontents.temp > 25 ? 'average' : 'good' , aircontents.temp)}}
-
-
-
- Oxygen:
-
-
- {{:~string('{1}%', aircontents.oxygen < 17 ? 'bad' : aircontents.oxygen < 19 ? 'average' : 'good' , aircontents.oxygen)}}
-
-
- Nitrogen:
-
-
- {{:~string('{1}%', aircontents.nitrogen > 82 ? 'bad' : aircontents.nitrogen > 80 ? 'average' : 'good' , aircontents.nitrogen)}}
-
-
- Carbon Dioxide:
-
-
- {{:~string('{1}%', aircontents.carbon_dioxide > 5 ? 'bad' : 'good' , aircontents.carbon_dioxide)}}
-
-
- Plasma:
-
-
- {{:~string('{1}%', aircontents.plasma > 0 ? 'bad' : 'good' , aircontents.plasma)}}
-
-
- {{if aircontents.other > 0}}
-
- Unknown:
-
-
- {{:aircontents.other}}%
-
- {{/if}}
- {{else}}
-
- Unable to get air reading
-
- {{/if}}
-
-
-
- {{else mode == 40}}
-
Remote Signaling System
-
-
- Frequency:
-
-
- {{:records.signal_freq}}
-
- {{:~link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-10"}, null, null)}}
- {{:~link('-.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-2"}, null, null)}}
-
- {{:~link('+.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "2"}, null, null)}}
- {{:~link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "10"}, null, null)}}
-
-
-
-
-
- Code:
-
-
-
- {{:records.signal_code}}
-
- {{:~link('-5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-5"}, null, null)}}
- {{:~link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-1"}, null, null)}}
- {{:~link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "1"}, null, null)}}
- {{:~link('+5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "5"}, null, null)}}
-
-
-
- {{:~link('Send Signal', 'radiation', {'cartmenu' : "1", 'choice' : "Send Signal"}, null, null)}}
-
-
- {{else mode == 42}}
-
Station Status Displays Interlink
-
-
- Code:
-
-
- {{:~link('Clear', 'trash', {'cartmenu' : "1", 'choice' : "Status", 'statdisp' : "blank"}, null, null)}}
- {{:~link('Shuttle ETA', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "shuttle"}, null, null)}}
- {{:~link('Message', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "message"}, null, null)}}
-
-
-
-
-
- Message line 1
-
-
- {{:~link(records.message1 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg1"}, null, null)}}
-
-
-
-
- Message line 2
-
-
- {{:~link(records.message2 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg2"}, null, null)}}
-
-
-
-
-
-
- ALERT!:
-
-
- {{:~link('None', 'alert', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "default"}, null, null)}}
- {{:~link('Red Alert', 'alert', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "redalert"}, null, null)}}
- {{:~link('Lockdown', 'caution', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "lockdown"}, null, null)}}
- {{:~link('Biohazard', 'radiation', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "biohazard"}, null, null)}}
-
-
-
- {{else mode == 43}}
-
-
Station Powermonitors
-
- Select A power monitor:
-
- {{for records.powermonitors}}
-
- {{:~link(Name, 'radiation', {'cartmenu' : "1", 'choice' : "Power Select",'target' : ref}, null, null)}}
-
- {{/for}}
-
- {{else mode == 433}}
-
Powernet Status
-
-
- Current Load:
-
-
- {{:records.powerload}} W
-
-
-
-
- Total Power:
-
-
- {{:records.poweravail}} W
-
-
-
-
-
- {{for records.apcs}}
- {{if #index % 20 === 0}}
- | Area | Eqp. | Lgt. | Env | Cell |
- {{/if}}
-
- | {{:Name}} |
- {{:~string(' | ', Equipment==1 ? '#4f7529' : '#8f1414')}}
- {{:~string(' | ', Lights==1 ? '#4f7529' : '#8f1414')}}
- {{:~string(' | ', Environment==1 ? '#4f7529' : '#8f1414')}}
- {{:~string('{1} | ', CellStatus==1 ? '#4f7529' : '#8f1414', CellStatus==-1 ? 'No Cell' : CellPct + '%')}}
-
- {{/for}}
-
-
-
- {{else mode == 44}}
-
Medical Record List
-
- Select A record
-
-
- {{for records.medical_records}}
-
- {{:~link(Name, 'gear', {'cartmenu' : "1", 'choice' : "Medical Records",'target' : ref}, null, null)}}
-
- {{/for}}
-
-
-
- {{else mode == 441}}
-
Medical Record
-
-
-
- {{if records.general_exists == 1}}
- Name: {{:records.general.name}}
- Sex: {{:records.general.sex}}
- Species: {{:records.general.species}}
- Age: {{:records.general.age}}
- Rank: {{:records.general.rank}}
- Fingerprint: {{:records.general.fingerprint}}
- Physical Status: {{:records.general.p_stat}}
- Mental Status: {{:records.general.m_stat}}
- {{else}}
-
- General Record Lost!
-
- {{/if}}
- {{if records.medical_exists == 1}}
- Medical Data:
- Blood Type: {{:records.medical.b_type}}
- Minor Disabilities: {{:records.medical.mi_dis}}
- Details: {{:records.medical.mi_dis_d}}
- Major Disabilities: {{:records.medical.ma_dis}}
- Details: {{:records.medical.ma_dis_d}}
- Allergies: {{:records.medical.alg}}
- Details: {{:records.medical.alg_d}}
- Current Disease: {{:records.medical.cdi}}
- Details: {{:records.medical.alg_d}}
- Important Notes: {{:records.medical.notes}}
- {{else}}
-
- Medical Record Lost!
-
- {{/if}}
-
-
-
-
-
- {{else mode == 45}}
-
Security Record List
-
- Select A record
+
+ Owner:
+
+
+ {{:data.owner}}, {{:data.ownjob}}
+
- {{for records.security_records}}
- {{:~link(Name, 'gear', {'cartmenu' : "1", 'choice' : "Security Records",'target' : ref}, null, null)}}
+
+ ID:
+
+
+ {{:helper.link(data.idLink, 'eject', {'choice' : "Authenticate"}, data.idInserted ? null : 'disabled', data.idInserted ? 'floatright' : 'fixedLeft')}}
+
- {{/for}}
-
-
-
- {{else mode == 451}}
-
Security Record
-
-
-
- {{if records.general_exists == 1}}
-
Name: {{:records.general.name}}
-
Sex: {{:records.general.sex}}
-
Species: {{:records.general.species}}
-
Age: {{:records.general.age}}
-
Rank: {{:records.general.rank}}
-
Fingerprint: {{:records.general.fingerprint}}
-
Physical Status: {{:records.general.p_stat}}
-
Mental Status: {{:records.general.m_stat}}
+
+
+
+ Cartridge:
+
+
+ {{if data.cart_loaded==1}}
+ {{:helper.link(data.cartridge.name, 'eject', {'choice' : "Eject"},null,null)}}
{{else}}
-
- General Record Lost!
-
+ {{:helper.link('None', 'eject', {'choice' : "Eject"},'disabled',null)}}
{{/if}}
- {{if records.security_exists == 1}}
- Security Data:
- Criminal Status: {{:records.security.criminal}}
- Minor Crimes: {{:records.security.mi_crim}}
- Details: {{:records.security.mi_crim_d}}
- Major Crimes: {{:records.security.ma_crim}}
- Details: {{:records.security.ma_crim_d}}
- Important Notes: {{:records.security.notes}}
- {{else}}
-
- Security Record Lost!
-
- {{/if}}
-
-
+
- {{else mode == 46}}
-
Security Bot Control
- {{if records.beepsky.active == null || records.beepsky.active == 0}}
- {{if records.beepsky.count == 0}}
+
+
Functions
+
+
+
+ General:
+
+
+ {{:helper.link('Notekeeper', 'note', {'choice' : "1"}, null, 'fixedLeftWide')}}
+ {{:helper.link('Messenger', data.newMessage ? 'mail-closed' : 'mail-open', {'choice' : "2"}, null, 'fixedLeftWide')}}
+ {{:helper.link('Crew Manifest', 'contact', {'choice' : "41"}, null, 'fixedLeftWide')}}
+
+
+
+ {{if data.cartridge}}
+ {{if data.cartridge.access.access_clown == 1}}
+
+
+ Clown:
+
+
+ {{:helper.link('Honk Synthesizer', 'gear', {'choice' : "Honk"}, null, 'fixedLeftWide')}}
+
+
+
+ {{/if}}
+ {{if data.cartridge.access.access_engine == 1}}
+
+
+ Engineering:
+
+
+ {{:helper.link('Power Monitor', 'alert', {'choice' : "43"}, null, 'fixedLeftWide')}}
+
+
+
+ {{/if}}
+ {{if data.cartridge.access.access_medical == 1}}
+
+
+ Medical:
+
+
+ {{:helper.link('Medical Records', 'gear', {'choice' : "44"}, null, 'fixedLeftWide')}}
+ {{:helper.link(data.scanmode == 1 ? 'Disable Med Scanner' : 'Enable Med Scanner', 'gear', {'choice' : "Medical Scan"}, null , 'fixedLeftWide')}}
+
+
+
+ {{/if}}
+ {{if data.cartridge.access.access_security == 1}}
+
+
+ Security:
+
+
+ {{:helper.link('Security Records', 'gear', {'choice' : "45"}, null, 'fixedLeftWide')}}
+ {{if data.cartridge.radio ==1}} {{:helper.link('Security Bot Access', 'gear', {'choice' : "46"}, null, 'fixedLeftWide')}} {{/if}}
+
+
+
+
+ {{/if}}
+ {{if data.cartridge.access.access_quartermaster == 1}}
+
+
+ Quartermaster:
+
+
+ {{:helper.link('Supply Records', 'gear', {'choice' : "47"}, null, 'fixedLeftWide')}}
+ {{if data.cartridge.radio == 3}} {{:helper.link('Delivery Bot Control', 'gear', {'choice' : "48"}, null, 'fixedLeftWide')}} {{/if}}
+
+
+
+
+ {{/if}}
+ {{/if}}
+
+
+
+ Utilities:
+
+
+ {{if data.cartridge}}
+ {{if data.cartridge.access.access_status_display == 1}}
+ {{:helper.link('Status Display', 'gear', {'choice' : "42"}, null, 'fixedLeftWide')}}
+ {{/if}}
+ {{if data.cartridge.access.access_janitor==1}}
+ {{:helper.link('Custodial Locator', 'gear', {'choice' : "49"}, null, 'fixedLeftWide')}}
+ {{/if}}
+ {{if data.cartridge.radio == 2}}
+ {{:helper.link('Signaler System', 'gear', {'choice' : "40"}, null, 'fixedLeftWide')}}
+ {{/if}}
+ {{if data.cartridge.access.access_reagent_scanner==1}}
+ {{:helper.link(data.scanmode == 3 ? 'Disable Reagent Scanner' : 'Enable Reagent Scanner', 'gear', {'choice' : "Reagent Scan"}, null, 'fixedLeftWider')}}
+ {{/if}}
+ {{if data.cartridge.access.access_engine==1}}
+ {{:helper.link(data.scanmode == 4 ? 'Disable Halogen Counter' : 'Enable Halogen Counter', 'gear', {'choice' : "Halogen Counter"}, null, 'fixedLeftWider')}}
+ {{/if}}
+ {{if data.cartridge.access.access_atmos==1}}
+ {{:helper.link(data.scanmode == 5 ? 'Disable Gas Scanner' : 'Enable Gas Scanner', 'gear', {'choice' : "Gas Scan"}, null, 'fixedLeftWide')}}
+ {{/if}}
+ {{if data.cartridge.access.access_remote_door==1}}
+ {{:helper.link('Toggle Door', 'gear', {'choice' : "Toggle Door"}, null, 'fixedLeftWide')}}
+ {{/if}}
+ {{/if}}
+ {{:helper.link('Atmospheric Scan', 'gear', {'choice' : "3"}, null, 'fixedLeftWide')}}
+ {{:helper.link(data.fon==1 ? 'Disable Flashlight' : 'Enable Flashlight', 'lightbulb', {'choice' : "Light"}, null,'fixedLeftWide')}}
+
+
+ {{if data.pai}}
+
+
+ PAI Utilities:
+
+
+ {{:helper.link('Configuration', 'gear', {'choice' : "pai", 'option' : "1"}, null, 'fixedLeft')}}
+ {{:helper.link('Eject pAI', 'eject', {'choice' : "pai", 'option' : "2"}, null, 'fixedLeft')}}
+
+
+ {{/if}}
+
+
+ {{else data.mode == 1}}
+
+
+
+
+ {{:helper.link('Edit Notes', 'gear', {'choice' : "Edit"}, null, 'fixedLeft')}}
+
+
+
+
+ {{else data.mode == 2}}
+
SpaceMessenger V4.0.1
+
+
+ Messenger Functions:
+
+
+ {{:helper.link(data.silent==1 ? 'Ringer: Off' : 'Ringer: On', data.silent==1 ? 'volume-off' : 'volume-on', {'choice' : "Toggle Ringer"}, null, 'fixedLeftWide')}}
+ {{:helper.link(data.toff==1 ? 'Messenger: Off' : 'Messenger: On',data.toff==1 ? 'close':'check', {'choice' : "Toggle Messenger"}, null, 'fixedLeftWide')}}
+ {{:helper.link('Set Ringtone', 'comment', {'choice' : "Ringtone"}, null, 'fixedLeftWide')}}
+ {{:helper.link('Delete all Conversations', 'trash', {'choice' : "Clear", 'option' : "All"}, null, 'fixedLeftWider')}}
+
+
+ {{if data.toff == 0}}
+
+ {{if data.cartridge}}
+ {{if data.cartridge.charges}}
+
+ {{:data.cartridge.charges}}
+ {{if data.cartridge.access.access_detonate_pda}} detonation charges left. {{/if}}
+ {{if data.cartridge.access.access_clown || data.cartridge.access.access_mime}} viral files left. {{/if}}
+
+
+
+ {{/if}}
+ {{/if}}
+
+ {{if data.pda_count == 0}}
+
No other PDAS located
+ {{else}}
+
Current Conversations
+ {{for data.convopdas}}
+
+ {{:helper.link(value.Name, 'circle-arrow-s', {'choice' : "Select Conversation", 'convo' : value.Reference } , null, value.fixedLeftWider)}}
+ {{if data.cartridge}}
+ {{if data.cartridge.access.access_detonate_pda && value.Detonate}}
+ {{:helper.link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : value.Reference}, null, 'fixedLeft')}}
+ {{/if}}
+ {{if data.cartridge.access.access_clown}}
+ {{:helper.link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : value.Reference}, null, 'fixedLeft')}}
+ {{/if}}
+ {{if data.cartridge.access.access_mime}}
+ {{:helper.link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : value.Reference}, null, 'fixedLeft')}}
+ {{/if}}
+ {{/if}}
+
+ {{/for}}
+
Other PDAs
+ {{for data.pdas}}
+
+ {{:helper.link(value.Name, 'circle-arrow-s', {'choice' : "Message", 'target' : value.Reference}, null, value.fixedLeftWider)}}
+ {{if data.cartridge}}
+ {{if data.cartridge.access.access_detonate_pda && value.Detonate}} {{:helper.link('*Detonate*', 'radiation', {'choice' : "Detonate", 'target' : value.Reference}, null, 'fixedLeft')}} {{/if}}
+ {{if data.cartridge.access.access_clown}} {{:helper.link('*Send Virus*', 'star', {'choice' : "Send Honk", 'target' : value.Reference}, null, 'fixedLeft')}} {{/if}}
+ {{if data.cartridge.access.access_mime}} {{:helper.link('*Send Virus*', 'circle-arrow-s', {'choice' : "Send Silence", 'target' : value.Reference}, null, 'fixedLeft')}} {{/if}}
+ {{/if}}
+
+ {{/for}}
+ {{/if}}
+ {{/if}}
+
+
+ {{else data.mode == 21}}
+
SpaceMessenger V4.0.1
+
+
+ Messenger Functions:
+
+
+ {{:helper.link('Delete Conversation', 'trash', {'choice' : "Clear", 'option' : "Convo"}, null, 'fixedLeftWide')}}
+
+
+
+
+
Conversation with: {{:data.convo_name}} ({{:data.convo_job}})
+
+
+
+ {{for data.messages}}
+ {{if data.active_conversation == value.target}}
+ {{if value.sent==0}}
+ Them: {{:value.message}}
+ {{else}}
+ You: {{:value.message}}
+ {{/if}}
+ {{/if}}
+ {{/for}}
+
+
+
+ {{:helper.link('Reply', 'comment', {'choice' : "Message", 'target': data.active_conversation}, null, 'fixedLeft')}}
+
+
+ {{else data.mode== 41}}
+
+
+ {{if data.manifest.heads.length}}
+ | Command |
+ {{for data.manifest["heads"]}}
+ {{if value.rank == "Captain"}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{else}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {{if data.manifest.sec.length}}
+ | Security |
+ {{for data.manifest["sec"]}}
+ {{if value.rank == "Head of Security"}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{else}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {{if data.manifest.eng.length}}
+ | Engineering |
+ {{for data.manifest["eng"]}}
+ {{if value.rank == "Chief Engineer"}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{else}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {{if data.manifest.med.length}}
+ | Medical |
+ {{for data.manifest["med"]}}
+ {{if value.rank == "Chief Medical Officer"}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{else}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {{if data.manifest.sci.length}}
+ | Science |
+ {{for data.manifest["sci"]}}
+ {{if value.rank == "Research Director"}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{else}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {{if data.manifest.civ.length}}
+ | Civilian |
+ {{for data.manifest["civ"]}}
+ {{if value.rank == "Head of Personnel"}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{else}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{/if}}
+ {{/for}}
+ {{/if}}
+ {{if data.manifest.misc.length}}
+ | Misc |
+ {{for data.manifest["misc"]}}
+ | {{:value.name}} | {{:value.rank}} | {{:value.active}} |
+ {{/for}}
+ {{/if}}
+
+
+
+
+ {{else data.mode == 3}}
+
Atmospheric Scan
+
+
+ {{if data.aircontents.reading == 1}}
+
+ Pressure:
+
+
+ {{:helper.string('{1} kPa', data.aircontents.pressure < 80 || data.aircontents.pressure > 120 ? 'bad' : data.aircontents.pressure < 95 || data.aircontents.pressure > 110 ? 'average' : 'good' , data.aircontents.pressure)}}
+
+
+ Temperature:
+
+
+ {{:helper.string('{1} °C', data.aircontents.temp < 5 || data.aircontents.temp > 35 ? 'bad' : data.aircontents.temp < 15 || data.aircontents.temp > 25 ? 'average' : 'good' , data.aircontents.temp)}}
+
+
+
+ Oxygen:
+
+
+ {{:helper.string('{1}%', data.aircontents.oxygen < 17 ? 'bad' : data.aircontents.oxygen < 19 ? 'average' : 'good' , data.aircontents.oxygen)}}
+
+
+ Nitrogen:
+
+
+ {{:helper.string('{1}%', data.aircontents.nitrogen > 82 ? 'bad' : data.aircontents.nitrogen > 80 ? 'average' : 'good' , data.aircontents.nitrogen)}}
+
+
+ Carbon Dioxide:
+
+
+ {{:helper.string('{1}%', data.aircontents.carbon_dioxide > 5 ? 'bad' : 'good' , data.aircontents.carbon_dioxide)}}
+
+
+ Phoron:
+
+
+ {{:helper.string('{1}%', data.aircontents.phoron > 0 ? 'bad' : 'good' , data.aircontents.phoron)}}
+
+
+ {{if data.aircontents.other > 0}}
+
+ Unknown:
+
+
+ {{:data.aircontents.other}}%
+
+ {{/if}}
+ {{else}}
+
+ Unable to get air reading
+
+ {{/if}}
+
+
+
+
+ {{else data.mode == 40}}
+
Remote Signaling System
+
+
+ Frequency:
+
+
+ {{:data.records.signal_freq}}
+
+
+ {{:helper.link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-10"}, null, null)}}
+ {{:helper.link('-.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "-2"}, null, null)}}
+
+ {{:helper.link('+.2', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "2"}, null, null)}}
+ {{:helper.link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Frequency", 'sfreq' : "10"}, null, null)}}
+
+
+
+
+
+
+ Code:
+
+
+
+ {{:data.records.signal_code}}
+
+ {{:helper.link('-5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-5"}, null, null)}}
+ {{:helper.link('-1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "-1"}, null, null)}}
+ {{:helper.link('+1', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "1"}, null, null)}}
+ {{:helper.link('+5', null, {'cartmenu' : "1", 'choice' : "Signal Code", 'scode' : "5"}, null, null)}}
+
+
+
+ {{:helper.link('Send Signal', 'radiation', {'cartmenu' : "1", 'choice' : "Send Signal"}, null, null)}}
+
+
+
+ {{else data.mode == 42}}
+
Station Status Displays Interlink
+
+
+ Code:
+
+
+ {{:helper.link('Clear', 'trash', {'cartmenu' : "1", 'choice' : "Status", 'statdisp' : "blank"}, null, null)}}
+ {{:helper.link('Shuttle ETA', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "shuttle"}, null, null)}}
+ {{:helper.link('Message', 'gear', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "message"}, null, null)}}
+
+
+
+
+
+ Message line 1
+
+
+ {{:helper.link(data.records.message1 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg1"}, null, null)}}
+
+
+
+
+ Message line 2
+
+
+ {{:helper.link(data.records.message2 + ' (set)', 'pencil', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "setmsg2"}, null, null)}}
+
+
+
+
+
+
+ ALERT!:
+
+
+ {{:helper.link('None', 'alert', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "default"}, null, null)}}
+ {{:helper.link('Red Alert', 'alert', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "redalert"}, null, null)}}
+ {{:helper.link('Lockdown', 'caution', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "lockdown"}, null, null)}}
+ {{:helper.link('Biohazard', 'radiation', {'cartmenu' : "1", 'choice' : "Status",'statdisp' : "alert", 'alert' : "biohazard"}, null, null)}}
+
+
+
+
+ {{else data.mode == 43}}
+
Station Power Monitors
+
+ Select a power monitor:
+
+ {{for data.records.powermonitors}}
+
+ {{:helper.link(value.Name, 'radiation', {'cartmenu' : "1", 'choice' : "Power Select",'target' : value.ref}, null, null)}}
+
+ {{/for}}
+
+
+ {{else data.mode == 433}}
+
Powernet Status
+ {{if data.records.powerconnected == 1}}
+
+
+ Current Load:
+
+
+ {{:data.records.powerload}} W
+
+
+
+
+ Total Power:
+
+
+ {{:data.records.poweravail}} W
+
+
+
+
+
+ {{for data.records.apcs}}
+ {{if index % 20 === 0}}
+ | Area | Eqp. | Lgt. | Env | Cell |
+ {{/if}}
+ | {{:value.Name}} |
+ {{:helper.string(' | ', value.Equipment==1 ? '#4f7529' : '#8f1414')}}
+ {{:helper.string(' | ', value.Lights==1 ? '#4f7529' : '#8f1414')}}
+ {{:helper.string(' | ', value.Environment==1 ? '#4f7529' : '#8f1414')}}
+ {{:helper.string('{1} | ', value.CellStatus==1 ? '#4f7529' : '#8f1414', value.CellStatus==-1 ? 'No Cell' : value.CellPct + '%')}}
+
+ {{/for}}
+
+
+ {{else}}
+
Power monitor not connected to net
+ {{/if}}
+
+ {{else data.mode == 44}}
+
Medical Record List
+
+ Select A record
+
+
+ {{for data.records.medical_records}}
+
+ {{:helper.link(value.Name, 'gear', {'cartmenu' : "1", 'choice' : "Medical Records",'target' : value.ref}, null, null)}}
+
+ {{/for}}
+
+
+ {{else data.mode == 441}}
+
Medical Record
+
+
+
+ {{if data.records.general_exists == 1}}
+ Name: {{:data.records.general.name}}
+ Sex: {{:data.records.general.sex}}
+ Species: {{:data.records.general.species}}
+ Age: {{:data.records.general.age}}
+ Rank: {{:data.records.general.rank}}
+ Fingerprint: {{:data.records.general.fingerprint}}
+ Physical Status: {{:data.records.general.p_stat}}
+ Mental Status: {{:data.records.general.m_stat}}
+ {{else}}
+
+ General Record Lost!
+
+ {{/if}}
+ {{if data.records.medical_exists == 1}}
+ Medical Data:
+ Blood Type: {{:data.records.medical.b_type}}
+ Minor Disabilities: {{:data.records.medical.mi_dis}}
+ Details: {{:data.records.medical.mi_dis_d}}
+ Major Disabilities: {{:data.records.medical.ma_dis}}
+ Details: {{:data.records.medical.ma_dis_d}}
+ Allergies: {{:data.records.medical.alg}}
+ Details: {{:data.records.medical.alg_d}}
+ Current Disease: {{:data.records.medical.cdi}}
+ Details: {{:data.records.medical.alg_d}}
+ Important Notes: {{:data.records.medical.notes}}
+ {{else}}
+
+ Medical Record Lost!
+
+
+
+ {{/if}}
+
+
+
+
+
+ {{else data.mode == 45}}
+
Security Record List
+
+ Select A record
+
+
+ {{for data.records.security_records}}
+
+ {{:helper.link(value.Name, 'gear', {'cartmenu' : "1", 'choice' : "Security Records",'target' : value.ref}, null, null)}}
+
+ {{/for}}
+
+
+ {{else data.mode == 451}}
+
Security Record
+
+
+
+ {{if data.records.general_exists == 1}}
+ Name: {{:data.records.general.name}}
+ Sex: {{:data.records.general.sex}}
+ Species: {{:data.records.general.species}}
+ Age: {{:data.records.general.age}}
+ Rank: {{:data.records.general.rank}}
+ Fingerprint: {{:data.records.general.fingerprint}}
+ Physical Status: {{:data.records.general.p_stat}}
+ Mental Status: {{:data.records.general.m_stat}}
+ {{else}}
+
+ General Record Lost!
+
+ {{/if}}
+ {{if data.records.security_exists == 1}}
+ Security Data:
+ Criminal Status: {{:data.records.security.criminal}}
+ Minor Crimes: {{:data.records.security.mi_crim}}
+ Details: {{:data.records.security.mi_crim_d}}
+ Major Crimes: {{:data.records.security.ma_crim}}
+ Details: {{:data.records.security.ma_crim_d}}
+ Important Notes: {{:data.records.security.notes}}
+ {{else}}
+
+ Security Record Lost!
+
+ {{/if}}
+
+
+
+
+
+ {{else data.mode == 46}}
+
Security Bot Control
+ {{if data.records.beepsky.active == null || data.records.beepsky.active == 0}}
+ {{if data.records.beepsky.count == 0}}
No bots found.
{{else}}
-
+
Select A Bot.
-
-
- {{for records.beepsky.bots}}
+
+
+ {{for data.records.beepsky.bots}}
- {{:~link(Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : ref}, null, null)}} (Location: {{:Location}})
+ {{:helper.link(value.Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : value.ref}, null, null)}} (Location: {{:value.Location}})
- {{/for}}
+ {{/for}}
{{/if}}
- {{:~link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"}, null, null)}}
-
+ {{:helper.link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"}, null, null)}}
{{else}}
-
{{:records.beepsky.active}}
+
{{:data.records.beepsky.active}}
- {{if records.beepsky.botstatus.mode == -1}}
-
Waiting for response...
+ {{if data.records.beepsky.botstatus.mode == -1}}
+
Waiting for response...
{{else}}
-
Status:
-
-
-
- Location:
-
-
- {{:records.beepsky.botstatus.loca}}
-
-
-
-
- Mode:
-
-
-
- {{if records.beepsky.botstatus.mode ==0}} Ready
- {{else records.beepsky.botstatus.mode == 1}}
- Apprehending target
- {{else records.beepsky.botstatus.mode ==2 || records.beepsky.botstatus.mode == 3}}
- Arresting target
- {{else records.beepsky.botstatus.mode ==4}}
- Starting patrol
- {{else records.beepsky.botstatus.mode ==5}}
- On Patrol
- {{else records.beepsky.botstatus.mode ==6}}
- Responding to summons
- {{/if}}
-
-
-
-
- {{:~link('Stop Patrol', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, null)}}
- {{:~link('Start Patrol', 'gear', {'radiomenu' : "1", 'op' : "go"}, null, null)}}
- {{:~link('Summon Bot', 'gear', {'radiomenu' : "1", 'op' : "summon"}, null, null)}}
-
- {{/if}}
- {{:~link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"}, null, null)}}
+
Status:
+
+
+
+ Location:
+
+
+ {{:data.records.beepsky.botstatus.loca}}
+
+
+
+
+ Mode:
+
+
+
+ {{if data.records.beepsky.botstatus.mode ==0}}
+ Ready
+ {{else data.records.beepsky.botstatus.mode == 1}}
+ Apprehending target
+ {{else data.records.beepsky.botstatus.mode ==2 || data.records.beepsky.botstatus.mode == 3}}
+ Arresting target
+ {{else data.records.beepsky.botstatus.mode ==4}}
+ Starting patrol
+ {{else data.records.beepsky.botstatus.mode ==5}}
+ On Patrol
+ {{else data.records.beepsky.botstatus.mode ==6}}
+ Responding to summons
+ {{/if}}
+
+
+
+
+ {{:helper.link('Stop Patrol', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, null)}}
+ {{:helper.link('Start Patrol', 'gear', {'radiomenu' : "1", 'op' : "go"}, null, null)}}
+ {{:helper.link('Summon Bot', 'gear', {'radiomenu' : "1", 'op' : "summon"}, null, null)}}
+
+ {{/if}}
+ {{:helper.link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"}, null, null)}}
{{/if}}
- {{else mode == 47}}
+
+
+ {{else data.mode == 47}}
Supply Record Interlink
-
+
Location:
- {{if records.supply.shuttle_moving}}
- Moving to station ({{:records.supply.shuttle_eta}})
+ {{if data.records.supply.shuttle_moving}}
+ Moving to station ({{:data.records.supply.shuttle_eta}})
{{else}}
- Shuttle at {{:records.supply.shuttle_loc}}
+ Shuttle at {{:data.records.supply.shuttle_loc}}
{{/if}}
-
-
-
Current Approved Orders
- {{if records.supply.approved_count == 0}}
-
No current approved orders
- {{else}}
- {{for records.supply.approved}}
-
#{{:Number}} - {{:Name}} approved by {{:OrderedBy}}
{{if Comment != ""}} {{:Comment}}
{{/if}}
- {{/for}}
- {{/if}}
-
-
Current Requested Orders
- {{if records.supply.requests_count == 0}}
-
No current requested orders
- {{else}}
- {{for records.supply.requests}}
-
#{{:Number}} - {{:Name}} requested by {{:OrderedBy}}
{{if Comment != ""}} {{:Comment}}
{{/if}}
- {{/for}}
- {{/if}}
+
+
+ Current Approved Orders
+ {{if data.records.supply.approved_count == 0}}
+ No current approved orders
+ {{else}}
+ {{for data.records.supply.approved}}
+ #{{:value.Number}} - {{:value.Name}} approved by {{:value.OrderedBy}}
{{if value.Comment != ""}} {{:value.Comment}}
{{/if}}
+ {{/for}}
+ {{/if}}
+
+ Current Requested Orders
+ {{if data.records.supply.requests_count == 0}}
+ No current requested orders
+ {{else}}
+ {{for data.records.supply.requests}}
+ #{{:value.Number}} - {{:value.Name}} requested by {{:value.OrderedBy}}
{{if value.Comment != ""}} {{:value.Comment}}
{{/if}}
+ {{/for}}
+ {{/if}}
-
- {{else mode == 48}}
+
+
+ {{else data.mode == 48}}
Mule Control
- {{if records.mulebot.active == null || records.mulebot.active == 0}}
- {{if records.mulebot.count == 0}}
-
No bots found.
-
- {{else}}
-
Mule List
-
- Select A Mulebot
-
-
- {{for records.mulebot.bots}}
-
- {{:~link(Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : ref}, null, null)}} (Location: {{:Location}})
-
- {{/for}}
- {{/if}}
-
- {{:~link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"}, null, null)}}
- {{else}}
- {{if records.mulebot.botstatus.mode == -1}}
-
Waiting for response...
- {{else}}
-
Status:
-
-
-
- Location:
-
-
- {{:records.mulebot.botstatus.loca}}
-
-
-
-
- Mode:
-
-
-
- {{if records.mulebot.botstatus.mode ==0}} Ready
- {{else records.mulebot.botstatus.mode == 1}}
- Loading/Unloading
- {{else records.mulebot.botstatus.mode ==2}}
- Navigating to Delivery Location
- {{else records.mulebot.botstatus.mode == 3}}
- Navigating to Home
- {{else records.mulebot.botstatus.mode ==4}}
- Waiting for Clear Path
- {{else records.mulebot.botstatus.mode ==5 || records.mulebot.botstatus.mode == 6}}
- Calculating navigation Path
-
- {{else records.mulebot.botstatus.mode ==7}}
- Unable to locate destination
- {{/if}}
-
-
-
-
-
- Current Load:
-
-
-
- {{:~link(records.mulebot.botstatus.load == null ? 'None (Unload)' : records.mulebot.botstatus.load + ' (Unload)', 'gear', {'radiomenu' : "1", 'op' : "unload"},records.mulebot.botstatus.load == null ? 'disabled' : null, null)}}
-
-
-
-
-
- Power:
-
-
-
- {{:records.mulebot.botstatus.powr}}%
-
-
-
-
-
-
- Destination:
-
-
- {{:~link(records.mulebot.botstatus.dest == null || records.mulebot.botstatus.dest == "" ? 'None (Set)': records.mulebot.botstatus.dest+ ' (Set)', 'gear', {'radiomenu' : "1", 'op' : "setdest"}, null, null)}}
-
-
-
-
-
- Home:
-
-
- {{if records.mulebot.botstatus.home == null}} None {{else}} {{:records.mulebot.botstatus.home}} {{/if}}
-
-
-
-
- Auto Return:
-
-
- {{:~link(records.mulebot.botstatus.retn == 1 ? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : records.mulebot.botstatus.retn==1 ? "retoff" : "reton"}, null, null)}}
-
-
-
-
- Auto Pickup:
-
-
- {{:~link(records.mulebot.botstatus.pick==1? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : records.mulebot.botstatus.pick==1 ? "pickoff" : "pickon"}, null, null)}}
-
-
-
-
- Functions:
-
-
- {{:~link('Stop', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, null)}}
- {{:~link('Proceed', 'gear', {'radiomenu' : "1", 'op' : "go"}, null, null)}}
- {{:~link('Return Home', 'gear', {'radiomenu' : "1", 'op' : "home"}, null, null)}}
-
-
-
- {{:~link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"}, null, null)}}
-
-
- {{/if}}
- {{/if}}
-
-
-
- {{else mode == 49}}
-
Janatorial Supplies Locator
-
- Current Location:
- {{if records.janitor.user_loc.x == 0}}
- Unknown
- {{else}}
- {{:records.janitor.user_loc.x}} / {{:records.janitor.user_loc.y}}
- {{/if}}
-
-
- {{for records.janitor.mops}}
- {{if x==0}}
-
Unable to locate Mop
- {{else}}
-
Mop Location:
-
({{:x}} / {{:y}}) - {{:dir}} - Status: {{:status}}
- {{/if}}
+ {{if data.records.mulebot.active == null || data.records.mulebot.active == 0}}
+ {{if data.records.mulebot.count == 0}}
+
No bots found.
+ {{else}}
+
Mule List
+
+ Select A Mulebot
+
+
+ {{for data.records.mulebot.bots}}
+
+ {{:helper.link(value.Name, 'gear', {'radiomenu' : "1", 'op' : "control",'bot' : value.ref}, null, null)}} (Location: {{:value.Location}})
+
{{/for}}
-
-
- {{for records.janitor.buckets}}
- {{if x==0}}
- Unable to locate Water Buckets
- {{else}}
- Water Buckets Location:
- ({{:x}} / {{:y}}) - {{:dir}} - Water Level: {{:status}}
- {{/if}}
- {{/for}}
-
-
- {{for records.janitor.cleanbots}}
- {{if x==0}}
- Unable to locate Clean Bots
- {{else}}
- Clean Bots Location:
- ({{:x}} / {{:y}}) - {{:dir}} - Status: {{:status}}
- {{/if}}
-
- {{/for}}
-
-
- {{for records.janitor.carts}}
- {{if x==0}}
- Unable to locate Janitorial Cart
- {{else}}
- Janitorial cart Location:
- ({{:x}} / {{:y}}) - {{:dir}} - Status: {{:status}}
- {{/if}}
-
- {{/for}}
-
-
-
-
-
+ {{/if}}
+
+ {{:helper.link('Scan for Bots','gear', {'radiomenu' : "1", 'op' : "scanbots"}, null, null)}}
+ {{else}}
+ {{if data.records.mulebot.botstatus.mode == -1}}
+
Waiting for response...
+ {{else}}
+
Status:
+
+
+
+ Location:
+
+
+ {{:data.records.mulebot.botstatus.loca}}
+
+
+
+
+ Mode:
+
+
+
+ {{if data.records.mulebot.botstatus.mode ==0}}
+ Ready
+ {{else data.records.mulebot.botstatus.mode == 1}}
+ Loading/Unloading
+ {{else data.records.mulebot.botstatus.mode ==2}}
+ Navigating to Delivery Location
+ {{else data.records.mulebot.botstatus.mode == 3}}
+ Navigating to Home
+ {{else data.records.mulebot.botstatus.mode ==4}}
+ Waiting for Clear Path
+ {{else data.records.mulebot.botstatus.mode ==5 || data.records.mulebot.botstatus.mode == 6}}
+ Calculating navigation Path
+ {{else data.records.mulebot.botstatus.mode ==7}}
+ Unable to locate destination
+ {{/if}}
+
+
+
+
+
+ Current Load:
+
+
+
+ {{:helper.link(data.records.mulebot.botstatus.load == null ? 'None (Unload)' : data.records.mulebot.botstatus.load + ' (Unload)', 'gear', {'radiomenu' : "1", 'op' : "unload"},data.records.mulebot.botstatus.load == null ? 'disabled' : null, null)}}
+
+
+
+
+
+ Power:
+
+
+
+ {{:data.records.mulebot.botstatus.powr}}%
+
+
+
+
+
+ Destination:
+
+
+ {{:helper.link(data.records.mulebot.botstatus.dest == null || data.records.mulebot.botstatus.dest == "" ? 'None (Set)': data.records.mulebot.botstatus.dest+ ' (Set)', 'gear', {'radiomenu' : "1", 'op' : "setdest"}, null, null)}}
+
+
+
+
+ Home:
+
+
+ {{if data.records.mulebot.botstatus.home == null}} None {{else}} {{:data.records.mulebot.botstatus.home}} {{/if}}
+
+
+
+
+ Auto Return:
+
+
+ {{:helper.link(data.records.mulebot.botstatus.retn == 1 ? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : data.records.mulebot.botstatus.retn==1 ? "retoff" : "reton"}, null, null)}}
+
+
+
+
+ Auto Pickup:
+
+
+ {{:helper.link(data.records.mulebot.botstatus.pick==1? 'ON' : 'OFF', 'gear', {'radiomenu' : "1", 'op' : data.records.mulebot.botstatus.pick==1 ? "pickoff" : "pickon"}, null, null)}}
+
+
+
+
+ Functions:
+
+
+ {{:helper.link('Stop', 'gear', {'radiomenu' : "1", 'op' : "stop"}, null, null)}}
+ {{:helper.link('Proceed', 'gear', {'radiomenu' : "1", 'op' : "go"}, null, null)}}
+ {{:helper.link('Return Home', 'gear', {'radiomenu' : "1", 'op' : "home"}, null, null)}}
+
+
+
+ {{:helper.link('Return to Bot list', 'gear', {'radiomenu' : "1", 'op' : "botlist"}, null, null)}}
+ {{/if}}
{{/if}}
+ {{else data.mode == 49}}
+
Janatorial Supplies Locator
+
+ Current Location:
+ {{if data.records.janitor.user_loc.x == 0}}
+ Unknown
+ {{else}}
+ {{:data.records.janitor.user_loc.x}} / {{:data.records.janitor.user_loc.y}}
+ {{/if}}
+
+
+ {{for data.records.janitor.mops}}
+ {{if value.x==0}}
+ Unable to locate Mop
+ {{else}}
+ Mop Location:
+ ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}
+ {{/if}}
+ {{/for}}
+
+
+ {{for data.records.janitor.buckets}}
+ {{if value.x==0}}
+ Unable to locate Water Buckets
+ {{else}}
+ Water Buckets Location:
+ ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Water Level: {{:value.status}}
+ {{/if}}
+ {{/for}}
+
+
+ {{for data.records.janitor.cleanbots}}
+ {{if value.x==0}}
+ Unable to locate Clean Bots
+ {{else}}
+ Clean Bots Location:
+ ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}
+ {{/if}}
+ {{/for}}
+
+
+ {{for data.records.janitor.carts}}
+ {{if value.x==0}}
+ Unable to locate Janitorial Cart
+ {{else}}
+ Janitorial cart Location:
+ ({{:value.x}} / {{:value.y}}) - {{:value.dir}} - Status: {{:value.status}}
+ {{/if}}
+ {{/for}}
+
+ {{/if}}
{{else}}
-
No Owner information found, please swipe ID
-
+
+
No Owner information found, please swipe ID
+
{{/if}}
diff --git a/nano/templates/pressure_regulator.tmpl b/nano/templates/pressure_regulator.tmpl
new file mode 100644
index 00000000..bbbfcc22
--- /dev/null
+++ b/nano/templates/pressure_regulator.tmpl
@@ -0,0 +1,76 @@
+
+
+ Input Pressure:
+
+
+ {{:(data.input_pressure/100)}} kPa
+
+
+
+
+
+ Output Pressure:
+
+
+ {{:(data.output_pressure/100)}} kPa
+
+
+
+
+
+ Flow Rate:
+
+
+
+ {{:(data.last_flow_rate/10)}} L/s
+
+
+
+
+
+
+
+
+ Valve:
+
+
+ {{:helper.link(data.on? 'Unlocked' : 'Closed', null, {'toggle_valve' : 1})}}
+
+
+
+
+
+ Pressure Regulation:
+
+
+ {{:helper.link('Off', null, {'regulate_mode' : 'off'}, data.regulate_mode == 0? 'selected' : null)}}
+ {{:helper.link('Input', null, {'regulate_mode' : 'input'}, data.regulate_mode == 1? 'selected' : null)}}
+ {{:helper.link('Output', null, {'regulate_mode' : 'output'}, data.regulate_mode == 2? 'selected' : null)}}
+
+
+
+
+
+ Target Pressure:
+
+
+
+ {{:helper.link('MAX', null, {'set_press' : 'max'}, null)}}
+ {{:helper.link('SET', null, {'set_press' : 'set'}, null)}}
+
{{:(data.pressure_set/100)}} kPa
+
+
+
+
+
+
+ Flow Rate Limit:
+
+
+
+ {{:helper.link('MAX', null, {'set_flow_rate' : 'max'}, null)}}
+ {{:helper.link('SET', null, {'set_flow_rate' : 'set'}, null)}}
+
{{:(data.set_flow_rate/10)}} L/s
+
+
+
\ No newline at end of file
diff --git a/nano/templates/shuttle_control_console.tmpl b/nano/templates/shuttle_control_console.tmpl
new file mode 100644
index 00000000..efd0a00b
--- /dev/null
+++ b/nano/templates/shuttle_control_console.tmpl
@@ -0,0 +1,66 @@
+
Shuttle Status
+
+
+ {{:data.shuttle_status}}
+
+
+
+
+
+ Bluespace Drive:
+
+
+ {{if data.shuttle_state == "idle"}}
+ IDLE
+ {{else data.shuttle_state == "warmup"}}
+ SPINNING UP
+ {{else data.shuttle_state == "in_transit"}}
+ ENGAGED
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+{{if data.has_docking}}
+
+
+
+ Docking Status:
+
+
+ {{if data.docking_status == "docked"}}
+ DOCKED
+ {{else data.docking_status == "docking"}}
+ {{if !data.docking_override}}
+ DOCKING
+ {{else}}
+ DOCKING-MANUAL
+ {{/if}}
+ {{else data.docking_status == "undocking"}}
+ {{if !data.docking_override}}
+ UNDOCKING
+ {{else}}
+ UNDOCKING-MANUAL
+ {{/if}}
+ {{else data.docking_status == "undocked"}}
+ UNDOCKED
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+
+{{/if}}
+
+
Shuttle Control
+
+
+
+ {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch? null : 'disabled' , null)}}
+ {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}}
+ {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force? null : 'disabled' , data.can_force ? 'redBackground' : null)}}
+
+
+
\ No newline at end of file
diff --git a/nano/templates/simple_airlock_console.tmpl b/nano/templates/simple_airlock_console.tmpl
index 99752958..714c9398 100644
--- a/nano/templates/simple_airlock_console.tmpl
+++ b/nano/templates/simple_airlock_console.tmpl
@@ -4,9 +4,9 @@
Chamber Pressure:
- {{:~displayBar(chamber_pressure, 0, 200, chamber_pressure < 80 || chamber_pressure > 120 ? 'bad' : chamber_pressure < 95 || chamber_pressure > 110 ? 'average' : 'good')}}
+ {{:helper.displayBar(data.chamber_pressure, 0, 200, (data.chamber_pressure < 80) || (data.chamber_pressure > 120) ? 'bad' : (data.chamber_pressure < 95) || (data.chamber_pressure > 110) ? 'average' : 'good')}}
- {{:chamber_pressure}} kPa
+ {{:data.chamber_pressure}} kPa
@@ -14,23 +14,23 @@
- {{:~link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, processing ? 'disabled' : null)}}
- {{:~link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, processing ? 'disabled' : null)}}
+ {{:helper.link('Cycle to Exterior', 'arrowthickstop-1-w', {'command' : 'cycle_ext'}, data.processing ? 'disabled' : null)}}
+ {{:helper.link('Cycle to Interior', 'arrowthickstop-1-e', {'command' : 'cycle_int'}, data.processing ? 'disabled' : null)}}
- {{if interior_status.state == "open"}}
- {{:~link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, 'redBackground')}}
+ {{if data.interior_status.state == "open"}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, null)}}
{{else}}
- {{:~link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, processing ? 'yellowBackground' : null)}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_ext'}, null, data.processing ? null : null)}}
{{/if}}
- {{if exterior_status.state == "open"}}
- {{:~link('Force interior door', 'alert', {'command' : 'force_int'}, null, 'redBackground')}}
+ {{if data.exterior_status.state == "open"}}
+ {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, null)}}
{{else}}
- {{:~link('Force interior door', 'alert', {'command' : 'force_int'}, null, processing ? 'yellowBackground' : null)}}
+ {{:helper.link('Force interior door', 'alert', {'command' : 'force_int'}, null, data.processing ? null : null)}}
{{/if}}
- {{:~link('Abort', 'cancel', {'command' : 'abort'}, processing ? null : 'disabled', processing ? 'redBackground' : null)}}
+ {{:helper.link('Abort', 'cancel', {'command' : 'abort'}, data.processing ? null : 'disabled', data.processing ? null : null)}}
\ No newline at end of file
diff --git a/nano/templates/simple_docking_console.tmpl b/nano/templates/simple_docking_console.tmpl
new file mode 100644
index 00000000..89d76849
--- /dev/null
+++ b/nano/templates/simple_docking_console.tmpl
@@ -0,0 +1,99 @@
+
+
+
+ Docking Port Status:
+
+
+ {{if data.docking_status == "docked"}}
+ {{if !data.override_enabled}}
+ DOCKED
+ {{else}}
+ DOCKED-OVERRIDE ENABLED
+ {{/if}}
+ {{else data.docking_status == "docking"}}
+ {{if !data.override_enabled}}
+ DOCKING
+ {{else}}
+ DOCKING-OVERRIDE ENABLED
+ {{/if}}
+ {{else data.docking_status == "undocking"}}
+ {{if !data.override_enabled}}
+ UNDOCKING
+ {{else}}
+ UNDOCKING-OVERRIDE ENABLED
+ {{/if}}
+ {{else data.docking_status == "undocked"}}
+ {{if !data.override_enabled}}
+ NOT IN USE
+ {{else}}
+ OVERRIDE ENABLED
+ {{/if}}
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+
+
+
+ Docking Hatch:
+
+
+ {{if data.docking_status == "docked"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed"}}
+ CLOSED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else data.docking_status == "docking"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed" && data.door_lock == "locked"}}
+ SECURED
+ {{else data.door_state == "closed" && data.door_lock == "unlocked"}}
+ UNSECURED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else data.docking_status == "undocking"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed" && data.door_lock == "locked"}}
+ SECURED
+ {{else data.door_state == "closed" && data.door_lock == "unlocked"}}
+ UNSECURED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else data.docking_status == "undocked"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed" && data.door_lock == "locked"}}
+ SECURED
+ {{else data.door_state == "closed" && data.door_lock == "unlocked"}}
+ UNSECURED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+
+
+
+ {{if data.docking_status == "docked"}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', null)}}
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : null)}}
+ {{else}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redBackground' : null)}}
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : 'yellowBackground')}}
+ {{/if}}
+
+
+
\ No newline at end of file
diff --git a/nano/templates/simple_docking_console_pod.tmpl b/nano/templates/simple_docking_console_pod.tmpl
new file mode 100644
index 00000000..3e9331ee
--- /dev/null
+++ b/nano/templates/simple_docking_console_pod.tmpl
@@ -0,0 +1,101 @@
+
+
+
+ Docking Port Status:
+
+
+ {{if data.docking_status == "docked"}}
+ {{if !data.override_enabled}}
+ DOCKED
+ {{else}}
+ DOCKED-OVERRIDE ENABLED
+ {{/if}}
+ {{else data.docking_status == "docking"}}
+ {{if !data.override_enabled}}
+ DOCKING
+ {{else}}
+ DOCKING-OVERRIDE ENABLED
+ {{/if}}
+ {{else data.docking_status == "undocking"}}
+ {{if !data.override_enabled}}
+ UNDOCKING
+ {{else}}
+ UNDOCKING-OVERRIDE ENABLED
+ {{/if}}
+ {{else data.docking_status == "undocked"}}
+ {{if !data.override_enabled}}
+ NOT IN USE
+ {{else}}
+ OVERRIDE ENABLED
+ {{/if}}
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+
+
+
+ Docking Hatch:
+
+
+ {{if data.docking_status == "docked"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed"}}
+ CLOSED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else data.docking_status == "docking"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed" && data.door_lock == "locked"}}
+ SECURED
+ {{else data.door_state == "closed" && data.door_lock == "unlocked"}}
+ UNSECURED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else data.docking_status == "undocking"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed" && data.door_lock == "locked"}}
+ SECURED
+ {{else data.door_state == "closed" && data.door_lock == "unlocked"}}
+ UNSECURED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else data.docking_status == "undocked"}}
+ {{if data.door_state == "open"}}
+ OPEN
+ {{else data.door_state == "closed" && data.door_lock == "locked"}}
+ SECURED
+ {{else data.door_state == "closed" && data.door_lock == "unlocked"}}
+ UNSECURED
+ {{else}}
+ ERROR
+ {{/if}}
+ {{else}}
+ ERROR
+ {{/if}}
+
+
+
+
+
+
+ {{if data.docking_status == "docked"}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', null)}}
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : null)}}
+ {{:helper.link('MANUAL EJECT', 'alert', {'command' : 'toggle_override'}, 'disabled', null)}}
+ {{else}}
+ {{:helper.link('Force exterior door', 'alert', {'command' : 'force_door'}, data.override_enabled ? null : 'disabled', data.override_enabled ? 'redBackground' : null)}}
+ {{:helper.link('Override', 'alert', {'command' : 'toggle_override'}, null, data.override_enabled ? 'redBackground' : 'yellowBackground')}}
+ {{:helper.link('MANUAL EJECT', 'alert', {'command' : 'toggle_override'}, data.can_force ? null : 'disabled', data.can_force ? 'redBackground' : null)}}
+ {{/if}}
+
+
+
\ No newline at end of file
diff --git a/nano/templates/smartfridge.tmpl b/nano/templates/smartfridge.tmpl
index 9e50bab9..b371baae 100644
--- a/nano/templates/smartfridge.tmpl
+++ b/nano/templates/smartfridge.tmpl
@@ -1,37 +1,33 @@
- {{:~link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}}
+ {{:helper.link('Close', 'gear', {'close' : 1}, null, 'fixedLeft')}}
Storage
- {{if secure}}
+ {{if data.secure}}
- {{:locked == -1 ? "Sec.re ACC_** //):securi_nt.diag=>##'or 1=1'%($..." : "Secure Access: Please have your identification ready."}}
+ {{:data.locked == -1 ? "Sec.re ACC_** //):securi_nt.diag=>##'or 1=1'%($..." : "Secure Access: Please have your identification ready."}}
{{/if}}
- {{if contents}}
- {{for contents}}
+ {{if data.contents}}
+ {{for data.contents}}
-
- {{:display_name}} ({{:quantity}}):
-
-
- {{:~link('Vend', 'circle-arrow-s', { "vend" : vend, "amount" : 1 }, null, 'statusValue')}}
- {{if quantity >= 5}}
- {{:~link('x5', 'circle-arrow-s', { "vend" : vend, "amount" : 5 }, null, 'statusValue')}}
- {{/if}}
- {{if quantity >= 10}}
- {{:~link('x10', 'circle-arrow-s', { "vend" : vend, "amount" : 10 }, null, 'statusValue')}}
- {{/if}}
- {{if quantity >= 25}}
- {{:~link('x25', 'circle-arrow-s', { "vend" : vend, "amount" : 25 }, null, 'statusValue')}}
- {{/if}}
- {{if quantity > 1}}
- {{:~link('All', 'circle-arrow-s', { "vend" : vend, "amount" : quantity }, null, 'statusValue')}}
- {{/if}}
-
+
{{:value.display_name}} ({{:value.quantity}} available)
+
Vend:
{{:helper.link('x1', 'circle-arrow-s', { "vend" : value.vend, "amount" : 1 }, null, 'statusValue')}}
+ {{if value.quantity >= 5}}
+ {{:helper.link('x5', 'circle-arrow-s', { "vend" : value.vend, "amount" : 5 }, null, 'statusValue')}}
+ {{/if}}
+ {{if value.quantity >= 10}}
+ {{:helper.link('x10', 'circle-arrow-s', { "vend" : value.vend, "amount" : 10 }, null, 'statusValue')}}
+ {{/if}}
+ {{if value.quantity >= 25}}
+ {{:helper.link('x25', 'circle-arrow-s', { "vend" : value.vend, "amount" : 25 }, null, 'statusValue')}}
+ {{/if}}
+ {{if value.quantity > 1}}
+ {{:helper.link('All', 'circle-arrow-s', { "vend" : value.vend, "amount" : value.quantity }, null, 'statusValue')}}
+ {{/if}}
{{/for}}
{{else}}
@@ -39,7 +35,7 @@
{{/if}}
-{{if panel_open}}
+{{if data.panel_open}}
Access Panel
@@ -48,17 +44,17 @@
Wires:
- {{for wires}}
+ {{for data.wires}}
-
- {{:wire}} wire:
+
+ {{:value.wire}} wire:
- {{if cut}}
- {{:~link('Mend', 'plus', {'cutwire' : index})}}
+ {{if value.cut}}
+ {{:helper.link('Mend', 'plus', {'cutwire' : value.index})}}
{{else}}
- {{:~link('Cut', 'minus', {'cutwire' : index})}}
- {{:~link('Pulse', 'signal-diag', {'pulsewire' : index})}}
+ {{:helper.link('Cut', 'minus', {'cutwire' : value.index})}}
+ {{:helper.link('Pulse', 'signal-diag', {'pulsewire' : value.index})}}
{{/if}}
@@ -67,12 +63,12 @@
- The orange light is {{:electrified ? "on" : "off"}}.
- The red light is {{:shoot_inventory ? "on" : "off"}}.
- {{if secure}}
+ The orange light is {{:data.electrified ? "on" : "off"}}.
+ The red light is {{:data.shoot_inventory ? "on" : "off"}}.
+ {{if data.secure}}
The green light is
-
- {{:locked == 1 ? "off" : locked == -1 ? "blinking" : "on"}}
+
+ {{:data.locked == 1 ? "off" : data.locked == -1 ? "blinking" : "on"}}
.
{{/if}}
diff --git a/nano/templates/smes.tmpl b/nano/templates/smes.tmpl
index 760228e4..8b72cefe 100644
--- a/nano/templates/smes.tmpl
+++ b/nano/templates/smes.tmpl
@@ -3,9 +3,9 @@
Stored Capacity:
- {{:~displayBar(storedCapacity, 0, 100, charging ? 'good' : 'average')}}
+ {{:helper.displayBar(data.storedCapacity, 0, 100, data.charging ? 'good' : 'average')}}
- {{:~round(storedCapacity)}}%
+ {{:helper.round(data.storedCapacity)}}%
@@ -16,12 +16,14 @@
Charge Mode:
- {{:~link('Auto', 'refresh', {'cmode' : 1}, chargeMode ? 'selected' : null)}}{{:~link('Off', 'close', {'cmode' : 1}, chargeMode ? null : 'selected')}}
+ {{:helper.link('Auto', 'refresh', {'cmode' : 1}, data.chargeMode ? 'selected' : null)}}{{:helper.link('Off', 'close', {'cmode' : 1}, data.chargeMode ? null : 'selected')}}
- {{if charging}}
+ {{if data.charging == 2}}
[Charging]
+ {{else data.charging == 1}}
+ [Partially Charging]
{{else}}
- [Not Charging]
+ [Not Charging]
{{/if}}
@@ -31,12 +33,12 @@
Input Level:
- {{:~displayBar(chargeLevel, 0, chargeMax)}}
+ {{:helper.displayBar(data.chargeLevel, 0, data.chargeMax)}}
- {{:~link('MIN', null, {'input' : 'min'}, (chargeLevel > 0) ? null : 'disabled')}}
- {{:~link('SET', null, {'input' : 'set'}, null)}}
- {{:~link('MAX', null, {'input' : 'max'}, (chargeLevel < chargeMax) ? null : 'disabled')}}
-
{{:chargeLevel}} W
+ {{:helper.link('MIN', null, {'input' : 'min'}, (data.chargeLevel > 0) ? null : 'disabled')}}
+ {{:helper.link('SET', null, {'input' : 'set'}, null)}}
+ {{:helper.link('MAX', null, {'input' : 'max'}, (data.chargeLevel < data.chargeMax) ? null : 'disabled')}}
+
{{:data.chargeLevel}} W
@@ -47,7 +49,7 @@
Output Status:
- {{:~link('Online', 'power', {'online' : 1}, outputOnline ? 'selected' : null)}}{{:~link('Offline', 'close', {'online' : 1}, outputOnline ? null : 'selected')}}
+ {{:helper.link('Online', 'power', {'online' : 1}, data.outputOnline ? 'selected' : null)}}{{:helper.link('Offline', 'close', {'online' : 1}, data.outputOnline ? null : 'selected')}}
@@ -56,12 +58,12 @@
Output Level:
- {{:~displayBar(outputLevel, 0, outputMax)}}
+ {{:helper.displayBar(data.outputLevel, 0, data.outputMax)}}
- {{:~link('MIN', null, {'output' : 'min'}, (outputLevel > 0) ? null : 'disabled')}}
- {{:~link('SET', null, {'output' : 'set'}, null)}}
- {{:~link('MAX', null, {'output' : 'max'}, (outputLevel < outputMax) ? null : 'disabled')}}
-
{{:outputLevel}} W
+ {{:helper.link('MIN', null, {'output' : 'min'}, (data.outputLevel > 0) ? null : 'disabled')}}
+ {{:helper.link('SET', null, {'output' : 'set'}, null)}}
+ {{:helper.link('MAX', null, {'output' : 'max'}, (data.outputLevel < data.outputMax) ? null : 'disabled')}}
+
{{:data.outputLevel}} W
@@ -71,9 +73,9 @@
Output Load:
- {{:~displayBar(outputLoad, 0, outputMax, (outputLoad < outputLevel) ? 'good' : 'average')}}
+ {{:helper.displayBar(data.outputLoad, 0, data.outputMax, (data.outputLoad < data.outputLevel) ? 'good' : 'average')}}
- {{:outputLoad}} W
+ {{:data.outputLoad}} W
\ No newline at end of file
diff --git a/nano/templates/tanks.tmpl b/nano/templates/tanks.tmpl
index af7ab874..c9d4e6c3 100644
--- a/nano/templates/tanks.tmpl
+++ b/nano/templates/tanks.tmpl
@@ -1,4 +1,4 @@
-{{if maskConnected}}
+{{if data.maskConnected}}
This tank is connected to a mask.
{{else}}
This tank is NOT connected to a mask.
@@ -9,9 +9,9 @@
Tank Pressure:
- {{:~displayBar(tankPressure, 0, 1013, (tankPressure > 200) ? 'good' : (tankPressure > 100) ? 'average' : 'bad'))}}
+ {{:helper.displayBar(data.tankPressure, 0, 1013, (data.tankPressure > 200) ? 'good' : ((data.tankPressure > 100) ? 'average' : 'bad'))}}
- {{:tankPressure}} kPa
+ {{:data.tankPressure}} kPa
@@ -23,15 +23,15 @@
Mask Release Pressure:
- {{:~displayBar(releasePressure, 0, maxReleasePressure, (releasePressure >= 23) ? null : ((releasePressure >= 17) ? 'average' : 'bad'))}}
+ {{:helper.displayBar(data.releasePressure, 0, data.maxReleasePressure, (data.releasePressure >= 23) ? null : ((data.releasePressure >= 17) ? 'average' : 'bad'))}}
- {{:~link('-', null, {'dist_p' : -10}, (releasePressure > 0) ? null : 'disabled')}}
- {{:~link('-', null, {'dist_p' : -1}, (releasePressure > 0) ? null : 'disabled')}}
-
{{:releasePressure}} kPa
- {{:~link('+', null, {'dist_p' : 1}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
- {{:~link('+', null, {'dist_p' : 10}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
- {{:~link('Max', null, {'dist_p' : 'max'}, (releasePressure < maxReleasePressure) ? null : 'disabled')}}
- {{:~link('Reset', null, {'dist_p' : 'reset'}, (releasePressure != defaultReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('-', null, {'dist_p' : -10}, (data.releasePressure > 0) ? null : 'disabled')}}
+ {{:helper.link('-', null, {'dist_p' : -1}, (data.releasePressure > 0) ? null : 'disabled')}}
+
{{:data.releasePressure}} kPa
+ {{:helper.link('+', null, {'dist_p' : 1}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('+', null, {'dist_p' : 10}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('Max', null, {'dist_p' : 'max'}, (data.releasePressure < data.maxReleasePressure) ? null : 'disabled')}}
+ {{:helper.link('Reset', null, {'dist_p' : 'reset'}, (data.releasePressure != data.defaultReleasePressure) ? null : 'disabled')}}
@@ -41,7 +41,7 @@
Mask Release Valve:
- {{:~link('Open', 'unlocked', {'stat' : 1}, (!maskConnected) ? 'disabled' : (valveOpen ? 'selected' : null))}}{{:~link('Close', 'locked', {'stat' : 1}, valveOpen ? null : 'selected')}}
+ {{:helper.link('Open', 'unlocked', {'stat' : 1}, (!data.maskConnected) ? 'disabled' : (data.valveOpen ? 'selected' : null))}}{{:helper.link('Close', 'locked', {'stat' : 1}, data.valveOpen ? null : 'selected')}}
diff --git a/nano/templates/telescience_console.tmpl b/nano/templates/telescience_console.tmpl
index bd88dc45..4f882675 100644
--- a/nano/templates/telescience_console.tmpl
+++ b/nano/templates/telescience_console.tmpl
@@ -5,16 +5,16 @@ Used In File(s): \code\modules\telesci\telesci_computer.dm
Coordinates:
- {{:~link('X: ' + coordx, 'gear', {'setx': 1})}}
- {{:~link('Y: ' + coordy, 'gear', {'sety': 1})}}
- {{:~link('Z: ' + coordz, 'gear', {'setz': 1})}}
+ {{:helper.link('X: ' + data.coordx, 'gear', {'setx': 1})}}
+ {{:helper.link('Y: ' + data.coordy, 'gear', {'sety': 1})}}
+ {{:helper.link('Z: ' + data.coordz, 'gear', {'setz': 1})}}
Controls:
- {{:~link('Send', 'gear', {'send': 1}, null, (coordx != null && coordy != null && coordz != null) ? '' : 'disabled')}}
- {{:~link('Receive', 'gear', {'receive': 1}, null, (coordx != null && coordy != null && coordz != null) ? '' : 'disabled')}}
- {{:~link('Recalibrate', 'gear', {'recal': 1})}}
+ {{:helper.link('Send', 'gear', {'send': 1}, null, (data.coordx != null && data.coordy != null && data.coordz != null) ? '' : 'disabled')}}
+ {{:helper.link('Receive', 'gear', {'receive': 1}, null, (data.coordx != null && data.coordy != null && data.coordz != null) ? '' : 'disabled')}}
+ {{:helper.link('Recalibrate', 'gear', {'recal': 1})}}
diff --git a/nano/templates/transfer_valve.tmpl b/nano/templates/transfer_valve.tmpl
index 6c5cca62..f8395839 100644
--- a/nano/templates/transfer_valve.tmpl
+++ b/nano/templates/transfer_valve.tmpl
@@ -3,12 +3,12 @@
Attachment One:
- {{if attachmentOne}}
- {{:attachmentOne}}
+ {{if data.attachmentOne}}
+ {{:data.attachmentOne}}
{{else}}
None
{{/if}}
- {{:~link('Remove', 'eject', {'tankone' : 1}, attachmentOne ? null : 'disabled')}}
+ {{:helper.link('Remove', 'eject', {'tankone' : 1}, data.attachmentOne ? null : 'disabled')}}
@@ -17,12 +17,12 @@
Attachment Two:
- {{if attachmentTwo}}
- {{:attachmentTwo}}
+ {{if data.attachmentTwo}}
+ {{:data.attachmentTwo}}
{{else}}
None
{{/if}}
- {{:~link('Remove', 'eject', {'tanktwo' : 1}, attachmentTwo ? null : 'disabled')}}
+ {{:helper.link('Remove', 'eject', {'tanktwo' : 1}, data.attachmentTwo ? null : 'disabled')}}
@@ -31,14 +31,14 @@
Valve Attachment:
- {{if valveAttachment}}
- {{:valveAttachment}}
+ {{if data.valveAttachment}}
+ {{:data.valveAttachment}}
{{else}}
None
{{/if}}
- {{:~link('Remove', 'eject', {'rem_device' : 1}, valveAttachment ? null : 'disabled')}}
- {{if valveAttachment}}
- {{:~link('View', 'wrench', {'device' : 1})}}
+ {{:helper.link('Remove', 'eject', {'rem_device' : 1}, data.valveAttachment ? null : 'disabled')}}
+ {{if data.valveAttachment}}
+ {{:helper.link('View', 'wrench', {'device' : 1})}}
{{/if}}
@@ -50,7 +50,7 @@
Valve Status:
- {{:~link('Open', 'unlocked', {'open' : 1}, (!attachmentOne || !attachmentTwo) ? 'disabled' : (valveOpen ? 'selected' : null))}}{{:~link('Close', 'locked', {'open' : 1}, (!attachmentOne || !attachmentTwo) ? 'disabled' : (valveOpen ? null : 'selected'))}}
+ {{:helper.link('Open', 'unlocked', {'open' : 1}, (!data.attachmentOne || !data.attachmentTwo) ? 'disabled' : (data.valveOpen ? 'selected' : null))}}{{:helper.link('Close', 'locked', {'open' : 1}, (!data.attachmentOne || !data.attachmentTwo) ? 'disabled' : (data.valveOpen ? null : 'selected'))}}
diff --git a/nano/templates/uplink.tmpl b/nano/templates/uplink.tmpl
index 34188899..e3d65b45 100644
--- a/nano/templates/uplink.tmpl
+++ b/nano/templates/uplink.tmpl
@@ -3,44 +3,91 @@
Title: Syndicate Uplink, uses some javascript to change nanoUI up a bit.
Used In File(s): \code\game\objects\items\devices\uplinks.dm
-->
-{{:~syndicateMode()}}
-{{:welcome}}
+{{:helper.syndicateMode()}}
+{{:data.welcome}}
Functions:
- {{:~link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}}
+ {{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}}
+ {{:helper.link('Exploitable Information', 'gear', {'menu' : 1}, null, 'fixedLeftWider')}}
+ {{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}}
+ {{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}}
-
+
+{{if data.menu == 0}}
+
Request items:
+
Each item costs a number of tele-crystals as indicated by the number following their name.
+
- Tele-Crystals:
+ Tele-Crystals:
- {{:crystals}}
+ {{:data.crystals}}
-
-
Request items:
-
Each item costs a number of tele-crystals as indicated by the number following their name.
+
+
+ {{for data.nano_items}}
+
+
{{:value.Category}}
+
+ {{for value.items :itemValue:itemIndex}}
+
+ {{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - {{:itemValue.Cost}}
+
+ {{/for}}
+
+ {{/for}}
-
-{{for nano_items}}
-
-
{{:Category}}
-
- {{for items}}
-
- {{:~link( Name, 'gear', {'buy_item' : obj_path, 'cost' : Cost}, Cost > ~root.crystals ? 'disabled' : null, null)}} - {{:Cost}}
-
- {{/for}}
-
-
-{{/for}}
-
-
- {{:~link('Buy Random (??)' , 'gear', {'buy_item' : 'random'}, null, 'fixedLeftWidest')}}
-
+
+ {{:helper.link('Buy Random (??)' , 'gear', {'buy_item' : 'random'}, data.crystals <= 0 ? 'disabled' : null, null)}}
+
+
+{{else data.menu == 1}}
+ Information Record List:
+
+
+ Select a Record
+
+
+ {{for data.exploit_records}}
+
+ {{:helper.link(value.Name, 'gear', {'menu' : 11, 'id' : value.id}, null, null)}}
+
+ {{/for}}
+
+{{else data.menu == 11}}
+ Information Record:
+
+
+
+
+ {{if data.exploit_exists == 1}}
+ Name: {{:data.exploit.name}}
+ Sex: {{:data.exploit.sex}}
+ Species: {{:data.exploit.species}}
+ Age: {{:data.exploit.age}}
+ Rank: {{:data.exploit.rank}}
+ Home System: {{:data.exploit.home_system}}
+ Citizenship: {{:data.exploit.citizenship}}
+ Faction: {{:data.exploit.faction}}
+ Religion: {{:data.exploit.religion}}
+ Fingerprint: {{:data.exploit.fingerprint}}
+
Acquired Information:
+ Notes:
{{:data.exploit.nanoui_exploit_record}}
+ {{else}}
+
+ No exploitative information acquired!
+
+
+
+ {{/if}}
+
+
+
+{{/if}}