kipphi 2.1.0 → 2.1.2-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,14 @@
1
+ # 用“奇谱”谱面内核将谱面解析为编辑器友好的格式!
2
+ 这是一个Phigros KPA、RPE谱面的解析器兼谱面操作系统。它是[KPA(奇谱发生器)](https://github.com/TeamZincs/KPA)的子项目。
3
+
4
+ “奇谱”来自荷兰化学家启普,他发明了“启普发生器”,用于生产气体并随时停止反应。
5
+
6
+ 在(Phigros 自制谱Wiki)[https://pgrfm.miraheze.org/wiki]了解更多。
7
+
1
8
  # Parse your chart into an editor-friendly format with Kipphi!
2
9
 
3
- This is a Phigros KipphiApparatus/Re:PhiEdit ChartJSON Parser. It is a subproject of [KPA](https://github.com/TeamZincs/KPA).
10
+ This is a Phigros KipphiApparatus/Re:PhiEdit ChartJSON Parser and Chart Operating System. It is a subproject of [KPA](https://github.com/TeamZincs/KPA).
4
11
 
5
12
  "Kipphi" comes from the Dutch chemist Kipp, who invented Kipp's Apparatus, which was used to produce gas and stop the reaction at any time.
6
13
 
7
- 警告:KPA 2.1版本发布以前均为实验性代码,可能会出现API兼容性问题,当前不建议将此代码用于生产!
14
+ Learn more at [Phigros Custom Chart Wiki](https://pgrfm.miraheze.org/wiki).
package/bpm.ts CHANGED
@@ -63,6 +63,15 @@ export class BPMEndNode extends EventEndNode {
63
63
  override previous: BPMStartNode;
64
64
  /** 下一个BPM起始节点 */
65
65
  override next: BPMStartNode;
66
+
67
+ // @ts-expect-error 强加一个getter
68
+ get value(): number {
69
+ return this.previous.value;
70
+ }
71
+ set value(value: number) {
72
+ if (!this.previous) { return; }
73
+ this.previous.value = value;
74
+ }
66
75
 
67
76
  /**
68
77
  * 创建一个新的BPM结束节点
package/env.ts CHANGED
@@ -53,6 +53,7 @@ export enum ERROR_IDS {
53
53
  SEQUENCE_NODE_TIME_OCCUPIED = ENS | OCCPIED | 1,
54
54
  INVALID_EVENT_NODE_SEQUENCE_TYPE = ENS | INVALID_DATA | 0,
55
55
  EVENT_NODE_TIME_NOT_INCREMENTAL = ENS | INVALID_DATA | 1,
56
+ EVENT_NODE_NOT_DENSE = ENS | INVALID_DATA | 2,
56
57
  PARENT_SEQUENCE_NOT_FOUND = ENS | INVALID_USAGE | 1,
57
58
  NEEDS_AT_LEAST_ONE_ENS = ENS | INVALID_USAGE | 2,
58
59
  SEQUENCE_TYPE_NOT_CONSISTENT = ENS | INVALID_USAGE | 3,
@@ -175,9 +176,37 @@ export const ERRORS = {
175
176
  `Parametric Macro requires key. At ${pos}`,
176
177
  MACRO_NOT_PARAMETRIC: (macroId: string, pos) =>
177
178
  `Macro '${macroId}' is not parametric. At ${pos}`,
179
+ EVENT_NODE_NOT_DENSE: (pos: string) =>
180
+ `EventNode is not dense. At ${pos}`,
178
181
  } satisfies Record<keyof typeof ERROR_IDS, (...args: any[]) => string>
179
182
 
183
+ type EnumKeys<E extends Record<string, string | number>> = E[keyof E];
184
+
185
+ // 工具类型:检查 T 的键是否恰好等于枚举的值集合
186
+ type AssertExactEnumKeys<T, E extends Record<string, string | number>> =
187
+ // 1. 收集 T 的键(作为字符串字面量类型)
188
+ (keyof T) extends (keyof E) // 不能有多余键
189
+ ? (keyof E) extends (keyof T) // 不能缺键
190
+ ? T // 通过检查
191
+ : { error: any/*error: "Interface is missing some enum keys"*/ }
192
+ : { error: "Interface has extra keys not in enum" };
193
+
194
+ // 用类型别名做“编译期断言”
195
+ type _CheckMap = AssertExactEnumKeys<ErrorMap, typeof ERROR_IDS>;
196
+ interface _Error extends _CheckMap {
197
+ error: "";
198
+ }
199
+
200
+
201
+ interface ErrorMap extends Record<keyof typeof ERROR_IDS, Array<any>>{
202
+ EVENT_NODE_NOT_DENSE: [EventNode];
203
+ }
204
+
205
+ type ArgsOf<ET extends ERROR_IDS> = ET extends keyof ErrorMap ? ErrorMap[ET] : never;
206
+
180
207
  export class KPAError<ET extends ERROR_IDS> extends Error {
208
+ fixed = false;
209
+ args: ArgsOf<ET> | [];
181
210
  constructor(message: string, public id: ET) {
182
211
  super(message);
183
212
  }
@@ -186,8 +215,15 @@ export class KPAError<ET extends ERROR_IDS> extends Error {
186
215
  *
187
216
  * 此时可以调用该方法,该方法会输出错误并把它保存到KPAError的一个`buffer`静态属性下。
188
217
  */
189
- warn() {
218
+ warn(...args: ArgsOf<ET> | []) {
190
219
  console.warn(this.stack);
220
+ this.args = args;
221
+ KPAError.buffer.push(this);
222
+ }
223
+ fix(...args: ArgsOf<ET> | []) {
224
+ console.warn("[Auto Fixed]" + this.stack);
225
+ this.fixed = true;
226
+ this.args = args;
191
227
  KPAError.buffer.push(this);
192
228
  }
193
229
  static buffer: KPAError<ERROR_IDS>[] = [];
package/event.ts CHANGED
@@ -505,7 +505,7 @@ export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型
505
505
  return type === EventType.speed ? 10 :
506
506
  type === EventType.scaleX || type === EventType.scaleY ? 1.0 :
507
507
  type === EventType.text ? "" :
508
- type === EventType.color ? [0, 0, 0] :
508
+ type === EventType.color ? [255, 255, 255] :
509
509
  0
510
510
  }
511
511
  /**
@@ -649,32 +649,28 @@ export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型
649
649
  err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn()
650
650
  }
651
651
  if (!TC.lt(event.startTime, event.endTime)) {
652
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn()
652
+ if (TC.eq(event.startTime, event.endTime)) {
653
+ // 零长事件直接忽略,并认为已经修复
654
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).fix();
655
+ continue;
656
+ } else {
657
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn()
658
+ }
653
659
  }
654
- lastEndTime = event.endTime;
655
660
  if (lastEnd.type === NodeType.HEAD) {
656
661
  EventNode.connect(lastEnd, start)
657
- // 如果上一个是钩定事件,那么一块捋平
658
- } else if (
659
- lastEnd.value === lastEnd.previous.value
660
- && lastEnd.previous.evaluator instanceof EasedEvaluator
661
- ) {
662
- lastEnd.time = start.time
663
- EventNode.connect(lastEnd, start)
664
- } else if (TC.eq(lastEnd.time, start.time)) {
665
- const val = lastEnd.value;
666
- const midStart = new EventStartNode(lastEnd.time, val);
667
- const midEnd = new EventEndNode(start.time, val);
668
- midStart.evaluator = lastEnd.previous.evaluator;
669
- EventNode.connect(lastEnd, midStart);
670
- EventNode.connect(midStart, midEnd);
662
+ } else if (TC.gt(event.startTime, lastEndTime)) {
663
+ err.EVENT_NODE_NOT_DENSE(`${pos}.events[${index}]`).warn();
664
+ const mid = new EventStartNode(lastEndTime, start.value);
665
+ const midEnd = new EventEndNode(event.startTime, end.value);
666
+ EventNode.connect(lastEnd, mid);
667
+ EventNode.connect(mid, midEnd);
671
668
  EventNode.connect(midEnd, start);
672
- listLength++;
673
669
  } else {
674
-
675
670
  EventNode.connect(lastEnd, start)
676
671
  }
677
672
 
673
+ lastEndTime = event.endTime;
678
674
  lastEnd = end;
679
675
  }
680
676
  const last = lastEnd;
@@ -948,6 +944,29 @@ export class EventNodeSequence<VT extends EventValueESType = number> { // 泛型
948
944
  dest.initJump();
949
945
  return dest;
950
946
  }
947
+ checkErrors() {
948
+ let currentNode: EventStartNode<VT> = this.head.next;
949
+ if (TC.ne(currentNode.time, [0, 0, 1])) {
950
+ err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).fix();
951
+ currentNode.time = [0, 0, 1];
952
+ }
953
+ const endNode = currentNode.next;
954
+ if (endNode.type === NodeType.TAIL) {
955
+ return;
956
+ }
957
+
958
+ let lastEnd: EventEndNode<VT> = endNode;
959
+ while (true) {
960
+ const endNode = currentNode.next;
961
+ if (endNode.type === NodeType.TAIL) {
962
+ break;
963
+ }
964
+ if (TC.ne(lastEnd.time, currentNode.time)) {
965
+ err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).warn();
966
+ }
967
+ currentNode = currentNode.next.next;
968
+ }
969
+ }
951
970
  }
952
971
 
953
972
  export type SpeedENS = EventNodeSequence<number> & { type: EventType.speed };
package/index.d.ts CHANGED
@@ -533,7 +533,7 @@ declare module "chartTypes" {
533
533
  export type ExtendedEventTypeName = "scaleX" | "scaleY" | "text" | "color";
534
534
  }
535
535
  declare module "version" {
536
- export const VERSION = 210;
536
+ export const VERSION = 212;
537
537
  export const SCHEMA = "https://cdn.jsdelivr.net/npm/kipphi@2.1.0/chartType2.schema.json";
538
538
  }
539
539
  declare module "util" {
@@ -652,6 +652,8 @@ declare module "bpm" {
652
652
  previous: BPMStartNode;
653
653
  /** 下一个BPM起始节点 */
654
654
  next: BPMStartNode;
655
+ get value(): number;
656
+ set value(value: number);
655
657
  /**
656
658
  * 创建一个新的BPM结束节点
657
659
  * @param endTime 节点结束时间
@@ -2179,6 +2181,7 @@ declare module "event" {
2179
2181
  * @throws {KPAError<ERROR_IDS.NEEDS_AT_LEAST_ONE_ENS>}
2180
2182
  */
2181
2183
  static mergeSequences(sequences: EventNodeSequence[]): EventNodeSequence<number>;
2184
+ checkErrors(): void;
2182
2185
  }
2183
2186
  export type SpeedENS = EventNodeSequence<number> & {
2184
2187
  type: EventType.speed;
@@ -2186,12 +2189,14 @@ declare module "event" {
2186
2189
  }
2187
2190
  declare module "env" {
2188
2191
  import { type TimeT, type EventValueType } from "chartTypes";
2192
+ import { EventNode } from "event";
2189
2193
  export enum ERROR_IDS {
2190
2194
  UI_OCCUPIED = 272,
2191
2195
  SEQUENCE_NAME_OCCUPIED = 1552,
2192
2196
  SEQUENCE_NODE_TIME_OCCUPIED = 1553,
2193
2197
  INVALID_EVENT_NODE_SEQUENCE_TYPE = 1568,
2194
2198
  EVENT_NODE_TIME_NOT_INCREMENTAL = 1569,
2199
+ EVENT_NODE_NOT_DENSE = 1570,
2195
2200
  PARENT_SEQUENCE_NOT_FOUND = 1585,
2196
2201
  NEEDS_AT_LEAST_ONE_ENS = 1586,
2197
2202
  SEQUENCE_TYPE_NOT_CONSISTENT = 1587,
@@ -2255,16 +2260,24 @@ declare module "env" {
2255
2260
  JAVASCRIPT_SYNTAX_ERROR: (error: Error, macroId: string) => string;
2256
2261
  PARAMETRIC_MACRO_REQUIRES_PROTO_KEY: (pos: any) => string;
2257
2262
  MACRO_NOT_PARAMETRIC: (macroId: string, pos: any) => string;
2263
+ EVENT_NODE_NOT_DENSE: (pos: string) => string;
2258
2264
  };
2265
+ interface ErrorMap extends Record<keyof typeof ERROR_IDS, Array<any>> {
2266
+ EVENT_NODE_NOT_DENSE: [EventNode];
2267
+ }
2268
+ type ArgsOf<ET extends ERROR_IDS> = ET extends keyof ErrorMap ? ErrorMap[ET] : never;
2259
2269
  export class KPAError<ET extends ERROR_IDS> extends Error {
2260
2270
  id: ET;
2271
+ fixed: boolean;
2272
+ args: ArgsOf<ET> | [];
2261
2273
  constructor(message: string, id: ET);
2262
2274
  /**
2263
2275
  * 对于解析谱面等场景,有时可能需要找出全部的错误,不宜直接抛出错误中断代码执行
2264
2276
  *
2265
2277
  * 此时可以调用该方法,该方法会输出错误并把它保存到KPAError的一个`buffer`静态属性下。
2266
2278
  */
2267
- warn(): void;
2279
+ warn(...args: ArgsOf<ET> | []): void;
2280
+ fix(...args: ArgsOf<ET> | []): void;
2268
2281
  static buffer: KPAError<ERROR_IDS>[];
2269
2282
  static flush(): void;
2270
2283
  }
@@ -2311,6 +2324,7 @@ declare module "env" {
2311
2324
  JAVASCRIPT_SYNTAX_ERROR: (error: Error, macroId: string) => KPAError<ERROR_IDS.JAVASCRIPT_SYNTAX_ERROR>;
2312
2325
  PARAMETRIC_MACRO_REQUIRES_PROTO_KEY: (pos: any) => KPAError<ERROR_IDS.PARAMETRIC_MACRO_REQUIRES_PROTO_KEY>;
2313
2326
  MACRO_NOT_PARAMETRIC: (macroId: string, pos: any) => KPAError<ERROR_IDS.MACRO_NOT_PARAMETRIC>;
2327
+ EVENT_NODE_NOT_DENSE: (pos: string) => KPAError<ERROR_IDS.EVENT_NODE_NOT_DENSE>;
2314
2328
  };
2315
2329
  freeze(): void;
2316
2330
  };
package/index.js CHANGED
@@ -60,6 +60,7 @@ var ERROR_IDS;
60
60
  ERROR_IDS2[ERROR_IDS2["SEQUENCE_NODE_TIME_OCCUPIED"] = ENS | OCCPIED | 1] = "SEQUENCE_NODE_TIME_OCCUPIED";
61
61
  ERROR_IDS2[ERROR_IDS2["INVALID_EVENT_NODE_SEQUENCE_TYPE"] = ENS | INVALID_DATA | 0] = "INVALID_EVENT_NODE_SEQUENCE_TYPE";
62
62
  ERROR_IDS2[ERROR_IDS2["EVENT_NODE_TIME_NOT_INCREMENTAL"] = ENS | INVALID_DATA | 1] = "EVENT_NODE_TIME_NOT_INCREMENTAL";
63
+ ERROR_IDS2[ERROR_IDS2["EVENT_NODE_NOT_DENSE"] = ENS | INVALID_DATA | 2] = "EVENT_NODE_NOT_DENSE";
63
64
  ERROR_IDS2[ERROR_IDS2["PARENT_SEQUENCE_NOT_FOUND"] = ENS | INVALID_USAGE | 1] = "PARENT_SEQUENCE_NOT_FOUND";
64
65
  ERROR_IDS2[ERROR_IDS2["NEEDS_AT_LEAST_ONE_ENS"] = ENS | INVALID_USAGE | 2] = "NEEDS_AT_LEAST_ONE_ENS";
65
66
  ERROR_IDS2[ERROR_IDS2["SEQUENCE_TYPE_NOT_CONSISTENT"] = ENS | INVALID_USAGE | 3] = "SEQUENCE_TYPE_NOT_CONSISTENT";
@@ -122,17 +123,27 @@ var ERRORS = {
122
123
  PROTO_PRESENT_IN_NONPARAMETRIC: (macroId) => `'@proto can only be used in parametric Macros. At ${macroId}'`,
123
124
  JAVASCRIPT_SYNTAX_ERROR: (error, macroId) => `JavaScript Syntax Error: ${error.message}. At ${macroId}`,
124
125
  PARAMETRIC_MACRO_REQUIRES_PROTO_KEY: (pos) => `Parametric Macro requires key. At ${pos}`,
125
- MACRO_NOT_PARAMETRIC: (macroId, pos) => `Macro '${macroId}' is not parametric. At ${pos}`
126
+ MACRO_NOT_PARAMETRIC: (macroId, pos) => `Macro '${macroId}' is not parametric. At ${pos}`,
127
+ EVENT_NODE_NOT_DENSE: (pos) => `EventNode is not dense. At ${pos}`
126
128
  };
127
129
 
128
130
  class KPAError extends Error {
129
131
  id;
132
+ fixed = false;
133
+ args;
130
134
  constructor(message, id) {
131
135
  super(message);
132
136
  this.id = id;
133
137
  }
134
- warn() {
138
+ warn(...args) {
135
139
  console.warn(this.stack);
140
+ this.args = args;
141
+ KPAError.buffer.push(this);
142
+ }
143
+ fix(...args) {
144
+ console.warn("[Auto Fixed]" + this.stack);
145
+ this.fixed = true;
146
+ this.args = args;
136
147
  KPAError.buffer.push(this);
137
148
  }
138
149
  static buffer = [];
@@ -1643,7 +1654,7 @@ class EventNodeSequence {
1643
1654
  this.listLength = 1;
1644
1655
  }
1645
1656
  static getDefaultValueFromEventType(type) {
1646
- return type === 4 /* speed */ ? 10 : type === 7 /* scaleX */ || type === 8 /* scaleY */ ? 1 : type === 9 /* text */ ? "" : type === 10 /* color */ ? [0, 0, 0] : 0;
1657
+ return type === 4 /* speed */ ? 10 : type === 7 /* scaleX */ || type === 8 /* scaleY */ ? 1 : type === 9 /* text */ ? "" : type === 10 /* color */ ? [255, 255, 255] : 0;
1647
1658
  }
1648
1659
  static fromRPEJSON(type, data, chart, pos, endValue) {
1649
1660
  const { templateEasingLib: templates } = chart;
@@ -1723,26 +1734,26 @@ class EventNodeSequence {
1723
1734
  err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}] and the previous`).warn();
1724
1735
  }
1725
1736
  if (!TC2.lt(event.startTime, event.endTime)) {
1726
- err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn();
1737
+ if (TC2.eq(event.startTime, event.endTime)) {
1738
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).fix();
1739
+ continue;
1740
+ } else {
1741
+ err.EVENT_NODE_TIME_NOT_INCREMENTAL(`${pos}.events[${index}]`).warn();
1742
+ }
1727
1743
  }
1728
- lastEndTime = event.endTime;
1729
1744
  if (lastEnd.type === 0 /* HEAD */) {
1730
1745
  EventNode.connect(lastEnd, start);
1731
- } else if (lastEnd.value === lastEnd.previous.value && lastEnd.previous.evaluator instanceof EasedEvaluator) {
1732
- lastEnd.time = start.time;
1733
- EventNode.connect(lastEnd, start);
1734
- } else if (TC2.eq(lastEnd.time, start.time)) {
1735
- const val = lastEnd.value;
1736
- const midStart = new EventStartNode(lastEnd.time, val);
1737
- const midEnd = new EventEndNode(start.time, val);
1738
- midStart.evaluator = lastEnd.previous.evaluator;
1739
- EventNode.connect(lastEnd, midStart);
1740
- EventNode.connect(midStart, midEnd);
1746
+ } else if (TC2.gt(event.startTime, lastEndTime)) {
1747
+ err.EVENT_NODE_NOT_DENSE(`${pos}.events[${index}]`).warn();
1748
+ const mid = new EventStartNode(lastEndTime, start.value);
1749
+ const midEnd = new EventEndNode(event.startTime, end.value);
1750
+ EventNode.connect(lastEnd, mid);
1751
+ EventNode.connect(mid, midEnd);
1741
1752
  EventNode.connect(midEnd, start);
1742
- listLength++;
1743
1753
  } else {
1744
1754
  EventNode.connect(lastEnd, start);
1745
1755
  }
1756
+ lastEndTime = event.endTime;
1746
1757
  lastEnd = end;
1747
1758
  }
1748
1759
  const last = lastEnd;
@@ -1945,6 +1956,28 @@ class EventNodeSequence {
1945
1956
  dest.initJump();
1946
1957
  return dest;
1947
1958
  }
1959
+ checkErrors() {
1960
+ let currentNode = this.head.next;
1961
+ if (TC2.ne(currentNode.time, [0, 0, 1])) {
1962
+ err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).fix();
1963
+ currentNode.time = [0, 0, 1];
1964
+ }
1965
+ const endNode = currentNode.next;
1966
+ if (endNode.type === 1 /* TAIL */) {
1967
+ return;
1968
+ }
1969
+ let lastEnd = endNode;
1970
+ while (true) {
1971
+ const endNode2 = currentNode.next;
1972
+ if (endNode2.type === 1 /* TAIL */) {
1973
+ break;
1974
+ }
1975
+ if (TC2.ne(lastEnd.time, currentNode.time)) {
1976
+ err.EVENT_NODE_NOT_DENSE(`${this.id}, ${currentNode.time}`).warn();
1977
+ }
1978
+ currentNode = currentNode.next.next;
1979
+ }
1980
+ }
1948
1981
  }
1949
1982
  // src/note.ts
1950
1983
  var notePropTypes = {
@@ -2007,7 +2040,7 @@ class Note {
2007
2040
  return note;
2008
2041
  }
2009
2042
  computeVisibleBeats(timeCalculator) {
2010
- if (!this.visibleTime || this.visibleTime >= 90000) {
2043
+ if (this.visibleTime === undefined || this.visibleTime === null || this.visibleTime >= 90000) {
2011
2044
  this.visibleBeats = Infinity;
2012
2045
  return;
2013
2046
  }
@@ -3033,6 +3066,15 @@ class BPMEndNode extends EventEndNode {
3033
3066
  spb;
3034
3067
  previous;
3035
3068
  next;
3069
+ get value() {
3070
+ return this.previous.value;
3071
+ }
3072
+ set value(value) {
3073
+ if (!this.previous) {
3074
+ return;
3075
+ }
3076
+ this.previous.value = value;
3077
+ }
3036
3078
  constructor(endTime) {
3037
3079
  super(endTime, null);
3038
3080
  }
@@ -3167,7 +3209,7 @@ class TimeCalculator {
3167
3209
  }
3168
3210
  }
3169
3211
  // src/version.ts
3170
- var VERSION = 210;
3212
+ var VERSION = 212;
3171
3213
  var SCHEMA = "https://cdn.jsdelivr.net/npm/kipphi@2.1.0/chartType2.schema.json";
3172
3214
 
3173
3215
  // src/chart.ts
@@ -3803,9 +3845,10 @@ class OperationList extends EventTarget {
3803
3845
  this.dispatchEvent(new OperationErrorEvent(operation, e));
3804
3846
  return;
3805
3847
  }
3848
+ this.undoneOperations = [];
3849
+ this.operations.push(operation);
3806
3850
  this.dispatchEvent(new OperationEvent("do", operation));
3807
3851
  this.processFlags(operation);
3808
- this.operations.push(operation);
3809
3852
  }
3810
3853
  processFlags(operation) {
3811
3854
  if (operation.updatesEditor) {
package/note.ts CHANGED
@@ -120,7 +120,7 @@ export class Note {
120
120
  return note;
121
121
  }
122
122
  computeVisibleBeats(timeCalculator: TimeCalculator) {
123
- if (!this.visibleTime || this.visibleTime >= 90000) {
123
+ if (this.visibleTime === undefined || this.visibleTime === null || this.visibleTime >= 90000) {
124
124
  this.visibleBeats = Infinity;
125
125
  return;
126
126
  }
@@ -147,9 +147,10 @@ export class OperationList extends EventTarget {
147
147
  this.dispatchEvent(new OperationErrorEvent(operation, e as Error))
148
148
  return
149
149
  }
150
+ this.undoneOperations = [];
151
+ this.operations.push(operation);
150
152
  this.dispatchEvent(new OperationEvent("do", operation));
151
153
  this.processFlags(operation);
152
- this.operations.push(operation);
153
154
  }
154
155
  processFlags(operation: Operation) {
155
156
 
package/package.json CHANGED
@@ -1,26 +1,26 @@
1
1
  {
2
- "name": "kipphi",
3
- "description": "Parse your Phigros Chart(.rpe.json or .kpa.json) into an editor-friendly format.",
4
- "version": "2.1.0",
5
- "author": "Team Zincs (https://github.com/TeamZincs)",
6
- "license": "MIT",
7
- "repository": {
8
- "type": "git",
9
- "url": "https://github.com/TeamZincs/kipphi.git"
10
- },
11
- "module": "index.ts",
12
- "main": "index.ts",
13
- "type": "module",
14
- "devDependencies": {
15
- "@types/bun": "latest"
16
- },
17
- "peerDependencies": {
18
- "typescript": "^5"
19
- },
20
- "exports": {
21
- "./operation": null,
22
- ".": {
23
- "import": "./index.ts"
2
+ "name": "kipphi",
3
+ "description": "Parse your Phigros Chart(.rpe.json or .kpa.json) into an editor-friendly format.",
4
+ "version": "2.1.2-rc.1",
5
+ "author": "Team Zincs (https://github.com/TeamZincs)",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/TeamZincs/kipphi.git"
10
+ },
11
+ "module": "index.ts",
12
+ "main": "index.ts",
13
+ "type": "module",
14
+ "devDependencies": {
15
+ "@types/bun": "latest"
16
+ },
17
+ "peerDependencies": {
18
+ "typescript": "^5"
19
+ },
20
+ "exports": {
21
+ "./operation": null,
22
+ ".": {
23
+ "import": "./index.ts"
24
+ }
24
25
  }
25
- }
26
26
  }
package/version.ts CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  /// #declaration:global
4
4
 
5
- export const VERSION = 210;
5
+ export const VERSION = 212;
6
6
  export const SCHEMA = "https://cdn.jsdelivr.net/npm/kipphi@2.1.0/chartType2.schema.json"
7
7
 
8
8