📦 添加虚拟环境和启动脚本

新增:
- backend/venv/ - Python 虚拟环境
- backend/start.sh - 启动脚本(使用虚拟环境)
- backend/requirements.txt - 依赖列表
- .gitignore - 忽略虚拟环境和缓存文件

说明:
- 每个项目使用独立虚拟环境
- 避免依赖冲突
- 启动脚本自动创建和激活虚拟环境
This commit is contained in:
2026-04-04 18:28:31 +08:00
parent 9ab279e1fe
commit 96f6318101
32058 changed files with 3949495 additions and 22 deletions

View File

@@ -0,0 +1,78 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Ivan Kopeykin @vankop
*/
"use strict";
/**
* @template T
*/
class AppendOnlyStackedSet {
/**
* @param {Set<T>[]} sets an optional array of sets
*/
constructor(sets = []) {
/** @type {Set<T>[]} */
this._sets = sets;
/** @type {Set<T> | undefined} */
this._current = undefined;
}
/**
* @param {T} el element
*/
add(el) {
if (!this._current) {
this._current = new Set();
this._sets.push(this._current);
}
this._current.add(el);
}
/**
* @param {T} el element
* @returns {boolean} result
*/
has(el) {
for (const set of this._sets) {
if (set.has(el)) return true;
}
return false;
}
clear() {
this._sets = [];
if (this._current) {
this._current = undefined;
}
}
/**
* @returns {AppendOnlyStackedSet<T>} child
*/
createChild() {
return new AppendOnlyStackedSet(this._sets.length ? [...this._sets] : []);
}
/**
* @returns {Iterator<T>} iterable iterator
*/
[Symbol.iterator]() {
const iterators = this._sets.map((map) => map[Symbol.iterator]());
let current = iterators.pop();
return {
next() {
if (!current) return { done: true, value: undefined };
let result = current.next();
while (result.done && iterators.length > 0) {
current = /** @type {SetIterator<T>} */ (iterators.pop());
result = current.next();
}
return result;
}
};
}
}
module.exports = AppendOnlyStackedSet;