import { Book, BookEntry, BookEntryKind, BookSection } from "@/types/book"; function makeEntries(sectionId: string, kind: BookEntryKind, titles: string[][]): BookEntry[] { return titles.map(([title, ...content], index) => ({ id: `${sectionId}-${index + 1}`, title, kind, order: index + 1, content })); } function makeSection( id: string, title: string, kind: BookEntryKind, order: number, titles: string[][] ): BookSection { return { id, title, kind, order, entries: makeEntries(id, kind, titles) }; } export const demoBooks: Book[] = [ { id: "memory-catcher", title: "记忆捕手", author: "墨尘", category: "悬疑", description: "一间只在深夜营业的记忆事务所,一群替人打捞记忆碎片的人,以及越来越像真实案件的委托记录。", wordCount: "约 6 万字(演示)", coverStyle: "linear-gradient(135deg, #7089a8, #2e405a)", sections: [ makeSection("mc-lore-world", "世界观设定", "lore", 1, [ [ "资料一 事务所规则", "记忆事务所只在每天凌晨零点到五点营业,所有委托都需要经过双重验证,且不得跨越自然死亡边界回收记忆。", "每次进入记忆深层前,执行者必须留下现实锚点,否则在高损耗片段中极易失去自我定位。" ], [ "资料二 回收协议", "记忆回收分为取样、修复、归还三个阶段,资料类委托和正文类案件都必须标记来源与完整度。", "当完整度低于百分之三十时,系统会自动建议多人协同解析。" ] ]), makeSection("mc-lore-roles", "人物档案", "lore", 2, [ [ "资料三 林夜", "林夜是事务所的主检索员,擅长在受损记忆中建立临时路径。", "他最大的弱点是不擅长拒绝任何一份“看起来还能救回来”的委托。" ], [ "资料四 深洲事务所", "事务所位于深洲旧城区地下一层,常年由蓝色工作灯照明,主工作台正对一面由十五块屏幕拼成的监控墙。", "多数外来委托都会先被收录为资料条目,再决定是否转入正式案件。" ] ]), makeSection("mc-novel-volume-1", "正文 第一卷", "novel", 100, [ [ "第一章 数据废墟", "深洲事务所的地下工作室被蓝色光芒覆盖,十五块屏幕全部亮起,数据流在每一个像素中涌动。", "林夜坐在工作台中央,接口头环已经戴好,眼前是一份来自匿名客户的委托:在七十二小时内找回一段被人为删除的童年记忆。", "这类工作本该只是技术活,可委托附件里多出了一段视频。视频结尾,有一只沾着雨水的手按住镜头,像是隔着时间朝他们打招呼。", "林夜把视频倒回三遍,每一次都在同一帧停住。那只手的背面有一条细长的旧疤,从食指根部一直延伸到手腕内侧。他在档案库里查了两个小时,没有找到任何匹配记录。", "助手阿洲从副屏那边探过头来,把一杯加了太多糖的速溶咖啡推到他手边。阿洲的全名是深洲,是前任所长留下的程序遗产,运行在事务所最老的那台主机里,声音一直带着轻微的电流底噪。", "委托标注的删除时间是十七年前,记忆主体的年龄标签显示为七岁。林夜见过各种各样的委托,但主动删除自己七岁记忆的案例,他只遇到过两次,而那两次都以失踪告终。", "他把委托文件重新读了一遍,这次注意到了一个细节:委托人在自我描述一栏填写的不是职业,而是一句话——我不记得自己是谁,但我记得那天下的雨很冷。", "阿洲把周边环境数据调出来投到主屏。十七年前的深洲旧城区,梅雨季,平均气温十八度,湿度百分之八十九。数据是对的,雨确实很冷。", "接入协议在凌晨一点十分完成,桥接通道稳定在百分之七十三。林夜把头环频率调低两档,告诉自己这只是一次普通的技术回收,不需要带入情绪。", "进入深层的第一秒,他感到一阵轻微的耳鸣。这是正常现象,每次穿越时间密度超过十五年的记忆节点,神经接口都会有短暂的校准延迟。他等那阵嗡鸣过去,睁开眼睛。", "眼前是一条砖墙巷子,地面是湿的,空气里有青苔和积水混合的气味。巷子的尽头挂着一盏昏黄的路灯,灯芯在雨里微微颤动,像是随时会熄灭,又始终没有熄灭。", "系统提示记忆完整度为百分之四十一,低于标准阈值,但还在可回收范围内。林夜沿着巷子向前走,注意到地面的青砖缝里长着一种深绿色的苔藓,每走一步都会发出细碎的轻响。", "他在路灯下停住。灯柱底部贴着一张褪色的寻人启事,纸张已经被雨水浸透,字迹模糊到只剩一个名字还能辨认:沈宁,女,七岁,失踪于本年六月十四日。", "林夜把这个名字发回给阿洲,让她在现实端同步检索。回复几乎是即时的:深洲民政记录中有两个同名条目,但其中一个的档案在八年前被标记为封存,无法访问。", "他继续往巷子深处走。记忆的密度在增加,四周的色彩开始从灰蓝色向暖黄色偏移,像是有人在用力把这段经历拉回到更早的时间里。林夜知道这是删除补丁留下的痕迹——当一段记忆被反复清除,边缘会产生色温偏差,就像照片被过度曝光之后留下的光晕。", "巷子的尽头出现了一扇半开的木门,门里透出温暖的灯光,还有锅里食物沸腾的声音。林夜站在门外,没有立刻进去。他知道记忆里的场景如果设置了访问壁垒,强行进入会触发清除反应,把这段残余也一并抹掉。", "他在门外等了大约三十秒,确认没有阻断信号之后才轻轻推开木门。室内是一间狭小但整洁的厨房,一个女人正背对着他站在炉灶前,长发用发绳随意绑着,颈侧有一块淡淡的胎记。", "女人没有回头,只是把火调小了一档,用很平静的声音说:你来了,就知道你会来。", "林夜没有回答。在记忆深层,对话必须谨慎,任何一个错误的字都可能成为触发清除的关键词。他绕到女人侧面,想看清她的脸,却发现她的面部细节正在以肉眼可见的速度消融,像是一张被水泡过的相片,在他将要看清的瞬间,悄悄变得模糊。", "阿洲在他耳机里提示:通道稳定性下降,当前百分之五十八,建议开始打包可回收片段。", "林夜扫了一眼周围,记下了三件东西:灶台上的白色搪瓷锅、窗台上放着的一双儿童雨鞋、以及冰箱上用磁贴压着的一张手绘地图。他把三个物件的坐标依次上传,转身从门口退出。", "记忆在他离开的瞬间开始收缩,巷子两侧的砖墙迅速向中间靠拢,路灯的光也跟着暗下去。林夜加快脚步,在通道完全闭合之前找到了出口锚点,用力踩下去。", "回到现实的过程像是从水里浮出来,有短暂的失重感,然后是所有感官同时回归的那种细密刺痛。他把头环摘下来,放在桌上,看着主屏上跳出的回收摘要。三个坐标,完整度分别是百分之七十一、八十三和九十四。", "阿洲把数据整理好推过来,在最后加了一句备注:冰箱上的手绘地图里,有一条街道的名字和封存档案里的最后一次登记地址完全一致。", "林夜盯着那个地址看了很久。深洲旧城区,合兴里十七号,楼上是一家早就停业的裁缝铺,楼下早年间开过一家小诊所,后来被并入了街道卫生站,所有历史档案按规定封存了二十年。", "他在键盘上敲了几个字,又删掉,重新敲,还是删掉。阿洲在旁边安静地等着,没有催他。事务所有一条不成文的规矩:遇到不确定要不要继续的案子,所有人都可以沉默五分钟,不需要解释。", "五分钟之后,林夜打开了一份新的申请表,在委托类型一栏勾选了实地核查,在附注里写下了三个字:谨慎推进。", "阿洲把申请表收录进当日工作日志,顺手把那杯已经凉掉的咖啡推远了一点。窗外,深洲旧城区的天光刚刚开始泛蓝,一辆早班公共汽车喘着气驶过街角,带起一阵潮湿的风。", "新的一天从这里开始,也从这里变得复杂起来。", "林夜在出发前最后看了一眼委托档案。委托时间戳是昨晚十一点五十七分,距离事务所开门整整差三分钟。他不确定这意味着什么,但他一向相信时间点不会是巧合。", "合兴里离事务所步行大约二十分钟,穿过旧城区的菜市场和两条窄得只能侧身通过的小巷。林夜出门时带了一把折叠伞,天气预报说上午有小雨,和十七年前那天一样。", "他走到菜市场边上的时候,雨真的落下来了。细密的雨丝打在雨伞上,发出连续的轻响。林夜把脚步放慢,在摊位前停了一下,买了两个刚出炉的茶叶蛋,一个给自己,一个装进外套口袋里,备用。", "合兴里十七号到了。楼上的裁缝铺招牌还挂着,漆已经掉了一半,另一半用透明胶带粘着,看上去在这个位置待了很多年。楼下的诊所已经改成了一家五金店,门口堆着各种管件和工具,老板坐在里面看手机,没有抬头。", "林夜在门口站了一会儿,然后走进五金店,用一种很随意的语气问老板:请问这里之前是个诊所对吧,老板您知不知道以前有个姓沈的医生?", "老板终于抬起头,看了他一眼,说:你是第几个来问这个问题的人?", "林夜没想到会得到这个答案。他在心里把今天的进展整理了一下,重新给阿洲发了条消息:这个案子比我以为的要复杂,先把等级从三级调到二级,多备一条回收通道。", "老板把手机扣在桌上,来了兴致。他说,大概每隔两三年,就会有人来问沈医生的事情,有时候是年轻人,有时候是上了年纪的,上一个来的是个穿黑色风衣的女人,大概半年前,问完就走了,什么都没留下。", "林夜在心里把半年前的时间点记住,然后问:那位女士有没有说她是谁,或者留下什么联系方式?", "老板摇摇头,说她来的时候是下午,雨也很大,问完转身就走,连个名字都没说。然后老板顿了顿,补充道:不过她走的时候,在门口那根电线杆上贴了一张纸。他说这话的时候朝门口努了努嘴,那根电线杆就在斜对面,生了锈,缠着几根废弃的网线。", "林夜走过去,在电线杆靠里侧的位置找到了一张已经被雨水反复浸泡、边缘开始卷翘的便利贴。纸上只有一行字,用极细的铅笔写成,笔压很轻,像是刻意不想留下太深的印记:记忆可以删,但地址不会改变。", "他把便利贴用镊子夹起来,装进随身携带的取证袋里。雨重新开始下,比刚才更密,整条合兴里在雨幕里变得灰白而遥远。林夜打开伞,站在电线杆边上,把这行字重新在脑子里过了一遍,觉得它不像是一句提示,更像是一句等了很久才说出口的承诺。", "他重新拨通了阿洲的通讯频道,说:准备第二次深层接入,目标时间节点往前推三年,从删除起点开始。阿洲沉默了两秒,回复说:收到,等你回来。" ], [ "第二章 深网潜入", "林夜坐在工作台中央,接口头环已经戴好,双手悬停在键盘上方,等待深网桥接程序完成最后一次校验。", "任务目标是一段被藏进深层节点的私人记忆。它没有文件名,也没有索引,像一枚被扔进黑潮里的钉子,只能靠微弱的访问残响定位。", "副屏上,系统给出了三条不太乐观的提示:来源匿名、时间戳错乱、回收通道不稳定。" ], [ "第三章 雨巷回声", "连接建立后,第一段回收到的不是画面,而是一阵潮湿的雨声。", "雨点顺着一条老旧的石板巷子落下,远处有人撑着黑伞停在路灯下,像在等谁,又像已经等了很久。", "系统记录显示,这段记忆在过去七年里被人为删除过四次,但每次都会在不同的深夜重新出现。" ], [ "第四章 失真坐标", "他们终于在失真层里找到了坐标,却发现坐标指向的是一座早已拆除的旧车站。", "记忆里的广播还在播报过期的列车时刻,玻璃穹顶上方积着雨,候车厅里坐满了看不清脸的人。" ], [ "第五章 双重委托", "清晨六点,他们刚从深层断开,门铃便响了。", "来的人戴着深灰色帽子,把同样一份委托重新放在桌上,连措辞都和昨晚的一字不差,只在签名处多了一个新的名字。" ], [ "第六章 无名乘客", "第二次进入时,他们看见候车厅角落多了一个孩子。", "孩子穿着被雨打湿的校服,手里攥着半张车票,车票背面写着一行几乎被水泡开的字:不要相信站台上的广播。" ], [ "第七章 镜像证词", "为了验证委托来源,他们调出了另一位委托人的证词记录。", "两份证词在前半段完全一致,只在最后三分钟出现了分叉。" ], [ "第八章 灯箱之后", "林夜在站台广告灯箱后找到了一扇隐藏维护门。", "门后不是管道井,而是一间布满旧磁带和纸质档案的小房间。" ], [ "第九章 回收协议", "事务所服务器在当晚收到一份未签名的回收协议。", "协议条款极短,只要求他们在二十四小时内交出目标记忆的完整副本。" ], [ "第十章 七号出口", "他们决定在现实中去找那座被封闭的七号出口。", "清晨的围挡后满是积水和灰尘,可在围挡缝隙后,林夜看见了一盏仍旧亮着的引导灯。" ] ]) ] }, { id: "lan-archive", title: "局域网夜航", author: "程未远", category: "近未来", description: "一座封闭园区、几台常亮的旧电脑,以及深夜里不断跳出的陌生消息。", wordCount: "12.8 万字", coverStyle: "linear-gradient(135deg, #b86143, #5c2d23)", sections: [ makeSection("lan-lore", "设定资料", "lore", 1, [ ["资料一 园区网络", "园区网络与公网完全隔离,所有访问记录由本地交换系统统一收敛。"], ["资料二 旧机房", "二层最靠里的旧机房仍保留着上一代局域网控制台与部分废弃机柜。"] ]), makeSection("lan-novel", "正文", "novel", 100, [ ["第一章 机房尽头的灯", "凌晨两点十三分,园区办公楼里只剩下二层最靠里的机房还亮着灯。"], ["第二章 没有登记的设备", "他先检查 DHCP 记录,又翻了交换机最近一小时的地址分配表,结果一片空白。"], ["第三章 反向截图", "对方没有回答,只发来一张刚刚拍下的机房照片。"] ]) ] }, { id: "tea-house", title: "旧书铺茶事", author: "沈南絮", category: "日常", description: "一间开在老街口的旧书铺,白天卖书,傍晚煮茶。", wordCount: "8.4 万字", coverStyle: "linear-gradient(135deg, #8f6a3d, #314438)", sections: [ makeSection("tea-lore", "店铺札记", "lore", 1, [ ["资料一 书铺门铃", "门铃是一枚老铜铃,雨天响起来比晴天更轻一些。"] ]), makeSection("tea-novel", "正文", "novel", 100, [ ["第一章 雨落在旧街口", "傍晚五点,雨刚刚落下来,青石板路被洗得发亮。"] ]) ] }, { id: "star-mail", title: "星港来信", author: "林观海", category: "科幻", description: "远航舰队返程之前,地球收到一封延迟了十九年的星际邮件。", wordCount: "15.1 万字", coverStyle: "linear-gradient(135deg, #355c7d, #121c2e)", sections: [ makeSection("star-lore", "星港档案", "lore", 1, [ ["资料一 深空信道", "民用深空信道十九年未曾亮起,因此被默认彻底沉寂。"] ]), makeSection("star-novel", "正文", "novel", 100, [ ["第一章 邮件抵达前夜", "海港城的夜总是比内陆亮一些。"] ]) ] }, { id: "north-city", title: "北城旧事簿", author: "顾行舟", category: "都市", description: "一座旧城的黄昏、几条重复经过的街道,以及那些看似平常却慢慢累积出重量的日子。", wordCount: "10.2 万字", coverStyle: "linear-gradient(135deg, #7c5a43, #28384f)", sections: [ makeSection("north-lore", "旧城资料", "lore", 1, [ ["资料一 北城地标", "天桥、报刊亭和旧商场灯牌,是北城许多故事共同的入口。"] ]), makeSection("north-novel", "正文", "novel", 100, [ ["第一章 天桥下的晚风", "晚高峰刚过,天桥下的人群还没散完。"] ]) ] } ]; export function getBookById(bookId: string) { return demoBooks.find((book) => book.id === bookId); }