1
0
mirror of https://shylinux.com/x/volcanos synced 2025-04-29 18:29:21 +08:00

opt web.stats

This commit is contained in:
IT 老营长 @云轩领航-创始人 2023-12-08 19:37:33 +08:00
parent 3ebb207715
commit 1d3975e844
6 changed files with 31 additions and 32 deletions

View File

@ -268,7 +268,9 @@ var http = {
GET: "GET", PUT: "PUT", POST: "POST", DELETE: "DELETE", GET: "GET", PUT: "PUT", POST: "POST", DELETE: "DELETE",
Accept: "Accept", ContentType: "Content-Type", ApplicationJSON: "application/json", ApplicationFORM: "application/x-www-form-urlencoded", Accept: "Accept", ContentType: "Content-Type", ApplicationJSON: "application/json", ApplicationFORM: "application/x-www-form-urlencoded",
} }
var html = {RIVER_MARGIN: 80, PLUGIN_MARGIN: 10, PLUGIN_PADDING: 10, ACTION_MARGIN: 200, ACTION_HEIGHT: 32, STATUS_HEIGHT: 32, var html = {
RIVER_WIDTH: 230,
RIVER_MARGIN: 80, PLUGIN_MARGIN: 10, PLUGIN_PADDING: 10, ACTION_MARGIN: 200, ACTION_HEIGHT: 32, STATUS_HEIGHT: 32,
FIELDSET: "fieldset", LEGEND: "legend", OPTION: "option", ACTION: "action", OUTPUT: "output", STATUS: "status", FIELDSET: "fieldset", LEGEND: "legend", OPTION: "option", ACTION: "action", OUTPUT: "output", STATUS: "status",
OPTION_ARGS: "select.args,input.args,textarea.args", INPUT_ARGS: "input.args,textarea.args", INPUT_BUTTON: "input[type=button]", INPUT_FILE: "input[type=file]", OPTION_ARGS: "select.args,input.args,textarea.args", INPUT_ARGS: "input.args,textarea.args", INPUT_BUTTON: "input[type=button]", INPUT_FILE: "input[type=file]",
FORM_OPTION: "form.option", DIV_ACTION: "div.action", DIV_OUTPUT: "div.output", DIV_STATUS: "div.status", FORM_OPTION: "form.option", DIV_ACTION: "div.action", DIV_OUTPUT: "div.output", DIV_STATUS: "div.status",

View File

@ -249,11 +249,11 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) {
can.onmotion.clear(can, can._action), sub.onappend._action(sub, can.Conf(ice.MSG_ACTION)||msg.Option(ice.MSG_ACTION), action||can._action) can.onmotion.clear(can, can._action), sub.onappend._action(sub, can.Conf(ice.MSG_ACTION)||msg.Option(ice.MSG_ACTION), action||can._action)
sub.onappend._status(sub, sub.onexport&&sub.onexport.list||msg.Option(ice.MSG_STATUS)), can.user.isMobile || sub.onappend.tools(sub, msg) sub.onappend._status(sub, sub.onexport&&sub.onexport.list||msg.Option(ice.MSG_STATUS)), can.user.isMobile || sub.onappend.tools(sub, msg)
can.core.Item(can.Action(), function(key) { var value = can.misc.sessionStorage(can, [can.ConfIndex(), ctx.ACTION, key]); value && can.Action(key, value[0]) }) can.core.Item(can.Action(), function(key) { var value = can.misc.sessionStorage(can, [can.ConfIndex(), ctx.ACTION, key]); value && can.Action(key, value[0]) })
} } can.onappend.style(sub, sub.Conf(ctx.STYLE)), can.onmotion.story.auto(can, can._output)
can.onappend.style(sub, sub.Conf(ctx.STYLE)), can.onmotion.story.auto(can, can._output)
if (can.onimport.size) { if (can.onimport.size) {
// if (can.isFullMode() || can.isCmdMode()) { can.ConfHeight(can.page.height()), can.ConfWidth(can.page.width()) } can.page.ClassList.has(can, can._target, html.FLOAT) && !can.page.ClassList.has(can, can._target, html.PLUG)?
can.onimport.size(can, can.ConfHeight(), can.ConfWidth(), can.Conf("_auto"), can.Mode()) can.onimport.size(can, can.ConfHeight(), can.base.Min(can.ConfWidth(), can._target.offsetWidth), can.Conf("_auto"), can.Mode()):
can.onimport.size(can, can.ConfHeight(), can.ConfWidth(), can.Conf("_auto"), can.Mode())
can.isCmdMode() && can.page.style(can, can._output, html.HEIGHT, sub.ConfHeight(), html.WIDTH, sub.ConfWidth()) can.isCmdMode() && can.page.style(can, can._output, html.HEIGHT, sub.ConfHeight(), html.WIDTH, sub.ConfWidth())
can.onexport.output(sub, msg) can.onexport.output(sub, msg)
} can.base.isFunc(cb) && cb(msg) } can.base.isFunc(cb) && cb(msg)
@ -619,11 +619,10 @@ Volcanos(chat.ONLAYOUT, {_init: function(can, target) { target = target||can._ro
}, },
_float: function(can) { var target = can._fields||can._target, sup = can._fields? can.sup: can _float: function(can) { var target = can._fields||can._target, sup = can._fields? can.sup: can
can.onappend.style(can, html.FLOAT), can.onmotion.resize(can, target, function(height, width) { sup.onimport.size(sup, height, width, true) }) can.onappend.style(can, html.FLOAT), can.onmotion.resize(can, target, function(height, width) { sup.onimport.size(sup, height, width, true) })
can.page.style(can, target, html.LEFT, 250, html.TOP, 132), sup.onimport.size(sup, 600, 600, true) var left = html.RIVER_WIDTH+html.PLUGIN_MARGIN+html.PLUGIN_PADDING+(can.user.mod.isCmd? 0: 120), top = can.page.height()/4; if (can.user.isMobile) { left = 0 }
can.page.style(can, target, html.LEFT, left, html.TOP, top), sup.onimport.size(sup, can.base.Max(600, can.page.height()-top), can.base.Max(can.user.mod.isCmd? 1200: 1000, can.page.width()-left), true)
target.onclick = function(event) { can.onkeymap.prevent(event) target.onclick = function(event) { can.onkeymap.prevent(event)
can.page.Select(can, document.body, "fieldset.float,div.float", function(target) { can.page.Select(can, document.body, "fieldset.float,div.float", function(target) { can.page.style(can, target, "z-index", 9) }), can.page.style(can, target, "z-index", 10)
can.page.style(can, target, "z-index", 9)
}), can.page.style(can, target, "z-index", 10)
} }
}, },
}) })

View File

@ -96,6 +96,7 @@ iframe { height:var(--iframe-height); width:100%; }
/* fieldset */ /* fieldset */
fieldset>legend { box-shadow:var(--box-shadow); } fieldset>legend { box-shadow:var(--box-shadow); }
fieldset>form.option>div.item:not(.icon) { margin-right:var(--button-margin); box-shadow:var(--box-shadow); } fieldset>form.option>div.item:not(.icon) { margin-right:var(--button-margin); box-shadow:var(--box-shadow); }
fieldset.story:not(.float)>form.option>div.item.icons:not(.icon) { margin-right:0; }
fieldset>form.option>div.item.textarea { width:100%; height:var(--textarea-height); } fieldset>form.option>div.item.textarea { width:100%; height:var(--textarea-height); }
fieldset>form.option>div.item.text.cmd { width:100%; } fieldset>form.option>div.item.text.cmd { width:100%; }
fieldset>form.option>div.item.text.cmd>input { background-color:var(--code-bg-color); color:var(--code-fg-color); width:100%; } fieldset>form.option>div.item.text.cmd>input { background-color:var(--code-bg-color); color:var(--code-fg-color); width:100%; }
@ -277,6 +278,8 @@ fieldset.plug>form.option>div.text>span.value { display:none; }
fieldset:not(.float)>form.option>div.text>span.value { display:none; } fieldset:not(.float)>form.option>div.text>span.value { display:none; }
fieldset.float:not(.plug)>form.option>div.text>input { display:none; } fieldset.float:not(.plug)>form.option>div.text>input { display:none; }
fieldset.float:not(.plug)>form.option>div.text>span.icon { display:none; } fieldset.float:not(.plug)>form.option>div.text>span.icon { display:none; }
fieldset.float:not(.plug)>form.option>div.item:last-child { margin-right:var(--action-height); }
fieldset.float:not(.plug)>div.action>div.item:last-child { margin-right:var(--action-height); }
/* svg */ /* svg */
svg text { font-size:var(--svg-font-size); font-family:var(--svg-font-family); stroke:var(--body-fg-color); fill:var(--body-fg-color); cursor:pointer; } svg text { font-size:var(--svg-font-size); font-family:var(--svg-font-family); stroke:var(--body-fg-color); fill:var(--body-fg-color); cursor:pointer; }
svg text.offline { stroke:var(--disable-fg-color); fill:var(--disable-fg-color); } svg text.offline { stroke:var(--disable-fg-color); fill:var(--disable-fg-color); }

View File

@ -33,6 +33,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) {
can.onimport.menu(can, mdb.SEARCH, function() { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH, word: can._search.value||""})) }) can.onimport.menu(can, mdb.SEARCH, function() { can.onengine.signal(can, chat.ONOPENSEARCH, can.request(event, {type: mdb.FOREACH, word: can._search.value||""})) })
}, },
_const: function(can) { _const: function(can) {
html.RIVER_WIDTH = can.page.styleValueInt(can, "--river-width")
html.RIVER_MARGIN = can.page.styleValueInt(can, "--river-margin") html.RIVER_MARGIN = can.page.styleValueInt(can, "--river-margin")
html.PLUGIN_PADDING = can.page.styleValueInt(can, "--plugin-padding") html.PLUGIN_PADDING = can.page.styleValueInt(can, "--plugin-padding")
html.PLUGIN_MARGIN = can.page.styleValueInt(can, "--plugin-margin") html.PLUGIN_MARGIN = can.page.styleValueInt(can, "--plugin-margin")

View File

@ -1,8 +1,12 @@
Volcanos(chat.ONIMPORT, { Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { can.onappend.style(can, ["stats", html.FLEX], can._output) _init: function(can, msg) { can.onappend.style(can, ["stats", html.FLEX], can._output)
var stats = {}, units = {}, index = {}; msg.Table(function(value) { units[value.name] = value.units var list = {}
var stats = {}, units = {}, trans = {}, index = {}; msg.Table(function(value) {
stats[value.name] = parseFloat(stats[value.name]||"0") + parseFloat(value.value) stats[value.name] = parseFloat(stats[value.name]||"0") + parseFloat(value.value)
units[value.name] = value.units
trans[value.name] = value._trans
index[value.name] = value.index index[value.name] = value.index
list[value.name] = value
}) })
function fmts(value) { var ls = [] function fmts(value) { var ls = []
while (value > 0) { ls.push(value%1000) while (value > 0) { ls.push(value%1000)
@ -10,11 +14,12 @@ Volcanos(chat.ONIMPORT, {
value = parseInt(value/1000) value = parseInt(value/1000)
} return ls.reverse().join(", ") } return ls.reverse().join(", ")
} }
can.user.trans(can, trans, null, html.INPUT)
can.core.Item(stats, function(name, value) { can.page.Append(can, can._output, [{view: [[html.ITEM, name, html.FLEX]], list: [ can.core.Item(stats, function(name, value) { can.page.Append(can, can._output, [{view: [[html.ITEM, name, html.FLEX]], list: [
{view: mdb.VALUE, list: [{text: can.base.trimSuffix(fmts(parseFloat(value).toFixed(2))+"", ".00")}, {text: [units[name], "", "units"]}]}, {view: mdb.VALUE, list: [{text: can.base.trimSuffix(fmts(parseFloat(value).toFixed(2))+"", ".00")}, {text: [units[name], "", "units"]}]},
{view: [mdb.NAME, "", can.user.trans(can, name, null, html.INPUT)]}, {view: [mdb.NAME, "", can.user.trans(can, name, trans[name]||null, html.INPUT)]},
], onclick: function() { ], onclick: function() {
can.onappend.plugin(can, {index: index[name], style: html.FLOAT}) can.onappend.plugin(can, {space: list[name].space, index: index[name], style: html.FLOAT})
}}]) }), can.isCmdMode() && can.onappend.table(can, msg) }}]) }), can.isCmdMode() && can.onappend.table(can, msg)
}, },
}) })

View File

@ -1,23 +1,19 @@
Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear(can, target) Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear(can, target)
if (can.Mode() == html.ZONE) { return can.onimport._vimer_zone(can, msg, target) } if (can.Mode() == html.ZONE) { return can.onimport._vimer_zone(can, msg, target) }
can.sup.onimport.size(can.sup, can.sup.ConfHeight(), can.sup.ConfWidth(), can.Conf("_auto"))
var cbs = can.onimport[can.Conf(ctx.STYLE)||msg.Option(ctx.STYLE)]; if (can.base.isFunc(cbs)) { var cbs = can.onimport[can.Conf(ctx.STYLE)||msg.Option(ctx.STYLE)]; if (can.base.isFunc(cbs)) {
can.onappend.style(can, can._args[ctx.STYLE], target), can.core.CallFunc(cbs, {can: can, msg: msg, target: target}) can.onappend.style(can, can._args[ctx.STYLE], target), can.core.CallFunc(cbs, {can: can, msg: msg, target: target})
} else { } else {
can.onappend.table(can, msg, null, target), can.onappend.board(can, msg, target), can.onmotion.story.auto(can, target) can.onappend.table(can, msg, null, target), can.onappend.board(can, msg, target), can.onmotion.story.auto(can, target)
} }
}, },
card: function(can, msg, target) { card: function(can, msg, target) { can.sup.onexport.outputMargin = function() { return 211 }
can.sup.onexport.outputMargin = function() { return 211 }
can.page.Appends(can, target||can._output, msg.Table(function(value) { value.icon = value.icon||value.image can.page.Appends(can, target||can._output, msg.Table(function(value) { value.icon = value.icon||value.image
return {view: [[html.ITEM, value.status]], list: [ return {view: [[html.ITEM, value.status]], list: [
{view: [wiki.TITLE, html.DIV], list: [value.icon && {img: can.misc.Resource(can, value.icon, value.name)}, {text: value.name}]}, {view: [wiki.TITLE, html.DIV], list: [value.icon && {img: can.misc.Resource(can, value.icon, value.name)}, {text: value.name}]},
{view: [wiki.CONTENT, html.DIV, value.text]}, {view: [wiki.CONTENT, html.DIV, value.text]},
{view: html.ACTION, inner: value.action, _init: function(target) { can.onappend.mores(can, target, value, 5) }}, {view: html.ACTION, inner: value.action, _init: function(target) { can.onappend.mores(can, target, value, 5) }},
]} ]}
})) })), can.onimport.layout = function() { can.onlayout.expand(can, can._output, 320) }, can.onappend.scroll(can, can._output)
can.onimport.layout = function() { can.onlayout.expand(can, can._output, 320) }
can.onappend.scroll(can, can._output)
}, },
_vimer_zone: function(can, msg, target) { msg.Table(function(value) { var action = can.page.parseAction(can, value) _vimer_zone: function(can, msg, target) { msg.Table(function(value) { var action = can.page.parseAction(can, value)
can.onimport.item(can, {icon: value.icon||value.avatar_url, name: can.page.Color(value[can.Conf(mdb.FIELD)||mdb.VIEW]||value[mdb.NAME]||value[mdb.TEXT]||value[mdb.TYPE]), title: value[mdb.TEXT]||value.description}, function(event) { can.onimport.item(can, {icon: value.icon||value.avatar_url, name: can.page.Color(value[can.Conf(mdb.FIELD)||mdb.VIEW]||value[mdb.NAME]||value[mdb.TEXT]||value[mdb.TYPE]), title: value[mdb.TEXT]||value.description}, function(event) {
@ -111,8 +107,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear(
can.page.Select(can, target, html.DIV_ITEM+":not(.hide)", function(target) { target.click() }) can.page.Select(can, target, html.DIV_ITEM+":not(.hide)", function(target) { target.click() })
} else if (event.key == code.ESCAPE) { event.currentTarget.value = "", event.currentTarget.blur() } else if (event.key == code.ESCAPE) { event.currentTarget.value = "", event.currentTarget.blur()
can.page.Select(can, target, html.DIV_ITEM, function(target) { can.onmotion.toggle(can, target, true) }) can.page.Select(can, target, html.DIV_ITEM, function(target) { can.onmotion.toggle(can, target, true) })
} else { } else { if (can.onkeymap.selectCtrlN(event, can, target, html.DIV_ITEM+":not(.filter):not(.hide)")) { return }
if (can.onkeymap.selectCtrlN(event, can, target, html.DIV_ITEM+":not(.filter):not(.hide)")) { return }
can.page.Select(can, target, html.DIV_ITEM, function(target) { can.page.Select(can, target, html.DIV_ITEM, function(target) {
can.onmotion.toggle(can, target, target.innerText.indexOf(event.currentTarget.value) > -1 || target == event.currentTarget.parentNode) can.onmotion.toggle(can, target, target.innerText.indexOf(event.currentTarget.value) > -1 || target == event.currentTarget.parentNode)
}) })
@ -149,7 +144,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear(
}}, {view: html.LIST}]); can.onimport.list(can, item, cb, ui.list, cbs) }) }}, {view: html.LIST}]); can.onimport.list(can, item, cb, ui.list, cbs) })
}, },
tabs: function(can, list, cb, cbs, action) { action = action||can._action; return can.page.Append(can, action, can.core.List(list, function(tabs) { tabs: function(can, list, cb, cbs, action) { action = action||can._action; return can.page.Append(can, action, can.core.List(list, function(tabs) {
if (typeof tabs == "string") { tabs = {name: tabs} } if (typeof tabs == code.STRING) { tabs = {name: tabs} }
function close(target) { function close(target) {
if (can.page.ClassList.has(can, target, html.SELECT)) { if (can.page.ClassList.has(can, target, html.SELECT)) {
var next = target.nextSibling||target.previousSibling; if (!next) { return } next.click() var next = target.nextSibling||target.previousSibling; if (!next) { return } next.click()
@ -189,9 +184,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear(
var height = can.base.Max(can.ConfHeight()/2, can.ConfHeight()-html.ACTION_HEIGHT, 320) var height = can.base.Max(can.ConfHeight()/2, can.ConfHeight()-html.ACTION_HEIGHT, 320)
can.page.style(can, sub._output, html.MAX_HEIGHT, "", html.HEIGHT, "", html.WIDTH, "", html.MAX_WIDTH, "") can.page.style(can, sub._output, html.MAX_HEIGHT, "", html.HEIGHT, "", html.WIDTH, "", html.MAX_WIDTH, "")
sub.onimport.size(sub, height, can.base.Max(sub._target.offsetWidth, width, 800), false) sub.onimport.size(sub, height, can.base.Max(sub._target.offsetWidth, width, 800), false)
can.onmotion.delay(can, function() { can.onmotion.delay(can, function() { sub.onimport.size(sub, height, can.base.Max(sub._target.offsetWidth, width, 800), false) })
sub.onimport.size(sub, height, can.base.Max(sub._target.offsetWidth, width, 800), false)
})
} }
can.onmotion.hidden(can, sub._target), sub._legend._target = sub._target, sub._legend._meta = {index: meta.index} can.onmotion.hidden(can, sub._target), sub._legend._target = sub._target, sub._legend._meta = {index: meta.index}
can.page.Append(can, sub._legend,[{text: [can.page.unicode.remove, "", mdb.REMOVE], onclick: function(event) { can.page.Append(can, sub._legend,[{text: [can.page.unicode.remove, "", mdb.REMOVE], onclick: function(event) {
@ -200,7 +193,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear(
status.appendChild(sub._legend), sub._legend.oncontextmenu = sub._legend.onclick, sub._legend.onclick = function(event) { can.misc.Event(event, can, function(msg) { status.appendChild(sub._legend), sub._legend.oncontextmenu = sub._legend.onclick, sub._legend.onclick = function(event) { can.misc.Event(event, can, function(msg) {
if (can.page.SelectOne(can, status, nfs.PT+html.SELECT, function(target) { can.onmotion.hidden(can, target._target), can.page.ClassList.del(can, target, html.SELECT); return target }) == sub._legend) { return } if (can.page.SelectOne(can, status, nfs.PT+html.SELECT, function(target) { can.onmotion.hidden(can, target._target), can.page.ClassList.del(can, target, html.SELECT); return target }) == sub._legend) { return }
can.onmotion.select(can, status, html.LEGEND, sub._legend), can.onmotion.toggle(can, sub._target, true) can.onmotion.select(can, status, html.LEGEND, sub._legend), can.onmotion.toggle(can, sub._target, true)
can.onmotion.select(can, target, "fieldset.plug", sub._target) can.onmotion.select(can, target, html.FIELDSET_PLUG, sub._target)
if (sub._delay_init || meta.msg) { sub._delay_init = false, meta.msg = false, (sub._inputs && sub._inputs.list || sub._inputs && sub._inputs.refresh) && sub.Update() } if (sub._delay_init || meta.msg) { sub._delay_init = false, meta.msg = false, (sub._inputs && sub._inputs.list || sub._inputs && sub._inputs.refresh) && sub.Update() }
}) }, sub._delay_init = true, sub.select = function(show) { }) }, sub._delay_init = true, sub.select = function(show) {
if (show && can.page.ClassList.has(can, sub._legend, html.SELECT)) { return sub } if (show && can.page.ClassList.has(can, sub._legend, html.SELECT)) { return sub }
@ -223,9 +216,7 @@ Volcanos(chat.ONIMPORT, {_init: function(can, msg, target) { can.onmotion.clear(
}, },
}) })
Volcanos(chat.ONLAYOUT, { Volcanos(chat.ONLAYOUT, {
_init: function(can, height, width) { _init: function(can, height, width) { can.core.CallFunc([can.onimport, html.LAYOUT], {can: can, height: height, width: width}) },
can.core.CallFunc([can.onimport, html.LAYOUT], {can: can, height: height, width: width})
},
zone: function(can, height, width) { can.onlayout._init(can, height, width) }, zone: function(can, height, width) { can.onlayout._init(can, height, width) },
result: function(can, height, width) { can.onlayout._init(can, height, width) }, result: function(can, height, width) { can.onlayout._init(can, height, width) },
simple: function(can, height, width) { can.onlayout._init(can, height, width) }, simple: function(can, height, width) { can.onlayout._init(can, height, width) },
@ -245,8 +236,7 @@ Volcanos(chat.ONEXPORT, {
}, },
board: function(can) { var msg = can._msg; return msg.Result() }, board: function(can) { var msg = can._msg; return msg.Result() },
session: function(can, key, value) { return can.misc[can.user.isWebview? "localStorage": "sessionStorage"](can, [can.Conf(ctx.INDEX), key, location.pathname].join(":"), value == ""? "": JSON.stringify(value)) }, session: function(can, key, value) { return can.misc[can.user.isWebview? "localStorage": "sessionStorage"](can, [can.Conf(ctx.INDEX), key, location.pathname].join(":"), value == ""? "": JSON.stringify(value)) },
action_value: function(can, key, def) { action_value: function(can, key, def) { var value = can.Action(key); return can.base.isIn(value, ice.AUTO, key)? def: value },
var value = can.Action(key); return can.base.isIn(value, ice.AUTO, key)? def: value },
tool: function(can) { can.misc.sessionStorage(can, [can.ConfIndex(), "tool"], JSON.stringify(can.page.Select(can, can._status, html.LEGEND, function(target) { return target._meta }))) }, tool: function(can) { can.misc.sessionStorage(can, [can.ConfIndex(), "tool"], JSON.stringify(can.page.Select(can, can._status, html.LEGEND, function(target) { return target._meta }))) },
tabs: function(can) {}, tabs: function(can) {},
}) })
@ -257,8 +247,7 @@ Volcanos(chat.ONACTION, {
}, },
}) })
Volcanos(chat.ONKEYMAP, { Volcanos(chat.ONKEYMAP, {
escape: function(event, can) {}, escape: function(event, can) {}, enter: function(event, can) {},
enter: function(event, can) {},
ctrln: function(event, can) { can.onkeymap.selectCtrlN(event, can, can._action, html.DIV_TABS) }, ctrln: function(event, can) { can.onkeymap.selectCtrlN(event, can, can._action, html.DIV_TABS) },
space: function(event, can) { can.ui.filter && (can.ui.filter.focus(), can.onkeymap.prevent(event)) }, space: function(event, can) { can.ui.filter && (can.ui.filter.focus(), can.onkeymap.prevent(event)) },
tabx: function(event, can) { can.page.Select(can, can._action, html.DIV_TABS_SELECT, function(target) { target._close() }) }, tabx: function(event, can) { can.page.Select(can, can._action, html.DIV_TABS_SELECT, function(target) { target._close() }) },