From 394f0475c828e70ab972d170c8dfa72b47d4bf07 Mon Sep 17 00:00:00 2001 From: harveyshao Date: Sat, 5 Nov 2022 14:46:19 +0800 Subject: [PATCH] opt wiki --- frame.js | 4 +- lib/misc.js | 1 + plugin/local/wiki/data.js | 352 +++++++------------------------------- proto.js | 1 + 4 files changed, 70 insertions(+), 288 deletions(-) diff --git a/frame.js b/frame.js index 697bd802..06f92613 100644 --- a/frame.js +++ b/frame.js @@ -6,7 +6,7 @@ Volcanos(chat.ONENGINE, {_init: function(can, meta, list, cb, target) { can.core.Next(list, function(item, next) { item.type = chat.PANEL can.onappend._init(can, can.base.Copy(item, can.core.Value(can, [chat.RIVER, item.name])), item.list, function(sub) { can[item.name] = sub sub.run = function(event, cmds, cb) { var msg = sub.request(event); cmds = cmds||[]; return (can.onengine[cmds[0]]||can.onengine._remote)(event, can, msg, sub, cmds, cb) } - can.core.Item(sub.onplugin, function(key, cmd) { sub.onplugin.hasOwnProperty(key) && can.base.isFunc(cmd) && can.onengine.plugin(sub, key, cmd) }) + can.core.Item(sub.onplugin, function(key, cmd) { sub.onplugin.hasOwnProperty(key) && can.base.isFunc(cmd) && can.onengine.plugin(sub, "can."+key, cmd) }) can.core.ItemCB(sub.onaction, function(key, cb) { can.onengine.listen(can, key, function(msg) { can.core.CallFunc(cb, {can: sub, msg: msg}) }) }) can.core.CallFunc([sub.onaction, chat._INIT], {can: sub, cb: next, target: sub._target}) }, target) @@ -198,7 +198,7 @@ Volcanos(chat.ONAPPEND, {_init: function(can, meta, list, cb, target, field) { can.core.List(can.base.Obj(list, can.core.Value(can, [chat.ONEXPORT, mdb.LIST])), function(item) { item = can.base.isString(item)? {name: item}: item if (can.base.beginWith(item.value, ice.PS, ice.HTTP)) { item.value = can.page.Format(html.A, item.value) } can.page.Append(can, status, [{view: can.base.join([html.ITEM, item.name]), title: item.name, list: [ - {text: [item.name, html.LABEL]}, {text: [": ", html.LABEL]}, {text: [(item.value||"")+"", html.SPAN, item.name]}, + {text: [item.name, html.LABEL]}, {text: [": ", html.LABEL]}, {text: [(item.value == undefined? "": item.value)+"", html.SPAN, item.name]}, ], onclick: function(event) { can.user.copy(event, can, item.value) }}]) }) }, diff --git a/lib/misc.js b/lib/misc.js index 4dfd7e14..f4859dc1 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -157,6 +157,7 @@ Volcanos("misc", {Message: function(event, can) { var msg = {} } }, + MergePath: function(can, file, path) { return file.indexOf(ice.PS) == 0 || file.indexOf(ice.HTTP) == 0? file: can.base.Path(path, file) }, MergeCache: function(can, hash) { return can.misc.MergeURL(can, {_path: can.base.Path(web.SHARE_CACHE, hash)}, true) }, MergePodCmd: function(can, objs) { objs.pod = can.core.Keys(can.misc.Search(can, ice.POD), objs.pod) diff --git a/plugin/local/wiki/data.js b/plugin/local/wiki/data.js index f94b8a36..44b10b6d 100644 --- a/plugin/local/wiki/data.js +++ b/plugin/local/wiki/data.js @@ -1,301 +1,81 @@ -Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg, cb, target) { can.onmotion.clear(can) - if (can.Option(mdb.TYPE)) { return can.onfigure[can.Option(mdb.TYPE)](can, msg, can.Option("fields")) } +Volcanos(chat.ONIMPORT, {_init: function(can, msg, cb, target) { can.onmotion.clear(can) + if (can.Option(mdb.TYPE)) { return can.onimport[can.Option(mdb.TYPE)](can, msg, can.Option("fields")) } can.ui = can.onlayout.display(can), can.table = can.onappend.table(can, msg, function(value, key, index, line) { - return {text: [value, html.TD], oncontextmenu: function(event) { - can.user.carte(event, can, can.ondetail, can.ondetail.list, function(ev, cmd, meta) { - var cb = meta[cmd]; cb && cb(event, can, cmd, value, key, index, line) - }) - }, onclick: function(event) { - key == nfs.PATH && can.run(event, [can.Option(nfs.PATH, value)]) - }, ondblclick: function(event) { - can.page.editable(can, event.target, true) - }} + return can.onimport._value(can, value) }, can.ui.content), can.base.isFunc(cb) && cb(msg), can.onappend._status(can, msg.append), can.onaction._compute(event, can) }, + _value: function(can, value) { + return {text: [value, html.TD], oncontextmenu: function(event) { + can.user.carte(event, can, can.ondetail, can.ondetail.list, function(ev, button, meta) { var cb = meta[button]; can.base.isFunc(cb) && cb(event, can, button) }) + }, ondblclick: function(event) { can.page.editable(can, event.target, true) }} + }, + _story: function(can, msg, fields, display, cb) { + return can.onappend.plugin(can, {mode: chat.OUTPUT, index: ice.CAN_PLUGIN, display: can.misc.MergePath(can, display, chat.PLUGIN_STORY)}, function(sub) { + sub.list = can.core.List(can.core.Split(fields), function(field) { return msg.Table(function(item) { return item[field] }) }), cb(sub) + }) + }, + "折线图": function(can, msg, fields) { return can.onimport._story(can, msg, fields, "trend.js", function(sub) { sub.Conf(ice.VIEW, "折线图") }) }, + "比例图": function(can, msg, fields) { return can.onimport._story(can, msg, fields, "pie.js", function(sub) { sub.Conf(mdb.FIELD, fields), sub.__msg = msg }) }, }, [""]) -Volcanos(chat.ONFIGURE, {help: "组件菜单", - "求和": function(event, can, res, td, index) { - res[index] = parseInt(td.innerText) + (res[index]||0); - }, - "最大": function(event, can, res, td, index) { - (res[index] === undefined || parseInt(td.innerText) > parseInt(res[index])) && (res[index] = parseInt(td.innerText)) - }, - "最小": function(event, can, res, td, index) { - (res[index] === undefined || parseInt(td.innerText) < parseInt(res[index])) && (res[index] = parseInt(td.innerText)) - }, - "平均": function(event, can, res, td, ncol, cols, rows, nrow) { - res[ncol] = parseInt(td.innerText) + (res[ncol]||0); - if (nrow == rows.length - 1) { - res[ncol] = res[ncol] / nrow - } - }, - "折线图": function(can, msg, fields) { - return can.onappend.plugin(can, {type: "output", index: "can.plugin", display: "/plugin/story/trend.js", width: can.ConfWidth(), height: can.ConfHeight()}, function(sub) { - sub.list = can.core.List(can.core.Split(fields), function(field) { return msg.Table(function(item) { return item[field] }) }) - sub.Conf(ice.VIEW, "折线图") - }) - }, - "比例图": function(can, msg, fields) { - return can.onappend.plugin(can, {type: "output", index: "can.plugin", display: "/plugin/story/pie.js", width: can.ConfWidth(), height: can.ConfHeight()}, function(sub) { - sub.list = can.core.List(can.core.Split(fields), function(field) { return msg.Table(function(item) { return item[field] }) }) - sub.__msg = msg, sub.Conf(mdb.FIELD, fields) - }) - }, +Volcanos(chat.ONFIGURE, { + "求和": function(event, can, res, td, index) { res[index] = parseFloat(td.innerText) + (res[index]||0) }, + "最大": function(event, can, res, td, index) { (res[index] === undefined || parseFloat(td.innerText) > parseFloat(res[index])) && (res[index] = parseFloat(td.innerText)) }, + "最小": function(event, can, res, td, index) { (res[index] === undefined || parseFloat(td.innerText) < parseFloat(res[index])) && (res[index] = parseFloat(td.innerText)) }, + "平均": function(event, can, res, td, index, cols, rows, nrow) { res[index] = parseFloat(td.innerText) + (res[index]||0); if (nrow == rows.length - 1) { res[index] = res[index] / nrow } }, }) -Volcanos(chat.ONACTION, {help: "组件菜单", list: [ice.SAVE, [ice.MODE, "全选", "块选", "反选", "多选", "拖动", "编辑"], [ice.EXEC, "求和", "最大", "最小", "平均"]], - _compute: function(event, can) { - var mul = html.TR + (can.Action(ice.MODE) == "全选"? "": ".select") - var method = can.onfigure[can.Action(ice.EXEC)], res = {} - - can.page.Select(can, can.ui.content, mul, function(tr, nrow, rows) { - (mul != html.TR || nrow > 0) && can.page.Select(can, tr, html.TD, function(td, ncol, cols) { - method && method(event, can, res, td, ncol, cols, rows, nrow) - }) - }) - can.core.Item(res, function(key, value) { can.Status(can._msg.append[key], value||"") }) +Volcanos(chat.ONACTION, {list: [ice.SAVE, + [ice.MODE, "全选", "块选", "反选", "多选", "拖动", "编辑"], + [ice.EXEC, "求和", "最大", "最小", "平均"], + ], + _compute: function(event, can) { var method = can.onfigure[can.Action(ice.EXEC)], res = {} + var mul = html.TR + (can.Action(ice.MODE) == "全选"? "": ".select"); can.page.Select(can, can.table, mul, function(tr, nrow, rows) { + (mul != html.TR || nrow > 0) && can.page.Select(can, tr, html.TD, function(td, ncol, cols) { method && method(event, can, res, td, ncol, cols, rows, nrow) }) + }), can.core.Item(res, function(key, value) { can.Status(can._msg.append[key], value||"") }) }, - - save: function(event, can, button) { can.runAction(event, button, [can.Option(nfs.PATH), can.onexport.file(can)]) }, + save: function(event, can, button) { can.runAction(event, button, [can.Option(nfs.PATH), can.onexport.content(can)]) }, exec: function(event, can, button) { can.onaction._compute(event, can) }, push: function(event, can, button) { - can.user.input(event, can, can.page.Select(can, can._output, ["table.content", "tr>th"], function(th, index) { return {name: th.innerText, run: function(event, cmds, cb) { - var msg = can.request(event); can.page.Select(can, can._output, ["table.content", "tr"], function(tr, order) { order != 0 && msg.Push(mdb.VALUE, tr.children[index].innerText) }), cb(msg) - }} }), function(list) { can.run(can.request(event, {_handle: true}), [button, can.Option(nfs.PATH)].concat(list), function() { can.Update() }) }) + can.user.input(event, can, can.page.Select(can, can.table, html.TH, function(th, index) { return {name: th.innerText, run: function(event, cmds, cb) { + var msg = can.request(event); can.page.Select(can, can.table, html.TR, function(tr, _index) { _index > 0 && msg.Push(mdb.VALUE, tr.children[index].innerText) }), cb(msg) + }} }), function(list) { can.runAction(event, button, [can.Option(nfs.PATH)].concat(list), function() { can.Update() }) }) }, draw: function(event, can, button) { - can.user.input(event, can, [["type", "折线图", "比例图"], {name: "fields", run: function(event, cmds, cb) { - var msg = can.request(event); can.page.Select(can, can._output, ["table.content", "tr>th"], function(th) { msg.Push(mdb.VALUE, th.innerText) }), cb(msg) - }}], function(list) { can.onfigure[list[0]](can, can._msg, list[1]) }) - }, - - _foreach: function(can, button, cb) { - button && can.Action(ice.MODE, button) - can.page.Select(can, can.ui.content, html.TR, function(item) { - cb(item) - }) - }, - - "全选": function(event, can, button) { - can.onaction._foreach(can, button, function(item) { - can.page.editable(can, item, false) - can.page.draggable(can, item, false) - item.onmouseenter = null, item.onclick = null - can.page.ClassList.del(can, item, html.SELECT) - can.page.ClassList.del(can, item, "over") - }) - can.onaction._compute(event, can) - }, - "块选": function(event, can, button) { - can.onaction._foreach(can, button, function(item) { - item.onmouseenter = function() { - can.page.ClassList.add(can, item, html.SELECT) - can.onaction._compute(event, can) - } - }) - }, - "反选": function(event, can, button) { - can.onaction._foreach(can, button, function(item) { - item.onmouseenter = function() { - can.page.ClassList.del(can, item, html.SELECT) - can.onaction._compute(event, can) - } - }) - }, - "多选": function(event, can, button) { - can.onaction._foreach(can, button, function(item) { - item.onmouseenter = function() {} - item.onclick = function() { - can.page.ClassList.neg(can, item, html.SELECT) - can.onaction._compute(event, can) - } - }) - }, - "拖动": function(event, can, button) { - can.onaction["全选"](event, can, button) - can.onaction._foreach(can, "", function(item) { - can.page.draggable(can, item, true) - item.ondragstart = function(event) { can.drag = item } - item.ondragover = function(event) { event.preventDefault(), can.page.ClassList.add(can, item, "over")} - item.ondragleave = function(event) { can.page.ClassList.del(can, item, "over") } - item.ondrop = function(event) { event.preventDefault() - can.page.Select(can, can.ui.content, html.TABLE, function(table) { - table.insertBefore(can.drag, item) - }) - } - }) - }, - "编辑": function(event, can, button) { - can.onaction._foreach(can, button, function(item) { - can.page.editable(can, item, true) - }) + can.user.input(event, can, [[mdb.TYPE, "折线图", "比例图"], {name: "fields", run: function(event, cmds, cb) { + var msg = can.request(event); can.page.Select(can, can.table, html.TH, function(th) { msg.Push(mdb.VALUE, th.innerText) }), cb(msg) + }}], function(list) { can.onimport[list[0]](can, can._msg, list[1]) }) }, + + _foreach: function(can, button, cb) { button && can.Action(ice.MODE, button), can.page.Select(can, can.table, html.TR, function(target) { cb(target) }) }, + "全选": function(event, can, button) { can.onaction._foreach(can, button, function(target) { + can.page.ClassList.del(can, target, html.SELECT), can.page.ClassList.del(can, target, "over") + can.page.editable(can, target, false), can.page.draggable(can, target, false) + target.onmouseenter = null, target.onclick = null + }), can.onaction._compute(event, can) }, + "块选": function(event, can, button) { can.onaction._foreach(can, button, function(target) { + target.onmouseenter = function() { can.page.ClassList.add(can, target, html.SELECT), can.onaction._compute(event, can) } + }) }, + "反选": function(event, can, button) { can.onaction._foreach(can, button, function(target) { + target.onmouseenter = function() { can.page.ClassList.del(can, target, html.SELECT), can.onaction._compute(event, can) } + }) }, + "多选": function(event, can, button) { can.onaction._foreach(can, button, function(target) { + target.onmouseenter = function() {}, target.onclick = function() { can.page.ClassList.neg(can, target, html.SELECT), can.onaction._compute(event, can) } + }) }, + "拖动": function(event, can, button) { can.onaction._foreach(can, "", function(target) { can.page.draggable(can, target, true) + target.ondragstart = function(event) { can.drag = target } + target.ondragover = function(event) { event.preventDefault(), can.page.ClassList.add(can, target, "over")} + target.ondragleave = function(event) { can.page.ClassList.del(can, target, "over") } + target.ondrop = function(event) { event.preventDefault(), can.table.insertBefore(can.drag, target) } + }), can.onaction["全选"](event, can, button) }, + "编辑": function(event, can, button) { can.onaction._foreach(can, button, function(target) { can.page.editable(can, target, true) }) }, }) -Volcanos(chat.ONDETAIL, {help: "组件详情", list: ["复制", "删除"], - "复制": function(event, can, button, value, key, index, line) { - var end = can.page.Append(can, can.table, [{type: html.TR, list: can.core.List(can._msg.append, function(key) { - return {text: [line[key], html.TD]} - })}]).tr; can.table.insertBefore(end, event.target.parentNode) - }, - "删除": function(event, can, button) { - can.page.Remove(can, event.target.parentNode) +Volcanos(chat.ONDETAIL, {list: ["复制", "删除"], + "复制": function(event, can) { var list = can.page.Select(can, event.target.parentNode, html.TD, function(target) { return target.innerHTML }) + can.page.insertBefore(can, [{type: html.TR, list: can.page.Select(can, can.table, html.TH, function(key, index) { return can.onimport._value(can, list[index]) })}], event.target.parentNode, can.table) }, + "删除": function(event, can) { can.page.Remove(can, event.target.parentNode) }, }) -Volcanos(chat.ONEXPORT, {help: "导出数据", - file: function(can) { - return can.page.Select(can, can.ui.content, html.TR, function(tr) { - return can.page.Select(can, tr, can.page.Keys(html.TH, html.TD), function(td) {return td.innerHTML}).join(ice.FS) - }).join(ice.NL) - }, -}) - -Volcanos(chat.ONIMPORT, {help: "导入数据", _init: function(can, msg, cb, target) { can.onmotion.clear(can) - if (can.Option(mdb.TYPE)) { return can.onfigure[can.Option(mdb.TYPE)](can, msg, can.Option("fields")) } - can.ui = can.onlayout.display(can), can.table = can.onappend.table(can, msg, function(value, key, index, line) { - return {text: [value, html.TD], oncontextmenu: function(event) { - can.user.carte(event, can, can.ondetail, can.ondetail.list, function(ev, cmd, meta) { - var cb = meta[cmd]; cb && cb(event, can, cmd, value, key, index, line) - }) - }, onclick: function(event) { - key == nfs.PATH && can.run(event, [can.Option(nfs.PATH, value)]) - }, ondblclick: function(event) { - can.page.editable(can, event.target, true) - }} - }, can.ui.content), can.base.isFunc(cb) && cb(msg), can.onappend._status(can, msg.append), can.onaction._compute(event, can) - }, -}, [""]) -Volcanos(chat.ONFIGURE, {help: "组件菜单", - "求和": function(event, can, res, td, index) { - res[index] = parseInt(td.innerText) + (res[index]||0); - }, - "最大": function(event, can, res, td, index) { - (res[index] === undefined || parseInt(td.innerText) > parseInt(res[index])) && (res[index] = parseInt(td.innerText)) - }, - "最小": function(event, can, res, td, index) { - (res[index] === undefined || parseInt(td.innerText) < parseInt(res[index])) && (res[index] = parseInt(td.innerText)) - }, - "平均": function(event, can, res, td, ncol, cols, rows, nrow) { - res[ncol] = parseInt(td.innerText) + (res[ncol]||0); - if (nrow == rows.length - 1) { - res[ncol] = res[ncol] / nrow - } - }, - "折线图": function(can, msg, fields) { - return can.onappend.plugin(can, {type: "output", index: "can.plugin", display: "/plugin/story/trend.js", width: can.ConfWidth(), height: can.ConfHeight()}, function(sub) { - sub.list = can.core.List(can.core.Split(fields), function(field) { return msg.Table(function(item) { return item[field] }) }) - sub.Conf(ice.VIEW, "折线图") - }) - }, - "比例图": function(can, msg, fields) { - return can.onappend.plugin(can, {type: "output", index: "can.plugin", display: "/plugin/story/pie.js", width: can.ConfWidth(), height: can.ConfHeight()}, function(sub) { - sub.list = can.core.List(can.core.Split(fields), function(field) { return msg.Table(function(item) { return item[field] }) }) - sub.__msg = msg, sub.Conf(mdb.FIELD, fields) - }) - }, -}) -Volcanos(chat.ONACTION, {help: "组件菜单", list: [ice.SAVE, [ice.MODE, "全选", "块选", "反选", "多选", "拖动", "编辑"], [ice.EXEC, "求和", "最大", "最小", "平均"]], - _compute: function(event, can) { - var mul = html.TR + (can.Action(ice.MODE) == "全选"? "": ".select") - var method = can.onfigure[can.Action(ice.EXEC)], res = {} - - can.page.Select(can, can.ui.content, mul, function(tr, nrow, rows) { - (mul != html.TR || nrow > 0) && can.page.Select(can, tr, html.TD, function(td, ncol, cols) { - method && method(event, can, res, td, ncol, cols, rows, nrow) - }) - }) - can.core.Item(res, function(key, value) { can.Status(can._msg.append[key], value||"") }) - }, - - save: function(event, can, button) { can.runAction(event, button, [can.Option(nfs.PATH), can.onexport.file(can)]) }, - exec: function(event, can, button) { can.onaction._compute(event, can) }, - draw: function(event, can, button) { - can.user.input(event, can, [{name: "type", values: ["折线图", "比例图"]}, "fields"], function(list) { can.onfigure[list[0]](can, can._msg, list[1]) }) - }, - push: function(event, can, button) { - can.user.input(event, can, can.page.Select(can, can._output, ["table.content", "tr>th"], function(th, index) { return {name: th.innerText, run: function(event, cmds, cb) { - var msg = can.request(event); can.page.Select(can, can._output, ["table.content", "tr"], function(tr, order) { - order != 0 && msg.Push("value", tr.children[index].innerText) - }), cb(msg) - }} }), function(list) { - can.run(can.request(event, {_handle: true}), [button, can.Option(nfs.PATH)].concat(list), function() { can.Update() }) - }) - }, - - _foreach: function(can, button, cb) { - button && can.Action(ice.MODE, button) - can.page.Select(can, can.ui.content, html.TR, function(item) { - cb(item) - }) - }, - - "全选": function(event, can, button) { - can.onaction._foreach(can, button, function(item) { - can.page.editable(can, item, false) - can.page.draggable(can, item, false) - item.onmouseenter = null, item.onclick = null - can.page.ClassList.del(can, item, html.SELECT) - can.page.ClassList.del(can, item, "over") - }) - can.onaction._compute(event, can) - }, - "块选": function(event, can, button) { - can.onaction._foreach(can, button, function(item) { - item.onmouseenter = function() { - can.page.ClassList.add(can, item, html.SELECT) - can.onaction._compute(event, can) - } - }) - }, - "反选": function(event, can, button) { - can.onaction._foreach(can, button, function(item) { - item.onmouseenter = function() { - can.page.ClassList.del(can, item, html.SELECT) - can.onaction._compute(event, can) - } - }) - }, - "多选": function(event, can, button) { - can.onaction._foreach(can, button, function(item) { - item.onmouseenter = function() {} - item.onclick = function() { - can.page.ClassList.neg(can, item, html.SELECT) - can.onaction._compute(event, can) - } - }) - }, - "拖动": function(event, can, button) { - can.onaction["全选"](event, can, button) - can.onaction._foreach(can, "", function(item) { - can.page.draggable(can, item, true) - item.ondragstart = function(event) { can.drag = item } - item.ondragover = function(event) { event.preventDefault(), can.page.ClassList.add(can, item, "over")} - item.ondragleave = function(event) { can.page.ClassList.del(can, item, "over") } - item.ondrop = function(event) { event.preventDefault() - can.page.Select(can, can.ui.content, html.TABLE, function(table) { - table.insertBefore(can.drag, item) - }) - } - }) - }, - "编辑": function(event, can, button) { - can.onaction._foreach(can, button, function(item) { - can.page.editable(can, item, true) - }) - }, -}) -Volcanos(chat.ONDETAIL, {help: "组件详情", list: ["复制", "删除"], - "复制": function(event, can, button, value, key, index, line) { - var end = can.page.Append(can, can.table, [{type: html.TR, list: can.core.List(can._msg.append, function(key) { - return {text: [line[key], html.TD]} - })}]).tr; can.table.insertBefore(end, event.target.parentNode) - }, - "删除": function(event, can, button) { - can.page.Remove(can, event.target.parentNode) - }, -}) -Volcanos(chat.ONEXPORT, {help: "导出数据", - file: function(can) { - return can.page.Select(can, can.ui.content, html.TR, function(tr) { - return can.page.Select(can, tr, can.page.Keys(html.TH, html.TD), function(td) {return td.innerHTML}).join(ice.FS) - }).join(ice.NL) - }, +Volcanos(chat.ONEXPORT, { + content: function(can) { return can.page.Select(can, can.ui.content, html.TR, function(tr) { + return can.page.Select(can, tr, can.page.Keys(html.TH, html.TD), function(td) {return td.innerHTML}).join(ice.FS) + }).join(ice.NL) }, }) diff --git a/proto.js b/proto.js index 165f0811..94fc26f2 100644 --- a/proto.js +++ b/proto.js @@ -13,6 +13,7 @@ var ice = { POD: "pod", CTX: "ctx", CMD: "cmd", ARG: "arg", OPT: "opt", CAN: "can", RUN: "run", RES: "res", ERR: "err", + CAN_PLUGIN: "can.plugin", MSG_DETAIL: "detail", MSG_OPTION: "option",