不成熟的改进

This commit is contained in:
2025-07-19 23:20:36 +08:00
parent 768b5bc5bc
commit 7e28958462
8 changed files with 391 additions and 30 deletions

Binary file not shown.

1
config.toml Normal file
View File

@@ -0,0 +1 @@
tasked_number = 8 # 新记忆核子数量

0
electron/陈情表.toml Normal file
View File

236
main.py
View File

@@ -0,0 +1,236 @@
from textual.app import App, ComposeResult
from textual.widgets import Header, Footer, ListView, ListItem, Label, Static, Button
from textual.containers import Container
from textual.screen import Screen
import particles as parti
import pathlib
ver = '0.2.1'
class MemScreen(Screen):
BINDINGS = [
("d", "toggle_dark", "改变色调"),
("q", "pop_screen", "返回主菜单"),
("v", "play_voice", "朗读"),
("0", "press('q0')", None),
("1", "press('q1')", None),
("2", "press('q2')", None),
("3", "press('q3')", None),
("4", "press('q4')", None),
("5", "press('q5')", None),
("[", "press('q5')", None),
("]", "press('q4')", None),
(";", "press('q3')", None),
("'", "press('q2')", None),
(".", "press('q1')", None),
("/", "press('q0')", None),
]
btn = dict()
def __init__(
self,
atoms_file: str = 'test_atoms.json',
tasked_num: int = 8, # 记忆最小单元数目
):
super().__init__(name=None, id=None, classes=None)
self.memobj = MemObject(atoms_file=atoms_file, tasked_num=tasked_num)
self.memobj.next_round()
self.memobj.update_runtime(1)
def compose(self) -> ComposeResult:
yield Header(show_clock=True)
with Container(id="main_container"):
yield Label("", id="round_label")
yield Label("记住了吗?", id="question")
yield Static(self.memobj.runtime['current_atom'].content, id="sentence")
yield Static("", id="feedback") # 用于显示反馈
yield Label(self._get_progress_text(), id="progress")
with Container(id="button_container"):
self.btn['5'] = Button("完美回想", variant="success", id="q5", classes="choice")
self.btn['4'] = Button("犹豫后正确", variant="success", id="q4", classes="choice")
self.btn['3'] = Button("困难地正确", variant="warning", id="q3", classes="choice")
self.btn['2'] = Button("错误但熟悉", variant="warning", id="q2", classes="choice")
self.btn['1'] = Button("错误且不熟", variant="error", id="q1", classes="choice")
self.btn['0'] = Button("完全空白", variant="error", id="q0", classes="choice")
yield Horizontal(self.btn['5'], self.btn['4'])
yield Horizontal(self.btn['3'], self.btn['2'])
yield Horizontal(self.btn['1'], self.btn['0'])
yield Footer()
def _get_progress_text(self):
return f"{self.memobj.runtime['left'] + 1}/{self.memobj.runtime['total']}"
def _get_round_text(self):
t = {
'A': "复习模式",
'B': "建立新记忆",
'C': "总复习"
}
return "当前模式: " + t[self.memobj.runtime['stage']]
def on_mount(self):
# 首次挂载时调用
self._update_ui()
def _update_ui(self):
self.query_one("#round_label", Label).update(self._get_round_text())
self.query_one("#sentence", Static).update(self.memobj.runtime['current_atom'].content)
self.query_one("#progress", Label).update(self._get_progress_text())
self.query_one("#feedback", Static).update("") # 清除任何之前的反馈消息
def _show_finished_screen(self, message):
self.query_one("#question", Label).update(message)
self.query_one("#sentence", Static).update("已经完成记忆任务")
self.query_one("#round_label").display = False
self.query_one("#progress").display = False
for i in range(6):
self.query_one(f"#q{i}", Button).display = False
def on_button_pressed(self, event):
feedback_label = self.query_one("#feedback", Static)
if type(event) == str:
btnid = event
else:
btnid = event.button.id
btnid = str(btnid)
quality = int(btnid.replace('q', ''))
assessment = self.memobj.report(self.memobj.runtime['current_atom'], quality)
if assessment == 1:
# 需要复习
feedback_label.update(f"评分为 {quality}, 已经加入至复习, 请重复记忆")
else:
ret = self.memobj.update_runtime(1)
if ret == 1:
self.memobj.switch_to_extra_review()
self.memobj.update_runtime(1)
elif ret == 2:
self.memobj.next_round()
self.memobj.update_runtime(1)
elif ret == 3:
self.memobj.save()
self._show_finished_screen("今日目标已完成")
return
#feedback_label.update("") # 清除反馈消息
self._update_ui()
def action_press(self, btnid):
self.on_button_pressed(btnid)
def action_play_voice(self):
def play():
cache = Path(f"./cache/voice/{self.memobj.runtime['current_atom'].content}.wav")
if not cache.exists():
communicate = tts.Communicate(self.memobj.runtime['current_atom'].content, "zh-CN-YunjianNeural")
communicate.save_sync(f"./cache/voice/{self.memobj.runtime['current_atom'].content}.wav")
playsound(str(cache))
threading.Thread(target=play).start()
def action_toggle_dark(self):
self.app.action_toggle_dark()
def action_pop_screen(self):
"""返回到上一个屏幕"""
self.app.pop_screen()
class PreparationScreen(Screen):
BINDINGS = [
("q", "go_back", "返回"),
("escape", "quit_app", "退出")
]
def __init__(self, nucleon_file: parti.AtomicFile, electron_file: parti.AtomicFile) -> None:
super().__init__(name=None, id=None, classes=None)
self.nucleon_file = nucleon_file
self.electron_file = electron_file
def compose(self) -> ComposeResult:
yield Header(show_clock=True)
with Container(id="learning_screen_container"):
yield Label(f"记忆项目: [b]{self.nucleon_file.name}[/b]\n")
yield Label(f"核子文件对象: ./nucleon/[b]{self.nucleon_file.name}[/b].toml")
yield Label(f"电子文件对象: ./electron/[b]{self.electron_file.name}[/b].toml")
yield Label(f"核子数量:{self.nucleon_file.get_len()}")
yield Button("开始记忆", id="start_memorizing_button", variant="primary", classes="start-button")
yield Static(f"\n全文如下:\n")
yield Static(self.nucleon_file.get_full_content(), classes="full")
yield Footer()
def action_go_back(self):
self.app.pop_screen()
def action_quit_app(self):
self.app.exit()
def on_button_pressed(self, event: Button.Pressed) -> None:
pass
#if event.button.id == "start_memorizing_button":
# #init_file(Path(self.atom_file).name)
# newscr = proc.MemScreen(Path(self.atom_file).name)
# self.app.push_screen(
# newscr
# )
#if event.button.id == "edit_metadata_button":
# init_file(Path(self.atom_file).name)
# os.system("reset;nano ./data/" + str(Path(self.atom_file).name.replace(".txt", "_atoms.json")))
class FileSelectorScreen(Screen):
global ver
def compose(self) -> ComposeResult:
yield Header(show_clock=True)
yield Container(
Label(f'欢迎使用 "潜进" 辅助记忆软件, 版本 {ver}', classes="title-label"),
Label("选择要学习的文件:", classes="title-label"),
ListView(id="file-list", classes="file-list-view")
)
yield Footer()
def on_mount(self) -> None:
file_list_widget = self.query_one("#file-list", ListView)
nucleon_path = pathlib.Path("./nucleon")
nucleon_files = sorted([f.name for f in nucleon_path.iterdir() if f.suffix == ".toml"])
if nucleon_files:
for filename in nucleon_files:
file_list_widget.append(ListItem(Label(filename)))
else:
file_list_widget.append(ListItem(Static("在 ./nucleon/ 中未找到任何核子文件. 请放置文件后重启应用.")))
file_list_widget.disabled = True
def on_list_view_selected(self, event: ListView.Selected) -> None:
if not isinstance(event.item, ListItem):
self.notify("无法选择此项。", severity="error")
return
selected_label = event.item.query_one(Label)
if "未找到任何 .toml 文件" in str(selected_label.renderable):
self.notify("请先在 `./atoms/` 目录中放置 .toml 文件。", severity="warning")
return
selected_filename = str(selected_label.renderable)
nucleon_file = parti.AtomicFile(pathlib.Path("./nucleon") / selected_filename, "nucleon")
electron_file_path = pathlib.Path("./electron") / selected_filename
if electron_file_path.exists():
pass
else:
electron_file_path.touch()
electron_file = parti.AtomicFile(pathlib.Path("./electron") / selected_filename, "electron")
# self.notify(f"已选择: {selected_filename}", timeout=2)
self.app.push_screen(PreparationScreen(nucleon_file, electron_file))
def action_quit_app(self) -> None:
self.app.exit()
class AppLauncher(App):
CSS_PATH = "styles.tcss"
TITLE = '潜进 - 辅助记忆程序'
BINDINGS = [("escape", "quit", "退出"), ("d", "toggle_dark", "改变色调")]
SCREENS = {
"file_selection_screen": FileSelectorScreen,
}
def on_mount(self) -> None:
self.action_toggle_dark()
self.push_screen("file_selection_screen")
if __name__ == "__main__":
css_path = pathlib.Path("styles_dashboard.tcss")
app = AppLauncher()
app.run()

View File

@@ -1,139 +1,139 @@
["臣密言:臣以险衅, 夙遭闵凶."]
note = []
translation = "臣子李密陈言:我因命运不好,小时候遭遇到了不幸"
keyword_note = {"险衅":"凶险祸患(这里指命运不好)", "夙":"早时,这里指年幼的时候", "闵":"通'悯',指可忧患的事", "凶":"不幸,指丧父"}
keyword_note = {"险衅"="凶险祸患(这里指命运不好)", "夙"="早时,这里指年幼的时候", "闵"="通'悯',指可忧患的事", "凶"="不幸,指丧父"}
["生孩六月, 慈父见背;行年四岁, 舅夺母志."]
note = []
translation = "刚出生六个月,我慈爱的父亲就不幸去世了。经过了四年,舅父逼母亲改嫁"
keyword_note = {"见背":"死的委婉说法", "行年":"经历的年岁", "母志":"母亲守节之志(改嫁的委婉说法)"}
keyword_note = {"见背"="死的委婉说法", "行年"="经历的年岁", "母志"="母亲守节之志(改嫁的委婉说法)"}
["祖母刘愍臣孤弱, 躬亲抚养."]
note = []
translation = "我的祖母刘氏,怜悯我从小丧父,便亲自对我加以抚养"
keyword_note = {"愍":"怜悯", "躬亲":"亲身"}
keyword_note = {"愍"="怜悯", "躬亲"="亲身"}
["臣少多疾病, 九岁不行, 零丁孤苦, 至于成立."]
note = []
translation = "臣小的时候经常生病,九岁时还不会行走。孤独无靠,一直到成人自立"
keyword_note = {"成立":"成人自立"}
keyword_note = {"成立"="成人自立"}
["既无伯叔, 终鲜兄弟, 门衰祚薄, 晚有儿息."]
note = []
translation = "既没有叔叔伯伯,又没什么兄弟,门庭衰微而福分浅薄,很晚才有儿子"
keyword_note = {"鲜":"少,这里指'无'", "祚薄":"福分浅薄", "儿息":"亲生子女"}
keyword_note = {"鲜"="少,这里指'无'", "祚薄"="福分浅薄", "儿息"="亲生子女"}
["外无期功强近之亲, 内无应门五尺之僮, 茕茕孑立, 形影相吊."]
note = []
translation = "在外面没有比较亲近的亲戚,在家里又没有照应门户的童仆。生活孤单没有依靠,每天只有自己的身体和影子相互安慰"
keyword_note = {"期功":"指关系较近的亲属", "茕茕孑立":"孤单无依靠的样子", "吊":"安慰"}
keyword_note = {"期功"="指关系较近的亲属", "茕茕孑立"="孤单无依靠的样子", "吊"="安慰"}
["而刘夙婴疾病, 常在床蓐, 臣侍汤药, 未曾废离."]
note = []
translation = "但祖母又早被疾病缠绕,常年卧床不起,我侍奉她吃饭喝药,从来就没有停止侍奉而离开她"
keyword_note = {"婴":"被...缠绕", "蓐":"通'褥',床垫", "废":"停止服侍", "离":"离开"}
keyword_note = {"婴"="被...缠绕", "蓐"="通'褥',床垫", "废"="停止服侍", "离"="离开"}
["逮奉圣朝, 沐浴清化."]
note = []
translation = "到了晋朝建立,我蒙受着清明的政治教化"
keyword_note = {"逮":"及,到", "奉":"承奉", "圣朝":"指当时的晋朝", "沐浴清化":"蒙受清平教化"}
keyword_note = {"逮"="及,到", "奉"="承奉", "圣朝"="指当时的晋朝", "沐浴清化"="蒙受清平教化"}
["前太守臣逵察臣孝廉;后刺史臣荣举臣秀才."]
note = []
translation = "前任太守逵,考察后推举臣下为孝廉,后任刺史荣又推举臣下为优秀人才"
keyword_note = {"察":"考察和推举", "孝廉":"孝顺,品性纯洁", "举":"推举", "秀才":"优秀人才"}
keyword_note = {"察"="考察和推举", "孝廉"="孝顺,品性纯洁", "举"="推举", "秀才"="优秀人才"}
["臣以供养无主, 辞不赴命."]
note = []
translation = "臣下因为供奉赡养祖母的事无人承担,辞谢不接受任命"
keyword_note = {"无主":"无人承担"}
keyword_note = {"无主"="无人承担"}
["诏书特下, 拜臣郎中, 寻蒙国恩, 除臣洗马."]
note = []
translation = "朝廷又特地下了诏书,任命我为郎中,不久又蒙受国家恩命,任命我为太子洗马"
keyword_note = {"拜":"授予官职", "郎中":"尚书省的属官", "寻":"不久", "除":"拜官受职", "洗马":"太子的属官"}
keyword_note = {"拜"="授予官职", "郎中"="尚书省的属官", "寻"="不久", "除"="拜官受职", "洗马"="太子的属官"}
["猥以微贱, 当侍东宫, 非臣陨首所能上报."]
note = []
translation = "像我这样出身微贱地位卑下的人,担当侍奉太子的职务,这实在不是我杀身捐躯所能报答朝廷的"
keyword_note = {"猥":"谦词", "微贱":"卑微低贱", "东宫":"太子居处", "陨首":"杀身"}
keyword_note = {"猥"="谦词", "微贱"="卑微低贱", "东宫"="太子居处", "陨首"="杀身"}
["臣具以表闻, 辞不就职."]
note = []
translation = "我将以上苦衷上表报告,加以推辞不去就职"
keyword_note = {"具":"详细", "闻":"使...知道"}
keyword_note = {"具"="详细", "闻"="使...知道"}
["诏书切峻, 责臣逋慢;郡县逼迫, 催臣上道;州司临门, 急于星火."]
note = []
translation = "但是诏书急切严峻,责备我逃避命令,有意拖延,态度傲慢。郡县长官催促我立刻上路;州官登门督促,比流星坠落还要急迫"
keyword_note = {"切峻":"急切而严厉", "逋慢":"逃避怠慢", "星火":"流星的光,喻急迫"}
keyword_note = {"切峻"="急切而严厉", "逋慢"="逃避怠慢", "星火"="流星的光,喻急迫"}
["臣欲奉诏奔驰, 则刘病日笃, 欲苟顺私情, 则告诉不许."]
note = []
translation = "我很想遵从皇上的旨意赴京就职,但祖母刘氏的病却一天比一天重;想要姑且顺从自己的私情,但报告申诉不被允许"
keyword_note = {"日笃":"病情日益加重", "苟":"姑且", "告诉":"报告申诉"}
keyword_note = {"日笃"="病情日益加重", "苟"="姑且", "告诉"="报告申诉"}
["臣之进退, 实为狼狈."]
note = []
translation = "我是进退两难,十分狼狈"
keyword_note = {"狼狈":"进退两难的样子"}
keyword_note = {"狼狈"="进退两难的样子"}
["伏惟圣朝以孝治天下, 凡在故老, 犹蒙矜育, 况臣孤苦, 特为尤甚."]
note = []
translation = "我俯伏思量晋朝是用孝道来治理天下的,凡是年老而德高的旧臣,尚且还受到怜悯养育,何况我的孤苦程度更为严重呢"
keyword_note = {"伏惟":"下对上的敬辞", "故老":"年老德高的旧臣", "矜育":"怜悯养育"}
keyword_note = {"伏惟"="下对上的敬辞", "故老"="年老德高的旧臣", "矜育"="怜悯养育"}
["且臣少仕伪朝, 历职郎署, 本图宦达, 不矜名节."]
note = []
translation = "况且我年轻的时候曾经做过蜀汉的官,担任过郎官职务,本来就希望做官显达,并不顾惜名声节操"
keyword_note = {"伪朝":"对前朝的蔑称", "历职":"连续任职", "郎署":"尚书郎的官衙", "宦达":"官场上显达"}
keyword_note = {"伪朝"="对前朝的蔑称", "历职"="连续任职", "郎署"="尚书郎的官衙", "宦达"="官场上显达"}
["今臣亡国贱俘, 至微至陋, 过蒙拔擢, 宠命优渥, 岂敢盘桓, 有所希冀!"]
note = []
translation = "现在我是一个低贱的亡国俘虏,十分卑微浅陋,受到过分提拔,恩宠优厚,怎敢犹豫不决而有非分的企求呢"
keyword_note = {"拔擢":"提拔", "优渥":"优厚", "盘桓":"徘徊不前", "希冀":"非分的企求"}
keyword_note = {"拔擢"="提拔", "优渥"="优厚", "盘桓"="徘徊不前", "希冀"="非分的企求"}
["但以刘日薄西山, 气息奄奄, 人命危浅, 朝不虑夕."]
note = []
translation = "只是因为祖母刘氏寿命即将终了,气息微弱,生命垂危,早上不能想到晚上怎样"
keyword_note = {"日薄西山":"太阳接近西山,喻人寿命将终", "危浅":"生命垂危"}
keyword_note = {"日薄西山"="太阳接近西山,喻人寿命将终", "危浅"="生命垂危"}
["臣无祖母, 无以至今日, 祖母无臣, 无以终余年."]
note = []
translation = "臣下我如果没有祖母,就没有今天的样子;祖母如果没有我的照料,也无法度过她的余生"
keyword_note = {"终余年":"度过余生"}
keyword_note = {"终余年"="度过余生"}
["母孙二人, 更相为命, 是以区区不能废远."]
note = []
translation = "我们祖孙二人,互相依靠而维持生命,因此我的内心不愿废止奉养,远离祖母"
keyword_note = {"更相":"相互", "区区":"自己的私情", "废远":"废止奉养而远离"}
keyword_note = {"更相"="相互", "区区"="自己的私情", "废远"="废止奉养而远离"}
["臣密今年四十有四, 祖母今年九十有六, 是臣尽节于陛下之日长, 报养刘之日短."]
note = []
translation = "臣下我现在的年龄四十四岁了,祖母现在的年龄九十六岁了,臣下我在陛下面前尽忠尽节的日子还长着呢,而在祖母刘氏面前尽孝尽心的日子已经不多了"
keyword_note = {"有":"又", "尽节":"尽忠节"}
keyword_note = {"有"="又", "尽节"="尽忠节"}
["乌鸟私情, 愿乞终养."]
note = []
translation = "我怀着乌鸦反哺的私情,乞求能够准许我完成对祖母养老送终的心愿"
keyword_note = {"乌鸟私情":"乌鸦反哺之情,喻孝心", "终养":"养老至终"}
keyword_note = {"乌鸟私情"="乌鸦反哺之情,喻孝心", "终养"="养老至终"}
["臣之辛苦, 非独蜀之人士及二州牧伯所见明知, 皇天后土, 实所共鉴."]
note = []
translation = "我的辛酸苦楚,并不仅仅被蜀地的百姓及益州、梁州的长官所亲眼目睹、内心明白,连天地神明也都看得清清楚楚"
keyword_note = {"辛苦":"辛酸苦楚", "牧伯":"州郡长官", "皇天后土":"天地神明", "鉴":"明察"}
keyword_note = {"辛苦"="辛酸苦楚", "牧伯"="州郡长官", "皇天后土"="天地神明", "鉴"="明察"}
["愿陛下矜悯愚诚, 听臣微志, 庶刘侥幸, 保卒余年."]
note = []
translation = "希望陛下能怜悯我愚昧诚心,请允许我完成臣下一点小小的心愿,使祖母刘氏能够侥幸地保全她的余生"
keyword_note = {"矜悯":"怜悯", "听":"准许", "庶":"或许(表希望)", "卒余年":"终老"}
keyword_note = {"矜悯"="怜悯", "听"="准许", "庶"="或许(表希望)", "卒余年"="终老"}
["臣生当陨首, 死当结草."]
note = []
translation = "我活着应当杀身报效朝廷,死了也要结草衔环来报答陛下的恩情"
keyword_note = {"陨首":"掉脑袋,指献出生命", "结草":"死后报恩的典故"}
keyword_note = {"陨首"="掉脑袋,指献出生命", "结草"="死后报恩的典故"}
["臣不胜犬马怖惧之情, 谨拜表以闻."]
note = []
translation = "臣下我怀着牛马一样不胜恐惧的心情,恭敬地呈上此表来使陛下知道这件事"
keyword_note = {"不胜":"禁不住", "犬马怖惧":"臣子谦卑的自比", "闻":"使...知道"}
keyword_note = {"不胜"="禁不住", "犬马怖惧"="臣子谦卑的自比", "闻"="使...知道"}

View File

@@ -5,6 +5,11 @@ import copy
import datetime
import json
class Aux():
@staticmethod
def get_daystamp():
return (time.time() // (24*3600))
class Atom():
"""原子: 由电子(分析数据)和核子(材料元数据)组成的反应(运行时)中间对象"""
@@ -18,7 +23,7 @@ class Electron():
real_rept = 0 # (实际)重复次数
rept = 0 # (有效)重复次数
interval = 0 # 最佳间隔
ept', last_date = 0 # 上一次复习的时间戳
last_date = 0 # 上一次复习的时间戳
next_date = 0 # 将要复习的时间戳
is_activated = 0 # 激活状态
# *NOTE: 这里的"时间戳" 是以天为单位的整数, 即 UNIX 时间戳除以一天的秒数取整
@@ -42,6 +47,47 @@ ept', last_date = 0 # 上一次复习的时间戳
setattr(self, var, value)
self.last_modify = time.time()
def update(self, quality):
"""
根据 quality(0 ~ 5) 进行参数迭代
quality 由主程序评估
"""
if quality == -1:
return -1
self.efactor = self.efactor + (0.1 - (5 - quality) * (0.08 + (5 - quality) * 0.02))
self.efactor = max(1.3, self.efactor)
if quality < 3:
# 如果回忆质量低于 3重置重复次数
self.rept = 0
self.interval = 0 # 设为0以便下面重新计算I(1)
else:
self.rept += 1
self.real_rept += 1
if self.rept == 0: # 刚被重置或首次遇到
self.interval = 1 # I(1)
elif self.rept == 1:
self.interval = 6 # I(2) 经验公式
else:
self.interval = round(self.interval * self.efactor)
self.last_date = Aux.get_daystamp()
self.next_date = self.last_date + self.interval
def __str__(self):
return (f"记忆单元预览 \n"
f"内容: '{self.content}' \n"
f"易度系数: {self.efactor:.2f} \n"
f"已经重复的次数: {self.rept} \n"
f"下次间隔: {self.interval}\n"
f"下次复习日期时间戳: {self.next_date}")
def __eq__(self, other):
if self.content == other.content:
return 1
return 0
def __hash__(self):
return hash(self.content)
@@ -81,3 +127,25 @@ class Nucleon():
with open(path, 'w') as f:
toml.dump(nucleon_list, f)
class AtomicFile():
def __init__(self, path, type_="unknown"):
self.path = path
self.type_ = type_
if type_ == "nucleon":
self.name, self.datalist = Nucleon.import_from_file(pathlib.Path(path))
if type_ == "electron":
self.name, self.datalist = Electron.import_from_file(pathlib.Path(path))
def save(self):
if self.type_ == "nucleon":
Nucleon.save_to_file(self.datalist, self.path)
if self.type_ == "electron":
Electron.save_to_file(self.datalist, self.path)
def get_full_content(self):
if self.type_ == "nucleon":
text = ""
for i in self.datalist:
text += i.content
return text
return ""
def get_len(self):
return len(self.datalist)

View File

@@ -0,0 +1 @@
class Reactor(tasked_num):

55
styles.tcss Normal file
View File

@@ -0,0 +1,55 @@
Screen {
align: center middle;
}
#main_container {
align: center middle;
width: 80%;
height: auto;
border: thick $primary-lighten-2;
padding: 2;
}
#sentence {
content-align: center middle;
width: 100%;
height: 5;
margin-bottom: 2;
text-style: bold;
}
#progress {
width: 100%;
content-align: center middle;
margin-bottom: 1;
color: $text-muted;
}
Button {
align-horizontal: center;
width: 50%;
margin: 0 0;
}
.choice {
align-horizontal: center;
width: 50%;
margin: 0 0;
height: auto;
}
/* no_margin.tcss */
#button_container {
align-horizontal: center;
height: 9;
}
/* 选中 #button_container 下所有的 Horizontal 子元素 */
#button_container > Horizontal {
margin-top: 0;
margin-bottom: 0;
align-horizontal: center;
width: 40%;
}