initial commit - cross reference with 5th port - obviously has compile errors

This commit is contained in:
LetterJay
2016-07-03 02:17:19 -05:00
commit 35a1723e98
4355 changed files with 2221257 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
{
"presets": [
"es2015-loose"
],
"plugins": [
"external-helpers"
]
}
+16
View File
@@ -0,0 +1,16 @@
<script>
component.exports = {
oninit () {
this.observe('value', (newkey, oldkey, keypath) => {
const { min, max } = this.get()
const value = Math.clamp(min, max, newkey)
this.animate('percentage', Math.round((value - min) / (max - min) * 100))
})
}
}
</script>
<div class='bar'>
<div class='barFill {{state}}' style='width: {{percentage}}%'></div>
<span class='barText'>{{yield}}</span>
</div>
+32
View File
@@ -0,0 +1,32 @@
context = selector()
.bar
display: inline-block
position: relative
vertical-align: middle
width: 100%
height: 20px
line-height: @height - 3px
padding: 1px
border: 1px solid bar-color-border
background: bar-color-background
.barText
@extend {context} $fontReset
position: absolute
top: 0
right: 3px
.barFill
display: block
height: 100%
transition: background-color 1s
background-color: bar-color-normal
&.good
background-color: bar-color-good
&.average
background-color: bar-color-average
&.bad
background-color: bar-color-bad
+59
View File
@@ -0,0 +1,59 @@
<script>
import { UI_INTERACTIVE } from 'util/constants'
import { act } from 'util/byond'
component.exports = {
computed: {
clickable () {
if (this.get('enabled') && !this.get('state')) {
return true
}
return false
},
enabled () {
if (this.get('config.status') === UI_INTERACTIVE) {
return true
}
return false
},
styles () {
let extra = ''
if (this.get('tooltip-side'))
extra = ` tooltip-${this.get('tooltip-side')}`
if (this.get('grid'))
extra += ' gridable'
if (this.get('enabled')) {
const state = this.get('state')
const style = this.get('style')
if (!state) {
return `active normal ${style} ${extra}`
} else {
return `inactive ${state} ${extra}`
}
} else {
return `inactive disabled ${extra}`
}
}
},
oninit () {
this.on('press', (event) => {
const { action, params } = this.get()
act(this.get('config.ref'), action, params)
event.node.blur()
})
}
}
</script>
<span class='button {{styles}}'
unselectable='on'
{{#clickable}}tabindex='0'{{/}}
data-tooltip='{{tooltip}}'
on-mouseover-mousemove='hover'
on-mouseleave='unhover'
on-click-enter='{{#clickable}}press{{/}}'>
{{#if icon}}
<i class='fa fa-{{icon}}'></i>
{{/if}}
{{yield}}
</span>
+41
View File
@@ -0,0 +1,41 @@
context = selector()
buttoncolor(selector, color)
&.{selector}
transition: background-color 0.5s
background-color: color
&.{selector}.active:hover,
&.{selector}.active:focus
transition: background-color 0.25s
background-color: lighten(color, button-lighten-hover)
outline: 0
span.button
@extend {context} $fontReset
display: inline-block
vertical-align: middle
height: 20px
line-height: @height - 3px
padding: 0 5px
white-space: nowrap
border: 1px solid button-color-border
.fa
padding-right: 2px
buttoncolor(normal, button-color-normal)
buttoncolor(disabled, button-color-disabled)
buttoncolor(selected, button-color-selected)
buttoncolor(caution, button-color-caution)
buttoncolor(danger, button-color-danger)
&.gridable
width: 125px
margin: 2px 0
span:not(.button) + span.button
margin-left: 5px
span.button + span:not(.button)
margin-left: 5px
+13
View File
@@ -0,0 +1,13 @@
<div class='display'>
{{#if title}}
<header>
<h3>{{title}}</h3>
{{#if button}}
<div class='buttonRight'>{{yield button}}</div>
{{/if}}
</header>
{{/if}}
<article>
{{yield}}
</article>
</div>
+29
View File
@@ -0,0 +1,29 @@
div.display
width: 100%
padding: 4px
margin: 6px 0
background-color: display-color-background // Transparent background.
box-shadow: inset 0 0 5px display-color-shadow
header
display: block
position: relative
width: 100%
padding: 0 4px
margin-bottom: 6px
color: display-color-title
border-bottom: rule-size solid rule-color-normal
.buttonRight
position: absolute
bottom: 6px
right: 4px
article
display: table
width: 100%
border-collapse: collapse;
+13
View File
@@ -0,0 +1,13 @@
<script>
component.exports = {
oninit () {
this.on('clear', () => {
this.set('value', '')
this.find('input').focus()
})
}
}
</script>
<input type='text' value='{{value}}' placeholder='{{placeholder}}'/>
<ui-button icon='refresh' on-press='clear'/>
+16
View File
@@ -0,0 +1,16 @@
input
display: inline-block
vertical-align: middle
height: 20px
line-height: @height - 3px
padding: 0 5px
white-space: nowrap
color: input-color-text
background-color: input-color-background
border: 1px solid input-color-border
&::placeholder
color: input-color-placeholder
&::-ms-clear
display: none
+88
View File
@@ -0,0 +1,88 @@
<script>
component.exports = {
data: {
graph: require('paths-js/smooth-line'),
xaccessor: point => point.x,
yaccessor: point => point.y
},
computed: {
size () {
const points = this.get('points')
return points[0].length
},
scale () {
const points = this.get('points')
return Math.max(...Array.map(points, a => Math.max(...Array.map(a, p => p.y))))
},
xaxis () {
const xinc = this.get('xinc')
const size = this.get('size')
return Array.from(Array(size).keys()).filter(num => num && num % xinc == 0)
},
yaxis () {
const yinc = this.get('yinc')
const scale = this.get('scale')
return Array.from(Array(yinc).keys()).map(num => Math.round((scale * (++num / 100)) * 10))
}
},
oninit () {
this.on({
enter (event) {
this.set('selected', event.index.count)
},
exit (event) {
this.set('selected')
}
})
window.addEventListener('resize', (event) => {
this.set('width', this.el.clientWidth)
})
},
onrender () {
this.set('width', this.el.clientWidth)
}
}
</script>
<svg class='linegraph' width='100%' height='{{height + 10}}'>
<g transform='translate(0, 5)'>
{{#graph({data: points, xaccessor: xaccessor, yaccessor: yaccessor, width: width, height: height})}}
{{#each xaxis}}
<line x1='{{xscale(.)}}' x2='{{xscale(.)}}' y1='0' y2='{{height}}' stroke='darkgray'/>
{{#if @index % 2 == 0}}
<text x='{{xscale(.)}}' y='{{height - 5}}' text-anchor='middle' fill='white'>{{(size - .) * xfactor}} {{xunit}}</text>
{{/if}}
{{/each}}
{{#each yaxis}}
<line x1='0' x2='{{width}}' y1='{{yscale(.)}}' y2='{{yscale(.)}}' stroke='darkgray'/>
<text x='0' y='{{yscale(.) - 5}}' text-anchor='begin' fill='white'>{{. * yfactor}} {{yunit}}</text>
{{/each}}
{{#each curves:curve}}
<path d='{{area.path.print()}}' fill='{{colors[curve]}}' opacity='0.1'/>
{{/each}}
{{#each curves:curve}}
<path d='{{line.path.print()}}' stroke='{{colors[curve]}}' fill='none'/>
{{/each}}
{{#each curves:curve}}
{{#each line.path.points():count}}
<circle transform='translate({{.}})' r='{{selected == count ? 10 : 4}}' fill='{{colors[curve]}}' on-mouseenter='enter' on-mouseleave='exit'/>
{{/each}}
{{/each}}
{{#each curves:curve}}
{{#each line.path.points():count}}
{{#if selected == count }}
<text transform='translate({{.}}) {{count <= size / 2 ? "translate(15, 4)" : "translate(-15, 4)"}}' text-anchor='{{count <= size / 2 ? "start" : "end"}}' fill='white'>
{{item[count].y * yfactor}} {{yunit}} @ {{(size - item[count].x) * xfactor}} {{xunit}}
</text>
{{/if}}
{{/each}}
{{/each}}
{{#each curves:curve}}
<g transform='translate({{(width / (curves.length + 1)) * (@index + 1)}}, 10)'>
<circle r='4' fill='{{colors[curve]}}'/>
<text x='8' y='4' fill='white'>{{legend[curve]}}</text>
</g>
{{/each}}
{{/graph}}
</g>
</svg>
+2
View File
@@ -0,0 +1,2 @@
svg.linegraph
overflow: hidden
+3
View File
@@ -0,0 +1,3 @@
<div class='notice'>
{{yield}}
</div>
+27
View File
@@ -0,0 +1,27 @@
div.notice
margin: 8px 0
padding: 4px
box-shadow: none
color: text-color-inverse
font-weight: bold
font-style: italic
background-color: notice-color-first
background-image: repeating-linear-gradient(
-45deg,
notice-color-first,
notice-color-first 10px,
notice-color-second 10px,
notice-color-second 20px
)
.label
color: text-color-inverse
.content:only-of-type
padding: 0
hr
background-color: rule-color-dark
+29
View File
@@ -0,0 +1,29 @@
<script>
import { winset } from 'util/byond'
import { resize } from 'util/dragresize'
component.exports = {
oninit () {
const onresize = resize.bind(this)
const onrelease = () => this.set({ resize: false, x: null, y: null })
this.observe('config.fancy', (newkey, oldkey, keypath) => {
winset(this.get('config.window'), 'can-resize', !newkey)
if (newkey) {
document.addEventListener('mousemove', onresize)
document.addEventListener('mouseup', onrelease)
} else {
document.removeEventListener('mousemove', onresize)
document.removeEventListener('mouseup', onrelease)
}
})
this.on('resize', () => this.toggle('resize'))
}
}
</script>
{{#if config.fancy}}
<div class='resize' on-mousedown='resize'></div>
{{/if}}
+12
View File
@@ -0,0 +1,12 @@
div.resize
position: fixed
bottom: 0
right: 0
width: 0
height: 0
border-style: solid;
border-width: 0 0 45px 45px;
border-color: transparent transparent resize-color transparent
transform: rotate(360deg)
+12
View File
@@ -0,0 +1,12 @@
<section class='{{#candystripe}}candystripe{{/candystripe}}'>
{{#if label}}
<span class='label' style='{{#labelcolor}}color:{{labelcolor}}{{/labelcolor}}'>{{label}}:</span>
{{/if}}
{{#if nowrap}}
{{yield}}
{{else}}
<div class='content' style='{{#right}}float:right;{{/right}}'>
{{yield}}
</div>
{{/if}}
</section>
+33
View File
@@ -0,0 +1,33 @@
/$cell
display: table-cell
margin: 0
text-align: left
vertical-align: middle
padding: 3px 2px
section
display: table-row
width: 100%
&:not(:first-child)
padding-top: 4px
&.candystripe:nth-child(even)
background-color: section-color-candystripe
.label
@extend $cell
width: 1%
padding-right: 32px
white-space: nowrap
color: section-color-label
.content
@extend $cell
&:not(:last-child)
padding-right: 16px
.line
@extend $cell
width: 100%
+11
View File
@@ -0,0 +1,11 @@
<div class='subdisplay'>
{{#if title}}
<header>
<h4>{{title}}</h4>
{{#if button}}{{yield button}}{{/if}}
</header>
{{/if}}
<article>
{{yield}}
</article>
</div>
+11
View File
@@ -0,0 +1,11 @@
context = selector()
div.subdisplay
width: 100%
margin: 0
header
@extend {context} div.display header
article
@extend {context} div.display article
+27
View File
@@ -0,0 +1,27 @@
<link rel='ractive' href='components/tabs/tab.ract'>
<script>
component.exports = {
oninit () {
this.set('active', this.findComponent('tab').get('name'))
this.on('switch', event => {
this.set('active', event.node.textContent.trim()) // Hack but it works...
})
this.observe('active', (newkey, oldkey, path) => {
for (let tab of this.findAllComponents('tab')) {
tab.set('shown', (tab.get('name') === newkey))
}
})
}
}
</script>
<header>
{{#each tabs}}
<ui-button pane='{{.}}' on-press='switch'>{{.}}</ui-button>
{{/each}}
</header>
<ui-display>
{{>content}}
</ui-display>
+3
View File
@@ -0,0 +1,3 @@
{{#if shown}}
{{yield}}
{{/if}}
+56
View File
@@ -0,0 +1,56 @@
<script>
import { UI_INTERACTIVE, UI_UPDATE, UI_DISABLED } from 'util/constants'
import { href, winset } from 'util/byond'
import { drag } from 'util/dragresize'
component.exports = {
computed: {
visualStatus () {
switch (this.get('config.status')) {
case UI_INTERACTIVE: return 'good'
case UI_UPDATE: return 'average'
case UI_DISABLED: return 'bad'
default: return 'bad'
}
}
},
oninit () {
const ondrag = drag.bind(this)
const onrelease = (event) => this.set({ drag: false, x: null, y: null })
this.observe('config.fancy', (newkey, oldkey, keypath) => {
winset(this.get('config.window'), 'titlebar', !newkey)
if (newkey) {
document.addEventListener('mousemove', ondrag)
document.addEventListener('mouseup', onrelease)
} else {
document.removeEventListener('mousemove', ondrag)
document.removeEventListener('mouseup', onrelease)
}
})
this.on({
drag () {
this.toggle('drag')
},
close () {
winset(this.get('config.window'), 'is-visible', false)
window.location.href = href({command: `uiclose ${this.get('config.ref')}`}, 'winset')
},
minimize () {
winset(this.get('config.window'), 'is-minimized', true)
}
})
}
}
</script>
<header class='titlebar' on-mousedown='drag'>
<i class='statusicon fa fa-eye fa-2x {{visualStatus}}'></i>
<span class='title'>{{yield}}</span>
{{#if config.fancy}}
<i class='minimize fa fa-minus fa-2x' on-click='minimize'></i>
<i class='close fa fa-close fa-2x' on-click='close'></i>
{{/if}}
</header>
+65
View File
@@ -0,0 +1,65 @@
context = selector()
$titleButton
display: inline-block
position: relative
padding: 7px // To make a bigger clickable area.
margin: -7px
color: titlebar-color-button;
&:hover
color: lighten(titlebar-color-button, button-lighten-hover)
header.titlebar
position: fixed;
z-index: 1
top: 0;
left: 0;
width: 100%;
height: 32px;
background-color: titlebar-color-background
border-bottom: 1px solid titlebar-color-coreshadow
box-shadow: 0 3px 3px titlebar-color-shadow
.statusicon
position: absolute
top: 4px
left: 12px
transition: color 0.5s
.title
position: absolute
top: 6px
left: 46px
color: titlebar-color-text
font-size: 16px
white-space: nowrap
.minimize
@extend {context} $titleButton
position: absolute
top: 6px
right: 46px
.close
@extend {context} $titleButton
position: absolute
top: 4px
right: 12px
/.no-icons header.titlebar
.statusicon
font-size: 20px
&::after
content: "O"
.minimize
top: -2px
font-size: 20px
&::after
content: ""
.close
font-size: 20px
&::after
content: "X"
+47
View File
@@ -0,0 +1,47 @@
<script>
const versions = [11, 10, 9, 8]
component.exports = {
data: {
userAgent: navigator.userAgent
},
computed: {
ie () {
if (document.documentMode) return document.documentMode
for (let version in versions) {
const div = document.createElement('div')
div.innerHTML = `<!--[if IE ${version}]><span></span><![endif]-->`
if (div.getElementsByTagName('span').length) return version
}
return undefined
}
},
oninit () {
this.on('debug', () => this.toggle('debug'))
}
}
</script>
{{#if config.fancy && ie && ie < 11}}
<ui-notice>
<span>You have an old (IE{{ie}}), end-of-life (click 'EOL Info' for more information) version of Internet Explorer installed.</span><br/>
<span>To upgrade, click 'Upgrade IE' to download IE11 from Microsoft.</span><br/>
<span>If you are unable to upgrade directly, click 'IE VMs' to download a VM with IE11 or Edge from Microsoft.</span><br/>
<span>Otherwise, click 'No Frills' below to disable potentially incompatible features (and this message).</span>
<hr/>
<ui-button icon='close' action='tgui:nofrills'>No Frills</ui-button>
<ui-button icon='internet-explorer' action='tgui:link' params='{"url": "http://windows.microsoft.com/en-us/internet-explorer/download-ie"}'>
Upgrade IE</ui-button>
<ui-button icon='edge' action='tgui:link' params='{"url": "https://dev.windows.com/en-us/microsoft-edge/tools/vms"}'>
IE VMs</ui-button>
<ui-button icon='info' action='tgui:link' params='{"url": "https://support.microsoft.com/en-us/lifecycle#gp/Microsoft-Internet-Explorer"}'>
EOL Info</ui-button>
<ui-button icon='bug' on-press='debug'>Debug Info</ui-button>
{{#if debug}}
<hr/>
<span>Detected: IE{{ie}}</span><br/>
<span>User Agent: {{userAgent}}</span>
{{/if}}
</ui-notice>
{{/if}}
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 425 200" opacity=".33">
<path d="m 178.00399,0.03869 -71.20393,0 a 6.7613422,6.0255495 0 0 0 -6.76134,6.02555 l 0,187.87147 a 6.7613422,6.0255495 0 0 0 6.76134,6.02554 l 53.1072,0 a 6.7613422,6.0255495 0 0 0 6.76135,-6.02554 l 0,-101.544018 72.21628,104.699398 a 6.7613422,6.0255495 0 0 0 5.76015,2.87016 l 73.55487,0 a 6.7613422,6.0255495 0 0 0 6.76135,-6.02554 l 0,-187.87147 a 6.7613422,6.0255495 0 0 0 -6.76135,-6.02555 l -54.71644,0 a 6.7613422,6.0255495 0 0 0 -6.76133,6.02555 l 0,102.61935 L 183.76413,2.90886 a 6.7613422,6.0255495 0 0 0 -5.76014,-2.87017 z" />
<path d="M 4.8446333,22.10875 A 13.412039,12.501842 0 0 1 13.477588,0.03924 l 66.118315,0 a 5.3648158,5.000737 0 0 1 5.364823,5.00073 l 0,79.87931 z" />
<path d="m 420.15535,177.89119 a 13.412038,12.501842 0 0 1 -8.63295,22.06951 l -66.11832,0 a 5.3648152,5.000737 0 0 1 -5.36482,-5.00074 l 0,-79.87931 z" />
</svg>
<!-- This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. -->
<!-- http://creativecommons.org/licenses/by-sa/4.0/ -->

After

Width:  |  Height:  |  Size: 1.1 KiB

+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" viewBox="0 0 200 289.742" opacity=".33">
<path d="m 93.537677,0 c -18.113125,0 -34.220133,3.11164 -48.323484,9.33437 -13.965092,6.22167 -24.612442,15.07114 -31.940651,26.5471 -7.1899398,11.33789 -10.3012266,24.74911 -10.3012266,40.23478 0,10.64662 2.7250026,20.46465 8.1751116,29.45258 5.615277,8.98686 14.038277,17.35204 25.268821,25.09436 11.230544,7.60531 26.507421,15.41835 45.830514,23.43782 19.983748,8.29557 34.848848,15.55471 44.592998,21.77638 9.74414,6.22273 16.7617,12.8585 21.05572,19.90951 4.29404,7.05208 6.44193,15.76408 6.44193,26.13459 0,16.17702 -5.20196,28.48222 -15.60673,36.91682 -10.2396,8.4347 -25.02203,12.6523 -44.345169,12.6523 -14.038171,0 -25.515247,-1.6594 -34.433618,-4.9777 -8.91837,-3.4566 -16.185572,-8.7113 -21.800839,-15.7633 -5.615277,-7.0521 -10.074795,-16.66088 -13.377899,-28.82812 l -24.7731626293945,0 0,56.82632 C 33.856769,286.07601 63.74904,289.74201 89.678383,289.74201 c 16.020027,0 30.719787,-1.3827 44.097337,-4.1479 13.54272,-2.9043 25.1041,-7.4676 34.68309,-13.6893 9.74413,-6.3597 17.34042,-14.5195 22.79052,-24.4748 5.4501,-10.09332 8.17511,-22.39959 8.17511,-36.91682 0,-12.99764 -3.3021,-24.33539 -9.90829,-34.0146 -6.44105,-9.81725 -15.52545,-18.52707 -27.25146,-26.13133 -11.56085,-7.60427 -27.91083,-15.83142 -49.05066,-24.68022 -17.50644,-7.19012 -30.719668,-13.68948 -39.638038,-19.49701 -8.918371,-5.80752 -18.607474,-12.43409 -24.096524,-18.87417 -5.426043,-6.36616 -9.658826,-15.07003 -9.658826,-24.88729 0,-9.26401 2.075414,-17.21345 6.223454,-23.85033 11.098298,-14.39748 41.286638,-1.79507 45.075609,24.34762 4.839392,6.77491 8.84935,16.24729 12.029515,28.4156 l 20.53234,0 0,-55.99967 c -4.47825,-5.92448 -9.95488,-10.63222 -15.90837,-14.37411 1.64055,0.47905 3.19039,1.02376 4.63865,1.64024 6.49861,2.62607 12.16793,7.32747 17.0073,14.10345 4.83939,6.77491 8.84935,16.24567 12.02952,28.41397 0,0 8.48128,-0.12894 8.48978,-0.002 0.41776,6.41494 -1.75339,9.45286 -4.12342,12.56104 -2.4174,3.16978 -5.14486,6.78973 -4.00278,13.0029 1.50786,8.20318 10.18354,10.59642 14.62194,9.31154 -3.31842,-0.49911 -5.31855,-1.74948 -5.31855,-1.74948 0,0 1.87646,0.99868 5.65117,-1.35981 -3.27695,0.95571 -10.70529,-0.79738 -11.80125,-6.76313 -0.95752,-5.20861 0.94654,-7.29514 3.40113,-10.51482 2.45462,-3.21968 5.28426,-6.95831 4.6843,-14.48824 l 0.003,0.002 8.92676,0 0,-55.99967 c -15.07125,-3.87168 -27.65314,-6.36042 -37.74671,-7.46586 -9.95531,-1.10755 -20.18823,-1.65981 -30.696613,-1.65981 z m 70.321603,17.30893 0.23805,40.3049 c 1.31808,1.22666 2.43965,2.27815 3.34081,3.10602 4.83939,6.77491 8.84934,16.24566 12.02951,28.41397 l 20.53234,0 0,-55.99967 c -6.67731,-4.59381 -19.83643,-10.47309 -36.14071,-15.82522 z m -28.12049,5.60551 8.56479,17.71655 c -11.97037,-6.46697 -13.84678,-9.71726 -8.56479,-17.71655 z m 22.79705,0 c 2.7715,7.99929 1.78741,11.24958 -4.49354,17.71655 l 4.49354,-17.71655 z m 15.22195,24.00848 8.56479,17.71655 c -11.97038,-6.46697 -13.84679,-9.71726 -8.56479,-17.71655 z m 22.79704,0 c 2.7715,7.99929 1.78741,11.24958 -4.49354,17.71655 l 4.49354,-17.71655 z m -99.11384,2.20764 8.56479,17.71655 c -11.970382,-6.46697 -13.846782,-9.71726 -8.56479,-17.71655 z m 22.79542,0 c 2.7715,7.99929 1.78741,11.24958 -4.49354,17.71655 l 4.49354,-17.71655 z" />
</svg>
<!-- This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. -->
<!-- http://creativecommons.org/licenses/by-sa/4.0/ -->

After

Width:  |  Height:  |  Size: 3.4 KiB

+51
View File
@@ -0,0 +1,51 @@
<link rel='ractive' href='./airalarm/scrubbers.ract'>
<link rel='ractive' href='./airalarm/status.ract'>
<link rel='ractive' href='./airalarm/thresholds.ract'>
<link rel='ractive' href='./airalarm/modes.ract'>
<link rel='ractive' href='./airalarm/vents.ract'>
<ui-notice>
{{#if data.siliconUser}}
<ui-section label='Interface Lock'>
<ui-button icon='{{data.locked ? "lock" : "unlock"}}' action='lock'>{{data.locked ? "Engaged" : "Disengaged"}}</ui-button>
</ui-section>
{{else}}
<span>Swipe an ID card to {{data.locked ? "unlock" : "lock"}} this interface.</span>
{{/if}}
</ui-notice>
<status/>
{{#if !data.locked || data.siliconUser}}
{{#if config.screen == "home"}}
<ui-display title='Air Controls'>
<ui-section>
<ui-button icon='{{data.atmos_alarm ? "exclamation-triangle" : "exclamation"}}' style='{{data.atmos_alarm ? "caution" : null}}'
action='{{data.atmos_alarm ? "reset" : "alarm"}}'>Area Atmosphere Alarm</ui-button>
</ui-section>
<ui-section>
<ui-button icon='{{data.mode == 3 ? "exclamation-triangle" : "exclamation"}}' style='{{data.mode == 3 ? "danger" : null}}'
action='mode' params='{"mode": {{data.mode == 3 ? 1 : 3}}}'>Panic Siphon</ui-button>
</ui-section>
<br/>
<ui-section>
<ui-button icon='sign-out' action='tgui:view' params='{"screen": "vents"}'>Vent Controls</ui-button>
</ui-section>
<ui-section>
<ui-button icon='filter' action='tgui:view' params='{"screen": "scrubbers"}'>Scrubber Controls</ui-button>
</ui-section>
<ui-section>
<ui-button icon='cog' action='tgui:view' params='{"screen": "modes"}'>Operating Mode</ui-button>
</ui-section>
<ui-section>
<ui-button icon='bar-chart' action='tgui:view' params='{"screen": "thresholds"}'>Alarm Thresholds</ui-button>
</ui-section>
</ui-display>
{{elseif config.screen == "vents"}}
<vents/>
{{elseif config.screen == "scrubbers"}}
<scrubbers/>
{{elseif config.screen == "modes"}}
<modes/>
{{elseif config.screen == "thresholds"}}
<thresholds/>
{{/if}}
{{/if}}
+1
View File
@@ -0,0 +1 @@
<ui-button icon='arrow-left' action='tgui:view' params='{"screen": "home"}'>Back</ui-button>
+14
View File
@@ -0,0 +1,14 @@
<link rel='ractive' href='./back.ract'>
<ui-display title='Operating Modes' button>
{{#partial button}}
<back/>
{{/partial}}
{{#each data.modes}}
<ui-section>
<ui-button icon='{{selected ? "check-square-o" : "square-o"}}'
state='{{selected ? danger ? "danger" : "selected" : null}}'
action='mode' params='{"mode": {{mode}}}'>{{name}}</ui-button>
</ui-section>
{{/each}}
</ui-display>
@@ -0,0 +1,35 @@
<link rel='ractive' href='./back.ract'>
<ui-display title='Scrubber Controls' button>
{{#partial button}}
<back/>
{{/partial}}
{{#each data.scrubbers}}
<ui-subdisplay title='{{long_name}}'>
<ui-section label='Power'>
<ui-button icon='{{power ? "power-off" : "close"}}' style='{{power ? "selected" : null}}'
action='power' params='{"id_tag": "{{id_tag}}", "val": {{+!power}}}'>{{power ? "On" : "Off"}}</ui-button>
</ui-section>
<ui-section label='Mode'>
<ui-button icon='{{scrubbing ? "filter" : "sign-in"}}' style='{{scrubbing ? null : "danger"}}'
action='scrubbing' params='{"id_tag": "{{id_tag}}", "val": {{+!scrubbing}}}'>{{scrubbing ? "Scrubbing" : "Siphoning"}}</ui-button>
</ui-section>
<ui-section label='Range'>
<ui-button icon='{{widenet ? "expand" : "compress"}}' style='{{widenet ? "selected" : null}}'
action='widenet' params='{"id_tag": "{{id_tag}}", "val": {{+!widenet}}}'>{{widenet ? "Expanded" : "Normal"}}</ui-button>
</ui-section>
<ui-section label='Filters'>
<ui-button icon='{{filter_co2 ? "check-square-o" : "square-o"}}' style='{{filter_co2 ? "selected" : null}}'
action='co2_scrub' params='{"id_tag": "{{id_tag}}", "val": {{+!filter_co2}}}'>CO2</ui-button>
<ui-button icon='{{filter_n2o ? "check-square-o" : "square-o"}}' style='{{filter_n2o ? "selected" : null}}'
action='n2o_scrub' params='{"id_tag": "{{id_tag}}", "val": {{+!filter_n2o}}}'>N2O</ui-button>
<ui-button icon='{{filter_toxins ? "check-square-o" : "square-o"}}' style='{{filter_toxins ? "selected" : null}}'
action='tox_scrub' params='{"id_tag": "{{id_tag}}", "val": {{+!filter_toxins}}}'>Plasma</ui-button>
<ui-button icon='{{filter_bz ? "check-square-o" : "square-o"}}' style='{{filter_bz ? "selected" : null}}'
action='bz_scrub' params='{"id_tag": "{{id_tag}}", "val": {{+!filter_bz}}}'>BZ</ui-button>
</ui-section>
</ui-subdisplay>
{{else}}
<span class='bad'>Error: No scrubbers connected.</span>
{{/each}}
</ui-display>
+30
View File
@@ -0,0 +1,30 @@
<ui-display title='Air Status'>
{{#if data.environment_data}}
{{#each adata.environment_data}}
<ui-section label='{{name}}'>
<span class='{{danger_level == 2 ? "bad" : danger_level == 1 ? "average" : "good"}}'>
{{Math.fixed(value, 2)}}{{unit}}
</span>
</ui-section>
{{/each}}
<ui-section label='Local Status'>
<span class='{{data.danger_level == 2 ? "bad bold" : data.danger_level == 1 ? "average bold" : "good"}}'>
{{data.danger_level == 2 ? "Danger (Internals Required)" : data.danger_level == 1 ? "Caution" : "Optimal"}}
</span>
</ui-section>
<ui-section label='Area Status'>
<span class='{{data.atmos_alarm || data.fire_alarm ? "bad bold" : "good"}}'>
{{data.atmos_alarm ? "Atmosphere Alarm" : fire_alarm ? "Fire Alarm" : "Nominal"}}
</span>
</ui-section>
{{else}}
<ui-section label='Warning'>
<span class='bad bold'>Cannot obtain air sample for analysis.</span>
</ui-section>
{{/if}}
{{#if data.emagged}}
<ui-section label='Warning'>
<span class='bad bold'>Safety measures offline. Device may exhibit abnormal behavior.</span>
</ui-section>
{{/if}}
</ui-display>
@@ -0,0 +1,31 @@
<link rel='ractive' href='./back.ract'>
<ui-display title='Alarm Thresholds' button>
{{#partial button}}
<back/>
{{/partial}}
<table>
<thead><tr>
<th></th>
<th><span class="bad">min2</span></th>
<th><span class="average">min1</span></th>
<th><span class="average">max1</span></th>
<th><span class="bad">max2</span></th>
</tr></thead>
<tbody>
{{#each data.thresholds}}<tr>
<th>{{{name}}}</th>
{{#each settings}}<td>
<ui-button action='threshold' params='{"env": "{{env}}", "var": "{{val}}"}'>{{Math.fixed(selected, 2)}}</ui-button>
</td>{{/each}}
</tr>{{/each}}
</tbody>
<table>
</ui-display>
<style>
th, td {
padding-right: 16px;
text-align: left;
}
</style>
+32
View File
@@ -0,0 +1,32 @@
<link rel='ractive' href='./back.ract'>
<ui-display title='Vent Controls' button>
{{#partial button}}
<back/>
{{/partial}}
{{#each data.vents}}
<ui-subdisplay title='{{long_name}}'>
<ui-section label='Power'>
<ui-button icon='{{power ? "power-off" : "close"}}' style='{{power ? "selected" : null}}'
action='power' params='{"id_tag": "{{id_tag}}", "val": {{+!power}}}'>{{power ? "On" : "Off"}}</ui-button>
</ui-section>
<ui-section label='Mode'>
<span>{{direction == "release" ? "Pressurizing" : "Siphoning"}}</span>
</ui-section>
<ui-section label='Pressure Regulator'>
<ui-button icon='sign-in' style='{{incheck ? "selected" : null}}'
action='incheck' params='{"id_tag": "{{id_tag}}", "val": {{checks}}}'>Internal</ui-button>
<ui-button icon='sign-out' style='{{excheck ? "selected" : null}}'
action='excheck' params='{"id_tag": "{{id_tag}}", "val": {{checks}}}'>External</ui-button>
</ui-section>
<ui-section label='Target Pressure'>
<ui-button icon='pencil' action='set_external_pressure'
params='{"id_tag": "{{id_tag}}"}'>{{Math.fixed(external)}}</ui-button>
<ui-button icon='refresh' state='{{extdefault ? "disabled" : null}}' action='reset_external_pressure'
params='{"id_tag": "{{id_tag}}"}'>Reset</ui-button>
</ui-section>
</ui-subdisplay>
{{else}}
<span class='bad'>Error: No vents connected.</span>
{{/each}}
</ui-display>
@@ -0,0 +1,39 @@
<ui-display>
<ui-section>
<ui-button icon='{{data.oneAccess ? "unlock" : "lock"}}' action='one_access'>{{data.oneAccess ? "One" : "All"}} Required</ui-button>
<ui-button icon='refresh' action='clear'>Clear</ui-button>
</ui-section>
<hr/>
<table>
<thead>
<tr>{{#each data.regions}}
<th><span class='highlight bold'>{{name}}</span></th>
{{/each}}</tr>
</thead>
<tbody>
<tr>{{#each data.regions}}
<td>{{#each accesses}}
<ui-button icon='{{req ? "check-square-o" : "square-o"}}' style='{{req ? "selected" : null}}'
action='set' params='{"access": "{{id}}"}'>{{name}}</ui-button>
<br/>
{{/each}}</td>
{{/each}}</tr>
</tbody>
</table>
</ui-display>
<style>
table {
width: 100%;
border-spacing: 2px;
}
th {
text-align: left;
}
td {
vertical-align: top;
}
td .button {
margin-top: 4px
}
</style>
+125
View File
@@ -0,0 +1,125 @@
<script>
component.exports = {
data: {
powerState (status) {
switch (status) {
case 2: return 'good'
case 1: return 'average'
default: return 'bad'
}
}
},
computed: {
malfAction () {
switch (this.get('data.malfStatus')) {
case 1: return 'hack'
case 2: return 'occupy'
case 3: return 'deoccupy'
}
},
malfButton () {
switch (this.get('data.malfStatus')) {
case 1: return 'Override Programming'
case 2:
case 4: return 'Shunt Core Process'
case 3: return 'Return to Main Core'
}
},
malfIcon () {
switch (this.get('data.malfStatus')) {
case 1: return 'terminal'
case 2:
case 4: return 'caret-square-o-down'
case 3: return 'caret-square-o-left'
}
},
powerCellStatusState () {
const status = this.get('data.powerCellStatus')
if (status > 50) return 'good'
else if (status > 25) return 'average'
else return 'bad'
}
}
}
</script>
<ui-notice>
{{#if data.siliconUser}}
<ui-section label='Interface Lock'>
<ui-button icon='{{data.locked ? "lock" : "unlock"}}' action='lock'>{{data.locked ? "Engaged" : "Disengaged"}}</ui-button>
</ui-section>
{{else}}
<span>Swipe an ID card to {{data.locked ? "unlock" : "lock"}} this interface.</span>
{{/if}}
</ui-notice>
<ui-display title='Power Status'>
<ui-section label='Main Breaker'>
{{#if data.locked && !data.siliconUser}}
<span class='{{data.isOperating ? "good" : "bad"}}'>{{data.isOperating ? "On" : "Off"}}</span>
{{else}}
<ui-button icon='{{data.isOperating ? "power-off" : "close"}}' style='{{data.isOperating ? "selected" : null}}'
action='breaker'>{{data.isOperating ? "On" : "Off"}}</ui-button>
{{/if}}
</ui-section>
<ui-section label='External Power'>
<span class='{{powerState(data.externalPower)}}'>{{data.externalPower == 2 ? "Good" : data.externalPower == 1 ? "Low" : "None"}}</span>
</ui-section>
<ui-section label='Power Cell'>
{{#if data.powerCellStatus != null}}
<ui-bar min='0' max='100' value='{{data.powerCellStatus}}' state='{{powerCellStatusState}}'>{{Math.fixed(adata.powerCellStatus)}}%</ui-bar>
{{else}}
<span class='bad'>Removed</span>
{{/if}}
</ui-section>
{{#if data.powerCellStatus != null}}
<ui-section label='Charge Mode'>
{{#if data.locked && !data.siliconUser}}
<span class='{{data.chargeMode ? "good" : "bad"}}'>{{data.chargeMode ? "Auto" : "Off"}}</span>
{{else}}
<ui-button icon='{{data.chargeMode ? "refresh" : "close"}}' style='{{data.chargeMode ? "selected" : null}}'
action='charge'>{{data.chargeMode ? "Auto" : "Off"}}</ui-button>
{{/if}}
&nbsp;
[<span class='{{powerState(data.chargingStatus)}}'>{{data.chargingStatus == 2 ? "Fully Charged" : data.chargingStatus == 1 ? "Charging" : "Not Charging"}}</span>]
</ui-section>
{{/if}}
</ui-display>
<ui-display title='Power Channels'>
{{#each data.powerChannels}}
<ui-section label='{{title}}' nowrap>
<div class='content'>{{Math.round(adata.powerChannels[@index].powerLoad)}} W</div>
<div class='content'><span class='{{status >= 2 ? "good" : "bad"}}'>{{status >= 2 ? "On" : "Off"}}</span></div>
<div class='content'>[<span>{{status == 1 || status == 3 ? "Auto" : "Manual"}}</span>]</div>
<div class='content' style='float:right'>
{{#if !data.locked || data.siliconUser}}
<ui-button icon='refresh' state='{{status == 1 || status == 3 ? "selected" : null}}'
action='channel' params='{{topicParams.auto}}'>Auto</ui-button>
<ui-button icon='power-off' state='{{status == 2 ? "selected" : null}}' action='channel'
params='{{topicParams.on}}'>On</ui-button>
<ui-button icon='close' state='{{status == 0 ? "selected" : null}}' action='channel'
params='{{topicParams.off}}'>Off</ui-button>
{{/if}}
</div>
</ui-section>
{{/each}}
<ui-section label='Total Load'>
<span class='bold'>{{Math.round(adata.totalLoad)}} W</span>
</ui-section>
</ui-display>
{{#if data.siliconUser}}
<ui-display title='System Overrides'>
<ui-button icon='lightbulb-o' action='overload'>Overload</ui-button>
{{#if data.malfStatus}}
<ui-button icon='{{malfIcon}}' state='{{data.malfStatus == 4 ? "disabled" : null}}' action='{{malfAction}}'>{{malfButton}}</ui-button>
{{/if}}
</ui-display>
{{/if}}
<ui-notice>
<ui-section label='Cover Lock'>
{{#if data.locked && !data.siliconUser}}
<span>{{data.coverLocked ? "Engaged" : "Disengaged"}}</span>
{{else}}
<ui-button icon='{{data.coverLocked ? "lock" : "unlock"}}' action='cover'>{{data.coverLocked ? "Engaged" : "Disengaged"}}</ui-button>
{{/if}}
</ui-section>
</ui-notice>
+14
View File
@@ -0,0 +1,14 @@
<ui-display title='Alarms'>
<ul>
{{#each data.priority}}
<li><ui-button icon='close' style='danger' action='clear' params='{"zone": "{{.}}"}'>{{.}}</ui-button></li>
{{else}}
<li><span class='good'>No Priority Alerts</span></li>
{{/each}}
{{#each data.minor}}
<li><ui-button icon='close' style='caution' action='clear' params='{"zone": "{{.}}"}'>{{.}}</ui-button></li>
{{else}}
<li><span class='good'>No Minor Alerts</span></li>
{{/each}}
</ul>
</ui-display>
+40
View File
@@ -0,0 +1,40 @@
<ui-display title='{{data.tank ? data.sensors[0].long_name : null}}'>
{{#each adata.sensors}}
<ui-subdisplay title='{{!data.tank ? long_name : null}}'>
<ui-section label='Pressure'>
<span>{{Math.fixed(pressure, 2)}} kPa</span>
</ui-section>
{{#if temperature}}
<ui-section label='Temperature'>
<span>{{Math.fixed(temperature, 2)}} K</span>
</ui-section>
{{/if}}
{{#each gases:id}}
<ui-section label='{{id}}'>
<span>{{Math.fixed(., 2)}}%</span>
</ui-section>
{{/each}}
</ui-subdisplay>
{{/each}}
</ui-display>
{{#if data.tank}}
<ui-display title='Controls' button>
{{#partial button}}
<ui-button icon='refresh' action='reconnect'>Reconnect</ui-button>
{{/partial}}
<ui-section label='Input Injector'>
<ui-button icon='{{data.inputting ? "power-off" : "close"}}' style='{{data.inputting ? "selected" : null}}' action='input'>
{{data.inputting ? "Injecting": "Off"}}</ui-button>
</ui-section>
<ui-section label='Input Rate'>
<span>{{Math.fixed(adata.inputRate)}} L/s</span>
</ui-section>
<ui-section label='Output Regulator'>
<ui-button icon='{{data.outputting ? "power-off" : "close"}}' style='{{data.outputting ? "selected" : null}}' action='output'>
{{data.outputting ? "Open": "Closed"}}</ui-button>
</ui-section>
<ui-section label='Output Pressure'>
<ui-button icon='pencil' action='pressure'>{{Math.round(adata.outputPressure)}} kPa</ui-button>
</ui-section>
</ui-display>
{{/if}}
+27
View File
@@ -0,0 +1,27 @@
<ui-display>
<ui-section label='Power'>
<ui-button icon='{{data.on ? "power-off" : "close"}}' style='{{data.on ? "selected" : null}}'
action='power'>{{data.on ? "On" : "Off"}}</ui-button>
</ui-section>
<ui-section label='Output Pressure'>
<ui-button icon='pencil' action='pressure' params='{"pressure": "input"}'>Set</ui-button>
<ui-button icon='plus' state='{{data.pressure == data.max_pressure ? "disabled" : null}}' action='pressure' params='{"pressure": "max"}'>Max</ui-button>
<span>{{Math.round(adata.pressure)}} kPa</span>
</ui-section>
<ui-section label='Filter'>
<ui-button state='{{data.filter_type == "" ? "selected" : null}}'
action='filter' params='{"mode": ""}'>Nothing</ui-button>
<ui-button state='{{data.filter_type == "plasma" ? "selected" : null}}'
action='filter' params='{"mode": "plasma"}'>Plasma</ui-button>
<ui-button state='{{data.filter_type == "o2" ? "selected" : null}}'
action='filter' params='{"mode": "o2"}'>O2</ui-button>
<ui-button state='{{data.filter_type == "n2" ? "selected" : null}}'
action='filter' params='{"mode": "n2"}'>N2</ui-button>
<ui-button state='{{data.filter_type == "co2" ? "selected" : null}}'
action='filter' params='{"mode": "co2"}'>CO2</ui-button>
<ui-button state='{{data.filter_type == "n2o" ? "selected" : null}}'
action='filter' params='{"mode": "n2o"}'>N2O</ui-button>
<ui-button state='{{data.filter_type == "bz" ? "selected" : null}}'
action='filter' params='{"mode": "bz"}'>BZ</ui-button>
</ui-section>
</ui-display>
+33
View File
@@ -0,0 +1,33 @@
<ui-display>
<ui-section label='Power'>
<ui-button icon='{{data.on ? "power-off" : "close"}}' style='{{data.on ? "selected" : null}}'
action='power'>{{data.on ? "On" : "Off"}}</ui-button>
</ui-section>
<ui-section label='Output Pressure'>
<ui-button icon='pencil' action='pressure' params='{"pressure": "input"}'>Set</ui-button>
<ui-button icon='plus' state='{{data.set_pressure == data.max_pressure ? "disabled" : null}}' action='pressure' params='{"pressure": "max"}'>Max</ui-button>
<span>{{Math.round(adata.set_pressure)}} kPa</span>
</ui-section>
<ui-section label='Node 1'>
<ui-button icon='fast-backward' state='{{data.node1_concentration == 0 ? "disabled" : null}}'
action='node1' params='{"concentration": -0.1}'/>
<ui-button icon='backward' state='{{data.node1_concentration == 0 ? "disabled" : null}}'
action='node1' params='{"concentration": -0.01}'/>
<ui-button icon='forward' state='{{data.node1_concentration == 100 ? "disabled" : null}}'
action='node1' params='{"concentration": 0.01}'/>
<ui-button icon='fast-forward' state='{{data.node1_concentration == 100 ? "disabled" : null}}'
action='node1' params='{"concentration": 0.1}'/>
<span>{{Math.round(adata.node1_concentration)}}%</span>
</ui-section>
<ui-section label='Node 2'>
<ui-button icon='fast-backward' state='{{data.node2_concentration == 0 ? "disabled" : null}}'
action='node2' params='{"concentration": -0.1}'/>
<ui-button icon='backward' state='{{data.node2_concentration == 0 ? "disabled" : null}}'
action='node2' params='{"concentration": -0.01}'/>
<ui-button icon='forward' state='{{data.node2_concentration == 100 ? "disabled" : null}}'
action='node2' params='{"concentration": 0.01}'/>
<ui-button icon='fast-forward' state='{{data.node2_concentration == 100 ? "disabled" : null}}'
action='node2' params='{"concentration": 0.1}'/>
<span>{{Math.round(adata.node2_concentration)}}%</span>
</ui-section>
</ui-display>
+19
View File
@@ -0,0 +1,19 @@
<ui-display>
<ui-section label='Power'>
<ui-button icon='{{data.on ? "power-off" : "close"}}' style='{{data.on ? "selected" : null}}'
action='power'>{{data.on ? "On" : "Off"}}</ui-button>
</ui-section>
{{#if data.max_rate}}
<ui-section label='Transfer Rate'>
<ui-button icon='pencil' action='rate' params='{"rate": "input"}'>Set</ui-button>
<ui-button icon='plus' state='{{data.rate == data.max_rate ? "disabled" : null}}' action='transfer' params='{"rate": "max"}'>Max</ui-button>
<span>{{Math.round(adata.rate)}} L/s</span>
</ui-section>
{{else}}
<ui-section label='Output Pressure'>
<ui-button icon='pencil' action='pressure' params='{"pressure": "input"}'>Set</ui-button>
<ui-button icon='plus' state='{{data.pressure == data.max_pressure ? "disabled" : null}}' action='pressure' params='{"pressure": "max"}'>Max</ui-button>
<span>{{Math.round(adata.pressure)}} kPa</span>
</ui-section>
{{/if}}
</ui-display>
+18
View File
@@ -0,0 +1,18 @@
<ui-display title='Cell Timer' button>
{{#partial button}}
<ui-button icon='clock-o' style='{{data.timing ? "selected" : null}}' action='{{data.timing ? "stop" : "start"}}'>{{data.timing ? "Stop" : "Start"}}</ui-button>
<ui-button icon='lightbulb-o' action='flash' style='{{data.flash_charging ? "disabled" : null}}'>{{data.flash_charging ? "Recharging" : "Flash"}}</ui-button>
{{/partial}}
<ui-section>
<ui-button icon='fast-backward' action='time' params='{"adjust": -600}'></ui-button>
<ui-button icon='backward' action='time' params='{"adjust": -100}'></ui-button>
<span>{{text.zeroPad(data.minutes, 2)}}:{{text.zeroPad(data.seconds, 2)}}</span>
<ui-button icon='forward' action='time' params='{"adjust": 100}'></ui-button>
<ui-button icon='fast-forward' action='time' params='{"adjust": 600}'></ui-button>
</ui-section>
<ui-section>
<ui-button icon='hourglass-start' action='preset' params='{"preset": "short"}'>Short</ui-button>
<ui-button icon='hourglass-start' action='preset' params='{"preset": "medium"}'>Medium</ui-button>
<ui-button icon='hourglass-start' action='preset' params='{"preset": "long"}'>Long</ui-button>
</ui-section>
</ui-display>
+53
View File
@@ -0,0 +1,53 @@
<ui-notice>
<span>The regulator {{data.hasHoldingTank ? "is" : "is not"}} connected to a tank.</span>
</ui-notice>
<ui-display title='Canister' button>
{{#partial button}}
<ui-button icon='pencil' action='relabel'>Relabel</ui-button>
{{/partial}}
<ui-section label='Pressure'>
<span>{{Math.round(adata.tankPressure)}} kPa</span>
</ui-section>
<ui-section label='Port'>
<span class='{{data.portConnected ? "good" : "average"}}'>{{data.portConnected ? "Connected" : "Not Connected"}}</span>
</ui-section>
</ui-display>
<ui-display title='Valve'>
<ui-section label='Release Pressure'>
<ui-bar min='{{data.minReleasePressure}}' max='{{data.maxReleasePressure}}'
value='{{data.releasePressure}}'>{{Math.round(adata.releasePressure)}} kPa</ui-bar>
</ui-section>
<ui-section label='Pressure Regulator'>
<ui-button icon='refresh' state='{{data.releasePressure != data.defaultReleasePressure ? null : "disabled"}}'
action='pressure' params='{"pressure": "reset"}'>Reset</ui-button>
<ui-button icon='minus' state='{{data.releasePressure > data.minReleasePressure ? null : "disabled"}}'
action='pressure' params='{"pressure": "min"}'>Min</ui-button>
<ui-button icon='pencil' action='pressure' params='{"pressure": "input"}'>Set</ui-button>
<ui-button icon='plus' state='{{data.releasePressure < data.maxReleasePressure ? null : "disabled"}}'
action='pressure' params='{"pressure": "max"}'>Max</ui-button>
</ui-section>
<ui-section label='Valve'>
<ui-button icon='{{data.valveOpen ? "unlock" : "lock"}}'
style='{{data.valveOpen ? data.hasHoldingTank ? "caution" : "danger" : null}}'
action='valve'>{{data.valveOpen ? "Open" : "Closed"}}</ui-button>
</ui-section>
</ui-display>
<ui-display title='Holding Tank' button>
{{#partial button}}
{{#if data.hasHoldingTank}}
<ui-button icon='eject' style='{{data.valveOpen ? "danger" : null}}' action='eject'>Eject</ui-button>
{{/if}}
{{/partial}}
{{#if data.hasHoldingTank}}
<ui-section label='Label'>
{{data.holdingTank.name}}
</ui-section>
<ui-section label='Pressure'>
{{Math.round(adata.holdingTank.tankPressure)}} kPa
</ui-section>
{{else}}
<ui-section>
<span class='average'>No Holding Tank</span>
</ui-section>
{{/if}}
</ui-display>
+88
View File
@@ -0,0 +1,88 @@
<script>
component.exports = {
computed: {
tabs () {
return Object.keys(this.get('data.supplies'))
}
}
}
</script>
<ui-display title='Cargo'>
<ui-section label='Shuttle'>
{{#if data.docked && !data.requestonly}}
<ui-button action='send'>{{data.location}}</ui-button>
{{else}}
<span>{{data.location}}</span>
{{/if}}
</ui-section>
<ui-section label='Credits'>
<span>{{Math.floor(adata.points)}}</span>
</ui-section>
<ui-section label='Centcom Message'>
<span>{{data.message}}</span>
</ui-section>
{{#if data.loan && !data.requestonly}}
<ui-section label='Loan'>
{{#if !data.loan_dispatched}}
<ui-button action='loan'>Loan Shuttle</ui-button>
{{else}}
<span class='bad'>Loaned to Centcom</span>
{{/if}}
</ui-section>
{{/if}}
</ui-display>
{{#if !data.requestonly}}
<ui-display title='Cart' button>
{{#partial button}}
<ui-button icon='close' state='{{data.cart.length ? null : "disabled"}}' action='clear'>Clear</ui-button>
{{/partial}}
{{#each data.cart}}
<ui-section candystripe nowrap>
<div class='content'>#{{id}}</div>
<div class='content'>{{object}}</div>
<div class='content'>{{cost}} Credits</div>
<div class='content'>
<ui-button icon='minus' action='remove' params='{"id": "{{id}}"}'/>
</div>
</ui-section>
{{else}}
<span>Nothing in Cart</span>
{{/each}}
</ui-display>
{{/if}}
<ui-display title='Requests' button>
{{#partial button}}
{{#if !data.requestonly}}
<ui-button icon='close' state='{{data.requests.length ? null : "disabled"}}' action='denyall'>Clear</ui-button>
{{/if}}
{{/partial}}
{{#each data.requests}}
<ui-section candystripe nowrap>
<div class='content'>#{{id}}</div>
<div class='content'>{{object}}</div>
<div class='content'>{{cost}} Credits</div>
<div class='content'>By {{orderer}}</div>
<div class='content'>Comment: {{reason}}</div>
{{#if !data.requestonly}}
<div class='content'>
<ui-button icon='check' action='approve' params='{"id": "{{id}}"}'/>
<ui-button icon='close' action='deny' params='{"id": "{{id}}"}'/>
</div>
{{/if}}
</ui-section>
{{else}}
<span>No Requests</span>
{{/each}}
</ui-display>
<ui-tabs tabs='{{tabs}}'>
{{#each data.supplies}}
<tab name='{{name}}'>
{{#each packs}}
<ui-section label='{{name}}' candystripe right>
<ui-button action='add' params='{"id": "{{id}}"}'>{{cost}} Credits</ui-button>
</ui-section>
{{/each}}
</tab>
{{/each}}
</ui-tabs>
@@ -0,0 +1,30 @@
<ui-display title="Cellular Emporium" button>
<ui-button icon='refresh' state='{{data.can_readapt ? null : "disabled"}}'
action='readapt'>Readapt</ui-button>
<ui-section label='Genetic Points Remaining' right>
{{data.genetic_points_remaining}}
</ui-section>
</ui-display>
<ui-display>
{{#each data.abilities}}
<ui-section label='{{name}}' candystripe right>
<span>{{desc}}</span>
<span>{{helptext}}</span>
<span>Cost: {{dna_cost}}</span>
{{#if required_absorbtions}}
<span>Required Absorbtions: {{required_absorbtions}}
{{/if}}
<ui-button
state='{{owned ? "selected" : can_purchase ? null : "disabled"}}'
action='evolve'
params='{"name": "{{name}}"}'>
{{owned ? "Evolved" : "Evolve"}}
</ui-button>
</ui-section>
{{/each}}
{{^data.abilities}}
<span class='warning'>No abilities availible.</span>
{{/data.abilities}}
</ui-display>
+38
View File
@@ -0,0 +1,38 @@
<ui-display title='Status'>
<ui-section label='Energy'>
<ui-bar min='0' max='{{data.maxEnergy}}' value='{{data.energy}}'>{{Math.fixed(adata.energy)}} Units</ui-bar>
</ui-section>
</ui-display>
<ui-display title='Dispense' button>
{{#partial button}}
{{#each data.beakerTransferAmounts}}
<ui-button icon='plus' state='{{data.amount == . ? "selected" : null}}' action='amount' params='{"target": {{.}}}'>{{.}}</ui-button>
{{/each}}
{{/partial}}
<ui-section>
{{#each data.chemicals}}
<ui-button grid icon='tint' action='dispense' params='{"reagent": "{{id}}"}'>{{title}}</ui-button>
{{/each}}
</ui-section>
</ui-display>
<ui-display title='Beaker' button>
{{#partial button}}
{{#each data.beakerTransferAmounts}}
<ui-button icon='minus' action='remove' params='{"amount": {{.}}}'>{{.}}</ui-button>
{{/each}}
<ui-button icon='eject' state='{{data.isBeakerLoaded ? null : "disabled"}}' action='eject'>Eject</ui-button>
{{/partial}}
<ui-section label='Contents'>
{{#if data.isBeakerLoaded}}
<span>{{Math.round(adata.beakerCurrentVolume)}}/{{data.beakerMaxVolume}} Units</span>
<br/>
{{#each adata.beakerContents}}
<span class='highlight' intro-outro='fade'>{{Math.fixed(volume, 2)}} units of {{name}}</span><br/>
{{else}}
<span class='bad'>Beaker Empty</span>
{{/each}}
{{else}}
<span class='average'>No Beaker</span>
{{/if}}
</ui-section>
</ui-display>
+29
View File
@@ -0,0 +1,29 @@
<ui-display title='Thermostat'>
<ui-section label='Power'>
<ui-button icon='{{data.isActive ? "power-off" : "close"}}'
style='{{data.isActive ? "selected" : null}}'
state='{{data.isBeakerLoaded ? null : "disabled"}}'
action='power'>{{data.isActive ? "On" : "Off"}}</ui-button>
</ui-section>
<ui-section label='Target'>
<ui-button icon='pencil' action='temperature' params='{"target": "input"}'>{{Math.round(adata.targetTemp)}} K</ui-button>
</ui-section>
</ui-display>
<ui-display title='Beaker' button>
{{#partial button}}
<ui-button icon='eject' state='{{data.isBeakerLoaded ? null : "disabled"}}' action='eject'>Eject</ui-button>
{{/partial}}
<ui-section label='Contents'>
{{#if data.isBeakerLoaded}}
<span>Temperature: {{Math.round(adata.currentTemp)}} K</span>
<br />
{{#each adata.beakerContents}}
<span class='highlight' intro-outro='fade'>{{Math.fixed(volume, 2)}} units of {{name}}</span><br/>
{{else}}
<span class='bad'>Beaker Empty</span>
{{/each}}
{{else}}
<span class='average'>No Beaker</span>
{{/if}}
</ui-section>
</ui-display>
+107
View File
@@ -0,0 +1,107 @@
{{#if data.screen == "home"}}
<ui-display title='Beaker' button>
<ui-button icon='{{data.isBeakerLoaded ? "Eject" : "close"}}'
style='{{data.isBeakerLoaded ? "selected" : null}}'
state='{{data.isBeakerLoaded ? null : "disabled"}}'
action='eject'
>{{data.isBeakerLoaded ? "Eject and Clear Buffer" : "No beaker"}}
</ui-button>
<ui-section>
{{#if data.isBeakerLoaded}}
{{#each data.beakerContents}}
<ui-section label='{{Math.fixed(volume, 2)}} units of {{name}}' nowrap>
<div class='content' style='float:right'>
<ui-button action='transferToBuffer' params='{"id": "{{id}}", "amount": 1}'>1</ui-button>
<ui-button action='transferToBuffer' params='{"id": "{{id}}", "amount": 5}'>5</ui-button>
<ui-button action='transferToBuffer' params='{"id": "{{id}}", "amount": 10}'>10</ui-button>
<ui-button action='transferToBuffer' params='{"id": "{{id}}", "amount": 1000}'>All</ui-button>
<ui-button action='transferToBuffer' params='{"id": "{{id}}", "amount": -1}'>Custom</ui-button>
<ui-button action='analyze' params='{"id": "{{id}}"}'>Analyze</ui-button>
</div>
</ui-section>
{{else}}
<span class='bad'>Beaker Empty</span>
{{/each}}
{{else}}
<span class='average'>No Beaker</span>
{{/if}}
</ui-section>
</ui-display>
<ui-display title='Buffer'>
<ui-button action='toggleMode' state='{{data.mode ? null : "selected"}}'>Destroy</ui-button>
<ui-button action='toggleMode' state='{{data.mode ? "selected" : null}}'>Transfer to Beaker</ui-button>
<ui-section>
{{#each data.bufferContents}}
<ui-section label='{{Math.fixed(volume, 2)}} units of {{name}}' nowrap>
<div class='content' style='float:right'>
<ui-button action='transferFromBuffer' params='{"id": "{{id}}", "amount": 1}'>1</ui-button>
<ui-button action='transferFromBuffer' params='{"id": "{{id}}", "amount": 5}'>5</ui-button>
<ui-button action='transferFromBuffer' params='{"id": "{{id}}", "amount": 10}'>10</ui-button>
<ui-button action='transferFromBuffer' params='{"id": "{{id}}", "amount": 1000}'>All</ui-button>
<ui-button action='transferFromBuffer' params='{"id": "{{id}}", "amount": -1}'>Custom</ui-button>
<ui-button action='analyze' params='{"id": "{{id}}"}'>Analyze</ui-button>
</div>
</ui-section>
{{/each}}
</ui-section>
</ui-display>
{{#if !data.condi}}
<ui-display title='Pills, Bottles and Patches' >
{{#if data.isPillBottleLoaded}}
<ui-button action='ejectp' state='{{data.isPillBottleLoaded ? null : "disabled"}}'>{{data.isPillBottleLoaded ? "Eject" : "No Pill bottle loaded"}}</ui-button>
<span class='content'>{{data.pillBotContent}}/{{data.pillBotMaxContent}}</span>
{{else}}
<span class='average'>No Pillbottle</span>
{{/if}}
<br/>
<br/>
<ui-button action='createPill' params='{"many": 0}' state='{{data.bufferContents ? null : "disabled"}}' >Create Pill (max 50µ)</ui-button>
<br/>
<ui-button action='createPill' params='{"many": 1}' state='{{data.bufferContents ? null : "disabled"}}' >Create Multiple Pills</ui-button>
<br/>
<br/>
<ui-button action='createPatch' params='{"many": 0}' state='{{data.bufferContents ? null : "disabled"}}' >Create Patch (max 50µ)</ui-button>
<br/>
<ui-button action='createPatch' params='{"many": 1}' state='{{data.bufferContents ? null : "disabled"}}' >Create Multiple Patches</ui-button>
<br/>
<br/>
<ui-button action='createBottle' state='{{data.bufferContents ? null : "disabled"}}' >Create Bottle (max 30µ)</ui-button>
</ui-display>
{{else}}
<ui-display title='Condiments bottles and packs' >
<ui-button action='createPill' params='{"many": 0}' state='{{data.bufferContents ? null : "disabled"}}' >Create Pack (max 10µ)</ui-button>
<br/>
<br/>
<ui-button action='createBottle' state='{{data.bufferContents ? null : "disabled"}}' >Create Bottle (max 50µ)</ui-button>
</ui-display>
{{/if}}
{{elseif data.screen == "analyze"}}
<ui-display title={{data.analyzeVars.name}} >
<span class='highlight'>Description: </span>
<span class='content' style='float:center'>{{data.analyzeVars.description}}</span>
<br/>
<span class='highlight'>Color: </span>
<span style='color: {{data.analyzeVars.color}}; background-color: {{data.analyzeVars.color}}'>{{data.analyzeVars.color}}</span>
<br/>
<span class='highlight'>State: </span>
<span class='content'>{{data.analyzeVars.state}}</span>
<br/>
<span class='highlight'>Metabolization Rate: </span>
<span class='content'>{{data.analyzeVars.metaRate}}µ/minute</span>
<br/>
<span class='highlight'>Overdose Threshold: </span>
<span class='content'>{{data.analyzeVars.overD}}</span>
<br/>
<span class='highlight'>Addiction Threshold: </span>
<span class='content'>{{data.analyzeVars.addicD}}</span>
<br/>
<br/>
<ui-button action='goScreen' params='{"screen": "home"}'>Back</ui-button>
</ui-display>
{{/if}}
+35
View File
@@ -0,0 +1,35 @@
{{#if data.has_cap}}
<ui-display>
<ui-section label='Cap'>
<ui-button icon='{{data.is_capped ? "power-off" : "close"}}' style='{{data.is_capped ? null : "selected"}}'
action='toggle_cap'>
{{data.is_capped ? "On": "Off"}}</ui-button>
</ui-section>
</ui-display>
{{/if}}
<ui-display>
{{!<ui-section label='Current Colour'>{{{current_colour}</span>
</ui-section>}}
{{#if data.can_change_colour}}
<ui-section>
<ui-button action='select_colour'>Select New Colour</ui-button>
</ui-section>
{{/if}}
</ui-display>
<ui-display title='Stencil'>
{{#each data.drawables}}
<ui-section label='{{name}}'>
{{#each items}}
<ui-button action='select_stencil' params='{"item":"{{item}}"}'
style='{{item == data.selected_stencil ? "selected" : null}}'>
{{item}}
</ui-button>
{{/each}}
</ui-section>
{{/each}}
</ui-display>
<ui-display title="Text Mode">
<ui-section label='Current Buffer'>{{text_buffer}}
</ui-section>
<ui-section><ui-button action='enter_text'>New Text</ui-button></ui-section>
</ui-display>
+74
View File
@@ -0,0 +1,74 @@
<script>
component.exports = {
data: {
temperatureStatus (temp) {
if (temp < 225) return 'good'
else if (temp < 273.15) return 'average'
else return 'bad'
}
},
computed: {
occupantStatState () {
switch (this.get('data.occupant.stat')) {
case 0: return 'good'
case 1: return 'average'
default: return 'bad'
}
}
}
}
</script>
<ui-display title='Occupant'>
<ui-section label='Occupant'>
<span>{{data.occupant.name ? data.occupant.name : "No Occupant"}}</span>
</ui-section>
{{#if data.hasOccupant}}
<ui-section label='State'>
<span class='{{occupantStatState}}'>{{data.occupant.stat == 0 ? "Conscious" : data.occupant.stat == 1 ? "Unconcious" : "Dead"}}</span>
</ui-section>
<ui-section label='Temperature'>
<span class='{{temperatureStatus(adata.occupant.bodyTemperature)}}'>{{Math.round(adata.occupant.bodyTemperature)}} K</span>
</ui-section>
<ui-section label='Health'>
<ui-bar min='{{data.occupant.minHealth}}' max='{{data.occupant.maxHealth}}' value='{{data.occupant.health}}'
state='{{data.occupant.health >= 0 ? "good" : "average"}}'>{{Math.round(adata.occupant.health)}}</ui-bar>
</ui-section>
{{#each [{label: "Brute", type: "bruteLoss"}, {label: "Respiratory", type: "oxyLoss"}, {label: "Toxin", type: "toxLoss"}, {label: "Burn", type: "fireLoss"}]}}
<ui-section label='{{label}}'>
<ui-bar min='0' max='{{data.occupant.maxHealth}}' value='{{data.occupant[type]}}' state='bad'>{{Math.round(adata.occupant[type])}}</ui-bar>
</ui-section>
{{/each}}
{{/if}}
</ui-display>
<ui-display title='Cell'>
<ui-section label='Power'>
<ui-button icon='{{data.isOperating ? "power-off" : "close"}}'
style='{{data.isOperating ? "selected" : null}}'
state='{{data.isOpen ? "disabled" : null}}'
action='power'>{{data.isOperating ? "On" : "Off"}}</ui-button>
</ui-section>
<ui-section label='Temperature'>
<span class='{{temperatureStatus(adata.cellTemperature)}}'>{{Math.round(adata.cellTemperature)}} K</span>
</ui-section>
<ui-section label='Door'>
<ui-button icon='{{data.isOpen ? "unlock" : "lock"}}' action='door'>{{data.isOpen ? "Open" : "Closed"}}</ui-button>
<ui-button icon='{{data.autoEject ? "sign-out" : "sign-in"}}' action='autoeject'>{{data.autoEject ? "Auto" : "Manual"}}</ui-button>
</ui-section>
</ui-display>
<ui-display title='Beaker' button>
{{#partial button}}
<ui-button icon='eject' state='{{data.isBeakerLoaded ? null : "disabled"}}' action='ejectbeaker'>Eject</ui-button>
{{/partial}}
<ui-section label='Contents'>
{{#if data.isBeakerLoaded}}
{{#each adata.beakerContents}}
<span class='highlight' intro-outro='fade'>{{Math.fixed(volume, 2)}} units of {{name}}</span><br/>
{{else}}
<span class='bad'>Beaker Empty</span>
{{/each}}
{{else}}
<span class='average'>No Beaker</span>
{{/if}}
</ui-section>
</ui-display>
@@ -0,0 +1,30 @@
<ui-notice>
<span>Time Until Launch: {{data.timer_str}}</span>
</ui-notice>
<ui-notice>
<span>Engines: {{data.engines_started ? 'Online' : 'Idle'}}</span>
</ui-notice>
<ui-display title='Early Launch'>
<span>Authorizations Remaining:
{{data.emagged ? "ERROR" : data.authorizations_remaining}}</span>
<ui-button icon="exclamation-triangle" action='authorize'
style='danger'
state='{{data.enabled ? null : 'disabled'}}'>
AUTHORIZE
</ui-button>
<ui-button icon="minus" action='repeal'
state='{{data.enabled ? null : 'disabled'}}'>
Repeal
</ui-button>
<ui-button icon="close" action='abort'
state='{{data.enabled ? null : 'disabled'}}'>
Repeal All
</ui-button>
</ui-display>
<ui-display title='Authorizations'>
{{#each data.authorizations}}
<ui-section candystripe nowrap>{{name}} ({{job}})</ui-section>
{{else}}
<ui-section candystripe nowrap>No authorizations.</ui-section>
{{/each}}
</ui-display>
+3
View File
@@ -0,0 +1,3 @@
<ui-notice>
<span>The requested interface ({{config.interface}}) was not found. Does it exist?</span>
</ui-notice>
+29
View File
@@ -0,0 +1,29 @@
<script>
component.exports = {
computed: {
seclevelState () {
switch (this.get('data.seclevel')) {
case 'blue': return 'average'
case 'red': return 'bad'
case 'delta': return 'bad bold'
default: return 'good'
}
}
}
}
</script>
<ui-display>
<ui-section label='Alert Level'>
<span class='{{seclevelState}}'>{{text.titleCase(data.seclevel)}}</span>
</ui-section>
<ui-section label='Controls'>
<ui-button icon='{{data.alarm ? "close" : "bell-o"}}' action='{{data.alarm ? "reset" : "alarm"}}'>
{{data.alarm ? "Reset" : "Activate"}}</ui-button>
</ui-section>
{{#if data.emagged}}
<ui-section label='Warning'>
<span class='bad bold'>Safety measures offline. Device may exhibit abnormal behavior.</span>
</ui-section>
{{/if}}
</ui-display>
+49
View File
@@ -0,0 +1,49 @@
<ui-display title='Labor Camp Teleporter'>
<ui-section label='Teleporter Status'>
<span class='{{data.teleporter ? "good" : "bad"}}'>{{data.teleporter ? "Connected" : "Not connected"}}</span>
</ui-section>
{{#if data.teleporter}}
<ui-section label='Location'>
<span>{{data.teleporter_location}}</span>
</ui-section>
<ui-section label='Locked status'>
<ui-button icon='{{data.teleporter_lock ? "lock" : "unlock"}}' action="teleporter_lock">{{data.teleporter_lock ? "Locked" : "Unlocked"}}</ui-button>
<ui-button action='toggle_open'>{{data.teleporter_state_open ? "Open" : "Closed"}}</ui-button>
</ui-section>
{{else}}
<span><ui-button action="scan_teleporter">Scan Teleporter</ui-button></span>
{{/if}}
</ui-display>
<ui-display title='Labor Camp Beacon'>
<ui-section label='Beacon Status'>
<span class='{{data.beacon ? "good" : "bad"}}'>{{data.beacon ? "Connected" : "Not connected"}}</span>
</ui-section>
{{#if data.beacon}}
<ui-section label='Location'>
<span>{{data.beacon_location}}</span>
</ui-section>
{{else}}
<span><ui-button action="scan_beacon">Scan Beacon</ui-button></span>
{{/if}}
</ui-display>
<ui-display title='Prisoner details'>
<ui-section label='Prisoner ID'>
<ui-button action="handle_id">{{data.id ? data.id_name : "-------------"}}</ui-button>
</ui-section>
{{#if data.id}}
<ui-section label='Set ID goal'>
<ui-button action="set_goal">{{data.goal}}</ui-button>
</ui-section>
{{/if}}
<ui-section label='Occupant'>
<span>{{data.prisoner.name ? data.prisoner.name : "No Occupant"}}</span>
</ui-section>
{{#if data.prisoner}}
<ui-section label='Criminal Status'>
<span>{{data.prisoner.crimstat}}</span>
</ui-section>
{{/if}}
</ui-display>
<ui-display>
<center><ui-button action="teleport" state={{data.can_teleport ? null : 'disabled'}}>Process Prisoner</ui-button></center>
</ui-display>
@@ -0,0 +1,10 @@
<ui-display>
<center><ui-button action="handle_id">{{data.id ? data.id.name : "-------------"}}</ui-button></center>
</ui-display>
<ui-display title='Stored Items'>
{{#each data.mobs}}
<ui-section label='{{name}}'>
<ui-button action="release_items" params='{"mobref":{{mob}}}' state={{data.can_reclaim ? null : 'disabled'}}>Drop Items</ui-button>
</ui-section>
{{/each}}
</ui-display>
+42
View File
@@ -0,0 +1,42 @@
<script>
component.exports = {
computed: {
healthState () {
const health = this.get('data.health')
if (health > 70) return 'good'
else if (health > 50) return 'average'
else return 'bad'
}
}
}
</script>
{{#if data.wiping}}
<ui-notice>
<span>Wipe in progress!</span>
</ui-notice>
{{/if}}
<ui-display title={{data.name || "Empty Card"}} button>
{{#partial button}}
{{#if data.name}}
<ui-button icon='trash' state='{{data.wiping || data.isDead ? "disabled" : null}}' action='wipe'>Wipe AI</ui-button>
{{/if}}
{{/partial}}
{{#if data.name}}
<ui-section label='Status'>
<span class='{{data.isDead || data.isBraindead ? "bad" : "good"}}'>{{data.isDead || data.isBraindead ? "Offline" : "Operational"}}</span>
</ui-section>
<ui-section label='Software Integrity'>
<ui-bar min='0' max='100' value='{{data.health}}' state='{{healthState}}'>{{Math.round(adata.health)}}%</ui-bar>
</ui-section>
<ui-section label='Laws'>
{{#each data.laws}}
<span class='highlight'>{{.}}</span><br/>
{{/each}}
</ui-section>
<ui-section label='Settings'>
<ui-button icon='signal' style='{{data.wireless ? "selected" : null}}' action="wireless">Wireless Activity</ui-button>
<ui-button icon='microphone' style='{{data.radio ? "selected" : null}}' action="radio">Subspace Radio</ui-button>
</ui-section>
{{/if}}
</ui-display>
+16
View File
@@ -0,0 +1,16 @@
{{#if data.waiting}}
<ui-notice>
<span>Waiting for another device to confirm your request...</span>
</ui-notice>
{{else}}
<ui-display>
<ui-section>
{{#if data.auth_required}}
<ui-button icon='check' action='auth_swipe'>Authorize {{data.auth_required}}</ui-button>
{{else}}
<ui-button icon='warning' state='{{data.red_alert ? 'disabled' : null}}' action='red_alert'>Red Alert</ui-button>
<ui-button icon='wrench' state='{{data.emergency_maint ? 'disabled' : null}}' action='emergency_maint'>Emergency Maintenance Access</ui-button>
{{/if}}
</ui-section>
</ui-display>
{{/if}}
@@ -0,0 +1,29 @@
<ui-display title='Ore values'>
{{#each data.ores}}
<ui-section label='{{ore}}'>
<span>{{value}}</span>
</ui-section>
{{/each}}
</ui-display>
<ui-display title='Points'>
<ui-section label='ID'>
<ui-button action="handle_id">{{data.id ? data.id_name : "-------------"}}</ui-button>
</ui-section>
{{#if data.id}}
<ui-section label='Points collected'>
<span>{{data.points}}</span>
</ui-section>
<ui-section label='Goal'>
<span>{{data.goal}}</span>
</ui-section>
<ui-section label='Unclaimed points'>
<span>{{data.unclaimed_points}}</span>
<ui-button action="claim_points" state={{data.unclaimed_points ? null : 'disabled'}}>Claim points</ui-button>
</ui-section>
{{/if}}
</ui-display>
<ui-display>
<center>
<ui-button action="move_shuttle" state={{data.can_go_home ? null : 'disabled'}}>Move shuttle</ui-button>
</center>
</ui-display>
@@ -0,0 +1,44 @@
<script>
component.exports = {
data: {
mechChargeState(charge) {
let maxcharge = this.get('data.recharge_port.mech.cell.maxcharge')
if(charge >= (maxcharge/1.5)) return 'good'
else if(charge >= (maxcharge/3)) return 'average'
else return 'bad'
},
mechHealthState(health) {
let maxhealth = this.get('data.recharge_port.mech.maxhealth')
if(health > (maxhealth/1.5)) return 'good'
else if(health > (maxhealth/3)) return 'average'
else return 'bad'
}
}
}
</script>
<ui-display title='Mech Status'>
{{#if data.recharge_port}}
{{#if data.recharge_port.mech}}
<ui-section label='Integrity'>
<ui-bar min='0' max='{{adata.recharge_port.mech.maxhealth}}' value='{{adata.recharge_port.mech.health}}'state='{{mechHealthState(adata.recharge_port.mech.health)}}'>{{Math.round(adata.recharge_port.mech.health)}}/{{adata.recharge_port.mech.maxhealth}}</ui-bar>
</ui-section>
{{#if data.recharge_port.mech.cell}}
{{#if data.recharge_port.mech.cell.critfail}}
<ui-section label='Power'><span class='bad'>Cell Critical Failure</span></ui-section>
{{else}}
<ui-section label='Power'>
<ui-bar min='0' max='{{adata.recharge_port.mech.cell.maxcharge}}' value='{{adata.recharge_port.mech.cell.charge}}'state='{{mechChargeState(adata.recharge_port.mech.cell.charge)}}'>{{Math.round(adata.recharge_port.mech.cell.charge)}}/{{Math.round(adata.recharge_port.mech.cell.maxcharge)}}</ui-bar>
</ui-section>
{{/if}}
{{else}}
<ui-section label='Power'><span class='bad'>Cell Missing</span></ui-section>
{{/if}}
{{else}}
<ui-section>Mech Not Found</ui-section>
{{/if}}
{{else}}
<ui-section>Recharging Port Not Found</ui-section>
<ui-button icon='refresh' action='reconnect'>Reconnect</ui-button>
{{/if}}
</ui-display>
+60
View File
@@ -0,0 +1,60 @@
<ui-notice>
{{#if data.siliconUser}}
<ui-section label='Interface Lock'>
<ui-button icon='{{data.locked ? "lock" : "unlock"}}' action='lock'>{{data.locked ? "Engaged" : "Disengaged"}}</ui-button>
</ui-section>
{{else}}
<span>Swipe an ID card to {{data.locked ? "unlock" : "lock"}} this interface.</span>
{{/if}}
</ui-notice>
<ui-display title='Status'>
<ui-section label='Power'>
{{#if !data.locked || data.siliconUser }}
<ui-button icon='{{data.on ? "power-off" : "close"}}' style='{{data.on ? "selected" : null}}' action="power">{{data.on ? "On" : "Off"}}</ui-button>
{{else}}
<span class='{{data.on ? "good" : "bad"}}' state='{{data.cell ? null : "disabled"}}'>{{data.on ? "On" : "Off"}}</span>
{{/if}}
</ui-section>
<ui-section label='Cell'>
<span class='{{data.cell ? null : "bad"}}'>{{data.cell ? data.cellPercent + "%" : "No Cell"}}</span>
</ui-section>
<ui-section label='Mode'>
<span class='{{data.modeStatus}}'>{{data.mode}}</span>
</ui-section>
<ui-section label='Load'>
<span class='{{data.load ? "good" : "average"}}'>{{data.load ? data.load : "None"}}</span>
</ui-section>
<ui-section label='Destination'>
<span class='{{data.destination ? "good": "average"}}'>{{data.destination ? data.destination : "None"}}</span>
</ui-section>
</ui-display>
{{#if !data.locked || data.siliconUser}}
<ui-display title='Controls' button>
{{#partial button}}
{{#if data.load}}
<ui-button icon='eject' action='unload'>Unload</ui-button>
{{/if}}
{{#if data.haspai}}
<ui-button icon='eject' action='ejectpai'>Eject PAI</ui-button>
{{/if}}
<ui-button icon='pencil' action='setid'>Set ID</ui-button>
{{/partial}}
<ui-section label='Destination'>
<ui-button icon='pencil' action='destination'>Set Destination</ui-button>
<ui-button icon='stop' action='stop'>Stop</ui-button>
<ui-button icon='play' action='go'>Go</ui-button>
</ui-section>
<ui-section label='Home'>
<ui-button icon='home' action='home'>Go Home</ui-button>
<ui-button icon='pencil' action='sethome'>Set Home</ui-button>
</ui-section>
<ui-section label='Settings'>
<ui-button icon='{{data.autoReturn ? "check-square-o" : "square-o"}}' style='{{data.autoReturn ? "selected" : null}}' action='autoret'>
Auto-Return Home</ui-button>
<ui-button icon='{{data.autoPickup ? "check-square-o" : "square-o"}}' style='{{data.autoPickup ? "selected" : null}}' action='autopick'>
Auto-Pickup Crate</ui-button>
<ui-button icon='{{data.reportDelivery ? "check-square-o" : "square-o"}}' style='{{data.reportDelivery ? "selected" : null}}' action='report'>
Report Deliveries</ui-button>
</ui-section>
</ui-display>
{{/if}}
@@ -0,0 +1,88 @@
<script>
import { filterMulti } from 'util/filter'
component.exports = {
data: {
filter: ''
},
oninit () {
this.observe('filter', (newkey, oldkey, keypath) => {
const categories = this.findAll('.display:not(:first-child)')
filterMulti(categories, this.get('filter').toLowerCase())
}, { init: false })
}
}
</script>
<ui-display title='{{data.category}}'>
{{#if data.busy}}
<ui-section>
Crafting... <i class='fa-spin fa fa-spinner'></i>
</ui-section>
{{else}}
<ui-section>
<ui-button icon='arrow-left' action ='backwardCat'>
{{data.prev_cat}}
</ui-button>
<ui-button icon='arrow-right' action='forwardCat'>
{{data.next_cat}}
</ui-button>
{{#if data.display_craftable_only}}
<ui-button icon='lock' action='toggle_recipes'>
Showing Craftable Recipes
</ui-button>
{{else}}
<ui-button icon='unlock' action='toggle_recipes'>
Showing All Recipes
</ui-button>
{{/if}}
{{#if config.fancy}}
<ui-input value='{{filter}}' placeholder='Filter..'/>
{{/if}}
</ui-section>
{{#each data.can_craft}}
<ui-display title='{{name}}'>
{{#if req_text}}
<ui-section label='Requirements'>
{{req_text}}
</ui-section>
{{/if}}
{{#if catalyst_text}}
<ui-section label='Catalysts'>
{{catalyst_text}}
</ui-section>
{{/if}}
{{#if tool_text}}
<ui-section label='Tools'>
{{tool_text}}
</ui-section>
{{/if}}
<ui-section>
<ui-button icon='gears' action='make' params='{"recipe": "{{ref}}"}'>
Craft
</ui-button>
</ui-section>
</ui-display>
{{/each}}
{{^data.display_craftable_only}}
{{#each data.cant_craft}}
<ui-display title='{{name}}'>
{{#if req_text}}
<ui-section label='Requirements'>
{{req_text}}
</ui-section>
{{/if}}
{{#if catalyst_text}}
<ui-section label='Catalysts'>
{{catalyst_text}}
</ui-section>
{{/if}}
{{#if tool_text}}
<ui-section label='Tools'>
{{tool_text}}
</ui-section>
{{/if}}
</ui-display>
{{/each}}
{{/data.display_craftable_only}}
{{/if}}
</ui-display>
+54
View File
@@ -0,0 +1,54 @@
<ui-notice>
<span>The regulator {{data.holding ? "is" : "is not"}} connected to a tank.</span>
</ui-notice>
<ui-display title='Status' button>
<ui-section label='Pressure'>
<span>{{Math.round(adata.pressure)}} kPa</span>
</ui-section>
<ui-section label='Port'>
<span class='{{data.connected ? "good" : "average"}}'>{{data.connected ? "Connected" : "Not Connected"}}</span>
</ui-section>
</ui-display>
<ui-display title='Pump'>
<ui-section label='Power'>
<ui-button icon='{{data.on ? "power-off" : "close"}}'
style='{{data.on ? "selected" : "null"}}'
action='power'>{{data.on ? "On" : "Off"}}</ui-button>
</ui-section>
<ui-section label='Direction'>
<ui-button icon='{{data.direction == "out" ? "sign-out" : "sign-in"}}'
action='direction'>{{data.direction == "out" ? "Out" : "In"}}</ui-button>
</ui-section>
<ui-section label='Target Pressure'>
<ui-bar min='{{data.min_pressure}}' max='{{data.max_pressure}}'
value='{{data.target_pressure}}'>{{Math.round(adata.target_pressure)}} kPa</ui-bar>
</ui-section>
<ui-section label='Pressure Regulator'>
<ui-button icon='refresh' state='{{data.target_pressure != data.default_pressure ? null : "disabled"}}'
action='pressure' params='{"pressure": "reset"}'>Reset</ui-button>
<ui-button icon='minus' state='{{data.target_pressure > data.min_pressure ? null : "disabled"}}'
action='pressure' params='{"pressure": "min"}'>Min</ui-button>
<ui-button icon='pencil' action='pressure' params='{"pressure": "input"}'>Set</ui-button>
<ui-button icon='plus' state='{{data.target_pressure < data.max_pressure ? null : "disabled"}}'
action='pressure' params='{"pressure": "max"}'>Max</ui-button>
</ui-section>
</ui-display>
<ui-display title='Holding Tank' button>
{{#partial button}}
{{#if data.holding}}
<ui-button icon='eject' style='{{data.on ? "danger" : null}}' action='eject'>Eject</ui-button>
{{/if}}
{{/partial}}
{{#if data.holding}}
<ui-section label='Label'>
{{data.holding.name}}
</ui-section>
<ui-section label='Pressure'>
{{Math.round(adata.holding.pressure)}} kPa
</ui-section>
{{else}}
<ui-section>
<span class='average'>No Holding Tank</span>
</ui-section>
{{/if}}
</ui-display>
@@ -0,0 +1,37 @@
<ui-notice>
<span>The regulator {{data.holding ? "is" : "is not"}} connected to a tank.</span>
</ui-notice>
<ui-display title='Status' button>
<ui-section label='Pressure'>
<span>{{Math.round(adata.pressure)}} kPa</span>
</ui-section>
<ui-section label='Port'>
<span class='{{data.connected ? "good" : "average"}}'>{{data.connected ? "Connected" : "Not Connected"}}</span>
</ui-section>
</ui-display>
<ui-display title='Filter'>
<ui-section label='Power'>
<ui-button icon='{{data.on ? "power-off" : "close"}}'
style='{{data.on ? "selected" : "null"}}'
action='power'>{{data.on ? "On" : "Off"}}</ui-button>
</ui-section>
</ui-display>
<ui-display title='Holding Tank' button>
{{#partial button}}
{{#if data.holding}}
<ui-button icon='eject' style='{{data.on ? "danger" : null}}' action='eject'>Eject</ui-button>
{{/if}}
{{/partial}}
{{#if data.holding}}
<ui-section label='Label'>
{{data.holding.name}}
</ui-section>
<ui-section label='Pressure'>
{{Math.round(adata.holding.pressure)}} kPa
</ui-section>
{{else}}
<ui-section>
<span class='average'>No Holding Tank</span>
</ui-section>
{{/if}}
</ui-display>
+77
View File
@@ -0,0 +1,77 @@
<script>
component.exports = {
data: {
chargingState (status) {
switch (status) {
case 2: return 'good'
case 1: return 'average'
default: return 'bad'
}
},
chargingMode (status) {
if (status == 2) return 'Full'
else if (status == 1) return 'Charging'
else return 'Draining'
},
channelState (status) {
if (status >= 2) return 'good'
else return 'bad'
},
channelPower (status) {
if (status >= 2) return 'On'
else return 'Off'
},
channelMode (status) {
if (status == 1 || status == 3) return 'Auto'
else return 'Manual'
}
},
computed: {
graphData () {
const history = this.get('data.history')
return Object.keys(history).map(key => {
return history[key].map((point, index) => {
return { x: index, y: point }
})
})
}
}
}
</script>
<ui-display title='Network'>
{{#if config.fancy}}
<ui-linegraph points='{{graphData}}' height='500'
legend='["Available", "Load"]' colors='["rgb(0, 102, 0)", "rgb(153, 0, 0)"]'
xunit='seconds ago' xfactor='{{data.interval}}' yunit='W' yfactor='1'
xinc='{{data.stored / 10}}' yinc='9'/>
{{else}}
<ui-section label='Available'>
<span>{{data.supply}} W</span>
</ui-section>
<ui-section label='Load'>
<span>{{data.demand}} W</span>
</ui-section>
{{/if}}
</ui-display>
<ui-display title='Areas'>
<ui-section nowrap>
<div class='content'>Area</div>
<div class='content'>Charge</div>
<div class='content'>Load</div>
<div class='content'>Status</div>
<div class='content'>Equipment</div>
<div class='content'>Lighting</div>
<div class='content'>Environment</div>
</ui-section>
{{#each data.areas}}
<ui-section label='{{name}}' nowrap>
<div class='content'>{{Math.round(adata.areas[@index].charge)}} %</div>
<div class='content'>{{Math.round(adata.areas[@index].load)}} W</div>
<div class='content'><span class='{{chargingState(charging)}}'>{{chargingMode(charging)}}</span></div>
<div class='content'><span class='{{channelState(eqp)}}'>{{channelPower(eqp)}} [<span>{{channelMode(eqp)}}</span>]</span></div>
<div class='content'><span class='{{channelState(lgt)}}'>{{channelPower(lgt)}} [<span>{{channelMode(lgt)}}</span>]</span></div>
<div class='content'><span class='{{channelState(env)}}'>{{channelPower(env)}} [<span>{{channelMode(env)}}</span>]</span></div>
</ui-section>
{{/each}}
</ui-display>
+66
View File
@@ -0,0 +1,66 @@
<script>
component.exports = {
computed: {
readableFrequency () {
return Math.round(this.get('adata.frequency')) / 10
}
}
}
</script>
<ui-display title='Settings'>
{{#if data.headset}}
<ui-section label='Power'>
<ui-button icon='{{data.listening ? "power-off" : "close"}}' style='{{data.listening ? "selected" : null}}'
action='listen'>
{{data.listening ? "On": "Off"}}</ui-button>
</ui-section>
{{else}}
<ui-section label='Microphone'>
<ui-button icon='{{data.broadcasting ? "power-off" : "close"}}' style='{{data.broadcasting ? "selected" : null}}'
action='broadcast'>
{{data.broadcasting ? "Engaged": "Disengaged"}}</ui-button>
</ui-section>
<ui-section label='Speaker'>
<ui-button icon='{{data.listening ? "power-off" : "close"}}' style='{{data.listening ? "selected" : null}}'
action='listen'>
{{data.listening ? "Engaged": "Disengaged"}}</ui-button>
</ui-section>
{{/if}}
{{#if data.command}}
<ui-section label='High Volume'>
<ui-button icon='{{data.useCommand ? "power-off" : "close"}}' style='{{data.useCommand ? "selected" : null}}'
action='command'>
{{data.useCommand ? "On": "Off"}}</ui-button>
</ui-section>
{{/if}}
</ui-display>
<ui-display title='Channel'>
<ui-section label='Frequency'>
{{#if data.freqlock}}
<span>{{readableFrequency}}</span>
{{else}}
<ui-button icon='fast-backward' state='{{data.frequency == data.minFrequency ? "disabled": null}}' action='frequency' params='{"adjust": -1}'/>
<ui-button icon='backward' state='{{data.frequency == data.minFrequency ? "disabled": null}}' action='frequency' params='{"adjust": -.2}'/>
<ui-button icon='pencil' action='frequency' params='{"tune": "input"}'>{{readableFrequency}}</ui-button>
<ui-button icon='forward' state='{{data.frequency == data.maxFrequency ? "disabled": null}}' action='frequency' params='{"adjust": .2}'/>
<ui-button icon='fast-forward' state='{{data.frequency == data.maxFrequency ? "disabled": null}}' action='frequency' params='{"adjust": 1}'/>
{{/if}}
</ui-section>
{{#if data.subspaceSwitchable}}
<ui-section label='Subspace Transmission'>
<ui-button icon='{{data.subspace ? "power-off" : "close"}}' style='{{data.subspace ? "selected" : null}}'
action='subspace'>{{data.subspace ? "Active" : "Inactive"}}</ui-button>
</ui-section>
{{/if}}
{{#if data.subspace && data.channels}}
<ui-section label='Channels'>
{{#each data.channels:channel}}
<ui-button icon='{{. ? "check-square-o" : "square-o"}}'
style='{{. ? "selected" : null}}'
action='channel' params='{"channel": "{{channel}}"}'>
{{channel}}</ui-button><br/>
{{/each}}
</ui-section>
{{/if}}
</ui-display>
@@ -0,0 +1,20 @@
<link rel='ractive' href='./shuttle_manipulator/status.ract'>
<link rel='ractive' href='./shuttle_manipulator/templates.ract'>
<link rel='ractive' href='./shuttle_manipulator/modification.ract'>
<ui-tabs tabs='{{data.tabs}}'>
<tab name='Status'>
<status/>
</tab>
<tab name='Templates'>
<templates/>
</tab>
<tab name='Modification'>
{{#if data.selected}}
<modification/>
{{/if}}
{{#if !data.selected}}
<span class='bad'>No shuttle selected.</span>
{{/if}}
</tab>
</ui-tabs>
@@ -0,0 +1,38 @@
<ui-display title='Selected: {{data.selected.name}}'>
{{#if data.selected.description}}
<ui-section label='Description'>{{data.selected.description}}</ui-section>
{{/if}}
{{#if data.selected.admin_notes}}
<ui-section label='Admin Notes'>{{data.selected.admin_notes}}</ui-section>
{{/if}}
</ui-display>
{{#if data.existing_shuttle}}
<ui-display title='Existing Shuttle: {{data.existing_shuttle.name}}'>
Status: {{data.existing_shuttle.status}}
{{#if data.existing_shuttle.timer}}
({{data.existing_shuttle.timeleft}})
{{/if}}
<ui-button action='jump_to'
params='{"type": "mobile", "id": "{{data.existing_shuttle.id}}"}'>
Jump To
</ui-button>
</ui-display>
{{/if}}
{{#if !data.existing_shuttle}}
<ui-display title='Existing Shuttle: None'></ui-display>
{{/if}}
<ui-button action='preview'
params='{"shuttle_id": "{{data.selected.shuttle_id}}"}'>
Preview
</ui-button>
<ui-button action='load'
params='{"shuttle_id": "{{data.selected.shuttle_id}}"}'
style='danger'>
Load
</ui-button>
<ui-display title='Status'>
</ui-display>
@@ -0,0 +1,14 @@
{{#each data.shuttles}}
<ui-section label='{{name}} ({{id}})'>
{{status}}
{{#if timer}}
({{timeleft}})
{{/if}}
<ui-button action='jump_to' params='{"type": "mobile", "id": "{{id}}"}'>
Jump To
</ui-button>
<ui-button action='fast_travel' params='{"id": "{{id}}"}' state='{{can_fast_travel ? null : 'disabled'}}'>
Fast Travel
</ui-button>
</ui-section>
{{/each}}
@@ -0,0 +1,24 @@
<ui-tabs tabs='{{data.templates_tabs}}'>
{{#each data.templates}}
<tab name='{{port_id}}'>
{{#each templates}}
<ui-display title='{{name}}'>
{{#if description}}
<ui-section label='Description'>{{description}}</ui-section>
{{/if}}
{{#if admin_notes}}
<ui-section label='Admin Notes'>{{admin_notes}}</ui-section>
{{/if}}
<ui-button action='select_template'
params='{"shuttle_id": "{{shuttle_id}}"}'
state='{{data.selected.shuttle_id == shuttle_id ?
"selected" : null}}'>
{{data.selected.shuttle_id == shuttle_id ? "Selected" : "Select"}}
</ui-button>
</ui-display>
{{/each}}
</tab>
{{/each}}
</ui-tabs>
+56
View File
@@ -0,0 +1,56 @@
<script>
component.exports = {
computed: {
occupantStatState () {
switch (this.get('data.occupant.stat')) {
case 0: return 'good'
case 1: return 'average'
default: return 'bad'
}
}
}
}
</script>
<ui-display title='Occupant'>
<ui-section label='Occupant'>
<span>{{data.occupant.name ? data.occupant.name : "No Occupant"}}</span>
</ui-section>
{{#if data.occupied}}
<ui-section label='State'>
<span class='{{occupantStatState}}'>{{data.occupant.stat == 0 ? "Conscious" : data.occupant.stat == 1 ? "Unconcious" : "Dead"}}</span>
</ui-section>
<ui-section label='Health'>
<ui-bar min='{{data.occupant.minHealth}}' max='{{data.occupant.maxHealth}}' value='{{data.occupant.health}}'
state='{{data.occupant.health >= 0 ? "good" : "average"}}'>{{Math.round(adata.occupant.health)}}</ui-bar>
</ui-section>
{{#each [{label: "Brute", type: "bruteLoss"}, {label: "Respiratory", type: "oxyLoss"}, {label: "Toxin", type: "toxLoss"}, {label: "Burn", type: "fireLoss"}]}}
<ui-section label='{{label}}'>
<ui-bar min='0' max='{{data.occupant.maxHealth}}' value='{{data.occupant[type]}}' state='bad'>{{Math.round(adata.occupant[type])}}</ui-bar>
</ui-section>
{{/each}}
<ui-section label='Cells'>
<span class='{{data.occupant.cloneLoss ? "bad" : "good"}}'>{{data.occupant.cloneLoss ? "Damaged" : "Healthy"}}</span>
</ui-section>
<ui-section label='Brain'>
<span class='{{data.occupant.brainLoss ? "bad" : "good"}}'>{{data.occupant.brainLoss ? "Abnormal" : "Healthy"}}</span>
</ui-section>
<ui-section label='Bloodstream'>
{{#each adata.occupant.reagents}}
<span class='highlight' intro-outro='fade'>{{Math.fixed(volume, 1)}} units of {{name}}</span><br/>
{{else}}
<span class='good'>Pure</span>
{{/each}}
</ui-section>
{{/if}}
</ui-display>
<ui-display title='Controls'>
<ui-section label='Door'>
<ui-button icon='{{data.open ? "unlock" : "lock"}}' action='door'>{{data.open ? "Open" : "Closed"}}</ui-button>
</ui-section>
<ui-section label='Inject'>
{{#each data.chems}}
<ui-button icon='flask' state='{{data.occupied && allowed ? null : "disabled"}}' action='inject' params='{"chem": "{{id}}"}'>{{name}}</ui-button><br/>
{{/each}}
</ui-section>
</ui-display>
+14
View File
@@ -0,0 +1,14 @@
{{#each data.bodies}}
<ui-section label='{{name}}' labelcolor='{{htmlcolor}}' candystripe right>
<ui-section label='Status'><span class='{{status == "Dead" ? "bad bold" : status == "Unconscious" ? "average bold" : "good"}}'>{{status}}</span></ui-section>
<ui-section label='Jelly'>{{exoticblood}}</ui-section>
<ui-section label='Location'>{{area}}</ui-section>
<ui-button
state='{{swap_button_state}}'
action='swap' params='{"ref": "{{ref}}"}'>
{{is_current ? "You Are Here" : "Swap"}}
</ui-button>
</ui-section>
{{/each}}
+70
View File
@@ -0,0 +1,70 @@
<script>
component.exports = {
computed: {
capacityPercentState () {
const charge = this.get('data.capacityPercent')
if (charge > 50) return 'good'
else if (charge > 15) return 'average'
else return 'bad'
},
inputState () {
if (this.get('data.capacityPercent') >= 100) return 'good'
else if (this.get('data.inputting')) return 'average'
else return 'bad'
},
outputState () {
if (this.get('data.outputting')) return 'good'
else if (this.get('data.charge') > 0) return 'average'
else return 'bad'
}
}
}
</script>
<ui-display title='Storage'>
<ui-section label='Stored Energy'>
<ui-bar min='0' max='100' value='{{data.capacityPercent}}' state='{{capacityPercentState}}'>{{Math.fixed(adata.capacityPercent)}}%</ui-bar>
</ui-section>
</ui-display>
<ui-display title='Input'>
<ui-section label='Charge Mode'>
<ui-button icon='{{data.inputAttempt ? "refresh" : "close"}}' style='{{data.inputAttempt ? "selected" : null}}'
action='tryinput'>{{data.inputAttempt ? "Auto" : "Off"}}</ui-button>
&nbsp;
[<span class='{{inputState}}'>{{data.capacityPercent >= 100 ? "Fully Charged" : data.inputting ? "Charging" : "Not Charging"}}</span>]
</ui-section>
<ui-section label='Target Input'>
<ui-bar min='0' max='{{data.inputLevelMax}}' value='{{data.inputLevel}}'>{{Math.round(adata.inputLevel)}}W</ui-bar>
</ui-section>
<ui-section label='Adjust Input'>
<ui-button icon='fast-backward' state='{{data.inputLevel == 0 ? "disabled" : null}}' action='input' params='{"target": "min"}'/>
<ui-button icon='backward' state='{{data.inputLevel == 0 ? "disabled" : null}}' action='input' params='{"adjust": -10000}'/>
<ui-button icon='pencil' action='input' params='{"target": "input"}'>Set</ui-button>
<ui-button icon='forward' state='{{data.inputLevel == data.inputLevelMax ? "disabled" : null}}' action='input' params='{"adjust": 10000}'/>
<ui-button icon='fast-forward' state='{{data.inputLevel == data.inputLevelMax ? "disabled" : null}}' action='input' params='{"target": "max"}'/>
</ui-section>
<ui-section label='Available'>
<span>{{Math.round(adata.inputAvailable)}}W</span>
</ui-section>
</ui-display>
<ui-display title='Output'>
<ui-section label='Output Mode'>
<ui-button icon='{{data.outputAttempt ? "power-off" : "close"}}' style='{{data.outputAttempt ? "selected" : null}}'
action='tryoutput'>{{data.outputAttempt ? "On" : "Off"}}</ui-button>
&nbsp;
[<span class='{{outputState}}'>{{data.outputting ? "Sending" : data.charge > 0 ? "Not Sending" : "No Charge"}}</span>]
</ui-section>
<ui-section label='Target Output'>
<ui-bar min='0' max='{{data.outputLevelMax}}' value='{{data.outputLevel}}'>{{Math.round(adata.outputLevel)}}W</ui-bar>
</ui-section>
<ui-section label='Adjust Output'>
<ui-button icon='fast-backward' state='{{data.outputLevel == 0 ? "disabled" : null}}' action='output' params='{"target": "min"}'/>
<ui-button icon='backward' state='{{data.outputLevel == 0 ? "disabled" : null}}' action='output' params='{"adjust": -10000}'/>
<ui-button icon='pencil' action='output' params='{"target": "input"}'>Set</ui-button>
<ui-button icon='forward' state='{{data.outputLevel == data.outputLevelMax ? "disabled" : null}}' action='output' params='{"adjust": 10000}'/>
<ui-button icon='fast-forward' state='{{data.outputLevel == data.outputLevelMax ? "disabled" : null}}' action='output' params='{"target": "max"}'/>
</ui-section>
<ui-section label='Outputting'>
<span>{{Math.round(adata.outputUsed)}}W</span>
</ui-section>
</ui-display>
+46
View File
@@ -0,0 +1,46 @@
<ui-display title='Status'>
<ui-section label='Generated Power'>
{{Math.round(adata.generated)}}W
</ui-section>
<ui-section label='Orientation'>
<span>{{Math.round(adata.angle)}}&deg; ({{data.direction}})</span>
</ui-section>
<ui-section label='Adjust Angle'>
<ui-button icon='step-backward' action='angle' params='{"adjust": -15}'>15&deg;</ui-button>
<ui-button icon='backward' action='angle' params='{"adjust": -5}'>5&deg;</ui-button>
<ui-button icon='forward' action='angle' params='{"adjust": 5}'>5&deg;</ui-button>
<ui-button icon='step-forward' action='angle' params='{"adjust": 15}'>15&deg;</ui-button>
</ui-section>
</ui-display>
<ui-display title='Tracking'>
<ui-section label='Tracker Mode'>
<ui-button icon='close' state='{{data.tracking_state == 0 ? "selected" : null}}'
action='tracking' params='{"mode": 0}'>Off</ui-button>
<ui-button icon='clock-o' state='{{data.tracking_state == 1 ? "selected" : null}}'
action='tracking' params='{"mode": 1}'>Timed</ui-button>
<ui-button icon='refresh' state='{{data.connected_tracker ? data.tracking_state == 2 ? "selected" : null : "disabled"}}'
action='tracking' params='{"mode": 2}'>Auto</ui-button>
</ui-section>
<ui-section label='Tracking Rate'>
<span>{{Math.round(adata.tracking_rate)}}&deg;/h ({{data.rotating_way}})</span>
</ui-section>
<ui-section label='Adjust Rate'>
<ui-button icon='fast-backward' action='rate' params='{"adjust": -180}'>180&deg;</ui-button>
<ui-button icon='step-backward' action='rate' params='{"adjust": -30}'>30&deg;</ui-button>
<ui-button icon='backward' action='rate' params='{"adjust": -5}'>5&deg;</ui-button>
<ui-button icon='forward' action='rate' params='{"adjust": 5}'>5&deg;</ui-button>
<ui-button icon='step-forward' action='rate' params='{"adjust": 30}'>30&deg;</ui-button>
<ui-button icon='fast-forward' action='rate' params='{"adjust": 180}'>180&deg;</ui-button>
</ui-section>
</ui-display>
<ui-display title="Devices" button>
{{#partial button}}
<ui-button icon='refresh' action='refresh'>Refresh</ui-button>
{{/partial}}
<ui-section label='Solar Tracker'>
<span class='{{data.connected_tracker ? "good" : "bad"}}'>{{data.connected_tracker ? "" : "Not "}}Found</span>
</ui-section>
<ui-section label='Solar Panels'>
<span class='{{data.connected_panels ? "good" : "bad"}}'>{{Math.round(adata.connected_panels)}} Panels Connected</span>
</ui-section>
</ui-display>
+45
View File
@@ -0,0 +1,45 @@
<ui-display title='Power' button>
{{#partial button}}
{{#if data.open}}
<ui-button icon='eject' state='{{data.hasPowercell ? null : "disabled"}}' action='eject'>Eject</ui-button>
{{/if}}
{{/partial}}
<ui-section label='Power'>
<ui-button icon='{{data.on ? "power-off" : "close"}}'
style='{{data.on ? "selected" : null}}' state='{{data.hasPowercell ? null : "disabled"}}'
action='power'>{{data.on ? "On" : "Off"}}</ui-button>
</ui-section>
<ui-section label='Cell'>
{{#if data.hasPowercell}}
<ui-bar min='0' max='100' value='{{data.powerLevel}}'>{{Math.fixed(adata.powerLevel)}}%</ui-bar>
{{else}}
<span class='bad'>No Cell</span>
{{/if}}
</ui-section>
</ui-display>
<ui-display title='Thermostat'>
<ui-section label='Current Temperature'>
<span>{{Math.round(adata.currentTemp)}}&deg;C</span>
</ui-section>
<ui-section label='Target Temperature'>
<span>{{Math.round(adata.targetTemp)}}&deg;C</span>
</ui-section>
{{#if data.open}}
<ui-section label='Adjust Target'>
<ui-button icon='fast-backward' state='{{data.targetTemp > data.minTemp ? null : "disabled"}}' action='target' params='{"adjust": -20}'/>
<ui-button icon='backward' state='{{data.targetTemp > data.minTemp ? null : "disabled"}}' action='target' params='{"adjust": -5}'/>
<ui-button icon='pencil' action='target' params='{"target": "input"}'>Set</ui-button>
<ui-button icon='forward' state='{{data.targetTemp < data.maxTemp ? null : "disabled"}}' action='target' params='{"adjust": 5}'/>
<ui-button icon='fast-forward' state='{{data.targetTemp < data.maxTemp ? null : "disabled"}}' action='target' params='{"adjust": 20}'/>
</ui-section>
{{/if}}
<ui-section label='Mode'>
{{#if data.open}}
<ui-button icon='long-arrow-up' state='{{data.mode == "heat" ? "selected" : null}}' action='mode' params='{"mode": "heat"}'>Heat</ui-button>
<ui-button icon='long-arrow-down' state='{{data.mode == "cool" ? "selected" : null}}' action='mode' params='{"mode": "cool"}'>Cool</ui-button>
<ui-button icon='arrows-v' state='{{data.mode == "auto" ? "selected" : null}}' action='mode' params='{"mode": "auto"}'>Auto</ui-button>
{{else}}
<span>{{text.titleCase(data.mode)}}</span>
{{/if}}
</ui-section>
</ui-display>
+11
View File
@@ -0,0 +1,11 @@
{{#each data.alarms:class}}
<ui-display title='{{class}} Alarms'>
<ul>
{{#each .}}
<li>{{.}}</li>
{{else}}
<li>System Nominal</li>
{{/each}}
</ul>
</ui-display>
{{/each}}
@@ -0,0 +1,41 @@
{{#if data.occupied && data.safeties}}
<ui-notice>
<span>Biological entity detected in contents. Please remove.</span>
</ui-notice>
{{/if}}
{{#if data.uv_active}}
<ui-notice>
<span>Contents are being disinfected. Please wait.</span>
</ui-notice>
{{else}}
<ui-display title='Storage' button>
{{#partial button}}
{{#if !data.open}}<ui-button icon='{{data.locked ? "unlock" : "lock"}}' action='lock'>{{data.locked ? 'Unlock' : 'Lock'}}</ui-button>{{/if}}
{{#if !data.locked}}<ui-button icon='{{data.open ? "sign-out" : "sign-in"}}' action='door'>{{data.open ? 'Close' : 'Open'}}</ui-button>{{/if}}
{{/partial}}
{{#if data.locked}}
<ui-notice>
<span>Unit Locked</span>
</ui-notice>
{{elseif data.open}}
<ui-section label='Helmet'>
<ui-button icon='{{data.helmet ? "square" : "square-o"}}'state='{{data.helmet ? null : "disabled"}}'
action='dispense' params='{"item": "helmet"}'>{{data.helmet || "Empty"}}</ui-button>
</ui-section>
<ui-section label='Suit'>
<ui-button icon='{{data.suit ? "square" : "square-o"}}' state='{{data.suit ? null : "disabled"}}'
action='dispense' params='{"item": "suit"}'>{{data.suit || "Empty"}}</ui-button>
</ui-section>
<ui-section label='Mask'>
<ui-button icon='{{data.mask ? "square" : "square-o"}}' state='{{data.mask ? null : "disabled"}}'
action='dispense' params='{"item": "mask"}'>{{data.mask || "Empty"}}</ui-button>
</ui-section>
<ui-section label='Storage'>
<ui-button icon='{{data.storage ? "square" : "square-o"}}' state='{{data.storage ? null : "disabled"}}'
action='dispense' params='{"item": "storage"}'>{{data.storage || "Empty"}}</ui-button>
</ui-section>
{{else}}
<ui-button icon='recycle' state='{{data.occupied && data.safeties ? "disabled" : null}}' action='uv'>Disinfect</ui-button>
{{/if}}
</ui-display>
{{/if}}
+8
View File
@@ -0,0 +1,8 @@
<ui-display>
<ui-section label='Dispense'>
<ui-button icon='{{data.plasma ? "square" : "square-o"}}' state='{{data.plasma ? null : "disabled"}}'
action='plasma'>Plasma ({{Math.round(adata.plasma)}})</ui-button>
<ui-button icon='{{data.oxygen ? "square" : "square-o"}}' state='{{data.oxygen ? null : "disabled"}}'
action='oxygen'>Oxygen ({{Math.round(adata.oxygen)}})</ui-button>
</ui-section>
</ui-display>
+35
View File
@@ -0,0 +1,35 @@
<script>
component.exports = {
computed: {
tankPressureState () {
const pressure = this.get('data.tankPressure')
if (pressure >= 200) return 'good'
else if (pressure >= 100) return 'average'
else return 'bad'
}
}
}
</script>
<ui-notice>
<span>The regulator {{data.connected? "is" : "is not"}} connected to a mask.</span>
</ui-notice>
<ui-display>
<ui-section label='Tank Pressure'>
<ui-bar min='0' max='1013' value='{{data.tankPressure}}'
state='{{tankPressureState}}'>{{Math.round(adata.tankPressure)}} kPa</ui-bar>
</ui-section>
<ui-section label='Release Pressure'>
<ui-bar min='{{data.minReleasePressure}}' max='{{data.maxReleasePressure}}'
value='{{data.releasePressure}}'>{{Math.round(adata.releasePressure)}} kPa</ui-bar>
</ui-section>
<ui-section label='Pressure Regulator'>
<ui-button icon='refresh' state='{{data.releasePressure != data.defaultReleasePressure ? null : "disabled"}}'
action='pressure' params='{"pressure": "reset"}'>Reset</ui-button>
<ui-button icon='minus' state='{{data.releasePressure > data.minReleasePressure ? null : "disabled"}}'
action='pressure' params='{"pressure": "min"}'>Min</ui-button>
<ui-button icon='pencil' action='pressure' params='{"pressure": "input"}'>Set</ui-button>
<ui-button icon='plus' state='{{data.releasePressure < data.maxReleasePressure ? null : "disabled"}}'
action='pressure' params='{"pressure": "max"}'>Max</ui-button>
</ui-section>
</ui-display>
+25
View File
@@ -0,0 +1,25 @@
<ui-display title='Status'>
<ui-section label='Temperature'>
<span>{{Math.fixed(adata.temperature, 2)}} K</span>
</ui-section>
<ui-section label='Pressure'>
<span>{{Math.fixed(adata.pressure, 2)}} kPa</span>
</ui-section>
</ui-display>
<ui-display title='Controls'>
<ui-section label='Power'>
<ui-button icon='{{data.on ? "power-off" : "close"}}' style="{{data.on ? "selected" : null}}"
action='power'>{{data.on ? "On": "Off"}}</ui-button>
</ui-section>
<ui-section label='Target Temperature'>
<ui-button icon='fast-backward' style='{{data.target == data.min ? "disabled" : null}}'
action='target' params='{"adjust": -20}'/>
<ui-button icon='backward' style='{{data.target == data.min ? "disabled" : null}}'
action='target' params='{"adjust": -5}'/>
<ui-button icon='pencil' action='target' params='{"target": "input"}'>{{Math.fixed(adata.target, 2)}}</ui-button>
<ui-button icon='forward' style='{{data.target == data.max ? "disabled" : null}}'
action='target' params='{"adjust": 5}'/>
<ui-button icon='fast-forward' style='{{data.target == data.max ? "disabled" : null}}'
action='target' params='{"adjust": 20}'/>
</ui-section>
</ui-display>
+50
View File
@@ -0,0 +1,50 @@
<script>
import { filterMulti } from 'util/filter'
component.exports = {
data: {
filter: ''
},
oninit () {
this.on({
hover (event) {
const uses = this.get('data.telecrystals')
if (uses >= event.context.params.cost)
this.set('hovered', event.context.params)
},
unhover (event) {
this.set('hovered')
}
})
this.observe('filter', (newkey, oldkey, keypath) => {
const categories = this.findAll('.display:not(:first-child)')
filterMulti(categories, this.get('filter').toLowerCase())
}, { init: false })
}
}
</script>
<ui-display title='Uplink' button>
{{#partial button}}
{{#if config.fancy}}
<ui-input value='{{filter}}' placeholder='Filter...'/>
{{/if}}
{{#if data.lockable}}
<ui-button icon='lock' action='lock'>Lock</ui-button>
{{/if}}
{{/partial}}
<ui-section label='Telecrystals' right>
<span class='{{data.telecrystals > 0 ? "good" : "bad"}}'>{{data.telecrystals}} TC</span>
</ui-section>
</ui-display>
{{#each data.categories}}
<ui-display title='{{name}}'>
{{#each items}}
<ui-section label='{{name}}' candystripe right>
<ui-button tooltip='{{name}}: {{desc}}' tooltip-side='left'
state='{{data.telecrystals < cost || (data.telecrystals - hovered.cost < cost && hovered.item != name) ? "disabled" : null}}'
action='buy' params='{"category": "{{category}}", "item": {{name}}, "cost": {{cost}}}'
on-hover='hover' on-unhover='unhover'>{{cost}} TC</ui-button>
</ui-section>
{{/each}}
</ui-display>
{{/each}}
+16
View File
@@ -0,0 +1,16 @@
<ui-display>
{{#each data.wires}}
<ui-section label='{{color}}{{wire ? " (" + wire + ")" : ""}}' labelcolor='{{color}}' candystripe right>
<ui-button action='cut' params='{"wire":"{{color}}"}'>{{cut ? "Mend" : "Cut"}}</ui-button>
<ui-button action='pulse' params='{"wire":"{{color}}"}'>Pulse</ui-button>
<ui-button action='attach' params='{"wire":"{{color}}"}'>{{attached ? "Detach" : "Attach"}}</ui-button>
</ui-section>
{{/each}}
</ui-display>
{{#if data.status}}
<ui-display>
{{#each data.status}}
<ui-section>{{.}}</ui-section>
{{/each}}
</ui-display>
{{/if}}
+7
View File
@@ -0,0 +1,7 @@
body.nanotrasen
background: data-url('images/nanotrasen.svg') no-repeat fixed center/70% 70%,
linear-gradient(to bottom,
background-color-start 0%,
background-color-end 100%)
@import "util/*"
@import "components/*"
+30
View File
@@ -0,0 +1,30 @@
body.syndicate
color-good = pale-green
color-highlight = black
background-color-start = #750000
background-color-end = #340404
rule-color-normal = dark-gray
titlebar-color-text = pale-red
titlebar-color-button = pale-red
display-color-background = alpha(#000, 0.5)
display-color-shadow = alpha(#000, 0.75)
notice-color-first = #750000
notice-color-second = #910101
section-color-label = white
bar-color-normal = black
bar-color-good = pale-green
bar-color-border = black
button-color-normal = dark-green
button-color-disabled = gray
button-color-selected = dark-red
button-color-caution = yellow-orange
button-color-danger = yellow
input-color-text = white
input-color-background = dark-red
background: data-url('images/syndicate.svg') no-repeat fixed center/70% 70%,
linear-gradient(to bottom,
background-color-start 0%,
background-color-end 100%)
@import "util/*"
@import "components/*"
+53
View File
@@ -0,0 +1,53 @@
// Temporarily import Ractive first to keep it from detecting ie8's object.defineProperty shim, which it misuses (ractivejs/ractive#2343).
import Ractive from 'ractive'
Ractive.DEBUG = /minified/.test(() => {/* minified */})
import 'ie8'
import 'babel-polyfill'
import 'dom4'
import 'html5shiv'
// Extend the Math builtin with our own utilities.
Object.assign(Math, require('util/math'))
// Set up the initialize function. This is either called below if JSON is provided
// inline, or called by the server if it was not.
import TGUI from 'tgui.ract'
window.initialize = (dataString) => {
if (window.tgui) return // Don't run twice.
window.tgui = new TGUI({
el: '#container',
data () {
const initial = JSON.parse(dataString)
return {
constants: require('util/constants'),
text: require('util/text'),
config: initial.config,
data: initial.data,
adata: initial.data
}
}
})
}
// Try to find data in the page. If the JSON was inlined, load it.
const holder = document.getElementById('data')
const data = holder.textContent
const ref = holder.getAttribute('data-ref')
if (data !== '{}') {
window.initialize(data)
holder.remove()
}
// Let the server know we're set up. This also sends data if it was not inlined.
import { act } from 'util/byond'
act(ref, 'tgui:initialize')
// Load fonts.
import { loadCSS } from 'fg-loadcss'
loadCSS('https://cdn.jsdelivr.net/fontawesome/4.5.0/css/font-awesome.min.css')
// Handle font loads.
import FontFaceObserver from 'fontfaceobserver'
const fontawesome = new FontFaceObserver('FontAwesome')
fontawesome.check('\uf240')
.then(() => document.body.classList.add('icons'))
.catch(() => document.body.classList.add('no-icons'))
+61
View File
@@ -0,0 +1,61 @@
<link rel='ractive' href='components/resize.ract'>
<link rel='ractive' href='components/titlebar.ract'>
<link rel='ractive' href='components/warnings.ract'>
<script>
import { winset } from 'util/byond'
import { lock } from 'util/dragresize'
component.exports = {
components: {
'ui-bar': require('components/bar'),
'ui-button': require('components/button'),
'ui-display': require('components/display'),
'ui-input': require('components/input'),
'ui-linegraph': require('components/linegraph'),
'ui-notice': require('components/notice'),
'ui-section': require('components/section'),
'ui-subdisplay': require('components/subdisplay'),
'ui-tabs': require('components/tabs'),
},
events: {
enter: require('ractive-events-keys').enter,
space: require('ractive-events-keys').space,
},
transitions: {
fade: require('ractive-transitions-fade'),
},
onconfig () {
const requested = this.get('config.interface')
const interfaces = require('interfaces/**/*.ract', { mode: 'hash' })
if (requested in interfaces) {
this.components.interface = interfaces[requested] // Use the interface specified in the config...
} else {
this.components.interface = interfaces.error // ...unless it does not exist.
}
},
oninit () {
this.observe('config.style', (newkey, oldkey, keypath) => {
if (newkey) document.body.classList.add(newkey)
if (oldkey) document.body.classList.remove(oldkey)
})
},
oncomplete () {
// If the window starts off screen, pull it back.
if (this.get('config.locked')) {
let {x, y} = lock(window.screenLeft, window.screenTop)
winset(this.get('config.window'), 'pos', `${x},${y}`)
}
// Give focus back to the map.
winset('mapwindow.map', 'focus', true)
}
}
</script>
<titlebar>{{{config.title}}}</titlebar>
<main>
<warnings/>
<interface/>
</main>
<resize/>
+134
View File
@@ -0,0 +1,134 @@
@charset "utf-8"
white = white
pale-red = #e74242
red = #b00e0e
dark-red = #9d0808
yellow-orange = #be6209
yellow = #9a9d00
pale-green = #73E573
green = #2f943c
grass-green = #537d29
dark-green = #397439
royal-blue = #40628a
pale-blue = #8ba5c4
black = black
black-gray = #161616
dark-gray = #272727
gray = #363636
light-gray = #999999
// Branding Colors
color-normal = royal-blue
color-good = grass-green
color-average = yellow-orange
color-bad = red
color-highlight = pale-blue
// Text
text-color-normal = white
text-color-inverse = black
// Background
background-color-start = #2a2a2a
background-color-end = #202020
// Rules (<hr/> etc)
rule-color-normal = royal-blue
rule-color-dark = dark-gray
rule-size = 2px
// Titlebar
titlebar-color-text = pale-blue
titlebar-color-button = pale-blue
titlebar-color-background = gray
titlebar-color-coreshadow = black-gray
titlebar-color-shadow = alpha(#000, 0.1)
// Resize
resize-color = gray
// Display
display-color-title = white
display-color-background = alpha(#000, 0.33)
display-color-shadow = alpha(#000, 0.5)
// Notice
notice-color-first = #bb9b68
notice-color-second = #b1905d
notice-color-border = dark-gray
// Section
section-color-label = pale-blue
section-color-candystripe = alpha(#000, 0.2)
// Bar
bar-color-normal = color-normal
bar-color-good = color-good
bar-color-average = color-average
bar-color-bad = color-bad
bar-color-border = royal-blue
bar-color-background = dark-gray
// Buttons
button-color-normal = royal-blue
button-color-disabled = light-gray
button-color-selected = green
button-color-caution = yellow
button-color-danger = dark-red
button-color-border = dark-gray
button-lighten-hover = 15%
button-alpha-disabled = .75
// Input
input-color-text = black
input-color-placeholder = light-gray
input-color-border = dark-gray
input-color-background = white
// Tooltips
tooltip-color-border = dark-gray
tooltip-color-background = gray
html, body
box-sizing: border-box
height: 100%
margin: 0
html
overflow: hidden
cursor: default // Reset the cursor.
body
overflow: auto
font-family: Verdana, Geneva, sans-serif
font-size: 12px
color: text-color-normal
background-color: background-color-start
background-image: linear-gradient(to bottom,
background-color-start 0%,
background-color-end 100%)
*, *:before, *:after
box-sizing: inherit
$h
display: inline-block
margin: 0
padding: 6px 0
h1
@extend $h
font-size: 18px
h2
@extend $h
font-size: 16px
h3
@extend $h
font-size: 14px
h4
@extend $h
font-size: 12px
@require "styles/*"
+16
View File
@@ -0,0 +1,16 @@
const encode = encodeURIComponent
// Helper to generate a BYOND href given 'params' as an object (with an optional 'url' for eg winset).
export function href (params = {}, url = '') {
return `byond://${url}?` + Object.keys(params).map(key => `${encode(key)}=${encode(params[key])}`).join('&')
}
// Helper to make a BYOND ui_act() call on the UI 'src' given an 'action' and optional 'params'.
export function act (src, action, params = {}) {
window.location.href = href(Object.assign({ src, action }, params))
}
// Helper to make a BYOND winset() call on 'window', setting 'key' to 'value'
export function winset (win, key, value) {
window.location.href = href({[`${win}.${key}`]: value}, 'winset')
}
+10
View File
@@ -0,0 +1,10 @@
.normal
color: color-normal
.good
color: color-good
.average
color: color-average
.bad
color: color-bad
.highlight
color: color-highlight
+5
View File
@@ -0,0 +1,5 @@
// Constants used in tgui; these are mirrored from the BYOND code.
export const UI_INTERACTIVE = 2
export const UI_UPDATE = 1
export const UI_DISABLED = 0
export const UI_CLOSE = -1
+51
View File
@@ -0,0 +1,51 @@
import {winset} from './byond'
export function lock (x, y) {
if (x < 0) { // Left
x = 0
} else if (x + window.innerWidth > window.screen.availWidth) { // Right
x = window.screen.availWidth - window.innerWidth
}
if (y < 0) { // Top
y = 0
} else if (y + window.innerHeight > window.screen.availHeight) { // Bottom
y = window.screen.availHeight - window.innerHeight
}
return {x, y}
}
export function drag (event) {
event.preventDefault()
if (!this.get('drag')) return
if (this.get('x')) {
let x = (event.screenX - this.get('x')) + window.screenLeft
let y = (event.screenY - this.get('y')) + window.screenTop
if (this.get('config.locked')) ({x, y} = lock(x, y)) // Lock to primary monitor.
winset(this.get('config.window'), 'pos', `${x},${y}`)
}
this.set({ x: event.screenX, y: event.screenY })
}
export function sane (x, y) {
x = Math.clamp(100, window.screen.width, x)
y = Math.clamp(100, window.screen.height, y)
return {x, y}
}
export function resize (event) {
event.preventDefault()
if (!this.get('resize')) return
if (this.get('x')) {
let x = (event.screenX - this.get('x')) + window.innerWidth
let y = (event.screenY - this.get('y')) + window.innerHeight
;({x, y} = sane(x, y))
winset(this.get('config.window'), 'size', `${x},${y}`)
}
this.set({ x: event.screenX, y: event.screenY })
}
+22
View File
@@ -0,0 +1,22 @@
export function filterMulti (displays, string) {
for (let display of displays) { // First check if the display includes the search term in the first place.
if (display.textContent.toLowerCase().includes(string)) {
display.style.display = ''
filter(display, string)
} else {
display.style.display = 'none'
}
}
}
export function filter (display, string) {
const items = display.queryAll('section')
const titleMatch = display.query('header').textContent.toLowerCase().includes(string)
for (let item of items) { // Check if the item or its displays title contains the search term.
if (titleMatch || item.textContent.toLowerCase().includes(string)) {
item.style.display = ''
} else {
item.style.display = 'none'
}
}
}
+9
View File
@@ -0,0 +1,9 @@
// Helper to limit a number to be inside 'min' and 'max'.
export function clamp (min, max, number) {
return Math.max(min, Math.min(number, max))
}
// Helper to round a number to 'decimals' decimals.
export function fixed (number, decimals = 1) {
return Number(Math.round(number + 'e' + decimals) + 'e-' + decimals)
}
+12
View File
@@ -0,0 +1,12 @@
main
display: block
margin-top: 32px
padding: 2px 6px 0
hr
height: rule-size
background-color: rule-color-normal
border: none
.hidden
display: none
+14
View File
@@ -0,0 +1,14 @@
export function upperCaseFirst (str) {
return str[0].toUpperCase() + str.slice(1).toLowerCase()
}
export function titleCase (str) {
return str.replace(/\w\S*/g, upperCaseFirst)
}
export function zeroPad (str, pad_size) {
str = str.toString()
while(str.length < pad_size)
str = '0' + str
return str
}
+17
View File
@@ -0,0 +1,17 @@
// Helper to reset font options to default.
$fontReset
color: text-color-normal
font-size: 12px
font-weight: normal
font-style: normal
text-decoration: none
// Utility classes to set font styles.
.bold
font-weight: bold
.italic
font-style: italic
// Make 'unselectable' text unselectable on all browsers.
[unselectable=on]
user-select: none
+53
View File
@@ -0,0 +1,53 @@
div[data-tooltip], span[data-tooltip]
position: relative
&::after
position: absolute
display: block
z-index: 2
width: 250px
padding: 10px
transform: translateX(-50%)
visibility: hidden
opacity: 0
white-space: normal
text-align: left
content: attr(data-tooltip)
transition: all .5s
border: 1px solid tooltip-color-border
background-color: tooltip-color-background
&:hover::after
visibility: visible
opacity: 1
&.tooltip-top::after
bottom: 100%
left: 50%
transform: translateX(-50%) translateY(8px)
&.tooltip-top:hover::after
transform: translateX(-50%) translateY(-8px)
&.tooltip-bottom::after
top: 100%
left: 50%
transform: translateX(-50%) translateY(-8px)
&.tooltip-bottom:hover::after
transform: translateX(-50%) translateY(8px)
&.tooltip-left::after
top: 50%
right: 100%
transform: translateX(8px) translateY(-50%)
&.tooltip-left:hover::after
transform: translateX(-8px) translateY(-50%)
&.tooltip-right::after
top: 50%
left: 100%
transform: translateX(-8px) translateY(-50%)
&.tooltip-right:hover::after
transform: translateX(8px) translateY(-50%)